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