diff --git a/action_route.xml b/action_route.xml
new file mode 100644
index 0000000..b8eac15
--- /dev/null
+++ b/action_route.xml
@@ -0,0 +1,77 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/loader/loader.c b/loader/loader.c
new file mode 100644
index 0000000..fe30bcf
--- /dev/null
+++ b/loader/loader.c
@@ -0,0 +1,288 @@
+#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
+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_event_callback_add(win, EVAS_CALLBACK_DEL, win_del, NULL);
+ return win;
+}
+
+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/start.c b/loader/start.c
new file mode 100644
index 0000000..7db270b
--- /dev/null
+++ b/loader/start.c
@@ -0,0 +1,182 @@
+#include
+#include
+
+static E_Gadget_Site_Orient gorient;
+static E_Gadget_Site_Anchor ganchor;
+static char *menu_action;
+
+static void
+do_orient(Evas_Object *ly, E_Gadget_Site_Orient orient, E_Gadget_Site_Anchor anchor)
+{
+ char buf[4096];
+ const char *s = "float";
+
+ if (anchor & E_GADGET_SITE_ANCHOR_LEFT)
+ {
+ if (anchor & E_GADGET_SITE_ANCHOR_TOP)
+ {
+ switch (orient)
+ {
+ case E_GADGET_SITE_ORIENT_HORIZONTAL:
+ s = "top_left";
+ break;
+ case E_GADGET_SITE_ORIENT_VERTICAL:
+ s = "left_top";
+ break;
+ case E_GADGET_SITE_ORIENT_NONE:
+ s = "left_top";
+ break;
+ }
+ }
+ else if (anchor & E_GADGET_SITE_ANCHOR_BOTTOM)
+ {
+ switch (orient)
+ {
+ case E_GADGET_SITE_ORIENT_HORIZONTAL:
+ s = "bottom_left";
+ break;
+ case E_GADGET_SITE_ORIENT_VERTICAL:
+ s = "left_bottom";
+ break;
+ case E_GADGET_SITE_ORIENT_NONE:
+ s = "left_bottom";
+ break;
+ }
+ }
+ else
+ s = "left";
+ }
+ else if (anchor & E_GADGET_SITE_ANCHOR_RIGHT)
+ {
+ if (anchor & E_GADGET_SITE_ANCHOR_TOP)
+ {
+ switch (orient)
+ {
+ case E_GADGET_SITE_ORIENT_HORIZONTAL:
+ s = "top_right";
+ break;
+ case E_GADGET_SITE_ORIENT_VERTICAL:
+ s = "right_top";
+ break;
+ case E_GADGET_SITE_ORIENT_NONE:
+ s = "right_top";
+ break;
+ }
+ }
+ else if (anchor & E_GADGET_SITE_ANCHOR_BOTTOM)
+ {
+ switch (orient)
+ {
+ case E_GADGET_SITE_ORIENT_HORIZONTAL:
+ s = "bottom_right";
+ break;
+ case E_GADGET_SITE_ORIENT_VERTICAL:
+ s = "right_bottom";
+ break;
+ case E_GADGET_SITE_ORIENT_NONE:
+ s = "right_bottom";
+ break;
+ }
+ }
+ else
+ s = "right";
+ }
+ else if (anchor & E_GADGET_SITE_ANCHOR_TOP)
+ s = "top";
+ else if (anchor & E_GADGET_SITE_ANCHOR_BOTTOM)
+ s = "bottom";
+ else
+ {
+ switch (orient)
+ {
+ case E_GADGET_SITE_ORIENT_HORIZONTAL:
+ s = "horizontal";
+ break;
+ case E_GADGET_SITE_ORIENT_VERTICAL:
+ s = "vertical";
+ break;
+ default: break;
+ }
+ }
+ snprintf(buf, sizeof(buf), "e,state,orientation,%s", s);
+ elm_layout_signal_emit(ly, buf, "e");
+}
+
+static void
+_menu_cb_post(void *data, Evas_Object *obj EINA_UNUSED, void *event_info)
+{
+ if (eina_streq(event_info, menu_action))
+ elm_layout_signal_emit(data, "e,state,unfocused", "e");
+}
+
+static void
+_button_cb_mouse_down(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
+{
+ Evas_Event_Mouse_Down *ev = event_info;
+
+ if (ev->button != 1) return;
+ if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return;
+ if (!menu_action) return;
+ ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
+ evas_object_smart_callback_call(elm_win_get(obj), menu_action, "main");
+ elm_layout_signal_emit(obj, "e,state,focused", "e");
+}
+
+static void
+anchor_change(void *data, Evas_Object *obj EINA_UNUSED, void *event_info)
+{
+ ganchor = (uintptr_t)event_info;
+ do_orient(data, gorient, ganchor);
+}
+
+static void
+orient_change(void *data, Evas_Object *obj EINA_UNUSED, void *event_info)
+{
+ gorient = (uintptr_t)event_info;
+ do_orient(data, gorient, ganchor);
+}
+
+static void
+action_deleted(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
+{
+ if (eina_streq(menu_action, event_info))
+ {
+ free(menu_action);
+ menu_action = NULL;
+ }
+}
+
+static void
+action_return(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
+{
+ fprintf(stderr, "AR RETURN: %s\n", (char*)event_info);
+ menu_action = eina_strdup(event_info);
+}
+
+int
+main(int argc, char *argv[])
+{
+ Evas_Object *win, *ly;
+
+ elm_init(argc, (char**)argv);
+ win = elm_win_add(NULL, "start", ELM_WIN_BASIC);
+ elm_win_autodel_set(win, 1);
+ elm_win_alpha_set(win, 1);
+ ly = elm_layout_add(win);
+ evas_object_size_hint_min_set(win, 100, 100);
+ evas_object_size_hint_aspect_set(ly, EVAS_ASPECT_CONTROL_BOTH, 1, 1);
+ elm_layout_file_set(ly,
+ elm_theme_group_path_find(NULL, "e/gadget/start/main"), "e/gadget/start/main");
+ elm_win_resize_object_add(win, ly);
+ evas_object_show(ly);
+ evas_object_smart_callback_add(win, "gadget_site_anchor", anchor_change, ly);
+ evas_object_smart_callback_add(win, "gadget_site_orient", orient_change, ly);
+ evas_object_smart_callback_add(win, "gadget_action", action_return, NULL);
+ evas_object_smart_callback_add(win, "gadget_action_end", _menu_cb_post, ly);
+ evas_object_smart_callback_add(win, "gadget_action_deleted", action_deleted, NULL);
+ evas_object_event_callback_add(ly, EVAS_CALLBACK_MOUSE_DOWN, _button_cb_mouse_down, NULL);
+ evas_object_smart_callback_call(win, "gadget_action_request", "menu_show");
+ evas_object_show(win);
+ ecore_main_loop_begin();
+ return 0;
+}
diff --git a/meson.build b/meson.build
index 5c18b67..ff130de 100644
--- a/meson.build
+++ b/meson.build
@@ -135,18 +135,45 @@ if dep_efl_wl.found() == true
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_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']
+ output: '@BASENAME@-protocol.c',
+ arguments: ['code', '@INPUT@', '@OUTPUT@'])
+ protos = [
+ 'e-gadget.xml',
+ 'action_route.xml',
+ ]
+ loader_src = ['loader/loader.c']
foreach proto: protos
- build_files += gen_scanner_client.process(proto)
+ 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)
+
+ executable('e_gadget_start',
+ 'loader/start.c',
+ dependencies: [dependency('elementary'), dependency('enlightenment')],
+ install_dir: dir_bin,
+ install: true)
endif
@@ -167,4 +194,5 @@ shared_module('desksanity', build_files,
install_dir: join_paths([dir_module_e, module_arch]),
install: true)
+
meson.add_install_script('meson_modules.sh', join_paths([dir_module_e, module_arch, 'desksanity.so']))
diff --git a/src/runner.c b/src/runner.c
index 5a94229..77de9ce 100644
--- a/src/runner.c
+++ b/src/runner.c
@@ -1,5 +1,8 @@
+#define HAVE_WAYLAND
#include "e_mod_main.h"
#include
+#include "e-gadget-server-protocol.h"
+#include "action_route-server-protocol.h"
typedef enum
{
@@ -22,6 +25,8 @@ typedef struct Instance
Evas_Object *obj;
Ecore_Exe *exe;
Config_Item *ci;
+ Eina_Hash *allowed_pids;
+ void *gadget_resource;
} Instance;
typedef struct RConfig
@@ -35,16 +40,44 @@ static E_Config_DD *conf_item_edd = NULL;
static RConfig *rconfig;
static Eina_List *instances;
+static Eina_List *wizards;
static Ecore_Event_Handler *exit_handler;
typedef struct Wizard_Item
{
+ Evas_Object *site;
+ Evas_Object *popup;
E_Gadget_Wizard_End_Cb cb;
void *data;
int id;
} 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);
+
+ inst->exe = efl_wl_run(inst->obj, inst->ci->cmd);
+
+ 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)
{
@@ -66,7 +99,7 @@ _config_close(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_inf
if (!ci->cmd_changed) return;
ci->cmd_changed = 0;
if (inst->exe) ecore_exe_quit(inst->exe);
- inst->exe = efl_wl_run(inst->obj, inst->ci->cmd);
+ runner_run(inst);
}
static void
@@ -114,7 +147,7 @@ _config_cmd_activate(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
e_config_save_queue();
if (!inst) return;
if (inst->exe) ecore_exe_quit(inst->exe);
- inst->exe = efl_wl_run(inst->obj, inst->ci->cmd);
+ runner_run(inst);
}
EINTERN Evas_Object *
@@ -228,7 +261,16 @@ _conf_item_get(int *id)
}
static void
-_wizard_end(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
+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;
@@ -246,27 +288,33 @@ _wizard_end(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void
}
}
- wi->cb(wi->data, wi->id);
+ 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)
+runner_wizard(E_Gadget_Wizard_End_Cb cb, void *data, Evas_Object *site)
{
int id = 0;
Config_Item *ci;
Wizard_Item *wi;
- Evas_Object *obj;
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;
- obj = config_runner(ci, NULL);
- evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _wizard_end, wi);
- return obj;
+ wi->popup = config_runner(ci, NULL);
+ evas_object_event_callback_add(wi->popup, EVAS_CALLBACK_DEL, _wizard_config_end, wi);
+ return wi->popup;
}
/////////////////////////////////////////
@@ -288,15 +336,34 @@ runner_removed(void *data, Evas_Object *obj EINA_UNUSED, void *event_info)
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_smart_callback_del_full(e_gadget_site_get(obj), "gadget_removed", runner_removed, inst);
+ evas_object_smart_callback_del_full(e_gadget_site_get(obj), "gadget_site_anchor", runner_site_anchor, inst);
+ evas_object_smart_callback_del_full(e_gadget_site_get(obj), "gadget_site_gravity", runner_site_gravity, inst);
E_FREE_FUNC(inst->exe, ecore_exe_quit);
if (inst->ci) inst->ci->inst = NULL;
instances = eina_list_remove(instances, inst);
+ eina_hash_free(inst->allowed_pids);
free(inst);
}
@@ -316,12 +383,71 @@ runner_created(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
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_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, NULL, data, gadget_unbind);
+ inst->gadget_resource = res;
+ site = e_gadget_site_get(inst->obj);
+ 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 Evas_Object *
runner_create(Evas_Object *parent, int *id, E_Gadget_Site_Orient orient)
{
Evas_Object *obj;
Instance *inst;
Config_Item *ci = NULL;
+ int ar_version;
if (orient) return NULL;
if (*id > 0) ci = _conf_item_get(id);
@@ -338,15 +464,21 @@ runner_create(Evas_Object *parent, int *id, E_Gadget_Site_Orient orient)
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);
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);
+ 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);
evas_object_pass_events_set(inst->obj, !inst->ci->allow_events);
- inst->exe = efl_wl_run(inst->obj, inst->ci->cmd);
+ runner_run(inst);
ecore_exe_data_set(inst->exe, inst);
evas_object_event_callback_add(inst->obj, EVAS_CALLBACK_DEL, runner_del, inst);
return inst->obj;
@@ -361,7 +493,7 @@ runner_exe_del(void *d EINA_UNUSED, int t EINA_UNUSED, Ecore_Exe_Event_Del *ev)
switch (inst->ci->exit_mode)
{
case EXIT_MODE_RESTART:
- inst->exe = efl_wl_run(inst->obj, inst->ci->cmd);
+ runner_run(inst);
ecore_exe_data_set(inst->exe, inst);
break;
case EXIT_MODE_DELETE: