From aafb9954ba1850a7173e841eef8fc0d1c4b5c3e9 Mon Sep 17 00:00:00 2001 From: Mike Blumenkrantz Date: Fri, 3 Nov 2017 11:41:14 -0400 Subject: [PATCH] remove sandbox base infra --- loader/loader.c | 310 ---------------- loader/test.c | 2 + meson.build | 44 +-- src/Makefile.mk | 4 - src/e_mod_main.c | 9 - src/e_mod_main.h | 5 - src/runner.c | 930 ----------------------------------------------- 7 files changed, 6 insertions(+), 1298 deletions(-) delete mode 100644 loader/loader.c delete mode 100644 src/runner.c diff --git a/loader/loader.c b/loader/loader.c deleted file mode 100644 index 1b32304..0000000 --- a/loader/loader.c +++ /dev/null @@ -1,310 +0,0 @@ -#include "config.h" -#define EFL_BETA_API_SUPPORT -#include -#include -#include -#include "e-gadget-client-protocol.h" -#include "action_route-client-protocol.h" -#include - -static Ecore_Event_Handler *handler; - -static Eina_Hash *wins; -static Eina_Hash *gadget_globals; -static Eina_Hash *ar_globals; -static Eina_Hash *display_actions; - -typedef struct Gadget_Action -{ - Ecore_Wl2_Display *d; - Eina_Stringshare *action; - char handle[37]; - Eina_List *requestors; - struct action_route_bind *ar_bind; -} Gadget_Action; - -static inline Ecore_Wl2_Display * -win_display_get(Evas_Object *win) -{ - Ecore_Wl2_Window *ww; - ww = elm_win_wl_window_get(win); - return ecore_wl2_window_display_get(ww); -} - -static void -wins_emit(Ecore_Wl2_Display *d, const char *sig, uint32_t val) -{ - Eina_List *l, *ll; - Evas_Object *win; - - l = eina_hash_find(wins, &d); - EINA_LIST_FOREACH(l, ll, win) - evas_object_smart_callback_call(win, sig, (uintptr_t*)(uintptr_t)val); -} - -static void -_gadget_anchor(void *data, struct e_gadget *e_gadget EINA_UNUSED, uint32_t anchor) -{ - wins_emit(data, "gadget_site_anchor", anchor); -} - -static void -_gadget_orient(void *data, struct e_gadget *e_gadget EINA_UNUSED, uint32_t orient) -{ - wins_emit(data, "gadget_site_orient", orient); -} - -static void -_gadget_gravity(void *data, struct e_gadget *e_gadget EINA_UNUSED, uint32_t gravity) -{ - wins_emit(data, "gadget_site_gravity", gravity); -} - -static const struct e_gadget_listener _gadget_listener = -{ - _gadget_anchor, - _gadget_orient, - _gadget_gravity, -}; - -static void -_gadget_global_bind(Ecore_Wl2_Display *d, uint32_t id) -{ - struct e_gadget *gadget_global = wl_registry_bind(ecore_wl2_display_registry_get(d), id, &e_gadget_interface, 1); - e_gadget_add_listener(gadget_global, &_gadget_listener, d); - eina_hash_add(gadget_globals, &d, gadget_global); -} - -static void -_ar_global_bind(Ecore_Wl2_Display *d, uint32_t id) -{ - struct action_route *ar_global = wl_registry_bind(ecore_wl2_display_registry_get(d), id, &action_route_interface, 1); - eina_hash_add(ar_globals, &d, ar_global); -} - -static Eina_Bool -_global_added(void *d EINA_UNUSED, int t EINA_UNUSED, Ecore_Wl2_Event_Global *ev) -{ - if (eina_streq(ev->interface, "e_gadget")) - _gadget_global_bind(ev->display, ev->id); - else if (eina_streq(ev->interface, "action_route")) - _ar_global_bind(ev->display, ev->id); - return ECORE_CALLBACK_RENEW; -} - -static void -_gadget_init(Ecore_Wl2_Display *d) -{ - Eina_Iterator *it; - Ecore_Wl2_Global *g; - - if (wins) - { - if (eina_hash_find(gadget_globals, &d)) return; - } - else - { - gadget_globals = eina_hash_pointer_new(NULL); - ar_globals = eina_hash_pointer_new(NULL); - } - it = ecore_wl2_display_globals_get(d); - EINA_ITERATOR_FOREACH(it, g) - { - if (eina_streq(g->interface, "e_gadget")) - _gadget_global_bind(d, g->id); - else if (eina_streq(g->interface, "action_route")) - _ar_global_bind(d, g->id); - } - eina_iterator_free(it); - if (!handler) - handler = ecore_event_handler_add(ECORE_WL2_EVENT_GLOBAL_ADDED, (Ecore_Event_Handler_Cb)_global_added, NULL); -} - -static void -_ar_bind_activate(void *data, Evas_Object *obj EINA_UNUSED, void *event_info) -{ - const char *params = event_info; - Gadget_Action *ga = data; - - if (params && (!params[0])) params = NULL; - action_route_bind_activate(ga->ar_bind, params); -} - -static void -_ar_bind_del(Gadget_Action *ga) -{ - Evas_Object *r; - eina_stringshare_del(ga->action); - EINA_LIST_FREE(ga->requestors, r) - evas_object_smart_callback_del_full(r, ga->handle, _ar_bind_activate, ga); - free(ga); -} - -static void -_ar_bind_end(void *data, struct action_route_bind *action_route_bind EINA_UNUSED) -{ - Gadget_Action *ga = data; - Eina_List *l; - Evas_Object *r; - - EINA_LIST_FOREACH(ga->requestors, l, r) - evas_object_smart_callback_call(r, "gadget_action_end", ga->handle); -} - -static void -_ar_bind_status(void *data, struct action_route_bind *action_route_bind, uint32_t state) -{ - uuid_t u; - Gadget_Action *ga = data; - Evas_Object *r; - - if (state == ACTION_ROUTE_BIND_STATE_REJECTED) - { - Eina_Hash *h; - Eina_List *l; - h = eina_hash_find(display_actions, &ga->d); - EINA_LIST_FOREACH(ga->requestors, l, r) - { - if (ga->handle[0]) - evas_object_smart_callback_call(r, "gadget_action_deleted", ga->handle); - else - evas_object_smart_callback_call(r, "gadget_action", NULL); - } - eina_hash_del_by_key(h, ga->action); - return; - } - uuid_generate(u); - uuid_unparse_lower(u, ga->handle); - ga->ar_bind = action_route_bind; - r = eina_list_data_get(ga->requestors); - evas_object_smart_callback_add(r, ga->handle, _ar_bind_activate, ga); - evas_object_smart_callback_call(r, "gadget_action", ga->handle); -} - -static const struct action_route_bind_listener _ar_bind_interface = -{ - _ar_bind_status, - _ar_bind_end -}; - -static void -uriopen_request(void *data, Evas_Object *obj EINA_UNUSED, void *event_info) -{ - Ecore_Wl2_Display *d = data; - const char *uri = event_info; - struct e_gadget *gadget_global = eina_hash_find(gadget_globals, &d); - - e_gadget_open_uri(gadget_global, uri); -} - -static void -action_request(void *data, Evas_Object *obj, void *event_info) -{ - Gadget_Action *ga; - const char *action = event_info; - Ecore_Wl2_Display *d = data; - void *ar_global; - struct action_route_bind *ar_bind; - Eina_Hash *h; - - if ((!action) || (!action[0])) - { - evas_object_smart_callback_call(obj, "gadget_action", NULL); - return; - } - if (display_actions) - { - h = eina_hash_find(display_actions, &d); - if (h) - { - ga = eina_hash_find(h, action); - if (ga && (!eina_list_data_find(ga->requestors, obj))) - { - ga->requestors = eina_list_append(ga->requestors, obj); - evas_object_smart_callback_add(obj, ga->handle, _ar_bind_activate, ga); - } - evas_object_smart_callback_call(obj, "gadget_action", ga ? ga->handle : NULL); - return; - } - } - ar_global = eina_hash_find(ar_globals, &d); - if (!ar_global) - { - evas_object_smart_callback_call(obj, "gadget_action", NULL); - return; - } - ga = calloc(1, sizeof(Gadget_Action)); - ga->d = d; - ga->requestors = eina_list_append(ga->requestors, obj); - ga->action = eina_stringshare_add(action); - if (!display_actions) - display_actions = eina_hash_string_superfast_new(NULL); - h = eina_hash_find(display_actions, &d); - if (!h) - { - h = eina_hash_pointer_new((Eina_Free_Cb)_ar_bind_del); - eina_hash_add(display_actions, &d, h); - } - - ar_bind = action_route_bind_action(ar_global, action); - action_route_bind_add_listener(ar_bind, &_ar_bind_interface, ga); - wl_display_roundtrip(ecore_wl2_display_get(d)); -} - -static void -win_del(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED) -{ - Ecore_Wl2_Display *d = win_display_get(obj); - eina_hash_list_remove(wins, &d, obj); -} - -static Evas_Object * -win_add(Evas_Object *win) -{ - Ecore_Wl2_Display *d; - if (!win) return NULL; - d = win_display_get(win); - _gadget_init(d); - if (!wins) - wins = eina_hash_pointer_new(NULL); - eina_hash_list_append(wins, &d, win); - evas_object_smart_callback_add(win, "gadget_action_request", action_request, d); - evas_object_smart_callback_add(win, "gadget_open_uri", uriopen_request, d); - evas_object_event_callback_add(win, EVAS_CALLBACK_DEL, win_del, NULL); - elm_win_borderless_set(win, 1); - return win; -} - -int -eina_init(void) -{ - int (*_eina_init)(void) = dlsym(RTLD_NEXT, __func__); - - if (wins) return _eina_init(); - if (getenv("RUNNER_DEBUG")) raise(SIGSTOP); - return _eina_init(); -} - -Evas_Object * -elm_win_util_dialog_add(Evas_Object *parent, const char *name, const char *title) -{ - Evas_Object *(*_elm_win_util_dialog_add)(Evas_Object *, const char *, const char *) = dlsym(RTLD_NEXT, __func__); - - return win_add(_elm_win_util_dialog_add(parent, name, title)); -} - -Evas_Object * -elm_win_util_standard_add(const char *name, const char *title) -{ - Evas_Object *(*_elm_win_util_standard_add)(const char *, const char *) = dlsym(RTLD_NEXT, __func__); - - return win_add(_elm_win_util_standard_add(name, title)); -} - -Evas_Object * -elm_win_add(Evas_Object *parent, const char *name, Elm_Win_Type type) -{ - Evas_Object *(*_elm_win_add)(Evas_Object *,const char*, Elm_Win_Type) = dlsym(RTLD_NEXT, __func__); - - return win_add(_elm_win_add(parent, name, type)); -} diff --git a/loader/test.c b/loader/test.c index 82c81f4..d44c278 100644 --- a/loader/test.c +++ b/loader/test.c @@ -97,6 +97,8 @@ main(int argc, char *argv[]) elm_win_alpha_set(win, EINA_TRUE); ic = elm_icon_add(win); + elm_object_tooltip_text_set(ic, "this is some test text which is probably going to be a lot longer than the overall icon size haHAA"); + elm_object_tooltip_window_mode_set(ic, 1); snprintf(buf, sizeof(buf), "%s/images/logo.png", elm_app_data_dir_get()); elm_image_file_set(ic, buf, NULL); elm_image_object_size_get(ic, &w, &h); diff --git a/meson.build b/meson.build index 12de729..ed346a8 100644 --- a/meson.build +++ b/meson.build @@ -40,7 +40,8 @@ endif endforeach add_global_arguments(dev_cflags, language: 'c') -release = 'ver-0.22' +dep_e = dependency('enlightenment') +release = dep_e.get_pkgconfig_variable('release') host_os = host_machine.system() if host_os == 'linux' if cc.has_header_symbol('features.h', '__UCLIBC__') @@ -109,8 +110,7 @@ add_global_arguments('-DPACKAGE_LIB_DIR="@0@"'.format(dir_lib), language: 'c') add_global_arguments('-DPACKAGE_DATA_DIR="@0@"'.format(join_paths(dir_data, meson.project_name())), language: 'c') add_global_arguments('-DPACKAGE_SYSCONF_DIR="@0@"'.format(dir_sysconf), language: 'c') -dep_efl_wl = dependency('efl-wl', version: '>= 1.20.99', required: false) -dep_e = dependency('enlightenment') +dep_efl_wl = dependency('efl-wl', required: false) dir_module_e = join_paths([dep_e.get_pkgconfig_variable('modules'), 'desksanity']) edje_cc = find_program('edje_cc') @@ -132,45 +132,9 @@ build_files = [ ] if dep_efl_wl.found() == true and dep_e.get_pkgconfig_variable('wayland') == 'true' - build_files += 'src/runner.c' config_h.set('HAVE_RUNNER', '1') - wayland_scanner = find_program('wayland-scanner') - gen_scanner_client = generator(wayland_scanner, - output: '@BASENAME@-client-protocol.h', - arguments: ['client-header', '@INPUT@', '@OUTPUT@']) - gen_scanner_server = generator(wayland_scanner, - output: '@BASENAME@-server-protocol.h', - arguments: ['server-header', '@INPUT@', '@OUTPUT@']) - gen_scanner_impl = generator(wayland_scanner, - output: '@BASENAME@-protocol.c', - arguments: ['code', '@INPUT@', '@OUTPUT@']) - protos = [ - 'e-gadget.xml', - 'action_route.xml', - ] - - loader_src = ['loader/loader.c'] - foreach proto: protos - loader_src += gen_scanner_client.process(proto) - loader_src += gen_scanner_impl.process(proto) - endforeach - foreach proto: protos - build_files += gen_scanner_server.process(proto) - build_files += gen_scanner_impl.process(proto) - endforeach - - shared_library('loader', loader_src, - name_prefix: '', - dependencies: [ - dependency('elementary'), - dependency('ecore-wl2'), - dependency('wayland-client'), - cc.find_library('uuid')], - install_dir: join_paths([dir_module_e, module_arch]), - install: true) - - dir_gadgets = join_paths([dir_lib, 'enlightenment/gadgets', dep_e.get_pkgconfig_variable('release')]) + dir_gadgets = join_paths([dir_lib, 'enlightenment/gadgets', module_arch]) executable('e_gadget_start', 'loader/start.c', c_args: '-fPIE', diff --git a/src/Makefile.mk b/src/Makefile.mk index 6559e64..1649c6b 100644 --- a/src/Makefile.mk +++ b/src/Makefile.mk @@ -19,10 +19,6 @@ src/zoom.c \ src/magnify.c \ src/desksanity.c -if BUILD_RUNNER -module_la_SOURCES += src/runner.c -endif - module_la_LIBADD = @E_LIBS@ module_la_LDFLAGS = -module -avoid-version module_la_DEPENDENCIES = $(top_builddir)/config.h diff --git a/src/e_mod_main.c b/src/e_mod_main.c index a77940a..1b3ce40 100644 --- a/src/e_mod_main.c +++ b/src/e_mod_main.c @@ -261,9 +261,6 @@ e_modapi_init(E_Module *m) pip_init(); zoom_init(); mag_init(); -#ifdef HAVE_RUNNER - runner_init(); -#endif E_LIST_HANDLER_APPEND(handlers, E_EVENT_CLIENT_PROPERTY, ds_client_urgent, NULL); E_LIST_HANDLER_APPEND(handlers, E_EVENT_CLIENT_REMOVE, ds_client_remove, NULL); E_LIST_HANDLER_APPEND(handlers, E_EVENT_DESK_AFTER_SHOW, ds_desk_after_show, NULL); @@ -278,9 +275,6 @@ e_modapi_init(E_Module *m) E_API int e_modapi_shutdown(E_Module *m EINA_UNUSED) { -#ifdef HAVE_RUNNER - runner_shutdown(); -#endif mag_shutdown(); zoom_shutdown(); pip_shutdown(); @@ -313,9 +307,6 @@ E_API int e_modapi_save(E_Module *m EINA_UNUSED) { e_config_domain_save("module.desksanity", conf_edd, ds_config); -#ifdef HAVE_RUNNER - runner_save(); -#endif return 1; } diff --git a/src/e_mod_main.h b/src/e_mod_main.h index 0c2904d..22d094c 100644 --- a/src/e_mod_main.h +++ b/src/e_mod_main.h @@ -106,9 +106,4 @@ EINTERN void zoom_shutdown(void); EINTERN void mag_init(void); EINTERN void mag_shutdown(void); -#ifdef HAVE_RUNNER -EINTERN void runner_init(void); -EINTERN void runner_shutdown(void); -EINTERN void runner_save(void); -#endif #endif diff --git a/src/runner.c b/src/runner.c deleted file mode 100644 index 434cdae..0000000 --- a/src/runner.c +++ /dev/null @@ -1,930 +0,0 @@ -#define HAVE_WAYLAND -#include "e_mod_main.h" -#include -#include "e-gadget-server-protocol.h" -#include "action_route-server-protocol.h" -#include - -#ifdef __GNUC__ -# pragma GCC diagnostic ignored "-Wformat-truncation" -#endif - -typedef enum -{ - EXIT_MODE_RESTART, - EXIT_MODE_DELETE, -} Exit_Mode; - -typedef struct Config_Item -{ - int id; - int exit_mode; - Eina_Stringshare *cmd; - void *inst; - Eina_Bool cmd_changed : 1; -} Config_Item; - -typedef struct Instance -{ - Evas_Object *box; - Evas_Object *obj; - Ecore_Exe *exe; - Config_Item *ci; - Eina_Hash *allowed_pids; - void *gadget_resource; - Evas_Object *popup; - Evas_Object *ctxpopup; - Eina_List *extracted; -} Instance; - -typedef struct RConfig -{ - Eina_List *items; - Evas_Object *config_dialog; -} RConfig; - -static E_Config_DD *conf_edd = NULL; -static E_Config_DD *conf_item_edd = NULL; - -static int ns_fd = -1; - -static RConfig *rconfig; -static Eina_List *instances; -static Eina_List *wizards; - -static Eina_Hash *sandbox_gadgets; - -static Eina_List *handlers; -static Eio_Monitor *gadget_monitor; -static Eio_File *gadget_lister; - -typedef struct Wizard_Item -{ - Evas_Object *site; - Evas_Object *popup; - E_Gadget_Wizard_End_Cb cb; - void *data; - int id; - Eina_Bool sandbox : 1; -} Wizard_Item; - -static void -runner_run(Instance *inst) -{ - char *preload = eina_strdup(getenv("LD_PRELOAD")); - char buf[PATH_MAX]; - char *file = ecore_file_dir_get(mod->module->file); - int pid; - - snprintf(buf, sizeof(buf), "%s/loader.so", file); - e_util_env_set("LD_PRELOAD", buf); - - snprintf(buf, sizeof(buf), "%d", inst->ci->id); - e_util_env_set("E_GADGET_ID", buf); - - unshare(CLONE_NEWPID); - - inst->exe = efl_wl_run(inst->obj, inst->ci->cmd); - - setns(ns_fd, CLONE_NEWPID); - - e_util_env_set("E_GADGET_ID", NULL); - e_util_env_set("LD_PRELOAD", preload); - free(file); - free(preload); - eina_hash_free_buckets(inst->allowed_pids); - pid = ecore_exe_pid_get(inst->exe); - eina_hash_add(inst->allowed_pids, &pid, (void*)1); -} - -static void -_config_close(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED) -{ - Config_Item *ci = data; - Instance *inst = ci->inst; - - e_comp_ungrab_input(1, 1); - rconfig->config_dialog = NULL; - if (ci->cmd_changed) - { - char *cmd; - - cmd = elm_entry_markup_to_utf8(elm_entry_entry_get(evas_object_data_get(obj, "entry"))); - eina_stringshare_replace(&ci->cmd, cmd); - free(cmd); - e_config_save_queue(); - } - if (!inst) ci->cmd_changed = 0; - if (!ci->cmd_changed) return; - ci->cmd_changed = 0; - if (inst->exe) ecore_exe_quit(inst->exe); - runner_run(inst); -} - -static void -_config_label_add(Evas_Object *tb, const char *txt, int row) -{ - Evas_Object *o; - - o = elm_label_add(tb); - E_ALIGN(o, 0, 0.5); - elm_object_text_set(o, txt); - evas_object_show(o); - elm_table_pack(tb, o, 0, row, 1, 1); -} - -static void -_config_cmd_changed(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) -{ - Config_Item *ci = data; - - ci->cmd_changed = 1; -} - -static void -_config_cmd_activate(void *data, Evas_Object *obj, void *event_info EINA_UNUSED) -{ - Config_Item *ci = data; - Instance *inst = ci->inst; - char *cmd; - - ci->cmd_changed = 0; - cmd = elm_entry_markup_to_utf8(elm_entry_entry_get(obj)); - eina_stringshare_replace(&ci->cmd, cmd); - free(cmd); - e_config_save_queue(); - if (!inst) return; - if (inst->exe) ecore_exe_quit(inst->exe); - runner_run(inst); -} - -EINTERN Evas_Object * -config_runner(Config_Item *ci, E_Zone *zone) -{ - Evas_Object *popup, *tb, *o, *ent, *rg; - int row = 0; - - if (!zone) zone = e_zone_current_get(); - popup = elm_popup_add(e_comp->elm); - E_EXPAND(popup); - evas_object_layer_set(popup, E_LAYER_POPUP); - elm_popup_allow_events_set(popup, 1); - elm_popup_scrollable_set(popup, 1); - - tb = elm_table_add(popup); - elm_table_align_set(tb, 0, 0.5); - E_EXPAND(tb); - evas_object_show(tb); - elm_object_content_set(popup, tb); - - o = evas_object_rectangle_add(e_comp->evas); - evas_object_size_hint_min_set(o, ELM_SCALE_SIZE(200), 1); - elm_table_pack(tb, o, 0, row++, 2, 1); - - _config_label_add(tb, D_("Command:"), row); - ent = o = elm_entry_add(tb); - E_FILL(o); - evas_object_show(o); - elm_entry_single_line_set(o, 1); - elm_entry_entry_set(o, ci->cmd); - evas_object_smart_callback_add(o, "changed,user", _config_cmd_changed, ci); - evas_object_smart_callback_add(o, "activated", _config_cmd_activate, ci); - elm_table_pack(tb, o, 1, row++, 1, 1); - - _config_label_add(tb, D_("On Exit:"), row); - o = rg = elm_radio_add(tb); - E_FILL(o); - evas_object_show(o); - elm_object_text_set(o, D_("Restart")); - elm_radio_state_value_set(o, EXIT_MODE_RESTART); - elm_radio_value_pointer_set(o, &ci->exit_mode); - elm_table_pack(tb, o, 1, row++, 1, 1); - - o = elm_radio_add(tb); - E_FILL(o); - elm_radio_group_add(o, rg); - evas_object_show(o); - elm_object_text_set(o, D_("Delete")); - elm_radio_state_value_set(o, EXIT_MODE_DELETE); - elm_table_pack(tb, o, 1, row++, 1, 1); - - - popup = e_comp_object_util_add(popup, E_COMP_OBJECT_TYPE_NONE); - evas_object_layer_set(popup, E_LAYER_POPUP); - evas_object_move(popup, zone->x, zone->y); - evas_object_resize(popup, zone->w / 4, zone->h / 3); - e_comp_object_util_center(popup); - evas_object_show(popup); - e_comp_object_util_autoclose(popup, NULL, e_comp_object_util_autoclose_on_escape, NULL); - evas_object_event_callback_priority_add(popup, EVAS_CALLBACK_DEL, EVAS_CALLBACK_PRIORITY_BEFORE, _config_close, ci); - evas_object_data_set(popup, "entry", ent); - e_comp_grab_input(1, 1); - - elm_object_focus_set(ent, 1); - - return rconfig->config_dialog = popup; -} - -static Config_Item * -_conf_item_get(int *id) -{ - Config_Item *ci; - Eina_List *l; - - if (*id > 0) - { - EINA_LIST_FOREACH(rconfig->items, l, ci) - if (*id == ci->id) return ci; - } - - ci = E_NEW(Config_Item, 1); - if (!*id) - *id = ci->id = rconfig->items ? eina_list_count(rconfig->items) + 1 : 1; - else - ci->id = *id; - - if (ci->id < 1) return ci; - rconfig->items = eina_list_append(rconfig->items, ci); - e_config_save_queue(); - - return ci; -} - -static void -wizard_site_del(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) -{ - Wizard_Item *wi = data; - wi->site = NULL; - evas_object_hide(wi->popup); - evas_object_del(wi->popup); -} - -static void -_wizard_config_end(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) -{ - Wizard_Item *wi = data; - Eina_List *l; - Config_Item *ci; - - EINA_LIST_FOREACH(rconfig->items, l, ci) - { - if (ci->id == wi->id) - { - if (ci->cmd) break; - wi->id = 0; - free(ci); - rconfig->items = eina_list_remove_list(rconfig->items, l); - break; - } - } - - if (wi->site) - wi->cb(wi->data, wi->id); - wizards = eina_list_remove(wizards, wi); - if (wi->site) - evas_object_event_callback_del_full(wi->site, EVAS_CALLBACK_DEL, wizard_site_del, wi); - free(wi); -} - -static Evas_Object * -runner_wizard(E_Gadget_Wizard_End_Cb cb, void *data, Evas_Object *site) -{ - int id = 0; - Config_Item *ci; - Wizard_Item *wi; - - wi = E_NEW(Wizard_Item, 1); - wi->cb = cb; - wi->data = data; - wi->site = site; - evas_object_event_callback_add(wi->site, EVAS_CALLBACK_DEL, wizard_site_del, wi); - wizards = eina_list_append(wizards, wi); - - ci = _conf_item_get(&id); - wi->id = ci->id; - wi->popup = config_runner(ci, NULL); - evas_object_event_callback_add(wi->popup, EVAS_CALLBACK_DEL, _wizard_config_end, wi); - return wi->popup; -} - -///////////////////////////////////////// - -static void -mouse_down(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) -{ - Instance *inst = data; - evas_object_focus_set(inst->obj, 1); -} - -static void -runner_removed(void *data, Evas_Object *obj EINA_UNUSED, void *event_info) -{ - Instance *inst = data; - if (inst->box != event_info) return; - rconfig->items = eina_list_remove(rconfig->items, inst->ci); - eina_stringshare_del(inst->ci->cmd); - E_FREE(inst->ci); -} - -static void -runner_site_gravity(void *data, Evas_Object *obj, void *event_info EINA_UNUSED) -{ - Instance *inst = data; - if (inst->gadget_resource) - e_gadget_send_gadget_gravity(inst->gadget_resource, e_gadget_site_gravity_get(obj)); -} - -static void -runner_site_anchor(void *data, Evas_Object *obj, void *event_info EINA_UNUSED) -{ - Instance *inst = data; - if (inst->gadget_resource) - e_gadget_send_gadget_anchor(inst->gadget_resource, e_gadget_site_anchor_get(obj)); -} - -static void -runner_del(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED) -{ - Instance *inst = data; - Evas_Object *site = e_gadget_site_get(obj); - - evas_object_smart_callback_del_full(site, "gadget_removed", runner_removed, inst); - evas_object_smart_callback_del_full(site, "gadget_site_anchor", runner_site_anchor, inst); - evas_object_smart_callback_del_full(site, "gadget_site_gravity", runner_site_gravity, inst); - if (inst->ci) - { - inst->ci->inst = NULL; - E_FREE_FUNC(inst->exe, ecore_exe_quit); - } - else - E_FREE_FUNC(inst->exe, ecore_exe_terminate); - instances = eina_list_remove(instances, inst); - eina_hash_free(inst->allowed_pids); - free(inst); -} - -static Evas_Object * -runner_gadget_configure(Evas_Object *g) -{ - Instance *inst = evas_object_data_get(g, "runner"); - return config_runner(inst->ci, e_comp_object_util_zone_get(g)); -} - -static void -runner_created(void *data, Evas_Object *obj, void *event_info EINA_UNUSED) -{ - Instance *inst = data; - if (inst->box != event_info) return; - e_gadget_configure_cb_set(inst->box, runner_gadget_configure); - evas_object_smart_callback_del_full(obj, "gadget_created", runner_created, data); -} - - -static void -gadget_unbind(struct wl_resource *resource) -{ - Instance *inst = wl_resource_get_user_data(resource); - inst->gadget_resource = NULL; -} - -static void -gadget_open_uri(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, const char *uri) -{ - Instance *inst = wl_resource_get_user_data(resource); - - /* FIXME: rate limit? */ - e_util_open(uri, NULL); -} - -static const struct e_gadget_interface _gadget_interface = -{ - .open_uri = gadget_open_uri, -}; - -static void -gadget_bind(struct wl_client *client, void *data, uint32_t version, uint32_t id) -{ - struct wl_resource *res; - Instance *inst = data; - pid_t pid; - Evas_Object *site; - - wl_client_get_credentials(client, &pid, NULL, NULL); - if (pid != ecore_exe_pid_get(inst->exe)) - { - wl_client_post_no_memory(client); - return; - } - - res = wl_resource_create(client, &e_gadget_interface, version, id); - wl_resource_set_implementation(res, &_gadget_interface, data, gadget_unbind); - inst->gadget_resource = res; - site = e_gadget_site_get(inst->box); - e_gadget_send_gadget_orient(res, e_gadget_site_orient_get(site)); - e_gadget_send_gadget_gravity(res, e_gadget_site_gravity_get(site)); - e_gadget_send_gadget_anchor(res, e_gadget_site_anchor_get(site)); -} - -static void -ar_bind(struct wl_client *client, void *data, uint32_t version, uint32_t id) -{ - struct wl_resource *res; - Instance *inst = data; - int v; - const void *ar_interface; - pid_t pid; - - wl_client_get_credentials(client, &pid, NULL, NULL); - if (pid != ecore_exe_pid_get(inst->exe)) - { - wl_client_post_no_memory(client); - return; - } - ar_interface = e_comp_wl_extension_action_route_interface_get(&v); - - if (!(res = wl_resource_create(client, &action_route_interface, MIN(v, version), id))) - { - wl_client_post_no_memory(client); - return; - } - - wl_resource_set_implementation(res, ar_interface, inst->allowed_pids, NULL); -} - -static void -child_close(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED) -{ - Instance *inst = data; - Evas_Object *ext; - - inst->popup = NULL; - ext = evas_object_data_get(obj, "extracted"); - elm_box_unpack_all(obj); - inst->extracted = eina_list_remove(inst->extracted, ext); - evas_object_hide(ext); -} - -static void -child_added(void *data, Evas_Object *obj, void *event_info) -{ - Evas_Object *popup, *bx; - E_Zone *zone = e_comp_object_util_zone_get(obj); - Instance *inst = data; - - if (!efl_wl_surface_extract(event_info)) return; - inst->extracted = eina_list_append(inst->extracted, event_info); - - popup = elm_popup_add(e_comp->elm); - e_comp_object_util_del_list_append(event_info, popup); - E_EXPAND(popup); - evas_object_layer_set(popup, E_LAYER_POPUP); - elm_popup_allow_events_set(popup, 1); - elm_popup_scrollable_set(popup, 1); - - bx = elm_box_add(popup); - E_EXPAND(event_info); - E_FILL(event_info); - elm_box_homogeneous_set(bx, 1); - evas_object_show(bx); - elm_box_pack_end(bx, event_info); - elm_object_content_set(popup, bx); - - inst->popup = popup = e_comp_object_util_add(popup, E_COMP_OBJECT_TYPE_NONE); - evas_object_layer_set(popup, E_LAYER_POPUP); - evas_object_move(popup, zone->x, zone->y); - evas_object_resize(popup, zone->w / 4, zone->h / 3); - e_comp_object_util_center(popup); - evas_object_show(popup); - e_comp_canvas_feed_mouse_up(0); - e_comp_object_util_autoclose(popup, NULL, e_comp_object_util_autoclose_on_escape, NULL); - evas_object_event_callback_add(bx, EVAS_CALLBACK_DEL, child_close, inst); - evas_object_data_set(bx, "extracted", event_info); - evas_object_focus_set(event_info, 1); -} - -static void -popup_del(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED) -{ - Instance *inst = data; - Evas_Object *ext; - - inst->ctxpopup = NULL; - ext = evas_object_data_get(obj, "extracted"); - elm_box_unpack_all(obj); - inst->extracted = eina_list_remove(inst->extracted, ext); - evas_object_hide(ext); -} - -static void -popup_dismissed(void *data EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED) -{ - evas_object_del(obj); -} - -static void -popup_hide(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) -{ - Instance *inst = data; - elm_ctxpopup_dismiss(inst->ctxpopup); - evas_object_del(elm_object_content_get(inst->ctxpopup)); -} - -static void -popup_hints_update(Evas_Object *obj) -{ - double w, h; - E_Zone *zone = e_comp_object_util_zone_get(obj); - - evas_object_size_hint_weight_get(obj, &w, &h); - w = E_CLAMP(w, 0, 0.5); - h = E_CLAMP(h, 0, 0.5); - - if ((w > 0) && (h > 0)) - { - evas_object_size_hint_min_set(obj, w * zone->w, h * zone->h); - evas_object_size_hint_max_set(obj, w * zone->w, h * zone->h); - } - if ((!EINA_DBL_NONZERO(w)) && (!EINA_DBL_NONZERO(h))) - { - int ww, hh; - evas_object_geometry_get(obj, NULL, NULL, &ww, &hh); - evas_object_size_hint_min_set(obj, ww, hh); - } - E_WEIGHT(obj, 0, 0); -} - -static void -popup_hints(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED) -{ - evas_object_event_callback_del_full(obj, EVAS_CALLBACK_CHANGED_SIZE_HINTS, popup_hints, data); - popup_hints_update(obj); - evas_object_event_callback_add(obj, EVAS_CALLBACK_CHANGED_SIZE_HINTS, popup_hints, data); -} - -static void -popup_added(void *data, Evas_Object *obj EINA_UNUSED, void *event_info) -{ - Instance *inst = data; - Evas_Object *bx; - - if (!efl_wl_surface_extract(event_info)) return; - inst->extracted = eina_list_append(inst->extracted, event_info); - - inst->ctxpopup = elm_ctxpopup_add(inst->box); - elm_object_style_set(inst->ctxpopup, "noblock"); - evas_object_smart_callback_add(inst->ctxpopup, "dismissed", popup_dismissed, inst); - evas_object_event_callback_add(event_info, EVAS_CALLBACK_DEL, popup_hide, inst); - - bx = elm_box_add(inst->ctxpopup); - popup_hints_update(event_info); - E_FILL(event_info); - evas_object_event_callback_add(event_info, EVAS_CALLBACK_CHANGED_SIZE_HINTS, popup_hints, inst); - evas_object_show(bx); - elm_box_pack_end(bx, event_info); - elm_box_recalculate(bx); - evas_object_data_set(bx, "extracted", event_info); - evas_object_event_callback_add(bx, EVAS_CALLBACK_DEL, popup_del, inst); - elm_object_content_set(inst->ctxpopup, bx); - - e_gadget_util_ctxpopup_place(inst->box, inst->ctxpopup, NULL); - evas_object_show(inst->ctxpopup); - evas_object_focus_set(event_info, 1); -} - -static void -runner_hints(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED) -{ - Instance *inst = data; - int w, h; - Evas_Aspect_Control aspect; - - evas_object_size_hint_min_get(obj, &w, &h); - evas_object_size_hint_min_set(inst->box, w, h); - evas_object_size_hint_max_get(obj, &w, &h); - evas_object_size_hint_max_set(inst->box, w, h); - evas_object_size_hint_aspect_get(obj, &aspect, &w, &h); - evas_object_size_hint_aspect_set(inst->box, aspect, w, h); -} - -static Evas_Object * -gadget_create(Evas_Object *parent, Config_Item *ci, int *id, E_Gadget_Site_Orient orient) -{ - Instance *inst; - int ar_version; - - inst = E_NEW(Instance, 1); - instances = eina_list_append(instances, inst); - inst->ci = ci; - if (!inst->ci) - inst->ci = _conf_item_get(id); - inst->ci->inst = inst; - inst->allowed_pids = eina_hash_int32_new(NULL); - inst->obj = efl_wl_add(e_comp->evas); - E_EXPAND(inst->obj); - E_FILL(inst->obj); - evas_object_show(inst->obj); - efl_wl_aspect_set(inst->obj, 1); - efl_wl_minmax_set(inst->obj, 1); - efl_wl_global_add(inst->obj, &e_gadget_interface, 1, inst, gadget_bind); - evas_object_smart_callback_add(inst->obj, "child_added", child_added, inst); - evas_object_smart_callback_add(inst->obj, "popup_added", popup_added, inst); - e_comp_wl_extension_action_route_interface_get(&ar_version); - efl_wl_global_add(inst->obj, &action_route_interface, ar_version, inst, ar_bind); - evas_object_data_set(inst->obj, "runner", inst); - evas_object_event_callback_add(inst->obj, EVAS_CALLBACK_MOUSE_DOWN, mouse_down, inst); - evas_object_smart_callback_add(parent, "gadget_created", runner_created, inst); - evas_object_smart_callback_add(parent, "gadget_removed", runner_removed, inst); - evas_object_smart_callback_add(parent, "gadget_site_anchor", runner_site_anchor, inst); - evas_object_smart_callback_add(parent, "gadget_site_gravity", runner_site_gravity, inst); - runner_run(inst); - ecore_exe_data_set(inst->exe, inst); - inst->box = elm_box_add(e_comp->elm); - e_util_size_debug_set(inst->box, 1); - evas_object_event_callback_add(inst->box, EVAS_CALLBACK_DEL, runner_del, inst); - evas_object_event_callback_add(inst->obj, EVAS_CALLBACK_CHANGED_SIZE_HINTS, runner_hints, inst); - elm_box_homogeneous_set(inst->box, 1); - elm_box_pack_end(inst->box, inst->obj); - return inst->box; -} - -static Evas_Object * -runner_create(Evas_Object *parent, int *id, E_Gadget_Site_Orient orient) -{ - Evas_Object *obj; - Config_Item *ci = NULL; - - if (orient) return NULL; - if (*id > 0) ci = _conf_item_get(id); - if ((*id < 0) || ci->inst) - { - obj = elm_image_add(parent); - elm_image_file_set(obj, e_theme_edje_file_get(NULL, "e/icons/modules-launcher"), "e/icons/modules-launcher"); - evas_object_size_hint_aspect_set(obj, EVAS_ASPECT_CONTROL_BOTH, 1, 1); - return obj; - } - return gadget_create(parent, ci, id, orient); -} - -static Eina_Bool -runner_exe_del(void *d EINA_UNUSED, int t EINA_UNUSED, Ecore_Exe_Event_Del *ev) -{ - Instance *inst = ecore_exe_data_get(ev->exe); - - if ((!inst) || (!instances) || (!eina_list_data_find(instances, inst))) return ECORE_CALLBACK_RENEW; - switch (inst->ci->exit_mode) - { - case EXIT_MODE_RESTART: - /* FIXME: probably notify? */ - if (ev->exit_code == 255) //exec error - e_gadget_del(inst->box); - else - { - runner_run(inst); - ecore_exe_data_set(inst->exe, inst); - } - break; - case EXIT_MODE_DELETE: - e_gadget_del(inst->box); - break; - } - return ECORE_CALLBACK_RENEW; -} - -/////////////////////////////// - -static Evas_Object * -sandbox_create(Evas_Object *parent, const char *type, int *id, E_Gadget_Site_Orient orient) -{ - Efreet_Desktop *ed = eina_hash_find(sandbox_gadgets, type); - Config_Item *ci = NULL; - - if (*id > 0) ci = _conf_item_get(id); - if ((*id < 0) || (ci && ci->inst)) - { - if (ed->x) - { - const char *orients = eina_hash_find(ed->x, "X-Gadget-Orientations"); - - if (orients) - { - const char *ostring[] = - { - "None", - "Horizontal", - "Vertical", - }; - char *v, *val = strdup(orients); - Eina_Bool found = EINA_FALSE; - - for (v = strtok(val, ";"); v; v = strtok(NULL, ";")) - if (!strcmp(v, ostring[orient])) - { - found = EINA_TRUE; - break; - } - free(val); - if (!found) return NULL; - } - } - if (ed->icon) - { - int w, h; - Eina_Bool fail = EINA_FALSE; - Evas_Object *obj; - - obj = elm_image_add(parent); - if (ed->icon[0] == '/') - { - if (eina_str_has_extension(ed->icon, ".edj")) - fail = !elm_image_file_set(obj, ed->icon, "icon"); - else - fail = !elm_image_file_set(obj, ed->icon, NULL); - } - else - { - if (!elm_image_file_set(obj, e_theme_edje_file_get(NULL, ed->icon), ed->icon)) - fail = !elm_icon_standard_set(obj, ed->icon); - } - if (!fail) - { - elm_image_object_size_get(obj, &w, &h); - if (w && h) - evas_object_size_hint_aspect_set(obj, EVAS_ASPECT_CONTROL_BOTH, w, h); - return obj; - } - evas_object_del(obj); - } - } - if (!ci) - { - ci = _conf_item_get(id); - ci->cmd = eina_stringshare_add(ed->exec); - ci->exit_mode = EXIT_MODE_RESTART; - } - return gadget_create(parent, ci, id, orient); -} - -static char * -sandbox_name(const char *filename) -{ - Efreet_Desktop *ed = eina_hash_find(sandbox_gadgets, filename); - const char *name = ed->name ?: ed->generic_name; - char buf[1024]; - - if (name) return strdup(name); - strncpy(buf, ed->orig_path, sizeof(buf) - 1); - buf[0] = toupper(buf[0]); - return strdup(buf); -} - -/////////////////////////////// - -static void -gadget_dir_add(const char *filename) -{ - const char *file; - char buf[PATH_MAX]; - Efreet_Desktop *ed; - - file = ecore_file_file_get(filename); - snprintf(buf, sizeof(buf), "%s/%s.desktop", filename, file); - ed = efreet_desktop_new(buf); - EINA_SAFETY_ON_NULL_RETURN(ed); - eina_hash_add(sandbox_gadgets, filename, ed); - e_gadget_external_type_add("runner_sandbox", filename, sandbox_create, NULL); - e_gadget_external_type_name_cb_set("runner_sandbox", filename, sandbox_name); -} - -static Eina_Bool -monitor_dir_create(void *d EINA_UNUSED, int t EINA_UNUSED, Eio_Monitor_Event *ev) -{ - if (!eina_hash_find(sandbox_gadgets, ev->filename)) - gadget_dir_add(ev->filename); - return ECORE_CALLBACK_RENEW; -} - -static Eina_Bool -monitor_dir_del(void *d EINA_UNUSED, int t EINA_UNUSED, Eio_Monitor_Event *ev) -{ - eina_hash_del_by_key(sandbox_gadgets, ev->filename); - e_gadget_external_type_del("runner_sandbox", ev->filename); - return ECORE_CALLBACK_RENEW; -} - -static Eina_Bool -monitor_error(void *d EINA_UNUSED, int t EINA_UNUSED, Eio_Monitor_Error *ev) -{ - /* panic? */ - return ECORE_CALLBACK_RENEW; -} - - -static Eina_Bool -list_filter_cb(void *d EINA_UNUSED, Eio_File *ls EINA_UNUSED, const Eina_File_Direct_Info *info) -{ - struct stat st; - char buf[PATH_MAX]; - - if (info->type != EINA_FILE_DIR) return EINA_FALSE; - if (info->path[info->name_start] == '.') return EINA_FALSE; - snprintf(buf, sizeof(buf), "%s/%s.desktop", info->path, info->path + info->name_start); - return !stat(info->path, &st); -} - -static void -list_main_cb(void *d EINA_UNUSED, Eio_File *ls EINA_UNUSED, const Eina_File_Direct_Info *info) -{ - gadget_dir_add(info->path); -} - -static void -list_done_cb(void *d EINA_UNUSED, Eio_File *ls EINA_UNUSED) -{ - gadget_lister = NULL; -} - -static void -list_error_cb(void *d EINA_UNUSED, Eio_File *ls EINA_UNUSED, int error EINA_UNUSED) -{ - gadget_lister = NULL; -} - -EINTERN void -runner_init(void) -{ - conf_item_edd = E_CONFIG_DD_NEW("Config_Item", Config_Item); -#undef T -#undef D -#define T Config_Item -#define D conf_item_edd - E_CONFIG_VAL(D, T, id, INT); - E_CONFIG_VAL(D, T, exit_mode, INT); - E_CONFIG_VAL(D, T, cmd, STR); - - conf_edd = E_CONFIG_DD_NEW("RConfig", RConfig); -#undef T -#undef D -#define T RConfig -#define D conf_edd - E_CONFIG_LIST(D, T, items, conf_item_edd); - - rconfig = e_config_domain_load("module.runner", conf_edd); - if (!rconfig) rconfig = E_NEW(RConfig, 1); - - e_gadget_type_add("runner", runner_create, runner_wizard); - { - gadget_monitor = eio_monitor_add(GADGET_DIR); - gadget_lister = eio_file_direct_ls(GADGET_DIR, list_filter_cb, list_main_cb, list_done_cb, list_error_cb, NULL); - } - E_LIST_HANDLER_APPEND(handlers, ECORE_EXE_EVENT_DEL, runner_exe_del, NULL); - E_LIST_HANDLER_APPEND(handlers, EIO_MONITOR_DIRECTORY_CREATED, monitor_dir_create, NULL); - E_LIST_HANDLER_APPEND(handlers, EIO_MONITOR_DIRECTORY_DELETED, monitor_dir_del, NULL); - E_LIST_HANDLER_APPEND(handlers, EIO_MONITOR_ERROR, monitor_error, NULL); - - sandbox_gadgets = eina_hash_string_superfast_new((Eina_Free_Cb)efreet_desktop_free); - { - char buf[PATH_MAX]; - - snprintf(buf, sizeof(buf), "/proc/%d/ns/pid", getpid()); - ns_fd = open(buf, O_RDONLY); - } -} - -EINTERN void -runner_shutdown(void) -{ - e_gadget_type_del("runner"); - e_gadget_external_type_del("runner_sandbox", NULL); - - if (rconfig) - { - Config_Item *ci; - - if (rconfig->config_dialog) - { - evas_object_hide(rconfig->config_dialog); - evas_object_del(rconfig->config_dialog); - } - - EINA_LIST_FREE(rconfig->items, ci) - { - eina_stringshare_del(ci->cmd); - free(ci); - } - - } - E_FREE(rconfig); - E_CONFIG_DD_FREE(conf_edd); - E_CONFIG_DD_FREE(conf_item_edd); - E_FREE_LIST(handlers, ecore_event_handler_del); - E_FREE_FUNC(sandbox_gadgets, eina_hash_free); - E_FREE_FUNC(gadget_lister, eio_file_cancel); - close(ns_fd); - ns_fd = -1; -} - -EINTERN void -runner_save(void) -{ - e_config_domain_save("module.runner", conf_edd, rconfig); -}