move getting started to header.
[framework/uifw/elementary.git] / src / lib / elm_main.c
1 #ifdef HAVE_CONFIG_H
2 # include "elementary_config.h"
3 #endif
4
5 #include <dlfcn.h> /* dlopen,dlclose,etc */
6
7 #ifdef HAVE_CRT_EXTERNS_H
8 # include <crt_externs.h>
9 #endif
10
11 #ifdef HAVE_EVIL
12 # include <Evil.h>
13 #endif
14
15 #include <Elementary.h>
16 #include "elm_priv.h"
17
18 #define SEMI_BROKEN_QUICKLAUNCH 1
19
20 static Elm_Version _version = { VMAJ, VMIN, VMIC, VREV };
21 EAPI Elm_Version *elm_version = &_version;
22
23 Eina_Bool
24 _elm_dangerous_call_check(const char *call)
25 {
26    char buf[256];
27    const char *eval;
28
29    snprintf(buf, sizeof(buf), "%i.%i.%i.%i", VMAJ, VMIN, VMIC, VREV);
30    eval = getenv("ELM_NO_FINGER_WAGGLING");
31    if ((eval) && (!strcmp(eval, buf)))
32      return 0;
33    printf("ELEMENTARY FINGER WAGGLE!!!!!!!!!!\n"
34           "\n"
35           "  %s() used.\n"
36           "PLEASE see the API documentation for this function. This call\n"
37           "should almost never be used. Only in very special cases.\n"
38           "\n"
39           "To remove this warning please set the environment variable:\n"
40           "  ELM_NO_FINGER_WAGGLING\n"
41           "To the value of the Elementary version + revision number. e.g.:\n"
42           "  1.2.5.40295\n"
43           "\n"
44           ,
45           call);
46    return 1;
47 }
48
49 static Eina_Bool _elm_signal_exit(void *data,
50                                   int   ev_type,
51                                   void *ev);
52
53 static Eina_Prefix *pfx = NULL;
54 char *_elm_appname = NULL;
55 const char *_elm_data_dir = NULL;
56 const char *_elm_lib_dir = NULL;
57 int _elm_log_dom = -1;
58
59 EAPI int ELM_EVENT_POLICY_CHANGED = 0;
60
61 static int _elm_init_count = 0;
62 static int _elm_sub_init_count = 0;
63 static int _elm_ql_init_count = 0;
64 static int _elm_policies[ELM_POLICY_LAST];
65 static Ecore_Event_Handler *_elm_exit_handler = NULL;
66 static Eina_Bool quicklaunch_on = 0;
67
68 static Eina_Bool
69 _elm_signal_exit(void *data  __UNUSED__,
70                  int ev_type __UNUSED__,
71                  void *ev    __UNUSED__)
72 {
73    elm_exit();
74    return ECORE_CALLBACK_PASS_ON;
75 }
76
77 void
78 _elm_rescale(void)
79 {
80    edje_scale_set(_elm_config->scale);
81    _elm_win_rescale(NULL, EINA_FALSE);
82 }
83
84 static void *app_mainfunc = NULL;
85 static const char *app_domain = NULL;
86 static const char *app_checkfile = NULL;
87
88 static const char *app_compile_bin_dir = NULL;
89 static const char *app_compile_lib_dir = NULL;
90 static const char *app_compile_data_dir = NULL;
91 static const char *app_compile_locale_dir = NULL;
92 static const char *app_prefix_dir = NULL;
93 static const char *app_bin_dir = NULL;
94 static const char *app_lib_dir = NULL;
95 static const char *app_data_dir = NULL;
96 static const char *app_locale_dir = NULL;
97
98 static Eina_Prefix *app_pfx = NULL;
99
100 static void
101 _prefix_check(void)
102 {
103    int argc = 0;
104    char **argv = NULL;
105    const char *dirs[4] = { NULL, NULL, NULL, NULL };
106    char *caps = NULL, *p1, *p2;
107
108    if (app_pfx) return;
109    if (!app_domain) return;
110
111    ecore_app_args_get(&argc, &argv);
112    if (argc < 1) return;
113
114    dirs[0] = app_compile_bin_dir;
115    dirs[1] = app_compile_lib_dir;
116    dirs[2] = app_compile_data_dir;
117    dirs[3] = app_compile_locale_dir;
118
119    if (!dirs[1]) dirs[1] = dirs[0];
120    if (!dirs[0]) dirs[0] = dirs[1];
121    if (!dirs[3]) dirs[3] = dirs[2];
122    if (!dirs[2]) dirs[2] = dirs[3];
123
124    if (app_domain)
125      {
126         caps = alloca(strlen(app_domain) + 1);
127         for (p1 = (char *)app_domain, p2 = caps; *p1; p1++, p2++)
128            *p2 = toupper(*p1);
129         *p2 = 0;
130      }
131    app_pfx = eina_prefix_new(argv[0], app_mainfunc, caps, app_domain,
132                              app_checkfile, dirs[0], dirs[1], dirs[2], dirs[3]);
133 }
134
135 static void
136 _prefix_shutdown(void)
137 {
138    if (app_pfx) eina_prefix_free(app_pfx);
139    if (app_domain) eina_stringshare_del(app_domain);
140    if (app_checkfile) eina_stringshare_del(app_checkfile);
141    if (app_compile_bin_dir) eina_stringshare_del(app_compile_bin_dir);
142    if (app_compile_lib_dir) eina_stringshare_del(app_compile_lib_dir);
143    if (app_compile_data_dir) eina_stringshare_del(app_compile_data_dir);
144    if (app_compile_locale_dir) eina_stringshare_del(app_compile_locale_dir);
145    if (app_prefix_dir) eina_stringshare_del(app_prefix_dir);
146    if (app_bin_dir) eina_stringshare_del(app_bin_dir);
147    if (app_lib_dir) eina_stringshare_del(app_lib_dir);
148    if (app_data_dir) eina_stringshare_del(app_data_dir);
149    if (app_locale_dir) eina_stringshare_del(app_locale_dir);
150    app_mainfunc = NULL;
151    app_domain = NULL;
152    app_checkfile = NULL;
153    app_compile_bin_dir = NULL;
154    app_compile_lib_dir = NULL;
155    app_compile_data_dir = NULL;
156    app_compile_locale_dir = NULL;
157    app_prefix_dir = NULL;
158    app_bin_dir = NULL;
159    app_lib_dir = NULL;
160    app_data_dir = NULL;
161    app_locale_dir = NULL;
162    app_pfx = NULL;
163 }
164
165 EAPI int
166 elm_init(int    argc,
167          char **argv)
168 {
169    _elm_init_count++;
170    if (_elm_init_count > 1) return _elm_init_count;
171    elm_quicklaunch_init(argc, argv);
172    elm_quicklaunch_sub_init(argc, argv);
173    _prefix_shutdown();
174    return _elm_init_count;
175 }
176
177 EAPI int
178 elm_shutdown(void)
179 {
180    _elm_init_count--;
181    if (_elm_init_count > 0) return _elm_init_count;
182    _elm_win_shutdown();
183    while (_elm_win_deferred_free) ecore_main_loop_iterate();
184 // wrningz :(
185 //   _prefix_shutdown();
186    elm_quicklaunch_sub_shutdown();
187    elm_quicklaunch_shutdown();
188    return _elm_init_count;
189 }
190
191 EAPI void
192 elm_app_info_set(void *mainfunc, const char *dom, const char *checkfile)
193 {
194    app_mainfunc = mainfunc;
195    eina_stringshare_replace(&app_domain, dom);
196    eina_stringshare_replace(&app_checkfile, checkfile);
197 }
198
199 EAPI void
200 elm_app_compile_bin_dir_set(const char *dir)
201 {
202    eina_stringshare_replace(&app_compile_bin_dir, dir);
203 }
204
205 EAPI void
206 elm_app_compile_lib_dir_set(const char *dir)
207 {
208    eina_stringshare_replace(&app_compile_lib_dir, dir);
209 }
210
211 EAPI void
212 elm_app_compile_data_dir_set(const char *dir)
213 {
214    eina_stringshare_replace(&app_compile_data_dir, dir);
215 }
216
217 EAPI void
218 elm_app_compile_locale_set(const char *dir)
219 {
220    eina_stringshare_replace(&app_compile_locale_dir, dir);
221 }
222
223 EAPI const char *
224 elm_app_prefix_dir_get(void)
225 {
226    if (app_prefix_dir) return app_prefix_dir;
227    _prefix_check();
228   if (!app_pfx) return "";
229    app_prefix_dir = eina_prefix_get(app_pfx);
230    return app_prefix_dir;
231 }
232
233 EAPI const char *
234 elm_app_bin_dir_get(void)
235 {
236    if (app_bin_dir) return app_bin_dir;
237    _prefix_check();
238    if (!app_pfx) return "";
239    app_bin_dir = eina_prefix_bin_get(app_pfx);
240    return app_bin_dir;
241 }
242
243 EAPI const char *
244 elm_app_lib_dir_get(void)
245 {
246    if (app_lib_dir) return app_lib_dir;
247    _prefix_check();
248    if (!app_pfx) return "";
249    app_lib_dir = eina_prefix_lib_get(app_pfx);
250    return app_lib_dir;
251 }
252
253 EAPI const char *
254 elm_app_data_dir_get(void)
255 {
256    if (app_data_dir) return app_data_dir;
257    _prefix_check();
258    if (!app_pfx) return "";
259    app_data_dir = eina_prefix_data_get(app_pfx);
260    return app_data_dir;
261 }
262
263 EAPI const char *
264 elm_app_locale_dir_get(void)
265 {
266    if (app_locale_dir) return app_locale_dir;
267    _prefix_check();
268    if (!app_pfx) return "";
269    app_locale_dir = eina_prefix_locale_get(app_pfx);
270    return app_locale_dir;
271 }
272
273 #ifdef ELM_EDBUS
274 static int _elm_need_e_dbus = 0;
275 #endif
276 EAPI Eina_Bool
277 elm_need_e_dbus(void)
278 {
279 #ifdef ELM_EDBUS
280    if (_elm_need_e_dbus++) return EINA_TRUE;
281    e_dbus_init();
282    return EINA_TRUE;
283 #else
284    return EINA_FALSE;
285 #endif
286 }
287
288 static void
289 _elm_unneed_e_dbus(void)
290 {
291 #ifdef ELM_EDBUS
292    if (--_elm_need_e_dbus) return;
293
294    _elm_need_e_dbus = 0;
295    e_dbus_shutdown();
296 #endif
297 }
298
299 #ifdef ELM_EFREET
300 static int _elm_need_efreet = 0;
301 #endif
302 EAPI Eina_Bool
303 elm_need_efreet(void)
304 {
305 #ifdef ELM_EFREET
306    if (_elm_need_efreet++) return EINA_TRUE;
307    efreet_init();
308    efreet_mime_init();
309    efreet_trash_init();
310     /*
311      {
312         Eina_List **list;
313
314         list = efreet_icon_extra_list_get();
315         if (list)
316           {
317              e_user_dir_concat_static(buf, "icons");
318              *list = eina_list_prepend(*list, (void *)eina_stringshare_add(buf));
319              e_prefix_data_concat_static(buf, "data/icons");
320              *list = eina_list_prepend(*list, (void *)eina_stringshare_add(buf));
321           }
322      }
323    */
324    return EINA_TRUE;
325 #else
326    return EINA_FALSE;
327 #endif
328 }
329
330 static void
331 _elm_unneed_efreet(void)
332 {
333 #ifdef ELM_EFREET
334    if (--_elm_need_efreet) return;
335
336    _elm_need_efreet = 0;
337    efreet_trash_shutdown();
338    efreet_mime_shutdown();
339    efreet_shutdown();
340 #endif
341 }
342
343 EAPI void
344 elm_quicklaunch_mode_set(Eina_Bool ql_on)
345 {
346    quicklaunch_on = ql_on;
347 }
348
349 EAPI Eina_Bool
350 elm_quicklaunch_mode_get(void)
351 {
352    return quicklaunch_on;
353 }
354
355 EAPI int
356 elm_quicklaunch_init(int    argc,
357                      char **argv)
358 {
359    _elm_ql_init_count++;
360    if (_elm_ql_init_count > 1) return _elm_ql_init_count;
361    eina_init();
362    _elm_log_dom = eina_log_domain_register("elementary", EINA_COLOR_LIGHTBLUE);
363    if (!_elm_log_dom)
364      {
365         EINA_LOG_ERR("could not register elementary log domain.");
366         _elm_log_dom = EINA_LOG_DOMAIN_GLOBAL;
367      }
368
369    eet_init();
370    ecore_init();
371
372 #ifdef HAVE_ELEMENTARY_EMAP
373    emap_init();
374 #endif
375    ecore_app_args_set(argc, (const char **)argv);
376
377    memset(_elm_policies, 0, sizeof(_elm_policies));
378    if (!ELM_EVENT_POLICY_CHANGED)
379      ELM_EVENT_POLICY_CHANGED = ecore_event_type_new();
380
381    ecore_file_init();
382
383    _elm_exit_handler = ecore_event_handler_add(ECORE_EVENT_SIGNAL_EXIT, _elm_signal_exit, NULL);
384
385    if (argv) _elm_appname = strdup(ecore_file_file_get(argv[0]));
386
387    pfx = eina_prefix_new(NULL, elm_quicklaunch_init,
388                          "ELM", "elementary", "config/profile.cfg",
389                          PACKAGE_LIB_DIR, /* don't have a bin dir currently */
390                          PACKAGE_LIB_DIR,
391                          PACKAGE_DATA_DIR,
392                          LOCALE_DIR);
393    if (pfx)
394      {
395         _elm_data_dir = eina_stringshare_add(eina_prefix_data_get(pfx));
396         _elm_lib_dir = eina_stringshare_add(eina_prefix_lib_get(pfx));
397      }
398    if (!_elm_data_dir) _elm_data_dir = eina_stringshare_add("/");
399    if (!_elm_lib_dir) _elm_lib_dir = eina_stringshare_add("/");
400
401    _elm_config_init();
402    return _elm_ql_init_count;
403 }
404
405 EAPI int
406 elm_quicklaunch_sub_init(int    argc,
407                          char **argv)
408 {
409    _elm_sub_init_count++;
410    if (_elm_sub_init_count > 1) return _elm_sub_init_count;
411    if (quicklaunch_on)
412      {
413 #ifdef SEMI_BROKEN_QUICKLAUNCH
414         return _elm_sub_init_count;
415 #endif
416      }
417    if (!quicklaunch_on)
418      {
419         ecore_app_args_set(argc, (const char **)argv);
420         evas_init();
421         edje_init();
422         _elm_module_init();
423         _elm_config_sub_init();
424 #define ENGINE_COMPARE(name) (!strcmp(_elm_config->engine, name))
425         if (ENGINE_COMPARE(ELM_SOFTWARE_X11) ||
426             ENGINE_COMPARE(ELM_SOFTWARE_16_X11) ||
427             ENGINE_COMPARE(ELM_XRENDER_X11) ||
428             ENGINE_COMPARE(ELM_OPENGL_X11))
429 #undef ENGINE_COMPARE
430           {
431 #ifdef HAVE_ELEMENTARY_X
432              ecore_x_init(NULL);
433 #endif
434           }
435         ecore_evas_init(); // FIXME: check errors
436         ecore_imf_init();
437         ecore_con_init();
438         ecore_con_url_init();
439      }
440    return _elm_sub_init_count;
441 }
442
443 EAPI int
444 elm_quicklaunch_sub_shutdown(void)
445 {
446    _elm_sub_init_count--;
447    if (_elm_sub_init_count > 0) return _elm_sub_init_count;
448    if (quicklaunch_on)
449      {
450 #ifdef SEMI_BROKEN_QUICKLAUNCH
451         return _elm_sub_init_count;
452 #endif
453      }
454    if (!quicklaunch_on)
455      {
456         _elm_win_shutdown();
457         _elm_module_shutdown();
458         ecore_con_url_shutdown();
459         ecore_con_shutdown();
460         ecore_imf_shutdown();
461         ecore_evas_shutdown();
462 #define ENGINE_COMPARE(name) (!strcmp(_elm_config->engine, name))
463         if (ENGINE_COMPARE(ELM_SOFTWARE_X11) ||
464             ENGINE_COMPARE(ELM_SOFTWARE_16_X11) ||
465             ENGINE_COMPARE(ELM_XRENDER_X11) ||
466             ENGINE_COMPARE(ELM_OPENGL_X11))
467 #undef ENGINE_COMPARE
468           {
469 #ifdef HAVE_ELEMENTARY_X
470              ecore_x_disconnect();
471 #endif
472           }
473 #define ENGINE_COMPARE(name) (!strcmp(_elm_config->engine, name))
474         if (ENGINE_COMPARE(ELM_SOFTWARE_X11) ||
475             ENGINE_COMPARE(ELM_SOFTWARE_16_X11) ||
476             ENGINE_COMPARE(ELM_XRENDER_X11) ||
477             ENGINE_COMPARE(ELM_OPENGL_X11) ||
478             ENGINE_COMPARE(ELM_SOFTWARE_SDL) ||
479             ENGINE_COMPARE(ELM_SOFTWARE_16_SDL) ||
480             ENGINE_COMPARE(ELM_OPENGL_SDL) ||
481             ENGINE_COMPARE(ELM_SOFTWARE_WIN32) ||
482             ENGINE_COMPARE(ELM_SOFTWARE_16_WINCE))
483 #undef ENGINE_COMPARE
484           evas_cserve_disconnect();
485         edje_shutdown();
486         evas_shutdown();
487      }
488    return _elm_sub_init_count;
489 }
490
491 EAPI int
492 elm_quicklaunch_shutdown(void)
493 {
494    _elm_ql_init_count--;
495    if (_elm_ql_init_count > 0) return _elm_ql_init_count;
496    if (pfx) eina_prefix_free(pfx);
497    pfx = NULL;
498    eina_stringshare_del(_elm_data_dir);
499    _elm_data_dir = NULL;
500    eina_stringshare_del(_elm_lib_dir);
501    _elm_lib_dir = NULL;
502
503    free(_elm_appname);
504    _elm_appname = NULL;
505
506    _elm_config_shutdown();
507
508    ecore_event_handler_del(_elm_exit_handler);
509    _elm_exit_handler = NULL;
510
511    _elm_theme_shutdown();
512    _elm_unneed_efreet();
513    _elm_unneed_e_dbus();
514    _elm_unneed_ethumb();
515    ecore_file_shutdown();
516
517 #ifdef HAVE_ELEMENTARY_EMAP
518    emap_shutdown();
519 #endif
520
521    ecore_shutdown();
522    eet_shutdown();
523
524    if ((_elm_log_dom > -1) && (_elm_log_dom != EINA_LOG_DOMAIN_GLOBAL))
525      {
526         eina_log_domain_unregister(_elm_log_dom);
527         _elm_log_dom = -1;
528      }
529
530    _elm_widget_type_clear();
531
532    eina_shutdown();
533    return _elm_ql_init_count;
534 }
535
536 EAPI void
537 elm_quicklaunch_seed(void)
538 {
539 #ifndef SEMI_BROKEN_QUICKLAUNCH
540    if (quicklaunch_on)
541      {
542         Evas_Object *win, *bg, *bt;
543
544         win = elm_win_add(NULL, "seed", ELM_WIN_BASIC);
545         bg = elm_bg_add(win);
546         elm_win_resize_object_add(win, bg);
547         evas_object_show(bg);
548         bt = elm_button_add(win);
549         elm_button_label_set(bt, " abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789~-_=+\\|]}[{;:'\",<.>/?");
550         elm_win_resize_object_add(win, bt);
551         ecore_main_loop_iterate();
552         evas_object_del(win);
553         ecore_main_loop_iterate();
554 #define ENGINE_COMPARE(name) (!strcmp(_elm_config->engine, name))
555         if (ENGINE_COMPARE(ELM_SOFTWARE_X11) ||
556             ENGINE_COMPARE(ELM_SOFTWARE_16_X11) ||
557             ENGINE_COMPARE(ELM_XRENDER_X11) ||
558             ENGINE_COMPARE(ELM_OPENGL_X11))
559 #undef ENGINE_COMPARE
560           {
561 # ifdef HAVE_ELEMENTARY_X
562              ecore_x_sync();
563 # endif
564           }
565         ecore_main_loop_iterate();
566      }
567 #endif
568 }
569
570 static void *qr_handle = NULL;
571 static int (*qr_main)(int    argc,
572                       char **argv) = NULL;
573
574 EAPI Eina_Bool
575 elm_quicklaunch_prepare(int argc __UNUSED__,
576                         char   **argv)
577 {
578 #ifdef HAVE_FORK
579    char *exe = elm_quicklaunch_exe_path_get(argv[0]);
580    if (!exe)
581      {
582         ERR("requested quicklaunch binary '%s' does not exist\n", argv[0]);
583         return EINA_FALSE;
584      }
585    else
586      {
587         char *exe2, *p;
588         char *exename;
589
590         exe2 = malloc(strlen(exe) + 1 + 10);
591         strcpy(exe2, exe);
592         p = strrchr(exe2, '/');
593         if (p) p++;
594         else p = exe2;
595         exename = alloca(strlen(p) + 1);
596         strcpy(exename, p);
597         *p = 0;
598         strcat(p, "../lib/");
599         strcat(p, exename);
600         strcat(p, ".so");
601         if (!access(exe2, R_OK | X_OK))
602           {
603              free(exe);
604              exe = exe2;
605           }
606         else
607           free(exe2);
608      }
609    qr_handle = dlopen(exe, RTLD_NOW | RTLD_GLOBAL);
610    if (!qr_handle)
611      {
612         fprintf(stderr, "dlerr: %s\n", dlerror());
613         WRN("dlopen('%s') failed: %s", exe, dlerror());
614         free(exe);
615         return EINA_FALSE;
616      }
617    INF("dlopen('%s') = %p", exe, qr_handle);
618    qr_main = dlsym(qr_handle, "elm_main");
619    INF("dlsym(%p, 'elm_main') = %p", qr_handle, qr_main);
620    if (!qr_main)
621      {
622         WRN("not quicklauncher capable: no elm_main in '%s'", exe);
623         dlclose(qr_handle);
624         qr_handle = NULL;
625         free(exe);
626         return EINA_FALSE;
627      }
628    free(exe);
629    return EINA_TRUE;
630 #else
631    return EINA_FALSE;
632    (void)argv;
633 #endif
634 }
635
636 #ifdef HAVE_FORK
637 static void
638 save_env(void)
639 {
640    int i, size;
641    extern char **environ;
642    char **oldenv, **p;
643
644    oldenv = environ;
645
646    for (i = 0, size = 0; environ[i]; i++)
647      size += strlen(environ[i]) + 1;
648
649    p = malloc((i + 1) * sizeof(char *));
650    if (!p) return;
651
652    environ = p;
653
654    for (i = 0; oldenv[i]; i++)
655      environ[i] = strdup(oldenv[i]);
656    environ[i] = NULL;
657 }
658
659 #endif
660
661 EAPI Eina_Bool
662 elm_quicklaunch_fork(int    argc,
663                      char **argv,
664                      char  *cwd,
665                      void (postfork_func) (void *data),
666                      void  *postfork_data)
667 {
668 #ifdef HAVE_FORK
669    pid_t child;
670    int ret;
671    int real_argc;
672    char **real_argv;
673
674    // FIXME:
675    // need to accept current environment from elementary_run
676    if (!qr_main)
677      {
678         int i;
679         char **args;
680
681         child = fork();
682         if (child > 0) return EINA_TRUE;
683         else if (child < 0)
684           {
685              perror("could not fork");
686              return EINA_FALSE;
687           }
688         setsid();
689         if (chdir(cwd) != 0)
690           perror("could not chdir");
691         args = alloca((argc + 1) * sizeof(char *));
692         for (i = 0; i < argc; i++) args[i] = argv[i];
693         args[argc] = NULL;
694         WRN("%s not quicklaunch capable, fallback...", argv[0]);
695         execvp(argv[0], args);
696         ERR("failed to execute '%s': %s", argv[0], strerror(errno));
697         exit(-1);
698      }
699    child = fork();
700    if (child > 0) return EINA_TRUE;
701    else if (child < 0)
702      {
703         perror("could not fork");
704         return EINA_FALSE;
705      }
706    if (postfork_func) postfork_func(postfork_data);
707
708    if (quicklaunch_on)
709      {
710 #ifdef SEMI_BROKEN_QUICKLAUNCH
711         ecore_app_args_set(argc, (const char **)argv);
712         evas_init();
713         edje_init();
714         _elm_config_sub_init();
715 #define ENGINE_COMPARE(name) (!strcmp(_elm_config->engine, name))
716         if (ENGINE_COMPARE(ELM_SOFTWARE_X11) ||
717             ENGINE_COMPARE(ELM_SOFTWARE_16_X11) ||
718             ENGINE_COMPARE(ELM_XRENDER_X11) ||
719             ENGINE_COMPARE(ELM_OPENGL_X11))
720 #undef ENGINE_COMPARE
721           {
722 # ifdef HAVE_ELEMENTARY_X
723              ecore_x_init(NULL);
724 # endif
725           }
726         ecore_evas_init(); // FIXME: check errors
727         ecore_imf_init();
728         _elm_module_init();
729 #endif
730      }
731
732    setsid();
733    if (chdir(cwd) != 0)
734      perror("could not chdir");
735    // FIXME: this is very linux specific. it changes argv[0] of the process
736    // so ps etc. report what you'd expect. for other unixes and os's this
737    // may just not work
738    save_env();
739    if (argv)
740      {
741         char *lastarg, *p;
742
743         ecore_app_args_get(&real_argc, &real_argv);
744         lastarg = real_argv[real_argc - 1] + strlen(real_argv[real_argc - 1]);
745         for (p = real_argv[0]; p < lastarg; p++) *p = 0;
746         strcpy(real_argv[0], argv[0]);
747      }
748    ecore_app_args_set(argc, (const char **)argv);
749    ret = qr_main(argc, argv);
750    exit(ret);
751    return EINA_TRUE;
752 #else
753    return EINA_FALSE;
754    (void)argc;
755    (void)argv;
756    (void)cwd;
757    (void)postfork_func;
758    (void)postfork_data;
759 #endif
760 }
761
762 EAPI void
763 elm_quicklaunch_cleanup(void)
764 {
765 #ifdef HAVE_FORK
766    if (qr_handle)
767      {
768         dlclose(qr_handle);
769         qr_handle = NULL;
770         qr_main = NULL;
771      }
772 #endif
773 }
774
775 EAPI int
776 elm_quicklaunch_fallback(int    argc,
777                          char **argv)
778 {
779    int ret;
780    elm_quicklaunch_init(argc, argv);
781    elm_quicklaunch_sub_init(argc, argv);
782    elm_quicklaunch_prepare(argc, argv);
783    ret = qr_main(argc, argv);
784    exit(ret);
785    return ret;
786 }
787
788 EAPI char *
789 elm_quicklaunch_exe_path_get(const char *exe)
790 {
791    static char *path = NULL;
792    static Eina_List *pathlist = NULL;
793    const char *pathitr;
794    const Eina_List *l;
795    char buf[PATH_MAX];
796    if (exe[0] == '/') return strdup(exe);
797    if ((exe[0] == '.') && (exe[1] == '/')) return strdup(exe);
798    if ((exe[0] == '.') && (exe[1] == '.') && (exe[2] == '/')) return strdup(exe);
799    if (!path)
800      {
801         const char *p, *pp;
802         char *buf2;
803         path = getenv("PATH");
804         buf2 = alloca(strlen(path) + 1);
805         p = path;
806         pp = p;
807         for (;; )
808           {
809              if ((*p == ':') || (!*p))
810                {
811                   int len;
812
813                   len = p - pp;
814                   strncpy(buf2, pp, len);
815                   buf2[len] = 0;
816                   pathlist = eina_list_append(pathlist, eina_stringshare_add(buf2));
817                   if (!*p) break;
818                   p++;
819                   pp = p;
820                }
821              else
822                {
823                   if (!*p) break;
824                   p++;
825                }
826           }
827      }
828    EINA_LIST_FOREACH(pathlist, l, pathitr)
829      {
830         snprintf(buf, sizeof(buf), "%s/%s", pathitr, exe);
831         if (!access(buf, R_OK | X_OK)) return strdup(buf);
832      }
833    return NULL;
834 }
835
836 EAPI void
837 elm_run(void)
838 {
839    ecore_main_loop_begin();
840 }
841
842 EAPI void
843 elm_exit(void)
844 {
845    ecore_main_loop_quit();
846 }
847
848 EAPI Eina_Bool
849 elm_policy_set(unsigned int policy,
850                int          value)
851 {
852    Elm_Event_Policy_Changed *ev;
853
854    if (policy >= ELM_POLICY_LAST)
855      return EINA_FALSE;
856
857    if (value == _elm_policies[policy])
858      return EINA_TRUE;
859
860    /* TODO: validade policy? */
861
862    ev = malloc(sizeof(*ev));
863    ev->policy = policy;
864    ev->new_value = value;
865    ev->old_value = _elm_policies[policy];
866
867    _elm_policies[policy] = value;
868
869    ecore_event_add(ELM_EVENT_POLICY_CHANGED, ev, NULL, NULL);
870
871    return EINA_TRUE;
872 }
873
874 EAPI int
875 elm_policy_get(unsigned int policy)
876 {
877    if (policy >= ELM_POLICY_LAST)
878      return 0;
879    return _elm_policies[policy];
880 }
881
882 /**
883  * @defgroup UI-Mirroring Selective Widget mirroring
884  *
885  * These functions allow you to set ui-mirroring on specific widgets or the
886  * whole interface. Widgets can be in one of two modes, automatic and manual.
887  * Automatic means they'll be changed according to the system mirroring mode
888  * and manual means only explicit changes will matter. You are not supposed to
889  * change mirroring state of a widget set to automatic, will mostly work, but
890  * the behavior is not really defined.
891  */
892
893 /**
894  * Returns the widget's mirrored mode.
895  *
896  * @param obj The widget.
897  * @return mirrored mode of the object.
898  *
899  **/
900 EAPI Eina_Bool
901 elm_object_mirrored_get(const Evas_Object *obj)
902 {
903    EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE);
904    return elm_widget_mirrored_get(obj);
905 }
906
907 /**
908  * Sets the widget's mirrored mode.
909  *
910  * @param obj The widget.
911  * @param mirrored EINA_TRUE to set mirrored mode. EINA_FALSE to unset.
912  */
913 EAPI void
914 elm_object_mirrored_set(Evas_Object *obj, Eina_Bool mirrored)
915 {
916    EINA_SAFETY_ON_NULL_RETURN(obj);
917    elm_widget_mirrored_set(obj, mirrored);
918 }
919
920 /**
921  * Returns the widget's mirrored mode setting.
922  *
923  * @param obj The widget.
924  * @return mirrored mode setting of the object.
925  *
926  **/
927 EAPI Eina_Bool
928 elm_object_mirrored_automatic_get(const Evas_Object *obj)
929 {
930    EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE);
931    return elm_widget_mirrored_automatic_get(obj);
932 }
933
934 /**
935  * Sets the widget's mirrored mode setting.
936  * When widget in automatic mode, it follows the system mirrored mode set by
937  * elm_mirrored_set().
938  * @param obj The widget.
939  * @param automatic EINA_TRUE for auto mirrored mode. EINA_FALSE for manual.
940  */
941 EAPI void
942 elm_object_mirrored_automatic_set(Evas_Object *obj, Eina_Bool automatic)
943 {
944    EINA_SAFETY_ON_NULL_RETURN(obj);
945    elm_widget_mirrored_automatic_set(obj, automatic);
946 }
947
948 EAPI void
949 elm_object_scale_set(Evas_Object *obj,
950                      double       scale)
951 {
952    EINA_SAFETY_ON_NULL_RETURN(obj);
953    elm_widget_scale_set(obj, scale);
954 }
955
956 EAPI double
957 elm_object_scale_get(const Evas_Object *obj)
958 {
959    EINA_SAFETY_ON_NULL_RETURN_VAL(obj, 0.0);
960    return elm_widget_scale_get(obj);
961 }
962
963 EAPI void
964 elm_object_text_part_set(Evas_Object *obj, const char *part, const char *label)
965 {
966    EINA_SAFETY_ON_NULL_RETURN(obj);
967    elm_widget_text_part_set(obj, part, label);
968 }
969
970 EAPI const char *
971 elm_object_text_part_get(const Evas_Object *obj, const char *part)
972 {
973    EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
974    return elm_widget_text_part_get(obj, part);
975 }
976
977 EAPI void
978 elm_object_content_part_set(Evas_Object *obj, const char *part, Evas_Object *content)
979 {
980    EINA_SAFETY_ON_NULL_RETURN(obj);
981    elm_widget_content_part_set(obj, part, content);
982 }
983
984 EAPI Evas_Object *
985 elm_object_content_part_get(const Evas_Object *obj, const char *part)
986 {
987    EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
988    return elm_widget_content_part_get(obj, part);
989 }
990
991 EAPI Evas_Object *
992 elm_object_content_part_unset(Evas_Object *obj, const char *part)
993 {
994    EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
995    return elm_widget_content_part_unset(obj, part);
996 }
997
998 /**
999  * Get the global scaling factor
1000  *
1001  * This gets the globally configured scaling factor that is applied to all
1002  * objects.
1003  *
1004  * @return The scaling factor
1005  * @ingroup Scaling
1006  */
1007 EAPI double
1008 elm_scale_get(void)
1009 {
1010    return _elm_config->scale;
1011 }
1012
1013 /**
1014  * Set the global scaling factor
1015  *
1016  * This sets the globally configured scaling factor that is applied to all
1017  * objects.
1018  *
1019  * @param scale The scaling factor to set
1020  * @ingroup Scaling
1021  */
1022 EAPI void
1023 elm_scale_set(double scale)
1024 {
1025    if (_elm_config->scale == scale) return;
1026    _elm_config->scale = scale;
1027    _elm_rescale();
1028 }
1029
1030 /**
1031  * Set the global scaling factor for all applications on the display
1032  *
1033  * This sets the globally configured scaling factor that is applied to all
1034  * objects for all applications.
1035  * @param scale The scaling factor to set
1036  * @ingroup Scaling
1037  */
1038 EAPI void
1039 elm_scale_all_set(double scale)
1040 {
1041 #ifdef HAVE_ELEMENTARY_X
1042    static Ecore_X_Atom atom = 0;
1043    unsigned int scale_i = (unsigned int)(scale * 1000.0);
1044
1045    if (!atom) atom = ecore_x_atom_get("ENLIGHTENMENT_SCALE");
1046    ecore_x_window_prop_card32_set(ecore_x_window_root_first_get(),
1047                                   atom, &scale_i, 1);
1048 #endif
1049 }
1050
1051 EAPI void
1052 elm_object_style_set(Evas_Object *obj,
1053                      const char  *style)
1054 {
1055    EINA_SAFETY_ON_NULL_RETURN(obj);
1056    elm_widget_style_set(obj, style);
1057 }
1058
1059 EAPI const char *
1060 elm_object_style_get(const Evas_Object *obj)
1061 {
1062    EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
1063    return elm_widget_style_get(obj);
1064 }
1065
1066 EAPI void
1067 elm_object_disabled_set(Evas_Object *obj,
1068                         Eina_Bool    disabled)
1069 {
1070    EINA_SAFETY_ON_NULL_RETURN(obj);
1071    elm_widget_disabled_set(obj, disabled);
1072 }
1073
1074 EAPI Eina_Bool
1075 elm_object_disabled_get(const Evas_Object *obj)
1076 {
1077    EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE);
1078    return elm_widget_disabled_get(obj);
1079 }
1080
1081 /**
1082  * @defgroup Config Elementary Config
1083  *
1084  * Elementary configuration is formed by a set options bounded to a
1085  * given @ref Profile profile, like @ref Theme theme, @ref Fingers
1086  * "finger size", etc. These are functions with which one syncronizes
1087  * changes made to those values to the configuration storing files, de
1088  * facto. You most probably don't want to use the functions in this
1089  * group unlees you're writing an elementary configuration manager.
1090  */
1091
1092 /**
1093  * Save back Elementary's configuration, so that it will persist on
1094  * future sessions.
1095  *
1096  * @return @c EINA_TRUE, when sucessful. @c EINA_FALSE, otherwise.
1097  * @ingroup Config
1098  *
1099  * This function will take effect -- thus, do I/O -- immediately. Use
1100  * it when you want to apply all configuration changes at once. The
1101  * current configuration set will get saved onto the current profile
1102  * configuration file.
1103  *
1104  */
1105 EAPI Eina_Bool
1106 elm_config_save(void)
1107 {
1108    return _elm_config_save();
1109 }
1110
1111 /**
1112  * Reload Elementary's configuration, bounded to current selected
1113  * profile.
1114  *
1115  * @return @c EINA_TRUE, when sucessful. @c EINA_FALSE, otherwise.
1116  * @ingroup Config
1117  *
1118  * Useful when you want to force reloading of configuration values for
1119  * a profile. If one removes user custom configuration directories,
1120  * for example, it will force a reload with system values insted.
1121  *
1122  */
1123 EAPI void
1124 elm_config_reload(void)
1125 {
1126    _elm_config_reload();
1127 }
1128
1129 /**
1130  * @defgroup Profile Elementary Profile
1131  *
1132  * Profiles are pre-set options that affect the whole look-and-feel of
1133  * Elementary-based applications. There are, for example, profiles
1134  * aimed at desktop computer applications and others aimed at mobile,
1135  * touchscreen-based ones. You most probably don't want to use the
1136  * functions in this group unlees you're writing an elementary
1137  * configuration manager.
1138  */
1139
1140 /**
1141  * Get Elementary's profile in use.
1142  *
1143  * This gets the global profile that is applied to all Elementary
1144  * applications.
1145  *
1146  * @return The profile's name
1147  * @ingroup Profile
1148  */
1149 EAPI const char *
1150 elm_profile_current_get(void)
1151 {
1152    return _elm_config_current_profile_get();
1153 }
1154
1155 /**
1156  * Get an Elementary's profile directory path in the filesystem. One
1157  * may want to fetch a system profile's dir or an user one (fetched
1158  * inside $HOME).
1159  *
1160  * @param profile The profile's name
1161  * @param is_user Whether to lookup for an user profile (@c EINA_TRUE)
1162  *                or a system one (@c EINA_FALSE)
1163  * @return The profile's directory path.
1164  * @ingroup Profile
1165  *
1166  * @note You must free it with elm_profile_dir_free().
1167  */
1168 EAPI const char *
1169 elm_profile_dir_get(const char *profile,
1170                     Eina_Bool   is_user)
1171 {
1172    return _elm_config_profile_dir_get(profile, is_user);
1173 }
1174
1175 /**
1176  * Free an Elementary's profile directory path, as returned by
1177  * elm_profile_dir_get().
1178  *
1179  * @param p_dir The profile's path
1180  * @ingroup Profile
1181  *
1182  */
1183 EAPI void
1184 elm_profile_dir_free(const char *p_dir)
1185 {
1186    free((void *)p_dir);
1187 }
1188
1189 /**
1190  * Get Elementary's list of available profiles.
1191  *
1192  * @return The profiles list. List node data are the profile name
1193  *         strings.
1194  * @ingroup Profile
1195  *
1196  * @note One must free this list, after usage, with the function
1197  *       elm_profile_list_free().
1198  */
1199 EAPI Eina_List *
1200 elm_profile_list_get(void)
1201 {
1202    return _elm_config_profiles_list();
1203 }
1204
1205 /**
1206  * Free Elementary's list of available profiles.
1207  *
1208  * @param The profiles list, as returned by elm_profile_list_get().
1209  * @ingroup Profile
1210  *
1211  */
1212 EAPI void
1213 elm_profile_list_free(Eina_List *l)
1214 {
1215    const char *dir;
1216
1217    EINA_LIST_FREE(l, dir)
1218      eina_stringshare_del(dir);
1219 }
1220
1221 /**
1222  * Set Elementary's profile.
1223  *
1224  * This sets the global profile that is applied to Elementary
1225  * applications. Just the process the call comes from will be
1226  * affected.
1227  *
1228  * @param profile The profile's name
1229  * @ingroup Profile
1230  *
1231  */
1232 EAPI void
1233 elm_profile_set(const char *profile)
1234 {
1235    EINA_SAFETY_ON_NULL_RETURN(profile);
1236    _elm_config_profile_set(profile);
1237 }
1238
1239 /**
1240  * Set Elementary's profile.
1241  *
1242  * This sets the global profile that is applied to all Elementary
1243  * applications. All running Elementary windows will be affected.
1244  *
1245  * @param profile The profile's name
1246  * @ingroup Profile
1247  *
1248  */
1249 EAPI void
1250 elm_profile_all_set(const char *profile)
1251 {
1252 #ifdef HAVE_ELEMENTARY_X
1253    static Ecore_X_Atom atom = 0;
1254
1255    if (!atom) atom = ecore_x_atom_get("ENLIGHTENMENT_PROFILE");
1256    ecore_x_window_prop_string_set(ecore_x_window_root_first_get(),
1257                                   atom, profile);
1258 #endif
1259 }
1260
1261 /**
1262  * @defgroup Engine Elementary Engine
1263  *
1264  * These are functions setting and querying which rendering engine
1265  * Elementary will use for drawing its windows' pixels.
1266  */
1267
1268 /**
1269  * Get Elementary's rendering engine in use.
1270  *
1271  * This gets the global rendering engine that is applied to all
1272  * Elementary applications.
1273  *
1274  * @return The rendering engine's name
1275  * @ingroup Engine
1276  *
1277  * @note there's no need to free the returned string, here.
1278  */
1279 EAPI const char *
1280 elm_engine_current_get(void)
1281 {
1282    return _elm_config->engine;
1283 }
1284
1285 /**
1286  * Set Elementary's rendering engine for use.
1287  *
1288  * This gets sets global rendering engine that is applied to all
1289  * Elementary applications. Note that it will take effect only to
1290  * subsequent Elementary window creations.
1291  *
1292  * @param The rendering engine's name
1293  * @ingroup Engine
1294  *
1295  * @note there's no need to free the returned string, here.
1296  */
1297 EAPI void
1298 elm_engine_set(const char *engine)
1299 {
1300    EINA_SAFETY_ON_NULL_RETURN(engine);
1301
1302    _elm_config_engine_set(engine);
1303 }
1304
1305 /**
1306  * @defgroup Fonts Elementary Fonts
1307  *
1308  * These are functions dealing with font rendering, selection and the
1309  * like for Elementary applications. One might fetch which system
1310  * fonts are there to use and set custom fonts for individual classes
1311  * of UI items containing text (text classes).
1312  */
1313
1314 /**
1315  * Get Elementary's list of supported text classes.
1316  *
1317  * @return The text classes list, with @c Elm_Text_Class blobs as data.
1318  * @ingroup Fonts
1319  *
1320  * Release the list with elm_text_classes_list_free().
1321  */
1322 EAPI const Eina_List *
1323 elm_text_classes_list_get(void)
1324 {
1325    return _elm_config_text_classes_get();
1326 }
1327
1328 /**
1329  * Free Elementary's list of supported text classes.
1330  *
1331  * @ingroup Fonts
1332  *
1333  * @see elm_text_classes_list_get().
1334  */
1335 EAPI void
1336 elm_text_classes_list_free(const Eina_List *list)
1337 {
1338    _elm_config_text_classes_free((Eina_List *)list);
1339 }
1340
1341 /**
1342  * Get Elementary's list of font overlays, set with
1343  * elm_font_overlay_set().
1344  *
1345  * @return The font overlays list, with @c Elm_Font_Overlay blobs as
1346  * data.
1347  *
1348  * @ingroup Fonts
1349  *
1350  * For each text class, one can set a <b>font overlay</b> for it,
1351  * overriding the default font properties for that class coming from
1352  * the theme in use. There is no need to free this list.
1353  *
1354  * @see elm_font_overlay_set() and elm_font_overlay_unset().
1355  */
1356 EAPI const Eina_List *
1357 elm_font_overlay_list_get(void)
1358 {
1359    return _elm_config_font_overlays_list();
1360 }
1361
1362 /**
1363  * Set a font overlay for a given Elementary text class.
1364  *
1365  * @param text_class Text class name
1366  * @param font Font name and style string
1367  * @param size Font size
1368  *
1369  * @ingroup Fonts
1370  *
1371  * @p font has to be in the format returned by
1372  * elm_font_fontconfig_name_get(). @see elm_font_overlay_list_get()
1373  * and elm_font_overlay_unset().
1374  */
1375 EAPI void
1376 elm_font_overlay_set(const char    *text_class,
1377                      const char    *font,
1378                      Evas_Font_Size size)
1379 {
1380    _elm_config_font_overlay_set(text_class, font, size);
1381 }
1382
1383 /**
1384  * Unset a font overlay for a given Elementary text class.
1385  *
1386  * @param text_class Text class name
1387  *
1388  * @ingroup Fonts
1389  *
1390  * This will bring back text elements belonging to text class @p
1391  * text_class back to their default font settings.
1392  */
1393 EAPI void
1394 elm_font_overlay_unset(const char *text_class)
1395 {
1396    _elm_config_font_overlay_remove(text_class);
1397 }
1398
1399 /**
1400  * Apply the changes made with elm_font_overlay_set() and
1401  * elm_font_overlay_unset() on the current Elementary window.
1402  *
1403  * @ingroup Fonts
1404  *
1405  * This applies all font overlays set to all objects in the UI.
1406  */
1407 EAPI void
1408 elm_font_overlay_apply(void)
1409 {
1410    _elm_config_font_overlay_apply();
1411 }
1412
1413 /**
1414  * Apply the changes made with elm_font_overlay_set() and
1415  * elm_font_overlay_unset() on all Elementary application windows.
1416  *
1417  * @ingroup Fonts
1418  *
1419  * This applies all font overlays set to all objects in the UI.
1420  */
1421 EAPI void
1422 elm_font_overlay_all_apply(void)
1423 {
1424 #ifdef HAVE_ELEMENTARY_X
1425    static Ecore_X_Atom atom = 0;
1426    unsigned int dummy = (unsigned int)(1 * 1000.0);
1427
1428    if (!atom) atom = ecore_x_atom_get("ENLIGHTENMENT_FONT_OVERLAY");
1429    ecore_x_window_prop_card32_set(ecore_x_window_root_first_get(), atom, &dummy,
1430                                   1);
1431 #endif
1432 }
1433
1434 /**
1435  * Translate a font (family) name string in fontconfig's font names
1436  * syntax into an @c Elm_Font_Properties struct.
1437  *
1438  * @param font The font name and styles string
1439  * @return the font properties struct
1440  *
1441  * @ingroup Fonts
1442  *
1443  * @note The reverse translation can be achived with
1444  * elm_font_fontconfig_name_get(), for one style only (single font
1445  * instance, not family).
1446  */
1447 EAPI Elm_Font_Properties *
1448 elm_font_properties_get(const char *font)
1449 {
1450    EINA_SAFETY_ON_NULL_RETURN_VAL(font, NULL);
1451    return _elm_font_properties_get(NULL, font);
1452 }
1453
1454 /**
1455  * Free font properties return by elm_font_properties_get().
1456  *
1457  * @param efp the font properties struct
1458  *
1459  * @ingroup Fonts
1460  */
1461 EAPI void
1462 elm_font_properties_free(Elm_Font_Properties *efp)
1463 {
1464    const char *str;
1465
1466    EINA_SAFETY_ON_NULL_RETURN(efp);
1467    EINA_LIST_FREE(efp->styles, str)
1468      if (str) eina_stringshare_del(str);
1469    if (efp->name) eina_stringshare_del(efp->name);
1470    free(efp);
1471 }
1472
1473 /**
1474  * Translate a font name, bound to a style, into fontconfig's font names
1475  * syntax.
1476  *
1477  * @param name The font (family) name
1478  * @param style The given style (may be @c NULL)
1479  *
1480  * @return the font name and style string
1481  *
1482  * @ingroup Fonts
1483  *
1484  * @note The reverse translation can be achived with
1485  * elm_font_properties_get(), for one style only (single font
1486  * instance, not family).
1487  */
1488 EAPI const char *
1489 elm_font_fontconfig_name_get(const char *name,
1490                              const char *style)
1491 {
1492    char buf[256];
1493
1494    EINA_SAFETY_ON_NULL_RETURN_VAL(name, NULL);
1495    if (!style || style[0] == 0) return eina_stringshare_add(name);
1496    snprintf(buf, 256, "%s" ELM_FONT_TOKEN_STYLE "%s", name, style);
1497    return eina_stringshare_add(buf);
1498 }
1499
1500 /**
1501  * Free the font string return by elm_font_fontconfig_name_get().
1502  *
1503  * @param efp the font properties struct
1504  *
1505  * @ingroup Fonts
1506  */
1507 EAPI void
1508 elm_font_fontconfig_name_free(const char *name)
1509 {
1510    eina_stringshare_del(name);
1511 }
1512
1513 /**
1514  * Create a font hash table of available system fonts.
1515  *
1516  * One must call it with @p list being the return value of
1517  * evas_font_available_list(). The hash will be indexed by font
1518  * (family) names, being its values @c Elm_Font_Properties blobs.
1519  *
1520  * @param list The list of available system fonts, as returned by
1521  * evas_font_available_list().
1522  * @return the font hash.
1523  *
1524  * @ingroup Fonts
1525  *
1526  * @note The user is supposed to get it populated at least with 3
1527  * default font families (Sans, Serif, Monospace), which should be
1528  * present on most systems.
1529  */
1530 EAPI Eina_Hash *
1531 elm_font_available_hash_add(Eina_List *list)
1532 {
1533    Eina_Hash *font_hash;
1534    Eina_List *l;
1535    void *key;
1536
1537    font_hash = NULL;
1538
1539    /* populate with default font families */
1540    font_hash = _elm_font_available_hash_add(font_hash, "Sans:style=Regular");
1541    font_hash = _elm_font_available_hash_add(font_hash, "Sans:style=Bold");
1542    font_hash = _elm_font_available_hash_add(font_hash, "Sans:style=Oblique");
1543    font_hash = _elm_font_available_hash_add(font_hash,
1544                                             "Sans:style=Bold Oblique");
1545
1546    font_hash = _elm_font_available_hash_add(font_hash, "Serif:style=Regular");
1547    font_hash = _elm_font_available_hash_add(font_hash, "Serif:style=Bold");
1548    font_hash = _elm_font_available_hash_add(font_hash, "Serif:style=Oblique");
1549    font_hash = _elm_font_available_hash_add(font_hash,
1550                                             "Serif:style=Bold Oblique");
1551
1552    font_hash = _elm_font_available_hash_add(font_hash,
1553                                             "Monospace:style=Regular");
1554    font_hash = _elm_font_available_hash_add(font_hash,
1555                                             "Monospace:style=Bold");
1556    font_hash = _elm_font_available_hash_add(font_hash,
1557                                             "Monospace:style=Oblique");
1558    font_hash = _elm_font_available_hash_add(font_hash,
1559                                             "Monospace:style=Bold Oblique");
1560
1561    EINA_LIST_FOREACH(list, l, key)
1562      font_hash = _elm_font_available_hash_add(font_hash, key);
1563
1564    return font_hash;
1565 }
1566
1567 /**
1568  * Free the hash return by elm_font_available_hash_add().
1569  *
1570  * @param hash the hash to be freed.
1571  *
1572  * @ingroup Fonts
1573  */
1574 EAPI void
1575 elm_font_available_hash_del(Eina_Hash *hash)
1576 {
1577    _elm_font_available_hash_del(hash);
1578 }
1579
1580 EAPI Evas_Coord
1581 elm_finger_size_get(void)
1582 {
1583    return _elm_config->finger_size;
1584 }
1585
1586 /**
1587  * Set the configured finger size
1588  *
1589  * This sets the globally configured finger size in pixels
1590  *
1591  * @param size The finger size
1592  * @ingroup Fingers
1593  */
1594 EAPI void
1595 elm_finger_size_set(Evas_Coord size)
1596 {
1597    if (_elm_config->finger_size == size) return;
1598    _elm_config->finger_size = size;
1599    _elm_rescale();
1600 }
1601
1602 /**
1603  * Set the configured finger size for all applications on the display
1604  *
1605  * This sets the globally configured finger size in pixels for all applications
1606  * on the display
1607  *
1608  * @param size The finger size
1609  * @ingroup Fingers
1610  */
1611 EAPI void
1612 elm_finger_size_all_set(Evas_Coord size)
1613 {
1614 #ifdef HAVE_ELEMENTARY_X
1615    static Ecore_X_Atom atom = 0;
1616    unsigned int size_i = (unsigned int)size;
1617
1618    if (!atom) atom = ecore_x_atom_get("ENLIGHTENMENT_FINGER_SIZE");
1619    ecore_x_window_prop_card32_set(ecore_x_window_root_first_get(),
1620                                   atom, &size_i, 1);
1621 #endif
1622 }
1623
1624 EAPI void
1625 elm_coords_finger_size_adjust(int         times_w,
1626                               Evas_Coord *w,
1627                               int         times_h,
1628                               Evas_Coord *h)
1629 {
1630    if ((w) && (*w < (_elm_config->finger_size * times_w)))
1631      *w = _elm_config->finger_size * times_w;
1632    if ((h) && (*h < (_elm_config->finger_size * times_h)))
1633      *h = _elm_config->finger_size * times_h;
1634 }
1635
1636 /**
1637  * @defgroup Caches Caches
1638  *
1639  * These are functions which let one fine-tune some cache values for
1640  * Elementary applications, thus allowing for performance adjustments.
1641  */
1642
1643 /**
1644  * Flush all caches & dump all data that can be to lean down to use
1645  * less memory
1646  *
1647  * @ingroup Caches
1648  */
1649 EAPI void
1650 elm_all_flush(void)
1651 {
1652    const Eina_List *l;
1653    Evas_Object *obj;
1654
1655    edje_file_cache_flush();
1656    edje_collection_cache_flush();
1657    eet_clearcache();
1658    EINA_LIST_FOREACH(_elm_win_list, l, obj)
1659      {
1660         Evas *e = evas_object_evas_get(obj);
1661         evas_image_cache_flush(e);
1662         evas_font_cache_flush(e);
1663         evas_render_dump(e);
1664      }
1665 }
1666
1667 /**
1668  * Get the configured cache flush interval time
1669  *
1670  * This gets the globally configured cache flush interval time, in
1671  * ticks
1672  *
1673  * @return The cache flush interval time
1674  * @ingroup Caches
1675  *
1676  * @see elm_all_flush()
1677  */
1678 EAPI int
1679 elm_cache_flush_interval_get(void)
1680 {
1681    return _elm_config->cache_flush_poll_interval;
1682 }
1683
1684 /**
1685  * Set the configured cache flush interval time
1686  *
1687  * This sets the globally configured cache flush interval time, in ticks
1688  *
1689  * @param size The cache flush interval time
1690  * @ingroup Caches
1691  *
1692  * @see elm_all_flush()
1693  */
1694 EAPI void
1695 elm_cache_flush_interval_set(int size)
1696 {
1697    if (_elm_config->cache_flush_poll_interval == size) return;
1698    _elm_config->cache_flush_poll_interval = size;
1699
1700    _elm_recache();
1701 }
1702
1703 /**
1704  * Set the configured cache flush interval time for all applications on the
1705  * display
1706  *
1707  * This sets the globally configured cache flush interval time -- in ticks
1708  * -- for all applications on the display.
1709  *
1710  * @param size The cache flush interval time
1711  * @ingroup Caches
1712  */
1713 EAPI void
1714 elm_cache_flush_interval_all_set(int size)
1715 {
1716 #ifdef HAVE_ELEMENTARY_X
1717    static Ecore_X_Atom atom = 0;
1718    unsigned int size_i = (unsigned int)size;
1719
1720    if (!atom) atom = ecore_x_atom_get("ENLIGHTENMENT_CACHE_FLUSH_INTERVAL");
1721    ecore_x_window_prop_card32_set(ecore_x_window_root_first_get(),
1722                                   atom, &size_i, 1);
1723 #endif
1724 }
1725
1726 /**
1727  * Get the configured cache flush enabled state
1728  *
1729  * This gets the globally configured cache flush state - if it is enabled
1730  * or not. When cache flushing is enabled, elementary will regularly
1731  * (see elm_cache_flush_interval_get() ) flush caches and dump data out of
1732  * memory and allow usage to re-seed caches and data in memory where it
1733  * can do so. An idle application will thus minimise its memory usage as
1734  * data will be freed from memory and not be re-loaded as it is idle and
1735  * not rendering or doing anything graphically right now.
1736  *
1737  * @return The cache flush state
1738  * @ingroup Caches
1739  *
1740  * @see elm_all_flush()
1741  */
1742 EAPI Eina_Bool
1743 elm_cache_flush_enabled_get(void)
1744 {
1745    return _elm_config->cache_flush_enable;
1746 }
1747
1748 /**
1749  * Set the configured cache flush enabled state
1750  *
1751  * This sets the globally configured cache flush enabled state
1752  *
1753  * @param size The cache flush enabled state
1754  * @ingroup Caches
1755  *
1756  * @see elm_all_flush()
1757  */
1758 EAPI void
1759 elm_cache_flush_enabled_set(Eina_Bool enabled)
1760 {
1761    enabled = !!enabled;
1762    if (_elm_config->cache_flush_enable == enabled) return;
1763    _elm_config->cache_flush_enable = enabled;
1764
1765    _elm_recache();
1766 }
1767
1768 /**
1769  * Set the configured cache flush enabled state for all applications on the
1770  * display
1771  *
1772  * This sets the globally configured cache flush enabled state for all
1773  * applications on the display.
1774  *
1775  * @param size The cache flush enabled state
1776  * @ingroup Caches
1777  */
1778 EAPI void
1779 elm_cache_flush_enabled_all_set(Eina_Bool enabled)
1780 {
1781 #ifdef HAVE_ELEMENTARY_X
1782    static Ecore_X_Atom atom = 0;
1783    unsigned int enabled_i = (unsigned int)enabled;
1784
1785    if (!atom) atom = ecore_x_atom_get("ENLIGHTENMENT_CACHE_FLUSH_ENABLE");
1786    ecore_x_window_prop_card32_set(ecore_x_window_root_first_get(),
1787                                   atom, &enabled_i, 1);
1788 #endif
1789 }
1790
1791 /**
1792  * Get the configured font cache size
1793  *
1794  * This gets the globally configured font cache size, in bytes
1795  *
1796  * @return The font cache size
1797  * @ingroup Caches
1798  */
1799 EAPI int
1800 elm_font_cache_get(void)
1801 {
1802    return _elm_config->font_cache;
1803 }
1804
1805 /**
1806  * Set the configured font cache size
1807  *
1808  * This sets the globally configured font cache size, in bytes
1809  *
1810  * @param size The font cache size
1811  * @ingroup Caches
1812  */
1813 EAPI void
1814 elm_font_cache_set(int size)
1815 {
1816    if (_elm_config->font_cache == size) return;
1817    _elm_config->font_cache = size;
1818
1819    _elm_recache();
1820 }
1821
1822 /**
1823  * Set the configured font cache size for all applications on the
1824  * display
1825  *
1826  * This sets the globally configured font cache size -- in bytes
1827  * -- for all applications on the display.
1828  *
1829  * @param size The font cache size
1830  * @ingroup Caches
1831  */
1832 EAPI void
1833 elm_font_cache_all_set(int size)
1834 {
1835 #ifdef HAVE_ELEMENTARY_X
1836    static Ecore_X_Atom atom = 0;
1837    unsigned int size_i = (unsigned int)size;
1838
1839    if (!atom) atom = ecore_x_atom_get("ENLIGHTENMENT_FONT_CACHE");
1840    ecore_x_window_prop_card32_set(ecore_x_window_root_first_get(),
1841                                   atom, &size_i, 1);
1842 #endif
1843 }
1844
1845 /**
1846  * Get the configured image cache size
1847  *
1848  * This gets the globally configured image cache size, in bytes
1849  *
1850  * @return The image cache size
1851  * @ingroup Caches
1852  */
1853 EAPI int
1854 elm_image_cache_get(void)
1855 {
1856    return _elm_config->image_cache;
1857 }
1858
1859 /**
1860  * Set the configured image cache size
1861  *
1862  * This sets the globally configured image cache size, in bytes
1863  *
1864  * @param size The image cache size
1865  * @ingroup Caches
1866  */
1867 EAPI void
1868 elm_image_cache_set(int size)
1869 {
1870    if (_elm_config->image_cache == size) return;
1871    _elm_config->image_cache = size;
1872
1873    _elm_recache();
1874 }
1875
1876 /**
1877  * Set the configured image cache size for all applications on the
1878  * display
1879  *
1880  * This sets the globally configured image cache size -- in bytes
1881  * -- for all applications on the display.
1882  *
1883  * @param size The image cache size
1884  * @ingroup Caches
1885  */
1886 EAPI void
1887 elm_image_cache_all_set(int size)
1888 {
1889 #ifdef HAVE_ELEMENTARY_X
1890    static Ecore_X_Atom atom = 0;
1891    unsigned int size_i = (unsigned int)size;
1892
1893    if (!atom) atom = ecore_x_atom_get("ENLIGHTENMENT_IMAGE_CACHE");
1894    ecore_x_window_prop_card32_set(ecore_x_window_root_first_get(),
1895                                   atom, &size_i, 1);
1896 #endif
1897 }
1898
1899 /**
1900  * Get the configured edje file cache size.
1901  *
1902  * This gets the globally configured edje file cache size, in number
1903  * of files.
1904  *
1905  * @return The edje file cache size
1906  * @ingroup Caches
1907  */
1908 EAPI int
1909 elm_edje_file_cache_get(void)
1910 {
1911    return _elm_config->edje_cache;
1912 }
1913
1914 /**
1915  * Set the configured edje file cache size
1916  *
1917  * This sets the globally configured edje file cache size, in number
1918  * of files.
1919  *
1920  * @param size The edje file cache size
1921  * @ingroup Caches
1922  */
1923 EAPI void
1924 elm_edje_file_cache_set(int size)
1925 {
1926    if (_elm_config->edje_cache == size) return;
1927    _elm_config->edje_cache = size;
1928
1929    _elm_recache();
1930 }
1931
1932 /**
1933  * Set the configured edje file cache size for all applications on the
1934  * display
1935  *
1936  * This sets the globally configured edje file cache size -- in number
1937  * of files -- for all applications on the display.
1938  *
1939  * @param size The edje file cache size
1940  * @ingroup Caches
1941  */
1942 EAPI void
1943 elm_edje_file_cache_all_set(int size)
1944 {
1945 #ifdef HAVE_ELEMENTARY_X
1946    static Ecore_X_Atom atom = 0;
1947    unsigned int size_i = (unsigned int)size;
1948
1949    if (!atom) atom = ecore_x_atom_get("ENLIGHTENMENT_EDJE_FILE_CACHE");
1950    ecore_x_window_prop_card32_set(ecore_x_window_root_first_get(),
1951                                   atom, &size_i, 1);
1952 #endif
1953 }
1954
1955 /**
1956  * Get the configured edje collections (groups) cache size.
1957  *
1958  * This gets the globally configured edje collections cache size, in
1959  * number of collections.
1960  *
1961  * @return The edje collections cache size
1962  * @ingroup Caches
1963  */
1964 EAPI int
1965 elm_edje_collection_cache_get(void)
1966 {
1967    return _elm_config->edje_collection_cache;
1968 }
1969
1970 /**
1971  * Set the configured edje collections (groups) cache size
1972  *
1973  * This sets the globally configured edje collections cache size, in
1974  * number of collections.
1975  *
1976  * @param size The edje collections cache size
1977  * @ingroup Caches
1978  */
1979 EAPI void
1980 elm_edje_collection_cache_set(int size)
1981 {
1982    if (_elm_config->edje_collection_cache == size) return;
1983    _elm_config->edje_collection_cache = size;
1984
1985    _elm_recache();
1986 }
1987
1988 /**
1989  * Set the configured edje collections (groups) cache size for all
1990  * applications on the display
1991  *
1992  * This sets the globally configured edje collections cache size -- in
1993  * number of collections -- for all applications on the display.
1994  *
1995  * @param size The edje collections cache size
1996  * @ingroup Caches
1997  */
1998 EAPI void
1999 elm_edje_collection_cache_all_set(int size)
2000 {
2001 #ifdef HAVE_ELEMENTARY_X
2002    static Ecore_X_Atom atom = 0;
2003    unsigned int size_i = (unsigned int)size;
2004
2005    if (!atom) atom = ecore_x_atom_get("ENLIGHTENMENT_EDJE_COLLECTION_CACHE");
2006    ecore_x_window_prop_card32_set(ecore_x_window_root_first_get(),
2007                                   atom, &size_i, 1);
2008 #endif
2009 }
2010
2011 EAPI Eina_Bool
2012 elm_object_focus_get(const Evas_Object *obj)
2013 {
2014    EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE);
2015    return elm_widget_focus_get(obj);
2016 }
2017
2018 EAPI void
2019 elm_object_focus_set(Evas_Object *obj,
2020                      Eina_Bool    focus)
2021 {
2022    EINA_SAFETY_ON_NULL_RETURN(obj);
2023    if (focus)
2024      {
2025         if (elm_widget_focus_get(obj)) return;
2026         elm_widget_focus_cycle(obj, ELM_FOCUS_NEXT);
2027      }
2028    else
2029      {
2030         if (!elm_widget_can_focus_get(obj)) return;
2031         elm_widget_focused_object_clear(obj);
2032      }
2033 }
2034
2035 EAPI void
2036 elm_object_focus(Evas_Object *obj)
2037 {
2038    EINA_SAFETY_ON_NULL_RETURN(obj);
2039    elm_object_focus_set(obj, EINA_TRUE);
2040 }
2041
2042 EAPI void
2043 elm_object_unfocus(Evas_Object *obj)
2044 {
2045    EINA_SAFETY_ON_NULL_RETURN(obj);
2046    elm_object_focus_set(obj, EINA_FALSE);
2047 }
2048
2049 EAPI void
2050 elm_object_focus_allow_set(Evas_Object *obj,
2051                            Eina_Bool    enable)
2052 {
2053    EINA_SAFETY_ON_NULL_RETURN(obj);
2054    elm_widget_can_focus_set(obj, enable);
2055 }
2056
2057 EAPI Eina_Bool
2058 elm_object_focus_allow_get(const Evas_Object *obj)
2059 {
2060    EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE);
2061    return (elm_widget_can_focus_get(obj)) || (elm_widget_child_can_focus_get(obj));
2062 }
2063
2064 /**
2065  * Set custom focus chain.
2066  *
2067  * This function i set one new and overwrite any previous custom focus chain
2068  * with the list of objects. The previous list will be deleted and this list
2069  * will be managed. After setted, don't modity it.
2070  *
2071  * @note On focus cycle, only will be evaluated children of this container.
2072  *
2073  * @param obj The container object
2074  * @param objs Chain of objects to pass focus
2075  * @ingroup Focus
2076  */
2077 EAPI void
2078 elm_object_focus_custom_chain_set(Evas_Object *obj,
2079                                   Eina_List   *objs)
2080 {
2081    EINA_SAFETY_ON_NULL_RETURN(obj);
2082    elm_widget_focus_custom_chain_set(obj, objs);
2083 }
2084
2085 /**
2086  * Unset custom focus chain
2087  *
2088  * @param obj The container object
2089  * @ingroup Focus
2090  */
2091 EAPI void
2092 elm_object_focus_custom_chain_unset(Evas_Object *obj)
2093 {
2094    EINA_SAFETY_ON_NULL_RETURN(obj);
2095    elm_widget_focus_custom_chain_unset(obj);
2096 }
2097
2098 /**
2099  * Get custom focus chain
2100  *
2101  * @param obj The container object
2102  * @ingroup Focus
2103  */
2104 EAPI const Eina_List *
2105 elm_object_focus_custom_chain_get(const Evas_Object *obj)
2106 {
2107    EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
2108    return elm_widget_focus_custom_chain_get(obj);
2109 }
2110
2111 /**
2112  * Append object to custom focus chain.
2113  *
2114  * @note If relative_child equal to NULL or not in custom chain, the object
2115  * will be added in end.
2116  *
2117  * @note On focus cycle, only will be evaluated children of this container.
2118  *
2119  * @param obj The container object
2120  * @param child The child to be added in custom chain
2121  * @param relative_child The relative object to position the child
2122  * @ingroup Focus
2123  */
2124 EAPI void
2125 elm_object_focus_custom_chain_append(Evas_Object *obj,
2126                                      Evas_Object *child,
2127                                      Evas_Object *relative_child)
2128 {
2129    EINA_SAFETY_ON_NULL_RETURN(obj);
2130    EINA_SAFETY_ON_NULL_RETURN(child);
2131    elm_widget_focus_custom_chain_append(obj, child, relative_child);
2132 }
2133
2134 /**
2135  * Prepend object to custom focus chain.
2136  *
2137  * @note If relative_child equal to NULL or not in custom chain, the object
2138  * will be added in begin.
2139  *
2140  * @note On focus cycle, only will be evaluated children of this container.
2141  *
2142  * @param obj The container object
2143  * @param child The child to be added in custom chain
2144  * @param relative_child The relative object to position the child
2145  * @ingroup Focus
2146  */
2147 EAPI void
2148 elm_object_focus_custom_chain_prepend(Evas_Object *obj,
2149                                       Evas_Object *child,
2150                                       Evas_Object *relative_child)
2151 {
2152    EINA_SAFETY_ON_NULL_RETURN(obj);
2153    EINA_SAFETY_ON_NULL_RETURN(child);
2154    elm_widget_focus_custom_chain_prepend(obj, child, relative_child);
2155 }
2156
2157 /**
2158  * Give focus to next object in object tree.
2159  *
2160  * Give focus to next object in focus chain of one object sub-tree.
2161  * If the last object of chain already have focus, the focus will go to the
2162  * first object of chain.
2163  *
2164  * @param obj The object root of sub-tree
2165  * @param dir Direction to cycle the focus
2166  *
2167  * @ingroup Focus
2168  */
2169 EAPI void
2170 elm_object_focus_cycle(Evas_Object        *obj,
2171                        Elm_Focus_Direction dir)
2172 {
2173    EINA_SAFETY_ON_NULL_RETURN(obj);
2174    elm_widget_focus_cycle(obj, dir);
2175 }
2176
2177 /**
2178  * Give focus to near object in one direction.
2179  *
2180  * Give focus to near object in direction of one object.
2181  * If none focusable object in given direction, the focus will not change.
2182  *
2183  * @param obj The reference object
2184  * @param x Horizontal component of direction to focus
2185  * @param y Vertical component of direction to focus
2186  *
2187  * @ingroup Focus
2188  */
2189 EAPI void
2190 elm_object_focus_direction_go(Evas_Object *obj,
2191                               int          x,
2192                               int          y)
2193 {
2194    EINA_SAFETY_ON_NULL_RETURN(obj);
2195    elm_widget_focus_direction_go(obj, x, y);
2196 }
2197
2198 EAPI void
2199 elm_object_tree_unfocusable_set(Evas_Object *obj,
2200                                 Eina_Bool    tree_unfocusable)
2201 {
2202    EINA_SAFETY_ON_NULL_RETURN(obj);
2203    elm_widget_tree_unfocusable_set(obj, tree_unfocusable);
2204 }
2205
2206 EAPI Eina_Bool
2207 elm_object_tree_unfocusable_get(const Evas_Object *obj)
2208 {
2209    EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE);
2210    return elm_widget_tree_unfocusable_get(obj);
2211 }
2212
2213 /**
2214  * Get the enable status of the focus highlight
2215  *
2216  * This gets whether the highlight on focused objects is enabled or not
2217  * @ingroup Focus
2218  */
2219 EAPI Eina_Bool
2220 elm_focus_highlight_enabled_get(void)
2221 {
2222    return _elm_config->focus_highlight_enable;
2223 }
2224
2225 /**
2226  * Set the enable status of the focus highlight
2227  *
2228  * Set whether to show or not the highlight on focused objects
2229  * @param enable Enable highlight if EINA_TRUE, disable otherwise
2230  * @ingroup Focus
2231  */
2232 EAPI void
2233 elm_focus_highlight_enabled_set(Eina_Bool enable)
2234 {
2235    _elm_config->focus_highlight_enable = !!enable;
2236 }
2237
2238 /**
2239  * Get the enable status of the highlight animation
2240  *
2241  * Get whether the focus highlight, if enabled, will animate its switch from
2242  * one object to the next
2243  * @ingroup Focus
2244  */
2245 EAPI Eina_Bool
2246 elm_focus_highlight_animate_get(void)
2247 {
2248    return _elm_config->focus_highlight_animate;
2249 }
2250
2251 /**
2252  * Set the enable status of the highlight animation
2253  *
2254  * Set whether the focus highlight, if enabled, will animate its switch from
2255  * one object to the next
2256  * @param animate Enable animation if EINA_TRUE, disable otherwise
2257  * @ingroup Focus
2258  */
2259 EAPI void
2260 elm_focus_highlight_animate_set(Eina_Bool animate)
2261 {
2262    _elm_config->focus_highlight_animate = !!animate;
2263 }
2264
2265 /**
2266  * @defgroup Scrolling Scrolling
2267  *
2268  * These are functions setting how scrollable views in Elementary
2269  * widgets should behave on user interaction.
2270  */
2271
2272 /**
2273  * Get whether scrollers should bounce when they reach their
2274  * viewport's edge during a scroll.
2275  *
2276  * @return the thumb scroll bouncing state
2277  *
2278  * This is the default behavior for touch screens, in general.
2279  * @ingroup Scrolling
2280  */
2281 EAPI Eina_Bool
2282 elm_scroll_bounce_enabled_get(void)
2283 {
2284    return _elm_config->thumbscroll_bounce_enable;
2285 }
2286
2287 /**
2288  * Set whether scrollers should bounce when they reach their
2289  * viewport's edge during a scroll.
2290  *
2291  * @param enabled the thumb scroll bouncing state
2292  *
2293  * @see elm_thumbscroll_bounce_enabled_get()
2294  * @ingroup Scrolling
2295  */
2296 EAPI void
2297 elm_scroll_bounce_enabled_set(Eina_Bool enabled)
2298 {
2299    _elm_config->thumbscroll_bounce_enable = enabled;
2300 }
2301
2302 /**
2303  * Set whether scrollers should bounce when they reach their
2304  * viewport's edge during a scroll, for all Elementary application
2305  * windows.
2306  *
2307  * @param enabled the thumb scroll bouncing state
2308  *
2309  * @see elm_thumbscroll_bounce_enabled_get()
2310  * @ingroup Scrolling
2311  */
2312 EAPI void
2313 elm_scroll_bounce_enabled_all_set(Eina_Bool enabled)
2314 {
2315 #ifdef HAVE_ELEMENTARY_X
2316    static Ecore_X_Atom atom = 0;
2317    unsigned int bounce_enable_i = (unsigned int)enabled;
2318
2319    if (!atom)
2320      atom = ecore_x_atom_get("ENLIGHTENMENT_THUMBSCROLL_BOUNCE_ENABLE");
2321    ecore_x_window_prop_card32_set(ecore_x_window_root_first_get(),
2322                                   atom, &bounce_enable_i, 1);
2323 #endif
2324 }
2325
2326 /**
2327  * Get the amount of inertia a scroller will impose at bounce
2328  * animations.
2329  *
2330  * @return the thumb scroll bounce friction
2331  *
2332  * @ingroup Scrolling
2333  */
2334 EAPI double
2335 elm_scroll_bounce_friction_get(void)
2336 {
2337    return _elm_config->thumbscroll_bounce_friction;
2338 }
2339
2340 /**
2341  * Set the amount of inertia a scroller will impose at bounce
2342  * animations.
2343  *
2344  * @param friction the thumb scroll bounce friction
2345  *
2346  * @see elm_thumbscroll_bounce_friction_get()
2347  * @ingroup Scrolling
2348  */
2349 EAPI void
2350 elm_scroll_bounce_friction_set(double friction)
2351 {
2352    _elm_config->thumbscroll_bounce_friction = friction;
2353 }
2354
2355 /**
2356  * Set the amount of inertia a scroller will impose at bounce
2357  * animations, for all Elementary application windows.
2358  *
2359  * @param friction the thumb scroll bounce friction
2360  *
2361  * @see elm_thumbscroll_bounce_friction_get()
2362  * @ingroup Scrolling
2363  */
2364 EAPI void
2365 elm_scroll_bounce_friction_all_set(double friction)
2366 {
2367 #ifdef HAVE_ELEMENTARY_X
2368    static Ecore_X_Atom atom = 0;
2369    unsigned int bounce_friction_i = (unsigned int)(friction * 1000.0);
2370
2371    if (!atom)
2372      atom = ecore_x_atom_get("ENLIGHTENMENT_THUMBSCROLL_BOUNCE_FRICTION");
2373    ecore_x_window_prop_card32_set(ecore_x_window_root_first_get(),
2374                                   atom, &bounce_friction_i, 1);
2375 #endif
2376 }
2377
2378 /**
2379  * Get the amount of inertia a <b>paged</b> scroller will impose at
2380  * page fitting animations.
2381  *
2382  * @return the page scroll friction
2383  *
2384  * @ingroup Scrolling
2385  */
2386 EAPI double
2387 elm_scroll_page_scroll_friction_get(void)
2388 {
2389    return _elm_config->page_scroll_friction;
2390 }
2391
2392 /**
2393  * Set the amount of inertia a <b>paged</b> scroller will impose at
2394  * page fitting animations.
2395  *
2396  * @param friction the page scroll friction
2397  *
2398  * @see elm_thumbscroll_page_scroll_friction_get()
2399  * @ingroup Scrolling
2400  */
2401 EAPI void
2402 elm_scroll_page_scroll_friction_set(double friction)
2403 {
2404    _elm_config->page_scroll_friction = friction;
2405 }
2406
2407 /**
2408  * Set the amount of inertia a <b>paged</b> scroller will impose at
2409  * page fitting animations, for all Elementary application windows.
2410  *
2411  * @param friction the page scroll friction
2412  *
2413  * @see elm_thumbscroll_page_scroll_friction_get()
2414  * @ingroup Scrolling
2415  */
2416 EAPI void
2417 elm_scroll_page_scroll_friction_all_set(double friction)
2418 {
2419 #ifdef HAVE_ELEMENTARY_X
2420    static Ecore_X_Atom atom = 0;
2421    unsigned int page_scroll_friction_i = (unsigned int)(friction * 1000.0);
2422
2423    if (!atom)
2424      atom = ecore_x_atom_get("ENLIGHTENMENT_THUMBSCROLL_PAGE_SCROLL_FRICTION");
2425    ecore_x_window_prop_card32_set(ecore_x_window_root_first_get(),
2426                                   atom, &page_scroll_friction_i, 1);
2427 #endif
2428 }
2429
2430 /**
2431  * Get the amount of inertia a scroller will impose at region bring
2432  * animations.
2433  *
2434  * @return the bring in scroll friction
2435  *
2436  * @ingroup Scrolling
2437  */
2438 EAPI double
2439 elm_scroll_bring_in_scroll_friction_get(void)
2440 {
2441    return _elm_config->bring_in_scroll_friction;
2442 }
2443
2444 /**
2445  * Set the amount of inertia a scroller will impose at region bring
2446  * animations.
2447  *
2448  * @param friction the bring in scroll friction
2449  *
2450  * @see elm_thumbscroll_bring_in_scroll_friction_get()
2451  * @ingroup Scrolling
2452  */
2453 EAPI void
2454 elm_scroll_bring_in_scroll_friction_set(double friction)
2455 {
2456    _elm_config->bring_in_scroll_friction = friction;
2457 }
2458
2459 /**
2460  * Set the amount of inertia a scroller will impose at region bring
2461  * animations, for all Elementary application windows.
2462  *
2463  * @param friction the bring in scroll friction
2464  *
2465  * @see elm_thumbscroll_bring_in_scroll_friction_get()
2466  * @ingroup Scrolling
2467  */
2468 EAPI void
2469 elm_scroll_bring_in_scroll_friction_all_set(double friction)
2470 {
2471 #ifdef HAVE_ELEMENTARY_X
2472    static Ecore_X_Atom atom = 0;
2473    unsigned int bring_in_scroll_friction_i = (unsigned int)(friction * 1000.0);
2474
2475    if (!atom)
2476      atom =
2477        ecore_x_atom_get("ENLIGHTENMENT_THUMBSCROLL_BRING_IN_SCROLL_FRICTION");
2478    ecore_x_window_prop_card32_set(ecore_x_window_root_first_get(),
2479                                   atom, &bring_in_scroll_friction_i, 1);
2480 #endif
2481 }
2482
2483 /**
2484  * Get the amount of inertia scrollers will impose at animations
2485  * triggered by Elementary widgets' zooming API.
2486  *
2487  * @return the zoom friction
2488  *
2489  * @ingroup Scrolling
2490  */
2491 EAPI double
2492 elm_scroll_zoom_friction_get(void)
2493 {
2494    return _elm_config->zoom_friction;
2495 }
2496
2497 /**
2498  * Set the amount of inertia scrollers will impose at animations
2499  * triggered by Elementary widgets' zooming API.
2500  *
2501  * @param friction the zoom friction
2502  *
2503  * @see elm_thumbscroll_zoom_friction_get()
2504  * @ingroup Scrolling
2505  */
2506 EAPI void
2507 elm_scroll_zoom_friction_set(double friction)
2508 {
2509    _elm_config->zoom_friction = friction;
2510 }
2511
2512 /**
2513  * Set the amount of inertia scrollers will impose at animations
2514  * triggered by Elementary widgets' zooming API, for all Elementary
2515  * application windows.
2516  *
2517  * @param friction the zoom friction
2518  *
2519  * @see elm_thumbscroll_zoom_friction_get()
2520  * @ingroup Scrolling
2521  */
2522 EAPI void
2523 elm_scroll_zoom_friction_all_set(double friction)
2524 {
2525 #ifdef HAVE_ELEMENTARY_X
2526    static Ecore_X_Atom atom = 0;
2527    unsigned int zoom_friction_i = (unsigned int)(friction * 1000.0);
2528
2529    if (!atom)
2530      atom = ecore_x_atom_get("ENLIGHTENMENT_THUMBSCROLL_ZOOM_FRICTION");
2531    ecore_x_window_prop_card32_set(ecore_x_window_root_first_get(),
2532                                   atom, &zoom_friction_i, 1);
2533 #endif
2534 }
2535
2536 /**
2537  * Get whether scrollers should be draggable from any point in their
2538  * views.
2539  *
2540  * @return the thumb scroll state
2541  *
2542  * @note This is the default behavior for touch screens, in general.
2543  * @note All other functions namespaced with "thumbscroll" will only
2544  *       have effect if this mode is enabled.
2545  *
2546  * @ingroup Scrolling
2547  */
2548 EAPI Eina_Bool
2549 elm_scroll_thumbscroll_enabled_get(void)
2550 {
2551    return _elm_config->thumbscroll_enable;
2552 }
2553
2554 /**
2555  * Set whether scrollers should be draggable from any point in their
2556  * views.
2557  *
2558  * @param enabled the thumb scroll state
2559  *
2560  * @see elm_thumbscroll_enabled_get()
2561  * @ingroup Scrolling
2562  */
2563 EAPI void
2564 elm_scroll_thumbscroll_enabled_set(Eina_Bool enabled)
2565 {
2566    _elm_config->thumbscroll_enable = enabled;
2567 }
2568
2569 /**
2570  * Set whether scrollers should be draggable from any point in their
2571  * views, for all Elementary application windows.
2572  *
2573  * @param enabled the thumb scroll state
2574  *
2575  * @see elm_thumbscroll_enabled_get()
2576  * @ingroup Scrolling
2577  */
2578 EAPI void
2579 elm_scroll_thumbscroll_enabled_all_set(Eina_Bool enabled)
2580 {
2581 #ifdef HAVE_ELEMENTARY_X
2582    static Ecore_X_Atom atom = 0;
2583    unsigned int ts_enable_i = (unsigned int)enabled;
2584
2585    if (!atom) atom = ecore_x_atom_get("ENLIGHTENMENT_THUMBSCROLL_ENABLE");
2586    ecore_x_window_prop_card32_set(ecore_x_window_root_first_get(),
2587                                   atom, &ts_enable_i, 1);
2588 #endif
2589 }
2590
2591 /**
2592  * Get the number of pixels one should travel while dragging a
2593  * scroller's view to actually trigger scrolling.
2594  *
2595  * @return the thumb scroll threshould
2596  *
2597  * One would use higher values for touch screens, in general, because
2598  * of their inherent imprecision.
2599  * @ingroup Scrolling
2600  */
2601 EAPI unsigned int
2602 elm_scroll_thumbscroll_threshold_get(void)
2603 {
2604    return _elm_config->thumbscroll_threshold;
2605 }
2606
2607 /**
2608  * Set the number of pixels one should travel while dragging a
2609  * scroller's view to actually trigger scrolling.
2610  *
2611  * @param threshold the thumb scroll threshould
2612  *
2613  * @see elm_thumbscroll_threshould_get()
2614  * @ingroup Scrolling
2615  */
2616 EAPI void
2617 elm_scroll_thumbscroll_threshold_set(unsigned int threshold)
2618 {
2619    _elm_config->thumbscroll_threshold = threshold;
2620 }
2621
2622 /**
2623  * Set the number of pixels one should travel while dragging a
2624  * scroller's view to actually trigger scrolling, for all Elementary
2625  * application windows.
2626  *
2627  * @param threshold the thumb scroll threshould
2628  *
2629  * @see elm_thumbscroll_threshould_get()
2630  * @ingroup Scrolling
2631  */
2632 EAPI void
2633 elm_scroll_thumbscroll_threshold_all_set(unsigned int threshold)
2634 {
2635 #ifdef HAVE_ELEMENTARY_X
2636    static Ecore_X_Atom atom = 0;
2637    unsigned int ts_threshold_i = (unsigned int)threshold;
2638
2639    if (!atom) atom = ecore_x_atom_get("ENLIGHTENMENT_THUMBSCROLL_THRESHOLD");
2640    ecore_x_window_prop_card32_set(ecore_x_window_root_first_get(),
2641                                   atom, &ts_threshold_i, 1);
2642 #endif
2643 }
2644
2645 /**
2646  * Get the minimum speed of mouse cursor movement which will trigger
2647  * list self scrolling animation after a mouse up event
2648  * (pixels/second).
2649  *
2650  * @return the thumb scroll momentum threshould
2651  *
2652  * @ingroup Scrolling
2653  */
2654 EAPI double
2655 elm_scroll_thumbscroll_momentum_threshold_get(void)
2656 {
2657    return _elm_config->thumbscroll_momentum_threshold;
2658 }
2659
2660 /**
2661  * Set the minimum speed of mouse cursor movement which will trigger
2662  * list self scrolling animation after a mouse up event
2663  * (pixels/second).
2664  *
2665  * @param threshold the thumb scroll momentum threshould
2666  *
2667  * @see elm_thumbscroll_momentum_threshould_get()
2668  * @ingroup Scrolling
2669  */
2670 EAPI void
2671 elm_scroll_thumbscroll_momentum_threshold_set(double threshold)
2672 {
2673    _elm_config->thumbscroll_momentum_threshold = threshold;
2674 }
2675
2676 /**
2677  * Set the minimum speed of mouse cursor movement which will trigger
2678  * list self scrolling animation after a mouse up event
2679  * (pixels/second), for all Elementary application windows.
2680  *
2681  * @param threshold the thumb scroll momentum threshould
2682  *
2683  * @see elm_thumbscroll_momentum_threshould_get()
2684  * @ingroup Scrolling
2685  */
2686 EAPI void
2687 elm_scroll_thumbscroll_momentum_threshold_all_set(double threshold)
2688 {
2689 #ifdef HAVE_ELEMENTARY_X
2690    static Ecore_X_Atom atom = 0;
2691    unsigned int ts_momentum_threshold_i = (unsigned int)(threshold * 1000.0);
2692
2693    if (!atom)
2694      atom = ecore_x_atom_get("ENLIGHTENMENT_THUMBSCROLL_MOMENTUM_THRESHOLD");
2695    ecore_x_window_prop_card32_set(ecore_x_window_root_first_get(),
2696                                   atom, &ts_momentum_threshold_i, 1);
2697 #endif
2698 }
2699
2700 /**
2701  * Get the amount of inertia a scroller will impose at self scrolling
2702  * animations.
2703  *
2704  * @return the thumb scroll friction
2705  *
2706  * @ingroup Scrolling
2707  */
2708 EAPI double
2709 elm_scroll_thumbscroll_friction_get(void)
2710 {
2711    return _elm_config->thumbscroll_friction;
2712 }
2713
2714 /**
2715  * Set the amount of inertia a scroller will impose at self scrolling
2716  * animations.
2717  *
2718  * @param friction the thumb scroll friction
2719  *
2720  * @see elm_thumbscroll_friction_get()
2721  * @ingroup Scrolling
2722  */
2723 EAPI void
2724 elm_scroll_thumbscroll_friction_set(double friction)
2725 {
2726    _elm_config->thumbscroll_friction = friction;
2727 }
2728
2729 /**
2730  * Set the amount of inertia a scroller will impose at self scrolling
2731  * animations, for all Elementary application windows.
2732  *
2733  * @param friction the thumb scroll friction
2734  *
2735  * @see elm_thumbscroll_friction_get()
2736  * @ingroup Scrolling
2737  */
2738 EAPI void
2739 elm_scroll_thumbscroll_friction_all_set(double friction)
2740 {
2741 #ifdef HAVE_ELEMENTARY_X
2742    static Ecore_X_Atom atom = 0;
2743    unsigned int ts_friction_i = (unsigned int)(friction * 1000.0);
2744
2745    if (!atom) atom = ecore_x_atom_get("ENLIGHTENMENT_THUMBSCROLL_FRICTION");
2746    ecore_x_window_prop_card32_set(ecore_x_window_root_first_get(),
2747                                   atom, &ts_friction_i, 1);
2748 #endif
2749 }
2750
2751 /**
2752  * Get the amount of lag between your actual mouse cursor dragging
2753  * movement and a scroller's view movement itself, while pushing it
2754  * into bounce state manually.
2755  *
2756  * @return the thumb scroll border friction
2757  *
2758  * @ingroup Scrolling
2759  */
2760 EAPI double
2761 elm_scroll_thumbscroll_border_friction_get(void)
2762 {
2763    return _elm_config->thumbscroll_border_friction;
2764 }
2765
2766 /**
2767  * Set the amount of lag between your actual mouse cursor dragging
2768  * movement and a scroller's view movement itself, while pushing it
2769  * into bounce state manually.
2770  *
2771  * @param friction the thumb scroll border friction. @c 0.0 for
2772  *        perfect synchrony between two movements, @c 1.0 for maximum
2773  *        lag.
2774  *
2775  * @see elm_thumbscroll_border_friction_get()
2776  * @note parameter value will get bound to 0.0 - 1.0 interval, always
2777  *
2778  * @ingroup Scrolling
2779  */
2780 EAPI void
2781 elm_scroll_thumbscroll_border_friction_set(double friction)
2782 {
2783    if (friction < 0.0)
2784      friction = 0.0;
2785
2786    if (friction > 1.0)
2787      friction = 1.0;
2788
2789    _elm_config->thumbscroll_friction = friction;
2790 }
2791
2792 /**
2793  * Set the amount of lag between your actual mouse cursor dragging
2794  * movement and a scroller's view movement itself, while pushing it
2795  * into bounce state manually, for all Elementary application windows.
2796  *
2797  * @param friction the thumb scroll border friction. @c 0.0 for
2798  *        perfect synchrony between two movements, @c 1.0 for maximum
2799  *        lag.
2800  *
2801  * @see elm_thumbscroll_border_friction_get()
2802  * @note parameter value will get bound to 0.0 - 1.0 interval, always
2803  *
2804  * @ingroup Scrolling
2805  */
2806 EAPI void
2807 elm_scroll_thumbscroll_border_friction_all_set(double friction)
2808 {
2809    if (friction < 0.0)
2810      friction = 0.0;
2811
2812    if (friction > 1.0)
2813      friction = 1.0;
2814
2815 #ifdef HAVE_ELEMENTARY_X
2816    static Ecore_X_Atom atom = 0;
2817    unsigned int border_friction_i = (unsigned int)(friction * 1000.0);
2818
2819    if (!atom)
2820      atom = ecore_x_atom_get("ENLIGHTENMENT_THUMBSCROLL_BORDER_FRICTION");
2821    ecore_x_window_prop_card32_set(ecore_x_window_root_first_get(),
2822                                   atom, &border_friction_i, 1);
2823 #endif
2824 }
2825
2826 /**
2827  * @defgroup Scrollhints Scrollhints
2828  *
2829  * Objects when inside a scroller can scroll, but this may not always be
2830  * desirable in certain situations. This allows an object to hint to itself
2831  * and parents to "not scroll" in one of 2 ways.
2832  *
2833  * 1. To hold on scrolling. This means just flicking and dragging may no
2834  * longer scroll, but pressing/dragging near an edge of the scroller will
2835  * still scroll. This is automastically used by the entry object when
2836  * selecting text.
2837  * 2. To totally freeze scrolling. This means it stops. until popped/released.
2838  */
2839
2840 /**
2841  * Push the scroll hold by 1
2842  *
2843  * This increments the scroll hold count by one. If it is more than 0 it will
2844  * take effect on the parents of the indicated object.
2845  *
2846  * @param obj The object
2847  * @ingroup Scrollhints
2848  */
2849 EAPI void
2850 elm_object_scroll_hold_push(Evas_Object *obj)
2851 {
2852    EINA_SAFETY_ON_NULL_RETURN(obj);
2853    elm_widget_scroll_hold_push(obj);
2854 }
2855
2856 /**
2857  * Pop the scroll hold by 1
2858  *
2859  * This decrements the scroll hold count by one. If it is more than 0 it will
2860  * take effect on the parents of the indicated object.
2861  *
2862  * @param obj The object
2863  * @ingroup Scrollhints
2864  */
2865 EAPI void
2866 elm_object_scroll_hold_pop(Evas_Object *obj)
2867 {
2868    EINA_SAFETY_ON_NULL_RETURN(obj);
2869    elm_widget_scroll_hold_pop(obj);
2870 }
2871
2872 /**
2873  * Push the scroll freeze by 1
2874  *
2875  * This increments the scroll freeze count by one. If it is more than 0 it will
2876  * take effect on the parents of the indicated object.
2877  *
2878  * @param obj The object
2879  * @ingroup Scrollhints
2880  */
2881 EAPI void
2882 elm_object_scroll_freeze_push(Evas_Object *obj)
2883 {
2884    EINA_SAFETY_ON_NULL_RETURN(obj);
2885    elm_widget_scroll_freeze_push(obj);
2886 }
2887
2888 /**
2889  * Lock the scrolling of the given widget (and thus all parents)
2890  *
2891  * This locks the given object from scrolling in the X axis (and implicitly
2892  * also locks all parent scrollers too from doing the same).
2893  *
2894  * @param obj The object
2895  * @param lock The lock state (1 == locked, 0 == unlocked)
2896  * @ingroup Scrollhints
2897  */
2898 EAPI void
2899 elm_object_scroll_lock_x_set(Evas_Object *obj,
2900                              Eina_Bool    lock)
2901 {
2902    EINA_SAFETY_ON_NULL_RETURN(obj);
2903    elm_widget_drag_lock_x_set(obj, lock);
2904 }
2905
2906 /**
2907  * Lock the scrolling of the given widget (and thus all parents)
2908  *
2909  * This locks the given object from scrolling in the Y axis (and implicitly
2910  * also locks all parent scrollers too from doing the same).
2911  *
2912  * @param obj The object
2913  * @param lock The lock state (1 == locked, 0 == unlocked)
2914  * @ingroup Scrollhints
2915  */
2916 EAPI void
2917 elm_object_scroll_lock_y_set(Evas_Object *obj,
2918                              Eina_Bool    lock)
2919 {
2920    EINA_SAFETY_ON_NULL_RETURN(obj);
2921    elm_widget_drag_lock_y_set(obj, lock);
2922 }
2923
2924 /**
2925  * Get the scrolling lock of the given widget
2926  *
2927  * This gets the lock for X axis scrolling.
2928  *
2929  * @param obj The object
2930  * @ingroup Scrollhints
2931  */
2932 EAPI Eina_Bool
2933 elm_object_scroll_lock_x_get(const Evas_Object *obj)
2934 {
2935    EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE);
2936    return elm_widget_drag_lock_x_get(obj);
2937 }
2938
2939 /**
2940  * Get the scrolling lock of the given widget
2941  *
2942  * This gets the lock for X axis scrolling.
2943  *
2944  * @param obj The object
2945  * @ingroup Scrollhints
2946  */
2947 EAPI Eina_Bool
2948 elm_object_scroll_lock_y_get(const Evas_Object *obj)
2949 {
2950    EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE);
2951    return elm_widget_drag_lock_y_get(obj);
2952 }
2953
2954 /**
2955  * Pop the scroll freeze by 1
2956  *
2957  * This decrements the scroll freeze count by one. If it is more than 0 it will
2958  * take effect on the parents of the indicated object.
2959  *
2960  * @param obj The object
2961  * @ingroup Scrollhints
2962  */
2963 EAPI void
2964 elm_object_scroll_freeze_pop(Evas_Object *obj)
2965 {
2966    EINA_SAFETY_ON_NULL_RETURN(obj);
2967    elm_widget_scroll_freeze_pop(obj);
2968 }
2969
2970 /**
2971  * Check if the given Evas Object is an Elementary widget.
2972  *
2973  * @param obj the object to query.
2974  * @return @c EINA_TRUE if it is an elementary widget variant,
2975  *         @c EINA_FALSE otherwise
2976  * @ingroup WidgetNavigation
2977  */
2978 EAPI Eina_Bool
2979 elm_object_widget_check(const Evas_Object *obj)
2980 {
2981    EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE);
2982    return elm_widget_is(obj);
2983 }
2984
2985 EAPI Evas_Object *
2986 elm_object_parent_widget_get(const Evas_Object *obj)
2987 {
2988    EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
2989    return elm_widget_parent_widget_get(obj);
2990 }
2991
2992 /**
2993  * Get the top level parent of an Elementary widget.
2994  *
2995  * @param obj The object to query.
2996  * @return The top level Elementary widget, or @c NULL if parent cannot be
2997  * found.
2998  * @ingroup WidgetNavigation
2999  */
3000 EAPI Evas_Object *
3001 elm_object_top_widget_get(const Evas_Object *obj)
3002 {
3003    EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
3004    return elm_widget_top_get(obj);
3005 }
3006
3007 /**
3008  * Get the string that represents this Elementary widget.
3009  *
3010  * @note Elementary is weird and exposes itself as a single
3011  *       Evas_Object_Smart_Class of type "elm_widget", so
3012  *       evas_object_type_get() always return that, making debug and
3013  *       language bindings hard. This function tries to mitigate this
3014  *       problem, but the solution is to change Elementary to use
3015  *       proper inheritance.
3016  *
3017  * @param obj the object to query.
3018  * @return Elementary widget name, or @c NULL if not a valid widget.
3019  * @ingroup WidgetNavigation
3020  */
3021 EAPI const char *
3022 elm_object_widget_type_get(const Evas_Object *obj)
3023 {
3024    EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
3025    return elm_widget_type_get(obj);
3026 }
3027
3028 /**
3029  * Send a signal to the widget edje object.
3030  *
3031  * This function sends a signal to the edje object of the obj. An edje program
3032  * can respond to a signal by specifying matching 'signal' and
3033  * 'source' fields.
3034  *
3035  * @param obj The object
3036  * @param emission The signal's name.
3037  * @param source The signal's source.
3038  * @ingroup General
3039  */
3040 EAPI void
3041 elm_object_signal_emit(Evas_Object *obj,
3042                        const char  *emission,
3043                        const char  *source)
3044 {
3045    EINA_SAFETY_ON_NULL_RETURN(obj);
3046    elm_widget_signal_emit(obj, emission, source);
3047 }
3048
3049 /**
3050  * Add a callback for a signal emitted by widget edje object.
3051  *
3052  * This function connects a callback function to a signal emitted by the
3053  * edje object of the obj.
3054  * Globs can occur in either the emission or source name.
3055  *
3056  * @param obj The object
3057  * @param emission The signal's name.
3058  * @param source The signal's source.
3059  * @param func The callback function to be executed when the signal is
3060  * emitted.
3061  * @param data A pointer to data to pass in to the callback function.
3062  * @ingroup General
3063  */
3064 EAPI void
3065 elm_object_signal_callback_add(Evas_Object *obj, const char *emission, const char *source, Edje_Signal_Cb func, void *data)
3066 {
3067     EINA_SAFETY_ON_NULL_RETURN(obj);
3068     EINA_SAFETY_ON_NULL_RETURN(func);
3069     elm_widget_signal_callback_add(obj, emission, source, func, data);
3070 }
3071
3072 /**
3073  * Remove a signal-triggered callback from an widget edje object.
3074  *
3075  * This function removes a callback, previoulsy attached to a signal emitted
3076  * by the edje object of the obj.
3077  * The parameters emission, source and func must match exactly those passed to
3078  * a previous call to elm_object_signal_callback_add(). The data pointer that
3079  * was passed to this call will be returned.
3080  *
3081  * @param obj The object
3082  * @param emission The signal's name.
3083  * @param source The signal's source.
3084  * @param func The callback function to be executed when the signal is
3085  * emitted.
3086  * @return The data pointer
3087  * @ingroup General
3088  */
3089 EAPI void *
3090 elm_object_signal_callback_del(Evas_Object *obj, const char *emission, const char *source, Edje_Signal_Cb func)
3091 {
3092     EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
3093     EINA_SAFETY_ON_NULL_RETURN_VAL(func, NULL);
3094     return elm_widget_signal_callback_del(obj, emission, source, func);
3095 }
3096
3097 /**
3098  * Add a callback for a event emitted by widget or their children.
3099  *
3100  * This function connects a callback function to any key_down key_up event
3101  * emitted by the @p obj or their children.
3102  * This only will be called if no other callback has consumed the event.
3103  * If you want consume the event, and no other get it, func should return
3104  * EINA_TRUE and put EVAS_EVENT_FLAG_ON_HOLD in event_flags.
3105  *
3106  * @warning Accept duplicated callback addition.
3107  *
3108  * @param obj The object
3109  * @param func The callback function to be executed when the event is
3110  * emitted.
3111  * @param data Data to pass in to the callback function.
3112  * @ingroup General
3113  */
3114 EAPI void
3115 elm_object_event_callback_add(Evas_Object *obj, Elm_Event_Cb func, const void *data)
3116 {
3117    EINA_SAFETY_ON_NULL_RETURN(obj);
3118    EINA_SAFETY_ON_NULL_RETURN(func);
3119    elm_widget_event_callback_add(obj, func, data);
3120 }
3121
3122 /**
3123  * Remove a event callback from an widget.
3124  *
3125  * This function removes a callback, previoulsy attached to event emission
3126  * by the @p obj.
3127  * The parameters func and data must match exactly those passed to
3128  * a previous call to elm_object_event_callback_add(). The data pointer that
3129  * was passed to this call will be returned.
3130  *
3131  * @param obj The object
3132  * @param func The callback function to be executed when the event is
3133  * emitted.
3134  * @param data Data to pass in to the callback function.
3135  * @return The data pointer
3136  * @ingroup General
3137  */
3138 EAPI void *
3139 elm_object_event_callback_del(Evas_Object *obj, Elm_Event_Cb func, const void *data)
3140 {
3141    EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
3142    EINA_SAFETY_ON_NULL_RETURN_VAL(func, NULL);
3143    return elm_widget_event_callback_del(obj, func, data);
3144 }
3145
3146
3147 /**
3148  * @defgroup Debug Debug
3149  */
3150
3151 /**
3152  * Print Tree object hierarchy in stdout
3153  *
3154  * @param obj The root object
3155  * @ingroup Debug
3156  */
3157 EAPI void
3158 elm_object_tree_dump(const Evas_Object *top)
3159 {
3160 #ifdef ELM_DEBUG
3161    elm_widget_tree_dump(top);
3162 #else
3163    return;
3164    (void)top;
3165 #endif
3166 }
3167
3168 /**
3169  * Print Elm Objects tree hierarchy in file as dot(graphviz) syntax.
3170  *
3171  * @param obj The root object
3172  * @param file The path of output file
3173  * @ingroup Debug
3174  */
3175 EAPI void
3176 elm_object_tree_dot_dump(const Evas_Object *top,
3177                          const char        *file)
3178 {
3179 #ifdef ELM_DEBUG
3180    FILE *f = fopen(file, "wb");
3181    elm_widget_tree_dot_dump(top, f);
3182    fclose(f);
3183 #else
3184    return;
3185    (void)top;
3186    (void)file;
3187 #endif
3188 }
3189
3190 /**
3191  * Set the duration for occuring long press event.
3192  *
3193  * @param lonpress_timeout Timeout for long press event
3194  * @ingroup Longpress
3195  */
3196 EAPI void
3197 elm_longpress_timeout_set(double longpress_timeout)
3198 {
3199    _elm_config->longpress_timeout = longpress_timeout;
3200 }
3201
3202 /**
3203  * Get the duration for occuring long press event.
3204  *
3205  * @return Timeout for long press event
3206  * @ingroup Longpress
3207  */
3208 EAPI double
3209 elm_longpress_timeout_get(void)
3210 {
3211    return _elm_config->longpress_timeout;
3212 }
3213
3214 EAPI void
3215 elm_object_item_content_part_set(Elm_Object_Item *it,
3216                                  const char *part,
3217                                  Evas_Object *content)
3218 {
3219    elm_widget_item_content_part_set(it, part, content);
3220 }
3221
3222 EAPI Evas_Object *
3223 elm_object_item_content_part_get(const Elm_Object_Item *it,
3224                                  const char *part)
3225 {
3226    return elm_widget_item_content_part_get(it, part);
3227 }
3228
3229 EAPI Evas_Object *
3230 elm_object_item_content_part_unset(Elm_Object_Item *it, const char *part)
3231 {
3232    return elm_widget_item_content_part_unset(it, part);
3233 }
3234
3235 EAPI void
3236 elm_object_item_text_part_set(Elm_Object_Item *it,
3237                               const char *part,
3238                               const char *label)
3239 {
3240    elm_widget_item_text_part_set(it, part, label);
3241 }
3242
3243 EAPI const char *
3244 elm_object_item_text_part_get(const Elm_Object_Item *it, const char *part)
3245 {
3246    return elm_widget_item_text_part_get(it, part);
3247 }