fixed plugin image size problem
[framework/uifw/elementary.git] / src / lib / elm_config.c
1 #ifdef HAVE_CONFIG_H
2 # include "elementary_config.h"
3 #endif
4
5 #ifdef HAVE_EVIL
6 # include <Evil.h>
7 #endif
8
9 #include <Elementary.h>
10 #include "elm_priv.h"
11
12 EAPI int ELM_EVENT_CONFIG_ALL_CHANGED = 0;
13
14 Elm_Config *_elm_config = NULL;
15 char *_elm_profile = NULL;
16 static Eet_Data_Descriptor *_config_edd = NULL;
17 static Eet_Data_Descriptor *_config_font_overlay_edd = NULL;
18 static Eet_Data_Descriptor *_config_color_edd = NULL;
19 static Eet_Data_Descriptor *_config_color_palette_edd = NULL;
20 const char *_elm_preferred_engine = NULL;
21
22 static Ecore_Poller *_elm_cache_flush_poller = NULL;
23
24 const char *_elm_engines[] = {
25    "software_x11",
26    "fb",
27    "directfb",
28    "software_16_x11",
29    "software_8_x11",
30    "xrender_x11",
31    "opengl_x11",
32    "software_gdi",
33    "software_16_wince_gdi",
34    "sdl",
35    "software_16_sdl",
36    "opengl_sdl",
37    "buffer",
38    "ews",
39    "opengl_cocoa",
40    "psl1ght",
41    "wayland_shm",
42    "wayland_egl",
43    NULL
44 };
45
46 /* whenever you want to add a new text class support into Elementary,
47    declare it both here and in the (default) theme */
48 static const Elm_Text_Class _elm_text_classes[] = {
49    {"button", "Button Labels"},
50    {"label", "Text Labels"},
51    {"entry", "Text Entries"},
52    {"title_bar", "Title Bar"},
53    {"list_item", "List Items"},
54    {"grid_item", "Grid Items"},
55    {"toolbar_item", "Toolbar Items"},
56    {"menu_item", "Menu Items"},
57    {NULL, NULL}
58 };
59
60 static void        _desc_init(void);
61 static void        _desc_shutdown(void);
62 static void        _profile_fetch_from_conf(void);
63 static void        _config_free(void);
64 static void        _config_apply(void);
65 static Elm_Config *_config_user_load(void);
66 static Elm_Config *_config_system_load(void);
67 static void        _config_load(void);
68 static void        _config_update(void);
69 static void        _env_get(void);
70 static size_t      _elm_data_dir_snprintf(char       *dst,
71                                           size_t      size,
72                                           const char *fmt, ...)
73                                           EINA_PRINTF(3, 4);
74 static size_t _elm_user_dir_snprintf(char       *dst,
75                                      size_t      size,
76                                      const char *fmt, ...)
77                                      EINA_PRINTF(3, 4);
78
79 #define ELM_CONFIG_VAL(edd, type, member, dtype) \
80   EET_DATA_DESCRIPTOR_ADD_BASIC(edd, type, #member, member, dtype)
81 #define ELM_CONFIG_LIST(edd, type, member, eddtype) \
82   EET_DATA_DESCRIPTOR_ADD_LIST(edd, type, #member, member, eddtype)
83
84 #ifdef HAVE_ELEMENTARY_X
85 static Ecore_Event_Handler *_prop_change_handler = NULL;
86 static Ecore_Timer *_prop_all_update_timer = NULL;
87 static Ecore_Timer *_prop_change_delay_timer = NULL;
88 static Ecore_X_Window _root_1st = 0;
89 #define ATOM_COUNT 2
90 static Ecore_X_Atom _atom[ATOM_COUNT];
91 static Ecore_X_Atom _atom_config = 0;
92 static const char *_atom_names[ATOM_COUNT] =
93 {
94    "ELM_PROFILE",
95    "ELM_CONFIG"
96 };
97 #define ATOM_E_PROFILE                              0
98 #define ATOM_E_CONFIG                               1
99
100 static Eina_Bool _prop_all_update_cb(void *data __UNUSED__);
101 static Eina_Bool _prop_config_get(void);
102 static void      _prop_config_set(void);
103 static Eina_Bool _prop_change(void *data  __UNUSED__,
104                               int ev_type __UNUSED__,
105                               void       *ev);
106
107 static Eina_Bool
108 _prop_all_update_cb(void *data __UNUSED__)
109 {
110    _prop_config_set();
111    ecore_x_window_prop_string_set(_root_1st, _atom[ATOM_E_PROFILE],
112                                   _elm_profile);
113    _prop_all_update_timer = NULL;
114    return EINA_FALSE;
115 }
116
117 static Eina_Bool
118 _prop_config_get(void)
119 {
120    int size = 0;
121    Ecore_X_Atom atom;
122    char buf[512];
123    unsigned char *data = NULL;
124    Elm_Config *config_data;
125
126    snprintf(buf, sizeof(buf), "ELM_CONFIG_%s", _elm_profile);
127    atom = ecore_x_atom_get(buf);
128    _atom_config = atom;
129    if (!ecore_x_window_prop_property_get(_root_1st,
130                                          atom, _atom[ATOM_E_CONFIG],
131                                          8, &data, &size))
132      {
133         if (!ecore_x_window_prop_property_get(_root_1st,
134                                               _atom[ATOM_E_CONFIG],
135                                               _atom[ATOM_E_CONFIG],
136                                               8, &data, &size))
137           return EINA_FALSE;
138         else
139           _atom_config = _atom[ATOM_E_CONFIG];
140      }
141    else
142      _atom_config = atom;
143    if (size < 1)
144      {
145         free(data);
146         return EINA_FALSE;
147      }
148    config_data = eet_data_descriptor_decode(_config_edd, data, size);
149    free(data);
150    if (!config_data) return EINA_FALSE;
151
152    /* What do we do on version mismatch when someone changes the
153     * config in the rootwindow? */
154    /* Most obvious case, new version and we are still linked to
155     * whatever was there before, we just ignore until user restarts us */
156    if (config_data->config_version > ELM_CONFIG_VERSION)
157      return EINA_TRUE;
158    /* What in the case the version is older? Do we even support those
159     * cases or we only check for equality above? */
160
161    _config_free();
162    _elm_config = config_data;
163    _config_apply();
164    _elm_config_font_overlay_apply();
165    _elm_rescale();
166    _elm_recache();
167    ecore_event_add(ELM_EVENT_CONFIG_ALL_CHANGED, NULL, NULL, NULL);
168    return EINA_TRUE;
169 }
170
171 static void
172 _prop_config_set(void)
173 {
174    unsigned char *config_data = NULL;
175    int size = 0;
176
177    config_data = eet_data_descriptor_encode(_config_edd, _elm_config, &size);
178    if (config_data)
179      {
180         Ecore_X_Atom atom;
181         char buf[512];
182
183         snprintf(buf, sizeof(buf), "ELM_CONFIG_%s", _elm_profile);
184         atom = ecore_x_atom_get(buf);
185         _atom_config = atom;
186
187         ecore_x_window_prop_property_set(_root_1st, _atom_config,
188                                          _atom[ATOM_E_CONFIG], 8,
189                                          config_data, size);
190         free(config_data);
191      }
192 }
193
194 static Eina_Bool
195 _prop_change_delay_cb(void *data __UNUSED__)
196 {
197    char *s;
198
199    s = ecore_x_window_prop_string_get(_root_1st, _atom[ATOM_E_PROFILE]);
200    if (s)
201      {
202         if (_elm_profile) free(_elm_profile);
203         _elm_profile = s;
204      }
205    _prop_config_get();
206    _prop_change_delay_timer = NULL;
207    return EINA_FALSE;
208 }
209
210 static Eina_Bool
211 _prop_change(void *data  __UNUSED__,
212              int ev_type __UNUSED__,
213              void       *ev)
214 {
215    Ecore_X_Event_Window_Property *event = ev;
216
217    if (event->win == _root_1st)
218      {
219         if (event->atom == _atom[ATOM_E_PROFILE])
220           {
221              if (_prop_change_delay_timer) ecore_timer_del(_prop_change_delay_timer);
222              _prop_change_delay_timer = ecore_timer_add(0.1, _prop_change_delay_cb, NULL);
223           }
224         else if (((_atom_config > 0) && (event->atom == _atom_config)) ||
225                  (event->atom == _atom[ATOM_E_CONFIG]))
226           {
227              if (_prop_change_delay_timer) ecore_timer_del(_prop_change_delay_timer);
228              _prop_change_delay_timer = ecore_timer_add(0.1, _prop_change_delay_cb, NULL);
229           }
230      }
231    return ECORE_CALLBACK_PASS_ON;
232 }
233
234 #endif
235
236 static void
237 _desc_init(void)
238 {
239    Eet_Data_Descriptor_Class eddc;
240
241    EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Elm_Config);
242    eddc.func.str_direct_alloc = NULL;
243    eddc.func.str_direct_free = NULL;
244
245    _config_edd = eet_data_descriptor_file_new(&eddc);
246    if (!_config_edd)
247      {
248         printf("EEEK! eet_data_descriptor_file_new() failed\n");
249         return;
250      }
251
252    memset(&eddc, 0, sizeof(eddc)); /* just in case... */
253    EET_EINA_STREAM_DATA_DESCRIPTOR_CLASS_SET(&eddc, Elm_Font_Overlay);
254    eddc.func.str_direct_alloc = NULL;
255    eddc.func.str_direct_free = NULL;
256
257    _config_font_overlay_edd = eet_data_descriptor_stream_new(&eddc);
258    if (!_config_font_overlay_edd)
259      {
260         printf("EEEK! eet_data_descriptor_stream_new() failed\n");
261         eet_data_descriptor_free(_config_edd);
262         return;
263      }
264
265    memset(&eddc, 0, sizeof(eddc)); /* just in case... */
266    EET_EINA_STREAM_DATA_DESCRIPTOR_CLASS_SET(&eddc, Elm_Color_RGBA);
267    eddc.func.str_direct_alloc = NULL;
268    eddc.func.str_direct_free = NULL;
269
270    _config_color_edd = eet_data_descriptor_stream_new(&eddc);
271    if (!_config_color_edd)
272      {
273         printf("EEEK! eet_data_descriptor_stream_new() failed\n");
274         eet_data_descriptor_free(_config_edd);
275         return;
276      }
277
278    memset(&eddc, 0, sizeof(eddc)); /* just in case... */
279    EET_EINA_STREAM_DATA_DESCRIPTOR_CLASS_SET(&eddc, Elm_Custom_Palette);
280    eddc.func.str_direct_alloc = NULL;
281    eddc.func.str_direct_free = NULL;
282
283    _config_color_palette_edd = eet_data_descriptor_stream_new(&eddc);
284    if (!_config_color_palette_edd)
285      {
286         printf("EEEK! eet_data_descriptor_stream_new() failed\n");
287         eet_data_descriptor_free(_config_edd);
288         return;
289      }
290
291 #define T_INT    EET_T_INT
292 #define T_DOUBLE EET_T_DOUBLE
293 #define T_STRING EET_T_STRING
294 #define T_UCHAR  EET_T_UCHAR
295
296 #define T        Elm_Font_Overlay
297 #define D        _config_font_overlay_edd
298    ELM_CONFIG_VAL(D, T, text_class, EET_T_STRING);
299    ELM_CONFIG_VAL(D, T, font, EET_T_STRING);
300    ELM_CONFIG_VAL(D, T, size, EET_T_INT);
301 #undef T
302 #undef D
303
304 #define T Elm_Color_RGBA
305 #define D _config_color_edd
306    ELM_CONFIG_VAL(D, T, r, EET_T_UINT);
307    ELM_CONFIG_VAL(D, T, g, EET_T_UINT);
308    ELM_CONFIG_VAL(D, T, b, EET_T_UINT);
309    ELM_CONFIG_VAL(D, T, a, EET_T_UINT);
310 #undef T
311 #undef D
312
313 #define T Elm_Custom_Palette
314 #define D _config_color_palette_edd
315    ELM_CONFIG_VAL(D, T, palette_name, EET_T_STRING);
316    ELM_CONFIG_LIST(D, T, color_list, _config_color_edd);
317 #undef T
318 #undef D
319
320 #define T Elm_Config
321 #define D _config_edd
322    ELM_CONFIG_VAL(D, T, config_version, T_INT);
323    ELM_CONFIG_VAL(D, T, engine, T_STRING);
324    ELM_CONFIG_VAL(D, T, vsync, T_UCHAR);
325    ELM_CONFIG_VAL(D, T, thumbscroll_enable, T_UCHAR);
326    ELM_CONFIG_VAL(D, T, thumbscroll_threshold, T_INT);
327    ELM_CONFIG_VAL(D, T, thumbscroll_momentum_threshold, T_DOUBLE);
328    ELM_CONFIG_VAL(D, T, thumbscroll_friction, T_DOUBLE);
329    ELM_CONFIG_VAL(D, T, thumbscroll_bounce_friction, T_DOUBLE);
330    ELM_CONFIG_VAL(D, T, thumbscroll_border_friction, T_DOUBLE);
331    ELM_CONFIG_VAL(D, T, thumbscroll_sensitivity_friction, T_DOUBLE);
332    ELM_CONFIG_VAL(D, T, page_scroll_friction, T_DOUBLE);
333    ELM_CONFIG_VAL(D, T, bring_in_scroll_friction, T_DOUBLE);
334    ELM_CONFIG_VAL(D, T, zoom_friction, T_DOUBLE);
335    ELM_CONFIG_VAL(D, T, thumbscroll_bounce_enable, T_UCHAR);
336    ELM_CONFIG_VAL(D, T, scroll_smooth_time_interval, T_DOUBLE);
337    ELM_CONFIG_VAL(D, T, scroll_smooth_amount, T_DOUBLE);
338    ELM_CONFIG_VAL(D, T, scroll_smooth_history_weight, T_DOUBLE);
339    ELM_CONFIG_VAL(D, T, scroll_smooth_future_time, T_DOUBLE);
340    ELM_CONFIG_VAL(D, T, scroll_smooth_time_window, T_DOUBLE);
341    ELM_CONFIG_VAL(D, T, scale, T_DOUBLE);
342    ELM_CONFIG_VAL(D, T, bgpixmap, T_INT);
343    ELM_CONFIG_VAL(D, T, compositing, T_INT);
344    /* EET_DATA_DESCRIPTOR_ADD_LIST(D, T, "font_dirs", font_dirs, sub_edd); */
345    ELM_CONFIG_LIST(D, T, font_overlays, _config_font_overlay_edd);
346    ELM_CONFIG_VAL(D, T, font_hinting, T_INT);
347    ELM_CONFIG_VAL(D, T, cache_flush_poll_interval, T_INT);
348    ELM_CONFIG_VAL(D, T, cache_flush_enable, T_UCHAR);
349    ELM_CONFIG_VAL(D, T, image_cache, T_INT);
350    ELM_CONFIG_VAL(D, T, font_cache, T_INT);
351    ELM_CONFIG_VAL(D, T, edje_cache, T_INT);
352    ELM_CONFIG_VAL(D, T, edje_collection_cache, T_INT);
353    ELM_CONFIG_VAL(D, T, finger_size, T_INT);
354    ELM_CONFIG_VAL(D, T, fps, T_DOUBLE);
355    ELM_CONFIG_VAL(D, T, theme, T_STRING);
356    ELM_CONFIG_VAL(D, T, modules, T_STRING);
357    ELM_CONFIG_VAL(D, T, tooltip_delay, T_DOUBLE);
358    ELM_CONFIG_VAL(D, T, cursor_engine_only, T_UCHAR);
359    ELM_CONFIG_VAL(D, T, focus_highlight_enable, T_UCHAR);
360    ELM_CONFIG_VAL(D, T, focus_highlight_animate, T_UCHAR);
361    ELM_CONFIG_VAL(D, T, toolbar_shrink_mode, T_INT);
362    ELM_CONFIG_VAL(D, T, fileselector_expand_enable, T_UCHAR);
363    ELM_CONFIG_VAL(D, T, inwin_dialogs_enable, T_UCHAR);
364    ELM_CONFIG_VAL(D, T, icon_size, T_INT);
365    ELM_CONFIG_VAL(D, T, longpress_timeout, T_DOUBLE);
366    ELM_CONFIG_VAL(D, T, effect_enable, T_UCHAR);
367    ELM_CONFIG_VAL(D, T, desktop_entry, T_UCHAR);
368    ELM_CONFIG_VAL(D, T, password_show_last, T_UCHAR);
369    ELM_CONFIG_VAL(D, T, password_show_last_timeout, T_DOUBLE);
370    ELM_CONFIG_VAL(D, T, glayer_zoom_finger_enable, T_UCHAR);
371    ELM_CONFIG_VAL(D, T, glayer_zoom_finger_factor, T_DOUBLE);
372    ELM_CONFIG_VAL(D, T, glayer_zoom_wheel_factor, T_DOUBLE);
373    ELM_CONFIG_VAL(D, T, glayer_zoom_distance_tolerance, T_DOUBLE);
374    ELM_CONFIG_VAL(D, T, glayer_rotate_finger_enable, T_UCHAR);
375    ELM_CONFIG_VAL(D, T, glayer_rotate_angular_tolerance, T_DOUBLE);
376    ELM_CONFIG_VAL(D, T, glayer_line_min_length, T_DOUBLE);
377    ELM_CONFIG_VAL(D, T, glayer_line_distance_tolerance, T_DOUBLE);
378    ELM_CONFIG_VAL(D, T, glayer_line_angular_tolerance, T_DOUBLE);
379    ELM_CONFIG_VAL(D, T, glayer_flick_time_limit_ms, T_INT);
380    ELM_CONFIG_VAL(D, T, glayer_long_tap_start_timeout, T_DOUBLE);
381    ELM_CONFIG_VAL(D, T, access_mode, T_INT);
382    ELM_CONFIG_VAL(D, T, glayer_continues_enable, T_UCHAR);
383    ELM_CONFIG_VAL(D, T, week_start, T_INT);
384    ELM_CONFIG_VAL(D, T, weekend_start, T_INT);
385    ELM_CONFIG_VAL(D, T, weekend_len, T_INT);
386    ELM_CONFIG_VAL(D, T, year_min, T_INT);
387    ELM_CONFIG_VAL(D, T, year_max, T_INT);
388    ELM_CONFIG_LIST(D, T, color_palette, _config_color_palette_edd);
389 #undef T
390 #undef D
391 #undef T_INT
392 #undef T_DOUBLE
393 #undef T_STRING
394 #undef T_UCHAR
395 }
396
397 static void
398 _desc_shutdown(void)
399 {
400    if (_config_edd)
401      {
402         eet_data_descriptor_free(_config_edd);
403         _config_edd = NULL;
404      }
405
406    if (_config_font_overlay_edd)
407      {
408         eet_data_descriptor_free(_config_font_overlay_edd);
409         _config_font_overlay_edd = NULL;
410      }
411
412    if (_config_color_edd)
413      {
414         eet_data_descriptor_free(_config_color_edd);
415         _config_color_edd = NULL;
416      }
417
418    if (_config_color_palette_edd)
419      {
420         eet_data_descriptor_free(_config_color_palette_edd);
421         _config_color_palette_edd = NULL;
422      }
423 }
424
425 static int
426 _sort_files_cb(const void *f1,
427                const void *f2)
428 {
429    return strcmp(f1, f2);
430 }
431
432 const char *
433 _elm_config_current_profile_get(void)
434 {
435    return _elm_profile;
436 }
437
438 static size_t
439 _elm_data_dir_snprintf(char       *dst,
440                        size_t      size,
441                        const char *fmt,
442                        ...)
443 {
444    size_t data_dir_len, off;
445    va_list ap;
446
447    data_dir_len = eina_strlcpy(dst, _elm_data_dir, size);
448
449    off = data_dir_len + 1;
450    if (off >= size)
451      goto end;
452
453    va_start(ap, fmt);
454    dst[data_dir_len] = '/';
455
456    off = off + vsnprintf(dst + off, size - off, fmt, ap);
457    va_end(ap);
458
459 end:
460    return off;
461 }
462
463 static size_t
464 _elm_user_dir_snprintf(char       *dst,
465                        size_t      size,
466                        const char *fmt,
467                        ...)
468 {
469    const char *home;
470    size_t user_dir_len, off;
471    va_list ap;
472
473 #ifdef _WIN32
474    home = evil_homedir_get();
475 #else
476    home = getenv("HOME");
477 #endif
478    if (!home)
479      home = "/";
480
481    user_dir_len = eina_str_join_len(dst, size, '/', home, strlen(home),
482                                     ELEMENTARY_BASE_DIR, sizeof(ELEMENTARY_BASE_DIR) - 1);
483
484    off = user_dir_len + 1;
485    if (off >= size)
486      goto end;
487
488    va_start(ap, fmt);
489    dst[user_dir_len] = '/';
490
491    off = off + vsnprintf(dst + off, size - off, fmt, ap);
492    va_end(ap);
493
494 end:
495    return off;
496 }
497
498 const char *
499 _elm_config_profile_dir_get(const char *prof,
500                             Eina_Bool   is_user)
501 {
502    char buf[PATH_MAX];
503
504    if (!is_user)
505      goto not_user;
506
507    _elm_user_dir_snprintf(buf, sizeof(buf), "config/%s", prof);
508
509    if (ecore_file_is_dir(buf))
510      return strdup(buf);
511
512    return NULL;
513
514 not_user:
515    snprintf(buf, sizeof(buf), "%s/config/%s", _elm_data_dir, prof);
516
517    if (ecore_file_is_dir(buf))
518      return strdup(buf);
519
520    return NULL;
521 }
522
523 Eina_List *
524 _elm_config_font_overlays_list(void)
525 {
526    return _elm_config->font_overlays;
527 }
528
529 void
530 _elm_config_font_overlay_set(const char    *text_class,
531                              const char    *font,
532                              Evas_Font_Size size)
533 {
534    Elm_Font_Overlay *efd;
535    Eina_List *l;
536
537    EINA_LIST_FOREACH(_elm_config->font_overlays, l, efd)
538      {
539         if (strcmp(efd->text_class, text_class))
540           continue;
541
542         if (efd->font) eina_stringshare_del(efd->font);
543         efd->font = eina_stringshare_add(font);
544         efd->size = size;
545         _elm_config->font_overlays =
546           eina_list_promote_list(_elm_config->font_overlays, l);
547         return;
548      }
549
550    /* the text class doesn't exist */
551    efd = calloc(1, sizeof(Elm_Font_Overlay));
552    efd->text_class = eina_stringshare_add(text_class);
553    efd->font = eina_stringshare_add(font);
554    efd->size = size;
555
556    _elm_config->font_overlays = eina_list_prepend(_elm_config->font_overlays,
557                                                   efd);
558 }
559
560 void
561 _elm_config_font_overlay_remove(const char *text_class)
562 {
563    Elm_Font_Overlay *efd;
564    Eina_List *l;
565
566    EINA_LIST_FOREACH(_elm_config->font_overlays, l, efd)
567      {
568         if (strcmp(efd->text_class, text_class))
569           continue;
570
571         _elm_config->font_overlays =
572           eina_list_remove_list(_elm_config->font_overlays, l);
573         if (efd->text_class) eina_stringshare_del(efd->text_class);
574         if (efd->font) eina_stringshare_del(efd->font);
575         free(efd);
576
577         return;
578      }
579 }
580
581 void
582 _elm_config_font_overlay_apply(void)
583 {
584    Elm_Font_Overlay *efd;
585    Eina_List *l;
586    int i;
587
588    for (i = 0; _elm_text_classes[i].desc; i++)
589      edje_text_class_del(_elm_text_classes[i].name);
590
591    EINA_LIST_FOREACH(_elm_config->font_overlays, l, efd)
592      edje_text_class_set(efd->text_class, efd->font, efd->size);
593 }
594
595 Eina_List *
596 _elm_config_text_classes_get(void)
597 {
598    Eina_List *ret = NULL;
599    int i;
600
601    for (i = 0; _elm_text_classes[i].desc; i++)
602      {
603         Elm_Text_Class *tc;
604         tc = malloc(sizeof(*tc));
605         if (!tc) continue;
606
607         *tc = _elm_text_classes[i];
608
609         ret = eina_list_append(ret, tc);
610      }
611
612    return ret;
613 }
614
615 void
616 _elm_config_text_classes_free(Eina_List *l)
617 {
618    Elm_Text_Class *tc;
619
620    EINA_LIST_FREE(l, tc)
621      free(tc);
622 }
623
624 Eina_List *
625 _elm_config_color_list_get(const char *palette_name)
626 {
627     Eina_List *plist;
628     Elm_Custom_Palette *cpalette;
629     EINA_LIST_FOREACH(_elm_config->color_palette, plist, cpalette)
630       {
631          if (strcmp(cpalette->palette_name, palette_name))
632            continue;
633          return cpalette->color_list;
634       }
635     return NULL;
636 }
637
638 void
639 _elm_config_color_set(const char *palette_name,
640                       int r,
641                       int g,
642                       int b,
643                       int a)
644 {
645    Eina_List *plist;
646    Elm_Custom_Palette *cpalette;
647    Elm_Color_RGBA *color;
648    EINA_LIST_FOREACH(_elm_config->color_palette, plist, cpalette)
649      {
650         if (strcmp(cpalette->palette_name, palette_name))
651           continue;
652
653         color = calloc(1, sizeof(Elm_Color_RGBA));
654         color->r = r;
655         color->g = g;
656         color->b = b;
657         color->a = a;
658         cpalette->color_list = eina_list_prepend(cpalette->color_list,
659                                                        color);
660      }
661 }
662
663 void
664 _elm_config_colors_free(const char *palette_name)
665 {
666    Eina_List *plist;
667    Elm_Custom_Palette *cpalette;
668    Elm_Color_RGBA *color;
669    EINA_LIST_FOREACH(_elm_config->color_palette, plist, cpalette)
670      {
671         if (strcmp(cpalette->palette_name, palette_name))
672           continue;
673
674         EINA_LIST_FREE(cpalette->color_list, color)
675           {
676              free(color);
677           }
678      }
679 }
680
681 Eina_List *
682 _elm_config_profiles_list(void)
683 {
684    Eina_File_Direct_Info *info;
685    Eina_List *flist = NULL;
686    Eina_Iterator *file_it;
687    char buf[PATH_MAX];
688    const char *dir;
689    size_t len;
690
691    len = _elm_user_dir_snprintf(buf, sizeof(buf), "config");
692
693    file_it = eina_file_stat_ls(buf);
694    if (!file_it)
695      goto sys;
696
697    buf[len] = '/';
698    len++;
699
700    len = sizeof(buf) - len;
701
702    EINA_ITERATOR_FOREACH(file_it, info)
703      {
704         if (info->name_length >= len)
705           continue;
706
707         if (info->type == EINA_FILE_DIR)
708           {
709              flist =
710                eina_list_sorted_insert(flist, _sort_files_cb,
711                                        eina_stringshare_add(info->path +
712                                                             info->name_start));
713           }
714      }
715
716    eina_iterator_free(file_it);
717
718 sys:
719    len = eina_str_join_len(buf, sizeof(buf), '/', _elm_data_dir,
720                            strlen(_elm_data_dir), "config",
721                            sizeof("config") - 1);
722
723    file_it = eina_file_direct_ls(buf);
724    if (!file_it)
725      goto list_free;
726
727    buf[len] = '/';
728    len++;
729
730    len = sizeof(buf) - len;
731    EINA_ITERATOR_FOREACH(file_it, info)
732      {
733         if (info->name_length >= len)
734           continue;
735
736         switch (info->type)
737           {
738            case EINA_FILE_DIR:
739            {
740               const Eina_List *l;
741               const char *tmp;
742
743               EINA_LIST_FOREACH(flist, l, tmp)
744                 if (!strcmp(info->path + info->name_start, tmp))
745                   break;
746
747               if (!l)
748                 flist =
749                   eina_list_sorted_insert(flist, _sort_files_cb,
750                                           eina_stringshare_add(info->path +
751                                                                info->name_start));
752            }
753            break;
754
755            default:
756              continue;
757           }
758      }
759    eina_iterator_free(file_it);
760    return flist;
761
762 list_free:
763    EINA_LIST_FREE(flist, dir)
764      eina_stringshare_del(dir);
765
766    return NULL;
767 }
768
769 static void
770 _profile_fetch_from_conf(void)
771 {
772    char buf[PATH_MAX], *p, *s;
773    Eet_File *ef = NULL;
774    int len = 0;
775
776    _elm_profile = strdup("default");
777
778    // if env var - use profile without question
779    s = getenv("ELM_PROFILE");
780    if (s)
781      {
782         free(_elm_profile);
783         _elm_profile = strdup(s);
784         return;
785      }
786
787    // user profile
788    _elm_user_dir_snprintf(buf, sizeof(buf), "config/profile.cfg");
789    ef = eet_open(buf, EET_FILE_MODE_READ);
790    if (ef)
791      {
792         p = eet_read(ef, "config", &len);
793         if (p)
794           {
795              free(_elm_profile);
796              _elm_profile = malloc(len + 1);
797              memcpy(_elm_profile, p, len);
798              _elm_profile[len] = 0;
799              free(p);
800           }
801         eet_close(ef);
802         if (!p) ef = NULL;
803      }
804    if (ef) return;
805
806    // system profile
807    _elm_data_dir_snprintf(buf, sizeof(buf), "config/profile.cfg");
808    ef = eet_open(buf, EET_FILE_MODE_READ);
809    if (ef)
810      {
811         p = eet_read(ef, "config", &len);
812         if (p)
813           {
814              free(_elm_profile);
815              _elm_profile = malloc(len + 1);
816              memcpy(_elm_profile, p, len);
817              _elm_profile[len] = 0;
818              free(p);
819           }
820         eet_close(ef);
821      }
822 }
823
824 static void
825 _config_free(void)
826 {
827    Elm_Font_Overlay *fo;
828    const char *fontdir;
829    Elm_Custom_Palette *palette;
830    Elm_Color_RGBA *color;
831
832    if (!_elm_config) return;
833    EINA_LIST_FREE(_elm_config->font_dirs, fontdir)
834      {
835         eina_stringshare_del(fontdir);
836      }
837    if (_elm_config->engine) eina_stringshare_del(_elm_config->engine);
838    EINA_LIST_FREE(_elm_config->font_overlays, fo)
839      {
840         if (fo->text_class) eina_stringshare_del(fo->text_class);
841         if (fo->font) eina_stringshare_del(fo->font);
842         free(fo);
843      }
844    EINA_LIST_FREE(_elm_config->color_palette, palette)
845      {
846         if (palette->palette_name) eina_stringshare_del(palette->palette_name);
847         EINA_LIST_FREE(palette->color_list, color) free(color);
848         free(palette);
849      }
850    if (_elm_config->theme) eina_stringshare_del(_elm_config->theme);
851    if (_elm_config->modules) eina_stringshare_del(_elm_config->modules);
852    free(_elm_config);
853    _elm_config = NULL;
854 }
855
856 static void
857 _config_apply(void)
858 {
859    _elm_theme_parse(NULL, _elm_config->theme);
860    ecore_animator_frametime_set(1.0 / _elm_config->fps);
861 }
862
863 static void
864 _config_sub_apply(void)
865 {
866    edje_frametime_set(1.0 / _elm_config->fps);
867    edje_scale_set(_elm_config->scale);
868    edje_password_show_last_set(_elm_config->password_show_last);
869    edje_password_show_last_timeout_set(_elm_config->password_show_last_timeout);
870    if (_elm_config->modules) _elm_module_parse(_elm_config->modules);
871 }
872
873 static Eina_Bool
874 _elm_cache_flush_cb(void *data __UNUSED__)
875 {
876    elm_cache_all_flush();
877    return ECORE_CALLBACK_RENEW;
878 }
879
880 /* kind of abusing this call right now -- shared between all of those
881  * properties -- but they are not meant to be called that periodically
882  * anyway */
883 void
884 _elm_recache(void)
885 {
886    Eina_List *l;
887    Evas_Object *win;
888
889    elm_cache_all_flush();
890
891    EINA_LIST_FOREACH(_elm_win_list, l, win)
892      {
893         Evas *e = evas_object_evas_get(win);
894         evas_image_cache_set(e, _elm_config->image_cache * 1024);
895         evas_font_cache_set(e, _elm_config->font_cache * 1024);
896      }
897    edje_file_cache_set(_elm_config->edje_cache);
898    edje_collection_cache_set(_elm_config->edje_collection_cache);
899
900    if (_elm_cache_flush_poller)
901      {
902         ecore_poller_del(_elm_cache_flush_poller);
903         _elm_cache_flush_poller = NULL;
904      }
905    if (_elm_config->cache_flush_enable)
906      {
907         if (_elm_config->cache_flush_poll_interval > 0)
908           {
909              _elm_cache_flush_poller =
910                 ecore_poller_add(ECORE_POLLER_CORE,
911                                  _elm_config->cache_flush_poll_interval,
912                                  _elm_cache_flush_cb, NULL);
913           }
914      }
915 }
916
917 static Elm_Config *
918 _config_user_load(void)
919 {
920    Elm_Config *cfg = NULL;
921    Eet_File *ef;
922    char buf[PATH_MAX];
923
924    _elm_user_dir_snprintf(buf, sizeof(buf), "config/%s/base.cfg",
925                           _elm_profile);
926
927    ef = eet_open(buf, EET_FILE_MODE_READ);
928    if (ef)
929      {
930         cfg = eet_data_read(ef, _config_edd, "config");
931         eet_close(ef);
932      }
933    return cfg;
934 }
935
936 static Elm_Config *
937 _config_system_load(void)
938 {
939    Elm_Config *cfg = NULL;
940    Eet_File *ef;
941    char buf[PATH_MAX];
942
943    _elm_data_dir_snprintf(buf, sizeof(buf), "config/%s/base.cfg",
944                           _elm_profile);
945
946    ef = eet_open(buf, EET_FILE_MODE_READ);
947    if (ef)
948      {
949         cfg = eet_data_read(ef, _config_edd, "config");
950         eet_close(ef);
951      }
952    return cfg;
953 }
954
955 static void
956 _config_load(void)
957 {
958    _elm_config = _config_user_load();
959    if (_elm_config)
960      {
961         if (_elm_config->config_version < ELM_CONFIG_VERSION)
962           _config_update();
963         return;
964      }
965
966    /* no user config, fallback for system. No need to check version for
967     * this one, if it's not the right one, someone screwed up at the time
968     * of installing it */
969    _elm_config = _config_system_load();
970    if (_elm_config) return;
971    /* FIXME: config load could have failed because of a non-existent
972     * profile. Fallback to default before moving on */
973
974    // config load fail - defaults
975    // why are these here? well if they are, it means you can make a gui
976    // config recovery app i guess...
977    _elm_config = ELM_NEW(Elm_Config);
978    _elm_config->config_version = ELM_CONFIG_VERSION;
979    _elm_config->engine = eina_stringshare_add("software_x11");
980    _elm_config->vsync = 0;
981    _elm_config->thumbscroll_enable = EINA_TRUE;
982    _elm_config->thumbscroll_threshold = 24;
983    _elm_config->thumbscroll_momentum_threshold = 100.0;
984    _elm_config->thumbscroll_friction = 1.0;
985    _elm_config->thumbscroll_bounce_friction = 0.5;
986    _elm_config->thumbscroll_bounce_enable = EINA_TRUE;
987    _elm_config->page_scroll_friction = 0.5;
988    _elm_config->bring_in_scroll_friction = 0.5;
989    _elm_config->zoom_friction = 0.5;
990    _elm_config->thumbscroll_border_friction = 0.5;
991    _elm_config->thumbscroll_sensitivity_friction = 0.25; // magic number! just trial and error shows this makes it behave "nicer" and not run off at high speed all the time
992    _elm_config->scroll_smooth_time_interval = 0.008;
993    _elm_config->scroll_smooth_amount = 1.0;
994    _elm_config->scroll_smooth_history_weight = 0.3;
995    _elm_config->scroll_smooth_future_time = 0.0;
996    _elm_config->scroll_smooth_time_window = 0.2;
997    _elm_config->scale = 1.0;
998    _elm_config->bgpixmap = 0;
999    _elm_config->compositing = 1;
1000    _elm_config->font_hinting = 2;
1001    _elm_config->cache_flush_poll_interval = 512;
1002    _elm_config->cache_flush_enable = EINA_TRUE;
1003    _elm_config->font_dirs = NULL;
1004    _elm_config->image_cache = 4096;
1005    _elm_config->font_cache = 512;
1006    _elm_config->edje_cache = 32;
1007    _elm_config->edje_collection_cache = 64;
1008    _elm_config->finger_size = 40;
1009    _elm_config->fps = 60.0;
1010    _elm_config->theme = eina_stringshare_add("default");
1011    _elm_config->modules = NULL;
1012    _elm_config->tooltip_delay = 1.0;
1013    _elm_config->cursor_engine_only = EINA_TRUE;
1014    _elm_config->focus_highlight_enable = EINA_FALSE;
1015    _elm_config->focus_highlight_animate = EINA_TRUE;
1016    _elm_config->toolbar_shrink_mode = 2;
1017    _elm_config->fileselector_expand_enable = EINA_FALSE;
1018    _elm_config->inwin_dialogs_enable = EINA_FALSE;
1019    _elm_config->icon_size = 32;
1020    _elm_config->longpress_timeout = 1.0;
1021    _elm_config->effect_enable = EINA_TRUE;
1022    _elm_config->desktop_entry = EINA_FALSE;
1023    _elm_config->is_mirrored = EINA_FALSE; /* Read sys value in env_get() */
1024    _elm_config->password_show_last = EINA_FALSE;
1025    _elm_config->password_show_last_timeout = 2.0;
1026    _elm_config->glayer_zoom_finger_enable = EINA_TRUE;
1027    _elm_config->glayer_zoom_finger_factor = 1.0;
1028    _elm_config->glayer_zoom_wheel_factor = 0.05;
1029    _elm_config->glayer_zoom_distance_tolerance = 1.0; /* 1 times elm_finger_size_get() */
1030    _elm_config->glayer_rotate_finger_enable = EINA_TRUE;
1031    _elm_config->glayer_rotate_angular_tolerance = 2.0; /* 2 DEG */
1032    _elm_config->glayer_line_min_length = 1.0;         /* 1 times elm_finger_size_get() */
1033    _elm_config->glayer_line_distance_tolerance = 3.0; /* 3 times elm_finger_size_get() */
1034    _elm_config->glayer_line_angular_tolerance = 20.0; /* 20 DEG */
1035    _elm_config->glayer_flick_time_limit_ms = 120;              /* ms to finish flick */
1036    _elm_config->glayer_long_tap_start_timeout = 1.2;   /* 1.2 second to start long-tap */
1037    _elm_config->glayer_continues_enable = EINA_TRUE;      /* Continue gestures default */
1038    _elm_config->week_start = 1; /* monday */
1039    _elm_config->weekend_start = 6; /* saturday */
1040    _elm_config->weekend_len = 2;
1041    _elm_config->year_min = 2;
1042    _elm_config->year_max = 137;
1043    _elm_config->color_palette = NULL;
1044 }
1045
1046 static const char *
1047 _elm_config_eet_close_error_get(Eet_File *ef,
1048                                 char     *file)
1049 {
1050    Eet_Error err;
1051    const char *erstr = NULL;
1052
1053    err = eet_close(ef);
1054    switch (err)
1055      {
1056       case EET_ERROR_WRITE_ERROR:
1057         erstr = "An error occurred while saving Elementary's "
1058                 "settings to disk. The error could not be "
1059                 "deterimined. The file where the error occurred was: "
1060                 "%s. This file has been deleted to avoid corrupt data.";
1061         break;
1062
1063       case EET_ERROR_WRITE_ERROR_FILE_TOO_BIG:
1064         erstr = "Elementary's settings files are too big "
1065                 "for the file system they are being saved to. "
1066                 "This error is very strange as the files should "
1067                 "be extremely small. Please check the settings "
1068                 "for your home directory. "
1069                 "The file where the error occurred was: %s ."
1070                 "This file has been deleted to avoid corrupt data.";
1071         break;
1072
1073       case EET_ERROR_WRITE_ERROR_IO_ERROR:
1074         erstr = "An output error occurred when writing the settings "
1075                 "files for Elementary. Your disk is having troubles "
1076                 "and possibly needs replacement. "
1077                 "The file where the error occurred was: %s ."
1078                 "This file has been deleted to avoid corrupt data.";
1079         break;
1080
1081       case EET_ERROR_WRITE_ERROR_OUT_OF_SPACE:
1082         erstr = "Elementary cannot write its settings file "
1083                 "because it ran out of space to write the file. "
1084                 "You have either run out of disk space or have "
1085                 "gone over your quota limit. "
1086                 "The file where the error occurred was: %s ."
1087                 "This file has been deleted to avoid corrupt data.";
1088         break;
1089
1090       case EET_ERROR_WRITE_ERROR_FILE_CLOSED:
1091         erstr = "Elementary unexpectedly had the settings file "
1092                 "it was writing closed on it. This is very unusual. "
1093                 "The file where the error occurred was: %s "
1094                 "This file has been deleted to avoid corrupt data.";
1095         break;
1096
1097       default:
1098         break;
1099      }
1100    if (erstr)
1101      {
1102         /* delete any partially-written file */
1103          ecore_file_unlink(file);
1104          return strdup(erstr);
1105      }
1106
1107    return NULL;
1108 }
1109
1110 static Eina_Bool
1111 _elm_config_profile_save(void)
1112 {
1113    char buf[4096], buf2[4096];
1114    int ok = 0, ret;
1115    const char *err;
1116    Eet_File *ef;
1117    size_t len;
1118
1119    len = _elm_user_dir_snprintf(buf, sizeof(buf), "config/profile.cfg");
1120    if (len + 1 >= sizeof(buf))
1121      return EINA_FALSE;
1122
1123    len = _elm_user_dir_snprintf(buf2, sizeof(buf2), "config/profile.cfg.tmp");
1124    if (len + 1 >= sizeof(buf2))
1125      return EINA_FALSE;
1126
1127    ef = eet_open(buf2, EET_FILE_MODE_WRITE);
1128    if (!ef)
1129      return EINA_FALSE;
1130
1131    ok = eet_write(ef, "config", _elm_profile, strlen(_elm_profile), 0);
1132    if (!ok)
1133      goto err;
1134
1135    err = _elm_config_eet_close_error_get(ef, buf2);
1136    if (err)
1137      {
1138         ERR("%s", err);
1139         free((void *)err);
1140         goto err;
1141      }
1142
1143    ret = ecore_file_mv(buf2, buf);
1144    if (!ret)
1145      {
1146         ERR("Error saving Elementary's configuration file");
1147         goto err;
1148      }
1149
1150    ecore_file_unlink(buf2);
1151    return EINA_TRUE;
1152
1153 err:
1154    ecore_file_unlink(buf2);
1155    return EINA_FALSE;
1156 }
1157
1158 Eina_Bool
1159 _elm_config_save(void)
1160 {
1161    char buf[4096], buf2[4096];
1162    int ok = 0, ret;
1163    const char *err;
1164    Eet_File *ef;
1165    size_t len;
1166
1167    len = _elm_user_dir_snprintf(buf, sizeof(buf), "config/%s", _elm_profile);
1168    if (len + 1 >= sizeof(buf))
1169      return EINA_FALSE;
1170
1171    ok = ecore_file_mkpath(buf);
1172    if (!ok)
1173      {
1174         ERR("Problem accessing Elementary's user configuration directory: %s",
1175             buf);
1176         return EINA_FALSE;
1177      }
1178
1179    if (!_elm_config_profile_save())
1180      return EINA_FALSE;
1181
1182    buf[len] = '/';
1183    len++;
1184
1185    if (len + sizeof("base.cfg") >= sizeof(buf) - len)
1186      return EINA_FALSE;
1187
1188    memcpy(buf + len, "base.cfg", sizeof("base.cfg"));
1189    len += sizeof("base.cfg") - 1;
1190
1191    if (len + sizeof(".tmp") >= sizeof(buf))
1192      return EINA_FALSE;
1193
1194    memcpy(buf2, buf, len);
1195    memcpy(buf2 + len, ".tmp", sizeof(".tmp"));
1196
1197    ef = eet_open(buf2, EET_FILE_MODE_WRITE);
1198    if (!ef)
1199      return EINA_FALSE;
1200
1201    ok = eet_data_write(ef, _config_edd, "config", _elm_config, 1);
1202    if (!ok)
1203      goto err;
1204
1205    err = _elm_config_eet_close_error_get(ef, buf2);
1206    if (err)
1207      {
1208         ERR("%s", err);
1209         free((void *)err);
1210         goto err;
1211      }
1212
1213    ret = ecore_file_mv(buf2, buf);
1214    if (!ret)
1215      {
1216         ERR("Error saving Elementary's configuration file");
1217         goto err;
1218      }
1219
1220    ecore_file_unlink(buf2);
1221    return EINA_TRUE;
1222
1223 err:
1224    ecore_file_unlink(buf2);
1225    return EINA_FALSE;
1226 }
1227
1228 static void
1229 _config_update(void)
1230 {
1231    Elm_Config *tcfg;
1232
1233    tcfg = _config_system_load();
1234    if (!tcfg)
1235      {
1236         /* weird profile or something? We should probably fill
1237          * with hardcoded defaults, or get from default previx */
1238           return;
1239      }
1240 #define IFCFG(v)   if ((_elm_config->config_version & 0xffff) < (v)) {
1241 #define IFCFGELSE } else {
1242 #define IFCFGEND  }
1243 #define COPYVAL(x) do {_elm_config->x = tcfg->x; } while (0)
1244 #define COPYPTR(x) do {_elm_config->x = tcfg->x; tcfg->x = NULL; } while (0)
1245 #define COPYSTR(x) COPYPTR(x)
1246
1247      /* we also need to update for property changes in the root window
1248       * if needed, but that will be dependent on new properties added
1249       * with each version */
1250
1251      IFCFG(0x0003);
1252      COPYVAL(longpress_timeout);
1253      IFCFGEND;
1254
1255 #undef COPYSTR
1256 #undef COPYPTR
1257 #undef COPYVAL
1258 #undef IFCFGEND
1259 #undef IFCFGELSE
1260 #undef IFCFG
1261
1262      /* after updating user config, we must save */
1263 }
1264
1265 static void
1266 _env_get(void)
1267 {
1268    char *s;
1269    double friction;
1270
1271    s = getenv("ELM_ENGINE");
1272    if (s)
1273      {
1274         if ((!strcasecmp(s, "x11")) ||
1275             (!strcasecmp(s, "x")) ||
1276             (!strcasecmp(s, "software-x11")) ||
1277             (!strcasecmp(s, "software_x11")))
1278           eina_stringshare_replace(&_elm_config->engine, ELM_SOFTWARE_X11);
1279         else if ((!strcasecmp(s, "opengl")) ||
1280                  (!strcasecmp(s, "gl")) ||
1281                  (!strcasecmp(s, "opengl-x11")) ||
1282                  (!strcasecmp(s, "opengl_x11")))
1283           eina_stringshare_replace(&_elm_config->engine, ELM_OPENGL_X11);
1284         else if ((!strcasecmp(s, "x11-8")) ||
1285                  (!strcasecmp(s, "x8")) ||
1286                  (!strcasecmp(s, "software-8-x11")) ||
1287                  (!strcasecmp(s, "software_8_x11")))
1288           eina_stringshare_replace(&_elm_config->engine, ELM_SOFTWARE_8_X11);
1289         else if ((!strcasecmp(s, "x11-16")) ||
1290                  (!strcasecmp(s, "x16")) ||
1291                  (!strcasecmp(s, "software-16-x11")) ||
1292                  (!strcasecmp(s, "software_16_x11")))
1293           eina_stringshare_replace(&_elm_config->engine, ELM_SOFTWARE_16_X11);
1294 /*
1295         else if ((!strcasecmp(s, "xrender")) ||
1296                  (!strcasecmp(s, "xr")) ||
1297                  (!strcasecmp(s, "xrender-x11")) ||
1298                  (!strcasecmp(s, "xrender_x11")))
1299           eina_stringshare_replace(&_elm_config->engine, ELM_XRENDER_X11);
1300  */
1301         else if ((!strcasecmp(s, "fb")) ||
1302                  (!strcasecmp(s, "software-fb")) ||
1303                  (!strcasecmp(s, "software_fb")))
1304           eina_stringshare_replace(&_elm_config->engine, ELM_SOFTWARE_FB);
1305         else if ((!strcasecmp(s, "directfb")) ||
1306                  (!strcasecmp(s, "dfb")))
1307           eina_stringshare_replace(&_elm_config->engine, ELM_SOFTWARE_DIRECTFB);
1308         else if ((!strcasecmp(s, "psl1ght")))
1309           eina_stringshare_replace(&_elm_config->engine, ELM_SOFTWARE_PSL1GHT);
1310         else if ((!strcasecmp(s, "sdl")) ||
1311                  (!strcasecmp(s, "software-sdl")) ||
1312                  (!strcasecmp(s, "software_sdl")))
1313           eina_stringshare_replace(&_elm_config->engine, ELM_SOFTWARE_SDL);
1314         else if ((!strcasecmp(s, "sdl-16")) ||
1315                  (!strcasecmp(s, "software-16-sdl")) ||
1316                  (!strcasecmp(s, "software_16_sdl")))
1317           eina_stringshare_replace(&_elm_config->engine, ELM_SOFTWARE_16_SDL);
1318         else if ((!strcasecmp(s, "opengl-sdl")) ||
1319                  (!strcasecmp(s, "opengl_sdl")) ||
1320                  (!strcasecmp(s, "gl-sdl")) ||
1321                  (!strcasecmp(s, "gl_sdl")))
1322           eina_stringshare_replace(&_elm_config->engine, ELM_OPENGL_SDL);
1323         else if ((!strcasecmp(s, "opengl-cocoa")) ||
1324                  (!strcasecmp(s, "opengl_cocoa")) ||
1325                  (!strcasecmp(s, "gl-cocoa")) ||
1326                  (!strcasecmp(s, "gl_cocoa")))
1327           eina_stringshare_replace(&_elm_config->engine, ELM_OPENGL_COCOA);
1328         else if ((!strcasecmp(s, "gdi")) ||
1329                  (!strcasecmp(s, "software-gdi")) ||
1330                  (!strcasecmp(s, "software_gdi")))
1331           eina_stringshare_replace(&_elm_config->engine, ELM_SOFTWARE_WIN32);
1332         else if ((!strcasecmp(s, "wince-gdi")) ||
1333                  (!strcasecmp(s, "software-16-wince-gdi")) ||
1334                  (!strcasecmp(s, "software_16_wince_gdi")))
1335           eina_stringshare_replace(&_elm_config->engine, ELM_SOFTWARE_16_WINCE);
1336         else if (!strcasecmp(s, "buffer"))
1337           eina_stringshare_replace(&_elm_config->engine, ELM_BUFFER);
1338         else if ((!strncmp(s, "shot:", 5)))
1339           eina_stringshare_replace(&_elm_config->engine, s);
1340         else if ((!strcasecmp(s, "ews")))
1341           eina_stringshare_replace(&_elm_config->engine, ELM_EWS);
1342         else if ((!strcasecmp(s, "wayland_shm")))
1343           eina_stringshare_replace(&_elm_config->engine, ELM_WAYLAND_SHM);
1344         else if ((!strcasecmp(s, "wayland_egl")))
1345           eina_stringshare_replace(&_elm_config->engine, ELM_WAYLAND_EGL);
1346         else
1347           ERR("Unknown engine '%s'.", s);
1348      }
1349
1350    s = getenv("ELM_VSYNC");
1351    if (s) _elm_config->vsync = !!atoi(s);
1352
1353    s = getenv("ELM_THUMBSCROLL_ENABLE");
1354    if (s) _elm_config->thumbscroll_enable = !!atoi(s);
1355    s = getenv("ELM_THUMBSCROLL_THRESHOLD");
1356    if (s) _elm_config->thumbscroll_threshold = atoi(s);
1357    // FIXME: floatformat locale issues here 1.0 vs 1,0 - should just be 1.0
1358    s = getenv("ELM_THUMBSCROLL_MOMENTUM_THRESHOLD");
1359    if (s) _elm_config->thumbscroll_momentum_threshold = _elm_atof(s);
1360    s = getenv("ELM_THUMBSCROLL_FRICTION");
1361    if (s) _elm_config->thumbscroll_friction = _elm_atof(s);
1362    s = getenv("ELM_THUMBSCROLL_BOUNCE_ENABLE");
1363    if (s) _elm_config->thumbscroll_bounce_enable = !!atoi(s);
1364    s = getenv("ELM_THUMBSCROLL_BOUNCE_FRICTION");
1365    if (s) _elm_config->thumbscroll_bounce_friction = _elm_atof(s);
1366    s = getenv("ELM_PAGE_SCROLL_FRICTION");
1367    if (s) _elm_config->page_scroll_friction = _elm_atof(s);
1368    s = getenv("ELM_BRING_IN_SCROLL_FRICTION");
1369    if (s) _elm_config->bring_in_scroll_friction = _elm_atof(s);
1370    s = getenv("ELM_ZOOM_FRICTION");
1371    if (s) _elm_config->zoom_friction = _elm_atof(s);
1372    s = getenv("ELM_THUMBSCROLL_BORDER_FRICTION");
1373    if (s)
1374      {
1375         friction = _elm_atof(s);
1376         if (friction < 0.0)
1377           friction = 0.0;
1378
1379         if (friction > 1.0)
1380           friction = 1.0;
1381
1382         _elm_config->thumbscroll_border_friction = friction;
1383      }
1384    s = getenv("ELM_THUMBSCROLL_SENSITIVITY_FRICTION");
1385    if (s)
1386      {
1387         friction = _elm_atof(s);
1388         if (friction < 0.1)
1389           friction = 0.1;
1390
1391         if (friction > 1.0)
1392           friction = 1.0;
1393
1394         _elm_config->thumbscroll_sensitivity_friction = friction;
1395      }
1396    s = getenv("ELM_SCROLL_SMOOTH_TIME_INTERVAL");
1397    if (s) _elm_config->scroll_smooth_time_interval = atof(s);
1398    s = getenv("ELM_SCROLL_SMOOTH_AMOUNT");
1399    if (s) _elm_config->scroll_smooth_amount = _elm_atof(s);
1400    s = getenv("ELM_SCROLL_SMOOTH_HISTORY_WEIGHT");
1401    if (s) _elm_config->scroll_smooth_history_weight = _elm_atof(s);
1402    s = getenv("ELM_SCROLL_SMOOTH_FUTURE_TIME");
1403    if (s) _elm_config->scroll_smooth_future_time = _elm_atof(s);
1404    s = getenv("ELM_SCROLL_SMOOTH_TIME_WINDOW");
1405    if (s) _elm_config->scroll_smooth_time_window = _elm_atof(s);
1406    s = getenv("ELM_THEME");
1407    if (s) eina_stringshare_replace(&_elm_config->theme, s);
1408
1409    s = getenv("ELM_FONT_HINTING");
1410    if (s)
1411      {
1412         if      (!strcasecmp(s, "none")) _elm_config->font_hinting = 0;
1413         else if (!strcasecmp(s, "auto"))
1414           _elm_config->font_hinting = 1;
1415         else if (!strcasecmp(s, "bytecode"))
1416           _elm_config->font_hinting = 2;
1417      }
1418
1419    s = getenv("ELM_FONT_PATH");
1420    if (s)
1421      {
1422         const char *p, *pp;
1423         char *buf2;
1424
1425         EINA_LIST_FREE(_elm_config->font_dirs, p)
1426           {
1427              eina_stringshare_del(p);
1428           }
1429
1430         buf2 = alloca(strlen(s) + 1);
1431         p = s;
1432         pp = p;
1433         for (;; )
1434           {
1435              if ((*p == ':') || (*p == 0))
1436                {
1437                   int len;
1438
1439                   len = p - pp;
1440                   strncpy(buf2, pp, len);
1441                   buf2[len] = 0;
1442                   _elm_config->font_dirs =
1443                     eina_list_append(_elm_config->font_dirs,
1444                                      eina_stringshare_add(buf2));
1445                   if (*p == 0) break;
1446                   p++;
1447                   pp = p;
1448                }
1449              else
1450                {
1451                   if (*p == 0) break;
1452                   p++;
1453                }
1454           }
1455      }
1456
1457    s = getenv("ELM_IMAGE_CACHE");
1458    if (s) _elm_config->image_cache = atoi(s);
1459
1460    s = getenv("ELM_FONT_CACHE");
1461    if (s) _elm_config->font_cache = atoi(s);
1462
1463    s = getenv("ELM_SCALE");
1464    if (s) _elm_config->scale = _elm_atof(s);
1465
1466    s = getenv("ELM_FINGER_SIZE");
1467    if (s) _elm_config->finger_size = atoi(s);
1468
1469    s = getenv("ELM_PASSWORD_SHOW_LAST");
1470    if (s) _elm_config->password_show_last = !!atoi(s);
1471
1472    s = getenv("ELM_PASSWORD_SHOW_LAST_TIMEOUT");
1473    if (s)
1474      {
1475         double pw_show_last_timeout = _elm_atof(s);
1476         if (pw_show_last_timeout >= 0.0)
1477           _elm_config->password_show_last_timeout = pw_show_last_timeout;
1478      }
1479
1480    s = getenv("ELM_FPS");
1481    if (s) _elm_config->fps = _elm_atof(s);
1482    if (_elm_config->fps < 1.0) _elm_config->fps = 1.0;
1483
1484    s = getenv("ELM_MODULES");
1485    if (s) eina_stringshare_replace(&_elm_config->modules, s);
1486
1487    /* Get RTL orientation from system */
1488    setlocale(LC_ALL, "");
1489    bindtextdomain(PACKAGE, LOCALE_DIR);
1490    _elm_config->is_mirrored = !strcmp(E_("default:LTR"), "default:RTL");
1491
1492    s = getenv("ELM_TOOLTIP_DELAY");
1493    if (s)
1494      {
1495         double delay = _elm_atof(s);
1496         if (delay >= 0.0)
1497           _elm_config->tooltip_delay = delay;
1498      }
1499
1500    s = getenv("ELM_CURSOR_ENGINE_ONLY");
1501    if (s) _elm_config->cursor_engine_only = !!atoi(s);
1502
1503    s = getenv("ELM_FOCUS_HIGHLIGHT_ENABLE");
1504    if (s) _elm_config->focus_highlight_enable = !!atoi(s);
1505
1506    s = getenv("ELM_FOCUS_HIGHLIGHT_ANIMATE");
1507    if (s) _elm_config->focus_highlight_animate = !!atoi(s);
1508
1509    s = getenv("ELM_TOOLBAR_SHRINK_MODE");
1510    if (s) _elm_config->toolbar_shrink_mode = atoi(s);
1511
1512    s = getenv("ELM_FILESELECTOR_EXPAND_ENABLE");
1513    if (s) _elm_config->fileselector_expand_enable = !!atoi(s);
1514
1515    s = getenv("ELM_INWIN_DIALOGS_ENABLE");
1516    if (s) _elm_config->inwin_dialogs_enable = !!atoi(s);
1517
1518    s = getenv("ELM_ICON_SIZE");
1519    if (s) _elm_config->icon_size = atoi(s);
1520
1521    s = getenv("ELM_LONGPRESS_TIMEOUT");
1522    if (s) _elm_config->longpress_timeout = _elm_atof(s);
1523    if (_elm_config->longpress_timeout < 0.0)
1524      _elm_config->longpress_timeout = 0.0;
1525
1526    s = getenv("ELM_EFFECT_ENABLE");
1527    if (s) _elm_config->effect_enable = !!atoi(s);
1528
1529    s = getenv("ELM_DESKTOP_ENTRY");
1530    if (s) _elm_config->desktop_entry = !!atoi(s);
1531    s = getenv("ELM_ACCESS_MODE");
1532    if (s) _elm_config->access_mode = ELM_ACCESS_MODE_ON;
1533 }
1534
1535 EAPI Eina_Bool
1536 elm_config_mirrored_get(void)
1537 {
1538    return _elm_config->is_mirrored;
1539 }
1540
1541 EAPI void
1542 elm_config_mirrored_set(Eina_Bool mirrored)
1543 {
1544    _elm_config->is_mirrored = mirrored;
1545    _elm_rescale();
1546 }
1547
1548 EAPI Eina_Bool
1549 elm_config_cursor_engine_only_get(void)
1550 {
1551    return _elm_config->cursor_engine_only;
1552 }
1553
1554 EAPI void
1555 elm_config_cursor_engine_only_set(Eina_Bool engine_only)
1556 {
1557    engine_only = !!engine_only;
1558    _elm_config->cursor_engine_only = engine_only;
1559 }
1560
1561 EAPI double
1562 elm_config_tooltip_delay_get(void)
1563 {
1564    return _elm_config->tooltip_delay;
1565 }
1566
1567 EAPI void
1568 elm_config_tooltip_delay_set(double delay)
1569 {
1570    if (delay < 0.0) return;
1571    _elm_config->tooltip_delay = delay;
1572 }
1573
1574 EAPI double
1575 elm_scale_get(void)
1576 {
1577    return elm_config_scale_get();
1578 }
1579
1580 EAPI double
1581 elm_config_scale_get(void)
1582 {
1583    return _elm_config->scale;
1584 }
1585
1586 EAPI void
1587 elm_scale_set(double scale)
1588 {
1589         elm_config_scale_set(scale);
1590 }
1591
1592 EAPI void
1593 elm_config_scale_set(double scale)
1594 {
1595    if (_elm_config->scale == scale) return;
1596    _elm_config->scale = scale;
1597    _elm_rescale();
1598 }
1599
1600 EAPI Eina_Bool
1601 elm_config_password_show_last_get(void)
1602 {
1603    return _elm_config->password_show_last;
1604 }
1605
1606 EAPI void
1607 elm_config_password_show_last_set(Eina_Bool password_show_last)
1608 {
1609    if (_elm_config->password_show_last == password_show_last) return;
1610    _elm_config->password_show_last = password_show_last;
1611    edje_password_show_last_set(_elm_config->password_show_last);
1612 }
1613
1614 EAPI double
1615 elm_config_password_show_last_timeout_get(void)
1616 {
1617    return _elm_config->password_show_last_timeout;
1618 }
1619
1620 EAPI void
1621 elm_config_password_show_last_timeout_set(double password_show_last_timeout)
1622 {
1623    if (_elm_config->password_show_last_timeout == password_show_last_timeout) return;
1624    _elm_config->password_show_last_timeout = password_show_last_timeout;
1625    edje_password_show_last_timeout_set(_elm_config->password_show_last_timeout);
1626 }
1627
1628 EAPI Eina_Bool
1629 elm_config_save(void)
1630 {
1631    return _elm_config_save();
1632 }
1633
1634 EAPI void
1635 elm_config_reload(void)
1636 {
1637    _elm_config_reload();
1638 }
1639
1640 EAPI const char *
1641 elm_config_profile_get(void)
1642 {
1643    return _elm_config_current_profile_get();
1644 }
1645
1646 EAPI const char *
1647 elm_config_profile_dir_get(const char *profile,
1648                     Eina_Bool   is_user)
1649 {
1650    return _elm_config_profile_dir_get(profile, is_user);
1651 }
1652
1653 EAPI void
1654 elm_config_profile_dir_free(const char *p_dir)
1655 {
1656    free((void *)p_dir);
1657 }
1658
1659 EAPI Eina_List *
1660 elm_config_profile_list_get(void)
1661 {
1662    return _elm_config_profiles_list();
1663 }
1664
1665 EAPI void
1666 elm_config_profile_list_free(Eina_List *l)
1667 {
1668    const char *dir;
1669
1670    EINA_LIST_FREE(l, dir)
1671      eina_stringshare_del(dir);
1672 }
1673
1674 EAPI void
1675 elm_config_profile_set(const char *profile)
1676 {
1677    EINA_SAFETY_ON_NULL_RETURN(profile);
1678    _elm_config_profile_set(profile);
1679 }
1680
1681 EAPI Eina_Bool
1682 elm_config_profile_exists(const char *profile)
1683 {
1684    EINA_SAFETY_ON_NULL_RETURN_VAL(profile, EINA_FALSE);
1685    return _elm_config_profile_exists(profile);
1686 }
1687
1688 EAPI const char *
1689 elm_config_engine_get(void)
1690 {
1691    return _elm_config->engine;
1692 }
1693
1694 EAPI void
1695 elm_config_engine_set(const char *engine)
1696 {
1697    EINA_SAFETY_ON_NULL_RETURN(engine);
1698
1699    _elm_config_engine_set(engine);
1700 }
1701
1702 EAPI Eina_List *
1703 elm_config_text_classes_list_get(void)
1704 {
1705    return _elm_config_text_classes_get();
1706 }
1707
1708 EAPI void
1709 elm_config_text_classes_list_free(Eina_List *list)
1710 {
1711    _elm_config_text_classes_free(list);
1712 }
1713
1714 EAPI const Eina_List *
1715 elm_config_font_overlay_list_get(void)
1716 {
1717    return _elm_config_font_overlays_list();
1718 }
1719
1720 EAPI void
1721 elm_config_font_overlay_set(const char    *text_class,
1722                      const char    *font,
1723                      Evas_Font_Size size)
1724 {
1725    EINA_SAFETY_ON_NULL_RETURN(text_class);
1726    _elm_config_font_overlay_set(text_class, font, size);
1727 }
1728
1729 EAPI void
1730 elm_config_font_overlay_unset(const char *text_class)
1731 {
1732    EINA_SAFETY_ON_NULL_RETURN(text_class);
1733    _elm_config_font_overlay_remove(text_class);
1734 }
1735
1736 EAPI void
1737 elm_config_font_overlay_apply(void)
1738 {
1739    _elm_config_font_overlay_apply();
1740    _elm_rescale();
1741 }
1742 // WRAPPER:: will be removed soon.
1743 EAPI Evas_Coord
1744 elm_finger_size_get(void)
1745 {
1746    return elm_config_finger_size_get();
1747 }
1748
1749 EAPI Evas_Coord
1750 elm_config_finger_size_get(void)
1751 {
1752    return _elm_config->finger_size;
1753 }
1754
1755 // WRAPPER:: will be removed soon.
1756 EAPI void
1757 elm_finger_size_set(Evas_Coord size)
1758 {
1759    elm_config_finger_size_set(size);
1760 }
1761
1762 EAPI void
1763 elm_config_finger_size_set(Evas_Coord size)
1764 {
1765    if (_elm_config->finger_size == size) return;
1766    _elm_config->finger_size = size;
1767    _elm_rescale();
1768 }
1769
1770 EAPI int
1771 elm_config_cache_flush_interval_get(void)
1772 {
1773    return _elm_config->cache_flush_poll_interval;
1774 }
1775
1776 EAPI void
1777 elm_config_cache_flush_interval_set(int size)
1778 {
1779    if (_elm_config->cache_flush_poll_interval == size) return;
1780    _elm_config->cache_flush_poll_interval = size;
1781
1782    _elm_recache();
1783 }
1784
1785 EAPI Eina_Bool
1786 elm_config_cache_flush_enabled_get(void)
1787 {
1788    return _elm_config->cache_flush_enable;
1789 }
1790
1791 EAPI void
1792 elm_config_cache_flush_enabled_set(Eina_Bool enabled)
1793 {
1794    enabled = !!enabled;
1795    if (_elm_config->cache_flush_enable == enabled) return;
1796    _elm_config->cache_flush_enable = enabled;
1797
1798    _elm_recache();
1799 }
1800
1801 EAPI int
1802 elm_config_cache_font_cache_size_get(void)
1803 {
1804    return _elm_config->font_cache;
1805 }
1806
1807 EAPI void
1808 elm_config_cache_font_cache_size_set(int size)
1809 {
1810    if (_elm_config->font_cache == size) return;
1811    _elm_config->font_cache = size;
1812
1813    _elm_recache();
1814 }
1815
1816 EAPI int
1817 elm_config_cache_image_cache_size_get(void)
1818 {
1819    return _elm_config->image_cache;
1820 }
1821
1822 EAPI void
1823 elm_config_cache_image_cache_size_set(int size)
1824 {
1825    if (_elm_config->image_cache == size) return;
1826    _elm_config->image_cache = size;
1827
1828    _elm_recache();
1829 }
1830
1831 EAPI int
1832 elm_config_cache_edje_file_cache_size_get()
1833 {
1834    return _elm_config->edje_cache;
1835 }
1836
1837 EAPI void
1838 elm_config_cache_edje_file_cache_size_set(int size)
1839 {
1840    if (_elm_config->edje_cache == size) return;
1841    _elm_config->edje_cache = size;
1842
1843    _elm_recache();
1844 }
1845
1846 EAPI int
1847 elm_config_cache_edje_collection_cache_size_get(void)
1848 {
1849    return _elm_config->edje_collection_cache;
1850 }
1851
1852 EAPI void
1853 elm_config_cache_edje_collection_cache_size_set(int size)
1854 {
1855    if (_elm_config->edje_collection_cache == size) return;
1856    _elm_config->edje_collection_cache = size;
1857
1858    _elm_recache();
1859 }
1860
1861 EAPI Eina_Bool
1862 elm_config_focus_highlight_enabled_get(void)
1863 {
1864    return _elm_config->focus_highlight_enable;
1865 }
1866
1867 EAPI void
1868 elm_config_focus_highlight_enabled_set(Eina_Bool enable)
1869 {
1870    _elm_config->focus_highlight_enable = !!enable;
1871 }
1872
1873 EAPI Eina_Bool
1874 elm_config_focus_highlight_animate_get(void)
1875 {
1876    return _elm_config->focus_highlight_animate;
1877 }
1878
1879 EAPI void
1880 elm_config_focus_highlight_animate_set(Eina_Bool animate)
1881 {
1882    _elm_config->focus_highlight_animate = !!animate;
1883 }
1884
1885 EAPI Eina_Bool
1886 elm_config_scroll_bounce_enabled_get(void)
1887 {
1888    return _elm_config->thumbscroll_bounce_enable;
1889 }
1890
1891 EAPI void
1892 elm_config_scroll_bounce_enabled_set(Eina_Bool enabled)
1893 {
1894    _elm_config->thumbscroll_bounce_enable = enabled;
1895 }
1896
1897 EAPI double
1898 elm_config_scroll_bounce_friction_get(void)
1899 {
1900    return _elm_config->thumbscroll_bounce_friction;
1901 }
1902
1903 EAPI void
1904 elm_config_scroll_bounce_friction_set(double friction)
1905 {
1906    _elm_config->thumbscroll_bounce_friction = friction;
1907 }
1908
1909 EAPI double
1910 elm_config_scroll_page_scroll_friction_get(void)
1911 {
1912    return _elm_config->page_scroll_friction;
1913 }
1914
1915 EAPI void
1916 elm_config_scroll_page_scroll_friction_set(double friction)
1917 {
1918    _elm_config->page_scroll_friction = friction;
1919 }
1920
1921 EAPI double
1922 elm_config_scroll_bring_in_scroll_friction_get(void)
1923 {
1924    return _elm_config->bring_in_scroll_friction;
1925 }
1926
1927 EAPI void
1928 elm_config_scroll_bring_in_scroll_friction_set(double friction)
1929 {
1930    _elm_config->bring_in_scroll_friction = friction;
1931 }
1932
1933 EAPI double
1934 elm_config_scroll_zoom_friction_get(void)
1935 {
1936    return _elm_config->zoom_friction;
1937 }
1938
1939 EAPI void
1940 elm_config_scroll_zoom_friction_set(double friction)
1941 {
1942    _elm_config->zoom_friction = friction;
1943 }
1944
1945 EAPI Eina_Bool
1946 elm_config_scroll_thumbscroll_enabled_get(void)
1947 {
1948    return _elm_config->thumbscroll_enable;
1949 }
1950
1951 EAPI void
1952 elm_config_scroll_thumbscroll_enabled_set(Eina_Bool enabled)
1953 {
1954    _elm_config->thumbscroll_enable = enabled;
1955 }
1956
1957 EAPI unsigned int
1958 elm_config_scroll_thumbscroll_threshold_get(void)
1959 {
1960    return _elm_config->thumbscroll_threshold;
1961 }
1962
1963 EAPI void
1964 elm_config_scroll_thumbscroll_threshold_set(unsigned int threshold)
1965 {
1966    _elm_config->thumbscroll_threshold = threshold;
1967 }
1968
1969 EAPI double
1970 elm_config_scroll_thumbscroll_momentum_threshold_get(void)
1971 {
1972    return _elm_config->thumbscroll_momentum_threshold;
1973 }
1974
1975 EAPI void
1976 elm_config_scroll_thumbscroll_momentum_threshold_set(double threshold)
1977 {
1978    _elm_config->thumbscroll_momentum_threshold = threshold;
1979 }
1980
1981 EAPI double
1982 elm_config_scroll_thumbscroll_friction_get(void)
1983 {
1984    return _elm_config->thumbscroll_friction;
1985 }
1986
1987 EAPI void
1988 elm_config_scroll_thumbscroll_friction_set(double friction)
1989 {
1990    _elm_config->thumbscroll_friction = friction;
1991 }
1992
1993 EAPI double
1994 elm_config_scroll_thumbscroll_border_friction_get(void)
1995 {
1996    return _elm_config->thumbscroll_border_friction;
1997 }
1998
1999 EAPI void
2000 elm_config_scroll_thumbscroll_border_friction_set(double friction)
2001 {
2002    if (friction < 0.0) friction = 0.0;
2003    if (friction > 1.0) friction = 1.0;
2004    _elm_config->thumbscroll_border_friction = friction;
2005 }
2006
2007 EAPI double
2008 elm_config_scroll_thumbscroll_sensitivity_friction_get(void)
2009 {
2010    return _elm_config->thumbscroll_sensitivity_friction;
2011 }
2012
2013 EAPI void
2014 elm_config_scroll_thumbscroll_sensitivity_friction_set(double friction)
2015 {
2016    if (friction < 0.1) friction = 0.1;
2017    if (friction > 1.0) friction = 1.0;
2018    _elm_config->thumbscroll_sensitivity_friction = friction;
2019 }
2020
2021 EAPI void
2022 elm_config_longpress_timeout_set(double longpress_timeout)
2023 {
2024    _elm_config->longpress_timeout = longpress_timeout;
2025 }
2026
2027 EAPI double
2028 elm_config_longpress_timeout_get(void)
2029 {
2030    return _elm_config->longpress_timeout;
2031 }
2032
2033 EAPI void
2034 elm_config_all_flush(void)
2035 {
2036 #ifdef HAVE_ELEMENTARY_X
2037    if (_prop_all_update_timer) ecore_timer_del(_prop_all_update_timer);
2038    _prop_all_update_timer = ecore_timer_add(0.1, _prop_all_update_cb, NULL);
2039 #endif
2040 }
2041
2042 static void
2043 _translation_init()
2044 {
2045 #ifdef ENABLE_NLS
2046    const char *cur_dom = textdomain(NULL);
2047    const char *trans_comment = gettext("");
2048    const char *msg_locale = setlocale(LC_MESSAGES, NULL);
2049
2050    /* Same concept as what glib does:
2051     * We shouldn't translate if there are no translations for the
2052     * application in the current locale + domain. (Unless locale is
2053     * en_/C where translating only parts of the interface make some
2054     * sense).
2055     */
2056    _elm_config->translate = !(strcmp (cur_dom, "messages") &&
2057          !*trans_comment && strncmp (msg_locale, "en_", 3) &&
2058          strcmp (msg_locale, "C"));
2059 #endif
2060 }
2061
2062 void
2063 _elm_config_init(void)
2064 {
2065    if (!ELM_EVENT_CONFIG_ALL_CHANGED)
2066       ELM_EVENT_CONFIG_ALL_CHANGED = ecore_event_type_new();
2067    _desc_init();
2068    _profile_fetch_from_conf();
2069    _config_load();
2070    _env_get();
2071    if (_elm_preferred_engine) eina_stringshare_del(_elm_preferred_engine);
2072    if (_elm_config->engine)
2073      _elm_preferred_engine = eina_stringshare_add(_elm_config->engine);
2074    else
2075      _elm_preferred_engine = NULL;
2076    _translation_init();
2077    _config_apply();
2078    _elm_config_font_overlay_apply();
2079    _elm_recache();
2080 }
2081
2082 void
2083 _elm_config_sub_shutdown(void)
2084 {
2085 #define ENGINE_COMPARE(name) (!strcmp(_elm_config->engine, name))
2086    if (ENGINE_COMPARE(ELM_SOFTWARE_X11) ||
2087        ENGINE_COMPARE(ELM_SOFTWARE_16_X11) ||
2088        ENGINE_COMPARE(ELM_XRENDER_X11) ||
2089        ENGINE_COMPARE(ELM_OPENGL_X11) ||
2090        ENGINE_COMPARE(ELM_OPENGL_COCOA))
2091 #undef ENGINE_COMPARE
2092      {
2093 #ifdef HAVE_ELEMENTARY_X
2094         ecore_x_shutdown();
2095 #endif
2096      }
2097 }
2098
2099 void
2100 _elm_config_sub_init(void)
2101 {
2102 #define ENGINE_COMPARE(name) (!strcmp(_elm_config->engine, name))
2103    if (ENGINE_COMPARE(ELM_SOFTWARE_X11) ||
2104        ENGINE_COMPARE(ELM_SOFTWARE_16_X11) ||
2105        ENGINE_COMPARE(ELM_XRENDER_X11) ||
2106        ENGINE_COMPARE(ELM_OPENGL_X11) ||
2107        ENGINE_COMPARE(ELM_OPENGL_COCOA))
2108 #undef ENGINE_COMPARE
2109      {
2110 #ifdef HAVE_ELEMENTARY_X
2111         if (!ecore_x_init(NULL))
2112           {
2113              ERR("Cannot connect to X11 display. check $DISPLAY variable");
2114              exit(1);
2115           }
2116         _root_1st = ecore_x_window_root_first_get();
2117
2118         if (!ecore_x_screen_is_composited(0))
2119           _elm_config->compositing = 0;
2120
2121         ecore_x_atoms_get(_atom_names, ATOM_COUNT, _atom);
2122         ecore_x_event_mask_set(_root_1st,
2123                                ECORE_X_EVENT_MASK_WINDOW_PROPERTY);
2124         _prop_change_handler = ecore_event_handler_add
2125             (ECORE_X_EVENT_WINDOW_PROPERTY, _prop_change, NULL);
2126         if (!getenv("ELM_PROFILE"))
2127           {
2128              char *s;
2129
2130              s = ecore_x_window_prop_string_get(_root_1st,
2131                                                 _atom[ATOM_E_PROFILE]);
2132              if (s)
2133                {
2134                   int changed = 0;
2135
2136                   if (_elm_profile)
2137                     {
2138                        if (strcmp(_elm_profile, s)) changed = 1;
2139                        free(_elm_profile);
2140                     }
2141                   _elm_profile = s;
2142                   if (changed) _prop_config_get();
2143                }
2144           }
2145 #endif
2146      }
2147    _config_sub_apply();
2148 }
2149
2150 void
2151 _elm_config_reload(void)
2152 {
2153    _config_free();
2154    _config_load();
2155    _config_apply();
2156    _elm_config_font_overlay_apply();
2157    _elm_rescale();
2158    _elm_recache();
2159 }
2160
2161 void
2162 _elm_config_engine_set(const char *engine)
2163 {
2164    if (_elm_config->engine && strcmp(_elm_config->engine, engine))
2165      eina_stringshare_del(_elm_config->engine);
2166
2167    _elm_config->engine = eina_stringshare_add(engine);
2168 }
2169
2170 EAPI const char *
2171 elm_config_preferred_engine_get(void)
2172 {
2173    return _elm_preferred_engine;
2174 }
2175
2176 EAPI void
2177 elm_config_preferred_engine_set(const char *engine)
2178 {
2179    if (engine)
2180      eina_stringshare_replace(&(_elm_preferred_engine), engine);
2181    else
2182      {
2183         if (_elm_preferred_engine) eina_stringshare_del(_elm_preferred_engine);
2184         _elm_preferred_engine = eina_stringshare_add(_elm_config->engine);
2185      }
2186 }
2187
2188 void
2189 _elm_config_profile_set(const char *profile)
2190 {
2191    Eina_Bool changed = EINA_FALSE;
2192
2193    if (_elm_profile)
2194      {
2195         if (strcmp(_elm_profile, profile))
2196           changed = 1;
2197         free(_elm_profile);
2198      }
2199
2200    _elm_profile = strdup(profile);
2201
2202    if (changed)
2203      {
2204         _config_free();
2205         _config_load();
2206         _config_apply();
2207         _elm_config_font_overlay_apply();
2208         _elm_rescale();
2209         _elm_recache();
2210      }
2211 }
2212
2213 Eina_Bool
2214 _elm_config_profile_exists(const char *profile)
2215 {
2216    Eina_List *profs = _elm_config_profiles_list();
2217    Eina_List *l;
2218    const char *p, *dir;
2219    Eina_Bool res = EINA_FALSE;
2220
2221    EINA_LIST_FOREACH(profs, l, p)
2222      {
2223         if (!strcmp(profile, p))
2224           {
2225              res = EINA_TRUE;
2226              break;
2227           }
2228      }
2229
2230    EINA_LIST_FREE(profs, dir)
2231      eina_stringshare_del(dir);
2232
2233    return res;
2234 }
2235
2236 void
2237 _elm_config_shutdown(void)
2238 {
2239 #ifdef HAVE_ELEMENTARY_X
2240    if (_prop_all_update_timer)
2241      {
2242         ecore_timer_del(_prop_all_update_timer);
2243         _prop_all_update_timer = NULL;
2244         _prop_all_update_cb(NULL);
2245      }
2246    if (_prop_change_delay_timer) ecore_timer_del(_prop_change_delay_timer);
2247    _prop_change_delay_timer = NULL;
2248 #endif
2249
2250 #define ENGINE_COMPARE(name) (!strcmp(_elm_config->engine, name))
2251    if (ENGINE_COMPARE(ELM_SOFTWARE_X11) ||
2252        ENGINE_COMPARE(ELM_SOFTWARE_16_X11) ||
2253        ENGINE_COMPARE(ELM_XRENDER_X11) ||
2254        ENGINE_COMPARE(ELM_OPENGL_X11))
2255 #undef ENGINE_COMPARE
2256      {
2257 #ifdef HAVE_ELEMENTARY_X
2258         ecore_event_handler_del(_prop_change_handler);
2259         _prop_change_handler = NULL;
2260 #endif
2261      }
2262    _config_free();
2263    if (_elm_preferred_engine)
2264      {
2265         eina_stringshare_del(_elm_preferred_engine);
2266         _elm_preferred_engine = NULL;
2267      }
2268    if (_elm_profile)
2269      {
2270         free(_elm_profile);
2271         _elm_profile = NULL;
2272      }
2273    _desc_shutdown();
2274 }
2275