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