blob: 5d13b087d82c22af1fc6c261271d46c7d0d54766 [file] [log] [blame]
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001/*
2 * Copyright © 2013 Intel Corporation
3 *
Bryce Harringtona0bbfea2015-06-11 15:35:43 -07004 * Permission is hereby granted, free of charge, to any person obtaining
5 * a copy of this software and associated documentation files (the
6 * "Software"), to deal in the Software without restriction, including
7 * without limitation the rights to use, copy, modify, merge, publish,
8 * distribute, sublicense, and/or sell copies of the Software, and to
9 * permit persons to whom the Software is furnished to do so, subject to
10 * the following conditions:
Kristian Høgsberg2158a882013-04-18 15:07:39 -040011 *
Bryce Harringtona0bbfea2015-06-11 15:35:43 -070012 * The above copyright notice and this permission notice (including the
13 * next paragraph) shall be included in all copies or substantial
14 * portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
20 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
21 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 * SOFTWARE.
Kristian Høgsberg2158a882013-04-18 15:07:39 -040024 */
25
Daniel Stone8e7a8bd2013-08-15 01:10:24 +010026#include "config.h"
27
Kristian Høgsberg2158a882013-04-18 15:07:39 -040028#include <stdlib.h>
29#include <stdint.h>
30#include <string.h>
Kristian Høgsbergb5e26102013-04-18 15:40:10 -040031#include <sys/mman.h>
32#include <assert.h>
33#include <unistd.h>
Matt Roper01a92732013-06-24 16:52:44 +010034#include <fcntl.h>
Ander Conselvan de Oliveira54e90c72013-12-13 22:10:56 +020035#include <limits.h>
Kristian Høgsberg2158a882013-04-18 15:07:39 -040036
Jon Cruz35b2eaa2015-06-15 15:37:08 -070037#include "shared/helpers.h"
Jon Cruz4678bab2015-06-15 15:37:07 -070038#include "shared/os-compatibility.h"
Kristian Høgsberg2158a882013-04-18 15:07:39 -040039#include "compositor.h"
40
Kristian Høgsbergb5e26102013-04-18 15:40:10 -040041static void
42empty_region(pixman_region32_t *region)
43{
44 pixman_region32_fini(region);
45 pixman_region32_init(region);
46}
47
Jonas Ådahl2cbf2932015-07-22 12:05:38 +080048static struct weston_pointer_client *
49weston_pointer_client_create(struct wl_client *client)
50{
51 struct weston_pointer_client *pointer_client;
52
53 pointer_client = zalloc(sizeof *pointer_client);
54 if (!pointer_client)
55 return NULL;
56
57 pointer_client->client = client;
58 wl_list_init(&pointer_client->pointer_resources);
59
60 return pointer_client;
61}
62
63static void
64weston_pointer_client_destroy(struct weston_pointer_client *pointer_client)
65{
66 free(pointer_client);
67}
68
69static bool
70weston_pointer_client_is_empty(struct weston_pointer_client *pointer_client)
71{
72 return wl_list_empty(&pointer_client->pointer_resources);
73}
74
75static struct weston_pointer_client *
76weston_pointer_get_pointer_client(struct weston_pointer *pointer,
77 struct wl_client *client)
78{
79 struct weston_pointer_client *pointer_client;
80
81 wl_list_for_each(pointer_client, &pointer->pointer_clients, link) {
82 if (pointer_client->client == client)
83 return pointer_client;
84 }
85
86 return NULL;
87}
88
89static struct weston_pointer_client *
90weston_pointer_ensure_pointer_client(struct weston_pointer *pointer,
91 struct wl_client *client)
92{
93 struct weston_pointer_client *pointer_client;
94
95 pointer_client = weston_pointer_get_pointer_client(pointer, client);
96 if (pointer_client)
97 return pointer_client;
98
99 pointer_client = weston_pointer_client_create(client);
100 wl_list_insert(&pointer->pointer_clients, &pointer_client->link);
101
102 if (pointer->focus &&
103 pointer->focus->surface->resource &&
104 wl_resource_get_client(pointer->focus->surface->resource) == client) {
105 pointer->focus_client = pointer_client;
106 }
107
108 return pointer_client;
109}
110
111static void
112weston_pointer_cleanup_pointer_client(struct weston_pointer *pointer,
113 struct weston_pointer_client *pointer_client)
114{
115 if (weston_pointer_client_is_empty(pointer_client)) {
116 if (pointer->focus_client == pointer_client)
117 pointer->focus_client = NULL;
118 wl_list_remove(&pointer_client->link);
119 weston_pointer_client_destroy(pointer_client);
120 }
121}
122
123static void
124unbind_pointer_client_resource(struct wl_resource *resource)
125{
126 struct weston_pointer *pointer = wl_resource_get_user_data(resource);
127 struct wl_client *client = wl_resource_get_client(resource);
128 struct weston_pointer_client *pointer_client;
129
130 pointer_client = weston_pointer_get_pointer_client(pointer, client);
131 assert(pointer_client);
132
133 wl_list_remove(wl_resource_get_link(resource));
134 weston_pointer_cleanup_pointer_client(pointer, pointer_client);
135}
136
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400137static void unbind_resource(struct wl_resource *resource)
138{
Jason Ekstrand44a38632013-06-14 10:08:00 -0500139 wl_list_remove(wl_resource_get_link(resource));
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400140}
141
Jonas Ådahl3042ffe2013-10-17 23:04:08 +0200142WL_EXPORT void
Kristian Høgsberga71e8b22013-05-06 21:51:21 -0400143weston_seat_repick(struct weston_seat *seat)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400144{
Derek Foreman1281a362015-07-31 16:55:32 -0500145 const struct weston_pointer *pointer = weston_seat_get_pointer(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400146
Derek Foreman1b786ee2015-06-03 15:53:23 -0500147 if (!pointer)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400148 return;
149
Derek Foreman1b786ee2015-06-03 15:53:23 -0500150 pointer->grab->interface->focus(pointer->grab);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400151}
152
153static void
154weston_compositor_idle_inhibit(struct weston_compositor *compositor)
155{
156 weston_compositor_wake(compositor);
157 compositor->idle_inhibit++;
158}
159
160static void
161weston_compositor_idle_release(struct weston_compositor *compositor)
162{
163 compositor->idle_inhibit--;
164 weston_compositor_wake(compositor);
165}
166
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400167static void
Giulio Camuffo576fe2a2013-11-20 18:00:24 +0100168pointer_focus_view_destroyed(struct wl_listener *listener, void *data)
169{
170 struct weston_pointer *pointer =
171 container_of(listener, struct weston_pointer,
172 focus_view_listener);
173
Derek Foremanf9318d12015-05-11 15:40:11 -0500174 weston_pointer_clear_focus(pointer);
Giulio Camuffo576fe2a2013-11-20 18:00:24 +0100175}
176
177static void
178pointer_focus_resource_destroyed(struct wl_listener *listener, void *data)
179{
180 struct weston_pointer *pointer =
181 container_of(listener, struct weston_pointer,
182 focus_resource_listener);
183
Derek Foremanf9318d12015-05-11 15:40:11 -0500184 weston_pointer_clear_focus(pointer);
Giulio Camuffo576fe2a2013-11-20 18:00:24 +0100185}
186
187static void
188keyboard_focus_resource_destroyed(struct wl_listener *listener, void *data)
189{
190 struct weston_keyboard *keyboard =
191 container_of(listener, struct weston_keyboard,
192 focus_resource_listener);
193
194 weston_keyboard_set_focus(keyboard, NULL);
195}
196
197static void
198touch_focus_view_destroyed(struct wl_listener *listener, void *data)
199{
200 struct weston_touch *touch =
201 container_of(listener, struct weston_touch,
202 focus_view_listener);
203
Derek Foreman4c93c082015-04-30 16:45:41 -0500204 weston_touch_set_focus(touch, NULL);
Giulio Camuffo576fe2a2013-11-20 18:00:24 +0100205}
206
207static void
208touch_focus_resource_destroyed(struct wl_listener *listener, void *data)
209{
210 struct weston_touch *touch =
211 container_of(listener, struct weston_touch,
212 focus_resource_listener);
213
Derek Foreman4c93c082015-04-30 16:45:41 -0500214 weston_touch_set_focus(touch, NULL);
Giulio Camuffo576fe2a2013-11-20 18:00:24 +0100215}
216
217static void
Neil Roberts96d790e2013-09-19 17:32:00 +0100218move_resources(struct wl_list *destination, struct wl_list *source)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400219{
Neil Roberts96d790e2013-09-19 17:32:00 +0100220 wl_list_insert_list(destination, source);
221 wl_list_init(source);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400222}
223
224static void
Neil Roberts96d790e2013-09-19 17:32:00 +0100225move_resources_for_client(struct wl_list *destination,
226 struct wl_list *source,
227 struct wl_client *client)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400228{
Neil Roberts96d790e2013-09-19 17:32:00 +0100229 struct wl_resource *resource, *tmp;
230 wl_resource_for_each_safe(resource, tmp, source) {
231 if (wl_resource_get_client(resource) == client) {
232 wl_list_remove(wl_resource_get_link(resource));
233 wl_list_insert(destination,
234 wl_resource_get_link(resource));
235 }
236 }
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400237}
238
239static void
Kristian Høgsbergb27901c2013-10-28 15:32:02 -0700240default_grab_pointer_focus(struct weston_pointer_grab *grab)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400241{
Kristian Høgsberg02bbabb2013-05-06 22:15:05 -0400242 struct weston_pointer *pointer = grab->pointer;
Jason Ekstranda7af7042013-10-12 22:38:11 -0500243 struct weston_view *view;
Kristian Høgsberg6848c252013-05-08 22:02:59 -0400244 wl_fixed_t sx, sy;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400245
246 if (pointer->button_count > 0)
247 return;
248
Jason Ekstranda7af7042013-10-12 22:38:11 -0500249 view = weston_compositor_pick_view(pointer->seat->compositor,
250 pointer->x, pointer->y,
251 &sx, &sy);
Kristian Høgsberg6848c252013-05-08 22:02:59 -0400252
Kristian Høgsbergdb1fccb2014-02-05 17:14:42 -0800253 if (pointer->focus != view || pointer->sx != sx || pointer->sy != sy)
Jason Ekstranda7af7042013-10-12 22:38:11 -0500254 weston_pointer_set_focus(pointer, view, sx, sy);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400255}
256
257static void
Giulio Camuffo1959ab82013-11-14 23:42:52 +0100258default_grab_pointer_motion(struct weston_pointer_grab *grab, uint32_t time,
Jonas Ådahld2510102014-10-05 21:39:14 +0200259 struct weston_pointer_motion_event *event)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400260{
Kristian Høgsbergbe6403e2013-05-08 21:03:21 -0400261 struct weston_pointer *pointer = grab->pointer;
Neil Roberts96d790e2013-09-19 17:32:00 +0100262 struct wl_list *resource_list;
263 struct wl_resource *resource;
Jonas Ådahld2510102014-10-05 21:39:14 +0200264 wl_fixed_t x, y;
Jonas Ådahl8283c342015-04-24 15:26:17 +0800265 wl_fixed_t old_sx = pointer->sx;
266 wl_fixed_t old_sy = pointer->sy;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400267
Jonas Ådahld2510102014-10-05 21:39:14 +0200268 if (pointer->focus) {
269 weston_pointer_motion_to_abs(pointer, event, &x, &y);
Kristian Høgsbergdb1fccb2014-02-05 17:14:42 -0800270 weston_view_from_global_fixed(pointer->focus, x, y,
271 &pointer->sx, &pointer->sy);
Jonas Ådahld2510102014-10-05 21:39:14 +0200272 }
Kristian Høgsbergdb1fccb2014-02-05 17:14:42 -0800273
Jonas Ådahld2510102014-10-05 21:39:14 +0200274 weston_pointer_move(pointer, event);
Giulio Camuffo1959ab82013-11-14 23:42:52 +0100275
Jonas Ådahl2cbf2932015-07-22 12:05:38 +0800276 if (pointer->focus_client &&
277 (old_sx != pointer->sx || old_sy != pointer->sy)) {
278 resource_list = &pointer->focus_client->pointer_resources;
Jonas Ådahl8283c342015-04-24 15:26:17 +0800279 wl_resource_for_each(resource, resource_list) {
280 wl_pointer_send_motion(resource, time,
281 pointer->sx, pointer->sy);
282 }
Kristian Høgsbergbe6403e2013-05-08 21:03:21 -0400283 }
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400284}
285
286static void
Kristian Høgsbergb27901c2013-10-28 15:32:02 -0700287default_grab_pointer_button(struct weston_pointer_grab *grab,
288 uint32_t time, uint32_t button, uint32_t state_w)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400289{
Kristian Høgsberg02bbabb2013-05-06 22:15:05 -0400290 struct weston_pointer *pointer = grab->pointer;
Kristian Høgsberge122b7b2013-05-08 16:47:00 -0400291 struct weston_compositor *compositor = pointer->seat->compositor;
Jason Ekstranda7af7042013-10-12 22:38:11 -0500292 struct weston_view *view;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400293 struct wl_resource *resource;
294 uint32_t serial;
295 enum wl_pointer_button_state state = state_w;
Rob Bradford880ebc72013-07-22 17:31:38 +0100296 struct wl_display *display = compositor->wl_display;
Kristian Høgsberge122b7b2013-05-08 16:47:00 -0400297 wl_fixed_t sx, sy;
Jonas Ådahl2cbf2932015-07-22 12:05:38 +0800298 struct wl_list *resource_list = NULL;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400299
Jonas Ådahl2cbf2932015-07-22 12:05:38 +0800300 if (pointer->focus_client)
301 resource_list = &pointer->focus_client->pointer_resources;
302 if (resource_list && !wl_list_empty(resource_list)) {
303 resource_list = &pointer->focus_client->pointer_resources;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400304 serial = wl_display_next_serial(display);
Neil Roberts96d790e2013-09-19 17:32:00 +0100305 wl_resource_for_each(resource, resource_list)
306 wl_pointer_send_button(resource,
307 serial,
308 time,
309 button,
310 state_w);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400311 }
312
313 if (pointer->button_count == 0 &&
Kristian Høgsberge122b7b2013-05-08 16:47:00 -0400314 state == WL_POINTER_BUTTON_STATE_RELEASED) {
Jason Ekstranda7af7042013-10-12 22:38:11 -0500315 view = weston_compositor_pick_view(compositor,
316 pointer->x, pointer->y,
317 &sx, &sy);
Kristian Høgsberge122b7b2013-05-08 16:47:00 -0400318
Jason Ekstranda7af7042013-10-12 22:38:11 -0500319 weston_pointer_set_focus(pointer, view, sx, sy);
Kristian Høgsberge122b7b2013-05-08 16:47:00 -0400320 }
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400321}
322
Jonas Ådahl0336ca02014-10-04 16:28:29 +0200323/** Send wl_pointer.axis events to focused resources.
324 *
325 * \param pointer The pointer where the axis events originates from.
326 * \param time The timestamp of the event
327 * \param axis The axis enum value of the event
328 * \param value The axis value of the event
329 *
330 * For every resource that is currently in focus, send a wl_pointer.axis event
331 * with the passed parameters. The focused resources are the wl_pointer
332 * resources of the client which currently has the surface with pointer focus.
333 */
334WL_EXPORT void
335weston_pointer_send_axis(struct weston_pointer *pointer,
Peter Hutterer89b6a492016-01-18 15:58:17 +1000336 uint32_t time,
337 struct weston_pointer_axis_event *event)
Jonas Ådahl0336ca02014-10-04 16:28:29 +0200338{
339 struct wl_resource *resource;
340 struct wl_list *resource_list;
341
Jonas Ådahl2cbf2932015-07-22 12:05:38 +0800342 if (!pointer->focus_client)
343 return;
344
345 resource_list = &pointer->focus_client->pointer_resources;
Peter Hutterer87743e92016-01-18 16:38:22 +1000346 wl_resource_for_each(resource, resource_list) {
347 if (event->has_discrete &&
348 wl_resource_get_version(resource) >=
349 WL_POINTER_AXIS_DISCRETE_SINCE_VERSION)
350 wl_pointer_send_axis_discrete(resource, event->axis,
351 event->discrete);
352
353 if (event->value)
354 wl_pointer_send_axis(resource, time,
355 event->axis, event->value);
356 else if (wl_resource_get_version(resource) >=
357 WL_POINTER_AXIS_STOP_SINCE_VERSION)
358 wl_pointer_send_axis_stop(resource, time,
359 event->axis);
360 }
361}
362
363WL_EXPORT void
364weston_pointer_send_axis_source(struct weston_pointer *pointer, uint32_t source)
365{
366 struct wl_resource *resource;
367 struct wl_list *resource_list;
368
369 resource_list = &pointer->focus_client->pointer_resources;
370 wl_resource_for_each(resource, resource_list) {
371 if (wl_resource_get_version(resource) >=
372 WL_POINTER_AXIS_SOURCE_SINCE_VERSION) {
373 wl_pointer_send_axis_source(resource, source);
374 }
375 }
376}
377
378static void
379pointer_send_frame(struct wl_resource *resource)
380{
381 if (wl_resource_get_version(resource) >=
382 WL_POINTER_FRAME_SINCE_VERSION) {
383 wl_pointer_send_frame(resource);
384 }
385}
386
387WL_EXPORT void
388weston_pointer_send_frame(struct weston_pointer *pointer)
389{
390 struct wl_resource *resource;
391 struct wl_list *resource_list;
392
Derek Foreman8efa31b2016-01-29 10:29:46 -0600393 if (!pointer->focus_client)
394 return;
395
Peter Hutterer87743e92016-01-18 16:38:22 +1000396 resource_list = &pointer->focus_client->pointer_resources;
Jonas Ådahl0336ca02014-10-04 16:28:29 +0200397 wl_resource_for_each(resource, resource_list)
Peter Hutterer87743e92016-01-18 16:38:22 +1000398 pointer_send_frame(resource);
Jonas Ådahl0336ca02014-10-04 16:28:29 +0200399}
400
401static void
402default_grab_pointer_axis(struct weston_pointer_grab *grab,
Peter Hutterer89b6a492016-01-18 15:58:17 +1000403 uint32_t time,
404 struct weston_pointer_axis_event *event)
Jonas Ådahl0336ca02014-10-04 16:28:29 +0200405{
Peter Hutterer89b6a492016-01-18 15:58:17 +1000406 weston_pointer_send_axis(grab->pointer, time, event);
Jonas Ådahl0336ca02014-10-04 16:28:29 +0200407}
408
Jonas Ådahl1ea343e2013-10-25 23:18:05 +0200409static void
Peter Hutterer87743e92016-01-18 16:38:22 +1000410default_grab_pointer_axis_source(struct weston_pointer_grab *grab,
411 uint32_t source)
412{
413 weston_pointer_send_axis_source(grab->pointer, source);
414}
415
416static void
417default_grab_pointer_frame(struct weston_pointer_grab *grab)
418{
419 weston_pointer_send_frame(grab->pointer);
420}
421
422static void
Jonas Ådahl1ea343e2013-10-25 23:18:05 +0200423default_grab_pointer_cancel(struct weston_pointer_grab *grab)
424{
425}
426
Kristian Høgsberg02bbabb2013-05-06 22:15:05 -0400427static const struct weston_pointer_grab_interface
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400428 default_pointer_grab_interface = {
Kristian Høgsbergb27901c2013-10-28 15:32:02 -0700429 default_grab_pointer_focus,
430 default_grab_pointer_motion,
431 default_grab_pointer_button,
Jonas Ådahl0336ca02014-10-04 16:28:29 +0200432 default_grab_pointer_axis,
Peter Hutterer87743e92016-01-18 16:38:22 +1000433 default_grab_pointer_axis_source,
434 default_grab_pointer_frame,
Jonas Ådahl1ea343e2013-10-25 23:18:05 +0200435 default_grab_pointer_cancel,
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400436};
437
Kristian Høgsberge329f362013-05-06 22:19:57 -0400438static void
439default_grab_touch_down(struct weston_touch_grab *grab, uint32_t time,
Giulio Camuffo61ed7b62015-07-08 11:55:28 +0300440 int touch_id, wl_fixed_t x, wl_fixed_t y)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400441{
Kristian Høgsberge329f362013-05-06 22:19:57 -0400442 struct weston_touch *touch = grab->touch;
Rob Bradford880ebc72013-07-22 17:31:38 +0100443 struct wl_display *display = touch->seat->compositor->wl_display;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400444 uint32_t serial;
Neil Roberts96d790e2013-09-19 17:32:00 +0100445 struct wl_resource *resource;
446 struct wl_list *resource_list;
Giulio Camuffo61ed7b62015-07-08 11:55:28 +0300447 wl_fixed_t sx, sy;
448
Bryce Harrington2c40d1d2016-02-02 10:18:48 -0800449 if (!touch->focus)
450 return;
451
Giulio Camuffo61ed7b62015-07-08 11:55:28 +0300452 weston_view_from_global_fixed(touch->focus, x, y, &sx, &sy);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400453
Neil Roberts96d790e2013-09-19 17:32:00 +0100454 resource_list = &touch->focus_resource_list;
455
Bryce Harrington2c40d1d2016-02-02 10:18:48 -0800456 if (!wl_list_empty(resource_list)) {
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400457 serial = wl_display_next_serial(display);
Neil Roberts96d790e2013-09-19 17:32:00 +0100458 wl_resource_for_each(resource, resource_list)
459 wl_touch_send_down(resource, serial, time,
Jason Ekstranda7af7042013-10-12 22:38:11 -0500460 touch->focus->surface->resource,
Neil Roberts96d790e2013-09-19 17:32:00 +0100461 touch_id, sx, sy);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400462 }
463}
464
Kristian Høgsberge329f362013-05-06 22:19:57 -0400465static void
466default_grab_touch_up(struct weston_touch_grab *grab,
467 uint32_t time, int touch_id)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400468{
Kristian Høgsberge329f362013-05-06 22:19:57 -0400469 struct weston_touch *touch = grab->touch;
Rob Bradford880ebc72013-07-22 17:31:38 +0100470 struct wl_display *display = touch->seat->compositor->wl_display;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400471 uint32_t serial;
Neil Roberts96d790e2013-09-19 17:32:00 +0100472 struct wl_resource *resource;
473 struct wl_list *resource_list;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400474
Neil Roberts96d790e2013-09-19 17:32:00 +0100475 resource_list = &touch->focus_resource_list;
476
477 if (!wl_list_empty(resource_list)) {
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400478 serial = wl_display_next_serial(display);
Neil Roberts96d790e2013-09-19 17:32:00 +0100479 wl_resource_for_each(resource, resource_list)
480 wl_touch_send_up(resource, serial, time, touch_id);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400481 }
482}
483
Kristian Høgsberge329f362013-05-06 22:19:57 -0400484static void
485default_grab_touch_motion(struct weston_touch_grab *grab, uint32_t time,
Giulio Camuffo61ed7b62015-07-08 11:55:28 +0300486 int touch_id, wl_fixed_t x, wl_fixed_t y)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400487{
Kristian Høgsberge329f362013-05-06 22:19:57 -0400488 struct weston_touch *touch = grab->touch;
Neil Roberts96d790e2013-09-19 17:32:00 +0100489 struct wl_resource *resource;
490 struct wl_list *resource_list;
Giulio Camuffo61ed7b62015-07-08 11:55:28 +0300491 wl_fixed_t sx, sy;
492
493 weston_view_from_global_fixed(touch->focus, x, y, &sx, &sy);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400494
Neil Roberts96d790e2013-09-19 17:32:00 +0100495 resource_list = &touch->focus_resource_list;
496
497 wl_resource_for_each(resource, resource_list) {
498 wl_touch_send_motion(resource, time,
Kristian Høgsberge329f362013-05-06 22:19:57 -0400499 touch_id, sx, sy);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400500 }
501}
502
Jonas Ådahl1ea343e2013-10-25 23:18:05 +0200503static void
Jonas Ådahl1679f232014-04-12 09:39:51 +0200504default_grab_touch_frame(struct weston_touch_grab *grab)
505{
506 struct wl_resource *resource;
507
508 wl_resource_for_each(resource, &grab->touch->focus_resource_list)
509 wl_touch_send_frame(resource);
510}
511
512static void
Jonas Ådahl1ea343e2013-10-25 23:18:05 +0200513default_grab_touch_cancel(struct weston_touch_grab *grab)
514{
515}
516
Kristian Høgsberge329f362013-05-06 22:19:57 -0400517static const struct weston_touch_grab_interface default_touch_grab_interface = {
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400518 default_grab_touch_down,
519 default_grab_touch_up,
Jonas Ådahl1ea343e2013-10-25 23:18:05 +0200520 default_grab_touch_motion,
Jonas Ådahl1679f232014-04-12 09:39:51 +0200521 default_grab_touch_frame,
Jonas Ådahl1ea343e2013-10-25 23:18:05 +0200522 default_grab_touch_cancel,
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400523};
524
525static void
Kristian Høgsbergb27901c2013-10-28 15:32:02 -0700526default_grab_keyboard_key(struct weston_keyboard_grab *grab,
527 uint32_t time, uint32_t key, uint32_t state)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400528{
Kristian Høgsberg29139d42013-04-18 15:25:39 -0400529 struct weston_keyboard *keyboard = grab->keyboard;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400530 struct wl_resource *resource;
Rob Bradford880ebc72013-07-22 17:31:38 +0100531 struct wl_display *display = keyboard->seat->compositor->wl_display;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400532 uint32_t serial;
Neil Roberts96d790e2013-09-19 17:32:00 +0100533 struct wl_list *resource_list;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400534
Neil Roberts96d790e2013-09-19 17:32:00 +0100535 resource_list = &keyboard->focus_resource_list;
536 if (!wl_list_empty(resource_list)) {
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400537 serial = wl_display_next_serial(display);
Neil Roberts96d790e2013-09-19 17:32:00 +0100538 wl_resource_for_each(resource, resource_list)
539 wl_keyboard_send_key(resource,
540 serial,
541 time,
542 key,
543 state);
544 }
545}
546
547static void
548send_modifiers_to_resource(struct weston_keyboard *keyboard,
549 struct wl_resource *resource,
550 uint32_t serial)
551{
552 wl_keyboard_send_modifiers(resource,
553 serial,
554 keyboard->modifiers.mods_depressed,
555 keyboard->modifiers.mods_latched,
556 keyboard->modifiers.mods_locked,
557 keyboard->modifiers.group);
558}
559
560static void
561send_modifiers_to_client_in_list(struct wl_client *client,
562 struct wl_list *list,
563 uint32_t serial,
564 struct weston_keyboard *keyboard)
565{
566 struct wl_resource *resource;
567
568 wl_resource_for_each(resource, list) {
569 if (wl_resource_get_client(resource) == client)
570 send_modifiers_to_resource(keyboard,
571 resource,
572 serial);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400573 }
574}
575
Jonas Ådahl2cbf2932015-07-22 12:05:38 +0800576static struct weston_pointer_client *
577find_pointer_client_for_surface(struct weston_pointer *pointer,
578 struct weston_surface *surface)
579{
580 struct wl_client *client;
581
582 if (!surface)
583 return NULL;
584
585 if (!surface->resource)
586 return NULL;
587
588 client = wl_resource_get_client(surface->resource);
589 return weston_pointer_get_pointer_client(pointer, client);
590}
591
592static struct weston_pointer_client *
593find_pointer_client_for_view(struct weston_pointer *pointer, struct weston_view *view)
594{
595 if (!view)
596 return NULL;
597
598 return find_pointer_client_for_surface(pointer, view->surface);
599}
600
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400601static struct wl_resource *
Kristian Høgsbergfe7aa902013-05-08 09:54:37 -0400602find_resource_for_surface(struct wl_list *list, struct weston_surface *surface)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400603{
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400604 if (!surface)
605 return NULL;
606
Jason Ekstrand44a38632013-06-14 10:08:00 -0500607 if (!surface->resource)
608 return NULL;
Stefan Schmidtfda26522013-09-17 10:54:09 +0100609
Jason Ekstrand44a38632013-06-14 10:08:00 -0500610 return wl_resource_find_for_client(list, wl_resource_get_client(surface->resource));
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400611}
612
613static void
Kristian Høgsbergb27901c2013-10-28 15:32:02 -0700614default_grab_keyboard_modifiers(struct weston_keyboard_grab *grab,
615 uint32_t serial, uint32_t mods_depressed,
616 uint32_t mods_latched,
617 uint32_t mods_locked, uint32_t group)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400618{
Kristian Høgsberg29139d42013-04-18 15:25:39 -0400619 struct weston_keyboard *keyboard = grab->keyboard;
Derek Foreman1281a362015-07-31 16:55:32 -0500620 struct weston_pointer *pointer =
621 weston_seat_get_pointer(grab->keyboard->seat);
Neil Roberts96d790e2013-09-19 17:32:00 +0100622 struct wl_resource *resource;
623 struct wl_list *resource_list;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400624
Neil Roberts96d790e2013-09-19 17:32:00 +0100625 resource_list = &keyboard->focus_resource_list;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400626
Neil Roberts96d790e2013-09-19 17:32:00 +0100627 wl_resource_for_each(resource, resource_list) {
628 wl_keyboard_send_modifiers(resource, serial, mods_depressed,
629 mods_latched, mods_locked, group);
630 }
Jason Ekstrand42133d42013-11-14 20:06:16 -0600631 if (pointer && pointer->focus && pointer->focus->surface->resource &&
632 pointer->focus->surface != keyboard->focus) {
Neil Roberts96d790e2013-09-19 17:32:00 +0100633 struct wl_client *pointer_client =
Jason Ekstranda7af7042013-10-12 22:38:11 -0500634 wl_resource_get_client(pointer->focus->surface->resource);
Neil Roberts96d790e2013-09-19 17:32:00 +0100635 send_modifiers_to_client_in_list(pointer_client,
636 &keyboard->resource_list,
637 serial,
638 keyboard);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400639 }
640}
641
Jonas Ådahl1ea343e2013-10-25 23:18:05 +0200642static void
643default_grab_keyboard_cancel(struct weston_keyboard_grab *grab)
644{
645}
646
Kristian Høgsberg29139d42013-04-18 15:25:39 -0400647static const struct weston_keyboard_grab_interface
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400648 default_keyboard_grab_interface = {
Kristian Høgsbergb27901c2013-10-28 15:32:02 -0700649 default_grab_keyboard_key,
650 default_grab_keyboard_modifiers,
Jonas Ådahl1ea343e2013-10-25 23:18:05 +0200651 default_grab_keyboard_cancel,
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400652};
653
Kristian Høgsberg195b8692013-05-08 15:02:05 -0400654static void
655pointer_unmap_sprite(struct weston_pointer *pointer)
656{
Pekka Paalanenc557ff72014-11-12 16:42:52 +0200657 struct weston_surface *surface = pointer->sprite->surface;
658
659 if (weston_surface_is_mapped(surface))
660 weston_surface_unmap(surface);
Kristian Høgsberg195b8692013-05-08 15:02:05 -0400661
662 wl_list_remove(&pointer->sprite_destroy_listener.link);
Pekka Paalanenc557ff72014-11-12 16:42:52 +0200663 surface->configure = NULL;
664 surface->configure_private = NULL;
Pekka Paalanen8274d902014-08-06 19:36:51 +0300665 weston_surface_set_label_func(surface, NULL);
Jason Ekstranda7af7042013-10-12 22:38:11 -0500666 weston_view_destroy(pointer->sprite);
Kristian Høgsberg195b8692013-05-08 15:02:05 -0400667 pointer->sprite = NULL;
668}
669
670static void
671pointer_handle_sprite_destroy(struct wl_listener *listener, void *data)
672{
673 struct weston_pointer *pointer =
674 container_of(listener, struct weston_pointer,
675 sprite_destroy_listener);
676
677 pointer->sprite = NULL;
678}
679
Jonas Ådahl3e12e632013-12-02 22:05:05 +0100680static void
681weston_pointer_reset_state(struct weston_pointer *pointer)
682{
683 pointer->button_count = 0;
684}
685
Ander Conselvan de Oliveiraf84327a2014-01-29 18:47:51 +0200686static void
687weston_pointer_handle_output_destroy(struct wl_listener *listener, void *data);
688
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400689WL_EXPORT struct weston_pointer *
Giulio Camuffocdb4d292013-11-14 23:42:53 +0100690weston_pointer_create(struct weston_seat *seat)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400691{
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400692 struct weston_pointer *pointer;
693
Peter Huttererf3d62272013-08-08 11:57:05 +1000694 pointer = zalloc(sizeof *pointer);
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400695 if (pointer == NULL)
696 return NULL;
697
Jonas Ådahl2cbf2932015-07-22 12:05:38 +0800698 wl_list_init(&pointer->pointer_clients);
Giulio Camuffocdb4d292013-11-14 23:42:53 +0100699 weston_pointer_set_default_grab(pointer,
700 seat->compositor->default_pointer_grab);
Giulio Camuffo576fe2a2013-11-20 18:00:24 +0100701 wl_list_init(&pointer->focus_resource_listener.link);
702 pointer->focus_resource_listener.notify = pointer_focus_resource_destroyed;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400703 pointer->default_grab.pointer = pointer;
704 pointer->grab = &pointer->default_grab;
Giulio Camuffo6fcb3782013-11-14 23:42:50 +0100705 wl_signal_init(&pointer->motion_signal);
Emilio Pozuelo Monfortaa7a4762013-11-19 11:37:15 +0100706 wl_signal_init(&pointer->focus_signal);
Giulio Camuffo576fe2a2013-11-20 18:00:24 +0100707 wl_list_init(&pointer->focus_view_listener.link);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400708
Kristian Høgsberg195b8692013-05-08 15:02:05 -0400709 pointer->sprite_destroy_listener.notify = pointer_handle_sprite_destroy;
710
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400711 /* FIXME: Pick better co-ords. */
712 pointer->x = wl_fixed_from_int(100);
713 pointer->y = wl_fixed_from_int(100);
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400714
Ander Conselvan de Oliveiraf84327a2014-01-29 18:47:51 +0200715 pointer->output_destroy_listener.notify =
716 weston_pointer_handle_output_destroy;
717 wl_signal_add(&seat->compositor->output_destroyed_signal,
718 &pointer->output_destroy_listener);
719
Derek Foremanf9318d12015-05-11 15:40:11 -0500720 pointer->sx = wl_fixed_from_int(-1000000);
721 pointer->sy = wl_fixed_from_int(-1000000);
722
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400723 return pointer;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400724}
725
726WL_EXPORT void
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400727weston_pointer_destroy(struct weston_pointer *pointer)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400728{
Kristian Høgsberg195b8692013-05-08 15:02:05 -0400729 if (pointer->sprite)
730 pointer_unmap_sprite(pointer);
731
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400732 /* XXX: What about pointer->resource_list? */
Neil Roberts96d790e2013-09-19 17:32:00 +0100733
Giulio Camuffo576fe2a2013-11-20 18:00:24 +0100734 wl_list_remove(&pointer->focus_resource_listener.link);
735 wl_list_remove(&pointer->focus_view_listener.link);
Ander Conselvan de Oliveiraf84327a2014-01-29 18:47:51 +0200736 wl_list_remove(&pointer->output_destroy_listener.link);
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400737 free(pointer);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400738}
739
Giulio Camuffocdb4d292013-11-14 23:42:53 +0100740void
741weston_pointer_set_default_grab(struct weston_pointer *pointer,
742 const struct weston_pointer_grab_interface *interface)
743{
744 if (interface)
745 pointer->default_grab.interface = interface;
746 else
747 pointer->default_grab.interface =
748 &default_pointer_grab_interface;
749}
750
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400751WL_EXPORT struct weston_keyboard *
752weston_keyboard_create(void)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400753{
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400754 struct weston_keyboard *keyboard;
755
Peter Huttererf3d62272013-08-08 11:57:05 +1000756 keyboard = zalloc(sizeof *keyboard);
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400757 if (keyboard == NULL)
Neil Roberts96d790e2013-09-19 17:32:00 +0100758 return NULL;
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400759
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400760 wl_list_init(&keyboard->resource_list);
Neil Roberts96d790e2013-09-19 17:32:00 +0100761 wl_list_init(&keyboard->focus_resource_list);
Giulio Camuffo576fe2a2013-11-20 18:00:24 +0100762 wl_list_init(&keyboard->focus_resource_listener.link);
763 keyboard->focus_resource_listener.notify = keyboard_focus_resource_destroyed;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400764 wl_array_init(&keyboard->keys);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400765 keyboard->default_grab.interface = &default_keyboard_grab_interface;
766 keyboard->default_grab.keyboard = keyboard;
767 keyboard->grab = &keyboard->default_grab;
768 wl_signal_init(&keyboard->focus_signal);
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400769
770 return keyboard;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400771}
772
Jonas Ådahl7395ea02013-12-03 09:14:26 +0100773static void
774weston_xkb_info_destroy(struct weston_xkb_info *xkb_info);
775
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400776WL_EXPORT void
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400777weston_keyboard_destroy(struct weston_keyboard *keyboard)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400778{
779 /* XXX: What about keyboard->resource_list? */
Neil Roberts96d790e2013-09-19 17:32:00 +0100780
Jonas Ådahl7395ea02013-12-03 09:14:26 +0100781#ifdef ENABLE_XKBCOMMON
782 if (keyboard->seat->compositor->use_xkbcommon) {
Ran Benitac9c74152014-08-19 23:59:52 +0300783 xkb_state_unref(keyboard->xkb_state.state);
Jonas Ådahl7395ea02013-12-03 09:14:26 +0100784 if (keyboard->xkb_info)
785 weston_xkb_info_destroy(keyboard->xkb_info);
Ran Benitac9c74152014-08-19 23:59:52 +0300786 xkb_keymap_unref(keyboard->pending_keymap);
Jonas Ådahl7395ea02013-12-03 09:14:26 +0100787 }
788#endif
789
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400790 wl_array_release(&keyboard->keys);
Giulio Camuffo576fe2a2013-11-20 18:00:24 +0100791 wl_list_remove(&keyboard->focus_resource_listener.link);
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400792 free(keyboard);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400793}
794
Jonas Ådahlcbfa7f72013-12-02 22:05:04 +0100795static void
796weston_touch_reset_state(struct weston_touch *touch)
797{
798 touch->num_tp = 0;
799}
800
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400801WL_EXPORT struct weston_touch *
802weston_touch_create(void)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400803{
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400804 struct weston_touch *touch;
805
Peter Huttererf3d62272013-08-08 11:57:05 +1000806 touch = zalloc(sizeof *touch);
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400807 if (touch == NULL)
808 return NULL;
809
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400810 wl_list_init(&touch->resource_list);
Neil Roberts96d790e2013-09-19 17:32:00 +0100811 wl_list_init(&touch->focus_resource_list);
Giulio Camuffo576fe2a2013-11-20 18:00:24 +0100812 wl_list_init(&touch->focus_view_listener.link);
813 touch->focus_view_listener.notify = touch_focus_view_destroyed;
814 wl_list_init(&touch->focus_resource_listener.link);
815 touch->focus_resource_listener.notify = touch_focus_resource_destroyed;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400816 touch->default_grab.interface = &default_touch_grab_interface;
817 touch->default_grab.touch = touch;
818 touch->grab = &touch->default_grab;
819 wl_signal_init(&touch->focus_signal);
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400820
821 return touch;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400822}
823
824WL_EXPORT void
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400825weston_touch_destroy(struct weston_touch *touch)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400826{
827 /* XXX: What about touch->resource_list? */
Neil Roberts96d790e2013-09-19 17:32:00 +0100828
Giulio Camuffo576fe2a2013-11-20 18:00:24 +0100829 wl_list_remove(&touch->focus_view_listener.link);
830 wl_list_remove(&touch->focus_resource_listener.link);
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400831 free(touch);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400832}
833
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400834static void
Kristian Høgsberge3148752013-05-06 23:19:49 -0400835seat_send_updated_caps(struct weston_seat *seat)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400836{
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400837 enum wl_seat_capability caps = 0;
Rob Bradford6e737f52013-09-06 17:48:19 +0100838 struct wl_resource *resource;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400839
Jonas Ådahld6e1c342013-10-17 23:04:05 +0200840 if (seat->pointer_device_count > 0)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400841 caps |= WL_SEAT_CAPABILITY_POINTER;
Jonas Ådahld6e1c342013-10-17 23:04:05 +0200842 if (seat->keyboard_device_count > 0)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400843 caps |= WL_SEAT_CAPABILITY_KEYBOARD;
Jonas Ådahld6e1c342013-10-17 23:04:05 +0200844 if (seat->touch_device_count > 0)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400845 caps |= WL_SEAT_CAPABILITY_TOUCH;
846
Rob Bradford6e737f52013-09-06 17:48:19 +0100847 wl_resource_for_each(resource, &seat->base_resource_list) {
848 wl_seat_send_capabilities(resource, caps);
Jason Ekstrand44a38632013-06-14 10:08:00 -0500849 }
Jason Ekstranda4ab5422014-04-02 19:53:45 -0500850 wl_signal_emit(&seat->updated_caps_signal, seat);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400851}
852
Derek Foremanf9318d12015-05-11 15:40:11 -0500853
854/** Clear the pointer focus
855 *
856 * \param pointer the pointer to clear focus for.
857 *
858 * This can be used to unset pointer focus and set the co-ordinates to the
859 * arbitrary values we use for the no focus case.
860 *
861 * There's no requirement to use this function. For example, passing the
862 * results of a weston_compositor_pick_view() directly to
863 * weston_pointer_set_focus() will do the right thing when no view is found.
864 */
865WL_EXPORT void
866weston_pointer_clear_focus(struct weston_pointer *pointer)
867{
868 weston_pointer_set_focus(pointer, NULL,
869 wl_fixed_from_int(-1000000),
870 wl_fixed_from_int(-1000000));
871}
872
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400873WL_EXPORT void
Kristian Høgsberg02bbabb2013-05-06 22:15:05 -0400874weston_pointer_set_focus(struct weston_pointer *pointer,
Jason Ekstranda7af7042013-10-12 22:38:11 -0500875 struct weston_view *view,
Kristian Høgsberg02bbabb2013-05-06 22:15:05 -0400876 wl_fixed_t sx, wl_fixed_t sy)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400877{
Jonas Ådahl2cbf2932015-07-22 12:05:38 +0800878 struct weston_pointer_client *pointer_client;
Derek Foreman1281a362015-07-31 16:55:32 -0500879 struct weston_keyboard *kbd = weston_seat_get_keyboard(pointer->seat);
Neil Roberts96d790e2013-09-19 17:32:00 +0100880 struct wl_resource *resource;
Jonas Ådahl2cbf2932015-07-22 12:05:38 +0800881 struct wl_resource *surface_resource;
Rob Bradford880ebc72013-07-22 17:31:38 +0100882 struct wl_display *display = pointer->seat->compositor->wl_display;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400883 uint32_t serial;
Neil Roberts96d790e2013-09-19 17:32:00 +0100884 struct wl_list *focus_resource_list;
Kristian Høgsbergdb1fccb2014-02-05 17:14:42 -0800885 int refocus = 0;
Jason Ekstranda7af7042013-10-12 22:38:11 -0500886
887 if ((!pointer->focus && view) ||
888 (pointer->focus && !view) ||
Kristian Høgsbergdb1fccb2014-02-05 17:14:42 -0800889 (pointer->focus && pointer->focus->surface != view->surface) ||
890 pointer->sx != sx || pointer->sy != sy)
891 refocus = 1;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400892
Jonas Ådahl2cbf2932015-07-22 12:05:38 +0800893 if (pointer->focus_client && refocus) {
894 focus_resource_list = &pointer->focus_client->pointer_resources;
895 if (!wl_list_empty(focus_resource_list)) {
896 serial = wl_display_next_serial(display);
897 surface_resource = pointer->focus->surface->resource;
898 wl_resource_for_each(resource, focus_resource_list) {
899 wl_pointer_send_leave(resource, serial,
900 surface_resource);
Peter Hutterer87743e92016-01-18 16:38:22 +1000901 pointer_send_frame(resource);
Jonas Ådahl2cbf2932015-07-22 12:05:38 +0800902 }
Neil Roberts96d790e2013-09-19 17:32:00 +0100903 }
904
Jonas Ådahl2cbf2932015-07-22 12:05:38 +0800905 pointer->focus_client = NULL;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400906 }
907
Jonas Ådahl2cbf2932015-07-22 12:05:38 +0800908 pointer_client = find_pointer_client_for_view(pointer, view);
909 if (pointer_client && refocus) {
910 struct wl_client *surface_client = pointer_client->client;
Neil Roberts96d790e2013-09-19 17:32:00 +0100911
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400912 serial = wl_display_next_serial(display);
Neil Roberts96d790e2013-09-19 17:32:00 +0100913
Jason Ekstranda7af7042013-10-12 22:38:11 -0500914 if (kbd && kbd->focus != view->surface)
Kristian Høgsbergcb406f12013-10-09 10:54:03 -0700915 send_modifiers_to_client_in_list(surface_client,
916 &kbd->resource_list,
917 serial,
918 kbd);
919
Jonas Ådahl2cbf2932015-07-22 12:05:38 +0800920 pointer->focus_client = pointer_client;
Neil Roberts96d790e2013-09-19 17:32:00 +0100921
Jonas Ådahl2cbf2932015-07-22 12:05:38 +0800922 focus_resource_list = &pointer->focus_client->pointer_resources;
Neil Roberts96d790e2013-09-19 17:32:00 +0100923 wl_resource_for_each(resource, focus_resource_list) {
924 wl_pointer_send_enter(resource,
925 serial,
Jason Ekstranda7af7042013-10-12 22:38:11 -0500926 view->surface->resource,
Neil Roberts96d790e2013-09-19 17:32:00 +0100927 sx, sy);
Peter Hutterer87743e92016-01-18 16:38:22 +1000928 pointer_send_frame(resource);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400929 }
Neil Roberts96d790e2013-09-19 17:32:00 +0100930
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400931 pointer->focus_serial = serial;
932 }
933
Giulio Camuffo65a07f82013-12-06 12:46:27 +0100934 wl_list_remove(&pointer->focus_view_listener.link);
935 wl_list_init(&pointer->focus_view_listener.link);
936 wl_list_remove(&pointer->focus_resource_listener.link);
937 wl_list_init(&pointer->focus_resource_listener.link);
Emilio Pozuelo Monfortaa7a4762013-11-19 11:37:15 +0100938 if (view)
Giulio Camuffo576fe2a2013-11-20 18:00:24 +0100939 wl_signal_add(&view->destroy_signal, &pointer->focus_view_listener);
Giulio Camuffo65a07f82013-12-06 12:46:27 +0100940 if (view && view->surface->resource)
941 wl_resource_add_destroy_listener(view->surface->resource,
942 &pointer->focus_resource_listener);
943
944 pointer->focus = view;
945 pointer->focus_view_listener.notify = pointer_focus_view_destroyed;
Kristian Høgsbergdb1fccb2014-02-05 17:14:42 -0800946 pointer->sx = sx;
947 pointer->sy = sy;
948
Derek Foremanf9318d12015-05-11 15:40:11 -0500949 assert(view || sx == wl_fixed_from_int(-1000000));
950 assert(view || sy == wl_fixed_from_int(-1000000));
951
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400952 wl_signal_emit(&pointer->focus_signal, pointer);
953}
954
Neil Roberts96d790e2013-09-19 17:32:00 +0100955static void
956send_enter_to_resource_list(struct wl_list *list,
957 struct weston_keyboard *keyboard,
958 struct weston_surface *surface,
959 uint32_t serial)
960{
961 struct wl_resource *resource;
962
963 wl_resource_for_each(resource, list) {
964 send_modifiers_to_resource(keyboard, resource, serial);
965 wl_keyboard_send_enter(resource, serial,
966 surface->resource,
967 &keyboard->keys);
968 }
969}
970
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400971WL_EXPORT void
Kristian Høgsberg29139d42013-04-18 15:25:39 -0400972weston_keyboard_set_focus(struct weston_keyboard *keyboard,
Kristian Høgsbergfe7aa902013-05-08 09:54:37 -0400973 struct weston_surface *surface)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400974{
975 struct wl_resource *resource;
Rob Bradford880ebc72013-07-22 17:31:38 +0100976 struct wl_display *display = keyboard->seat->compositor->wl_display;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400977 uint32_t serial;
Neil Roberts96d790e2013-09-19 17:32:00 +0100978 struct wl_list *focus_resource_list;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400979
Neil Roberts96d790e2013-09-19 17:32:00 +0100980 focus_resource_list = &keyboard->focus_resource_list;
981
982 if (!wl_list_empty(focus_resource_list) && keyboard->focus != surface) {
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400983 serial = wl_display_next_serial(display);
Neil Roberts96d790e2013-09-19 17:32:00 +0100984 wl_resource_for_each(resource, focus_resource_list) {
985 wl_keyboard_send_leave(resource, serial,
986 keyboard->focus->resource);
987 }
988 move_resources(&keyboard->resource_list, focus_resource_list);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400989 }
990
Neil Roberts96d790e2013-09-19 17:32:00 +0100991 if (find_resource_for_surface(&keyboard->resource_list, surface) &&
992 keyboard->focus != surface) {
993 struct wl_client *surface_client =
994 wl_resource_get_client(surface->resource);
995
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400996 serial = wl_display_next_serial(display);
Neil Roberts96d790e2013-09-19 17:32:00 +0100997
998 move_resources_for_client(focus_resource_list,
999 &keyboard->resource_list,
1000 surface_client);
1001 send_enter_to_resource_list(focus_resource_list,
1002 keyboard,
1003 surface,
1004 serial);
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001005 keyboard->focus_serial = serial;
Giulio Camuffo65a07f82013-12-06 12:46:27 +01001006 }
1007
1008 wl_list_remove(&keyboard->focus_resource_listener.link);
1009 wl_list_init(&keyboard->focus_resource_listener.link);
1010 if (surface && surface->resource)
Giulio Camuffo576fe2a2013-11-20 18:00:24 +01001011 wl_resource_add_destroy_listener(surface->resource,
1012 &keyboard->focus_resource_listener);
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001013
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001014 keyboard->focus = surface;
1015 wl_signal_emit(&keyboard->focus_signal, keyboard);
1016}
1017
Giulio Camuffoa20ca812014-11-22 11:16:56 +02001018/* Users of this function must manually manage the keyboard focus */
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001019WL_EXPORT void
Kristian Høgsberg29139d42013-04-18 15:25:39 -04001020weston_keyboard_start_grab(struct weston_keyboard *keyboard,
1021 struct weston_keyboard_grab *grab)
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001022{
1023 keyboard->grab = grab;
1024 grab->keyboard = keyboard;
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001025}
1026
1027WL_EXPORT void
Kristian Høgsberg29139d42013-04-18 15:25:39 -04001028weston_keyboard_end_grab(struct weston_keyboard *keyboard)
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001029{
1030 keyboard->grab = &keyboard->default_grab;
1031}
1032
Jonas Ådahl1ea343e2013-10-25 23:18:05 +02001033static void
1034weston_keyboard_cancel_grab(struct weston_keyboard *keyboard)
1035{
1036 keyboard->grab->interface->cancel(keyboard->grab);
1037}
1038
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001039WL_EXPORT void
Kristian Høgsberg02bbabb2013-05-06 22:15:05 -04001040weston_pointer_start_grab(struct weston_pointer *pointer,
1041 struct weston_pointer_grab *grab)
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001042{
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001043 pointer->grab = grab;
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001044 grab->pointer = pointer;
Kristian Høgsbergda751b82013-07-04 00:58:07 -04001045 pointer->grab->interface->focus(pointer->grab);
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001046}
1047
1048WL_EXPORT void
Kristian Høgsberg02bbabb2013-05-06 22:15:05 -04001049weston_pointer_end_grab(struct weston_pointer *pointer)
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001050{
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001051 pointer->grab = &pointer->default_grab;
Kristian Høgsbergda751b82013-07-04 00:58:07 -04001052 pointer->grab->interface->focus(pointer->grab);
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001053}
1054
Jonas Ådahl1ea343e2013-10-25 23:18:05 +02001055static void
1056weston_pointer_cancel_grab(struct weston_pointer *pointer)
1057{
1058 pointer->grab->interface->cancel(pointer->grab);
1059}
1060
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001061WL_EXPORT void
Kristian Høgsberge329f362013-05-06 22:19:57 -04001062weston_touch_start_grab(struct weston_touch *touch, struct weston_touch_grab *grab)
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001063{
1064 touch->grab = grab;
1065 grab->touch = touch;
1066}
1067
1068WL_EXPORT void
Kristian Høgsberge329f362013-05-06 22:19:57 -04001069weston_touch_end_grab(struct weston_touch *touch)
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001070{
1071 touch->grab = &touch->default_grab;
1072}
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001073
Jonas Ådahl1ea343e2013-10-25 23:18:05 +02001074static void
1075weston_touch_cancel_grab(struct weston_touch *touch)
1076{
1077 touch->grab->interface->cancel(touch->grab);
1078}
1079
Ander Conselvan de Oliveira54e90c72013-12-13 22:10:56 +02001080static void
1081weston_pointer_clamp_for_output(struct weston_pointer *pointer,
1082 struct weston_output *output,
1083 wl_fixed_t *fx, wl_fixed_t *fy)
1084{
1085 int x, y;
1086
1087 x = wl_fixed_to_int(*fx);
1088 y = wl_fixed_to_int(*fy);
1089
1090 if (x < output->x)
1091 *fx = wl_fixed_from_int(output->x);
1092 else if (x >= output->x + output->width)
1093 *fx = wl_fixed_from_int(output->x +
1094 output->width - 1);
1095 if (y < output->y)
1096 *fy = wl_fixed_from_int(output->y);
1097 else if (y >= output->y + output->height)
1098 *fy = wl_fixed_from_int(output->y +
1099 output->height - 1);
1100}
1101
Rob Bradford806d8c02013-06-25 18:56:41 +01001102WL_EXPORT void
1103weston_pointer_clamp(struct weston_pointer *pointer, wl_fixed_t *fx, wl_fixed_t *fy)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001104{
Rob Bradford806d8c02013-06-25 18:56:41 +01001105 struct weston_compositor *ec = pointer->seat->compositor;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001106 struct weston_output *output, *prev = NULL;
1107 int x, y, old_x, old_y, valid = 0;
1108
1109 x = wl_fixed_to_int(*fx);
1110 y = wl_fixed_to_int(*fy);
Rob Bradford806d8c02013-06-25 18:56:41 +01001111 old_x = wl_fixed_to_int(pointer->x);
1112 old_y = wl_fixed_to_int(pointer->y);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001113
1114 wl_list_for_each(output, &ec->output_list, link) {
Rob Bradford66bd9f52013-06-25 18:56:42 +01001115 if (pointer->seat->output && pointer->seat->output != output)
1116 continue;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001117 if (pixman_region32_contains_point(&output->region,
1118 x, y, NULL))
1119 valid = 1;
1120 if (pixman_region32_contains_point(&output->region,
1121 old_x, old_y, NULL))
1122 prev = output;
1123 }
1124
Rob Bradford66bd9f52013-06-25 18:56:42 +01001125 if (!prev)
1126 prev = pointer->seat->output;
1127
Ander Conselvan de Oliveira54e90c72013-12-13 22:10:56 +02001128 if (prev && !valid)
1129 weston_pointer_clamp_for_output(pointer, prev, fx, fy);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001130}
1131
Jonas Ådahld2510102014-10-05 21:39:14 +02001132static void
1133weston_pointer_move_to(struct weston_pointer *pointer,
1134 wl_fixed_t x, wl_fixed_t y)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001135{
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001136 int32_t ix, iy;
1137
Rob Bradford806d8c02013-06-25 18:56:41 +01001138 weston_pointer_clamp (pointer, &x, &y);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001139
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001140 pointer->x = x;
1141 pointer->y = y;
1142
1143 ix = wl_fixed_to_int(x);
1144 iy = wl_fixed_to_int(y);
1145
Kristian Høgsberg195b8692013-05-08 15:02:05 -04001146 if (pointer->sprite) {
Jason Ekstranda7af7042013-10-12 22:38:11 -05001147 weston_view_set_position(pointer->sprite,
1148 ix - pointer->hotspot_x,
1149 iy - pointer->hotspot_y);
1150 weston_view_schedule_repaint(pointer->sprite);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001151 }
Giulio Camuffo6fcb3782013-11-14 23:42:50 +01001152
Giulio Camuffo1959ab82013-11-14 23:42:52 +01001153 pointer->grab->interface->focus(pointer->grab);
Giulio Camuffo6fcb3782013-11-14 23:42:50 +01001154 wl_signal_emit(&pointer->motion_signal, pointer);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001155}
1156
Jonas Ådahld2510102014-10-05 21:39:14 +02001157WL_EXPORT void
1158weston_pointer_motion_to_abs(struct weston_pointer *pointer,
1159 struct weston_pointer_motion_event *event,
1160 wl_fixed_t *x, wl_fixed_t *y)
1161{
1162 if (event->mask & WESTON_POINTER_MOTION_ABS) {
1163 *x = wl_fixed_from_double(event->x);
1164 *y = wl_fixed_from_double(event->y);
1165 } else if (event->mask & WESTON_POINTER_MOTION_REL) {
1166 *x = pointer->x + wl_fixed_from_double(event->dx);
1167 *y = pointer->y + wl_fixed_from_double(event->dy);
1168 } else {
1169 assert(!"invalid motion event");
1170 *x = *y = 0;
1171 }
1172}
1173
1174WL_EXPORT void
1175weston_pointer_move(struct weston_pointer *pointer,
1176 struct weston_pointer_motion_event *event)
1177{
1178 wl_fixed_t x, y;
1179
1180 weston_pointer_motion_to_abs(pointer, event, &x, &y);
1181 weston_pointer_move_to(pointer, x, y);
1182}
1183
Ander Conselvan de Oliveira54e90c72013-12-13 22:10:56 +02001184/** Verify if the pointer is in a valid position and move it if it isn't.
1185 */
Ander Conselvan de Oliveiraf84327a2014-01-29 18:47:51 +02001186static void
1187weston_pointer_handle_output_destroy(struct wl_listener *listener, void *data)
Ander Conselvan de Oliveira54e90c72013-12-13 22:10:56 +02001188{
Ander Conselvan de Oliveiraf84327a2014-01-29 18:47:51 +02001189 struct weston_pointer *pointer;
1190 struct weston_compositor *ec;
Ander Conselvan de Oliveira54e90c72013-12-13 22:10:56 +02001191 struct weston_output *output, *closest = NULL;
1192 int x, y, distance, min = INT_MAX;
1193 wl_fixed_t fx, fy;
1194
Ander Conselvan de Oliveiraf84327a2014-01-29 18:47:51 +02001195 pointer = container_of(listener, struct weston_pointer,
1196 output_destroy_listener);
1197 ec = pointer->seat->compositor;
1198
Ander Conselvan de Oliveira54e90c72013-12-13 22:10:56 +02001199 x = wl_fixed_to_int(pointer->x);
1200 y = wl_fixed_to_int(pointer->y);
1201
1202 wl_list_for_each(output, &ec->output_list, link) {
1203 if (pixman_region32_contains_point(&output->region,
1204 x, y, NULL))
1205 return;
1206
1207 /* Aproximante the distance from the pointer to the center of
1208 * the output. */
1209 distance = abs(output->x + output->width / 2 - x) +
1210 abs(output->y + output->height / 2 - y);
1211 if (distance < min) {
1212 min = distance;
1213 closest = output;
1214 }
1215 }
1216
1217 /* Nothing to do if there's no output left. */
1218 if (!closest)
1219 return;
1220
1221 fx = pointer->x;
1222 fy = pointer->y;
1223
1224 weston_pointer_clamp_for_output(pointer, closest, &fx, &fy);
Jonas Ådahld2510102014-10-05 21:39:14 +02001225 weston_pointer_move_to(pointer, fx, fy);
Ander Conselvan de Oliveira54e90c72013-12-13 22:10:56 +02001226}
1227
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001228WL_EXPORT void
1229notify_motion(struct weston_seat *seat,
Jonas Ådahld2510102014-10-05 21:39:14 +02001230 uint32_t time,
1231 struct weston_pointer_motion_event *event)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001232{
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001233 struct weston_compositor *ec = seat->compositor;
Derek Foreman1281a362015-07-31 16:55:32 -05001234 struct weston_pointer *pointer = weston_seat_get_pointer(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001235
1236 weston_compositor_wake(ec);
Jonas Ådahld2510102014-10-05 21:39:14 +02001237 pointer->grab->interface->motion(pointer->grab, time, event);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001238}
1239
Daniel Stone96d47c02013-11-19 11:37:12 +01001240static void
1241run_modifier_bindings(struct weston_seat *seat, uint32_t old, uint32_t new)
1242{
1243 struct weston_compositor *compositor = seat->compositor;
Derek Foreman1281a362015-07-31 16:55:32 -05001244 struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
Daniel Stone96d47c02013-11-19 11:37:12 +01001245 uint32_t diff;
1246 unsigned int i;
1247 struct {
1248 uint32_t xkb;
1249 enum weston_keyboard_modifier weston;
1250 } mods[] = {
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001251 { keyboard->xkb_info->ctrl_mod, MODIFIER_CTRL },
1252 { keyboard->xkb_info->alt_mod, MODIFIER_ALT },
1253 { keyboard->xkb_info->super_mod, MODIFIER_SUPER },
1254 { keyboard->xkb_info->shift_mod, MODIFIER_SHIFT },
Daniel Stone96d47c02013-11-19 11:37:12 +01001255 };
1256
1257 diff = new & ~old;
1258 for (i = 0; i < ARRAY_LENGTH(mods); i++) {
1259 if (diff & (1 << mods[i].xkb))
1260 weston_compositor_run_modifier_binding(compositor,
Derek Foreman99a6a2d2015-07-15 13:00:43 -05001261 keyboard,
Daniel Stone96d47c02013-11-19 11:37:12 +01001262 mods[i].weston,
1263 WL_KEYBOARD_KEY_STATE_PRESSED);
1264 }
1265
1266 diff = old & ~new;
1267 for (i = 0; i < ARRAY_LENGTH(mods); i++) {
1268 if (diff & (1 << mods[i].xkb))
1269 weston_compositor_run_modifier_binding(compositor,
Derek Foreman99a6a2d2015-07-15 13:00:43 -05001270 keyboard,
Daniel Stone96d47c02013-11-19 11:37:12 +01001271 mods[i].weston,
1272 WL_KEYBOARD_KEY_STATE_RELEASED);
1273 }
1274}
1275
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001276WL_EXPORT void
1277notify_motion_absolute(struct weston_seat *seat,
1278 uint32_t time, wl_fixed_t x, wl_fixed_t y)
1279{
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001280 struct weston_compositor *ec = seat->compositor;
Derek Foreman1281a362015-07-31 16:55:32 -05001281 struct weston_pointer *pointer = weston_seat_get_pointer(seat);
Jonas Ådahld2510102014-10-05 21:39:14 +02001282 struct weston_pointer_motion_event event = { 0 };
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001283
1284 weston_compositor_wake(ec);
Jonas Ådahld2510102014-10-05 21:39:14 +02001285
1286 event = (struct weston_pointer_motion_event) {
1287 .mask = WESTON_POINTER_MOTION_ABS,
1288 .x = wl_fixed_to_double(x),
1289 .y = wl_fixed_to_double(y),
1290 };
1291
1292 pointer->grab->interface->motion(pointer->grab, time, &event);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001293}
1294
1295WL_EXPORT void
1296weston_surface_activate(struct weston_surface *surface,
1297 struct weston_seat *seat)
1298{
1299 struct weston_compositor *compositor = seat->compositor;
Derek Foreman1281a362015-07-31 16:55:32 -05001300 struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001301
Derek Foreman1281a362015-07-31 16:55:32 -05001302 if (keyboard) {
1303 weston_keyboard_set_focus(keyboard, surface);
Kristian Høgsberge3148752013-05-06 23:19:49 -04001304 wl_data_device_set_keyboard_focus(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001305 }
1306
1307 wl_signal_emit(&compositor->activate_signal, surface);
1308}
1309
1310WL_EXPORT void
1311notify_button(struct weston_seat *seat, uint32_t time, int32_t button,
1312 enum wl_pointer_button_state state)
1313{
1314 struct weston_compositor *compositor = seat->compositor;
Derek Foreman1281a362015-07-31 16:55:32 -05001315 struct weston_pointer *pointer = weston_seat_get_pointer(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001316
1317 if (state == WL_POINTER_BUTTON_STATE_PRESSED) {
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001318 weston_compositor_idle_inhibit(compositor);
1319 if (pointer->button_count == 0) {
1320 pointer->grab_button = button;
1321 pointer->grab_time = time;
1322 pointer->grab_x = pointer->x;
1323 pointer->grab_y = pointer->y;
1324 }
1325 pointer->button_count++;
1326 } else {
1327 weston_compositor_idle_release(compositor);
1328 pointer->button_count--;
1329 }
1330
Derek Foreman99a6a2d2015-07-15 13:00:43 -05001331 weston_compositor_run_button_binding(compositor, pointer, time, button,
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001332 state);
1333
1334 pointer->grab->interface->button(pointer->grab, time, button, state);
1335
1336 if (pointer->button_count == 1)
1337 pointer->grab_serial =
1338 wl_display_get_serial(compositor->wl_display);
1339}
1340
1341WL_EXPORT void
Peter Hutterer89b6a492016-01-18 15:58:17 +10001342notify_axis(struct weston_seat *seat, uint32_t time,
1343 struct weston_pointer_axis_event *event)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001344{
1345 struct weston_compositor *compositor = seat->compositor;
Derek Foreman1281a362015-07-31 16:55:32 -05001346 struct weston_pointer *pointer = weston_seat_get_pointer(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001347
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001348 weston_compositor_wake(compositor);
1349
Derek Foreman99a6a2d2015-07-15 13:00:43 -05001350 if (weston_compositor_run_axis_binding(compositor, pointer,
Peter Hutterer89b6a492016-01-18 15:58:17 +10001351 time, event))
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001352 return;
1353
Peter Hutterer89b6a492016-01-18 15:58:17 +10001354 pointer->grab->interface->axis(pointer->grab, time, event);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001355}
1356
Peter Hutterer87743e92016-01-18 16:38:22 +10001357WL_EXPORT void
1358notify_axis_source(struct weston_seat *seat, uint32_t source)
1359{
1360 struct weston_compositor *compositor = seat->compositor;
1361 struct weston_pointer *pointer = weston_seat_get_pointer(seat);
1362
1363 weston_compositor_wake(compositor);
1364
1365 pointer->grab->interface->axis_source(pointer->grab, source);
1366}
1367
1368WL_EXPORT void
1369notify_pointer_frame(struct weston_seat *seat)
1370{
1371 struct weston_compositor *compositor = seat->compositor;
1372 struct weston_pointer *pointer = weston_seat_get_pointer(seat);
1373
1374 weston_compositor_wake(compositor);
1375
1376 pointer->grab->interface->frame(pointer->grab);
1377}
1378
Giulio Camuffo6ef444d2014-08-28 19:44:09 +03001379WL_EXPORT int
1380weston_keyboard_set_locks(struct weston_keyboard *keyboard,
1381 uint32_t mask, uint32_t value)
1382{
1383#ifdef ENABLE_XKBCOMMON
1384 uint32_t serial;
1385 xkb_mod_mask_t mods_depressed, mods_latched, mods_locked, group;
1386 xkb_mod_mask_t num, caps;
1387
1388 /* We don't want the leds to go out of sync with the actual state
1389 * so if the backend has no way to change the leds don't try to
1390 * change the state */
1391 if (!keyboard->seat->led_update)
1392 return -1;
1393
1394 mods_depressed = xkb_state_serialize_mods(keyboard->xkb_state.state,
1395 XKB_STATE_DEPRESSED);
1396 mods_latched = xkb_state_serialize_mods(keyboard->xkb_state.state,
1397 XKB_STATE_LATCHED);
1398 mods_locked = xkb_state_serialize_mods(keyboard->xkb_state.state,
1399 XKB_STATE_LOCKED);
1400 group = xkb_state_serialize_group(keyboard->xkb_state.state,
1401 XKB_STATE_EFFECTIVE);
1402
1403 num = (1 << keyboard->xkb_info->mod2_mod);
1404 caps = (1 << keyboard->xkb_info->caps_mod);
1405 if (mask & WESTON_NUM_LOCK) {
1406 if (value & WESTON_NUM_LOCK)
1407 mods_locked |= num;
1408 else
1409 mods_locked &= ~num;
1410 }
1411 if (mask & WESTON_CAPS_LOCK) {
1412 if (value & WESTON_CAPS_LOCK)
1413 mods_locked |= caps;
1414 else
1415 mods_locked &= ~caps;
1416 }
1417
1418 xkb_state_update_mask(keyboard->xkb_state.state, mods_depressed,
1419 mods_latched, mods_locked, 0, 0, group);
1420
1421 serial = wl_display_next_serial(
1422 keyboard->seat->compositor->wl_display);
1423 notify_modifiers(keyboard->seat, serial);
1424
1425 return 0;
1426#else
1427 return -1;
1428#endif
1429}
1430
Rob Bradford382ff462013-06-24 16:52:45 +01001431#ifdef ENABLE_XKBCOMMON
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001432WL_EXPORT void
1433notify_modifiers(struct weston_seat *seat, uint32_t serial)
1434{
Derek Foreman1281a362015-07-31 16:55:32 -05001435 struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001436 struct weston_keyboard_grab *grab = keyboard->grab;
1437 uint32_t mods_depressed, mods_latched, mods_locked, group;
1438 uint32_t mods_lookup;
1439 enum weston_led leds = 0;
1440 int changed = 0;
1441
1442 /* Serialize and update our internal state, checking to see if it's
1443 * different to the previous state. */
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001444 mods_depressed = xkb_state_serialize_mods(keyboard->xkb_state.state,
Ran Benita2e1968f2014-08-19 23:59:51 +03001445 XKB_STATE_MODS_DEPRESSED);
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001446 mods_latched = xkb_state_serialize_mods(keyboard->xkb_state.state,
Ran Benita2e1968f2014-08-19 23:59:51 +03001447 XKB_STATE_MODS_LATCHED);
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001448 mods_locked = xkb_state_serialize_mods(keyboard->xkb_state.state,
Ran Benita2e1968f2014-08-19 23:59:51 +03001449 XKB_STATE_MODS_LOCKED);
1450 group = xkb_state_serialize_layout(keyboard->xkb_state.state,
1451 XKB_STATE_LAYOUT_EFFECTIVE);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001452
Derek Foreman244e99e2015-06-03 15:53:26 -05001453 if (mods_depressed != keyboard->modifiers.mods_depressed ||
1454 mods_latched != keyboard->modifiers.mods_latched ||
1455 mods_locked != keyboard->modifiers.mods_locked ||
1456 group != keyboard->modifiers.group)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001457 changed = 1;
1458
Derek Foreman244e99e2015-06-03 15:53:26 -05001459 run_modifier_bindings(seat, keyboard->modifiers.mods_depressed,
Daniel Stone96d47c02013-11-19 11:37:12 +01001460 mods_depressed);
1461
Derek Foreman244e99e2015-06-03 15:53:26 -05001462 keyboard->modifiers.mods_depressed = mods_depressed;
1463 keyboard->modifiers.mods_latched = mods_latched;
1464 keyboard->modifiers.mods_locked = mods_locked;
1465 keyboard->modifiers.group = group;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001466
1467 /* And update the modifier_state for bindings. */
1468 mods_lookup = mods_depressed | mods_latched;
1469 seat->modifier_state = 0;
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001470 if (mods_lookup & (1 << keyboard->xkb_info->ctrl_mod))
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001471 seat->modifier_state |= MODIFIER_CTRL;
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001472 if (mods_lookup & (1 << keyboard->xkb_info->alt_mod))
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001473 seat->modifier_state |= MODIFIER_ALT;
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001474 if (mods_lookup & (1 << keyboard->xkb_info->super_mod))
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001475 seat->modifier_state |= MODIFIER_SUPER;
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001476 if (mods_lookup & (1 << keyboard->xkb_info->shift_mod))
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001477 seat->modifier_state |= MODIFIER_SHIFT;
1478
1479 /* Finally, notify the compositor that LEDs have changed. */
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001480 if (xkb_state_led_index_is_active(keyboard->xkb_state.state,
1481 keyboard->xkb_info->num_led))
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001482 leds |= LED_NUM_LOCK;
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001483 if (xkb_state_led_index_is_active(keyboard->xkb_state.state,
1484 keyboard->xkb_info->caps_led))
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001485 leds |= LED_CAPS_LOCK;
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001486 if (xkb_state_led_index_is_active(keyboard->xkb_state.state,
1487 keyboard->xkb_info->scroll_led))
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001488 leds |= LED_SCROLL_LOCK;
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001489 if (leds != keyboard->xkb_state.leds && seat->led_update)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001490 seat->led_update(seat, leds);
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001491 keyboard->xkb_state.leds = leds;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001492
1493 if (changed) {
1494 grab->interface->modifiers(grab,
1495 serial,
1496 keyboard->modifiers.mods_depressed,
1497 keyboard->modifiers.mods_latched,
1498 keyboard->modifiers.mods_locked,
1499 keyboard->modifiers.group);
1500 }
1501}
1502
1503static void
1504update_modifier_state(struct weston_seat *seat, uint32_t serial, uint32_t key,
1505 enum wl_keyboard_key_state state)
1506{
Derek Foreman1281a362015-07-31 16:55:32 -05001507 struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001508 enum xkb_key_direction direction;
1509
Matt Roper01a92732013-06-24 16:52:44 +01001510 /* Keyboard modifiers don't exist in raw keyboard mode */
1511 if (!seat->compositor->use_xkbcommon)
1512 return;
1513
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001514 if (state == WL_KEYBOARD_KEY_STATE_PRESSED)
1515 direction = XKB_KEY_DOWN;
1516 else
1517 direction = XKB_KEY_UP;
1518
1519 /* Offset the keycode by 8, as the evdev XKB rules reflect X's
1520 * broken keycode system, which starts at 8. */
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001521 xkb_state_update_key(keyboard->xkb_state.state, key + 8, direction);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001522
1523 notify_modifiers(seat, serial);
1524}
Rui Matos65196bc2013-10-10 19:44:19 +02001525
1526static void
1527send_keymap(struct wl_resource *resource, struct weston_xkb_info *xkb_info)
1528{
1529 wl_keyboard_send_keymap(resource,
1530 WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1,
1531 xkb_info->keymap_fd,
1532 xkb_info->keymap_size);
1533}
1534
1535static void
1536send_modifiers(struct wl_resource *resource, uint32_t serial, struct weston_keyboard *keyboard)
1537{
1538 wl_keyboard_send_modifiers(resource, serial,
1539 keyboard->modifiers.mods_depressed,
1540 keyboard->modifiers.mods_latched,
1541 keyboard->modifiers.mods_locked,
1542 keyboard->modifiers.group);
1543}
1544
1545static struct weston_xkb_info *
1546weston_xkb_info_create(struct xkb_keymap *keymap);
Rui Matos65196bc2013-10-10 19:44:19 +02001547
1548static void
1549update_keymap(struct weston_seat *seat)
1550{
Derek Foreman1281a362015-07-31 16:55:32 -05001551 struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
Rui Matos65196bc2013-10-10 19:44:19 +02001552 struct wl_resource *resource;
1553 struct weston_xkb_info *xkb_info;
1554 struct xkb_state *state;
1555 xkb_mod_mask_t latched_mods;
1556 xkb_mod_mask_t locked_mods;
1557
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001558 xkb_info = weston_xkb_info_create(keyboard->pending_keymap);
Rui Matos65196bc2013-10-10 19:44:19 +02001559
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001560 xkb_keymap_unref(keyboard->pending_keymap);
1561 keyboard->pending_keymap = NULL;
Rui Matos65196bc2013-10-10 19:44:19 +02001562
1563 if (!xkb_info) {
1564 weston_log("failed to create XKB info\n");
1565 return;
1566 }
1567
1568 state = xkb_state_new(xkb_info->keymap);
1569 if (!state) {
1570 weston_log("failed to initialise XKB state\n");
1571 weston_xkb_info_destroy(xkb_info);
1572 return;
1573 }
1574
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001575 latched_mods = xkb_state_serialize_mods(keyboard->xkb_state.state,
1576 XKB_STATE_MODS_LATCHED);
1577 locked_mods = xkb_state_serialize_mods(keyboard->xkb_state.state,
1578 XKB_STATE_MODS_LOCKED);
Rui Matos65196bc2013-10-10 19:44:19 +02001579 xkb_state_update_mask(state,
1580 0, /* depressed */
1581 latched_mods,
1582 locked_mods,
1583 0, 0, 0);
1584
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001585 weston_xkb_info_destroy(keyboard->xkb_info);
1586 keyboard->xkb_info = xkb_info;
Rui Matos65196bc2013-10-10 19:44:19 +02001587
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001588 xkb_state_unref(keyboard->xkb_state.state);
1589 keyboard->xkb_state.state = state;
Rui Matos65196bc2013-10-10 19:44:19 +02001590
Derek Foremanbc91e542015-06-03 15:53:27 -05001591 wl_resource_for_each(resource, &keyboard->resource_list)
Rui Matos65196bc2013-10-10 19:44:19 +02001592 send_keymap(resource, xkb_info);
Derek Foremanbc91e542015-06-03 15:53:27 -05001593 wl_resource_for_each(resource, &keyboard->focus_resource_list)
Rui Matos65196bc2013-10-10 19:44:19 +02001594 send_keymap(resource, xkb_info);
1595
1596 notify_modifiers(seat, wl_display_next_serial(seat->compositor->wl_display));
1597
1598 if (!latched_mods && !locked_mods)
1599 return;
1600
Derek Foremanbc91e542015-06-03 15:53:27 -05001601 wl_resource_for_each(resource, &keyboard->resource_list)
1602 send_modifiers(resource, wl_display_get_serial(seat->compositor->wl_display), keyboard);
1603 wl_resource_for_each(resource, &keyboard->focus_resource_list)
1604 send_modifiers(resource, wl_display_get_serial(seat->compositor->wl_display), keyboard);
Rui Matos65196bc2013-10-10 19:44:19 +02001605}
Rob Bradford382ff462013-06-24 16:52:45 +01001606#else
1607WL_EXPORT void
1608notify_modifiers(struct weston_seat *seat, uint32_t serial)
1609{
1610}
1611
1612static void
1613update_modifier_state(struct weston_seat *seat, uint32_t serial, uint32_t key,
1614 enum wl_keyboard_key_state state)
1615{
1616}
Rui Matos65196bc2013-10-10 19:44:19 +02001617
1618static void
1619update_keymap(struct weston_seat *seat)
1620{
1621}
Rob Bradford382ff462013-06-24 16:52:45 +01001622#endif
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001623
1624WL_EXPORT void
1625notify_key(struct weston_seat *seat, uint32_t time, uint32_t key,
1626 enum wl_keyboard_key_state state,
1627 enum weston_key_state_update update_state)
1628{
1629 struct weston_compositor *compositor = seat->compositor;
Derek Foreman1281a362015-07-31 16:55:32 -05001630 struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001631 struct weston_keyboard_grab *grab = keyboard->grab;
Pekka Paalanen86b53962014-11-19 13:43:32 +02001632 uint32_t *k, *end;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001633
1634 if (state == WL_KEYBOARD_KEY_STATE_PRESSED) {
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001635 weston_compositor_idle_inhibit(compositor);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001636 } else {
1637 weston_compositor_idle_release(compositor);
1638 }
1639
Pekka Paalanen86b53962014-11-19 13:43:32 +02001640 end = keyboard->keys.data + keyboard->keys.size;
1641 for (k = keyboard->keys.data; k < end; k++) {
1642 if (*k == key) {
1643 /* Ignore server-generated repeats. */
1644 if (state == WL_KEYBOARD_KEY_STATE_PRESSED)
1645 return;
1646 *k = *--end;
1647 }
1648 }
1649 keyboard->keys.size = (void *) end - keyboard->keys.data;
1650 if (state == WL_KEYBOARD_KEY_STATE_PRESSED) {
1651 k = wl_array_add(&keyboard->keys, sizeof *k);
1652 *k = key;
1653 }
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001654
1655 if (grab == &keyboard->default_grab ||
1656 grab == &keyboard->input_method_grab) {
Derek Foreman99a6a2d2015-07-15 13:00:43 -05001657 weston_compositor_run_key_binding(compositor, keyboard, time,
1658 key, state);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001659 grab = keyboard->grab;
1660 }
1661
1662 grab->interface->key(grab, time, key, state);
1663
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001664 if (keyboard->pending_keymap &&
Pekka Paalanen86b53962014-11-19 13:43:32 +02001665 keyboard->keys.size == 0)
Rui Matos65196bc2013-10-10 19:44:19 +02001666 update_keymap(seat);
1667
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001668 if (update_state == STATE_UPDATE_AUTOMATIC) {
1669 update_modifier_state(seat,
1670 wl_display_get_serial(compositor->wl_display),
1671 key,
1672 state);
1673 }
Giulio Camuffob6ddf6c2015-02-06 19:06:54 +02001674
1675 if (state == WL_KEYBOARD_KEY_STATE_PRESSED) {
1676 keyboard->grab_serial =
1677 wl_display_get_serial(compositor->wl_display);
1678 keyboard->grab_time = time;
1679 keyboard->grab_key = key;
1680 }
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001681}
1682
1683WL_EXPORT void
1684notify_pointer_focus(struct weston_seat *seat, struct weston_output *output,
1685 wl_fixed_t x, wl_fixed_t y)
1686{
Derek Foreman1281a362015-07-31 16:55:32 -05001687 struct weston_pointer *pointer = weston_seat_get_pointer(seat);
1688
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001689 if (output) {
Jonas Ådahld2510102014-10-05 21:39:14 +02001690 weston_pointer_move_to(pointer, x, y);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001691 } else {
Kristian Høgsberg02bbabb2013-05-06 22:15:05 -04001692 /* FIXME: We should call weston_pointer_set_focus(seat,
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001693 * NULL) here, but somehow that breaks re-entry... */
1694 }
1695}
1696
1697static void
1698destroy_device_saved_kbd_focus(struct wl_listener *listener, void *data)
1699{
1700 struct weston_seat *ws;
1701
1702 ws = container_of(listener, struct weston_seat,
1703 saved_kbd_focus_listener);
1704
1705 ws->saved_kbd_focus = NULL;
1706}
1707
1708WL_EXPORT void
1709notify_keyboard_focus_in(struct weston_seat *seat, struct wl_array *keys,
1710 enum weston_key_state_update update_state)
1711{
1712 struct weston_compositor *compositor = seat->compositor;
Derek Foreman1281a362015-07-31 16:55:32 -05001713 struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
Kristian Høgsbergfe7aa902013-05-08 09:54:37 -04001714 struct weston_surface *surface;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001715 uint32_t *k, serial;
1716
1717 serial = wl_display_next_serial(compositor->wl_display);
1718 wl_array_copy(&keyboard->keys, keys);
1719 wl_array_for_each(k, &keyboard->keys) {
1720 weston_compositor_idle_inhibit(compositor);
1721 if (update_state == STATE_UPDATE_AUTOMATIC)
1722 update_modifier_state(seat, serial, *k,
1723 WL_KEYBOARD_KEY_STATE_PRESSED);
1724 }
1725
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001726 surface = seat->saved_kbd_focus;
1727
1728 if (surface) {
1729 wl_list_remove(&seat->saved_kbd_focus_listener.link);
1730 weston_keyboard_set_focus(keyboard, surface);
1731 seat->saved_kbd_focus = NULL;
1732 }
1733}
1734
1735WL_EXPORT void
1736notify_keyboard_focus_out(struct weston_seat *seat)
1737{
1738 struct weston_compositor *compositor = seat->compositor;
Derek Foreman1281a362015-07-31 16:55:32 -05001739 struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
1740 struct weston_pointer *pointer = weston_seat_get_pointer(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001741 uint32_t *k, serial;
1742
1743 serial = wl_display_next_serial(compositor->wl_display);
1744 wl_array_for_each(k, &keyboard->keys) {
1745 weston_compositor_idle_release(compositor);
1746 update_modifier_state(seat, serial, *k,
1747 WL_KEYBOARD_KEY_STATE_RELEASED);
1748 }
1749
1750 seat->modifier_state = 0;
1751
1752 if (keyboard->focus) {
1753 seat->saved_kbd_focus = keyboard->focus;
1754 seat->saved_kbd_focus_listener.notify =
1755 destroy_device_saved_kbd_focus;
Jason Ekstrand26ed73c2013-06-06 22:34:41 -05001756 wl_signal_add(&keyboard->focus->destroy_signal,
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001757 &seat->saved_kbd_focus_listener);
1758 }
1759
1760 weston_keyboard_set_focus(keyboard, NULL);
Jonas Ådahl1ea343e2013-10-25 23:18:05 +02001761 weston_keyboard_cancel_grab(keyboard);
Derek Foreman1281a362015-07-31 16:55:32 -05001762 if (pointer)
1763 weston_pointer_cancel_grab(pointer);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001764}
1765
Michael Fua2bb7912013-07-23 15:51:06 +08001766WL_EXPORT void
Derek Foreman4c93c082015-04-30 16:45:41 -05001767weston_touch_set_focus(struct weston_touch *touch, struct weston_view *view)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001768{
Neil Roberts96d790e2013-09-19 17:32:00 +01001769 struct wl_list *focus_resource_list;
1770
Derek Foreman4c93c082015-04-30 16:45:41 -05001771 focus_resource_list = &touch->focus_resource_list;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001772
Derek Foreman4c93c082015-04-30 16:45:41 -05001773 if (view && touch->focus &&
1774 touch->focus->surface == view->surface) {
1775 touch->focus = view;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001776 return;
Jason Ekstranda7af7042013-10-12 22:38:11 -05001777 }
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001778
Derek Foreman4c93c082015-04-30 16:45:41 -05001779 wl_list_remove(&touch->focus_resource_listener.link);
1780 wl_list_init(&touch->focus_resource_listener.link);
1781 wl_list_remove(&touch->focus_view_listener.link);
1782 wl_list_init(&touch->focus_view_listener.link);
Giulio Camuffo576fe2a2013-11-20 18:00:24 +01001783
Neil Roberts96d790e2013-09-19 17:32:00 +01001784 if (!wl_list_empty(focus_resource_list)) {
Derek Foreman4c93c082015-04-30 16:45:41 -05001785 move_resources(&touch->resource_list,
Neil Roberts96d790e2013-09-19 17:32:00 +01001786 focus_resource_list);
1787 }
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001788
Jason Ekstranda7af7042013-10-12 22:38:11 -05001789 if (view) {
Derek Foreman362656b2014-09-04 10:23:05 -05001790 struct wl_client *surface_client;
1791
1792 if (!view->surface->resource) {
Derek Foreman4c93c082015-04-30 16:45:41 -05001793 touch->focus = NULL;
Derek Foreman362656b2014-09-04 10:23:05 -05001794 return;
1795 }
1796
1797 surface_client = wl_resource_get_client(view->surface->resource);
Neil Roberts96d790e2013-09-19 17:32:00 +01001798 move_resources_for_client(focus_resource_list,
Derek Foreman4c93c082015-04-30 16:45:41 -05001799 &touch->resource_list,
Neil Roberts96d790e2013-09-19 17:32:00 +01001800 surface_client);
Giulio Camuffo576fe2a2013-11-20 18:00:24 +01001801 wl_resource_add_destroy_listener(view->surface->resource,
Derek Foreman4c93c082015-04-30 16:45:41 -05001802 &touch->focus_resource_listener);
1803 wl_signal_add(&view->destroy_signal, &touch->focus_view_listener);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001804 }
Derek Foreman4c93c082015-04-30 16:45:41 -05001805 touch->focus = view;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001806}
1807
1808/**
1809 * notify_touch - emulates button touches and notifies surfaces accordingly.
1810 *
1811 * It assumes always the correct cycle sequence until it gets here: touch_down
1812 * → touch_update → ... → touch_update → touch_end. The driver is responsible
1813 * for sending along such order.
1814 *
1815 */
1816WL_EXPORT void
1817notify_touch(struct weston_seat *seat, uint32_t time, int touch_id,
1818 wl_fixed_t x, wl_fixed_t y, int touch_type)
1819{
1820 struct weston_compositor *ec = seat->compositor;
Derek Foreman1281a362015-07-31 16:55:32 -05001821 struct weston_touch *touch = weston_seat_get_touch(seat);
Kristian Høgsberge329f362013-05-06 22:19:57 -04001822 struct weston_touch_grab *grab = touch->grab;
Jason Ekstranda7af7042013-10-12 22:38:11 -05001823 struct weston_view *ev;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001824 wl_fixed_t sx, sy;
1825
1826 /* Update grab's global coordinates. */
Neil Roberts306fe082013-10-03 16:43:06 +01001827 if (touch_id == touch->grab_touch_id && touch_type != WL_TOUCH_UP) {
1828 touch->grab_x = x;
1829 touch->grab_y = y;
1830 }
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001831
1832 switch (touch_type) {
1833 case WL_TOUCH_DOWN:
1834 weston_compositor_idle_inhibit(ec);
1835
Jonas Ådahl9484b692013-12-02 22:05:03 +01001836 touch->num_tp++;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001837
Jason Ekstranda7af7042013-10-12 22:38:11 -05001838 /* the first finger down picks the view, and all further go
1839 * to that view for the remainder of the touch session i.e.
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001840 * until all touch points are up again. */
Jonas Ådahl9484b692013-12-02 22:05:03 +01001841 if (touch->num_tp == 1) {
Jason Ekstranda7af7042013-10-12 22:38:11 -05001842 ev = weston_compositor_pick_view(ec, x, y, &sx, &sy);
Derek Foreman4c93c082015-04-30 16:45:41 -05001843 weston_touch_set_focus(touch, ev);
Giulio Camuffo61ed7b62015-07-08 11:55:28 +03001844 } else if (!touch->focus) {
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001845 /* Unexpected condition: We have non-initial touch but
1846 * there is no focused surface.
1847 */
Chris Michael3f607d32015-10-07 11:59:49 -04001848 weston_log("touch event received with %d points down "
Jonas Ådahl9484b692013-12-02 22:05:03 +01001849 "but no surface focused\n", touch->num_tp);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001850 return;
1851 }
1852
Derek Foreman99a6a2d2015-07-15 13:00:43 -05001853 weston_compositor_run_touch_binding(ec, touch,
Kristian Høgsbergc8964012014-02-05 14:25:18 -08001854 time, touch_type);
1855
Giulio Camuffo61ed7b62015-07-08 11:55:28 +03001856 grab->interface->down(grab, time, touch_id, x, y);
Jonas Ådahl9484b692013-12-02 22:05:03 +01001857 if (touch->num_tp == 1) {
Rusty Lynchf1407ff2013-08-08 21:13:57 -07001858 touch->grab_serial =
1859 wl_display_get_serial(ec->wl_display);
Neil Roberts306fe082013-10-03 16:43:06 +01001860 touch->grab_touch_id = touch_id;
Rusty Lynchf1407ff2013-08-08 21:13:57 -07001861 touch->grab_time = time;
1862 touch->grab_x = x;
1863 touch->grab_y = y;
1864 }
1865
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001866 break;
1867 case WL_TOUCH_MOTION:
Jason Ekstranda7af7042013-10-12 22:38:11 -05001868 ev = touch->focus;
1869 if (!ev)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001870 break;
1871
Giulio Camuffo61ed7b62015-07-08 11:55:28 +03001872 grab->interface->motion(grab, time, touch_id, x, y);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001873 break;
1874 case WL_TOUCH_UP:
Kristian Høgsberga30e29a2014-01-08 22:29:20 -08001875 if (touch->num_tp == 0) {
1876 /* This can happen if we start out with one or
1877 * more fingers on the touch screen, in which
1878 * case we didn't get the corresponding down
1879 * event. */
1880 weston_log("unmatched touch up event\n");
1881 break;
1882 }
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001883 weston_compositor_idle_release(ec);
Jonas Ådahl9484b692013-12-02 22:05:03 +01001884 touch->num_tp--;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001885
1886 grab->interface->up(grab, time, touch_id);
Jonas Ådahl9484b692013-12-02 22:05:03 +01001887 if (touch->num_tp == 0)
Derek Foreman4c93c082015-04-30 16:45:41 -05001888 weston_touch_set_focus(touch, NULL);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001889 break;
1890 }
1891}
1892
Jonas Ådahl1679f232014-04-12 09:39:51 +02001893WL_EXPORT void
1894notify_touch_frame(struct weston_seat *seat)
1895{
Derek Foreman1281a362015-07-31 16:55:32 -05001896 struct weston_touch *touch = weston_seat_get_touch(seat);
Jonas Ådahl1679f232014-04-12 09:39:51 +02001897 struct weston_touch_grab *grab = touch->grab;
1898
1899 grab->interface->frame(grab);
1900}
1901
Derek Foreman3cc004a2015-11-06 15:56:09 -06001902WL_EXPORT void
1903notify_touch_cancel(struct weston_seat *seat)
1904{
1905 struct weston_touch *touch = weston_seat_get_touch(seat);
1906 struct weston_touch_grab *grab = touch->grab;
1907
1908 grab->interface->cancel(grab);
1909}
1910
Pekka Paalanen8274d902014-08-06 19:36:51 +03001911static int
1912pointer_cursor_surface_get_label(struct weston_surface *surface,
1913 char *buf, size_t len)
1914{
1915 return snprintf(buf, len, "cursor");
1916}
1917
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001918static void
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001919pointer_cursor_surface_configure(struct weston_surface *es,
Jason Ekstrand918f2dd2013-12-02 21:01:53 -06001920 int32_t dx, int32_t dy)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001921{
Kristian Høgsberg195b8692013-05-08 15:02:05 -04001922 struct weston_pointer *pointer = es->configure_private;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001923 int x, y;
1924
Jason Ekstrand918f2dd2013-12-02 21:01:53 -06001925 if (es->width == 0)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001926 return;
1927
Jason Ekstranda7af7042013-10-12 22:38:11 -05001928 assert(es == pointer->sprite->surface);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001929
Kristian Høgsberg195b8692013-05-08 15:02:05 -04001930 pointer->hotspot_x -= dx;
1931 pointer->hotspot_y -= dy;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001932
Kristian Høgsberg195b8692013-05-08 15:02:05 -04001933 x = wl_fixed_to_int(pointer->x) - pointer->hotspot_x;
1934 y = wl_fixed_to_int(pointer->y) - pointer->hotspot_y;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001935
Jason Ekstrand918f2dd2013-12-02 21:01:53 -06001936 weston_view_set_position(pointer->sprite, x, y);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001937
1938 empty_region(&es->pending.input);
Ander Conselvan de Oliveira23900f72014-01-31 16:07:51 +02001939 empty_region(&es->input);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001940
1941 if (!weston_surface_is_mapped(es)) {
Giulio Camuffo412e6a52014-07-09 22:12:56 +03001942 weston_layer_entry_insert(&es->compositor->cursor_layer.view_list,
1943 &pointer->sprite->layer_link);
Jason Ekstranda7af7042013-10-12 22:38:11 -05001944 weston_view_update_transform(pointer->sprite);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001945 }
1946}
1947
1948static void
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001949pointer_set_cursor(struct wl_client *client, struct wl_resource *resource,
1950 uint32_t serial, struct wl_resource *surface_resource,
1951 int32_t x, int32_t y)
1952{
Jason Ekstrand44a38632013-06-14 10:08:00 -05001953 struct weston_pointer *pointer = wl_resource_get_user_data(resource);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001954 struct weston_surface *surface = NULL;
1955
1956 if (surface_resource)
Jason Ekstrand0f2ef7e2013-06-14 10:07:53 -05001957 surface = wl_resource_get_user_data(surface_resource);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001958
Kristian Høgsberg195b8692013-05-08 15:02:05 -04001959 if (pointer->focus == NULL)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001960 return;
Jason Ekstranda7af7042013-10-12 22:38:11 -05001961 /* pointer->focus->surface->resource can be NULL. Surfaces like the
Giulio Camuffo1fd4b012013-06-20 18:13:07 +02001962 black_surface used in shell.c for fullscreen don't have
1963 a resource, but can still have focus */
Jason Ekstranda7af7042013-10-12 22:38:11 -05001964 if (pointer->focus->surface->resource == NULL)
Giulio Camuffo1fd4b012013-06-20 18:13:07 +02001965 return;
Jason Ekstranda7af7042013-10-12 22:38:11 -05001966 if (wl_resource_get_client(pointer->focus->surface->resource) != client)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001967 return;
Kristian Høgsberg195b8692013-05-08 15:02:05 -04001968 if (pointer->focus_serial - serial > UINT32_MAX / 2)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001969 return;
1970
Derek Foreman4e53c532015-03-23 10:55:32 -05001971 if (!surface) {
1972 if (pointer->sprite)
1973 pointer_unmap_sprite(pointer);
1974 return;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001975 }
1976
Jonas Ådahlb4070242015-03-18 15:08:03 +08001977 if (pointer->sprite && pointer->sprite->surface == surface &&
1978 pointer->hotspot_x == x && pointer->hotspot_y == y)
1979 return;
1980
Derek Foreman4e53c532015-03-23 10:55:32 -05001981 if (!pointer->sprite || pointer->sprite->surface != surface) {
1982 if (weston_surface_set_role(surface, "wl_pointer-cursor",
1983 resource,
1984 WL_POINTER_ERROR_ROLE) < 0)
1985 return;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001986
Derek Foreman4e53c532015-03-23 10:55:32 -05001987 if (pointer->sprite)
1988 pointer_unmap_sprite(pointer);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001989
Derek Foreman4e53c532015-03-23 10:55:32 -05001990 wl_signal_add(&surface->destroy_signal,
1991 &pointer->sprite_destroy_listener);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001992
Derek Foreman4e53c532015-03-23 10:55:32 -05001993 surface->configure = pointer_cursor_surface_configure;
1994 surface->configure_private = pointer;
1995 weston_surface_set_label_func(surface,
1996 pointer_cursor_surface_get_label);
1997 pointer->sprite = weston_view_create(surface);
1998 }
1999
Kristian Høgsberg195b8692013-05-08 15:02:05 -04002000 pointer->hotspot_x = x;
2001 pointer->hotspot_y = y;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002002
Jonas Ådahl16fe4dc2014-09-08 19:33:41 +02002003 if (surface->buffer_ref.buffer) {
Jason Ekstrand918f2dd2013-12-02 21:01:53 -06002004 pointer_cursor_surface_configure(surface, 0, 0);
Jonas Ådahl16fe4dc2014-09-08 19:33:41 +02002005 weston_view_schedule_repaint(pointer->sprite);
2006 }
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002007}
2008
Kristian Høgsberg69e25fc2013-08-13 20:11:02 +01002009static void
2010pointer_release(struct wl_client *client, struct wl_resource *resource)
2011{
2012 wl_resource_destroy(resource);
2013}
2014
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002015static const struct wl_pointer_interface pointer_interface = {
Kristian Høgsberg69e25fc2013-08-13 20:11:02 +01002016 pointer_set_cursor,
2017 pointer_release
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002018};
2019
2020static void
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002021seat_get_pointer(struct wl_client *client, struct wl_resource *resource,
2022 uint32_t id)
2023{
Jason Ekstrand44a38632013-06-14 10:08:00 -05002024 struct weston_seat *seat = wl_resource_get_user_data(resource);
Derek Foreman1281a362015-07-31 16:55:32 -05002025 /* We use the pointer_state directly, which means we'll
2026 * give a wl_pointer if the seat has ever had one - even though
2027 * the spec explicitly states that this request only takes effect
2028 * if the seat has the pointer capability.
2029 *
2030 * This prevents a race between the compositor sending new
2031 * capabilities and the client trying to use the old ones.
2032 */
2033 struct weston_pointer *pointer = seat->pointer_state;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002034 struct wl_resource *cr;
Jonas Ådahl2cbf2932015-07-22 12:05:38 +08002035 struct weston_pointer_client *pointer_client;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002036
Derek Foreman1281a362015-07-31 16:55:32 -05002037 if (!pointer)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002038 return;
2039
Jason Ekstranda85118c2013-06-27 20:17:02 -05002040 cr = wl_resource_create(client, &wl_pointer_interface,
2041 wl_resource_get_version(resource), id);
Kristian Høgsberg0ff79082013-08-06 16:46:25 -07002042 if (cr == NULL) {
2043 wl_client_post_no_memory(client);
2044 return;
2045 }
2046
Jonas Ådahl2cbf2932015-07-22 12:05:38 +08002047 pointer_client = weston_pointer_ensure_pointer_client(pointer, client);
2048 if (!pointer_client) {
2049 wl_client_post_no_memory(client);
2050 return;
2051 }
2052
2053 wl_list_insert(&pointer_client->pointer_resources,
2054 wl_resource_get_link(cr));
Derek Foreman1281a362015-07-31 16:55:32 -05002055 wl_resource_set_implementation(cr, &pointer_interface, pointer,
Jonas Ådahl2cbf2932015-07-22 12:05:38 +08002056 unbind_pointer_client_resource);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002057
Derek Foreman1281a362015-07-31 16:55:32 -05002058 if (pointer->focus && pointer->focus->surface->resource &&
2059 wl_resource_get_client(pointer->focus->surface->resource) == client) {
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002060 wl_fixed_t sx, sy;
2061
Derek Foreman1281a362015-07-31 16:55:32 -05002062 weston_view_from_global_fixed(pointer->focus,
2063 pointer->x,
2064 pointer->y,
Jason Ekstranda7af7042013-10-12 22:38:11 -05002065 &sx, &sy);
Neil Roberts96d790e2013-09-19 17:32:00 +01002066
Neil Roberts96d790e2013-09-19 17:32:00 +01002067 wl_pointer_send_enter(cr,
Derek Foreman1281a362015-07-31 16:55:32 -05002068 pointer->focus_serial,
2069 pointer->focus->surface->resource,
Neil Roberts96d790e2013-09-19 17:32:00 +01002070 sx, sy);
Peter Hutterer87743e92016-01-18 16:38:22 +10002071 pointer_send_frame(cr);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002072 }
2073}
2074
2075static void
Kristian Høgsberg69e25fc2013-08-13 20:11:02 +01002076keyboard_release(struct wl_client *client, struct wl_resource *resource)
2077{
2078 wl_resource_destroy(resource);
2079}
2080
2081static const struct wl_keyboard_interface keyboard_interface = {
2082 keyboard_release
2083};
2084
Derek Foreman280e7dd2014-10-03 13:13:42 -05002085static bool
Neil Roberts96d790e2013-09-19 17:32:00 +01002086should_send_modifiers_to_client(struct weston_seat *seat,
2087 struct wl_client *client)
2088{
Derek Foreman1281a362015-07-31 16:55:32 -05002089 struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
2090 struct weston_pointer *pointer = weston_seat_get_pointer(seat);
2091
2092 if (keyboard &&
2093 keyboard->focus &&
2094 keyboard->focus->resource &&
2095 wl_resource_get_client(keyboard->focus->resource) == client)
Derek Foreman280e7dd2014-10-03 13:13:42 -05002096 return true;
Neil Roberts96d790e2013-09-19 17:32:00 +01002097
Derek Foreman1281a362015-07-31 16:55:32 -05002098 if (pointer &&
2099 pointer->focus &&
2100 pointer->focus->surface->resource &&
2101 wl_resource_get_client(pointer->focus->surface->resource) == client)
Derek Foreman280e7dd2014-10-03 13:13:42 -05002102 return true;
Neil Roberts96d790e2013-09-19 17:32:00 +01002103
Derek Foreman280e7dd2014-10-03 13:13:42 -05002104 return false;
Neil Roberts96d790e2013-09-19 17:32:00 +01002105}
2106
Kristian Høgsberg69e25fc2013-08-13 20:11:02 +01002107static void
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002108seat_get_keyboard(struct wl_client *client, struct wl_resource *resource,
2109 uint32_t id)
2110{
Jason Ekstrand44a38632013-06-14 10:08:00 -05002111 struct weston_seat *seat = wl_resource_get_user_data(resource);
Derek Foreman1281a362015-07-31 16:55:32 -05002112 /* We use the keyboard_state directly, which means we'll
2113 * give a wl_keyboard if the seat has ever had one - even though
2114 * the spec explicitly states that this request only takes effect
2115 * if the seat has the keyboard capability.
2116 *
2117 * This prevents a race between the compositor sending new
2118 * capabilities and the client trying to use the old ones.
2119 */
2120 struct weston_keyboard *keyboard = seat->keyboard_state;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002121 struct wl_resource *cr;
2122
Derek Foreman345c9f32015-06-03 15:53:28 -05002123 if (!keyboard)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002124 return;
2125
Jason Ekstranda85118c2013-06-27 20:17:02 -05002126 cr = wl_resource_create(client, &wl_keyboard_interface,
2127 wl_resource_get_version(resource), id);
Kristian Høgsberg0ff79082013-08-06 16:46:25 -07002128 if (cr == NULL) {
2129 wl_client_post_no_memory(client);
2130 return;
2131 }
2132
Neil Roberts96d790e2013-09-19 17:32:00 +01002133 /* May be moved to focused list later by either
2134 * weston_keyboard_set_focus or directly if this client is already
2135 * focused */
Derek Foreman345c9f32015-06-03 15:53:28 -05002136 wl_list_insert(&keyboard->resource_list, wl_resource_get_link(cr));
Kristian Høgsberg69e25fc2013-08-13 20:11:02 +01002137 wl_resource_set_implementation(cr, &keyboard_interface,
2138 seat, unbind_resource);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002139
Jonny Lamb66a41a02014-08-12 14:58:25 +02002140 if (wl_resource_get_version(cr) >= WL_KEYBOARD_REPEAT_INFO_SINCE_VERSION) {
2141 wl_keyboard_send_repeat_info(cr,
2142 seat->compositor->kb_repeat_rate,
2143 seat->compositor->kb_repeat_delay);
2144 }
Jasper St. Pierred8c6aeb2014-08-04 13:43:24 -04002145
Matt Roper01a92732013-06-24 16:52:44 +01002146 if (seat->compositor->use_xkbcommon) {
2147 wl_keyboard_send_keymap(cr, WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1,
Jonas Ådahl7395ea02013-12-03 09:14:26 +01002148 keyboard->xkb_info->keymap_fd,
2149 keyboard->xkb_info->keymap_size);
Matt Roper01a92732013-06-24 16:52:44 +01002150 } else {
2151 int null_fd = open("/dev/null", O_RDONLY);
2152 wl_keyboard_send_keymap(cr, WL_KEYBOARD_KEYMAP_FORMAT_NO_KEYMAP,
2153 null_fd,
2154 0);
2155 close(null_fd);
2156 }
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002157
Neil Roberts96d790e2013-09-19 17:32:00 +01002158 if (should_send_modifiers_to_client(seat, client)) {
Derek Foreman345c9f32015-06-03 15:53:28 -05002159 send_modifiers_to_resource(keyboard,
Neil Roberts96d790e2013-09-19 17:32:00 +01002160 cr,
Derek Foreman345c9f32015-06-03 15:53:28 -05002161 keyboard->focus_serial);
Neil Roberts96d790e2013-09-19 17:32:00 +01002162 }
2163
Derek Foreman345c9f32015-06-03 15:53:28 -05002164 if (keyboard->focus && keyboard->focus->resource &&
2165 wl_resource_get_client(keyboard->focus->resource) == client) {
Neil Roberts96d790e2013-09-19 17:32:00 +01002166 struct weston_surface *surface =
Derek Foreman345c9f32015-06-03 15:53:28 -05002167 (struct weston_surface *)keyboard->focus;
Neil Roberts96d790e2013-09-19 17:32:00 +01002168
2169 wl_list_remove(wl_resource_get_link(cr));
Derek Foreman345c9f32015-06-03 15:53:28 -05002170 wl_list_insert(&keyboard->focus_resource_list,
Neil Roberts96d790e2013-09-19 17:32:00 +01002171 wl_resource_get_link(cr));
2172 wl_keyboard_send_enter(cr,
Derek Foreman345c9f32015-06-03 15:53:28 -05002173 keyboard->focus_serial,
Neil Roberts96d790e2013-09-19 17:32:00 +01002174 surface->resource,
Derek Foreman345c9f32015-06-03 15:53:28 -05002175 &keyboard->keys);
Neil Roberts96d790e2013-09-19 17:32:00 +01002176
2177 /* If this is the first keyboard resource for this
2178 * client... */
Derek Foreman345c9f32015-06-03 15:53:28 -05002179 if (keyboard->focus_resource_list.prev ==
Neil Roberts96d790e2013-09-19 17:32:00 +01002180 wl_resource_get_link(cr))
2181 wl_data_device_set_keyboard_focus(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002182 }
2183}
2184
2185static void
Kristian Høgsberg69e25fc2013-08-13 20:11:02 +01002186touch_release(struct wl_client *client, struct wl_resource *resource)
2187{
2188 wl_resource_destroy(resource);
2189}
2190
2191static const struct wl_touch_interface touch_interface = {
2192 touch_release
2193};
2194
2195static void
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002196seat_get_touch(struct wl_client *client, struct wl_resource *resource,
2197 uint32_t id)
2198{
Jason Ekstrand44a38632013-06-14 10:08:00 -05002199 struct weston_seat *seat = wl_resource_get_user_data(resource);
Derek Foreman1281a362015-07-31 16:55:32 -05002200 /* We use the touch_state directly, which means we'll
2201 * give a wl_touch if the seat has ever had one - even though
2202 * the spec explicitly states that this request only takes effect
2203 * if the seat has the touch capability.
2204 *
2205 * This prevents a race between the compositor sending new
2206 * capabilities and the client trying to use the old ones.
2207 */
2208 struct weston_touch *touch = seat->touch_state;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002209 struct wl_resource *cr;
2210
Derek Foreman1281a362015-07-31 16:55:32 -05002211 if (!touch)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002212 return;
2213
Jason Ekstranda85118c2013-06-27 20:17:02 -05002214 cr = wl_resource_create(client, &wl_touch_interface,
2215 wl_resource_get_version(resource), id);
Kristian Høgsberg0ff79082013-08-06 16:46:25 -07002216 if (cr == NULL) {
2217 wl_client_post_no_memory(client);
2218 return;
2219 }
2220
Derek Foreman1281a362015-07-31 16:55:32 -05002221 if (touch->focus &&
2222 wl_resource_get_client(touch->focus->surface->resource) == client) {
Chokshi, Mituld6697142015-10-09 08:28:47 +00002223 wl_list_insert(&touch->focus_resource_list,
Neil Roberts96d790e2013-09-19 17:32:00 +01002224 wl_resource_get_link(cr));
2225 } else {
Chokshi, Mituld6697142015-10-09 08:28:47 +00002226 wl_list_insert(&touch->resource_list,
Neil Roberts96d790e2013-09-19 17:32:00 +01002227 wl_resource_get_link(cr));
2228 }
Kristian Høgsberg69e25fc2013-08-13 20:11:02 +01002229 wl_resource_set_implementation(cr, &touch_interface,
2230 seat, unbind_resource);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002231}
2232
Quentin Glidicaab1d362016-03-13 17:49:08 +01002233static void
2234seat_release(struct wl_client *client, struct wl_resource *resource)
2235{
2236 wl_resource_destroy(resource);
2237}
2238
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002239static const struct wl_seat_interface seat_interface = {
2240 seat_get_pointer,
2241 seat_get_keyboard,
2242 seat_get_touch,
Quentin Glidicaab1d362016-03-13 17:49:08 +01002243 seat_release,
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002244};
2245
2246static void
2247bind_seat(struct wl_client *client, void *data, uint32_t version, uint32_t id)
2248{
Kristian Høgsberge3148752013-05-06 23:19:49 -04002249 struct weston_seat *seat = data;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002250 struct wl_resource *resource;
2251 enum wl_seat_capability caps = 0;
2252
Jason Ekstranda85118c2013-06-27 20:17:02 -05002253 resource = wl_resource_create(client,
Derek Foreman1909c102015-11-26 14:17:47 -06002254 &wl_seat_interface, version, id);
Jason Ekstrand44a38632013-06-14 10:08:00 -05002255 wl_list_insert(&seat->base_resource_list, wl_resource_get_link(resource));
Jason Ekstranda85118c2013-06-27 20:17:02 -05002256 wl_resource_set_implementation(resource, &seat_interface, data,
2257 unbind_resource);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002258
Derek Foreman1281a362015-07-31 16:55:32 -05002259 if (weston_seat_get_pointer(seat))
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002260 caps |= WL_SEAT_CAPABILITY_POINTER;
Derek Foreman1281a362015-07-31 16:55:32 -05002261 if (weston_seat_get_keyboard(seat))
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002262 caps |= WL_SEAT_CAPABILITY_KEYBOARD;
Derek Foreman1281a362015-07-31 16:55:32 -05002263 if (weston_seat_get_touch(seat))
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002264 caps |= WL_SEAT_CAPABILITY_TOUCH;
2265
2266 wl_seat_send_capabilities(resource, caps);
Jasper St. Pierre0013a292014-08-07 16:43:11 -04002267 if (version >= WL_SEAT_NAME_SINCE_VERSION)
Rob Bradforde445ae62013-05-31 18:09:51 +01002268 wl_seat_send_name(resource, seat->seat_name);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002269}
2270
Rob Bradford382ff462013-06-24 16:52:45 +01002271#ifdef ENABLE_XKBCOMMON
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002272int
2273weston_compositor_xkb_init(struct weston_compositor *ec,
2274 struct xkb_rule_names *names)
2275{
Rob Bradford382ff462013-06-24 16:52:45 +01002276 ec->use_xkbcommon = 1;
Matt Roper01a92732013-06-24 16:52:44 +01002277
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002278 if (ec->xkb_context == NULL) {
2279 ec->xkb_context = xkb_context_new(0);
2280 if (ec->xkb_context == NULL) {
2281 weston_log("failed to create XKB context\n");
2282 return -1;
2283 }
2284 }
2285
2286 if (names)
2287 ec->xkb_names = *names;
2288 if (!ec->xkb_names.rules)
2289 ec->xkb_names.rules = strdup("evdev");
2290 if (!ec->xkb_names.model)
2291 ec->xkb_names.model = strdup("pc105");
2292 if (!ec->xkb_names.layout)
2293 ec->xkb_names.layout = strdup("us");
2294
2295 return 0;
2296}
2297
Stefan Schmidtfda26522013-09-17 10:54:09 +01002298static void
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00002299weston_xkb_info_destroy(struct weston_xkb_info *xkb_info)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002300{
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00002301 if (--xkb_info->ref_count > 0)
2302 return;
2303
Ran Benitac9c74152014-08-19 23:59:52 +03002304 xkb_keymap_unref(xkb_info->keymap);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002305
2306 if (xkb_info->keymap_area)
2307 munmap(xkb_info->keymap_area, xkb_info->keymap_size);
2308 if (xkb_info->keymap_fd >= 0)
2309 close(xkb_info->keymap_fd);
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00002310 free(xkb_info);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002311}
2312
2313void
2314weston_compositor_xkb_destroy(struct weston_compositor *ec)
2315{
Matt Roper01a92732013-06-24 16:52:44 +01002316 /*
2317 * If we're operating in raw keyboard mode, we never initialized
2318 * libxkbcommon so there's no cleanup to do either.
2319 */
2320 if (!ec->use_xkbcommon)
2321 return;
2322
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002323 free((char *) ec->xkb_names.rules);
2324 free((char *) ec->xkb_names.model);
2325 free((char *) ec->xkb_names.layout);
2326 free((char *) ec->xkb_names.variant);
2327 free((char *) ec->xkb_names.options);
Stefan Schmidtfda26522013-09-17 10:54:09 +01002328
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00002329 if (ec->xkb_info)
2330 weston_xkb_info_destroy(ec->xkb_info);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002331 xkb_context_unref(ec->xkb_context);
2332}
2333
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00002334static struct weston_xkb_info *
2335weston_xkb_info_create(struct xkb_keymap *keymap)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002336{
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00002337 struct weston_xkb_info *xkb_info = zalloc(sizeof *xkb_info);
2338 if (xkb_info == NULL)
2339 return NULL;
2340
Ran Benita2e1968f2014-08-19 23:59:51 +03002341 xkb_info->keymap = xkb_keymap_ref(keymap);
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00002342 xkb_info->ref_count = 1;
2343
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002344 char *keymap_str;
2345
Ran Benita2e1968f2014-08-19 23:59:51 +03002346 xkb_info->shift_mod = xkb_keymap_mod_get_index(xkb_info->keymap,
2347 XKB_MOD_NAME_SHIFT);
2348 xkb_info->caps_mod = xkb_keymap_mod_get_index(xkb_info->keymap,
2349 XKB_MOD_NAME_CAPS);
2350 xkb_info->ctrl_mod = xkb_keymap_mod_get_index(xkb_info->keymap,
2351 XKB_MOD_NAME_CTRL);
2352 xkb_info->alt_mod = xkb_keymap_mod_get_index(xkb_info->keymap,
2353 XKB_MOD_NAME_ALT);
2354 xkb_info->mod2_mod = xkb_keymap_mod_get_index(xkb_info->keymap,
2355 "Mod2");
2356 xkb_info->mod3_mod = xkb_keymap_mod_get_index(xkb_info->keymap,
2357 "Mod3");
2358 xkb_info->super_mod = xkb_keymap_mod_get_index(xkb_info->keymap,
2359 XKB_MOD_NAME_LOGO);
2360 xkb_info->mod5_mod = xkb_keymap_mod_get_index(xkb_info->keymap,
2361 "Mod5");
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002362
Ran Benita2e1968f2014-08-19 23:59:51 +03002363 xkb_info->num_led = xkb_keymap_led_get_index(xkb_info->keymap,
2364 XKB_LED_NAME_NUM);
2365 xkb_info->caps_led = xkb_keymap_led_get_index(xkb_info->keymap,
2366 XKB_LED_NAME_CAPS);
2367 xkb_info->scroll_led = xkb_keymap_led_get_index(xkb_info->keymap,
2368 XKB_LED_NAME_SCROLL);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002369
Ran Benita2e1968f2014-08-19 23:59:51 +03002370 keymap_str = xkb_keymap_get_as_string(xkb_info->keymap,
2371 XKB_KEYMAP_FORMAT_TEXT_V1);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002372 if (keymap_str == NULL) {
2373 weston_log("failed to get string version of keymap\n");
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00002374 goto err_keymap;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002375 }
2376 xkb_info->keymap_size = strlen(keymap_str) + 1;
2377
2378 xkb_info->keymap_fd = os_create_anonymous_file(xkb_info->keymap_size);
2379 if (xkb_info->keymap_fd < 0) {
2380 weston_log("creating a keymap file for %lu bytes failed: %m\n",
2381 (unsigned long) xkb_info->keymap_size);
2382 goto err_keymap_str;
2383 }
2384
2385 xkb_info->keymap_area = mmap(NULL, xkb_info->keymap_size,
2386 PROT_READ | PROT_WRITE,
2387 MAP_SHARED, xkb_info->keymap_fd, 0);
2388 if (xkb_info->keymap_area == MAP_FAILED) {
2389 weston_log("failed to mmap() %lu bytes\n",
2390 (unsigned long) xkb_info->keymap_size);
2391 goto err_dev_zero;
2392 }
2393 strcpy(xkb_info->keymap_area, keymap_str);
2394 free(keymap_str);
2395
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00002396 return xkb_info;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002397
2398err_dev_zero:
2399 close(xkb_info->keymap_fd);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002400err_keymap_str:
2401 free(keymap_str);
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00002402err_keymap:
Ran Benita2e1968f2014-08-19 23:59:51 +03002403 xkb_keymap_unref(xkb_info->keymap);
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00002404 free(xkb_info);
2405 return NULL;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002406}
2407
2408static int
2409weston_compositor_build_global_keymap(struct weston_compositor *ec)
2410{
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00002411 struct xkb_keymap *keymap;
2412
2413 if (ec->xkb_info != NULL)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002414 return 0;
2415
Ran Benita2e1968f2014-08-19 23:59:51 +03002416 keymap = xkb_keymap_new_from_names(ec->xkb_context,
2417 &ec->xkb_names,
2418 0);
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00002419 if (keymap == NULL) {
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002420 weston_log("failed to compile global XKB keymap\n");
2421 weston_log(" tried rules %s, model %s, layout %s, variant %s, "
2422 "options %s\n",
2423 ec->xkb_names.rules, ec->xkb_names.model,
2424 ec->xkb_names.layout, ec->xkb_names.variant,
2425 ec->xkb_names.options);
2426 return -1;
2427 }
2428
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00002429 ec->xkb_info = weston_xkb_info_create(keymap);
Rui Matos73d93952013-10-24 19:28:41 +02002430 xkb_keymap_unref(keymap);
Stefan Schmidtfda26522013-09-17 10:54:09 +01002431 if (ec->xkb_info == NULL)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002432 return -1;
2433
2434 return 0;
2435}
Rob Bradford382ff462013-06-24 16:52:45 +01002436#else
2437int
2438weston_compositor_xkb_init(struct weston_compositor *ec,
2439 struct xkb_rule_names *names)
2440{
2441 return 0;
2442}
2443
2444void
2445weston_compositor_xkb_destroy(struct weston_compositor *ec)
2446{
2447}
2448#endif
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002449
Rui Matos65196bc2013-10-10 19:44:19 +02002450WL_EXPORT void
2451weston_seat_update_keymap(struct weston_seat *seat, struct xkb_keymap *keymap)
2452{
Derek Foreman1281a362015-07-31 16:55:32 -05002453 struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
2454
2455 if (!keyboard || !keymap)
Rui Matos65196bc2013-10-10 19:44:19 +02002456 return;
2457
2458#ifdef ENABLE_XKBCOMMON
2459 if (!seat->compositor->use_xkbcommon)
2460 return;
2461
Derek Foreman1281a362015-07-31 16:55:32 -05002462 xkb_keymap_unref(keyboard->pending_keymap);
2463 keyboard->pending_keymap = xkb_keymap_ref(keymap);
Rui Matos65196bc2013-10-10 19:44:19 +02002464
Derek Foreman1281a362015-07-31 16:55:32 -05002465 if (keyboard->keys.size == 0)
Rui Matos65196bc2013-10-10 19:44:19 +02002466 update_keymap(seat);
2467#endif
2468}
2469
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002470WL_EXPORT int
2471weston_seat_init_keyboard(struct weston_seat *seat, struct xkb_keymap *keymap)
2472{
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04002473 struct weston_keyboard *keyboard;
2474
Derek Foreman1281a362015-07-31 16:55:32 -05002475 if (seat->keyboard_state) {
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002476 seat->keyboard_device_count += 1;
2477 if (seat->keyboard_device_count == 1)
2478 seat_send_updated_caps(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002479 return 0;
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002480 }
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002481
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04002482 keyboard = weston_keyboard_create();
2483 if (keyboard == NULL) {
2484 weston_log("failed to allocate weston keyboard struct\n");
2485 return -1;
2486 }
2487
Jonas Ådahl7395ea02013-12-03 09:14:26 +01002488#ifdef ENABLE_XKBCOMMON
2489 if (seat->compositor->use_xkbcommon) {
2490 if (keymap != NULL) {
2491 keyboard->xkb_info = weston_xkb_info_create(keymap);
2492 if (keyboard->xkb_info == NULL)
Ander Conselvan de Oliveira4d363cf2014-01-31 17:35:45 +02002493 goto err;
Jonas Ådahl7395ea02013-12-03 09:14:26 +01002494 } else {
2495 if (weston_compositor_build_global_keymap(seat->compositor) < 0)
Ander Conselvan de Oliveira4d363cf2014-01-31 17:35:45 +02002496 goto err;
Jonas Ådahl7395ea02013-12-03 09:14:26 +01002497 keyboard->xkb_info = seat->compositor->xkb_info;
2498 keyboard->xkb_info->ref_count++;
2499 }
2500
2501 keyboard->xkb_state.state = xkb_state_new(keyboard->xkb_info->keymap);
2502 if (keyboard->xkb_state.state == NULL) {
2503 weston_log("failed to initialise XKB state\n");
Ander Conselvan de Oliveira4d363cf2014-01-31 17:35:45 +02002504 goto err;
Jonas Ådahl7395ea02013-12-03 09:14:26 +01002505 }
2506
2507 keyboard->xkb_state.leds = 0;
2508 }
2509#endif
2510
Derek Foreman1281a362015-07-31 16:55:32 -05002511 seat->keyboard_state = keyboard;
Ander Conselvan de Oliveira4d363cf2014-01-31 17:35:45 +02002512 seat->keyboard_device_count = 1;
2513 keyboard->seat = seat;
2514
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04002515 seat_send_updated_caps(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002516
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002517 return 0;
Ander Conselvan de Oliveira4d363cf2014-01-31 17:35:45 +02002518
2519err:
2520 if (keyboard->xkb_info)
2521 weston_xkb_info_destroy(keyboard->xkb_info);
2522 free(keyboard);
2523
2524 return -1;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002525}
2526
Jonas Ådahl91fed542013-12-03 09:14:27 +01002527static void
2528weston_keyboard_reset_state(struct weston_keyboard *keyboard)
2529{
2530 struct weston_seat *seat = keyboard->seat;
2531 struct xkb_state *state;
2532
2533#ifdef ENABLE_XKBCOMMON
2534 if (seat->compositor->use_xkbcommon) {
2535 state = xkb_state_new(keyboard->xkb_info->keymap);
2536 if (!state) {
2537 weston_log("failed to reset XKB state\n");
2538 return;
2539 }
2540 xkb_state_unref(keyboard->xkb_state.state);
2541 keyboard->xkb_state.state = state;
2542
2543 keyboard->xkb_state.leds = 0;
2544 }
2545#endif
2546
2547 seat->modifier_state = 0;
2548}
2549
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002550WL_EXPORT void
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002551weston_seat_release_keyboard(struct weston_seat *seat)
2552{
2553 seat->keyboard_device_count--;
Derek Foremand621df22014-11-19 11:04:12 -06002554 assert(seat->keyboard_device_count >= 0);
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002555 if (seat->keyboard_device_count == 0) {
Derek Foreman1281a362015-07-31 16:55:32 -05002556 weston_keyboard_set_focus(seat->keyboard_state, NULL);
2557 weston_keyboard_cancel_grab(seat->keyboard_state);
2558 weston_keyboard_reset_state(seat->keyboard_state);
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002559 seat_send_updated_caps(seat);
2560 }
2561}
2562
2563WL_EXPORT void
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002564weston_seat_init_pointer(struct weston_seat *seat)
2565{
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04002566 struct weston_pointer *pointer;
2567
Derek Foreman1281a362015-07-31 16:55:32 -05002568 if (seat->pointer_state) {
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002569 seat->pointer_device_count += 1;
2570 if (seat->pointer_device_count == 1)
2571 seat_send_updated_caps(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002572 return;
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002573 }
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002574
Giulio Camuffocdb4d292013-11-14 23:42:53 +01002575 pointer = weston_pointer_create(seat);
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04002576 if (pointer == NULL)
2577 return;
2578
Derek Foreman1281a362015-07-31 16:55:32 -05002579 seat->pointer_state = pointer;
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002580 seat->pointer_device_count = 1;
2581 pointer->seat = seat;
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04002582
2583 seat_send_updated_caps(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002584}
2585
2586WL_EXPORT void
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002587weston_seat_release_pointer(struct weston_seat *seat)
2588{
Derek Foreman1281a362015-07-31 16:55:32 -05002589 struct weston_pointer *pointer = seat->pointer_state;
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002590
2591 seat->pointer_device_count--;
2592 if (seat->pointer_device_count == 0) {
Derek Foremanf9318d12015-05-11 15:40:11 -05002593 weston_pointer_clear_focus(pointer);
Jonas Ådahl1ea343e2013-10-25 23:18:05 +02002594 weston_pointer_cancel_grab(pointer);
Jonas Ådahl630bae82013-10-17 23:04:06 +02002595
Jonas Ådahla4932742013-10-17 23:04:07 +02002596 if (pointer->sprite)
2597 pointer_unmap_sprite(pointer);
2598
Jonas Ådahl3e12e632013-12-02 22:05:05 +01002599 weston_pointer_reset_state(pointer);
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002600 seat_send_updated_caps(seat);
Derek Foremanfd5ca512015-01-07 15:00:25 -06002601
2602 /* seat->pointer is intentionally not destroyed so that
2603 * a newly attached pointer on this seat will retain
2604 * the previous cursor co-ordinates.
2605 */
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002606 }
2607}
2608
2609WL_EXPORT void
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002610weston_seat_init_touch(struct weston_seat *seat)
2611{
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04002612 struct weston_touch *touch;
2613
Derek Foreman1281a362015-07-31 16:55:32 -05002614 if (seat->touch_state) {
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002615 seat->touch_device_count += 1;
2616 if (seat->touch_device_count == 1)
2617 seat_send_updated_caps(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002618 return;
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002619 }
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002620
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04002621 touch = weston_touch_create();
2622 if (touch == NULL)
2623 return;
2624
Derek Foreman1281a362015-07-31 16:55:32 -05002625 seat->touch_state = touch;
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002626 seat->touch_device_count = 1;
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04002627 touch->seat = seat;
2628
2629 seat_send_updated_caps(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002630}
2631
2632WL_EXPORT void
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002633weston_seat_release_touch(struct weston_seat *seat)
2634{
2635 seat->touch_device_count--;
2636 if (seat->touch_device_count == 0) {
Derek Foreman1281a362015-07-31 16:55:32 -05002637 weston_touch_set_focus(seat->touch_state, NULL);
2638 weston_touch_cancel_grab(seat->touch_state);
2639 weston_touch_reset_state(seat->touch_state);
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002640 seat_send_updated_caps(seat);
2641 }
2642}
2643
2644WL_EXPORT void
Rob Bradford9af5f9e2013-05-31 18:09:50 +01002645weston_seat_init(struct weston_seat *seat, struct weston_compositor *ec,
2646 const char *seat_name)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002647{
Kristian Høgsberg4a2a2742013-05-06 22:24:50 -04002648 memset(seat, 0, sizeof *seat);
2649
Kristian Høgsberge3148752013-05-06 23:19:49 -04002650 seat->selection_data_source = NULL;
2651 wl_list_init(&seat->base_resource_list);
2652 wl_signal_init(&seat->selection_signal);
2653 wl_list_init(&seat->drag_resource_list);
Kristian Høgsberge3148752013-05-06 23:19:49 -04002654 wl_signal_init(&seat->destroy_signal);
Jason Ekstranda4ab5422014-04-02 19:53:45 -05002655 wl_signal_init(&seat->updated_caps_signal);
Kristian Høgsberg4a2a2742013-05-06 22:24:50 -04002656
Peter Hutterer87743e92016-01-18 16:38:22 +10002657 seat->global = wl_global_create(ec->wl_display, &wl_seat_interface, 5,
Kristian Høgsberg919cddb2013-07-08 19:03:57 -04002658 seat, bind_seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002659
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002660 seat->compositor = ec;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002661 seat->modifier_state = 0;
Rob Bradford9af5f9e2013-05-31 18:09:50 +01002662 seat->seat_name = strdup(seat_name);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002663
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002664 wl_list_insert(ec->seat_list.prev, &seat->link);
2665
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002666 clipboard_create(seat);
2667
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002668 wl_signal_emit(&ec->seat_created_signal, seat);
2669}
2670
2671WL_EXPORT void
2672weston_seat_release(struct weston_seat *seat)
2673{
2674 wl_list_remove(&seat->link);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002675
Jonas Ådahl1afb2382014-01-03 19:46:51 +01002676 if (seat->saved_kbd_focus)
2677 wl_list_remove(&seat->saved_kbd_focus_listener.link);
2678
Derek Foreman1281a362015-07-31 16:55:32 -05002679 if (seat->pointer_state)
2680 weston_pointer_destroy(seat->pointer_state);
2681 if (seat->keyboard_state)
2682 weston_keyboard_destroy(seat->keyboard_state);
2683 if (seat->touch_state)
2684 weston_touch_destroy(seat->touch_state);
Kristian Høgsberg4a2a2742013-05-06 22:24:50 -04002685
Rob Bradford9af5f9e2013-05-31 18:09:50 +01002686 free (seat->seat_name);
2687
Kristian Høgsberg919cddb2013-07-08 19:03:57 -04002688 wl_global_destroy(seat->global);
Kristian Høgsbergaaadc772013-07-08 16:20:31 -04002689
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002690 wl_signal_emit(&seat->destroy_signal, seat);
2691}
Derek Foreman1281a362015-07-31 16:55:32 -05002692
2693/** Get a seat's keyboard pointer
2694 *
2695 * \param seat The seat to query
2696 * \return The seat's keyboard pointer, or NULL if no keyboard is present
2697 *
2698 * The keyboard pointer for a seat isn't freed when all keyboards are removed,
2699 * so it should only be used when the seat's keyboard_device_count is greater
2700 * than zero. This function does that test and only returns a pointer
2701 * when a keyboard is present.
2702 */
2703WL_EXPORT struct weston_keyboard *
2704weston_seat_get_keyboard(struct weston_seat *seat)
2705{
2706 if (!seat)
2707 return NULL;
2708
2709 if (seat->keyboard_device_count)
2710 return seat->keyboard_state;
2711
2712 return NULL;
2713}
2714
2715/** Get a seat's pointer pointer
2716 *
2717 * \param seat The seat to query
2718 * \return The seat's pointer pointer, or NULL if no pointer device is present
2719 *
2720 * The pointer pointer for a seat isn't freed when all mice are removed,
2721 * so it should only be used when the seat's pointer_device_count is greater
2722 * than zero. This function does that test and only returns a pointer
2723 * when a pointing device is present.
2724 */
2725WL_EXPORT struct weston_pointer *
2726weston_seat_get_pointer(struct weston_seat *seat)
2727{
2728 if (!seat)
2729 return NULL;
2730
2731 if (seat->pointer_device_count)
2732 return seat->pointer_state;
2733
2734 return NULL;
2735}
2736
2737/** Get a seat's touch pointer
2738 *
2739 * \param seat The seat to query
2740 * \return The seat's touch pointer, or NULL if no touch device is present
2741 *
2742 * The touch pointer for a seat isn't freed when all touch devices are removed,
2743 * so it should only be used when the seat's touch_device_count is greater
2744 * than zero. This function does that test and only returns a pointer
2745 * when a touch device is present.
2746 */
2747WL_EXPORT struct weston_touch *
2748weston_seat_get_touch(struct weston_seat *seat)
2749{
2750 if (!seat)
2751 return NULL;
2752
2753 if (seat->touch_device_count)
2754 return seat->touch_state;
2755
2756 return NULL;
2757}