blob: 004d063471390487eaf56ab8150ca72ee18bcd9d [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{
Jason Ekstrand44a38632013-06-14 10:08:00 -050042 wl_list_remove(wl_resource_get_link(resource));
Kristian Høgsbergb5e26102013-04-18 15:40:10 -040043}
44
45void
Kristian Høgsberga71e8b22013-05-06 21:51:21 -040046weston_seat_repick(struct weston_seat *seat)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -040047{
Kristian Høgsberg02bbabb2013-05-06 22:15:05 -040048 const struct weston_pointer_grab_interface *interface;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -040049
Kristian Høgsberg6848c252013-05-08 22:02:59 -040050 if (seat->pointer == NULL)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -040051 return;
52
Kristian Høgsberg6848c252013-05-08 22:02:59 -040053 interface = seat->pointer->grab->interface;
54 interface->focus(seat->pointer->grab);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -040055}
56
57static void
58weston_compositor_idle_inhibit(struct weston_compositor *compositor)
59{
60 weston_compositor_wake(compositor);
61 compositor->idle_inhibit++;
62}
63
64static void
65weston_compositor_idle_release(struct weston_compositor *compositor)
66{
67 compositor->idle_inhibit--;
68 weston_compositor_wake(compositor);
69}
70
Kristian Høgsberg2158a882013-04-18 15:07:39 -040071static void
72lose_pointer_focus(struct wl_listener *listener, void *data)
73{
Kristian Høgsberg02bbabb2013-05-06 22:15:05 -040074 struct weston_pointer *pointer =
75 container_of(listener, struct weston_pointer, focus_listener);
Kristian Høgsberg2158a882013-04-18 15:07:39 -040076
77 pointer->focus_resource = NULL;
78}
79
80static void
81lose_keyboard_focus(struct wl_listener *listener, void *data)
82{
Kristian Høgsberg29139d42013-04-18 15:25:39 -040083 struct weston_keyboard *keyboard =
84 container_of(listener, struct weston_keyboard, focus_listener);
Kristian Høgsberg2158a882013-04-18 15:07:39 -040085
86 keyboard->focus_resource = NULL;
87}
88
89static void
90lose_touch_focus(struct wl_listener *listener, void *data)
91{
Kristian Høgsberge329f362013-05-06 22:19:57 -040092 struct weston_touch *touch =
93 container_of(listener, struct weston_touch, focus_listener);
Kristian Høgsberg2158a882013-04-18 15:07:39 -040094
95 touch->focus_resource = NULL;
96}
97
98static void
Kristian Høgsberg6848c252013-05-08 22:02:59 -040099default_grab_focus(struct weston_pointer_grab *grab)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400100{
Kristian Høgsberg02bbabb2013-05-06 22:15:05 -0400101 struct weston_pointer *pointer = grab->pointer;
Kristian Høgsberg6848c252013-05-08 22:02:59 -0400102 struct weston_surface *surface;
103 wl_fixed_t sx, sy;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400104
105 if (pointer->button_count > 0)
106 return;
107
Kristian Høgsberg6848c252013-05-08 22:02:59 -0400108 surface = weston_compositor_pick_surface(pointer->seat->compositor,
109 pointer->x, pointer->y,
110 &sx, &sy);
111
Kristian Høgsberge122b7b2013-05-08 16:47:00 -0400112 if (pointer->focus != surface)
Kristian Høgsberg6848c252013-05-08 22:02:59 -0400113 weston_pointer_set_focus(pointer, surface, sx, sy);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400114}
115
116static void
Kristian Høgsbergbe6403e2013-05-08 21:03:21 -0400117default_grab_motion(struct weston_pointer_grab *grab, uint32_t time)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400118{
Kristian Høgsbergbe6403e2013-05-08 21:03:21 -0400119 struct weston_pointer *pointer = grab->pointer;
120 wl_fixed_t sx, sy;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400121
Kristian Høgsbergbe6403e2013-05-08 21:03:21 -0400122 if (pointer->focus_resource) {
123 weston_surface_from_global_fixed(pointer->focus,
124 pointer->x, pointer->y,
125 &sx, &sy);
126 wl_pointer_send_motion(pointer->focus_resource, time, sx, sy);
127 }
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400128}
129
130static void
Kristian Høgsberg02bbabb2013-05-06 22:15:05 -0400131default_grab_button(struct weston_pointer_grab *grab,
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400132 uint32_t time, uint32_t button, uint32_t state_w)
133{
Kristian Høgsberg02bbabb2013-05-06 22:15:05 -0400134 struct weston_pointer *pointer = grab->pointer;
Kristian Høgsberge122b7b2013-05-08 16:47:00 -0400135 struct weston_compositor *compositor = pointer->seat->compositor;
136 struct weston_surface *surface;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400137 struct wl_resource *resource;
138 uint32_t serial;
139 enum wl_pointer_button_state state = state_w;
140 struct wl_display *display;
Kristian Høgsberge122b7b2013-05-08 16:47:00 -0400141 wl_fixed_t sx, sy;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400142
143 resource = pointer->focus_resource;
144 if (resource) {
Jason Ekstrand44a38632013-06-14 10:08:00 -0500145 display = wl_client_get_display(wl_resource_get_client(resource));
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400146 serial = wl_display_next_serial(display);
147 wl_pointer_send_button(resource, serial, time, button, state_w);
148 }
149
150 if (pointer->button_count == 0 &&
Kristian Høgsberge122b7b2013-05-08 16:47:00 -0400151 state == WL_POINTER_BUTTON_STATE_RELEASED) {
152 surface = weston_compositor_pick_surface(compositor,
153 pointer->x,
154 pointer->y,
155 &sx, &sy);
156
157 weston_pointer_set_focus(pointer, surface, sx, sy);
158 }
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400159}
160
Kristian Høgsberg02bbabb2013-05-06 22:15:05 -0400161static const struct weston_pointer_grab_interface
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400162 default_pointer_grab_interface = {
163 default_grab_focus,
164 default_grab_motion,
165 default_grab_button
166};
167
Kristian Høgsberge329f362013-05-06 22:19:57 -0400168static void
169default_grab_touch_down(struct weston_touch_grab *grab, uint32_t time,
170 int touch_id, wl_fixed_t sx, wl_fixed_t sy)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400171{
Kristian Høgsberge329f362013-05-06 22:19:57 -0400172 struct weston_touch *touch = grab->touch;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400173 struct wl_display *display;
174 uint32_t serial;
175
176 if (touch->focus_resource && touch->focus) {
Jason Ekstrand44a38632013-06-14 10:08:00 -0500177 display = wl_client_get_display(wl_resource_get_client(touch->focus_resource));
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400178 serial = wl_display_next_serial(display);
179 wl_touch_send_down(touch->focus_resource, serial, time,
Jason Ekstrand26ed73c2013-06-06 22:34:41 -0500180 touch->focus->resource,
Kristian Høgsberge329f362013-05-06 22:19:57 -0400181 touch_id, sx, sy);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400182 }
183}
184
Kristian Høgsberge329f362013-05-06 22:19:57 -0400185static void
186default_grab_touch_up(struct weston_touch_grab *grab,
187 uint32_t time, int touch_id)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400188{
Kristian Høgsberge329f362013-05-06 22:19:57 -0400189 struct weston_touch *touch = grab->touch;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400190 struct wl_display *display;
191 uint32_t serial;
192
193 if (touch->focus_resource) {
Jason Ekstrand44a38632013-06-14 10:08:00 -0500194 display = wl_client_get_display(wl_resource_get_client(touch->focus_resource));
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400195 serial = wl_display_next_serial(display);
196 wl_touch_send_up(touch->focus_resource, serial, time, touch_id);
197 }
198}
199
Kristian Høgsberge329f362013-05-06 22:19:57 -0400200static void
201default_grab_touch_motion(struct weston_touch_grab *grab, uint32_t time,
202 int touch_id, wl_fixed_t sx, wl_fixed_t sy)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400203{
Kristian Høgsberge329f362013-05-06 22:19:57 -0400204 struct weston_touch *touch = grab->touch;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400205
206 if (touch->focus_resource) {
207 wl_touch_send_motion(touch->focus_resource, time,
Kristian Høgsberge329f362013-05-06 22:19:57 -0400208 touch_id, sx, sy);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400209 }
210}
211
Kristian Høgsberge329f362013-05-06 22:19:57 -0400212static const struct weston_touch_grab_interface default_touch_grab_interface = {
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400213 default_grab_touch_down,
214 default_grab_touch_up,
215 default_grab_touch_motion
216};
217
218static void
Kristian Høgsberg29139d42013-04-18 15:25:39 -0400219default_grab_key(struct weston_keyboard_grab *grab,
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400220 uint32_t time, uint32_t key, uint32_t state)
221{
Kristian Høgsberg29139d42013-04-18 15:25:39 -0400222 struct weston_keyboard *keyboard = grab->keyboard;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400223 struct wl_resource *resource;
224 struct wl_display *display;
225 uint32_t serial;
226
227 resource = keyboard->focus_resource;
228 if (resource) {
Jason Ekstrand44a38632013-06-14 10:08:00 -0500229 display = wl_client_get_display(wl_resource_get_client(resource));
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400230 serial = wl_display_next_serial(display);
231 wl_keyboard_send_key(resource, serial, time, key, state);
232 }
233}
234
235static struct wl_resource *
Kristian Høgsbergfe7aa902013-05-08 09:54:37 -0400236find_resource_for_surface(struct wl_list *list, struct weston_surface *surface)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400237{
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400238 if (!surface)
239 return NULL;
240
Jason Ekstrand44a38632013-06-14 10:08:00 -0500241 if (!surface->resource)
242 return NULL;
243
244 return wl_resource_find_for_client(list, wl_resource_get_client(surface->resource));
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400245}
246
247static void
Kristian Høgsberg29139d42013-04-18 15:25:39 -0400248default_grab_modifiers(struct weston_keyboard_grab *grab, uint32_t serial,
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400249 uint32_t mods_depressed, uint32_t mods_latched,
250 uint32_t mods_locked, uint32_t group)
251{
Kristian Høgsberg29139d42013-04-18 15:25:39 -0400252 struct weston_keyboard *keyboard = grab->keyboard;
Kristian Høgsberg02bbabb2013-05-06 22:15:05 -0400253 struct weston_pointer *pointer = keyboard->seat->pointer;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400254 struct wl_resource *resource, *pr;
255
256 resource = keyboard->focus_resource;
257 if (!resource)
258 return;
259
260 wl_keyboard_send_modifiers(resource, serial, mods_depressed,
261 mods_latched, mods_locked, group);
262
263 if (pointer && pointer->focus && pointer->focus != keyboard->focus) {
264 pr = find_resource_for_surface(&keyboard->resource_list,
265 pointer->focus);
266 if (pr) {
267 wl_keyboard_send_modifiers(pr,
268 serial,
269 keyboard->modifiers.mods_depressed,
270 keyboard->modifiers.mods_latched,
271 keyboard->modifiers.mods_locked,
272 keyboard->modifiers.group);
273 }
274 }
275}
276
Kristian Høgsberg29139d42013-04-18 15:25:39 -0400277static const struct weston_keyboard_grab_interface
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400278 default_keyboard_grab_interface = {
279 default_grab_key,
280 default_grab_modifiers,
281};
282
Kristian Høgsberg195b8692013-05-08 15:02:05 -0400283static void
284pointer_unmap_sprite(struct weston_pointer *pointer)
285{
286 if (weston_surface_is_mapped(pointer->sprite))
287 weston_surface_unmap(pointer->sprite);
288
289 wl_list_remove(&pointer->sprite_destroy_listener.link);
290 pointer->sprite->configure = NULL;
291 pointer->sprite->configure_private = NULL;
292 pointer->sprite = NULL;
293}
294
295static void
296pointer_handle_sprite_destroy(struct wl_listener *listener, void *data)
297{
298 struct weston_pointer *pointer =
299 container_of(listener, struct weston_pointer,
300 sprite_destroy_listener);
301
302 pointer->sprite = NULL;
303}
304
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400305WL_EXPORT struct weston_pointer *
306weston_pointer_create(void)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400307{
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400308 struct weston_pointer *pointer;
309
310 pointer = malloc(sizeof *pointer);
311 if (pointer == NULL)
312 return NULL;
313
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400314 memset(pointer, 0, sizeof *pointer);
315 wl_list_init(&pointer->resource_list);
316 pointer->focus_listener.notify = lose_pointer_focus;
317 pointer->default_grab.interface = &default_pointer_grab_interface;
318 pointer->default_grab.pointer = pointer;
319 pointer->grab = &pointer->default_grab;
320 wl_signal_init(&pointer->focus_signal);
321
Kristian Høgsberg195b8692013-05-08 15:02:05 -0400322 pointer->sprite_destroy_listener.notify = pointer_handle_sprite_destroy;
323
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400324 /* FIXME: Pick better co-ords. */
325 pointer->x = wl_fixed_from_int(100);
326 pointer->y = wl_fixed_from_int(100);
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400327
328 return pointer;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400329}
330
331WL_EXPORT void
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400332weston_pointer_destroy(struct weston_pointer *pointer)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400333{
Kristian Høgsberg195b8692013-05-08 15:02:05 -0400334 if (pointer->sprite)
335 pointer_unmap_sprite(pointer);
336
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400337 /* XXX: What about pointer->resource_list? */
338 if (pointer->focus_resource)
339 wl_list_remove(&pointer->focus_listener.link);
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400340 free(pointer);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400341}
342
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400343WL_EXPORT struct weston_keyboard *
344weston_keyboard_create(void)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400345{
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400346 struct weston_keyboard *keyboard;
347
348 keyboard = malloc(sizeof *keyboard);
349 if (keyboard == NULL)
350 return NULL;
351
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400352 memset(keyboard, 0, sizeof *keyboard);
353 wl_list_init(&keyboard->resource_list);
354 wl_array_init(&keyboard->keys);
355 keyboard->focus_listener.notify = lose_keyboard_focus;
356 keyboard->default_grab.interface = &default_keyboard_grab_interface;
357 keyboard->default_grab.keyboard = keyboard;
358 keyboard->grab = &keyboard->default_grab;
359 wl_signal_init(&keyboard->focus_signal);
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400360
361 return keyboard;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400362}
363
364WL_EXPORT void
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400365weston_keyboard_destroy(struct weston_keyboard *keyboard)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400366{
367 /* XXX: What about keyboard->resource_list? */
368 if (keyboard->focus_resource)
369 wl_list_remove(&keyboard->focus_listener.link);
370 wl_array_release(&keyboard->keys);
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400371 free(keyboard);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400372}
373
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400374WL_EXPORT struct weston_touch *
375weston_touch_create(void)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400376{
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400377 struct weston_touch *touch;
378
379 touch = malloc(sizeof *touch);
380 if (touch == NULL)
381 return NULL;
382
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400383 memset(touch, 0, sizeof *touch);
384 wl_list_init(&touch->resource_list);
385 touch->focus_listener.notify = lose_touch_focus;
386 touch->default_grab.interface = &default_touch_grab_interface;
387 touch->default_grab.touch = touch;
388 touch->grab = &touch->default_grab;
389 wl_signal_init(&touch->focus_signal);
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400390
391 return touch;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400392}
393
394WL_EXPORT void
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400395weston_touch_destroy(struct weston_touch *touch)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400396{
397 /* XXX: What about touch->resource_list? */
398 if (touch->focus_resource)
399 wl_list_remove(&touch->focus_listener.link);
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400400 free(touch);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400401}
402
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400403static void
Kristian Høgsberge3148752013-05-06 23:19:49 -0400404seat_send_updated_caps(struct weston_seat *seat)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400405{
Jason Ekstrand44a38632013-06-14 10:08:00 -0500406 struct wl_list *link;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400407 enum wl_seat_capability caps = 0;
408
409 if (seat->pointer)
410 caps |= WL_SEAT_CAPABILITY_POINTER;
411 if (seat->keyboard)
412 caps |= WL_SEAT_CAPABILITY_KEYBOARD;
413 if (seat->touch)
414 caps |= WL_SEAT_CAPABILITY_TOUCH;
415
Jason Ekstrand44a38632013-06-14 10:08:00 -0500416 for (link = seat->base_resource_list.next;
417 link != &seat->base_resource_list; link = link->next) {
418 wl_seat_send_capabilities(wl_resource_from_link(link), caps);
419 }
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400420}
421
422WL_EXPORT void
Kristian Høgsberg02bbabb2013-05-06 22:15:05 -0400423weston_pointer_set_focus(struct weston_pointer *pointer,
Kristian Høgsbergfe7aa902013-05-08 09:54:37 -0400424 struct weston_surface *surface,
Kristian Høgsberg02bbabb2013-05-06 22:15:05 -0400425 wl_fixed_t sx, wl_fixed_t sy)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400426{
Kristian Høgsberg29139d42013-04-18 15:25:39 -0400427 struct weston_keyboard *kbd = pointer->seat->keyboard;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400428 struct wl_resource *resource, *kr;
429 struct wl_display *display;
430 uint32_t serial;
431
432 resource = pointer->focus_resource;
433 if (resource && pointer->focus != surface) {
Jason Ekstrand44a38632013-06-14 10:08:00 -0500434 display = wl_client_get_display(wl_resource_get_client(resource));
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400435 serial = wl_display_next_serial(display);
436 wl_pointer_send_leave(resource, serial,
Jason Ekstrand26ed73c2013-06-06 22:34:41 -0500437 pointer->focus->resource);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400438 wl_list_remove(&pointer->focus_listener.link);
439 }
440
441 resource = find_resource_for_surface(&pointer->resource_list,
442 surface);
443 if (resource &&
444 (pointer->focus != surface ||
445 pointer->focus_resource != resource)) {
Jason Ekstrand44a38632013-06-14 10:08:00 -0500446 display = wl_client_get_display(wl_resource_get_client(resource));
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400447 serial = wl_display_next_serial(display);
448 if (kbd) {
449 kr = find_resource_for_surface(&kbd->resource_list,
450 surface);
451 if (kr) {
452 wl_keyboard_send_modifiers(kr,
453 serial,
454 kbd->modifiers.mods_depressed,
455 kbd->modifiers.mods_latched,
456 kbd->modifiers.mods_locked,
457 kbd->modifiers.group);
458 }
459 }
Jason Ekstrand26ed73c2013-06-06 22:34:41 -0500460 wl_pointer_send_enter(resource, serial, surface->resource,
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400461 sx, sy);
Jason Ekstrand44a38632013-06-14 10:08:00 -0500462 wl_resource_add_destroy_listener(resource,
463 &pointer->focus_listener);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400464 pointer->focus_serial = serial;
465 }
466
467 pointer->focus_resource = resource;
468 pointer->focus = surface;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400469 wl_signal_emit(&pointer->focus_signal, pointer);
470}
471
472WL_EXPORT void
Kristian Høgsberg29139d42013-04-18 15:25:39 -0400473weston_keyboard_set_focus(struct weston_keyboard *keyboard,
Kristian Høgsbergfe7aa902013-05-08 09:54:37 -0400474 struct weston_surface *surface)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400475{
476 struct wl_resource *resource;
477 struct wl_display *display;
478 uint32_t serial;
479
480 if (keyboard->focus_resource && keyboard->focus != surface) {
481 resource = keyboard->focus_resource;
Jason Ekstrand44a38632013-06-14 10:08:00 -0500482 display = wl_client_get_display(wl_resource_get_client(resource));
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400483 serial = wl_display_next_serial(display);
484 wl_keyboard_send_leave(resource, serial,
Jason Ekstrand26ed73c2013-06-06 22:34:41 -0500485 keyboard->focus->resource);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400486 wl_list_remove(&keyboard->focus_listener.link);
487 }
488
489 resource = find_resource_for_surface(&keyboard->resource_list,
490 surface);
491 if (resource &&
492 (keyboard->focus != surface ||
493 keyboard->focus_resource != resource)) {
Jason Ekstrand44a38632013-06-14 10:08:00 -0500494 display = wl_client_get_display(wl_resource_get_client(resource));
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400495 serial = wl_display_next_serial(display);
496 wl_keyboard_send_modifiers(resource, serial,
497 keyboard->modifiers.mods_depressed,
498 keyboard->modifiers.mods_latched,
499 keyboard->modifiers.mods_locked,
500 keyboard->modifiers.group);
Jason Ekstrand26ed73c2013-06-06 22:34:41 -0500501 wl_keyboard_send_enter(resource, serial, surface->resource,
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400502 &keyboard->keys);
Jason Ekstrand44a38632013-06-14 10:08:00 -0500503 wl_resource_add_destroy_listener(resource,
504 &keyboard->focus_listener);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400505 keyboard->focus_serial = serial;
506 }
507
508 keyboard->focus_resource = resource;
509 keyboard->focus = surface;
510 wl_signal_emit(&keyboard->focus_signal, keyboard);
511}
512
513WL_EXPORT void
Kristian Høgsberg29139d42013-04-18 15:25:39 -0400514weston_keyboard_start_grab(struct weston_keyboard *keyboard,
515 struct weston_keyboard_grab *grab)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400516{
517 keyboard->grab = grab;
518 grab->keyboard = keyboard;
519
520 /* XXX focus? */
521}
522
523WL_EXPORT void
Kristian Høgsberg29139d42013-04-18 15:25:39 -0400524weston_keyboard_end_grab(struct weston_keyboard *keyboard)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400525{
526 keyboard->grab = &keyboard->default_grab;
527}
528
529WL_EXPORT void
Kristian Høgsberg02bbabb2013-05-06 22:15:05 -0400530weston_pointer_start_grab(struct weston_pointer *pointer,
531 struct weston_pointer_grab *grab)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400532{
Kristian Høgsberg02bbabb2013-05-06 22:15:05 -0400533 const struct weston_pointer_grab_interface *interface;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400534
535 pointer->grab = grab;
536 interface = pointer->grab->interface;
537 grab->pointer = pointer;
Kristian Høgsberg6848c252013-05-08 22:02:59 -0400538 interface->focus(pointer->grab);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400539}
540
541WL_EXPORT void
Kristian Høgsberg02bbabb2013-05-06 22:15:05 -0400542weston_pointer_end_grab(struct weston_pointer *pointer)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400543{
Kristian Høgsberg02bbabb2013-05-06 22:15:05 -0400544 const struct weston_pointer_grab_interface *interface;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400545
546 pointer->grab = &pointer->default_grab;
547 interface = pointer->grab->interface;
Kristian Høgsberg6848c252013-05-08 22:02:59 -0400548 interface->focus(pointer->grab);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400549}
550
551WL_EXPORT void
Kristian Høgsberge329f362013-05-06 22:19:57 -0400552weston_touch_start_grab(struct weston_touch *touch, struct weston_touch_grab *grab)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400553{
554 touch->grab = grab;
555 grab->touch = touch;
556}
557
558WL_EXPORT void
Kristian Høgsberge329f362013-05-06 22:19:57 -0400559weston_touch_end_grab(struct weston_touch *touch)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400560{
561 touch->grab = &touch->default_grab;
562}
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400563
Rob Bradford806d8c02013-06-25 18:56:41 +0100564WL_EXPORT void
565weston_pointer_clamp(struct weston_pointer *pointer, wl_fixed_t *fx, wl_fixed_t *fy)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400566{
Rob Bradford806d8c02013-06-25 18:56:41 +0100567 struct weston_compositor *ec = pointer->seat->compositor;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400568 struct weston_output *output, *prev = NULL;
569 int x, y, old_x, old_y, valid = 0;
570
571 x = wl_fixed_to_int(*fx);
572 y = wl_fixed_to_int(*fy);
Rob Bradford806d8c02013-06-25 18:56:41 +0100573 old_x = wl_fixed_to_int(pointer->x);
574 old_y = wl_fixed_to_int(pointer->y);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400575
576 wl_list_for_each(output, &ec->output_list, link) {
577 if (pixman_region32_contains_point(&output->region,
578 x, y, NULL))
579 valid = 1;
580 if (pixman_region32_contains_point(&output->region,
581 old_x, old_y, NULL))
582 prev = output;
583 }
584
585 if (!valid) {
586 if (x < prev->x)
587 *fx = wl_fixed_from_int(prev->x);
588 else if (x >= prev->x + prev->width)
589 *fx = wl_fixed_from_int(prev->x +
590 prev->width - 1);
591 if (y < prev->y)
592 *fy = wl_fixed_from_int(prev->y);
Alexander Larssonbcd18d92013-05-28 16:23:33 +0200593 else if (y >= prev->y + prev->height)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400594 *fy = wl_fixed_from_int(prev->y +
595 prev->height - 1);
596 }
597}
598
599/* Takes absolute values */
600static void
601move_pointer(struct weston_seat *seat, wl_fixed_t x, wl_fixed_t y)
602{
603 struct weston_compositor *ec = seat->compositor;
Kristian Høgsberge3148752013-05-06 23:19:49 -0400604 struct weston_pointer *pointer = seat->pointer;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400605 struct weston_output *output;
606 int32_t ix, iy;
607
Rob Bradford806d8c02013-06-25 18:56:41 +0100608 weston_pointer_clamp (pointer, &x, &y);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400609
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400610 pointer->x = x;
611 pointer->y = y;
612
613 ix = wl_fixed_to_int(x);
614 iy = wl_fixed_to_int(y);
615
616 wl_list_for_each(output, &ec->output_list, link)
617 if (output->zoom.active &&
618 pixman_region32_contains_point(&output->region,
619 ix, iy, NULL))
620 weston_output_update_zoom(output, ZOOM_FOCUS_POINTER);
621
Kristian Høgsberg195b8692013-05-08 15:02:05 -0400622 if (pointer->sprite) {
623 weston_surface_set_position(pointer->sprite,
624 ix - pointer->hotspot_x,
625 iy - pointer->hotspot_y);
626 weston_surface_schedule_repaint(pointer->sprite);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400627 }
628}
629
630WL_EXPORT void
631notify_motion(struct weston_seat *seat,
632 uint32_t time, wl_fixed_t dx, wl_fixed_t dy)
633{
Kristian Høgsberg02bbabb2013-05-06 22:15:05 -0400634 const struct weston_pointer_grab_interface *interface;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400635 struct weston_compositor *ec = seat->compositor;
Kristian Høgsberge3148752013-05-06 23:19:49 -0400636 struct weston_pointer *pointer = seat->pointer;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400637
638 weston_compositor_wake(ec);
639
640 move_pointer(seat, pointer->x + dx, pointer->y + dy);
641
642 interface = pointer->grab->interface;
Kristian Høgsberg6848c252013-05-08 22:02:59 -0400643 interface->focus(pointer->grab);
Kristian Høgsbergbe6403e2013-05-08 21:03:21 -0400644 interface->motion(pointer->grab, time);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400645}
646
647WL_EXPORT void
648notify_motion_absolute(struct weston_seat *seat,
649 uint32_t time, wl_fixed_t x, wl_fixed_t y)
650{
Kristian Høgsberg02bbabb2013-05-06 22:15:05 -0400651 const struct weston_pointer_grab_interface *interface;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400652 struct weston_compositor *ec = seat->compositor;
Kristian Høgsberge3148752013-05-06 23:19:49 -0400653 struct weston_pointer *pointer = seat->pointer;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400654
655 weston_compositor_wake(ec);
656
657 move_pointer(seat, x, y);
658
659 interface = pointer->grab->interface;
Kristian Høgsberg6848c252013-05-08 22:02:59 -0400660 interface->focus(pointer->grab);
Kristian Høgsbergbe6403e2013-05-08 21:03:21 -0400661 interface->motion(pointer->grab, time);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400662}
663
664WL_EXPORT void
665weston_surface_activate(struct weston_surface *surface,
666 struct weston_seat *seat)
667{
668 struct weston_compositor *compositor = seat->compositor;
669
Kristian Høgsberge3148752013-05-06 23:19:49 -0400670 if (seat->keyboard) {
Kristian Høgsbergfe7aa902013-05-08 09:54:37 -0400671 weston_keyboard_set_focus(seat->keyboard, surface);
Kristian Høgsberge3148752013-05-06 23:19:49 -0400672 wl_data_device_set_keyboard_focus(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400673 }
674
675 wl_signal_emit(&compositor->activate_signal, surface);
676}
677
678WL_EXPORT void
679notify_button(struct weston_seat *seat, uint32_t time, int32_t button,
680 enum wl_pointer_button_state state)
681{
682 struct weston_compositor *compositor = seat->compositor;
Kristian Høgsberge3148752013-05-06 23:19:49 -0400683 struct weston_pointer *pointer = seat->pointer;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400684 struct weston_surface *focus =
685 (struct weston_surface *) pointer->focus;
686 uint32_t serial = wl_display_next_serial(compositor->wl_display);
687
688 if (state == WL_POINTER_BUTTON_STATE_PRESSED) {
689 if (compositor->ping_handler && focus)
690 compositor->ping_handler(focus, serial);
691 weston_compositor_idle_inhibit(compositor);
692 if (pointer->button_count == 0) {
693 pointer->grab_button = button;
694 pointer->grab_time = time;
695 pointer->grab_x = pointer->x;
696 pointer->grab_y = pointer->y;
697 }
698 pointer->button_count++;
699 } else {
700 weston_compositor_idle_release(compositor);
701 pointer->button_count--;
702 }
703
704 weston_compositor_run_button_binding(compositor, seat, time, button,
705 state);
706
707 pointer->grab->interface->button(pointer->grab, time, button, state);
708
709 if (pointer->button_count == 1)
710 pointer->grab_serial =
711 wl_display_get_serial(compositor->wl_display);
712}
713
714WL_EXPORT void
715notify_axis(struct weston_seat *seat, uint32_t time, uint32_t axis,
716 wl_fixed_t value)
717{
718 struct weston_compositor *compositor = seat->compositor;
Kristian Høgsberge3148752013-05-06 23:19:49 -0400719 struct weston_pointer *pointer = seat->pointer;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400720 struct weston_surface *focus =
721 (struct weston_surface *) pointer->focus;
722 uint32_t serial = wl_display_next_serial(compositor->wl_display);
723
724 if (compositor->ping_handler && focus)
725 compositor->ping_handler(focus, serial);
726
727 weston_compositor_wake(compositor);
728
729 if (!value)
730 return;
731
732 if (weston_compositor_run_axis_binding(compositor, seat,
733 time, axis, value))
734 return;
735
736 if (pointer->focus_resource)
737 wl_pointer_send_axis(pointer->focus_resource, time, axis,
738 value);
739}
740
741WL_EXPORT void
742notify_modifiers(struct weston_seat *seat, uint32_t serial)
743{
Kristian Høgsberge3148752013-05-06 23:19:49 -0400744 struct weston_keyboard *keyboard = seat->keyboard;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400745 struct weston_keyboard_grab *grab = keyboard->grab;
746 uint32_t mods_depressed, mods_latched, mods_locked, group;
747 uint32_t mods_lookup;
748 enum weston_led leds = 0;
749 int changed = 0;
750
751 /* Serialize and update our internal state, checking to see if it's
752 * different to the previous state. */
753 mods_depressed = xkb_state_serialize_mods(seat->xkb_state.state,
754 XKB_STATE_DEPRESSED);
755 mods_latched = xkb_state_serialize_mods(seat->xkb_state.state,
756 XKB_STATE_LATCHED);
757 mods_locked = xkb_state_serialize_mods(seat->xkb_state.state,
758 XKB_STATE_LOCKED);
759 group = xkb_state_serialize_group(seat->xkb_state.state,
760 XKB_STATE_EFFECTIVE);
761
Kristian Høgsberge3148752013-05-06 23:19:49 -0400762 if (mods_depressed != seat->keyboard->modifiers.mods_depressed ||
763 mods_latched != seat->keyboard->modifiers.mods_latched ||
764 mods_locked != seat->keyboard->modifiers.mods_locked ||
765 group != seat->keyboard->modifiers.group)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400766 changed = 1;
767
Kristian Høgsberge3148752013-05-06 23:19:49 -0400768 seat->keyboard->modifiers.mods_depressed = mods_depressed;
769 seat->keyboard->modifiers.mods_latched = mods_latched;
770 seat->keyboard->modifiers.mods_locked = mods_locked;
771 seat->keyboard->modifiers.group = group;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400772
773 /* And update the modifier_state for bindings. */
774 mods_lookup = mods_depressed | mods_latched;
775 seat->modifier_state = 0;
776 if (mods_lookup & (1 << seat->xkb_info.ctrl_mod))
777 seat->modifier_state |= MODIFIER_CTRL;
778 if (mods_lookup & (1 << seat->xkb_info.alt_mod))
779 seat->modifier_state |= MODIFIER_ALT;
780 if (mods_lookup & (1 << seat->xkb_info.super_mod))
781 seat->modifier_state |= MODIFIER_SUPER;
782 if (mods_lookup & (1 << seat->xkb_info.shift_mod))
783 seat->modifier_state |= MODIFIER_SHIFT;
784
785 /* Finally, notify the compositor that LEDs have changed. */
786 if (xkb_state_led_index_is_active(seat->xkb_state.state,
787 seat->xkb_info.num_led))
788 leds |= LED_NUM_LOCK;
789 if (xkb_state_led_index_is_active(seat->xkb_state.state,
790 seat->xkb_info.caps_led))
791 leds |= LED_CAPS_LOCK;
792 if (xkb_state_led_index_is_active(seat->xkb_state.state,
793 seat->xkb_info.scroll_led))
794 leds |= LED_SCROLL_LOCK;
795 if (leds != seat->xkb_state.leds && seat->led_update)
796 seat->led_update(seat, leds);
797 seat->xkb_state.leds = leds;
798
799 if (changed) {
800 grab->interface->modifiers(grab,
801 serial,
802 keyboard->modifiers.mods_depressed,
803 keyboard->modifiers.mods_latched,
804 keyboard->modifiers.mods_locked,
805 keyboard->modifiers.group);
806 }
807}
808
809static void
810update_modifier_state(struct weston_seat *seat, uint32_t serial, uint32_t key,
811 enum wl_keyboard_key_state state)
812{
813 enum xkb_key_direction direction;
814
815 if (state == WL_KEYBOARD_KEY_STATE_PRESSED)
816 direction = XKB_KEY_DOWN;
817 else
818 direction = XKB_KEY_UP;
819
820 /* Offset the keycode by 8, as the evdev XKB rules reflect X's
821 * broken keycode system, which starts at 8. */
822 xkb_state_update_key(seat->xkb_state.state, key + 8, direction);
823
824 notify_modifiers(seat, serial);
825}
826
827WL_EXPORT void
828notify_key(struct weston_seat *seat, uint32_t time, uint32_t key,
829 enum wl_keyboard_key_state state,
830 enum weston_key_state_update update_state)
831{
832 struct weston_compositor *compositor = seat->compositor;
Kristian Høgsberge3148752013-05-06 23:19:49 -0400833 struct weston_keyboard *keyboard = seat->keyboard;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400834 struct weston_surface *focus =
835 (struct weston_surface *) keyboard->focus;
836 struct weston_keyboard_grab *grab = keyboard->grab;
837 uint32_t serial = wl_display_next_serial(compositor->wl_display);
838 uint32_t *k, *end;
839
840 if (state == WL_KEYBOARD_KEY_STATE_PRESSED) {
841 if (compositor->ping_handler && focus)
842 compositor->ping_handler(focus, serial);
843
844 weston_compositor_idle_inhibit(compositor);
845 keyboard->grab_key = key;
846 keyboard->grab_time = time;
847 } else {
848 weston_compositor_idle_release(compositor);
849 }
850
851 end = keyboard->keys.data + keyboard->keys.size;
852 for (k = keyboard->keys.data; k < end; k++) {
853 if (*k == key) {
854 /* Ignore server-generated repeats. */
855 if (state == WL_KEYBOARD_KEY_STATE_PRESSED)
856 return;
857 *k = *--end;
858 }
859 }
860 keyboard->keys.size = (void *) end - keyboard->keys.data;
861 if (state == WL_KEYBOARD_KEY_STATE_PRESSED) {
862 k = wl_array_add(&keyboard->keys, sizeof *k);
863 *k = key;
864 }
865
866 if (grab == &keyboard->default_grab ||
867 grab == &keyboard->input_method_grab) {
868 weston_compositor_run_key_binding(compositor, seat, time, key,
869 state);
870 grab = keyboard->grab;
871 }
872
873 grab->interface->key(grab, time, key, state);
874
875 if (update_state == STATE_UPDATE_AUTOMATIC) {
876 update_modifier_state(seat,
877 wl_display_get_serial(compositor->wl_display),
878 key,
879 state);
880 }
881}
882
883WL_EXPORT void
884notify_pointer_focus(struct weston_seat *seat, struct weston_output *output,
885 wl_fixed_t x, wl_fixed_t y)
886{
887 struct weston_compositor *compositor = seat->compositor;
888
889 if (output) {
890 move_pointer(seat, x, y);
891 compositor->focus = 1;
892 } else {
893 compositor->focus = 0;
Kristian Høgsberg02bbabb2013-05-06 22:15:05 -0400894 /* FIXME: We should call weston_pointer_set_focus(seat,
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400895 * NULL) here, but somehow that breaks re-entry... */
896 }
897}
898
899static void
900destroy_device_saved_kbd_focus(struct wl_listener *listener, void *data)
901{
902 struct weston_seat *ws;
903
904 ws = container_of(listener, struct weston_seat,
905 saved_kbd_focus_listener);
906
907 ws->saved_kbd_focus = NULL;
908}
909
910WL_EXPORT void
911notify_keyboard_focus_in(struct weston_seat *seat, struct wl_array *keys,
912 enum weston_key_state_update update_state)
913{
914 struct weston_compositor *compositor = seat->compositor;
Kristian Høgsberge3148752013-05-06 23:19:49 -0400915 struct weston_keyboard *keyboard = seat->keyboard;
Kristian Høgsbergfe7aa902013-05-08 09:54:37 -0400916 struct weston_surface *surface;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400917 uint32_t *k, serial;
918
919 serial = wl_display_next_serial(compositor->wl_display);
920 wl_array_copy(&keyboard->keys, keys);
921 wl_array_for_each(k, &keyboard->keys) {
922 weston_compositor_idle_inhibit(compositor);
923 if (update_state == STATE_UPDATE_AUTOMATIC)
924 update_modifier_state(seat, serial, *k,
925 WL_KEYBOARD_KEY_STATE_PRESSED);
926 }
927
928 /* Run key bindings after we've updated the state. */
929 wl_array_for_each(k, &keyboard->keys) {
930 weston_compositor_run_key_binding(compositor, seat, 0, *k,
931 WL_KEYBOARD_KEY_STATE_PRESSED);
932 }
933
934 surface = seat->saved_kbd_focus;
935
936 if (surface) {
937 wl_list_remove(&seat->saved_kbd_focus_listener.link);
938 weston_keyboard_set_focus(keyboard, surface);
939 seat->saved_kbd_focus = NULL;
940 }
941}
942
943WL_EXPORT void
944notify_keyboard_focus_out(struct weston_seat *seat)
945{
946 struct weston_compositor *compositor = seat->compositor;
Kristian Høgsberge3148752013-05-06 23:19:49 -0400947 struct weston_keyboard *keyboard = seat->keyboard;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400948 uint32_t *k, serial;
949
950 serial = wl_display_next_serial(compositor->wl_display);
951 wl_array_for_each(k, &keyboard->keys) {
952 weston_compositor_idle_release(compositor);
953 update_modifier_state(seat, serial, *k,
954 WL_KEYBOARD_KEY_STATE_RELEASED);
955 }
956
957 seat->modifier_state = 0;
958
959 if (keyboard->focus) {
960 seat->saved_kbd_focus = keyboard->focus;
961 seat->saved_kbd_focus_listener.notify =
962 destroy_device_saved_kbd_focus;
Jason Ekstrand26ed73c2013-06-06 22:34:41 -0500963 wl_signal_add(&keyboard->focus->destroy_signal,
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400964 &seat->saved_kbd_focus_listener);
965 }
966
967 weston_keyboard_set_focus(keyboard, NULL);
968 /* FIXME: We really need keyboard grab cancel here to
969 * let the grab shut down properly. As it is we leak
970 * the grab data. */
971 weston_keyboard_end_grab(keyboard);
972}
973
974static void
Kristian Høgsbergfe7aa902013-05-08 09:54:37 -0400975touch_set_focus(struct weston_seat *seat, struct weston_surface *surface)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400976{
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400977 struct wl_resource *resource;
978
979 if (seat->touch->focus == surface)
980 return;
981
982 if (seat->touch->focus_resource)
983 wl_list_remove(&seat->touch->focus_listener.link);
984 seat->touch->focus = NULL;
985 seat->touch->focus_resource = NULL;
986
987 if (surface) {
988 resource =
Kristian Høgsberg80fb82d2013-05-06 21:49:55 -0400989 find_resource_for_surface(&seat->touch->resource_list,
990 surface);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400991 if (!resource) {
992 weston_log("couldn't find resource\n");
993 return;
994 }
995
996 seat->touch->focus = surface;
997 seat->touch->focus_resource = resource;
Jason Ekstrand44a38632013-06-14 10:08:00 -0500998 wl_resource_add_destroy_listener(resource,
999 &seat->touch->focus_listener);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001000 }
1001}
1002
1003/**
1004 * notify_touch - emulates button touches and notifies surfaces accordingly.
1005 *
1006 * It assumes always the correct cycle sequence until it gets here: touch_down
1007 * → touch_update → ... → touch_update → touch_end. The driver is responsible
1008 * for sending along such order.
1009 *
1010 */
1011WL_EXPORT void
1012notify_touch(struct weston_seat *seat, uint32_t time, int touch_id,
1013 wl_fixed_t x, wl_fixed_t y, int touch_type)
1014{
1015 struct weston_compositor *ec = seat->compositor;
Kristian Høgsberge3148752013-05-06 23:19:49 -04001016 struct weston_touch *touch = seat->touch;
Kristian Høgsberge329f362013-05-06 22:19:57 -04001017 struct weston_touch_grab *grab = touch->grab;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001018 struct weston_surface *es;
1019 wl_fixed_t sx, sy;
1020
1021 /* Update grab's global coordinates. */
1022 touch->grab_x = x;
1023 touch->grab_y = y;
1024
1025 switch (touch_type) {
1026 case WL_TOUCH_DOWN:
1027 weston_compositor_idle_inhibit(ec);
1028
1029 seat->num_tp++;
1030
1031 /* the first finger down picks the surface, and all further go
1032 * to that surface for the remainder of the touch session i.e.
1033 * until all touch points are up again. */
1034 if (seat->num_tp == 1) {
1035 es = weston_compositor_pick_surface(ec, x, y, &sx, &sy);
Kristian Høgsbergfe7aa902013-05-08 09:54:37 -04001036 touch_set_focus(seat, es);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001037 } else if (touch->focus) {
1038 es = (struct weston_surface *) touch->focus;
1039 weston_surface_from_global_fixed(es, x, y, &sx, &sy);
1040 } else {
1041 /* Unexpected condition: We have non-initial touch but
1042 * there is no focused surface.
1043 */
1044 weston_log("touch event received with %d points down"
1045 "but no surface focused\n", seat->num_tp);
1046 return;
1047 }
1048
1049 grab->interface->down(grab, time, touch_id, sx, sy);
1050 break;
1051 case WL_TOUCH_MOTION:
1052 es = (struct weston_surface *) touch->focus;
1053 if (!es)
1054 break;
1055
1056 weston_surface_from_global_fixed(es, x, y, &sx, &sy);
1057 grab->interface->motion(grab, time, touch_id, sx, sy);
1058 break;
1059 case WL_TOUCH_UP:
1060 weston_compositor_idle_release(ec);
1061 seat->num_tp--;
1062
1063 grab->interface->up(grab, time, touch_id);
1064 if (seat->num_tp == 0)
1065 touch_set_focus(seat, NULL);
1066 break;
1067 }
1068}
1069
1070static void
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001071pointer_cursor_surface_configure(struct weston_surface *es,
1072 int32_t dx, int32_t dy, int32_t width, int32_t height)
1073{
Kristian Høgsberg195b8692013-05-08 15:02:05 -04001074 struct weston_pointer *pointer = es->configure_private;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001075 int x, y;
1076
1077 if (width == 0)
1078 return;
1079
Kristian Høgsberg195b8692013-05-08 15:02:05 -04001080 assert(es == pointer->sprite);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001081
Kristian Høgsberg195b8692013-05-08 15:02:05 -04001082 pointer->hotspot_x -= dx;
1083 pointer->hotspot_y -= dy;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001084
Kristian Høgsberg195b8692013-05-08 15:02:05 -04001085 x = wl_fixed_to_int(pointer->x) - pointer->hotspot_x;
1086 y = wl_fixed_to_int(pointer->y) - pointer->hotspot_y;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001087
Kristian Høgsberg195b8692013-05-08 15:02:05 -04001088 weston_surface_configure(pointer->sprite, x, y, width, height);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001089
1090 empty_region(&es->pending.input);
1091
1092 if (!weston_surface_is_mapped(es)) {
1093 wl_list_insert(&es->compositor->cursor_layer.surface_list,
1094 &es->layer_link);
1095 weston_surface_update_transform(es);
1096 }
1097}
1098
1099static void
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001100pointer_set_cursor(struct wl_client *client, struct wl_resource *resource,
1101 uint32_t serial, struct wl_resource *surface_resource,
1102 int32_t x, int32_t y)
1103{
Jason Ekstrand44a38632013-06-14 10:08:00 -05001104 struct weston_pointer *pointer = wl_resource_get_user_data(resource);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001105 struct weston_surface *surface = NULL;
1106
1107 if (surface_resource)
Jason Ekstrand0f2ef7e2013-06-14 10:07:53 -05001108 surface = wl_resource_get_user_data(surface_resource);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001109
Kristian Høgsberg195b8692013-05-08 15:02:05 -04001110 if (pointer->focus == NULL)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001111 return;
Giulio Camuffo1fd4b012013-06-20 18:13:07 +02001112 /* pointer->focus->resource can be NULL. Surfaces like the
1113 black_surface used in shell.c for fullscreen don't have
1114 a resource, but can still have focus */
1115 if (pointer->focus->resource == NULL)
1116 return;
Jason Ekstrand26ed73c2013-06-06 22:34:41 -05001117 if (wl_resource_get_client(pointer->focus->resource) != client)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001118 return;
Kristian Høgsberg195b8692013-05-08 15:02:05 -04001119 if (pointer->focus_serial - serial > UINT32_MAX / 2)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001120 return;
1121
Kristian Høgsberg195b8692013-05-08 15:02:05 -04001122 if (surface && surface != pointer->sprite) {
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001123 if (surface->configure) {
Jason Ekstrand26ed73c2013-06-06 22:34:41 -05001124 wl_resource_post_error(surface->resource,
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001125 WL_DISPLAY_ERROR_INVALID_OBJECT,
1126 "surface->configure already "
1127 "set");
1128 return;
1129 }
1130 }
1131
Kristian Høgsberg195b8692013-05-08 15:02:05 -04001132 if (pointer->sprite)
1133 pointer_unmap_sprite(pointer);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001134
1135 if (!surface)
1136 return;
1137
Jason Ekstrand26ed73c2013-06-06 22:34:41 -05001138 wl_signal_add(&surface->destroy_signal,
Kristian Høgsberg195b8692013-05-08 15:02:05 -04001139 &pointer->sprite_destroy_listener);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001140
1141 surface->configure = pointer_cursor_surface_configure;
Kristian Høgsberg195b8692013-05-08 15:02:05 -04001142 surface->configure_private = pointer;
1143 pointer->sprite = surface;
1144 pointer->hotspot_x = x;
1145 pointer->hotspot_y = y;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001146
1147 if (surface->buffer_ref.buffer)
1148 pointer_cursor_surface_configure(surface, 0, 0, weston_surface_buffer_width(surface),
1149 weston_surface_buffer_height(surface));
1150}
1151
1152static const struct wl_pointer_interface pointer_interface = {
1153 pointer_set_cursor
1154};
1155
1156static void
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001157seat_get_pointer(struct wl_client *client, struct wl_resource *resource,
1158 uint32_t id)
1159{
Jason Ekstrand44a38632013-06-14 10:08:00 -05001160 struct weston_seat *seat = wl_resource_get_user_data(resource);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001161 struct wl_resource *cr;
1162
Kristian Høgsberge3148752013-05-06 23:19:49 -04001163 if (!seat->pointer)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001164 return;
1165
1166 cr = wl_client_add_object(client, &wl_pointer_interface,
Kristian Høgsberg195b8692013-05-08 15:02:05 -04001167 &pointer_interface, id, seat->pointer);
Jason Ekstrand44a38632013-06-14 10:08:00 -05001168 wl_list_insert(&seat->pointer->resource_list, wl_resource_get_link(cr));
1169 wl_resource_set_destructor(cr, unbind_resource);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001170
Kristian Høgsberge3148752013-05-06 23:19:49 -04001171 if (seat->pointer->focus &&
Jason Ekstrand26ed73c2013-06-06 22:34:41 -05001172 wl_resource_get_client(seat->pointer->focus->resource) == client) {
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001173 struct weston_surface *surface;
1174 wl_fixed_t sx, sy;
1175
Kristian Høgsberge3148752013-05-06 23:19:49 -04001176 surface = (struct weston_surface *) seat->pointer->focus;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001177 weston_surface_from_global_fixed(surface,
Kristian Høgsberge3148752013-05-06 23:19:49 -04001178 seat->pointer->x,
1179 seat->pointer->y,
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001180 &sx,
1181 &sy);
Kristian Høgsberge3148752013-05-06 23:19:49 -04001182 weston_pointer_set_focus(seat->pointer,
1183 seat->pointer->focus,
Kristian Høgsberg02bbabb2013-05-06 22:15:05 -04001184 sx,
1185 sy);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001186 }
1187}
1188
1189static void
1190seat_get_keyboard(struct wl_client *client, struct wl_resource *resource,
1191 uint32_t id)
1192{
Jason Ekstrand44a38632013-06-14 10:08:00 -05001193 struct weston_seat *seat = wl_resource_get_user_data(resource);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001194 struct wl_resource *cr;
1195
Kristian Høgsberge3148752013-05-06 23:19:49 -04001196 if (!seat->keyboard)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001197 return;
1198
1199 cr = wl_client_add_object(client, &wl_keyboard_interface, NULL, id,
1200 seat);
Jason Ekstrand44a38632013-06-14 10:08:00 -05001201 wl_list_insert(&seat->keyboard->resource_list, wl_resource_get_link(cr));
1202 wl_resource_set_destructor(cr, unbind_resource);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001203
1204 wl_keyboard_send_keymap(cr, WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1,
1205 seat->xkb_info.keymap_fd,
1206 seat->xkb_info.keymap_size);
1207
Kristian Høgsberge3148752013-05-06 23:19:49 -04001208 if (seat->keyboard->focus &&
Jason Ekstrand26ed73c2013-06-06 22:34:41 -05001209 wl_resource_get_client(seat->keyboard->focus->resource) == client) {
Kristian Høgsberge3148752013-05-06 23:19:49 -04001210 weston_keyboard_set_focus(seat->keyboard,
1211 seat->keyboard->focus);
1212 wl_data_device_set_keyboard_focus(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001213 }
1214}
1215
1216static void
1217seat_get_touch(struct wl_client *client, struct wl_resource *resource,
1218 uint32_t id)
1219{
Jason Ekstrand44a38632013-06-14 10:08:00 -05001220 struct weston_seat *seat = wl_resource_get_user_data(resource);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001221 struct wl_resource *cr;
1222
Kristian Høgsberge3148752013-05-06 23:19:49 -04001223 if (!seat->touch)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001224 return;
1225
1226 cr = wl_client_add_object(client, &wl_touch_interface, NULL, id, seat);
Jason Ekstrand44a38632013-06-14 10:08:00 -05001227 wl_list_insert(&seat->touch->resource_list, wl_resource_get_link(cr));
1228 wl_resource_set_destructor(cr, unbind_resource);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001229}
1230
1231static const struct wl_seat_interface seat_interface = {
1232 seat_get_pointer,
1233 seat_get_keyboard,
1234 seat_get_touch,
1235};
1236
1237static void
1238bind_seat(struct wl_client *client, void *data, uint32_t version, uint32_t id)
1239{
Kristian Høgsberge3148752013-05-06 23:19:49 -04001240 struct weston_seat *seat = data;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001241 struct wl_resource *resource;
1242 enum wl_seat_capability caps = 0;
1243
1244 resource = wl_client_add_object(client, &wl_seat_interface,
1245 &seat_interface, id, data);
Jason Ekstrand44a38632013-06-14 10:08:00 -05001246 wl_list_insert(&seat->base_resource_list, wl_resource_get_link(resource));
1247 wl_resource_set_destructor(resource, unbind_resource);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001248
1249 if (seat->pointer)
1250 caps |= WL_SEAT_CAPABILITY_POINTER;
1251 if (seat->keyboard)
1252 caps |= WL_SEAT_CAPABILITY_KEYBOARD;
1253 if (seat->touch)
1254 caps |= WL_SEAT_CAPABILITY_TOUCH;
1255
1256 wl_seat_send_capabilities(resource, caps);
Rob Bradforde445ae62013-05-31 18:09:51 +01001257 if (version >= 2)
1258 wl_seat_send_name(resource, seat->seat_name);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001259}
1260
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001261int
1262weston_compositor_xkb_init(struct weston_compositor *ec,
1263 struct xkb_rule_names *names)
1264{
1265 if (ec->xkb_context == NULL) {
1266 ec->xkb_context = xkb_context_new(0);
1267 if (ec->xkb_context == NULL) {
1268 weston_log("failed to create XKB context\n");
1269 return -1;
1270 }
1271 }
1272
1273 if (names)
1274 ec->xkb_names = *names;
1275 if (!ec->xkb_names.rules)
1276 ec->xkb_names.rules = strdup("evdev");
1277 if (!ec->xkb_names.model)
1278 ec->xkb_names.model = strdup("pc105");
1279 if (!ec->xkb_names.layout)
1280 ec->xkb_names.layout = strdup("us");
1281
1282 return 0;
1283}
1284
1285static void xkb_info_destroy(struct weston_xkb_info *xkb_info)
1286{
1287 if (xkb_info->keymap)
1288 xkb_map_unref(xkb_info->keymap);
1289
1290 if (xkb_info->keymap_area)
1291 munmap(xkb_info->keymap_area, xkb_info->keymap_size);
1292 if (xkb_info->keymap_fd >= 0)
1293 close(xkb_info->keymap_fd);
1294}
1295
1296void
1297weston_compositor_xkb_destroy(struct weston_compositor *ec)
1298{
1299 free((char *) ec->xkb_names.rules);
1300 free((char *) ec->xkb_names.model);
1301 free((char *) ec->xkb_names.layout);
1302 free((char *) ec->xkb_names.variant);
1303 free((char *) ec->xkb_names.options);
1304
1305 xkb_info_destroy(&ec->xkb_info);
1306 xkb_context_unref(ec->xkb_context);
1307}
1308
1309static int
1310weston_xkb_info_new_keymap(struct weston_xkb_info *xkb_info)
1311{
1312 char *keymap_str;
1313
1314 xkb_info->shift_mod = xkb_map_mod_get_index(xkb_info->keymap,
1315 XKB_MOD_NAME_SHIFT);
1316 xkb_info->caps_mod = xkb_map_mod_get_index(xkb_info->keymap,
1317 XKB_MOD_NAME_CAPS);
1318 xkb_info->ctrl_mod = xkb_map_mod_get_index(xkb_info->keymap,
1319 XKB_MOD_NAME_CTRL);
1320 xkb_info->alt_mod = xkb_map_mod_get_index(xkb_info->keymap,
1321 XKB_MOD_NAME_ALT);
1322 xkb_info->mod2_mod = xkb_map_mod_get_index(xkb_info->keymap, "Mod2");
1323 xkb_info->mod3_mod = xkb_map_mod_get_index(xkb_info->keymap, "Mod3");
1324 xkb_info->super_mod = xkb_map_mod_get_index(xkb_info->keymap,
1325 XKB_MOD_NAME_LOGO);
1326 xkb_info->mod5_mod = xkb_map_mod_get_index(xkb_info->keymap, "Mod5");
1327
1328 xkb_info->num_led = xkb_map_led_get_index(xkb_info->keymap,
1329 XKB_LED_NAME_NUM);
1330 xkb_info->caps_led = xkb_map_led_get_index(xkb_info->keymap,
1331 XKB_LED_NAME_CAPS);
1332 xkb_info->scroll_led = xkb_map_led_get_index(xkb_info->keymap,
1333 XKB_LED_NAME_SCROLL);
1334
1335 keymap_str = xkb_map_get_as_string(xkb_info->keymap);
1336 if (keymap_str == NULL) {
1337 weston_log("failed to get string version of keymap\n");
1338 return -1;
1339 }
1340 xkb_info->keymap_size = strlen(keymap_str) + 1;
1341
1342 xkb_info->keymap_fd = os_create_anonymous_file(xkb_info->keymap_size);
1343 if (xkb_info->keymap_fd < 0) {
1344 weston_log("creating a keymap file for %lu bytes failed: %m\n",
1345 (unsigned long) xkb_info->keymap_size);
1346 goto err_keymap_str;
1347 }
1348
1349 xkb_info->keymap_area = mmap(NULL, xkb_info->keymap_size,
1350 PROT_READ | PROT_WRITE,
1351 MAP_SHARED, xkb_info->keymap_fd, 0);
1352 if (xkb_info->keymap_area == MAP_FAILED) {
1353 weston_log("failed to mmap() %lu bytes\n",
1354 (unsigned long) xkb_info->keymap_size);
1355 goto err_dev_zero;
1356 }
1357 strcpy(xkb_info->keymap_area, keymap_str);
1358 free(keymap_str);
1359
1360 return 0;
1361
1362err_dev_zero:
1363 close(xkb_info->keymap_fd);
1364 xkb_info->keymap_fd = -1;
1365err_keymap_str:
1366 free(keymap_str);
1367 return -1;
1368}
1369
1370static int
1371weston_compositor_build_global_keymap(struct weston_compositor *ec)
1372{
1373 if (ec->xkb_info.keymap != NULL)
1374 return 0;
1375
1376 ec->xkb_info.keymap = xkb_map_new_from_names(ec->xkb_context,
1377 &ec->xkb_names,
1378 0);
1379 if (ec->xkb_info.keymap == NULL) {
1380 weston_log("failed to compile global XKB keymap\n");
1381 weston_log(" tried rules %s, model %s, layout %s, variant %s, "
1382 "options %s\n",
1383 ec->xkb_names.rules, ec->xkb_names.model,
1384 ec->xkb_names.layout, ec->xkb_names.variant,
1385 ec->xkb_names.options);
1386 return -1;
1387 }
1388
1389 if (weston_xkb_info_new_keymap(&ec->xkb_info) < 0)
1390 return -1;
1391
1392 return 0;
1393}
1394
1395WL_EXPORT int
1396weston_seat_init_keyboard(struct weston_seat *seat, struct xkb_keymap *keymap)
1397{
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04001398 struct weston_keyboard *keyboard;
1399
Kristian Høgsberg2bf87622013-05-07 23:17:41 -04001400 if (seat->keyboard)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001401 return 0;
1402
1403 if (keymap != NULL) {
1404 seat->xkb_info.keymap = xkb_map_ref(keymap);
1405 if (weston_xkb_info_new_keymap(&seat->xkb_info) < 0)
1406 return -1;
1407 } else {
1408 if (weston_compositor_build_global_keymap(seat->compositor) < 0)
1409 return -1;
1410 seat->xkb_info = seat->compositor->xkb_info;
1411 seat->xkb_info.keymap = xkb_map_ref(seat->xkb_info.keymap);
1412 }
1413
1414 seat->xkb_state.state = xkb_state_new(seat->xkb_info.keymap);
1415 if (seat->xkb_state.state == NULL) {
1416 weston_log("failed to initialise XKB state\n");
1417 return -1;
1418 }
1419
1420 seat->xkb_state.leds = 0;
1421
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04001422 keyboard = weston_keyboard_create();
1423 if (keyboard == NULL) {
1424 weston_log("failed to allocate weston keyboard struct\n");
1425 return -1;
1426 }
1427
1428 seat->keyboard = keyboard;
1429 keyboard->seat = seat;
1430
1431 seat_send_updated_caps(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001432
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001433 return 0;
1434}
1435
1436WL_EXPORT void
1437weston_seat_init_pointer(struct weston_seat *seat)
1438{
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04001439 struct weston_pointer *pointer;
1440
Kristian Høgsberg2bf87622013-05-07 23:17:41 -04001441 if (seat->pointer)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001442 return;
1443
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04001444 pointer = weston_pointer_create();
1445 if (pointer == NULL)
1446 return;
1447
1448 seat->pointer = pointer;
1449 pointer->seat = seat;
1450
1451 seat_send_updated_caps(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001452}
1453
1454WL_EXPORT void
1455weston_seat_init_touch(struct weston_seat *seat)
1456{
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04001457 struct weston_touch *touch;
1458
Kristian Høgsberg2bf87622013-05-07 23:17:41 -04001459 if (seat->touch)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001460 return;
1461
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04001462 touch = weston_touch_create();
1463 if (touch == NULL)
1464 return;
1465
1466 seat->touch = touch;
1467 touch->seat = seat;
1468
1469 seat_send_updated_caps(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001470}
1471
1472WL_EXPORT void
Rob Bradford9af5f9e2013-05-31 18:09:50 +01001473weston_seat_init(struct weston_seat *seat, struct weston_compositor *ec,
1474 const char *seat_name)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001475{
Kristian Høgsberg4a2a2742013-05-06 22:24:50 -04001476 memset(seat, 0, sizeof *seat);
1477
Kristian Høgsberge3148752013-05-06 23:19:49 -04001478 seat->selection_data_source = NULL;
1479 wl_list_init(&seat->base_resource_list);
1480 wl_signal_init(&seat->selection_signal);
1481 wl_list_init(&seat->drag_resource_list);
Kristian Høgsberge3148752013-05-06 23:19:49 -04001482 wl_signal_init(&seat->destroy_signal);
Kristian Høgsberg4a2a2742013-05-06 22:24:50 -04001483
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001484 wl_display_add_global(ec->wl_display, &wl_seat_interface, seat,
1485 bind_seat);
1486
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001487 seat->compositor = ec;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001488 seat->modifier_state = 0;
1489 seat->num_tp = 0;
Rob Bradford9af5f9e2013-05-31 18:09:50 +01001490 seat->seat_name = strdup(seat_name);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001491
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001492 wl_list_insert(ec->seat_list.prev, &seat->link);
1493
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001494 clipboard_create(seat);
1495
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001496 wl_signal_emit(&ec->seat_created_signal, seat);
1497}
1498
1499WL_EXPORT void
1500weston_seat_release(struct weston_seat *seat)
1501{
1502 wl_list_remove(&seat->link);
1503 /* The global object is destroyed at wl_display_destroy() time. */
1504
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001505 if (seat->xkb_state.state != NULL)
1506 xkb_state_unref(seat->xkb_state.state);
1507 xkb_info_destroy(&seat->xkb_info);
1508
Kristian Høgsberge3148752013-05-06 23:19:49 -04001509 if (seat->pointer)
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04001510 weston_pointer_destroy(seat->pointer);
Kristian Høgsberge3148752013-05-06 23:19:49 -04001511 if (seat->keyboard)
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04001512 weston_keyboard_destroy(seat->keyboard);
Kristian Høgsberge3148752013-05-06 23:19:49 -04001513 if (seat->touch)
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04001514 weston_touch_destroy(seat->touch);
Kristian Høgsberg4a2a2742013-05-06 22:24:50 -04001515
Rob Bradford9af5f9e2013-05-31 18:09:50 +01001516 free (seat->seat_name);
1517
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001518 wl_signal_emit(&seat->destroy_signal, seat);
1519}