Elementary ui-mirroring: move elm_widget_mirrored_* functions to elm_widget.h.
[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 UI-Mirroring Selective Widget mirroring
1063  *
1064  * These functions allow you to set ui-miroring on specific widgets or whe
1065  * whole interface. Widgets can be in one of two modes, automatic and manual.
1066  * Automatic means they'll be changed according to the system mirroring mode
1067  * and manual means only explicit changes will matter. You are not supposed to
1068  * change mirroring state of a widget set to automatic, will mostly work, but
1069  * the behavior is not really defined.
1070  */
1071
1072 /**
1073  * Returns the widget's mirrored mode.
1074  *
1075  * @param obj The widget.
1076  * @return mirrored mode of the object.
1077  *
1078  **/
1079 EAPI Eina_Bool
1080 elm_object_mirrored_get(const Evas_Object *obj)
1081 {
1082    EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE);
1083    return elm_widget_mirrored_get(obj);
1084 }
1085
1086 /**
1087  * Sets the widget's mirrored mode.
1088  *
1089  * @param obj The widget.
1090  * @param mirrored EINA_TRUE to set mirrored mode. EINA_FALSE to unset.
1091  */
1092 EAPI void
1093 elm_object_mirrored_set(Evas_Object *obj, Eina_Bool mirrored)
1094 {
1095    EINA_SAFETY_ON_NULL_RETURN(obj);
1096    elm_widget_mirrored_set(obj, mirrored);
1097 }
1098
1099 /**
1100  * Returns the widget's mirrored mode setting.
1101  *
1102  * @param obj The widget.
1103  * @return mirrored mode setting of the object.
1104  *
1105  **/
1106 EAPI Eina_Bool
1107 elm_object_mirrored_automatic_get(const Evas_Object *obj)
1108 {
1109    EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE);
1110    return elm_widget_mirrored_automatic_get(obj);
1111 }
1112
1113 /**
1114  * Sets the widget's mirrored mode setting.
1115  * When widget in automatic mode, it follows the system mirrored mode set by
1116  * elm_mirrored_set().
1117  * @param obj The widget.
1118  * @param automatic EINA_TRUE for auto mirrored mode. EINA_FALSE for manual.
1119  */
1120 EAPI void
1121 elm_object_mirrored_automatic_set(Evas_Object *obj, Eina_Bool automatic)
1122 {
1123    EINA_SAFETY_ON_NULL_RETURN(obj);
1124    elm_widget_mirrored_automatic_set(obj, automatic);
1125 }
1126
1127 /**
1128  * @defgroup Scaling Selective Widget Scaling
1129  *
1130  * Different widgets can be scaled independently. These functions allow you to
1131  * manipulate this scaling on a per-widget basis. The object and all its
1132  * children get their scaling factors multiplied by the scale factor set.
1133  * This is multiplicative, in that if a child also has a scale size set it is
1134  * in turn multiplied by its parent's scale size. 1.0 means “don't scale”,
1135  * 2.0 is double size, 0.5 is half etc.
1136  */
1137
1138 /**
1139  * Set the scaling factor
1140  *
1141  * @param obj The object
1142  * @param scale Scale factor (from 0.0 up, with 1.0 == no scaling)
1143  * @ingroup Scaling
1144  */
1145 EAPI void
1146 elm_object_scale_set(Evas_Object *obj,
1147                      double       scale)
1148 {
1149    EINA_SAFETY_ON_NULL_RETURN(obj);
1150    elm_widget_scale_set(obj, scale);
1151 }
1152
1153 /**
1154  * Get the scaling factor
1155  *
1156  * @param obj The object
1157  * @return The scaling factor set by elm_object_scale_set()
1158  * @ingroup Scaling
1159  */
1160 EAPI double
1161 elm_object_scale_get(const Evas_Object *obj)
1162 {
1163    EINA_SAFETY_ON_NULL_RETURN_VAL(obj, 0.0);
1164    return elm_widget_scale_get(obj);
1165 }
1166
1167 /**
1168  * Get the global scaling factor
1169  *
1170  * This gets the globally configured scaling factor that is applied to all
1171  * objects.
1172  *
1173  * @return The scaling factor
1174  * @ingroup Scaling
1175  */
1176 EAPI double
1177 elm_scale_get(void)
1178 {
1179    return _elm_config->scale;
1180 }
1181
1182 /**
1183  * Set the global scaling factor
1184  *
1185  * This sets the globally configured scaling factor that is applied to all
1186  * objects.
1187  *
1188  * @param scale The scaling factor to set
1189  * @ingroup Scaling
1190  */
1191 EAPI void
1192 elm_scale_set(double scale)
1193 {
1194    if (_elm_config->scale == scale) return;
1195    _elm_config->scale = scale;
1196    _elm_rescale();
1197 }
1198
1199 /**
1200  * Set the global scaling factor for all applications on the display
1201  *
1202  * This sets the globally configured scaling factor that is applied to all
1203  * objects for all applications.
1204  * @param scale The scaling factor to set
1205  * @ingroup Scaling
1206  */
1207 EAPI void
1208 elm_scale_all_set(double scale)
1209 {
1210 #ifdef HAVE_ELEMENTARY_X
1211    static Ecore_X_Atom atom = 0;
1212    unsigned int scale_i = (unsigned int)(scale * 1000.0);
1213
1214    if (!atom) atom = ecore_x_atom_get("ENLIGHTENMENT_SCALE");
1215    ecore_x_window_prop_card32_set(ecore_x_window_root_first_get(),
1216                                   atom, &scale_i, 1);
1217 #endif
1218 }
1219
1220 /**
1221  * @defgroup Styles Styles
1222  *
1223  * Widgets can have different styles of look. These generic API's set
1224  * styles of widgets, if they support them (and if the theme(s) do).
1225  */
1226
1227 /**
1228  * Set the style
1229  *
1230  * This sets the name of the style
1231  * @param obj The object
1232  * @param style The style name to use
1233  * @ingroup Styles
1234  */
1235 EAPI void
1236 elm_object_style_set(Evas_Object *obj,
1237                      const char  *style)
1238 {
1239    EINA_SAFETY_ON_NULL_RETURN(obj);
1240    elm_widget_style_set(obj, style);
1241 }
1242
1243 /**
1244  * Get the style
1245  *
1246  * This gets the style being used for that widget. Note that the string
1247  * pointer is only valid as longas the object is valid and the style doesn't
1248  * change.
1249  *
1250  * @param obj The object
1251  * @return The style name
1252  * @ingroup Styles
1253  */
1254 EAPI const char *
1255 elm_object_style_get(const Evas_Object *obj)
1256 {
1257    EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
1258    return elm_widget_style_get(obj);
1259 }
1260
1261 /**
1262  * Set the disable state
1263  *
1264  * This sets the disable state for the widget.
1265  *
1266  * @param obj The object
1267  * @param disabled The state
1268  * @ingroup Styles
1269  */
1270 EAPI void
1271 elm_object_disabled_set(Evas_Object *obj,
1272                         Eina_Bool    disabled)
1273 {
1274    EINA_SAFETY_ON_NULL_RETURN(obj);
1275    elm_widget_disabled_set(obj, disabled);
1276 }
1277
1278 /**
1279  * Get the disable state
1280  *
1281  * This gets the disable state for the widget.
1282  *
1283  * @param obj The object
1284  * @return True, if the widget is disabled
1285  * @ingroup Styles
1286  */
1287 EAPI Eina_Bool
1288 elm_object_disabled_get(const Evas_Object *obj)
1289 {
1290    EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE);
1291    return elm_widget_disabled_get(obj);
1292 }
1293
1294 /**
1295  * @defgroup Config Elementary Config
1296  *
1297  * Elementary configuration is formed by a set options bounded to a
1298  * given @ref Profile profile, like @ref Theme theme, @ref Fingers
1299  * "finger size", etc. These are functions with which one syncronizes
1300  * changes made to those values to the configuration storing files, de
1301  * facto. You most probably don't want to use the functions in this
1302  * group unlees you're writing an elementary configuration manager.
1303  */
1304
1305 /**
1306  * Save back Elementary's configuration, so that it will persist on
1307  * future sessions.
1308  *
1309  * @return @c EINA_TRUE, when sucessful. @c EINA_FALSE, otherwise.
1310  * @ingroup Config
1311  *
1312  * This function will take effect -- thus, do I/O -- immediately. Use
1313  * it when you want to apply all configuration changes at once. The
1314  * current configuration set will get saved onto the current profile
1315  * configuration file.
1316  *
1317  */
1318 EAPI Eina_Bool
1319 elm_config_save(void)
1320 {
1321    return _elm_config_save();
1322 }
1323
1324 /**
1325  * Reload Elementary's configuration, bounded to current selected
1326  * profile.
1327  *
1328  * @return @c EINA_TRUE, when sucessful. @c EINA_FALSE, otherwise.
1329  * @ingroup Config
1330  *
1331  * Useful when you want to force reloading of configuration values for
1332  * a profile. If one removes user custom configuration directories,
1333  * for example, it will force a reload with system values insted.
1334  *
1335  */
1336 EAPI void
1337 elm_config_reload(void)
1338 {
1339    _elm_config_reload();
1340 }
1341
1342 /**
1343  * @defgroup Profile Elementary Profile
1344  *
1345  * Profiles are pre-set options that affect the whole look-and-feel of
1346  * Elementary-based applications. There are, for example, profiles
1347  * aimed at desktop computer applications and others aimed at mobile,
1348  * touchscreen-based ones. You most probably don't want to use the
1349  * functions in this group unlees you're writing an elementary
1350  * configuration manager.
1351  */
1352
1353 /**
1354  * Get Elementary's profile in use.
1355  *
1356  * This gets the global profile that is applied to all Elementary
1357  * applications.
1358  *
1359  * @return The profile's name
1360  * @ingroup Profile
1361  */
1362 EAPI const char *
1363 elm_profile_current_get(void)
1364 {
1365    return _elm_config_current_profile_get();
1366 }
1367
1368 /**
1369  * Get an Elementary's profile directory path in the filesystem. One
1370  * may want to fetch a system profile's dir or an user one (fetched
1371  * inside $HOME).
1372  *
1373  * @param profile The profile's name
1374  * @param is_user Whether to lookup for an user profile (@c EINA_TRUE)
1375  *                or a system one (@c EINA_FALSE)
1376  * @return The profile's directory path.
1377  * @ingroup Profile
1378  *
1379  * @note You must free it with elm_profile_dir_free().
1380  */
1381 EAPI const char *
1382 elm_profile_dir_get(const char *profile,
1383                     Eina_Bool   is_user)
1384 {
1385    return _elm_config_profile_dir_get(profile, is_user);
1386 }
1387
1388 /**
1389  * Free an Elementary's profile directory path, as returned by
1390  * elm_profile_dir_get().
1391  *
1392  * @param p_dir The profile's path
1393  * @ingroup Profile
1394  *
1395  */
1396 EAPI void
1397 elm_profile_dir_free(const char *p_dir)
1398 {
1399    free((void *)p_dir);
1400 }
1401
1402 /**
1403  * Get Elementary's list of available profiles.
1404  *
1405  * @return The profiles list. List node data are the profile name
1406  *         strings.
1407  * @ingroup Profile
1408  *
1409  * @note One must free this list, after usage, with the function
1410  *       elm_profile_list_free().
1411  */
1412 EAPI Eina_List *
1413 elm_profile_list_get(void)
1414 {
1415    return _elm_config_profiles_list();
1416 }
1417
1418 /**
1419  * Free Elementary's list of available profiles.
1420  *
1421  * @param The profiles list, as returned by elm_profile_list_get().
1422  * @ingroup Profile
1423  *
1424  */
1425 EAPI void
1426 elm_profile_list_free(Eina_List *l)
1427 {
1428    const char *dir;
1429
1430    EINA_LIST_FREE(l, dir)
1431      eina_stringshare_del(dir);
1432 }
1433
1434 /**
1435  * Set Elementary's profile.
1436  *
1437  * This sets the global profile that is applied to Elementary
1438  * applications. Just the process the call comes from will be
1439  * affected.
1440  *
1441  * @param profile The profile's name
1442  * @ingroup Profile
1443  *
1444  */
1445 EAPI void
1446 elm_profile_set(const char *profile)
1447 {
1448    EINA_SAFETY_ON_NULL_RETURN(profile);
1449    _elm_config_profile_set(profile);
1450 }
1451
1452 /**
1453  * Set Elementary's profile.
1454  *
1455  * This sets the global profile that is applied to all Elementary
1456  * applications. All running Elementary windows will be affected.
1457  *
1458  * @param profile The profile's name
1459  * @ingroup Profile
1460  *
1461  */
1462 EAPI void
1463 elm_profile_all_set(const char *profile)
1464 {
1465 #ifdef HAVE_ELEMENTARY_X
1466    static Ecore_X_Atom atom = 0;
1467
1468    if (!atom) atom = ecore_x_atom_get("ENLIGHTENMENT_PROFILE");
1469    ecore_x_window_prop_string_set(ecore_x_window_root_first_get(),
1470                                   atom, profile);
1471 #endif
1472 }
1473
1474 /**
1475  * @defgroup Engine Elementary Engine
1476  *
1477  * These are functions setting and querying which rendering engine
1478  * Elementary will use for drawing its windows' pixels.
1479  */
1480
1481 /**
1482  * Get Elementary's rendering engine in use.
1483  *
1484  * This gets the global rendering engine that is applied to all
1485  * Elementary applications.
1486  *
1487  * @return The rendering engine's name
1488  * @ingroup Engine
1489  *
1490  * @note there's no need to free the returned string, here.
1491  */
1492 EAPI const char *
1493 elm_engine_current_get(void)
1494 {
1495    return _elm_config->engine;
1496 }
1497
1498 /**
1499  * Set Elementary's rendering engine for use.
1500  *
1501  * This gets sets global rendering engine that is applied to all
1502  * Elementary applications. Note that it will take effect only to
1503  * subsequent Elementary window creations.
1504  *
1505  * @param The rendering engine's name
1506  * @ingroup Engine
1507  *
1508  * @note there's no need to free the returned string, here.
1509  */
1510 EAPI void
1511 elm_engine_set(const char *engine)
1512 {
1513    EINA_SAFETY_ON_NULL_RETURN(engine);
1514
1515    _elm_config_engine_set(engine);
1516 }
1517
1518 /**
1519  * @defgroup Fonts Elementary Fonts
1520  *
1521  * These are functions dealing with font rendering, selection and the
1522  * like for Elementary applications. One might fetch which system
1523  * fonts are there to use and set custom fonts for individual classes
1524  * of UI items containing text (text classes).
1525  */
1526
1527 /**
1528  * Get Elementary's list of supported text classes.
1529  *
1530  * @return The text classes list, with @c Elm_Text_Class blobs as data.
1531  * @ingroup Fonts
1532  *
1533  * Release the list with elm_text_classes_list_free().
1534  */
1535 EAPI const Eina_List *
1536 elm_text_classes_list_get(void)
1537 {
1538    return _elm_config_text_classes_get();
1539 }
1540
1541 /**
1542  * Free Elementary's list of supported text classes.
1543  *
1544  * @ingroup Fonts
1545  *
1546  * @see elm_text_classes_list_get().
1547  */
1548 EAPI void
1549 elm_text_classes_list_free(const Eina_List *list)
1550 {
1551    _elm_config_text_classes_free((Eina_List *)list);
1552 }
1553
1554 /**
1555  * Get Elementary's list of font overlays, set with
1556  * elm_font_overlay_set().
1557  *
1558  * @return The font overlays list, with @c Elm_Font_Overlay blobs as
1559  * data.
1560  *
1561  * @ingroup Fonts
1562  *
1563  * For each text class, one can set a <b>font overlay</b> for it,
1564  * overriding the default font properties for that class coming from
1565  * the theme in use. There is no need to free this list.
1566  *
1567  * @see elm_font_overlay_set() and elm_font_overlay_unset().
1568  */
1569 EAPI const Eina_List *
1570 elm_font_overlay_list_get(void)
1571 {
1572    return _elm_config_font_overlays_list();
1573 }
1574
1575 /**
1576  * Set a font overlay for a given Elementary text class.
1577  *
1578  * @param text_class Text class name
1579  * @param font Font name and style string
1580  * @param size Font size
1581  *
1582  * @ingroup Fonts
1583  *
1584  * @p font has to be in the format returned by
1585  * elm_font_fontconfig_name_get(). @see elm_font_overlay_list_get()
1586  * and @elm_font_overlay_unset().
1587  */
1588 EAPI void
1589 elm_font_overlay_set(const char    *text_class,
1590                      const char    *font,
1591                      Evas_Font_Size size)
1592 {
1593    _elm_config_font_overlay_set(text_class, font, size);
1594 }
1595
1596 /**
1597  * Unset a font overlay for a given Elementary text class.
1598  *
1599  * @param text_class Text class name
1600  *
1601  * @ingroup Fonts
1602  *
1603  * This will bring back text elements belonging to text class @p
1604  * text_class back to their default font settings.
1605  */
1606 EAPI void
1607 elm_font_overlay_unset(const char *text_class)
1608 {
1609    _elm_config_font_overlay_remove(text_class);
1610 }
1611
1612 /**
1613  * Apply the changes made with elm_font_overlay_set() and
1614  * elm_font_overlay_unset() on the current Elementary window.
1615  *
1616  * @ingroup Fonts
1617  *
1618  * This applies all font overlays set to all objects in the UI.
1619  */
1620 EAPI void
1621 elm_font_overlay_apply(void)
1622 {
1623    _elm_config_font_overlay_apply();
1624 }
1625
1626 /**
1627  * Apply the changes made with elm_font_overlay_set() and
1628  * elm_font_overlay_unset() on all Elementary application windows.
1629  *
1630  * @ingroup Fonts
1631  *
1632  * This applies all font overlays set to all objects in the UI.
1633  */
1634 EAPI void
1635 elm_font_overlay_all_apply(void)
1636 {
1637 #ifdef HAVE_ELEMENTARY_X
1638    static Ecore_X_Atom atom = 0;
1639    unsigned int dummy = (unsigned int)(1 * 1000.0);
1640
1641    if (!atom) atom = ecore_x_atom_get("ENLIGHTENMENT_FONT_OVERLAY");
1642    ecore_x_window_prop_card32_set(ecore_x_window_root_first_get(), atom, &dummy,
1643                                   1);
1644 #endif
1645 }
1646
1647 /**
1648  * Translate a font (family) name string in fontconfig's font names
1649  * syntax into an @c Elm_Font_Properties struct.
1650  *
1651  * @param font The font name and styles string
1652  * @return the font properties struct
1653  *
1654  * @ingroup Fonts
1655  *
1656  * @note The reverse translation can be achived with
1657  * elm_font_fontconfig_name_get(), for one style only (single font
1658  * instance, not family).
1659  */
1660 EAPI Elm_Font_Properties *
1661 elm_font_properties_get(const char *font)
1662 {
1663    EINA_SAFETY_ON_NULL_RETURN_VAL(font, NULL);
1664    return _elm_font_properties_get(NULL, font);
1665 }
1666
1667 /**
1668  * Free font properties return by elm_font_properties_get().
1669  *
1670  * @param efp the font properties struct
1671  *
1672  * @ingroup Fonts
1673  */
1674 EAPI void
1675 elm_font_properties_free(Elm_Font_Properties *efp)
1676 {
1677    const char *str;
1678
1679    EINA_SAFETY_ON_NULL_RETURN(efp);
1680    EINA_LIST_FREE(efp->styles, str)
1681      if (str) eina_stringshare_del(str);
1682    if (efp->name) eina_stringshare_del(efp->name);
1683    free(efp);
1684 }
1685
1686 /**
1687  * Translate a font name, bound to a style, into fontconfig's font names
1688  * syntax.
1689  *
1690  * @param name The font (family) name
1691  * @param style The given style (may be @c NULL)
1692  *
1693  * @return the font name and style string
1694  *
1695  * @ingroup Fonts
1696  *
1697  * @note The reverse translation can be achived with
1698  * elm_font_properties_get(), for one style only (single font
1699  * instance, not family).
1700  */
1701 EAPI const char *
1702 elm_font_fontconfig_name_get(const char *name,
1703                              const char *style)
1704 {
1705    char buf[256];
1706
1707    EINA_SAFETY_ON_NULL_RETURN_VAL(name, NULL);
1708    if (!style || style[0] == 0) return eina_stringshare_add(name);
1709    snprintf(buf, 256, "%s" ELM_FONT_TOKEN_STYLE "%s", name, style);
1710    return eina_stringshare_add(buf);
1711 }
1712
1713 /**
1714  * Free the font string return by elm_font_fontconfig_name_get().
1715  *
1716  * @param efp the font properties struct
1717  *
1718  * @ingroup Fonts
1719  */
1720 EAPI void
1721 elm_font_fontconfig_name_free(const char *name)
1722 {
1723    eina_stringshare_del(name);
1724 }
1725
1726 /**
1727  * Create a font hash table of available system fonts.
1728  *
1729  * One must call it with @p list being the return value of
1730  * evas_font_available_list(). The hash will be indexed by font
1731  * (family) names, being its values @c Elm_Font_Properties blobs.
1732  *
1733  * @param list The list of available system fonts, as returned by
1734  * evas_font_available_list().
1735  * @return the font hash.
1736  *
1737  * @ingroup Fonts
1738  *
1739  * @note The user is supposed to get it populated at least with 3
1740  * default font families (Sans, Serif, Monospace), which should be
1741  * present on most systems.
1742  */
1743 EAPI Eina_Hash *
1744 elm_font_available_hash_add(Eina_List *list)
1745 {
1746    Eina_Hash *font_hash;
1747    Eina_List *l;
1748    void *key;
1749
1750    font_hash = NULL;
1751
1752    /* populate with default font families */
1753    font_hash = _elm_font_available_hash_add(font_hash, "Sans:style=Regular");
1754    font_hash = _elm_font_available_hash_add(font_hash, "Sans:style=Bold");
1755    font_hash = _elm_font_available_hash_add(font_hash, "Sans:style=Oblique");
1756    font_hash = _elm_font_available_hash_add(font_hash,
1757                                             "Sans:style=Bold Oblique");
1758
1759    font_hash = _elm_font_available_hash_add(font_hash, "Serif:style=Regular");
1760    font_hash = _elm_font_available_hash_add(font_hash, "Serif:style=Bold");
1761    font_hash = _elm_font_available_hash_add(font_hash, "Serif:style=Oblique");
1762    font_hash = _elm_font_available_hash_add(font_hash,
1763                                             "Serif:style=Bold Oblique");
1764
1765    font_hash = _elm_font_available_hash_add(font_hash,
1766                                             "Monospace:style=Regular");
1767    font_hash = _elm_font_available_hash_add(font_hash,
1768                                             "Monospace:style=Bold");
1769    font_hash = _elm_font_available_hash_add(font_hash,
1770                                             "Monospace:style=Oblique");
1771    font_hash = _elm_font_available_hash_add(font_hash,
1772                                             "Monospace:style=Bold Oblique");
1773
1774    EINA_LIST_FOREACH(list, l, key)
1775      font_hash = _elm_font_available_hash_add(font_hash, key);
1776
1777    return font_hash;
1778 }
1779
1780 /**
1781  * Free the hash return by elm_font_available_hash_add().
1782  *
1783  * @param hash the hash to be freed.
1784  *
1785  * @ingroup Fonts
1786  */
1787 EAPI void
1788 elm_font_available_hash_del(Eina_Hash *hash)
1789 {
1790    _elm_font_available_hash_del(hash);
1791 }
1792
1793 /**
1794  * @defgroup Fingers Fingers
1795  *
1796  * Elementary is designed to be finger-friendly for touchscreens, and so in
1797  * addition to scaling for display resolution, it can also scale based on
1798  * finger "resolution" (or size).
1799  */
1800
1801 /**
1802  * Get the configured finger size
1803  *
1804  * This gets the globally configured finger size in pixels
1805  *
1806  * @return The finger size
1807  * @ingroup Fingers
1808  */
1809 EAPI Evas_Coord
1810 elm_finger_size_get(void)
1811 {
1812    return _elm_config->finger_size;
1813 }
1814
1815 /**
1816  * Set the configured finger size
1817  *
1818  * This sets the globally configured finger size in pixels
1819  *
1820  * @param size The finger size
1821  * @ingroup Fingers
1822  */
1823 EAPI void
1824 elm_finger_size_set(Evas_Coord size)
1825 {
1826    if (_elm_config->finger_size == size) return;
1827    _elm_config->finger_size = size;
1828    _elm_rescale();
1829 }
1830
1831 /**
1832  * Set the configured finger size for all applications on the display
1833  *
1834  * This sets the globally configured finger size in pixels for all applications
1835  * on the display
1836  *
1837  * @param size The finger size
1838  * @ingroup Fingers
1839  */
1840 EAPI void
1841 elm_finger_size_all_set(Evas_Coord size)
1842 {
1843 #ifdef HAVE_ELEMENTARY_X
1844    static Ecore_X_Atom atom = 0;
1845    unsigned int size_i = (unsigned int)size;
1846
1847    if (!atom) atom = ecore_x_atom_get("ENLIGHTENMENT_FINGER_SIZE");
1848    ecore_x_window_prop_card32_set(ecore_x_window_root_first_get(),
1849                                   atom, &size_i, 1);
1850 #endif
1851 }
1852
1853 /**
1854  * Adjust size of an element for finger usage
1855  *
1856  * This takes width and height sizes (in pixels) as input and a size multiple
1857  * (which is how many fingers you want to place within the area), and adjusts
1858  * the size tobe large enough to accommodate finger. On return the w and h
1859  * sizes poiner do by these parameters will be modified.
1860  *
1861  * @param times_w How many fingers should fit horizontally
1862  * @param w Pointer to the width size to adjust
1863  * @param times_h How many fingers should fit vertically
1864  * @param h Pointer to the height size to adjust
1865  * @ingroup Fingers
1866  */
1867 EAPI void
1868 elm_coords_finger_size_adjust(int         times_w,
1869                               Evas_Coord *w,
1870                               int         times_h,
1871                               Evas_Coord *h)
1872 {
1873    if ((w) && (*w < (_elm_config->finger_size * times_w)))
1874      *w = _elm_config->finger_size * times_w;
1875    if ((h) && (*h < (_elm_config->finger_size * times_h)))
1876      *h = _elm_config->finger_size * times_h;
1877 }
1878
1879 /**
1880  * @defgroup Caches Caches
1881  *
1882  * These are functions which let one fine-tune some cache values for
1883  * Elementary applications, thus allowing for performance adjustments.
1884  */
1885
1886 /**
1887  * Flush all caches & dump all data that can be to lean down to use
1888  * less memory
1889  *
1890  * @ingroup Caches
1891  */
1892 EAPI void
1893 elm_all_flush(void)
1894 {
1895    const Eina_List *l;
1896    Evas_Object *obj;
1897
1898    edje_file_cache_flush();
1899    edje_collection_cache_flush();
1900    eet_clearcache();
1901    EINA_LIST_FOREACH(_elm_win_list, l, obj)
1902      {
1903         Evas *e = evas_object_evas_get(obj);
1904         evas_image_cache_flush(e);
1905         evas_font_cache_flush(e);
1906         evas_render_dump(e);
1907      }
1908 }
1909
1910 /**
1911  * Get the configured cache flush interval time
1912  *
1913  * This gets the globally configured cache flush interval time, in
1914  * ticks
1915  *
1916  * @return The cache flush interval time
1917  * @ingroup Caches
1918  *
1919  * @see elm_all_flush()
1920  */
1921 EAPI int
1922 elm_cache_flush_interval_get(void)
1923 {
1924    return _elm_config->cache_flush_poll_interval;
1925 }
1926
1927 /**
1928  * Set the configured cache flush interval time
1929  *
1930  * This sets the globally configured cache flush interval time, in ticks
1931  *
1932  * @param size The cache flush interval time
1933  * @ingroup Caches
1934  *
1935  * @see elm_all_flush()
1936  */
1937 EAPI void
1938 elm_cache_flush_interval_set(int size)
1939 {
1940    if (_elm_config->cache_flush_poll_interval == size) return;
1941    _elm_config->cache_flush_poll_interval = size;
1942
1943    _elm_recache();
1944 }
1945
1946 /**
1947  * Set the configured cache flush interval time for all applications on the
1948  * display
1949  *
1950  * This sets the globally configured cache flush interval time -- in ticks
1951  * -- for all applications on the display.
1952  *
1953  * @param size The cache flush interval time
1954  * @ingroup Caches
1955  */
1956 EAPI void
1957 elm_cache_flush_interval_all_set(int size)
1958 {
1959 #ifdef HAVE_ELEMENTARY_X
1960    static Ecore_X_Atom atom = 0;
1961    unsigned int size_i = (unsigned int)size;
1962
1963    if (!atom) atom = ecore_x_atom_get("ENLIGHTENMENT_CACHE_FLUSH_INTERVAL");
1964    ecore_x_window_prop_card32_set(ecore_x_window_root_first_get(),
1965                                   atom, &size_i, 1);
1966 #endif
1967 }
1968
1969 /**
1970  * Get the configured cache flush enabled state
1971  *
1972  * This gets the globally configured cache flush state - if it is enabled
1973  * or not. When cache flushing is enabled, elementary will regularly
1974  * (see elm_cache_flush_interval_get() ) flush caches and dump data out of
1975  * memory and allow usage to re-seed caches and data in memory where it
1976  * can do so. An idle application will thus minimise its memory usage as
1977  * data will be freed from memory and not be re-loaded as it is idle and
1978  * not rendering or doing anything graphically right now.
1979  *
1980  * @return The cache flush state
1981  * @ingroup Caches
1982  *
1983  * @see elm_all_flush()
1984  */
1985 EAPI Eina_Bool
1986 elm_cache_flush_enmabled_get(void)
1987 {
1988    return _elm_config->cache_flush_enable;
1989 }
1990
1991 /**
1992  * Set the configured cache flush enabled state
1993  *
1994  * This sets the globally configured cache flush enabled state
1995  *
1996  * @param size The cache flush enabled state
1997  * @ingroup Caches
1998  *
1999  * @see elm_all_flush()
2000  */
2001 EAPI void
2002 elm_cache_flush_enabled_set(Eina_Bool enabled)
2003 {
2004    enabled = !!enabled;
2005    if (_elm_config->cache_flush_enable == enabled) return;
2006    _elm_config->cache_flush_enable = enabled;
2007
2008    _elm_recache();
2009 }
2010
2011 /**
2012  * Set the configured cache flush enabled state for all applications on the
2013  * display
2014  *
2015  * This sets the globally configured cache flush enabled state for all 
2016  * applications on the display.
2017  *
2018  * @param size The cache flush enabled state
2019  * @ingroup Caches
2020  */
2021 EAPI void
2022 elm_cache_flush_enabled_all_set(Eina_Bool enabled)
2023 {
2024 #ifdef HAVE_ELEMENTARY_X
2025    static Ecore_X_Atom atom = 0;
2026    unsigned int enabled_i = (unsigned int)enabled;
2027
2028    if (!atom) atom = ecore_x_atom_get("ENLIGHTENMENT_CACHE_FLUSH_ENABLE");
2029    ecore_x_window_prop_card32_set(ecore_x_window_root_first_get(),
2030                                   atom, &enabled_i, 1);
2031 #endif
2032 }
2033
2034 /**
2035  * Get the configured font cache size
2036  *
2037  * This gets the globally configured font cache size, in bytes
2038  *
2039  * @return The font cache size
2040  * @ingroup Caches
2041  */
2042 EAPI int
2043 elm_font_cache_get(void)
2044 {
2045    return _elm_config->font_cache;
2046 }
2047
2048 /**
2049  * Set the configured font cache size
2050  *
2051  * This sets the globally configured font cache size, in bytes
2052  *
2053  * @param size The font cache size
2054  * @ingroup Caches
2055  */
2056 EAPI void
2057 elm_font_cache_set(int size)
2058 {
2059    if (_elm_config->font_cache == size) return;
2060    _elm_config->font_cache = size;
2061
2062    _elm_recache();
2063 }
2064
2065 /**
2066  * Set the configured font cache size for all applications on the
2067  * display
2068  *
2069  * This sets the globally configured font cache size -- in bytes
2070  * -- for all applications on the display.
2071  *
2072  * @param size The font cache size
2073  * @ingroup Caches
2074  */
2075 EAPI void
2076 elm_font_cache_all_set(int size)
2077 {
2078 #ifdef HAVE_ELEMENTARY_X
2079    static Ecore_X_Atom atom = 0;
2080    unsigned int size_i = (unsigned int)size;
2081
2082    if (!atom) atom = ecore_x_atom_get("ENLIGHTENMENT_FONT_CACHE");
2083    ecore_x_window_prop_card32_set(ecore_x_window_root_first_get(),
2084                                   atom, &size_i, 1);
2085 #endif
2086 }
2087
2088 /**
2089  * Get the configured image cache size
2090  *
2091  * This gets the globally configured image cache size, in bytes
2092  *
2093  * @return The image cache size
2094  * @ingroup Caches
2095  */
2096 EAPI int
2097 elm_image_cache_get(void)
2098 {
2099    return _elm_config->image_cache;
2100 }
2101
2102 /**
2103  * Set the configured image cache size
2104  *
2105  * This sets the globally configured image cache size, in bytes
2106  *
2107  * @param size The image cache size
2108  * @ingroup Caches
2109  */
2110 EAPI void
2111 elm_image_cache_set(int size)
2112 {
2113    if (_elm_config->image_cache == size) return;
2114    _elm_config->image_cache = size;
2115
2116    _elm_recache();
2117 }
2118
2119 /**
2120  * Set the configured image cache size for all applications on the
2121  * display
2122  *
2123  * This sets the globally configured image cache size -- in bytes
2124  * -- for all applications on the display.
2125  *
2126  * @param size The image cache size
2127  * @ingroup Caches
2128  */
2129 EAPI void
2130 elm_image_cache_all_set(int size)
2131 {
2132 #ifdef HAVE_ELEMENTARY_X
2133    static Ecore_X_Atom atom = 0;
2134    unsigned int size_i = (unsigned int)size;
2135
2136    if (!atom) atom = ecore_x_atom_get("ENLIGHTENMENT_IMAGE_CACHE");
2137    ecore_x_window_prop_card32_set(ecore_x_window_root_first_get(),
2138                                   atom, &size_i, 1);
2139 #endif
2140 }
2141
2142 /**
2143  * Get the configured edje file cache size.
2144  *
2145  * This gets the globally configured edje file cache size, in number
2146  * of files.
2147  *
2148  * @return The edje file cache size
2149  * @ingroup Caches
2150  */
2151 EAPI int
2152 elm_edje_file_cache_get(void)
2153 {
2154    return _elm_config->edje_cache;
2155 }
2156
2157 /**
2158  * Set the configured edje file cache size
2159  *
2160  * This sets the globally configured edje file cache size, in number
2161  * of files.
2162  *
2163  * @param size The edje file cache size
2164  * @ingroup Caches
2165  */
2166 EAPI void
2167 elm_edje_file_cache_set(int size)
2168 {
2169    if (_elm_config->edje_cache == size) return;
2170    _elm_config->edje_cache = size;
2171
2172    _elm_recache();
2173 }
2174
2175 /**
2176  * Set the configured edje file cache size for all applications on the
2177  * display
2178  *
2179  * This sets the globally configured edje file cache size -- in number
2180  * of files -- for all applications on the display.
2181  *
2182  * @param size The edje file cache size
2183  * @ingroup Caches
2184  */
2185 EAPI void
2186 elm_edje_file_cache_all_set(int size)
2187 {
2188 #ifdef HAVE_ELEMENTARY_X
2189    static Ecore_X_Atom atom = 0;
2190    unsigned int size_i = (unsigned int)size;
2191
2192    if (!atom) atom = ecore_x_atom_get("ENLIGHTENMENT_EDJE_FILE_CACHE");
2193    ecore_x_window_prop_card32_set(ecore_x_window_root_first_get(),
2194                                   atom, &size_i, 1);
2195 #endif
2196 }
2197
2198 /**
2199  * Get the configured edje collections (groups) cache size.
2200  *
2201  * This gets the globally configured edje collections cache size, in
2202  * number of collections.
2203  *
2204  * @return The edje collections cache size
2205  * @ingroup Caches
2206  */
2207 EAPI int
2208 elm_edje_collection_cache_get(void)
2209 {
2210    return _elm_config->edje_collection_cache;
2211 }
2212
2213 /**
2214  * Set the configured edje collections (groups) cache size
2215  *
2216  * This sets the globally configured edje collections cache size, in
2217  * number of collections.
2218  *
2219  * @param size The edje collections cache size
2220  * @ingroup Caches
2221  */
2222 EAPI void
2223 elm_edje_collection_cache_set(int size)
2224 {
2225    if (_elm_config->edje_collection_cache == size) return;
2226    _elm_config->edje_collection_cache = size;
2227
2228    _elm_recache();
2229 }
2230
2231 /**
2232  * Set the configured edje collections (groups) cache size for all
2233  * applications on the display
2234  *
2235  * This sets the globally configured edje collections cache size -- in
2236  * number of collections -- for all applications on the display.
2237  *
2238  * @param size The edje collections cache size
2239  * @ingroup Caches
2240  */
2241 EAPI void
2242 elm_edje_collection_cache_all_set(int size)
2243 {
2244 #ifdef HAVE_ELEMENTARY_X
2245    static Ecore_X_Atom atom = 0;
2246    unsigned int size_i = (unsigned int)size;
2247
2248    if (!atom) atom = ecore_x_atom_get("ENLIGHTENMENT_EDJE_COLLECTION_CACHE");
2249    ecore_x_window_prop_card32_set(ecore_x_window_root_first_get(),
2250                                   atom, &size_i, 1);
2251 #endif
2252 }
2253
2254 /**
2255  * @defgroup Focus Focus
2256  *
2257  * Objects have focus. This is what determines where the keyboard input goes to
2258  * within the application window.
2259  */
2260
2261 /**
2262  * Get the focus of the object
2263  *
2264  * This gets the focused property of the object.
2265  *
2266  * @param obj The object
2267  * @return 1 if the object is focused, 0 if not.
2268  * @ingroup Focus
2269  */
2270 EAPI Eina_Bool
2271 elm_object_focus_get(const Evas_Object *obj)
2272 {
2273    EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE);
2274    return elm_widget_focus_get(obj);
2275 }
2276
2277 /**
2278  * Set the focus to the object
2279  *
2280  * This sets the focus target for keyboard input to be the object indicated.
2281  *
2282  * @param obj The object
2283  * @ingroup Focus
2284  */
2285 EAPI void
2286 elm_object_focus(Evas_Object *obj)
2287 {
2288    EINA_SAFETY_ON_NULL_RETURN(obj);
2289    if (elm_widget_focus_get(obj))
2290      return;
2291
2292    elm_widget_focus_cycle(obj, ELM_FOCUS_NEXT);
2293 }
2294
2295 /**
2296  * Remove the focus from the object
2297  *
2298  * This removes the focus target for keyboard input from be the object
2299  * indicated.
2300  *
2301  * @param obj The object
2302  * @ingroup Focus
2303  */
2304 EAPI void
2305 elm_object_unfocus(Evas_Object *obj)
2306 {
2307    EINA_SAFETY_ON_NULL_RETURN(obj);
2308    if (!elm_widget_can_focus_get(obj)) return;
2309    elm_widget_focused_object_clear(obj);
2310 }
2311
2312 /**
2313  * Set the ability for the object to focus
2314  *
2315  * This sets the ability for the object to be able to get keyboard focus or
2316  * not. By default all objects are able to be focused.
2317  *
2318  * @param obj The object
2319  * @param enable 1 if the object can be focused, 0 if not
2320  * @ingroup Focus
2321  */
2322 EAPI void
2323 elm_object_focus_allow_set(Evas_Object *obj,
2324                            Eina_Bool    enable)
2325 {
2326    EINA_SAFETY_ON_NULL_RETURN(obj);
2327    elm_widget_can_focus_set(obj, enable);
2328 }
2329
2330 /**
2331  * Get the ability for the object to focus
2332  *
2333  * This gets the ability for the object to be able to get keyboard focus or
2334  * not. By default all objects are able to be focused.
2335  *
2336  * @param obj The object
2337  * @return 1 if the object is allowed to be focused, 0 if not.
2338  * @ingroup Focus
2339  */
2340 EAPI Eina_Bool
2341 elm_object_focus_allow_get(const Evas_Object *obj)
2342 {
2343    EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE);
2344    return (elm_widget_can_focus_get(obj)) || (elm_widget_child_can_focus_get(obj));
2345 }
2346
2347 /**
2348  * Set custom focus chain.
2349  *
2350  * This function i set one new and overwrite any previous custom focus chain
2351  * with the list of objects. The previous list will be deleted and this list
2352  * will be managed. After setted, don't modity it.
2353  *
2354  * @note On focus cycle, only will be evaluated children of this container.
2355  *
2356  * @param obj The container object
2357  * @param objs Chain of objects to pass focus
2358  * @ingroup Focus
2359  */
2360 EAPI void
2361 elm_object_focus_custom_chain_set(Evas_Object *obj,
2362                                   Eina_List   *objs)
2363 {
2364    EINA_SAFETY_ON_NULL_RETURN(obj);
2365    elm_widget_focus_custom_chain_set(obj, objs);
2366 }
2367
2368 /**
2369  * Unset custom focus chain
2370  *
2371  * @param obj The container object
2372  * @ingroup Focus
2373  */
2374 EAPI void
2375 elm_object_focus_custom_chain_unset(Evas_Object *obj)
2376 {
2377    EINA_SAFETY_ON_NULL_RETURN(obj);
2378    elm_widget_focus_custom_chain_unset(obj);
2379 }
2380
2381 /**
2382  * Get custom focus chain
2383  *
2384  * @param obj The container object
2385  * @ingroup Focus
2386  */
2387 EAPI const Eina_List *
2388 elm_object_focus_custom_chain_get(const Evas_Object *obj)
2389 {
2390    EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
2391    return elm_widget_focus_custom_chain_get(obj);
2392 }
2393
2394 /**
2395  * Append object to custom focus chain.
2396  *
2397  * @note If relative_child equal to NULL or not in custom chain, the object
2398  * will be added in end.
2399  *
2400  * @note On focus cycle, only will be evaluated children of this container.
2401  *
2402  * @param obj The container object
2403  * @param child The child to be added in custom chain
2404  * @param relative_child The relative object to position the child
2405  * @ingroup Focus
2406  */
2407 EAPI void
2408 elm_object_focus_custom_chain_append(Evas_Object *obj,
2409                                      Evas_Object *child,
2410                                      Evas_Object *relative_child)
2411 {
2412    EINA_SAFETY_ON_NULL_RETURN(obj);
2413    EINA_SAFETY_ON_NULL_RETURN(child);
2414    elm_widget_focus_custom_chain_append(obj, child, relative_child);
2415 }
2416
2417 /**
2418  * Prepend object to custom focus chain.
2419  *
2420  * @note If relative_child equal to NULL or not in custom chain, the object
2421  * will be added in begin.
2422  *
2423  * @note On focus cycle, only will be evaluated children of this container.
2424  *
2425  * @param obj The container object
2426  * @param child The child to be added in custom chain
2427  * @param relative_child The relative object to position the child
2428  * @ingroup Focus
2429  */
2430 EAPI void
2431 elm_object_focus_custom_chain_prepend(Evas_Object *obj,
2432                                       Evas_Object *child,
2433                                       Evas_Object *relative_child)
2434 {
2435    EINA_SAFETY_ON_NULL_RETURN(obj);
2436    EINA_SAFETY_ON_NULL_RETURN(child);
2437    elm_widget_focus_custom_chain_prepend(obj, child, relative_child);
2438 }
2439
2440 /**
2441  * Give focus to next object in object tree.
2442  *
2443  * Give focus to next object in focus chain of one object sub-tree.
2444  * If the last object of chain already have focus, the focus will go to the
2445  * first object of chain.
2446  *
2447  * @param obj The object root of sub-tree
2448  * @param dir Direction to cycle the focus
2449  *
2450  * @ingroup Focus
2451  */
2452 EAPI void
2453 elm_object_focus_cycle(Evas_Object        *obj,
2454                        Elm_Focus_Direction dir)
2455 {
2456    EINA_SAFETY_ON_NULL_RETURN(obj);
2457    elm_widget_focus_cycle(obj, dir);
2458 }
2459
2460 /**
2461  * Give focus to near object in one direction.
2462  *
2463  * Give focus to near object in direction of one object.
2464  * If none focusable object in given direction, the focus will not change.
2465  *
2466  * @param obj The reference object
2467  * @param x Horizontal component of direction to focus
2468  * @param y Vertical component of direction to focus
2469  *
2470  * @ingroup Focus
2471  */
2472 EAPI void
2473 elm_object_focus_direction_go(Evas_Object *obj,
2474                               int          x,
2475                               int          y)
2476 {
2477    EINA_SAFETY_ON_NULL_RETURN(obj);
2478    elm_widget_focus_direction_go(obj, x, y);
2479 }
2480
2481 /**
2482  * Get the enable status of the focus highlight
2483  *
2484  * This gets whether the highlight on focused objects is enabled or not
2485  * @ingroup Focus
2486  */
2487 EAPI Eina_Bool
2488 elm_focus_highlight_enabled_get(void)
2489 {
2490    return _elm_config->focus_highlight_enable;
2491 }
2492
2493 /**
2494  * Set the enable status of the focus highlight
2495  *
2496  * Set whether to show or not the highlight on focused objects
2497  * @param enable Enable highlight if EINA_TRUE, disable otherwise
2498  * @ingroup Focus
2499  */
2500 EAPI void
2501 elm_focus_highlight_enabled_set(Eina_Bool enable)
2502 {
2503    _elm_config->focus_highlight_enable = !!enable;
2504 }
2505
2506 /**
2507  * Get the enable status of the highlight animation
2508  *
2509  * Get whether the focus highlight, if enabled, will animate its switch from
2510  * one object to the next
2511  * @ingroup Focus
2512  */
2513 EAPI Eina_Bool
2514 elm_focus_highlight_animate_get(void)
2515 {
2516    return _elm_config->focus_highlight_animate;
2517 }
2518
2519 /**
2520  * Set the enable status of the highlight animation
2521  *
2522  * Set whether the focus highlight, if enabled, will animate its switch from
2523  * one object to the next
2524  * @param animate Enable animation if EINA_TRUE, disable otherwise
2525  * @ingroup Focus
2526  */
2527 EAPI void
2528 elm_focus_highlight_animate_set(Eina_Bool animate)
2529 {
2530    _elm_config->focus_highlight_animate = !!animate;
2531 }
2532
2533 /**
2534  * @defgroup Scrolling Scrolling
2535  *
2536  * These are functions setting how scrollable views in Elementary
2537  * widgets should behave on user interaction.
2538  */
2539
2540 /**
2541  * Get whether scrollers should bounce when they reach their
2542  * viewport's edge during a scroll.
2543  *
2544  * @return the thumb scroll bouncing state
2545  *
2546  * This is the default behavior for touch screens, in general.
2547  * @ingroup Scrolling
2548  */
2549 EAPI Eina_Bool
2550 elm_scroll_bounce_enabled_get(void)
2551 {
2552    return _elm_config->thumbscroll_bounce_enable;
2553 }
2554
2555 /**
2556  * Set whether scrollers should bounce when they reach their
2557  * viewport's edge during a scroll.
2558  *
2559  * @param enabled the thumb scroll bouncing state
2560  *
2561  * @see elm_thumbscroll_bounce_enabled_get()
2562  * @ingroup Scrolling
2563  */
2564 EAPI void
2565 elm_scroll_bounce_enabled_set(Eina_Bool enabled)
2566 {
2567    _elm_config->thumbscroll_bounce_enable = enabled;
2568 }
2569
2570 /**
2571  * Set whether scrollers should bounce when they reach their
2572  * viewport's edge during a scroll, for all Elementary application
2573  * windows.
2574  *
2575  * @param enabled the thumb scroll bouncing state
2576  *
2577  * @see elm_thumbscroll_bounce_enabled_get()
2578  * @ingroup Scrolling
2579  */
2580 EAPI void
2581 elm_scroll_bounce_enabled_all_set(Eina_Bool enabled)
2582 {
2583 #ifdef HAVE_ELEMENTARY_X
2584    static Ecore_X_Atom atom = 0;
2585    unsigned int bounce_enable_i = (unsigned int)enabled;
2586
2587    if (!atom)
2588      atom = ecore_x_atom_get("ENLIGHTENMENT_THUMBSCROLL_BOUNCE_ENABLE");
2589    ecore_x_window_prop_card32_set(ecore_x_window_root_first_get(),
2590                                   atom, &bounce_enable_i, 1);
2591 #endif
2592 }
2593
2594 /**
2595  * Get the amount of inertia a scroller will impose at bounce
2596  * animations.
2597  *
2598  * @return the thumb scroll bounce friction
2599  *
2600  * @ingroup Scrolling
2601  */
2602 EAPI double
2603 elm_scroll_bounce_friction_get(void)
2604 {
2605    return _elm_config->thumbscroll_bounce_friction;
2606 }
2607
2608 /**
2609  * Set the amount of inertia a scroller will impose at bounce
2610  * animations.
2611  *
2612  * @param friction the thumb scroll bounce friction
2613  *
2614  * @see elm_thumbscroll_bounce_friction_get()
2615  * @ingroup Scrolling
2616  */
2617 EAPI void
2618 elm_scroll_bounce_friction_set(double friction)
2619 {
2620    _elm_config->thumbscroll_bounce_friction = friction;
2621 }
2622
2623 /**
2624  * Set the amount of inertia a scroller will impose at bounce
2625  * animations, for all Elementary application windows.
2626  *
2627  * @param friction the thumb scroll bounce friction
2628  *
2629  * @see elm_thumbscroll_bounce_friction_get()
2630  * @ingroup Scrolling
2631  */
2632 EAPI void
2633 elm_scroll_bounce_friction_all_set(double friction)
2634 {
2635 #ifdef HAVE_ELEMENTARY_X
2636    static Ecore_X_Atom atom = 0;
2637    unsigned int bounce_friction_i = (unsigned int)(friction * 1000.0);
2638
2639    if (!atom)
2640      atom = ecore_x_atom_get("ENLIGHTENMENT_THUMBSCROLL_BOUNCE_FRICTION");
2641    ecore_x_window_prop_card32_set(ecore_x_window_root_first_get(),
2642                                   atom, &bounce_friction_i, 1);
2643 #endif
2644 }
2645
2646 /**
2647  * Get the amount of inertia a <b>paged</b> scroller will impose at
2648  * page fitting animations.
2649  *
2650  * @return the page scroll friction
2651  *
2652  * @ingroup Scrolling
2653  */
2654 EAPI double
2655 elm_scroll_page_scroll_friction_get(void)
2656 {
2657    return _elm_config->page_scroll_friction;
2658 }
2659
2660 /**
2661  * Set the amount of inertia a <b>paged</b> scroller will impose at
2662  * page fitting animations.
2663  *
2664  * @param friction the page scroll friction
2665  *
2666  * @see elm_thumbscroll_page_scroll_friction_get()
2667  * @ingroup Scrolling
2668  */
2669 EAPI void
2670 elm_scroll_page_scroll_friction_set(double friction)
2671 {
2672    _elm_config->page_scroll_friction = friction;
2673 }
2674
2675 /**
2676  * Set the amount of inertia a <b>paged</b> scroller will impose at
2677  * page fitting animations, for all Elementary application windows.
2678  *
2679  * @param friction the page scroll friction
2680  *
2681  * @see elm_thumbscroll_page_scroll_friction_get()
2682  * @ingroup Scrolling
2683  */
2684 EAPI void
2685 elm_scroll_page_scroll_friction_all_set(double friction)
2686 {
2687 #ifdef HAVE_ELEMENTARY_X
2688    static Ecore_X_Atom atom = 0;
2689    unsigned int page_scroll_friction_i = (unsigned int)(friction * 1000.0);
2690
2691    if (!atom)
2692      atom = ecore_x_atom_get("ENLIGHTENMENT_THUMBSCROLL_PAGE_SCROLL_FRICTION");
2693    ecore_x_window_prop_card32_set(ecore_x_window_root_first_get(),
2694                                   atom, &page_scroll_friction_i, 1);
2695 #endif
2696 }
2697
2698 /**
2699  * Get the amount of inertia a scroller will impose at region bring
2700  * animations.
2701  *
2702  * @return the bring in scroll friction
2703  *
2704  * @ingroup Scrolling
2705  */
2706 EAPI double
2707 elm_scroll_bring_in_scroll_friction_get(void)
2708 {
2709    return _elm_config->bring_in_scroll_friction;
2710 }
2711
2712 /**
2713  * Set the amount of inertia a scroller will impose at region bring
2714  * animations.
2715  *
2716  * @param friction the bring in scroll friction
2717  *
2718  * @see elm_thumbscroll_bring_in_scroll_friction_get()
2719  * @ingroup Scrolling
2720  */
2721 EAPI void
2722 elm_scroll_bring_in_scroll_friction_set(double friction)
2723 {
2724    _elm_config->bring_in_scroll_friction = friction;
2725 }
2726
2727 /**
2728  * Set the amount of inertia a scroller will impose at region bring
2729  * animations, for all Elementary application windows.
2730  *
2731  * @param friction the bring in scroll friction
2732  *
2733  * @see elm_thumbscroll_bring_in_scroll_friction_get()
2734  * @ingroup Scrolling
2735  */
2736 EAPI void
2737 elm_scroll_bring_in_scroll_friction_all_set(double friction)
2738 {
2739 #ifdef HAVE_ELEMENTARY_X
2740    static Ecore_X_Atom atom = 0;
2741    unsigned int bring_in_scroll_friction_i = (unsigned int)(friction * 1000.0);
2742
2743    if (!atom)
2744      atom =
2745        ecore_x_atom_get("ENLIGHTENMENT_THUMBSCROLL_BRING_IN_SCROLL_FRICTION");
2746    ecore_x_window_prop_card32_set(ecore_x_window_root_first_get(),
2747                                   atom, &bring_in_scroll_friction_i, 1);
2748 #endif
2749 }
2750
2751 /**
2752  * Get the amount of inertia scrollers will impose at animations
2753  * triggered by Elementary widgets' zooming API.
2754  *
2755  * @return the zoom friction
2756  *
2757  * @ingroup Scrolling
2758  */
2759 EAPI double
2760 elm_scroll_zoom_friction_get(void)
2761 {
2762    return _elm_config->zoom_friction;
2763 }
2764
2765 /**
2766  * Set the amount of inertia scrollers will impose at animations
2767  * triggered by Elementary widgets' zooming API.
2768  *
2769  * @param friction the zoom friction
2770  *
2771  * @see elm_thumbscroll_zoom_friction_get()
2772  * @ingroup Scrolling
2773  */
2774 EAPI void
2775 elm_scroll_zoom_friction_set(double friction)
2776 {
2777    _elm_config->zoom_friction = friction;
2778 }
2779
2780 /**
2781  * Set the amount of inertia scrollers will impose at animations
2782  * triggered by Elementary widgets' zooming API, for all Elementary
2783  * application windows.
2784  *
2785  * @param friction the zoom friction
2786  *
2787  * @see elm_thumbscroll_zoom_friction_get()
2788  * @ingroup Scrolling
2789  */
2790 EAPI void
2791 elm_scroll_zoom_friction_all_set(double friction)
2792 {
2793 #ifdef HAVE_ELEMENTARY_X
2794    static Ecore_X_Atom atom = 0;
2795    unsigned int zoom_friction_i = (unsigned int)(friction * 1000.0);
2796
2797    if (!atom)
2798      atom = ecore_x_atom_get("ENLIGHTENMENT_THUMBSCROLL_ZOOM_FRICTION");
2799    ecore_x_window_prop_card32_set(ecore_x_window_root_first_get(),
2800                                   atom, &zoom_friction_i, 1);
2801 #endif
2802 }
2803
2804 /**
2805  * Get whether scrollers should be draggable from any point in their
2806  * views.
2807  *
2808  * @return the thumb scroll state
2809  *
2810  * @note This is the default behavior for touch screens, in general.
2811  * @note All other functions namespaced with "thumbscroll" will only
2812  *       have effect if this mode is enabled.
2813  *
2814  * @ingroup Scrolling
2815  */
2816 EAPI Eina_Bool
2817 elm_scroll_thumbscroll_enabled_get(void)
2818 {
2819    return _elm_config->thumbscroll_enable;
2820 }
2821
2822 /**
2823  * Set whether scrollers should be draggable from any point in their
2824  * views.
2825  *
2826  * @param enabled the thumb scroll state
2827  *
2828  * @see elm_thumbscroll_enabled_get()
2829  * @ingroup Scrolling
2830  */
2831 EAPI void
2832 elm_scroll_thumbscroll_enabled_set(Eina_Bool enabled)
2833 {
2834    _elm_config->thumbscroll_enable = enabled;
2835 }
2836
2837 /**
2838  * Set whether scrollers should be draggable from any point in their
2839  * views, for all Elementary application windows.
2840  *
2841  * @param enabled the thumb scroll state
2842  *
2843  * @see elm_thumbscroll_enabled_get()
2844  * @ingroup Scrolling
2845  */
2846 EAPI void
2847 elm_scroll_thumbscroll_enabled_all_set(Eina_Bool enabled)
2848 {
2849 #ifdef HAVE_ELEMENTARY_X
2850    static Ecore_X_Atom atom = 0;
2851    unsigned int ts_enable_i = (unsigned int)enabled;
2852
2853    if (!atom) atom = ecore_x_atom_get("ENLIGHTENMENT_THUMBSCROLL_ENABLE");
2854    ecore_x_window_prop_card32_set(ecore_x_window_root_first_get(),
2855                                   atom, &ts_enable_i, 1);
2856 #endif
2857 }
2858
2859 /**
2860  * Get the number of pixels one should travel while dragging a
2861  * scroller's view to actually trigger scrolling.
2862  *
2863  * @return the thumb scroll threshould
2864  *
2865  * One would use higher values for touch screens, in general, because
2866  * of their inherent imprecision.
2867  * @ingroup Scrolling
2868  */
2869 EAPI unsigned int
2870 elm_scroll_thumbscroll_threshold_get(void)
2871 {
2872    return _elm_config->thumbscroll_threshold;
2873 }
2874
2875 /**
2876  * Set the number of pixels one should travel while dragging a
2877  * scroller's view to actually trigger scrolling.
2878  *
2879  * @param threshold the thumb scroll threshould
2880  *
2881  * @see elm_thumbscroll_threshould_get()
2882  * @ingroup Scrolling
2883  */
2884 EAPI void
2885 elm_scroll_thumbscroll_threshold_set(unsigned int threshold)
2886 {
2887    _elm_config->thumbscroll_threshold = threshold;
2888 }
2889
2890 /**
2891  * Set the number of pixels one should travel while dragging a
2892  * scroller's view to actually trigger scrolling, for all Elementary
2893  * application windows.
2894  *
2895  * @param threshold the thumb scroll threshould
2896  *
2897  * @see elm_thumbscroll_threshould_get()
2898  * @ingroup Scrolling
2899  */
2900 EAPI void
2901 elm_scroll_thumbscroll_threshold_all_set(unsigned int threshold)
2902 {
2903 #ifdef HAVE_ELEMENTARY_X
2904    static Ecore_X_Atom atom = 0;
2905    unsigned int ts_threshold_i = (unsigned int)threshold;
2906
2907    if (!atom) atom = ecore_x_atom_get("ENLIGHTENMENT_THUMBSCROLL_THRESHOLD");
2908    ecore_x_window_prop_card32_set(ecore_x_window_root_first_get(),
2909                                   atom, &ts_threshold_i, 1);
2910 #endif
2911 }
2912
2913 /**
2914  * Get the minimum speed of mouse cursor movement which will trigger
2915  * list self scrolling animation after a mouse up event
2916  * (pixels/second).
2917  *
2918  * @return the thumb scroll momentum threshould
2919  *
2920  * @ingroup Scrolling
2921  */
2922 EAPI double
2923 elm_scroll_thumbscroll_momentum_threshold_get(void)
2924 {
2925    return _elm_config->thumbscroll_momentum_threshold;
2926 }
2927
2928 /**
2929  * Set the minimum speed of mouse cursor movement which will trigger
2930  * list self scrolling animation after a mouse up event
2931  * (pixels/second).
2932  *
2933  * @param threshold the thumb scroll momentum threshould
2934  *
2935  * @see elm_thumbscroll_momentum_threshould_get()
2936  * @ingroup Scrolling
2937  */
2938 EAPI void
2939 elm_scroll_thumbscroll_momentum_threshold_set(double threshold)
2940 {
2941    _elm_config->thumbscroll_momentum_threshold = threshold;
2942 }
2943
2944 /**
2945  * Set the minimum speed of mouse cursor movement which will trigger
2946  * list self scrolling animation after a mouse up event
2947  * (pixels/second), for all Elementary application windows.
2948  *
2949  * @param threshold the thumb scroll momentum threshould
2950  *
2951  * @see elm_thumbscroll_momentum_threshould_get()
2952  * @ingroup Scrolling
2953  */
2954 EAPI void
2955 elm_scroll_thumbscroll_momentum_threshold_all_set(double threshold)
2956 {
2957 #ifdef HAVE_ELEMENTARY_X
2958    static Ecore_X_Atom atom = 0;
2959    unsigned int ts_momentum_threshold_i = (unsigned int)(threshold * 1000.0);
2960
2961    if (!atom)
2962      atom = ecore_x_atom_get("ENLIGHTENMENT_THUMBSCROLL_MOMENTUM_THRESHOLD");
2963    ecore_x_window_prop_card32_set(ecore_x_window_root_first_get(),
2964                                   atom, &ts_momentum_threshold_i, 1);
2965 #endif
2966 }
2967
2968 /**
2969  * Get the amount of inertia a scroller will impose at self scrolling
2970  * animations.
2971  *
2972  * @return the thumb scroll friction
2973  *
2974  * @ingroup Scrolling
2975  */
2976 EAPI double
2977 elm_scroll_thumbscroll_friction_get(void)
2978 {
2979    return _elm_config->thumbscroll_friction;
2980 }
2981
2982 /**
2983  * Set the amount of inertia a scroller will impose at self scrolling
2984  * animations.
2985  *
2986  * @param friction the thumb scroll friction
2987  *
2988  * @see elm_thumbscroll_friction_get()
2989  * @ingroup Scrolling
2990  */
2991 EAPI void
2992 elm_scroll_thumbscroll_friction_set(double friction)
2993 {
2994    _elm_config->thumbscroll_friction = friction;
2995 }
2996
2997 /**
2998  * Set the amount of inertia a scroller will impose at self scrolling
2999  * animations, for all Elementary application windows.
3000  *
3001  * @param friction the thumb scroll friction
3002  *
3003  * @see elm_thumbscroll_friction_get()
3004  * @ingroup Scrolling
3005  */
3006 EAPI void
3007 elm_scroll_thumbscroll_friction_all_set(double friction)
3008 {
3009 #ifdef HAVE_ELEMENTARY_X
3010    static Ecore_X_Atom atom = 0;
3011    unsigned int ts_friction_i = (unsigned int)(friction * 1000.0);
3012
3013    if (!atom) atom = ecore_x_atom_get("ENLIGHTENMENT_THUMBSCROLL_FRICTION");
3014    ecore_x_window_prop_card32_set(ecore_x_window_root_first_get(),
3015                                   atom, &ts_friction_i, 1);
3016 #endif
3017 }
3018
3019 /**
3020  * Get the amount of lag between your actual mouse cursor dragging
3021  * movement and a scroller's view movement itself, while pushing it
3022  * into bounce state manually.
3023  *
3024  * @return the thumb scroll border friction
3025  *
3026  * @ingroup Scrolling
3027  */
3028 EAPI double
3029 elm_scroll_thumbscroll_border_friction_get(void)
3030 {
3031    return _elm_config->thumbscroll_border_friction;
3032 }
3033
3034 /**
3035  * Set the amount of lag between your actual mouse cursor dragging
3036  * movement and a scroller's view movement itself, while pushing it
3037  * into bounce state manually.
3038  *
3039  * @param friction the thumb scroll border friction. @c 0.0 for
3040  *        perfect synchrony between two movements, @c 1.0 for maximum
3041  *        lag.
3042  *
3043  * @see elm_thumbscroll_border_friction_get()
3044  * @note parameter value will get bound to 0.0 - 1.0 interval, always
3045  *
3046  * @ingroup Scrolling
3047  */
3048 EAPI void
3049 elm_scroll_thumbscroll_border_friction_set(double friction)
3050 {
3051    if (friction < 0.0)
3052      friction = 0.0;
3053
3054    if (friction > 1.0)
3055      friction = 1.0;
3056
3057    _elm_config->thumbscroll_friction = friction;
3058 }
3059
3060 /**
3061  * Set the amount of lag between your actual mouse cursor dragging
3062  * movement and a scroller's view movement itself, while pushing it
3063  * into bounce state manually, for all Elementary application windows.
3064  *
3065  * @param friction the thumb scroll border friction. @c 0.0 for
3066  *        perfect synchrony between two movements, @c 1.0 for maximum
3067  *        lag.
3068  *
3069  * @see elm_thumbscroll_border_friction_get()
3070  * @note parameter value will get bound to 0.0 - 1.0 interval, always
3071  *
3072  * @ingroup Scrolling
3073  */
3074 EAPI void
3075 elm_scroll_thumbscroll_border_friction_all_set(double friction)
3076 {
3077    if (friction < 0.0)
3078      friction = 0.0;
3079
3080    if (friction > 1.0)
3081      friction = 1.0;
3082
3083 #ifdef HAVE_ELEMENTARY_X
3084    static Ecore_X_Atom atom = 0;
3085    unsigned int border_friction_i = (unsigned int)(friction * 1000.0);
3086
3087    if (!atom)
3088      atom = ecore_x_atom_get("ENLIGHTENMENT_THUMBSCROLL_BORDER_FRICTION");
3089    ecore_x_window_prop_card32_set(ecore_x_window_root_first_get(),
3090                                   atom, &border_friction_i, 1);
3091 #endif
3092 }
3093
3094 /**
3095  * @defgroup Scrollhints Scrollhints
3096  *
3097  * Objects when inside a scroller can scroll, but this may not always be
3098  * desirable in certain situations. This allows an object to hint to itself
3099  * and parents to "not scroll" in one of 2 ways.
3100  *
3101  * 1. To hold on scrolling. This means just flicking and dragging may no
3102  * longer scroll, but pressing/dragging near an edge of the scroller will
3103  * still scroll. This is automastically used by the entry object when
3104  * selecting text.
3105  * 2. To totally freeze scrolling. This means it stops. until popped/released.
3106  */
3107
3108 /**
3109  * Push the scroll hold by 1
3110  *
3111  * This increments the scroll hold count by one. If it is more than 0 it will
3112  * take effect on the parents of the indicated object.
3113  *
3114  * @param obj The object
3115  * @ingroup Scrollhints
3116  */
3117 EAPI void
3118 elm_object_scroll_hold_push(Evas_Object *obj)
3119 {
3120    EINA_SAFETY_ON_NULL_RETURN(obj);
3121    elm_widget_scroll_hold_push(obj);
3122 }
3123
3124 /**
3125  * Pop the scroll hold by 1
3126  *
3127  * This decrements the scroll hold count by one. If it is more than 0 it will
3128  * take effect on the parents of the indicated object.
3129  *
3130  * @param obj The object
3131  * @ingroup Scrollhints
3132  */
3133 EAPI void
3134 elm_object_scroll_hold_pop(Evas_Object *obj)
3135 {
3136    EINA_SAFETY_ON_NULL_RETURN(obj);
3137    elm_widget_scroll_hold_pop(obj);
3138 }
3139
3140 /**
3141  * Push the scroll freeze by 1
3142  *
3143  * This increments the scroll freeze count by one. If it is more than 0 it will
3144  * take effect on the parents of the indicated object.
3145  *
3146  * @param obj The object
3147  * @ingroup Scrollhints
3148  */
3149 EAPI void
3150 elm_object_scroll_freeze_push(Evas_Object *obj)
3151 {
3152    EINA_SAFETY_ON_NULL_RETURN(obj);
3153    elm_widget_scroll_freeze_push(obj);
3154 }
3155
3156 /**
3157  * Lock the scrolling of the given widget (and thus all parents)
3158  *
3159  * This locks the given object from scrolling in the X axis (and implicitly
3160  * also locks all parent scrollers too from doing the same).
3161  *
3162  * @param obj The object
3163  * @param lock The lock state (1 == locked, 0 == unlocked)
3164  * @ingroup Scrollhints
3165  */
3166 EAPI void
3167 elm_object_scroll_lock_x_set(Evas_Object *obj,
3168                              Eina_Bool    lock)
3169 {
3170    EINA_SAFETY_ON_NULL_RETURN(obj);
3171    elm_widget_drag_lock_x_set(obj, lock);
3172 }
3173
3174 /**
3175  * Lock the scrolling of the given widget (and thus all parents)
3176  *
3177  * This locks the given object from scrolling in the Y axis (and implicitly
3178  * also locks all parent scrollers too from doing the same).
3179  *
3180  * @param obj The object
3181  * @param lock The lock state (1 == locked, 0 == unlocked)
3182  * @ingroup Scrollhints
3183  */
3184 EAPI void
3185 elm_object_scroll_lock_y_set(Evas_Object *obj,
3186                              Eina_Bool    lock)
3187 {
3188    EINA_SAFETY_ON_NULL_RETURN(obj);
3189    elm_widget_drag_lock_y_set(obj, lock);
3190 }
3191
3192 /**
3193  * Get the scrolling lock of the given widget
3194  *
3195  * This gets the lock for X axis scrolling.
3196  *
3197  * @param obj The object
3198  * @ingroup Scrollhints
3199  */
3200 EAPI Eina_Bool
3201 elm_object_scroll_lock_x_get(const Evas_Object *obj)
3202 {
3203    EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE);
3204    return elm_widget_drag_lock_x_get(obj);
3205 }
3206
3207 /**
3208  * Get the scrolling lock of the given widget
3209  *
3210  * This gets the lock for X axis scrolling.
3211  *
3212  * @param obj The object
3213  * @ingroup Scrollhints
3214  */
3215 EAPI Eina_Bool
3216 elm_object_scroll_lock_y_get(const Evas_Object *obj)
3217 {
3218    EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE);
3219    return elm_widget_drag_lock_y_get(obj);
3220 }
3221
3222 /**
3223  * Pop the scroll freeze by 1
3224  *
3225  * This decrements the scroll freeze count by one. If it is more than 0 it will
3226  * take effect on the parents of the indicated object.
3227  *
3228  * @param obj The object
3229  * @ingroup Scrollhints
3230  */
3231 EAPI void
3232 elm_object_scroll_freeze_pop(Evas_Object *obj)
3233 {
3234    EINA_SAFETY_ON_NULL_RETURN(obj);
3235    elm_widget_scroll_freeze_pop(obj);
3236 }
3237
3238 /**
3239  * @defgroup WidgetNavigation Widget Tree Navigation.
3240  *
3241  * How to check if an Evas Object is an Elementary widget? How to get
3242  * the first elementary widget that is parent of the given object?
3243  * These are all covered in widget tree navigation.
3244  */
3245
3246 /**
3247  * Check if the given Evas Object is an Elementary widget.
3248  *
3249  * @param obj the object to query.
3250  * @return @c EINA_TRUE if it is an elementary widget variant,
3251  *         @c EINA_FALSE otherwise
3252  * @ingroup WidgetNavigation
3253  */
3254 EAPI Eina_Bool
3255 elm_object_widget_check(const Evas_Object *obj)
3256 {
3257    EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE);
3258    return elm_widget_is(obj);
3259 }
3260
3261 /**
3262  * Get the first parent of the given object that is an Elementary widget.
3263  *
3264  * @param obj the object to query.
3265  * @return the parent object that is an Elementary widget, or @c NULL
3266  *         if no parent is, or no parents at all.
3267  * @ingroup WidgetNavigation
3268  */
3269 EAPI Evas_Object *
3270 elm_object_parent_widget_get(const Evas_Object *obj)
3271 {
3272    EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
3273    return elm_widget_parent_widget_get(obj);
3274 }
3275
3276 /**
3277  * Get the top level parent of an Elementary widget.
3278  *
3279  * @param obj The object to query.
3280  * @return The top level Elementary widget, or @c NULL if parent cannot be
3281  * found.
3282  * @ingroup WidgetNavigation
3283  */
3284 EAPI Evas_Object *
3285 elm_object_top_widget_get(const Evas_Object *obj)
3286 {
3287    EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
3288    return elm_widget_top_get(obj);
3289 }
3290
3291 /**
3292  * Get the string that represents this Elementary widget.
3293  *
3294  * @note Elementary is weird and exposes itself as a single
3295  *       Evas_Object_Smart_Class of type "elm_widget", so
3296  *       evas_object_type_get() always return that, making debug and
3297  *       language bindings hard. This function tries to mitigate this
3298  *       problem, but the solution is to change Elementary to use
3299  *       proper inheritance.
3300  *
3301  * @param obj the object to query.
3302  * @return Elementary widget name, or @c NULL if not a valid widget.
3303  * @ingroup WidgetNavigation
3304  */
3305 EAPI const char *
3306 elm_object_widget_type_get(const Evas_Object *obj)
3307 {
3308    EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
3309    return elm_widget_type_get(obj);
3310 }
3311
3312 /**
3313  * Send a signal to the widget edje object.
3314  *
3315  * This function sends a signal to the edje object of the obj. An edje program
3316  * can respond to a signal by specifying matching 'signal' and
3317  * 'source' fields.
3318  *
3319  * @param obj The object
3320  * @param emission The signal's name.
3321  * @param source The signal's source.
3322  * @ingroup General
3323  */
3324 EAPI void
3325 elm_object_signal_emit(Evas_Object *obj,
3326                        const char  *emission,
3327                        const char  *source)
3328 {
3329    EINA_SAFETY_ON_NULL_RETURN(obj);
3330    elm_widget_signal_emit(obj, emission, source);
3331 }
3332
3333 /**
3334  * Add a callback for a signal emitted by widget edje object.
3335  *
3336  * This function connects a callback function to a signal emitted by the
3337  * edje object of the obj.
3338  * Globs can occur in either the emission or source name.
3339  *
3340  * @param obj The object
3341  * @param emission The signal's name.
3342  * @param source The signal's source.
3343  * @param func The callback function to be executed when the signal is
3344  * emitted.
3345  * @param data A pointer to data to pass in to the callback function.
3346  * @ingroup General
3347  */
3348 EAPI void 
3349 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)
3350 {
3351     EINA_SAFETY_ON_NULL_RETURN(obj);
3352     EINA_SAFETY_ON_NULL_RETURN(func);
3353     elm_widget_signal_callback_add(obj, emission, source, func, data);
3354 }
3355
3356 /**
3357  * Remove a signal-triggered callback from an widget edje object.
3358  *
3359  * This function removes a callback, previoulsy attached to a signal emitted
3360  * by the edje object of the obj.
3361  * The parameters emission, source and func must match exactly those passed to
3362  * a previous call to elm_object_signal_callback_add(). The data pointer that
3363  * was passed to this call will be returned.
3364  *
3365  * @param obj The object
3366  * @param emission The signal's name.
3367  * @param source The signal's source.
3368  * @param func The callback function to be executed when the signal is
3369  * emitted.
3370  * @return The data pointer
3371  * @ingroup General
3372  */
3373 EAPI void *
3374 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))
3375 {
3376     EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
3377     EINA_SAFETY_ON_NULL_RETURN_VAL(func, NULL);
3378     return elm_widget_signal_callback_del(obj, emission, source, func);
3379 }
3380
3381 /**
3382  * Add a callback for a event emitted by widget or their children.
3383  *
3384  * This function connects a callback function to any key_down key_up event
3385  * emitted by the @p obj or their children.
3386  * This only will be called if no other callback has consumed the event.
3387  * If you want consume the event, and no other get it, func should return
3388  * EINA_TRUE and put EVAS_EVENT_FLAG_ON_HOLD in event_flags.
3389  *
3390  * @warning Accept duplicated callback addition.
3391  *
3392  * @param obj The object
3393  * @param func The callback function to be executed when the event is
3394  * emitted.
3395  * @param data Data to pass in to the callback function.
3396  * @ingroup General
3397  */
3398 EAPI void
3399 elm_object_event_callback_add(Evas_Object *obj, Elm_Event_Cb func, const void *data)
3400 {
3401    EINA_SAFETY_ON_NULL_RETURN(obj);
3402    EINA_SAFETY_ON_NULL_RETURN(func);
3403    elm_widget_event_callback_add(obj, func, data);
3404 }
3405
3406 /**
3407  * Remove a event callback from an widget.
3408  *
3409  * This function removes a callback, previoulsy attached to event emission
3410  * by the @p obj.
3411  * The parameters func and data must match exactly those passed to
3412  * a previous call to elm_object_event_callback_add(). The data pointer that
3413  * was passed to this call will be returned.
3414  *
3415  * @param obj The object
3416  * @param func The callback function to be executed when the event is
3417  * emitted.
3418  * @param data Data to pass in to the callback function.
3419  * @return The data pointer
3420  * @ingroup General
3421  */
3422 EAPI void *
3423 elm_object_event_callback_del(Evas_Object *obj, Elm_Event_Cb func, const void *data)
3424 {
3425    EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
3426    EINA_SAFETY_ON_NULL_RETURN_VAL(func, NULL);
3427    return elm_widget_event_callback_del(obj, func, data);
3428 }
3429
3430
3431 /**
3432  * @defgroup Debug Debug
3433  */
3434
3435 /**
3436  * Print Tree object hierarchy in stdout
3437  *
3438  * @param obj The root object
3439  * @ingroup Debug
3440  */
3441 EAPI void
3442 elm_object_tree_dump(const Evas_Object *top)
3443 {
3444 #ifdef ELM_DEBUG
3445    elm_widget_tree_dump(top);
3446 #else
3447    return;
3448    (void)top;
3449 #endif
3450 }
3451
3452 /**
3453  * Print Elm Objects tree hierarchy in file as dot(graphviz) syntax.
3454  *
3455  * @param obj The root object
3456  * @param file The path of output file
3457  * @ingroup Debug
3458  */
3459 EAPI void
3460 elm_object_tree_dot_dump(const Evas_Object *top,
3461                          const char        *file)
3462 {
3463 #ifdef ELM_DEBUG
3464    FILE *f = fopen(file, "w");
3465    elm_widget_tree_dot_dump(top, f);
3466    fclose(f);
3467 #else
3468    return;
3469    (void)top;
3470    (void)file;
3471 #endif
3472 }
3473
3474 /**
3475  * Set the duration for occuring long press event.
3476  *
3477  * @param lonpress_timeout Timeout for long press event
3478  * @ingroup Longpress
3479  */
3480 EAPI void
3481 elm_longpress_timeout_set(double longpress_timeout)
3482 {
3483    _elm_config->longpress_timeout = longpress_timeout;
3484 }
3485
3486 /**
3487  * Get the duration for occuring long press event.
3488  *
3489  * @return Timeout for long press event
3490  * @ingroup Longpress
3491  */
3492 EAPI double
3493 elm_longpress_timeout_get(void)
3494 {
3495    return _elm_config->longpress_timeout;
3496 }