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