summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Blumenkrantz <zmike@osg.samsung.com>2017-01-13 11:35:26 -0500
committerMike Blumenkrantz <zmike@osg.samsung.com>2017-01-13 11:34:50 -0500
commit5aadf3b3ffe3c6876f795cea03566105625c9748 (patch)
tree8b46d1b3053de159916efc882c6839986bfdf550
parentd1bb23954fc312f8ee025c3a0b43a1d21708c33d (diff)
implement xdg-foreign v1
Reviewed-by: Derek Foreman <derekf@osg.samsung.com>
-rw-r--r--src/bin/Makefile.mk8
-rw-r--r--src/bin/e_comp_wl.h11
-rw-r--r--src/bin/e_comp_wl_extensions.c226
-rw-r--r--src/protocol/xdg-foreign-unstable-v1.xml182
4 files changed, 425 insertions, 2 deletions
diff --git a/src/bin/Makefile.mk b/src/bin/Makefile.mk
index e214a7d44..667a644b7 100644
--- a/src/bin/Makefile.mk
+++ b/src/bin/Makefile.mk
@@ -443,11 +443,15 @@ src/bin/generated/session-recovery-server-protocol.h \
443src/bin/generated/www-protocol.c \ 443src/bin/generated/www-protocol.c \
444src/bin/generated/www-server-protocol.h \ 444src/bin/generated/www-server-protocol.h \
445src/bin/generated/screenshooter-protocol.c \ 445src/bin/generated/screenshooter-protocol.c \
446src/bin/generated/screenshooter-server-protocol.h 446src/bin/generated/screenshooter-server-protocol.h \
447src/bin/generated/xdg-foreign-unstable-v1-protocol.c \
448src/bin/generated/xdg-foreign-unstable-v1-server-protocol.h
447 449
448src/bin/e_comp_wl_extensions.c: \ 450src/bin/e_comp_wl_extensions.c: \
449 src/bin/generated/screenshooter-server-protocol.h \ 451 src/bin/generated/screenshooter-server-protocol.h \
450 src/bin/generated/session-recovery-server-protocol.h 452 src/bin/generated/session-recovery-server-protocol.h \
453 src/bin/generated/xdg-foreign-unstable-v1-protocol.c \
454 src/bin/generated/xdg-foreign-unstable-v1-server-protocol.h
451 455
452src/bin/e_comp_wl.c: \ 456src/bin/e_comp_wl.c: \
453 src/bin/generated/www-server-protocol.h 457 src/bin/generated/www-server-protocol.h
diff --git a/src/bin/e_comp_wl.h b/src/bin/e_comp_wl.h
index 48ff97ad6..8d0ac5a90 100644
--- a/src/bin/e_comp_wl.h
+++ b/src/bin/e_comp_wl.h
@@ -110,6 +110,17 @@ typedef struct E_Comp_Wl_Extension_Data
110 { 110 {
111 struct wl_global *global; 111 struct wl_global *global;
112 } www; 112 } www;
113 /* begin xdg-foreign */
114 struct
115 {
116 struct wl_global *global;
117 Eina_Hash *surfaces;
118 } zxdg_exporter_v1;
119 struct
120 {
121 struct wl_global *global;
122 } zxdg_importer_v1;
123 /* end xdg-foreign */
113} E_Comp_Wl_Extension_Data; 124} E_Comp_Wl_Extension_Data;
114 125
115struct _E_Comp_Wl_Data 126struct _E_Comp_Wl_Data
diff --git a/src/bin/e_comp_wl_extensions.c b/src/bin/e_comp_wl_extensions.c
index ea9833df6..517579b27 100644
--- a/src/bin/e_comp_wl_extensions.c
+++ b/src/bin/e_comp_wl_extensions.c
@@ -6,6 +6,26 @@
6#include "screenshooter-server-protocol.h" 6#include "screenshooter-server-protocol.h"
7#include "session-recovery-server-protocol.h" 7#include "session-recovery-server-protocol.h"
8#include "www-server-protocol.h" 8#include "www-server-protocol.h"
9#include "xdg-foreign-unstable-v1-server-protocol.h"
10
11/* mutter uses 32, seems reasonable */
12#define HANDLE_LEN 32
13
14typedef struct Exported
15{
16 E_Client *ec;
17 struct wl_resource *res;
18 char handle[HANDLE_LEN + 1];
19 Eina_List *imported;
20} Exported;
21
22typedef struct Imported
23{
24 /* child */
25 E_Client *ec;
26 struct wl_resource *res;
27 Exported *ex;
28} Imported;
9 29
10static void 30static void
11_e_comp_wl_extensions_client_move_begin(void *d EINA_UNUSED, E_Client *ec) 31_e_comp_wl_extensions_client_move_begin(void *d EINA_UNUSED, E_Client *ec)
@@ -207,6 +227,195 @@ _e_comp_wl_www_cb_create(struct wl_client *client, struct wl_resource *resource,
207 e_object_ref(E_OBJECT(ec)); 227 e_object_ref(E_OBJECT(ec));
208} 228}
209 229
230///////////////////////////////////////////////////////
231
232static void
233_e_comp_wl_zxdg_exported_v1_destroy(struct wl_client *client EINA_UNUSED, struct wl_resource *resource)
234{
235 wl_resource_destroy(resource);
236}
237
238static void _imported_v1_del(Imported *im);
239static void _exported_del(void *data, Evas *e, Evas_Object *obj, void *event_info);
240
241static void
242_exported_v1_del(Exported *ex)
243{
244 while (ex->imported)
245 {
246 Imported *im = eina_list_data_get(ex->imported);
247
248 zxdg_imported_v1_send_destroyed(im->res);
249 _imported_v1_del(im);
250 }
251 evas_object_event_callback_del(ex->ec->frame, EVAS_CALLBACK_DEL, _exported_del);
252 wl_resource_set_user_data(ex->res, NULL);
253 eina_hash_del_by_key(e_comp_wl->extensions->zxdg_exporter_v1.surfaces, ex->handle);
254 free(ex);
255}
256
257static void
258_e_zxdg_exported_v1_del(struct wl_resource *resource)
259{
260 Exported *ex = wl_resource_get_user_data(resource);
261
262 if (ex) _exported_v1_del(ex);
263}
264
265static void
266_exported_del(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
267{
268 _exported_v1_del(data);
269}
270
271static void
272_e_comp_wl_zxdg_exporter_v1_exporter_destroy(struct wl_client *client EINA_UNUSED, struct wl_resource *resource)
273{
274 wl_resource_destroy(resource);
275}
276
277static const struct zxdg_exported_v1_interface _e_zxdg_exported_v1_interface =
278{
279 _e_comp_wl_zxdg_exported_v1_destroy,
280};
281
282static void
283_e_comp_wl_zxdg_exporter_v1_export(struct wl_client *client, struct wl_resource *resource, uint32_t id, struct wl_resource *surface)
284{
285 E_Client *ec = wl_resource_get_user_data(surface);
286 Exported *ex;
287
288 if ((!ec) || (!ec->comp_data->is_xdg_surface) || ec->comp_data->cursor)
289 {
290 wl_resource_post_error(resource, WL_DISPLAY_ERROR_INVALID_OBJECT, "invalid role for exported surface");
291 return;
292 }
293
294 ex = E_NEW(Exported, 1);
295 ex->ec = ec;
296 ex->res = wl_resource_create(client, &zxdg_exported_v1_interface, wl_resource_get_version(resource), id);
297 wl_resource_set_implementation(ex->res, &_e_zxdg_exported_v1_interface, ex, _e_zxdg_exported_v1_del);
298 evas_object_event_callback_add(ec->frame, EVAS_CALLBACK_DEL, _exported_del, ex);
299
300 do
301 {
302 int n;
303
304 for (n = 0; n < HANDLE_LEN; n++)
305 {
306 /* only printable ascii */
307 ex->handle[n] = (rand() % (127 - 32)) + 32;
308 }
309 } while (eina_hash_find(e_comp_wl->extensions->zxdg_exporter_v1.surfaces, ex->handle));
310 eina_hash_add(e_comp_wl->extensions->zxdg_exporter_v1.surfaces, ex->handle, ex);
311
312 zxdg_exported_v1_send_handle(ex->res, ex->handle);
313}
314
315
316static void
317_e_comp_wl_zxdg_imported_v1_destroy(struct wl_client *client EINA_UNUSED, struct wl_resource *resource)
318{
319 wl_resource_destroy(resource);
320}
321
322static void _imported_del(void *data, Evas *e, Evas_Object *obj, void *event_info);
323
324static void
325_imported_v1_del(Imported *im)
326{
327 im->ex->imported = eina_list_remove(im->ex->imported, im);
328 if (im->ec)
329 {
330 evas_object_event_callback_del(im->ec->frame, EVAS_CALLBACK_DEL, _imported_del);
331 e_client_parent_set(im->ec, NULL);
332 }
333 if (im->res) wl_resource_set_user_data(im->res, NULL);
334 free(im);
335}
336
337static void
338_e_zxdg_imported_v1_del(struct wl_resource *resource)
339{
340 Imported *im = wl_resource_get_user_data(resource);
341
342 if (im) _imported_v1_del(im);
343}
344
345static void
346_imported_del(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
347{
348 Imported *im = data;
349
350 im->ec = NULL;
351}
352
353static void
354_e_comp_wl_zxdg_importer_v1_importer_destroy(struct wl_client *client EINA_UNUSED, struct wl_resource *resource)
355{
356 wl_resource_destroy(resource);
357}
358
359static void
360_e_comp_wl_zxdg_imported_v1_set_parent_of(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, struct wl_resource *surface_resource)
361{
362 Imported *im = wl_resource_get_user_data(resource);
363 E_Client *ec = NULL;
364
365 if (surface_resource) ec = wl_resource_get_user_data(surface_resource);
366
367 if (ec && ((ec->netwm.type != E_WINDOW_TYPE_NORMAL) || (!ec->comp_data->is_xdg_surface)))
368 {
369 wl_resource_post_error(im->res, WL_DISPLAY_ERROR_INVALID_OBJECT,
370 "xdg_imported.set_parent_of called with invalid surface");
371 return;
372 }
373
374 if (im->ec)
375 evas_object_event_callback_del(im->ec->frame, EVAS_CALLBACK_DEL, _imported_del);
376
377 im->ec = ec;
378
379 if (ec)
380 {
381 evas_object_event_callback_add(ec->frame, EVAS_CALLBACK_DEL, _imported_del, im);
382 e_client_parent_set(ec, im->ex->ec);
383 ec->parent->modal = ec;
384 ec->parent->lock_close = 1;
385 }
386}
387
388static const struct zxdg_imported_v1_interface _e_zxdg_imported_v1_interface =
389{
390 _e_comp_wl_zxdg_imported_v1_destroy,
391 _e_comp_wl_zxdg_imported_v1_set_parent_of,
392};
393
394static void
395_e_comp_wl_zxdg_importer_v1_import(struct wl_client *client, struct wl_resource *resource, uint32_t id, const char *handle)
396{
397 Imported *im;
398 Exported *ex;
399
400 im = E_NEW(Imported, 1);
401 im->res = wl_resource_create(client, &zxdg_imported_v1_interface, wl_resource_get_version(resource), id);
402 wl_resource_set_implementation(im->res, &_e_zxdg_imported_v1_interface, NULL, _e_zxdg_imported_v1_del);
403
404 ex = eina_hash_find(e_comp_wl->extensions->zxdg_exporter_v1.surfaces, handle);
405 if ((!ex) || (!ex->ec->netwm.type))
406 {
407 zxdg_imported_v1_send_destroyed(im->res);
408 free(im);
409 return;
410 }
411
412 im->ex = ex;
413 wl_resource_set_user_data(im->res, im);
414 ex->imported = eina_list_append(ex->imported, im);
415}
416
417/////////////////////////////////////////////////////////
418
210static const struct zwp_e_session_recovery_interface _e_session_recovery_interface = 419static const struct zwp_e_session_recovery_interface _e_session_recovery_interface =
211{ 420{
212 _e_comp_wl_session_recovery_get_uuid, 421 _e_comp_wl_session_recovery_get_uuid,
@@ -224,6 +433,18 @@ static const struct www_interface _e_www_interface =
224 _e_comp_wl_www_cb_create 433 _e_comp_wl_www_cb_create
225}; 434};
226 435
436static const struct zxdg_exporter_v1_interface _e_zxdg_exporter_v1_interface =
437{
438 _e_comp_wl_zxdg_exporter_v1_exporter_destroy,
439 _e_comp_wl_zxdg_exporter_v1_export,
440};
441
442static const struct zxdg_importer_v1_interface _e_zxdg_importer_v1_interface =
443{
444 _e_comp_wl_zxdg_importer_v1_importer_destroy,
445 _e_comp_wl_zxdg_importer_v1_import,
446};
447
227 448
228#define GLOBAL_BIND_CB(NAME, IFACE, ...) \ 449#define GLOBAL_BIND_CB(NAME, IFACE, ...) \
229static void \ 450static void \
@@ -244,6 +465,8 @@ _e_comp_wl_##NAME##_cb_bind(struct wl_client *client, void *data EINA_UNUSED, ui
244GLOBAL_BIND_CB(session_recovery, zwp_e_session_recovery_interface) 465GLOBAL_BIND_CB(session_recovery, zwp_e_session_recovery_interface)
245GLOBAL_BIND_CB(screenshooter, zwp_screenshooter_interface) 466GLOBAL_BIND_CB(screenshooter, zwp_screenshooter_interface)
246GLOBAL_BIND_CB(www, www_interface) 467GLOBAL_BIND_CB(www, www_interface)
468GLOBAL_BIND_CB(zxdg_exporter_v1, zxdg_exporter_v1_interface)
469GLOBAL_BIND_CB(zxdg_importer_v1, zxdg_importer_v1_interface)
247 470
248 471
249#define GLOBAL_CREATE_OR_RETURN(NAME, IFACE, VERSION) \ 472#define GLOBAL_CREATE_OR_RETURN(NAME, IFACE, VERSION) \
@@ -285,6 +508,9 @@ e_comp_wl_extensions_init(void)
285 GLOBAL_CREATE_OR_RETURN(session_recovery, zwp_e_session_recovery_interface, 1); 508 GLOBAL_CREATE_OR_RETURN(session_recovery, zwp_e_session_recovery_interface, 1);
286 GLOBAL_CREATE_OR_RETURN(screenshooter, zwp_screenshooter_interface, 1); 509 GLOBAL_CREATE_OR_RETURN(screenshooter, zwp_screenshooter_interface, 1);
287 GLOBAL_CREATE_OR_RETURN(www, www_interface, 1); 510 GLOBAL_CREATE_OR_RETURN(www, www_interface, 1);
511 GLOBAL_CREATE_OR_RETURN(zxdg_exporter_v1, zxdg_exporter_v1_interface, 1);
512 e_comp_wl->extensions->zxdg_exporter_v1.surfaces = eina_hash_string_superfast_new(NULL);
513 GLOBAL_CREATE_OR_RETURN(zxdg_importer_v1, zxdg_importer_v1_interface, 1);
288 514
289 ecore_event_handler_add(ECORE_WL2_EVENT_SYNC_DONE, _dmabuf_add, NULL); 515 ecore_event_handler_add(ECORE_WL2_EVENT_SYNC_DONE, _dmabuf_add, NULL);
290 516
diff --git a/src/protocol/xdg-foreign-unstable-v1.xml b/src/protocol/xdg-foreign-unstable-v1.xml
new file mode 100644
index 000000000..062b09041
--- /dev/null
+++ b/src/protocol/xdg-foreign-unstable-v1.xml
@@ -0,0 +1,182 @@
1<?xml version="1.0" encoding="UTF-8"?>
2<protocol name="xdg_foreign_unstable_v1">
3
4 <copyright>
5 Copyright © 2015-2016 Red Hat Inc.
6
7 Permission is hereby granted, free of charge, to any person obtaining a
8 copy of this software and associated documentation files (the "Software"),
9 to deal in the Software without restriction, including without limitation
10 the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 and/or sell copies of the Software, and to permit persons to whom the
12 Software is furnished to do so, subject to the following conditions:
13
14 The above copyright notice and this permission notice (including the next
15 paragraph) shall be included in all copies or substantial portions of the
16 Software.
17
18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24 DEALINGS IN THE SOFTWARE.
25 </copyright>
26
27 <description summary="Protocol for exporting xdg surface handles">
28 This protocol specifies a way for making it possible to reference a surface
29 of a different client. With such a reference, a client can, by using the
30 interfaces provided by this protocol, manipulate the relationship between
31 its own surfaces and the surface of some other client. For example, stack
32 some of its own surface above the other clients surface.
33
34 In order for a client A to get a reference of a surface of client B, client
35 B must first export its surface using xdg_exporter.export. Upon doing this,
36 client B will receive a handle (a unique string) that it may share with
37 client A in some way (for example D-Bus). After client A has received the
38 handle from client B, it may use xdg_importer.import to create a reference
39 to the surface client B just exported. See the corresponding requests for
40 details.
41
42 A possible use case for this is out-of-process dialogs. For example when a
43 sandboxed client without file system access needs the user to select a file
44 on the file system, given sandbox environment support, it can export its
45 surface, passing the exported surface handle to an unsandboxed process that
46 can show a file browser dialog and stack it above the sandboxed client's
47 surface.
48
49 Warning! The protocol described in this file is experimental and backward
50 incompatible changes may be made. Backward compatible changes may be added
51 together with the corresponding interface version bump. Backward
52 incompatible changes are done by bumping the version number in the protocol
53 and interface names and resetting the interface version. Once the protocol
54 is to be declared stable, the 'z' prefix and the version number in the
55 protocol and interface names are removed and the interface version number is
56 reset.
57 </description>
58
59 <interface name="zxdg_exporter_v1" version="1">
60 <description summary="interface for exporting surfaces">
61 A global interface used for exporting surfaces that can later be imported
62 using xdg_importer.
63 </description>
64
65 <request name="destroy" type="destructor">
66 <description summary="destroy the xdg_exporter object">
67 Notify the compositor that the xdg_exporter object will no longer be
68 used.
69 </description>
70 </request>
71
72 <request name="export">
73 <description summary="export a surface">
74 The export request exports the passed surface so that it can later be
75 imported via xdg_importer. When called, a new xdg_exported object will
76 be created and xdg_exported.handle will be sent immediately. See the
77 corresponding interface and event for details.
78
79 A surface may be exported multiple times, and each exported handle may
80 be used to create a xdg_imported multiple times. Only xdg_surface
81 surfaces may be exported.
82 </description>
83 <arg name="id" type="new_id" interface="zxdg_exported_v1"
84 summary="the new xdg_exported object"/>
85 <arg name="surface" type="object" interface="wl_surface"
86 summary="the surface to export"/>
87 </request>
88 </interface>
89
90 <interface name="zxdg_importer_v1" version="1">
91 <description summary="interface for importing surfaces">
92 A global interface used for importing surfaces exported by xdg_exporter.
93 With this interface, a client can create a reference to a surface of
94 another client.
95 </description>
96
97 <request name="destroy" type="destructor">
98 <description summary="destroy the xdg_importer object">
99 Notify the compositor that the xdg_importer object will no longer be
100 used.
101 </description>
102 </request>
103
104 <request name="import">
105 <description summary="import a surface">
106 The import request imports a surface from any client given a handle
107 retrieved by exporting said surface using xdg_exporter.export. When
108 called, a new xdg_imported object will be created. This new object
109 represents the imported surface, and the importing client can
110 manipulate its relationship using it. See xdg_imported for details.
111 </description>
112 <arg name="id" type="new_id" interface="zxdg_imported_v1"
113 summary="the new xdg_imported object"/>
114 <arg name="handle" type="string"
115 summary="the exported surface handle"/>
116 </request>
117 </interface>
118
119 <interface name="zxdg_exported_v1" version="1">
120 <description summary="an exported surface handle">
121 A xdg_exported object represents an exported reference to a surface. The
122 exported surface may be referenced as long as the xdg_exported object not
123 destroyed. Destroying the xdg_exported invalidates any relationship the
124 importer may have established using xdg_imported.
125 </description>
126
127 <request name="destroy" type="destructor">
128 <description summary="unexport the exported surface">
129 Revoke the previously exported surface. This invalidates any
130 relationship the importer may have set up using the xdg_imported created
131 given the handle sent via xdg_exported.handle.
132 </description>
133 </request>
134
135 <event name="handle">
136 <description summary="the exported surface handle">
137 The handle event contains the unique handle of this exported surface
138 reference. It may be shared with any client, which then can use it to
139 import the surface by calling xdg_importer.import. A handle may be
140 used to import the surface multiple times.
141 </description>
142 <arg name="handle" type="string" summary="the exported surface handle"/>
143 </event>
144 </interface>
145
146 <interface name="zxdg_imported_v1" version="1">
147 <description summary="an imported surface handle">
148 A xdg_imported object represents an imported reference to surface exported
149 by some client. A client can use this interface to manipulate
150 relationships between its own surfaces and the imported surface.
151 </description>
152
153 <request name="destroy" type="destructor">
154 <description summary="destroy the xdg_imported object">
155 Notify the compositor that it will no longer use the xdg_imported
156 object. Any relationship that may have been set up will at this point
157 be invalidated.
158 </description>
159 </request>
160
161 <request name="set_parent_of">
162 <description summary="set as the parent of some surface">
163 Set the imported surface as the parent of some surface of the client.
164 The passed surface must be a toplevel xdg_surface. Calling this function
165 sets up a surface to surface relation with the same stacking and positioning
166 semantics as xdg_surface.set_parent.
167 </description>
168 <arg name="surface" type="object" interface="wl_surface"
169 summary="the child surface"/>
170 </request>
171
172 <event name="destroyed">
173 <description summary="the imported surface handle has been destroyed">
174 The imported surface handle has been destroyed and any relationship set
175 up has been invalidated. This may happen for various reasons, for
176 example if the exported surface or the exported surface handle has been
177 destroyed, if the handle used for importing was invalid.
178 </description>
179 </event>
180 </interface>
181
182</protocol>