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