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