blob: 1737beb06da6c5460c7b95654bc59cb41b279407 [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) {
Rob Bradford66bd9f52013-06-25 18:56:42 +0100577 if (pointer->seat->output && pointer->seat->output != output)
578 continue;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400579 if (pixman_region32_contains_point(&output->region,
580 x, y, NULL))
581 valid = 1;
582 if (pixman_region32_contains_point(&output->region,
583 old_x, old_y, NULL))
584 prev = output;
585 }
586
Rob Bradford66bd9f52013-06-25 18:56:42 +0100587 if (!prev)
588 prev = pointer->seat->output;
589
590 if (prev && !valid) {
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400591 if (x < prev->x)
592 *fx = wl_fixed_from_int(prev->x);
593 else if (x >= prev->x + prev->width)
594 *fx = wl_fixed_from_int(prev->x +
595 prev->width - 1);
596 if (y < prev->y)
597 *fy = wl_fixed_from_int(prev->y);
Alexander Larssonbcd18d92013-05-28 16:23:33 +0200598 else if (y >= prev->y + prev->height)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400599 *fy = wl_fixed_from_int(prev->y +
600 prev->height - 1);
601 }
602}
603
604/* Takes absolute values */
605static void
606move_pointer(struct weston_seat *seat, wl_fixed_t x, wl_fixed_t y)
607{
608 struct weston_compositor *ec = seat->compositor;
Kristian Høgsberge3148752013-05-06 23:19:49 -0400609 struct weston_pointer *pointer = seat->pointer;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400610 struct weston_output *output;
611 int32_t ix, iy;
612
Rob Bradford806d8c02013-06-25 18:56:41 +0100613 weston_pointer_clamp (pointer, &x, &y);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400614
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400615 pointer->x = x;
616 pointer->y = y;
617
618 ix = wl_fixed_to_int(x);
619 iy = wl_fixed_to_int(y);
620
621 wl_list_for_each(output, &ec->output_list, link)
622 if (output->zoom.active &&
623 pixman_region32_contains_point(&output->region,
624 ix, iy, NULL))
625 weston_output_update_zoom(output, ZOOM_FOCUS_POINTER);
626
Kristian Høgsberg195b8692013-05-08 15:02:05 -0400627 if (pointer->sprite) {
628 weston_surface_set_position(pointer->sprite,
629 ix - pointer->hotspot_x,
630 iy - pointer->hotspot_y);
631 weston_surface_schedule_repaint(pointer->sprite);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400632 }
633}
634
635WL_EXPORT void
636notify_motion(struct weston_seat *seat,
637 uint32_t time, wl_fixed_t dx, wl_fixed_t dy)
638{
Kristian Høgsberg02bbabb2013-05-06 22:15:05 -0400639 const struct weston_pointer_grab_interface *interface;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400640 struct weston_compositor *ec = seat->compositor;
Kristian Høgsberge3148752013-05-06 23:19:49 -0400641 struct weston_pointer *pointer = seat->pointer;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400642
643 weston_compositor_wake(ec);
644
645 move_pointer(seat, pointer->x + dx, pointer->y + dy);
646
647 interface = pointer->grab->interface;
Kristian Høgsberg6848c252013-05-08 22:02:59 -0400648 interface->focus(pointer->grab);
Kristian Høgsbergbe6403e2013-05-08 21:03:21 -0400649 interface->motion(pointer->grab, time);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400650}
651
652WL_EXPORT void
653notify_motion_absolute(struct weston_seat *seat,
654 uint32_t time, wl_fixed_t x, wl_fixed_t y)
655{
Kristian Høgsberg02bbabb2013-05-06 22:15:05 -0400656 const struct weston_pointer_grab_interface *interface;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400657 struct weston_compositor *ec = seat->compositor;
Kristian Høgsberge3148752013-05-06 23:19:49 -0400658 struct weston_pointer *pointer = seat->pointer;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400659
660 weston_compositor_wake(ec);
661
662 move_pointer(seat, x, y);
663
664 interface = pointer->grab->interface;
Kristian Høgsberg6848c252013-05-08 22:02:59 -0400665 interface->focus(pointer->grab);
Kristian Høgsbergbe6403e2013-05-08 21:03:21 -0400666 interface->motion(pointer->grab, time);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400667}
668
669WL_EXPORT void
670weston_surface_activate(struct weston_surface *surface,
671 struct weston_seat *seat)
672{
673 struct weston_compositor *compositor = seat->compositor;
674
Kristian Høgsberge3148752013-05-06 23:19:49 -0400675 if (seat->keyboard) {
Kristian Høgsbergfe7aa902013-05-08 09:54:37 -0400676 weston_keyboard_set_focus(seat->keyboard, surface);
Kristian Høgsberge3148752013-05-06 23:19:49 -0400677 wl_data_device_set_keyboard_focus(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400678 }
679
680 wl_signal_emit(&compositor->activate_signal, surface);
681}
682
683WL_EXPORT void
684notify_button(struct weston_seat *seat, uint32_t time, int32_t button,
685 enum wl_pointer_button_state state)
686{
687 struct weston_compositor *compositor = seat->compositor;
Kristian Høgsberge3148752013-05-06 23:19:49 -0400688 struct weston_pointer *pointer = seat->pointer;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400689 struct weston_surface *focus =
690 (struct weston_surface *) pointer->focus;
691 uint32_t serial = wl_display_next_serial(compositor->wl_display);
692
693 if (state == WL_POINTER_BUTTON_STATE_PRESSED) {
694 if (compositor->ping_handler && focus)
695 compositor->ping_handler(focus, serial);
696 weston_compositor_idle_inhibit(compositor);
697 if (pointer->button_count == 0) {
698 pointer->grab_button = button;
699 pointer->grab_time = time;
700 pointer->grab_x = pointer->x;
701 pointer->grab_y = pointer->y;
702 }
703 pointer->button_count++;
704 } else {
705 weston_compositor_idle_release(compositor);
706 pointer->button_count--;
707 }
708
709 weston_compositor_run_button_binding(compositor, seat, time, button,
710 state);
711
712 pointer->grab->interface->button(pointer->grab, time, button, state);
713
714 if (pointer->button_count == 1)
715 pointer->grab_serial =
716 wl_display_get_serial(compositor->wl_display);
717}
718
719WL_EXPORT void
720notify_axis(struct weston_seat *seat, uint32_t time, uint32_t axis,
721 wl_fixed_t value)
722{
723 struct weston_compositor *compositor = seat->compositor;
Kristian Høgsberge3148752013-05-06 23:19:49 -0400724 struct weston_pointer *pointer = seat->pointer;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400725 struct weston_surface *focus =
726 (struct weston_surface *) pointer->focus;
727 uint32_t serial = wl_display_next_serial(compositor->wl_display);
728
729 if (compositor->ping_handler && focus)
730 compositor->ping_handler(focus, serial);
731
732 weston_compositor_wake(compositor);
733
734 if (!value)
735 return;
736
737 if (weston_compositor_run_axis_binding(compositor, seat,
738 time, axis, value))
739 return;
740
741 if (pointer->focus_resource)
742 wl_pointer_send_axis(pointer->focus_resource, time, axis,
743 value);
744}
745
746WL_EXPORT void
747notify_modifiers(struct weston_seat *seat, uint32_t serial)
748{
Kristian Høgsberge3148752013-05-06 23:19:49 -0400749 struct weston_keyboard *keyboard = seat->keyboard;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400750 struct weston_keyboard_grab *grab = keyboard->grab;
751 uint32_t mods_depressed, mods_latched, mods_locked, group;
752 uint32_t mods_lookup;
753 enum weston_led leds = 0;
754 int changed = 0;
755
756 /* Serialize and update our internal state, checking to see if it's
757 * different to the previous state. */
758 mods_depressed = xkb_state_serialize_mods(seat->xkb_state.state,
759 XKB_STATE_DEPRESSED);
760 mods_latched = xkb_state_serialize_mods(seat->xkb_state.state,
761 XKB_STATE_LATCHED);
762 mods_locked = xkb_state_serialize_mods(seat->xkb_state.state,
763 XKB_STATE_LOCKED);
764 group = xkb_state_serialize_group(seat->xkb_state.state,
765 XKB_STATE_EFFECTIVE);
766
Kristian Høgsberge3148752013-05-06 23:19:49 -0400767 if (mods_depressed != seat->keyboard->modifiers.mods_depressed ||
768 mods_latched != seat->keyboard->modifiers.mods_latched ||
769 mods_locked != seat->keyboard->modifiers.mods_locked ||
770 group != seat->keyboard->modifiers.group)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400771 changed = 1;
772
Kristian Høgsberge3148752013-05-06 23:19:49 -0400773 seat->keyboard->modifiers.mods_depressed = mods_depressed;
774 seat->keyboard->modifiers.mods_latched = mods_latched;
775 seat->keyboard->modifiers.mods_locked = mods_locked;
776 seat->keyboard->modifiers.group = group;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400777
778 /* And update the modifier_state for bindings. */
779 mods_lookup = mods_depressed | mods_latched;
780 seat->modifier_state = 0;
781 if (mods_lookup & (1 << seat->xkb_info.ctrl_mod))
782 seat->modifier_state |= MODIFIER_CTRL;
783 if (mods_lookup & (1 << seat->xkb_info.alt_mod))
784 seat->modifier_state |= MODIFIER_ALT;
785 if (mods_lookup & (1 << seat->xkb_info.super_mod))
786 seat->modifier_state |= MODIFIER_SUPER;
787 if (mods_lookup & (1 << seat->xkb_info.shift_mod))
788 seat->modifier_state |= MODIFIER_SHIFT;
789
790 /* Finally, notify the compositor that LEDs have changed. */
791 if (xkb_state_led_index_is_active(seat->xkb_state.state,
792 seat->xkb_info.num_led))
793 leds |= LED_NUM_LOCK;
794 if (xkb_state_led_index_is_active(seat->xkb_state.state,
795 seat->xkb_info.caps_led))
796 leds |= LED_CAPS_LOCK;
797 if (xkb_state_led_index_is_active(seat->xkb_state.state,
798 seat->xkb_info.scroll_led))
799 leds |= LED_SCROLL_LOCK;
800 if (leds != seat->xkb_state.leds && seat->led_update)
801 seat->led_update(seat, leds);
802 seat->xkb_state.leds = leds;
803
804 if (changed) {
805 grab->interface->modifiers(grab,
806 serial,
807 keyboard->modifiers.mods_depressed,
808 keyboard->modifiers.mods_latched,
809 keyboard->modifiers.mods_locked,
810 keyboard->modifiers.group);
811 }
812}
813
814static void
815update_modifier_state(struct weston_seat *seat, uint32_t serial, uint32_t key,
816 enum wl_keyboard_key_state state)
817{
818 enum xkb_key_direction direction;
819
820 if (state == WL_KEYBOARD_KEY_STATE_PRESSED)
821 direction = XKB_KEY_DOWN;
822 else
823 direction = XKB_KEY_UP;
824
825 /* Offset the keycode by 8, as the evdev XKB rules reflect X's
826 * broken keycode system, which starts at 8. */
827 xkb_state_update_key(seat->xkb_state.state, key + 8, direction);
828
829 notify_modifiers(seat, serial);
830}
831
832WL_EXPORT void
833notify_key(struct weston_seat *seat, uint32_t time, uint32_t key,
834 enum wl_keyboard_key_state state,
835 enum weston_key_state_update update_state)
836{
837 struct weston_compositor *compositor = seat->compositor;
Kristian Høgsberge3148752013-05-06 23:19:49 -0400838 struct weston_keyboard *keyboard = seat->keyboard;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400839 struct weston_surface *focus =
840 (struct weston_surface *) keyboard->focus;
841 struct weston_keyboard_grab *grab = keyboard->grab;
842 uint32_t serial = wl_display_next_serial(compositor->wl_display);
843 uint32_t *k, *end;
844
845 if (state == WL_KEYBOARD_KEY_STATE_PRESSED) {
846 if (compositor->ping_handler && focus)
847 compositor->ping_handler(focus, serial);
848
849 weston_compositor_idle_inhibit(compositor);
850 keyboard->grab_key = key;
851 keyboard->grab_time = time;
852 } else {
853 weston_compositor_idle_release(compositor);
854 }
855
856 end = keyboard->keys.data + keyboard->keys.size;
857 for (k = keyboard->keys.data; k < end; k++) {
858 if (*k == key) {
859 /* Ignore server-generated repeats. */
860 if (state == WL_KEYBOARD_KEY_STATE_PRESSED)
861 return;
862 *k = *--end;
863 }
864 }
865 keyboard->keys.size = (void *) end - keyboard->keys.data;
866 if (state == WL_KEYBOARD_KEY_STATE_PRESSED) {
867 k = wl_array_add(&keyboard->keys, sizeof *k);
868 *k = key;
869 }
870
871 if (grab == &keyboard->default_grab ||
872 grab == &keyboard->input_method_grab) {
873 weston_compositor_run_key_binding(compositor, seat, time, key,
874 state);
875 grab = keyboard->grab;
876 }
877
878 grab->interface->key(grab, time, key, state);
879
880 if (update_state == STATE_UPDATE_AUTOMATIC) {
881 update_modifier_state(seat,
882 wl_display_get_serial(compositor->wl_display),
883 key,
884 state);
885 }
886}
887
888WL_EXPORT void
889notify_pointer_focus(struct weston_seat *seat, struct weston_output *output,
890 wl_fixed_t x, wl_fixed_t y)
891{
892 struct weston_compositor *compositor = seat->compositor;
893
894 if (output) {
895 move_pointer(seat, x, y);
896 compositor->focus = 1;
897 } else {
898 compositor->focus = 0;
Kristian Høgsberg02bbabb2013-05-06 22:15:05 -0400899 /* FIXME: We should call weston_pointer_set_focus(seat,
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400900 * NULL) here, but somehow that breaks re-entry... */
901 }
902}
903
904static void
905destroy_device_saved_kbd_focus(struct wl_listener *listener, void *data)
906{
907 struct weston_seat *ws;
908
909 ws = container_of(listener, struct weston_seat,
910 saved_kbd_focus_listener);
911
912 ws->saved_kbd_focus = NULL;
913}
914
915WL_EXPORT void
916notify_keyboard_focus_in(struct weston_seat *seat, struct wl_array *keys,
917 enum weston_key_state_update update_state)
918{
919 struct weston_compositor *compositor = seat->compositor;
Kristian Høgsberge3148752013-05-06 23:19:49 -0400920 struct weston_keyboard *keyboard = seat->keyboard;
Kristian Høgsbergfe7aa902013-05-08 09:54:37 -0400921 struct weston_surface *surface;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400922 uint32_t *k, serial;
923
924 serial = wl_display_next_serial(compositor->wl_display);
925 wl_array_copy(&keyboard->keys, keys);
926 wl_array_for_each(k, &keyboard->keys) {
927 weston_compositor_idle_inhibit(compositor);
928 if (update_state == STATE_UPDATE_AUTOMATIC)
929 update_modifier_state(seat, serial, *k,
930 WL_KEYBOARD_KEY_STATE_PRESSED);
931 }
932
933 /* Run key bindings after we've updated the state. */
934 wl_array_for_each(k, &keyboard->keys) {
935 weston_compositor_run_key_binding(compositor, seat, 0, *k,
936 WL_KEYBOARD_KEY_STATE_PRESSED);
937 }
938
939 surface = seat->saved_kbd_focus;
940
941 if (surface) {
942 wl_list_remove(&seat->saved_kbd_focus_listener.link);
943 weston_keyboard_set_focus(keyboard, surface);
944 seat->saved_kbd_focus = NULL;
945 }
946}
947
948WL_EXPORT void
949notify_keyboard_focus_out(struct weston_seat *seat)
950{
951 struct weston_compositor *compositor = seat->compositor;
Kristian Høgsberge3148752013-05-06 23:19:49 -0400952 struct weston_keyboard *keyboard = seat->keyboard;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400953 uint32_t *k, serial;
954
955 serial = wl_display_next_serial(compositor->wl_display);
956 wl_array_for_each(k, &keyboard->keys) {
957 weston_compositor_idle_release(compositor);
958 update_modifier_state(seat, serial, *k,
959 WL_KEYBOARD_KEY_STATE_RELEASED);
960 }
961
962 seat->modifier_state = 0;
963
964 if (keyboard->focus) {
965 seat->saved_kbd_focus = keyboard->focus;
966 seat->saved_kbd_focus_listener.notify =
967 destroy_device_saved_kbd_focus;
Jason Ekstrand26ed73c2013-06-06 22:34:41 -0500968 wl_signal_add(&keyboard->focus->destroy_signal,
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400969 &seat->saved_kbd_focus_listener);
970 }
971
972 weston_keyboard_set_focus(keyboard, NULL);
973 /* FIXME: We really need keyboard grab cancel here to
974 * let the grab shut down properly. As it is we leak
975 * the grab data. */
976 weston_keyboard_end_grab(keyboard);
977}
978
979static void
Kristian Høgsbergfe7aa902013-05-08 09:54:37 -0400980touch_set_focus(struct weston_seat *seat, struct weston_surface *surface)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400981{
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400982 struct wl_resource *resource;
983
984 if (seat->touch->focus == surface)
985 return;
986
987 if (seat->touch->focus_resource)
988 wl_list_remove(&seat->touch->focus_listener.link);
989 seat->touch->focus = NULL;
990 seat->touch->focus_resource = NULL;
991
992 if (surface) {
993 resource =
Kristian Høgsberg80fb82d2013-05-06 21:49:55 -0400994 find_resource_for_surface(&seat->touch->resource_list,
995 surface);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400996 if (!resource) {
997 weston_log("couldn't find resource\n");
998 return;
999 }
1000
1001 seat->touch->focus = surface;
1002 seat->touch->focus_resource = resource;
Jason Ekstrand44a38632013-06-14 10:08:00 -05001003 wl_resource_add_destroy_listener(resource,
1004 &seat->touch->focus_listener);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001005 }
1006}
1007
1008/**
1009 * notify_touch - emulates button touches and notifies surfaces accordingly.
1010 *
1011 * It assumes always the correct cycle sequence until it gets here: touch_down
1012 * → touch_update → ... → touch_update → touch_end. The driver is responsible
1013 * for sending along such order.
1014 *
1015 */
1016WL_EXPORT void
1017notify_touch(struct weston_seat *seat, uint32_t time, int touch_id,
1018 wl_fixed_t x, wl_fixed_t y, int touch_type)
1019{
1020 struct weston_compositor *ec = seat->compositor;
Kristian Høgsberge3148752013-05-06 23:19:49 -04001021 struct weston_touch *touch = seat->touch;
Kristian Høgsberge329f362013-05-06 22:19:57 -04001022 struct weston_touch_grab *grab = touch->grab;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001023 struct weston_surface *es;
1024 wl_fixed_t sx, sy;
1025
1026 /* Update grab's global coordinates. */
1027 touch->grab_x = x;
1028 touch->grab_y = y;
1029
1030 switch (touch_type) {
1031 case WL_TOUCH_DOWN:
1032 weston_compositor_idle_inhibit(ec);
1033
1034 seat->num_tp++;
1035
1036 /* the first finger down picks the surface, and all further go
1037 * to that surface for the remainder of the touch session i.e.
1038 * until all touch points are up again. */
1039 if (seat->num_tp == 1) {
1040 es = weston_compositor_pick_surface(ec, x, y, &sx, &sy);
Kristian Høgsbergfe7aa902013-05-08 09:54:37 -04001041 touch_set_focus(seat, es);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001042 } else if (touch->focus) {
1043 es = (struct weston_surface *) touch->focus;
1044 weston_surface_from_global_fixed(es, x, y, &sx, &sy);
1045 } else {
1046 /* Unexpected condition: We have non-initial touch but
1047 * there is no focused surface.
1048 */
1049 weston_log("touch event received with %d points down"
1050 "but no surface focused\n", seat->num_tp);
1051 return;
1052 }
1053
1054 grab->interface->down(grab, time, touch_id, sx, sy);
1055 break;
1056 case WL_TOUCH_MOTION:
1057 es = (struct weston_surface *) touch->focus;
1058 if (!es)
1059 break;
1060
1061 weston_surface_from_global_fixed(es, x, y, &sx, &sy);
1062 grab->interface->motion(grab, time, touch_id, sx, sy);
1063 break;
1064 case WL_TOUCH_UP:
1065 weston_compositor_idle_release(ec);
1066 seat->num_tp--;
1067
1068 grab->interface->up(grab, time, touch_id);
1069 if (seat->num_tp == 0)
1070 touch_set_focus(seat, NULL);
1071 break;
1072 }
1073}
1074
1075static void
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001076pointer_cursor_surface_configure(struct weston_surface *es,
1077 int32_t dx, int32_t dy, int32_t width, int32_t height)
1078{
Kristian Høgsberg195b8692013-05-08 15:02:05 -04001079 struct weston_pointer *pointer = es->configure_private;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001080 int x, y;
1081
1082 if (width == 0)
1083 return;
1084
Kristian Høgsberg195b8692013-05-08 15:02:05 -04001085 assert(es == pointer->sprite);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001086
Kristian Høgsberg195b8692013-05-08 15:02:05 -04001087 pointer->hotspot_x -= dx;
1088 pointer->hotspot_y -= dy;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001089
Kristian Høgsberg195b8692013-05-08 15:02:05 -04001090 x = wl_fixed_to_int(pointer->x) - pointer->hotspot_x;
1091 y = wl_fixed_to_int(pointer->y) - pointer->hotspot_y;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001092
Kristian Høgsberg195b8692013-05-08 15:02:05 -04001093 weston_surface_configure(pointer->sprite, x, y, width, height);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001094
1095 empty_region(&es->pending.input);
1096
1097 if (!weston_surface_is_mapped(es)) {
1098 wl_list_insert(&es->compositor->cursor_layer.surface_list,
1099 &es->layer_link);
1100 weston_surface_update_transform(es);
1101 }
1102}
1103
1104static void
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001105pointer_set_cursor(struct wl_client *client, struct wl_resource *resource,
1106 uint32_t serial, struct wl_resource *surface_resource,
1107 int32_t x, int32_t y)
1108{
Jason Ekstrand44a38632013-06-14 10:08:00 -05001109 struct weston_pointer *pointer = wl_resource_get_user_data(resource);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001110 struct weston_surface *surface = NULL;
1111
1112 if (surface_resource)
Jason Ekstrand0f2ef7e2013-06-14 10:07:53 -05001113 surface = wl_resource_get_user_data(surface_resource);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001114
Kristian Høgsberg195b8692013-05-08 15:02:05 -04001115 if (pointer->focus == NULL)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001116 return;
Giulio Camuffo1fd4b012013-06-20 18:13:07 +02001117 /* pointer->focus->resource can be NULL. Surfaces like the
1118 black_surface used in shell.c for fullscreen don't have
1119 a resource, but can still have focus */
1120 if (pointer->focus->resource == NULL)
1121 return;
Jason Ekstrand26ed73c2013-06-06 22:34:41 -05001122 if (wl_resource_get_client(pointer->focus->resource) != client)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001123 return;
Kristian Høgsberg195b8692013-05-08 15:02:05 -04001124 if (pointer->focus_serial - serial > UINT32_MAX / 2)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001125 return;
1126
Kristian Høgsberg195b8692013-05-08 15:02:05 -04001127 if (surface && surface != pointer->sprite) {
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001128 if (surface->configure) {
Jason Ekstrand26ed73c2013-06-06 22:34:41 -05001129 wl_resource_post_error(surface->resource,
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001130 WL_DISPLAY_ERROR_INVALID_OBJECT,
1131 "surface->configure already "
1132 "set");
1133 return;
1134 }
1135 }
1136
Kristian Høgsberg195b8692013-05-08 15:02:05 -04001137 if (pointer->sprite)
1138 pointer_unmap_sprite(pointer);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001139
1140 if (!surface)
1141 return;
1142
Jason Ekstrand26ed73c2013-06-06 22:34:41 -05001143 wl_signal_add(&surface->destroy_signal,
Kristian Høgsberg195b8692013-05-08 15:02:05 -04001144 &pointer->sprite_destroy_listener);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001145
1146 surface->configure = pointer_cursor_surface_configure;
Kristian Høgsberg195b8692013-05-08 15:02:05 -04001147 surface->configure_private = pointer;
1148 pointer->sprite = surface;
1149 pointer->hotspot_x = x;
1150 pointer->hotspot_y = y;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001151
1152 if (surface->buffer_ref.buffer)
1153 pointer_cursor_surface_configure(surface, 0, 0, weston_surface_buffer_width(surface),
1154 weston_surface_buffer_height(surface));
1155}
1156
1157static const struct wl_pointer_interface pointer_interface = {
1158 pointer_set_cursor
1159};
1160
1161static void
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001162seat_get_pointer(struct wl_client *client, struct wl_resource *resource,
1163 uint32_t id)
1164{
Jason Ekstrand44a38632013-06-14 10:08:00 -05001165 struct weston_seat *seat = wl_resource_get_user_data(resource);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001166 struct wl_resource *cr;
1167
Kristian Høgsberge3148752013-05-06 23:19:49 -04001168 if (!seat->pointer)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001169 return;
1170
1171 cr = wl_client_add_object(client, &wl_pointer_interface,
Kristian Høgsberg195b8692013-05-08 15:02:05 -04001172 &pointer_interface, id, seat->pointer);
Jason Ekstrand44a38632013-06-14 10:08:00 -05001173 wl_list_insert(&seat->pointer->resource_list, wl_resource_get_link(cr));
1174 wl_resource_set_destructor(cr, unbind_resource);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001175
Kristian Høgsberge3148752013-05-06 23:19:49 -04001176 if (seat->pointer->focus &&
Jason Ekstrand26ed73c2013-06-06 22:34:41 -05001177 wl_resource_get_client(seat->pointer->focus->resource) == client) {
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001178 struct weston_surface *surface;
1179 wl_fixed_t sx, sy;
1180
Kristian Høgsberge3148752013-05-06 23:19:49 -04001181 surface = (struct weston_surface *) seat->pointer->focus;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001182 weston_surface_from_global_fixed(surface,
Kristian Høgsberge3148752013-05-06 23:19:49 -04001183 seat->pointer->x,
1184 seat->pointer->y,
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001185 &sx,
1186 &sy);
Kristian Høgsberge3148752013-05-06 23:19:49 -04001187 weston_pointer_set_focus(seat->pointer,
1188 seat->pointer->focus,
Kristian Høgsberg02bbabb2013-05-06 22:15:05 -04001189 sx,
1190 sy);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001191 }
1192}
1193
1194static void
1195seat_get_keyboard(struct wl_client *client, struct wl_resource *resource,
1196 uint32_t id)
1197{
Jason Ekstrand44a38632013-06-14 10:08:00 -05001198 struct weston_seat *seat = wl_resource_get_user_data(resource);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001199 struct wl_resource *cr;
1200
Kristian Høgsberge3148752013-05-06 23:19:49 -04001201 if (!seat->keyboard)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001202 return;
1203
1204 cr = wl_client_add_object(client, &wl_keyboard_interface, NULL, id,
1205 seat);
Jason Ekstrand44a38632013-06-14 10:08:00 -05001206 wl_list_insert(&seat->keyboard->resource_list, wl_resource_get_link(cr));
1207 wl_resource_set_destructor(cr, unbind_resource);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001208
1209 wl_keyboard_send_keymap(cr, WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1,
1210 seat->xkb_info.keymap_fd,
1211 seat->xkb_info.keymap_size);
1212
Kristian Høgsberge3148752013-05-06 23:19:49 -04001213 if (seat->keyboard->focus &&
Jason Ekstrand26ed73c2013-06-06 22:34:41 -05001214 wl_resource_get_client(seat->keyboard->focus->resource) == client) {
Kristian Høgsberge3148752013-05-06 23:19:49 -04001215 weston_keyboard_set_focus(seat->keyboard,
1216 seat->keyboard->focus);
1217 wl_data_device_set_keyboard_focus(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001218 }
1219}
1220
1221static void
1222seat_get_touch(struct wl_client *client, struct wl_resource *resource,
1223 uint32_t id)
1224{
Jason Ekstrand44a38632013-06-14 10:08:00 -05001225 struct weston_seat *seat = wl_resource_get_user_data(resource);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001226 struct wl_resource *cr;
1227
Kristian Høgsberge3148752013-05-06 23:19:49 -04001228 if (!seat->touch)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001229 return;
1230
1231 cr = wl_client_add_object(client, &wl_touch_interface, NULL, id, seat);
Jason Ekstrand44a38632013-06-14 10:08:00 -05001232 wl_list_insert(&seat->touch->resource_list, wl_resource_get_link(cr));
1233 wl_resource_set_destructor(cr, unbind_resource);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001234}
1235
1236static const struct wl_seat_interface seat_interface = {
1237 seat_get_pointer,
1238 seat_get_keyboard,
1239 seat_get_touch,
1240};
1241
1242static void
1243bind_seat(struct wl_client *client, void *data, uint32_t version, uint32_t id)
1244{
Kristian Høgsberge3148752013-05-06 23:19:49 -04001245 struct weston_seat *seat = data;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001246 struct wl_resource *resource;
1247 enum wl_seat_capability caps = 0;
1248
1249 resource = wl_client_add_object(client, &wl_seat_interface,
1250 &seat_interface, id, data);
Jason Ekstrand44a38632013-06-14 10:08:00 -05001251 wl_list_insert(&seat->base_resource_list, wl_resource_get_link(resource));
1252 wl_resource_set_destructor(resource, unbind_resource);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001253
1254 if (seat->pointer)
1255 caps |= WL_SEAT_CAPABILITY_POINTER;
1256 if (seat->keyboard)
1257 caps |= WL_SEAT_CAPABILITY_KEYBOARD;
1258 if (seat->touch)
1259 caps |= WL_SEAT_CAPABILITY_TOUCH;
1260
1261 wl_seat_send_capabilities(resource, caps);
Rob Bradforde445ae62013-05-31 18:09:51 +01001262 if (version >= 2)
1263 wl_seat_send_name(resource, seat->seat_name);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001264}
1265
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001266int
1267weston_compositor_xkb_init(struct weston_compositor *ec,
1268 struct xkb_rule_names *names)
1269{
1270 if (ec->xkb_context == NULL) {
1271 ec->xkb_context = xkb_context_new(0);
1272 if (ec->xkb_context == NULL) {
1273 weston_log("failed to create XKB context\n");
1274 return -1;
1275 }
1276 }
1277
1278 if (names)
1279 ec->xkb_names = *names;
1280 if (!ec->xkb_names.rules)
1281 ec->xkb_names.rules = strdup("evdev");
1282 if (!ec->xkb_names.model)
1283 ec->xkb_names.model = strdup("pc105");
1284 if (!ec->xkb_names.layout)
1285 ec->xkb_names.layout = strdup("us");
1286
1287 return 0;
1288}
1289
1290static void xkb_info_destroy(struct weston_xkb_info *xkb_info)
1291{
1292 if (xkb_info->keymap)
1293 xkb_map_unref(xkb_info->keymap);
1294
1295 if (xkb_info->keymap_area)
1296 munmap(xkb_info->keymap_area, xkb_info->keymap_size);
1297 if (xkb_info->keymap_fd >= 0)
1298 close(xkb_info->keymap_fd);
1299}
1300
1301void
1302weston_compositor_xkb_destroy(struct weston_compositor *ec)
1303{
1304 free((char *) ec->xkb_names.rules);
1305 free((char *) ec->xkb_names.model);
1306 free((char *) ec->xkb_names.layout);
1307 free((char *) ec->xkb_names.variant);
1308 free((char *) ec->xkb_names.options);
1309
1310 xkb_info_destroy(&ec->xkb_info);
1311 xkb_context_unref(ec->xkb_context);
1312}
1313
1314static int
1315weston_xkb_info_new_keymap(struct weston_xkb_info *xkb_info)
1316{
1317 char *keymap_str;
1318
1319 xkb_info->shift_mod = xkb_map_mod_get_index(xkb_info->keymap,
1320 XKB_MOD_NAME_SHIFT);
1321 xkb_info->caps_mod = xkb_map_mod_get_index(xkb_info->keymap,
1322 XKB_MOD_NAME_CAPS);
1323 xkb_info->ctrl_mod = xkb_map_mod_get_index(xkb_info->keymap,
1324 XKB_MOD_NAME_CTRL);
1325 xkb_info->alt_mod = xkb_map_mod_get_index(xkb_info->keymap,
1326 XKB_MOD_NAME_ALT);
1327 xkb_info->mod2_mod = xkb_map_mod_get_index(xkb_info->keymap, "Mod2");
1328 xkb_info->mod3_mod = xkb_map_mod_get_index(xkb_info->keymap, "Mod3");
1329 xkb_info->super_mod = xkb_map_mod_get_index(xkb_info->keymap,
1330 XKB_MOD_NAME_LOGO);
1331 xkb_info->mod5_mod = xkb_map_mod_get_index(xkb_info->keymap, "Mod5");
1332
1333 xkb_info->num_led = xkb_map_led_get_index(xkb_info->keymap,
1334 XKB_LED_NAME_NUM);
1335 xkb_info->caps_led = xkb_map_led_get_index(xkb_info->keymap,
1336 XKB_LED_NAME_CAPS);
1337 xkb_info->scroll_led = xkb_map_led_get_index(xkb_info->keymap,
1338 XKB_LED_NAME_SCROLL);
1339
1340 keymap_str = xkb_map_get_as_string(xkb_info->keymap);
1341 if (keymap_str == NULL) {
1342 weston_log("failed to get string version of keymap\n");
1343 return -1;
1344 }
1345 xkb_info->keymap_size = strlen(keymap_str) + 1;
1346
1347 xkb_info->keymap_fd = os_create_anonymous_file(xkb_info->keymap_size);
1348 if (xkb_info->keymap_fd < 0) {
1349 weston_log("creating a keymap file for %lu bytes failed: %m\n",
1350 (unsigned long) xkb_info->keymap_size);
1351 goto err_keymap_str;
1352 }
1353
1354 xkb_info->keymap_area = mmap(NULL, xkb_info->keymap_size,
1355 PROT_READ | PROT_WRITE,
1356 MAP_SHARED, xkb_info->keymap_fd, 0);
1357 if (xkb_info->keymap_area == MAP_FAILED) {
1358 weston_log("failed to mmap() %lu bytes\n",
1359 (unsigned long) xkb_info->keymap_size);
1360 goto err_dev_zero;
1361 }
1362 strcpy(xkb_info->keymap_area, keymap_str);
1363 free(keymap_str);
1364
1365 return 0;
1366
1367err_dev_zero:
1368 close(xkb_info->keymap_fd);
1369 xkb_info->keymap_fd = -1;
1370err_keymap_str:
1371 free(keymap_str);
1372 return -1;
1373}
1374
1375static int
1376weston_compositor_build_global_keymap(struct weston_compositor *ec)
1377{
1378 if (ec->xkb_info.keymap != NULL)
1379 return 0;
1380
1381 ec->xkb_info.keymap = xkb_map_new_from_names(ec->xkb_context,
1382 &ec->xkb_names,
1383 0);
1384 if (ec->xkb_info.keymap == NULL) {
1385 weston_log("failed to compile global XKB keymap\n");
1386 weston_log(" tried rules %s, model %s, layout %s, variant %s, "
1387 "options %s\n",
1388 ec->xkb_names.rules, ec->xkb_names.model,
1389 ec->xkb_names.layout, ec->xkb_names.variant,
1390 ec->xkb_names.options);
1391 return -1;
1392 }
1393
1394 if (weston_xkb_info_new_keymap(&ec->xkb_info) < 0)
1395 return -1;
1396
1397 return 0;
1398}
1399
1400WL_EXPORT int
1401weston_seat_init_keyboard(struct weston_seat *seat, struct xkb_keymap *keymap)
1402{
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04001403 struct weston_keyboard *keyboard;
1404
Kristian Høgsberg2bf87622013-05-07 23:17:41 -04001405 if (seat->keyboard)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001406 return 0;
1407
1408 if (keymap != NULL) {
1409 seat->xkb_info.keymap = xkb_map_ref(keymap);
1410 if (weston_xkb_info_new_keymap(&seat->xkb_info) < 0)
1411 return -1;
1412 } else {
1413 if (weston_compositor_build_global_keymap(seat->compositor) < 0)
1414 return -1;
1415 seat->xkb_info = seat->compositor->xkb_info;
1416 seat->xkb_info.keymap = xkb_map_ref(seat->xkb_info.keymap);
1417 }
1418
1419 seat->xkb_state.state = xkb_state_new(seat->xkb_info.keymap);
1420 if (seat->xkb_state.state == NULL) {
1421 weston_log("failed to initialise XKB state\n");
1422 return -1;
1423 }
1424
1425 seat->xkb_state.leds = 0;
1426
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04001427 keyboard = weston_keyboard_create();
1428 if (keyboard == NULL) {
1429 weston_log("failed to allocate weston keyboard struct\n");
1430 return -1;
1431 }
1432
1433 seat->keyboard = keyboard;
1434 keyboard->seat = seat;
1435
1436 seat_send_updated_caps(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001437
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001438 return 0;
1439}
1440
1441WL_EXPORT void
1442weston_seat_init_pointer(struct weston_seat *seat)
1443{
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04001444 struct weston_pointer *pointer;
1445
Kristian Høgsberg2bf87622013-05-07 23:17:41 -04001446 if (seat->pointer)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001447 return;
1448
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04001449 pointer = weston_pointer_create();
1450 if (pointer == NULL)
1451 return;
1452
1453 seat->pointer = pointer;
1454 pointer->seat = seat;
1455
1456 seat_send_updated_caps(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001457}
1458
1459WL_EXPORT void
1460weston_seat_init_touch(struct weston_seat *seat)
1461{
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04001462 struct weston_touch *touch;
1463
Kristian Høgsberg2bf87622013-05-07 23:17:41 -04001464 if (seat->touch)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001465 return;
1466
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04001467 touch = weston_touch_create();
1468 if (touch == NULL)
1469 return;
1470
1471 seat->touch = touch;
1472 touch->seat = seat;
1473
1474 seat_send_updated_caps(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001475}
1476
1477WL_EXPORT void
Rob Bradford9af5f9e2013-05-31 18:09:50 +01001478weston_seat_init(struct weston_seat *seat, struct weston_compositor *ec,
1479 const char *seat_name)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001480{
Kristian Høgsberg4a2a2742013-05-06 22:24:50 -04001481 memset(seat, 0, sizeof *seat);
1482
Kristian Høgsberge3148752013-05-06 23:19:49 -04001483 seat->selection_data_source = NULL;
1484 wl_list_init(&seat->base_resource_list);
1485 wl_signal_init(&seat->selection_signal);
1486 wl_list_init(&seat->drag_resource_list);
Kristian Høgsberge3148752013-05-06 23:19:49 -04001487 wl_signal_init(&seat->destroy_signal);
Kristian Høgsberg4a2a2742013-05-06 22:24:50 -04001488
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001489 wl_display_add_global(ec->wl_display, &wl_seat_interface, seat,
1490 bind_seat);
1491
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001492 seat->compositor = ec;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001493 seat->modifier_state = 0;
1494 seat->num_tp = 0;
Rob Bradford9af5f9e2013-05-31 18:09:50 +01001495 seat->seat_name = strdup(seat_name);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001496
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001497 wl_list_insert(ec->seat_list.prev, &seat->link);
1498
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001499 clipboard_create(seat);
1500
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001501 wl_signal_emit(&ec->seat_created_signal, seat);
1502}
1503
1504WL_EXPORT void
1505weston_seat_release(struct weston_seat *seat)
1506{
1507 wl_list_remove(&seat->link);
1508 /* The global object is destroyed at wl_display_destroy() time. */
1509
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001510 if (seat->xkb_state.state != NULL)
1511 xkb_state_unref(seat->xkb_state.state);
1512 xkb_info_destroy(&seat->xkb_info);
1513
Kristian Høgsberge3148752013-05-06 23:19:49 -04001514 if (seat->pointer)
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04001515 weston_pointer_destroy(seat->pointer);
Kristian Høgsberge3148752013-05-06 23:19:49 -04001516 if (seat->keyboard)
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04001517 weston_keyboard_destroy(seat->keyboard);
Kristian Høgsberge3148752013-05-06 23:19:49 -04001518 if (seat->touch)
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04001519 weston_touch_destroy(seat->touch);
Kristian Høgsberg4a2a2742013-05-06 22:24:50 -04001520
Rob Bradford9af5f9e2013-05-31 18:09:50 +01001521 free (seat->seat_name);
1522
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001523 wl_signal_emit(&seat->destroy_signal, seat);
1524}