blob: c881792d0b246b6db7376937b1b268a71aa4ae6a [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,
Giulio Camuffo90a6fc62016-03-22 17:44:54 +0200355 event->axis,
356 wl_fixed_from_double(event->value));
Peter Hutterer87743e92016-01-18 16:38:22 +1000357 else if (wl_resource_get_version(resource) >=
358 WL_POINTER_AXIS_STOP_SINCE_VERSION)
359 wl_pointer_send_axis_stop(resource, time,
360 event->axis);
361 }
362}
363
364WL_EXPORT void
365weston_pointer_send_axis_source(struct weston_pointer *pointer, uint32_t source)
366{
367 struct wl_resource *resource;
368 struct wl_list *resource_list;
369
370 resource_list = &pointer->focus_client->pointer_resources;
371 wl_resource_for_each(resource, resource_list) {
372 if (wl_resource_get_version(resource) >=
373 WL_POINTER_AXIS_SOURCE_SINCE_VERSION) {
374 wl_pointer_send_axis_source(resource, source);
375 }
376 }
377}
378
379static void
380pointer_send_frame(struct wl_resource *resource)
381{
382 if (wl_resource_get_version(resource) >=
383 WL_POINTER_FRAME_SINCE_VERSION) {
384 wl_pointer_send_frame(resource);
385 }
386}
387
388WL_EXPORT void
389weston_pointer_send_frame(struct weston_pointer *pointer)
390{
391 struct wl_resource *resource;
392 struct wl_list *resource_list;
393
Derek Foreman8efa31b2016-01-29 10:29:46 -0600394 if (!pointer->focus_client)
395 return;
396
Peter Hutterer87743e92016-01-18 16:38:22 +1000397 resource_list = &pointer->focus_client->pointer_resources;
Jonas Ådahl0336ca02014-10-04 16:28:29 +0200398 wl_resource_for_each(resource, resource_list)
Peter Hutterer87743e92016-01-18 16:38:22 +1000399 pointer_send_frame(resource);
Jonas Ådahl0336ca02014-10-04 16:28:29 +0200400}
401
402static void
403default_grab_pointer_axis(struct weston_pointer_grab *grab,
Peter Hutterer89b6a492016-01-18 15:58:17 +1000404 uint32_t time,
405 struct weston_pointer_axis_event *event)
Jonas Ådahl0336ca02014-10-04 16:28:29 +0200406{
Peter Hutterer89b6a492016-01-18 15:58:17 +1000407 weston_pointer_send_axis(grab->pointer, time, event);
Jonas Ådahl0336ca02014-10-04 16:28:29 +0200408}
409
Jonas Ådahl1ea343e2013-10-25 23:18:05 +0200410static void
Peter Hutterer87743e92016-01-18 16:38:22 +1000411default_grab_pointer_axis_source(struct weston_pointer_grab *grab,
412 uint32_t source)
413{
414 weston_pointer_send_axis_source(grab->pointer, source);
415}
416
417static void
418default_grab_pointer_frame(struct weston_pointer_grab *grab)
419{
420 weston_pointer_send_frame(grab->pointer);
421}
422
423static void
Jonas Ådahl1ea343e2013-10-25 23:18:05 +0200424default_grab_pointer_cancel(struct weston_pointer_grab *grab)
425{
426}
427
Kristian Høgsberg02bbabb2013-05-06 22:15:05 -0400428static const struct weston_pointer_grab_interface
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400429 default_pointer_grab_interface = {
Kristian Høgsbergb27901c2013-10-28 15:32:02 -0700430 default_grab_pointer_focus,
431 default_grab_pointer_motion,
432 default_grab_pointer_button,
Jonas Ådahl0336ca02014-10-04 16:28:29 +0200433 default_grab_pointer_axis,
Peter Hutterer87743e92016-01-18 16:38:22 +1000434 default_grab_pointer_axis_source,
435 default_grab_pointer_frame,
Jonas Ådahl1ea343e2013-10-25 23:18:05 +0200436 default_grab_pointer_cancel,
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400437};
438
Kristian Høgsberge329f362013-05-06 22:19:57 -0400439static void
440default_grab_touch_down(struct weston_touch_grab *grab, uint32_t time,
Giulio Camuffo61ed7b62015-07-08 11:55:28 +0300441 int touch_id, wl_fixed_t x, wl_fixed_t y)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400442{
Kristian Høgsberge329f362013-05-06 22:19:57 -0400443 struct weston_touch *touch = grab->touch;
Rob Bradford880ebc72013-07-22 17:31:38 +0100444 struct wl_display *display = touch->seat->compositor->wl_display;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400445 uint32_t serial;
Neil Roberts96d790e2013-09-19 17:32:00 +0100446 struct wl_resource *resource;
447 struct wl_list *resource_list;
Giulio Camuffo61ed7b62015-07-08 11:55:28 +0300448 wl_fixed_t sx, sy;
449
Bryce Harrington2c40d1d2016-02-02 10:18:48 -0800450 if (!touch->focus)
451 return;
452
Giulio Camuffo61ed7b62015-07-08 11:55:28 +0300453 weston_view_from_global_fixed(touch->focus, x, y, &sx, &sy);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400454
Neil Roberts96d790e2013-09-19 17:32:00 +0100455 resource_list = &touch->focus_resource_list;
456
Bryce Harrington2c40d1d2016-02-02 10:18:48 -0800457 if (!wl_list_empty(resource_list)) {
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400458 serial = wl_display_next_serial(display);
Neil Roberts96d790e2013-09-19 17:32:00 +0100459 wl_resource_for_each(resource, resource_list)
460 wl_touch_send_down(resource, serial, time,
Jason Ekstranda7af7042013-10-12 22:38:11 -0500461 touch->focus->surface->resource,
Neil Roberts96d790e2013-09-19 17:32:00 +0100462 touch_id, sx, sy);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400463 }
464}
465
Kristian Høgsberge329f362013-05-06 22:19:57 -0400466static void
467default_grab_touch_up(struct weston_touch_grab *grab,
468 uint32_t time, int touch_id)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400469{
Kristian Høgsberge329f362013-05-06 22:19:57 -0400470 struct weston_touch *touch = grab->touch;
Rob Bradford880ebc72013-07-22 17:31:38 +0100471 struct wl_display *display = touch->seat->compositor->wl_display;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400472 uint32_t serial;
Neil Roberts96d790e2013-09-19 17:32:00 +0100473 struct wl_resource *resource;
474 struct wl_list *resource_list;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400475
Neil Roberts96d790e2013-09-19 17:32:00 +0100476 resource_list = &touch->focus_resource_list;
477
478 if (!wl_list_empty(resource_list)) {
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400479 serial = wl_display_next_serial(display);
Neil Roberts96d790e2013-09-19 17:32:00 +0100480 wl_resource_for_each(resource, resource_list)
481 wl_touch_send_up(resource, serial, time, touch_id);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400482 }
483}
484
Kristian Høgsberge329f362013-05-06 22:19:57 -0400485static void
486default_grab_touch_motion(struct weston_touch_grab *grab, uint32_t time,
Giulio Camuffo61ed7b62015-07-08 11:55:28 +0300487 int touch_id, wl_fixed_t x, wl_fixed_t y)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400488{
Kristian Høgsberge329f362013-05-06 22:19:57 -0400489 struct weston_touch *touch = grab->touch;
Neil Roberts96d790e2013-09-19 17:32:00 +0100490 struct wl_resource *resource;
491 struct wl_list *resource_list;
Giulio Camuffo61ed7b62015-07-08 11:55:28 +0300492 wl_fixed_t sx, sy;
493
494 weston_view_from_global_fixed(touch->focus, x, y, &sx, &sy);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400495
Neil Roberts96d790e2013-09-19 17:32:00 +0100496 resource_list = &touch->focus_resource_list;
497
498 wl_resource_for_each(resource, resource_list) {
499 wl_touch_send_motion(resource, time,
Kristian Høgsberge329f362013-05-06 22:19:57 -0400500 touch_id, sx, sy);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400501 }
502}
503
Jonas Ådahl1ea343e2013-10-25 23:18:05 +0200504static void
Jonas Ådahl1679f232014-04-12 09:39:51 +0200505default_grab_touch_frame(struct weston_touch_grab *grab)
506{
507 struct wl_resource *resource;
508
509 wl_resource_for_each(resource, &grab->touch->focus_resource_list)
510 wl_touch_send_frame(resource);
511}
512
513static void
Jonas Ådahl1ea343e2013-10-25 23:18:05 +0200514default_grab_touch_cancel(struct weston_touch_grab *grab)
515{
516}
517
Kristian Høgsberge329f362013-05-06 22:19:57 -0400518static const struct weston_touch_grab_interface default_touch_grab_interface = {
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400519 default_grab_touch_down,
520 default_grab_touch_up,
Jonas Ådahl1ea343e2013-10-25 23:18:05 +0200521 default_grab_touch_motion,
Jonas Ådahl1679f232014-04-12 09:39:51 +0200522 default_grab_touch_frame,
Jonas Ådahl1ea343e2013-10-25 23:18:05 +0200523 default_grab_touch_cancel,
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400524};
525
526static void
Kristian Høgsbergb27901c2013-10-28 15:32:02 -0700527default_grab_keyboard_key(struct weston_keyboard_grab *grab,
528 uint32_t time, uint32_t key, uint32_t state)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400529{
Kristian Høgsberg29139d42013-04-18 15:25:39 -0400530 struct weston_keyboard *keyboard = grab->keyboard;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400531 struct wl_resource *resource;
Rob Bradford880ebc72013-07-22 17:31:38 +0100532 struct wl_display *display = keyboard->seat->compositor->wl_display;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400533 uint32_t serial;
Neil Roberts96d790e2013-09-19 17:32:00 +0100534 struct wl_list *resource_list;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400535
Neil Roberts96d790e2013-09-19 17:32:00 +0100536 resource_list = &keyboard->focus_resource_list;
537 if (!wl_list_empty(resource_list)) {
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400538 serial = wl_display_next_serial(display);
Neil Roberts96d790e2013-09-19 17:32:00 +0100539 wl_resource_for_each(resource, resource_list)
540 wl_keyboard_send_key(resource,
541 serial,
542 time,
543 key,
544 state);
545 }
546}
547
548static void
549send_modifiers_to_resource(struct weston_keyboard *keyboard,
550 struct wl_resource *resource,
551 uint32_t serial)
552{
553 wl_keyboard_send_modifiers(resource,
554 serial,
555 keyboard->modifiers.mods_depressed,
556 keyboard->modifiers.mods_latched,
557 keyboard->modifiers.mods_locked,
558 keyboard->modifiers.group);
559}
560
561static void
562send_modifiers_to_client_in_list(struct wl_client *client,
563 struct wl_list *list,
564 uint32_t serial,
565 struct weston_keyboard *keyboard)
566{
567 struct wl_resource *resource;
568
569 wl_resource_for_each(resource, list) {
570 if (wl_resource_get_client(resource) == client)
571 send_modifiers_to_resource(keyboard,
572 resource,
573 serial);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400574 }
575}
576
Jonas Ådahl2cbf2932015-07-22 12:05:38 +0800577static struct weston_pointer_client *
578find_pointer_client_for_surface(struct weston_pointer *pointer,
579 struct weston_surface *surface)
580{
581 struct wl_client *client;
582
583 if (!surface)
584 return NULL;
585
586 if (!surface->resource)
587 return NULL;
588
589 client = wl_resource_get_client(surface->resource);
590 return weston_pointer_get_pointer_client(pointer, client);
591}
592
593static struct weston_pointer_client *
594find_pointer_client_for_view(struct weston_pointer *pointer, struct weston_view *view)
595{
596 if (!view)
597 return NULL;
598
599 return find_pointer_client_for_surface(pointer, view->surface);
600}
601
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400602static struct wl_resource *
Kristian Høgsbergfe7aa902013-05-08 09:54:37 -0400603find_resource_for_surface(struct wl_list *list, struct weston_surface *surface)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400604{
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400605 if (!surface)
606 return NULL;
607
Jason Ekstrand44a38632013-06-14 10:08:00 -0500608 if (!surface->resource)
609 return NULL;
Stefan Schmidtfda26522013-09-17 10:54:09 +0100610
Jason Ekstrand44a38632013-06-14 10:08:00 -0500611 return wl_resource_find_for_client(list, wl_resource_get_client(surface->resource));
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400612}
613
614static void
Kristian Høgsbergb27901c2013-10-28 15:32:02 -0700615default_grab_keyboard_modifiers(struct weston_keyboard_grab *grab,
616 uint32_t serial, uint32_t mods_depressed,
617 uint32_t mods_latched,
618 uint32_t mods_locked, uint32_t group)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400619{
Kristian Høgsberg29139d42013-04-18 15:25:39 -0400620 struct weston_keyboard *keyboard = grab->keyboard;
Derek Foreman1281a362015-07-31 16:55:32 -0500621 struct weston_pointer *pointer =
622 weston_seat_get_pointer(grab->keyboard->seat);
Neil Roberts96d790e2013-09-19 17:32:00 +0100623 struct wl_resource *resource;
624 struct wl_list *resource_list;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400625
Neil Roberts96d790e2013-09-19 17:32:00 +0100626 resource_list = &keyboard->focus_resource_list;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400627
Neil Roberts96d790e2013-09-19 17:32:00 +0100628 wl_resource_for_each(resource, resource_list) {
629 wl_keyboard_send_modifiers(resource, serial, mods_depressed,
630 mods_latched, mods_locked, group);
631 }
Jason Ekstrand42133d42013-11-14 20:06:16 -0600632 if (pointer && pointer->focus && pointer->focus->surface->resource &&
633 pointer->focus->surface != keyboard->focus) {
Neil Roberts96d790e2013-09-19 17:32:00 +0100634 struct wl_client *pointer_client =
Jason Ekstranda7af7042013-10-12 22:38:11 -0500635 wl_resource_get_client(pointer->focus->surface->resource);
Neil Roberts96d790e2013-09-19 17:32:00 +0100636 send_modifiers_to_client_in_list(pointer_client,
637 &keyboard->resource_list,
638 serial,
639 keyboard);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400640 }
641}
642
Jonas Ådahl1ea343e2013-10-25 23:18:05 +0200643static void
644default_grab_keyboard_cancel(struct weston_keyboard_grab *grab)
645{
646}
647
Kristian Høgsberg29139d42013-04-18 15:25:39 -0400648static const struct weston_keyboard_grab_interface
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400649 default_keyboard_grab_interface = {
Kristian Høgsbergb27901c2013-10-28 15:32:02 -0700650 default_grab_keyboard_key,
651 default_grab_keyboard_modifiers,
Jonas Ådahl1ea343e2013-10-25 23:18:05 +0200652 default_grab_keyboard_cancel,
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400653};
654
Kristian Høgsberg195b8692013-05-08 15:02:05 -0400655static void
656pointer_unmap_sprite(struct weston_pointer *pointer)
657{
Pekka Paalanenc557ff72014-11-12 16:42:52 +0200658 struct weston_surface *surface = pointer->sprite->surface;
659
660 if (weston_surface_is_mapped(surface))
661 weston_surface_unmap(surface);
Kristian Høgsberg195b8692013-05-08 15:02:05 -0400662
663 wl_list_remove(&pointer->sprite_destroy_listener.link);
Pekka Paalanenc557ff72014-11-12 16:42:52 +0200664 surface->configure = NULL;
665 surface->configure_private = NULL;
Pekka Paalanen8274d902014-08-06 19:36:51 +0300666 weston_surface_set_label_func(surface, NULL);
Jason Ekstranda7af7042013-10-12 22:38:11 -0500667 weston_view_destroy(pointer->sprite);
Kristian Høgsberg195b8692013-05-08 15:02:05 -0400668 pointer->sprite = NULL;
669}
670
671static void
672pointer_handle_sprite_destroy(struct wl_listener *listener, void *data)
673{
674 struct weston_pointer *pointer =
675 container_of(listener, struct weston_pointer,
676 sprite_destroy_listener);
677
678 pointer->sprite = NULL;
679}
680
Jonas Ådahl3e12e632013-12-02 22:05:05 +0100681static void
682weston_pointer_reset_state(struct weston_pointer *pointer)
683{
684 pointer->button_count = 0;
685}
686
Ander Conselvan de Oliveiraf84327a2014-01-29 18:47:51 +0200687static void
688weston_pointer_handle_output_destroy(struct wl_listener *listener, void *data);
689
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400690WL_EXPORT struct weston_pointer *
Giulio Camuffocdb4d292013-11-14 23:42:53 +0100691weston_pointer_create(struct weston_seat *seat)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400692{
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400693 struct weston_pointer *pointer;
694
Peter Huttererf3d62272013-08-08 11:57:05 +1000695 pointer = zalloc(sizeof *pointer);
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400696 if (pointer == NULL)
697 return NULL;
698
Jonas Ådahl2cbf2932015-07-22 12:05:38 +0800699 wl_list_init(&pointer->pointer_clients);
Giulio Camuffocdb4d292013-11-14 23:42:53 +0100700 weston_pointer_set_default_grab(pointer,
701 seat->compositor->default_pointer_grab);
Giulio Camuffo576fe2a2013-11-20 18:00:24 +0100702 wl_list_init(&pointer->focus_resource_listener.link);
703 pointer->focus_resource_listener.notify = pointer_focus_resource_destroyed;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400704 pointer->default_grab.pointer = pointer;
705 pointer->grab = &pointer->default_grab;
Giulio Camuffo6fcb3782013-11-14 23:42:50 +0100706 wl_signal_init(&pointer->motion_signal);
Emilio Pozuelo Monfortaa7a4762013-11-19 11:37:15 +0100707 wl_signal_init(&pointer->focus_signal);
Giulio Camuffo576fe2a2013-11-20 18:00:24 +0100708 wl_list_init(&pointer->focus_view_listener.link);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400709
Kristian Høgsberg195b8692013-05-08 15:02:05 -0400710 pointer->sprite_destroy_listener.notify = pointer_handle_sprite_destroy;
711
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400712 /* FIXME: Pick better co-ords. */
713 pointer->x = wl_fixed_from_int(100);
714 pointer->y = wl_fixed_from_int(100);
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400715
Ander Conselvan de Oliveiraf84327a2014-01-29 18:47:51 +0200716 pointer->output_destroy_listener.notify =
717 weston_pointer_handle_output_destroy;
718 wl_signal_add(&seat->compositor->output_destroyed_signal,
719 &pointer->output_destroy_listener);
720
Derek Foremanf9318d12015-05-11 15:40:11 -0500721 pointer->sx = wl_fixed_from_int(-1000000);
722 pointer->sy = wl_fixed_from_int(-1000000);
723
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400724 return pointer;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400725}
726
727WL_EXPORT void
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400728weston_pointer_destroy(struct weston_pointer *pointer)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400729{
Kristian Høgsberg195b8692013-05-08 15:02:05 -0400730 if (pointer->sprite)
731 pointer_unmap_sprite(pointer);
732
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400733 /* XXX: What about pointer->resource_list? */
Neil Roberts96d790e2013-09-19 17:32:00 +0100734
Giulio Camuffo576fe2a2013-11-20 18:00:24 +0100735 wl_list_remove(&pointer->focus_resource_listener.link);
736 wl_list_remove(&pointer->focus_view_listener.link);
Ander Conselvan de Oliveiraf84327a2014-01-29 18:47:51 +0200737 wl_list_remove(&pointer->output_destroy_listener.link);
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400738 free(pointer);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400739}
740
Giulio Camuffocdb4d292013-11-14 23:42:53 +0100741void
742weston_pointer_set_default_grab(struct weston_pointer *pointer,
743 const struct weston_pointer_grab_interface *interface)
744{
745 if (interface)
746 pointer->default_grab.interface = interface;
747 else
748 pointer->default_grab.interface =
749 &default_pointer_grab_interface;
750}
751
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400752WL_EXPORT struct weston_keyboard *
753weston_keyboard_create(void)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400754{
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400755 struct weston_keyboard *keyboard;
756
Peter Huttererf3d62272013-08-08 11:57:05 +1000757 keyboard = zalloc(sizeof *keyboard);
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400758 if (keyboard == NULL)
Neil Roberts96d790e2013-09-19 17:32:00 +0100759 return NULL;
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400760
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400761 wl_list_init(&keyboard->resource_list);
Neil Roberts96d790e2013-09-19 17:32:00 +0100762 wl_list_init(&keyboard->focus_resource_list);
Giulio Camuffo576fe2a2013-11-20 18:00:24 +0100763 wl_list_init(&keyboard->focus_resource_listener.link);
764 keyboard->focus_resource_listener.notify = keyboard_focus_resource_destroyed;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400765 wl_array_init(&keyboard->keys);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400766 keyboard->default_grab.interface = &default_keyboard_grab_interface;
767 keyboard->default_grab.keyboard = keyboard;
768 keyboard->grab = &keyboard->default_grab;
769 wl_signal_init(&keyboard->focus_signal);
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400770
771 return keyboard;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400772}
773
Jonas Ådahl7395ea02013-12-03 09:14:26 +0100774static void
775weston_xkb_info_destroy(struct weston_xkb_info *xkb_info);
776
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400777WL_EXPORT void
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400778weston_keyboard_destroy(struct weston_keyboard *keyboard)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400779{
780 /* XXX: What about keyboard->resource_list? */
Neil Roberts96d790e2013-09-19 17:32:00 +0100781
Jonas Ådahl7395ea02013-12-03 09:14:26 +0100782#ifdef ENABLE_XKBCOMMON
783 if (keyboard->seat->compositor->use_xkbcommon) {
Ran Benitac9c74152014-08-19 23:59:52 +0300784 xkb_state_unref(keyboard->xkb_state.state);
Jonas Ådahl7395ea02013-12-03 09:14:26 +0100785 if (keyboard->xkb_info)
786 weston_xkb_info_destroy(keyboard->xkb_info);
Ran Benitac9c74152014-08-19 23:59:52 +0300787 xkb_keymap_unref(keyboard->pending_keymap);
Jonas Ådahl7395ea02013-12-03 09:14:26 +0100788 }
789#endif
790
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400791 wl_array_release(&keyboard->keys);
Giulio Camuffo576fe2a2013-11-20 18:00:24 +0100792 wl_list_remove(&keyboard->focus_resource_listener.link);
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400793 free(keyboard);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400794}
795
Jonas Ådahlcbfa7f72013-12-02 22:05:04 +0100796static void
797weston_touch_reset_state(struct weston_touch *touch)
798{
799 touch->num_tp = 0;
800}
801
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400802WL_EXPORT struct weston_touch *
803weston_touch_create(void)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400804{
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400805 struct weston_touch *touch;
806
Peter Huttererf3d62272013-08-08 11:57:05 +1000807 touch = zalloc(sizeof *touch);
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400808 if (touch == NULL)
809 return NULL;
810
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400811 wl_list_init(&touch->resource_list);
Neil Roberts96d790e2013-09-19 17:32:00 +0100812 wl_list_init(&touch->focus_resource_list);
Giulio Camuffo576fe2a2013-11-20 18:00:24 +0100813 wl_list_init(&touch->focus_view_listener.link);
814 touch->focus_view_listener.notify = touch_focus_view_destroyed;
815 wl_list_init(&touch->focus_resource_listener.link);
816 touch->focus_resource_listener.notify = touch_focus_resource_destroyed;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400817 touch->default_grab.interface = &default_touch_grab_interface;
818 touch->default_grab.touch = touch;
819 touch->grab = &touch->default_grab;
820 wl_signal_init(&touch->focus_signal);
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400821
822 return touch;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400823}
824
825WL_EXPORT void
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400826weston_touch_destroy(struct weston_touch *touch)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400827{
828 /* XXX: What about touch->resource_list? */
Neil Roberts96d790e2013-09-19 17:32:00 +0100829
Giulio Camuffo576fe2a2013-11-20 18:00:24 +0100830 wl_list_remove(&touch->focus_view_listener.link);
831 wl_list_remove(&touch->focus_resource_listener.link);
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400832 free(touch);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400833}
834
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400835static void
Kristian Høgsberge3148752013-05-06 23:19:49 -0400836seat_send_updated_caps(struct weston_seat *seat)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400837{
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400838 enum wl_seat_capability caps = 0;
Rob Bradford6e737f52013-09-06 17:48:19 +0100839 struct wl_resource *resource;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400840
Jonas Ådahld6e1c342013-10-17 23:04:05 +0200841 if (seat->pointer_device_count > 0)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400842 caps |= WL_SEAT_CAPABILITY_POINTER;
Jonas Ådahld6e1c342013-10-17 23:04:05 +0200843 if (seat->keyboard_device_count > 0)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400844 caps |= WL_SEAT_CAPABILITY_KEYBOARD;
Jonas Ådahld6e1c342013-10-17 23:04:05 +0200845 if (seat->touch_device_count > 0)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400846 caps |= WL_SEAT_CAPABILITY_TOUCH;
847
Rob Bradford6e737f52013-09-06 17:48:19 +0100848 wl_resource_for_each(resource, &seat->base_resource_list) {
849 wl_seat_send_capabilities(resource, caps);
Jason Ekstrand44a38632013-06-14 10:08:00 -0500850 }
Jason Ekstranda4ab5422014-04-02 19:53:45 -0500851 wl_signal_emit(&seat->updated_caps_signal, seat);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400852}
853
Derek Foremanf9318d12015-05-11 15:40:11 -0500854
855/** Clear the pointer focus
856 *
857 * \param pointer the pointer to clear focus for.
858 *
859 * This can be used to unset pointer focus and set the co-ordinates to the
860 * arbitrary values we use for the no focus case.
861 *
862 * There's no requirement to use this function. For example, passing the
863 * results of a weston_compositor_pick_view() directly to
864 * weston_pointer_set_focus() will do the right thing when no view is found.
865 */
866WL_EXPORT void
867weston_pointer_clear_focus(struct weston_pointer *pointer)
868{
869 weston_pointer_set_focus(pointer, NULL,
870 wl_fixed_from_int(-1000000),
871 wl_fixed_from_int(-1000000));
872}
873
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400874WL_EXPORT void
Kristian Høgsberg02bbabb2013-05-06 22:15:05 -0400875weston_pointer_set_focus(struct weston_pointer *pointer,
Jason Ekstranda7af7042013-10-12 22:38:11 -0500876 struct weston_view *view,
Kristian Høgsberg02bbabb2013-05-06 22:15:05 -0400877 wl_fixed_t sx, wl_fixed_t sy)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400878{
Jonas Ådahl2cbf2932015-07-22 12:05:38 +0800879 struct weston_pointer_client *pointer_client;
Derek Foreman1281a362015-07-31 16:55:32 -0500880 struct weston_keyboard *kbd = weston_seat_get_keyboard(pointer->seat);
Neil Roberts96d790e2013-09-19 17:32:00 +0100881 struct wl_resource *resource;
Jonas Ådahl2cbf2932015-07-22 12:05:38 +0800882 struct wl_resource *surface_resource;
Rob Bradford880ebc72013-07-22 17:31:38 +0100883 struct wl_display *display = pointer->seat->compositor->wl_display;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400884 uint32_t serial;
Neil Roberts96d790e2013-09-19 17:32:00 +0100885 struct wl_list *focus_resource_list;
Kristian Høgsbergdb1fccb2014-02-05 17:14:42 -0800886 int refocus = 0;
Jason Ekstranda7af7042013-10-12 22:38:11 -0500887
888 if ((!pointer->focus && view) ||
889 (pointer->focus && !view) ||
Kristian Høgsbergdb1fccb2014-02-05 17:14:42 -0800890 (pointer->focus && pointer->focus->surface != view->surface) ||
891 pointer->sx != sx || pointer->sy != sy)
892 refocus = 1;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400893
Jonas Ådahl2cbf2932015-07-22 12:05:38 +0800894 if (pointer->focus_client && refocus) {
895 focus_resource_list = &pointer->focus_client->pointer_resources;
896 if (!wl_list_empty(focus_resource_list)) {
897 serial = wl_display_next_serial(display);
898 surface_resource = pointer->focus->surface->resource;
899 wl_resource_for_each(resource, focus_resource_list) {
900 wl_pointer_send_leave(resource, serial,
901 surface_resource);
Peter Hutterer87743e92016-01-18 16:38:22 +1000902 pointer_send_frame(resource);
Jonas Ådahl2cbf2932015-07-22 12:05:38 +0800903 }
Neil Roberts96d790e2013-09-19 17:32:00 +0100904 }
905
Jonas Ådahl2cbf2932015-07-22 12:05:38 +0800906 pointer->focus_client = NULL;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400907 }
908
Jonas Ådahl2cbf2932015-07-22 12:05:38 +0800909 pointer_client = find_pointer_client_for_view(pointer, view);
910 if (pointer_client && refocus) {
911 struct wl_client *surface_client = pointer_client->client;
Neil Roberts96d790e2013-09-19 17:32:00 +0100912
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400913 serial = wl_display_next_serial(display);
Neil Roberts96d790e2013-09-19 17:32:00 +0100914
Jason Ekstranda7af7042013-10-12 22:38:11 -0500915 if (kbd && kbd->focus != view->surface)
Kristian Høgsbergcb406f12013-10-09 10:54:03 -0700916 send_modifiers_to_client_in_list(surface_client,
917 &kbd->resource_list,
918 serial,
919 kbd);
920
Jonas Ådahl2cbf2932015-07-22 12:05:38 +0800921 pointer->focus_client = pointer_client;
Neil Roberts96d790e2013-09-19 17:32:00 +0100922
Jonas Ådahl2cbf2932015-07-22 12:05:38 +0800923 focus_resource_list = &pointer->focus_client->pointer_resources;
Neil Roberts96d790e2013-09-19 17:32:00 +0100924 wl_resource_for_each(resource, focus_resource_list) {
925 wl_pointer_send_enter(resource,
926 serial,
Jason Ekstranda7af7042013-10-12 22:38:11 -0500927 view->surface->resource,
Neil Roberts96d790e2013-09-19 17:32:00 +0100928 sx, sy);
Peter Hutterer87743e92016-01-18 16:38:22 +1000929 pointer_send_frame(resource);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400930 }
Neil Roberts96d790e2013-09-19 17:32:00 +0100931
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400932 pointer->focus_serial = serial;
933 }
934
Giulio Camuffo65a07f82013-12-06 12:46:27 +0100935 wl_list_remove(&pointer->focus_view_listener.link);
936 wl_list_init(&pointer->focus_view_listener.link);
937 wl_list_remove(&pointer->focus_resource_listener.link);
938 wl_list_init(&pointer->focus_resource_listener.link);
Emilio Pozuelo Monfortaa7a4762013-11-19 11:37:15 +0100939 if (view)
Giulio Camuffo576fe2a2013-11-20 18:00:24 +0100940 wl_signal_add(&view->destroy_signal, &pointer->focus_view_listener);
Giulio Camuffo65a07f82013-12-06 12:46:27 +0100941 if (view && view->surface->resource)
942 wl_resource_add_destroy_listener(view->surface->resource,
943 &pointer->focus_resource_listener);
944
945 pointer->focus = view;
946 pointer->focus_view_listener.notify = pointer_focus_view_destroyed;
Kristian Høgsbergdb1fccb2014-02-05 17:14:42 -0800947 pointer->sx = sx;
948 pointer->sy = sy;
949
Derek Foremanf9318d12015-05-11 15:40:11 -0500950 assert(view || sx == wl_fixed_from_int(-1000000));
951 assert(view || sy == wl_fixed_from_int(-1000000));
952
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400953 wl_signal_emit(&pointer->focus_signal, pointer);
954}
955
Neil Roberts96d790e2013-09-19 17:32:00 +0100956static void
957send_enter_to_resource_list(struct wl_list *list,
958 struct weston_keyboard *keyboard,
959 struct weston_surface *surface,
960 uint32_t serial)
961{
962 struct wl_resource *resource;
963
964 wl_resource_for_each(resource, list) {
965 send_modifiers_to_resource(keyboard, resource, serial);
966 wl_keyboard_send_enter(resource, serial,
967 surface->resource,
968 &keyboard->keys);
969 }
970}
971
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400972WL_EXPORT void
Kristian Høgsberg29139d42013-04-18 15:25:39 -0400973weston_keyboard_set_focus(struct weston_keyboard *keyboard,
Kristian Høgsbergfe7aa902013-05-08 09:54:37 -0400974 struct weston_surface *surface)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400975{
976 struct wl_resource *resource;
Rob Bradford880ebc72013-07-22 17:31:38 +0100977 struct wl_display *display = keyboard->seat->compositor->wl_display;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400978 uint32_t serial;
Neil Roberts96d790e2013-09-19 17:32:00 +0100979 struct wl_list *focus_resource_list;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400980
Neil Roberts96d790e2013-09-19 17:32:00 +0100981 focus_resource_list = &keyboard->focus_resource_list;
982
983 if (!wl_list_empty(focus_resource_list) && keyboard->focus != surface) {
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400984 serial = wl_display_next_serial(display);
Neil Roberts96d790e2013-09-19 17:32:00 +0100985 wl_resource_for_each(resource, focus_resource_list) {
986 wl_keyboard_send_leave(resource, serial,
987 keyboard->focus->resource);
988 }
989 move_resources(&keyboard->resource_list, focus_resource_list);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400990 }
991
Neil Roberts96d790e2013-09-19 17:32:00 +0100992 if (find_resource_for_surface(&keyboard->resource_list, surface) &&
993 keyboard->focus != surface) {
994 struct wl_client *surface_client =
995 wl_resource_get_client(surface->resource);
996
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400997 serial = wl_display_next_serial(display);
Neil Roberts96d790e2013-09-19 17:32:00 +0100998
999 move_resources_for_client(focus_resource_list,
1000 &keyboard->resource_list,
1001 surface_client);
1002 send_enter_to_resource_list(focus_resource_list,
1003 keyboard,
1004 surface,
1005 serial);
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001006 keyboard->focus_serial = serial;
Giulio Camuffo65a07f82013-12-06 12:46:27 +01001007 }
1008
1009 wl_list_remove(&keyboard->focus_resource_listener.link);
1010 wl_list_init(&keyboard->focus_resource_listener.link);
1011 if (surface && surface->resource)
Giulio Camuffo576fe2a2013-11-20 18:00:24 +01001012 wl_resource_add_destroy_listener(surface->resource,
1013 &keyboard->focus_resource_listener);
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001014
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001015 keyboard->focus = surface;
1016 wl_signal_emit(&keyboard->focus_signal, keyboard);
1017}
1018
Giulio Camuffoa20ca812014-11-22 11:16:56 +02001019/* Users of this function must manually manage the keyboard focus */
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001020WL_EXPORT void
Kristian Høgsberg29139d42013-04-18 15:25:39 -04001021weston_keyboard_start_grab(struct weston_keyboard *keyboard,
1022 struct weston_keyboard_grab *grab)
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001023{
1024 keyboard->grab = grab;
1025 grab->keyboard = keyboard;
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001026}
1027
1028WL_EXPORT void
Kristian Høgsberg29139d42013-04-18 15:25:39 -04001029weston_keyboard_end_grab(struct weston_keyboard *keyboard)
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001030{
1031 keyboard->grab = &keyboard->default_grab;
1032}
1033
Jonas Ådahl1ea343e2013-10-25 23:18:05 +02001034static void
1035weston_keyboard_cancel_grab(struct weston_keyboard *keyboard)
1036{
1037 keyboard->grab->interface->cancel(keyboard->grab);
1038}
1039
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001040WL_EXPORT void
Kristian Høgsberg02bbabb2013-05-06 22:15:05 -04001041weston_pointer_start_grab(struct weston_pointer *pointer,
1042 struct weston_pointer_grab *grab)
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001043{
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001044 pointer->grab = grab;
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001045 grab->pointer = pointer;
Kristian Høgsbergda751b82013-07-04 00:58:07 -04001046 pointer->grab->interface->focus(pointer->grab);
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001047}
1048
1049WL_EXPORT void
Kristian Høgsberg02bbabb2013-05-06 22:15:05 -04001050weston_pointer_end_grab(struct weston_pointer *pointer)
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001051{
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001052 pointer->grab = &pointer->default_grab;
Kristian Høgsbergda751b82013-07-04 00:58:07 -04001053 pointer->grab->interface->focus(pointer->grab);
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001054}
1055
Jonas Ådahl1ea343e2013-10-25 23:18:05 +02001056static void
1057weston_pointer_cancel_grab(struct weston_pointer *pointer)
1058{
1059 pointer->grab->interface->cancel(pointer->grab);
1060}
1061
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001062WL_EXPORT void
Kristian Høgsberge329f362013-05-06 22:19:57 -04001063weston_touch_start_grab(struct weston_touch *touch, struct weston_touch_grab *grab)
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001064{
1065 touch->grab = grab;
1066 grab->touch = touch;
1067}
1068
1069WL_EXPORT void
Kristian Høgsberge329f362013-05-06 22:19:57 -04001070weston_touch_end_grab(struct weston_touch *touch)
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001071{
1072 touch->grab = &touch->default_grab;
1073}
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001074
Jonas Ådahl1ea343e2013-10-25 23:18:05 +02001075static void
1076weston_touch_cancel_grab(struct weston_touch *touch)
1077{
1078 touch->grab->interface->cancel(touch->grab);
1079}
1080
Ander Conselvan de Oliveira54e90c72013-12-13 22:10:56 +02001081static void
1082weston_pointer_clamp_for_output(struct weston_pointer *pointer,
1083 struct weston_output *output,
1084 wl_fixed_t *fx, wl_fixed_t *fy)
1085{
1086 int x, y;
1087
1088 x = wl_fixed_to_int(*fx);
1089 y = wl_fixed_to_int(*fy);
1090
1091 if (x < output->x)
1092 *fx = wl_fixed_from_int(output->x);
1093 else if (x >= output->x + output->width)
1094 *fx = wl_fixed_from_int(output->x +
1095 output->width - 1);
1096 if (y < output->y)
1097 *fy = wl_fixed_from_int(output->y);
1098 else if (y >= output->y + output->height)
1099 *fy = wl_fixed_from_int(output->y +
1100 output->height - 1);
1101}
1102
Rob Bradford806d8c02013-06-25 18:56:41 +01001103WL_EXPORT void
1104weston_pointer_clamp(struct weston_pointer *pointer, wl_fixed_t *fx, wl_fixed_t *fy)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001105{
Rob Bradford806d8c02013-06-25 18:56:41 +01001106 struct weston_compositor *ec = pointer->seat->compositor;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001107 struct weston_output *output, *prev = NULL;
1108 int x, y, old_x, old_y, valid = 0;
1109
1110 x = wl_fixed_to_int(*fx);
1111 y = wl_fixed_to_int(*fy);
Rob Bradford806d8c02013-06-25 18:56:41 +01001112 old_x = wl_fixed_to_int(pointer->x);
1113 old_y = wl_fixed_to_int(pointer->y);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001114
1115 wl_list_for_each(output, &ec->output_list, link) {
Rob Bradford66bd9f52013-06-25 18:56:42 +01001116 if (pointer->seat->output && pointer->seat->output != output)
1117 continue;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001118 if (pixman_region32_contains_point(&output->region,
1119 x, y, NULL))
1120 valid = 1;
1121 if (pixman_region32_contains_point(&output->region,
1122 old_x, old_y, NULL))
1123 prev = output;
1124 }
1125
Rob Bradford66bd9f52013-06-25 18:56:42 +01001126 if (!prev)
1127 prev = pointer->seat->output;
1128
Ander Conselvan de Oliveira54e90c72013-12-13 22:10:56 +02001129 if (prev && !valid)
1130 weston_pointer_clamp_for_output(pointer, prev, fx, fy);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001131}
1132
Jonas Ådahld2510102014-10-05 21:39:14 +02001133static void
1134weston_pointer_move_to(struct weston_pointer *pointer,
1135 wl_fixed_t x, wl_fixed_t y)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001136{
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001137 int32_t ix, iy;
1138
Rob Bradford806d8c02013-06-25 18:56:41 +01001139 weston_pointer_clamp (pointer, &x, &y);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001140
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001141 pointer->x = x;
1142 pointer->y = y;
1143
1144 ix = wl_fixed_to_int(x);
1145 iy = wl_fixed_to_int(y);
1146
Kristian Høgsberg195b8692013-05-08 15:02:05 -04001147 if (pointer->sprite) {
Jason Ekstranda7af7042013-10-12 22:38:11 -05001148 weston_view_set_position(pointer->sprite,
1149 ix - pointer->hotspot_x,
1150 iy - pointer->hotspot_y);
1151 weston_view_schedule_repaint(pointer->sprite);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001152 }
Giulio Camuffo6fcb3782013-11-14 23:42:50 +01001153
Giulio Camuffo1959ab82013-11-14 23:42:52 +01001154 pointer->grab->interface->focus(pointer->grab);
Giulio Camuffo6fcb3782013-11-14 23:42:50 +01001155 wl_signal_emit(&pointer->motion_signal, pointer);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001156}
1157
Jonas Ådahld2510102014-10-05 21:39:14 +02001158WL_EXPORT void
1159weston_pointer_motion_to_abs(struct weston_pointer *pointer,
1160 struct weston_pointer_motion_event *event,
1161 wl_fixed_t *x, wl_fixed_t *y)
1162{
1163 if (event->mask & WESTON_POINTER_MOTION_ABS) {
1164 *x = wl_fixed_from_double(event->x);
1165 *y = wl_fixed_from_double(event->y);
1166 } else if (event->mask & WESTON_POINTER_MOTION_REL) {
1167 *x = pointer->x + wl_fixed_from_double(event->dx);
1168 *y = pointer->y + wl_fixed_from_double(event->dy);
1169 } else {
1170 assert(!"invalid motion event");
1171 *x = *y = 0;
1172 }
1173}
1174
1175WL_EXPORT void
1176weston_pointer_move(struct weston_pointer *pointer,
1177 struct weston_pointer_motion_event *event)
1178{
1179 wl_fixed_t x, y;
1180
1181 weston_pointer_motion_to_abs(pointer, event, &x, &y);
1182 weston_pointer_move_to(pointer, x, y);
1183}
1184
Ander Conselvan de Oliveira54e90c72013-12-13 22:10:56 +02001185/** Verify if the pointer is in a valid position and move it if it isn't.
1186 */
Ander Conselvan de Oliveiraf84327a2014-01-29 18:47:51 +02001187static void
1188weston_pointer_handle_output_destroy(struct wl_listener *listener, void *data)
Ander Conselvan de Oliveira54e90c72013-12-13 22:10:56 +02001189{
Ander Conselvan de Oliveiraf84327a2014-01-29 18:47:51 +02001190 struct weston_pointer *pointer;
1191 struct weston_compositor *ec;
Ander Conselvan de Oliveira54e90c72013-12-13 22:10:56 +02001192 struct weston_output *output, *closest = NULL;
1193 int x, y, distance, min = INT_MAX;
1194 wl_fixed_t fx, fy;
1195
Ander Conselvan de Oliveiraf84327a2014-01-29 18:47:51 +02001196 pointer = container_of(listener, struct weston_pointer,
1197 output_destroy_listener);
1198 ec = pointer->seat->compositor;
1199
Ander Conselvan de Oliveira54e90c72013-12-13 22:10:56 +02001200 x = wl_fixed_to_int(pointer->x);
1201 y = wl_fixed_to_int(pointer->y);
1202
1203 wl_list_for_each(output, &ec->output_list, link) {
1204 if (pixman_region32_contains_point(&output->region,
1205 x, y, NULL))
1206 return;
1207
1208 /* Aproximante the distance from the pointer to the center of
1209 * the output. */
1210 distance = abs(output->x + output->width / 2 - x) +
1211 abs(output->y + output->height / 2 - y);
1212 if (distance < min) {
1213 min = distance;
1214 closest = output;
1215 }
1216 }
1217
1218 /* Nothing to do if there's no output left. */
1219 if (!closest)
1220 return;
1221
1222 fx = pointer->x;
1223 fy = pointer->y;
1224
1225 weston_pointer_clamp_for_output(pointer, closest, &fx, &fy);
Jonas Ådahld2510102014-10-05 21:39:14 +02001226 weston_pointer_move_to(pointer, fx, fy);
Ander Conselvan de Oliveira54e90c72013-12-13 22:10:56 +02001227}
1228
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001229WL_EXPORT void
1230notify_motion(struct weston_seat *seat,
Jonas Ådahld2510102014-10-05 21:39:14 +02001231 uint32_t time,
1232 struct weston_pointer_motion_event *event)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001233{
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001234 struct weston_compositor *ec = seat->compositor;
Derek Foreman1281a362015-07-31 16:55:32 -05001235 struct weston_pointer *pointer = weston_seat_get_pointer(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001236
1237 weston_compositor_wake(ec);
Jonas Ådahld2510102014-10-05 21:39:14 +02001238 pointer->grab->interface->motion(pointer->grab, time, event);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001239}
1240
Daniel Stone96d47c02013-11-19 11:37:12 +01001241static void
1242run_modifier_bindings(struct weston_seat *seat, uint32_t old, uint32_t new)
1243{
1244 struct weston_compositor *compositor = seat->compositor;
Derek Foreman1281a362015-07-31 16:55:32 -05001245 struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
Daniel Stone96d47c02013-11-19 11:37:12 +01001246 uint32_t diff;
1247 unsigned int i;
1248 struct {
1249 uint32_t xkb;
1250 enum weston_keyboard_modifier weston;
1251 } mods[] = {
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001252 { keyboard->xkb_info->ctrl_mod, MODIFIER_CTRL },
1253 { keyboard->xkb_info->alt_mod, MODIFIER_ALT },
1254 { keyboard->xkb_info->super_mod, MODIFIER_SUPER },
1255 { keyboard->xkb_info->shift_mod, MODIFIER_SHIFT },
Daniel Stone96d47c02013-11-19 11:37:12 +01001256 };
1257
1258 diff = new & ~old;
1259 for (i = 0; i < ARRAY_LENGTH(mods); i++) {
1260 if (diff & (1 << mods[i].xkb))
1261 weston_compositor_run_modifier_binding(compositor,
Derek Foreman99a6a2d2015-07-15 13:00:43 -05001262 keyboard,
Daniel Stone96d47c02013-11-19 11:37:12 +01001263 mods[i].weston,
1264 WL_KEYBOARD_KEY_STATE_PRESSED);
1265 }
1266
1267 diff = old & ~new;
1268 for (i = 0; i < ARRAY_LENGTH(mods); i++) {
1269 if (diff & (1 << mods[i].xkb))
1270 weston_compositor_run_modifier_binding(compositor,
Derek Foreman99a6a2d2015-07-15 13:00:43 -05001271 keyboard,
Daniel Stone96d47c02013-11-19 11:37:12 +01001272 mods[i].weston,
1273 WL_KEYBOARD_KEY_STATE_RELEASED);
1274 }
1275}
1276
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001277WL_EXPORT void
1278notify_motion_absolute(struct weston_seat *seat,
Giulio Camuffo90a6fc62016-03-22 17:44:54 +02001279 uint32_t time, double x, double y)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001280{
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001281 struct weston_compositor *ec = seat->compositor;
Derek Foreman1281a362015-07-31 16:55:32 -05001282 struct weston_pointer *pointer = weston_seat_get_pointer(seat);
Jonas Ådahld2510102014-10-05 21:39:14 +02001283 struct weston_pointer_motion_event event = { 0 };
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001284
1285 weston_compositor_wake(ec);
Jonas Ådahld2510102014-10-05 21:39:14 +02001286
1287 event = (struct weston_pointer_motion_event) {
1288 .mask = WESTON_POINTER_MOTION_ABS,
Giulio Camuffo90a6fc62016-03-22 17:44:54 +02001289 .x = x,
1290 .y = y,
Jonas Ådahld2510102014-10-05 21:39:14 +02001291 };
1292
1293 pointer->grab->interface->motion(pointer->grab, time, &event);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001294}
1295
1296WL_EXPORT void
1297weston_surface_activate(struct weston_surface *surface,
1298 struct weston_seat *seat)
1299{
1300 struct weston_compositor *compositor = seat->compositor;
Derek Foreman1281a362015-07-31 16:55:32 -05001301 struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001302
Derek Foreman1281a362015-07-31 16:55:32 -05001303 if (keyboard) {
1304 weston_keyboard_set_focus(keyboard, surface);
Kristian Høgsberge3148752013-05-06 23:19:49 -04001305 wl_data_device_set_keyboard_focus(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001306 }
1307
1308 wl_signal_emit(&compositor->activate_signal, surface);
1309}
1310
1311WL_EXPORT void
1312notify_button(struct weston_seat *seat, uint32_t time, int32_t button,
1313 enum wl_pointer_button_state state)
1314{
1315 struct weston_compositor *compositor = seat->compositor;
Derek Foreman1281a362015-07-31 16:55:32 -05001316 struct weston_pointer *pointer = weston_seat_get_pointer(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001317
1318 if (state == WL_POINTER_BUTTON_STATE_PRESSED) {
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001319 weston_compositor_idle_inhibit(compositor);
1320 if (pointer->button_count == 0) {
1321 pointer->grab_button = button;
1322 pointer->grab_time = time;
1323 pointer->grab_x = pointer->x;
1324 pointer->grab_y = pointer->y;
1325 }
1326 pointer->button_count++;
1327 } else {
1328 weston_compositor_idle_release(compositor);
1329 pointer->button_count--;
1330 }
1331
Derek Foreman99a6a2d2015-07-15 13:00:43 -05001332 weston_compositor_run_button_binding(compositor, pointer, time, button,
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001333 state);
1334
1335 pointer->grab->interface->button(pointer->grab, time, button, state);
1336
1337 if (pointer->button_count == 1)
1338 pointer->grab_serial =
1339 wl_display_get_serial(compositor->wl_display);
1340}
1341
1342WL_EXPORT void
Peter Hutterer89b6a492016-01-18 15:58:17 +10001343notify_axis(struct weston_seat *seat, uint32_t time,
1344 struct weston_pointer_axis_event *event)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001345{
1346 struct weston_compositor *compositor = seat->compositor;
Derek Foreman1281a362015-07-31 16:55:32 -05001347 struct weston_pointer *pointer = weston_seat_get_pointer(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001348
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001349 weston_compositor_wake(compositor);
1350
Derek Foreman99a6a2d2015-07-15 13:00:43 -05001351 if (weston_compositor_run_axis_binding(compositor, pointer,
Peter Hutterer89b6a492016-01-18 15:58:17 +10001352 time, event))
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001353 return;
1354
Peter Hutterer89b6a492016-01-18 15:58:17 +10001355 pointer->grab->interface->axis(pointer->grab, time, event);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001356}
1357
Peter Hutterer87743e92016-01-18 16:38:22 +10001358WL_EXPORT void
1359notify_axis_source(struct weston_seat *seat, uint32_t source)
1360{
1361 struct weston_compositor *compositor = seat->compositor;
1362 struct weston_pointer *pointer = weston_seat_get_pointer(seat);
1363
1364 weston_compositor_wake(compositor);
1365
1366 pointer->grab->interface->axis_source(pointer->grab, source);
1367}
1368
1369WL_EXPORT void
1370notify_pointer_frame(struct weston_seat *seat)
1371{
1372 struct weston_compositor *compositor = seat->compositor;
1373 struct weston_pointer *pointer = weston_seat_get_pointer(seat);
1374
1375 weston_compositor_wake(compositor);
1376
1377 pointer->grab->interface->frame(pointer->grab);
1378}
1379
Giulio Camuffo6ef444d2014-08-28 19:44:09 +03001380WL_EXPORT int
1381weston_keyboard_set_locks(struct weston_keyboard *keyboard,
1382 uint32_t mask, uint32_t value)
1383{
1384#ifdef ENABLE_XKBCOMMON
1385 uint32_t serial;
1386 xkb_mod_mask_t mods_depressed, mods_latched, mods_locked, group;
1387 xkb_mod_mask_t num, caps;
1388
1389 /* We don't want the leds to go out of sync with the actual state
1390 * so if the backend has no way to change the leds don't try to
1391 * change the state */
1392 if (!keyboard->seat->led_update)
1393 return -1;
1394
1395 mods_depressed = xkb_state_serialize_mods(keyboard->xkb_state.state,
1396 XKB_STATE_DEPRESSED);
1397 mods_latched = xkb_state_serialize_mods(keyboard->xkb_state.state,
1398 XKB_STATE_LATCHED);
1399 mods_locked = xkb_state_serialize_mods(keyboard->xkb_state.state,
1400 XKB_STATE_LOCKED);
1401 group = xkb_state_serialize_group(keyboard->xkb_state.state,
1402 XKB_STATE_EFFECTIVE);
1403
1404 num = (1 << keyboard->xkb_info->mod2_mod);
1405 caps = (1 << keyboard->xkb_info->caps_mod);
1406 if (mask & WESTON_NUM_LOCK) {
1407 if (value & WESTON_NUM_LOCK)
1408 mods_locked |= num;
1409 else
1410 mods_locked &= ~num;
1411 }
1412 if (mask & WESTON_CAPS_LOCK) {
1413 if (value & WESTON_CAPS_LOCK)
1414 mods_locked |= caps;
1415 else
1416 mods_locked &= ~caps;
1417 }
1418
1419 xkb_state_update_mask(keyboard->xkb_state.state, mods_depressed,
1420 mods_latched, mods_locked, 0, 0, group);
1421
1422 serial = wl_display_next_serial(
1423 keyboard->seat->compositor->wl_display);
1424 notify_modifiers(keyboard->seat, serial);
1425
1426 return 0;
1427#else
1428 return -1;
1429#endif
1430}
1431
Rob Bradford382ff462013-06-24 16:52:45 +01001432#ifdef ENABLE_XKBCOMMON
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001433WL_EXPORT void
1434notify_modifiers(struct weston_seat *seat, uint32_t serial)
1435{
Derek Foreman1281a362015-07-31 16:55:32 -05001436 struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001437 struct weston_keyboard_grab *grab = keyboard->grab;
1438 uint32_t mods_depressed, mods_latched, mods_locked, group;
1439 uint32_t mods_lookup;
1440 enum weston_led leds = 0;
1441 int changed = 0;
1442
1443 /* Serialize and update our internal state, checking to see if it's
1444 * different to the previous state. */
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001445 mods_depressed = xkb_state_serialize_mods(keyboard->xkb_state.state,
Ran Benita2e1968f2014-08-19 23:59:51 +03001446 XKB_STATE_MODS_DEPRESSED);
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001447 mods_latched = xkb_state_serialize_mods(keyboard->xkb_state.state,
Ran Benita2e1968f2014-08-19 23:59:51 +03001448 XKB_STATE_MODS_LATCHED);
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001449 mods_locked = xkb_state_serialize_mods(keyboard->xkb_state.state,
Ran Benita2e1968f2014-08-19 23:59:51 +03001450 XKB_STATE_MODS_LOCKED);
1451 group = xkb_state_serialize_layout(keyboard->xkb_state.state,
1452 XKB_STATE_LAYOUT_EFFECTIVE);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001453
Derek Foreman244e99e2015-06-03 15:53:26 -05001454 if (mods_depressed != keyboard->modifiers.mods_depressed ||
1455 mods_latched != keyboard->modifiers.mods_latched ||
1456 mods_locked != keyboard->modifiers.mods_locked ||
1457 group != keyboard->modifiers.group)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001458 changed = 1;
1459
Derek Foreman244e99e2015-06-03 15:53:26 -05001460 run_modifier_bindings(seat, keyboard->modifiers.mods_depressed,
Daniel Stone96d47c02013-11-19 11:37:12 +01001461 mods_depressed);
1462
Derek Foreman244e99e2015-06-03 15:53:26 -05001463 keyboard->modifiers.mods_depressed = mods_depressed;
1464 keyboard->modifiers.mods_latched = mods_latched;
1465 keyboard->modifiers.mods_locked = mods_locked;
1466 keyboard->modifiers.group = group;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001467
1468 /* And update the modifier_state for bindings. */
1469 mods_lookup = mods_depressed | mods_latched;
1470 seat->modifier_state = 0;
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001471 if (mods_lookup & (1 << keyboard->xkb_info->ctrl_mod))
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001472 seat->modifier_state |= MODIFIER_CTRL;
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001473 if (mods_lookup & (1 << keyboard->xkb_info->alt_mod))
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001474 seat->modifier_state |= MODIFIER_ALT;
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001475 if (mods_lookup & (1 << keyboard->xkb_info->super_mod))
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001476 seat->modifier_state |= MODIFIER_SUPER;
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001477 if (mods_lookup & (1 << keyboard->xkb_info->shift_mod))
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001478 seat->modifier_state |= MODIFIER_SHIFT;
1479
1480 /* Finally, notify the compositor that LEDs have changed. */
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001481 if (xkb_state_led_index_is_active(keyboard->xkb_state.state,
1482 keyboard->xkb_info->num_led))
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001483 leds |= LED_NUM_LOCK;
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001484 if (xkb_state_led_index_is_active(keyboard->xkb_state.state,
1485 keyboard->xkb_info->caps_led))
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001486 leds |= LED_CAPS_LOCK;
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001487 if (xkb_state_led_index_is_active(keyboard->xkb_state.state,
1488 keyboard->xkb_info->scroll_led))
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001489 leds |= LED_SCROLL_LOCK;
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001490 if (leds != keyboard->xkb_state.leds && seat->led_update)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001491 seat->led_update(seat, leds);
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001492 keyboard->xkb_state.leds = leds;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001493
1494 if (changed) {
1495 grab->interface->modifiers(grab,
1496 serial,
1497 keyboard->modifiers.mods_depressed,
1498 keyboard->modifiers.mods_latched,
1499 keyboard->modifiers.mods_locked,
1500 keyboard->modifiers.group);
1501 }
1502}
1503
1504static void
1505update_modifier_state(struct weston_seat *seat, uint32_t serial, uint32_t key,
1506 enum wl_keyboard_key_state state)
1507{
Derek Foreman1281a362015-07-31 16:55:32 -05001508 struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001509 enum xkb_key_direction direction;
1510
Matt Roper01a92732013-06-24 16:52:44 +01001511 /* Keyboard modifiers don't exist in raw keyboard mode */
1512 if (!seat->compositor->use_xkbcommon)
1513 return;
1514
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001515 if (state == WL_KEYBOARD_KEY_STATE_PRESSED)
1516 direction = XKB_KEY_DOWN;
1517 else
1518 direction = XKB_KEY_UP;
1519
1520 /* Offset the keycode by 8, as the evdev XKB rules reflect X's
1521 * broken keycode system, which starts at 8. */
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001522 xkb_state_update_key(keyboard->xkb_state.state, key + 8, direction);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001523
1524 notify_modifiers(seat, serial);
1525}
Rui Matos65196bc2013-10-10 19:44:19 +02001526
1527static void
1528send_keymap(struct wl_resource *resource, struct weston_xkb_info *xkb_info)
1529{
1530 wl_keyboard_send_keymap(resource,
1531 WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1,
1532 xkb_info->keymap_fd,
1533 xkb_info->keymap_size);
1534}
1535
1536static void
1537send_modifiers(struct wl_resource *resource, uint32_t serial, struct weston_keyboard *keyboard)
1538{
1539 wl_keyboard_send_modifiers(resource, serial,
1540 keyboard->modifiers.mods_depressed,
1541 keyboard->modifiers.mods_latched,
1542 keyboard->modifiers.mods_locked,
1543 keyboard->modifiers.group);
1544}
1545
1546static struct weston_xkb_info *
1547weston_xkb_info_create(struct xkb_keymap *keymap);
Rui Matos65196bc2013-10-10 19:44:19 +02001548
1549static void
1550update_keymap(struct weston_seat *seat)
1551{
Derek Foreman1281a362015-07-31 16:55:32 -05001552 struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
Rui Matos65196bc2013-10-10 19:44:19 +02001553 struct wl_resource *resource;
1554 struct weston_xkb_info *xkb_info;
1555 struct xkb_state *state;
1556 xkb_mod_mask_t latched_mods;
1557 xkb_mod_mask_t locked_mods;
1558
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001559 xkb_info = weston_xkb_info_create(keyboard->pending_keymap);
Rui Matos65196bc2013-10-10 19:44:19 +02001560
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001561 xkb_keymap_unref(keyboard->pending_keymap);
1562 keyboard->pending_keymap = NULL;
Rui Matos65196bc2013-10-10 19:44:19 +02001563
1564 if (!xkb_info) {
1565 weston_log("failed to create XKB info\n");
1566 return;
1567 }
1568
1569 state = xkb_state_new(xkb_info->keymap);
1570 if (!state) {
1571 weston_log("failed to initialise XKB state\n");
1572 weston_xkb_info_destroy(xkb_info);
1573 return;
1574 }
1575
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001576 latched_mods = xkb_state_serialize_mods(keyboard->xkb_state.state,
1577 XKB_STATE_MODS_LATCHED);
1578 locked_mods = xkb_state_serialize_mods(keyboard->xkb_state.state,
1579 XKB_STATE_MODS_LOCKED);
Rui Matos65196bc2013-10-10 19:44:19 +02001580 xkb_state_update_mask(state,
1581 0, /* depressed */
1582 latched_mods,
1583 locked_mods,
1584 0, 0, 0);
1585
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001586 weston_xkb_info_destroy(keyboard->xkb_info);
1587 keyboard->xkb_info = xkb_info;
Rui Matos65196bc2013-10-10 19:44:19 +02001588
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001589 xkb_state_unref(keyboard->xkb_state.state);
1590 keyboard->xkb_state.state = state;
Rui Matos65196bc2013-10-10 19:44:19 +02001591
Derek Foremanbc91e542015-06-03 15:53:27 -05001592 wl_resource_for_each(resource, &keyboard->resource_list)
Rui Matos65196bc2013-10-10 19:44:19 +02001593 send_keymap(resource, xkb_info);
Derek Foremanbc91e542015-06-03 15:53:27 -05001594 wl_resource_for_each(resource, &keyboard->focus_resource_list)
Rui Matos65196bc2013-10-10 19:44:19 +02001595 send_keymap(resource, xkb_info);
1596
1597 notify_modifiers(seat, wl_display_next_serial(seat->compositor->wl_display));
1598
1599 if (!latched_mods && !locked_mods)
1600 return;
1601
Derek Foremanbc91e542015-06-03 15:53:27 -05001602 wl_resource_for_each(resource, &keyboard->resource_list)
1603 send_modifiers(resource, wl_display_get_serial(seat->compositor->wl_display), keyboard);
1604 wl_resource_for_each(resource, &keyboard->focus_resource_list)
1605 send_modifiers(resource, wl_display_get_serial(seat->compositor->wl_display), keyboard);
Rui Matos65196bc2013-10-10 19:44:19 +02001606}
Rob Bradford382ff462013-06-24 16:52:45 +01001607#else
1608WL_EXPORT void
1609notify_modifiers(struct weston_seat *seat, uint32_t serial)
1610{
1611}
1612
1613static void
1614update_modifier_state(struct weston_seat *seat, uint32_t serial, uint32_t key,
1615 enum wl_keyboard_key_state state)
1616{
1617}
Rui Matos65196bc2013-10-10 19:44:19 +02001618
1619static void
1620update_keymap(struct weston_seat *seat)
1621{
1622}
Rob Bradford382ff462013-06-24 16:52:45 +01001623#endif
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001624
1625WL_EXPORT void
1626notify_key(struct weston_seat *seat, uint32_t time, uint32_t key,
1627 enum wl_keyboard_key_state state,
1628 enum weston_key_state_update update_state)
1629{
1630 struct weston_compositor *compositor = seat->compositor;
Derek Foreman1281a362015-07-31 16:55:32 -05001631 struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001632 struct weston_keyboard_grab *grab = keyboard->grab;
Pekka Paalanen86b53962014-11-19 13:43:32 +02001633 uint32_t *k, *end;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001634
1635 if (state == WL_KEYBOARD_KEY_STATE_PRESSED) {
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001636 weston_compositor_idle_inhibit(compositor);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001637 } else {
1638 weston_compositor_idle_release(compositor);
1639 }
1640
Pekka Paalanen86b53962014-11-19 13:43:32 +02001641 end = keyboard->keys.data + keyboard->keys.size;
1642 for (k = keyboard->keys.data; k < end; k++) {
1643 if (*k == key) {
1644 /* Ignore server-generated repeats. */
1645 if (state == WL_KEYBOARD_KEY_STATE_PRESSED)
1646 return;
1647 *k = *--end;
1648 }
1649 }
1650 keyboard->keys.size = (void *) end - keyboard->keys.data;
1651 if (state == WL_KEYBOARD_KEY_STATE_PRESSED) {
1652 k = wl_array_add(&keyboard->keys, sizeof *k);
1653 *k = key;
1654 }
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001655
1656 if (grab == &keyboard->default_grab ||
1657 grab == &keyboard->input_method_grab) {
Derek Foreman99a6a2d2015-07-15 13:00:43 -05001658 weston_compositor_run_key_binding(compositor, keyboard, time,
1659 key, state);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001660 grab = keyboard->grab;
1661 }
1662
1663 grab->interface->key(grab, time, key, state);
1664
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001665 if (keyboard->pending_keymap &&
Pekka Paalanen86b53962014-11-19 13:43:32 +02001666 keyboard->keys.size == 0)
Rui Matos65196bc2013-10-10 19:44:19 +02001667 update_keymap(seat);
1668
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001669 if (update_state == STATE_UPDATE_AUTOMATIC) {
1670 update_modifier_state(seat,
1671 wl_display_get_serial(compositor->wl_display),
1672 key,
1673 state);
1674 }
Giulio Camuffob6ddf6c2015-02-06 19:06:54 +02001675
1676 if (state == WL_KEYBOARD_KEY_STATE_PRESSED) {
1677 keyboard->grab_serial =
1678 wl_display_get_serial(compositor->wl_display);
1679 keyboard->grab_time = time;
1680 keyboard->grab_key = key;
1681 }
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001682}
1683
1684WL_EXPORT void
1685notify_pointer_focus(struct weston_seat *seat, struct weston_output *output,
Giulio Camuffo90a6fc62016-03-22 17:44:54 +02001686 double x, double y)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001687{
Derek Foreman1281a362015-07-31 16:55:32 -05001688 struct weston_pointer *pointer = weston_seat_get_pointer(seat);
1689
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001690 if (output) {
Giulio Camuffo90a6fc62016-03-22 17:44:54 +02001691 weston_pointer_move_to(pointer,
1692 wl_fixed_from_double(x),
1693 wl_fixed_from_double(y));
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001694 } else {
Kristian Høgsberg02bbabb2013-05-06 22:15:05 -04001695 /* FIXME: We should call weston_pointer_set_focus(seat,
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001696 * NULL) here, but somehow that breaks re-entry... */
1697 }
1698}
1699
1700static void
1701destroy_device_saved_kbd_focus(struct wl_listener *listener, void *data)
1702{
1703 struct weston_seat *ws;
1704
1705 ws = container_of(listener, struct weston_seat,
1706 saved_kbd_focus_listener);
1707
1708 ws->saved_kbd_focus = NULL;
1709}
1710
1711WL_EXPORT void
1712notify_keyboard_focus_in(struct weston_seat *seat, struct wl_array *keys,
1713 enum weston_key_state_update update_state)
1714{
1715 struct weston_compositor *compositor = seat->compositor;
Derek Foreman1281a362015-07-31 16:55:32 -05001716 struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
Kristian Høgsbergfe7aa902013-05-08 09:54:37 -04001717 struct weston_surface *surface;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001718 uint32_t *k, serial;
1719
1720 serial = wl_display_next_serial(compositor->wl_display);
1721 wl_array_copy(&keyboard->keys, keys);
1722 wl_array_for_each(k, &keyboard->keys) {
1723 weston_compositor_idle_inhibit(compositor);
1724 if (update_state == STATE_UPDATE_AUTOMATIC)
1725 update_modifier_state(seat, serial, *k,
1726 WL_KEYBOARD_KEY_STATE_PRESSED);
1727 }
1728
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001729 surface = seat->saved_kbd_focus;
1730
1731 if (surface) {
1732 wl_list_remove(&seat->saved_kbd_focus_listener.link);
1733 weston_keyboard_set_focus(keyboard, surface);
1734 seat->saved_kbd_focus = NULL;
1735 }
1736}
1737
1738WL_EXPORT void
1739notify_keyboard_focus_out(struct weston_seat *seat)
1740{
1741 struct weston_compositor *compositor = seat->compositor;
Derek Foreman1281a362015-07-31 16:55:32 -05001742 struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
1743 struct weston_pointer *pointer = weston_seat_get_pointer(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001744 uint32_t *k, serial;
1745
1746 serial = wl_display_next_serial(compositor->wl_display);
1747 wl_array_for_each(k, &keyboard->keys) {
1748 weston_compositor_idle_release(compositor);
1749 update_modifier_state(seat, serial, *k,
1750 WL_KEYBOARD_KEY_STATE_RELEASED);
1751 }
1752
1753 seat->modifier_state = 0;
1754
1755 if (keyboard->focus) {
1756 seat->saved_kbd_focus = keyboard->focus;
1757 seat->saved_kbd_focus_listener.notify =
1758 destroy_device_saved_kbd_focus;
Jason Ekstrand26ed73c2013-06-06 22:34:41 -05001759 wl_signal_add(&keyboard->focus->destroy_signal,
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001760 &seat->saved_kbd_focus_listener);
1761 }
1762
1763 weston_keyboard_set_focus(keyboard, NULL);
Jonas Ådahl1ea343e2013-10-25 23:18:05 +02001764 weston_keyboard_cancel_grab(keyboard);
Derek Foreman1281a362015-07-31 16:55:32 -05001765 if (pointer)
1766 weston_pointer_cancel_grab(pointer);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001767}
1768
Michael Fua2bb7912013-07-23 15:51:06 +08001769WL_EXPORT void
Derek Foreman4c93c082015-04-30 16:45:41 -05001770weston_touch_set_focus(struct weston_touch *touch, struct weston_view *view)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001771{
Neil Roberts96d790e2013-09-19 17:32:00 +01001772 struct wl_list *focus_resource_list;
1773
Derek Foreman4c93c082015-04-30 16:45:41 -05001774 focus_resource_list = &touch->focus_resource_list;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001775
Derek Foreman4c93c082015-04-30 16:45:41 -05001776 if (view && touch->focus &&
1777 touch->focus->surface == view->surface) {
1778 touch->focus = view;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001779 return;
Jason Ekstranda7af7042013-10-12 22:38:11 -05001780 }
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001781
Derek Foreman4c93c082015-04-30 16:45:41 -05001782 wl_list_remove(&touch->focus_resource_listener.link);
1783 wl_list_init(&touch->focus_resource_listener.link);
1784 wl_list_remove(&touch->focus_view_listener.link);
1785 wl_list_init(&touch->focus_view_listener.link);
Giulio Camuffo576fe2a2013-11-20 18:00:24 +01001786
Neil Roberts96d790e2013-09-19 17:32:00 +01001787 if (!wl_list_empty(focus_resource_list)) {
Derek Foreman4c93c082015-04-30 16:45:41 -05001788 move_resources(&touch->resource_list,
Neil Roberts96d790e2013-09-19 17:32:00 +01001789 focus_resource_list);
1790 }
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001791
Jason Ekstranda7af7042013-10-12 22:38:11 -05001792 if (view) {
Derek Foreman362656b2014-09-04 10:23:05 -05001793 struct wl_client *surface_client;
1794
1795 if (!view->surface->resource) {
Derek Foreman4c93c082015-04-30 16:45:41 -05001796 touch->focus = NULL;
Derek Foreman362656b2014-09-04 10:23:05 -05001797 return;
1798 }
1799
1800 surface_client = wl_resource_get_client(view->surface->resource);
Neil Roberts96d790e2013-09-19 17:32:00 +01001801 move_resources_for_client(focus_resource_list,
Derek Foreman4c93c082015-04-30 16:45:41 -05001802 &touch->resource_list,
Neil Roberts96d790e2013-09-19 17:32:00 +01001803 surface_client);
Giulio Camuffo576fe2a2013-11-20 18:00:24 +01001804 wl_resource_add_destroy_listener(view->surface->resource,
Derek Foreman4c93c082015-04-30 16:45:41 -05001805 &touch->focus_resource_listener);
1806 wl_signal_add(&view->destroy_signal, &touch->focus_view_listener);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001807 }
Derek Foreman4c93c082015-04-30 16:45:41 -05001808 touch->focus = view;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001809}
1810
1811/**
1812 * notify_touch - emulates button touches and notifies surfaces accordingly.
1813 *
1814 * It assumes always the correct cycle sequence until it gets here: touch_down
1815 * → touch_update → ... → touch_update → touch_end. The driver is responsible
1816 * for sending along such order.
1817 *
1818 */
1819WL_EXPORT void
1820notify_touch(struct weston_seat *seat, uint32_t time, int touch_id,
Giulio Camuffo90a6fc62016-03-22 17:44:54 +02001821 double double_x, double double_y, int touch_type)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001822{
1823 struct weston_compositor *ec = seat->compositor;
Derek Foreman1281a362015-07-31 16:55:32 -05001824 struct weston_touch *touch = weston_seat_get_touch(seat);
Kristian Høgsberge329f362013-05-06 22:19:57 -04001825 struct weston_touch_grab *grab = touch->grab;
Jason Ekstranda7af7042013-10-12 22:38:11 -05001826 struct weston_view *ev;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001827 wl_fixed_t sx, sy;
Giulio Camuffo90a6fc62016-03-22 17:44:54 +02001828 wl_fixed_t x = wl_fixed_from_double(double_x);
1829 wl_fixed_t y = wl_fixed_from_double(double_y);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001830
1831 /* Update grab's global coordinates. */
Neil Roberts306fe082013-10-03 16:43:06 +01001832 if (touch_id == touch->grab_touch_id && touch_type != WL_TOUCH_UP) {
1833 touch->grab_x = x;
1834 touch->grab_y = y;
1835 }
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001836
1837 switch (touch_type) {
1838 case WL_TOUCH_DOWN:
1839 weston_compositor_idle_inhibit(ec);
1840
Jonas Ådahl9484b692013-12-02 22:05:03 +01001841 touch->num_tp++;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001842
Jason Ekstranda7af7042013-10-12 22:38:11 -05001843 /* the first finger down picks the view, and all further go
1844 * to that view for the remainder of the touch session i.e.
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001845 * until all touch points are up again. */
Jonas Ådahl9484b692013-12-02 22:05:03 +01001846 if (touch->num_tp == 1) {
Jason Ekstranda7af7042013-10-12 22:38:11 -05001847 ev = weston_compositor_pick_view(ec, x, y, &sx, &sy);
Derek Foreman4c93c082015-04-30 16:45:41 -05001848 weston_touch_set_focus(touch, ev);
Giulio Camuffo61ed7b62015-07-08 11:55:28 +03001849 } else if (!touch->focus) {
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001850 /* Unexpected condition: We have non-initial touch but
1851 * there is no focused surface.
1852 */
Chris Michael3f607d32015-10-07 11:59:49 -04001853 weston_log("touch event received with %d points down "
Jonas Ådahl9484b692013-12-02 22:05:03 +01001854 "but no surface focused\n", touch->num_tp);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001855 return;
1856 }
1857
Derek Foreman99a6a2d2015-07-15 13:00:43 -05001858 weston_compositor_run_touch_binding(ec, touch,
Kristian Høgsbergc8964012014-02-05 14:25:18 -08001859 time, touch_type);
1860
Giulio Camuffo61ed7b62015-07-08 11:55:28 +03001861 grab->interface->down(grab, time, touch_id, x, y);
Jonas Ådahl9484b692013-12-02 22:05:03 +01001862 if (touch->num_tp == 1) {
Rusty Lynchf1407ff2013-08-08 21:13:57 -07001863 touch->grab_serial =
1864 wl_display_get_serial(ec->wl_display);
Neil Roberts306fe082013-10-03 16:43:06 +01001865 touch->grab_touch_id = touch_id;
Rusty Lynchf1407ff2013-08-08 21:13:57 -07001866 touch->grab_time = time;
1867 touch->grab_x = x;
1868 touch->grab_y = y;
1869 }
1870
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001871 break;
1872 case WL_TOUCH_MOTION:
Jason Ekstranda7af7042013-10-12 22:38:11 -05001873 ev = touch->focus;
1874 if (!ev)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001875 break;
1876
Giulio Camuffo61ed7b62015-07-08 11:55:28 +03001877 grab->interface->motion(grab, time, touch_id, x, y);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001878 break;
1879 case WL_TOUCH_UP:
Kristian Høgsberga30e29a2014-01-08 22:29:20 -08001880 if (touch->num_tp == 0) {
1881 /* This can happen if we start out with one or
1882 * more fingers on the touch screen, in which
1883 * case we didn't get the corresponding down
1884 * event. */
1885 weston_log("unmatched touch up event\n");
1886 break;
1887 }
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001888 weston_compositor_idle_release(ec);
Jonas Ådahl9484b692013-12-02 22:05:03 +01001889 touch->num_tp--;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001890
1891 grab->interface->up(grab, time, touch_id);
Jonas Ådahl9484b692013-12-02 22:05:03 +01001892 if (touch->num_tp == 0)
Derek Foreman4c93c082015-04-30 16:45:41 -05001893 weston_touch_set_focus(touch, NULL);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001894 break;
1895 }
1896}
1897
Jonas Ådahl1679f232014-04-12 09:39:51 +02001898WL_EXPORT void
1899notify_touch_frame(struct weston_seat *seat)
1900{
Derek Foreman1281a362015-07-31 16:55:32 -05001901 struct weston_touch *touch = weston_seat_get_touch(seat);
Jonas Ådahl1679f232014-04-12 09:39:51 +02001902 struct weston_touch_grab *grab = touch->grab;
1903
1904 grab->interface->frame(grab);
1905}
1906
Derek Foreman3cc004a2015-11-06 15:56:09 -06001907WL_EXPORT void
1908notify_touch_cancel(struct weston_seat *seat)
1909{
1910 struct weston_touch *touch = weston_seat_get_touch(seat);
1911 struct weston_touch_grab *grab = touch->grab;
1912
1913 grab->interface->cancel(grab);
1914}
1915
Pekka Paalanen8274d902014-08-06 19:36:51 +03001916static int
1917pointer_cursor_surface_get_label(struct weston_surface *surface,
1918 char *buf, size_t len)
1919{
1920 return snprintf(buf, len, "cursor");
1921}
1922
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001923static void
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001924pointer_cursor_surface_configure(struct weston_surface *es,
Jason Ekstrand918f2dd2013-12-02 21:01:53 -06001925 int32_t dx, int32_t dy)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001926{
Kristian Høgsberg195b8692013-05-08 15:02:05 -04001927 struct weston_pointer *pointer = es->configure_private;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001928 int x, y;
1929
Jason Ekstrand918f2dd2013-12-02 21:01:53 -06001930 if (es->width == 0)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001931 return;
1932
Jason Ekstranda7af7042013-10-12 22:38:11 -05001933 assert(es == pointer->sprite->surface);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001934
Kristian Høgsberg195b8692013-05-08 15:02:05 -04001935 pointer->hotspot_x -= dx;
1936 pointer->hotspot_y -= dy;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001937
Kristian Høgsberg195b8692013-05-08 15:02:05 -04001938 x = wl_fixed_to_int(pointer->x) - pointer->hotspot_x;
1939 y = wl_fixed_to_int(pointer->y) - pointer->hotspot_y;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001940
Jason Ekstrand918f2dd2013-12-02 21:01:53 -06001941 weston_view_set_position(pointer->sprite, x, y);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001942
1943 empty_region(&es->pending.input);
Ander Conselvan de Oliveira23900f72014-01-31 16:07:51 +02001944 empty_region(&es->input);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001945
1946 if (!weston_surface_is_mapped(es)) {
Giulio Camuffo412e6a52014-07-09 22:12:56 +03001947 weston_layer_entry_insert(&es->compositor->cursor_layer.view_list,
1948 &pointer->sprite->layer_link);
Jason Ekstranda7af7042013-10-12 22:38:11 -05001949 weston_view_update_transform(pointer->sprite);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001950 }
1951}
1952
1953static void
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001954pointer_set_cursor(struct wl_client *client, struct wl_resource *resource,
1955 uint32_t serial, struct wl_resource *surface_resource,
1956 int32_t x, int32_t y)
1957{
Jason Ekstrand44a38632013-06-14 10:08:00 -05001958 struct weston_pointer *pointer = wl_resource_get_user_data(resource);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001959 struct weston_surface *surface = NULL;
1960
1961 if (surface_resource)
Jason Ekstrand0f2ef7e2013-06-14 10:07:53 -05001962 surface = wl_resource_get_user_data(surface_resource);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001963
Kristian Høgsberg195b8692013-05-08 15:02:05 -04001964 if (pointer->focus == NULL)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001965 return;
Jason Ekstranda7af7042013-10-12 22:38:11 -05001966 /* pointer->focus->surface->resource can be NULL. Surfaces like the
Giulio Camuffo1fd4b012013-06-20 18:13:07 +02001967 black_surface used in shell.c for fullscreen don't have
1968 a resource, but can still have focus */
Jason Ekstranda7af7042013-10-12 22:38:11 -05001969 if (pointer->focus->surface->resource == NULL)
Giulio Camuffo1fd4b012013-06-20 18:13:07 +02001970 return;
Jason Ekstranda7af7042013-10-12 22:38:11 -05001971 if (wl_resource_get_client(pointer->focus->surface->resource) != client)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001972 return;
Kristian Høgsberg195b8692013-05-08 15:02:05 -04001973 if (pointer->focus_serial - serial > UINT32_MAX / 2)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001974 return;
1975
Derek Foreman4e53c532015-03-23 10:55:32 -05001976 if (!surface) {
1977 if (pointer->sprite)
1978 pointer_unmap_sprite(pointer);
1979 return;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001980 }
1981
Jonas Ådahlb4070242015-03-18 15:08:03 +08001982 if (pointer->sprite && pointer->sprite->surface == surface &&
1983 pointer->hotspot_x == x && pointer->hotspot_y == y)
1984 return;
1985
Derek Foreman4e53c532015-03-23 10:55:32 -05001986 if (!pointer->sprite || pointer->sprite->surface != surface) {
1987 if (weston_surface_set_role(surface, "wl_pointer-cursor",
1988 resource,
1989 WL_POINTER_ERROR_ROLE) < 0)
1990 return;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001991
Derek Foreman4e53c532015-03-23 10:55:32 -05001992 if (pointer->sprite)
1993 pointer_unmap_sprite(pointer);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001994
Derek Foreman4e53c532015-03-23 10:55:32 -05001995 wl_signal_add(&surface->destroy_signal,
1996 &pointer->sprite_destroy_listener);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001997
Derek Foreman4e53c532015-03-23 10:55:32 -05001998 surface->configure = pointer_cursor_surface_configure;
1999 surface->configure_private = pointer;
2000 weston_surface_set_label_func(surface,
2001 pointer_cursor_surface_get_label);
2002 pointer->sprite = weston_view_create(surface);
2003 }
2004
Kristian Høgsberg195b8692013-05-08 15:02:05 -04002005 pointer->hotspot_x = x;
2006 pointer->hotspot_y = y;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002007
Jonas Ådahl16fe4dc2014-09-08 19:33:41 +02002008 if (surface->buffer_ref.buffer) {
Jason Ekstrand918f2dd2013-12-02 21:01:53 -06002009 pointer_cursor_surface_configure(surface, 0, 0);
Jonas Ådahl16fe4dc2014-09-08 19:33:41 +02002010 weston_view_schedule_repaint(pointer->sprite);
2011 }
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002012}
2013
Kristian Høgsberg69e25fc2013-08-13 20:11:02 +01002014static void
2015pointer_release(struct wl_client *client, struct wl_resource *resource)
2016{
2017 wl_resource_destroy(resource);
2018}
2019
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002020static const struct wl_pointer_interface pointer_interface = {
Kristian Høgsberg69e25fc2013-08-13 20:11:02 +01002021 pointer_set_cursor,
2022 pointer_release
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002023};
2024
2025static void
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002026seat_get_pointer(struct wl_client *client, struct wl_resource *resource,
2027 uint32_t id)
2028{
Jason Ekstrand44a38632013-06-14 10:08:00 -05002029 struct weston_seat *seat = wl_resource_get_user_data(resource);
Derek Foreman1281a362015-07-31 16:55:32 -05002030 /* We use the pointer_state directly, which means we'll
2031 * give a wl_pointer if the seat has ever had one - even though
2032 * the spec explicitly states that this request only takes effect
2033 * if the seat has the pointer capability.
2034 *
2035 * This prevents a race between the compositor sending new
2036 * capabilities and the client trying to use the old ones.
2037 */
2038 struct weston_pointer *pointer = seat->pointer_state;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002039 struct wl_resource *cr;
Jonas Ådahl2cbf2932015-07-22 12:05:38 +08002040 struct weston_pointer_client *pointer_client;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002041
Derek Foreman1281a362015-07-31 16:55:32 -05002042 if (!pointer)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002043 return;
2044
Jason Ekstranda85118c2013-06-27 20:17:02 -05002045 cr = wl_resource_create(client, &wl_pointer_interface,
2046 wl_resource_get_version(resource), id);
Kristian Høgsberg0ff79082013-08-06 16:46:25 -07002047 if (cr == NULL) {
2048 wl_client_post_no_memory(client);
2049 return;
2050 }
2051
Jonas Ådahl2cbf2932015-07-22 12:05:38 +08002052 pointer_client = weston_pointer_ensure_pointer_client(pointer, client);
2053 if (!pointer_client) {
2054 wl_client_post_no_memory(client);
2055 return;
2056 }
2057
2058 wl_list_insert(&pointer_client->pointer_resources,
2059 wl_resource_get_link(cr));
Derek Foreman1281a362015-07-31 16:55:32 -05002060 wl_resource_set_implementation(cr, &pointer_interface, pointer,
Jonas Ådahl2cbf2932015-07-22 12:05:38 +08002061 unbind_pointer_client_resource);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002062
Derek Foreman1281a362015-07-31 16:55:32 -05002063 if (pointer->focus && pointer->focus->surface->resource &&
2064 wl_resource_get_client(pointer->focus->surface->resource) == client) {
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002065 wl_fixed_t sx, sy;
2066
Derek Foreman1281a362015-07-31 16:55:32 -05002067 weston_view_from_global_fixed(pointer->focus,
2068 pointer->x,
2069 pointer->y,
Jason Ekstranda7af7042013-10-12 22:38:11 -05002070 &sx, &sy);
Neil Roberts96d790e2013-09-19 17:32:00 +01002071
Neil Roberts96d790e2013-09-19 17:32:00 +01002072 wl_pointer_send_enter(cr,
Derek Foreman1281a362015-07-31 16:55:32 -05002073 pointer->focus_serial,
2074 pointer->focus->surface->resource,
Neil Roberts96d790e2013-09-19 17:32:00 +01002075 sx, sy);
Peter Hutterer87743e92016-01-18 16:38:22 +10002076 pointer_send_frame(cr);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002077 }
2078}
2079
2080static void
Kristian Høgsberg69e25fc2013-08-13 20:11:02 +01002081keyboard_release(struct wl_client *client, struct wl_resource *resource)
2082{
2083 wl_resource_destroy(resource);
2084}
2085
2086static const struct wl_keyboard_interface keyboard_interface = {
2087 keyboard_release
2088};
2089
Derek Foreman280e7dd2014-10-03 13:13:42 -05002090static bool
Neil Roberts96d790e2013-09-19 17:32:00 +01002091should_send_modifiers_to_client(struct weston_seat *seat,
2092 struct wl_client *client)
2093{
Derek Foreman1281a362015-07-31 16:55:32 -05002094 struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
2095 struct weston_pointer *pointer = weston_seat_get_pointer(seat);
2096
2097 if (keyboard &&
2098 keyboard->focus &&
2099 keyboard->focus->resource &&
2100 wl_resource_get_client(keyboard->focus->resource) == client)
Derek Foreman280e7dd2014-10-03 13:13:42 -05002101 return true;
Neil Roberts96d790e2013-09-19 17:32:00 +01002102
Derek Foreman1281a362015-07-31 16:55:32 -05002103 if (pointer &&
2104 pointer->focus &&
2105 pointer->focus->surface->resource &&
2106 wl_resource_get_client(pointer->focus->surface->resource) == client)
Derek Foreman280e7dd2014-10-03 13:13:42 -05002107 return true;
Neil Roberts96d790e2013-09-19 17:32:00 +01002108
Derek Foreman280e7dd2014-10-03 13:13:42 -05002109 return false;
Neil Roberts96d790e2013-09-19 17:32:00 +01002110}
2111
Kristian Høgsberg69e25fc2013-08-13 20:11:02 +01002112static void
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002113seat_get_keyboard(struct wl_client *client, struct wl_resource *resource,
2114 uint32_t id)
2115{
Jason Ekstrand44a38632013-06-14 10:08:00 -05002116 struct weston_seat *seat = wl_resource_get_user_data(resource);
Derek Foreman1281a362015-07-31 16:55:32 -05002117 /* We use the keyboard_state directly, which means we'll
2118 * give a wl_keyboard if the seat has ever had one - even though
2119 * the spec explicitly states that this request only takes effect
2120 * if the seat has the keyboard capability.
2121 *
2122 * This prevents a race between the compositor sending new
2123 * capabilities and the client trying to use the old ones.
2124 */
2125 struct weston_keyboard *keyboard = seat->keyboard_state;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002126 struct wl_resource *cr;
2127
Derek Foreman345c9f32015-06-03 15:53:28 -05002128 if (!keyboard)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002129 return;
2130
Jason Ekstranda85118c2013-06-27 20:17:02 -05002131 cr = wl_resource_create(client, &wl_keyboard_interface,
2132 wl_resource_get_version(resource), id);
Kristian Høgsberg0ff79082013-08-06 16:46:25 -07002133 if (cr == NULL) {
2134 wl_client_post_no_memory(client);
2135 return;
2136 }
2137
Neil Roberts96d790e2013-09-19 17:32:00 +01002138 /* May be moved to focused list later by either
2139 * weston_keyboard_set_focus or directly if this client is already
2140 * focused */
Derek Foreman345c9f32015-06-03 15:53:28 -05002141 wl_list_insert(&keyboard->resource_list, wl_resource_get_link(cr));
Kristian Høgsberg69e25fc2013-08-13 20:11:02 +01002142 wl_resource_set_implementation(cr, &keyboard_interface,
2143 seat, unbind_resource);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002144
Jonny Lamb66a41a02014-08-12 14:58:25 +02002145 if (wl_resource_get_version(cr) >= WL_KEYBOARD_REPEAT_INFO_SINCE_VERSION) {
2146 wl_keyboard_send_repeat_info(cr,
2147 seat->compositor->kb_repeat_rate,
2148 seat->compositor->kb_repeat_delay);
2149 }
Jasper St. Pierred8c6aeb2014-08-04 13:43:24 -04002150
Matt Roper01a92732013-06-24 16:52:44 +01002151 if (seat->compositor->use_xkbcommon) {
2152 wl_keyboard_send_keymap(cr, WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1,
Jonas Ådahl7395ea02013-12-03 09:14:26 +01002153 keyboard->xkb_info->keymap_fd,
2154 keyboard->xkb_info->keymap_size);
Matt Roper01a92732013-06-24 16:52:44 +01002155 } else {
2156 int null_fd = open("/dev/null", O_RDONLY);
2157 wl_keyboard_send_keymap(cr, WL_KEYBOARD_KEYMAP_FORMAT_NO_KEYMAP,
2158 null_fd,
2159 0);
2160 close(null_fd);
2161 }
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002162
Neil Roberts96d790e2013-09-19 17:32:00 +01002163 if (should_send_modifiers_to_client(seat, client)) {
Derek Foreman345c9f32015-06-03 15:53:28 -05002164 send_modifiers_to_resource(keyboard,
Neil Roberts96d790e2013-09-19 17:32:00 +01002165 cr,
Derek Foreman345c9f32015-06-03 15:53:28 -05002166 keyboard->focus_serial);
Neil Roberts96d790e2013-09-19 17:32:00 +01002167 }
2168
Derek Foreman345c9f32015-06-03 15:53:28 -05002169 if (keyboard->focus && keyboard->focus->resource &&
2170 wl_resource_get_client(keyboard->focus->resource) == client) {
Neil Roberts96d790e2013-09-19 17:32:00 +01002171 struct weston_surface *surface =
Derek Foreman345c9f32015-06-03 15:53:28 -05002172 (struct weston_surface *)keyboard->focus;
Neil Roberts96d790e2013-09-19 17:32:00 +01002173
2174 wl_list_remove(wl_resource_get_link(cr));
Derek Foreman345c9f32015-06-03 15:53:28 -05002175 wl_list_insert(&keyboard->focus_resource_list,
Neil Roberts96d790e2013-09-19 17:32:00 +01002176 wl_resource_get_link(cr));
2177 wl_keyboard_send_enter(cr,
Derek Foreman345c9f32015-06-03 15:53:28 -05002178 keyboard->focus_serial,
Neil Roberts96d790e2013-09-19 17:32:00 +01002179 surface->resource,
Derek Foreman345c9f32015-06-03 15:53:28 -05002180 &keyboard->keys);
Neil Roberts96d790e2013-09-19 17:32:00 +01002181
2182 /* If this is the first keyboard resource for this
2183 * client... */
Derek Foreman345c9f32015-06-03 15:53:28 -05002184 if (keyboard->focus_resource_list.prev ==
Neil Roberts96d790e2013-09-19 17:32:00 +01002185 wl_resource_get_link(cr))
2186 wl_data_device_set_keyboard_focus(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002187 }
2188}
2189
2190static void
Kristian Høgsberg69e25fc2013-08-13 20:11:02 +01002191touch_release(struct wl_client *client, struct wl_resource *resource)
2192{
2193 wl_resource_destroy(resource);
2194}
2195
2196static const struct wl_touch_interface touch_interface = {
2197 touch_release
2198};
2199
2200static void
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002201seat_get_touch(struct wl_client *client, struct wl_resource *resource,
2202 uint32_t id)
2203{
Jason Ekstrand44a38632013-06-14 10:08:00 -05002204 struct weston_seat *seat = wl_resource_get_user_data(resource);
Derek Foreman1281a362015-07-31 16:55:32 -05002205 /* We use the touch_state directly, which means we'll
2206 * give a wl_touch if the seat has ever had one - even though
2207 * the spec explicitly states that this request only takes effect
2208 * if the seat has the touch capability.
2209 *
2210 * This prevents a race between the compositor sending new
2211 * capabilities and the client trying to use the old ones.
2212 */
2213 struct weston_touch *touch = seat->touch_state;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002214 struct wl_resource *cr;
2215
Derek Foreman1281a362015-07-31 16:55:32 -05002216 if (!touch)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002217 return;
2218
Jason Ekstranda85118c2013-06-27 20:17:02 -05002219 cr = wl_resource_create(client, &wl_touch_interface,
2220 wl_resource_get_version(resource), id);
Kristian Høgsberg0ff79082013-08-06 16:46:25 -07002221 if (cr == NULL) {
2222 wl_client_post_no_memory(client);
2223 return;
2224 }
2225
Derek Foreman1281a362015-07-31 16:55:32 -05002226 if (touch->focus &&
2227 wl_resource_get_client(touch->focus->surface->resource) == client) {
Chokshi, Mituld6697142015-10-09 08:28:47 +00002228 wl_list_insert(&touch->focus_resource_list,
Neil Roberts96d790e2013-09-19 17:32:00 +01002229 wl_resource_get_link(cr));
2230 } else {
Chokshi, Mituld6697142015-10-09 08:28:47 +00002231 wl_list_insert(&touch->resource_list,
Neil Roberts96d790e2013-09-19 17:32:00 +01002232 wl_resource_get_link(cr));
2233 }
Kristian Høgsberg69e25fc2013-08-13 20:11:02 +01002234 wl_resource_set_implementation(cr, &touch_interface,
2235 seat, unbind_resource);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002236}
2237
Quentin Glidicaab1d362016-03-13 17:49:08 +01002238static void
2239seat_release(struct wl_client *client, struct wl_resource *resource)
2240{
2241 wl_resource_destroy(resource);
2242}
2243
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002244static const struct wl_seat_interface seat_interface = {
2245 seat_get_pointer,
2246 seat_get_keyboard,
2247 seat_get_touch,
Quentin Glidicaab1d362016-03-13 17:49:08 +01002248 seat_release,
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002249};
2250
2251static void
2252bind_seat(struct wl_client *client, void *data, uint32_t version, uint32_t id)
2253{
Kristian Høgsberge3148752013-05-06 23:19:49 -04002254 struct weston_seat *seat = data;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002255 struct wl_resource *resource;
2256 enum wl_seat_capability caps = 0;
2257
Jason Ekstranda85118c2013-06-27 20:17:02 -05002258 resource = wl_resource_create(client,
Derek Foreman1909c102015-11-26 14:17:47 -06002259 &wl_seat_interface, version, id);
Jason Ekstrand44a38632013-06-14 10:08:00 -05002260 wl_list_insert(&seat->base_resource_list, wl_resource_get_link(resource));
Jason Ekstranda85118c2013-06-27 20:17:02 -05002261 wl_resource_set_implementation(resource, &seat_interface, data,
2262 unbind_resource);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002263
Derek Foreman1281a362015-07-31 16:55:32 -05002264 if (weston_seat_get_pointer(seat))
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002265 caps |= WL_SEAT_CAPABILITY_POINTER;
Derek Foreman1281a362015-07-31 16:55:32 -05002266 if (weston_seat_get_keyboard(seat))
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002267 caps |= WL_SEAT_CAPABILITY_KEYBOARD;
Derek Foreman1281a362015-07-31 16:55:32 -05002268 if (weston_seat_get_touch(seat))
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002269 caps |= WL_SEAT_CAPABILITY_TOUCH;
2270
2271 wl_seat_send_capabilities(resource, caps);
Jasper St. Pierre0013a292014-08-07 16:43:11 -04002272 if (version >= WL_SEAT_NAME_SINCE_VERSION)
Rob Bradforde445ae62013-05-31 18:09:51 +01002273 wl_seat_send_name(resource, seat->seat_name);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002274}
2275
Rob Bradford382ff462013-06-24 16:52:45 +01002276#ifdef ENABLE_XKBCOMMON
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002277int
2278weston_compositor_xkb_init(struct weston_compositor *ec,
2279 struct xkb_rule_names *names)
2280{
Rob Bradford382ff462013-06-24 16:52:45 +01002281 ec->use_xkbcommon = 1;
Matt Roper01a92732013-06-24 16:52:44 +01002282
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002283 if (ec->xkb_context == NULL) {
2284 ec->xkb_context = xkb_context_new(0);
2285 if (ec->xkb_context == NULL) {
2286 weston_log("failed to create XKB context\n");
2287 return -1;
2288 }
2289 }
2290
2291 if (names)
2292 ec->xkb_names = *names;
2293 if (!ec->xkb_names.rules)
2294 ec->xkb_names.rules = strdup("evdev");
2295 if (!ec->xkb_names.model)
2296 ec->xkb_names.model = strdup("pc105");
2297 if (!ec->xkb_names.layout)
2298 ec->xkb_names.layout = strdup("us");
2299
2300 return 0;
2301}
2302
Stefan Schmidtfda26522013-09-17 10:54:09 +01002303static void
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00002304weston_xkb_info_destroy(struct weston_xkb_info *xkb_info)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002305{
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00002306 if (--xkb_info->ref_count > 0)
2307 return;
2308
Ran Benitac9c74152014-08-19 23:59:52 +03002309 xkb_keymap_unref(xkb_info->keymap);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002310
2311 if (xkb_info->keymap_area)
2312 munmap(xkb_info->keymap_area, xkb_info->keymap_size);
2313 if (xkb_info->keymap_fd >= 0)
2314 close(xkb_info->keymap_fd);
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00002315 free(xkb_info);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002316}
2317
2318void
2319weston_compositor_xkb_destroy(struct weston_compositor *ec)
2320{
Matt Roper01a92732013-06-24 16:52:44 +01002321 /*
2322 * If we're operating in raw keyboard mode, we never initialized
2323 * libxkbcommon so there's no cleanup to do either.
2324 */
2325 if (!ec->use_xkbcommon)
2326 return;
2327
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002328 free((char *) ec->xkb_names.rules);
2329 free((char *) ec->xkb_names.model);
2330 free((char *) ec->xkb_names.layout);
2331 free((char *) ec->xkb_names.variant);
2332 free((char *) ec->xkb_names.options);
Stefan Schmidtfda26522013-09-17 10:54:09 +01002333
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00002334 if (ec->xkb_info)
2335 weston_xkb_info_destroy(ec->xkb_info);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002336 xkb_context_unref(ec->xkb_context);
2337}
2338
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00002339static struct weston_xkb_info *
2340weston_xkb_info_create(struct xkb_keymap *keymap)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002341{
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00002342 struct weston_xkb_info *xkb_info = zalloc(sizeof *xkb_info);
2343 if (xkb_info == NULL)
2344 return NULL;
2345
Ran Benita2e1968f2014-08-19 23:59:51 +03002346 xkb_info->keymap = xkb_keymap_ref(keymap);
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00002347 xkb_info->ref_count = 1;
2348
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002349 char *keymap_str;
2350
Ran Benita2e1968f2014-08-19 23:59:51 +03002351 xkb_info->shift_mod = xkb_keymap_mod_get_index(xkb_info->keymap,
2352 XKB_MOD_NAME_SHIFT);
2353 xkb_info->caps_mod = xkb_keymap_mod_get_index(xkb_info->keymap,
2354 XKB_MOD_NAME_CAPS);
2355 xkb_info->ctrl_mod = xkb_keymap_mod_get_index(xkb_info->keymap,
2356 XKB_MOD_NAME_CTRL);
2357 xkb_info->alt_mod = xkb_keymap_mod_get_index(xkb_info->keymap,
2358 XKB_MOD_NAME_ALT);
2359 xkb_info->mod2_mod = xkb_keymap_mod_get_index(xkb_info->keymap,
2360 "Mod2");
2361 xkb_info->mod3_mod = xkb_keymap_mod_get_index(xkb_info->keymap,
2362 "Mod3");
2363 xkb_info->super_mod = xkb_keymap_mod_get_index(xkb_info->keymap,
2364 XKB_MOD_NAME_LOGO);
2365 xkb_info->mod5_mod = xkb_keymap_mod_get_index(xkb_info->keymap,
2366 "Mod5");
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002367
Ran Benita2e1968f2014-08-19 23:59:51 +03002368 xkb_info->num_led = xkb_keymap_led_get_index(xkb_info->keymap,
2369 XKB_LED_NAME_NUM);
2370 xkb_info->caps_led = xkb_keymap_led_get_index(xkb_info->keymap,
2371 XKB_LED_NAME_CAPS);
2372 xkb_info->scroll_led = xkb_keymap_led_get_index(xkb_info->keymap,
2373 XKB_LED_NAME_SCROLL);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002374
Ran Benita2e1968f2014-08-19 23:59:51 +03002375 keymap_str = xkb_keymap_get_as_string(xkb_info->keymap,
2376 XKB_KEYMAP_FORMAT_TEXT_V1);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002377 if (keymap_str == NULL) {
2378 weston_log("failed to get string version of keymap\n");
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00002379 goto err_keymap;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002380 }
2381 xkb_info->keymap_size = strlen(keymap_str) + 1;
2382
2383 xkb_info->keymap_fd = os_create_anonymous_file(xkb_info->keymap_size);
2384 if (xkb_info->keymap_fd < 0) {
2385 weston_log("creating a keymap file for %lu bytes failed: %m\n",
2386 (unsigned long) xkb_info->keymap_size);
2387 goto err_keymap_str;
2388 }
2389
2390 xkb_info->keymap_area = mmap(NULL, xkb_info->keymap_size,
2391 PROT_READ | PROT_WRITE,
2392 MAP_SHARED, xkb_info->keymap_fd, 0);
2393 if (xkb_info->keymap_area == MAP_FAILED) {
2394 weston_log("failed to mmap() %lu bytes\n",
2395 (unsigned long) xkb_info->keymap_size);
2396 goto err_dev_zero;
2397 }
2398 strcpy(xkb_info->keymap_area, keymap_str);
2399 free(keymap_str);
2400
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00002401 return xkb_info;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002402
2403err_dev_zero:
2404 close(xkb_info->keymap_fd);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002405err_keymap_str:
2406 free(keymap_str);
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00002407err_keymap:
Ran Benita2e1968f2014-08-19 23:59:51 +03002408 xkb_keymap_unref(xkb_info->keymap);
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00002409 free(xkb_info);
2410 return NULL;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002411}
2412
2413static int
2414weston_compositor_build_global_keymap(struct weston_compositor *ec)
2415{
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00002416 struct xkb_keymap *keymap;
2417
2418 if (ec->xkb_info != NULL)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002419 return 0;
2420
Ran Benita2e1968f2014-08-19 23:59:51 +03002421 keymap = xkb_keymap_new_from_names(ec->xkb_context,
2422 &ec->xkb_names,
2423 0);
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00002424 if (keymap == NULL) {
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002425 weston_log("failed to compile global XKB keymap\n");
2426 weston_log(" tried rules %s, model %s, layout %s, variant %s, "
2427 "options %s\n",
2428 ec->xkb_names.rules, ec->xkb_names.model,
2429 ec->xkb_names.layout, ec->xkb_names.variant,
2430 ec->xkb_names.options);
2431 return -1;
2432 }
2433
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00002434 ec->xkb_info = weston_xkb_info_create(keymap);
Rui Matos73d93952013-10-24 19:28:41 +02002435 xkb_keymap_unref(keymap);
Stefan Schmidtfda26522013-09-17 10:54:09 +01002436 if (ec->xkb_info == NULL)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002437 return -1;
2438
2439 return 0;
2440}
Rob Bradford382ff462013-06-24 16:52:45 +01002441#else
2442int
2443weston_compositor_xkb_init(struct weston_compositor *ec,
2444 struct xkb_rule_names *names)
2445{
2446 return 0;
2447}
2448
2449void
2450weston_compositor_xkb_destroy(struct weston_compositor *ec)
2451{
2452}
2453#endif
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002454
Rui Matos65196bc2013-10-10 19:44:19 +02002455WL_EXPORT void
2456weston_seat_update_keymap(struct weston_seat *seat, struct xkb_keymap *keymap)
2457{
Derek Foreman1281a362015-07-31 16:55:32 -05002458 struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
2459
2460 if (!keyboard || !keymap)
Rui Matos65196bc2013-10-10 19:44:19 +02002461 return;
2462
2463#ifdef ENABLE_XKBCOMMON
2464 if (!seat->compositor->use_xkbcommon)
2465 return;
2466
Derek Foreman1281a362015-07-31 16:55:32 -05002467 xkb_keymap_unref(keyboard->pending_keymap);
2468 keyboard->pending_keymap = xkb_keymap_ref(keymap);
Rui Matos65196bc2013-10-10 19:44:19 +02002469
Derek Foreman1281a362015-07-31 16:55:32 -05002470 if (keyboard->keys.size == 0)
Rui Matos65196bc2013-10-10 19:44:19 +02002471 update_keymap(seat);
2472#endif
2473}
2474
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002475WL_EXPORT int
2476weston_seat_init_keyboard(struct weston_seat *seat, struct xkb_keymap *keymap)
2477{
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04002478 struct weston_keyboard *keyboard;
2479
Derek Foreman1281a362015-07-31 16:55:32 -05002480 if (seat->keyboard_state) {
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002481 seat->keyboard_device_count += 1;
2482 if (seat->keyboard_device_count == 1)
2483 seat_send_updated_caps(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002484 return 0;
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002485 }
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002486
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04002487 keyboard = weston_keyboard_create();
2488 if (keyboard == NULL) {
2489 weston_log("failed to allocate weston keyboard struct\n");
2490 return -1;
2491 }
2492
Jonas Ådahl7395ea02013-12-03 09:14:26 +01002493#ifdef ENABLE_XKBCOMMON
2494 if (seat->compositor->use_xkbcommon) {
2495 if (keymap != NULL) {
2496 keyboard->xkb_info = weston_xkb_info_create(keymap);
2497 if (keyboard->xkb_info == NULL)
Ander Conselvan de Oliveira4d363cf2014-01-31 17:35:45 +02002498 goto err;
Jonas Ådahl7395ea02013-12-03 09:14:26 +01002499 } else {
2500 if (weston_compositor_build_global_keymap(seat->compositor) < 0)
Ander Conselvan de Oliveira4d363cf2014-01-31 17:35:45 +02002501 goto err;
Jonas Ådahl7395ea02013-12-03 09:14:26 +01002502 keyboard->xkb_info = seat->compositor->xkb_info;
2503 keyboard->xkb_info->ref_count++;
2504 }
2505
2506 keyboard->xkb_state.state = xkb_state_new(keyboard->xkb_info->keymap);
2507 if (keyboard->xkb_state.state == NULL) {
2508 weston_log("failed to initialise XKB state\n");
Ander Conselvan de Oliveira4d363cf2014-01-31 17:35:45 +02002509 goto err;
Jonas Ådahl7395ea02013-12-03 09:14:26 +01002510 }
2511
2512 keyboard->xkb_state.leds = 0;
2513 }
2514#endif
2515
Derek Foreman1281a362015-07-31 16:55:32 -05002516 seat->keyboard_state = keyboard;
Ander Conselvan de Oliveira4d363cf2014-01-31 17:35:45 +02002517 seat->keyboard_device_count = 1;
2518 keyboard->seat = seat;
2519
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04002520 seat_send_updated_caps(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002521
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002522 return 0;
Ander Conselvan de Oliveira4d363cf2014-01-31 17:35:45 +02002523
2524err:
2525 if (keyboard->xkb_info)
2526 weston_xkb_info_destroy(keyboard->xkb_info);
2527 free(keyboard);
2528
2529 return -1;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002530}
2531
Jonas Ådahl91fed542013-12-03 09:14:27 +01002532static void
2533weston_keyboard_reset_state(struct weston_keyboard *keyboard)
2534{
2535 struct weston_seat *seat = keyboard->seat;
2536 struct xkb_state *state;
2537
2538#ifdef ENABLE_XKBCOMMON
2539 if (seat->compositor->use_xkbcommon) {
2540 state = xkb_state_new(keyboard->xkb_info->keymap);
2541 if (!state) {
2542 weston_log("failed to reset XKB state\n");
2543 return;
2544 }
2545 xkb_state_unref(keyboard->xkb_state.state);
2546 keyboard->xkb_state.state = state;
2547
2548 keyboard->xkb_state.leds = 0;
2549 }
2550#endif
2551
2552 seat->modifier_state = 0;
2553}
2554
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002555WL_EXPORT void
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002556weston_seat_release_keyboard(struct weston_seat *seat)
2557{
2558 seat->keyboard_device_count--;
Derek Foremand621df22014-11-19 11:04:12 -06002559 assert(seat->keyboard_device_count >= 0);
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002560 if (seat->keyboard_device_count == 0) {
Derek Foreman1281a362015-07-31 16:55:32 -05002561 weston_keyboard_set_focus(seat->keyboard_state, NULL);
2562 weston_keyboard_cancel_grab(seat->keyboard_state);
2563 weston_keyboard_reset_state(seat->keyboard_state);
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002564 seat_send_updated_caps(seat);
2565 }
2566}
2567
2568WL_EXPORT void
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002569weston_seat_init_pointer(struct weston_seat *seat)
2570{
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04002571 struct weston_pointer *pointer;
2572
Derek Foreman1281a362015-07-31 16:55:32 -05002573 if (seat->pointer_state) {
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002574 seat->pointer_device_count += 1;
2575 if (seat->pointer_device_count == 1)
2576 seat_send_updated_caps(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002577 return;
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002578 }
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002579
Giulio Camuffocdb4d292013-11-14 23:42:53 +01002580 pointer = weston_pointer_create(seat);
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04002581 if (pointer == NULL)
2582 return;
2583
Derek Foreman1281a362015-07-31 16:55:32 -05002584 seat->pointer_state = pointer;
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002585 seat->pointer_device_count = 1;
2586 pointer->seat = seat;
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04002587
2588 seat_send_updated_caps(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002589}
2590
2591WL_EXPORT void
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002592weston_seat_release_pointer(struct weston_seat *seat)
2593{
Derek Foreman1281a362015-07-31 16:55:32 -05002594 struct weston_pointer *pointer = seat->pointer_state;
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002595
2596 seat->pointer_device_count--;
2597 if (seat->pointer_device_count == 0) {
Derek Foremanf9318d12015-05-11 15:40:11 -05002598 weston_pointer_clear_focus(pointer);
Jonas Ådahl1ea343e2013-10-25 23:18:05 +02002599 weston_pointer_cancel_grab(pointer);
Jonas Ådahl630bae82013-10-17 23:04:06 +02002600
Jonas Ådahla4932742013-10-17 23:04:07 +02002601 if (pointer->sprite)
2602 pointer_unmap_sprite(pointer);
2603
Jonas Ådahl3e12e632013-12-02 22:05:05 +01002604 weston_pointer_reset_state(pointer);
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002605 seat_send_updated_caps(seat);
Derek Foremanfd5ca512015-01-07 15:00:25 -06002606
2607 /* seat->pointer is intentionally not destroyed so that
2608 * a newly attached pointer on this seat will retain
2609 * the previous cursor co-ordinates.
2610 */
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002611 }
2612}
2613
2614WL_EXPORT void
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002615weston_seat_init_touch(struct weston_seat *seat)
2616{
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04002617 struct weston_touch *touch;
2618
Derek Foreman1281a362015-07-31 16:55:32 -05002619 if (seat->touch_state) {
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002620 seat->touch_device_count += 1;
2621 if (seat->touch_device_count == 1)
2622 seat_send_updated_caps(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002623 return;
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002624 }
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002625
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04002626 touch = weston_touch_create();
2627 if (touch == NULL)
2628 return;
2629
Derek Foreman1281a362015-07-31 16:55:32 -05002630 seat->touch_state = touch;
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002631 seat->touch_device_count = 1;
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04002632 touch->seat = seat;
2633
2634 seat_send_updated_caps(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002635}
2636
2637WL_EXPORT void
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002638weston_seat_release_touch(struct weston_seat *seat)
2639{
2640 seat->touch_device_count--;
2641 if (seat->touch_device_count == 0) {
Derek Foreman1281a362015-07-31 16:55:32 -05002642 weston_touch_set_focus(seat->touch_state, NULL);
2643 weston_touch_cancel_grab(seat->touch_state);
2644 weston_touch_reset_state(seat->touch_state);
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002645 seat_send_updated_caps(seat);
2646 }
2647}
2648
2649WL_EXPORT void
Rob Bradford9af5f9e2013-05-31 18:09:50 +01002650weston_seat_init(struct weston_seat *seat, struct weston_compositor *ec,
2651 const char *seat_name)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002652{
Kristian Høgsberg4a2a2742013-05-06 22:24:50 -04002653 memset(seat, 0, sizeof *seat);
2654
Kristian Høgsberge3148752013-05-06 23:19:49 -04002655 seat->selection_data_source = NULL;
2656 wl_list_init(&seat->base_resource_list);
2657 wl_signal_init(&seat->selection_signal);
2658 wl_list_init(&seat->drag_resource_list);
Kristian Høgsberge3148752013-05-06 23:19:49 -04002659 wl_signal_init(&seat->destroy_signal);
Jason Ekstranda4ab5422014-04-02 19:53:45 -05002660 wl_signal_init(&seat->updated_caps_signal);
Kristian Høgsberg4a2a2742013-05-06 22:24:50 -04002661
Peter Hutterer87743e92016-01-18 16:38:22 +10002662 seat->global = wl_global_create(ec->wl_display, &wl_seat_interface, 5,
Kristian Høgsberg919cddb2013-07-08 19:03:57 -04002663 seat, bind_seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002664
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002665 seat->compositor = ec;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002666 seat->modifier_state = 0;
Rob Bradford9af5f9e2013-05-31 18:09:50 +01002667 seat->seat_name = strdup(seat_name);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002668
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002669 wl_list_insert(ec->seat_list.prev, &seat->link);
2670
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002671 clipboard_create(seat);
2672
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002673 wl_signal_emit(&ec->seat_created_signal, seat);
2674}
2675
2676WL_EXPORT void
2677weston_seat_release(struct weston_seat *seat)
2678{
2679 wl_list_remove(&seat->link);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002680
Jonas Ådahl1afb2382014-01-03 19:46:51 +01002681 if (seat->saved_kbd_focus)
2682 wl_list_remove(&seat->saved_kbd_focus_listener.link);
2683
Derek Foreman1281a362015-07-31 16:55:32 -05002684 if (seat->pointer_state)
2685 weston_pointer_destroy(seat->pointer_state);
2686 if (seat->keyboard_state)
2687 weston_keyboard_destroy(seat->keyboard_state);
2688 if (seat->touch_state)
2689 weston_touch_destroy(seat->touch_state);
Kristian Høgsberg4a2a2742013-05-06 22:24:50 -04002690
Rob Bradford9af5f9e2013-05-31 18:09:50 +01002691 free (seat->seat_name);
2692
Kristian Høgsberg919cddb2013-07-08 19:03:57 -04002693 wl_global_destroy(seat->global);
Kristian Høgsbergaaadc772013-07-08 16:20:31 -04002694
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002695 wl_signal_emit(&seat->destroy_signal, seat);
2696}
Derek Foreman1281a362015-07-31 16:55:32 -05002697
2698/** Get a seat's keyboard pointer
2699 *
2700 * \param seat The seat to query
2701 * \return The seat's keyboard pointer, or NULL if no keyboard is present
2702 *
2703 * The keyboard pointer for a seat isn't freed when all keyboards are removed,
2704 * so it should only be used when the seat's keyboard_device_count is greater
2705 * than zero. This function does that test and only returns a pointer
2706 * when a keyboard is present.
2707 */
2708WL_EXPORT struct weston_keyboard *
2709weston_seat_get_keyboard(struct weston_seat *seat)
2710{
2711 if (!seat)
2712 return NULL;
2713
2714 if (seat->keyboard_device_count)
2715 return seat->keyboard_state;
2716
2717 return NULL;
2718}
2719
2720/** Get a seat's pointer pointer
2721 *
2722 * \param seat The seat to query
2723 * \return The seat's pointer pointer, or NULL if no pointer device is present
2724 *
2725 * The pointer pointer for a seat isn't freed when all mice are removed,
2726 * so it should only be used when the seat's pointer_device_count is greater
2727 * than zero. This function does that test and only returns a pointer
2728 * when a pointing device is present.
2729 */
2730WL_EXPORT struct weston_pointer *
2731weston_seat_get_pointer(struct weston_seat *seat)
2732{
2733 if (!seat)
2734 return NULL;
2735
2736 if (seat->pointer_device_count)
2737 return seat->pointer_state;
2738
2739 return NULL;
2740}
2741
2742/** Get a seat's touch pointer
2743 *
2744 * \param seat The seat to query
2745 * \return The seat's touch pointer, or NULL if no touch device is present
2746 *
2747 * The touch pointer for a seat isn't freed when all touch devices are removed,
2748 * so it should only be used when the seat's touch_device_count is greater
2749 * than zero. This function does that test and only returns a pointer
2750 * when a touch device is present.
2751 */
2752WL_EXPORT struct weston_touch *
2753weston_seat_get_touch(struct weston_seat *seat)
2754{
2755 if (!seat)
2756 return NULL;
2757
2758 if (seat->touch_device_count)
2759 return seat->touch_state;
2760
2761 return NULL;
2762}