[elm main] bug fix - wrong order in calling elm module and loading env. variables...
[framework/uifw/elementary.git] / src / lib / elm_main.c
1 #ifdef HAVE_CONFIG_H
2 # include "elementary_config.h"
3 #endif
4
5 #ifndef _GNU_SOURCE
6 # define _GNU_SOURCE
7 #endif
8
9 #include <dlfcn.h>      /* dlopen,dlclose,etc */
10
11 #ifdef HAVE_CRT_EXTERNS_H
12 # include <crt_externs.h>
13 #endif
14
15 #ifdef HAVE_EVIL
16 # include <Evil.h>
17 #endif
18
19 #include <Elementary.h>
20 #include "elm_priv.h"
21
22 #define SEMI_BROKEN_QUICKLAUNCH 1
23
24 static Elm_Version _version = { VMAJ, VMIN, VMIC, VREV };
25 EAPI Elm_Version *elm_version = &_version;
26 /**
27  * @defgroup Main Main
28  * @ingroup Elementary
29  *
30  * This group includes functions of elm_main.c
31  */
32
33
34 Eina_Bool
35 _elm_dangerous_call_check(const char *call)
36 {
37    char buf[256];
38    const char *eval;
39    
40    snprintf(buf, sizeof(buf), "%i.%i.%i.%i", VMAJ, VMIN, VMIC, VREV);
41    eval = getenv("ELM_NO_FINGER_WAGGLING");
42    if ((eval) && (!strcmp(eval, buf)))
43      return 0;
44    printf("ELEMENTARY FINGER WAGGLE!!!!!!!!!!\n"
45           "\n"
46           "  %s() used.\n"
47           "PLEASE see the API documentation for this function. This call\n"
48           "should almost never be used. Only in very special cases.\n"
49           "\n"
50           "To remove this warning please set the environment variable:\n"
51           "  ELM_NO_FINGER_WAGGLING\n"
52           "To the value of the Elementary version + revision number. e.g.:\n"
53           "  1.2.5.40295\n"
54           "\n"
55           ,
56           call);
57    return 1;
58 }
59
60 /**
61  * @defgroup Start Getting Started
62  * @ingroup Main
63  *
64  * To write an Elementary app, you can get started with the following:
65  *
66  * @code
67  * #include <Elementary.h>
68  * #ifndef ELM_LIB_QUICKLAUNCH
69  * EAPI int
70  * elm_main(int argc, char **argv)
71  * {
72  *    // create window(s) here and do any application init
73  *    elm_run(); // run main loop
74  *    elm_shutdown(); // after mainloop finishes running, shutdown
75  *    return 0; // exit 0 for exit code
76  * }
77  * #endif
78  * ELM_MAIN()
79  * @endcode
80  *
81  * To take full advantage of the quicklaunch architecture for launching
82  * processes as quickly as possible (saving time at startup time like
83  * connecting to X11, loading and linking shared libraries) you may want to
84  * use the following configure.in/configure.ac and Makefile.am and autogen.sh
85  * script to generate your files. It is assumed your application uses the
86  * main.c file for its code.
87  *
88  * configure.in/configure.ac:
89  *
90 @verbatim
91 AC_INIT(myapp, 0.0.0, myname@mydomain.com)
92 AC_PREREQ(2.52)
93 AC_CONFIG_SRCDIR(configure.in)
94
95 AM_INIT_AUTOMAKE(1.6 dist-bzip2)
96 AM_CONFIG_HEADER(config.h)
97
98 AC_C_BIGENDIAN
99 AC_ISC_POSIX
100 AC_PROG_CC
101 AM_PROG_CC_STDC
102 AC_HEADER_STDC
103 AC_C_CONST
104
105 AC_LIBTOOL_WIN32_DLL
106 define([AC_LIBTOOL_LANG_CXX_CONFIG], [:])dnl
107 define([AC_LIBTOOL_LANG_F77_CONFIG], [:])dnl
108 AC_PROG_LIBTOOL
109
110 PKG_CHECK_MODULES([ELEMENTARY], elementary)
111
112 AC_OUTPUT(Makefile)
113 @endverbatim
114  *
115  * Makefile.am:
116  *
117 @verbatim
118 AUTOMAKE_OPTIONS     = 1.4 foreign
119 MAINTAINERCLEANFILES = Makefile.in
120
121 INCLUDES = -I$(top_srcdir) @ELEMENTARY_CFLAGS@
122
123 bin_PROGRAMS      = myapp
124 myapp_LTLIBRARIES = myapp.la
125
126 myappdir = $(libdir)
127
128 myapp_la_SOURCES = main.c
129 myapp_la_LIBADD = @ELEMENTARY_LIBS@
130 myapp_la_CFLAGS =
131 myapp_la_LDFLAGS = -module -avoid-version -no-undefined
132
133 myapp_SOURCES = main.c
134 myapp_LDADD = @ELEMENTARY_LIBS@
135 myapp_CFLAGS = -DELM_LIB_QUICKLAUNCH=1
136 @endverbatim
137  *
138  * autogen.sh:
139  *
140 @verbatim
141 #!/bin/sh
142 rm -rf autom4te.cache
143 rm -f aclocal.m4 ltmain.sh
144 rm -rf m4
145 mkdir m4
146
147 touch README
148 echo "Running aclocal..." ; aclocal $ACLOCAL_FLAGS -I m4 || exit 1
149 echo "Running autoheader..." ; autoheader || exit 1
150 echo "Running autoconf..." ; autoconf || exit 1
151 echo "Running libtoolize..." ; (libtoolize --copy --automake || glibtoolize --automake) || exit 1
152 echo "Running automake..." ; automake --add-missing --copy --gnu || exit 1
153
154 if [ -z "$NOCONFIGURE" ]; then
155   ./configure "$@"
156 fi
157 @endverbatim
158  *
159  * To gnerate all the things needed to bootstrap just run:
160  *
161 @verbatim
162 ./autogen.sh
163 @endverbatim
164  *
165  * This will generate Makefile.in's, the confgure script and everything else.
166  * After this it works like all normal autotools projects:
167 @verbatim
168 ./configure
169 make
170 sudo make install
171 @endverbatim
172  *
173  * Note sudo was assumed to get root permissions, as this would install in
174  * /usr/local which is system-owned. Ue any way you like to gain root, or
175  * specify a different prefix with configure:
176  *
177 @verbatim
178 ./confiugre --prefix=$HOME/mysoftware
179 @endverbatim
180  *
181  * Also remember that autotools buys you some useful commands like:
182 @verbatim
183 make uninstall
184 @endverbatim
185  *
186  * This uninstalls the software after it was installed with "make install".
187  * It is very useful to clear up what you built if you wish to clean the
188  * system.
189  *
190 @verbatim
191 make distcheck
192 @endverbatim
193  *
194  * This firstly checks if your build tree is "clean" and ready for
195  * distribution. It also builds a tarball (myapp-0.0.0.tar.gz) that is
196  * ready to upload and distribute to the world, that contains the generated
197  * Makefile.in's and configure script. The users do not need to run
198  * autogen.sh - just configure and on. They don't need autotools installed.
199  * This tarball also builds cleanly, has all the sources it needs to build
200  * included (that is sources for your application, not libraries it depends
201  * on like Elementary). It builds cleanly in a buildroot and does not
202  * contain any files that are temporarily generated like binaries and other
203  * build-gnerated files, so the tarball is clean, and no need to worry
204  * about cleaning up your tree before packaging.
205  *
206 @verbatim
207 make clean
208 @endverbatim
209  *
210  * This cleans up all build files (binaries, objects etc.) from the tree.
211  *
212 @verbatim
213 make distclean
214 @endverbatim
215  *
216  * This cleans out all files from the build and from configure's output too.
217  *
218 @verbatim
219 make maintainer-clean
220 @endverbatim
221  *
222  * This deletes all the files autogen.sh will produce so the tree is clean
223  * to be put into a revision-control system (like CVS, SVN or GIT for example).
224  *
225  * The above will build a library - libmyapp.so and install in the target
226  * library directory (default is /usr/local/lib). You will also get a
227  * myapp.a and myapp.la - these are useless and can be deleted. Libtool likes
228  * to generate these all the time. You will also get a binary in the target
229  * binary directory (default is /usr/local/bin). This is a "debug binary".
230  * This will run and dlopen() the myapp.so and then jump to it's elm_main
231  * function. This allows for easy debugging with GDB and Valgrind. When you
232  * are ready to go to production do the following:
233  *
234  * 1. delete the myapp binary. i.e. rm /usr/local/bin/myapp
235  *
236  * 2. symlink the myapp binary to elementary_run (supplied by elementary).
237  * i.e. ln -s elmentary_run /usr/local/bin/myapp
238  *
239  * 3. run elementary_quicklaunch as part of your graphical login session and
240  * keep it running.
241  *
242  * This will man elementary_quicklaunch does pre-initialization before the
243  * application needs to be run, saving the effort at the time the application
244  * is needed, thus speeding up the time it takes to appear.
245  *
246  * If you don't want to use the quicklaunch infrastructure (which is
247  * optional), you can execute the old fashioned way by just running the
248  * myapp binary loader than will load the myapp.so for you, or you can
249  * remove the split-file binary and put it into one binary as things always
250  * have been with the following configure.in/configure.ac and Makfile.am
251  * files:
252  *
253  * configure.in/configure.ac:
254  *
255 @verbatim
256 AC_INIT(myapp, 0.0.0, myname@mydomain.com)
257 AC_PREREQ(2.52)
258 AC_CONFIG_SRCDIR(configure.in)
259
260 AM_INIT_AUTOMAKE(1.6 dist-bzip2)
261 AM_CONFIG_HEADER(config.h)
262
263 AC_C_BIGENDIAN
264 AC_ISC_POSIX
265 AC_PROG_CC
266 AM_PROG_CC_STDC
267 AC_HEADER_STDC
268 AC_C_CONST
269
270 PKG_CHECK_MODULES([ELEMENTARY], elementary)
271
272 AC_OUTPUT(Makefile)
273 @endverbatim
274  *
275  * Makefile.am:
276  *
277 @verbatim
278 AUTOMAKE_OPTIONS     = 1.4 foreign
279 MAINTAINERCLEANFILES = Makefile.in
280
281 INCLUDES = -I$(top_srcdir) @ELEMENTARY_CFLAGS@
282
283 bin_PROGRAMS      = myapp
284
285 myapp_SOURCES = main.c
286 myapp_LDADD = @ELEMENTARY_LIBS@
287 myapp_CFLAGS =
288 @endverbatim
289  *
290  * Notice that they are the same as before, just with libtool and library
291  * building sections removed. Both ways work for building elementary
292  * applications. It is up to you to decide what is best for you. If you just
293  * follow the template above, you can do it both ways and can decide at build
294  * time. The more advanced of you may suggest making it a configure option.
295  * That is perfectly valid, but has been left out here for simplicity, as our
296  * aim to have an Elementary (and EFL) tutorial, not an autoconf & automake
297  * document.
298  *
299  */
300
301 static Eina_Bool _elm_signal_exit(void *data, int ev_type, void *ev);
302
303 char *_elm_appname = NULL;
304 const char *_elm_data_dir = NULL;
305 const char *_elm_lib_dir = NULL;
306 int _elm_log_dom = -1;
307
308 EAPI int ELM_EVENT_POLICY_CHANGED = 0;
309
310 static int _elm_init_count = 0;
311 static int _elm_sub_init_count = 0;  
312 static int _elm_ql_init_count = 0; 
313 static int _elm_policies[ELM_POLICY_LAST];
314 static Ecore_Event_Handler *_elm_exit_handler = NULL;
315 static Eina_Bool quicklaunch_on = 0;
316
317 static Eina_Bool
318 _elm_signal_exit(void *data __UNUSED__, int ev_type __UNUSED__, void *ev __UNUSED__)
319 {
320    elm_exit();
321    return ECORE_CALLBACK_PASS_ON;
322 }
323
324 void
325 _elm_rescale(void)
326 {
327    edje_scale_set(_elm_config->scale);
328    _elm_win_rescale();
329 }
330
331 static Eina_List *widtypes = NULL;
332
333 void
334 _elm_widtype_register(const char **ptr)
335 {
336    widtypes = eina_list_append(widtypes, (void *)ptr);
337 }
338
339 static void
340 _elm_widtype_clear(void)
341 {
342    const char **ptr;
343    
344    EINA_LIST_FREE(widtypes, ptr)
345      {
346         eina_stringshare_del(*ptr);
347         *ptr = NULL;
348      }
349 }
350
351 /**
352  * @defgroup General General
353  * @ingroup Main
354  */
355
356 /**
357  * Inititalise Elementary
358  *
359  * @return The init counter value.
360  * 
361  * This call is exported only for use by the ELM_MAIN() macro. There is no
362  * need to use this if you use this macro (which is highly advisable).
363  * @ingroup General
364  */
365 EAPI int
366 elm_init(int argc, char **argv)
367 {
368    _elm_init_count++;
369    if (_elm_init_count > 1) return _elm_init_count;
370    elm_quicklaunch_init(argc, argv);
371    elm_quicklaunch_sub_init(argc, argv);
372    return _elm_init_count;
373 }
374
375 /**
376  * Shut down Elementary
377  *
378  * This should be called at the end of your application just before it ceases
379  * to do any more processing. This will clean up any permanent resources your
380  * application may have allocated via Elementary that would otherwise persist
381  * on an exit without this call.
382  * @ingroup General
383  */
384 EAPI int
385 elm_shutdown(void)
386 {
387    _elm_init_count--;
388    if (_elm_init_count > 0) return _elm_init_count;   
389    elm_quicklaunch_sub_shutdown();
390    elm_quicklaunch_shutdown();
391    return _elm_init_count;
392 }
393
394 #ifdef ELM_EDBUS
395 static Eina_Bool _elm_need_e_dbus = EINA_FALSE;
396 #endif
397 EAPI void
398 elm_need_e_dbus(void)
399 {
400 #ifdef ELM_EDBUS
401    if (_elm_need_e_dbus) return;
402    _elm_need_e_dbus = 1;
403    e_dbus_init();
404    e_hal_init();
405 #endif   
406 }
407
408 static void
409 _elm_unneed_e_dbus(void)
410 {
411 #ifdef ELM_EDBUS
412    if (_elm_need_e_dbus)
413      {
414         _elm_need_e_dbus = 0;
415         e_hal_shutdown();
416         e_dbus_shutdown();
417      }
418 #endif   
419 }
420
421 #ifdef ELM_EFREET
422 static Eina_Bool _elm_need_efreet = EINA_FALSE;
423 #endif
424 EAPI void
425 elm_need_efreet(void)
426 {
427 #ifdef ELM_EFREET
428    if (_elm_need_efreet) return;
429    _elm_need_efreet = 1;
430    efreet_init();
431    efreet_mime_init();
432    efreet_trash_init();
433    /*
434      {
435         Eina_List **list;
436         
437         list = efreet_icon_extra_list_get();
438         if (list)
439           {
440              e_user_dir_concat_static(buf, "icons");
441              *list = eina_list_prepend(*list, (void *)eina_stringshare_add(buf));
442              e_prefix_data_concat_static(buf, "data/icons");
443              *list = eina_list_prepend(*list, (void *)eina_stringshare_add(buf));
444           }
445      }
446    */
447 #endif
448 }
449
450 static void
451 _elm_unneed_efreet(void)
452 {
453 #ifdef ELM_EFREET
454    if (_elm_need_efreet)
455      {
456         _elm_need_efreet = 0;
457         efreet_trash_shutdown();
458         efreet_mime_shutdown();
459         efreet_shutdown();
460      }
461 #endif   
462 }
463
464 EAPI void  
465 elm_quicklaunch_mode_set(Eina_Bool ql_on)  
466 {  
467    quicklaunch_on = ql_on;  
468 }
469
470 EAPI int
471 elm_quicklaunch_init(int argc, char **argv)
472 {
473    char buf[PATH_MAX], *s;
474    
475    _elm_ql_init_count++;  
476    if (_elm_ql_init_count > 1) return _elm_ql_init_count;
477    eina_init();
478    _elm_log_dom = eina_log_domain_register("elementary", EINA_COLOR_LIGHTBLUE);
479    if (!_elm_log_dom)
480      {
481    EINA_LOG_ERR("could not register elementary log domain.");
482    _elm_log_dom = EINA_LOG_DOMAIN_GLOBAL;
483      }
484
485    eet_init();
486    ecore_init();
487    ecore_app_args_set(argc, (const char **)argv);
488
489    memset(_elm_policies, 0, sizeof(_elm_policies));
490    if (ELM_EVENT_POLICY_CHANGED == 0)
491      ELM_EVENT_POLICY_CHANGED = ecore_event_type_new();
492
493    ecore_file_init();
494
495    _elm_exit_handler = ecore_event_handler_add(ECORE_EVENT_SIGNAL_EXIT, _elm_signal_exit, NULL);
496
497    if (argv) _elm_appname = strdup(ecore_file_file_get(argv[0]));
498
499    if (!_elm_data_dir)
500      {
501    s = getenv("ELM_DATA_DIR");
502    _elm_data_dir = eina_stringshare_add(s);
503      }
504    if (!_elm_data_dir)
505      {
506    s = getenv("ELM_PREFIX");
507    if (s)
508      {
509         snprintf(buf, sizeof(buf), "%s/share/elementary", s);
510         _elm_data_dir = eina_stringshare_add(buf);
511      }
512      }
513    if (!_elm_lib_dir)
514      {
515    s = getenv("ELM_LIB_DIR");
516    _elm_lib_dir = eina_stringshare_add(s);
517      }
518    if (!_elm_lib_dir)
519      {
520    s = getenv("ELM_PREFIX");
521    if (s)
522      {
523         snprintf(buf, sizeof(buf), "%s/lib", s);
524         _elm_lib_dir = eina_stringshare_add(buf);
525      }
526      }
527 #ifdef HAVE_DLADDR
528    if ((!_elm_data_dir) || (!_elm_lib_dir))
529      {
530    Dl_info elementary_dl;
531    // libelementary.so/../../share/elementary/
532    if (dladdr(elm_init, &elementary_dl))
533      {
534         char *dir, *dir2;
535
536         dir = ecore_file_dir_get(elementary_dl.dli_fname);
537         if (dir)
538           {
539                   if (!_elm_lib_dir)
540                     {
541                        if (ecore_file_is_dir(dir))
542                          _elm_lib_dir = eina_stringshare_add(dir);
543                     }
544                   if (!_elm_data_dir)
545                     {
546                        dir2 = ecore_file_dir_get(dir);
547                        if (dir2)
548                          {
549                             snprintf(buf, sizeof(buf), "%s/share/elementary", dir2);
550                             if (ecore_file_is_dir(buf))
551                               _elm_data_dir = eina_stringshare_add(buf);
552                             free(dir2);
553                          }
554                     }
555         free(dir);
556           }
557      }
558      }
559 #endif
560    if (!_elm_data_dir)
561      _elm_data_dir = eina_stringshare_add(PACKAGE_DATA_DIR);
562   if (!_elm_data_dir)
563      _elm_data_dir = eina_stringshare_add("/");
564    if (!_elm_lib_dir)
565      _elm_lib_dir = eina_stringshare_add(PACKAGE_LIB_DIR);
566    if (!_elm_lib_dir)
567      _elm_lib_dir = eina_stringshare_add("/");
568
569    _elm_config_init();
570    return _elm_ql_init_count;
571 }
572
573 EAPI int
574 elm_quicklaunch_sub_init(int argc, char **argv)
575 {
576    _elm_sub_init_count++;  
577    if (_elm_sub_init_count > 1) return _elm_sub_init_count;  
578    if (quicklaunch_on)  
579      {  
580 #ifdef SEMI_BROKEN_QUICKLAUNCH  
581         return _elm_sub_init_count;  
582 #endif  
583      }  
584    if (!quicklaunch_on)  
585      {  
586         ecore_app_args_set(argc, (const char **)argv);  
587         evas_init();  
588         edje_init();  
589         _elm_module_init();  
590         _elm_config_sub_init();  
591         if ((_elm_config->engine == ELM_SOFTWARE_X11) ||  
592             (_elm_config->engine == ELM_SOFTWARE_16_X11) ||  
593             (_elm_config->engine == ELM_XRENDER_X11) ||  
594             (_elm_config->engine == ELM_OPENGL_X11))  
595           {              
596 #ifdef HAVE_ELEMENTARY_X  
597              ecore_x_init(NULL);  
598 #endif  
599           }  
600         ecore_evas_init(); // FIXME: check errors  
601         ecore_imf_init();  
602
603      }    
604    return _elm_sub_init_count;      
605 }
606
607 EAPI int
608 elm_quicklaunch_sub_shutdown(void)
609 {
610    _elm_sub_init_count--;  
611    if (_elm_sub_init_count > 0) return _elm_sub_init_count;  
612    if (quicklaunch_on)  
613      {  
614 #ifdef SEMI_BROKEN_QUICKLAUNCH  
615         return _elm_sub_init_count;  
616 #endif  
617      }  
618    if (!quicklaunch_on)  
619      {  
620         _elm_win_shutdown();  
621         _elm_module_shutdown();  
622         ecore_imf_shutdown();  
623         ecore_evas_shutdown();  
624         if ((_elm_config->engine == ELM_SOFTWARE_X11) ||  
625             (_elm_config->engine == ELM_SOFTWARE_16_X11) ||  
626             (_elm_config->engine == ELM_XRENDER_X11) ||  
627             (_elm_config->engine == ELM_OPENGL_X11))  
628           {                                                                      
629 #ifdef HAVE_ELEMENTARY_X
630              ecore_x_disconnect();  
631 #endif  
632           }  
633         if ((_elm_config->engine == ELM_SOFTWARE_X11) ||  
634             (_elm_config->engine == ELM_SOFTWARE_16_X11) ||  
635             (_elm_config->engine == ELM_XRENDER_X11) ||  
636             (_elm_config->engine == ELM_OPENGL_X11) ||  
637             (_elm_config->engine == ELM_SOFTWARE_SDL) ||  
638             (_elm_config->engine == ELM_SOFTWARE_16_SDL) ||  
639             (_elm_config->engine == ELM_OPENGL_SDL) ||  
640             (_elm_config->engine == ELM_SOFTWARE_WIN32) ||  
641             (_elm_config->engine == ELM_SOFTWARE_16_WINCE))  
642            evas_cserve_disconnect();  
643         edje_shutdown();  
644         evas_shutdown();  
645      }                 
646    return _elm_sub_init_count;   
647 }
648
649 EAPI int
650 elm_quicklaunch_shutdown(void)
651 {
652    _elm_ql_init_count--;  
653    if (_elm_ql_init_count > 0) return _elm_ql_init_count; 
654    eina_stringshare_del(_elm_data_dir);
655    _elm_data_dir = NULL;
656    eina_stringshare_del(_elm_lib_dir);
657    _elm_lib_dir = NULL;
658
659    free(_elm_appname);
660    _elm_appname = NULL;
661    
662    _elm_config_shutdown();
663    
664    ecore_event_handler_del(_elm_exit_handler);
665    _elm_exit_handler = NULL;
666
667    _elm_theme_shutdown();
668    _elm_unneed_efreet();
669    _elm_unneed_e_dbus();
670    _elm_unneed_ethumb();
671    ecore_file_shutdown();
672    ecore_shutdown();
673    eet_shutdown();
674
675    if ((_elm_log_dom > -1) && (_elm_log_dom != EINA_LOG_DOMAIN_GLOBAL))
676      {
677    eina_log_domain_unregister(_elm_log_dom);
678    _elm_log_dom = -1;
679      }
680
681    _elm_widtype_clear();
682    
683    eina_shutdown();
684    return _elm_ql_init_count;
685 }
686
687 EAPI void
688 elm_quicklaunch_seed(void)
689 {
690 #ifndef SEMI_BROKEN_QUICKLAUNCH    
691    if (quicklaunch_on)  
692      {  
693          Evas_Object *win, *bg, *bt;  
694            
695          win = elm_win_add(NULL, "seed", ELM_WIN_BASIC);  
696          bg = elm_bg_add(win);  
697          elm_win_resize_object_add(win, bg);  
698          evas_object_show(bg);  
699          bt = elm_button_add(win);  
700          elm_button_label_set(bt, " abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789~-_=+\\|]}[{;:'\",<.>/?");  
701          elm_win_resize_object_add(win, bt);  
702          ecore_main_loop_iterate();  
703          evas_object_del(win);  
704          ecore_main_loop_iterate();  
705          if ((_elm_config->engine == ELM_SOFTWARE_X11) ||  
706              (_elm_config->engine == ELM_SOFTWARE_16_X11) ||  
707              (_elm_config->engine == ELM_XRENDER_X11) ||  
708              (_elm_config->engine == ELM_OPENGL_X11))  
709            {  
710 # ifdef HAVE_ELEMENTARY_X  
711               ecore_x_sync();  
712 # endif  
713            }  
714          ecore_main_loop_iterate();  
715      }                                                                        
716 #endif
717 }
718
719 static void *qr_handle = NULL;
720 static int (*qr_main) (int argc, char **argv) = NULL;
721
722 EAPI Eina_Bool
723 elm_quicklaunch_prepare(int argc __UNUSED__, char **argv)
724 {
725 #ifdef HAVE_FORK
726    char *exe = elm_quicklaunch_exe_path_get(argv[0]);
727    if (!exe)
728      {
729    ERR("requested quicklaunch binary '%s' does not exist\n", argv[0]);
730    return EINA_FALSE;
731      }
732    else
733      {
734    char *exe2, *p;
735    char *exename;
736
737    exe2 = malloc(strlen(exe) + 1 + 10);
738    strcpy(exe2, exe);
739    p = strrchr(exe2, '/');
740    if (p) p++;
741    else p = exe2;
742    exename = alloca(strlen(p) + 1);
743    strcpy(exename, p);
744    *p = 0;
745    strcat(p, "../lib/");
746    strcat(p, exename);
747    strcat(p, ".so");
748    if (access(exe2, R_OK | X_OK) == 0)
749      {
750         free(exe);
751         exe = exe2;
752      }
753    else
754      free(exe2);
755      }
756    qr_handle = dlopen(exe, RTLD_NOW | RTLD_GLOBAL);
757    if (!qr_handle)
758      {
759         fprintf(stderr, "dlerr: %s\n", dlerror());
760    WRN("dlopen('%s') failed: %s", exe, dlerror());
761    free(exe);
762    return EINA_FALSE;
763      }
764    INF("dlopen('%s') = %p", exe, qr_handle);
765    free(exe);
766    qr_main = dlsym(qr_handle, "elm_main");
767    INF("dlsym(%p, 'elm_main') = %p", qr_handle, qr_main);
768    if (!qr_main)
769      {
770    WRN("not quicklauncher capable: no elm_main in '%s'", exe);
771    dlclose(qr_handle);
772    qr_handle = NULL;
773    return EINA_FALSE;
774      }
775    return EINA_TRUE;
776 #else
777    return EINA_FALSE;
778 #endif
779 }
780
781 #ifdef HAVE_FORK
782 static void
783 save_env(void)
784 {
785    int i, size;
786    extern char **environ;
787    char **oldenv, **p;
788
789    oldenv = environ;
790
791    for (i = 0, size = 0; environ[i]; i++)
792      size += strlen(environ[i]) + 1;
793
794    p = malloc((i + 1) * sizeof(char *));
795    if (!p) return;
796
797    environ = p;
798
799    for (i = 0; oldenv[i]; i++)
800      environ[i] = strdup(oldenv[i]);
801    environ[i] = NULL;
802 }
803 #endif
804
805 EAPI Eina_Bool
806 elm_quicklaunch_fork(int argc, char **argv, char *cwd, void (postfork_func) (void *data), 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         if ((_elm_config->engine == ELM_SOFTWARE_X11) ||  
856             (_elm_config->engine == ELM_SOFTWARE_16_X11) ||  
857             (_elm_config->engine == ELM_XRENDER_X11) ||  
858             (_elm_config->engine == ELM_OPENGL_X11))  
859           {  
860 # ifdef HAVE_ELEMENTARY_X  
861              ecore_x_init(NULL);  
862 # endif  
863           }  
864         ecore_evas_init(); // FIXME: check errors  
865         ecore_imf_init();  
866         _elm_module_init();  
867 #endif  
868      }                                                       
869    
870    setsid();
871    if (chdir(cwd) != 0)
872      perror("could not chdir");
873    // FIXME: this is very linux specific. it changes argv[0] of the process
874    // so ps etc. report what you'd expect. for other unixes and os's this
875    // may just not work
876    save_env();
877    if (argv)
878      {
879    char *lastarg, *p;
880
881    ecore_app_args_get(&real_argc, &real_argv);
882    lastarg = real_argv[real_argc - 1] + strlen(real_argv[real_argc - 1]);
883    for (p = real_argv[0]; p < lastarg; p++) *p = 0;
884    strcpy(real_argv[0], argv[0]);
885      }
886    ecore_app_args_set(argc, (const char **)argv);
887    ret = qr_main(argc, argv);
888    exit(ret);
889    return EINA_TRUE;
890 #else
891    return EINA_FALSE;
892 #endif
893 }
894
895 EAPI void
896 elm_quicklaunch_cleanup(void)
897 {
898 #ifdef HAVE_FORK
899    if (qr_handle)
900      {
901    dlclose(qr_handle);
902    qr_handle = NULL;
903    qr_main = NULL;
904      }
905 #endif
906 }
907
908 EAPI int
909 elm_quicklaunch_fallback(int argc, char **argv)
910 {
911    int ret;
912    elm_quicklaunch_init(argc, argv);
913    elm_quicklaunch_sub_init(argc, argv);
914    elm_quicklaunch_prepare(argc, argv);
915    ret = qr_main(argc, argv);
916    exit(ret);
917    return ret;
918 }
919
920 EAPI char *
921 elm_quicklaunch_exe_path_get(const char *exe)
922 {
923    static char *path = NULL;
924    static Eina_List *pathlist = NULL;
925    const char *pathitr;
926    const Eina_List *l;
927    char buf[PATH_MAX];
928    if (exe[0] == '/') return strdup(exe);
929    if ((exe[0] == '.') && (exe[1] == '/')) return strdup(exe);
930    if ((exe[0] == '.') && (exe[1] == '.') && (exe[2] == '/')) return strdup(exe);
931    if (!path)
932      {
933    const char *p, *pp;
934    char *buf2;
935    path = getenv("PATH");
936    buf2 = alloca(strlen(path) + 1);
937    p = path;
938    pp = p;
939    for (;;)
940      {
941         if ((*p == ':') || (*p == 0))
942           {
943         int len;
944
945         len = p - pp;
946         strncpy(buf2, pp, len);
947         buf2[len] = 0;
948         pathlist = eina_list_append(pathlist, eina_stringshare_add(buf2));
949         if (*p == 0) break;
950         p++;
951         pp = p;
952           }
953         else
954           {
955         if (*p == 0) break;
956         p++;
957           }
958      }
959      }
960    EINA_LIST_FOREACH(pathlist, l, pathitr)
961      {
962    snprintf(buf, sizeof(buf), "%s/%s", pathitr, exe);
963    if (access(buf, R_OK | X_OK) == 0) return strdup(buf);
964      }
965    return NULL;
966 }
967
968 /**
969  * Run the main loop
970  *
971  * This call should be called just after all initialization is complete. This
972  * function will not return until elm_exit() is called. It will keep looping
973  * running the main event/processing loop for Elementary.
974  * @ingroup General
975  */
976 EAPI void
977 elm_run(void)
978 {
979    ecore_main_loop_begin();
980 }
981
982 /**
983  * Exit the main loop
984  *
985  * If this call is called, it will flag the main loop to cease processing and
986  * return back to its parent function.
987  * @ingroup General
988  */
989 EAPI void
990 elm_exit(void)
991 {
992    ecore_main_loop_quit();
993 }
994
995
996 /**
997  * Set new policy value.
998  *
999  * This will emit the ecore event ELM_EVENT_POLICY_CHANGED in the main
1000  * loop giving the event information Elm_Event_Policy_Changed with
1001  * policy identifier, new and old values.
1002  *
1003  * @param policy policy identifier as in Elm_Policy.
1004  * @param value policy value, depends on identifiers, usually there is
1005  *        an enumeration with the same prefix as the policy name, for
1006  *        example: ELM_POLICY_QUIT and Elm_Policy_Quit
1007  *        (ELM_POLICY_QUIT_NONE, ELM_POLICY_QUIT_LAST_WINDOW_CLOSED).
1008  *
1009  * @return @c EINA_TRUE on success or @c EINA_FALSE on error (right
1010  *         now just invalid policy identifier, but in future policy
1011  *         value might be enforced).
1012  */
1013 EAPI Eina_Bool
1014 elm_policy_set(unsigned int policy, int value)
1015 {
1016    Elm_Event_Policy_Changed *ev;
1017
1018    if (policy >= ELM_POLICY_LAST)
1019      return EINA_FALSE;
1020
1021    if (value == _elm_policies[policy])
1022      return EINA_TRUE;
1023
1024    /* TODO: validade policy? */
1025
1026    ev = malloc(sizeof(*ev));
1027    ev->policy = policy;
1028    ev->new_value = value;
1029    ev->old_value = _elm_policies[policy];
1030
1031    _elm_policies[policy] = value;
1032
1033    ecore_event_add(ELM_EVENT_POLICY_CHANGED, ev, NULL, NULL);
1034
1035    return EINA_TRUE;
1036 }
1037
1038 /**
1039  * Gets the policy value set for given identifier.
1040  *
1041  * @param policy policy identifier as in Elm_Policy.
1042  *
1043  * @return policy value. Will be 0 if policy identifier is invalid.
1044  */
1045 EAPI int
1046 elm_policy_get(unsigned int policy)
1047 {
1048    if (policy >= ELM_POLICY_LAST)
1049      return 0;
1050    return _elm_policies[policy];
1051 }
1052
1053 /**
1054  * Flush all caches & dump all data that can be to lean down to use less memory
1055  */
1056 EAPI void
1057 elm_all_flush(void)
1058 {
1059    const Eina_List *l;
1060    Evas_Object *obj;
1061    
1062    EINA_LIST_FOREACH(_elm_win_list, l, obj)
1063      {
1064         Evas *e = evas_object_evas_get(obj);
1065         edje_file_cache_flush();
1066         edje_collection_cache_flush();
1067         evas_image_cache_flush(e);
1068         evas_font_cache_flush(e);
1069         evas_render_dump(e);
1070      }
1071 }
1072
1073 /**
1074  * @defgroup Scaling Selective Widget Scaling
1075  * @ingroup Main
1076  *
1077  * Different widgets can be scaled independently. These functions allow you to
1078  * manipulate this scaling on a per-widget basis. The object and all its
1079  * children get their scaling factors multiplied by the scale factor set.
1080  * This is multiplicative, in that if a child also has a scale size set it is
1081  * in turn multiplied by its parent's scale size. 1.0 means “don't scale”,
1082  * 2.0 is double size, 0.5 is half etc.
1083  */
1084
1085 /**
1086  * Set the scaling factor
1087  *
1088  * @param obj The object
1089  * @param scale Scale factor (from 0.0 up, with 1.0 == no scaling)
1090  * @ingroup Scaling
1091  */
1092 EAPI void
1093 elm_object_scale_set(Evas_Object *obj, double scale)
1094 {
1095    elm_widget_scale_set(obj, scale);
1096 }
1097
1098 /**
1099  * Get the scaling factor
1100  *
1101  * @param obj The object
1102  * @return The scaling factor set by elm_object_scale_set()
1103  * @ingroup Scaling
1104  */
1105 EAPI double
1106 elm_object_scale_get(const Evas_Object *obj)
1107 {
1108    return elm_widget_scale_get(obj);
1109 }
1110
1111 /**
1112  * @defgroup Styles Styles
1113  * @ingroup Main
1114  *
1115  * Widgets can have different styles of look. These generic API's set
1116  * styles of widgets, if they support them (and if the theme(s) do).
1117  */
1118
1119 /**
1120  * Set the style
1121  *
1122  * This sets the name of the style
1123  * @param obj The object
1124  * @param style The style name to use
1125  * @ingroup Styles
1126  */
1127 EAPI void
1128 elm_object_style_set(Evas_Object *obj, const char *style)
1129 {
1130    elm_widget_style_set(obj, style);
1131 }
1132
1133 /**
1134  * Get the style
1135  *
1136  * This gets the style being used for that widget. Note that the string
1137  * pointer is only valid as longas the object is valid and the style doesn't
1138  * change.
1139  *
1140  * @param obj The object
1141  * @return The style name
1142  * @ingroup Styles
1143  */
1144 EAPI const char *
1145 elm_object_style_get(const Evas_Object *obj)
1146 {
1147    return elm_widget_style_get(obj);
1148 }
1149
1150 /**
1151  * Set the disable state
1152  *
1153  * This sets the disable state for the widget.
1154  *
1155  * @param obj The object
1156  * @param disabled The state
1157  * @ingroup Styles
1158  */
1159 EAPI void
1160 elm_object_disabled_set(Evas_Object *obj, Eina_Bool disabled)
1161 {
1162    elm_widget_disabled_set(obj, disabled);
1163 }
1164
1165 /**
1166  * Get the disable state
1167  *
1168  * This gets the disable state for the widget.
1169  *
1170  * @param obj The object
1171  * @return True, if the widget is disabled
1172  * @ingroup Styles
1173  */
1174 EAPI Eina_Bool
1175 elm_object_disabled_get(const Evas_Object *obj)
1176 {
1177    return elm_widget_disabled_get(obj);
1178 }
1179
1180 /**
1181  * Get the global scaling factor
1182  *
1183  * This gets the globally configured scaling factor that is applied to all
1184  * objects.
1185  *
1186  * @return The scaling factor
1187  * @ingroup Scaling
1188  */
1189 EAPI double
1190 elm_scale_get(void)
1191 {
1192    return _elm_config->scale;
1193 }
1194
1195 /**
1196  * Set the global scaling factor
1197  *
1198  * This sets the globally configured scaling factor that is applied to all
1199  * objects.
1200  *
1201  * @param scale The scaling factor to set
1202  * @ingroup Scaling
1203  */
1204 EAPI void
1205 elm_scale_set(double scale)
1206 {
1207    if (_elm_config->scale == scale) return;
1208    _elm_config->scale = scale;
1209    _elm_rescale();
1210 }
1211
1212 /**
1213  * Set the global scaling factor for all applications on the display
1214  * 
1215  * This sets the globally configured scaling factor that is applied to all
1216  * objects for all applications.
1217  * @param scale The scaling factor to set
1218  * @ingroup Scaling
1219  */
1220 EAPI void
1221 elm_scale_all_set(double scale)
1222 {
1223 #ifdef HAVE_ELEMENTARY_X
1224    static Ecore_X_Atom atom = 0;
1225    unsigned int scale_i = (unsigned int)(scale * 1000.0);
1226
1227    if (!atom) atom = ecore_x_atom_get("ENLIGHTENMENT_SCALE");
1228    ecore_x_window_prop_card32_set(ecore_x_window_root_first_get(),
1229                                   atom, &scale_i, 1);
1230 #endif   
1231 }
1232
1233 /**
1234  * @defgroup Fingers Fingers
1235  * @ingroup Main
1236  *
1237  * Elementary is designed to be finger-friendly for touchscreens, and so in
1238  * addition to scaling for display resolution, it can also scale based on
1239  * finger "resolution" (or size).
1240  */
1241
1242 /**
1243  * Get the configured finger size
1244  *
1245  * This gets the globally configured finger size in pixels
1246  *
1247  * @return The finger size
1248  * @ingroup Fingers
1249  */
1250 EAPI Evas_Coord
1251 elm_finger_size_get(void)
1252 {
1253    return _elm_config->finger_size;
1254 }
1255
1256 /**
1257  * Set the configured finger size
1258  *
1259  * This sets the globally configured finger size in pixels
1260  *
1261  * @param size The finger size
1262  * @ingroup Fingers
1263  */
1264 EAPI void
1265 elm_finger_size_set(Evas_Coord size)
1266 {
1267    if (_elm_config->finger_size == size) return;
1268    _elm_config->finger_size = size;
1269    _elm_rescale();
1270 }
1271
1272 /**
1273  * Set the configured finger size for all applications on the display
1274  *
1275  * This sets the globally configured finger size in pixels for all applications
1276  * on the display
1277  *
1278  * @param size The finger size
1279  * @ingroup Fingers
1280  */
1281 EAPI void
1282 elm_finger_size_all_set(Evas_Coord size)
1283 {
1284 #ifdef HAVE_ELEMENTARY_X
1285    static Ecore_X_Atom atom = 0;
1286    unsigned int size_i = (unsigned int)size;
1287
1288    if (!atom) atom = ecore_x_atom_get("ENLIGHTENMENT_FINGER_SIZE");
1289    ecore_x_window_prop_card32_set(ecore_x_window_root_first_get(),
1290                                   atom, &size_i, 1);
1291 #endif   
1292 }
1293
1294 EAPI void
1295 elm_autocapitalization_allow_all_set(Eina_Bool on)
1296 {
1297 #ifdef HAVE_ELEMENTARY_X
1298    static Ecore_X_Atom atom = 0;
1299    unsigned int on_i = (unsigned int)on;
1300
1301    if (!atom) atom = ecore_x_atom_get("ENLIGHTENMENT_AUTOCAPITAL_ALLOW");
1302    ecore_x_window_prop_card32_set(ecore_x_window_root_first_get(),
1303                                   atom, &on_i, 1);
1304 #endif
1305 }
1306
1307 EAPI void
1308 elm_autoperiod_allow_all_set(Eina_Bool on)
1309 {
1310 #ifdef HAVE_ELEMENTARY_X
1311    static Ecore_X_Atom atom = 0;
1312    unsigned int on_i = (unsigned int)on;
1313
1314    if (!atom) atom = ecore_x_atom_get("ENLIGHTENMENT_AUTOPERIOD_ALLOW");
1315    ecore_x_window_prop_card32_set(ecore_x_window_root_first_get(),
1316                                   atom, &on_i, 1);
1317 #endif
1318 }
1319
1320
1321 /**
1322  * Adjust size of an element for finger usage
1323  *
1324  * This takes width and height sizes (in pixels) as input and a size multiple
1325  * (which is how many fingers you want to place within the area), and adjusts
1326  * the size tobe large enough to accomodate finger. On return the w and h
1327  * sizes poiner do by these parameters will be modified.
1328  *
1329  * @param times_w How many fingers should fit horizontally
1330  * @param w Pointer to the width size to adjust
1331  * @param times_h How many fingers should fit vertically
1332  * @param h Pointer to the height size to adjust
1333  * @ingroup Fingers
1334  */
1335 EAPI void
1336 elm_coords_finger_size_adjust(int times_w, Evas_Coord *w, int times_h, Evas_Coord *h)
1337 {
1338    if ((w) && (*w < (_elm_config->finger_size * times_w)))
1339      *w = _elm_config->finger_size * times_w;
1340    if ((h) && (*h < (_elm_config->finger_size * times_h)))
1341      *h = _elm_config->finger_size * times_h;
1342 }
1343
1344 /**
1345  * @defgroup Focus Focus
1346  * @ingroup Main
1347  *
1348  * Objects have focus. This is what determines where the keyboard input goes to
1349  * within the application window.
1350  */
1351
1352 /**
1353  * Get the focus of the object
1354  *
1355  * This gets the focused property of the object.
1356  *
1357  * @param obj The object
1358  * @return 1 if the object is focused, 0 if not.
1359  * @ingroup Focus
1360  */
1361 EAPI Eina_Bool
1362 elm_object_focus_get(Evas_Object *obj)
1363 {
1364    return elm_widget_focus_get(obj);
1365 }
1366
1367 /**
1368  * Set the focus to the object
1369  *
1370  * This sets the focus target for keyboard input to be the object indicated.
1371  *
1372  * @param obj The object
1373  * @ingroup Focus
1374  */
1375 EAPI void
1376 elm_object_focus(Evas_Object *obj)
1377 {
1378    if (!elm_widget_can_focus_get(obj)) return;
1379    elm_widget_focus_steal(obj);
1380 }
1381
1382 /**
1383  * Remove the focus from the object
1384  *
1385  * This removes the focus target for keyboard input from be the object
1386  * indicated.
1387  *
1388  * @param obj The object
1389  * @ingroup Focus
1390  */
1391 EAPI void
1392 elm_object_unfocus(Evas_Object *obj)
1393 {
1394    if (!elm_widget_can_focus_get(obj)) return;
1395    elm_widget_focused_object_clear(obj);
1396 }
1397
1398 /**
1399  * Set the ability for the object to focus
1400  *
1401  * This sets the ability for the object to be able to get keyboard focus or
1402  * not. By default all objects are able to be focused.
1403  *
1404  * @param obj The object
1405  * @param enable 1 if the object can be focused, 0 if not
1406  * @ingroup Focus
1407  */
1408 EAPI void
1409 elm_object_focus_allow_set(Evas_Object *obj, Eina_Bool enable)
1410 {
1411    elm_widget_can_focus_set(obj, enable);
1412 }
1413
1414 /**
1415  * Get the ability for the object to focus
1416  *
1417  * This gets the ability for the object to be able to get keyboard focus or
1418  * not. By default all objects are able to be focused.
1419  *
1420  * @param obj The object
1421  * @return 1 if the object is allowed to be focused, 0 if not.
1422  * @ingroup Focus
1423  */
1424 EAPI Eina_Bool
1425 elm_object_focus_allow_get(const Evas_Object *obj)
1426 {
1427    return elm_widget_can_focus_get(obj);
1428 }
1429
1430 /**
1431  * @defgroup Scrollhints Scrollhints
1432  * @ingroup Main
1433  *
1434  * Objects when inside a scroller can scroll, but this may not always be
1435  * desireable in certain situations. This allows an object to hint to itself
1436  * and parents to "not scroll" in one of 2 ways.
1437  * 
1438  * 1. To hold on scrolling. This means just flicking and dragging may no
1439  * longer scroll, but pressing/dragging near an edge of the scroller will
1440  * still scroll. This is automastically used by the entry object when
1441  * selecting text.
1442  * 2. To totally freeze scrolling. This means it stops. until popped/released.
1443  */
1444
1445 /**
1446  * Push the scroll hold by 1
1447  *
1448  * This increments the scroll hold count by one. If it is more than 0 it will
1449  * take effect on the parents of the indicated object.
1450  *
1451  * @param obj The object
1452  * @ingroup Scrollhints
1453  */
1454 EAPI void
1455 elm_object_scroll_hold_push(Evas_Object *obj)
1456 {
1457    elm_widget_scroll_hold_push(obj);
1458 }
1459
1460 /**
1461  * Pop the scroll hold by 1
1462  *
1463  * This decrements the scroll hold count by one. If it is more than 0 it will
1464  * take effect on the parents of the indicated object.
1465  *
1466  * @param obj The object
1467  * @ingroup Scrollhints
1468  */
1469 EAPI void
1470 elm_object_scroll_hold_pop(Evas_Object *obj)
1471 {
1472    elm_widget_scroll_hold_pop(obj);
1473 }
1474
1475 /**
1476  * Push the scroll freeze by 1
1477  *
1478  * This increments the scroll freeze count by one. If it is more than 0 it will
1479  * take effect on the parents of the indicated object.
1480  *
1481  * @param obj The object
1482  * @ingroup Scrollhints
1483  */
1484 EAPI void
1485 elm_object_scroll_freeze_push(Evas_Object *obj)
1486 {
1487    elm_widget_scroll_freeze_push(obj);
1488 }
1489
1490 /**
1491  * Lock the scrolling of the given widget (and thus all parents)
1492  *
1493  * This locks the given object from scrolling in the X axis (and implicitly
1494  * also locks all parent scrollers too from doing the same).
1495  *
1496  * @param obj The object
1497  * @param lock The lock state (1 == locked, 0 == unlocked)
1498  * @ingroup Scrollhints
1499  */
1500 EAPI void
1501 elm_object_scroll_lock_x_set(Evas_Object *obj, Eina_Bool lock)
1502 {
1503    elm_widget_drag_lock_x_set(obj, lock);
1504 }
1505
1506 /**
1507  * Lock the scrolling of the given widget (and thus all parents)
1508  *
1509  * This locks the given object from scrolling in the Y axis (and implicitly
1510  * also locks all parent scrollers too from doing the same).
1511  *
1512  * @param obj The object
1513  * @param lock The lock state (1 == locked, 0 == unlocked)
1514  * @ingroup Scrollhints
1515  */
1516 EAPI void
1517 elm_object_scroll_lock_y_set(Evas_Object *obj, Eina_Bool lock)
1518 {
1519    elm_widget_drag_lock_y_set(obj, lock);
1520 }
1521
1522 /**
1523  * Get the scrolling lock of the given widget
1524  *
1525  * This gets the lock for X axis scrolling.
1526  *
1527  * @param obj The object
1528  * @ingroup Scrollhints
1529  */
1530 EAPI Eina_Bool
1531 elm_object_scroll_lock_x_get(const Evas_Object *obj)
1532 {
1533    return elm_widget_drag_lock_x_get(obj);
1534 }
1535
1536 /**
1537  * Get the scrolling lock of the given widget
1538  *
1539  * This gets the lock for X axis scrolling.
1540  *
1541  * @param obj The object
1542  * @ingroup Scrollhints
1543  */
1544 EAPI Eina_Bool
1545 elm_object_scroll_lock_y_get(const Evas_Object *obj)
1546 {
1547    return elm_widget_drag_lock_y_get(obj);
1548 }
1549
1550 /**
1551  * Pop the scroll freeze by 1
1552  *
1553  * This decrements the scroll freeze count by one. If it is more than 0 it will
1554  * take effect on the parents of the indicated object.
1555  *
1556  * @param obj The object
1557  * @ingroup Scrollhints
1558  */
1559 EAPI void
1560 elm_object_scroll_freeze_pop(Evas_Object *obj)
1561 {
1562    elm_widget_scroll_freeze_pop(obj);
1563 }
1564
1565
1566 /**
1567  * Check if the given Evas Object is an Elementary widget.
1568  *
1569  * @param obj the object to query.
1570  * @return @c EINA_TRUE if it is an elementary widget variant,
1571  *         @c EINA_FALSE otherwise
1572  */
1573 EAPI Eina_Bool
1574 elm_object_widget_check(const Evas_Object *obj)
1575 {
1576    return elm_widget_is(obj);
1577 }
1578
1579 /**
1580  * Get the first parent of the given object that is an Elementary widget.
1581  *
1582  * @param obj the object to query.
1583  * @return the parent object that is an Elementary widget, or @c NULL
1584  *         if no parent is, or no parents at all.
1585  */
1586 EAPI Evas_Object *
1587 elm_object_parent_widget_get(const Evas_Object *obj)
1588 {
1589    return elm_widget_parent_widget_get(obj);
1590 }
1591
1592 /**
1593  * Get the top level parent of an Elementary widget.
1594  *
1595  * @param obj The object to query.
1596  * @return The top level Elementary widget, or @c NULL if parent cannot be
1597  * found.
1598  */
1599 EAPI Evas_Object *
1600 elm_object_top_widget_get(const Evas_Object *obj)
1601 {
1602    return elm_widget_top_get(obj);
1603 }
1604
1605 /**
1606  * Get the string that represents this Elementary widget.
1607  *
1608  * @note Elementary is weird and exposes itself as a single
1609  *       Evas_Object_Smart_Class of type "elm_widget", so
1610  *       evas_object_type_get() always return that, making debug and
1611  *       language bindings hard. This function tries to mitigate this
1612  *       problem, but the solution is to change Elementary to use
1613  *       proper inheritance.
1614  *
1615  * @param obj the object to query.
1616  * @return Elementary widget name, or @c NULL if not a valid widget.
1617  */
1618 EAPI const char *
1619 elm_object_widget_type_get(const Evas_Object *obj)
1620 {
1621    return elm_widget_type_get(obj);
1622 }
1623
1624 /**
1625  * Send a signal to the widget edje object.
1626  *
1627  * This function sends a signal to the edje object of the obj. An edje program
1628  * can respond to a signal by specifying matching 'signal' and
1629  * 'source' fields.
1630  *
1631  * @param obj The object
1632  * @param emission The signal's name.
1633  * @param source The signal's source.
1634  * @ingroup General
1635  */
1636 EAPI void elm_object_signal_emit(Evas_Object *obj, const char *emission, const char *source)
1637 {
1638     elm_widget_signal_emit(obj, emission, source);
1639 }
1640
1641 /**
1642  * Add a callback for a signal emitted by widget edje object.
1643  *
1644  * This function connects a callback function to a signal emitted by the
1645  * edje object of the obj.
1646  * Globs can occur in either the emission or source name.
1647  *
1648  * @param obj The object
1649  * @param emission The signal's name.
1650  * @param source The signal's source.
1651  * @param func The callback function to be executed when the signal is
1652  * emitted.
1653  * @param data A pointer to data to pass in to the callback function.
1654  * @ingroup General
1655  */
1656 EAPI void 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)
1657 {
1658     elm_widget_signal_callback_add(obj, emission, source, func, data);
1659 }
1660
1661 /**
1662  * Remove a signal-triggered callback from an widget edje object.
1663  *
1664  * This function removes a callback, previoulsy attached to a signal emitted
1665  * by the edje object of the obj.
1666  * The parameters emission, source and func must match exactly those passed to
1667  * a previous call to elm_object_signal_callback_add(). The data pointer that
1668  * was passed to this call will be returned.
1669  *
1670  * @param obj The object
1671  * @param emission The signal's name.
1672  * @param source The signal's source.
1673  * @param func The callback function to be executed when the signal is
1674  * emitted.
1675  * @return The data pointer
1676  * @ingroup General
1677  */
1678 EAPI void *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))
1679 {
1680     return elm_widget_signal_callback_del(obj, emission, source, func);
1681 }