summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Blumenkrantz <zmike@osg.samsung.com>2018-02-27 16:06:18 -0500
committerMike Blumenkrantz <zmike@osg.samsung.com>2018-02-27 16:06:46 -0500
commit625e530764d0ba1ea5d35a74e22a5370f3b2b21a (patch)
tree880acc76b44d3e2e55d75bc7cbd84ceadb4f894f
parentbc7596d3ab02c087ce8f366452bcee997dbef39a (diff)
-rw-r--r--src/bin/e_ql_helper.c12
-rw-r--r--src/bin/e_start_quicklaunch.c20
-rw-r--r--src/bin/e_start_quicklaunch_impl.c207
-rw-r--r--src/protocol/quicklaunch.xml56
4 files changed, 293 insertions, 2 deletions
diff --git a/src/bin/e_ql_helper.c b/src/bin/e_ql_helper.c
new file mode 100644
index 000000000..4b508441a
--- /dev/null
+++ b/src/bin/e_ql_helper.c
@@ -0,0 +1,12 @@
1#include <stdio.h>
2
3int
4main(int argc, char*argv[])
5{
6 int i;
7
8 printf("%d\n", argc - 1)
9 for (i = 1; i < argc; i++)
10 printf("%s", argv[i]);
11 return 0;
12}
diff --git a/src/bin/e_start_quicklaunch.c b/src/bin/e_start_quicklaunch.c
index 1d3888e8e..7006ac817 100644
--- a/src/bin/e_start_quicklaunch.c
+++ b/src/bin/e_start_quicklaunch.c
@@ -2,6 +2,7 @@
2 2
3#include <Elementary.h> 3#include <Elementary.h>
4#include <sys/prctl.h> 4#include <sys/prctl.h>
5# include <uuid.h>
5# ifdef E_API 6# ifdef E_API
6# undef E_API 7# undef E_API
7# endif 8# endif
@@ -37,9 +38,10 @@ static Ecore_Event_Handler *signal_handler;
37static void env_set(const char *var, const char *val); 38static void env_set(const char *var, const char *val);
38E_API int prefix_determine(char *argv0); 39E_API int prefix_determine(char *argv0);
39 40
40static int e_pid = -1; 41E_API int e_pid = -1;
41static Ecore_Exe *crash_exe; 42static Ecore_Exe *crash_exe;
42static Ecore_Exe *bt_exe; 43static Ecore_Exe *bt_exe;
44static Ecore_Wl2_Display *disp;
43 45
44static void 46static void
45env_set(const char *var, const char *val) 47env_set(const char *var, const char *val)
@@ -255,16 +257,19 @@ _sig_continue(int sig)
255 sig != SIGABRT); 257 sig != SIGABRT);
256} 258}
257 259
258static void 260__attribute__((visibility("hidden"))) void
259post_fork() 261post_fork()
260{ 262{
261 ecore_event_handler_del(exit_handler); 263 ecore_event_handler_del(exit_handler);
262 ecore_event_handler_del(signal_handler); 264 ecore_event_handler_del(signal_handler);
265 ecore_wl2_display_destroy(disp);
266 disp = NULL;
263 e_pid = -1; 267 e_pid = -1;
264 e_args = NULL; 268 e_args = NULL;
265 e_argc = -1; 269 e_argc = -1;
266 prctl(PR_SET_NAME, "enlightenment", NULL, NULL, NULL); 270 prctl(PR_SET_NAME, "enlightenment", NULL, NULL, NULL);
267 prctl(PR_SET_PDEATHSIG, SIGKILL); 271 prctl(PR_SET_PDEATHSIG, SIGKILL);
272 e_start_ql_postfork();
268} 273}
269 274
270static void 275static void
@@ -554,7 +559,18 @@ main(int argc, char **argv)
554 ecore_job_add(_e_start_child, NULL); 559 ecore_job_add(_e_start_child, NULL);
555 exit_handler = ecore_event_handler_add(ECORE_EXE_EVENT_DEL, (Ecore_Event_Handler_Cb)e_exited, NULL); 560 exit_handler = ecore_event_handler_add(ECORE_EXE_EVENT_DEL, (Ecore_Event_Handler_Cb)e_exited, NULL);
556 signal_handler = ecore_event_handler_add(ECORE_EVENT_SIGNAL_USER, (Ecore_Event_Handler_Cb)e_signal, NULL); 561 signal_handler = ecore_event_handler_add(ECORE_EVENT_SIGNAL_USER, (Ecore_Event_Handler_Cb)e_signal, NULL);
562 {
563 uuid_t u;
564 char uuid[37];
565 uuid_generate(u);
566 uuid_unparse_lower(u, uuid);
567 setenv("E_QUICKLAUNCH", uuid, 1);
568 }
569 disp = ecore_wl2_display_manual_create(ql_domain);
570 e_start_ql_impl_init(disp);
557 ecore_main_loop_begin(); 571 ecore_main_loop_begin();
572 ecore_wl2_display_unlink(disp);
573 ecore_wl2_display_destroy(disp);
558 574
559 return 0; 575 return 0;
560} 576}
diff --git a/src/bin/e_start_quicklaunch_impl.c b/src/bin/e_start_quicklaunch_impl.c
new file mode 100644
index 000000000..12663b008
--- /dev/null
+++ b/src/bin/e_start_quicklaunch_impl.c
@@ -0,0 +1,207 @@
1#include <Ecore_Wl2.h>
2
3extern int e_pid;
4static Ecore_Event_Handler *ql_exe_data;
5static Ecore_Event_Handler *ql_exe_del;
6
7static Eina_Inlist *instances;
8
9typedef struct Instance
10{
11 EINA_INLIST;
12 char **argv;
13 char *cwd;
14 int argc;
15 int last;
16 Ecore_Exe_Flags flags;
17 Ecore_Exe *exe;
18} Instance;
19
20typedef struct Exe
21{
22 int pid;
23 struct wl_resource *res;
24} Exe;
25
26__attribute__((visibility("hidden"))) void post_fork();
27
28static const struct quicklaunch_exe_interface ql_exe_instance_interface =
29{
30};
31
32static void
33set_cwd(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, const char *cwd)
34{
35 Instance *inst = wl_resource_get_user_data(resource);
36 inst->cwd = eina_strdup(cwd);
37}
38
39static void
40set_flags(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, uint32_t flags)
41{
42 Instance *inst = wl_resource_get_user_data(resource);
43 inst->flags = flags;
44}
45
46static void
47ql_instance_run(struct wl_client *client, struct wl_resource *resource, uint32_t id, const char *env, uint32_t envc, struct wl_array *envoffsets)
48{
49 struct wl_resource *res;
50 Instance *inst = wl_resource_get_user_data(resource);
51 Exe *exe;
52
53 res = wl_resource_create(client, &quicklaunch_exe_interface, 1, id);
54 if (!res)
55 {
56 wl_client_post_no_memory(client);
57 return;
58 }
59 exe = calloc(1, sizeof(Exe));
60 wl_resource_set_implementation(res, &ql_exe_instance_interface, exe, ql_exe_instance_destroy);
61 if (!efl_quicklaunch_prepare(inst->argc, inst->argv, inst->cwd))
62 if (!elm_quicklaunch_prepare(inst->argc, inst->argv, inst->cwd))
63 {
64 wl_resource_destroy(res);
65 return;
66 }
67
68 exe->pid = elm_quicklaunch_fork(e_argc, e_args, e_cwd, post_fork, NULL);
69 if (exe->pid == -1)
70 {
71 wl_resource_destroy(res);
72 return;
73 }
74 elm_quicklaunch_cleanup();
75}
76
77static void
78ql_instance_destroy(struct wl_client *client, struct wl_resource *resource)
79{
80 wl_resource_destroy(resource);
81}
82
83static const struct quicklaunch_instance_interface ql_instance_interface =
84{
85 ql_instance_set_flags,
86 ql_instance_run,
87 ql_instance_destroy,
88};
89
90static void
91ql_instance_destroy(struct wl_resource *res)
92{
93 Instance *inst = wl_resource_get_user_data(res);
94 char **argv;
95
96 for (argv = inst->argv; *argv; argv++)
97 free(*argv);
98 free(inst->argv);
99 ecore_exe_free(inst->exe);
100 instances = eina_inlist_remove(instances, EINA_INLIST_GET(inst));
101 free(inst);
102}
103
104static void
105ql_instance_create(struct wl_client *client, struct wl_resource *resource, uint32_t id, const char *cmd)
106{
107 Instance *inst;
108 Eina_Strbuf *buf;
109 struct wl_resource *res;
110
111 res = wl_resource_create(client, &quicklaunch_instance_interface, 1, id);
112 if (!res)
113 {
114 wl_client_post_no_memory(client);
115 return;
116 }
117 inst = calloc(1, sizeof(Instance));
118 inst->argc = -1;
119 instances = eina_inlist_append(instances, EINA_INLIST_GET(inst));
120 buf = eina_strbuf_new();
121 eina_strbuf_append_printf(buf, "e_ql_helper %s", cmd)
122 inst->exe = ecore_exe_pipe_run(eina_strbuf_string_get(buf), ECORE_EXE_USE_SH | ECORE_EXE_NOT_LEADER | ECORE_EXE_PIPE_READ_LINE_BUFFERED, inst);
123 wl_resource_set_implementation(res, &ql_instance_interface, inst, ql_instance_destroy);
124 eina_strbuf_free(buf);
125}
126
127static const struct quicklaunch_interface ql_interface =
128{
129 ql_instance_create
130};
131
132static void
133ql_impl_bind(struct wl_client *client, void *data EINA_UNUSED, uint32_t version, uint32_t id)
134{
135 struct wl_resource *res;
136 pid_t pid;
137
138 wl_client_get_credentials(client, &pid, NULL, NULL);
139 if (pid != e_pid)
140 {
141 wl_client_post_no_memory(client);
142 return;
143 }
144 res = wl_resource_create(client, &quicklaunch_interface, version, id);
145 if (!res)
146 {
147 wl_client_post_no_memory(client);
148 return;
149 }
150
151 wl_resource_set_implementation(res, &ql_interface, NULL, NULL);
152}
153
154static Eina_Bool
155ql_data(void *d EINA_UNUSED, int t EINA_UNUSED, Ecore_Exe_Event_Data *ev)
156{
157 Instance *inst;
158
159 EINA_INLIST_FOREACH(instances, inst)
160 {
161 int i;
162
163 if (inst->exe != ev->exe) continue;
164 for (i = 0; ev->lines[i].line; i++)
165 {
166 if ((!i) && (inst->argc == -1))
167 {
168 inst->argc = strtol(ev->lines[i].line, NULL, 10);
169 inst->argv = calloc(argc + 1, sizeof(char*));
170 }
171 else
172 inst->argv[inst->last++] = strdup(ev->lines[i].line);
173 }
174 break;
175 }
176 return ECORE_CALLBACK_RENEW;
177}
178
179static Eina_Bool
180ql_del(void *d EINA_UNUSED, int t EINA_UNUSED, Ecore_Exe_Event_Del *ev)
181{
182 EINA_INLIST_FOREACH(instances, inst)
183 {
184 if (inst->exe != ev->exe) continue;
185 ecore_exe_free(inst->exe);
186 inst->exe = NULL;
187 break;
188 }
189 return ECORE_CALLBACK_RENEW;
190}
191
192__attribute__((visibility("hidden"))) void
193e_start_ql_postfork(void)
194{
195 ecore_event_handler_del(ql_exe_data);
196 ecore_event_handler_del(ql_exe_del);
197}
198
199__attribute__((visibility("hidden"))) void
200e_start_ql_impl_init(Ecore_Wl2_Display *disp)
201{
202 struct wl_display *d = ecore_wl2_display_get(disp);
203
204 wl_global_create(d, &quicklaunch_interface, 1, NULL, ql_impl_bind);
205 ql_exe_data = ecore_event_handler_add(ECORE_EXE_EVENT_DATA, (Ecore_Event_Handler_Cb)ql_data, NULL);
206 ql_exe_del = ecore_event_handler_add(ECORE_EXE_EVENT_DEL, (Ecore_Event_Handler_Cb)ql_del, NULL);
207}
diff --git a/src/protocol/quicklaunch.xml b/src/protocol/quicklaunch.xml
new file mode 100644
index 000000000..a69c839c2
--- /dev/null
+++ b/src/protocol/quicklaunch.xml
@@ -0,0 +1,56 @@
1<protocol name="zwp_quicklaunch">
2 <interface name="quicklaunch" version="1">
3 <request name="create">
4 <arg name="id" type="new_id" interface="quicklaunch_instance"/>
5 <arg name="cmd" type="string"/>
6 </request>
7 </interface>
8 <interface name="quicklaunch_instance" version="1">
9 <enum name="flags">
10 <description summary="launch flags; see ecore-exe docs"/>
11 <entry name="none" value="0"/>
12 <entry name="pipe_read" value="1"/>
13 <entry name="pipe_write" value="2"/>
14 <entry name="pipe_error" value="4"/>
15 <entry name="pipe_read_line_buffered" value="8"/>
16 <entry name="pipe_error_line_buffered" value="16"/>
17 <entry name="pipe_auto" value="32"/>
18 <entry name="respawn" value="64"/>
19 <entry name="use_sh" value="128"/>
20 <entry name="use_sh" value="256"/>
21 <entry name="term_with_parent" value="512"/>
22 <entry name="isolate_io" value="1024"/>
23 </enum>
24 <request name="set_flags">
25 <arg name="flags" type="uint"/>
26 </request>
27 <request name="set_cwd">
28 <arg name="cwd" type="string"/>
29 </request>
30 <request name="run">
31 <arg name="id" type="new_id" interface="quicklaunch_exe"/>
32 <arg name="env" type="string"/>
33 <arg name="envc" type="uint"/>
34 <arg name="envoffsets" type="array"/>
35 </request>
36 <request name="destroy" type="destructor"/>
37 </interface>
38 <interface name="quicklaunch_exe" version="1">
39 <event name="started">
40 <arg name="pid" type="int"/>
41 <arg name="read_fd" type="fd"/>
42 <arg name="write_fd" type="fd"/>
43 <arg name="error_fd" type="fd"/>
44 </event>
45 <event name="exit_signal">
46 <arg name="signal" type="int"/>
47 <arg name="code" type="int"/>
48 <arg name="timestamp" type="uint"/>
49 <arg name="errno" type="int"/>
50 </event>
51 <event name="exit_code">
52 <arg name="code" type="int"/>
53 <arg name="timestamp" type="uint"/>
54 </event>
55 </interface>
56</protocol>