1 #ifdef HAVE_CONFIG_H
2 # include "elementary_config.h"
3 #endif
4 
5 #include <Elementary.h>
6 #include "elm_priv.h"
7 
8 #include "../../static_libs/buildsystem/buildsystem.h"
9 #include "efl_config_global.eo.h"
10 
11 EAPI int ELM_EVENT_CONFIG_ALL_CHANGED = 0;
12 EAPI void __efl_internal_elm_config_set(Efl_Config *cfg);
13 
14 Elm_Config *_elm_config = NULL;
15 Efl_Config *_efl_config_obj = NULL;
16 static char *_elm_profile = NULL;
17 static Eet_Data_Descriptor *_config_edd = NULL;
18 static Eet_Data_Descriptor *_config_font_overlay_edd = NULL;
19 static Eet_Data_Descriptor *_config_color_edd = NULL;
20 static Eet_Data_Descriptor *_config_color_palette_edd = NULL;
21 static Eet_Data_Descriptor *_config_color_overlay_edd = NULL;
22 static Eet_Data_Descriptor *_config_bindings_widget_edd = NULL;
23 static Eet_Data_Descriptor *_config_binding_key_edd = NULL;
24 static Eet_Data_Descriptor *_config_binding_modifier_edd = NULL;
25 const char *_elm_preferred_engine = NULL;
26 const char *_elm_accel_preference = NULL;
27 static const char *_elm_gl_preference = NULL;
28 static Eina_List  *_font_overlays_del = NULL;
29 static Eina_List  *_color_overlays_del = NULL;
30 
31 static Ecore_Poller *_elm_cache_flush_poller = NULL;
32 static void _elm_config_key_binding_hash(void);
33 
34 Eina_Bool _config_profile_lock = EINA_FALSE;
35 static Ecore_Timer *_config_change_delay_timer = NULL;
36 static Ecore_Timer *_config_profile_change_delay_timer = NULL;
37 static Ecore_Event_Handler *_monitor_file_created_handler = NULL;
38 static Ecore_Event_Handler *_monitor_file_modified_handler = NULL;
39 static Ecore_Event_Handler *_monitor_directory_created_handler = NULL;
40 static Eio_Monitor *_eio_config_monitor = NULL;
41 static Eio_Monitor *_eio_profile_monitor = NULL;
42 
43 Eina_Hash *_elm_key_bindings = NULL;
44 
45 const char *_elm_engines[] = {
46    "software_x11",
47    "fb",
48    "opengl_x11",
49    "software_gdi",
50    "sdl",
51    "opengl_sdl",
52    "buffer",
53    "ews",
54    "opengl_cocoa",
55    "wayland_shm",
56    "wayland_egl",
57    "drm",
58    "ddraw",
59    "gl_drm",
60    NULL
61 };
62 
63 /* whenever you want to add a new text class support into Elementary,
64    declare it both here and in the (default) theme */
65 static const Elm_Text_Class _elm_text_classes[] = {
66    {"button", "Button"},
67    {"calendar_year_text", "Year Text in Title Area"},
68    {"calendar_month_text", "Month Text in Title Area"},
69    {"calendar_weekday_text", "Weekday Text"},
70    {"calendar_day_text", "Day Text"},
71    {"calendar_day_text_holiday", "Holiday Text"},
72    {"calendar_day_text_today", "Today Text"},
73    {"calendar_day_text_disabled", "Disabled Day Text"},
74    {"datetime_separator_text", "Datetime Separator Text"},
75    {"datetime_separator_text_disabled", "Datetime Separator Disabled Text"},
76    {"label", "Label"},
77    {"entry_text", "Entry Text"},
78    {"entry_text_disabled", "Entry Disabled Text"},
79    {"entry_guide_text", "Entry Guide Text"},
80    {"entry", "Entry"},
81    {"index_highlight_text", "Index Highlight Text"},
82    {"index_item_text", "Index Items Text"},
83    {"index_item_text_selected", "Index Selected Items Text"},
84    {"multibuttonentry_item_text", "Multibuttonentry Items"},
85    {"multibuttonentry_item_text_pressed", "Multibuttonentry Pressed Items"},
86    {"multibuttonentry_item_text_disabled", "Multibuttonentry Disabled Items"},
87    {"tags_item_text", "Tags Items"},
88    {"tags_item_text_pressed", "Tags Pressed Items"},
89    {"tags_item_text_disabled", "Tags Disabled Items"},
90    {"title_bar", "Title Bar"},
91    {"list_item", "List Items"},
92    {"grid_item", "Grid Items"},
93    {"toolbar_item", "Toolbar Items"},
94    {"menu_item", "Menu Items"},
95    {NULL, NULL}
96 };
97 
98 /* whenever you want to add a new class class support into Elementary,
99    declare it both here and in the (default) theme */
100 static const Elm_Color_Class _elm_color_classes[] = {
101    {"button_text", "Button Text"},
102    {"button_text_disabled", "Button Disabled Text"},
103    {"button_text_anchor", "Anchor Button Text"},
104    {"button_text_anchor_disabled", "Anchor Button Disabled Text"},
105    {"calendar_year_text", "Year Text in Title Area"},
106    {"calendar_month_text", "Month Text in Title Area"},
107    {"calendar_weekday_text", "Weekday Text"},
108    {"calendar_day_text", "Day Text"},
109    {"calendar_day_text_holiday", "Holiday Text"},
110    {"calendar_day_text_today", "Today Text"},
111    {"calendar_day_text_disabled", "Disabled Day Text"},
112    {"calendar_day_selected", "Selected Day Effect"},
113    {"calendar_day_highlighted", "Highlighted Day Effect"},
114    {"calendar_day_checked", "Checked Day Effect"},
115    {"datetime_bg", "Datetime Background"},
116    {"datepicker_bg", "Datepicker Background"},
117    {"timepicker_bg", "Timepicker Background"},
118    {"datetime_separator_text", "Datetime Separator Text"},
119    {"datetime_separator_text_disabled", "Datetime Separator Disabled Text"},
120    {"hoversel_item_active", "Hoversel Item Text"},
121    {"hoversel_text_disabled", "Hoversel Item Disabled Text"},
122    {"radio_text", "Radio Text"},
123    {"frame", "Frame Text"},
124    {"entry_text", "Entry Text"},
125    {"entry_text_disabled", "Entry Disabled Text"},
126    {"entry_guide_text", "Entry Guide Text"},
127    {"entry_cursor", "Entry Cursor"},
128    {"entry_selection_handler", "Entry Selection Handler"},
129    {"entry_scrollframe_base", "Entry Scrollframe Base"},
130    {"check_text", "Check Text"},
131    {"check_on_text", "Check On Text"},
132    {"check_off_text", "Check Off Text"},
133    {"list_item_base", "List Item Base"},
134    {"list_item_base_odd", "List Odd Item Base"},
135    {"list_item_disabled", "List Item Disabled Base"},
136    {"list_item_selected", "List Item Selected Base"},
137    {"grid_item", "Grid Item Text"},
138    {"grid_item_disabled", "Grid Item Disabled Text"},
139    {"grid_item_selected", "Grid Item Selected Text"},
140    {"index_bg", "Index Background"},
141    {"index_item_bg", "Index Item Background"},
142    {"index_highlight_text", "Index Highlight Text"},
143    {"index_item_text", "Index Items Text"},
144    {"index_item_text_selected", "Index Selected Items Text"},
145    {"toolbar_item", "Toolbar Item Text"},
146    {"toolbar_item_disabled", "Toolbar Item Disabled Text"},
147    {"toolbar_item_selected", "Toolbar Item Selected Text"},
148    {"toolbar_item_active", "Toolbar Item Active Text"},
149    {"slider_text", "Slider Text"},
150    {"slider_text_disabled", "Slider Disabled Text"},
151    {"slider_indicator", "Slider Indicator Text"},
152    {"spinner_bg", "Spinner Background"},
153    {"progressbar_text", "Progressbar Text"},
154    {"progressbar_text_disabled", "Progressbar Disabled Text"},
155    {"progressbar_status", "Progressbar Status Text"},
156    {"bubble_text", "Bubble Text"},
157    {"bubble_info", "Bubble Info Text"},
158    {"menu_item_active", "Menu Item Text"},
159    {"menu_item_disabled", "Menu Item Disabled Text"},
160    {"multibuttonentry_bg", "Multibuttonentry Background"},
161    {"multibuttonentry_item_bg", "Multibuttonentry Item Background"},
162    {"multibuttonentry_item_bg_selected", "Multibuttonentry Item Selected Background"},
163    {"multibuttonentry_item_text", "Multibuttonentry Item Text"},
164    {"multibuttonentry_item_text_pressed", "Multibuttonentry Item Pressed Text"},
165    {"multibuttonentry_item_text_disabled", "Multibuttonentry Item Disabled Text"},
166    {"tags_bg", "Tags Background"},
167    {"tags_item_bg", "Tags Item Background"},
168    {"tags_item_bg_selected", "Tags Item Selected Background"},
169    {"tags_item_text", "Tags Item Text"},
170    {"tags_item_text_pressed", "Tags Item Pressed Text"},
171    {"tags_item_text_disabled", "Tags Item Disabled Text"},
172    {"border_title", "Border Title Text"},
173    {"border_title_active", "Border Title Active Text"},
174    {"datetime_text", "Datetime Text"},
175    {"multibuttonentry_label", "Multibuttonentry Text"},
176    {"tags_label", "Tags Text"},
177    {"tags_number", "Tags Number Text"},
178    {"spinner", "Spinner Text"},
179    {"spinner_disabled", "Spinner Disabled Text"},
180    {NULL, NULL}
181 };
182 
183 static void        _config_free(Elm_Config *cfg);
184 static void        _config_apply(void);
185 static void        _config_sub_apply(void);
186 static void        _config_update(void);
187 static void        _env_get(void);
188 static void        _color_overlays_cancel(void);
189 
190 #define ELM_CONFIG_VAL(edd, type, member, dtype) \
191   EET_DATA_DESCRIPTOR_ADD_BASIC(edd, type, #member, member, dtype)
192 #define ELM_CONFIG_LIST(edd, type, member, eddtype) \
193   EET_DATA_DESCRIPTOR_ADD_LIST(edd, type, #member, member, eddtype)
194 
195 static void
_elm_font_overlays_del_free(void)196 _elm_font_overlays_del_free(void)
197 {
198    char *text_class;
199    Eina_List *l;
200    EINA_LIST_FOREACH(_font_overlays_del, l, text_class)
201      eina_stringshare_del(text_class);
202    _font_overlays_del = eina_list_free(_font_overlays_del);
203 }
204 
205 static void
_elm_config_font_overlays_cancel(void)206 _elm_config_font_overlays_cancel(void)
207 {
208    Elm_Font_Overlay *efd;
209    Eina_List *l;
210    EINA_LIST_FOREACH(_elm_config->font_overlays, l, efd)
211      edje_text_class_del(efd->text_class);
212 }
213 
214 static void
_desc_init(void)215 _desc_init(void)
216 {
217    Eet_Data_Descriptor_Class eddc;
218 
219    EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Elm_Config);
220    eddc.func.str_direct_alloc = NULL;
221    eddc.func.str_direct_free = NULL;
222 
223    _config_edd = eet_data_descriptor_file_new(&eddc);
224    if (!_config_edd)
225      {
226         ERR("EEEK! eet_data_descriptor_file_new() failed.");
227         return;
228      }
229 
230    memset(&eddc, 0, sizeof(eddc)); /* just in case... */
231    EET_EINA_STREAM_DATA_DESCRIPTOR_CLASS_SET(&eddc, Elm_Font_Overlay);
232    eddc.func.str_direct_alloc = NULL;
233    eddc.func.str_direct_free = NULL;
234 
235    _config_font_overlay_edd = eet_data_descriptor_stream_new(&eddc);
236    if (!_config_font_overlay_edd)
237      {
238         ERR("EEEK! eet_data_descriptor_stream_new() failed.");
239         eet_data_descriptor_free(_config_edd);
240         return;
241      }
242 
243    memset(&eddc, 0, sizeof(eddc)); /* just in case... */
244    EET_EINA_STREAM_DATA_DESCRIPTOR_CLASS_SET(&eddc, Elm_Color_RGBA);
245    eddc.func.str_direct_alloc = NULL;
246    eddc.func.str_direct_free = NULL;
247 
248    _config_color_edd = eet_data_descriptor_stream_new(&eddc);
249    if (!_config_color_edd)
250      {
251         ERR("EEEK! eet_data_descriptor_stream_new() failed.");
252         eet_data_descriptor_free(_config_edd);
253         return;
254      }
255 
256    memset(&eddc, 0, sizeof(eddc)); /* just in case... */
257    EET_EINA_STREAM_DATA_DESCRIPTOR_CLASS_SET(&eddc, Elm_Custom_Palette);
258    eddc.func.str_direct_alloc = NULL;
259    eddc.func.str_direct_free = NULL;
260 
261    _config_color_palette_edd = eet_data_descriptor_stream_new(&eddc);
262    if (!_config_color_palette_edd)
263      {
264         ERR("EEEK! eet_data_descriptor_stream_new() failed.");
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_Overlay);
271    eddc.func.str_direct_alloc = NULL;
272    eddc.func.str_direct_free = NULL;
273 
274    _config_color_overlay_edd = eet_data_descriptor_stream_new(&eddc);
275    if (!_config_color_overlay_edd)
276      {
277         ERR("EEEK! eet_data_descriptor_stream_new() failed.");
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_Config_Bindings_Widget);
284    eddc.func.str_direct_alloc = NULL;
285    eddc.func.str_direct_free = NULL;
286 
287    _config_bindings_widget_edd = eet_data_descriptor_stream_new(&eddc);
288    if (!_config_bindings_widget_edd)
289      {
290         ERR("EEEK! eet_data_descriptor_stream_new() failed.");
291         eet_data_descriptor_free(_config_edd);
292         return;
293      }
294 
295    memset(&eddc, 0, sizeof(eddc)); /* just in case... */
296    EET_EINA_STREAM_DATA_DESCRIPTOR_CLASS_SET(&eddc, Elm_Config_Binding_Key);
297    eddc.func.str_direct_alloc = NULL;
298    eddc.func.str_direct_free = NULL;
299 
300    _config_binding_key_edd = eet_data_descriptor_stream_new(&eddc);
301    if (!_config_binding_key_edd)
302      {
303         ERR("EEEK! eet_data_descriptor_stream_new() failed.");
304         eet_data_descriptor_free(_config_edd);
305         return;
306      }
307 
308    memset(&eddc, 0, sizeof(eddc)); /* just in case... */
309    EET_EINA_STREAM_DATA_DESCRIPTOR_CLASS_SET(&eddc, Elm_Config_Binding_Modifier);
310    eddc.func.str_direct_alloc = NULL;
311    eddc.func.str_direct_free = NULL;
312 
313    _config_binding_modifier_edd = eet_data_descriptor_stream_new(&eddc);
314    if (!_config_binding_modifier_edd)
315      {
316         ERR("EEEK! eet_data_descriptor_stream_new() failed.");
317         eet_data_descriptor_free(_config_edd);
318         return;
319      }
320 
321 #define T_INT    EET_T_INT
322 #define T_DOUBLE EET_T_DOUBLE
323 #define T_STRING EET_T_STRING
324 #define T_UCHAR  EET_T_UCHAR
325 
326 #define T        Elm_Font_Overlay
327 #define D        _config_font_overlay_edd
328    ELM_CONFIG_VAL(D, T, text_class, EET_T_STRING);
329    ELM_CONFIG_VAL(D, T, font, EET_T_STRING);
330    ELM_CONFIG_VAL(D, T, size, EET_T_INT);
331 #undef T
332 #undef D
333 
334 #define T Elm_Color_RGBA
335 #define D _config_color_edd
336    ELM_CONFIG_VAL(D, T, r, EET_T_UINT);
337    ELM_CONFIG_VAL(D, T, g, EET_T_UINT);
338    ELM_CONFIG_VAL(D, T, b, EET_T_UINT);
339    ELM_CONFIG_VAL(D, T, a, EET_T_UINT);
340 #undef T
341 #undef D
342 
343 #define T Elm_Custom_Palette
344 #define D _config_color_palette_edd
345    ELM_CONFIG_VAL(D, T, palette_name, EET_T_STRING);
346    ELM_CONFIG_LIST(D, T, color_list, _config_color_edd);
347 #undef T
348 #undef D
349 
350 #define T Elm_Color_Overlay
351 #define D _config_color_overlay_edd
352    ELM_CONFIG_VAL(D, T, color_class, EET_T_STRING);
353    ELM_CONFIG_VAL(D, T, color.r, EET_T_UCHAR);
354    ELM_CONFIG_VAL(D, T, color.g, EET_T_UCHAR);
355    ELM_CONFIG_VAL(D, T, color.b, EET_T_UCHAR);
356    ELM_CONFIG_VAL(D, T, color.a, EET_T_UCHAR);
357    ELM_CONFIG_VAL(D, T, outline.r, EET_T_UCHAR);
358    ELM_CONFIG_VAL(D, T, outline.g, EET_T_UCHAR);
359    ELM_CONFIG_VAL(D, T, outline.b, EET_T_UCHAR);
360    ELM_CONFIG_VAL(D, T, outline.a, EET_T_UCHAR);
361    ELM_CONFIG_VAL(D, T, shadow.r, EET_T_UCHAR);
362    ELM_CONFIG_VAL(D, T, shadow.g, EET_T_UCHAR);
363    ELM_CONFIG_VAL(D, T, shadow.b, EET_T_UCHAR);
364    ELM_CONFIG_VAL(D, T, shadow.a, EET_T_UCHAR);
365 #undef T
366 #undef D
367 
368 #define T        Elm_Config_Bindings_Widget
369 #define D        _config_bindings_widget_edd
370    ELM_CONFIG_VAL(D, T, name, EET_T_STRING);
371    ELM_CONFIG_LIST(D, T, key_bindings, _config_binding_key_edd);
372 #undef T
373 #undef D
374 
375 #define T        Elm_Config_Binding_Key
376 #define D        _config_binding_key_edd
377    ELM_CONFIG_VAL(D, T, context, EET_T_INT);
378    ELM_CONFIG_VAL(D, T, key, EET_T_STRING);
379    ELM_CONFIG_VAL(D, T, action, EET_T_STRING);
380    ELM_CONFIG_VAL(D, T, params, EET_T_STRING);
381    ELM_CONFIG_LIST(D, T, modifiers, _config_binding_modifier_edd);
382 #undef T
383 #undef D
384 
385 #define T        Elm_Config_Binding_Modifier
386 #define D        _config_binding_modifier_edd
387    ELM_CONFIG_VAL(D, T, mod, EET_T_STRING);
388    ELM_CONFIG_VAL(D, T, flag, EET_T_UCHAR);
389 #undef T
390 #undef D
391 
392 #define T Elm_Config
393 #define D _config_edd
394    ELM_CONFIG_VAL(D, T, config_version, T_INT);
395    ELM_CONFIG_VAL(D, T, engine, T_STRING);
396    ELM_CONFIG_VAL(D, T, accel, T_STRING);
397    ELM_CONFIG_VAL(D, T, web_backend, T_STRING);
398    ELM_CONFIG_VAL(D, T, accel_override, T_UCHAR);
399    ELM_CONFIG_VAL(D, T, vsync, T_UCHAR);
400    //
401    ELM_CONFIG_VAL(D, T, thumbscroll_enable, T_UCHAR);
402    ELM_CONFIG_VAL(D, T, thumbscroll_threshold, T_INT);
403    ELM_CONFIG_VAL(D, T, thumbscroll_hold_threshold, T_INT);
404    // bounce
405    ELM_CONFIG_VAL(D, T, thumbscroll_bounce_friction, T_DOUBLE);
406    ELM_CONFIG_VAL(D, T, thumbscroll_bounce_enable, T_UCHAR);
407    ELM_CONFIG_VAL(D, T, thumbscroll_border_friction, T_DOUBLE);
408    ELM_CONFIG_VAL(D, T, thumbscroll_sensitivity_friction, T_DOUBLE);
409    // momeuntum
410    ELM_CONFIG_VAL(D, T, thumbscroll_momentum_threshold, T_DOUBLE);
411    ELM_CONFIG_VAL(D, T, thumbscroll_momentum_distance_max, T_INT);
412    ELM_CONFIG_VAL(D, T, thumbscroll_momentum_friction, T_DOUBLE);
413    ELM_CONFIG_VAL(D, T, thumbscroll_momentum_animation_duration_min_limit, T_DOUBLE);
414    ELM_CONFIG_VAL(D, T, thumbscroll_momentum_animation_duration_max_limit, T_DOUBLE);
415    // acceleration
416    ELM_CONFIG_VAL(D, T, thumbscroll_acceleration_threshold, T_DOUBLE);
417    ELM_CONFIG_VAL(D, T, thumbscroll_acceleration_time_limit, T_DOUBLE);
418    ELM_CONFIG_VAL(D, T, thumbscroll_acceleration_weight, T_DOUBLE);
419    //deprecated
420    ELM_CONFIG_VAL(D, T, thumbscroll_friction, T_DOUBLE);
421    ELM_CONFIG_VAL(D, T, thumbscroll_min_friction, T_DOUBLE);
422    ELM_CONFIG_VAL(D, T, thumbscroll_friction_standard, T_DOUBLE);
423    ELM_CONFIG_VAL(D, T, thumbscroll_flick_distance_tolerance, T_INT);
424    //
425    ELM_CONFIG_VAL(D, T, page_scroll_friction, T_DOUBLE);
426    ELM_CONFIG_VAL(D, T, bring_in_scroll_friction, T_DOUBLE);
427    ELM_CONFIG_VAL(D, T, zoom_friction, T_DOUBLE);
428    ELM_CONFIG_VAL(D, T, scroll_smooth_start_enable, T_UCHAR);
429    ELM_CONFIG_VAL(D, T, scroll_animation_disable, T_UCHAR);
430    ELM_CONFIG_VAL(D, T, scroll_accel_factor, T_DOUBLE);
431 //   ELM_CONFIG_VAL(D, T, scroll_smooth_time_interval, T_DOUBLE); // not used anymore
432    ELM_CONFIG_VAL(D, T, scroll_smooth_amount, T_DOUBLE);
433 //   ELM_CONFIG_VAL(D, T, scroll_smooth_history_weight, T_DOUBLE); // not used anymore
434 //   ELM_CONFIG_VAL(D, T, scroll_smooth_future_time, T_DOUBLE); // not used anymore
435    ELM_CONFIG_VAL(D, T, scroll_smooth_time_window, T_DOUBLE);
436    ELM_CONFIG_VAL(D, T, scale, T_DOUBLE);
437    ELM_CONFIG_VAL(D, T, bgpixmap, T_INT);
438    ELM_CONFIG_VAL(D, T, compositing, T_INT);
439    /* EET_DATA_DESCRIPTOR_ADD_LIST(D, T, "font_dirs", font_dirs, sub_edd); */
440    ELM_CONFIG_LIST(D, T, font_overlays, _config_font_overlay_edd);
441    ELM_CONFIG_VAL(D, T, font_hinting, T_INT);
442    ELM_CONFIG_VAL(D, T, cache_flush_poll_interval, T_INT);
443    ELM_CONFIG_VAL(D, T, cache_flush_enable, T_UCHAR);
444    ELM_CONFIG_VAL(D, T, image_cache, T_INT);
445    ELM_CONFIG_VAL(D, T, font_cache, T_INT);
446    ELM_CONFIG_VAL(D, T, edje_cache, T_INT);
447    ELM_CONFIG_VAL(D, T, edje_collection_cache, T_INT);
448    ELM_CONFIG_VAL(D, T, finger_size, T_INT);
449    ELM_CONFIG_VAL(D, T, fps, T_DOUBLE);
450    ELM_CONFIG_VAL(D, T, theme, T_STRING);
451    ELM_CONFIG_VAL(D, T, modules, T_STRING);
452    ELM_CONFIG_VAL(D, T, tooltip_delay, T_DOUBLE);
453    ELM_CONFIG_VAL(D, T, cursor_engine_only, T_UCHAR);
454    ELM_CONFIG_VAL(D, T, focus_highlight_enable, T_UCHAR);
455    ELM_CONFIG_VAL(D, T, focus_highlight_animate, T_UCHAR);
456    ELM_CONFIG_VAL(D, T, focus_highlight_clip_disable, T_UCHAR);
457    ELM_CONFIG_VAL(D, T, focus_move_policy, T_UCHAR);
458    ELM_CONFIG_VAL(D, T, focus_autoscroll_mode, T_UCHAR);
459    ELM_CONFIG_VAL(D, T, context_menu_disabled, T_UCHAR);
460    ELM_CONFIG_VAL(D, T, slider_indicator_visible_mode, T_INT);
461    ELM_CONFIG_VAL(D, T, item_select_on_focus_disable, T_UCHAR);
462    ELM_CONFIG_VAL(D, T, first_item_focus_on_first_focus_in, T_UCHAR);
463    ELM_CONFIG_VAL(D, T, toolbar_shrink_mode, T_INT);
464    ELM_CONFIG_VAL(D, T, fileselector_expand_enable, T_UCHAR);
465    ELM_CONFIG_VAL(D, T, fileselector_double_tap_navigation_enable, T_UCHAR);
466    ELM_CONFIG_VAL(D, T, inwin_dialogs_enable, T_UCHAR);
467    ELM_CONFIG_VAL(D, T, icon_size, T_INT);
468    ELM_CONFIG_VAL(D, T, longpress_timeout, T_DOUBLE);
469    ELM_CONFIG_VAL(D, T, effect_enable, T_UCHAR);
470    ELM_CONFIG_VAL(D, T, desktop_entry, T_UCHAR);
471    ELM_CONFIG_VAL(D, T, password_show_last, T_UCHAR);
472    ELM_CONFIG_VAL(D, T, password_show_last_timeout, T_DOUBLE);
473    ELM_CONFIG_VAL(D, T, glayer_zoom_finger_enable, T_UCHAR);
474    ELM_CONFIG_VAL(D, T, glayer_zoom_finger_factor, T_DOUBLE);
475    ELM_CONFIG_VAL(D, T, glayer_zoom_wheel_factor, T_DOUBLE);
476    ELM_CONFIG_VAL(D, T, glayer_zoom_distance_tolerance, T_DOUBLE);
477    ELM_CONFIG_VAL(D, T, glayer_rotate_finger_enable, T_UCHAR);
478    ELM_CONFIG_VAL(D, T, glayer_rotate_angular_tolerance, T_DOUBLE);
479    ELM_CONFIG_VAL(D, T, glayer_line_min_length, T_DOUBLE);
480    ELM_CONFIG_VAL(D, T, glayer_line_distance_tolerance, T_DOUBLE);
481    ELM_CONFIG_VAL(D, T, glayer_line_angular_tolerance, T_DOUBLE);
482    ELM_CONFIG_VAL(D, T, glayer_flick_time_limit_ms, T_INT);
483    ELM_CONFIG_VAL(D, T, glayer_long_tap_start_timeout, T_DOUBLE);
484    ELM_CONFIG_VAL(D, T, glayer_double_tap_timeout, T_DOUBLE);
485    ELM_CONFIG_VAL(D, T, glayer_tap_finger_size, T_INT);
486    ELM_CONFIG_VAL(D, T, access_mode, T_UCHAR);
487    ELM_CONFIG_VAL(D, T, selection_clear_enable, T_UCHAR);
488    ELM_CONFIG_VAL(D, T, glayer_continues_enable, T_UCHAR);
489    ELM_CONFIG_VAL(D, T, week_start, T_INT);
490    ELM_CONFIG_VAL(D, T, weekend_start, T_INT);
491    ELM_CONFIG_VAL(D, T, weekend_len, T_INT);
492    ELM_CONFIG_VAL(D, T, year_min, T_INT);
493    ELM_CONFIG_VAL(D, T, year_max, T_INT);
494    ELM_CONFIG_LIST(D, T, color_overlays, _config_color_overlay_edd);
495    ELM_CONFIG_LIST(D, T, color_palette, _config_color_palette_edd);
496    ELM_CONFIG_VAL(D, T, softcursor_mode, T_UCHAR);
497    ELM_CONFIG_VAL(D, T, auto_norender_withdrawn, T_UCHAR);
498    ELM_CONFIG_VAL(D, T, auto_norender_iconified_same_as_withdrawn, T_UCHAR);
499    ELM_CONFIG_VAL(D, T, auto_flush_withdrawn, T_UCHAR);
500    ELM_CONFIG_VAL(D, T, auto_dump_withdrawn, T_UCHAR);
501    ELM_CONFIG_VAL(D, T, auto_throttle, T_UCHAR);
502    ELM_CONFIG_VAL(D, T, auto_throttle_amount, T_DOUBLE);
503    ELM_CONFIG_VAL(D, T, indicator_service_0, T_STRING);
504    ELM_CONFIG_VAL(D, T, indicator_service_90, T_STRING);
505    ELM_CONFIG_VAL(D, T, indicator_service_180, T_STRING);
506    ELM_CONFIG_VAL(D, T, indicator_service_270, T_STRING);
507    ELM_CONFIG_VAL(D, T, disable_external_menu, T_UCHAR);
508    ELM_CONFIG_VAL(D, T, clouseau_enable, T_UCHAR);
509    ELM_CONFIG_VAL(D, T, magnifier_enable, T_UCHAR);
510    ELM_CONFIG_VAL(D, T, magnifier_scale, T_DOUBLE);
511    ELM_CONFIG_VAL(D, T, audio_mute_effect, T_UCHAR);
512    ELM_CONFIG_VAL(D, T, audio_mute_background, T_UCHAR);
513    ELM_CONFIG_VAL(D, T, audio_mute_music, T_UCHAR);
514    ELM_CONFIG_VAL(D, T, audio_mute_foreground, T_UCHAR);
515    ELM_CONFIG_VAL(D, T, audio_mute_interface, T_UCHAR);
516    ELM_CONFIG_VAL(D, T, audio_mute_input, T_UCHAR);
517    ELM_CONFIG_VAL(D, T, audio_mute_alert, T_UCHAR);
518    ELM_CONFIG_VAL(D, T, audio_mute_all, T_UCHAR);
519    ELM_CONFIG_LIST(D, T, bindings, _config_bindings_widget_edd);
520    ELM_CONFIG_VAL(D, T, atspi_mode, T_UCHAR);
521    ELM_CONFIG_VAL(D, T, win_auto_focus_enable, T_UCHAR);
522    ELM_CONFIG_VAL(D, T, win_auto_focus_animate, T_UCHAR);
523    ELM_CONFIG_VAL(D, T, transition_duration_factor, T_DOUBLE);
524    ELM_CONFIG_VAL(D, T, naviframe_prev_btn_auto_pushed, T_UCHAR);
525    ELM_CONFIG_VAL(D, T, popup_horizontal_align, T_DOUBLE);
526    ELM_CONFIG_VAL(D, T, popup_vertical_align, T_DOUBLE);
527    ELM_CONFIG_VAL(D, T, popup_scrollable, T_UCHAR);
528    ELM_CONFIG_VAL(D, T, spinner_min_max_filter_enable, T_UCHAR);
529    ELM_CONFIG_VAL(D, T, icon_theme, T_STRING);
530    ELM_CONFIG_VAL(D, T, entry_select_allow, T_UCHAR);
531    ELM_CONFIG_VAL(D, T, offline, T_UCHAR);
532    ELM_CONFIG_VAL(D, T, powersave, T_INT);
533    ELM_CONFIG_VAL(D, T, drag_anim_duration, T_DOUBLE);
534    ELM_CONFIG_VAL(D, T, win_no_border, T_UCHAR);
535 #undef T
536 #undef D
537 #undef T_INT
538 #undef T_DOUBLE
539 #undef T_STRING
540 #undef T_UCHAR
541 }
542 
543 static void
_desc_shutdown(void)544 _desc_shutdown(void)
545 {
546    if (_config_edd)
547      {
548         eet_data_descriptor_free(_config_edd);
549         _config_edd = NULL;
550      }
551 
552    if (_config_font_overlay_edd)
553      {
554         eet_data_descriptor_free(_config_font_overlay_edd);
555         _config_font_overlay_edd = NULL;
556      }
557 
558    if (_config_color_edd)
559      {
560         eet_data_descriptor_free(_config_color_edd);
561         _config_color_edd = NULL;
562      }
563 
564    if (_config_color_palette_edd)
565      {
566         eet_data_descriptor_free(_config_color_palette_edd);
567         _config_color_palette_edd = NULL;
568      }
569 
570    if (_config_color_overlay_edd)
571      {
572         eet_data_descriptor_free(_config_color_overlay_edd);
573         _config_color_overlay_edd = NULL;
574      }
575 
576    if (_config_bindings_widget_edd)
577      {
578         eet_data_descriptor_free(_config_bindings_widget_edd);
579         _config_bindings_widget_edd = NULL;
580      }
581 
582    if (_config_binding_key_edd)
583      {
584         eet_data_descriptor_free(_config_binding_key_edd);
585         _config_binding_key_edd = NULL;
586      }
587 
588    if (_config_binding_modifier_edd)
589      {
590         eet_data_descriptor_free(_config_binding_modifier_edd);
591         _config_binding_modifier_edd = NULL;
592      }
593 }
594 
595 static int
_sort_files_cb(const void * f1,const void * f2)596 _sort_files_cb(const void *f1,
597                const void *f2)
598 {
599    return strcmp(f1, f2);
600 }
601 
602 const char *
_elm_config_current_profile_get(void)603 _elm_config_current_profile_get(void)
604 {
605    return _elm_profile;
606 }
607 
608 static size_t
_elm_data_dir_snprintf(char * dst,size_t size,const char * fmt,...)609 _elm_data_dir_snprintf(char       *dst,
610                        size_t      size,
611                        const char *fmt,
612                        ...)
613 {
614    size_t data_dir_len, off;
615    va_list ap;
616 
617    data_dir_len = eina_strlcpy(dst, _elm_data_dir, size);
618 
619    off = data_dir_len + 1;
620    if (off >= size)
621      goto end;
622 
623    va_start(ap, fmt);
624    dst[data_dir_len] = '/';
625 
626    off = off + vsnprintf(dst + off, size - off, fmt, ap);
627    va_end(ap);
628 
629 end:
630    return off;
631 }
632 
633 static Eina_Hash *_getenv_once_envs = NULL;
634 static const char *_getenv_once_empty = "";
635 
636 static const char *
_getenv_once(const char * env)637 _getenv_once(const char *env)
638 {
639    const char *s;
640 
641    if (_getenv_once_envs)
642      {
643         s = eina_hash_find(_getenv_once_envs, env);
644         if (s == _getenv_once_empty) return NULL;
645         if (s) return s;
646      }
647    else _getenv_once_envs = eina_hash_string_superfast_new(NULL);
648    s = getenv(env);
649    if (s)
650      {
651         s = eina_stringshare_add(s);
652         eina_hash_add(_getenv_once_envs, env, s);
653         return s;
654      }
655    else
656      {
657         eina_hash_add(_getenv_once_envs, env, _getenv_once_empty);
658      }
659    return NULL;
660 }
661 
662 size_t
_elm_config_user_dir_snprintf(char * dst,size_t size,const char * fmt,...)663 _elm_config_user_dir_snprintf(char       *dst,
664                               size_t      size,
665                               const char *fmt,
666                               ...)
667 {
668    size_t user_dir_len = 0, off = 0;
669    va_list ap;
670    char *tmp;
671    static int use_xdg_config = -1;
672 
673    if (use_xdg_config == -1)
674      {
675         if (_getenv_once("ELM_CONFIG_DIR_XDG")) use_xdg_config = 1;
676         else use_xdg_config = 0;
677      }
678    if (use_xdg_config)
679      tmp = eina_vpath_resolve("(:usr.config:)/elementary");
680    else
681      tmp = eina_vpath_resolve("(:home:)/" ELEMENTARY_BASE_DIR);
682 
683    eina_strlcpy(dst, tmp, size);
684    free(tmp);
685 
686    user_dir_len = strlen(dst);
687    off = user_dir_len + 1;
688    if (off >= size) return off;
689    dst[user_dir_len] = '/';
690    va_start(ap, fmt);
691    off = off + vsnprintf(dst + off, size - off, fmt, ap);
692    va_end(ap);
693    return off;
694 }
695 
696 typedef struct _Elm_Config_Derived          Elm_Config_Derived;
697 typedef struct _Elm_Config_Derived_Profile  Elm_Config_Derived_Profile;
698 
699 struct _Elm_Config_Derived
700 {
701    Eina_List *profiles;
702 };
703 
704 struct _Elm_Config_Derived_Profile
705 {
706    const char *profile;
707    const char *derive_options;
708 };
709 
710 static Eet_Data_Descriptor *_config_derived_edd = NULL;
711 static Eet_Data_Descriptor *_config_derived_profile_edd = NULL;
712 
713 static void
_elm_config_profile_derived_init(void)714 _elm_config_profile_derived_init(void)
715 {
716    Eet_Data_Descriptor_Class eddc;
717 
718    EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Elm_Config_Derived);
719    eddc.func.str_direct_alloc = NULL;
720    eddc.func.str_direct_free = NULL;
721    _config_derived_edd = eet_data_descriptor_file_new(&eddc);
722 
723    memset(&eddc, 0, sizeof(eddc)); /* just in case... */
724    EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Elm_Config_Derived_Profile);
725    eddc.func.str_direct_alloc = NULL;
726    eddc.func.str_direct_free = NULL;
727    _config_derived_profile_edd = eet_data_descriptor_file_new(&eddc);
728 
729 #define T        Elm_Config_Derived_Profile
730 #define D        _config_derived_profile_edd
731    ELM_CONFIG_VAL(D, T, profile, EET_T_STRING);
732    ELM_CONFIG_VAL(D, T, derive_options, EET_T_STRING);
733 #undef T
734 #undef D
735 
736 #define T        Elm_Config_Derived
737 #define D        _config_derived_edd
738    ELM_CONFIG_LIST(D, T, profiles, _config_derived_profile_edd);
739 #undef T
740 #undef D
741 }
742 
743 static void
_elm_config_profile_derived_shutdown(void)744 _elm_config_profile_derived_shutdown(void)
745 {
746    if (_config_derived_profile_edd)
747      {
748         eet_data_descriptor_free(_config_derived_profile_edd);
749         _config_derived_profile_edd = NULL;
750      }
751    if (_config_derived_edd)
752      {
753         eet_data_descriptor_free(_config_derived_edd);
754         _config_derived_edd = NULL;
755      }
756 }
757 
758 static Elm_Config_Derived *
_elm_config_derived_load(const char * profile)759 _elm_config_derived_load(const char *profile)
760 {
761    char buf[PATH_MAX];
762    Eet_File *ef;
763    Elm_Config_Derived *derived;
764 
765    if (!profile) profile = _elm_profile;
766    _elm_config_user_dir_snprintf(buf, sizeof(buf), "config/%s/derived.cfg",
767                                  profile);
768    ef = eet_open(buf, EET_FILE_MODE_READ);
769    if (ef)
770      {
771         derived = eet_data_read(ef, _config_derived_edd, "config");
772         eet_close(ef);
773         if (derived) return derived;
774      }
775    snprintf(buf, sizeof(buf), "%s/config/%s/derived.cfg",
776             _elm_data_dir, profile);
777    ef = eet_open(buf, EET_FILE_MODE_READ);
778    if (ef)
779      {
780         derived = eet_data_read(ef, _config_derived_edd, "config");
781         eet_close(ef);
782         if (derived) return derived;
783      }
784    return NULL;
785 }
786 
787 static void
_elm_config_profile_derived_save(const char * profile,Elm_Config_Derived * derived)788 _elm_config_profile_derived_save(const char *profile, Elm_Config_Derived *derived)
789 {
790    Eet_File *ef;
791    char buf[PATH_MAX], buf2[PATH_MAX];
792    int ret;
793 
794    _elm_config_user_dir_snprintf(buf, sizeof(buf), "config/%s",
795                                  profile ? profile : _elm_profile);
796    ecore_file_mkpath(buf);
797    _elm_config_user_dir_snprintf(buf, sizeof(buf), "config/%s/derived.cfg.tmp",
798                                  profile ? profile : _elm_profile);
799    _elm_config_user_dir_snprintf(buf2, sizeof(buf2), "config/%s/derived.cfg",
800                                  profile ? profile : _elm_profile);
801    ef = eet_open(buf, EET_FILE_MODE_WRITE);
802    if (ef)
803      {
804         ret = eet_data_write(ef, _config_derived_edd, "config", derived, 1);
805         eet_close(ef);
806         if (ret)
807           {
808              if (!ecore_file_mv(buf, buf2))
809                {
810                   ERR("Error saving Elementary's derived configuration profile file");
811                   ecore_file_unlink(buf);
812                }
813           }
814         else
815           {
816              ERR("Error saving Elementary's derived configuration profile file");
817           }
818      }
819 }
820 
821 static void
_elm_config_derived_free(Elm_Config_Derived * derived)822 _elm_config_derived_free(Elm_Config_Derived *derived)
823 {
824    Elm_Config_Derived_Profile *dp;
825 
826    if (!derived) return;
827    EINA_LIST_FREE(derived->profiles, dp)
828      {
829         eina_stringshare_del(dp->profile);
830         eina_stringshare_del(dp->derive_options);
831         free(dp);
832      }
833    free(derived);
834 }
835 
836 static void
_elm_config_derived_option_op_apply(Elm_Config * cfg,const char * op,const char * params)837 _elm_config_derived_option_op_apply(Elm_Config *cfg, const char *op, const char *params)
838 {
839    if (!strcmp(op, "scale-mul"))
840      {
841         int multiplier = atoi(params);
842         if (multiplier > 0)
843           {
844              cfg->scale = cfg->scale * (((double)multiplier) / 100.0);
845           }
846      }
847    // Add more derivation commands here
848 }
849 
850 static void
_elm_config_derived_option_apply(Elm_Config * cfg,const char * option)851 _elm_config_derived_option_apply(Elm_Config *cfg, const char *option)
852 {
853    const char *p;
854    char *buf = alloca(strlen(option) + 1);
855    char *bp = buf;
856 
857    p = option;
858    for (;;)
859      {
860         if ((*p == 0) || (*p == ' '))
861           {
862              if (*p == ' ') p++;
863              *bp = 0;
864              _elm_config_derived_option_op_apply(cfg, buf, p);
865              return;
866           }
867         else
868           {
869              *bp = *p;
870              bp++;
871           }
872         if (*p == 0) break;
873         p++;
874      }
875 }
876 
877 static void
_elm_config_derived_apply(Elm_Config * cfg,const char * derive_options)878 _elm_config_derived_apply(Elm_Config *cfg, const char *derive_options)
879 {
880    // derive_options = "option1 param param2 ...; option2 param1 ..."
881    const char *p;
882    char *buf = alloca(strlen(derive_options) + 1);
883    char *bp = buf;
884 
885    p = derive_options;
886    for (;;)
887      {
888         if ((*p == 0) || (*p == ';'))
889           {
890              if (*p == ';') p++;
891              *bp = 0;
892              _elm_config_derived_option_apply(cfg, buf);
893              bp = buf;
894           }
895         else
896           {
897              *bp = *p;
898              bp++;
899           }
900         if (*p == 0) break;
901         p++;
902      }
903 }
904 
905 static void
_elm_config_derived_save(Elm_Config * cfg,Elm_Config_Derived * derived)906 _elm_config_derived_save(Elm_Config *cfg, Elm_Config_Derived *derived)
907 {
908    Elm_Config_Derived_Profile *dp;
909    Eina_List *l;
910 
911    if (!derived) return;
912    EINA_LIST_FOREACH(derived->profiles, l, dp)
913      {
914         if ((dp->profile) && (dp->derive_options))
915           {
916              Elm_Config *cfg2;
917 
918              cfg2 = malloc(sizeof(Elm_Config));
919              if (cfg2)
920                {
921                   memcpy(cfg2, cfg, sizeof(Elm_Config));
922                   _elm_config_derived_apply(cfg2, dp->derive_options);
923                   _elm_config_save(cfg2, dp->profile);
924                   free(cfg2);
925                }
926           }
927      }
928 }
929 
930 EAPI void
elm_config_profile_derived_add(const char * profile,const char * derive_options)931 elm_config_profile_derived_add(const char *profile, const char *derive_options)
932 {
933    Elm_Config_Derived *derived;
934 
935    derived = _elm_config_derived_load(_elm_profile);
936    if (!derived) derived = calloc(1, sizeof(Elm_Config_Derived));
937    if (derived)
938      {
939         Elm_Config_Derived_Profile *dp = calloc(1, sizeof(Elm_Config_Derived_Profile));
940 
941         if (dp)
942           {
943              dp->profile = eina_stringshare_add(profile);
944              dp->derive_options = eina_stringshare_add(derive_options);
945              derived->profiles = eina_list_append(derived->profiles, dp);
946              _elm_config_profile_derived_save(_elm_profile, derived);
947              _elm_config_derived_save(_elm_config, derived);
948           }
949         _elm_config_derived_free(derived);
950      }
951 }
952 
953 EAPI void
elm_config_profile_derived_del(const char * profile)954 elm_config_profile_derived_del(const char *profile)
955 {
956    Elm_Config_Derived *derived;
957    Elm_Config_Derived_Profile *dp;
958    Eina_List *l;
959 
960    if (!profile) return;
961    derived = _elm_config_derived_load(_elm_profile);
962    if (derived)
963      {
964         EINA_LIST_FOREACH(derived->profiles, l, dp)
965           {
966              if ((dp->profile) && (!strcmp(dp->profile, profile)))
967                {
968                   char buf[PATH_MAX];
969 
970                   _elm_config_user_dir_snprintf(buf, sizeof(buf), "config/%s",
971                                                 profile);
972                   ecore_file_recursive_rm(buf);
973                   derived->profiles = eina_list_remove_list(derived->profiles, l);
974                   eina_stringshare_del(dp->profile);
975                   eina_stringshare_del(dp->derive_options);
976                   free(dp);
977                   _elm_config_profile_derived_save(_elm_profile, derived);
978                   _elm_config_derived_free(derived);
979                   return;
980                }
981           }
982         _elm_config_derived_free(derived);
983      }
984 }
985 
986 const char *
_elm_config_profile_dir_get(const char * prof,Eina_Bool is_user)987 _elm_config_profile_dir_get(const char *prof,
988                             Eina_Bool   is_user)
989 {
990    char buf[PATH_MAX];
991 
992    if (!is_user)
993      goto not_user;
994 
995    if ((!_running_in_tree) || (!bs_data_path_get(buf, sizeof(buf), "elementary/config", prof)))
996      _elm_config_user_dir_snprintf(buf, sizeof(buf), "config/%s", prof);
997 
998    // See elm_config_profile_dir_free: always use strdup+free
999    if (ecore_file_is_dir(buf))
1000      return strdup(buf);
1001 
1002    return NULL;
1003 
1004 not_user:
1005    if ((!_running_in_tree) || (!bs_data_path_get(buf, sizeof(buf), "elementary/config", prof)))
1006      snprintf(buf, sizeof(buf), "%s/config/%s", _elm_data_dir, prof);
1007 
1008    // See elm_config_profile_dir_free: always use strdup+free
1009    if (ecore_file_is_dir(buf))
1010      return strdup(buf);
1011 
1012    return NULL;
1013 }
1014 
1015 Eina_List *
_elm_config_font_overlays_list(void)1016 _elm_config_font_overlays_list(void)
1017 {
1018    return _elm_config->font_overlays;
1019 }
1020 
_elm_config_access_get(void)1021 Eina_Bool _elm_config_access_get(void)
1022 {
1023    return _elm_config->access_mode;
1024 }
1025 
_elm_config_access_set(Eina_Bool is_access)1026 void _elm_config_access_set(Eina_Bool is_access)
1027 {
1028    is_access = !!is_access;
1029    if (_elm_config->access_mode == is_access) return;
1030    _elm_config->access_mode = is_access;
1031    _elm_win_access(is_access);
1032 
1033    if (!is_access) _elm_access_shutdown();
1034 }
1035 
_elm_config_atspi_mode_get(void)1036 static Eina_Bool _elm_config_atspi_mode_get(void)
1037 {
1038    return _elm_config->atspi_mode;
1039 }
1040 
_elm_config_atspi_mode_set(Eina_Bool is_enabled)1041 static void _elm_config_atspi_mode_set(Eina_Bool is_enabled)
1042 {
1043    _elm_config->priv.atspi_mode = EINA_TRUE;
1044    is_enabled = !!is_enabled;
1045    if (_elm_config->atspi_mode == is_enabled) return;
1046    _elm_config->atspi_mode = is_enabled;
1047 
1048    if (!is_enabled) _elm_atspi_bridge_shutdown();
1049    else _elm_atspi_bridge_init();
1050 }
1051 
_elm_config_selection_unfocused_clear_get(void)1052 static Eina_Bool _elm_config_selection_unfocused_clear_get(void)
1053 {
1054    return _elm_config->selection_clear_enable;
1055 }
1056 
_elm_config_selection_unfocused_clear_set(Eina_Bool enabled)1057 static void _elm_config_selection_unfocused_clear_set(Eina_Bool enabled)
1058 {
1059    enabled = !!enabled;
1060    if (_elm_config->selection_clear_enable == enabled) return;
1061    _elm_config->selection_clear_enable = enabled;
1062 }
1063 
1064 void
_elm_config_font_overlay_set(const char * text_class,const char * font,Evas_Font_Size size)1065 _elm_config_font_overlay_set(const char    *text_class,
1066                              const char    *font,
1067                              Evas_Font_Size size)
1068 {
1069    Elm_Font_Overlay *efd;
1070    Eina_List *l;
1071 
1072    EINA_LIST_FOREACH(_elm_config->font_overlays, l, efd)
1073      {
1074         if (strcmp(efd->text_class, text_class))
1075           continue;
1076 
1077         eina_stringshare_del(efd->font);
1078         efd->font = eina_stringshare_add(font);
1079         efd->size = size;
1080         _elm_config->font_overlays =
1081           eina_list_promote_list(_elm_config->font_overlays, l);
1082         return;
1083      }
1084 
1085    /* the text class doesn't exist */
1086    efd = calloc(1, sizeof(Elm_Font_Overlay));
1087    if (!efd) return;
1088    efd->text_class = eina_stringshare_add(text_class);
1089    efd->font = eina_stringshare_add(font);
1090    efd->size = size;
1091 
1092    _elm_config->font_overlays = eina_list_prepend(_elm_config->font_overlays,
1093                                                   efd);
1094 }
1095 
1096 void
_elm_config_font_overlay_remove(const char * text_class)1097 _elm_config_font_overlay_remove(const char *text_class)
1098 {
1099    Elm_Font_Overlay *efd;
1100    Eina_List *l;
1101 
1102    EINA_LIST_FOREACH(_elm_config->font_overlays, l, efd)
1103      {
1104         if (!efd->text_class) continue;
1105         if (strcmp(efd->text_class, text_class)) continue;
1106 
1107         _font_overlays_del =
1108            eina_list_append(_font_overlays_del,
1109                             eina_stringshare_add(text_class));
1110         _elm_config->font_overlays =
1111           eina_list_remove_list(_elm_config->font_overlays, l);
1112         eina_stringshare_del(efd->text_class);
1113         eina_stringshare_del(efd->font);
1114         free(efd);
1115 
1116         return;
1117      }
1118 }
1119 
1120 void
_elm_config_font_overlay_apply(void)1121 _elm_config_font_overlay_apply(void)
1122 {
1123    Elm_Font_Overlay *efd;
1124    Eina_List *l;
1125    char *text_class;
1126    EINA_LIST_FOREACH(_font_overlays_del, l, text_class)
1127      {
1128         edje_text_class_del(text_class);
1129         eina_stringshare_del(text_class);
1130      }
1131    _font_overlays_del = eina_list_free(_font_overlays_del);
1132 
1133    EINA_LIST_FOREACH(_elm_config->font_overlays, l, efd)
1134      edje_text_class_set(efd->text_class, efd->font, efd->size);
1135 }
1136 
1137 Eina_List *
_elm_config_text_classes_get(void)1138 _elm_config_text_classes_get(void)
1139 {
1140    Eina_List *ret = NULL;
1141    int i;
1142 
1143    for (i = 0; _elm_text_classes[i].desc; i++)
1144      {
1145         Elm_Text_Class *tc;
1146         tc = malloc(sizeof(*tc));
1147         if (!tc) continue;
1148 
1149         *tc = _elm_text_classes[i];
1150 
1151         ret = eina_list_append(ret, tc);
1152      }
1153 
1154    return ret;
1155 }
1156 
1157 void
_elm_config_text_classes_free(Eina_List * l)1158 _elm_config_text_classes_free(Eina_List *l)
1159 {
1160    Elm_Text_Class *tc;
1161 
1162    EINA_LIST_FREE(l, tc)
1163      free(tc);
1164 }
1165 
1166 Eina_List *
_elm_config_color_classes_get(void)1167 _elm_config_color_classes_get(void)
1168 {
1169    Eina_List *ret = NULL;
1170    int i;
1171 
1172    for (i = 0; _elm_color_classes[i].desc; i++)
1173      {
1174         Elm_Color_Class *cc;
1175         cc = malloc(sizeof(*cc));
1176         if (!cc) continue;
1177 
1178         *cc = _elm_color_classes[i];
1179 
1180         ret = eina_list_append(ret, cc);
1181      }
1182 
1183    return ret;
1184 }
1185 
1186 void
_elm_config_color_classes_free(Eina_List * l)1187 _elm_config_color_classes_free(Eina_List *l)
1188 {
1189    Elm_Color_Class *cc;
1190 
1191    EINA_LIST_FREE(l, cc)
1192      free(cc);
1193 }
1194 
1195 static void
_color_overlays_cancel(void)1196 _color_overlays_cancel(void)
1197 {
1198    Elm_Color_Overlay *ecd;
1199    Eina_List *l;
1200    EINA_LIST_FOREACH(_elm_config->color_overlays, l, ecd)
1201      edje_color_class_del(ecd->color_class);
1202 }
1203 
1204 Eina_List *
_elm_config_color_overlays_list(void)1205 _elm_config_color_overlays_list(void)
1206 {
1207    return _elm_config->color_overlays;
1208 }
1209 
1210 void
_elm_config_color_overlay_set(const char * color_class,int r,int g,int b,int a,int r2,int g2,int b2,int a2,int r3,int g3,int b3,int a3)1211 _elm_config_color_overlay_set(const char *color_class,
1212                               int r, int g, int b, int a,
1213                               int r2, int g2, int b2, int a2,
1214                               int r3, int g3, int b3, int a3)
1215 {
1216    Elm_Color_Overlay *ecd;
1217    Eina_List *l;
1218 
1219 #define CHECK_COLOR_VAL(v) v = (v > 255)? 255 : (v < 0)? 0: v
1220    CHECK_COLOR_VAL(r);
1221    CHECK_COLOR_VAL(g);
1222    CHECK_COLOR_VAL(b);
1223    CHECK_COLOR_VAL(a);
1224    CHECK_COLOR_VAL(r2);
1225    CHECK_COLOR_VAL(g2);
1226    CHECK_COLOR_VAL(b2);
1227    CHECK_COLOR_VAL(a2);
1228    CHECK_COLOR_VAL(r3);
1229    CHECK_COLOR_VAL(g3);
1230    CHECK_COLOR_VAL(b3);
1231    CHECK_COLOR_VAL(a3);
1232 #undef CHECK_COLOR_VAL
1233 
1234    EINA_LIST_FOREACH(_elm_config->color_overlays, l, ecd)
1235      {
1236         if (!eina_streq(ecd->color_class, color_class))
1237           continue;
1238 
1239         ecd->color.r = r;
1240         ecd->color.g = g;
1241         ecd->color.b = b;
1242         ecd->color.a = a;
1243         ecd->outline.r = r2;
1244         ecd->outline.g = g2;
1245         ecd->outline.b = b2;
1246         ecd->outline.a = a2;
1247         ecd->shadow.r = r3;
1248         ecd->shadow.g = g3;
1249         ecd->shadow.b = b3;
1250         ecd->shadow.a = a3;
1251 
1252         _elm_config->color_overlays =
1253            eina_list_promote_list(_elm_config->color_overlays, l);
1254         return;
1255      }
1256 
1257    /* the color class doesn't exist */
1258    ecd = calloc(1, sizeof(Elm_Color_Overlay));
1259    if (!ecd) return;
1260 
1261    ecd->color_class = eina_stringshare_add(color_class);
1262    ecd->color.r = r;
1263    ecd->color.g = g;
1264    ecd->color.b = b;
1265    ecd->color.a = a;
1266    ecd->outline.r = r2;
1267    ecd->outline.g = g2;
1268    ecd->outline.b = b2;
1269    ecd->outline.a = a2;
1270    ecd->shadow.r = r3;
1271    ecd->shadow.g = g3;
1272    ecd->shadow.b = b3;
1273    ecd->shadow.a = a3;
1274 
1275    _elm_config->color_overlays =
1276       eina_list_prepend(_elm_config->color_overlays, ecd);
1277 }
1278 
1279 void
_elm_config_color_overlay_remove(const char * color_class)1280 _elm_config_color_overlay_remove(const char *color_class)
1281 {
1282    Elm_Color_Overlay *ecd;
1283    Eina_List *l;
1284 
1285    EINA_LIST_FOREACH(_elm_config->color_overlays, l, ecd)
1286      {
1287         if (!ecd->color_class) continue;
1288         if (!eina_streq(ecd->color_class, color_class)) continue;
1289 
1290         _color_overlays_del =
1291            eina_list_append(_color_overlays_del,
1292                             eina_stringshare_add(color_class));
1293         _elm_config->color_overlays =
1294           eina_list_remove_list(_elm_config->color_overlays, l);
1295         eina_stringshare_del(ecd->color_class);
1296         free(ecd);
1297 
1298         return;
1299      }
1300 }
1301 
1302 void
_elm_config_color_overlay_apply(void)1303 _elm_config_color_overlay_apply(void)
1304 {
1305    Elm_Color_Overlay *ecd;
1306    Eina_List *l;
1307    char *color_class;
1308 
1309    EINA_LIST_FREE(_color_overlays_del, color_class)
1310      {
1311         edje_color_class_del(color_class);
1312         eina_stringshare_del(color_class);
1313      }
1314 
1315    EINA_LIST_FOREACH(_elm_config->color_overlays, l, ecd)
1316      edje_color_class_set(ecd->color_class,
1317                 ecd->color.r, ecd->color.g, ecd->color.b, ecd->color.a,
1318                 ecd->outline.r, ecd->outline.g, ecd->outline.b, ecd->outline.a,
1319                 ecd->shadow.r, ecd->shadow.g, ecd->shadow.b, ecd->shadow.a);
1320 }
1321 
1322 Eina_List *
_elm_config_color_list_get(const char * palette_name)1323 _elm_config_color_list_get(const char *palette_name)
1324 {
1325     Eina_List *plist;
1326     Elm_Custom_Palette *cpalette;
1327     EINA_LIST_FOREACH(_elm_config->color_palette, plist, cpalette)
1328       {
1329          if (strcmp(cpalette->palette_name, palette_name))
1330            continue;
1331          return cpalette->color_list;
1332       }
1333     return NULL;
1334 }
1335 
1336 void
_elm_config_color_set(const char * palette_name,int r,int g,int b,int a)1337 _elm_config_color_set(const char *palette_name,
1338                       int r,
1339                       int g,
1340                       int b,
1341                       int a)
1342 {
1343    Eina_List *plist;
1344    Elm_Custom_Palette *cpalette;
1345    Elm_Color_RGBA *color;
1346    EINA_LIST_FOREACH(_elm_config->color_palette, plist, cpalette)
1347      {
1348         if (strcmp(cpalette->palette_name, palette_name))
1349           continue;
1350 
1351         color = calloc(1, sizeof(Elm_Color_RGBA));
1352         if (!color) continue;
1353         color->r = r;
1354         color->g = g;
1355         color->b = b;
1356         color->a = a;
1357         cpalette->color_list = eina_list_prepend(cpalette->color_list,
1358                                                        color);
1359      }
1360 }
1361 
1362 void
_elm_config_colors_free(const char * palette_name)1363 _elm_config_colors_free(const char *palette_name)
1364 {
1365    Eina_List *plist;
1366    Elm_Custom_Palette *cpalette;
1367    Elm_Color_RGBA *color;
1368    EINA_LIST_FOREACH(_elm_config->color_palette, plist, cpalette)
1369      {
1370         if (strcmp(cpalette->palette_name, palette_name))
1371           continue;
1372 
1373         EINA_LIST_FREE(cpalette->color_list, color)
1374           {
1375              free(color);
1376           }
1377      }
1378 }
1379 
1380 Eina_List *
_elm_config_profiles_list(Eina_Bool hide_profiles)1381 _elm_config_profiles_list(Eina_Bool hide_profiles)
1382 {
1383    Eina_File_Direct_Info *info;
1384    Eina_List *flist = NULL;
1385    Eina_Iterator *file_it;
1386    char buf[PATH_MAX];
1387    const char *dir;
1388    size_t len = 0;
1389 
1390    if (_running_in_tree)
1391      {
1392         len = bs_data_path_get(buf, sizeof(buf), "elementary", "config");
1393         if (len) len = strlen(buf);
1394      }
1395    if (!len)
1396      len = _elm_config_user_dir_snprintf(buf, sizeof(buf), "config");
1397 
1398    file_it = eina_file_stat_ls(buf);
1399    if (!file_it) goto sys;
1400 
1401    buf[len] = '/';
1402    len++;
1403 
1404    len = sizeof(buf) - len;
1405 
1406    EINA_ITERATOR_FOREACH(file_it, info)
1407      {
1408         if (info->name_length >= len) continue;
1409         if ((hide_profiles) && (info->path[info->name_start] == '.')) continue;
1410 
1411         if (info->type == EINA_FILE_DIR)
1412           {
1413              flist =
1414                eina_list_sorted_insert(flist, _sort_files_cb,
1415                                        eina_stringshare_add
1416                                          (info->path + info->name_start));
1417           }
1418      }
1419 
1420    eina_iterator_free(file_it);
1421 
1422 sys:
1423    len = eina_str_join_len(buf, sizeof(buf), '/', _elm_data_dir,
1424                            strlen(_elm_data_dir), "config",
1425                            sizeof("config") - 1);
1426 
1427    file_it = eina_file_stat_ls(buf);
1428    if (!file_it) goto list_free;
1429 
1430    buf[len] = '/';
1431    len++;
1432 
1433    len = sizeof(buf) - len;
1434    EINA_ITERATOR_FOREACH(file_it, info)
1435      {
1436         if (info->name_length >= len) continue;
1437         if ((hide_profiles) && (info->path[info->name_start] == '.')) continue;
1438 
1439         switch (info->type)
1440           {
1441            case EINA_FILE_DIR:
1442                {
1443                   const Eina_List *l;
1444                   const char *tmp;
1445 
1446                   EINA_LIST_FOREACH(flist, l, tmp)
1447                     {
1448                        if (!strcmp(info->path + info->name_start, tmp)) break;
1449                     }
1450                   if (!l)
1451                     flist = eina_list_sorted_insert(flist, _sort_files_cb,
1452                                                     eina_stringshare_add
1453                                                     (info->path +
1454                                                      info->name_start));
1455                }
1456            break;
1457 
1458            default:
1459              continue;
1460           }
1461      }
1462    eina_iterator_free(file_it);
1463    return flist;
1464 
1465 list_free:
1466    EINA_LIST_FREE(flist, dir) eina_stringshare_del(dir);
1467    return NULL;
1468 }
1469 
1470 static void
_profile_fetch_from_conf(void)1471 _profile_fetch_from_conf(void)
1472 {
1473    char buf[PATH_MAX], *p;
1474    const char *s;
1475    Eet_File *ef = NULL;
1476    int len = 0, i;
1477 
1478    if (_running_in_tree) goto end;
1479    // if env var - use profile without question
1480    s = _getenv_once("ELM_PROFILE");
1481    if (s)
1482      {
1483         _elm_profile = strdup(s);
1484         if (_elm_profile)
1485           {
1486              p = strchr(_elm_profile, '/');
1487              if (p) *p = 0;
1488              p = strchr(_elm_profile, '\\');
1489              if (p) *p = 0;
1490              if (!strcmp(_elm_profile, ".."))
1491                {
1492                   free(_elm_profile);
1493                   _elm_profile = NULL;
1494                }
1495              else return;
1496           }
1497      }
1498 
1499    for (i = 0; i < 2; i++)
1500      {
1501         // user profile
1502         if (i == 0)
1503           _elm_config_user_dir_snprintf(buf, sizeof(buf), "config/profile.cfg");
1504         // system profile
1505         else if (i == 1)
1506           _elm_data_dir_snprintf(buf, sizeof(buf), "config/profile.cfg");
1507         ef = eet_open(buf, EET_FILE_MODE_READ);
1508         if (ef)
1509           {
1510              p = eet_read(ef, "config", &len);
1511              if (p)
1512                {
1513                   _elm_profile = malloc(len + 1);
1514                   if (_elm_profile)
1515                     {
1516                        memcpy(_elm_profile, p, len);
1517                        _elm_profile[len] = 0;
1518                        free(p);
1519                        p = strchr(_elm_profile, '/');
1520                        if (p) *p = 0;
1521                     }
1522                   else free(p);
1523                   eet_close(ef);
1524                   return;
1525                }
1526              eet_close(ef);
1527           }
1528      }
1529 end:
1530    _elm_profile = strdup("default");
1531 }
1532 
1533 static void
_config_free(Elm_Config * cfg)1534 _config_free(Elm_Config *cfg)
1535 {
1536    Elm_Font_Overlay *fo;
1537    const char *fontdir;
1538    Elm_Color_Overlay *co;
1539    Elm_Custom_Palette *palette;
1540    Elm_Color_RGBA *color;
1541    char *color_class;
1542    Elm_Config_Bindings_Widget *wb;
1543    Elm_Config_Binding_Key *kb;
1544    Elm_Config_Binding_Modifier *mb;
1545 
1546    if (!cfg) return;
1547    EINA_LIST_FREE(cfg->font_dirs, fontdir)
1548      {
1549         eina_stringshare_del(fontdir);
1550      }
1551    eina_stringshare_del(cfg->engine);
1552    eina_stringshare_del(cfg->accel);
1553    EINA_LIST_FREE(cfg->font_overlays, fo)
1554      {
1555         eina_stringshare_del(fo->text_class);
1556         eina_stringshare_del(fo->font);
1557         free(fo);
1558      }
1559    EINA_LIST_FREE(_color_overlays_del, color_class)
1560      eina_stringshare_del(color_class);
1561    EINA_LIST_FREE(cfg->color_overlays, co)
1562      {
1563         if (co->color_class) eina_stringshare_del(co->color_class);
1564         free(co);
1565      }
1566    EINA_LIST_FREE(cfg->color_palette, palette)
1567      {
1568         eina_stringshare_del(palette->palette_name);
1569         EINA_LIST_FREE(palette->color_list, color) free(color);
1570         free(palette);
1571      }
1572    EINA_LIST_FREE(cfg->bindings, wb)
1573      {
1574         eina_stringshare_del(wb->name);
1575         EINA_LIST_FREE(wb->key_bindings, kb)
1576           {
1577              eina_stringshare_del(kb->key);
1578              eina_stringshare_del(kb->action);
1579              eina_stringshare_del(kb->params);
1580              EINA_LIST_FREE(kb->modifiers, mb)
1581                {
1582                   eina_stringshare_del(mb->mod);
1583                   free(mb);
1584                }
1585              free(kb);
1586           }
1587         free(wb);
1588      }
1589    eina_stringshare_del(cfg->theme);
1590    eina_stringshare_del(cfg->modules);
1591    eina_stringshare_del(cfg->indicator_service_0);
1592    eina_stringshare_del(cfg->indicator_service_90);
1593    eina_stringshare_del(cfg->indicator_service_180);
1594    eina_stringshare_del(cfg->indicator_service_270);
1595    eina_stringshare_del(cfg->icon_theme);
1596    free(cfg);
1597 }
1598 
1599 static void
_config_apply(void)1600 _config_apply(void)
1601 {
1602    _elm_theme_parse(NULL, _elm_config->theme);
1603    ecore_animator_frametime_set(1.0 / _elm_config->fps);
1604    edje_password_show_last_set(_elm_config->password_show_last);
1605    edje_password_show_last_timeout_set(_elm_config->password_show_last_timeout);
1606 }
1607 
1608 static void
_config_sub_apply(void)1609 _config_sub_apply(void)
1610 {
1611    edje_frametime_set(1.0 / _elm_config->fps);
1612    edje_scale_set(_elm_config->scale);
1613    edje_transition_duration_factor_set(_elm_config->transition_duration_factor);
1614    if (_elm_config->modules) _elm_module_parse(_elm_config->modules);
1615    edje_audio_channel_mute_set(EDJE_CHANNEL_EFFECT, _elm_config->audio_mute_effect);
1616    edje_audio_channel_mute_set(EDJE_CHANNEL_BACKGROUND, _elm_config->audio_mute_background);
1617    edje_audio_channel_mute_set(EDJE_CHANNEL_MUSIC, _elm_config->audio_mute_music);
1618    edje_audio_channel_mute_set(EDJE_CHANNEL_FOREGROUND, _elm_config->audio_mute_foreground);
1619    edje_audio_channel_mute_set(EDJE_CHANNEL_INTERFACE, _elm_config->audio_mute_interface);
1620    edje_audio_channel_mute_set(EDJE_CHANNEL_INPUT, _elm_config->audio_mute_input);
1621    edje_audio_channel_mute_set(EDJE_CHANNEL_ALERT, _elm_config->audio_mute_alert);
1622    edje_audio_channel_mute_set(EDJE_CHANNEL_ALL, _elm_config->audio_mute_all);
1623 }
1624 
1625 static Eina_Bool
_elm_cache_flush_cb(void * data EINA_UNUSED)1626 _elm_cache_flush_cb(void *data EINA_UNUSED)
1627 {
1628    elm_cache_all_flush();
1629    return ECORE_CALLBACK_RENEW;
1630 }
1631 
1632 /* kind of abusing this call right now -- shared between all of those
1633  * properties -- but they are not meant to be called that periodically
1634  * anyway */
1635 void
_elm_recache(void)1636 _elm_recache(void)
1637 {
1638    Eina_List *l;
1639    Evas_Object *win;
1640 
1641    elm_cache_all_flush();
1642 
1643    EINA_LIST_FOREACH(_elm_win_list, l, win)
1644      {
1645         Evas *e = evas_object_evas_get(win);
1646         evas_image_cache_set(e, _elm_config->image_cache * 1024);
1647         evas_font_cache_set(e, _elm_config->font_cache * 1024);
1648      }
1649    edje_file_cache_set(_elm_config->edje_cache);
1650    edje_collection_cache_set(_elm_config->edje_collection_cache);
1651 
1652    ELM_SAFE_FREE(_elm_cache_flush_poller, ecore_poller_del);
1653    if (_elm_config->cache_flush_enable)
1654      {
1655         if (_elm_config->cache_flush_poll_interval > 0)
1656           {
1657              _elm_cache_flush_poller =
1658                 ecore_poller_add(ECORE_POLLER_CORE,
1659                                  _elm_config->cache_flush_poll_interval,
1660                                  _elm_cache_flush_cb, NULL);
1661           }
1662      }
1663 }
1664 
1665 static Elm_Config *
_config_user_load(void)1666 _config_user_load(void)
1667 {
1668    Elm_Config *cfg = NULL;
1669    Eet_File *ef;
1670    char buf[PATH_MAX];
1671 
1672    _elm_config_user_dir_snprintf(buf, sizeof(buf), "config/%s",
1673                           _elm_profile);
1674    ecore_file_mkpath(buf);
1675    if (_eio_config_monitor) eio_monitor_del(_eio_config_monitor);
1676    _eio_config_monitor = eio_monitor_add(buf);
1677 
1678    _elm_config_user_dir_snprintf(buf, sizeof(buf), "config/%s/base.cfg",
1679                                  _elm_profile);
1680 
1681    ef = eet_open(buf, EET_FILE_MODE_READ);
1682    if (ef)
1683      {
1684         cfg = eet_data_read(ef, _config_edd, "config");
1685         eet_close(ef);
1686      }
1687 
1688    if (cfg)
1689      {
1690         size_t len;
1691 
1692         len = _elm_config_user_dir_snprintf(buf, sizeof(buf), "themes/");
1693         if (len + 1 < sizeof(buf))
1694           ecore_file_mkpath(buf);
1695      }
1696 
1697    return cfg;
1698 }
1699 
1700 #include "elm_default_config.x"
1701 
1702 static Elm_Config *
_config_system_load(void)1703 _config_system_load(void)
1704 {
1705    Elm_Config *cfg = NULL;
1706    Eet_File *ef;
1707    char buf[PATH_MAX];
1708 
1709    _elm_data_dir_snprintf(buf, sizeof(buf), "config/%s/base.cfg",
1710                           _elm_profile);
1711 
1712    ef = eet_open(buf, EET_FILE_MODE_READ);
1713    if (!ef)
1714      {
1715         _elm_data_dir_snprintf(buf, sizeof(buf), "config/default/base.cfg");
1716 
1717         ef = eet_open(buf, EET_FILE_MODE_READ);
1718      }
1719    if (ef)
1720      {
1721         cfg = eet_data_read(ef, _config_edd, "config");
1722         eet_close(ef);
1723      }
1724 
1725    if (!cfg)
1726      {
1727         Eina_Tmpstr* tmp;
1728         ERR("System loading config failed! Check your setup! Falling back to compile time defaults");
1729         EINA_SAFETY_ON_FALSE_RETURN_VAL(eina_file_mkstemp("elementary_configXXXXXX", &tmp), NULL);
1730         ef = eet_open(tmp, EET_FILE_MODE_WRITE);
1731         EINA_SAFETY_ON_FALSE_RETURN_VAL(eet_data_undump(ef, "config", embedded_config, strlen(embedded_config)-1, EINA_FALSE), NULL);
1732         eet_close(ef);
1733         ef = eet_open(tmp, EET_FILE_MODE_READ);
1734         if (!ef)
1735           {
1736              ERR("Failed to load a fallback config file.");
1737              return NULL;
1738           }
1739         cfg = eet_data_read(ef, _config_edd, "config");
1740         eet_close(ef);
1741      }
1742 
1743    return cfg;
1744 }
1745 
1746 static void
_efl_config_obj_del(Eo * obj EINA_UNUSED)1747 _efl_config_obj_del(Eo *obj EINA_UNUSED)
1748 {
1749    ERR("You can not delete the global configuration object!");
1750 }
1751 
1752 static void
_config_load(void)1753 _config_load(void)
1754 {
1755    if (_efl_config_obj)
1756      {
1757         efl_del_intercept_set(_efl_config_obj, NULL);
1758         efl_provider_unregister(efl_main_loop_get(), EFL_CONFIG_INTERFACE, _efl_config_obj);
1759         efl_provider_unregister(efl_main_loop_get(), EFL_CONFIG_GLOBAL_CLASS, _efl_config_obj);
1760         ELM_SAFE_FREE(_efl_config_obj, efl_del);
1761         ELM_SAFE_FREE(_elm_config, _config_free);
1762         _elm_font_overlays_del_free();
1763 
1764         ELM_SAFE_FREE(_elm_key_bindings, eina_hash_free);
1765      }
1766    _efl_config_obj = efl_add(EFL_CONFIG_GLOBAL_CLASS, efl_main_loop_get());
1767    efl_provider_register(efl_main_loop_get(), EFL_CONFIG_INTERFACE, _efl_config_obj);
1768    efl_provider_register(efl_main_loop_get(), EFL_CONFIG_GLOBAL_CLASS, _efl_config_obj);
1769    efl_del_intercept_set(_efl_config_obj, _efl_config_obj_del);
1770    if (!_running_in_tree)
1771      {
1772         _elm_config = _config_user_load();
1773         if (_elm_config)
1774           {
1775              if ((_elm_config->config_version >> ELM_CONFIG_VERSION_EPOCH_OFFSET) < ELM_CONFIG_EPOCH)
1776                 {
1777                    WRN("User's elementary config seems outdated and unusable. Fallback to load system config.");
1778                    _config_free(_elm_config);
1779                    _elm_config = NULL;
1780                 }
1781              else
1782                {
1783                   if (_elm_config->config_version < ELM_CONFIG_VERSION)
1784                     _config_update();
1785                   _env_get();
1786                   return;
1787                }
1788           }
1789      }
1790 
1791    /* no user config, fallback for system. No need to check version for
1792     * this one, if it's not the right one, someone screwed up at the time
1793     * of installing it */
1794    _elm_config = _config_system_load();
1795    if (_elm_config)
1796      {
1797         _env_get();
1798         return;
1799      }
1800    else
1801      {
1802         ERR("Everything failed, no config found or created. This will not work");
1803      }
1804 }
1805 
1806 static void
_elm_config_reload_do(void)1807 _elm_config_reload_do(void)
1808 {
1809    Elm_Config *prev_config;
1810 
1811    prev_config = _elm_config;
1812    _elm_config = NULL;
1813    _config_load();
1814    if ((prev_config) && (_elm_config))
1815      {
1816 #define KEEP_VAL(xxx) \
1817    if (prev_config->priv.xxx) { \
1818       _elm_config->xxx = prev_config->xxx; \
1819    }
1820 #define KEEP_STR(xxx) \
1821    if (prev_config->priv.xxx) { \
1822       eina_stringshare_replace(&(_elm_config->xxx), prev_config->xxx); \
1823    }
1824         Elm_Font_Overlay *fo;
1825         Elm_Color_Overlay *co;
1826         Elm_Custom_Palette *palette;
1827         Elm_Color_RGBA *color;
1828         Elm_Config_Bindings_Widget *wb;
1829         Elm_Config_Binding_Key *kb;
1830         Elm_Config_Binding_Modifier *mb;
1831 
1832         KEEP_STR(engine);
1833         KEEP_STR(accel);
1834         KEEP_STR(web_backend);
1835         KEEP_VAL(accel_override);
1836         KEEP_VAL(vsync);
1837         KEEP_VAL(thumbscroll_enable);
1838         KEEP_VAL(thumbscroll_threshold);
1839         KEEP_VAL(thumbscroll_hold_threshold);
1840         KEEP_VAL(thumbscroll_momentum_threshold);
1841         KEEP_VAL(thumbscroll_flick_distance_tolerance);
1842         KEEP_VAL(thumbscroll_momentum_distance_max);
1843         KEEP_VAL(thumbscroll_friction);
1844         KEEP_VAL(thumbscroll_momentum_friction);
1845         KEEP_VAL(thumbscroll_min_friction);
1846         KEEP_VAL(thumbscroll_friction_standard);
1847         KEEP_VAL(thumbscroll_bounce_friction);
1848         KEEP_VAL(thumbscroll_acceleration_threshold);
1849         KEEP_VAL(thumbscroll_acceleration_time_limit);
1850         KEEP_VAL(thumbscroll_acceleration_weight);
1851 
1852         KEEP_VAL(thumbscroll_momentum_animation_duration_min_limit);
1853         KEEP_VAL(thumbscroll_momentum_animation_duration_max_limit);
1854 
1855         KEEP_VAL(page_scroll_friction);
1856         KEEP_VAL(bring_in_scroll_friction);
1857         KEEP_VAL(zoom_friction);
1858         KEEP_VAL(scroll_animation_disable);
1859         KEEP_VAL(scroll_accel_factor);
1860         KEEP_VAL(thumbscroll_bounce_enable);
1861         KEEP_VAL(thumbscroll_border_friction);
1862         KEEP_VAL(thumbscroll_sensitivity_friction);
1863         KEEP_VAL(scroll_smooth_start_enable);
1864         KEEP_VAL(scroll_smooth_amount);
1865         KEEP_VAL(scroll_smooth_time_window);
1866         KEEP_VAL(scale);
1867         if (prev_config->priv.font_overlays)
1868           {
1869              EINA_LIST_FREE(_elm_config->font_overlays, fo)
1870                {
1871                   eina_stringshare_del(fo->text_class);
1872                   eina_stringshare_del(fo->font);
1873                   free(fo);
1874                }
1875              _elm_config->font_overlays = prev_config->font_overlays;
1876              prev_config->font_overlays = NULL;
1877           }
1878         KEEP_VAL(font_hinting);
1879         KEEP_VAL(cache_flush_poll_interval);
1880 
1881         KEEP_VAL(cache_flush_enable);
1882         KEEP_VAL(image_cache);
1883         KEEP_VAL(font_cache);
1884         KEEP_VAL(edje_cache);
1885         KEEP_VAL(edje_collection_cache);
1886         KEEP_VAL(finger_size);
1887         KEEP_VAL(tooltip_delay);
1888         KEEP_VAL(cursor_engine_only);
1889         KEEP_VAL(focus_highlight_enable);
1890         KEEP_VAL(focus_highlight_animate);
1891         KEEP_VAL(focus_highlight_clip_disable);
1892         KEEP_VAL(focus_move_policy);
1893         KEEP_VAL(item_select_on_focus_disable);
1894         KEEP_VAL(first_item_focus_on_first_focus_in);
1895         KEEP_VAL(focus_autoscroll_mode);
1896         KEEP_VAL(slider_indicator_visible_mode);
1897         KEEP_VAL(popup_horizontal_align);
1898         KEEP_VAL(popup_vertical_align);
1899         KEEP_VAL(popup_scrollable);
1900         KEEP_VAL(toolbar_shrink_mode);
1901         KEEP_VAL(fileselector_expand_enable);
1902         KEEP_VAL(fileselector_double_tap_navigation_enable);
1903         KEEP_VAL(inwin_dialogs_enable);
1904         KEEP_VAL(icon_size);
1905         KEEP_VAL(longpress_timeout);
1906         KEEP_VAL(effect_enable);
1907         KEEP_VAL(desktop_entry);
1908         KEEP_VAL(context_menu_disabled);
1909         KEEP_VAL(password_show_last);
1910         KEEP_VAL(password_show_last_timeout);
1911         KEEP_VAL(glayer_zoom_finger_enable);
1912         KEEP_VAL(glayer_zoom_finger_factor);
1913         KEEP_VAL(glayer_zoom_wheel_factor);
1914         KEEP_VAL(glayer_zoom_distance_tolerance);
1915         KEEP_VAL(glayer_rotate_finger_enable);
1916         KEEP_VAL(glayer_rotate_angular_tolerance);
1917         KEEP_VAL(glayer_line_min_length);
1918         KEEP_VAL(glayer_line_distance_tolerance);
1919         KEEP_VAL(glayer_line_angular_tolerance);
1920         KEEP_VAL(glayer_flick_time_limit_ms);
1921         KEEP_VAL(glayer_long_tap_start_timeout);
1922         KEEP_VAL(glayer_double_tap_timeout);
1923         KEEP_VAL(glayer_tap_finger_size);
1924         KEEP_VAL(access_mode);
1925         KEEP_VAL(glayer_continues_enable);
1926         KEEP_VAL(week_start);
1927         KEEP_VAL(weekend_start);
1928         KEEP_VAL(weekend_len);
1929         KEEP_VAL(year_min);
1930         KEEP_VAL(year_max);
1931         if (prev_config->priv.color_overlays)
1932           {
1933              EINA_LIST_FREE(_elm_config->color_overlays, co)
1934                {
1935                   if (co->color_class) eina_stringshare_del(co->color_class);
1936                   free(co);
1937                }
1938              _elm_config->color_overlays = prev_config->color_overlays;
1939              prev_config->color_overlays = NULL;
1940           }
1941         if (prev_config->priv.color_palette)
1942           {
1943              EINA_LIST_FREE(_elm_config->color_palette, palette)
1944                {
1945                   eina_stringshare_del(palette->palette_name);
1946                   EINA_LIST_FREE(palette->color_list, color) free(color);
1947                   free(palette);
1948                }
1949              _elm_config->color_palette = prev_config->color_palette;
1950              prev_config->color_palette = NULL;
1951           }
1952 
1953         KEEP_VAL(softcursor_mode);
1954         KEEP_VAL(auto_norender_withdrawn);
1955         KEEP_VAL(auto_norender_iconified_same_as_withdrawn);
1956         KEEP_VAL(auto_flush_withdrawn);
1957         KEEP_VAL(auto_dump_withdrawn);
1958         KEEP_VAL(auto_throttle);
1959         KEEP_VAL(auto_throttle_amount);
1960         KEEP_STR(indicator_service_0);
1961         KEEP_STR(indicator_service_90);
1962         KEEP_STR(indicator_service_180);
1963         KEEP_STR(indicator_service_270);
1964         KEEP_VAL(selection_clear_enable);
1965         KEEP_VAL(disable_external_menu);
1966         KEEP_VAL(clouseau_enable);
1967         KEEP_VAL(magnifier_enable);
1968         KEEP_VAL(magnifier_scale);
1969         KEEP_VAL(audio_mute_effect);
1970         KEEP_VAL(audio_mute_background);
1971         KEEP_VAL(audio_mute_music);
1972         KEEP_VAL(audio_mute_foreground);
1973         KEEP_VAL(audio_mute_interface);
1974         KEEP_VAL(audio_mute_input);
1975         KEEP_VAL(audio_mute_alert);
1976         KEEP_VAL(audio_mute_all);
1977         KEEP_VAL(win_auto_focus_enable);
1978         KEEP_VAL(win_auto_focus_animate);
1979         KEEP_VAL(transition_duration_factor);
1980         KEEP_VAL(naviframe_prev_btn_auto_pushed);
1981         KEEP_VAL(spinner_min_max_filter_enable);
1982         if (prev_config->priv.bindings)
1983           {
1984              EINA_LIST_FREE(_elm_config->bindings, wb)
1985                {
1986                   eina_stringshare_del(wb->name);
1987                   EINA_LIST_FREE(wb->key_bindings, kb)
1988                     {
1989                        eina_stringshare_del(kb->key);
1990                        eina_stringshare_del(kb->action);
1991                        eina_stringshare_del(kb->params);
1992                        EINA_LIST_FREE(kb->modifiers, mb)
1993                          {
1994                             eina_stringshare_del(mb->mod);
1995                             free(mb);
1996                          }
1997                        free(kb);
1998                     }
1999                   free(wb);
2000                }
2001              _elm_config->bindings = prev_config->bindings;
2002              prev_config->bindings = NULL;
2003           }
2004         KEEP_VAL(atspi_mode);
2005         KEEP_VAL(gl_depth);
2006         KEEP_VAL(gl_stencil);
2007         KEEP_VAL(gl_msaa);
2008         KEEP_STR(icon_theme);
2009         KEEP_VAL(entry_select_allow);
2010         KEEP_VAL(drag_anim_duration);
2011 
2012         KEEP_VAL(win_no_border);
2013 
2014         _elm_config->priv = prev_config->priv;
2015         _config_free(prev_config);
2016      }
2017    if (_elm_config) _env_get();
2018 }
2019 
2020 static void
_config_flush_get(void)2021 _config_flush_get(void)
2022 {
2023    Eina_Bool is_mirrored;
2024    Eina_Bool translate;
2025    double pre_scale;
2026 
2027    is_mirrored = _elm_config->is_mirrored;
2028    translate = _elm_config->translate;
2029    pre_scale = _elm_config->scale;
2030 
2031    _elm_config_font_overlays_cancel();
2032    _color_overlays_cancel();
2033 
2034    _elm_config_reload_do();
2035 
2036    /* restore prev value which is not part of the EET file */
2037    _elm_config->is_mirrored = is_mirrored;
2038    _elm_config->translate = translate;
2039 
2040    _elm_recache();
2041    _config_apply();
2042    _config_sub_apply();
2043    evas_font_reinit();
2044    _elm_config_font_overlay_apply();
2045    _elm_config_color_overlay_apply();
2046    if (!EINA_DBL_EQ(pre_scale, _elm_config->scale))
2047      _elm_rescale();
2048    _elm_old_clouseau_reload();
2049    _elm_config_key_binding_hash();
2050    _elm_win_access(_elm_config->access_mode);
2051    ecore_event_add(ELM_EVENT_CONFIG_ALL_CHANGED, NULL, NULL, NULL);
2052    efl_event_callback_call(_efl_config_obj, EFL_CONFIG_EVENT_CONFIG_CHANGED, NULL);
2053 }
2054 
2055 static const char *
_elm_config_eet_close_error_get(Eet_File * ef,char * file)2056 _elm_config_eet_close_error_get(Eet_File *ef,
2057                                 char     *file)
2058 {
2059    Eet_Error err;
2060    const char *erstr = NULL;
2061 
2062    err = eet_close(ef);
2063    switch (err)
2064      {
2065       case EET_ERROR_WRITE_ERROR:
2066         erstr = "An error occurred while saving Elementary's "
2067                 "settings to disk. The error could not be "
2068                 "deterimined. The file where the error occurred was: "
2069                 "%s. This file has been deleted to avoid corrupt data.";
2070         break;
2071 
2072       case EET_ERROR_WRITE_ERROR_FILE_TOO_BIG:
2073         erstr = "Elementary's settings files are too big "
2074                 "for the file system they are being saved to. "
2075                 "This error is very strange as the files should "
2076                 "be extremely small. Please check the settings "
2077                 "for your home directory. "
2078                 "The file where the error occurred was: %s ."
2079                 "This file has been deleted to avoid corrupt data.";
2080         break;
2081 
2082       case EET_ERROR_WRITE_ERROR_IO_ERROR:
2083         erstr = "An output error occurred when writing the settings "
2084                 "files for Elementary. Your disk is having troubles "
2085                 "and possibly needs replacement. "
2086                 "The file where the error occurred was: %s ."
2087                 "This file has been deleted to avoid corrupt data.";
2088         break;
2089 
2090       case EET_ERROR_WRITE_ERROR_OUT_OF_SPACE:
2091         erstr = "Elementary cannot write its settings file "
2092                 "because it ran out of space to write the file. "
2093                 "You have either run out of disk space or have "
2094                 "gone over your quota limit. "
2095                 "The file where the error occurred was: %s ."
2096                 "This file has been deleted to avoid corrupt data.";
2097         break;
2098 
2099       case EET_ERROR_WRITE_ERROR_FILE_CLOSED:
2100         erstr = "Elementary unexpectedly had the settings file "
2101                 "it was writing closed on it. This is very unusual. "
2102                 "The file where the error occurred was: %s "
2103                 "This file has been deleted to avoid corrupt data.";
2104         break;
2105 
2106       default:
2107         break;
2108      }
2109    if (erstr)
2110      {
2111         /* delete any partially-written file */
2112          ecore_file_unlink(file);
2113          return strdup(erstr);
2114      }
2115 
2116    return NULL;
2117 }
2118 
2119 static Eina_Bool
_elm_config_profile_save(const char * profile)2120 _elm_config_profile_save(const char *profile)
2121 {
2122    Elm_Config_Derived *derived;
2123    char buf[4096], buf2[4096];
2124    int ok = 0, ret;
2125    const char *err, *s;
2126    Eet_File *ef;
2127    size_t len;
2128 
2129    if (_running_in_tree || ((s = _getenv_once("ELM_PROFILE_NOSAVE")) && atoi(s)))
2130      return EINA_TRUE;
2131 
2132    len = _elm_config_user_dir_snprintf(buf, sizeof(buf), "config/profile.cfg");
2133    if (len + 1 >= sizeof(buf))
2134      return EINA_FALSE;
2135 
2136    len = _elm_config_user_dir_snprintf(buf2, sizeof(buf2),
2137                                        "config/profile.cfg.tmp");
2138    if (len + 1 >= sizeof(buf2))
2139      return EINA_FALSE;
2140 
2141    ef = eet_open(buf2, EET_FILE_MODE_WRITE);
2142    if (!ef)
2143      return EINA_FALSE;
2144 
2145    ok = eet_write(ef, "config", _elm_profile, strlen(_elm_profile), 0);
2146    if (!ok)
2147      goto err;
2148 
2149    err = _elm_config_eet_close_error_get(ef, buf2);
2150    if (err)
2151      {
2152         ERR("%s", err);
2153         free((void *)err);
2154         goto err;
2155      }
2156 
2157    ret = ecore_file_mv(buf2, buf);
2158    if (!ret)
2159      {
2160         ERR("Error saving Elementary's configuration profile file");
2161         goto err;
2162      }
2163 
2164    derived = _elm_config_derived_load(profile ? profile : _elm_profile);
2165    if (derived)
2166      {
2167         _elm_config_derived_save(_elm_config, derived);
2168         _elm_config_derived_free(derived);
2169      }
2170    return EINA_TRUE;
2171 
2172 err:
2173    ecore_file_unlink(buf2);
2174    return EINA_FALSE;
2175 }
2176 
2177 Eina_Bool
_elm_config_save(Elm_Config * cfg,const char * profile)2178 _elm_config_save(Elm_Config *cfg, const char *profile)
2179 {
2180    char buf[4096], buf2[4096];
2181    int ok = 0, ret;
2182    const char *err;
2183    Eet_File *ef;
2184    size_t len;
2185 
2186    len = _elm_config_user_dir_snprintf(buf, sizeof(buf), "themes/");
2187    if (len + 1 >= sizeof(buf))
2188      return EINA_FALSE;
2189 
2190    ok = ecore_file_mkpath(buf);
2191    if (!ok)
2192      {
2193         ERR("Problem accessing Elementary's user configuration directory: %s",
2194             buf);
2195         return EINA_FALSE;
2196      }
2197 
2198    len = _elm_config_user_dir_snprintf(buf, sizeof(buf), "config/%s",
2199                                        profile ? profile : _elm_profile);
2200    if (len + 1 >= sizeof(buf))
2201      return EINA_FALSE;
2202 
2203    ok = ecore_file_mkpath(buf);
2204    if (!ok)
2205      {
2206         ERR("Problem accessing Elementary's user configuration directory: %s",
2207             buf);
2208         return EINA_FALSE;
2209      }
2210 
2211    if (!profile)
2212      {
2213         if (!_elm_config_profile_save(NULL))
2214           return EINA_FALSE;
2215      }
2216 
2217    buf[len] = '/';
2218    len++;
2219 
2220    if (len + sizeof("base.cfg") >= sizeof(buf) - len)
2221      return EINA_FALSE;
2222 
2223    memcpy(buf + len, "base.cfg", sizeof("base.cfg"));
2224    len += sizeof("base.cfg") - 1;
2225 
2226    if (len + sizeof(".tmp") >= sizeof(buf))
2227      return EINA_FALSE;
2228 
2229    memcpy(buf2, buf, len);
2230    memcpy(buf2 + len, ".tmp", sizeof(".tmp"));
2231 
2232    ef = eet_open(buf2, EET_FILE_MODE_WRITE);
2233    if (!ef)
2234      return EINA_FALSE;
2235 
2236    ok = eet_data_write(ef, _config_edd, "config", cfg, 1);
2237    if (!ok)
2238      goto err;
2239 
2240    err = _elm_config_eet_close_error_get(ef, buf2);
2241    if (err)
2242      {
2243         ERR("%s", err);
2244         free((void *)err);
2245         goto err;
2246      }
2247 
2248    ret = ecore_file_mv(buf2, buf);
2249    if (!ret)
2250      {
2251         ERR("Error saving Elementary's configuration file");
2252         goto err;
2253      }
2254 
2255    return EINA_TRUE;
2256 
2257 err:
2258    ecore_file_unlink(buf2);
2259    return EINA_FALSE;
2260 }
2261 
2262 // those widgets changed name over time, breaking key bindings
2263 typedef struct _Widget_Class_Name_Map {
2264    const char *const legacy;
2265    const char *const newname;
2266 } Widget_Class_Name_Map;
2267 
2268 static const Widget_Class_Name_Map _widget_class_name_map [] = {
2269 { "elm_win", "Efl.Ui.Win" },
2270 { "elm_image", "Efl.Ui.Image" },
2271 { "elm_video", "Efl.Ui.Video" },
2272 { "elm_photocam", "Efl.Ui.Image_Zoomable" },
2273 };
2274 
2275 static void
_elm_key_bindings_update(Elm_Config * cfg,Elm_Config * syscfg EINA_UNUSED)2276 _elm_key_bindings_update(Elm_Config *cfg, Elm_Config *syscfg EINA_UNUSED)
2277 {
2278    for (size_t k = 0; k < EINA_C_ARRAY_LENGTH(_widget_class_name_map); k++)
2279      {
2280         const Widget_Class_Name_Map *cmap = &_widget_class_name_map[k];
2281         Elm_Config_Bindings_Widget *wb;
2282         Eina_List *l;
2283 
2284         // find old name in local memory and replace with new name
2285         EINA_LIST_FOREACH(cfg->bindings, l, wb)
2286           {
2287              if (wb->name && !strcasecmp(wb->name, cmap->legacy))
2288                {
2289                   eina_stringshare_replace(&wb->name, cmap->newname);
2290                   break;
2291                }
2292           }
2293      }
2294 }
2295 
2296 static void
_elm_key_bindings_copy_missing_bindings_of_widget(Elm_Config * cfg,Elm_Config * syscfg,const char * widget_name)2297 _elm_key_bindings_copy_missing_bindings_of_widget(Elm_Config *cfg, Elm_Config *syscfg, const char *widget_name)
2298 {
2299    Elm_Config_Bindings_Widget *wd;
2300    Eina_List *n, *nnext;
2301 
2302    EINA_LIST_FOREACH_SAFE(syscfg->bindings, n, nnext, wd)
2303      {
2304          if (eina_streq(widget_name, wd->name))
2305            {
2306               syscfg->bindings = eina_list_remove_list(syscfg->bindings, n);
2307               cfg->bindings = eina_list_append(cfg->bindings, wd);
2308               printf("Upgraded keybindings for %s!\n", wd->name);
2309            }
2310      }
2311 }
2312 
2313 static void
_elm_key_bindings_copy_missing_bindings(Elm_Config * cfg,Elm_Config * syscfg)2314 _elm_key_bindings_copy_missing_bindings(Elm_Config *cfg, Elm_Config *syscfg)
2315 {
2316    Eina_Hash *safed_bindings = eina_hash_string_superfast_new(NULL);
2317    Elm_Config_Bindings_Widget *wd;
2318    Eina_List *n, *nnext;
2319    Eina_Bool missing_bindings = EINA_FALSE;
2320 
2321    EINA_LIST_FOREACH(cfg->bindings, n, wd)
2322      {
2323         eina_hash_add(safed_bindings, wd->name, wd);
2324      }
2325 
2326    EINA_LIST_FOREACH_SAFE(syscfg->bindings, n, nnext, wd)
2327      {
2328          if (!eina_hash_find(safed_bindings, wd->name))
2329            {
2330               syscfg->bindings = eina_list_remove_list(syscfg->bindings, n);
2331               cfg->bindings = eina_list_append(cfg->bindings, wd);
2332               printf("Upgraded keybindings for %s!\n", wd->name);
2333               missing_bindings = EINA_TRUE;
2334            }
2335      }
2336    if (missing_bindings)
2337      {
2338         printf("There have been missing Key bindings in the config, config is now adjusted\n");
2339      }
2340    eina_hash_free(safed_bindings);
2341 }
2342 
2343 static void
_config_update(void)2344 _config_update(void)
2345 {
2346    Elm_Config *tcfg;
2347    tcfg = _config_system_load();
2348    if (!tcfg)
2349      {
2350         /* weird profile or something? We should probably fill
2351          * with hardcoded defaults, or get from default previx */
2352         return;
2353      }
2354 #define IFCFG(v)   if ((_elm_config->config_version & 0xffff) < (v)) {
2355 #define IFCFGELSE } else {
2356 #define IFCFGEND  }
2357 #define COPYVAL(x) do {_elm_config->x = tcfg->x; } while (0)
2358 #define COPYPTR(x) do {_elm_config->x = tcfg->x; tcfg->x = NULL; } while (0)
2359 #define COPYSTR(x) COPYPTR(x)
2360 
2361    /* we also need to update for property changes in the root window
2362     * if needed, but that will be dependent on new properties added
2363     * with each version */
2364    IFCFG(0x0002)
2365    _elm_config->win_auto_focus_enable = tcfg->win_auto_focus_enable;;
2366    _elm_config->win_auto_focus_animate = tcfg->win_auto_focus_animate;
2367    IFCFGEND
2368 
2369    IFCFG(0x0003)
2370    _elm_config->transition_duration_factor = tcfg->transition_duration_factor;
2371    IFCFGEND
2372 
2373    IFCFG(0x0004)
2374    Elm_Config_Bindings_Widget *wb, *twb = NULL;
2375    Eina_List *l;
2376 
2377    EINA_LIST_FOREACH(tcfg->bindings, l, wb)
2378      {
2379         if (wb->name && !strcmp(wb->name, "Elm_Hoversel"))
2380           {
2381              twb = wb;
2382              break;
2383           }
2384      }
2385    if (twb)
2386      {
2387         EINA_LIST_FOREACH(_elm_config->bindings, l, wb)
2388            {
2389               if (wb->name && !strcmp(wb->name, "Elm_Hoversel"))
2390                 {
2391                    // simply swap bindngs for Elm_Hoversel with system ones
2392                    Eina_List *tmp = wb->key_bindings;
2393                    wb->key_bindings = twb->key_bindings;
2394                    twb->key_bindings = tmp;
2395                    break;
2396                 }
2397            }
2398      }
2399    IFCFGEND
2400 
2401    IFCFG(0x0005)
2402    _elm_config->naviframe_prev_btn_auto_pushed = tcfg->naviframe_prev_btn_auto_pushed;
2403    IFCFGEND
2404 
2405    IFCFG(0x0006)
2406    _elm_config->cursor_engine_only = 0;
2407    IFCFGEND
2408 
2409    IFCFG(0x0007)
2410    Elm_Config_Bindings_Widget *wb, *twb = NULL;
2411    Eina_List *l;
2412 
2413    EINA_LIST_FOREACH(tcfg->bindings, l, wb)
2414      {
2415         if (wb->name && !strcmp(wb->name, "Elm_Combobox"))
2416           {
2417              twb = wb;
2418              break;
2419           }
2420      }
2421    if (twb)
2422      {
2423         EINA_LIST_FOREACH(_elm_config->bindings, l, wb)
2424            {
2425               if (wb->name && !strcmp(wb->name, "Elm_Combobox"))
2426                 {
2427                    // simply swap bindngs for Elm_Combobox with system ones
2428                    Eina_List *tmp = wb->key_bindings;
2429                    wb->key_bindings = twb->key_bindings;
2430                    twb->key_bindings = tmp;
2431                    break;
2432                 }
2433            }
2434      }
2435    IFCFGEND
2436 
2437    IFCFG(0x0008)
2438    _elm_config->popup_horizontal_align = 0.5;
2439    _elm_config->popup_vertical_align = 0.5;
2440    IFCFGEND
2441 
2442    IFCFG(0x0009)
2443    _elm_config->scroll_accel_factor = 7.0;
2444    IFCFGEND
2445 
2446    IFCFG(0x000a)
2447    _elm_config->icon_theme = eina_stringshare_add(ELM_CONFIG_ICON_THEME_ELEMENTARY);
2448    IFCFGEND
2449 
2450    IFCFG(0x000b)
2451    eina_stringshare_refplace(&_elm_config->modules, tcfg->modules);
2452    IFCFGEND
2453 
2454    IFCFG(0x000e)
2455    _elm_config->entry_select_allow = EINA_TRUE;
2456    IFCFGEND
2457 
2458    IFCFG(0x000f)
2459    _elm_key_bindings_update(_elm_config, tcfg);
2460    IFCFGEND
2461 
2462    IFCFG(0x0010)
2463    _elm_config->win_no_border = EINA_FALSE;
2464    IFCFGEND
2465 
2466    IFCFG(0x0016)
2467 
2468    _elm_key_bindings_copy_missing_bindings(_elm_config, tcfg);
2469    /* after this function call, the tcfg is partly invalidated, reload! */
2470    _config_free(tcfg);
2471    tcfg = _config_system_load();
2472    IFCFGEND
2473 
2474    IFCFG(0x0017)
2475    _elm_key_bindings_copy_missing_bindings_of_widget(_elm_config, tcfg, "Efl.Ui.Textbox");
2476    /* after this function call, the tcfg is partly invalidated, reload! */
2477    _config_free(tcfg);
2478    tcfg = _config_system_load();
2479    IFCFGEND
2480 
2481    IFCFG(0x0018)
2482    if (!_elm_config->priv.thumbscroll_momentum_distance_max)
2483      COPYVAL(thumbscroll_momentum_distance_max);
2484    if (!_elm_config->priv.thumbscroll_momentum_friction)
2485      COPYVAL(thumbscroll_momentum_friction);
2486    IFCFGEND
2487    /**
2488     * Fix user config for current ELM_CONFIG_EPOCH here.
2489     **/
2490 
2491 #undef COPYSTR
2492 #undef COPYPTR
2493 #undef COPYVAL
2494 #undef IFCFGEND
2495 #undef IFCFGELSE
2496 #undef IFCFG
2497 
2498    _elm_config->config_version = ELM_CONFIG_VERSION;
2499    /* after updating user config, we must save */
2500    _config_free(tcfg);
2501    _elm_config_save(_elm_config, NULL);
2502 }
2503 
2504 static void
_env_get(void)2505 _env_get(void)
2506 {
2507    const char *s;
2508    double friction;
2509 
2510    s = _getenv_once("ELM_ENGINE");
2511    if (s)
2512      {
2513         if ((!strcasecmp(s, "x11")) ||
2514             (!strcasecmp(s, "x")) ||
2515             (!strcasecmp(s, "software-x11")) ||
2516             (!strcasecmp(s, "software_x11")))
2517           eina_stringshare_replace(&_elm_config->engine, ELM_SOFTWARE_X11);
2518         else if ((!strcasecmp(s, "opengl")) ||
2519                  (!strcasecmp(s, "gl")) ||
2520                  (!strcasecmp(s, "opengl-x11")) ||
2521                  (!strcasecmp(s, "opengl_x11")))
2522           eina_stringshare_replace(&_elm_config->engine, ELM_OPENGL_X11);
2523         else if ((!strcasecmp(s, "fb")) ||
2524                  (!strcasecmp(s, "software-fb")) ||
2525                  (!strcasecmp(s, "software_fb")))
2526           eina_stringshare_replace(&_elm_config->engine, ELM_SOFTWARE_FB);
2527         else if ((!strcasecmp(s, "sdl")) ||
2528                  (!strcasecmp(s, "software-sdl")) ||
2529                  (!strcasecmp(s, "software_sdl")))
2530           eina_stringshare_replace(&_elm_config->engine, ELM_SOFTWARE_SDL);
2531         else if ((!strcasecmp(s, "opengl-sdl")) ||
2532                  (!strcasecmp(s, "opengl_sdl")) ||
2533                  (!strcasecmp(s, "gl-sdl")) ||
2534                  (!strcasecmp(s, "gl_sdl")))
2535           eina_stringshare_replace(&_elm_config->engine, ELM_OPENGL_SDL);
2536         else if ((!strcasecmp(s, "opengl-cocoa")) ||
2537                  (!strcasecmp(s, "opengl_cocoa")) ||
2538                  (!strcasecmp(s, "gl-cocoa")) ||
2539                  (!strcasecmp(s, "gl_cocoa")))
2540           eina_stringshare_replace(&_elm_config->engine, ELM_OPENGL_COCOA);
2541         else if ((!strcasecmp(s, "gdi")) ||
2542                  (!strcasecmp(s, "software-gdi")) ||
2543                  (!strcasecmp(s, "software_gdi")))
2544           eina_stringshare_replace(&_elm_config->engine, ELM_SOFTWARE_WIN32);
2545         else if (!strcasecmp(s, "buffer"))
2546           eina_stringshare_replace(&_elm_config->engine, ELM_BUFFER);
2547         else if ((!strncmp(s, "shot:", 5)))
2548           eina_stringshare_replace(&_elm_config->engine, s);
2549         else if ((!strcasecmp(s, "ews")))
2550           eina_stringshare_replace(&_elm_config->engine, ELM_EWS);
2551         else if ((!strcasecmp(s, "wayland_shm")) ||
2552                  (!strcasecmp(s, "wayland-shm")))
2553           eina_stringshare_replace(&_elm_config->engine, ELM_WAYLAND_SHM);
2554         else if ((!strcasecmp(s, "wayland_egl")) ||
2555                  (!strcasecmp(s, "wayland-egl")))
2556           eina_stringshare_replace(&_elm_config->engine, ELM_WAYLAND_EGL);
2557         else if ((!strcasecmp(s, "drm")))
2558           eina_stringshare_replace(&_elm_config->engine, ELM_DRM);
2559         else if ((!strcasecmp(s, "ddraw")))
2560           eina_stringshare_replace(&_elm_config->engine, ELM_SOFTWARE_DDRAW);
2561         else
2562           ERR("Unknown engine '%s'.", s);
2563         if (_elm_config->engine)
2564           eina_stringshare_replace(&_elm_preferred_engine, _elm_config->engine);
2565      }
2566 
2567    s = _getenv_once("ELM_VSYNC");
2568    if (s) _elm_config->vsync = !!atoi(s);
2569 
2570    s = _getenv_once("ELM_THUMBSCROLL_ENABLE");
2571    if (s) _elm_config->thumbscroll_enable = !!atoi(s);
2572    s = _getenv_once("ELM_THUMBSCROLL_THRESHOLD");
2573    if (s) _elm_config->thumbscroll_threshold = atoi(s);
2574    s = _getenv_once("ELM_THUMBSCROLL_HOLD_THRESHOLD");
2575    if (s) _elm_config->thumbscroll_hold_threshold = atoi(s);
2576    // FIXME: floatformat locale issues here 1.0 vs 1,0 - should just be 1.0
2577    s = _getenv_once("ELM_THUMBSCROLL_MOMENTUM_THRESHOLD");
2578    if (s) _elm_config->thumbscroll_momentum_threshold = _elm_atof(s);
2579    s = _getenv_once("ELM_THUMBSCROLL_FLICK_DISTANCE_TOLERANCE");
2580    if (s) _elm_config->thumbscroll_flick_distance_tolerance = atoi(s);
2581    s = _getenv_once("ELM_THUMBSCROLL_MOMENTUM_DISTANCE_MAX");
2582    if (s) _elm_config->thumbscroll_momentum_distance_max = atoi(s);
2583    s = _getenv_once("ELM_THUMBSCROLL_FRICTION");
2584    if (s) _elm_config->thumbscroll_friction = _elm_atof(s);
2585    s = _getenv_once("ELM_THUMBSCROLL_MOMENTUM_FRICTION");
2586    if (s) _elm_config->thumbscroll_momentum_friction = _elm_atof(s);
2587    s = _getenv_once("ELM_THUMBSCROLL_MIN_FRICTION");
2588    if (s) _elm_config->thumbscroll_min_friction = _elm_atof(s);
2589    s = _getenv_once("ELM_THUMBSCROLL_FRICTION_STANDARD");
2590    if (s) _elm_config->thumbscroll_friction_standard = _elm_atof(s);
2591    s = _getenv_once("ELM_THUMBSCROLL_BOUNCE_ENABLE");
2592    if (s) _elm_config->thumbscroll_bounce_enable = !!atoi(s);
2593    s = _getenv_once("ELM_THUMBSCROLL_BOUNCE_FRICTION");
2594    if (s) _elm_config->thumbscroll_bounce_friction = _elm_atof(s);
2595    s = _getenv_once("ELM_THUMBSCROLL_ACCELERATION_THRESHOLD");
2596    if (s) _elm_config->thumbscroll_acceleration_threshold = _elm_atof(s);
2597    s = _getenv_once("ELM_THUMBSCROLL_ACCELERATION_TIME_LIMIT");
2598    if (s) _elm_config->thumbscroll_acceleration_time_limit = _elm_atof(s);
2599    s = _getenv_once("ELM_THUMBSCROLL_ACCELERATION_WEIGHT");
2600    if (s) _elm_config->thumbscroll_acceleration_weight = _elm_atof(s);
2601    s = _getenv_once("ELM_PAGE_SCROLL_FRICTION");
2602    if (s) _elm_config->page_scroll_friction = _elm_atof(s);
2603    s = _getenv_once("ELM_BRING_IN_SCROLL_FRICTION");
2604    if (s) _elm_config->bring_in_scroll_friction = _elm_atof(s);
2605    s = _getenv_once("ELM_ZOOM_FRICTION");
2606    if (s) _elm_config->zoom_friction = _elm_atof(s);
2607    s = _getenv_once("ELM_THUMBSCROLL_BORDER_FRICTION");
2608    if (s)
2609      {
2610         friction = _elm_atof(s);
2611         if (friction < 0.0)
2612           friction = 0.0;
2613 
2614         if (friction > 1.0)
2615           friction = 1.0;
2616 
2617         _elm_config->thumbscroll_border_friction = friction;
2618      }
2619    s = _getenv_once("ELM_THUMBSCROLL_SENSITIVITY_FRICTION");
2620    if (s)
2621      {
2622         friction = _elm_atof(s);
2623         if (friction < 0.1)
2624           friction = 0.1;
2625 
2626         if (friction > 1.0)
2627           friction = 1.0;
2628 
2629         _elm_config->thumbscroll_sensitivity_friction = friction;
2630      }
2631    s = _getenv_once("ELM_SCROLL_SMOOTH_START_ENABLE");
2632    if (s) _elm_config->scroll_smooth_start_enable = !!atoi(s);
2633    s = _getenv_once("ELM_SCROLL_ANIMATION_DISABLE");
2634    if (s) _elm_config->scroll_animation_disable = !!atoi(s);
2635    s = _getenv_once("ELM_SCROLL_ACCEL_FACTOR");
2636    if (s) _elm_config->scroll_accel_factor = atof(s);
2637 //   s = _getenv_once("ELM_SCROLL_SMOOTH_TIME_INTERVAL"); // not used anymore
2638 //   if (s) _elm_config->scroll_smooth_time_interval = atof(s); // not used anymore
2639    s = _getenv_once("ELM_SCROLL_SMOOTH_AMOUNT");
2640    if (s) _elm_config->scroll_smooth_amount = _elm_atof(s);
2641 //   s = _getenv_once("ELM_SCROLL_SMOOTH_HISTORY_WEIGHT"); // not used anymore
2642 //   if (s) _elm_config->scroll_smooth_history_weight = _elm_atof(s); // not used anymore
2643 //   s = _getenv_once("ELM_SCROLL_SMOOTH_FUTURE_TIME"); // not used anymore
2644 //   if (s) _elm_config->scroll_smooth_future_time = _elm_atof(s); // not used anymore
2645    s = _getenv_once("ELM_SCROLL_SMOOTH_TIME_WINDOW");
2646    if (s) _elm_config->scroll_smooth_time_window = _elm_atof(s);
2647    s = _getenv_once("ELM_FOCUS_AUTOSCROLL_MODE");
2648    if (s)
2649      {
2650         if (!strcmp(s, "ELM_FOCUS_AUTOSCROLL_MODE_NONE"))
2651           _elm_config->focus_autoscroll_mode = ELM_FOCUS_AUTOSCROLL_MODE_NONE;
2652         else if (!strcmp(s, "ELM_FOCUS_AUTOSCROLL_MODE_BRING_IN"))
2653           _elm_config->focus_autoscroll_mode = ELM_FOCUS_AUTOSCROLL_MODE_BRING_IN;
2654         else
2655           _elm_config->focus_autoscroll_mode = ELM_FOCUS_AUTOSCROLL_MODE_SHOW;
2656      }
2657    s = _getenv_once("ELM_SLIDER_INDICATOR_VISIBLE_MODE");
2658    if (s)
2659      {
2660         if (!strcmp(s, "ELM_SLIDER_INDICATOR_VISIBLE_MODE_DEFAULT"))
2661           _elm_config->slider_indicator_visible_mode = ELM_SLIDER_INDICATOR_VISIBLE_MODE_DEFAULT;
2662         else if (!strcmp(s, "ELM_SLIDER_INDICATOR_VISIBLE_MODE_ALWAYS"))
2663           _elm_config->slider_indicator_visible_mode = ELM_SLIDER_INDICATOR_VISIBLE_MODE_ALWAYS;
2664         else if (!strcmp(s, "ELM_SLIDER_INDICATOR_VISIBLE_MODE_ON_FOCUS"))
2665           _elm_config->slider_indicator_visible_mode = ELM_SLIDER_INDICATOR_VISIBLE_MODE_ON_FOCUS;
2666         else
2667           _elm_config->slider_indicator_visible_mode = ELM_SLIDER_INDICATOR_VISIBLE_MODE_NONE;
2668      }
2669    s = _getenv_once("ELM_THEME");
2670    if (s) eina_stringshare_replace(&_elm_config->theme, s);
2671 
2672    s = _getenv_once("ELM_FONT_HINTING");
2673    if (s)
2674      {
2675         if      (!strcasecmp(s, "none")) _elm_config->font_hinting = 0;
2676         else if (!strcasecmp(s, "auto"))
2677           _elm_config->font_hinting = 1;
2678         else if (!strcasecmp(s, "bytecode"))
2679           _elm_config->font_hinting = 2;
2680      }
2681 
2682    s = _getenv_once("ELM_FONT_PATH");
2683    if (s)
2684      {
2685         const char *p, *pp;
2686         char *buf2;
2687 
2688         EINA_LIST_FREE(_elm_config->font_dirs, p)
2689           {
2690              eina_stringshare_del(p);
2691           }
2692 
2693         buf2 = alloca(strlen(s) + 1);
2694         p = s;
2695         pp = p;
2696         for (;; )
2697           {
2698              if ((*p == ':') || (*p == 0))
2699                {
2700                   int len;
2701 
2702                   len = p - pp;
2703                   strncpy(buf2, pp, len);
2704                   buf2[len] = 0;
2705                   _elm_config->font_dirs =
2706                     eina_list_append(_elm_config->font_dirs,
2707                                      eina_stringshare_add(buf2));
2708                   if (*p == 0) break;
2709                   p++;
2710                   pp = p;
2711                }
2712              else
2713                {
2714                   if (*p == 0) break;
2715                   p++;
2716                }
2717           }
2718      }
2719 
2720    s = _getenv_once("ELM_IMAGE_CACHE");
2721    if (s) _elm_config->image_cache = atoi(s);
2722 
2723    s = _getenv_once("ELM_FONT_CACHE");
2724    if (s) _elm_config->font_cache = atoi(s);
2725 
2726    s = _getenv_once("ELM_SCALE");
2727    if (s) _elm_config->scale = _elm_atof(s);
2728 
2729    s = _getenv_once("ELM_FINGER_SIZE");
2730    if (s) _elm_config->finger_size = atoi(s);
2731 
2732    s = _getenv_once("ELM_PASSWORD_SHOW_LAST");
2733    if (s) _elm_config->password_show_last = !!atoi(s);
2734 
2735    s = _getenv_once("ELM_PASSWORD_SHOW_LAST_TIMEOUT");
2736    if (s)
2737      {
2738         double pw_show_last_timeout = _elm_atof(s);
2739         if (pw_show_last_timeout >= 0.0)
2740           _elm_config->password_show_last_timeout = pw_show_last_timeout;
2741      }
2742 
2743    s = _getenv_once("ELM_FPS");
2744    if (s) _elm_config->fps = _elm_atof(s);
2745    if (_elm_config->fps < 1.0) _elm_config->fps = 1.0;
2746 
2747    s = _getenv_once("ELM_MODULES");
2748    if (s) eina_stringshare_replace(&_elm_config->modules, s);
2749 
2750    s = _getenv_once("ELM_TOOLTIP_DELAY");
2751    if (s)
2752      {
2753         double delay = _elm_atof(s);
2754         if (delay >= 0.0)
2755           _elm_config->tooltip_delay = delay;
2756      }
2757 
2758    s = _getenv_once("ELM_CURSOR_ENGINE_ONLY");
2759    if (s) _elm_config->cursor_engine_only = !!atoi(s);
2760 
2761    s = _getenv_once("ELM_FOCUS_HIGHLIGHT_ENABLE");
2762    if (s) _elm_config->focus_highlight_enable = !!atoi(s);
2763 
2764    s = _getenv_once("ELM_FOCUS_HIGHLIGHT_ANIMATE");
2765    if (s) _elm_config->focus_highlight_animate = !!atoi(s);
2766 
2767    s = _getenv_once("ELM_FOCUS_HIGHLIGHT_CLIP_DISABLE");
2768    if (s) _elm_config->focus_highlight_clip_disable = !!atoi(s);
2769 
2770    s = _getenv_once("ELM_FOCUS_MOVE_POLICY");
2771    if (s) _elm_config->focus_move_policy = !!atoi(s);
2772 
2773    s = _getenv_once("ELM_ITEM_SELECT_ON_FOCUS_DISABLE");
2774    if (s) _elm_config->item_select_on_focus_disable = !!atoi(s);
2775 
2776    s = _getenv_once("ELM_FIRST_ITEM_FOCUS_ON_FIRST_FOCUS_IN");
2777    if (s) _elm_config->first_item_focus_on_first_focus_in = !!atoi(s);
2778 
2779    s = _getenv_once("ELM_TOOLBAR_SHRINK_MODE");
2780    if (s) _elm_config->toolbar_shrink_mode = atoi(s);
2781 
2782    s = _getenv_once("ELM_FILESELECTOR_EXPAND_ENABLE");
2783    if (s) _elm_config->fileselector_expand_enable = !!atoi(s);
2784 
2785    s = _getenv_once("ELM_FILESELECTOR_DOUBLE_TAP_NAVIGATION_ENABLE");
2786    if (s) _elm_config->fileselector_double_tap_navigation_enable = !!atoi(s);
2787 
2788    s = _getenv_once("ELM_INWIN_DIALOGS_ENABLE");
2789    if (s) _elm_config->inwin_dialogs_enable = !!atoi(s);
2790 
2791    s = _getenv_once("ELM_ICON_SIZE");
2792    if (s) _elm_config->icon_size = atoi(s);
2793 
2794    s = _getenv_once("ELM_CONTEXT_MENU_DISABLED");
2795    if (s) _elm_config->context_menu_disabled = !!atoi(s);
2796 
2797    s = _getenv_once("ELM_LONGPRESS_TIMEOUT");
2798    if (s) _elm_config->longpress_timeout = _elm_atof(s);
2799    if (_elm_config->longpress_timeout < 0.0)
2800      _elm_config->longpress_timeout = 0.0;
2801 
2802    s = _getenv_once("ELM_EFFECT_ENABLE");
2803    if (s) _elm_config->effect_enable = !!atoi(s);
2804 
2805    s = _getenv_once("ELM_DESKTOP_ENTRY");
2806    if (s) _elm_config->desktop_entry = !!atoi(s);
2807    s = _getenv_once("ELM_ACCESS_MODE");
2808    if (s) _elm_config->access_mode = ELM_ACCESS_MODE_ON;
2809 
2810    s = _getenv_once("ELM_SELECTION_CLEAR_ENABLE");
2811    if (s) _elm_config->selection_clear_enable = !!atoi(s);
2812 
2813    s = _getenv_once("ELM_AUTO_THROTTLE");
2814    if (s) _elm_config->auto_throttle = EINA_TRUE;
2815    s = _getenv_once("ELM_AUTO_THROTTLE_AMOUNT");
2816    if (s) _elm_config->auto_throttle_amount = _elm_atof(s);
2817    s = _getenv_once("ELM_AUTO_NORENDER_WITHDRAWN");
2818    if (s) _elm_config->auto_norender_withdrawn = EINA_TRUE;
2819    s = _getenv_once("ELM_AUTO_NORENDER_ICONIFIED_SAME_AS_WITHDRAWN");
2820    if (s) _elm_config->auto_norender_iconified_same_as_withdrawn = EINA_TRUE;
2821    s = _getenv_once("ELM_AUTO_FLUSH_WITHDRAWN");
2822    if (s) _elm_config->auto_flush_withdrawn = EINA_TRUE;
2823    s = _getenv_once("ELM_AUTO_DUMP_WIDTHDRAWN");
2824    if (s) _elm_config->auto_dump_withdrawn = EINA_TRUE;
2825 
2826    s = _getenv_once("ELM_INDICATOR_SERVICE_0");
2827    if (s) eina_stringshare_replace(&_elm_config->indicator_service_0, s);
2828    s = _getenv_once("ELM_INDICATOR_SERVICE_90");
2829    if (s) eina_stringshare_replace(&_elm_config->indicator_service_90, s);
2830    s = _getenv_once("ELM_INDICATOR_SERVICE_180");
2831    if (s) eina_stringshare_replace(&_elm_config->indicator_service_180, s);
2832    s = _getenv_once("ELM_INDICATOR_SERVICE_270");
2833    if (s) eina_stringshare_replace(&_elm_config->indicator_service_270, s);
2834    s = _getenv_once("ELM_DISABLE_EXTERNAL_MENU");
2835    if (s) _elm_config->disable_external_menu = !!atoi(s);
2836 
2837    s = _getenv_once("ELM_CLOUSEAU");
2838    if (s) _elm_config->clouseau_enable = atoi(s);
2839    s = _getenv_once("ELM_MAGNIFIER_ENABLE");
2840    if (s) _elm_config->magnifier_enable = !!atoi(s);
2841    s = _getenv_once("ELM_MAGNIFIER_SCALE");
2842    if (s) _elm_config->magnifier_scale = _elm_atof(s);
2843    s = _getenv_once("ELM_ATSPI_MODE");
2844    if (s) _elm_config->atspi_mode = ELM_ATSPI_MODE_ON;
2845    s = _getenv_once("ELM_SPINNER_MIN_MAX_FILTER_ENABLE");
2846    if (s) _elm_config->spinner_min_max_filter_enable = !!atoi(s);
2847 
2848    s = _getenv_once("ELM_TRANSITION_DURATION_FACTOR");
2849    if (s) _elm_config->transition_duration_factor = atof(s);
2850 
2851    s = _getenv_once("ELM_POPUP_HORIZONTAL_ALIGN");
2852    if (s) _elm_config->popup_horizontal_align = _elm_atof(s);
2853    s = _getenv_once("ELM_POPUP_VERTICAL_ALIGN");
2854    if (s) _elm_config->popup_vertical_align = _elm_atof(s);
2855    s = _getenv_once("ELM_POPUP_SCROLLABLE");
2856    if (s) _elm_config->popup_scrollable = atoi(s);
2857 
2858    s = _getenv_once("ELM_GLAYER_TAP_FINGER_SIZE");
2859    if (s) _elm_config->glayer_tap_finger_size = atoi(s);
2860 
2861    s = _getenv_once("EFL_UI_DND_DRAG_ANIM_DURATION");
2862    if (s) _elm_config->drag_anim_duration = _elm_atof(s);
2863 
2864    s = _getenv_once("ELM_WIN_NO_BORDER");
2865    if (s) _elm_config->win_no_border = EINA_TRUE;
2866 }
2867 
2868 static void
_elm_config_key_binding_hash(void)2869 _elm_config_key_binding_hash(void)
2870 {
2871    Elm_Config_Bindings_Widget *wb;
2872    Eina_List *l;
2873 
2874    if (_elm_key_bindings)
2875      eina_hash_free(_elm_key_bindings);
2876 
2877    _elm_key_bindings = eina_hash_string_superfast_new(NULL);
2878    EINA_LIST_FOREACH(_elm_config->bindings, l, wb)
2879      {
2880         if (wb->name)
2881           {
2882              char *namelower = alloca(strlen(wb->name) + 1);
2883 
2884              strcpy(namelower, wb->name);
2885              eina_str_tolower(&namelower);
2886              eina_hash_add(_elm_key_bindings, namelower, wb->key_bindings);
2887           }
2888      }
2889 }
2890 
2891 static Eina_Bool
_elm_config_modifier_check(const Evas_Modifier * m,Eina_List * mod_list)2892 _elm_config_modifier_check(const Evas_Modifier *m,
2893                            Eina_List *mod_list)
2894 {
2895    Eina_List *l;
2896    Elm_Config_Binding_Modifier *mod;
2897    EINA_LIST_FOREACH(mod_list, l, mod)
2898      {
2899         if ((evas_key_modifier_is_set(m, mod->mod)) ^ (mod->flag))
2900           return EINA_FALSE;
2901      }
2902    return EINA_TRUE;
2903 }
2904 
2905 Eina_Bool
_elm_config_key_binding_call(Evas_Object * obj,const char * name,const Evas_Event_Key_Down * ev,const Elm_Action * actions)2906 _elm_config_key_binding_call(Evas_Object *obj,
2907                              const char *name,
2908                              const Evas_Event_Key_Down *ev,
2909                              const Elm_Action *actions)
2910 {
2911    Elm_Config_Binding_Key *binding;
2912    Eina_List *binding_list, *l;
2913    char *namelower;
2914    int i = 0;
2915 
2916    namelower = alloca(strlen(name) + 1);
2917    strcpy(namelower, name);
2918    eina_str_tolower(&namelower);
2919 
2920    binding_list = eina_hash_find(_elm_key_bindings, namelower);
2921 
2922    if (binding_list)
2923      {
2924         EINA_LIST_FOREACH(binding_list, l, binding)
2925           {
2926              if (binding->key && (!strcmp(binding->key, ev->key))
2927                  && _elm_config_modifier_check(ev->modifiers, binding->modifiers))
2928                {
2929                   while (actions[i].name)
2930                     {
2931                        if (!strcmp(binding->action, actions[i].name))
2932                          return actions[i].func(obj, binding->params);
2933                        i++;
2934                     }
2935                   break;
2936                }
2937           }
2938      }
2939    return EINA_FALSE;
2940 }
2941 
2942 EAPI Eina_Bool
elm_config_mirrored_get(void)2943 elm_config_mirrored_get(void)
2944 {
2945    return _elm_config->is_mirrored;
2946 }
2947 
2948 EAPI void
elm_config_mirrored_set(Eina_Bool mirrored)2949 elm_config_mirrored_set(Eina_Bool mirrored)
2950 {
2951    mirrored = !!mirrored;
2952    if (_elm_config->is_mirrored == mirrored) return;
2953    _elm_config->is_mirrored = mirrored;
2954    _elm_rescale();
2955 }
2956 
2957 EAPI Eina_Bool
elm_config_cursor_engine_only_get(void)2958 elm_config_cursor_engine_only_get(void)
2959 {
2960    return _elm_config->cursor_engine_only;
2961 }
2962 
2963 EAPI void
elm_config_cursor_engine_only_set(Eina_Bool engine_only)2964 elm_config_cursor_engine_only_set(Eina_Bool engine_only)
2965 {
2966    _elm_config->priv.cursor_engine_only = EINA_TRUE;
2967    engine_only = !!engine_only;
2968    _elm_config->cursor_engine_only = engine_only;
2969 }
2970 
2971 EAPI double
elm_config_tooltip_delay_get(void)2972 elm_config_tooltip_delay_get(void)
2973 {
2974    return _elm_config->tooltip_delay;
2975 }
2976 
2977 EAPI void
elm_config_tooltip_delay_set(double delay)2978 elm_config_tooltip_delay_set(double delay)
2979 {
2980    _elm_config->priv.tooltip_delay = EINA_TRUE;
2981    if (delay < 0.0) return;
2982    _elm_config->tooltip_delay = delay;
2983 }
2984 
2985 EAPI double
elm_config_scale_get(void)2986 elm_config_scale_get(void)
2987 {
2988    return _elm_config->scale;
2989 }
2990 
2991 EAPI void
elm_config_scale_set(double scale)2992 elm_config_scale_set(double scale)
2993 {
2994    _elm_config->priv.scale = EINA_TRUE;
2995    if (scale < 0.0) return;
2996    if (EINA_DBL_EQ(_elm_config->scale, scale)) return;
2997    _elm_config->scale = scale;
2998    _elm_rescale();
2999 }
3000 
3001 EAPI const char *
elm_config_icon_theme_get(void)3002 elm_config_icon_theme_get(void)
3003 {
3004    if (!_elm_config->icon_theme)
3005      return ELM_CONFIG_ICON_THEME_ELEMENTARY;
3006 
3007    return _elm_config->icon_theme;
3008 }
3009 
3010 EAPI void
elm_config_icon_theme_set(const char * theme)3011 elm_config_icon_theme_set(const char *theme)
3012 {
3013    _elm_config->priv.icon_theme = EINA_TRUE;
3014    eina_stringshare_del(_elm_config->icon_theme);
3015 
3016    if (theme)
3017      _elm_config->icon_theme = eina_stringshare_add(theme);
3018    else
3019      _elm_config->icon_theme = eina_stringshare_add(ELM_CONFIG_ICON_THEME_ELEMENTARY);
3020 }
3021 
3022 EAPI Eina_Bool
elm_config_password_show_last_get(void)3023 elm_config_password_show_last_get(void)
3024 {
3025    return _elm_config->password_show_last;
3026 }
3027 
3028 EAPI void
elm_config_password_show_last_set(Eina_Bool password_show_last)3029 elm_config_password_show_last_set(Eina_Bool password_show_last)
3030 {
3031    _elm_config->priv.password_show_last = EINA_TRUE;
3032    if (_elm_config->password_show_last == password_show_last) return;
3033    _elm_config->password_show_last = password_show_last;
3034    edje_password_show_last_set(_elm_config->password_show_last);
3035 }
3036 
3037 EAPI double
elm_config_password_show_last_timeout_get(void)3038 elm_config_password_show_last_timeout_get(void)
3039 {
3040    return _elm_config->password_show_last_timeout;
3041 }
3042 
3043 EAPI void
elm_config_password_show_last_timeout_set(double password_show_last_timeout)3044 elm_config_password_show_last_timeout_set(double password_show_last_timeout)
3045 {
3046    _elm_config->priv.password_show_last_timeout = EINA_TRUE;
3047    if (password_show_last_timeout < 0.0) return;
3048    if (EINA_DBL_EQ(_elm_config->password_show_last_timeout, password_show_last_timeout)) return;
3049    _elm_config->password_show_last_timeout = password_show_last_timeout;
3050    edje_password_show_last_timeout_set(_elm_config->password_show_last_timeout);
3051 }
3052 
3053 EAPI Eina_Bool
elm_config_save(void)3054 elm_config_save(void)
3055 {
3056    return _elm_config_save(_elm_config, NULL);
3057 }
3058 
3059 EAPI void
elm_config_reload(void)3060 elm_config_reload(void)
3061 {
3062    _elm_config_reload();
3063 }
3064 
3065 EAPI const char *
elm_config_profile_get(void)3066 elm_config_profile_get(void)
3067 {
3068    return _elm_config_current_profile_get();
3069 }
3070 
3071 EAPI const char *
elm_config_profile_dir_get(const char * profile,Eina_Bool is_user)3072 elm_config_profile_dir_get(const char *profile,
3073                     Eina_Bool   is_user)
3074 {
3075    return _elm_config_profile_dir_get(profile, is_user);
3076 }
3077 
3078 EAPI void
elm_config_profile_dir_free(const char * p_dir)3079 elm_config_profile_dir_free(const char *p_dir)
3080 {
3081    // Don't change this: EO relies on free() to be used.
3082    free((void *)p_dir);
3083 }
3084 
3085 EAPI Eina_List *
elm_config_profile_list_get(void)3086 elm_config_profile_list_get(void)
3087 {
3088    return _elm_config_profiles_list(EINA_TRUE);
3089 }
3090 
3091 EAPI Eina_List *
elm_config_profile_list_full_get(void)3092 elm_config_profile_list_full_get(void)
3093 {
3094    return _elm_config_profiles_list(EINA_FALSE);
3095 }
3096 
3097 EAPI void
elm_config_profile_list_free(Eina_List * l)3098 elm_config_profile_list_free(Eina_List *l)
3099 {
3100    const char *dir;
3101 
3102    EINA_LIST_FREE(l, dir)
3103      eina_stringshare_del(dir);
3104 }
3105 
3106 EAPI Eina_Bool
elm_config_profile_exists(const char * profile)3107 elm_config_profile_exists(const char *profile)
3108 {
3109    char buf[PATH_MAX], buf2[PATH_MAX];
3110 
3111    if (!profile) return EINA_FALSE;
3112 
3113    if (_running_in_tree)
3114      {
3115         if (!bs_data_path_get(buf, sizeof(buf), "elementary/config", profile)) return EINA_FALSE;
3116         return ecore_file_exists(buf);
3117      }
3118    _elm_config_user_dir_snprintf(buf, sizeof(buf),
3119                                  "config/%s/base.cfg", profile);
3120    if (ecore_file_exists(buf)) return EINA_TRUE;
3121 
3122    snprintf(buf2, sizeof(buf2), "config/%s/base.cfg", profile);
3123    eina_str_join_len(buf, sizeof(buf), '/',
3124                      _elm_data_dir, strlen(_elm_data_dir),
3125                      buf2, strlen(buf2));
3126    if (ecore_file_exists(buf)) return EINA_TRUE;
3127    return EINA_FALSE;
3128 }
3129 
3130 EAPI void
elm_config_profile_set(const char * profile)3131 elm_config_profile_set(const char *profile)
3132 {
3133    EINA_SAFETY_ON_NULL_RETURN(profile);
3134    _elm_config_profile_set(profile);
3135 }
3136 
3137 EAPI void
elm_config_profile_save(const char * profile)3138 elm_config_profile_save(const char *profile)
3139 {
3140    EINA_SAFETY_ON_NULL_RETURN(profile);
3141    _elm_config_save(_elm_config, profile);
3142 }
3143 
3144 EAPI const char *
elm_config_engine_get(void)3145 elm_config_engine_get(void)
3146 {
3147    return _elm_config->engine;
3148 }
3149 
3150 EAPI void
elm_config_engine_set(const char * engine)3151 elm_config_engine_set(const char *engine)
3152 {
3153    EINA_SAFETY_ON_NULL_RETURN(engine);
3154 
3155    _elm_config_engine_set(engine);
3156 }
3157 
3158 EAPI Eina_List *
elm_config_text_classes_list_get(void)3159 elm_config_text_classes_list_get(void)
3160 {
3161    return _elm_config_text_classes_get();
3162 }
3163 
3164 EAPI void
elm_config_text_classes_list_free(Eina_List * list)3165 elm_config_text_classes_list_free(Eina_List *list)
3166 {
3167    _elm_config_text_classes_free(list);
3168 }
3169 
3170 EAPI const Eina_List *
elm_config_font_overlay_list_get(void)3171 elm_config_font_overlay_list_get(void)
3172 {
3173    return _elm_config_font_overlays_list();
3174 }
3175 
3176 EAPI Eina_Bool
elm_config_access_get(void)3177 elm_config_access_get(void)
3178 {
3179    return _elm_config_access_get();
3180 }
3181 
3182 EAPI void
elm_config_access_set(Eina_Bool is_access)3183 elm_config_access_set(Eina_Bool is_access)
3184 {
3185    _elm_config->priv.access_mode = EINA_TRUE;
3186    _elm_config_access_set(is_access);
3187 }
3188 
3189 EAPI Eina_Bool
elm_config_atspi_mode_get(void)3190 elm_config_atspi_mode_get(void)
3191 {
3192    return _elm_config_atspi_mode_get();
3193 }
3194 
3195 EAPI void
elm_config_atspi_mode_set(Eina_Bool is_enable)3196 elm_config_atspi_mode_set(Eina_Bool is_enable)
3197 {
3198    _elm_config_atspi_mode_set(is_enable);
3199 }
3200 
3201 EAPI Eina_Bool
elm_config_selection_unfocused_clear_get(void)3202 elm_config_selection_unfocused_clear_get(void)
3203 {
3204    return _elm_config_selection_unfocused_clear_get();
3205 }
3206 
3207 EAPI void
elm_config_selection_unfocused_clear_set(Eina_Bool enabled)3208 elm_config_selection_unfocused_clear_set(Eina_Bool enabled)
3209 {
3210    _elm_config->priv.selection_clear_enable = EINA_TRUE;
3211    _elm_config_selection_unfocused_clear_set(enabled);
3212 }
3213 
3214 EAPI void
elm_config_font_overlay_set(const char * text_class,const char * font,Evas_Font_Size size)3215 elm_config_font_overlay_set(const char    *text_class,
3216                      const char    *font,
3217                      Evas_Font_Size size)
3218 {
3219    _elm_config->priv.font_overlays = EINA_TRUE;
3220    EINA_SAFETY_ON_NULL_RETURN(text_class);
3221    _elm_config_font_overlay_set(text_class, font, size);
3222 }
3223 
3224 EAPI void
elm_config_font_overlay_unset(const char * text_class)3225 elm_config_font_overlay_unset(const char *text_class)
3226 {
3227    _elm_config->priv.font_overlays = EINA_TRUE;
3228    EINA_SAFETY_ON_NULL_RETURN(text_class);
3229    _elm_config_font_overlay_remove(text_class);
3230 }
3231 
3232 EAPI void
elm_config_font_overlay_apply(void)3233 elm_config_font_overlay_apply(void)
3234 {
3235    _elm_config_font_overlay_apply();
3236    _elm_rescale();
3237 }
3238 
3239 EAPI Eina_List *
elm_config_color_classes_list_get(void)3240 elm_config_color_classes_list_get(void)
3241 {
3242    return _elm_config_color_classes_get();
3243 }
3244 
3245 EAPI void
elm_config_color_classes_list_free(Eina_List * list)3246 elm_config_color_classes_list_free(Eina_List *list)
3247 {
3248    _elm_config_color_classes_free(list);
3249 }
3250 
3251 EAPI const Eina_List *
elm_config_color_overlay_list_get(void)3252 elm_config_color_overlay_list_get(void)
3253 {
3254    return _elm_config_color_overlays_list();
3255 }
3256 
3257 EAPI void
elm_config_color_overlay_set(const char * color_class,int r,int g,int b,int a,int r2,int g2,int b2,int a2,int r3,int g3,int b3,int a3)3258 elm_config_color_overlay_set(const char *color_class,
3259                              int r, int g, int b, int a,
3260                              int r2, int g2, int b2, int a2,
3261                              int r3, int g3, int b3, int a3)
3262 {
3263    _elm_config->priv.color_overlays = EINA_TRUE;
3264    EINA_SAFETY_ON_NULL_RETURN(color_class);
3265    _elm_config_color_overlay_set(color_class,
3266                                  r, g, b, a,
3267                                  r2, g2, b2, a2,
3268                                  r3, g3, b3, a3);
3269 }
3270 
3271 EAPI void
elm_config_color_overlay_unset(const char * color_class)3272 elm_config_color_overlay_unset(const char *color_class)
3273 {
3274    _elm_config->priv.color_overlays = EINA_TRUE;
3275    EINA_SAFETY_ON_NULL_RETURN(color_class);
3276    _elm_config_color_overlay_remove(color_class);
3277 }
3278 
3279 EAPI void
elm_config_color_overlay_apply(void)3280 elm_config_color_overlay_apply(void)
3281 {
3282    _elm_config_color_overlay_apply();
3283 }
3284 
3285 EAPI Evas_Coord
elm_config_finger_size_get(void)3286 elm_config_finger_size_get(void)
3287 {
3288    return _elm_config->finger_size;
3289 }
3290 
3291 EAPI void
elm_config_finger_size_set(Evas_Coord size)3292 elm_config_finger_size_set(Evas_Coord size)
3293 {
3294    _elm_config->priv.finger_size = EINA_TRUE;
3295    if (size < 0) return;
3296    if (_elm_config->finger_size == size) return;
3297    _elm_config->finger_size = size;
3298    _elm_rescale();
3299 }
3300 
3301 EAPI int
elm_config_cache_flush_interval_get(void)3302 elm_config_cache_flush_interval_get(void)
3303 {
3304    return _elm_config->cache_flush_poll_interval;
3305 }
3306 
3307 EAPI void
elm_config_cache_flush_interval_set(int size)3308 elm_config_cache_flush_interval_set(int size)
3309 {
3310    _elm_config->priv.cache_flush_poll_interval = EINA_TRUE;
3311    EINA_SAFETY_ON_FALSE_RETURN(size > 0);
3312    if (_elm_config->cache_flush_poll_interval == size) return;
3313    _elm_config->cache_flush_poll_interval = size;
3314 
3315    _elm_recache();
3316 }
3317 
3318 EAPI Eina_Bool
elm_config_cache_flush_enabled_get(void)3319 elm_config_cache_flush_enabled_get(void)
3320 {
3321    return _elm_config->cache_flush_enable;
3322 }
3323 
3324 EAPI void
elm_config_cache_flush_enabled_set(Eina_Bool enabled)3325 elm_config_cache_flush_enabled_set(Eina_Bool enabled)
3326 {
3327    _elm_config->priv.cache_flush_enable = EINA_TRUE;
3328    enabled = !!enabled;
3329    if (_elm_config->cache_flush_enable == enabled) return;
3330    _elm_config->cache_flush_enable = enabled;
3331 
3332    _elm_recache();
3333 }
3334 
3335 EAPI int
elm_config_cache_font_cache_size_get(void)3336 elm_config_cache_font_cache_size_get(void)
3337 {
3338    return _elm_config->font_cache;
3339 }
3340 
3341 EAPI void
elm_config_cache_font_cache_size_set(int size)3342 elm_config_cache_font_cache_size_set(int size)
3343 {
3344    _elm_config->priv.font_cache = EINA_TRUE;
3345    if (size < 0) return;
3346    if (_elm_config->font_cache == size) return;
3347    _elm_config->font_cache = size;
3348 
3349    _elm_recache();
3350 }
3351 
3352 EAPI int
elm_config_cache_image_cache_size_get(void)3353 elm_config_cache_image_cache_size_get(void)
3354 {
3355    return _elm_config->image_cache;
3356 }
3357 
3358 EAPI void
elm_config_cache_image_cache_size_set(int size)3359 elm_config_cache_image_cache_size_set(int size)
3360 {
3361    _elm_config->priv.image_cache = EINA_TRUE;
3362    if (size < 0) return;
3363    if (_elm_config->image_cache == size) return;
3364    _elm_config->image_cache = size;
3365 
3366    _elm_recache();
3367 }
3368 
3369 EAPI void
elm_config_font_hint_type_set(int type)3370 elm_config_font_hint_type_set(int type)
3371 {
3372    Eina_List *l;
3373    Evas_Object *win;
3374 
3375    _elm_config->priv.font_hinting = EINA_TRUE;
3376    if ((type < 0) || (type > 2)) return;
3377    _elm_config->font_hinting = type;
3378 
3379    EINA_LIST_FOREACH(_elm_win_list, l, win)
3380      {
3381         Evas *e = evas_object_evas_get(win);
3382 
3383         if (!_elm_config->font_hinting)
3384           evas_font_hinting_set(e, EVAS_FONT_HINTING_NONE);
3385         else if (_elm_config->font_hinting == 1)
3386           evas_font_hinting_set(e, EVAS_FONT_HINTING_AUTO);
3387         else if (_elm_config->font_hinting == 2)
3388           evas_font_hinting_set(e, EVAS_FONT_HINTING_BYTECODE);
3389      }
3390 }
3391 
3392 EAPI int
elm_config_cache_edje_file_cache_size_get()3393 elm_config_cache_edje_file_cache_size_get()
3394 {
3395    return _elm_config->edje_cache;
3396 }
3397 
3398 EAPI void
elm_config_cache_edje_file_cache_size_set(int size)3399 elm_config_cache_edje_file_cache_size_set(int size)
3400 {
3401    _elm_config->priv.edje_cache = EINA_TRUE;
3402    if (size < 0) return;
3403    if (_elm_config->edje_cache == size) return;
3404    _elm_config->edje_cache = size;
3405 
3406    _elm_recache();
3407 }
3408 
3409 EAPI int
elm_config_cache_edje_collection_cache_size_get(void)3410 elm_config_cache_edje_collection_cache_size_get(void)
3411 {
3412    return _elm_config->edje_collection_cache;
3413 }
3414 
3415 EAPI void
elm_config_cache_edje_collection_cache_size_set(int size)3416 elm_config_cache_edje_collection_cache_size_set(int size)
3417 {
3418    _elm_config->priv.edje_collection_cache = EINA_TRUE;
3419    if (_elm_config->edje_collection_cache == size) return;
3420    _elm_config->edje_collection_cache = size;
3421 
3422    _elm_recache();
3423 }
3424 
3425 EAPI Eina_Bool
elm_config_vsync_get(void)3426 elm_config_vsync_get(void)
3427 {
3428    return _elm_config->vsync;
3429 }
3430 
3431 EAPI void
elm_config_vsync_set(Eina_Bool enabled)3432 elm_config_vsync_set(Eina_Bool enabled)
3433 {
3434    _elm_config->priv.vsync = EINA_TRUE;
3435    _elm_config->vsync = enabled;
3436 }
3437 
3438 EAPI Eina_Bool
elm_config_agressive_withdrawn_get(void)3439 elm_config_agressive_withdrawn_get(void)
3440 {
3441    return _elm_config->auto_norender_withdrawn &&
3442      _elm_config->auto_norender_iconified_same_as_withdrawn &&
3443      _elm_config->auto_flush_withdrawn &&
3444      _elm_config->auto_dump_withdrawn;
3445 }
3446 
3447 EAPI void
elm_config_agressive_withdrawn_set(Eina_Bool enabled)3448 elm_config_agressive_withdrawn_set(Eina_Bool enabled)
3449 {
3450    _elm_config->auto_norender_withdrawn = enabled;
3451    _elm_config->auto_norender_iconified_same_as_withdrawn = enabled;
3452    _elm_config->auto_flush_withdrawn = enabled;
3453    _elm_config->auto_dump_withdrawn = enabled;
3454 }
3455 
3456 EAPI Eina_Bool
elm_config_accel_preference_override_get(void)3457 elm_config_accel_preference_override_get(void)
3458 {
3459    return _elm_config->accel_override;
3460 }
3461 
3462 EAPI void
elm_config_accel_preference_override_set(Eina_Bool enabled)3463 elm_config_accel_preference_override_set(Eina_Bool enabled)
3464 {
3465    _elm_config->priv.accel_override = EINA_TRUE;
3466    _elm_config->accel_override = enabled;
3467 }
3468 
3469 EAPI Eina_Bool
elm_config_focus_highlight_enabled_get(void)3470 elm_config_focus_highlight_enabled_get(void)
3471 {
3472    return _elm_config->focus_highlight_enable;
3473 }
3474 
3475 EAPI void
elm_config_focus_highlight_enabled_set(Eina_Bool enable)3476 elm_config_focus_highlight_enabled_set(Eina_Bool enable)
3477 {
3478    _elm_config->priv.focus_highlight_enable = EINA_TRUE;
3479    _elm_config->focus_highlight_enable = !!enable;
3480 }
3481 
3482 EAPI Eina_Bool
elm_config_focus_highlight_animate_get(void)3483 elm_config_focus_highlight_animate_get(void)
3484 {
3485    return _elm_config->focus_highlight_animate;
3486 }
3487 
3488 EAPI void
elm_config_focus_highlight_animate_set(Eina_Bool animate)3489 elm_config_focus_highlight_animate_set(Eina_Bool animate)
3490 {
3491    _elm_config->priv.focus_highlight_animate = EINA_TRUE;
3492    _elm_config->focus_highlight_animate = !!animate;
3493 }
3494 
3495 EAPI Eina_Bool
elm_config_focus_highlight_clip_disabled_get(void)3496 elm_config_focus_highlight_clip_disabled_get(void)
3497 {
3498    return _elm_config->focus_highlight_clip_disable;
3499 }
3500 
3501 EAPI void
elm_config_focus_highlight_clip_disabled_set(Eina_Bool disable)3502 elm_config_focus_highlight_clip_disabled_set(Eina_Bool disable)
3503 {
3504    _elm_config->priv.focus_highlight_clip_disable = EINA_TRUE;
3505    _elm_config->focus_highlight_clip_disable = !!disable;
3506 }
3507 
3508 EAPI Elm_Focus_Move_Policy
elm_config_focus_move_policy_get(void)3509 elm_config_focus_move_policy_get(void)
3510 {
3511    return _elm_config->focus_move_policy;
3512 }
3513 
3514 static void
_efl_ui_widget_config_reload(Efl_Ui_Widget * obj)3515 _efl_ui_widget_config_reload(Efl_Ui_Widget *obj)
3516 {
3517    Elm_Focus_Move_Policy focus_move_policy = elm_config_focus_move_policy_get();
3518    ELM_WIDGET_DATA_GET_OR_RETURN(obj, sd);
3519    Efl_Ui_Widget *w;
3520 
3521    //reload focus move policy
3522    if (efl_ui_widget_focus_move_policy_automatic_get(obj) &&
3523        (sd->focus_move_policy != focus_move_policy))
3524      {
3525         sd->focus_move_policy = focus_move_policy;
3526      }
3527 
3528    for (unsigned int i = 0; i < eina_array_count(sd->children); ++i)
3529      {
3530         w = eina_array_data_get(sd->children, i);
3531         if (efl_isa(w, EFL_UI_WIDGET_CLASS))
3532           _efl_ui_widget_config_reload(w);
3533      }
3534 }
3535 
3536 void
_elm_win_focus_reconfigure(void)3537 _elm_win_focus_reconfigure(void)
3538 {
3539    const Eina_List *l;
3540    Evas_Object *obj;
3541 
3542    EINA_LIST_FOREACH(_elm_win_list, l, obj)
3543      {
3544         _efl_ui_widget_config_reload(obj);
3545      }
3546 }
3547 
3548 EAPI void
elm_config_focus_move_policy_set(Elm_Focus_Move_Policy policy)3549 elm_config_focus_move_policy_set(Elm_Focus_Move_Policy policy)
3550 {
3551    _elm_config->priv.focus_move_policy = EINA_TRUE;
3552    _elm_config->focus_move_policy = policy;
3553    _elm_win_focus_reconfigure();
3554 }
3555 
3556 EAPI Eina_Bool
elm_config_item_select_on_focus_disabled_get(void)3557 elm_config_item_select_on_focus_disabled_get(void)
3558 {
3559    return _elm_config->item_select_on_focus_disable;
3560 }
3561 
3562 EAPI void
elm_config_item_select_on_focus_disabled_set(Eina_Bool disable)3563 elm_config_item_select_on_focus_disabled_set(Eina_Bool disable)
3564 {
3565    _elm_config->priv.item_select_on_focus_disable = EINA_TRUE;
3566    _elm_config->item_select_on_focus_disable = !!disable;
3567 }
3568 
3569 EAPI Eina_Bool
elm_config_first_item_focus_on_first_focusin_get(void)3570 elm_config_first_item_focus_on_first_focusin_get(void)
3571 {
3572    return _elm_config->first_item_focus_on_first_focus_in;
3573 }
3574 
3575 EAPI void
elm_config_first_item_focus_on_first_focusin_set(Eina_Bool enable)3576 elm_config_first_item_focus_on_first_focusin_set(Eina_Bool enable)
3577 {
3578    _elm_config->priv.first_item_focus_on_first_focus_in = EINA_TRUE;
3579    _elm_config->first_item_focus_on_first_focus_in = !!enable;
3580 }
3581 
3582 EAPI Eina_Bool
elm_config_scroll_bounce_enabled_get(void)3583 elm_config_scroll_bounce_enabled_get(void)
3584 {
3585    return _elm_config->thumbscroll_bounce_enable;
3586 }
3587 
3588 EAPI void
elm_config_scroll_bounce_enabled_set(Eina_Bool enabled)3589 elm_config_scroll_bounce_enabled_set(Eina_Bool enabled)
3590 {
3591    _elm_config->priv.thumbscroll_bounce_enable = EINA_TRUE;
3592    _elm_config->thumbscroll_bounce_enable = enabled;
3593 }
3594 
3595 EAPI double
elm_config_scroll_bounce_friction_get(void)3596 elm_config_scroll_bounce_friction_get(void)
3597 {
3598    return _elm_config->thumbscroll_bounce_friction;
3599 }
3600 
3601 EAPI void
elm_config_scroll_bounce_friction_set(double friction)3602 elm_config_scroll_bounce_friction_set(double friction)
3603 {
3604    _elm_config->priv.thumbscroll_bounce_friction = EINA_TRUE;
3605    _elm_config->thumbscroll_bounce_friction = friction;
3606 }
3607 
3608 EAPI double
elm_config_scroll_page_scroll_friction_get(void)3609 elm_config_scroll_page_scroll_friction_get(void)
3610 {
3611    return _elm_config->page_scroll_friction;
3612 }
3613 
3614 EAPI void
elm_config_scroll_page_scroll_friction_set(double friction)3615 elm_config_scroll_page_scroll_friction_set(double friction)
3616 {
3617    _elm_config->priv.page_scroll_friction = EINA_TRUE;
3618    _elm_config->page_scroll_friction = friction;
3619 }
3620 
3621 EAPI double
elm_config_scroll_bring_in_scroll_friction_get(void)3622 elm_config_scroll_bring_in_scroll_friction_get(void)
3623 {
3624    return _elm_config->bring_in_scroll_friction;
3625 }
3626 
3627 EAPI void
elm_config_scroll_bring_in_scroll_friction_set(double friction)3628 elm_config_scroll_bring_in_scroll_friction_set(double friction)
3629 {
3630    _elm_config->priv.bring_in_scroll_friction = EINA_TRUE;
3631    _elm_config->bring_in_scroll_friction = friction;
3632 }
3633 
3634 EAPI double
elm_config_scroll_zoom_friction_get(void)3635 elm_config_scroll_zoom_friction_get(void)
3636 {
3637    return _elm_config->zoom_friction;
3638 }
3639 
3640 EAPI void
elm_config_scroll_zoom_friction_set(double friction)3641 elm_config_scroll_zoom_friction_set(double friction)
3642 {
3643    _elm_config->zoom_friction = friction;
3644 }
3645 
3646 EAPI Eina_Bool
elm_config_scroll_thumbscroll_enabled_get(void)3647 elm_config_scroll_thumbscroll_enabled_get(void)
3648 {
3649    return _elm_config->thumbscroll_enable;
3650 }
3651 
3652 EAPI void
elm_config_scroll_thumbscroll_enabled_set(Eina_Bool enabled)3653 elm_config_scroll_thumbscroll_enabled_set(Eina_Bool enabled)
3654 {
3655    _elm_config->priv.thumbscroll_enable = EINA_TRUE;
3656    _elm_config->thumbscroll_enable = enabled;
3657 }
3658 
3659 EAPI unsigned int
elm_config_scroll_thumbscroll_threshold_get(void)3660 elm_config_scroll_thumbscroll_threshold_get(void)
3661 {
3662    return _elm_config->thumbscroll_threshold;
3663 }
3664 
3665 EAPI void
elm_config_scroll_thumbscroll_threshold_set(unsigned int threshold)3666 elm_config_scroll_thumbscroll_threshold_set(unsigned int threshold)
3667 {
3668    _elm_config->priv.thumbscroll_threshold = EINA_TRUE;
3669    _elm_config->thumbscroll_threshold = threshold;
3670 }
3671 
3672 EAPI unsigned int
elm_config_scroll_thumbscroll_hold_threshold_get(void)3673 elm_config_scroll_thumbscroll_hold_threshold_get(void)
3674 {
3675    return _elm_config->thumbscroll_hold_threshold;
3676 }
3677 
3678 EAPI void
elm_config_scroll_thumbscroll_hold_threshold_set(unsigned int threshold)3679 elm_config_scroll_thumbscroll_hold_threshold_set(unsigned int threshold)
3680 {
3681    _elm_config->priv.thumbscroll_hold_threshold = EINA_TRUE;
3682    _elm_config->thumbscroll_hold_threshold = threshold;
3683 }
3684 
3685 EAPI double
elm_config_scroll_thumbscroll_momentum_threshold_get(void)3686 elm_config_scroll_thumbscroll_momentum_threshold_get(void)
3687 {
3688    return _elm_config->thumbscroll_momentum_threshold;
3689 }
3690 
3691 EAPI void
elm_config_scroll_thumbscroll_momentum_threshold_set(double threshold)3692 elm_config_scroll_thumbscroll_momentum_threshold_set(double threshold)
3693 {
3694    _elm_config->priv.thumbscroll_momentum_threshold = EINA_TRUE;
3695    _elm_config->thumbscroll_momentum_threshold = threshold;
3696 }
3697 
3698 EAPI unsigned int
elm_config_scroll_thumbscroll_flick_distance_tolerance_get(void)3699 elm_config_scroll_thumbscroll_flick_distance_tolerance_get(void)
3700 {
3701    return _elm_config->thumbscroll_flick_distance_tolerance;
3702 }
3703 
3704 EAPI void
elm_config_scroll_thumbscroll_flick_distance_tolerance_set(unsigned int distance)3705 elm_config_scroll_thumbscroll_flick_distance_tolerance_set(unsigned int distance)
3706 {
3707    _elm_config->priv.thumbscroll_flick_distance_tolerance = EINA_TRUE;
3708    _elm_config->thumbscroll_flick_distance_tolerance = distance;
3709 }
3710 
3711 EAPI unsigned int
elm_config_scroll_thumbscroll_momentum_distance_max_get(void)3712 elm_config_scroll_thumbscroll_momentum_distance_max_get(void)
3713 {
3714    return _elm_config->thumbscroll_momentum_distance_max;
3715 }
3716 
3717 EAPI void
elm_config_scroll_thumbscroll_momentum_distance_max_set(unsigned int distance)3718 elm_config_scroll_thumbscroll_momentum_distance_max_set(unsigned int distance)
3719 {
3720    _elm_config->priv.thumbscroll_momentum_distance_max = EINA_TRUE;
3721    _elm_config->thumbscroll_momentum_distance_max = distance;
3722 }
3723 
3724 EAPI double
elm_config_scroll_thumbscroll_friction_get(void)3725 elm_config_scroll_thumbscroll_friction_get(void)
3726 {
3727    return _elm_config->thumbscroll_friction;
3728 }
3729 
3730 EAPI void
elm_config_scroll_thumbscroll_friction_set(double friction)3731 elm_config_scroll_thumbscroll_friction_set(double friction)
3732 {
3733    _elm_config->priv.thumbscroll_friction = EINA_TRUE;
3734    _elm_config->thumbscroll_friction = friction;
3735 }
3736 
3737 EAPI double
elm_config_scroll_thumbscroll_momentum_friction_get(void)3738 elm_config_scroll_thumbscroll_momentum_friction_get(void)
3739 {
3740    return _elm_config->thumbscroll_momentum_friction;
3741 }
3742 
3743 EAPI void
elm_config_scroll_thumbscroll_momentum_friction_set(double friction)3744 elm_config_scroll_thumbscroll_momentum_friction_set(double friction)
3745 {
3746    _elm_config->priv.thumbscroll_momentum_friction = EINA_TRUE;
3747    _elm_config->thumbscroll_momentum_friction = friction;
3748 }
3749 
3750 EAPI double
elm_config_scroll_thumbscroll_min_friction_get(void)3751 elm_config_scroll_thumbscroll_min_friction_get(void)
3752 {
3753    return _elm_config->thumbscroll_min_friction;
3754 }
3755 
3756 EAPI void
elm_config_scroll_thumbscroll_min_friction_set(double friction)3757 elm_config_scroll_thumbscroll_min_friction_set(double friction)
3758 {
3759    _elm_config->priv.thumbscroll_min_friction = EINA_TRUE;
3760    _elm_config->thumbscroll_min_friction = friction;
3761 }
3762 
3763 EAPI double
elm_config_scroll_thumbscroll_friction_standard_get(void)3764 elm_config_scroll_thumbscroll_friction_standard_get(void)
3765 {
3766    return _elm_config->thumbscroll_friction_standard;
3767 }
3768 
3769 EAPI void
elm_config_scroll_thumbscroll_friction_standard_set(double standard)3770 elm_config_scroll_thumbscroll_friction_standard_set(double standard)
3771 {
3772    _elm_config->priv.thumbscroll_friction_standard = EINA_TRUE;
3773    _elm_config->thumbscroll_friction_standard = standard;
3774 }
3775 
3776 EAPI double
elm_config_scroll_thumbscroll_border_friction_get(void)3777 elm_config_scroll_thumbscroll_border_friction_get(void)
3778 {
3779    return _elm_config->thumbscroll_border_friction;
3780 }
3781 
3782 EAPI void
elm_config_scroll_thumbscroll_border_friction_set(double friction)3783 elm_config_scroll_thumbscroll_border_friction_set(double friction)
3784 {
3785    _elm_config->priv.thumbscroll_border_friction = EINA_TRUE;
3786    if (friction < 0.0) friction = 0.0;
3787    if (friction > 1.0) friction = 1.0;
3788    _elm_config->thumbscroll_border_friction = friction;
3789 }
3790 
3791 EAPI double
elm_config_scroll_thumbscroll_sensitivity_friction_get(void)3792 elm_config_scroll_thumbscroll_sensitivity_friction_get(void)
3793 {
3794    return _elm_config->thumbscroll_sensitivity_friction;
3795 }
3796 
3797 EAPI Eina_Bool
elm_config_context_menu_disabled_get(void)3798 elm_config_context_menu_disabled_get(void)
3799 {
3800    return _elm_config->context_menu_disabled;
3801 }
3802 
3803 EAPI void
elm_config_context_menu_disabled_set(Eina_Bool disabled)3804 elm_config_context_menu_disabled_set(Eina_Bool disabled)
3805 {
3806    _elm_config->priv.context_menu_disabled = EINA_TRUE;
3807    _elm_config->context_menu_disabled = !!disabled;
3808 }
3809 
3810 EAPI void
elm_config_scroll_thumbscroll_sensitivity_friction_set(double friction)3811 elm_config_scroll_thumbscroll_sensitivity_friction_set(double friction)
3812 {
3813    _elm_config->priv.thumbscroll_sensitivity_friction = EINA_TRUE;
3814    if (friction < 0.1) friction = 0.1;
3815    if (friction > 1.0) friction = 1.0;
3816    _elm_config->thumbscroll_sensitivity_friction = friction;
3817 }
3818 
3819 EAPI Eina_Bool
elm_config_scroll_thumbscroll_smooth_start_get(void)3820 elm_config_scroll_thumbscroll_smooth_start_get(void)
3821 {
3822    return _elm_config->scroll_smooth_start_enable;
3823 }
3824 
3825 EAPI void
elm_config_scroll_thumbscroll_smooth_start_set(Eina_Bool enable)3826 elm_config_scroll_thumbscroll_smooth_start_set(Eina_Bool enable)
3827 {
3828    _elm_config->priv.scroll_smooth_start_enable = EINA_TRUE;
3829    _elm_config->scroll_smooth_start_enable = enable;
3830 }
3831 
3832 EAPI Eina_Bool
elm_config_scroll_animation_disabled_get(void)3833 elm_config_scroll_animation_disabled_get(void)
3834 {
3835    return _elm_config->scroll_animation_disable;
3836 }
3837 
3838 EAPI void
elm_config_scroll_animation_disabled_set(Eina_Bool disable)3839 elm_config_scroll_animation_disabled_set(Eina_Bool disable)
3840 {
3841    _elm_config->priv.scroll_animation_disable = EINA_TRUE;
3842    _elm_config->scroll_animation_disable = !!disable;
3843 }
3844 
3845 EAPI void
elm_config_scroll_accel_factor_set(double factor)3846 elm_config_scroll_accel_factor_set(double factor)
3847 {
3848    _elm_config->priv.scroll_accel_factor = EINA_TRUE;
3849    if (factor < 0.0) factor = 0.0;
3850    if (factor > 10.0) factor = 10.0;
3851    _elm_config->scroll_accel_factor = factor;
3852 }
3853 
3854 EAPI double
elm_config_scroll_accel_factor_get(void)3855 elm_config_scroll_accel_factor_get(void)
3856 {
3857    return _elm_config->scroll_accel_factor;
3858 }
3859 
3860 EAPI void
elm_config_scroll_thumbscroll_smooth_amount_set(double amount)3861 elm_config_scroll_thumbscroll_smooth_amount_set(double amount)
3862 {
3863    _elm_config->priv.scroll_smooth_amount = EINA_TRUE;
3864    if (amount < 0.0) amount = 0.0;
3865    if (amount > 1.0) amount = 1.0;
3866    _elm_config->scroll_smooth_amount = amount;
3867 }
3868 
3869 EAPI double
elm_config_scroll_thumbscroll_smooth_amount_get(void)3870 elm_config_scroll_thumbscroll_smooth_amount_get(void)
3871 {
3872    return _elm_config->scroll_smooth_amount;
3873 }
3874 
3875 EAPI void
elm_config_scroll_thumbscroll_smooth_time_window_set(double amount)3876 elm_config_scroll_thumbscroll_smooth_time_window_set(double amount)
3877 {
3878    _elm_config->priv.scroll_smooth_time_window = EINA_TRUE;
3879    if (amount < 0.0) amount = 0.0;
3880    if (amount > 1.0) amount = 1.0;
3881    _elm_config->scroll_smooth_time_window = amount;
3882 }
3883 
3884 EAPI double
elm_config_scroll_thumbscroll_smooth_time_window_get(void)3885 elm_config_scroll_thumbscroll_smooth_time_window_get(void)
3886 {
3887    return _elm_config->scroll_smooth_time_window;
3888 }
3889 
3890 EAPI double
elm_config_scroll_thumbscroll_acceleration_threshold_get(void)3891 elm_config_scroll_thumbscroll_acceleration_threshold_get(void)
3892 {
3893    return _elm_config->thumbscroll_acceleration_threshold;
3894 }
3895 
3896 EAPI void
elm_config_scroll_thumbscroll_acceleration_threshold_set(double threshold)3897 elm_config_scroll_thumbscroll_acceleration_threshold_set(double threshold)
3898 {
3899    _elm_config->priv.thumbscroll_acceleration_threshold = EINA_TRUE;
3900    _elm_config->thumbscroll_acceleration_threshold = threshold;
3901 }
3902 
3903 EAPI double
elm_config_scroll_thumbscroll_acceleration_time_limit_get(void)3904 elm_config_scroll_thumbscroll_acceleration_time_limit_get(void)
3905 {
3906    return _elm_config->thumbscroll_acceleration_time_limit;
3907 }
3908 
3909 EAPI void
elm_config_scroll_thumbscroll_acceleration_time_limit_set(double time_limit)3910 elm_config_scroll_thumbscroll_acceleration_time_limit_set(double time_limit)
3911 {
3912    _elm_config->priv.thumbscroll_acceleration_time_limit = EINA_TRUE;
3913    _elm_config->thumbscroll_acceleration_time_limit = time_limit;
3914 }
3915 
3916 EAPI double
elm_config_scroll_thumbscroll_acceleration_weight_get(void)3917 elm_config_scroll_thumbscroll_acceleration_weight_get(void)
3918 {
3919    return _elm_config->thumbscroll_acceleration_weight;
3920 }
3921 
3922 EAPI void
elm_config_scroll_thumbscroll_acceleration_weight_set(double weight)3923 elm_config_scroll_thumbscroll_acceleration_weight_set(double weight)
3924 {
3925    _elm_config->priv.thumbscroll_acceleration_weight = EINA_TRUE;
3926    _elm_config->thumbscroll_acceleration_weight = weight;
3927 }
3928 
3929 EAPI double
elm_config_scroll_thumbscroll_momentum_animation_duration_min_limit_get(void)3930 elm_config_scroll_thumbscroll_momentum_animation_duration_min_limit_get(void)
3931 {
3932    return _elm_config->thumbscroll_momentum_animation_duration_min_limit;
3933 }
3934 
3935 EAPI void
elm_config_scroll_thumbscroll_momentum_animation_duration_min_limit_set(double min)3936 elm_config_scroll_thumbscroll_momentum_animation_duration_min_limit_set(double min)
3937 {
3938    _elm_config->priv.thumbscroll_momentum_animation_duration_min_limit = EINA_TRUE;
3939    _elm_config->thumbscroll_momentum_animation_duration_min_limit = min;
3940 }
3941 
3942 EAPI double
elm_config_scroll_thumbscroll_momentum_animation_duration_max_limit_get(void)3943 elm_config_scroll_thumbscroll_momentum_animation_duration_max_limit_get(void)
3944 {
3945    return _elm_config->thumbscroll_momentum_animation_duration_max_limit;
3946 }
3947 
3948 EAPI void
elm_config_scroll_thumbscroll_momentum_animation_duration_max_limit_set(double max)3949 elm_config_scroll_thumbscroll_momentum_animation_duration_max_limit_set(double max)
3950 {
3951    _elm_config->priv.thumbscroll_momentum_animation_duration_max_limit = EINA_TRUE;
3952    _elm_config->thumbscroll_momentum_animation_duration_max_limit = max;
3953 }
3954 
3955 EAPI Elm_Focus_Autoscroll_Mode
elm_config_focus_autoscroll_mode_get(void)3956 elm_config_focus_autoscroll_mode_get(void)
3957 {
3958    return _elm_config->focus_autoscroll_mode;
3959 }
3960 
3961 EAPI void
elm_config_slider_indicator_visible_mode_set(Elm_Slider_Indicator_Visible_Mode mode)3962 elm_config_slider_indicator_visible_mode_set(Elm_Slider_Indicator_Visible_Mode mode)
3963 {
3964    _elm_config->priv.slider_indicator_visible_mode = EINA_TRUE;
3965    _elm_config->slider_indicator_visible_mode = mode;
3966 }
3967 
3968 EAPI Elm_Slider_Indicator_Visible_Mode
elm_config_slider_indicator_visible_mode_get(void)3969 elm_config_slider_indicator_visible_mode_get(void)
3970 {
3971     return _elm_config->slider_indicator_visible_mode;
3972 }
3973 
3974 EAPI void
elm_config_focus_autoscroll_mode_set(Elm_Focus_Autoscroll_Mode mode)3975 elm_config_focus_autoscroll_mode_set(Elm_Focus_Autoscroll_Mode mode)
3976 {
3977    _elm_config->priv.focus_autoscroll_mode = EINA_TRUE;
3978    _elm_config->focus_autoscroll_mode = mode;
3979 }
3980 
3981 EAPI void
elm_config_longpress_timeout_set(double longpress_timeout)3982 elm_config_longpress_timeout_set(double longpress_timeout)
3983 {
3984    _elm_config->priv.longpress_timeout = EINA_TRUE;
3985    _elm_config->longpress_timeout = longpress_timeout;
3986 }
3987 
3988 EAPI double
elm_config_longpress_timeout_get(void)3989 elm_config_longpress_timeout_get(void)
3990 {
3991    return _elm_config->longpress_timeout;
3992 }
3993 
3994 EAPI void
elm_config_softcursor_mode_set(Elm_Softcursor_Mode mode)3995 elm_config_softcursor_mode_set(Elm_Softcursor_Mode mode)
3996 {
3997    _elm_config->priv.softcursor_mode = EINA_TRUE;
3998    _elm_config->softcursor_mode = mode;
3999 }
4000 
4001 EAPI Elm_Softcursor_Mode
elm_config_softcursor_mode_get(void)4002 elm_config_softcursor_mode_get(void)
4003 {
4004    return _elm_config->softcursor_mode;
4005 }
4006 
4007 EAPI Eina_Bool
elm_config_disable_external_menu_get(void)4008 elm_config_disable_external_menu_get(void)
4009 {
4010    return _elm_config->disable_external_menu;
4011 }
4012 
4013 EAPI void
elm_config_disable_external_menu_set(Eina_Bool disable)4014 elm_config_disable_external_menu_set(Eina_Bool disable)
4015 {
4016    _elm_config->priv.disable_external_menu = EINA_TRUE;
4017    _elm_config->disable_external_menu = !!disable;
4018 }
4019 
4020 EAPI Eina_Bool
elm_config_clouseau_enabled_get(void)4021 elm_config_clouseau_enabled_get(void)
4022 {
4023    return _elm_config->clouseau_enable;
4024 }
4025 
4026 EAPI void
elm_config_clouseau_enabled_set(Eina_Bool enable)4027 elm_config_clouseau_enabled_set(Eina_Bool enable)
4028 {
4029    _elm_config->priv.clouseau_enable = EINA_TRUE;
4030    _elm_config->clouseau_enable = !!enable;
4031    _elm_old_clouseau_reload();
4032 }
4033 
4034 EAPI double
elm_config_glayer_long_tap_start_timeout_get(void)4035 elm_config_glayer_long_tap_start_timeout_get(void)
4036 {
4037    return _elm_config->glayer_long_tap_start_timeout;
4038 }
4039 
4040 EAPI void
elm_config_glayer_long_tap_start_timeout_set(double long_tap_timeout)4041 elm_config_glayer_long_tap_start_timeout_set(double long_tap_timeout)
4042 {
4043    _elm_config->priv.glayer_long_tap_start_timeout = EINA_TRUE;
4044    _elm_config->glayer_long_tap_start_timeout = long_tap_timeout;
4045 }
4046 
4047 EAPI double
elm_config_glayer_double_tap_timeout_get(void)4048 elm_config_glayer_double_tap_timeout_get(void)
4049 {
4050    return _elm_config->glayer_double_tap_timeout;
4051 }
4052 
4053 EAPI void
elm_config_glayer_double_tap_timeout_set(double double_tap_timeout)4054 elm_config_glayer_double_tap_timeout_set(double double_tap_timeout)
4055 {
4056    _elm_config->priv.glayer_double_tap_timeout = EINA_TRUE;
4057    _elm_config->glayer_double_tap_timeout = double_tap_timeout;
4058 }
4059 
4060 EAPI Eina_Bool
elm_config_desktop_entry_get(void)4061 elm_config_desktop_entry_get(void)
4062 {
4063    return _elm_config->desktop_entry;
4064 }
4065 
4066 EAPI void
elm_config_desktop_entry_set(Eina_Bool enable)4067 elm_config_desktop_entry_set(Eina_Bool enable)
4068 {
4069    _elm_config->priv.desktop_entry = EINA_TRUE;
4070    _elm_config->desktop_entry = !!enable;
4071 }
4072 
4073 EAPI Eina_Bool
elm_config_magnifier_enable_get(void)4074 elm_config_magnifier_enable_get(void)
4075 {
4076    return _elm_config->magnifier_enable;
4077 }
4078 
4079 EAPI void
elm_config_magnifier_enable_set(Eina_Bool enable)4080 elm_config_magnifier_enable_set(Eina_Bool enable)
4081 {
4082    _elm_config->priv.magnifier_enable = EINA_TRUE;
4083    _elm_config->magnifier_enable = !!enable;
4084 }
4085 
4086 EAPI double
elm_config_magnifier_scale_get(void)4087 elm_config_magnifier_scale_get(void)
4088 {
4089    return _elm_config->magnifier_scale;
4090 }
4091 
4092 EAPI void
elm_config_magnifier_scale_set(double scale)4093 elm_config_magnifier_scale_set(double scale)
4094 {
4095    _elm_config->priv.magnifier_scale = EINA_TRUE;
4096    _elm_config->magnifier_scale = scale;
4097 }
4098 
4099 EAPI Eina_Bool
elm_config_audio_mute_get(Edje_Channel channel)4100 elm_config_audio_mute_get(Edje_Channel channel)
4101 {
4102    switch (channel)
4103      {
4104       case EDJE_CHANNEL_EFFECT:
4105         return _elm_config->audio_mute_effect;
4106         break;
4107       case EDJE_CHANNEL_BACKGROUND:
4108         return _elm_config->audio_mute_background;
4109         break;
4110       case EDJE_CHANNEL_MUSIC:
4111         return _elm_config->audio_mute_music;
4112         break;
4113       case EDJE_CHANNEL_FOREGROUND:
4114         return _elm_config->audio_mute_foreground;
4115         break;
4116       case EDJE_CHANNEL_INTERFACE:
4117         return _elm_config->audio_mute_interface;
4118         break;
4119       case EDJE_CHANNEL_INPUT:
4120         return _elm_config->audio_mute_input;
4121         break;
4122       case EDJE_CHANNEL_ALERT:
4123         return _elm_config->audio_mute_alert;
4124         break;
4125       case EDJE_CHANNEL_ALL:
4126         return _elm_config->audio_mute_all;
4127         break;
4128       default:
4129         break;
4130      }
4131    return EINA_FALSE;
4132 }
4133 
4134 EAPI void
elm_config_audio_mute_set(Edje_Channel channel,Eina_Bool mute)4135 elm_config_audio_mute_set(Edje_Channel channel, Eina_Bool mute)
4136 {
4137    switch (channel)
4138      {
4139       case EDJE_CHANNEL_EFFECT:
4140         _elm_config->priv.audio_mute_effect = EINA_TRUE;
4141         _elm_config->audio_mute_effect = mute;
4142         break;
4143       case EDJE_CHANNEL_BACKGROUND:
4144         _elm_config->priv.audio_mute_background = EINA_TRUE;
4145         _elm_config->audio_mute_background = mute;
4146         break;
4147       case EDJE_CHANNEL_MUSIC:
4148         _elm_config->priv.audio_mute_music = EINA_TRUE;
4149         _elm_config->audio_mute_music = mute;
4150         break;
4151       case EDJE_CHANNEL_FOREGROUND:
4152         _elm_config->priv.audio_mute_foreground = EINA_TRUE;
4153         _elm_config->audio_mute_foreground = mute;
4154         break;
4155       case EDJE_CHANNEL_INTERFACE:
4156         _elm_config->priv.audio_mute_interface = EINA_TRUE;
4157         _elm_config->audio_mute_interface = mute;
4158         break;
4159       case EDJE_CHANNEL_INPUT:
4160         _elm_config->priv.audio_mute_input = EINA_TRUE;
4161         _elm_config->audio_mute_input = mute;
4162         break;
4163       case EDJE_CHANNEL_ALERT:
4164         _elm_config->priv.audio_mute_alert = EINA_TRUE;
4165         _elm_config->audio_mute_alert = mute;
4166         break;
4167       case EDJE_CHANNEL_ALL:
4168         _elm_config->priv.audio_mute_all = EINA_TRUE;
4169         _elm_config->audio_mute_all = mute;
4170         break;
4171       default:
4172         break;
4173      }
4174    edje_audio_channel_mute_set(channel, mute);
4175 }
4176 
4177 EAPI Eina_Bool
elm_config_window_auto_focus_enable_get(void)4178 elm_config_window_auto_focus_enable_get(void)
4179 {
4180    return _elm_config->win_auto_focus_enable;
4181 }
4182 
4183 EAPI void
elm_config_window_auto_focus_enable_set(Eina_Bool enable)4184 elm_config_window_auto_focus_enable_set(Eina_Bool enable)
4185 {
4186    _elm_config->priv.win_auto_focus_enable = EINA_TRUE;
4187    _elm_config->win_auto_focus_enable = enable;
4188 }
4189 
4190 EAPI Eina_Bool
elm_config_window_auto_focus_animate_get(void)4191 elm_config_window_auto_focus_animate_get(void)
4192 {
4193    return _elm_config->win_auto_focus_animate;
4194 }
4195 
4196 EAPI void
elm_config_window_auto_focus_animate_set(Eina_Bool enable)4197 elm_config_window_auto_focus_animate_set(Eina_Bool enable)
4198 {
4199    _elm_config->priv.win_auto_focus_animate = EINA_TRUE;
4200    _elm_config->win_auto_focus_animate = enable;
4201 }
4202 
4203 EAPI Eina_Bool
elm_config_popup_scrollable_get(void)4204 elm_config_popup_scrollable_get(void)
4205 {
4206    return _elm_config->popup_scrollable;
4207 }
4208 
4209 EAPI void
elm_config_popup_scrollable_set(Eina_Bool scrollable)4210 elm_config_popup_scrollable_set(Eina_Bool scrollable)
4211 {
4212    _elm_config->priv.popup_scrollable = EINA_TRUE;
4213    _elm_config->popup_scrollable = scrollable;
4214 }
4215 
4216 EAPI void
elm_config_all_flush(void)4217 elm_config_all_flush(void)
4218 {
4219    char buf[PATH_MAX];
4220    int ok = 0;
4221    size_t len;
4222 
4223    if (_running_in_tree) return;
4224    len = _elm_config_user_dir_snprintf(buf, sizeof(buf), "themes/");
4225    if (len + 1 >= sizeof(buf))
4226      return;
4227 
4228    ok = ecore_file_mkpath(buf);
4229    if (!ok)
4230      {
4231         ERR("Problem accessing Elementary's user configuration directory: %s",
4232             buf);
4233         return;
4234      }
4235 
4236    len = _elm_config_user_dir_snprintf(buf, sizeof(buf), "config");
4237    if (len + 1 >= sizeof(buf))
4238      return;
4239 
4240    ok = ecore_file_mkpath(buf);
4241    if (!ok)
4242      {
4243         ERR("Problem accessing Elementary's user configuration directory: %s",
4244             buf);
4245         return;
4246      }
4247 
4248    if (!_elm_config_profile_save(NULL))
4249      {
4250         ERR("Failed to save profile");
4251         return;
4252      }
4253 
4254    elm_config_save();
4255    return;
4256 }
4257 
4258 static void
_translation_init(void)4259 _translation_init(void)
4260 {
4261 #ifdef ENABLE_NLS
4262    const char *cur_dom = textdomain(NULL);
4263    const char *trans_comment = gettext("");
4264    const char *msg_locale = setlocale(LC_MESSAGES, NULL);
4265 
4266    /* Same concept as what glib does:
4267     * We shouldn't translate if there are no translations for the
4268     * application in the current locale + domain. (Unless locale is
4269     * en_/C where translating only parts of the interface make some
4270     * sense).
4271     */
4272    if (msg_locale && cur_dom)
4273      _elm_config->translate = !(strcmp (cur_dom, "messages") &&
4274            !*trans_comment && strncmp (msg_locale, "en_", 3) &&
4275            strcmp (msg_locale, "C"));
4276    /* Get RTL orientation from system */
4277    if (_elm_config->translate)
4278      {
4279         bindtextdomain(PACKAGE, LOCALE_DIR);
4280         /* TRANSLATORS: This string is special and defines if the language
4281            by default is a Left To Right or Right To Left language. Most
4282            languages are LTR and thus the default string is "default:LTR"
4283            but if this is a right-to-left language like arabic, Farsi,
4284            Hebrew, etc. then change this string to be "default:RTL"
4285          */
4286         _elm_config->is_mirrored = !strcmp(E_("default:LTR"), "default:RTL");
4287      }
4288 
4289 #endif
4290 }
4291 
4292 void
_elm_config_init(void)4293 _elm_config_init(void)
4294 {
4295    ELM_EVENT_CONFIG_ALL_CHANGED = ecore_event_type_new();
4296    _desc_init();
4297    _elm_config_profile_derived_init();
4298    _profile_fetch_from_conf();
4299    _config_load();
4300    if (_elm_config) _env_get();
4301    ELM_SAFE_FREE(_elm_accel_preference, eina_stringshare_del);
4302    ELM_SAFE_FREE(_elm_gl_preference, eina_stringshare_del);
4303    _translation_init();
4304    _elm_recache();
4305    _config_apply();
4306    _elm_config_font_overlay_apply();
4307    _elm_config_color_overlay_apply();
4308    _elm_old_clouseau_reload();
4309    _elm_config_key_binding_hash();
4310 }
4311 
4312 void
_elm_config_sub_shutdown(void)4313 _elm_config_sub_shutdown(void)
4314 {
4315    ecore_event_type_flush(ELM_EVENT_CONFIG_ALL_CHANGED);
4316 
4317    ELM_SAFE_FREE(_eio_config_monitor, eio_monitor_del);
4318    ELM_SAFE_FREE(_eio_profile_monitor, eio_monitor_del);
4319    ELM_SAFE_FREE(_config_change_delay_timer, ecore_timer_del);
4320    ELM_SAFE_FREE(_config_profile_change_delay_timer, ecore_timer_del);
4321    ELM_SAFE_FREE(_monitor_file_created_handler, ecore_event_handler_del);
4322    ELM_SAFE_FREE(_monitor_file_modified_handler, ecore_event_handler_del);
4323    ELM_SAFE_FREE(_monitor_directory_created_handler, ecore_event_handler_del);
4324    _running_in_tree = EINA_FALSE;
4325 }
4326 
4327 static Eina_Bool
_config_profile_change_delay_cb(void * data EINA_UNUSED)4328 _config_profile_change_delay_cb(void *data EINA_UNUSED)
4329 {
4330    char *pprof = NULL;
4331 
4332    if (_elm_profile) pprof = strdup(_elm_profile);
4333    _profile_fetch_from_conf();
4334    if ((!pprof) || (!(!strcmp(pprof, _elm_profile))))
4335      {
4336         _config_flush_get();
4337      }
4338    free(pprof);
4339    _config_profile_change_delay_timer = NULL;
4340    return ECORE_CALLBACK_CANCEL;
4341 }
4342 
4343 static Eina_Bool
_config_change_delay_cb(void * data EINA_UNUSED)4344 _config_change_delay_cb(void *data EINA_UNUSED)
4345 {
4346    _elm_config_reload();
4347 
4348    _config_change_delay_timer = NULL;
4349    return ECORE_CALLBACK_CANCEL;
4350 }
4351 
4352 static Eina_Bool
_elm_config_file_monitor_cb(void * data EINA_UNUSED,int type,void * event)4353 _elm_config_file_monitor_cb(void *data EINA_UNUSED,
4354                             int type,
4355                             void *event)
4356 {
4357    Eio_Monitor_Event *ev = event;
4358    const char *file = ecore_file_file_get(ev->filename);
4359 
4360    if (ev->monitor == _eio_config_monitor)
4361      {
4362         if ((type == EIO_MONITOR_FILE_CREATED) || (type == EIO_MONITOR_FILE_MODIFIED))
4363           {
4364              if (!strcmp(file, "base.cfg"))
4365                {
4366                   if (_config_change_delay_timer)
4367                     ecore_timer_del(_config_change_delay_timer);
4368                   _config_change_delay_timer = ecore_timer_add(0.1, _config_change_delay_cb, NULL);
4369                }
4370           }
4371      }
4372    if (ev->monitor == _eio_profile_monitor)
4373      {
4374         if ((type == EIO_MONITOR_FILE_CREATED) || (type == EIO_MONITOR_FILE_MODIFIED))
4375           {
4376              if ((!_config_profile_lock) && (!strcmp(file, "profile.cfg")))
4377                {
4378                   if (_config_profile_change_delay_timer)
4379                     ecore_timer_del(_config_profile_change_delay_timer);
4380                   _config_profile_change_delay_timer = ecore_timer_add(0.1, _config_profile_change_delay_cb, NULL);
4381                }
4382           }
4383         else if (type == EIO_MONITOR_DIRECTORY_CREATED)
4384           {
4385              if (!_eio_config_monitor)
4386                {
4387                   char buf[PATH_MAX];
4388 
4389                   _eio_config_monitor = eio_monitor_add(ev->filename);
4390                   snprintf(buf, sizeof(buf), "%s/base.cfg", ev->filename);
4391                   if (ecore_file_exists(buf))
4392                     {
4393                        if (_config_change_delay_timer)
4394                          ecore_timer_del(_config_change_delay_timer);
4395                        _config_change_delay_timer = ecore_timer_add(0.1, _config_change_delay_cb, NULL);
4396                     }
4397                }
4398           }
4399      }
4400 
4401    return ECORE_CALLBACK_PASS_ON;
4402 }
4403 
4404 void
_elm_config_sub_init(void)4405 _elm_config_sub_init(void)
4406 {
4407    char buf[PATH_MAX];
4408    int ok = 0;
4409 
4410    if (_running_in_tree)
4411      ok = bs_data_path_get(buf, sizeof(buf), "elementary", "config");
4412    else
4413      {
4414         _elm_config_user_dir_snprintf(buf, sizeof(buf), "config");
4415         ok = ecore_file_mkpath(buf);
4416      }
4417    if (!ok)
4418      {
4419         ERR("Problem accessing Elementary's user configuration directory: %s",
4420             buf);
4421         goto end;
4422      }
4423    _eio_profile_monitor = eio_monitor_add(buf);
4424    _monitor_file_created_handler = ecore_event_handler_add
4425      (EIO_MONITOR_FILE_CREATED, _elm_config_file_monitor_cb, NULL);
4426    _monitor_file_modified_handler = ecore_event_handler_add
4427      (EIO_MONITOR_FILE_MODIFIED, _elm_config_file_monitor_cb, NULL);
4428    _monitor_directory_created_handler = ecore_event_handler_add
4429      (EIO_MONITOR_DIRECTORY_CREATED, _elm_config_file_monitor_cb, NULL);
4430 
4431 end:
4432    _config_sub_apply();
4433 }
4434 
4435 void
_elm_config_reload(void)4436 _elm_config_reload(void)
4437 {
4438    Eina_Bool is_mirrored;
4439    Eina_Bool translate;
4440 
4441    Eina_Stringshare *ptheme = NULL, *pmodules = NULL, *picon_theme = NULL;
4442    double pscale;
4443    int pfinger_size, picon_size;
4444    unsigned char ppassword_show_last;
4445    double ppassword_show_last_timeout;
4446    int pweek_start, pweekend_start, pweekend_len, pyear_min, pyear_max;
4447    Eina_List *pfont_overlays;
4448 
4449 #define STO(x) if (_elm_config->x) p##x = eina_stringshare_add(_elm_config->x)
4450    STO(theme);
4451    STO(modules);
4452    STO(icon_theme);
4453 #undef STO
4454 
4455 #define STO(x) p##x = _elm_config->x
4456    STO(scale);
4457    STO(finger_size);
4458    STO(icon_size);
4459    STO(password_show_last);
4460    STO(password_show_last_timeout);
4461    STO(week_start);
4462    STO(weekend_start);
4463    STO(weekend_len);
4464    STO(year_min);
4465    STO(year_max);
4466    STO(font_overlays);
4467 #undef STO
4468 
4469    is_mirrored = _elm_config->is_mirrored;
4470    translate = _elm_config->translate;
4471 
4472    _elm_config_reload_do();
4473 
4474    /* restore prev value which is not part of the EET file */
4475    _elm_config->is_mirrored = is_mirrored;
4476    _elm_config->translate = translate;
4477 
4478    _elm_recache();
4479    _config_apply();
4480    _elm_config_font_overlay_apply();
4481    _elm_config_color_overlay_apply();
4482 #define CMP(x) (p##x != _elm_config->x)
4483 #define DBL_CMP(x) !EINA_DBL_EQ(p##x, _elm_config->x)
4484    if (
4485           DBL_CMP(scale)
4486        || CMP(finger_size)
4487        || CMP(icon_size)
4488        || CMP(password_show_last)
4489        || DBL_CMP(password_show_last_timeout)
4490        || CMP(week_start)
4491        || CMP(weekend_start)
4492        || CMP(weekend_len)
4493        || CMP(year_min)
4494        || CMP(year_max)
4495        // these are string ptr compares but this is right because they are
4496        // stringshare strings and thus an identical string has the same
4497        // exact pointer guaranteed
4498        || CMP(theme)
4499        || CMP(modules)
4500        || CMP(icon_theme)
4501        || CMP(font_overlays)
4502       )
4503      _elm_rescale();
4504 #undef DBL_CMP
4505 #undef CMP
4506    _elm_old_clouseau_reload();
4507    _elm_config_key_binding_hash();
4508    ecore_event_add(ELM_EVENT_CONFIG_ALL_CHANGED, NULL, NULL, NULL);
4509    efl_event_callback_call(_efl_config_obj, EFL_CONFIG_EVENT_CONFIG_CHANGED, NULL);
4510    if (ptheme) eina_stringshare_del(ptheme);
4511    if (pmodules) eina_stringshare_del(pmodules);
4512    if (picon_theme) eina_stringshare_del(picon_theme);
4513 }
4514 
4515 void
_elm_config_engine_set(const char * engine)4516 _elm_config_engine_set(const char *engine)
4517 {
4518    _elm_config->priv.engine = EINA_TRUE;
4519    eina_stringshare_replace(&(_elm_config->engine), engine);
4520 }
4521 
4522 EAPI const char *
elm_config_preferred_engine_get(void)4523 elm_config_preferred_engine_get(void)
4524 {
4525    return _elm_preferred_engine;
4526 }
4527 
4528 EAPI void
elm_config_preferred_engine_set(const char * engine)4529 elm_config_preferred_engine_set(const char *engine)
4530 {
4531    if (engine)
4532      eina_stringshare_replace(&(_elm_preferred_engine), engine);
4533    else
4534      {
4535         ELM_SAFE_FREE(_elm_preferred_engine, eina_stringshare_del);
4536      }
4537 }
4538 
4539 EAPI const char *
elm_config_accel_preference_get(void)4540 elm_config_accel_preference_get(void)
4541 {
4542    if (_elm_gl_preference) return _elm_gl_preference;
4543    if (_elm_accel_preference) return _elm_accel_preference;
4544    return _elm_config->accel;
4545 }
4546 
4547 Eina_Bool
_elm_config_accel_preference_parse(const char * pref,Eina_Stringshare ** accel,int * gl_depth,int * gl_stencil,int * gl_msaa)4548 _elm_config_accel_preference_parse(const char *pref, Eina_Stringshare **accel,
4549                                    int *gl_depth, int *gl_stencil, int *gl_msaa)
4550 {
4551    Eina_Bool is_hw_accel = EINA_FALSE;
4552    unsigned int tokens = 0, i;
4553    char **arr;
4554 
4555    /* Accel preference's string has the window surface configuration as a hw accel, depth, stencil and msaa.
4556     * The string format is   "{HW Accel}:depth{value}:stencil{value}:msaa{msaa string}"
4557     * Especially, msaa string is related Evas GL MSAA enum value(low, mid, high)
4558     * so msaa string has four types as msaa, msaa_low, msaa_mid, msaa_high
4559     * For instance, "opengl:depth24:stencil8:msaa_high".
4560     * It means that using hw accelation, window surface depth buffer's size is 24, stencil buffer's size 8 and msaa bits is the highest.
4561     * The other use-case is  "opengl:depth24".
4562     * It measn that using hw accelation, depth buffer size is 24. stencil and msaa are not used.
4563     * The simple case is  "opengl:depth:stencil:msaa".
4564     * It means that depth, stencil and msaa are setted by pre-defined value(depth:24, stencil:8, msaa:low)
4565     */
4566 
4567    DBG("accel preference's string: %s", pref);
4568 
4569    /* split GL items (hw accel, gl depth, gl stencil, gl msaa */
4570    arr = eina_str_split_full(pref, ":", 0, &tokens);
4571    for (i = 0; arr && arr[i]; i++)
4572      {
4573         if ((!strcasecmp(arr[i], "gl")) ||
4574             (!strcasecmp(arr[i], "opengl")) ||
4575             (!strcasecmp(arr[i], "3d")) ||
4576             (!strcasecmp(arr[i], "hw")) ||
4577             (!strcasecmp(arr[i], "accel")) ||
4578             (!strcasecmp(arr[i], "hardware"))
4579             )
4580           {
4581              eina_stringshare_replace(accel, arr[i]);
4582              is_hw_accel = EINA_TRUE;
4583              *gl_depth = 0;
4584              *gl_stencil = 0;
4585              *gl_msaa = 0;
4586           }
4587         else if (!strncmp(arr[i], "depth", 5))
4588           {
4589              char *value_str = arr[i] + 5;
4590              if ((value_str) && (isdigit(*value_str)))
4591                *gl_depth = atoi(value_str);
4592              else
4593                *gl_depth = 24;
4594           }
4595         else if (!strncmp(arr[i], "stencil", 7))
4596           {
4597              char *value_str = arr[i] + 7;
4598              if ((value_str) && (isdigit(*value_str)))
4599                *gl_stencil = atoi(value_str);
4600              else
4601                *gl_stencil = 8;
4602           }
4603         else if (!strncmp(arr[i], "msaa_low", 8))
4604           *gl_msaa = 1;             // 1 means msaa low
4605         else if (!strncmp(arr[i], "msaa_mid", 8))
4606           *gl_msaa = 2;             // 2 means msaa mid
4607         else if (!strncmp(arr[i], "msaa_high", 9))
4608           *gl_msaa = 4;             // 4 means msaa high
4609         else if (!strncmp(arr[i], "msaa", 4))
4610           *gl_msaa = 1;            // 1 means msaa low
4611      }
4612 
4613    DBG("accel: %s", *accel);
4614    DBG("gl depth: %d", *gl_depth);
4615    DBG("gl stencil: %d", *gl_stencil);
4616    DBG("gl msaa: %d", *gl_msaa);
4617    if (arr)
4618      {
4619         free(arr[0]);
4620         free(arr);
4621      }
4622 
4623    return is_hw_accel;
4624 }
4625 
4626 EAPI void
elm_config_accel_preference_set(const char * pref)4627 elm_config_accel_preference_set(const char *pref)
4628 {
4629    _elm_config->priv.accel = EINA_TRUE;
4630    _elm_config->priv.gl_depth = EINA_TRUE;
4631    _elm_config->priv.gl_stencil = EINA_TRUE;
4632    _elm_config->priv.gl_msaa = EINA_TRUE;
4633    if (pref)
4634      {
4635         Eina_Bool hw;
4636 
4637         /* full string */
4638         eina_stringshare_replace(&(_elm_gl_preference), pref);
4639         ELM_SAFE_FREE(_elm_accel_preference, eina_stringshare_del);
4640         ELM_SAFE_FREE(_elm_config->accel, eina_stringshare_del);
4641 
4642         hw = _elm_config_accel_preference_parse(pref, &_elm_config->accel,
4643                                                 &_elm_config->gl_depth,
4644                                                 &_elm_config->gl_stencil,
4645                                                 &_elm_config->gl_msaa);
4646 
4647         if (hw)
4648           {
4649              eina_stringshare_replace(&(_elm_accel_preference), _elm_config->accel);
4650           }
4651         else
4652           {
4653              ELM_SAFE_FREE(_elm_config->accel, eina_stringshare_del);
4654           }
4655      }
4656    else
4657      {
4658         ELM_SAFE_FREE(_elm_gl_preference, eina_stringshare_del);
4659         ELM_SAFE_FREE(_elm_accel_preference, eina_stringshare_del);
4660         ELM_SAFE_FREE(_elm_config->accel, eina_stringshare_del);
4661      }
4662 }
4663 
4664 EAPI const char *
elm_config_indicator_service_get(int rotation)4665 elm_config_indicator_service_get(int rotation)
4666 {
4667    switch (rotation)
4668      {
4669       case 0:
4670         return _elm_config->indicator_service_0;
4671       case 90:
4672         return _elm_config->indicator_service_90;
4673       case 180:
4674         return _elm_config->indicator_service_180;
4675       case 270:
4676         return _elm_config->indicator_service_270;
4677       default:
4678         return NULL;
4679      }
4680 }
4681 
4682 EAPI void
elm_config_transition_duration_factor_set(double factor)4683 elm_config_transition_duration_factor_set(double factor)
4684 {
4685     _elm_config->priv.transition_duration_factor = EINA_TRUE;
4686     if (factor < 0.0) return;
4687     if (EINA_DBL_EQ(_elm_config->transition_duration_factor, factor)) return;
4688     _elm_config->transition_duration_factor = factor;
4689     edje_transition_duration_factor_set(_elm_config->transition_duration_factor);
4690 }
4691 
4692 EAPI double
elm_config_transition_duration_factor_get(void)4693 elm_config_transition_duration_factor_get(void)
4694 {
4695     return _elm_config->transition_duration_factor;
4696 }
4697 
4698 EAPI void
elm_config_web_backend_set(const char * backend)4699 elm_config_web_backend_set(const char *backend)
4700 {
4701    _elm_config->priv.web_backend = EINA_TRUE;
4702    if (_elm_web_init(backend))
4703      eina_stringshare_replace(&_elm_config->web_backend, backend);
4704 }
4705 
4706 EAPI const char *
elm_config_web_backend_get(void)4707 elm_config_web_backend_get(void)
4708 {
4709    if (!_elm_config) return NULL;
4710    return _elm_config->web_backend;
4711 }
4712 
4713 EAPI Eina_Bool
elm_config_offline_get(void)4714 elm_config_offline_get(void)
4715 {
4716    if (!_elm_config) return EINA_FALSE;
4717    return _elm_config->offline;
4718 }
4719 
4720 EAPI void
elm_config_offline_set(Eina_Bool set)4721 elm_config_offline_set(Eina_Bool set)
4722 {
4723    if (!_elm_config) return;
4724    _elm_config->offline = !!set;
4725 }
4726 
4727 EAPI int
elm_config_powersave_get(void)4728 elm_config_powersave_get(void)
4729 {
4730    if (!_elm_config) return EINA_FALSE;
4731    return _elm_config->powersave;
4732 }
4733 
4734 EAPI void
elm_config_powersave_set(int set)4735 elm_config_powersave_set(int set)
4736 {
4737    if (!_elm_config) return;
4738    _elm_config->powersave = set;
4739 }
4740 
4741 EAPI double
elm_config_drag_anim_duration_get(void)4742 elm_config_drag_anim_duration_get(void)
4743 {
4744    if (!_elm_config) return 0.0;
4745    return _elm_config->drag_anim_duration;
4746 }
4747 
4748 EAPI void
elm_config_drag_anim_duration_set(double set)4749 elm_config_drag_anim_duration_set(double set)
4750 {
4751    if (!_elm_config) return;
4752    _elm_config->drag_anim_duration = set;
4753 }
4754 
4755 void
_elm_config_profile_set(const char * profile)4756 _elm_config_profile_set(const char *profile)
4757 {
4758    Eina_Bool is_mirrored;
4759    Eina_Bool translate;
4760    is_mirrored = _elm_config->is_mirrored;
4761    translate = _elm_config->translate;
4762 
4763    if (!profile) return;
4764 
4765    if (_elm_profile)
4766      {
4767         if (!strcmp(_elm_profile, profile))
4768           return;
4769 
4770         free(_elm_profile);
4771      }
4772 
4773    _elm_profile = strdup(profile);
4774 
4775    _color_overlays_cancel();
4776 
4777    _elm_config_reload_do();
4778 
4779    /* restore prev value which is not part of the EET file */
4780    _elm_config->is_mirrored = is_mirrored;
4781    _elm_config->translate = translate;
4782 
4783    _elm_recache();
4784    _config_apply();
4785    _elm_config_font_overlay_apply();
4786    _elm_config_color_overlay_apply();
4787    _elm_rescale();
4788    _elm_old_clouseau_reload();
4789    _elm_config_key_binding_hash();
4790 }
4791 
4792 void
_elm_config_shutdown(void)4793 _elm_config_shutdown(void)
4794 {
4795    efl_del_intercept_set(_efl_config_obj, NULL);
4796    efl_provider_unregister(efl_main_loop_get(), EFL_CONFIG_INTERFACE, _efl_config_obj);
4797    efl_provider_unregister(efl_main_loop_get(), EFL_CONFIG_GLOBAL_CLASS, _efl_config_obj);
4798    ELM_SAFE_FREE(_efl_config_obj, efl_del);
4799    ELM_SAFE_FREE(_elm_config, _config_free);
4800    ELM_SAFE_FREE(_elm_preferred_engine, eina_stringshare_del);
4801    ELM_SAFE_FREE(_elm_accel_preference, eina_stringshare_del);
4802    ELM_SAFE_FREE(_elm_cache_flush_poller, ecore_poller_del);
4803    ELM_SAFE_FREE(_elm_profile, free);
4804    ELM_SAFE_FREE(_getenv_once_envs, eina_hash_free);
4805    _elm_font_overlays_del_free();
4806 
4807    _elm_config_profile_derived_shutdown();
4808    _desc_shutdown();
4809 
4810    ELM_SAFE_FREE(_elm_key_bindings, eina_hash_free);
4811 }
4812 
4813 
4814 /* Efl.Config implementation */
4815 
4816 typedef const char * cstring;
4817 
4818 static inline Eina_Bool
_eina_value_to_int(const Eina_Value * val,int * i)4819 _eina_value_to_int(const Eina_Value *val, int *i)
4820 {
4821    Eina_Value *ival;
4822    Eina_Bool ret;
4823 
4824    if (eina_value_type_get(val) == EINA_VALUE_TYPE_INT)
4825      {
4826         return eina_value_get(val, i);
4827      }
4828 
4829    ival = eina_value_new(EINA_VALUE_TYPE_INT);
4830    if (!eina_value_convert(val, ival))
4831      ret = EINA_FALSE;
4832    else
4833      ret = eina_value_get(ival, i);
4834    eina_value_free(ival);
4835    return ret;
4836 }
4837 
4838 static inline Eina_Bool
_eina_value_to_cstring(const Eina_Value * val,cstring * s)4839 _eina_value_to_cstring(const Eina_Value *val, cstring *s)
4840 {
4841    Eina_Value *sval = eina_value_new(EINA_VALUE_TYPE_STRING);
4842    Eina_Bool ret = EINA_TRUE;
4843    if (!eina_value_convert(val, sval))
4844      ret = EINA_FALSE;
4845    else
4846      ret = eina_value_get(sval, s);
4847    eina_value_free(sval);
4848    return ret;
4849 }
4850 
4851 static inline Eina_Bool
_edje_channel_get(const char * channel,Edje_Channel * chan)4852 _edje_channel_get(const char *channel, Edje_Channel *chan)
4853 {
4854 
4855    if (!*channel)
4856      *chan = EDJE_CHANNEL_ALL;
4857    else
4858      {
4859         if (!strcmp("_effect", channel))
4860           *chan = EDJE_CHANNEL_EFFECT;
4861         else if (!strcmp("_background", channel))
4862           *chan = EDJE_CHANNEL_BACKGROUND;
4863         else if (!strcmp("_music", channel))
4864           *chan = EDJE_CHANNEL_MUSIC;
4865         else if (!strcmp("_foreground", channel))
4866           *chan = EDJE_CHANNEL_FOREGROUND;
4867         else if (!strcmp("_interface", channel))
4868           *chan = EDJE_CHANNEL_INTERFACE;
4869         else if (!strcmp("_input", channel))
4870           *chan = EDJE_CHANNEL_INPUT;
4871         else if (!strcmp("_alert", channel))
4872           *chan = EDJE_CHANNEL_ALERT;
4873         else if (!strcmp("_all", channel))
4874           *chan = EDJE_CHANNEL_ALL;
4875         else
4876           return EINA_FALSE;
4877      }
4878    return EINA_TRUE;
4879 }
4880 
4881 static const struct {
4882    Efl_Ui_Focus_Autoscroll_Mode  val;
4883    const char                   *str;
4884 } _enum_map_focus_autoscroll_mode[] = {
4885 { EFL_UI_FOCUS_AUTOSCROLL_MODE_SHOW, "show" },
4886 { EFL_UI_FOCUS_AUTOSCROLL_MODE_NONE, "none" },
4887 { EFL_UI_FOCUS_AUTOSCROLL_MODE_BRING_IN, "bring_in" }
4888 };
4889 
4890 static const struct {
4891    Efl_Ui_Softcursor_Mode  val;
4892    const char             *str;
4893 } _enum_map_softcursor_mode[] = {
4894 { EFL_UI_SOFTCURSOR_MODE_AUTO, "auto" },
4895 { EFL_UI_SOFTCURSOR_MODE_ON, "on" },
4896 { EFL_UI_SOFTCURSOR_MODE_OFF, "off" }
4897 };
4898 
4899 static const struct {
4900    Efl_Ui_Focus_Move_Policy  val;
4901    const char               *str;
4902 } _enum_map_focus_move_policy[] = {
4903 { EFL_UI_FOCUS_MOVE_POLICY_CLICK, "click" },
4904 { EFL_UI_FOCUS_MOVE_POLICY_MOVE_IN, "in" },
4905 { EFL_UI_FOCUS_MOVE_POLICY_KEY_ONLY, "key_only" }
4906 };
4907 
4908 EOLIAN static Eina_Bool
_efl_config_global_efl_config_config_set(Eo * obj EINA_UNUSED,void * _pd EINA_UNUSED,const char * name,const Eina_Value * val)4909 _efl_config_global_efl_config_config_set(Eo *obj EINA_UNUSED, void *_pd EINA_UNUSED,
4910                                          const char *name, const Eina_Value *val)
4911 {
4912    if (!name) return EINA_FALSE;
4913    // TODO: if (!val) reset to default
4914 
4915 #define CONFIG_SET(opt, primityp, valtyp, alttyp) do { \
4916    if (!strcmp(name, #opt)) \
4917      { \
4918         primityp v = 0; \
4919         alttyp alt = 0; \
4920         const Eina_Value_Type *typ = EINA_VALUE_TYPE_ ## valtyp; \
4921         if (eina_value_type_get(val) == typ)  \
4922           { \
4923              if (!eina_value_get(val, &v)) return EINA_FALSE; \
4924           } \
4925         else if (_eina_value_to_ ## alttyp(val, &alt)) \
4926           { \
4927              v = alt; \
4928           } \
4929         else \
4930           { \
4931              ERR("Invalid value type for config '%s' (got %s wanted %s)", \
4932                  name, eina_value_type_name_get(eina_value_type_get(val)), \
4933                  eina_value_type_name_get(EINA_VALUE_TYPE_ ## valtyp)); \
4934              return EINA_FALSE; \
4935           } \
4936         elm_config_ ## opt ## _set(v); \
4937         efl_event_callback_call(_efl_config_obj, EFL_CONFIG_EVENT_CONFIG_CHANGED, (void*)name); \
4938         return EINA_TRUE; \
4939      } \
4940    } while (0)
4941 
4942 #define CONFIG_SETB(opt) CONFIG_SET(opt, Eina_Bool, UCHAR, int)
4943 #define CONFIG_SETI(opt) CONFIG_SET(opt, int, INT, int)
4944 #define CONFIG_SETU(opt) CONFIG_SET(opt, unsigned int, UINT, int)
4945 #define CONFIG_SETD(opt) CONFIG_SET(opt, double, DOUBLE, int)
4946 #define CONFIG_SETS(opt) CONFIG_SET(opt, const char *, STRING, cstring)
4947 
4948 #define CONFIG_SETE(opt) do { \
4949    if (!strcmp(name, #opt)) \
4950      { \
4951         int v = -1; \
4952         if (eina_value_type_get(val) == EINA_VALUE_TYPE_STRING) \
4953           { \
4954              const char *str; \
4955              if (eina_value_get(val, &str)) \
4956                { \
4957                   for (unsigned i = 0; i < (sizeof(_enum_map_ ## opt) / sizeof(_enum_map_ ## opt[0])); i++) \
4958                     { \
4959                        if (eina_streq(_enum_map_ ## opt[i].str, str)) { v = _enum_map_ ## opt[i].val; break; } \
4960                     } \
4961                } \
4962              if (v == -1) \
4963                { \
4964                  ERR("Invalid value for config '%s' (got '%s')", #opt, str); \
4965                  return EINA_FALSE; \
4966                } \
4967           } \
4968         else if (!_eina_value_to_int(val, &v)) \
4969           { \
4970              ERR("Invalid value type for config '%s' (got %s wanted int or string)", \
4971                  name, eina_value_type_name_get(eina_value_type_get(val))); \
4972              return EINA_FALSE; \
4973           } \
4974         elm_config_ ## opt ## _set(v); \
4975         efl_event_callback_call(_efl_config_obj, EFL_CONFIG_EVENT_CONFIG_CHANGED, (void*)name); \
4976         return EINA_TRUE; \
4977      } \
4978    } while (0)
4979 
4980    CONFIG_SETB(scroll_bounce_enabled);
4981    CONFIG_SETD(scroll_bounce_friction);
4982    CONFIG_SETD(scroll_page_scroll_friction);
4983    CONFIG_SETB(context_menu_disabled);
4984    CONFIG_SETD(scroll_bring_in_scroll_friction);
4985    CONFIG_SETD(scroll_zoom_friction);
4986    CONFIG_SETB(scroll_thumbscroll_enabled);
4987    CONFIG_SETI(scroll_thumbscroll_threshold);
4988    CONFIG_SETI(scroll_thumbscroll_hold_threshold);
4989    CONFIG_SETD(scroll_thumbscroll_momentum_threshold);
4990    CONFIG_SETI(scroll_thumbscroll_flick_distance_tolerance);
4991    CONFIG_SETI(scroll_thumbscroll_momentum_distance_max);
4992    CONFIG_SETD(scroll_thumbscroll_friction);
4993    CONFIG_SETD(scroll_thumbscroll_momentum_friction);
4994    CONFIG_SETD(scroll_thumbscroll_min_friction);
4995    CONFIG_SETD(scroll_thumbscroll_friction_standard);
4996    CONFIG_SETD(scroll_thumbscroll_border_friction);
4997    CONFIG_SETD(scroll_thumbscroll_sensitivity_friction);
4998    CONFIG_SETB(scroll_thumbscroll_smooth_start);
4999    CONFIG_SETB(scroll_animation_disabled);
5000    CONFIG_SETD(scroll_accel_factor);
5001    CONFIG_SETD(scroll_thumbscroll_smooth_amount);
5002    CONFIG_SETD(scroll_thumbscroll_smooth_time_window);
5003    CONFIG_SETD(scroll_thumbscroll_acceleration_threshold);
5004    CONFIG_SETD(scroll_thumbscroll_acceleration_time_limit);
5005    CONFIG_SETD(scroll_thumbscroll_acceleration_weight);
5006 
5007    CONFIG_SETD(scroll_thumbscroll_momentum_animation_duration_min_limit);
5008    CONFIG_SETD(scroll_thumbscroll_momentum_animation_duration_max_limit);
5009 
5010    CONFIG_SETE(focus_autoscroll_mode);
5011    CONFIG_SETD(longpress_timeout);
5012    CONFIG_SETE(softcursor_mode);
5013    CONFIG_SETD(tooltip_delay);
5014    CONFIG_SETB(cursor_engine_only);
5015    CONFIG_SETD(scale);
5016    CONFIG_SETS(icon_theme);
5017    CONFIG_SETB(password_show_last);
5018    CONFIG_SETD(password_show_last_timeout);
5019    CONFIG_SETS(preferred_engine);
5020    CONFIG_SETS(accel_preference);
5021    //font_overlay const char *text_class, const char *font, Evas_Font_Size size);
5022    CONFIG_SETB(access);
5023    CONFIG_SETB(selection_unfocused_clear);
5024    //elm_config.h:EAPI void             elm_config_font_overlay_unset(const char *text_class);
5025    CONFIG_SETI(font_hint_type);
5026    CONFIG_SETI(finger_size);
5027    CONFIG_SETI(cache_flush_interval);
5028    CONFIG_SETB(cache_flush_enabled);
5029    CONFIG_SETI(cache_font_cache_size);
5030    CONFIG_SETI(cache_image_cache_size);
5031    CONFIG_SETI(cache_edje_file_cache_size);
5032    CONFIG_SETI(cache_edje_collection_cache_size);
5033    CONFIG_SETB(vsync);
5034    CONFIG_SETB(accel_preference_override);
5035    CONFIG_SETB(focus_highlight_enabled);
5036    CONFIG_SETB(focus_highlight_animate);
5037    CONFIG_SETB(focus_highlight_clip_disabled);
5038    CONFIG_SETE(focus_move_policy);
5039    CONFIG_SETB(item_select_on_focus_disabled);
5040    CONFIG_SETB(first_item_focus_on_first_focusin);
5041    CONFIG_SETB(mirrored);
5042    CONFIG_SETB(clouseau_enabled);
5043 
5044    //color_overlay const char *color_class,
5045    //elm_config.h:EAPI void      elm_config_color_overlay_unset(const char *color_class);
5046    CONFIG_SETB(magnifier_enable);
5047    CONFIG_SETD(magnifier_scale);
5048    CONFIG_SETB(window_auto_focus_enable);
5049    CONFIG_SETB(window_auto_focus_animate);
5050    CONFIG_SETB(popup_scrollable);
5051    CONFIG_SETB(atspi_mode);
5052    CONFIG_SETD(transition_duration_factor);
5053    CONFIG_SETS(web_backend);
5054    CONFIG_SETB(offline);
5055    CONFIG_SETI(powersave);
5056 
5057    CONFIG_SETD(glayer_long_tap_start_timeout);
5058    CONFIG_SETD(glayer_double_tap_timeout);
5059 
5060 #undef CONFIG_SET
5061 #define CONFIG_SET(opt, primityp, valtyp, alttyp) do { \
5062    if (!strcmp(name, #opt)) \
5063      { \
5064         primityp v = 0; \
5065         alttyp alt = 0; \
5066         const Eina_Value_Type *typ = EINA_VALUE_TYPE_ ## valtyp; \
5067         if (eina_value_type_get(val) == typ)  \
5068           { \
5069              if (!eina_value_get(val, &v)) return EINA_FALSE; \
5070           } \
5071         else if (_eina_value_to_ ## alttyp(val, &alt)) \
5072           { \
5073              v = alt; \
5074           } \
5075         else \
5076           { \
5077              ERR("Invalid value type for config '%s' (got %s wanted %s)", \
5078                  name, eina_value_type_name_get(eina_value_type_get(val)), \
5079                  eina_value_type_name_get(EINA_VALUE_TYPE_ ## valtyp)); \
5080              return EINA_FALSE; \
5081           } \
5082         _elm_config->opt = v; \
5083         _elm_config->priv.opt = EINA_TRUE; \
5084         efl_event_callback_call(_efl_config_obj, EFL_CONFIG_EVENT_CONFIG_CHANGED, (void*)name); \
5085         return EINA_TRUE; \
5086      } \
5087    } while (0)
5088 
5089 
5090    CONFIG_SETB(glayer_zoom_finger_enable);
5091    CONFIG_SETD(glayer_zoom_finger_factor);
5092    CONFIG_SETD(glayer_zoom_wheel_factor);
5093    CONFIG_SETD(glayer_zoom_distance_tolerance);
5094    CONFIG_SETD(glayer_rotate_finger_enable);
5095    CONFIG_SETD(glayer_rotate_angular_tolerance);
5096    CONFIG_SETD(glayer_line_min_length);
5097    CONFIG_SETD(glayer_line_distance_tolerance);
5098    CONFIG_SETD(glayer_line_angular_tolerance);
5099    CONFIG_SETU(glayer_flick_time_limit_ms);
5100    CONFIG_SETD(glayer_long_tap_start_timeout);
5101    CONFIG_SETD(glayer_double_tap_timeout);
5102    CONFIG_SETI(glayer_tap_finger_size);
5103    CONFIG_SETB(glayer_continues_enable);
5104 
5105    CONFIG_SETI(thumbscroll_momentum_distance_max);
5106    CONFIG_SETD(thumbscroll_momentum_friction);
5107    CONFIG_SETD(thumbscroll_momentum_animation_duration_min_limit);
5108    CONFIG_SETD(thumbscroll_momentum_animation_duration_max_limit);
5109    CONFIG_SETD(thumbscroll_momentum_threshold);
5110    CONFIG_SETD(thumbscroll_bounce_friction);
5111    CONFIG_SETD(thumbscroll_acceleration_threshold);
5112    CONFIG_SETD(thumbscroll_acceleration_time_limit);
5113    CONFIG_SETD(thumbscroll_acceleration_weight);
5114 
5115 
5116    const size_t len = sizeof("audio_mute") - 1;
5117    if (!strncmp(name, "audio_mute", len))
5118      {
5119         const char *channel = name + len;
5120         Edje_Channel chan;
5121         int v;
5122         if (!_eina_value_to_int(val, &v))
5123           {
5124              ERR("Invalid value type for config '%s' (got %s wanted int)",
5125                  name, eina_value_type_name_get(eina_value_type_get(val)));
5126              return EINA_FALSE;
5127           }
5128         if (!_edje_channel_get(channel, &chan))
5129           {
5130              ERR("Unknown audio channel '%s'", channel);
5131              return EINA_FALSE;
5132           }
5133         elm_config_audio_mute_set(chan, !!v);
5134 #ifdef ENABLE_MULTISENSE
5135         efl_event_callback_call(_efl_config_obj, EFL_CONFIG_EVENT_CONFIG_CHANGED, (void*)name);
5136         return EINA_TRUE;
5137 #else
5138         return EINA_FALSE;
5139 #endif
5140      }
5141 
5142    ERR("Config '%s' does not exist", name);
5143    return EINA_FALSE;
5144 }
5145 
5146 EOLIAN static Eina_Value *
_efl_config_global_efl_config_config_get(const Eo * obj EINA_UNUSED,void * _pd EINA_UNUSED,const char * name)5147 _efl_config_global_efl_config_config_get(const Eo *obj EINA_UNUSED, void *_pd EINA_UNUSED,
5148                                          const char *name)
5149 {
5150    Eina_Value *val = NULL;
5151 
5152    if (!name) return NULL;
5153 
5154    // NOTE: returning INT instead of UINT for unsigned int types
5155 
5156 #define CONFIG_GET(opt, primityp, valtyp) do { \
5157    if (!strcmp(name, #opt)) \
5158      { \
5159         val = eina_value_new(EINA_VALUE_TYPE_ ## valtyp); \
5160         eina_value_set(val, elm_config_ ## opt ## _get()); \
5161         return val; \
5162      } \
5163    } while (0)
5164 
5165 #define CONFIG_GETB(opt) CONFIG_GET(opt, Eina_Bool, UCHAR)
5166 #define CONFIG_GETI(opt) CONFIG_GET(opt, int, INT)
5167 #define CONFIG_GETU(opt) CONFIG_GET(opt, unsigned int, UINT)
5168 #define CONFIG_GETD(opt) CONFIG_GET(opt, double, DOUBLE)
5169 #define CONFIG_GETS(opt) CONFIG_GET(opt, const char *, STRING)
5170 
5171 #define CONFIG_GETE(opt) do { \
5172    if (!strcmp(name, #opt)) \
5173      { \
5174         int v = elm_config_ ## opt ## _get(); \
5175         if ((v < 0) || (v > (int)(sizeof(_enum_map_ ## opt) / sizeof(_enum_map_ ## opt[0])))) \
5176           v = 0; \
5177         val = eina_value_new(EINA_VALUE_TYPE_STRING); \
5178         eina_value_set(val, _enum_map_ ## opt[v].str); \
5179         return val; \
5180      } \
5181    } while (0)
5182 
5183    CONFIG_GETB(scroll_bounce_enabled);
5184    CONFIG_GETD(scroll_bounce_friction);
5185    CONFIG_GETD(scroll_page_scroll_friction);
5186    CONFIG_GETB(context_menu_disabled);
5187    CONFIG_GETD(scroll_bring_in_scroll_friction);
5188    CONFIG_GETD(scroll_zoom_friction);
5189    CONFIG_GETB(scroll_thumbscroll_enabled);
5190    CONFIG_GETI(scroll_thumbscroll_threshold);
5191    CONFIG_GETI(scroll_thumbscroll_hold_threshold);
5192    CONFIG_GETD(scroll_thumbscroll_momentum_threshold);
5193    CONFIG_GETI(scroll_thumbscroll_flick_distance_tolerance);
5194    CONFIG_GETI(scroll_thumbscroll_momentum_distance_max);
5195    CONFIG_GETD(scroll_thumbscroll_friction);
5196    CONFIG_GETD(scroll_thumbscroll_momentum_friction);
5197    CONFIG_GETD(scroll_thumbscroll_min_friction);
5198    CONFIG_GETD(scroll_thumbscroll_friction_standard);
5199    CONFIG_GETD(scroll_thumbscroll_border_friction);
5200    CONFIG_GETD(scroll_thumbscroll_sensitivity_friction);
5201    CONFIG_GETB(scroll_thumbscroll_smooth_start);
5202    CONFIG_GETB(scroll_animation_disabled);
5203    CONFIG_GETD(scroll_accel_factor);
5204    CONFIG_GETD(scroll_thumbscroll_smooth_amount);
5205    CONFIG_GETD(scroll_thumbscroll_smooth_time_window);
5206    CONFIG_GETD(scroll_thumbscroll_acceleration_threshold);
5207    CONFIG_GETD(scroll_thumbscroll_acceleration_time_limit);
5208    CONFIG_GETD(scroll_thumbscroll_acceleration_weight);
5209 
5210    CONFIG_GETD(scroll_thumbscroll_momentum_animation_duration_min_limit);
5211    CONFIG_GETD(scroll_thumbscroll_momentum_animation_duration_max_limit);
5212 
5213    CONFIG_GETE(focus_autoscroll_mode);
5214    CONFIG_GETD(longpress_timeout);
5215    CONFIG_GETE(softcursor_mode);
5216    CONFIG_GETD(tooltip_delay);
5217    CONFIG_GETB(cursor_engine_only);
5218    CONFIG_GETD(scale);
5219    CONFIG_GETS(icon_theme);
5220    CONFIG_GETB(password_show_last);
5221    CONFIG_GETD(password_show_last_timeout);
5222    CONFIG_GETS(preferred_engine);
5223    CONFIG_GETS(accel_preference);
5224    //font_overlay
5225    CONFIG_GETB(access);
5226    CONFIG_GETB(selection_unfocused_clear);
5227    //elm_config_font_overlay_unset
5228    //CONFIG_GETI(font_hint_type); // this has no get!
5229    CONFIG_GETI(finger_size);
5230    CONFIG_GETI(cache_flush_interval);
5231    CONFIG_GETB(cache_flush_enabled);
5232    CONFIG_GETI(cache_font_cache_size);
5233    CONFIG_GETI(cache_image_cache_size);
5234    CONFIG_GETI(cache_edje_file_cache_size);
5235    CONFIG_GETI(cache_edje_collection_cache_size);
5236    CONFIG_GETB(vsync);
5237    CONFIG_GETB(accel_preference_override);
5238    CONFIG_GETB(focus_highlight_enabled);
5239    CONFIG_GETB(focus_highlight_animate);
5240    CONFIG_GETB(focus_highlight_clip_disabled);
5241    CONFIG_GETE(focus_move_policy);
5242    CONFIG_GETB(item_select_on_focus_disabled);
5243    CONFIG_GETB(first_item_focus_on_first_focusin);
5244    CONFIG_GETB(mirrored);
5245    CONFIG_GETB(clouseau_enabled);
5246 
5247    //color_overlay
5248    //color_overlay_unset
5249    CONFIG_GETB(magnifier_enable);
5250    CONFIG_GETD(magnifier_scale);
5251    CONFIG_GETB(window_auto_focus_enable);
5252    CONFIG_GETB(window_auto_focus_animate);
5253    CONFIG_GETB(popup_scrollable);
5254    CONFIG_GETB(atspi_mode);
5255    CONFIG_GETD(transition_duration_factor);
5256    CONFIG_GETS(web_backend);
5257    CONFIG_GETB(offline);
5258    CONFIG_GETI(powersave);
5259    CONFIG_GETD(drag_anim_duration);
5260 
5261    CONFIG_GETD(glayer_long_tap_start_timeout);
5262    CONFIG_GETD(glayer_double_tap_timeout);
5263 #undef CONFIG_GET
5264 #define CONFIG_GET(opt, primityp, valtyp) do { \
5265    if (!strcmp(name, #opt)) \
5266      { \
5267         val = eina_value_new(EINA_VALUE_TYPE_ ## valtyp); \
5268         eina_value_set(val, _elm_config->opt); \
5269         return val; \
5270      } \
5271    } while (0)
5272    CONFIG_GETB(glayer_zoom_finger_enable);
5273    CONFIG_GETD(glayer_zoom_finger_factor);
5274    CONFIG_GETD(glayer_zoom_wheel_factor);
5275    CONFIG_GETD(glayer_zoom_distance_tolerance);
5276    CONFIG_GETD(glayer_rotate_finger_enable);
5277    CONFIG_GETD(glayer_rotate_angular_tolerance);
5278    CONFIG_GETD(glayer_line_min_length);
5279    CONFIG_GETD(glayer_line_distance_tolerance);
5280    CONFIG_GETD(glayer_line_angular_tolerance);
5281    CONFIG_GETU(glayer_flick_time_limit_ms);
5282    CONFIG_GETD(glayer_long_tap_start_timeout);
5283    CONFIG_GETD(glayer_double_tap_timeout);
5284    CONFIG_GETI(glayer_tap_finger_size);
5285    CONFIG_GETB(glayer_continues_enable);
5286 
5287    CONFIG_GETI(thumbscroll_momentum_distance_max);
5288    CONFIG_GETD(thumbscroll_momentum_friction);
5289    CONFIG_GETD(thumbscroll_momentum_animation_duration_min_limit);
5290    CONFIG_GETD(thumbscroll_momentum_animation_duration_max_limit);
5291    CONFIG_GETD(thumbscroll_momentum_threshold);
5292    CONFIG_GETD(thumbscroll_bounce_friction);
5293    CONFIG_GETD(thumbscroll_acceleration_threshold);
5294    CONFIG_GETD(thumbscroll_acceleration_time_limit);
5295    CONFIG_GETD(thumbscroll_acceleration_weight);
5296 
5297    const size_t len = sizeof("audio_mute") - 1;
5298    if (!strncmp(name, "audio_mute", len))
5299      {
5300         const char *channel = name + len;
5301         Edje_Channel chan;
5302         Eina_Bool b;
5303         if (!_edje_channel_get(channel, &chan))
5304           {
5305              ERR("Unknown audio channel '%s'", channel);
5306              return NULL;
5307           }
5308         val = eina_value_new(EINA_VALUE_TYPE_UCHAR);
5309         b = elm_config_audio_mute_get(chan);
5310         if (b != edje_audio_channel_mute_get(chan))
5311           ERR("config state for audio channel '%s' does not match active state!", channel);
5312         eina_value_set(val, b);
5313         return val;
5314      }
5315 
5316    ERR("Config '%s' does not exist", name);
5317    return NULL;
5318 }
5319 
5320 EOLIAN static void
_efl_config_global_profile_set(Eo * obj EINA_UNUSED,void * _pd EINA_UNUSED,const char * profile)5321 _efl_config_global_profile_set(Eo *obj EINA_UNUSED, void *_pd EINA_UNUSED, const char *profile)
5322 {
5323    elm_config_profile_set(profile);
5324 }
5325 
5326 EOLIAN static const char *
_efl_config_global_profile_get(const Eo * obj EINA_UNUSED,void * _pd EINA_UNUSED)5327 _efl_config_global_profile_get(const Eo *obj EINA_UNUSED, void *_pd EINA_UNUSED)
5328 {
5329    return elm_config_profile_get();
5330 }
5331 
5332 EOLIAN static Eina_Bool
_efl_config_global_save(Eo * obj EINA_UNUSED,void * _pd EINA_UNUSED,const char * profile)5333 _efl_config_global_save(Eo *obj EINA_UNUSED, void *_pd EINA_UNUSED, const char *profile)
5334 {
5335    return _elm_config_save(_elm_config, profile);
5336 }
5337 
5338 typedef struct
5339 {
5340    Eina_Iterator  iterator;
5341    Eina_List     *list;
5342    Eina_Iterator *real_iterator;
5343    Eo            *object;
5344 } Profile_Iterator;
5345 
5346 static Eina_Bool
_profile_iterator_next(Profile_Iterator * it,void ** data)5347 _profile_iterator_next(Profile_Iterator *it, void **data)
5348 {
5349    Efl_Gfx_Entity *sub;
5350 
5351    if (!it->object) return EINA_FALSE;
5352    if (!eina_iterator_next(it->real_iterator, (void **) &sub))
5353      return EINA_FALSE;
5354 
5355    if (data) *data = sub;
5356    return EINA_TRUE;
5357 }
5358 
5359 static Eo *
_profile_iterator_get_container(Profile_Iterator * it)5360 _profile_iterator_get_container(Profile_Iterator *it)
5361 {
5362    return it->object;
5363 }
5364 
5365 static void
_profile_iterator_free(Profile_Iterator * it)5366 _profile_iterator_free(Profile_Iterator *it)
5367 {
5368    efl_wref_del(it->object, &it->object);
5369    eina_iterator_free(it->real_iterator);
5370    elm_config_profile_list_free(it->list);
5371    free(it);
5372 }
5373 
5374 EOLIAN static Eina_Iterator *
_efl_config_global_profile_iterate(Eo * obj EINA_UNUSED,void * _pd EINA_UNUSED,Eina_Bool hidden)5375 _efl_config_global_profile_iterate(Eo *obj EINA_UNUSED, void *_pd EINA_UNUSED, Eina_Bool hidden)
5376 {
5377    Profile_Iterator *it;
5378    Eina_List *list;
5379 
5380    list = _elm_config_profiles_list(!hidden);
5381    if (!list) return NULL;
5382 
5383    it = calloc(1, sizeof(*it));
5384    if (!it) return NULL;
5385 
5386    EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR);
5387 
5388    it->list = list;
5389    it->real_iterator = eina_list_iterator_new(it->list);
5390    it->iterator.version = EINA_ITERATOR_VERSION;
5391    it->iterator.next = FUNC_ITERATOR_NEXT(_profile_iterator_next);
5392    it->iterator.get_container = FUNC_ITERATOR_GET_CONTAINER(_profile_iterator_get_container);
5393    it->iterator.free = FUNC_ITERATOR_FREE(_profile_iterator_free);
5394    efl_wref_add(obj, &it->object);
5395 
5396    return &it->iterator;
5397 }
5398 
5399 EOLIAN static Eina_Bool
_efl_config_global_profile_exists(Eo * obj EINA_UNUSED,void * _pd EINA_UNUSED,const char * profile)5400 _efl_config_global_profile_exists(Eo *obj EINA_UNUSED, void *_pd EINA_UNUSED, const char *profile)
5401 {
5402    return elm_config_profile_exists(profile);
5403 }
5404 
5405 EOLIAN static Eina_Stringshare *
_efl_config_global_profile_dir_get(Eo * obj EINA_UNUSED,void * _pd EINA_UNUSED,const char * profile,Eina_Bool is_user)5406 _efl_config_global_profile_dir_get(Eo *obj EINA_UNUSED, void *_pd EINA_UNUSED, const char *profile, Eina_Bool is_user)
5407 {
5408    Eina_Stringshare *str;
5409    const char *dir;
5410 
5411    dir = elm_config_profile_dir_get(profile, is_user);
5412    str = eina_stringshare_add(dir);
5413    elm_config_profile_dir_free(dir);
5414 
5415    return str;
5416 }
5417 
5418 EOLIAN static void
_efl_config_global_profile_derived_add(Eo * obj EINA_UNUSED,void * _pd EINA_UNUSED,const char * profile,const char * options)5419 _efl_config_global_profile_derived_add(Eo *obj EINA_UNUSED, void *_pd EINA_UNUSED, const char *profile, const char *options)
5420 {
5421    elm_config_profile_derived_add(profile, options);
5422 }
5423 
5424 EOLIAN static void
_efl_config_global_profile_derived_del(Eo * obj EINA_UNUSED,void * _pd EINA_UNUSED,const char * profile)5425 _efl_config_global_profile_derived_del(Eo *obj EINA_UNUSED, void *_pd EINA_UNUSED, const char *profile)
5426 {
5427    elm_config_profile_derived_del(profile);
5428 }
5429 
5430 #include "efl_config_global.eo.c"
5431