blob: 88fd64c1e800c8ae3dbdcfbf501e12c179effbc7 [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>
Matt Roper01a92732013-06-24 16:52:44 +010029#include <fcntl.h>
Kristian Høgsberg2158a882013-04-18 15:07:39 -040030
Kristian Høgsbergb5e26102013-04-18 15:40:10 -040031#include "../shared/os-compatibility.h"
Kristian Høgsberg2158a882013-04-18 15:07:39 -040032#include "compositor.h"
33
Kristian Høgsbergb5e26102013-04-18 15:40:10 -040034static void
35empty_region(pixman_region32_t *region)
36{
37 pixman_region32_fini(region);
38 pixman_region32_init(region);
39}
40
41static void unbind_resource(struct wl_resource *resource)
42{
Jason Ekstrand44a38632013-06-14 10:08:00 -050043 wl_list_remove(wl_resource_get_link(resource));
Kristian Høgsbergb5e26102013-04-18 15:40:10 -040044}
45
46void
Kristian Høgsberga71e8b22013-05-06 21:51:21 -040047weston_seat_repick(struct weston_seat *seat)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -040048{
Kristian Høgsberg02bbabb2013-05-06 22:15:05 -040049 const struct weston_pointer_grab_interface *interface;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -040050
Kristian Høgsberg6848c252013-05-08 22:02:59 -040051 if (seat->pointer == NULL)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -040052 return;
53
Kristian Høgsberg6848c252013-05-08 22:02:59 -040054 interface = seat->pointer->grab->interface;
55 interface->focus(seat->pointer->grab);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -040056}
57
58static void
59weston_compositor_idle_inhibit(struct weston_compositor *compositor)
60{
61 weston_compositor_wake(compositor);
62 compositor->idle_inhibit++;
63}
64
65static void
66weston_compositor_idle_release(struct weston_compositor *compositor)
67{
68 compositor->idle_inhibit--;
69 weston_compositor_wake(compositor);
70}
71
Kristian Høgsberg2158a882013-04-18 15:07:39 -040072static void
73lose_pointer_focus(struct wl_listener *listener, void *data)
74{
Kristian Høgsberg02bbabb2013-05-06 22:15:05 -040075 struct weston_pointer *pointer =
76 container_of(listener, struct weston_pointer, focus_listener);
Kristian Høgsberg2158a882013-04-18 15:07:39 -040077
78 pointer->focus_resource = NULL;
79}
80
81static void
82lose_keyboard_focus(struct wl_listener *listener, void *data)
83{
Kristian Høgsberg29139d42013-04-18 15:25:39 -040084 struct weston_keyboard *keyboard =
85 container_of(listener, struct weston_keyboard, focus_listener);
Kristian Høgsberg2158a882013-04-18 15:07:39 -040086
87 keyboard->focus_resource = NULL;
88}
89
90static void
91lose_touch_focus(struct wl_listener *listener, void *data)
92{
Kristian Høgsberge329f362013-05-06 22:19:57 -040093 struct weston_touch *touch =
94 container_of(listener, struct weston_touch, focus_listener);
Kristian Høgsberg2158a882013-04-18 15:07:39 -040095
96 touch->focus_resource = NULL;
97}
98
99static void
Kristian Høgsberg6848c252013-05-08 22:02:59 -0400100default_grab_focus(struct weston_pointer_grab *grab)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400101{
Kristian Høgsberg02bbabb2013-05-06 22:15:05 -0400102 struct weston_pointer *pointer = grab->pointer;
Kristian Høgsberg6848c252013-05-08 22:02:59 -0400103 struct weston_surface *surface;
104 wl_fixed_t sx, sy;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400105
106 if (pointer->button_count > 0)
107 return;
108
Kristian Høgsberg6848c252013-05-08 22:02:59 -0400109 surface = weston_compositor_pick_surface(pointer->seat->compositor,
110 pointer->x, pointer->y,
111 &sx, &sy);
112
Kristian Høgsberge122b7b2013-05-08 16:47:00 -0400113 if (pointer->focus != surface)
Kristian Høgsberg6848c252013-05-08 22:02:59 -0400114 weston_pointer_set_focus(pointer, surface, sx, sy);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400115}
116
117static void
Kristian Høgsbergbe6403e2013-05-08 21:03:21 -0400118default_grab_motion(struct weston_pointer_grab *grab, uint32_t time)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400119{
Kristian Høgsbergbe6403e2013-05-08 21:03:21 -0400120 struct weston_pointer *pointer = grab->pointer;
121 wl_fixed_t sx, sy;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400122
Kristian Høgsbergbe6403e2013-05-08 21:03:21 -0400123 if (pointer->focus_resource) {
124 weston_surface_from_global_fixed(pointer->focus,
125 pointer->x, pointer->y,
126 &sx, &sy);
127 wl_pointer_send_motion(pointer->focus_resource, time, sx, sy);
128 }
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400129}
130
131static void
Kristian Høgsberg02bbabb2013-05-06 22:15:05 -0400132default_grab_button(struct weston_pointer_grab *grab,
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400133 uint32_t time, uint32_t button, uint32_t state_w)
134{
Kristian Høgsberg02bbabb2013-05-06 22:15:05 -0400135 struct weston_pointer *pointer = grab->pointer;
Kristian Høgsberge122b7b2013-05-08 16:47:00 -0400136 struct weston_compositor *compositor = pointer->seat->compositor;
137 struct weston_surface *surface;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400138 struct wl_resource *resource;
139 uint32_t serial;
140 enum wl_pointer_button_state state = state_w;
141 struct wl_display *display;
Kristian Høgsberge122b7b2013-05-08 16:47:00 -0400142 wl_fixed_t sx, sy;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400143
144 resource = pointer->focus_resource;
145 if (resource) {
Jason Ekstrand44a38632013-06-14 10:08:00 -0500146 display = wl_client_get_display(wl_resource_get_client(resource));
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400147 serial = wl_display_next_serial(display);
148 wl_pointer_send_button(resource, serial, time, button, state_w);
149 }
150
151 if (pointer->button_count == 0 &&
Kristian Høgsberge122b7b2013-05-08 16:47:00 -0400152 state == WL_POINTER_BUTTON_STATE_RELEASED) {
153 surface = weston_compositor_pick_surface(compositor,
154 pointer->x,
155 pointer->y,
156 &sx, &sy);
157
158 weston_pointer_set_focus(pointer, surface, sx, sy);
159 }
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400160}
161
Kristian Høgsberg02bbabb2013-05-06 22:15:05 -0400162static const struct weston_pointer_grab_interface
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400163 default_pointer_grab_interface = {
164 default_grab_focus,
165 default_grab_motion,
166 default_grab_button
167};
168
Kristian Høgsberge329f362013-05-06 22:19:57 -0400169static void
170default_grab_touch_down(struct weston_touch_grab *grab, uint32_t time,
171 int touch_id, wl_fixed_t sx, wl_fixed_t sy)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400172{
Kristian Høgsberge329f362013-05-06 22:19:57 -0400173 struct weston_touch *touch = grab->touch;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400174 struct wl_display *display;
175 uint32_t serial;
176
177 if (touch->focus_resource && touch->focus) {
Jason Ekstrand44a38632013-06-14 10:08:00 -0500178 display = wl_client_get_display(wl_resource_get_client(touch->focus_resource));
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400179 serial = wl_display_next_serial(display);
180 wl_touch_send_down(touch->focus_resource, serial, time,
Jason Ekstrand26ed73c2013-06-06 22:34:41 -0500181 touch->focus->resource,
Kristian Høgsberge329f362013-05-06 22:19:57 -0400182 touch_id, sx, sy);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400183 }
184}
185
Kristian Høgsberge329f362013-05-06 22:19:57 -0400186static void
187default_grab_touch_up(struct weston_touch_grab *grab,
188 uint32_t time, int touch_id)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400189{
Kristian Høgsberge329f362013-05-06 22:19:57 -0400190 struct weston_touch *touch = grab->touch;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400191 struct wl_display *display;
192 uint32_t serial;
193
194 if (touch->focus_resource) {
Jason Ekstrand44a38632013-06-14 10:08:00 -0500195 display = wl_client_get_display(wl_resource_get_client(touch->focus_resource));
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400196 serial = wl_display_next_serial(display);
197 wl_touch_send_up(touch->focus_resource, serial, time, touch_id);
198 }
199}
200
Kristian Høgsberge329f362013-05-06 22:19:57 -0400201static void
202default_grab_touch_motion(struct weston_touch_grab *grab, uint32_t time,
203 int touch_id, wl_fixed_t sx, wl_fixed_t sy)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400204{
Kristian Høgsberge329f362013-05-06 22:19:57 -0400205 struct weston_touch *touch = grab->touch;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400206
207 if (touch->focus_resource) {
208 wl_touch_send_motion(touch->focus_resource, time,
Kristian Høgsberge329f362013-05-06 22:19:57 -0400209 touch_id, sx, sy);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400210 }
211}
212
Kristian Høgsberge329f362013-05-06 22:19:57 -0400213static const struct weston_touch_grab_interface default_touch_grab_interface = {
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400214 default_grab_touch_down,
215 default_grab_touch_up,
216 default_grab_touch_motion
217};
218
219static void
Kristian Høgsberg29139d42013-04-18 15:25:39 -0400220default_grab_key(struct weston_keyboard_grab *grab,
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400221 uint32_t time, uint32_t key, uint32_t state)
222{
Kristian Høgsberg29139d42013-04-18 15:25:39 -0400223 struct weston_keyboard *keyboard = grab->keyboard;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400224 struct wl_resource *resource;
225 struct wl_display *display;
226 uint32_t serial;
227
228 resource = keyboard->focus_resource;
229 if (resource) {
Jason Ekstrand44a38632013-06-14 10:08:00 -0500230 display = wl_client_get_display(wl_resource_get_client(resource));
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400231 serial = wl_display_next_serial(display);
232 wl_keyboard_send_key(resource, serial, time, key, state);
233 }
234}
235
236static struct wl_resource *
Kristian Høgsbergfe7aa902013-05-08 09:54:37 -0400237find_resource_for_surface(struct wl_list *list, struct weston_surface *surface)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400238{
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400239 if (!surface)
240 return NULL;
241
Jason Ekstrand44a38632013-06-14 10:08:00 -0500242 if (!surface->resource)
243 return NULL;
244
245 return wl_resource_find_for_client(list, wl_resource_get_client(surface->resource));
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400246}
247
248static void
Kristian Høgsberg29139d42013-04-18 15:25:39 -0400249default_grab_modifiers(struct weston_keyboard_grab *grab, uint32_t serial,
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400250 uint32_t mods_depressed, uint32_t mods_latched,
251 uint32_t mods_locked, uint32_t group)
252{
Kristian Høgsberg29139d42013-04-18 15:25:39 -0400253 struct weston_keyboard *keyboard = grab->keyboard;
Kristian Høgsberg02bbabb2013-05-06 22:15:05 -0400254 struct weston_pointer *pointer = keyboard->seat->pointer;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400255 struct wl_resource *resource, *pr;
256
257 resource = keyboard->focus_resource;
258 if (!resource)
259 return;
260
261 wl_keyboard_send_modifiers(resource, serial, mods_depressed,
262 mods_latched, mods_locked, group);
263
264 if (pointer && pointer->focus && pointer->focus != keyboard->focus) {
265 pr = find_resource_for_surface(&keyboard->resource_list,
266 pointer->focus);
267 if (pr) {
268 wl_keyboard_send_modifiers(pr,
269 serial,
270 keyboard->modifiers.mods_depressed,
271 keyboard->modifiers.mods_latched,
272 keyboard->modifiers.mods_locked,
273 keyboard->modifiers.group);
274 }
275 }
276}
277
Kristian Høgsberg29139d42013-04-18 15:25:39 -0400278static const struct weston_keyboard_grab_interface
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400279 default_keyboard_grab_interface = {
280 default_grab_key,
281 default_grab_modifiers,
282};
283
Kristian Høgsberg195b8692013-05-08 15:02:05 -0400284static void
285pointer_unmap_sprite(struct weston_pointer *pointer)
286{
287 if (weston_surface_is_mapped(pointer->sprite))
288 weston_surface_unmap(pointer->sprite);
289
290 wl_list_remove(&pointer->sprite_destroy_listener.link);
291 pointer->sprite->configure = NULL;
292 pointer->sprite->configure_private = NULL;
293 pointer->sprite = NULL;
294}
295
296static void
297pointer_handle_sprite_destroy(struct wl_listener *listener, void *data)
298{
299 struct weston_pointer *pointer =
300 container_of(listener, struct weston_pointer,
301 sprite_destroy_listener);
302
303 pointer->sprite = NULL;
304}
305
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400306WL_EXPORT struct weston_pointer *
307weston_pointer_create(void)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400308{
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400309 struct weston_pointer *pointer;
310
311 pointer = malloc(sizeof *pointer);
312 if (pointer == NULL)
313 return NULL;
314
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400315 memset(pointer, 0, sizeof *pointer);
316 wl_list_init(&pointer->resource_list);
317 pointer->focus_listener.notify = lose_pointer_focus;
318 pointer->default_grab.interface = &default_pointer_grab_interface;
319 pointer->default_grab.pointer = pointer;
320 pointer->grab = &pointer->default_grab;
321 wl_signal_init(&pointer->focus_signal);
322
Kristian Høgsberg195b8692013-05-08 15:02:05 -0400323 pointer->sprite_destroy_listener.notify = pointer_handle_sprite_destroy;
324
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400325 /* FIXME: Pick better co-ords. */
326 pointer->x = wl_fixed_from_int(100);
327 pointer->y = wl_fixed_from_int(100);
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400328
329 return pointer;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400330}
331
332WL_EXPORT void
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400333weston_pointer_destroy(struct weston_pointer *pointer)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400334{
Kristian Høgsberg195b8692013-05-08 15:02:05 -0400335 if (pointer->sprite)
336 pointer_unmap_sprite(pointer);
337
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400338 /* XXX: What about pointer->resource_list? */
339 if (pointer->focus_resource)
340 wl_list_remove(&pointer->focus_listener.link);
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400341 free(pointer);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400342}
343
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400344WL_EXPORT struct weston_keyboard *
345weston_keyboard_create(void)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400346{
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400347 struct weston_keyboard *keyboard;
348
349 keyboard = malloc(sizeof *keyboard);
350 if (keyboard == NULL)
351 return NULL;
352
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400353 memset(keyboard, 0, sizeof *keyboard);
354 wl_list_init(&keyboard->resource_list);
355 wl_array_init(&keyboard->keys);
356 keyboard->focus_listener.notify = lose_keyboard_focus;
357 keyboard->default_grab.interface = &default_keyboard_grab_interface;
358 keyboard->default_grab.keyboard = keyboard;
359 keyboard->grab = &keyboard->default_grab;
360 wl_signal_init(&keyboard->focus_signal);
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400361
362 return keyboard;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400363}
364
365WL_EXPORT void
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400366weston_keyboard_destroy(struct weston_keyboard *keyboard)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400367{
368 /* XXX: What about keyboard->resource_list? */
369 if (keyboard->focus_resource)
370 wl_list_remove(&keyboard->focus_listener.link);
371 wl_array_release(&keyboard->keys);
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400372 free(keyboard);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400373}
374
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400375WL_EXPORT struct weston_touch *
376weston_touch_create(void)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400377{
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400378 struct weston_touch *touch;
379
380 touch = malloc(sizeof *touch);
381 if (touch == NULL)
382 return NULL;
383
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400384 memset(touch, 0, sizeof *touch);
385 wl_list_init(&touch->resource_list);
386 touch->focus_listener.notify = lose_touch_focus;
387 touch->default_grab.interface = &default_touch_grab_interface;
388 touch->default_grab.touch = touch;
389 touch->grab = &touch->default_grab;
390 wl_signal_init(&touch->focus_signal);
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400391
392 return touch;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400393}
394
395WL_EXPORT void
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400396weston_touch_destroy(struct weston_touch *touch)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400397{
398 /* XXX: What about touch->resource_list? */
399 if (touch->focus_resource)
400 wl_list_remove(&touch->focus_listener.link);
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400401 free(touch);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400402}
403
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400404static void
Kristian Høgsberge3148752013-05-06 23:19:49 -0400405seat_send_updated_caps(struct weston_seat *seat)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400406{
Jason Ekstrand44a38632013-06-14 10:08:00 -0500407 struct wl_list *link;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400408 enum wl_seat_capability caps = 0;
409
410 if (seat->pointer)
411 caps |= WL_SEAT_CAPABILITY_POINTER;
412 if (seat->keyboard)
413 caps |= WL_SEAT_CAPABILITY_KEYBOARD;
414 if (seat->touch)
415 caps |= WL_SEAT_CAPABILITY_TOUCH;
416
Jason Ekstrand44a38632013-06-14 10:08:00 -0500417 for (link = seat->base_resource_list.next;
418 link != &seat->base_resource_list; link = link->next) {
419 wl_seat_send_capabilities(wl_resource_from_link(link), caps);
420 }
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400421}
422
423WL_EXPORT void
Kristian Høgsberg02bbabb2013-05-06 22:15:05 -0400424weston_pointer_set_focus(struct weston_pointer *pointer,
Kristian Høgsbergfe7aa902013-05-08 09:54:37 -0400425 struct weston_surface *surface,
Kristian Høgsberg02bbabb2013-05-06 22:15:05 -0400426 wl_fixed_t sx, wl_fixed_t sy)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400427{
Kristian Høgsberg29139d42013-04-18 15:25:39 -0400428 struct weston_keyboard *kbd = pointer->seat->keyboard;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400429 struct wl_resource *resource, *kr;
430 struct wl_display *display;
431 uint32_t serial;
432
433 resource = pointer->focus_resource;
434 if (resource && pointer->focus != surface) {
Jason Ekstrand44a38632013-06-14 10:08:00 -0500435 display = wl_client_get_display(wl_resource_get_client(resource));
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400436 serial = wl_display_next_serial(display);
437 wl_pointer_send_leave(resource, serial,
Jason Ekstrand26ed73c2013-06-06 22:34:41 -0500438 pointer->focus->resource);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400439 wl_list_remove(&pointer->focus_listener.link);
440 }
441
442 resource = find_resource_for_surface(&pointer->resource_list,
443 surface);
444 if (resource &&
445 (pointer->focus != surface ||
446 pointer->focus_resource != resource)) {
Jason Ekstrand44a38632013-06-14 10:08:00 -0500447 display = wl_client_get_display(wl_resource_get_client(resource));
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400448 serial = wl_display_next_serial(display);
449 if (kbd) {
450 kr = find_resource_for_surface(&kbd->resource_list,
451 surface);
452 if (kr) {
453 wl_keyboard_send_modifiers(kr,
454 serial,
455 kbd->modifiers.mods_depressed,
456 kbd->modifiers.mods_latched,
457 kbd->modifiers.mods_locked,
458 kbd->modifiers.group);
459 }
460 }
Jason Ekstrand26ed73c2013-06-06 22:34:41 -0500461 wl_pointer_send_enter(resource, serial, surface->resource,
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400462 sx, sy);
Jason Ekstrand44a38632013-06-14 10:08:00 -0500463 wl_resource_add_destroy_listener(resource,
464 &pointer->focus_listener);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400465 pointer->focus_serial = serial;
466 }
467
468 pointer->focus_resource = resource;
469 pointer->focus = surface;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400470 wl_signal_emit(&pointer->focus_signal, pointer);
471}
472
473WL_EXPORT void
Kristian Høgsberg29139d42013-04-18 15:25:39 -0400474weston_keyboard_set_focus(struct weston_keyboard *keyboard,
Kristian Høgsbergfe7aa902013-05-08 09:54:37 -0400475 struct weston_surface *surface)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400476{
477 struct wl_resource *resource;
478 struct wl_display *display;
479 uint32_t serial;
480
481 if (keyboard->focus_resource && keyboard->focus != surface) {
482 resource = keyboard->focus_resource;
Jason Ekstrand44a38632013-06-14 10:08:00 -0500483 display = wl_client_get_display(wl_resource_get_client(resource));
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400484 serial = wl_display_next_serial(display);
485 wl_keyboard_send_leave(resource, serial,
Jason Ekstrand26ed73c2013-06-06 22:34:41 -0500486 keyboard->focus->resource);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400487 wl_list_remove(&keyboard->focus_listener.link);
488 }
489
490 resource = find_resource_for_surface(&keyboard->resource_list,
491 surface);
492 if (resource &&
493 (keyboard->focus != surface ||
494 keyboard->focus_resource != resource)) {
Jason Ekstrand44a38632013-06-14 10:08:00 -0500495 display = wl_client_get_display(wl_resource_get_client(resource));
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400496 serial = wl_display_next_serial(display);
497 wl_keyboard_send_modifiers(resource, serial,
498 keyboard->modifiers.mods_depressed,
499 keyboard->modifiers.mods_latched,
500 keyboard->modifiers.mods_locked,
501 keyboard->modifiers.group);
Jason Ekstrand26ed73c2013-06-06 22:34:41 -0500502 wl_keyboard_send_enter(resource, serial, surface->resource,
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400503 &keyboard->keys);
Jason Ekstrand44a38632013-06-14 10:08:00 -0500504 wl_resource_add_destroy_listener(resource,
505 &keyboard->focus_listener);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400506 keyboard->focus_serial = serial;
507 }
508
509 keyboard->focus_resource = resource;
510 keyboard->focus = surface;
511 wl_signal_emit(&keyboard->focus_signal, keyboard);
512}
513
514WL_EXPORT void
Kristian Høgsberg29139d42013-04-18 15:25:39 -0400515weston_keyboard_start_grab(struct weston_keyboard *keyboard,
516 struct weston_keyboard_grab *grab)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400517{
518 keyboard->grab = grab;
519 grab->keyboard = keyboard;
520
521 /* XXX focus? */
522}
523
524WL_EXPORT void
Kristian Høgsberg29139d42013-04-18 15:25:39 -0400525weston_keyboard_end_grab(struct weston_keyboard *keyboard)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400526{
527 keyboard->grab = &keyboard->default_grab;
528}
529
530WL_EXPORT void
Kristian Høgsberg02bbabb2013-05-06 22:15:05 -0400531weston_pointer_start_grab(struct weston_pointer *pointer,
532 struct weston_pointer_grab *grab)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400533{
Kristian Høgsberg02bbabb2013-05-06 22:15:05 -0400534 const struct weston_pointer_grab_interface *interface;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400535
536 pointer->grab = grab;
537 interface = pointer->grab->interface;
538 grab->pointer = pointer;
Kristian Høgsberg6848c252013-05-08 22:02:59 -0400539 interface->focus(pointer->grab);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400540}
541
542WL_EXPORT void
Kristian Høgsberg02bbabb2013-05-06 22:15:05 -0400543weston_pointer_end_grab(struct weston_pointer *pointer)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400544{
Kristian Høgsberg02bbabb2013-05-06 22:15:05 -0400545 const struct weston_pointer_grab_interface *interface;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400546
547 pointer->grab = &pointer->default_grab;
548 interface = pointer->grab->interface;
Kristian Høgsberg6848c252013-05-08 22:02:59 -0400549 interface->focus(pointer->grab);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400550}
551
552WL_EXPORT void
Kristian Høgsberge329f362013-05-06 22:19:57 -0400553weston_touch_start_grab(struct weston_touch *touch, struct weston_touch_grab *grab)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400554{
555 touch->grab = grab;
556 grab->touch = touch;
557}
558
559WL_EXPORT void
Kristian Høgsberge329f362013-05-06 22:19:57 -0400560weston_touch_end_grab(struct weston_touch *touch)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400561{
562 touch->grab = &touch->default_grab;
563}
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400564
Rob Bradford806d8c02013-06-25 18:56:41 +0100565WL_EXPORT void
566weston_pointer_clamp(struct weston_pointer *pointer, wl_fixed_t *fx, wl_fixed_t *fy)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400567{
Rob Bradford806d8c02013-06-25 18:56:41 +0100568 struct weston_compositor *ec = pointer->seat->compositor;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400569 struct weston_output *output, *prev = NULL;
570 int x, y, old_x, old_y, valid = 0;
571
572 x = wl_fixed_to_int(*fx);
573 y = wl_fixed_to_int(*fy);
Rob Bradford806d8c02013-06-25 18:56:41 +0100574 old_x = wl_fixed_to_int(pointer->x);
575 old_y = wl_fixed_to_int(pointer->y);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400576
577 wl_list_for_each(output, &ec->output_list, link) {
Rob Bradford66bd9f52013-06-25 18:56:42 +0100578 if (pointer->seat->output && pointer->seat->output != output)
579 continue;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400580 if (pixman_region32_contains_point(&output->region,
581 x, y, NULL))
582 valid = 1;
583 if (pixman_region32_contains_point(&output->region,
584 old_x, old_y, NULL))
585 prev = output;
586 }
587
Rob Bradford66bd9f52013-06-25 18:56:42 +0100588 if (!prev)
589 prev = pointer->seat->output;
590
591 if (prev && !valid) {
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400592 if (x < prev->x)
593 *fx = wl_fixed_from_int(prev->x);
594 else if (x >= prev->x + prev->width)
595 *fx = wl_fixed_from_int(prev->x +
596 prev->width - 1);
597 if (y < prev->y)
598 *fy = wl_fixed_from_int(prev->y);
Alexander Larssonbcd18d92013-05-28 16:23:33 +0200599 else if (y >= prev->y + prev->height)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400600 *fy = wl_fixed_from_int(prev->y +
601 prev->height - 1);
602 }
603}
604
605/* Takes absolute values */
606static void
607move_pointer(struct weston_seat *seat, wl_fixed_t x, wl_fixed_t y)
608{
609 struct weston_compositor *ec = seat->compositor;
Kristian Høgsberge3148752013-05-06 23:19:49 -0400610 struct weston_pointer *pointer = seat->pointer;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400611 struct weston_output *output;
612 int32_t ix, iy;
613
Rob Bradford806d8c02013-06-25 18:56:41 +0100614 weston_pointer_clamp (pointer, &x, &y);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400615
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400616 pointer->x = x;
617 pointer->y = y;
618
619 ix = wl_fixed_to_int(x);
620 iy = wl_fixed_to_int(y);
621
622 wl_list_for_each(output, &ec->output_list, link)
623 if (output->zoom.active &&
624 pixman_region32_contains_point(&output->region,
625 ix, iy, NULL))
626 weston_output_update_zoom(output, ZOOM_FOCUS_POINTER);
627
Kristian Høgsberg195b8692013-05-08 15:02:05 -0400628 if (pointer->sprite) {
629 weston_surface_set_position(pointer->sprite,
630 ix - pointer->hotspot_x,
631 iy - pointer->hotspot_y);
632 weston_surface_schedule_repaint(pointer->sprite);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400633 }
634}
635
636WL_EXPORT void
637notify_motion(struct weston_seat *seat,
638 uint32_t time, wl_fixed_t dx, wl_fixed_t dy)
639{
Kristian Høgsberg02bbabb2013-05-06 22:15:05 -0400640 const struct weston_pointer_grab_interface *interface;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400641 struct weston_compositor *ec = seat->compositor;
Kristian Høgsberge3148752013-05-06 23:19:49 -0400642 struct weston_pointer *pointer = seat->pointer;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400643
644 weston_compositor_wake(ec);
645
646 move_pointer(seat, pointer->x + dx, pointer->y + dy);
647
648 interface = pointer->grab->interface;
Kristian Høgsberg6848c252013-05-08 22:02:59 -0400649 interface->focus(pointer->grab);
Kristian Høgsbergbe6403e2013-05-08 21:03:21 -0400650 interface->motion(pointer->grab, time);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400651}
652
653WL_EXPORT void
654notify_motion_absolute(struct weston_seat *seat,
655 uint32_t time, wl_fixed_t x, wl_fixed_t y)
656{
Kristian Høgsberg02bbabb2013-05-06 22:15:05 -0400657 const struct weston_pointer_grab_interface *interface;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400658 struct weston_compositor *ec = seat->compositor;
Kristian Høgsberge3148752013-05-06 23:19:49 -0400659 struct weston_pointer *pointer = seat->pointer;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400660
661 weston_compositor_wake(ec);
662
663 move_pointer(seat, x, y);
664
665 interface = pointer->grab->interface;
Kristian Høgsberg6848c252013-05-08 22:02:59 -0400666 interface->focus(pointer->grab);
Kristian Høgsbergbe6403e2013-05-08 21:03:21 -0400667 interface->motion(pointer->grab, time);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400668}
669
670WL_EXPORT void
671weston_surface_activate(struct weston_surface *surface,
672 struct weston_seat *seat)
673{
674 struct weston_compositor *compositor = seat->compositor;
675
Kristian Høgsberge3148752013-05-06 23:19:49 -0400676 if (seat->keyboard) {
Kristian Høgsbergfe7aa902013-05-08 09:54:37 -0400677 weston_keyboard_set_focus(seat->keyboard, surface);
Kristian Høgsberge3148752013-05-06 23:19:49 -0400678 wl_data_device_set_keyboard_focus(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400679 }
680
681 wl_signal_emit(&compositor->activate_signal, surface);
682}
683
684WL_EXPORT void
685notify_button(struct weston_seat *seat, uint32_t time, int32_t button,
686 enum wl_pointer_button_state state)
687{
688 struct weston_compositor *compositor = seat->compositor;
Kristian Høgsberge3148752013-05-06 23:19:49 -0400689 struct weston_pointer *pointer = seat->pointer;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400690 struct weston_surface *focus =
691 (struct weston_surface *) pointer->focus;
692 uint32_t serial = wl_display_next_serial(compositor->wl_display);
693
694 if (state == WL_POINTER_BUTTON_STATE_PRESSED) {
695 if (compositor->ping_handler && focus)
696 compositor->ping_handler(focus, serial);
697 weston_compositor_idle_inhibit(compositor);
698 if (pointer->button_count == 0) {
699 pointer->grab_button = button;
700 pointer->grab_time = time;
701 pointer->grab_x = pointer->x;
702 pointer->grab_y = pointer->y;
703 }
704 pointer->button_count++;
705 } else {
706 weston_compositor_idle_release(compositor);
707 pointer->button_count--;
708 }
709
710 weston_compositor_run_button_binding(compositor, seat, time, button,
711 state);
712
713 pointer->grab->interface->button(pointer->grab, time, button, state);
714
715 if (pointer->button_count == 1)
716 pointer->grab_serial =
717 wl_display_get_serial(compositor->wl_display);
718}
719
720WL_EXPORT void
721notify_axis(struct weston_seat *seat, uint32_t time, uint32_t axis,
722 wl_fixed_t value)
723{
724 struct weston_compositor *compositor = seat->compositor;
Kristian Høgsberge3148752013-05-06 23:19:49 -0400725 struct weston_pointer *pointer = seat->pointer;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400726 struct weston_surface *focus =
727 (struct weston_surface *) pointer->focus;
728 uint32_t serial = wl_display_next_serial(compositor->wl_display);
729
730 if (compositor->ping_handler && focus)
731 compositor->ping_handler(focus, serial);
732
733 weston_compositor_wake(compositor);
734
735 if (!value)
736 return;
737
738 if (weston_compositor_run_axis_binding(compositor, seat,
739 time, axis, value))
740 return;
741
742 if (pointer->focus_resource)
743 wl_pointer_send_axis(pointer->focus_resource, time, axis,
744 value);
745}
746
Rob Bradford382ff462013-06-24 16:52:45 +0100747#ifdef ENABLE_XKBCOMMON
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400748WL_EXPORT void
749notify_modifiers(struct weston_seat *seat, uint32_t serial)
750{
Kristian Høgsberge3148752013-05-06 23:19:49 -0400751 struct weston_keyboard *keyboard = seat->keyboard;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400752 struct weston_keyboard_grab *grab = keyboard->grab;
753 uint32_t mods_depressed, mods_latched, mods_locked, group;
754 uint32_t mods_lookup;
755 enum weston_led leds = 0;
756 int changed = 0;
757
758 /* Serialize and update our internal state, checking to see if it's
759 * different to the previous state. */
760 mods_depressed = xkb_state_serialize_mods(seat->xkb_state.state,
761 XKB_STATE_DEPRESSED);
762 mods_latched = xkb_state_serialize_mods(seat->xkb_state.state,
763 XKB_STATE_LATCHED);
764 mods_locked = xkb_state_serialize_mods(seat->xkb_state.state,
765 XKB_STATE_LOCKED);
766 group = xkb_state_serialize_group(seat->xkb_state.state,
767 XKB_STATE_EFFECTIVE);
768
Kristian Høgsberge3148752013-05-06 23:19:49 -0400769 if (mods_depressed != seat->keyboard->modifiers.mods_depressed ||
770 mods_latched != seat->keyboard->modifiers.mods_latched ||
771 mods_locked != seat->keyboard->modifiers.mods_locked ||
772 group != seat->keyboard->modifiers.group)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400773 changed = 1;
774
Kristian Høgsberge3148752013-05-06 23:19:49 -0400775 seat->keyboard->modifiers.mods_depressed = mods_depressed;
776 seat->keyboard->modifiers.mods_latched = mods_latched;
777 seat->keyboard->modifiers.mods_locked = mods_locked;
778 seat->keyboard->modifiers.group = group;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400779
780 /* And update the modifier_state for bindings. */
781 mods_lookup = mods_depressed | mods_latched;
782 seat->modifier_state = 0;
783 if (mods_lookup & (1 << seat->xkb_info.ctrl_mod))
784 seat->modifier_state |= MODIFIER_CTRL;
785 if (mods_lookup & (1 << seat->xkb_info.alt_mod))
786 seat->modifier_state |= MODIFIER_ALT;
787 if (mods_lookup & (1 << seat->xkb_info.super_mod))
788 seat->modifier_state |= MODIFIER_SUPER;
789 if (mods_lookup & (1 << seat->xkb_info.shift_mod))
790 seat->modifier_state |= MODIFIER_SHIFT;
791
792 /* Finally, notify the compositor that LEDs have changed. */
793 if (xkb_state_led_index_is_active(seat->xkb_state.state,
794 seat->xkb_info.num_led))
795 leds |= LED_NUM_LOCK;
796 if (xkb_state_led_index_is_active(seat->xkb_state.state,
797 seat->xkb_info.caps_led))
798 leds |= LED_CAPS_LOCK;
799 if (xkb_state_led_index_is_active(seat->xkb_state.state,
800 seat->xkb_info.scroll_led))
801 leds |= LED_SCROLL_LOCK;
802 if (leds != seat->xkb_state.leds && seat->led_update)
803 seat->led_update(seat, leds);
804 seat->xkb_state.leds = leds;
805
806 if (changed) {
807 grab->interface->modifiers(grab,
808 serial,
809 keyboard->modifiers.mods_depressed,
810 keyboard->modifiers.mods_latched,
811 keyboard->modifiers.mods_locked,
812 keyboard->modifiers.group);
813 }
814}
815
816static void
817update_modifier_state(struct weston_seat *seat, uint32_t serial, uint32_t key,
818 enum wl_keyboard_key_state state)
819{
820 enum xkb_key_direction direction;
821
Matt Roper01a92732013-06-24 16:52:44 +0100822 /* Keyboard modifiers don't exist in raw keyboard mode */
823 if (!seat->compositor->use_xkbcommon)
824 return;
825
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400826 if (state == WL_KEYBOARD_KEY_STATE_PRESSED)
827 direction = XKB_KEY_DOWN;
828 else
829 direction = XKB_KEY_UP;
830
831 /* Offset the keycode by 8, as the evdev XKB rules reflect X's
832 * broken keycode system, which starts at 8. */
833 xkb_state_update_key(seat->xkb_state.state, key + 8, direction);
834
835 notify_modifiers(seat, serial);
836}
Rob Bradford382ff462013-06-24 16:52:45 +0100837#else
838WL_EXPORT void
839notify_modifiers(struct weston_seat *seat, uint32_t serial)
840{
841}
842
843static void
844update_modifier_state(struct weston_seat *seat, uint32_t serial, uint32_t key,
845 enum wl_keyboard_key_state state)
846{
847}
848#endif
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400849
850WL_EXPORT void
851notify_key(struct weston_seat *seat, uint32_t time, uint32_t key,
852 enum wl_keyboard_key_state state,
853 enum weston_key_state_update update_state)
854{
855 struct weston_compositor *compositor = seat->compositor;
Kristian Høgsberge3148752013-05-06 23:19:49 -0400856 struct weston_keyboard *keyboard = seat->keyboard;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400857 struct weston_surface *focus =
858 (struct weston_surface *) keyboard->focus;
859 struct weston_keyboard_grab *grab = keyboard->grab;
860 uint32_t serial = wl_display_next_serial(compositor->wl_display);
861 uint32_t *k, *end;
862
863 if (state == WL_KEYBOARD_KEY_STATE_PRESSED) {
864 if (compositor->ping_handler && focus)
865 compositor->ping_handler(focus, serial);
866
867 weston_compositor_idle_inhibit(compositor);
868 keyboard->grab_key = key;
869 keyboard->grab_time = time;
870 } else {
871 weston_compositor_idle_release(compositor);
872 }
873
874 end = keyboard->keys.data + keyboard->keys.size;
875 for (k = keyboard->keys.data; k < end; k++) {
876 if (*k == key) {
877 /* Ignore server-generated repeats. */
878 if (state == WL_KEYBOARD_KEY_STATE_PRESSED)
879 return;
880 *k = *--end;
881 }
882 }
883 keyboard->keys.size = (void *) end - keyboard->keys.data;
884 if (state == WL_KEYBOARD_KEY_STATE_PRESSED) {
885 k = wl_array_add(&keyboard->keys, sizeof *k);
886 *k = key;
887 }
888
889 if (grab == &keyboard->default_grab ||
890 grab == &keyboard->input_method_grab) {
891 weston_compositor_run_key_binding(compositor, seat, time, key,
892 state);
893 grab = keyboard->grab;
894 }
895
896 grab->interface->key(grab, time, key, state);
897
898 if (update_state == STATE_UPDATE_AUTOMATIC) {
899 update_modifier_state(seat,
900 wl_display_get_serial(compositor->wl_display),
901 key,
902 state);
903 }
904}
905
906WL_EXPORT void
907notify_pointer_focus(struct weston_seat *seat, struct weston_output *output,
908 wl_fixed_t x, wl_fixed_t y)
909{
910 struct weston_compositor *compositor = seat->compositor;
911
912 if (output) {
913 move_pointer(seat, x, y);
914 compositor->focus = 1;
915 } else {
916 compositor->focus = 0;
Kristian Høgsberg02bbabb2013-05-06 22:15:05 -0400917 /* FIXME: We should call weston_pointer_set_focus(seat,
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400918 * NULL) here, but somehow that breaks re-entry... */
919 }
920}
921
922static void
923destroy_device_saved_kbd_focus(struct wl_listener *listener, void *data)
924{
925 struct weston_seat *ws;
926
927 ws = container_of(listener, struct weston_seat,
928 saved_kbd_focus_listener);
929
930 ws->saved_kbd_focus = NULL;
931}
932
933WL_EXPORT void
934notify_keyboard_focus_in(struct weston_seat *seat, struct wl_array *keys,
935 enum weston_key_state_update update_state)
936{
937 struct weston_compositor *compositor = seat->compositor;
Kristian Høgsberge3148752013-05-06 23:19:49 -0400938 struct weston_keyboard *keyboard = seat->keyboard;
Kristian Høgsbergfe7aa902013-05-08 09:54:37 -0400939 struct weston_surface *surface;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400940 uint32_t *k, serial;
941
942 serial = wl_display_next_serial(compositor->wl_display);
943 wl_array_copy(&keyboard->keys, keys);
944 wl_array_for_each(k, &keyboard->keys) {
945 weston_compositor_idle_inhibit(compositor);
946 if (update_state == STATE_UPDATE_AUTOMATIC)
947 update_modifier_state(seat, serial, *k,
948 WL_KEYBOARD_KEY_STATE_PRESSED);
949 }
950
951 /* Run key bindings after we've updated the state. */
952 wl_array_for_each(k, &keyboard->keys) {
953 weston_compositor_run_key_binding(compositor, seat, 0, *k,
954 WL_KEYBOARD_KEY_STATE_PRESSED);
955 }
956
957 surface = seat->saved_kbd_focus;
958
959 if (surface) {
960 wl_list_remove(&seat->saved_kbd_focus_listener.link);
961 weston_keyboard_set_focus(keyboard, surface);
962 seat->saved_kbd_focus = NULL;
963 }
964}
965
966WL_EXPORT void
967notify_keyboard_focus_out(struct weston_seat *seat)
968{
969 struct weston_compositor *compositor = seat->compositor;
Kristian Høgsberge3148752013-05-06 23:19:49 -0400970 struct weston_keyboard *keyboard = seat->keyboard;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400971 uint32_t *k, serial;
972
973 serial = wl_display_next_serial(compositor->wl_display);
974 wl_array_for_each(k, &keyboard->keys) {
975 weston_compositor_idle_release(compositor);
976 update_modifier_state(seat, serial, *k,
977 WL_KEYBOARD_KEY_STATE_RELEASED);
978 }
979
980 seat->modifier_state = 0;
981
982 if (keyboard->focus) {
983 seat->saved_kbd_focus = keyboard->focus;
984 seat->saved_kbd_focus_listener.notify =
985 destroy_device_saved_kbd_focus;
Jason Ekstrand26ed73c2013-06-06 22:34:41 -0500986 wl_signal_add(&keyboard->focus->destroy_signal,
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400987 &seat->saved_kbd_focus_listener);
988 }
989
990 weston_keyboard_set_focus(keyboard, NULL);
991 /* FIXME: We really need keyboard grab cancel here to
992 * let the grab shut down properly. As it is we leak
993 * the grab data. */
994 weston_keyboard_end_grab(keyboard);
995}
996
997static void
Kristian Høgsbergfe7aa902013-05-08 09:54:37 -0400998touch_set_focus(struct weston_seat *seat, struct weston_surface *surface)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400999{
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001000 struct wl_resource *resource;
1001
1002 if (seat->touch->focus == surface)
1003 return;
1004
1005 if (seat->touch->focus_resource)
1006 wl_list_remove(&seat->touch->focus_listener.link);
1007 seat->touch->focus = NULL;
1008 seat->touch->focus_resource = NULL;
1009
1010 if (surface) {
1011 resource =
Kristian Høgsberg80fb82d2013-05-06 21:49:55 -04001012 find_resource_for_surface(&seat->touch->resource_list,
1013 surface);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001014 if (!resource) {
1015 weston_log("couldn't find resource\n");
1016 return;
1017 }
1018
1019 seat->touch->focus = surface;
1020 seat->touch->focus_resource = resource;
Jason Ekstrand44a38632013-06-14 10:08:00 -05001021 wl_resource_add_destroy_listener(resource,
1022 &seat->touch->focus_listener);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001023 }
1024}
1025
1026/**
1027 * notify_touch - emulates button touches and notifies surfaces accordingly.
1028 *
1029 * It assumes always the correct cycle sequence until it gets here: touch_down
1030 * → touch_update → ... → touch_update → touch_end. The driver is responsible
1031 * for sending along such order.
1032 *
1033 */
1034WL_EXPORT void
1035notify_touch(struct weston_seat *seat, uint32_t time, int touch_id,
1036 wl_fixed_t x, wl_fixed_t y, int touch_type)
1037{
1038 struct weston_compositor *ec = seat->compositor;
Kristian Høgsberge3148752013-05-06 23:19:49 -04001039 struct weston_touch *touch = seat->touch;
Kristian Høgsberge329f362013-05-06 22:19:57 -04001040 struct weston_touch_grab *grab = touch->grab;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001041 struct weston_surface *es;
1042 wl_fixed_t sx, sy;
1043
1044 /* Update grab's global coordinates. */
1045 touch->grab_x = x;
1046 touch->grab_y = y;
1047
1048 switch (touch_type) {
1049 case WL_TOUCH_DOWN:
1050 weston_compositor_idle_inhibit(ec);
1051
1052 seat->num_tp++;
1053
1054 /* the first finger down picks the surface, and all further go
1055 * to that surface for the remainder of the touch session i.e.
1056 * until all touch points are up again. */
1057 if (seat->num_tp == 1) {
1058 es = weston_compositor_pick_surface(ec, x, y, &sx, &sy);
Kristian Høgsbergfe7aa902013-05-08 09:54:37 -04001059 touch_set_focus(seat, es);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001060 } else if (touch->focus) {
1061 es = (struct weston_surface *) touch->focus;
1062 weston_surface_from_global_fixed(es, x, y, &sx, &sy);
1063 } else {
1064 /* Unexpected condition: We have non-initial touch but
1065 * there is no focused surface.
1066 */
1067 weston_log("touch event received with %d points down"
1068 "but no surface focused\n", seat->num_tp);
1069 return;
1070 }
1071
1072 grab->interface->down(grab, time, touch_id, sx, sy);
1073 break;
1074 case WL_TOUCH_MOTION:
1075 es = (struct weston_surface *) touch->focus;
1076 if (!es)
1077 break;
1078
1079 weston_surface_from_global_fixed(es, x, y, &sx, &sy);
1080 grab->interface->motion(grab, time, touch_id, sx, sy);
1081 break;
1082 case WL_TOUCH_UP:
1083 weston_compositor_idle_release(ec);
1084 seat->num_tp--;
1085
1086 grab->interface->up(grab, time, touch_id);
1087 if (seat->num_tp == 0)
1088 touch_set_focus(seat, NULL);
1089 break;
1090 }
1091}
1092
1093static void
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001094pointer_cursor_surface_configure(struct weston_surface *es,
1095 int32_t dx, int32_t dy, int32_t width, int32_t height)
1096{
Kristian Høgsberg195b8692013-05-08 15:02:05 -04001097 struct weston_pointer *pointer = es->configure_private;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001098 int x, y;
1099
1100 if (width == 0)
1101 return;
1102
Kristian Høgsberg195b8692013-05-08 15:02:05 -04001103 assert(es == pointer->sprite);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001104
Kristian Høgsberg195b8692013-05-08 15:02:05 -04001105 pointer->hotspot_x -= dx;
1106 pointer->hotspot_y -= dy;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001107
Kristian Høgsberg195b8692013-05-08 15:02:05 -04001108 x = wl_fixed_to_int(pointer->x) - pointer->hotspot_x;
1109 y = wl_fixed_to_int(pointer->y) - pointer->hotspot_y;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001110
Kristian Høgsberg195b8692013-05-08 15:02:05 -04001111 weston_surface_configure(pointer->sprite, x, y, width, height);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001112
1113 empty_region(&es->pending.input);
1114
1115 if (!weston_surface_is_mapped(es)) {
1116 wl_list_insert(&es->compositor->cursor_layer.surface_list,
1117 &es->layer_link);
1118 weston_surface_update_transform(es);
1119 }
1120}
1121
1122static void
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001123pointer_set_cursor(struct wl_client *client, struct wl_resource *resource,
1124 uint32_t serial, struct wl_resource *surface_resource,
1125 int32_t x, int32_t y)
1126{
Jason Ekstrand44a38632013-06-14 10:08:00 -05001127 struct weston_pointer *pointer = wl_resource_get_user_data(resource);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001128 struct weston_surface *surface = NULL;
1129
1130 if (surface_resource)
Jason Ekstrand0f2ef7e2013-06-14 10:07:53 -05001131 surface = wl_resource_get_user_data(surface_resource);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001132
Kristian Høgsberg195b8692013-05-08 15:02:05 -04001133 if (pointer->focus == NULL)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001134 return;
Giulio Camuffo1fd4b012013-06-20 18:13:07 +02001135 /* pointer->focus->resource can be NULL. Surfaces like the
1136 black_surface used in shell.c for fullscreen don't have
1137 a resource, but can still have focus */
1138 if (pointer->focus->resource == NULL)
1139 return;
Jason Ekstrand26ed73c2013-06-06 22:34:41 -05001140 if (wl_resource_get_client(pointer->focus->resource) != client)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001141 return;
Kristian Høgsberg195b8692013-05-08 15:02:05 -04001142 if (pointer->focus_serial - serial > UINT32_MAX / 2)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001143 return;
1144
Kristian Høgsberg195b8692013-05-08 15:02:05 -04001145 if (surface && surface != pointer->sprite) {
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001146 if (surface->configure) {
Jason Ekstrand26ed73c2013-06-06 22:34:41 -05001147 wl_resource_post_error(surface->resource,
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001148 WL_DISPLAY_ERROR_INVALID_OBJECT,
1149 "surface->configure already "
1150 "set");
1151 return;
1152 }
1153 }
1154
Kristian Høgsberg195b8692013-05-08 15:02:05 -04001155 if (pointer->sprite)
1156 pointer_unmap_sprite(pointer);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001157
1158 if (!surface)
1159 return;
1160
Jason Ekstrand26ed73c2013-06-06 22:34:41 -05001161 wl_signal_add(&surface->destroy_signal,
Kristian Høgsberg195b8692013-05-08 15:02:05 -04001162 &pointer->sprite_destroy_listener);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001163
1164 surface->configure = pointer_cursor_surface_configure;
Kristian Høgsberg195b8692013-05-08 15:02:05 -04001165 surface->configure_private = pointer;
1166 pointer->sprite = surface;
1167 pointer->hotspot_x = x;
1168 pointer->hotspot_y = y;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001169
1170 if (surface->buffer_ref.buffer)
1171 pointer_cursor_surface_configure(surface, 0, 0, weston_surface_buffer_width(surface),
1172 weston_surface_buffer_height(surface));
1173}
1174
1175static const struct wl_pointer_interface pointer_interface = {
1176 pointer_set_cursor
1177};
1178
1179static void
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001180seat_get_pointer(struct wl_client *client, struct wl_resource *resource,
1181 uint32_t id)
1182{
Jason Ekstrand44a38632013-06-14 10:08:00 -05001183 struct weston_seat *seat = wl_resource_get_user_data(resource);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001184 struct wl_resource *cr;
1185
Kristian Høgsberge3148752013-05-06 23:19:49 -04001186 if (!seat->pointer)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001187 return;
1188
1189 cr = wl_client_add_object(client, &wl_pointer_interface,
Kristian Høgsberg195b8692013-05-08 15:02:05 -04001190 &pointer_interface, id, seat->pointer);
Jason Ekstrand44a38632013-06-14 10:08:00 -05001191 wl_list_insert(&seat->pointer->resource_list, wl_resource_get_link(cr));
1192 wl_resource_set_destructor(cr, unbind_resource);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001193
Kristian Høgsberge3148752013-05-06 23:19:49 -04001194 if (seat->pointer->focus &&
Jason Ekstrand26ed73c2013-06-06 22:34:41 -05001195 wl_resource_get_client(seat->pointer->focus->resource) == client) {
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001196 struct weston_surface *surface;
1197 wl_fixed_t sx, sy;
1198
Kristian Høgsberge3148752013-05-06 23:19:49 -04001199 surface = (struct weston_surface *) seat->pointer->focus;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001200 weston_surface_from_global_fixed(surface,
Kristian Høgsberge3148752013-05-06 23:19:49 -04001201 seat->pointer->x,
1202 seat->pointer->y,
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001203 &sx,
1204 &sy);
Kristian Høgsberge3148752013-05-06 23:19:49 -04001205 weston_pointer_set_focus(seat->pointer,
1206 seat->pointer->focus,
Kristian Høgsberg02bbabb2013-05-06 22:15:05 -04001207 sx,
1208 sy);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001209 }
1210}
1211
1212static void
1213seat_get_keyboard(struct wl_client *client, struct wl_resource *resource,
1214 uint32_t id)
1215{
Jason Ekstrand44a38632013-06-14 10:08:00 -05001216 struct weston_seat *seat = wl_resource_get_user_data(resource);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001217 struct wl_resource *cr;
1218
Kristian Høgsberge3148752013-05-06 23:19:49 -04001219 if (!seat->keyboard)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001220 return;
1221
1222 cr = wl_client_add_object(client, &wl_keyboard_interface, NULL, id,
1223 seat);
Jason Ekstrand44a38632013-06-14 10:08:00 -05001224 wl_list_insert(&seat->keyboard->resource_list, wl_resource_get_link(cr));
1225 wl_resource_set_destructor(cr, unbind_resource);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001226
Matt Roper01a92732013-06-24 16:52:44 +01001227 if (seat->compositor->use_xkbcommon) {
1228 wl_keyboard_send_keymap(cr, WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1,
1229 seat->xkb_info.keymap_fd,
1230 seat->xkb_info.keymap_size);
1231 } else {
1232 int null_fd = open("/dev/null", O_RDONLY);
1233 wl_keyboard_send_keymap(cr, WL_KEYBOARD_KEYMAP_FORMAT_NO_KEYMAP,
1234 null_fd,
1235 0);
1236 close(null_fd);
1237 }
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001238
Kristian Høgsberge3148752013-05-06 23:19:49 -04001239 if (seat->keyboard->focus &&
Jason Ekstrand26ed73c2013-06-06 22:34:41 -05001240 wl_resource_get_client(seat->keyboard->focus->resource) == client) {
Kristian Høgsberge3148752013-05-06 23:19:49 -04001241 weston_keyboard_set_focus(seat->keyboard,
1242 seat->keyboard->focus);
1243 wl_data_device_set_keyboard_focus(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001244 }
1245}
1246
1247static void
1248seat_get_touch(struct wl_client *client, struct wl_resource *resource,
1249 uint32_t id)
1250{
Jason Ekstrand44a38632013-06-14 10:08:00 -05001251 struct weston_seat *seat = wl_resource_get_user_data(resource);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001252 struct wl_resource *cr;
1253
Kristian Høgsberge3148752013-05-06 23:19:49 -04001254 if (!seat->touch)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001255 return;
1256
1257 cr = wl_client_add_object(client, &wl_touch_interface, NULL, id, seat);
Jason Ekstrand44a38632013-06-14 10:08:00 -05001258 wl_list_insert(&seat->touch->resource_list, wl_resource_get_link(cr));
1259 wl_resource_set_destructor(cr, unbind_resource);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001260}
1261
1262static const struct wl_seat_interface seat_interface = {
1263 seat_get_pointer,
1264 seat_get_keyboard,
1265 seat_get_touch,
1266};
1267
1268static void
1269bind_seat(struct wl_client *client, void *data, uint32_t version, uint32_t id)
1270{
Kristian Høgsberge3148752013-05-06 23:19:49 -04001271 struct weston_seat *seat = data;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001272 struct wl_resource *resource;
1273 enum wl_seat_capability caps = 0;
1274
1275 resource = wl_client_add_object(client, &wl_seat_interface,
1276 &seat_interface, id, data);
Jason Ekstrand44a38632013-06-14 10:08:00 -05001277 wl_list_insert(&seat->base_resource_list, wl_resource_get_link(resource));
1278 wl_resource_set_destructor(resource, unbind_resource);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001279
1280 if (seat->pointer)
1281 caps |= WL_SEAT_CAPABILITY_POINTER;
1282 if (seat->keyboard)
1283 caps |= WL_SEAT_CAPABILITY_KEYBOARD;
1284 if (seat->touch)
1285 caps |= WL_SEAT_CAPABILITY_TOUCH;
1286
1287 wl_seat_send_capabilities(resource, caps);
Rob Bradforde445ae62013-05-31 18:09:51 +01001288 if (version >= 2)
1289 wl_seat_send_name(resource, seat->seat_name);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001290}
1291
Rob Bradford382ff462013-06-24 16:52:45 +01001292#ifdef ENABLE_XKBCOMMON
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001293int
1294weston_compositor_xkb_init(struct weston_compositor *ec,
1295 struct xkb_rule_names *names)
1296{
Rob Bradford382ff462013-06-24 16:52:45 +01001297 ec->use_xkbcommon = 1;
Matt Roper01a92732013-06-24 16:52:44 +01001298
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001299 if (ec->xkb_context == NULL) {
1300 ec->xkb_context = xkb_context_new(0);
1301 if (ec->xkb_context == NULL) {
1302 weston_log("failed to create XKB context\n");
1303 return -1;
1304 }
1305 }
1306
1307 if (names)
1308 ec->xkb_names = *names;
1309 if (!ec->xkb_names.rules)
1310 ec->xkb_names.rules = strdup("evdev");
1311 if (!ec->xkb_names.model)
1312 ec->xkb_names.model = strdup("pc105");
1313 if (!ec->xkb_names.layout)
1314 ec->xkb_names.layout = strdup("us");
1315
1316 return 0;
1317}
1318
1319static void xkb_info_destroy(struct weston_xkb_info *xkb_info)
1320{
1321 if (xkb_info->keymap)
1322 xkb_map_unref(xkb_info->keymap);
1323
1324 if (xkb_info->keymap_area)
1325 munmap(xkb_info->keymap_area, xkb_info->keymap_size);
1326 if (xkb_info->keymap_fd >= 0)
1327 close(xkb_info->keymap_fd);
1328}
1329
1330void
1331weston_compositor_xkb_destroy(struct weston_compositor *ec)
1332{
Matt Roper01a92732013-06-24 16:52:44 +01001333 /*
1334 * If we're operating in raw keyboard mode, we never initialized
1335 * libxkbcommon so there's no cleanup to do either.
1336 */
1337 if (!ec->use_xkbcommon)
1338 return;
1339
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001340 free((char *) ec->xkb_names.rules);
1341 free((char *) ec->xkb_names.model);
1342 free((char *) ec->xkb_names.layout);
1343 free((char *) ec->xkb_names.variant);
1344 free((char *) ec->xkb_names.options);
1345
1346 xkb_info_destroy(&ec->xkb_info);
1347 xkb_context_unref(ec->xkb_context);
1348}
1349
1350static int
1351weston_xkb_info_new_keymap(struct weston_xkb_info *xkb_info)
1352{
1353 char *keymap_str;
1354
1355 xkb_info->shift_mod = xkb_map_mod_get_index(xkb_info->keymap,
1356 XKB_MOD_NAME_SHIFT);
1357 xkb_info->caps_mod = xkb_map_mod_get_index(xkb_info->keymap,
1358 XKB_MOD_NAME_CAPS);
1359 xkb_info->ctrl_mod = xkb_map_mod_get_index(xkb_info->keymap,
1360 XKB_MOD_NAME_CTRL);
1361 xkb_info->alt_mod = xkb_map_mod_get_index(xkb_info->keymap,
1362 XKB_MOD_NAME_ALT);
1363 xkb_info->mod2_mod = xkb_map_mod_get_index(xkb_info->keymap, "Mod2");
1364 xkb_info->mod3_mod = xkb_map_mod_get_index(xkb_info->keymap, "Mod3");
1365 xkb_info->super_mod = xkb_map_mod_get_index(xkb_info->keymap,
1366 XKB_MOD_NAME_LOGO);
1367 xkb_info->mod5_mod = xkb_map_mod_get_index(xkb_info->keymap, "Mod5");
1368
1369 xkb_info->num_led = xkb_map_led_get_index(xkb_info->keymap,
1370 XKB_LED_NAME_NUM);
1371 xkb_info->caps_led = xkb_map_led_get_index(xkb_info->keymap,
1372 XKB_LED_NAME_CAPS);
1373 xkb_info->scroll_led = xkb_map_led_get_index(xkb_info->keymap,
1374 XKB_LED_NAME_SCROLL);
1375
1376 keymap_str = xkb_map_get_as_string(xkb_info->keymap);
1377 if (keymap_str == NULL) {
1378 weston_log("failed to get string version of keymap\n");
1379 return -1;
1380 }
1381 xkb_info->keymap_size = strlen(keymap_str) + 1;
1382
1383 xkb_info->keymap_fd = os_create_anonymous_file(xkb_info->keymap_size);
1384 if (xkb_info->keymap_fd < 0) {
1385 weston_log("creating a keymap file for %lu bytes failed: %m\n",
1386 (unsigned long) xkb_info->keymap_size);
1387 goto err_keymap_str;
1388 }
1389
1390 xkb_info->keymap_area = mmap(NULL, xkb_info->keymap_size,
1391 PROT_READ | PROT_WRITE,
1392 MAP_SHARED, xkb_info->keymap_fd, 0);
1393 if (xkb_info->keymap_area == MAP_FAILED) {
1394 weston_log("failed to mmap() %lu bytes\n",
1395 (unsigned long) xkb_info->keymap_size);
1396 goto err_dev_zero;
1397 }
1398 strcpy(xkb_info->keymap_area, keymap_str);
1399 free(keymap_str);
1400
1401 return 0;
1402
1403err_dev_zero:
1404 close(xkb_info->keymap_fd);
1405 xkb_info->keymap_fd = -1;
1406err_keymap_str:
1407 free(keymap_str);
1408 return -1;
1409}
1410
1411static int
1412weston_compositor_build_global_keymap(struct weston_compositor *ec)
1413{
1414 if (ec->xkb_info.keymap != NULL)
1415 return 0;
1416
1417 ec->xkb_info.keymap = xkb_map_new_from_names(ec->xkb_context,
1418 &ec->xkb_names,
1419 0);
1420 if (ec->xkb_info.keymap == NULL) {
1421 weston_log("failed to compile global XKB keymap\n");
1422 weston_log(" tried rules %s, model %s, layout %s, variant %s, "
1423 "options %s\n",
1424 ec->xkb_names.rules, ec->xkb_names.model,
1425 ec->xkb_names.layout, ec->xkb_names.variant,
1426 ec->xkb_names.options);
1427 return -1;
1428 }
1429
1430 if (weston_xkb_info_new_keymap(&ec->xkb_info) < 0)
1431 return -1;
1432
1433 return 0;
1434}
Rob Bradford382ff462013-06-24 16:52:45 +01001435#else
1436int
1437weston_compositor_xkb_init(struct weston_compositor *ec,
1438 struct xkb_rule_names *names)
1439{
1440 return 0;
1441}
1442
1443void
1444weston_compositor_xkb_destroy(struct weston_compositor *ec)
1445{
1446}
1447#endif
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001448
1449WL_EXPORT int
1450weston_seat_init_keyboard(struct weston_seat *seat, struct xkb_keymap *keymap)
1451{
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04001452 struct weston_keyboard *keyboard;
1453
Kristian Høgsberg2bf87622013-05-07 23:17:41 -04001454 if (seat->keyboard)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001455 return 0;
1456
Rob Bradford382ff462013-06-24 16:52:45 +01001457#ifdef ENABLE_XKBCOMMON
Matt Roper01a92732013-06-24 16:52:44 +01001458 if (seat->compositor->use_xkbcommon) {
1459 if (keymap != NULL) {
1460 seat->xkb_info.keymap = xkb_map_ref(keymap);
1461 if (weston_xkb_info_new_keymap(&seat->xkb_info) < 0)
1462 return -1;
1463 } else {
1464 if (weston_compositor_build_global_keymap(seat->compositor) < 0)
1465 return -1;
1466 seat->xkb_info = seat->compositor->xkb_info;
1467 seat->xkb_info.keymap = xkb_map_ref(seat->xkb_info.keymap);
1468 }
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001469
Matt Roper01a92732013-06-24 16:52:44 +01001470 seat->xkb_state.state = xkb_state_new(seat->xkb_info.keymap);
1471 if (seat->xkb_state.state == NULL) {
1472 weston_log("failed to initialise XKB state\n");
1473 return -1;
1474 }
1475
1476 seat->xkb_state.leds = 0;
1477 }
Rob Bradford382ff462013-06-24 16:52:45 +01001478#endif
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001479
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04001480 keyboard = weston_keyboard_create();
1481 if (keyboard == NULL) {
1482 weston_log("failed to allocate weston keyboard struct\n");
1483 return -1;
1484 }
1485
1486 seat->keyboard = keyboard;
1487 keyboard->seat = seat;
1488
1489 seat_send_updated_caps(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001490
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001491 return 0;
1492}
1493
1494WL_EXPORT void
1495weston_seat_init_pointer(struct weston_seat *seat)
1496{
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04001497 struct weston_pointer *pointer;
1498
Kristian Høgsberg2bf87622013-05-07 23:17:41 -04001499 if (seat->pointer)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001500 return;
1501
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04001502 pointer = weston_pointer_create();
1503 if (pointer == NULL)
1504 return;
1505
1506 seat->pointer = pointer;
1507 pointer->seat = seat;
1508
1509 seat_send_updated_caps(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001510}
1511
1512WL_EXPORT void
1513weston_seat_init_touch(struct weston_seat *seat)
1514{
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04001515 struct weston_touch *touch;
1516
Kristian Høgsberg2bf87622013-05-07 23:17:41 -04001517 if (seat->touch)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001518 return;
1519
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04001520 touch = weston_touch_create();
1521 if (touch == NULL)
1522 return;
1523
1524 seat->touch = touch;
1525 touch->seat = seat;
1526
1527 seat_send_updated_caps(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001528}
1529
1530WL_EXPORT void
Rob Bradford9af5f9e2013-05-31 18:09:50 +01001531weston_seat_init(struct weston_seat *seat, struct weston_compositor *ec,
1532 const char *seat_name)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001533{
Kristian Høgsberg4a2a2742013-05-06 22:24:50 -04001534 memset(seat, 0, sizeof *seat);
1535
Kristian Høgsberge3148752013-05-06 23:19:49 -04001536 seat->selection_data_source = NULL;
1537 wl_list_init(&seat->base_resource_list);
1538 wl_signal_init(&seat->selection_signal);
1539 wl_list_init(&seat->drag_resource_list);
Kristian Høgsberge3148752013-05-06 23:19:49 -04001540 wl_signal_init(&seat->destroy_signal);
Kristian Høgsberg4a2a2742013-05-06 22:24:50 -04001541
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001542 wl_display_add_global(ec->wl_display, &wl_seat_interface, seat,
1543 bind_seat);
1544
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001545 seat->compositor = ec;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001546 seat->modifier_state = 0;
1547 seat->num_tp = 0;
Rob Bradford9af5f9e2013-05-31 18:09:50 +01001548 seat->seat_name = strdup(seat_name);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001549
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001550 wl_list_insert(ec->seat_list.prev, &seat->link);
1551
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001552 clipboard_create(seat);
1553
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001554 wl_signal_emit(&ec->seat_created_signal, seat);
1555}
1556
1557WL_EXPORT void
1558weston_seat_release(struct weston_seat *seat)
1559{
1560 wl_list_remove(&seat->link);
1561 /* The global object is destroyed at wl_display_destroy() time. */
1562
Rob Bradford382ff462013-06-24 16:52:45 +01001563#ifdef ENABLE_XKBCOMMON
Matt Roper01a92732013-06-24 16:52:44 +01001564 if (seat->compositor->use_xkbcommon) {
1565 if (seat->xkb_state.state != NULL)
1566 xkb_state_unref(seat->xkb_state.state);
1567 xkb_info_destroy(&seat->xkb_info);
1568 }
Rob Bradford382ff462013-06-24 16:52:45 +01001569#endif
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001570
Kristian Høgsberge3148752013-05-06 23:19:49 -04001571 if (seat->pointer)
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04001572 weston_pointer_destroy(seat->pointer);
Kristian Høgsberge3148752013-05-06 23:19:49 -04001573 if (seat->keyboard)
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04001574 weston_keyboard_destroy(seat->keyboard);
Kristian Høgsberge3148752013-05-06 23:19:49 -04001575 if (seat->touch)
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04001576 weston_touch_destroy(seat->touch);
Kristian Høgsberg4a2a2742013-05-06 22:24:50 -04001577
Rob Bradford9af5f9e2013-05-31 18:09:50 +01001578 free (seat->seat_name);
1579
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001580 wl_signal_emit(&seat->destroy_signal, seat);
1581}