Merge branch 'master' of 165.213.180.234:slp/pkgs/e/elementary
[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                 eet_clearcache();
1068         evas_image_cache_flush(e);
1069         evas_font_cache_flush(e);
1070         evas_render_dump(e);
1071      }
1072 }
1073
1074 /**
1075  * @defgroup Scaling Selective Widget Scaling
1076  * @ingroup Main
1077  *
1078  * Different widgets can be scaled independently. These functions allow you to
1079  * manipulate this scaling on a per-widget basis. The object and all its
1080  * children get their scaling factors multiplied by the scale factor set.
1081  * This is multiplicative, in that if a child also has a scale size set it is
1082  * in turn multiplied by its parent's scale size. 1.0 means “don't scale”,
1083  * 2.0 is double size, 0.5 is half etc.
1084  */
1085
1086 /**
1087  * Set the scaling factor
1088  *
1089  * @param obj The object
1090  * @param scale Scale factor (from 0.0 up, with 1.0 == no scaling)
1091  * @ingroup Scaling
1092  */
1093 EAPI void
1094 elm_object_scale_set(Evas_Object *obj, double scale)
1095 {
1096    elm_widget_scale_set(obj, scale);
1097 }
1098
1099 /**
1100  * Get the scaling factor
1101  *
1102  * @param obj The object
1103  * @return The scaling factor set by elm_object_scale_set()
1104  * @ingroup Scaling
1105  */
1106 EAPI double
1107 elm_object_scale_get(const Evas_Object *obj)
1108 {
1109    return elm_widget_scale_get(obj);
1110 }
1111
1112 /**
1113  * @defgroup Styles Styles
1114  * @ingroup Main
1115  *
1116  * Widgets can have different styles of look. These generic API's set
1117  * styles of widgets, if they support them (and if the theme(s) do).
1118  */
1119
1120 /**
1121  * Set the style
1122  *
1123  * This sets the name of the style
1124  * @param obj The object
1125  * @param style The style name to use
1126  * @ingroup Styles
1127  */
1128 EAPI void
1129 elm_object_style_set(Evas_Object *obj, const char *style)
1130 {
1131    elm_widget_style_set(obj, style);
1132 }
1133
1134 /**
1135  * Get the style
1136  *
1137  * This gets the style being used for that widget. Note that the string
1138  * pointer is only valid as longas the object is valid and the style doesn't
1139  * change.
1140  *
1141  * @param obj The object
1142  * @return The style name
1143  * @ingroup Styles
1144  */
1145 EAPI const char *
1146 elm_object_style_get(const Evas_Object *obj)
1147 {
1148    return elm_widget_style_get(obj);
1149 }
1150
1151 /**
1152  * Set the disable state
1153  *
1154  * This sets the disable state for the widget.
1155  *
1156  * @param obj The object
1157  * @param disabled The state
1158  * @ingroup Styles
1159  */
1160 EAPI void
1161 elm_object_disabled_set(Evas_Object *obj, Eina_Bool disabled)
1162 {
1163    elm_widget_disabled_set(obj, disabled);
1164 }
1165
1166 /**
1167  * Get the disable state
1168  *
1169  * This gets the disable state for the widget.
1170  *
1171  * @param obj The object
1172  * @return True, if the widget is disabled
1173  * @ingroup Styles
1174  */
1175 EAPI Eina_Bool
1176 elm_object_disabled_get(const Evas_Object *obj)
1177 {
1178    return elm_widget_disabled_get(obj);
1179 }
1180
1181 /**
1182  * Get the global scaling factor
1183  *
1184  * This gets the globally configured scaling factor that is applied to all
1185  * objects.
1186  *
1187  * @return The scaling factor
1188  * @ingroup Scaling
1189  */
1190 EAPI double
1191 elm_scale_get(void)
1192 {
1193    return _elm_config->scale;
1194 }
1195
1196 /**
1197  * Set the global scaling factor
1198  *
1199  * This sets the globally configured scaling factor that is applied to all
1200  * objects.
1201  *
1202  * @param scale The scaling factor to set
1203  * @ingroup Scaling
1204  */
1205 EAPI void
1206 elm_scale_set(double scale)
1207 {
1208    if (_elm_config->scale == scale) return;
1209    _elm_config->scale = scale;
1210    _elm_rescale();
1211 }
1212
1213 /**
1214  * Set the global scaling factor for all applications on the display
1215  * 
1216  * This sets the globally configured scaling factor that is applied to all
1217  * objects for all applications.
1218  * @param scale The scaling factor to set
1219  * @ingroup Scaling
1220  */
1221 EAPI void
1222 elm_scale_all_set(double scale)
1223 {
1224 #ifdef HAVE_ELEMENTARY_X
1225    static Ecore_X_Atom atom = 0;
1226    unsigned int scale_i = (unsigned int)(scale * 1000.0);
1227
1228    if (!atom) atom = ecore_x_atom_get("ENLIGHTENMENT_SCALE");
1229    ecore_x_window_prop_card32_set(ecore_x_window_root_first_get(),
1230                                   atom, &scale_i, 1);
1231 #endif   
1232 }
1233
1234 /**
1235  * @defgroup Fingers Fingers
1236  * @ingroup Main
1237  *
1238  * Elementary is designed to be finger-friendly for touchscreens, and so in
1239  * addition to scaling for display resolution, it can also scale based on
1240  * finger "resolution" (or size).
1241  */
1242
1243 /**
1244  * Get the configured finger size
1245  *
1246  * This gets the globally configured finger size in pixels
1247  *
1248  * @return The finger size
1249  * @ingroup Fingers
1250  */
1251 EAPI Evas_Coord
1252 elm_finger_size_get(void)
1253 {
1254    return _elm_config->finger_size;
1255 }
1256
1257 /**
1258  * Set the configured finger size
1259  *
1260  * This sets the globally configured finger size in pixels
1261  *
1262  * @param size The finger size
1263  * @ingroup Fingers
1264  */
1265 EAPI void
1266 elm_finger_size_set(Evas_Coord size)
1267 {
1268    if (_elm_config->finger_size == size) return;
1269    _elm_config->finger_size = size;
1270    _elm_rescale();
1271 }
1272
1273 /**
1274  * Set the configured finger size for all applications on the display
1275  *
1276  * This sets the globally configured finger size in pixels for all applications
1277  * on the display
1278  *
1279  * @param size The finger size
1280  * @ingroup Fingers
1281  */
1282 EAPI void
1283 elm_finger_size_all_set(Evas_Coord size)
1284 {
1285 #ifdef HAVE_ELEMENTARY_X
1286    static Ecore_X_Atom atom = 0;
1287    unsigned int size_i = (unsigned int)size;
1288
1289    if (!atom) atom = ecore_x_atom_get("ENLIGHTENMENT_FINGER_SIZE");
1290    ecore_x_window_prop_card32_set(ecore_x_window_root_first_get(),
1291                                   atom, &size_i, 1);
1292 #endif   
1293 }
1294
1295 EAPI void
1296 elm_autocapitalization_allow_all_set(Eina_Bool on)
1297 {
1298 #ifdef HAVE_ELEMENTARY_X
1299    static Ecore_X_Atom atom = 0;
1300    unsigned int on_i = (unsigned int)on;
1301
1302    if (!atom) atom = ecore_x_atom_get("ENLIGHTENMENT_AUTOCAPITAL_ALLOW");
1303    ecore_x_window_prop_card32_set(ecore_x_window_root_first_get(),
1304                                   atom, &on_i, 1);
1305 #endif
1306 }
1307
1308 EAPI void
1309 elm_autoperiod_allow_all_set(Eina_Bool on)
1310 {
1311 #ifdef HAVE_ELEMENTARY_X
1312    static Ecore_X_Atom atom = 0;
1313    unsigned int on_i = (unsigned int)on;
1314
1315    if (!atom) atom = ecore_x_atom_get("ENLIGHTENMENT_AUTOPERIOD_ALLOW");
1316    ecore_x_window_prop_card32_set(ecore_x_window_root_first_get(),
1317                                   atom, &on_i, 1);
1318 #endif
1319 }
1320
1321
1322 /**
1323  * Adjust size of an element for finger usage
1324  *
1325  * This takes width and height sizes (in pixels) as input and a size multiple
1326  * (which is how many fingers you want to place within the area), and adjusts
1327  * the size tobe large enough to accomodate finger. On return the w and h
1328  * sizes poiner do by these parameters will be modified.
1329  *
1330  * @param times_w How many fingers should fit horizontally
1331  * @param w Pointer to the width size to adjust
1332  * @param times_h How many fingers should fit vertically
1333  * @param h Pointer to the height size to adjust
1334  * @ingroup Fingers
1335  */
1336 EAPI void
1337 elm_coords_finger_size_adjust(int times_w, Evas_Coord *w, int times_h, Evas_Coord *h)
1338 {
1339    if ((w) && (*w < (_elm_config->finger_size * times_w)))
1340      *w = _elm_config->finger_size * times_w;
1341    if ((h) && (*h < (_elm_config->finger_size * times_h)))
1342      *h = _elm_config->finger_size * times_h;
1343 }
1344
1345 /**
1346  * @defgroup Focus Focus
1347  * @ingroup Main
1348  *
1349  * Objects have focus. This is what determines where the keyboard input goes to
1350  * within the application window.
1351  */
1352
1353 /**
1354  * Get the focus of the object
1355  *
1356  * This gets the focused property of the object.
1357  *
1358  * @param obj The object
1359  * @return 1 if the object is focused, 0 if not.
1360  * @ingroup Focus
1361  */
1362 EAPI Eina_Bool
1363 elm_object_focus_get(Evas_Object *obj)
1364 {
1365    return elm_widget_focus_get(obj);
1366 }
1367
1368 /**
1369  * Set the focus to the object
1370  *
1371  * This sets the focus target for keyboard input to be the object indicated.
1372  *
1373  * @param obj The object
1374  * @ingroup Focus
1375  */
1376 EAPI void
1377 elm_object_focus(Evas_Object *obj)
1378 {
1379    if (!elm_widget_can_focus_get(obj)) return;
1380    elm_widget_focus_steal(obj);
1381 }
1382
1383 /**
1384  * Remove the focus from the object
1385  *
1386  * This removes the focus target for keyboard input from be the object
1387  * indicated.
1388  *
1389  * @param obj The object
1390  * @ingroup Focus
1391  */
1392 EAPI void
1393 elm_object_unfocus(Evas_Object *obj)
1394 {
1395    if (!elm_widget_can_focus_get(obj)) return;
1396    elm_widget_focused_object_clear(obj);
1397 }
1398
1399 /**
1400  * Set the ability for the object to focus
1401  *
1402  * This sets the ability for the object to be able to get keyboard focus or
1403  * not. By default all objects are able to be focused.
1404  *
1405  * @param obj The object
1406  * @param enable 1 if the object can be focused, 0 if not
1407  * @ingroup Focus
1408  */
1409 EAPI void
1410 elm_object_focus_allow_set(Evas_Object *obj, Eina_Bool enable)
1411 {
1412    elm_widget_can_focus_set(obj, enable);
1413 }
1414
1415 /**
1416  * Get the ability for the object to focus
1417  *
1418  * This gets the ability for the object to be able to get keyboard focus or
1419  * not. By default all objects are able to be focused.
1420  *
1421  * @param obj The object
1422  * @return 1 if the object is allowed to be focused, 0 if not.
1423  * @ingroup Focus
1424  */
1425 EAPI Eina_Bool
1426 elm_object_focus_allow_get(const Evas_Object *obj)
1427 {
1428    return elm_widget_can_focus_get(obj);
1429 }
1430
1431 /**
1432  * @defgroup Scrollhints Scrollhints
1433  * @ingroup Main
1434  *
1435  * Objects when inside a scroller can scroll, but this may not always be
1436  * desireable in certain situations. This allows an object to hint to itself
1437  * and parents to "not scroll" in one of 2 ways.
1438  * 
1439  * 1. To hold on scrolling. This means just flicking and dragging may no
1440  * longer scroll, but pressing/dragging near an edge of the scroller will
1441  * still scroll. This is automastically used by the entry object when
1442  * selecting text.
1443  * 2. To totally freeze scrolling. This means it stops. until popped/released.
1444  */
1445
1446 /**
1447  * Push the scroll hold by 1
1448  *
1449  * This increments the scroll hold count by one. If it is more than 0 it will
1450  * take effect on the parents of the indicated object.
1451  *
1452  * @param obj The object
1453  * @ingroup Scrollhints
1454  */
1455 EAPI void
1456 elm_object_scroll_hold_push(Evas_Object *obj)
1457 {
1458    elm_widget_scroll_hold_push(obj);
1459 }
1460
1461 /**
1462  * Pop the scroll hold by 1
1463  *
1464  * This decrements the scroll hold count by one. If it is more than 0 it will
1465  * take effect on the parents of the indicated object.
1466  *
1467  * @param obj The object
1468  * @ingroup Scrollhints
1469  */
1470 EAPI void
1471 elm_object_scroll_hold_pop(Evas_Object *obj)
1472 {
1473    elm_widget_scroll_hold_pop(obj);
1474 }
1475
1476 /**
1477  * Push the scroll freeze by 1
1478  *
1479  * This increments the scroll freeze count by one. If it is more than 0 it will
1480  * take effect on the parents of the indicated object.
1481  *
1482  * @param obj The object
1483  * @ingroup Scrollhints
1484  */
1485 EAPI void
1486 elm_object_scroll_freeze_push(Evas_Object *obj)
1487 {
1488    elm_widget_scroll_freeze_push(obj);
1489 }
1490
1491 /**
1492  * Lock the scrolling of the given widget (and thus all parents)
1493  *
1494  * This locks the given object from scrolling in the X axis (and implicitly
1495  * also locks all parent scrollers too from doing the same).
1496  *
1497  * @param obj The object
1498  * @param lock The lock state (1 == locked, 0 == unlocked)
1499  * @ingroup Scrollhints
1500  */
1501 EAPI void
1502 elm_object_scroll_lock_x_set(Evas_Object *obj, Eina_Bool lock)
1503 {
1504    elm_widget_drag_lock_x_set(obj, lock);
1505 }
1506
1507 /**
1508  * Lock the scrolling of the given widget (and thus all parents)
1509  *
1510  * This locks the given object from scrolling in the Y axis (and implicitly
1511  * also locks all parent scrollers too from doing the same).
1512  *
1513  * @param obj The object
1514  * @param lock The lock state (1 == locked, 0 == unlocked)
1515  * @ingroup Scrollhints
1516  */
1517 EAPI void
1518 elm_object_scroll_lock_y_set(Evas_Object *obj, Eina_Bool lock)
1519 {
1520    elm_widget_drag_lock_y_set(obj, lock);
1521 }
1522
1523 /**
1524  * Get the scrolling lock of the given widget
1525  *
1526  * This gets the lock for X axis scrolling.
1527  *
1528  * @param obj The object
1529  * @ingroup Scrollhints
1530  */
1531 EAPI Eina_Bool
1532 elm_object_scroll_lock_x_get(const Evas_Object *obj)
1533 {
1534    return elm_widget_drag_lock_x_get(obj);
1535 }
1536
1537 /**
1538  * Get the scrolling lock of the given widget
1539  *
1540  * This gets the lock for X axis scrolling.
1541  *
1542  * @param obj The object
1543  * @ingroup Scrollhints
1544  */
1545 EAPI Eina_Bool
1546 elm_object_scroll_lock_y_get(const Evas_Object *obj)
1547 {
1548    return elm_widget_drag_lock_y_get(obj);
1549 }
1550
1551 /**
1552  * Pop the scroll freeze by 1
1553  *
1554  * This decrements the scroll freeze count by one. If it is more than 0 it will
1555  * take effect on the parents of the indicated object.
1556  *
1557  * @param obj The object
1558  * @ingroup Scrollhints
1559  */
1560 EAPI void
1561 elm_object_scroll_freeze_pop(Evas_Object *obj)
1562 {
1563    elm_widget_scroll_freeze_pop(obj);
1564 }
1565
1566
1567 /**
1568  * Check if the given Evas Object is an Elementary widget.
1569  *
1570  * @param obj the object to query.
1571  * @return @c EINA_TRUE if it is an elementary widget variant,
1572  *         @c EINA_FALSE otherwise
1573  */
1574 EAPI Eina_Bool
1575 elm_object_widget_check(const Evas_Object *obj)
1576 {
1577    return elm_widget_is(obj);
1578 }
1579
1580 /**
1581  * Get the first parent of the given object that is an Elementary widget.
1582  *
1583  * @param obj the object to query.
1584  * @return the parent object that is an Elementary widget, or @c NULL
1585  *         if no parent is, or no parents at all.
1586  */
1587 EAPI Evas_Object *
1588 elm_object_parent_widget_get(const Evas_Object *obj)
1589 {
1590    return elm_widget_parent_widget_get(obj);
1591 }
1592
1593 /**
1594  * Get the top level parent of an Elementary widget.
1595  *
1596  * @param obj The object to query.
1597  * @return The top level Elementary widget, or @c NULL if parent cannot be
1598  * found.
1599  */
1600 EAPI Evas_Object *
1601 elm_object_top_widget_get(const Evas_Object *obj)
1602 {
1603    return elm_widget_top_get(obj);
1604 }
1605
1606 /**
1607  * Get the string that represents this Elementary widget.
1608  *
1609  * @note Elementary is weird and exposes itself as a single
1610  *       Evas_Object_Smart_Class of type "elm_widget", so
1611  *       evas_object_type_get() always return that, making debug and
1612  *       language bindings hard. This function tries to mitigate this
1613  *       problem, but the solution is to change Elementary to use
1614  *       proper inheritance.
1615  *
1616  * @param obj the object to query.
1617  * @return Elementary widget name, or @c NULL if not a valid widget.
1618  */
1619 EAPI const char *
1620 elm_object_widget_type_get(const Evas_Object *obj)
1621 {
1622    return elm_widget_type_get(obj);
1623 }
1624
1625 /**
1626  * Send a signal to the widget edje object.
1627  *
1628  * This function sends a signal to the edje object of the obj. An edje program
1629  * can respond to a signal by specifying matching 'signal' and
1630  * 'source' fields.
1631  *
1632  * @param obj The object
1633  * @param emission The signal's name.
1634  * @param source The signal's source.
1635  * @ingroup General
1636  */
1637 EAPI void elm_object_signal_emit(Evas_Object *obj, const char *emission, const char *source)
1638 {
1639     elm_widget_signal_emit(obj, emission, source);
1640 }
1641
1642 /**
1643  * Add a callback for a signal emitted by widget edje object.
1644  *
1645  * This function connects a callback function to a signal emitted by the
1646  * edje object of the obj.
1647  * Globs can occur in either the emission or source name.
1648  *
1649  * @param obj The object
1650  * @param emission The signal's name.
1651  * @param source The signal's source.
1652  * @param func The callback function to be executed when the signal is
1653  * emitted.
1654  * @param data A pointer to data to pass in to the callback function.
1655  * @ingroup General
1656  */
1657 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)
1658 {
1659     elm_widget_signal_callback_add(obj, emission, source, func, data);
1660 }
1661
1662 /**
1663  * Remove a signal-triggered callback from an widget edje object.
1664  *
1665  * This function removes a callback, previoulsy attached to a signal emitted
1666  * by the edje object of the obj.
1667  * The parameters emission, source and func must match exactly those passed to
1668  * a previous call to elm_object_signal_callback_add(). The data pointer that
1669  * was passed to this call will be returned.
1670  *
1671  * @param obj The object
1672  * @param emission The signal's name.
1673  * @param source The signal's source.
1674  * @param func The callback function to be executed when the signal is
1675  * emitted.
1676  * @return The data pointer
1677  * @ingroup General
1678  */
1679 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))
1680 {
1681     return elm_widget_signal_callback_del(obj, emission, source, func);
1682 }
1683
1684 /**
1685  * Set the duration for occuring long press event.
1686  *
1687  * @param lonpress_timeout Timeout for long press event
1688  * @ingroup Longpress
1689  */
1690 EAPI void
1691 elm_longpress_timeout_set(double longpress_timeout)
1692 {
1693    _elm_config->longpress_timeout = longpress_timeout;
1694 }
1695
1696 /**
1697  * Get the duration for occuring long press event.
1698  *
1699  * @return Timeout for long press event
1700  * @ingroup Longpress
1701  */
1702 EAPI double
1703 elm_longpress_timeout_get(void)
1704 {
1705    return _elm_config->longpress_timeout;
1706 }