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