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