blob: 9b6d475b1e7c4c5eb8130458160cb6ff84d66cbc [file] [log] [blame]
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001/*
2 * Copyright © 2013 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 <stdint.h>
25#include <string.h>
Kristian Høgsbergb5e26102013-04-18 15:40:10 -040026#include <sys/mman.h>
27#include <assert.h>
28#include <unistd.h>
Kristian Høgsberg2158a882013-04-18 15:07:39 -040029
Kristian Høgsbergb5e26102013-04-18 15:40:10 -040030#include "../shared/os-compatibility.h"
Kristian Høgsberg2158a882013-04-18 15:07:39 -040031#include "compositor.h"
32
Kristian Høgsbergb5e26102013-04-18 15:40:10 -040033static void
34empty_region(pixman_region32_t *region)
35{
36 pixman_region32_fini(region);
37 pixman_region32_init(region);
38}
39
40static void unbind_resource(struct wl_resource *resource)
41{
42 wl_list_remove(&resource->link);
43 free(resource);
44}
45
46void
Kristian Høgsberga71e8b22013-05-06 21:51:21 -040047weston_seat_repick(struct weston_seat *seat)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -040048{
Kristian Høgsberg02bbabb2013-05-06 22:15:05 -040049 const struct weston_pointer_grab_interface *interface;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -040050
Kristian Høgsberg6848c252013-05-08 22:02:59 -040051 if (seat->pointer == NULL)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -040052 return;
53
Kristian Høgsberg6848c252013-05-08 22:02:59 -040054 interface = seat->pointer->grab->interface;
55 interface->focus(seat->pointer->grab);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -040056}
57
58static void
59weston_compositor_idle_inhibit(struct weston_compositor *compositor)
60{
61 weston_compositor_wake(compositor);
62 compositor->idle_inhibit++;
63}
64
65static void
66weston_compositor_idle_release(struct weston_compositor *compositor)
67{
68 compositor->idle_inhibit--;
69 weston_compositor_wake(compositor);
70}
71
Kristian Høgsberg2158a882013-04-18 15:07:39 -040072static void
73lose_pointer_focus(struct wl_listener *listener, void *data)
74{
Kristian Høgsberg02bbabb2013-05-06 22:15:05 -040075 struct weston_pointer *pointer =
76 container_of(listener, struct weston_pointer, focus_listener);
Kristian Høgsberg2158a882013-04-18 15:07:39 -040077
78 pointer->focus_resource = NULL;
79}
80
81static void
82lose_keyboard_focus(struct wl_listener *listener, void *data)
83{
Kristian Høgsberg29139d42013-04-18 15:25:39 -040084 struct weston_keyboard *keyboard =
85 container_of(listener, struct weston_keyboard, focus_listener);
Kristian Høgsberg2158a882013-04-18 15:07:39 -040086
87 keyboard->focus_resource = NULL;
88}
89
90static void
91lose_touch_focus(struct wl_listener *listener, void *data)
92{
Kristian Høgsberge329f362013-05-06 22:19:57 -040093 struct weston_touch *touch =
94 container_of(listener, struct weston_touch, focus_listener);
Kristian Høgsberg2158a882013-04-18 15:07:39 -040095
96 touch->focus_resource = NULL;
97}
98
99static void
Kristian Høgsberg6848c252013-05-08 22:02:59 -0400100default_grab_focus(struct weston_pointer_grab *grab)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400101{
Kristian Høgsberg02bbabb2013-05-06 22:15:05 -0400102 struct weston_pointer *pointer = grab->pointer;
Kristian Høgsberg6848c252013-05-08 22:02:59 -0400103 struct weston_surface *surface;
104 wl_fixed_t sx, sy;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400105
106 if (pointer->button_count > 0)
107 return;
108
Kristian Høgsberg6848c252013-05-08 22:02:59 -0400109 surface = weston_compositor_pick_surface(pointer->seat->compositor,
110 pointer->x, pointer->y,
111 &sx, &sy);
112
Kristian Høgsberge122b7b2013-05-08 16:47:00 -0400113 if (pointer->focus != surface)
Kristian Høgsberg6848c252013-05-08 22:02:59 -0400114 weston_pointer_set_focus(pointer, surface, sx, sy);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400115}
116
117static void
Kristian Høgsbergbe6403e2013-05-08 21:03:21 -0400118default_grab_motion(struct weston_pointer_grab *grab, uint32_t time)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400119{
Kristian Høgsbergbe6403e2013-05-08 21:03:21 -0400120 struct weston_pointer *pointer = grab->pointer;
121 wl_fixed_t sx, sy;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400122
Kristian Høgsbergbe6403e2013-05-08 21:03:21 -0400123 if (pointer->focus_resource) {
124 weston_surface_from_global_fixed(pointer->focus,
125 pointer->x, pointer->y,
126 &sx, &sy);
127 wl_pointer_send_motion(pointer->focus_resource, time, sx, sy);
128 }
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400129}
130
131static void
Kristian Høgsberg02bbabb2013-05-06 22:15:05 -0400132default_grab_button(struct weston_pointer_grab *grab,
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400133 uint32_t time, uint32_t button, uint32_t state_w)
134{
Kristian Høgsberg02bbabb2013-05-06 22:15:05 -0400135 struct weston_pointer *pointer = grab->pointer;
Kristian Høgsberge122b7b2013-05-08 16:47:00 -0400136 struct weston_compositor *compositor = pointer->seat->compositor;
137 struct weston_surface *surface;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400138 struct wl_resource *resource;
139 uint32_t serial;
140 enum wl_pointer_button_state state = state_w;
141 struct wl_display *display;
Kristian Høgsberge122b7b2013-05-08 16:47:00 -0400142 wl_fixed_t sx, sy;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400143
144 resource = pointer->focus_resource;
145 if (resource) {
146 display = wl_client_get_display(resource->client);
147 serial = wl_display_next_serial(display);
148 wl_pointer_send_button(resource, serial, time, button, state_w);
149 }
150
151 if (pointer->button_count == 0 &&
Kristian Høgsberge122b7b2013-05-08 16:47:00 -0400152 state == WL_POINTER_BUTTON_STATE_RELEASED) {
153 surface = weston_compositor_pick_surface(compositor,
154 pointer->x,
155 pointer->y,
156 &sx, &sy);
157
158 weston_pointer_set_focus(pointer, surface, sx, sy);
159 }
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400160}
161
Kristian Høgsberg02bbabb2013-05-06 22:15:05 -0400162static const struct weston_pointer_grab_interface
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400163 default_pointer_grab_interface = {
164 default_grab_focus,
165 default_grab_motion,
166 default_grab_button
167};
168
Kristian Høgsberge329f362013-05-06 22:19:57 -0400169static void
170default_grab_touch_down(struct weston_touch_grab *grab, uint32_t time,
171 int touch_id, wl_fixed_t sx, wl_fixed_t sy)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400172{
Kristian Høgsberge329f362013-05-06 22:19:57 -0400173 struct weston_touch *touch = grab->touch;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400174 struct wl_display *display;
175 uint32_t serial;
176
177 if (touch->focus_resource && touch->focus) {
178 display = wl_client_get_display(touch->focus_resource->client);
179 serial = wl_display_next_serial(display);
180 wl_touch_send_down(touch->focus_resource, serial, time,
Jason Ekstrand26ed73c2013-06-06 22:34:41 -0500181 touch->focus->resource,
Kristian Høgsberge329f362013-05-06 22:19:57 -0400182 touch_id, sx, sy);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400183 }
184}
185
Kristian Høgsberge329f362013-05-06 22:19:57 -0400186static void
187default_grab_touch_up(struct weston_touch_grab *grab,
188 uint32_t time, int touch_id)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400189{
Kristian Høgsberge329f362013-05-06 22:19:57 -0400190 struct weston_touch *touch = grab->touch;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400191 struct wl_display *display;
192 uint32_t serial;
193
194 if (touch->focus_resource) {
195 display = wl_client_get_display(touch->focus_resource->client);
196 serial = wl_display_next_serial(display);
197 wl_touch_send_up(touch->focus_resource, serial, time, touch_id);
198 }
199}
200
Kristian Høgsberge329f362013-05-06 22:19:57 -0400201static void
202default_grab_touch_motion(struct weston_touch_grab *grab, uint32_t time,
203 int touch_id, wl_fixed_t sx, wl_fixed_t sy)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400204{
Kristian Høgsberge329f362013-05-06 22:19:57 -0400205 struct weston_touch *touch = grab->touch;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400206
207 if (touch->focus_resource) {
208 wl_touch_send_motion(touch->focus_resource, time,
Kristian Høgsberge329f362013-05-06 22:19:57 -0400209 touch_id, sx, sy);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400210 }
211}
212
Kristian Høgsberge329f362013-05-06 22:19:57 -0400213static const struct weston_touch_grab_interface default_touch_grab_interface = {
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400214 default_grab_touch_down,
215 default_grab_touch_up,
216 default_grab_touch_motion
217};
218
219static void
Kristian Høgsberg29139d42013-04-18 15:25:39 -0400220default_grab_key(struct weston_keyboard_grab *grab,
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400221 uint32_t time, uint32_t key, uint32_t state)
222{
Kristian Høgsberg29139d42013-04-18 15:25:39 -0400223 struct weston_keyboard *keyboard = grab->keyboard;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400224 struct wl_resource *resource;
225 struct wl_display *display;
226 uint32_t serial;
227
228 resource = keyboard->focus_resource;
229 if (resource) {
230 display = wl_client_get_display(resource->client);
231 serial = wl_display_next_serial(display);
232 wl_keyboard_send_key(resource, serial, time, key, state);
233 }
234}
235
236static struct wl_resource *
Kristian Høgsbergfe7aa902013-05-08 09:54:37 -0400237find_resource_for_surface(struct wl_list *list, struct weston_surface *surface)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400238{
239 struct wl_resource *r;
240
241 if (!surface)
242 return NULL;
243
244 wl_list_for_each(r, list, link) {
Jason Ekstrand26ed73c2013-06-06 22:34:41 -0500245 if (r->client == wl_resource_get_client(surface->resource))
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400246 return r;
247 }
248
249 return NULL;
250}
251
252static void
Kristian Høgsberg29139d42013-04-18 15:25:39 -0400253default_grab_modifiers(struct weston_keyboard_grab *grab, uint32_t serial,
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400254 uint32_t mods_depressed, uint32_t mods_latched,
255 uint32_t mods_locked, uint32_t group)
256{
Kristian Høgsberg29139d42013-04-18 15:25:39 -0400257 struct weston_keyboard *keyboard = grab->keyboard;
Kristian Høgsberg02bbabb2013-05-06 22:15:05 -0400258 struct weston_pointer *pointer = keyboard->seat->pointer;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400259 struct wl_resource *resource, *pr;
260
261 resource = keyboard->focus_resource;
262 if (!resource)
263 return;
264
265 wl_keyboard_send_modifiers(resource, serial, mods_depressed,
266 mods_latched, mods_locked, group);
267
268 if (pointer && pointer->focus && pointer->focus != keyboard->focus) {
269 pr = find_resource_for_surface(&keyboard->resource_list,
270 pointer->focus);
271 if (pr) {
272 wl_keyboard_send_modifiers(pr,
273 serial,
274 keyboard->modifiers.mods_depressed,
275 keyboard->modifiers.mods_latched,
276 keyboard->modifiers.mods_locked,
277 keyboard->modifiers.group);
278 }
279 }
280}
281
Kristian Høgsberg29139d42013-04-18 15:25:39 -0400282static const struct weston_keyboard_grab_interface
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400283 default_keyboard_grab_interface = {
284 default_grab_key,
285 default_grab_modifiers,
286};
287
Kristian Høgsberg195b8692013-05-08 15:02:05 -0400288static void
289pointer_unmap_sprite(struct weston_pointer *pointer)
290{
291 if (weston_surface_is_mapped(pointer->sprite))
292 weston_surface_unmap(pointer->sprite);
293
294 wl_list_remove(&pointer->sprite_destroy_listener.link);
295 pointer->sprite->configure = NULL;
296 pointer->sprite->configure_private = NULL;
297 pointer->sprite = NULL;
298}
299
300static void
301pointer_handle_sprite_destroy(struct wl_listener *listener, void *data)
302{
303 struct weston_pointer *pointer =
304 container_of(listener, struct weston_pointer,
305 sprite_destroy_listener);
306
307 pointer->sprite = NULL;
308}
309
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400310WL_EXPORT struct weston_pointer *
311weston_pointer_create(void)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400312{
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400313 struct weston_pointer *pointer;
314
315 pointer = malloc(sizeof *pointer);
316 if (pointer == NULL)
317 return NULL;
318
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400319 memset(pointer, 0, sizeof *pointer);
320 wl_list_init(&pointer->resource_list);
321 pointer->focus_listener.notify = lose_pointer_focus;
322 pointer->default_grab.interface = &default_pointer_grab_interface;
323 pointer->default_grab.pointer = pointer;
324 pointer->grab = &pointer->default_grab;
325 wl_signal_init(&pointer->focus_signal);
326
Kristian Høgsberg195b8692013-05-08 15:02:05 -0400327 pointer->sprite_destroy_listener.notify = pointer_handle_sprite_destroy;
328
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400329 /* FIXME: Pick better co-ords. */
330 pointer->x = wl_fixed_from_int(100);
331 pointer->y = wl_fixed_from_int(100);
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400332
333 return pointer;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400334}
335
336WL_EXPORT void
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400337weston_pointer_destroy(struct weston_pointer *pointer)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400338{
Kristian Høgsberg195b8692013-05-08 15:02:05 -0400339 if (pointer->sprite)
340 pointer_unmap_sprite(pointer);
341
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400342 /* XXX: What about pointer->resource_list? */
343 if (pointer->focus_resource)
344 wl_list_remove(&pointer->focus_listener.link);
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400345 free(pointer);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400346}
347
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400348WL_EXPORT struct weston_keyboard *
349weston_keyboard_create(void)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400350{
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400351 struct weston_keyboard *keyboard;
352
353 keyboard = malloc(sizeof *keyboard);
354 if (keyboard == NULL)
355 return NULL;
356
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400357 memset(keyboard, 0, sizeof *keyboard);
358 wl_list_init(&keyboard->resource_list);
359 wl_array_init(&keyboard->keys);
360 keyboard->focus_listener.notify = lose_keyboard_focus;
361 keyboard->default_grab.interface = &default_keyboard_grab_interface;
362 keyboard->default_grab.keyboard = keyboard;
363 keyboard->grab = &keyboard->default_grab;
364 wl_signal_init(&keyboard->focus_signal);
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400365
366 return keyboard;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400367}
368
369WL_EXPORT void
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400370weston_keyboard_destroy(struct weston_keyboard *keyboard)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400371{
372 /* XXX: What about keyboard->resource_list? */
373 if (keyboard->focus_resource)
374 wl_list_remove(&keyboard->focus_listener.link);
375 wl_array_release(&keyboard->keys);
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400376 free(keyboard);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400377}
378
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400379WL_EXPORT struct weston_touch *
380weston_touch_create(void)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400381{
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400382 struct weston_touch *touch;
383
384 touch = malloc(sizeof *touch);
385 if (touch == NULL)
386 return NULL;
387
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400388 memset(touch, 0, sizeof *touch);
389 wl_list_init(&touch->resource_list);
390 touch->focus_listener.notify = lose_touch_focus;
391 touch->default_grab.interface = &default_touch_grab_interface;
392 touch->default_grab.touch = touch;
393 touch->grab = &touch->default_grab;
394 wl_signal_init(&touch->focus_signal);
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400395
396 return touch;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400397}
398
399WL_EXPORT void
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400400weston_touch_destroy(struct weston_touch *touch)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400401{
402 /* XXX: What about touch->resource_list? */
403 if (touch->focus_resource)
404 wl_list_remove(&touch->focus_listener.link);
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400405 free(touch);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400406}
407
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400408static void
Kristian Høgsberge3148752013-05-06 23:19:49 -0400409seat_send_updated_caps(struct weston_seat *seat)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400410{
411 struct wl_resource *r;
412 enum wl_seat_capability caps = 0;
413
414 if (seat->pointer)
415 caps |= WL_SEAT_CAPABILITY_POINTER;
416 if (seat->keyboard)
417 caps |= WL_SEAT_CAPABILITY_KEYBOARD;
418 if (seat->touch)
419 caps |= WL_SEAT_CAPABILITY_TOUCH;
420
421 wl_list_for_each(r, &seat->base_resource_list, link)
422 wl_seat_send_capabilities(r, caps);
423}
424
425WL_EXPORT void
Kristian Høgsberg02bbabb2013-05-06 22:15:05 -0400426weston_pointer_set_focus(struct weston_pointer *pointer,
Kristian Høgsbergfe7aa902013-05-08 09:54:37 -0400427 struct weston_surface *surface,
Kristian Høgsberg02bbabb2013-05-06 22:15:05 -0400428 wl_fixed_t sx, wl_fixed_t sy)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400429{
Kristian Høgsberg29139d42013-04-18 15:25:39 -0400430 struct weston_keyboard *kbd = pointer->seat->keyboard;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400431 struct wl_resource *resource, *kr;
432 struct wl_display *display;
433 uint32_t serial;
434
435 resource = pointer->focus_resource;
436 if (resource && pointer->focus != surface) {
437 display = wl_client_get_display(resource->client);
438 serial = wl_display_next_serial(display);
439 wl_pointer_send_leave(resource, serial,
Jason Ekstrand26ed73c2013-06-06 22:34:41 -0500440 pointer->focus->resource);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400441 wl_list_remove(&pointer->focus_listener.link);
442 }
443
444 resource = find_resource_for_surface(&pointer->resource_list,
445 surface);
446 if (resource &&
447 (pointer->focus != surface ||
448 pointer->focus_resource != resource)) {
449 display = wl_client_get_display(resource->client);
450 serial = wl_display_next_serial(display);
451 if (kbd) {
452 kr = find_resource_for_surface(&kbd->resource_list,
453 surface);
454 if (kr) {
455 wl_keyboard_send_modifiers(kr,
456 serial,
457 kbd->modifiers.mods_depressed,
458 kbd->modifiers.mods_latched,
459 kbd->modifiers.mods_locked,
460 kbd->modifiers.group);
461 }
462 }
Jason Ekstrand26ed73c2013-06-06 22:34:41 -0500463 wl_pointer_send_enter(resource, serial, surface->resource,
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400464 sx, sy);
465 wl_signal_add(&resource->destroy_signal,
466 &pointer->focus_listener);
467 pointer->focus_serial = serial;
468 }
469
470 pointer->focus_resource = resource;
471 pointer->focus = surface;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400472 wl_signal_emit(&pointer->focus_signal, pointer);
473}
474
475WL_EXPORT void
Kristian Høgsberg29139d42013-04-18 15:25:39 -0400476weston_keyboard_set_focus(struct weston_keyboard *keyboard,
Kristian Høgsbergfe7aa902013-05-08 09:54:37 -0400477 struct weston_surface *surface)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400478{
479 struct wl_resource *resource;
480 struct wl_display *display;
481 uint32_t serial;
482
483 if (keyboard->focus_resource && keyboard->focus != surface) {
484 resource = keyboard->focus_resource;
485 display = wl_client_get_display(resource->client);
486 serial = wl_display_next_serial(display);
487 wl_keyboard_send_leave(resource, serial,
Jason Ekstrand26ed73c2013-06-06 22:34:41 -0500488 keyboard->focus->resource);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400489 wl_list_remove(&keyboard->focus_listener.link);
490 }
491
492 resource = find_resource_for_surface(&keyboard->resource_list,
493 surface);
494 if (resource &&
495 (keyboard->focus != surface ||
496 keyboard->focus_resource != resource)) {
497 display = wl_client_get_display(resource->client);
498 serial = wl_display_next_serial(display);
499 wl_keyboard_send_modifiers(resource, serial,
500 keyboard->modifiers.mods_depressed,
501 keyboard->modifiers.mods_latched,
502 keyboard->modifiers.mods_locked,
503 keyboard->modifiers.group);
Jason Ekstrand26ed73c2013-06-06 22:34:41 -0500504 wl_keyboard_send_enter(resource, serial, surface->resource,
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400505 &keyboard->keys);
506 wl_signal_add(&resource->destroy_signal,
507 &keyboard->focus_listener);
508 keyboard->focus_serial = serial;
509 }
510
511 keyboard->focus_resource = resource;
512 keyboard->focus = surface;
513 wl_signal_emit(&keyboard->focus_signal, keyboard);
514}
515
516WL_EXPORT void
Kristian Høgsberg29139d42013-04-18 15:25:39 -0400517weston_keyboard_start_grab(struct weston_keyboard *keyboard,
518 struct weston_keyboard_grab *grab)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400519{
520 keyboard->grab = grab;
521 grab->keyboard = keyboard;
522
523 /* XXX focus? */
524}
525
526WL_EXPORT void
Kristian Høgsberg29139d42013-04-18 15:25:39 -0400527weston_keyboard_end_grab(struct weston_keyboard *keyboard)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400528{
529 keyboard->grab = &keyboard->default_grab;
530}
531
532WL_EXPORT void
Kristian Høgsberg02bbabb2013-05-06 22:15:05 -0400533weston_pointer_start_grab(struct weston_pointer *pointer,
534 struct weston_pointer_grab *grab)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400535{
Kristian Høgsberg02bbabb2013-05-06 22:15:05 -0400536 const struct weston_pointer_grab_interface *interface;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400537
538 pointer->grab = grab;
539 interface = pointer->grab->interface;
540 grab->pointer = pointer;
Kristian Høgsberg6848c252013-05-08 22:02:59 -0400541 interface->focus(pointer->grab);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400542}
543
544WL_EXPORT void
Kristian Høgsberg02bbabb2013-05-06 22:15:05 -0400545weston_pointer_end_grab(struct weston_pointer *pointer)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400546{
Kristian Høgsberg02bbabb2013-05-06 22:15:05 -0400547 const struct weston_pointer_grab_interface *interface;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400548
549 pointer->grab = &pointer->default_grab;
550 interface = pointer->grab->interface;
Kristian Høgsberg6848c252013-05-08 22:02:59 -0400551 interface->focus(pointer->grab);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400552}
553
554WL_EXPORT void
Kristian Høgsberge329f362013-05-06 22:19:57 -0400555weston_touch_start_grab(struct weston_touch *touch, struct weston_touch_grab *grab)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400556{
557 touch->grab = grab;
558 grab->touch = touch;
559}
560
561WL_EXPORT void
Kristian Høgsberge329f362013-05-06 22:19:57 -0400562weston_touch_end_grab(struct weston_touch *touch)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400563{
564 touch->grab = &touch->default_grab;
565}
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400566
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400567static void
568clip_pointer_motion(struct weston_seat *seat, wl_fixed_t *fx, wl_fixed_t *fy)
569{
570 struct weston_compositor *ec = seat->compositor;
571 struct weston_output *output, *prev = NULL;
572 int x, y, old_x, old_y, valid = 0;
573
574 x = wl_fixed_to_int(*fx);
575 y = wl_fixed_to_int(*fy);
Kristian Høgsberge3148752013-05-06 23:19:49 -0400576 old_x = wl_fixed_to_int(seat->pointer->x);
577 old_y = wl_fixed_to_int(seat->pointer->y);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400578
579 wl_list_for_each(output, &ec->output_list, link) {
580 if (pixman_region32_contains_point(&output->region,
581 x, y, NULL))
582 valid = 1;
583 if (pixman_region32_contains_point(&output->region,
584 old_x, old_y, NULL))
585 prev = output;
586 }
587
588 if (!valid) {
589 if (x < prev->x)
590 *fx = wl_fixed_from_int(prev->x);
591 else if (x >= prev->x + prev->width)
592 *fx = wl_fixed_from_int(prev->x +
593 prev->width - 1);
594 if (y < prev->y)
595 *fy = wl_fixed_from_int(prev->y);
Alexander Larssonbcd18d92013-05-28 16:23:33 +0200596 else if (y >= prev->y + prev->height)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400597 *fy = wl_fixed_from_int(prev->y +
598 prev->height - 1);
599 }
600}
601
602/* Takes absolute values */
603static void
604move_pointer(struct weston_seat *seat, wl_fixed_t x, wl_fixed_t y)
605{
606 struct weston_compositor *ec = seat->compositor;
Kristian Høgsberge3148752013-05-06 23:19:49 -0400607 struct weston_pointer *pointer = seat->pointer;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400608 struct weston_output *output;
609 int32_t ix, iy;
610
611 clip_pointer_motion(seat, &x, &y);
612
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400613 pointer->x = x;
614 pointer->y = y;
615
616 ix = wl_fixed_to_int(x);
617 iy = wl_fixed_to_int(y);
618
619 wl_list_for_each(output, &ec->output_list, link)
620 if (output->zoom.active &&
621 pixman_region32_contains_point(&output->region,
622 ix, iy, NULL))
623 weston_output_update_zoom(output, ZOOM_FOCUS_POINTER);
624
Kristian Høgsberg195b8692013-05-08 15:02:05 -0400625 if (pointer->sprite) {
626 weston_surface_set_position(pointer->sprite,
627 ix - pointer->hotspot_x,
628 iy - pointer->hotspot_y);
629 weston_surface_schedule_repaint(pointer->sprite);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400630 }
631}
632
633WL_EXPORT void
634notify_motion(struct weston_seat *seat,
635 uint32_t time, wl_fixed_t dx, wl_fixed_t dy)
636{
Kristian Høgsberg02bbabb2013-05-06 22:15:05 -0400637 const struct weston_pointer_grab_interface *interface;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400638 struct weston_compositor *ec = seat->compositor;
Kristian Høgsberge3148752013-05-06 23:19:49 -0400639 struct weston_pointer *pointer = seat->pointer;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400640
641 weston_compositor_wake(ec);
642
643 move_pointer(seat, pointer->x + dx, pointer->y + dy);
644
645 interface = pointer->grab->interface;
Kristian Høgsberg6848c252013-05-08 22:02:59 -0400646 interface->focus(pointer->grab);
Kristian Høgsbergbe6403e2013-05-08 21:03:21 -0400647 interface->motion(pointer->grab, time);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400648}
649
650WL_EXPORT void
651notify_motion_absolute(struct weston_seat *seat,
652 uint32_t time, wl_fixed_t x, wl_fixed_t y)
653{
Kristian Høgsberg02bbabb2013-05-06 22:15:05 -0400654 const struct weston_pointer_grab_interface *interface;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400655 struct weston_compositor *ec = seat->compositor;
Kristian Høgsberge3148752013-05-06 23:19:49 -0400656 struct weston_pointer *pointer = seat->pointer;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400657
658 weston_compositor_wake(ec);
659
660 move_pointer(seat, x, y);
661
662 interface = pointer->grab->interface;
Kristian Høgsberg6848c252013-05-08 22:02:59 -0400663 interface->focus(pointer->grab);
Kristian Høgsbergbe6403e2013-05-08 21:03:21 -0400664 interface->motion(pointer->grab, time);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400665}
666
667WL_EXPORT void
668weston_surface_activate(struct weston_surface *surface,
669 struct weston_seat *seat)
670{
671 struct weston_compositor *compositor = seat->compositor;
672
Kristian Høgsberge3148752013-05-06 23:19:49 -0400673 if (seat->keyboard) {
Kristian Høgsbergfe7aa902013-05-08 09:54:37 -0400674 weston_keyboard_set_focus(seat->keyboard, surface);
Kristian Høgsberge3148752013-05-06 23:19:49 -0400675 wl_data_device_set_keyboard_focus(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400676 }
677
678 wl_signal_emit(&compositor->activate_signal, surface);
679}
680
681WL_EXPORT void
682notify_button(struct weston_seat *seat, uint32_t time, int32_t button,
683 enum wl_pointer_button_state state)
684{
685 struct weston_compositor *compositor = seat->compositor;
Kristian Høgsberge3148752013-05-06 23:19:49 -0400686 struct weston_pointer *pointer = seat->pointer;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400687 struct weston_surface *focus =
688 (struct weston_surface *) pointer->focus;
689 uint32_t serial = wl_display_next_serial(compositor->wl_display);
690
691 if (state == WL_POINTER_BUTTON_STATE_PRESSED) {
692 if (compositor->ping_handler && focus)
693 compositor->ping_handler(focus, serial);
694 weston_compositor_idle_inhibit(compositor);
695 if (pointer->button_count == 0) {
696 pointer->grab_button = button;
697 pointer->grab_time = time;
698 pointer->grab_x = pointer->x;
699 pointer->grab_y = pointer->y;
700 }
701 pointer->button_count++;
702 } else {
703 weston_compositor_idle_release(compositor);
704 pointer->button_count--;
705 }
706
707 weston_compositor_run_button_binding(compositor, seat, time, button,
708 state);
709
710 pointer->grab->interface->button(pointer->grab, time, button, state);
711
712 if (pointer->button_count == 1)
713 pointer->grab_serial =
714 wl_display_get_serial(compositor->wl_display);
715}
716
717WL_EXPORT void
718notify_axis(struct weston_seat *seat, uint32_t time, uint32_t axis,
719 wl_fixed_t value)
720{
721 struct weston_compositor *compositor = seat->compositor;
Kristian Høgsberge3148752013-05-06 23:19:49 -0400722 struct weston_pointer *pointer = seat->pointer;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400723 struct weston_surface *focus =
724 (struct weston_surface *) pointer->focus;
725 uint32_t serial = wl_display_next_serial(compositor->wl_display);
726
727 if (compositor->ping_handler && focus)
728 compositor->ping_handler(focus, serial);
729
730 weston_compositor_wake(compositor);
731
732 if (!value)
733 return;
734
735 if (weston_compositor_run_axis_binding(compositor, seat,
736 time, axis, value))
737 return;
738
739 if (pointer->focus_resource)
740 wl_pointer_send_axis(pointer->focus_resource, time, axis,
741 value);
742}
743
744WL_EXPORT void
745notify_modifiers(struct weston_seat *seat, uint32_t serial)
746{
Kristian Høgsberge3148752013-05-06 23:19:49 -0400747 struct weston_keyboard *keyboard = seat->keyboard;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400748 struct weston_keyboard_grab *grab = keyboard->grab;
749 uint32_t mods_depressed, mods_latched, mods_locked, group;
750 uint32_t mods_lookup;
751 enum weston_led leds = 0;
752 int changed = 0;
753
754 /* Serialize and update our internal state, checking to see if it's
755 * different to the previous state. */
756 mods_depressed = xkb_state_serialize_mods(seat->xkb_state.state,
757 XKB_STATE_DEPRESSED);
758 mods_latched = xkb_state_serialize_mods(seat->xkb_state.state,
759 XKB_STATE_LATCHED);
760 mods_locked = xkb_state_serialize_mods(seat->xkb_state.state,
761 XKB_STATE_LOCKED);
762 group = xkb_state_serialize_group(seat->xkb_state.state,
763 XKB_STATE_EFFECTIVE);
764
Kristian Høgsberge3148752013-05-06 23:19:49 -0400765 if (mods_depressed != seat->keyboard->modifiers.mods_depressed ||
766 mods_latched != seat->keyboard->modifiers.mods_latched ||
767 mods_locked != seat->keyboard->modifiers.mods_locked ||
768 group != seat->keyboard->modifiers.group)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400769 changed = 1;
770
Kristian Høgsberge3148752013-05-06 23:19:49 -0400771 seat->keyboard->modifiers.mods_depressed = mods_depressed;
772 seat->keyboard->modifiers.mods_latched = mods_latched;
773 seat->keyboard->modifiers.mods_locked = mods_locked;
774 seat->keyboard->modifiers.group = group;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400775
776 /* And update the modifier_state for bindings. */
777 mods_lookup = mods_depressed | mods_latched;
778 seat->modifier_state = 0;
779 if (mods_lookup & (1 << seat->xkb_info.ctrl_mod))
780 seat->modifier_state |= MODIFIER_CTRL;
781 if (mods_lookup & (1 << seat->xkb_info.alt_mod))
782 seat->modifier_state |= MODIFIER_ALT;
783 if (mods_lookup & (1 << seat->xkb_info.super_mod))
784 seat->modifier_state |= MODIFIER_SUPER;
785 if (mods_lookup & (1 << seat->xkb_info.shift_mod))
786 seat->modifier_state |= MODIFIER_SHIFT;
787
788 /* Finally, notify the compositor that LEDs have changed. */
789 if (xkb_state_led_index_is_active(seat->xkb_state.state,
790 seat->xkb_info.num_led))
791 leds |= LED_NUM_LOCK;
792 if (xkb_state_led_index_is_active(seat->xkb_state.state,
793 seat->xkb_info.caps_led))
794 leds |= LED_CAPS_LOCK;
795 if (xkb_state_led_index_is_active(seat->xkb_state.state,
796 seat->xkb_info.scroll_led))
797 leds |= LED_SCROLL_LOCK;
798 if (leds != seat->xkb_state.leds && seat->led_update)
799 seat->led_update(seat, leds);
800 seat->xkb_state.leds = leds;
801
802 if (changed) {
803 grab->interface->modifiers(grab,
804 serial,
805 keyboard->modifiers.mods_depressed,
806 keyboard->modifiers.mods_latched,
807 keyboard->modifiers.mods_locked,
808 keyboard->modifiers.group);
809 }
810}
811
812static void
813update_modifier_state(struct weston_seat *seat, uint32_t serial, uint32_t key,
814 enum wl_keyboard_key_state state)
815{
816 enum xkb_key_direction direction;
817
818 if (state == WL_KEYBOARD_KEY_STATE_PRESSED)
819 direction = XKB_KEY_DOWN;
820 else
821 direction = XKB_KEY_UP;
822
823 /* Offset the keycode by 8, as the evdev XKB rules reflect X's
824 * broken keycode system, which starts at 8. */
825 xkb_state_update_key(seat->xkb_state.state, key + 8, direction);
826
827 notify_modifiers(seat, serial);
828}
829
830WL_EXPORT void
831notify_key(struct weston_seat *seat, uint32_t time, uint32_t key,
832 enum wl_keyboard_key_state state,
833 enum weston_key_state_update update_state)
834{
835 struct weston_compositor *compositor = seat->compositor;
Kristian Høgsberge3148752013-05-06 23:19:49 -0400836 struct weston_keyboard *keyboard = seat->keyboard;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400837 struct weston_surface *focus =
838 (struct weston_surface *) keyboard->focus;
839 struct weston_keyboard_grab *grab = keyboard->grab;
840 uint32_t serial = wl_display_next_serial(compositor->wl_display);
841 uint32_t *k, *end;
842
843 if (state == WL_KEYBOARD_KEY_STATE_PRESSED) {
844 if (compositor->ping_handler && focus)
845 compositor->ping_handler(focus, serial);
846
847 weston_compositor_idle_inhibit(compositor);
848 keyboard->grab_key = key;
849 keyboard->grab_time = time;
850 } else {
851 weston_compositor_idle_release(compositor);
852 }
853
854 end = keyboard->keys.data + keyboard->keys.size;
855 for (k = keyboard->keys.data; k < end; k++) {
856 if (*k == key) {
857 /* Ignore server-generated repeats. */
858 if (state == WL_KEYBOARD_KEY_STATE_PRESSED)
859 return;
860 *k = *--end;
861 }
862 }
863 keyboard->keys.size = (void *) end - keyboard->keys.data;
864 if (state == WL_KEYBOARD_KEY_STATE_PRESSED) {
865 k = wl_array_add(&keyboard->keys, sizeof *k);
866 *k = key;
867 }
868
869 if (grab == &keyboard->default_grab ||
870 grab == &keyboard->input_method_grab) {
871 weston_compositor_run_key_binding(compositor, seat, time, key,
872 state);
873 grab = keyboard->grab;
874 }
875
876 grab->interface->key(grab, time, key, state);
877
878 if (update_state == STATE_UPDATE_AUTOMATIC) {
879 update_modifier_state(seat,
880 wl_display_get_serial(compositor->wl_display),
881 key,
882 state);
883 }
884}
885
886WL_EXPORT void
887notify_pointer_focus(struct weston_seat *seat, struct weston_output *output,
888 wl_fixed_t x, wl_fixed_t y)
889{
890 struct weston_compositor *compositor = seat->compositor;
891
892 if (output) {
893 move_pointer(seat, x, y);
894 compositor->focus = 1;
895 } else {
896 compositor->focus = 0;
Kristian Høgsberg02bbabb2013-05-06 22:15:05 -0400897 /* FIXME: We should call weston_pointer_set_focus(seat,
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400898 * NULL) here, but somehow that breaks re-entry... */
899 }
900}
901
902static void
903destroy_device_saved_kbd_focus(struct wl_listener *listener, void *data)
904{
905 struct weston_seat *ws;
906
907 ws = container_of(listener, struct weston_seat,
908 saved_kbd_focus_listener);
909
910 ws->saved_kbd_focus = NULL;
911}
912
913WL_EXPORT void
914notify_keyboard_focus_in(struct weston_seat *seat, struct wl_array *keys,
915 enum weston_key_state_update update_state)
916{
917 struct weston_compositor *compositor = seat->compositor;
Kristian Høgsberge3148752013-05-06 23:19:49 -0400918 struct weston_keyboard *keyboard = seat->keyboard;
Kristian Høgsbergfe7aa902013-05-08 09:54:37 -0400919 struct weston_surface *surface;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400920 uint32_t *k, serial;
921
922 serial = wl_display_next_serial(compositor->wl_display);
923 wl_array_copy(&keyboard->keys, keys);
924 wl_array_for_each(k, &keyboard->keys) {
925 weston_compositor_idle_inhibit(compositor);
926 if (update_state == STATE_UPDATE_AUTOMATIC)
927 update_modifier_state(seat, serial, *k,
928 WL_KEYBOARD_KEY_STATE_PRESSED);
929 }
930
931 /* Run key bindings after we've updated the state. */
932 wl_array_for_each(k, &keyboard->keys) {
933 weston_compositor_run_key_binding(compositor, seat, 0, *k,
934 WL_KEYBOARD_KEY_STATE_PRESSED);
935 }
936
937 surface = seat->saved_kbd_focus;
938
939 if (surface) {
940 wl_list_remove(&seat->saved_kbd_focus_listener.link);
941 weston_keyboard_set_focus(keyboard, surface);
942 seat->saved_kbd_focus = NULL;
943 }
944}
945
946WL_EXPORT void
947notify_keyboard_focus_out(struct weston_seat *seat)
948{
949 struct weston_compositor *compositor = seat->compositor;
Kristian Høgsberge3148752013-05-06 23:19:49 -0400950 struct weston_keyboard *keyboard = seat->keyboard;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400951 uint32_t *k, serial;
952
953 serial = wl_display_next_serial(compositor->wl_display);
954 wl_array_for_each(k, &keyboard->keys) {
955 weston_compositor_idle_release(compositor);
956 update_modifier_state(seat, serial, *k,
957 WL_KEYBOARD_KEY_STATE_RELEASED);
958 }
959
960 seat->modifier_state = 0;
961
962 if (keyboard->focus) {
963 seat->saved_kbd_focus = keyboard->focus;
964 seat->saved_kbd_focus_listener.notify =
965 destroy_device_saved_kbd_focus;
Jason Ekstrand26ed73c2013-06-06 22:34:41 -0500966 wl_signal_add(&keyboard->focus->destroy_signal,
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400967 &seat->saved_kbd_focus_listener);
968 }
969
970 weston_keyboard_set_focus(keyboard, NULL);
971 /* FIXME: We really need keyboard grab cancel here to
972 * let the grab shut down properly. As it is we leak
973 * the grab data. */
974 weston_keyboard_end_grab(keyboard);
975}
976
977static void
Kristian Høgsbergfe7aa902013-05-08 09:54:37 -0400978touch_set_focus(struct weston_seat *seat, struct weston_surface *surface)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400979{
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400980 struct wl_resource *resource;
981
982 if (seat->touch->focus == surface)
983 return;
984
985 if (seat->touch->focus_resource)
986 wl_list_remove(&seat->touch->focus_listener.link);
987 seat->touch->focus = NULL;
988 seat->touch->focus_resource = NULL;
989
990 if (surface) {
991 resource =
Kristian Høgsberg80fb82d2013-05-06 21:49:55 -0400992 find_resource_for_surface(&seat->touch->resource_list,
993 surface);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400994 if (!resource) {
995 weston_log("couldn't find resource\n");
996 return;
997 }
998
999 seat->touch->focus = surface;
1000 seat->touch->focus_resource = resource;
1001 wl_signal_add(&resource->destroy_signal,
1002 &seat->touch->focus_listener);
1003 }
1004}
1005
1006/**
1007 * notify_touch - emulates button touches and notifies surfaces accordingly.
1008 *
1009 * It assumes always the correct cycle sequence until it gets here: touch_down
1010 * → touch_update → ... → touch_update → touch_end. The driver is responsible
1011 * for sending along such order.
1012 *
1013 */
1014WL_EXPORT void
1015notify_touch(struct weston_seat *seat, uint32_t time, int touch_id,
1016 wl_fixed_t x, wl_fixed_t y, int touch_type)
1017{
1018 struct weston_compositor *ec = seat->compositor;
Kristian Høgsberge3148752013-05-06 23:19:49 -04001019 struct weston_touch *touch = seat->touch;
Kristian Høgsberge329f362013-05-06 22:19:57 -04001020 struct weston_touch_grab *grab = touch->grab;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001021 struct weston_surface *es;
1022 wl_fixed_t sx, sy;
1023
1024 /* Update grab's global coordinates. */
1025 touch->grab_x = x;
1026 touch->grab_y = y;
1027
1028 switch (touch_type) {
1029 case WL_TOUCH_DOWN:
1030 weston_compositor_idle_inhibit(ec);
1031
1032 seat->num_tp++;
1033
1034 /* the first finger down picks the surface, and all further go
1035 * to that surface for the remainder of the touch session i.e.
1036 * until all touch points are up again. */
1037 if (seat->num_tp == 1) {
1038 es = weston_compositor_pick_surface(ec, x, y, &sx, &sy);
Kristian Høgsbergfe7aa902013-05-08 09:54:37 -04001039 touch_set_focus(seat, es);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001040 } else if (touch->focus) {
1041 es = (struct weston_surface *) touch->focus;
1042 weston_surface_from_global_fixed(es, x, y, &sx, &sy);
1043 } else {
1044 /* Unexpected condition: We have non-initial touch but
1045 * there is no focused surface.
1046 */
1047 weston_log("touch event received with %d points down"
1048 "but no surface focused\n", seat->num_tp);
1049 return;
1050 }
1051
1052 grab->interface->down(grab, time, touch_id, sx, sy);
1053 break;
1054 case WL_TOUCH_MOTION:
1055 es = (struct weston_surface *) touch->focus;
1056 if (!es)
1057 break;
1058
1059 weston_surface_from_global_fixed(es, x, y, &sx, &sy);
1060 grab->interface->motion(grab, time, touch_id, sx, sy);
1061 break;
1062 case WL_TOUCH_UP:
1063 weston_compositor_idle_release(ec);
1064 seat->num_tp--;
1065
1066 grab->interface->up(grab, time, touch_id);
1067 if (seat->num_tp == 0)
1068 touch_set_focus(seat, NULL);
1069 break;
1070 }
1071}
1072
1073static void
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001074pointer_cursor_surface_configure(struct weston_surface *es,
1075 int32_t dx, int32_t dy, int32_t width, int32_t height)
1076{
Kristian Høgsberg195b8692013-05-08 15:02:05 -04001077 struct weston_pointer *pointer = es->configure_private;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001078 int x, y;
1079
1080 if (width == 0)
1081 return;
1082
Kristian Høgsberg195b8692013-05-08 15:02:05 -04001083 assert(es == pointer->sprite);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001084
Kristian Høgsberg195b8692013-05-08 15:02:05 -04001085 pointer->hotspot_x -= dx;
1086 pointer->hotspot_y -= dy;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001087
Kristian Høgsberg195b8692013-05-08 15:02:05 -04001088 x = wl_fixed_to_int(pointer->x) - pointer->hotspot_x;
1089 y = wl_fixed_to_int(pointer->y) - pointer->hotspot_y;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001090
Kristian Høgsberg195b8692013-05-08 15:02:05 -04001091 weston_surface_configure(pointer->sprite, x, y, width, height);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001092
1093 empty_region(&es->pending.input);
1094
1095 if (!weston_surface_is_mapped(es)) {
1096 wl_list_insert(&es->compositor->cursor_layer.surface_list,
1097 &es->layer_link);
1098 weston_surface_update_transform(es);
1099 }
1100}
1101
1102static void
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001103pointer_set_cursor(struct wl_client *client, struct wl_resource *resource,
1104 uint32_t serial, struct wl_resource *surface_resource,
1105 int32_t x, int32_t y)
1106{
Kristian Høgsberg195b8692013-05-08 15:02:05 -04001107 struct weston_pointer *pointer = resource->data;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001108 struct weston_surface *surface = NULL;
1109
1110 if (surface_resource)
Jason Ekstrand0f2ef7e2013-06-14 10:07:53 -05001111 surface = wl_resource_get_user_data(surface_resource);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001112
Kristian Høgsberg195b8692013-05-08 15:02:05 -04001113 if (pointer->focus == NULL)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001114 return;
Jason Ekstrand26ed73c2013-06-06 22:34:41 -05001115 if (wl_resource_get_client(pointer->focus->resource) != client)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001116 return;
Kristian Høgsberg195b8692013-05-08 15:02:05 -04001117 if (pointer->focus_serial - serial > UINT32_MAX / 2)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001118 return;
1119
Kristian Høgsberg195b8692013-05-08 15:02:05 -04001120 if (surface && surface != pointer->sprite) {
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001121 if (surface->configure) {
Jason Ekstrand26ed73c2013-06-06 22:34:41 -05001122 wl_resource_post_error(surface->resource,
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001123 WL_DISPLAY_ERROR_INVALID_OBJECT,
1124 "surface->configure already "
1125 "set");
1126 return;
1127 }
1128 }
1129
Kristian Høgsberg195b8692013-05-08 15:02:05 -04001130 if (pointer->sprite)
1131 pointer_unmap_sprite(pointer);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001132
1133 if (!surface)
1134 return;
1135
Jason Ekstrand26ed73c2013-06-06 22:34:41 -05001136 wl_signal_add(&surface->destroy_signal,
Kristian Høgsberg195b8692013-05-08 15:02:05 -04001137 &pointer->sprite_destroy_listener);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001138
1139 surface->configure = pointer_cursor_surface_configure;
Kristian Høgsberg195b8692013-05-08 15:02:05 -04001140 surface->configure_private = pointer;
1141 pointer->sprite = surface;
1142 pointer->hotspot_x = x;
1143 pointer->hotspot_y = y;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001144
1145 if (surface->buffer_ref.buffer)
1146 pointer_cursor_surface_configure(surface, 0, 0, weston_surface_buffer_width(surface),
1147 weston_surface_buffer_height(surface));
1148}
1149
1150static const struct wl_pointer_interface pointer_interface = {
1151 pointer_set_cursor
1152};
1153
1154static void
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001155seat_get_pointer(struct wl_client *client, struct wl_resource *resource,
1156 uint32_t id)
1157{
1158 struct weston_seat *seat = resource->data;
1159 struct wl_resource *cr;
1160
Kristian Høgsberge3148752013-05-06 23:19:49 -04001161 if (!seat->pointer)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001162 return;
1163
1164 cr = wl_client_add_object(client, &wl_pointer_interface,
Kristian Høgsberg195b8692013-05-08 15:02:05 -04001165 &pointer_interface, id, seat->pointer);
Kristian Høgsberge3148752013-05-06 23:19:49 -04001166 wl_list_insert(&seat->pointer->resource_list, &cr->link);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001167 cr->destroy = unbind_resource;
1168
Kristian Høgsberge3148752013-05-06 23:19:49 -04001169 if (seat->pointer->focus &&
Jason Ekstrand26ed73c2013-06-06 22:34:41 -05001170 wl_resource_get_client(seat->pointer->focus->resource) == client) {
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001171 struct weston_surface *surface;
1172 wl_fixed_t sx, sy;
1173
Kristian Høgsberge3148752013-05-06 23:19:49 -04001174 surface = (struct weston_surface *) seat->pointer->focus;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001175 weston_surface_from_global_fixed(surface,
Kristian Høgsberge3148752013-05-06 23:19:49 -04001176 seat->pointer->x,
1177 seat->pointer->y,
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001178 &sx,
1179 &sy);
Kristian Høgsberge3148752013-05-06 23:19:49 -04001180 weston_pointer_set_focus(seat->pointer,
1181 seat->pointer->focus,
Kristian Høgsberg02bbabb2013-05-06 22:15:05 -04001182 sx,
1183 sy);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001184 }
1185}
1186
1187static void
1188seat_get_keyboard(struct wl_client *client, struct wl_resource *resource,
1189 uint32_t id)
1190{
1191 struct weston_seat *seat = resource->data;
1192 struct wl_resource *cr;
1193
Kristian Høgsberge3148752013-05-06 23:19:49 -04001194 if (!seat->keyboard)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001195 return;
1196
1197 cr = wl_client_add_object(client, &wl_keyboard_interface, NULL, id,
1198 seat);
Kristian Høgsberge3148752013-05-06 23:19:49 -04001199 wl_list_insert(&seat->keyboard->resource_list, &cr->link);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001200 cr->destroy = unbind_resource;
1201
1202 wl_keyboard_send_keymap(cr, WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1,
1203 seat->xkb_info.keymap_fd,
1204 seat->xkb_info.keymap_size);
1205
Kristian Høgsberge3148752013-05-06 23:19:49 -04001206 if (seat->keyboard->focus &&
Jason Ekstrand26ed73c2013-06-06 22:34:41 -05001207 wl_resource_get_client(seat->keyboard->focus->resource) == client) {
Kristian Høgsberge3148752013-05-06 23:19:49 -04001208 weston_keyboard_set_focus(seat->keyboard,
1209 seat->keyboard->focus);
1210 wl_data_device_set_keyboard_focus(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001211 }
1212}
1213
1214static void
1215seat_get_touch(struct wl_client *client, struct wl_resource *resource,
1216 uint32_t id)
1217{
1218 struct weston_seat *seat = resource->data;
1219 struct wl_resource *cr;
1220
Kristian Høgsberge3148752013-05-06 23:19:49 -04001221 if (!seat->touch)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001222 return;
1223
1224 cr = wl_client_add_object(client, &wl_touch_interface, NULL, id, seat);
Kristian Høgsberge3148752013-05-06 23:19:49 -04001225 wl_list_insert(&seat->touch->resource_list, &cr->link);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001226 cr->destroy = unbind_resource;
1227}
1228
1229static const struct wl_seat_interface seat_interface = {
1230 seat_get_pointer,
1231 seat_get_keyboard,
1232 seat_get_touch,
1233};
1234
1235static void
1236bind_seat(struct wl_client *client, void *data, uint32_t version, uint32_t id)
1237{
Kristian Høgsberge3148752013-05-06 23:19:49 -04001238 struct weston_seat *seat = data;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001239 struct wl_resource *resource;
1240 enum wl_seat_capability caps = 0;
1241
1242 resource = wl_client_add_object(client, &wl_seat_interface,
1243 &seat_interface, id, data);
1244 wl_list_insert(&seat->base_resource_list, &resource->link);
1245 resource->destroy = unbind_resource;
1246
1247 if (seat->pointer)
1248 caps |= WL_SEAT_CAPABILITY_POINTER;
1249 if (seat->keyboard)
1250 caps |= WL_SEAT_CAPABILITY_KEYBOARD;
1251 if (seat->touch)
1252 caps |= WL_SEAT_CAPABILITY_TOUCH;
1253
1254 wl_seat_send_capabilities(resource, caps);
Rob Bradforde445ae62013-05-31 18:09:51 +01001255 if (version >= 2)
1256 wl_seat_send_name(resource, seat->seat_name);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001257}
1258
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001259int
1260weston_compositor_xkb_init(struct weston_compositor *ec,
1261 struct xkb_rule_names *names)
1262{
1263 if (ec->xkb_context == NULL) {
1264 ec->xkb_context = xkb_context_new(0);
1265 if (ec->xkb_context == NULL) {
1266 weston_log("failed to create XKB context\n");
1267 return -1;
1268 }
1269 }
1270
1271 if (names)
1272 ec->xkb_names = *names;
1273 if (!ec->xkb_names.rules)
1274 ec->xkb_names.rules = strdup("evdev");
1275 if (!ec->xkb_names.model)
1276 ec->xkb_names.model = strdup("pc105");
1277 if (!ec->xkb_names.layout)
1278 ec->xkb_names.layout = strdup("us");
1279
1280 return 0;
1281}
1282
1283static void xkb_info_destroy(struct weston_xkb_info *xkb_info)
1284{
1285 if (xkb_info->keymap)
1286 xkb_map_unref(xkb_info->keymap);
1287
1288 if (xkb_info->keymap_area)
1289 munmap(xkb_info->keymap_area, xkb_info->keymap_size);
1290 if (xkb_info->keymap_fd >= 0)
1291 close(xkb_info->keymap_fd);
1292}
1293
1294void
1295weston_compositor_xkb_destroy(struct weston_compositor *ec)
1296{
1297 free((char *) ec->xkb_names.rules);
1298 free((char *) ec->xkb_names.model);
1299 free((char *) ec->xkb_names.layout);
1300 free((char *) ec->xkb_names.variant);
1301 free((char *) ec->xkb_names.options);
1302
1303 xkb_info_destroy(&ec->xkb_info);
1304 xkb_context_unref(ec->xkb_context);
1305}
1306
1307static int
1308weston_xkb_info_new_keymap(struct weston_xkb_info *xkb_info)
1309{
1310 char *keymap_str;
1311
1312 xkb_info->shift_mod = xkb_map_mod_get_index(xkb_info->keymap,
1313 XKB_MOD_NAME_SHIFT);
1314 xkb_info->caps_mod = xkb_map_mod_get_index(xkb_info->keymap,
1315 XKB_MOD_NAME_CAPS);
1316 xkb_info->ctrl_mod = xkb_map_mod_get_index(xkb_info->keymap,
1317 XKB_MOD_NAME_CTRL);
1318 xkb_info->alt_mod = xkb_map_mod_get_index(xkb_info->keymap,
1319 XKB_MOD_NAME_ALT);
1320 xkb_info->mod2_mod = xkb_map_mod_get_index(xkb_info->keymap, "Mod2");
1321 xkb_info->mod3_mod = xkb_map_mod_get_index(xkb_info->keymap, "Mod3");
1322 xkb_info->super_mod = xkb_map_mod_get_index(xkb_info->keymap,
1323 XKB_MOD_NAME_LOGO);
1324 xkb_info->mod5_mod = xkb_map_mod_get_index(xkb_info->keymap, "Mod5");
1325
1326 xkb_info->num_led = xkb_map_led_get_index(xkb_info->keymap,
1327 XKB_LED_NAME_NUM);
1328 xkb_info->caps_led = xkb_map_led_get_index(xkb_info->keymap,
1329 XKB_LED_NAME_CAPS);
1330 xkb_info->scroll_led = xkb_map_led_get_index(xkb_info->keymap,
1331 XKB_LED_NAME_SCROLL);
1332
1333 keymap_str = xkb_map_get_as_string(xkb_info->keymap);
1334 if (keymap_str == NULL) {
1335 weston_log("failed to get string version of keymap\n");
1336 return -1;
1337 }
1338 xkb_info->keymap_size = strlen(keymap_str) + 1;
1339
1340 xkb_info->keymap_fd = os_create_anonymous_file(xkb_info->keymap_size);
1341 if (xkb_info->keymap_fd < 0) {
1342 weston_log("creating a keymap file for %lu bytes failed: %m\n",
1343 (unsigned long) xkb_info->keymap_size);
1344 goto err_keymap_str;
1345 }
1346
1347 xkb_info->keymap_area = mmap(NULL, xkb_info->keymap_size,
1348 PROT_READ | PROT_WRITE,
1349 MAP_SHARED, xkb_info->keymap_fd, 0);
1350 if (xkb_info->keymap_area == MAP_FAILED) {
1351 weston_log("failed to mmap() %lu bytes\n",
1352 (unsigned long) xkb_info->keymap_size);
1353 goto err_dev_zero;
1354 }
1355 strcpy(xkb_info->keymap_area, keymap_str);
1356 free(keymap_str);
1357
1358 return 0;
1359
1360err_dev_zero:
1361 close(xkb_info->keymap_fd);
1362 xkb_info->keymap_fd = -1;
1363err_keymap_str:
1364 free(keymap_str);
1365 return -1;
1366}
1367
1368static int
1369weston_compositor_build_global_keymap(struct weston_compositor *ec)
1370{
1371 if (ec->xkb_info.keymap != NULL)
1372 return 0;
1373
1374 ec->xkb_info.keymap = xkb_map_new_from_names(ec->xkb_context,
1375 &ec->xkb_names,
1376 0);
1377 if (ec->xkb_info.keymap == NULL) {
1378 weston_log("failed to compile global XKB keymap\n");
1379 weston_log(" tried rules %s, model %s, layout %s, variant %s, "
1380 "options %s\n",
1381 ec->xkb_names.rules, ec->xkb_names.model,
1382 ec->xkb_names.layout, ec->xkb_names.variant,
1383 ec->xkb_names.options);
1384 return -1;
1385 }
1386
1387 if (weston_xkb_info_new_keymap(&ec->xkb_info) < 0)
1388 return -1;
1389
1390 return 0;
1391}
1392
1393WL_EXPORT int
1394weston_seat_init_keyboard(struct weston_seat *seat, struct xkb_keymap *keymap)
1395{
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04001396 struct weston_keyboard *keyboard;
1397
Kristian Høgsberg2bf87622013-05-07 23:17:41 -04001398 if (seat->keyboard)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001399 return 0;
1400
1401 if (keymap != NULL) {
1402 seat->xkb_info.keymap = xkb_map_ref(keymap);
1403 if (weston_xkb_info_new_keymap(&seat->xkb_info) < 0)
1404 return -1;
1405 } else {
1406 if (weston_compositor_build_global_keymap(seat->compositor) < 0)
1407 return -1;
1408 seat->xkb_info = seat->compositor->xkb_info;
1409 seat->xkb_info.keymap = xkb_map_ref(seat->xkb_info.keymap);
1410 }
1411
1412 seat->xkb_state.state = xkb_state_new(seat->xkb_info.keymap);
1413 if (seat->xkb_state.state == NULL) {
1414 weston_log("failed to initialise XKB state\n");
1415 return -1;
1416 }
1417
1418 seat->xkb_state.leds = 0;
1419
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04001420 keyboard = weston_keyboard_create();
1421 if (keyboard == NULL) {
1422 weston_log("failed to allocate weston keyboard struct\n");
1423 return -1;
1424 }
1425
1426 seat->keyboard = keyboard;
1427 keyboard->seat = seat;
1428
1429 seat_send_updated_caps(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001430
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001431 return 0;
1432}
1433
1434WL_EXPORT void
1435weston_seat_init_pointer(struct weston_seat *seat)
1436{
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04001437 struct weston_pointer *pointer;
1438
Kristian Høgsberg2bf87622013-05-07 23:17:41 -04001439 if (seat->pointer)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001440 return;
1441
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04001442 pointer = weston_pointer_create();
1443 if (pointer == NULL)
1444 return;
1445
1446 seat->pointer = pointer;
1447 pointer->seat = seat;
1448
1449 seat_send_updated_caps(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001450}
1451
1452WL_EXPORT void
1453weston_seat_init_touch(struct weston_seat *seat)
1454{
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04001455 struct weston_touch *touch;
1456
Kristian Høgsberg2bf87622013-05-07 23:17:41 -04001457 if (seat->touch)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001458 return;
1459
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04001460 touch = weston_touch_create();
1461 if (touch == NULL)
1462 return;
1463
1464 seat->touch = touch;
1465 touch->seat = seat;
1466
1467 seat_send_updated_caps(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001468}
1469
1470WL_EXPORT void
Rob Bradford9af5f9e2013-05-31 18:09:50 +01001471weston_seat_init(struct weston_seat *seat, struct weston_compositor *ec,
1472 const char *seat_name)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001473{
Kristian Høgsberg4a2a2742013-05-06 22:24:50 -04001474 memset(seat, 0, sizeof *seat);
1475
Kristian Høgsberge3148752013-05-06 23:19:49 -04001476 seat->selection_data_source = NULL;
1477 wl_list_init(&seat->base_resource_list);
1478 wl_signal_init(&seat->selection_signal);
1479 wl_list_init(&seat->drag_resource_list);
Kristian Høgsberge3148752013-05-06 23:19:49 -04001480 wl_signal_init(&seat->destroy_signal);
Kristian Høgsberg4a2a2742013-05-06 22:24:50 -04001481
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001482 wl_display_add_global(ec->wl_display, &wl_seat_interface, seat,
1483 bind_seat);
1484
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001485 seat->compositor = ec;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001486 seat->modifier_state = 0;
1487 seat->num_tp = 0;
Rob Bradford9af5f9e2013-05-31 18:09:50 +01001488 seat->seat_name = strdup(seat_name);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001489
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001490 wl_list_insert(ec->seat_list.prev, &seat->link);
1491
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001492 clipboard_create(seat);
1493
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001494 wl_signal_emit(&ec->seat_created_signal, seat);
1495}
1496
1497WL_EXPORT void
1498weston_seat_release(struct weston_seat *seat)
1499{
1500 wl_list_remove(&seat->link);
1501 /* The global object is destroyed at wl_display_destroy() time. */
1502
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001503 if (seat->xkb_state.state != NULL)
1504 xkb_state_unref(seat->xkb_state.state);
1505 xkb_info_destroy(&seat->xkb_info);
1506
Kristian Høgsberge3148752013-05-06 23:19:49 -04001507 if (seat->pointer)
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04001508 weston_pointer_destroy(seat->pointer);
Kristian Høgsberge3148752013-05-06 23:19:49 -04001509 if (seat->keyboard)
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04001510 weston_keyboard_destroy(seat->keyboard);
Kristian Høgsberge3148752013-05-06 23:19:49 -04001511 if (seat->touch)
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04001512 weston_touch_destroy(seat->touch);
Kristian Høgsberg4a2a2742013-05-06 22:24:50 -04001513
Rob Bradford9af5f9e2013-05-31 18:09:50 +01001514 free (seat->seat_name);
1515
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001516 wl_signal_emit(&seat->destroy_signal, seat);
1517}