blob: 1ff32e980059c81b79a0a39421e0ca35fcdb2cc5 [file] [log] [blame]
Kristian Høgsberg4cca3492011-01-18 07:53:49 -05001/*
2 * Copyright © 2010 Intel Corporation
3 *
4 * Permission to use, copy, modify, distribute, and sell this software and
5 * its documentation for any purpose is hereby granted without fee, provided
6 * that the above copyright notice appear in all copies and that both that
7 * copyright notice and this permission notice appear in supporting
8 * documentation, and that the name of the copyright holders not be used in
9 * advertising or publicity pertaining to distribution of the software
10 * without specific, written prior permission. The copyright holders make
11 * no representations about the suitability of this software for any
12 * purpose. It is provided "as is" without express or implied warranty.
13 *
14 * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
15 * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
16 * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
17 * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
18 * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
19 * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
20 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
21 */
22
23#include <stdlib.h>
24#include <string.h>
25#include <unistd.h>
26
27#include "wayland-server.h"
28#include "compositor.h"
29
30struct wlsc_move_grab {
31 struct wl_grab grab;
Kristian Høgsbergdd4046a2011-01-21 17:00:09 -050032 struct wlsc_surface *surface;
Kristian Høgsberg4cca3492011-01-18 07:53:49 -050033 int32_t dx, dy;
34};
35
36static void
37move_grab_motion(struct wl_grab *grab,
38 uint32_t time, int32_t x, int32_t y)
39{
40 struct wlsc_move_grab *move = (struct wlsc_move_grab *) grab;
Kristian Høgsbergdd4046a2011-01-21 17:00:09 -050041 struct wlsc_surface *es = move->surface;
Kristian Høgsberg4cca3492011-01-18 07:53:49 -050042
43 es->x = x + move->dx;
44 es->y = y + move->dy;
45 wlsc_surface_update_matrix(es);
46}
47
48static void
49move_grab_button(struct wl_grab *grab,
50 uint32_t time, int32_t button, int32_t state)
51{
52}
53
54static void
55move_grab_end(struct wl_grab *grab, uint32_t time)
56{
Kristian Høgsbergdd4046a2011-01-21 17:00:09 -050057 struct wlsc_surface *es;
58 struct wl_input_device *device = grab->input_device;
59 int32_t sx, sy;
60
61 es = pick_surface(grab->input_device, &sx, &sy);
62 wl_input_device_set_pointer_focus(device,
63 &es->surface, time,
64 device->x, device->y, sx, sy);
Kristian Høgsberg4cca3492011-01-18 07:53:49 -050065 free(grab);
66}
67
68static const struct wl_grab_interface move_grab_interface = {
69 move_grab_motion,
70 move_grab_button,
71 move_grab_end
72};
73
74void
75shell_move(struct wl_client *client, struct wl_shell *shell,
76 struct wl_surface *surface,
77 struct wl_input_device *device, uint32_t time)
78{
79 struct wlsc_input_device *wd = (struct wlsc_input_device *) device;
80 struct wlsc_surface *es = (struct wlsc_surface *) surface;
81 struct wlsc_move_grab *move;
82
Kristian Høgsberg0ce24572011-01-28 15:18:33 -050083 /* FIXME: Reject if fullscreen */
84
Kristian Høgsberg4cca3492011-01-18 07:53:49 -050085 move = malloc(sizeof *move);
86 if (!move) {
87 wl_client_post_no_memory(client);
88 return;
89 }
90
91 move->grab.interface = &move_grab_interface;
92 move->dx = es->x - wd->input_device.grab_x;
93 move->dy = es->y - wd->input_device.grab_y;
Kristian Høgsbergdd4046a2011-01-21 17:00:09 -050094 move->surface = es;
Kristian Høgsberg4cca3492011-01-18 07:53:49 -050095
96 if (wl_input_device_update_grab(&wd->input_device,
97 &move->grab, surface, time) < 0)
98 return;
99
100 wlsc_input_device_set_pointer_image(wd, WLSC_POINTER_DRAGGING);
Kristian Høgsbergdd4046a2011-01-21 17:00:09 -0500101 wl_input_device_set_pointer_focus(device, NULL, time, 0, 0, 0, 0);
Kristian Høgsberg4cca3492011-01-18 07:53:49 -0500102}
103
104struct wlsc_resize_grab {
105 struct wl_grab grab;
106 uint32_t edges;
107 int32_t dx, dy, width, height;
Kristian Høgsbergdd4046a2011-01-21 17:00:09 -0500108 struct wlsc_surface *surface;
Kristian Høgsberg4cca3492011-01-18 07:53:49 -0500109};
110
111static void
112resize_grab_motion(struct wl_grab *grab,
113 uint32_t time, int32_t x, int32_t y)
114{
115 struct wlsc_resize_grab *resize = (struct wlsc_resize_grab *) grab;
116 struct wl_input_device *device = grab->input_device;
117 struct wlsc_compositor *ec =
118 (struct wlsc_compositor *) device->compositor;
Kristian Høgsbergdd4046a2011-01-21 17:00:09 -0500119 struct wl_surface *surface = &resize->surface->surface;
Kristian Høgsberg4cca3492011-01-18 07:53:49 -0500120 int32_t width, height;
121
Kristian Høgsberg027931b2011-01-21 21:57:55 -0500122 if (resize->edges & WL_SHELL_RESIZE_LEFT) {
Kristian Høgsberg4cca3492011-01-18 07:53:49 -0500123 width = device->grab_x - x + resize->width;
Kristian Høgsberg027931b2011-01-21 21:57:55 -0500124 } else if (resize->edges & WL_SHELL_RESIZE_RIGHT) {
Kristian Høgsberg4cca3492011-01-18 07:53:49 -0500125 width = x - device->grab_x + resize->width;
126 } else {
127 width = resize->width;
128 }
129
Kristian Høgsberg027931b2011-01-21 21:57:55 -0500130 if (resize->edges & WL_SHELL_RESIZE_TOP) {
Kristian Høgsberg4cca3492011-01-18 07:53:49 -0500131 height = device->grab_y - y + resize->height;
Kristian Høgsberg027931b2011-01-21 21:57:55 -0500132 } else if (resize->edges & WL_SHELL_RESIZE_BOTTOM) {
Kristian Høgsberg4cca3492011-01-18 07:53:49 -0500133 height = y - device->grab_y + resize->height;
134 } else {
135 height = resize->height;
136 }
137
138 wl_client_post_event(surface->client, &ec->shell.object,
139 WL_SHELL_CONFIGURE, time, resize->edges,
140 surface, width, height);
141}
142
143static void
144resize_grab_button(struct wl_grab *grab,
145 uint32_t time, int32_t button, int32_t state)
146{
147}
148
149static void
150resize_grab_end(struct wl_grab *grab, uint32_t time)
151{
Kristian Høgsbergdd4046a2011-01-21 17:00:09 -0500152 struct wlsc_surface *es;
153 struct wl_input_device *device = grab->input_device;
154 int32_t sx, sy;
155
156 es = pick_surface(grab->input_device, &sx, &sy);
157 wl_input_device_set_pointer_focus(device,
158 &es->surface, time,
159 device->x, device->y, sx, sy);
Kristian Høgsberg4cca3492011-01-18 07:53:49 -0500160 free(grab);
161}
162
163static const struct wl_grab_interface resize_grab_interface = {
164 resize_grab_motion,
165 resize_grab_button,
166 resize_grab_end
167};
168
169void
170shell_resize(struct wl_client *client, struct wl_shell *shell,
171 struct wl_surface *surface,
172 struct wl_input_device *device, uint32_t time, uint32_t edges)
173{
174 struct wlsc_input_device *wd = (struct wlsc_input_device *) device;
175 struct wlsc_resize_grab *resize;
176 enum wlsc_pointer_type pointer = WLSC_POINTER_LEFT_PTR;
177 struct wlsc_surface *es = (struct wlsc_surface *) surface;
178
Kristian Høgsberg0ce24572011-01-28 15:18:33 -0500179 /* FIXME: Reject if fullscreen */
180
Kristian Høgsberg4cca3492011-01-18 07:53:49 -0500181 resize = malloc(sizeof *resize);
182 if (!resize) {
183 wl_client_post_no_memory(client);
184 return;
185 }
186
187 resize->grab.interface = &resize_grab_interface;
188 resize->edges = edges;
189 resize->dx = es->x - wd->input_device.grab_x;
190 resize->dy = es->y - wd->input_device.grab_y;
191 resize->width = es->width;
192 resize->height = es->height;
Kristian Høgsbergdd4046a2011-01-21 17:00:09 -0500193 resize->surface = es;
Kristian Høgsberg4cca3492011-01-18 07:53:49 -0500194
195 if (edges == 0 || edges > 15 ||
196 (edges & 3) == 3 || (edges & 12) == 12)
197 return;
198
199 switch (edges) {
Kristian Høgsberg027931b2011-01-21 21:57:55 -0500200 case WL_SHELL_RESIZE_TOP:
Kristian Høgsberg4cca3492011-01-18 07:53:49 -0500201 pointer = WLSC_POINTER_TOP;
202 break;
Kristian Høgsberg027931b2011-01-21 21:57:55 -0500203 case WL_SHELL_RESIZE_BOTTOM:
Kristian Høgsberg4cca3492011-01-18 07:53:49 -0500204 pointer = WLSC_POINTER_BOTTOM;
205 break;
Kristian Høgsberg027931b2011-01-21 21:57:55 -0500206 case WL_SHELL_RESIZE_LEFT:
Kristian Høgsberg4cca3492011-01-18 07:53:49 -0500207 pointer = WLSC_POINTER_LEFT;
208 break;
Kristian Høgsberg027931b2011-01-21 21:57:55 -0500209 case WL_SHELL_RESIZE_TOP_LEFT:
Kristian Høgsberg4cca3492011-01-18 07:53:49 -0500210 pointer = WLSC_POINTER_TOP_LEFT;
211 break;
Kristian Høgsberg027931b2011-01-21 21:57:55 -0500212 case WL_SHELL_RESIZE_BOTTOM_LEFT:
Kristian Høgsberg4cca3492011-01-18 07:53:49 -0500213 pointer = WLSC_POINTER_BOTTOM_LEFT;
214 break;
Kristian Høgsberg027931b2011-01-21 21:57:55 -0500215 case WL_SHELL_RESIZE_RIGHT:
Kristian Høgsberg4cca3492011-01-18 07:53:49 -0500216 pointer = WLSC_POINTER_RIGHT;
217 break;
Kristian Høgsberg027931b2011-01-21 21:57:55 -0500218 case WL_SHELL_RESIZE_TOP_RIGHT:
Kristian Høgsberg4cca3492011-01-18 07:53:49 -0500219 pointer = WLSC_POINTER_TOP_RIGHT;
220 break;
Kristian Høgsberg027931b2011-01-21 21:57:55 -0500221 case WL_SHELL_RESIZE_BOTTOM_RIGHT:
Kristian Høgsberg4cca3492011-01-18 07:53:49 -0500222 pointer = WLSC_POINTER_BOTTOM_RIGHT;
223 break;
224 }
225
226 if (wl_input_device_update_grab(&wd->input_device,
227 &resize->grab, surface, time) < 0)
228 return;
229
230 wlsc_input_device_set_pointer_image(wd, pointer);
Kristian Høgsbergdd4046a2011-01-21 17:00:09 -0500231 wl_input_device_set_pointer_focus(device, NULL, time, 0, 0, 0, 0);
Kristian Høgsberg4cca3492011-01-18 07:53:49 -0500232}
233
234static void
Kristian Høgsberg4cca3492011-01-18 07:53:49 -0500235destroy_drag(struct wl_resource *resource, struct wl_client *client)
236{
237 struct wl_drag *drag =
238 container_of(resource, struct wl_drag, resource);
239
240 wl_list_remove(&drag->drag_focus_listener.link);
241 if (drag->grab.input_device)
242 wl_input_device_end_grab(drag->grab.input_device, get_time());
243
244 free(drag);
245}
246
247
248static void
249wl_drag_set_pointer_focus(struct wl_drag *drag,
250 struct wl_surface *surface, uint32_t time,
251 int32_t x, int32_t y, int32_t sx, int32_t sy)
252{
253 char **p, **end;
254
255 if (drag->drag_focus == surface)
256 return;
257
258 if (drag->drag_focus &&
259 (!surface || drag->drag_focus->client != surface->client))
260 wl_client_post_event(drag->drag_focus->client,
261 &drag->drag_offer.object,
262 WL_DRAG_OFFER_POINTER_FOCUS,
263 time, NULL, 0, 0, 0, 0);
264
265 if (surface &&
266 (!drag->drag_focus ||
267 drag->drag_focus->client != surface->client)) {
268 wl_client_post_global(surface->client,
269 &drag->drag_offer.object);
270
271 end = drag->types.data + drag->types.size;
272 for (p = drag->types.data; p < end; p++)
273 wl_client_post_event(surface->client,
274 &drag->drag_offer.object,
275 WL_DRAG_OFFER_OFFER, *p);
276 }
277
278 if (surface) {
279 wl_client_post_event(surface->client,
280 &drag->drag_offer.object,
281 WL_DRAG_OFFER_POINTER_FOCUS,
282 time, surface,
283 x, y, sx, sy);
284
285 }
286
287 drag->drag_focus = surface;
288 drag->pointer_focus_time = time;
289 drag->target = NULL;
290
291 wl_list_remove(&drag->drag_focus_listener.link);
292 if (surface)
293 wl_list_insert(surface->destroy_listener_list.prev,
294 &drag->drag_focus_listener.link);
295}
296
297static void
298drag_offer_accept(struct wl_client *client,
299 struct wl_drag_offer *offer, uint32_t time, const char *type)
300{
301 struct wl_drag *drag = container_of(offer, struct wl_drag, drag_offer);
302 char **p, **end;
303
304 /* If the client responds to drag pointer_focus or motion
305 * events after the pointer has left the surface, we just
306 * discard the accept requests. The drag source just won't
307 * get the corresponding 'target' events and eventually the
308 * next surface/root will start sending events. */
309 if (time < drag->pointer_focus_time)
310 return;
311
312 drag->target = client;
313 drag->type = NULL;
314 end = drag->types.data + drag->types.size;
315 for (p = drag->types.data; p < end; p++)
316 if (type && strcmp(*p, type) == 0)
317 drag->type = *p;
318
319 wl_client_post_event(drag->source->client, &drag->resource.object,
320 WL_DRAG_TARGET, drag->type);
321}
322
323static void
324drag_offer_receive(struct wl_client *client,
325 struct wl_drag_offer *offer, int fd)
326{
327 struct wl_drag *drag = container_of(offer, struct wl_drag, drag_offer);
328
329 wl_client_post_event(drag->source->client, &drag->resource.object,
330 WL_DRAG_FINISH, fd);
331 close(fd);
332}
333
334static void
335drag_offer_reject(struct wl_client *client, struct wl_drag_offer *offer)
336{
337 struct wl_drag *drag = container_of(offer, struct wl_drag, drag_offer);
338
339 wl_client_post_event(drag->source->client, &drag->resource.object,
340 WL_DRAG_REJECT);
341}
342
343static const struct wl_drag_offer_interface drag_offer_interface = {
344 drag_offer_accept,
345 drag_offer_receive,
346 drag_offer_reject
347};
348
349static void
350drag_offer(struct wl_client *client, struct wl_drag *drag, const char *type)
351{
352 char **p;
353
354 p = wl_array_add(&drag->types, sizeof *p);
355 if (p)
356 *p = strdup(type);
357 if (!p || !*p)
358 wl_client_post_no_memory(client);
359}
360
361static void
362drag_grab_motion(struct wl_grab *grab,
363 uint32_t time, int32_t x, int32_t y)
364{
365 struct wl_drag *drag = container_of(grab, struct wl_drag, grab);
366 struct wlsc_surface *es;
367 int32_t sx, sy;
368
369 es = pick_surface(grab->input_device, &sx, &sy);
370 wl_drag_set_pointer_focus(drag, &es->surface, time, x, y, sx, sy);
371 if (es)
372 wl_client_post_event(es->surface.client,
373 &drag->drag_offer.object,
374 WL_DRAG_OFFER_MOTION,
375 time, x, y, sx, sy);
376}
377
378static void
379drag_grab_button(struct wl_grab *grab,
380 uint32_t time, int32_t button, int32_t state)
381{
382}
383
384static void
385drag_grab_end(struct wl_grab *grab, uint32_t time)
386{
387 struct wl_drag *drag = container_of(grab, struct wl_drag, grab);
Kristian Høgsbergdd4046a2011-01-21 17:00:09 -0500388 struct wlsc_surface *es;
389 struct wl_input_device *device = grab->input_device;
390 int32_t sx, sy;
Kristian Høgsberg4cca3492011-01-18 07:53:49 -0500391
392 if (drag->target)
393 wl_client_post_event(drag->target,
394 &drag->drag_offer.object,
395 WL_DRAG_OFFER_DROP);
396
397 wl_drag_set_pointer_focus(drag, NULL, time, 0, 0, 0, 0);
Kristian Høgsbergdd4046a2011-01-21 17:00:09 -0500398
399 es = pick_surface(grab->input_device, &sx, &sy);
400 wl_input_device_set_pointer_focus(device,
401 &es->surface, time,
402 device->x, device->y, sx, sy);
Kristian Høgsberg4cca3492011-01-18 07:53:49 -0500403}
404
405static const struct wl_grab_interface drag_grab_interface = {
406 drag_grab_motion,
407 drag_grab_button,
408 drag_grab_end
409};
410
411static void
412drag_activate(struct wl_client *client,
413 struct wl_drag *drag,
414 struct wl_surface *surface,
415 struct wl_input_device *device, uint32_t time)
416{
417 struct wl_display *display = wl_client_get_display (client);
418 struct wlsc_surface *target;
419 int32_t sx, sy;
420
421 if (wl_input_device_update_grab(device,
422 &drag->grab, surface, time) < 0)
423 return;
424
425 drag->grab.interface = &drag_grab_interface;
426
427 drag->source = surface;
428
429 drag->drag_offer.object.interface = &wl_drag_offer_interface;
430 drag->drag_offer.object.implementation =
431 (void (**)(void)) &drag_offer_interface;
432
433 wl_display_add_object(display, &drag->drag_offer.object);
434
435 target = pick_surface(device, &sx, &sy);
Kristian Høgsbergdd4046a2011-01-21 17:00:09 -0500436 wl_input_device_set_pointer_focus(device, NULL, time, 0, 0, 0, 0);
Kristian Høgsberg4cca3492011-01-18 07:53:49 -0500437 wl_drag_set_pointer_focus(drag, &target->surface, time,
438 device->x, device->y, sx, sy);
439}
440
441static void
442drag_destroy(struct wl_client *client, struct wl_drag *drag)
443{
444 wl_resource_destroy(&drag->resource, client);
445}
446
447static const struct wl_drag_interface drag_interface = {
448 drag_offer,
449 drag_activate,
450 drag_destroy,
451};
452
453static void
454drag_handle_surface_destroy(struct wl_listener *listener,
455 struct wl_surface *surface, uint32_t time)
456{
457 struct wl_drag *drag =
458 container_of(listener, struct wl_drag, drag_focus_listener);
459
460 if (drag->drag_focus == surface)
461 wl_drag_set_pointer_focus(drag, NULL, time, 0, 0, 0, 0);
462}
463
464static void
465shell_create_drag(struct wl_client *client,
466 struct wl_shell *shell, uint32_t id)
467{
468 struct wl_drag *drag;
469
470 drag = malloc(sizeof *drag);
471 if (drag == NULL) {
472 wl_client_post_no_memory(client);
473 return;
474 }
475
476 memset(drag, 0, sizeof *drag);
477 drag->resource.object.id = id;
478 drag->resource.object.interface = &wl_drag_interface;
479 drag->resource.object.implementation =
480 (void (**)(void)) &drag_interface;
481
482 drag->resource.destroy = destroy_drag;
483
484 drag->drag_focus_listener.func = drag_handle_surface_destroy;
485 wl_list_init(&drag->drag_focus_listener.link);
486
487 wl_client_add_resource(client, &drag->resource);
488}
489
Kristian Høgsbergae6c8a62011-01-18 09:08:53 -0500490void
491wlsc_selection_set_focus(struct wl_selection *selection,
492 struct wl_surface *surface, uint32_t time)
493{
494 char **p, **end;
495
496 if (selection->selection_focus == surface)
497 return;
498
499 if (selection->selection_focus != NULL)
500 wl_client_post_event(selection->selection_focus->client,
501 &selection->selection_offer.object,
502 WL_SELECTION_OFFER_KEYBOARD_FOCUS,
503 NULL);
504
505 if (surface) {
506 wl_client_post_global(surface->client,
507 &selection->selection_offer.object);
508
509 end = selection->types.data + selection->types.size;
510 for (p = selection->types.data; p < end; p++)
511 wl_client_post_event(surface->client,
512 &selection->selection_offer.object,
513 WL_SELECTION_OFFER_OFFER, *p);
514
515 wl_list_remove(&selection->selection_focus_listener.link);
516 wl_list_insert(surface->destroy_listener_list.prev,
517 &selection->selection_focus_listener.link);
518
519 wl_client_post_event(surface->client,
520 &selection->selection_offer.object,
521 WL_SELECTION_OFFER_KEYBOARD_FOCUS,
522 selection->input_device);
523 }
524
525 selection->selection_focus = surface;
526
527 wl_list_remove(&selection->selection_focus_listener.link);
528 if (surface)
529 wl_list_insert(surface->destroy_listener_list.prev,
530 &selection->selection_focus_listener.link);
531}
532
533static void
534selection_offer_receive(struct wl_client *client,
535 struct wl_selection_offer *offer,
536 const char *mime_type, int fd)
537{
538 struct wl_selection *selection =
539 container_of(offer, struct wl_selection, selection_offer);
540
541 wl_client_post_event(selection->client,
542 &selection->resource.object,
543 WL_SELECTION_SEND, mime_type, fd);
544 close(fd);
545}
546
547static const struct wl_selection_offer_interface selection_offer_interface = {
548 selection_offer_receive
549};
550
551static void
552selection_offer(struct wl_client *client,
553 struct wl_selection *selection, const char *type)
554{
555 char **p;
556
557 p = wl_array_add(&selection->types, sizeof *p);
558 if (p)
559 *p = strdup(type);
560 if (!p || !*p)
561 wl_client_post_no_memory(client);
562}
563
564static void
565selection_activate(struct wl_client *client,
566 struct wl_selection *selection,
567 struct wl_input_device *device, uint32_t time)
568{
569 struct wlsc_input_device *wd = (struct wlsc_input_device *) device;
570 struct wl_display *display = wl_client_get_display (client);
571
572 selection->input_device = device;
573
574 selection->selection_offer.object.interface =
575 &wl_selection_offer_interface;
576 selection->selection_offer.object.implementation =
577 (void (**)(void)) &selection_offer_interface;
578
579 wl_display_add_object(display, &selection->selection_offer.object);
580
581 if (wd->selection) {
582 wl_client_post_event(wd->selection->client,
583 &wd->selection->resource.object,
584 WL_SELECTION_CANCELLED);
585 }
586 wd->selection = selection;
587
588 wlsc_selection_set_focus(selection, device->keyboard_focus, time);
589}
590
591static void
592selection_destroy(struct wl_client *client, struct wl_selection *selection)
593{
594 wl_resource_destroy(&selection->resource, client);
595}
596
597static const struct wl_selection_interface selection_interface = {
598 selection_offer,
599 selection_activate,
600 selection_destroy
601};
602
603static void
604destroy_selection(struct wl_resource *resource, struct wl_client *client)
605{
606 struct wl_selection *selection =
607 container_of(resource, struct wl_selection, resource);
608 struct wlsc_input_device *wd =
609 (struct wlsc_input_device *) selection->input_device;
610
611 if (wd && wd->selection == selection) {
612 wd->selection = NULL;
613 wlsc_selection_set_focus(selection, NULL, get_time());
614 }
615
616 wl_list_remove(&selection->selection_focus_listener.link);
617 free(selection);
618}
619
620static void
621selection_handle_surface_destroy(struct wl_listener *listener,
622 struct wl_surface *surface, uint32_t time)
623{
624}
625
626static void
627shell_create_selection(struct wl_client *client,
628 struct wl_shell *shell, uint32_t id)
629{
630 struct wl_selection *selection;
631
632 selection = malloc(sizeof *selection);
633 if (selection == NULL) {
634 wl_client_post_no_memory(client);
635 return;
636 }
637
638 memset(selection, 0, sizeof *selection);
639 selection->resource.object.id = id;
640 selection->resource.object.interface = &wl_selection_interface;
641 selection->resource.object.implementation =
642 (void (**)(void)) &selection_interface;
643
644 selection->client = client;
645 selection->resource.destroy = destroy_selection;
646 selection->selection_focus = NULL;
647
648 selection->selection_focus_listener.func =
649 selection_handle_surface_destroy;
650 wl_list_init(&selection->selection_focus_listener.link);
651
652 wl_client_add_resource(client, &selection->resource);
653}
654
Kristian Høgsberg4cca3492011-01-18 07:53:49 -0500655const static struct wl_shell_interface shell_interface = {
656 shell_move,
657 shell_resize,
Kristian Høgsbergae6c8a62011-01-18 09:08:53 -0500658 shell_create_drag,
659 shell_create_selection
Kristian Høgsberg4cca3492011-01-18 07:53:49 -0500660};
661
662int
663wlsc_shell_init(struct wlsc_compositor *ec)
664{
665 struct wl_shell *shell = &ec->shell;
666
667 shell->object.interface = &wl_shell_interface;
668 shell->object.implementation = (void (**)(void)) &shell_interface;
669 wl_display_add_object(ec->wl_display, &shell->object);
670 if (wl_display_add_global(ec->wl_display, &shell->object, NULL))
671 return -1;
672
673 return 0;
674}