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