From f7a18a3db95b026ea19e425c980b242ae075d464 Mon Sep 17 00:00:00 2001 From: Carsten Haitzler Date: Wed, 25 Feb 2009 11:00:07 +0000 Subject: [PATCH] add quicklauncher infra! elementary_testql uses this infra. SVN revision: 39199 --- legacy/elementary/configure.in | 1 + legacy/elementary/src/bin/Makefile.am | 29 +- legacy/elementary/src/bin/quicklaunch.c | 130 +++++++++ legacy/elementary/src/bin/run.c | 159 ++++++++++ legacy/elementary/src/bin/test.c | 3 +- legacy/elementary/src/lib/Elementary.h.in | 22 ++ legacy/elementary/src/lib/elm_main.c | 336 +++++++++++++++++----- 7 files changed, 609 insertions(+), 71 deletions(-) create mode 100644 legacy/elementary/src/bin/quicklaunch.c create mode 100644 legacy/elementary/src/bin/run.c diff --git a/legacy/elementary/configure.in b/legacy/elementary/configure.in index 60e6bb6b1a..6762921757 100644 --- a/legacy/elementary/configure.in +++ b/legacy/elementary/configure.in @@ -18,6 +18,7 @@ AC_PROG_CC AM_PROG_CC_STDC AC_HEADER_STDC AC_C_CONST +AC_FUNC_ALLOCA AC_LIBTOOL_WIN32_DLL define([AC_LIBTOOL_LANG_CXX_CONFIG], [:])dnl diff --git a/legacy/elementary/src/bin/Makefile.am b/legacy/elementary/src/bin/Makefile.am index b307f74ba0..efb3cc064f 100644 --- a/legacy/elementary/src/bin/Makefile.am +++ b/legacy/elementary/src/bin/Makefile.am @@ -18,8 +18,33 @@ if ELEMENTARY_WINDOWS_BUILD AM_CPPFLAGS += -DELEMENTARY_BUILD endif -bin_PROGRAMS = elementary_test +bin_PROGRAMS = elementary_test elementary_quicklaunch elementary_run \ +elementary_testql elementary_test_SOURCES = test.c elementary_test_LDADD = $(top_builddir)/src/lib/libelementary.la -elementary_test_LDFLAGS = +elementary_test_LDFLAGS = + +elementary_quicklaunch_SOURCES = quicklaunch.c +elementary_quicklaunch_LDADD = $(top_builddir)/src/lib/libelementary.la +elementary_quicklaunch_LDFLAGS = + +elementary_run_SOURCES = run.c +elementary_run_LDADD = +elementary_run_LDFLAGS = + +## This is how to build a quicklanch capable app +# build the shared lib version - libtool produces a .a and .la file as well +# as a .so - these get put in libdir ($PREIFX/lib) as elementary_testql.so +# etc. - this is where elementary will expect to find the .so's for +# quicklaunch apps. +elementary_testqldir = $(libdir) +elementary_testql_LTLIBRARIES = elementary_testql.la +elementary_testql_la_SOURCES = test.c +elementary_testql_la_LIBADD = $(top_builddir)/src/lib/libelementary.la +elementary_testql_la_CFLAGS = +elementary_testql_la_LDFLAGS = -module -avoid-version -no-undefined +elementary_testql_SOURCES = test.c +elementary_testql_LDADD = $(top_builddir)/src/lib/libelementary.la +elementary_testql_CFLAGS = -DELM_LIB_QUICKLAUNCH=1 +elementary_testql_LDFLAGS = diff --git a/legacy/elementary/src/bin/quicklaunch.c b/legacy/elementary/src/bin/quicklaunch.c new file mode 100644 index 0000000000..8db5b5f2f8 --- /dev/null +++ b/legacy/elementary/src/bin/quicklaunch.c @@ -0,0 +1,130 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define LENGTH_OF_SOCKADDR_UN(s) (strlen((s)->sun_path) + (size_t)(((struct sockaddr_un *)NULL)->sun_path)) + +static void +handle_run(int fd, unsigned long bytes) +{ + unsigned char *buf = NULL; + int i, num; + char **argv = NULL; + char *cwd; + int argc; + + buf = alloca(bytes); + if ((num = read(fd, buf, bytes)) < 0) + { + close(fd); + return; + } + close(fd); + argc = ((unsigned long *)(buf))[0]; + argv = (char **)(&(((unsigned long *)(buf))[1])); + for (i = 0; i < argc; i++) argv[i] = buf + (unsigned long)argv[i]; + cwd = argv[argc - 1] + strlen(argv[argc - 1]) + 1; + elm_quicklaunch_prepare(argc, argv); + elm_quicklaunch_fork(argc, argv, cwd); + elm_quicklaunch_cleanup(); +} + +static void +child_handler(int n) +{ + int status; + wait(&status); +} + +int +main(int argc, char **argv) +{ + int sock, socket_unix_len; + struct stat st; + struct sockaddr_un socket_unix; + struct linger lin; + char buf[PATH_MAX]; + struct sigaction sa; + + if (!getenv("DISPLAY")) + { + fprintf(stderr, "elementary_quicklaunch: DISPLAY env var not set\n"); + exit(-1); + } + snprintf(buf, sizeof(buf), "/tmp/elm-ql-%i", getuid()); + if (stat(buf, &st) < 0) mkdir(buf, S_IRUSR | S_IWUSR | S_IXUSR); + snprintf(buf, sizeof(buf), "/tmp/elm-ql-%i/%s", getuid(), getenv("DISPLAY")); + unlink(buf); + sock = socket(AF_UNIX, SOCK_STREAM, 0); + if (sock < 0) + { + perror("elementary_quicklaunch: socket(AF_UNIX, SOCK_STREAM, 0)"); + exit(-1); + } + if (fcntl(sock, F_SETFD, FD_CLOEXEC) < 0) + { + perror("elementary_quicklaunch: fcntl(sock, F_SETFD, FD_CLOEXEC)"); + exit(-1); + } + lin.l_onoff = 1; + lin.l_linger = 0; + if (setsockopt(sock, SOL_SOCKET, SO_LINGER, &lin, sizeof(struct linger)) < 0) + { + perror("elementary_quicklaunch: setsockopt(sock, SOL_SOCKET, SO_LINGER, &lin, sizeof(struct linger)) "); + exit(-1); + } + socket_unix.sun_family = AF_UNIX; + strncpy(socket_unix.sun_path, buf, sizeof(socket_unix.sun_path)); + socket_unix_len = LENGTH_OF_SOCKADDR_UN(&socket_unix); + if (bind(sock, (struct sockaddr *)&socket_unix, socket_unix_len) < 0) + { + perror("elementary_quicklaunch: bind(sock, (struct sockaddr *)&socket_unix, socket_unix_len)"); + printf("elementary_quicklaunch: cannot bind socket for '%s'\n", buf); + exit(-1); + } + if (listen(sock, 4096) < 0) + { + perror("elementary_quicklaunch: listen(sock, 4096)"); + exit(-1); + } + elm_quicklaunch_init(argc, argv); + signal(SIGINT, SIG_DFL); + signal(SIGTERM, SIG_DFL); + signal(SIGQUIT, SIG_DFL); + signal(SIGALRM, SIG_DFL); + signal(SIGUSR1, SIG_DFL); + signal(SIGUSR2, SIG_DFL); + signal(SIGHUP, SIG_DFL); + signal(SIGCHLD, child_handler); + for (;;) + { + int fd; + struct sockaddr_un client; + socklen_t len; + + elm_quicklaunch_sub_init(argc, argv); + elm_quicklaunch_seed(); + len = sizeof(struct sockaddr_un); + fd = accept(sock, (struct sockaddr *)&client, &len); + if (fd >= 0) + { + int bytes; + char line[4096]; + + read(fd, &bytes, sizeof(unsigned long)); + handle_run(fd, bytes); + } + elm_quicklaunch_sub_shutdown(); + } + elm_quicklaunch_shutdown(); + return 0; +} diff --git a/legacy/elementary/src/bin/run.c b/legacy/elementary/src/bin/run.c new file mode 100644 index 0000000000..d3aaf3b680 --- /dev/null +++ b/legacy/elementary/src/bin/run.c @@ -0,0 +1,159 @@ +#include "elementary_config.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef HAVE_ALLOCA_H +# include +#endif + +#define LENGTH_OF_SOCKADDR_UN(s) (strlen((s)->sun_path) + (size_t)(((struct sockaddr_un *)NULL)->sun_path)) + +int +main(int argc, char **argv) +{ + int sock, socket_unix_len, i; + struct sockaddr_un socket_unix; + char buf[PATH_MAX]; + struct stat st; + char *exe; + int we_are_elementary_run = 0; + char *disp; + char *cwd; + + int sargc, slen; + unsigned char *sbuf = NULL, *pos; + char **sargv = NULL; + + if (!getcwd(buf, sizeof(buf) - 1)) + { + fprintf(stderr, "elementary_quicklaunch: currect working dir too big.\n"); + exit(-1); + } + cwd = strdup(buf); + if (!(disp = getenv("DISPLAY"))) + { + fprintf(stderr, "elementary_quicklaunch: DISPLAY env var not set\n"); + exit(-1); + } + snprintf(buf, sizeof(buf), "/tmp/elm-ql-%i/%s", getuid(), disp); + if ((sock = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) + { + perror("elementary_quicklaunch: socket(AF_UNIX, SOCK_STREAM, 0)"); + exit(-1); + } + socket_unix.sun_family = AF_UNIX; + strncpy(socket_unix.sun_path, buf, sizeof(socket_unix.sun_path)); + socket_unix_len = LENGTH_OF_SOCKADDR_UN(&socket_unix); + if (connect(sock, (struct sockaddr *)&socket_unix, socket_unix_len) < 0) + { + perror("elementary_quicklaunch: connect(sock, (struct sockaddr *)&socket_unix, socket_unix_len)"); + printf("elementary_quicklaunch: cannot connect to socket '%s'\n", buf); + exit(1); + } + exe = argv[0]; + if (!(((exe[0] == '/')) || + ((exe[0] == '.') && (exe[1] == '/')) || + ((exe[0] == '.') && (exe[1] == '.') && (exe[2] == '/')))) + { + char *path = getenv("PATH"); + int exelen = strlen(argv[0]); + if (path) + { + const char *p, *pp, *s; + int exelen; + + p = path; + pp = p; + exe = NULL; + for (;;) + { + if ((*p == ':') || (*p == 0)) + { + int len; + + len = p - pp; + if (len < (sizeof(buf) - exelen - 3)) + { + strncpy(buf, pp, len); + strcpy(buf + len, "/"); + strcpy(buf + len + 1, argv[0]); + if (access(buf, R_OK | X_OK) == 0) + { + exe = buf; + break; + } + if (*p == 0) break; + p++; + pp = p; + } + } + else + { + if (*p == 0) break; + p++; + } + } + } + } + if (exe) + { + if (lstat(exe, &st) == 0) + { + if (S_ISLNK(st.st_mode)) + { + char buf2[PATH_MAX]; + + ssize_t len = readlink(exe, buf2, sizeof(buf2) - 1); + if (len >= 0) + { + char *p; + buf2[len] = 0; + p = strrchr(buf2, '/'); + if (p) p++; + else p = buf2; + if (!strncasecmp(p, "elementary_run", 14)) + we_are_elementary_run = 1; + } + } + } + } + if (we_are_elementary_run) + { + sargc = argc; + sargv = argv; + } + else + { + sargc = argc - 1; + sargv = &(argv[1]); + } + slen = sizeof(unsigned long) + sizeof(unsigned long); + for (i = 0; i < sargc; i++) + { + slen += sizeof(unsigned long); + slen += strlen(sargv[i]) + 1; + } + slen += strlen(cwd) + 1; + sbuf = alloca(slen); + ((unsigned long *)(sbuf))[0] = slen - sizeof(unsigned long); + ((unsigned long *)(sbuf))[1] = sargc; + pos = (unsigned char *)(&((((unsigned long *)(sbuf))[2 + sargc]))); + for (i = 0; i < sargc; i++) + { + ((unsigned long *)(sbuf))[2 + i] = + (unsigned long)pos - ((unsigned long)sbuf + sizeof(unsigned long)); + strcpy(pos, sargv[i]); + pos += strlen(sargv[i]) + 1; + } + strcpy(pos, cwd); + write(sock, sbuf, slen); + close(sock); + return 0; +} diff --git a/legacy/elementary/src/bin/test.c b/legacy/elementary/src/bin/test.c index 6ec80976dc..88a288d602 100644 --- a/legacy/elementary/src/bin/test.c +++ b/legacy/elementary/src/bin/test.c @@ -1,5 +1,5 @@ #include - +#ifndef ELM_LIB_QUICKLAUNCH static void my_win_del(void *data, Evas_Object *obj, void *event_info); static void my_bt_1(void *data, Evas_Object *obj, void *event_info); static void my_win_main(void); @@ -2879,5 +2879,6 @@ elm_main(int argc, char **argv) /* exit code */ return 0; } +#endif /* all emeentary apps should use this. but it right after elm_main() */ ELM_MAIN() diff --git a/legacy/elementary/src/lib/Elementary.h.in b/legacy/elementary/src/lib/Elementary.h.in index 2b6003743c..cc2cf814a5 100644 --- a/legacy/elementary/src/lib/Elementary.h.in +++ b/legacy/elementary/src/lib/Elementary.h.in @@ -136,7 +136,11 @@ extern "C" { ELM_WIN_KEYBOARD_PASSWORD } Elm_Win_Keyboard_Mode; +#ifndef ELM_LIB_QUICKLAUNCH #define ELM_MAIN() int main(int argc, char **argv) {elm_init(argc, argv); return elm_main(argc, argv);} +#else +#define ELM_MAIN() int main(int argc, char **argv) {return elm_quicklaunch_fallback(argc, argv);} +#endif /**************************************************************************/ /* General calls */ @@ -145,6 +149,17 @@ extern "C" { EAPI void elm_run(void); EAPI void elm_exit(void); + EAPI void elm_quicklaunch_init(int argc, char **argv); + EAPI void elm_quicklaunch_sub_init(int argc, char **argv); + EAPI void elm_quicklaunch_sub_shutdown(void); + EAPI void elm_quicklaunch_shutdown(void); + EAPI void elm_quicklaunch_seed(void); + EAPI Evas_Bool elm_quicklaunch_prepare(int argc, char **argv); + EAPI Evas_Bool elm_quicklaunch_fork(int argc, char **argv, char *cwd); + EAPI void elm_quicklaunch_cleanup(void); + EAPI int elm_quicklaunch_fallback(int argc, char **argv); + EAPI char *elm_quicklaunch_exe_path_get(const char *exe); + EAPI void elm_object_scale_set(Evas_Object *obj, double scale); EAPI double elm_object_scale_get(Evas_Object *obj); EAPI void elm_object_focus(Evas_Object *obj); @@ -626,6 +641,13 @@ extern "C" { // * test for all bubble styles // * test for all frame styles // * test for all genlist item styles +// * test for all button styles +// * test for all hoversel styles +// * test for all inwin styles +// * test for all anchorblock styles +// * test for all anchorview styles +// * test more layout in layout +// * test normal evas (and edje) objects used as children in elm widgets // * need a way to attach a "dnd detector" to any object // * need a dnd handler (able to hook to dnd detector) // * need another sample theme diff --git a/legacy/elementary/src/lib/elm_main.c b/legacy/elementary/src/lib/elm_main.c index 552c247129..8a3fc6c02c 100644 --- a/legacy/elementary/src/lib/elm_main.c +++ b/legacy/elementary/src/lib/elm_main.c @@ -26,6 +26,7 @@ char *_elm_appname = NULL; Elm_Config *_elm_config = NULL; const char *_elm_data_dir = NULL; +static Ecore_Event_Handler *_elm_exit_handler = NULL; static Ecore_Event_Handler *_elm_event_property_change = NULL; #ifdef HAVE_ELEMENTARY_X static Ecore_X_Atom _elm_atom_enlightenment_scale = 0; @@ -75,22 +76,37 @@ _elm_rescale(void) EAPI void elm_init(int argc, char **argv) +{ + elm_quicklaunch_init(argc, argv); + elm_quicklaunch_sub_init(argc, argv); +} + +EAPI void +elm_shutdown(void) +{ + elm_quicklaunch_sub_shutdown(); + elm_quicklaunch_shutdown(); +} + +static const char *elm_engine, *elm_scale, *elm_theme, *elm_prefix, *elm_data_dir; +static const char *elm_font_hinting, *elm_font_path, *elm_image_cache; +static const char *elm_font_cache, *elm_finger_size; + +EAPI void +elm_quicklaunch_init(int argc, char **argv) { int i; - const char *elm_engine, *elm_scale, *elm_theme, *elm_prefix, *elm_data_dir; - const char *elm_font_hinting, *elm_font_path, *elm_image_cache; - const char *elm_font_cache, *elm_finger_size; char buf[PATH_MAX]; eet_init(); - ecore_init(); + ecore_init(); ecore_app_args_set(argc, (const char **)argv); ecore_file_init(); evas_init(); edje_init(); ecore_evas_init(); // FIXME: check errors - ecore_event_handler_add(ECORE_EVENT_SIGNAL_EXIT, _elm_signal_exit, NULL); + _elm_exit_handler = ecore_event_handler_add(ECORE_EVENT_SIGNAL_EXIT, _elm_signal_exit, NULL); _elm_appname = strdup(ecore_file_file_get(argv[0])); @@ -154,6 +170,19 @@ elm_init(int argc, char **argv) // FIXME: actually load config _elm_config = ELM_NEW(Elm_Config); _elm_config->engine = ELM_SOFTWARE_X11; + _elm_config->thumbscroll_enable = 1; + _elm_config->thumbscroll_threshhold = 24; + _elm_config->thumbscroll_momentum_threshhold = 100.0; + _elm_config->thumbscroll_friction = 1.0; + _elm_config->scale = 1.0; + _elm_config->font_hinting = 2; + _elm_config->font_dirs = NULL; + _elm_config->image_cache = 4096; + _elm_config->font_cache = 512; + _elm_config->finger_size = 40; + _elm_config->bgpixmap = 0; + _elm_config->compositing = 1; + if (elm_engine) { if ((!strcasecmp(elm_engine, "x11")) || @@ -190,55 +219,6 @@ elm_init(int argc, char **argv) _elm_config->engine = ELM_SOFTWARE_16_WINCE; } - _elm_config->thumbscroll_enable = 1; - _elm_config->thumbscroll_threshhold = 24; - _elm_config->thumbscroll_momentum_threshhold = 100.0; - _elm_config->thumbscroll_friction = 1.0; - _elm_config->scale = 1.0; - _elm_config->font_hinting = 2; - _elm_config->font_dirs = NULL; - _elm_config->image_cache = 4096; - _elm_config->font_cache = 512; - _elm_config->finger_size = 40; - - _elm_config->bgpixmap = 0; - _elm_config->compositing = 1; - - if ((_elm_config->engine == ELM_SOFTWARE_X11) || - (_elm_config->engine == ELM_SOFTWARE_16_X11) || - (_elm_config->engine == ELM_XRENDER_X11) || - (_elm_config->engine == ELM_OPENGL_X11) || - (_elm_config->engine == ELM_SOFTWARE_WIN32) || - (_elm_config->engine == ELM_SOFTWARE_16_WINCE)) - { -#ifdef HAVE_ELEMENTARY_X - int val = 1000; - - if (!ecore_x_init(NULL)) - { - EINA_ERROR_PERR("elementary: ERROR. Cannot connect to X11 display. check $DISPLAY variable\n"); - exit(1); - } - if (!ecore_x_screen_is_composited(0)) - _elm_config->compositing = 0; - _elm_atom_enlightenment_scale = ecore_x_atom_get("ENLIGHTENMENT_SCALE"); - ecore_x_event_mask_set(ecore_x_window_root_first_get(), - ECORE_X_EVENT_MASK_WINDOW_PROPERTY); - _elm_event_property_change = ecore_event_handler_add - (ECORE_X_EVENT_WINDOW_PROPERTY, _elm_window_property_change, NULL); - /* FIXME if quickstart this happens in child */ - if (ecore_x_window_prop_card32_get(ecore_x_window_root_first_get(), - _elm_atom_enlightenment_scale, - &val, 1) > 0) - { - if (val > 0) _elm_config->scale = (double)val / 1000.0; - } -#endif - } - - if (elm_scale) - _elm_config->scale = atof(elm_scale); - if (elm_theme) _elm_theme_parse(elm_theme); else @@ -272,7 +252,7 @@ elm_init(int argc, char **argv) len = p - pp; strncpy(buf, pp, len); buf[len] = 0; - _elm_config->font_dirs = eina_list_append(_elm_config->font_dirs, buf); + _elm_config->font_dirs = eina_list_append(_elm_config->font_dirs, eina_stringshare_add(buf)); if (*p == 0) break; p++; pp = p; @@ -291,11 +271,6 @@ elm_init(int argc, char **argv) if (elm_font_cache) _elm_config->font_cache = atoi(elm_font_cache); - _elm_config->finger_size = - (double)_elm_config->finger_size * _elm_config->scale; - if (elm_finger_size) - _elm_config->finger_size = atoi(elm_finger_size); - /* FIXME: implement quickstart below */ /* if !quickstart return * else @@ -320,24 +295,70 @@ elm_init(int argc, char **argv) } EAPI void -elm_shutdown(void) +elm_quicklaunch_sub_init(int argc, char **argv) +{ + ecore_app_args_set(argc, (const char **)argv); + if ((_elm_config->engine == ELM_SOFTWARE_X11) || + (_elm_config->engine == ELM_SOFTWARE_16_X11) || + (_elm_config->engine == ELM_XRENDER_X11) || + (_elm_config->engine == ELM_OPENGL_X11)) + { +#ifdef HAVE_ELEMENTARY_X + int val = 1000; + + if (!ecore_x_init(NULL)) + { + EINA_ERROR_PERR("elementary: ERROR. Cannot connect to X11 display. check $DISPLAY variable\n"); + exit(1); + } + if (!ecore_x_screen_is_composited(0)) + _elm_config->compositing = 0; + _elm_atom_enlightenment_scale = ecore_x_atom_get("ENLIGHTENMENT_SCALE"); + ecore_x_event_mask_set(ecore_x_window_root_first_get(), + ECORE_X_EVENT_MASK_WINDOW_PROPERTY); + _elm_event_property_change = ecore_event_handler_add + (ECORE_X_EVENT_WINDOW_PROPERTY, _elm_window_property_change, NULL); + /* FIXME if quickstart this happens in child */ + if (ecore_x_window_prop_card32_get(ecore_x_window_root_first_get(), + _elm_atom_enlightenment_scale, + &val, 1) > 0) + { + if (val > 0) _elm_config->scale = (double)val / 1000.0; + } +#endif + } + + if (elm_scale) + _elm_config->scale = atof(elm_scale); + + _elm_config->finger_size = + (double)_elm_config->finger_size * _elm_config->scale; + if (elm_finger_size) + _elm_config->finger_size = atoi(elm_finger_size); +} + +EAPI void +elm_quicklaunch_sub_shutdown(void) { _elm_win_shutdown(); - if ((_elm_config->engine == ELM_SOFTWARE_X11) || - (_elm_config->engine == ELM_SOFTWARE_16_X11) || - (_elm_config->engine == ELM_XRENDER_X11) || - (_elm_config->engine == ELM_OPENGL_X11) || - (_elm_config->engine == ELM_SOFTWARE_WIN32) || - (_elm_config->engine == ELM_SOFTWARE_16_WINCE)) + (_elm_config->engine == ELM_SOFTWARE_16_X11) || + (_elm_config->engine == ELM_XRENDER_X11) || + (_elm_config->engine == ELM_OPENGL_X11) || + (_elm_config->engine == ELM_SOFTWARE_WIN32) || + (_elm_config->engine == ELM_SOFTWARE_16_WINCE)) { #ifdef HAVE_ELEMENTARY_X ecore_event_handler_del(_elm_event_property_change); _elm_event_property_change = NULL; - ecore_x_shutdown(); + ecore_x_disconnect(); #endif } +} +EAPI void +elm_quicklaunch_shutdown(void) +{ eina_stringshare_del(_elm_data_dir); _elm_data_dir = NULL; @@ -347,6 +368,9 @@ elm_shutdown(void) _elm_config->font_dirs = eina_list_remove_list(_elm_config->font_dirs, _elm_config->font_dirs); } + ecore_event_handler_del(_elm_exit_handler); + _elm_exit_handler = NULL; + free(_elm_config); free(_elm_appname); ecore_evas_shutdown(); @@ -357,6 +381,182 @@ elm_shutdown(void) eet_shutdown(); } +EAPI void +elm_quicklaunch_seed(void) +{ + Evas_Object *win, *bg, *bt; + + win = elm_win_add(NULL, "seed", ELM_WIN_BASIC); + bg = elm_bg_add(win); + elm_win_resize_object_add(win, bg); + evas_object_show(bg); + bt = elm_button_add(win); + elm_button_label_set(bt, " abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789~-_=+\\|]}[{;:'\",<.>/?"); + elm_win_resize_object_add(win, bt); + ecore_main_loop_iterate(); + evas_object_del(win); + ecore_main_loop_iterate(); + if ((_elm_config->engine == ELM_SOFTWARE_X11) || + (_elm_config->engine == ELM_SOFTWARE_16_X11) || + (_elm_config->engine == ELM_XRENDER_X11) || + (_elm_config->engine == ELM_OPENGL_X11)) + { +#ifdef HAVE_ELEMENTARY_X + ecore_x_sync(); +#endif + } + ecore_main_loop_iterate(); +} + +static void *qr_handle = NULL; +static int (*qr_main) (int argc, char **argv) = NULL; + +EAPI Evas_Bool +elm_quicklaunch_prepare(int argc, char **argv) +{ + char *exe = elm_quicklaunch_exe_path_get(argv[0]); + if (!exe) + { + printf("ERROR: %s does not exist\n", argv[0]); + return; + } + else + { + char *exe2, *p; + char *exename; + + exe2 = malloc(strlen(exe) + 1 + 10); + strcpy(exe2, exe); + p = strrchr(exe2, '/'); + if (p) p++; + else p = exe2; + exename = alloca(strlen(p) + 1); + strcpy(exename, p); + *p = 0; + strcat(p, "../lib/"); + strcat(p, exename); + strcat(p, ".so"); + if (access(exe2, R_OK | X_OK) == 0) + { + free(exe); + exe = exe2; + } + else + free(exe2); + } + qr_handle = dlopen(exe, RTLD_NOW | RTLD_GLOBAL); + free(exe); + if (!qr_handle) return 0; + qr_main = dlsym(qr_handle, "elm_main"); + if (!qr_main) + { + dlclose(qr_handle); + qr_handle = NULL; + return 0; + } + return 1; +} + +EAPI Evas_Bool +elm_quicklaunch_fork(int argc, char **argv, char *cwd) +{ + pid_t child; + int ret; + int real_argc; + char **real_argv; + + // FIXME: + // need to accept current environment from elementary_run + if (!qr_main) + { + int i; + char **args; + + child = fork(); + if (child) return 1; + chdir(cwd); + args = alloca((argc + 1) * sizeof(char *)); + for (i = 0; i < argc; i++) args[i] = argv[i]; + args[argc] = NULL; + printf("WARNING: %s not quicklaunch capable\n", argv[0]); + exit(execvp(argv[0], args)); + } + child = fork(); + if (child) return 1; + chdir(cwd); + ret = qr_main(argc, argv); + exit(ret); +} + +EAPI void +elm_quicklaunch_cleanup(void) +{ + if (qr_handle) + { + dlclose(qr_handle); + qr_handle = NULL; + qr_main = NULL; + } +} + +EAPI int +elm_quicklaunch_fallback(int argc, char **argv) +{ + int ret; + elm_quicklaunch_init(argc, argv); + elm_quicklaunch_sub_init(argc, argv); + elm_quicklaunch_prepare(argc, argv); + ret = qr_main(argc, argv); + exit(ret); +} + +EAPI char * +elm_quicklaunch_exe_path_get(const char *exe) +{ + static char *path = NULL; + static Eina_List *pathlist = NULL; + Eina_List *l; + char buf[PATH_MAX]; + if (exe[0] == '/') return strdup(exe); + if ((exe[0] == '.') && (exe[1] == '/')) return strdup(exe); + if ((exe[0] == '.') && (exe[1] == '.') && (exe[2] == '/')) return strdup(exe); + if (!path) + { + const char *p, *pp, *s; + char *buf; + path = getenv("PATH"); + buf = alloca(strlen(path) + 1); + p = path; + pp = p; + for (;;) + { + if ((*p == ':') || (*p == 0)) + { + int len; + + len = p - pp; + strncpy(buf, pp, len); + buf[len] = 0; + pathlist = eina_list_append(pathlist, eina_stringshare_add(buf)); + if (*p == 0) break; + p++; + pp = p; + } + else + { + if (*p == 0) break; + p++; + } + } + } + for (l = pathlist; l; l = l->next) + { + snprintf(buf, sizeof(buf), "%s/%s", l->data, exe); + if (access(buf, R_OK | X_OK) == 0) return strdup(buf); + } + return NULL; +} + EAPI void elm_run(void) {