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