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