summaryrefslogtreecommitdiff
path: root/src/lib/efl_wl/copiedfromweston.x
diff options
context:
space:
mode:
authorMike Blumenkrantz <zmike@osg.samsung.com>2017-06-30 14:59:21 -0400
committerMike Blumenkrantz <zmike@osg.samsung.com>2017-06-30 14:59:55 -0400
commitc2fde93c9ef1108c0809a538cf2ec482ed8369a9 (patch)
treed9879e4ebea4d25cda1a6cc1268461ad0d669c3b /src/lib/efl_wl/copiedfromweston.x
parent3775a9645da7e92599babccfe8454304cec367b7 (diff)
efl_wl: a multiseat wayland compositor in an evas smart object
build when wayland support is enabled and provide two test/demo cases beta api @feature Reviewed-By: Cedric BAIL <cedric@osg.samsung.com>
Diffstat (limited to 'src/lib/efl_wl/copiedfromweston.x')
-rw-r--r--src/lib/efl_wl/copiedfromweston.x358
1 files changed, 358 insertions, 0 deletions
diff --git a/src/lib/efl_wl/copiedfromweston.x b/src/lib/efl_wl/copiedfromweston.x
new file mode 100644
index 0000000000..0b1388b064
--- /dev/null
+++ b/src/lib/efl_wl/copiedfromweston.x
@@ -0,0 +1,358 @@
1/*
2 * Copyright © 2011 Kristian Høgsberg
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining
5 * a copy of this software and associated documentation files (the
6 * "Software"), to deal in the Software without restriction, including
7 * without limitation the rights to use, copy, modify, merge, publish,
8 * distribute, sublicense, and/or sell copies of the Software, and to
9 * permit persons to whom the Software is furnished to do so, subject to
10 * the following conditions:
11 *
12 * The above copyright notice and this permission notice (including the
13 * next paragraph) shall be included in all copies or substantial
14 * portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
20 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
21 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 * SOFTWARE.
24 */
25
26#define ALL_ACTIONS (WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY | \
27 WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE | \
28 WL_DATA_DEVICE_MANAGER_DND_ACTION_ASK)
29
30static uint32_t
31data_offer_choose_action(Comp_Data_Device_Offer *offer)
32{
33 uint32_t available_actions, preferred_action = 0;
34 uint32_t source_actions, offer_actions;
35
36 if (wl_resource_get_version(offer->res) >=
37 WL_DATA_OFFER_ACTION_SINCE_VERSION)
38 {
39 offer_actions = offer->dnd_actions;
40 preferred_action = offer->preferred_dnd_action;
41 }
42 else
43 {
44 offer_actions = WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY;
45 }
46
47 if (wl_resource_get_version(offer->source->res) >=
48 WL_DATA_SOURCE_ACTION_SINCE_VERSION)
49 source_actions = offer->source->dnd_actions;
50 else
51 source_actions = WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY;
52
53 available_actions = offer_actions & source_actions;
54
55 if (!available_actions)
56 return WL_DATA_DEVICE_MANAGER_DND_ACTION_NONE;
57
58 if (offer->source->seat &&
59 offer->source->compositor_action & available_actions)
60 return offer->source->compositor_action;
61
62 /* If the dest side has a preferred DnD action, use it */
63 if ((preferred_action & available_actions) != 0)
64 return preferred_action;
65
66 /* Use the first found action, in bit order */
67 return 1 << (ffs(available_actions) - 1);
68}
69
70static void
71data_offer_update_action(Comp_Data_Device_Offer *offer)
72{
73 uint32_t action;
74
75 if (!offer->source)
76 return;
77
78 action = data_offer_choose_action(offer);
79
80 if (offer->source->current_dnd_action == action)
81 return;
82
83 offer->source->current_dnd_action = action;
84
85 if (offer->in_ask)
86 return;
87
88 if (wl_resource_get_version(offer->source->res) >=
89 WL_DATA_SOURCE_ACTION_SINCE_VERSION)
90 wl_data_source_send_action(offer->source->res, action);
91
92 if (wl_resource_get_version(offer->res) >=
93 WL_DATA_OFFER_ACTION_SINCE_VERSION)
94 wl_data_offer_send_action(offer->res, action);
95}
96
97static void
98data_device_offer_set_actions(struct wl_client *client,
99 struct wl_resource *resource,
100 uint32_t dnd_actions, uint32_t preferred_action)
101{
102 Comp_Data_Device_Offer *offer = wl_resource_get_user_data(resource);
103
104 if (dnd_actions & ~ALL_ACTIONS)
105 {
106 wl_resource_post_error(offer->res,
107 WL_DATA_OFFER_ERROR_INVALID_ACTION_MASK,
108 "invalid action mask %x", dnd_actions);
109 return;
110 }
111
112 if (preferred_action &&
113 (!(preferred_action & dnd_actions) ||
114 __builtin_popcount(preferred_action) > 1))
115 {
116 wl_resource_post_error(offer->res,
117 WL_DATA_OFFER_ERROR_INVALID_ACTION,
118 "invalid action %x", preferred_action);
119 return;
120 }
121
122 offer->dnd_actions = dnd_actions;
123 offer->preferred_dnd_action = preferred_action;
124 data_offer_update_action(offer);
125}
126
127#ifdef HAVE_ECORE_X
128static Ecore_X_Atom
129action_convert(uint32_t action)
130{
131 if (action == WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE)
132 return ECORE_X_ATOM_XDND_ACTION_MOVE;
133 if (action == WL_DATA_DEVICE_MANAGER_DND_ACTION_ASK)
134 return ECORE_X_ATOM_XDND_ACTION_ASK;
135 return ECORE_X_ATOM_XDND_ACTION_COPY;
136}
137#endif
138static void
139data_device_offer_accept(struct wl_client *client, struct wl_resource *resource,
140 uint32_t serial, const char *mime_type)
141{
142 Comp_Data_Device_Offer *offer = wl_resource_get_user_data(resource);
143 Comp_Surface *cs;
144
145 /* Protect against untimely calls from older data offers */
146 if (!offer->source || offer != offer->source->offer)
147 return;
148
149 switch (offer->type)
150 {
151 case COMP_DATA_DEVICE_OFFER_TYPE_DND:
152 cs = offer->source->seat->drag.enter;
153 if (!offer->source->seat->drag.res) return;
154 if ((!offer->source->seat->drag.source) &&
155 (wl_resource_get_client(cs->res) != wl_resource_get_client(offer->source->seat->drag.res)))
156 return;
157#ifdef HAVE_ECORE_X
158 if (offer->source->x11_owner)
159 {
160 Ecore_Window win = ecore_evas_window_get(ecore_evas_ecore_evas_get(offer->source->seat->c->evas));
161 offer->source->accepted = mime_type != NULL;
162 ecore_x_client_message32_send(offer->source->x11_owner,
163 ECORE_X_ATOM_XDND_STATUS, ECORE_X_EVENT_MASK_NONE,
164 win, 2 | !!mime_type, 0, 0,
165 (!!mime_type) * action_convert(offer->source->current_dnd_action));
166 return;
167 }
168#endif
169 break;
170
171 case COMP_DATA_DEVICE_OFFER_TYPE_CLIPBOARD:
172 break;
173 default: return;
174 }
175 if (offer->source->seat->client_offer)
176 ecore_wl2_offer_accept(offer->source->seat->client_offer, mime_type);
177 else
178 wl_data_source_send_target(offer->source->res, mime_type);
179 offer->source->accepted = mime_type != NULL;
180}
181
182static void
183data_device_offer_receive(struct wl_client *client, struct wl_resource *resource,
184 const char *mime_type, int32_t fd)
185{
186 Comp_Data_Device_Offer *offer = wl_resource_get_user_data(resource);
187
188 if (offer->source && offer == offer->source->offer)
189 {
190 if (offer->proxy)
191 {
192 Ecore_Wl2_Offer *off;
193#ifdef HAVE_ECORE_X
194 if (offer->source->x11_owner)
195 {
196 x11_send_send(offer->source, mime_type, fd, offer->type);
197 return;
198 }
199#endif
200 if (offer->type == COMP_DATA_DEVICE_OFFER_TYPE_CLIPBOARD)
201 off = ecore_wl2_dnd_selection_get(offer->source->seat->seat);
202 else
203 {
204 off = offer->source->seat->client_offer;
205 offer->source->seat->client_offer = NULL;
206 }
207 ecore_wl2_offer_proxy_receive(off, mime_type, fd);
208 offer->proxy_offer = off;
209 }
210 else
211 wl_data_source_send_send(offer->source->res, mime_type, fd);
212 }
213 close(fd);
214}
215
216static void
217data_source_notify_finish(Comp_Data_Device_Source *source)
218{
219 if (!source->actions_set)
220 return;
221
222 if (source->proxy && (!source->x11_owner))
223 ecore_wl2_offer_finish(source->offer->proxy_offer);
224
225 if (source->offer && source->offer->in_ask &&
226 wl_resource_get_version(source->res) >=
227 WL_DATA_SOURCE_ACTION_SINCE_VERSION)
228 {
229 wl_data_source_send_action(source->res,
230 source->current_dnd_action);
231 }
232
233 if (wl_resource_get_version(source->res) >=
234 WL_DATA_SOURCE_DND_FINISHED_SINCE_VERSION)
235 {
236 wl_data_source_send_dnd_finished(source->res);
237 }
238
239 source->offer = NULL;
240}
241
242static void
243data_device_offer_finish(struct wl_client *client, struct wl_resource *resource)
244{
245 Comp_Data_Device_Offer *offer = wl_resource_get_user_data(resource);
246
247 if (!offer->source || offer->source->offer != offer)
248 return;
249
250 /* Disallow finish while we have a grab driving drag-and-drop, or
251 * if the negotiation is not at the right stage
252 */
253 if (((!offer->proxy) && offer->source->seat) ||
254 !offer->source->accepted)
255 {
256 wl_resource_post_error(offer->res,
257 WL_DATA_OFFER_ERROR_INVALID_FINISH,
258 "premature finish request");
259 return;
260 }
261
262 switch (offer->source->current_dnd_action)
263 {
264 case WL_DATA_DEVICE_MANAGER_DND_ACTION_NONE:
265 case WL_DATA_DEVICE_MANAGER_DND_ACTION_ASK:
266 wl_resource_post_error(offer->res,
267 WL_DATA_OFFER_ERROR_INVALID_OFFER,
268 "offer finished with an invalid action");
269 return;
270
271 default:
272 break;
273 }
274
275 data_source_notify_finish(offer->source);
276}
277
278static void
279data_device_offer_impl_destroy(struct wl_resource *resource)
280{
281 Comp_Data_Device_Offer *offer = wl_resource_get_user_data(resource);
282
283 if (!offer->source)
284 goto out;
285
286 if (offer->source->offer != offer)
287 goto out;
288
289 if (offer->type == COMP_DATA_DEVICE_OFFER_TYPE_DND)
290 {
291 /* If the drag destination has version < 3, wl_data_offer.finish
292 * won't be called, so do this here as a safety net, because
293 * we still want the version >=3 drag source to be happy.
294 */
295 if (wl_resource_get_version(offer->res) <
296 WL_DATA_OFFER_ACTION_SINCE_VERSION)
297 {
298 data_source_notify_finish(offer->source);
299 }
300 else if (offer->source->res &&
301 wl_resource_get_version(offer->source->res) >=
302 WL_DATA_SOURCE_DND_FINISHED_SINCE_VERSION)
303 {
304 wl_data_source_send_cancelled(offer->source->res);
305 }
306 }
307
308 offer->source->offer = NULL;
309 if (offer->proxy_offer && offer->proxy)
310 ecore_wl2_offer_proxy_receive_end(offer->proxy_offer);
311out:
312 free(offer);
313}
314
315static void
316drag_grab_button(Comp_Seat *s,
317 uint32_t time, uint32_t button, uint32_t state_w)
318{
319 Comp_Data_Device_Source *data_source = s->drag.source;
320 enum wl_pointer_button_state state = state_w;
321
322 if (data_source &&
323 s->drag.id == button &&
324 state == WL_POINTER_BUTTON_STATE_RELEASED)
325 {
326 if ((s->drag.enter || (s->drag.x11_owner == ecore_evas_window_get(ecore_evas_ecore_evas_get(s->c->evas)))) &&
327 data_source->accepted &&
328 data_source->current_dnd_action)
329 {
330 if (s->drag.enter)
331 wl_data_device_send_drop(data_device_find(s, s->drag.enter->res));
332
333 if (wl_resource_get_version(data_source->res) >=
334 WL_DATA_SOURCE_DND_DROP_PERFORMED_SINCE_VERSION)
335 wl_data_source_send_dnd_drop_performed(data_source->res);
336
337 if (data_source->offer)
338 data_source->offer->in_ask =
339 data_source->current_dnd_action ==
340 WL_DATA_DEVICE_MANAGER_DND_ACTION_ASK;
341
342 if (!data_source->proxy)
343 data_source->seat = NULL;
344 }
345 else if (wl_resource_get_version(data_source->res) >=
346 WL_DATA_SOURCE_DND_FINISHED_SINCE_VERSION)
347 {
348 wl_data_source_send_cancelled(data_source->res);
349 }
350 seat_drag_end(s);
351 if (!data_source->x11_owner)
352 s->drag.source = NULL;
353#ifdef HAVE_ECORE_X
354 if (ecore_x_display_get())
355 ecore_x_pointer_ungrab();
356#endif
357 }
358}