blob: c34e27ff257f9c19c5b12ca10f3e1c5e43976773 [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
Jonas Ådahled6014a2016-04-21 10:21:48 +0800370 if (!pointer->focus_client)
371 return;
372
Peter Hutterer87743e92016-01-18 16:38:22 +1000373 resource_list = &pointer->focus_client->pointer_resources;
374 wl_resource_for_each(resource, resource_list) {
375 if (wl_resource_get_version(resource) >=
376 WL_POINTER_AXIS_SOURCE_SINCE_VERSION) {
377 wl_pointer_send_axis_source(resource, source);
378 }
379 }
380}
381
382static void
383pointer_send_frame(struct wl_resource *resource)
384{
385 if (wl_resource_get_version(resource) >=
386 WL_POINTER_FRAME_SINCE_VERSION) {
387 wl_pointer_send_frame(resource);
388 }
389}
390
391WL_EXPORT void
392weston_pointer_send_frame(struct weston_pointer *pointer)
393{
394 struct wl_resource *resource;
395 struct wl_list *resource_list;
396
Derek Foreman8efa31b2016-01-29 10:29:46 -0600397 if (!pointer->focus_client)
398 return;
399
Peter Hutterer87743e92016-01-18 16:38:22 +1000400 resource_list = &pointer->focus_client->pointer_resources;
Jonas Ådahl0336ca02014-10-04 16:28:29 +0200401 wl_resource_for_each(resource, resource_list)
Peter Hutterer87743e92016-01-18 16:38:22 +1000402 pointer_send_frame(resource);
Jonas Ådahl0336ca02014-10-04 16:28:29 +0200403}
404
405static void
406default_grab_pointer_axis(struct weston_pointer_grab *grab,
Peter Hutterer89b6a492016-01-18 15:58:17 +1000407 uint32_t time,
408 struct weston_pointer_axis_event *event)
Jonas Ådahl0336ca02014-10-04 16:28:29 +0200409{
Peter Hutterer89b6a492016-01-18 15:58:17 +1000410 weston_pointer_send_axis(grab->pointer, time, event);
Jonas Ådahl0336ca02014-10-04 16:28:29 +0200411}
412
Jonas Ådahl1ea343e2013-10-25 23:18:05 +0200413static void
Peter Hutterer87743e92016-01-18 16:38:22 +1000414default_grab_pointer_axis_source(struct weston_pointer_grab *grab,
415 uint32_t source)
416{
417 weston_pointer_send_axis_source(grab->pointer, source);
418}
419
420static void
421default_grab_pointer_frame(struct weston_pointer_grab *grab)
422{
423 weston_pointer_send_frame(grab->pointer);
424}
425
426static void
Jonas Ådahl1ea343e2013-10-25 23:18:05 +0200427default_grab_pointer_cancel(struct weston_pointer_grab *grab)
428{
429}
430
Kristian Høgsberg02bbabb2013-05-06 22:15:05 -0400431static const struct weston_pointer_grab_interface
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400432 default_pointer_grab_interface = {
Kristian Høgsbergb27901c2013-10-28 15:32:02 -0700433 default_grab_pointer_focus,
434 default_grab_pointer_motion,
435 default_grab_pointer_button,
Jonas Ådahl0336ca02014-10-04 16:28:29 +0200436 default_grab_pointer_axis,
Peter Hutterer87743e92016-01-18 16:38:22 +1000437 default_grab_pointer_axis_source,
438 default_grab_pointer_frame,
Jonas Ådahl1ea343e2013-10-25 23:18:05 +0200439 default_grab_pointer_cancel,
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400440};
441
Kristian Høgsberge329f362013-05-06 22:19:57 -0400442static void
443default_grab_touch_down(struct weston_touch_grab *grab, uint32_t time,
Giulio Camuffo61ed7b62015-07-08 11:55:28 +0300444 int touch_id, wl_fixed_t x, wl_fixed_t y)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400445{
Kristian Høgsberge329f362013-05-06 22:19:57 -0400446 struct weston_touch *touch = grab->touch;
Rob Bradford880ebc72013-07-22 17:31:38 +0100447 struct wl_display *display = touch->seat->compositor->wl_display;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400448 uint32_t serial;
Neil Roberts96d790e2013-09-19 17:32:00 +0100449 struct wl_resource *resource;
450 struct wl_list *resource_list;
Giulio Camuffo61ed7b62015-07-08 11:55:28 +0300451 wl_fixed_t sx, sy;
452
Bryce Harrington2c40d1d2016-02-02 10:18:48 -0800453 if (!touch->focus)
454 return;
455
Giulio Camuffo61ed7b62015-07-08 11:55:28 +0300456 weston_view_from_global_fixed(touch->focus, x, y, &sx, &sy);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400457
Neil Roberts96d790e2013-09-19 17:32:00 +0100458 resource_list = &touch->focus_resource_list;
459
Bryce Harrington2c40d1d2016-02-02 10:18:48 -0800460 if (!wl_list_empty(resource_list)) {
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400461 serial = wl_display_next_serial(display);
Neil Roberts96d790e2013-09-19 17:32:00 +0100462 wl_resource_for_each(resource, resource_list)
463 wl_touch_send_down(resource, serial, time,
Jason Ekstranda7af7042013-10-12 22:38:11 -0500464 touch->focus->surface->resource,
Neil Roberts96d790e2013-09-19 17:32:00 +0100465 touch_id, sx, sy);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400466 }
467}
468
Kristian Høgsberge329f362013-05-06 22:19:57 -0400469static void
470default_grab_touch_up(struct weston_touch_grab *grab,
471 uint32_t time, int touch_id)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400472{
Kristian Høgsberge329f362013-05-06 22:19:57 -0400473 struct weston_touch *touch = grab->touch;
Rob Bradford880ebc72013-07-22 17:31:38 +0100474 struct wl_display *display = touch->seat->compositor->wl_display;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400475 uint32_t serial;
Neil Roberts96d790e2013-09-19 17:32:00 +0100476 struct wl_resource *resource;
477 struct wl_list *resource_list;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400478
Neil Roberts96d790e2013-09-19 17:32:00 +0100479 resource_list = &touch->focus_resource_list;
480
481 if (!wl_list_empty(resource_list)) {
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400482 serial = wl_display_next_serial(display);
Neil Roberts96d790e2013-09-19 17:32:00 +0100483 wl_resource_for_each(resource, resource_list)
484 wl_touch_send_up(resource, serial, time, touch_id);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400485 }
486}
487
Kristian Høgsberge329f362013-05-06 22:19:57 -0400488static void
489default_grab_touch_motion(struct weston_touch_grab *grab, uint32_t time,
Giulio Camuffo61ed7b62015-07-08 11:55:28 +0300490 int touch_id, wl_fixed_t x, wl_fixed_t y)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400491{
Kristian Høgsberge329f362013-05-06 22:19:57 -0400492 struct weston_touch *touch = grab->touch;
Neil Roberts96d790e2013-09-19 17:32:00 +0100493 struct wl_resource *resource;
494 struct wl_list *resource_list;
Giulio Camuffo61ed7b62015-07-08 11:55:28 +0300495 wl_fixed_t sx, sy;
496
497 weston_view_from_global_fixed(touch->focus, x, y, &sx, &sy);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400498
Neil Roberts96d790e2013-09-19 17:32:00 +0100499 resource_list = &touch->focus_resource_list;
500
501 wl_resource_for_each(resource, resource_list) {
502 wl_touch_send_motion(resource, time,
Kristian Høgsberge329f362013-05-06 22:19:57 -0400503 touch_id, sx, sy);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400504 }
505}
506
Jonas Ådahl1ea343e2013-10-25 23:18:05 +0200507static void
Jonas Ådahl1679f232014-04-12 09:39:51 +0200508default_grab_touch_frame(struct weston_touch_grab *grab)
509{
510 struct wl_resource *resource;
511
512 wl_resource_for_each(resource, &grab->touch->focus_resource_list)
513 wl_touch_send_frame(resource);
514}
515
516static void
Jonas Ådahl1ea343e2013-10-25 23:18:05 +0200517default_grab_touch_cancel(struct weston_touch_grab *grab)
518{
519}
520
Kristian Høgsberge329f362013-05-06 22:19:57 -0400521static const struct weston_touch_grab_interface default_touch_grab_interface = {
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400522 default_grab_touch_down,
523 default_grab_touch_up,
Jonas Ådahl1ea343e2013-10-25 23:18:05 +0200524 default_grab_touch_motion,
Jonas Ådahl1679f232014-04-12 09:39:51 +0200525 default_grab_touch_frame,
Jonas Ådahl1ea343e2013-10-25 23:18:05 +0200526 default_grab_touch_cancel,
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400527};
528
529static void
Kristian Høgsbergb27901c2013-10-28 15:32:02 -0700530default_grab_keyboard_key(struct weston_keyboard_grab *grab,
531 uint32_t time, uint32_t key, uint32_t state)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400532{
Kristian Høgsberg29139d42013-04-18 15:25:39 -0400533 struct weston_keyboard *keyboard = grab->keyboard;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400534 struct wl_resource *resource;
Rob Bradford880ebc72013-07-22 17:31:38 +0100535 struct wl_display *display = keyboard->seat->compositor->wl_display;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400536 uint32_t serial;
Neil Roberts96d790e2013-09-19 17:32:00 +0100537 struct wl_list *resource_list;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400538
Neil Roberts96d790e2013-09-19 17:32:00 +0100539 resource_list = &keyboard->focus_resource_list;
540 if (!wl_list_empty(resource_list)) {
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400541 serial = wl_display_next_serial(display);
Neil Roberts96d790e2013-09-19 17:32:00 +0100542 wl_resource_for_each(resource, resource_list)
543 wl_keyboard_send_key(resource,
544 serial,
545 time,
546 key,
547 state);
548 }
549}
550
551static void
552send_modifiers_to_resource(struct weston_keyboard *keyboard,
553 struct wl_resource *resource,
554 uint32_t serial)
555{
556 wl_keyboard_send_modifiers(resource,
557 serial,
558 keyboard->modifiers.mods_depressed,
559 keyboard->modifiers.mods_latched,
560 keyboard->modifiers.mods_locked,
561 keyboard->modifiers.group);
562}
563
564static void
565send_modifiers_to_client_in_list(struct wl_client *client,
566 struct wl_list *list,
567 uint32_t serial,
568 struct weston_keyboard *keyboard)
569{
570 struct wl_resource *resource;
571
572 wl_resource_for_each(resource, list) {
573 if (wl_resource_get_client(resource) == client)
574 send_modifiers_to_resource(keyboard,
575 resource,
576 serial);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400577 }
578}
579
Jonas Ådahl2cbf2932015-07-22 12:05:38 +0800580static struct weston_pointer_client *
581find_pointer_client_for_surface(struct weston_pointer *pointer,
582 struct weston_surface *surface)
583{
584 struct wl_client *client;
585
586 if (!surface)
587 return NULL;
588
589 if (!surface->resource)
590 return NULL;
591
592 client = wl_resource_get_client(surface->resource);
593 return weston_pointer_get_pointer_client(pointer, client);
594}
595
596static struct weston_pointer_client *
597find_pointer_client_for_view(struct weston_pointer *pointer, struct weston_view *view)
598{
599 if (!view)
600 return NULL;
601
602 return find_pointer_client_for_surface(pointer, view->surface);
603}
604
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400605static struct wl_resource *
Kristian Høgsbergfe7aa902013-05-08 09:54:37 -0400606find_resource_for_surface(struct wl_list *list, struct weston_surface *surface)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400607{
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400608 if (!surface)
609 return NULL;
610
Jason Ekstrand44a38632013-06-14 10:08:00 -0500611 if (!surface->resource)
612 return NULL;
Stefan Schmidtfda26522013-09-17 10:54:09 +0100613
Jason Ekstrand44a38632013-06-14 10:08:00 -0500614 return wl_resource_find_for_client(list, wl_resource_get_client(surface->resource));
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400615}
616
617static void
Kristian Høgsbergb27901c2013-10-28 15:32:02 -0700618default_grab_keyboard_modifiers(struct weston_keyboard_grab *grab,
619 uint32_t serial, uint32_t mods_depressed,
620 uint32_t mods_latched,
621 uint32_t mods_locked, uint32_t group)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400622{
Kristian Høgsberg29139d42013-04-18 15:25:39 -0400623 struct weston_keyboard *keyboard = grab->keyboard;
Derek Foreman1281a362015-07-31 16:55:32 -0500624 struct weston_pointer *pointer =
625 weston_seat_get_pointer(grab->keyboard->seat);
Neil Roberts96d790e2013-09-19 17:32:00 +0100626 struct wl_resource *resource;
627 struct wl_list *resource_list;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400628
Neil Roberts96d790e2013-09-19 17:32:00 +0100629 resource_list = &keyboard->focus_resource_list;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400630
Neil Roberts96d790e2013-09-19 17:32:00 +0100631 wl_resource_for_each(resource, resource_list) {
632 wl_keyboard_send_modifiers(resource, serial, mods_depressed,
633 mods_latched, mods_locked, group);
634 }
Jason Ekstrand42133d42013-11-14 20:06:16 -0600635 if (pointer && pointer->focus && pointer->focus->surface->resource &&
636 pointer->focus->surface != keyboard->focus) {
Neil Roberts96d790e2013-09-19 17:32:00 +0100637 struct wl_client *pointer_client =
Jason Ekstranda7af7042013-10-12 22:38:11 -0500638 wl_resource_get_client(pointer->focus->surface->resource);
Neil Roberts96d790e2013-09-19 17:32:00 +0100639 send_modifiers_to_client_in_list(pointer_client,
640 &keyboard->resource_list,
641 serial,
642 keyboard);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400643 }
644}
645
Jonas Ådahl1ea343e2013-10-25 23:18:05 +0200646static void
647default_grab_keyboard_cancel(struct weston_keyboard_grab *grab)
648{
649}
650
Kristian Høgsberg29139d42013-04-18 15:25:39 -0400651static const struct weston_keyboard_grab_interface
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400652 default_keyboard_grab_interface = {
Kristian Høgsbergb27901c2013-10-28 15:32:02 -0700653 default_grab_keyboard_key,
654 default_grab_keyboard_modifiers,
Jonas Ådahl1ea343e2013-10-25 23:18:05 +0200655 default_grab_keyboard_cancel,
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400656};
657
Kristian Høgsberg195b8692013-05-08 15:02:05 -0400658static void
659pointer_unmap_sprite(struct weston_pointer *pointer)
660{
Pekka Paalanenc557ff72014-11-12 16:42:52 +0200661 struct weston_surface *surface = pointer->sprite->surface;
662
663 if (weston_surface_is_mapped(surface))
664 weston_surface_unmap(surface);
Kristian Høgsberg195b8692013-05-08 15:02:05 -0400665
666 wl_list_remove(&pointer->sprite_destroy_listener.link);
Pekka Paalanenc557ff72014-11-12 16:42:52 +0200667 surface->configure = NULL;
668 surface->configure_private = NULL;
Pekka Paalanen8274d902014-08-06 19:36:51 +0300669 weston_surface_set_label_func(surface, NULL);
Jason Ekstranda7af7042013-10-12 22:38:11 -0500670 weston_view_destroy(pointer->sprite);
Kristian Høgsberg195b8692013-05-08 15:02:05 -0400671 pointer->sprite = NULL;
672}
673
674static void
675pointer_handle_sprite_destroy(struct wl_listener *listener, void *data)
676{
677 struct weston_pointer *pointer =
678 container_of(listener, struct weston_pointer,
679 sprite_destroy_listener);
680
681 pointer->sprite = NULL;
682}
683
Jonas Ådahl3e12e632013-12-02 22:05:05 +0100684static void
685weston_pointer_reset_state(struct weston_pointer *pointer)
686{
687 pointer->button_count = 0;
688}
689
Ander Conselvan de Oliveiraf84327a2014-01-29 18:47:51 +0200690static void
691weston_pointer_handle_output_destroy(struct wl_listener *listener, void *data);
692
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400693WL_EXPORT struct weston_pointer *
Giulio Camuffocdb4d292013-11-14 23:42:53 +0100694weston_pointer_create(struct weston_seat *seat)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400695{
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400696 struct weston_pointer *pointer;
697
Peter Huttererf3d62272013-08-08 11:57:05 +1000698 pointer = zalloc(sizeof *pointer);
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400699 if (pointer == NULL)
700 return NULL;
701
Jonas Ådahl2cbf2932015-07-22 12:05:38 +0800702 wl_list_init(&pointer->pointer_clients);
Giulio Camuffocdb4d292013-11-14 23:42:53 +0100703 weston_pointer_set_default_grab(pointer,
704 seat->compositor->default_pointer_grab);
Giulio Camuffo576fe2a2013-11-20 18:00:24 +0100705 wl_list_init(&pointer->focus_resource_listener.link);
706 pointer->focus_resource_listener.notify = pointer_focus_resource_destroyed;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400707 pointer->default_grab.pointer = pointer;
708 pointer->grab = &pointer->default_grab;
Giulio Camuffo6fcb3782013-11-14 23:42:50 +0100709 wl_signal_init(&pointer->motion_signal);
Emilio Pozuelo Monfortaa7a4762013-11-19 11:37:15 +0100710 wl_signal_init(&pointer->focus_signal);
Giulio Camuffo576fe2a2013-11-20 18:00:24 +0100711 wl_list_init(&pointer->focus_view_listener.link);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400712
Kristian Høgsberg195b8692013-05-08 15:02:05 -0400713 pointer->sprite_destroy_listener.notify = pointer_handle_sprite_destroy;
714
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400715 /* FIXME: Pick better co-ords. */
716 pointer->x = wl_fixed_from_int(100);
717 pointer->y = wl_fixed_from_int(100);
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400718
Ander Conselvan de Oliveiraf84327a2014-01-29 18:47:51 +0200719 pointer->output_destroy_listener.notify =
720 weston_pointer_handle_output_destroy;
721 wl_signal_add(&seat->compositor->output_destroyed_signal,
722 &pointer->output_destroy_listener);
723
Derek Foremanf9318d12015-05-11 15:40:11 -0500724 pointer->sx = wl_fixed_from_int(-1000000);
725 pointer->sy = wl_fixed_from_int(-1000000);
726
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400727 return pointer;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400728}
729
730WL_EXPORT void
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400731weston_pointer_destroy(struct weston_pointer *pointer)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400732{
Kristian Høgsberg195b8692013-05-08 15:02:05 -0400733 if (pointer->sprite)
734 pointer_unmap_sprite(pointer);
735
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400736 /* XXX: What about pointer->resource_list? */
Neil Roberts96d790e2013-09-19 17:32:00 +0100737
Giulio Camuffo576fe2a2013-11-20 18:00:24 +0100738 wl_list_remove(&pointer->focus_resource_listener.link);
739 wl_list_remove(&pointer->focus_view_listener.link);
Ander Conselvan de Oliveiraf84327a2014-01-29 18:47:51 +0200740 wl_list_remove(&pointer->output_destroy_listener.link);
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400741 free(pointer);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400742}
743
Giulio Camuffocdb4d292013-11-14 23:42:53 +0100744void
745weston_pointer_set_default_grab(struct weston_pointer *pointer,
746 const struct weston_pointer_grab_interface *interface)
747{
748 if (interface)
749 pointer->default_grab.interface = interface;
750 else
751 pointer->default_grab.interface =
752 &default_pointer_grab_interface;
753}
754
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400755WL_EXPORT struct weston_keyboard *
756weston_keyboard_create(void)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400757{
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400758 struct weston_keyboard *keyboard;
759
Peter Huttererf3d62272013-08-08 11:57:05 +1000760 keyboard = zalloc(sizeof *keyboard);
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400761 if (keyboard == NULL)
Neil Roberts96d790e2013-09-19 17:32:00 +0100762 return NULL;
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400763
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400764 wl_list_init(&keyboard->resource_list);
Neil Roberts96d790e2013-09-19 17:32:00 +0100765 wl_list_init(&keyboard->focus_resource_list);
Giulio Camuffo576fe2a2013-11-20 18:00:24 +0100766 wl_list_init(&keyboard->focus_resource_listener.link);
767 keyboard->focus_resource_listener.notify = keyboard_focus_resource_destroyed;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400768 wl_array_init(&keyboard->keys);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400769 keyboard->default_grab.interface = &default_keyboard_grab_interface;
770 keyboard->default_grab.keyboard = keyboard;
771 keyboard->grab = &keyboard->default_grab;
772 wl_signal_init(&keyboard->focus_signal);
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400773
774 return keyboard;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400775}
776
Jonas Ådahl7395ea02013-12-03 09:14:26 +0100777static void
778weston_xkb_info_destroy(struct weston_xkb_info *xkb_info);
779
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400780WL_EXPORT void
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400781weston_keyboard_destroy(struct weston_keyboard *keyboard)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400782{
783 /* XXX: What about keyboard->resource_list? */
Neil Roberts96d790e2013-09-19 17:32:00 +0100784
Jonas Ådahl7395ea02013-12-03 09:14:26 +0100785#ifdef ENABLE_XKBCOMMON
786 if (keyboard->seat->compositor->use_xkbcommon) {
Ran Benitac9c74152014-08-19 23:59:52 +0300787 xkb_state_unref(keyboard->xkb_state.state);
Jonas Ådahl7395ea02013-12-03 09:14:26 +0100788 if (keyboard->xkb_info)
789 weston_xkb_info_destroy(keyboard->xkb_info);
Ran Benitac9c74152014-08-19 23:59:52 +0300790 xkb_keymap_unref(keyboard->pending_keymap);
Jonas Ådahl7395ea02013-12-03 09:14:26 +0100791 }
792#endif
793
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400794 wl_array_release(&keyboard->keys);
Giulio Camuffo576fe2a2013-11-20 18:00:24 +0100795 wl_list_remove(&keyboard->focus_resource_listener.link);
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400796 free(keyboard);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400797}
798
Jonas Ådahlcbfa7f72013-12-02 22:05:04 +0100799static void
800weston_touch_reset_state(struct weston_touch *touch)
801{
802 touch->num_tp = 0;
803}
804
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400805WL_EXPORT struct weston_touch *
806weston_touch_create(void)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400807{
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400808 struct weston_touch *touch;
809
Peter Huttererf3d62272013-08-08 11:57:05 +1000810 touch = zalloc(sizeof *touch);
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400811 if (touch == NULL)
812 return NULL;
813
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400814 wl_list_init(&touch->resource_list);
Neil Roberts96d790e2013-09-19 17:32:00 +0100815 wl_list_init(&touch->focus_resource_list);
Giulio Camuffo576fe2a2013-11-20 18:00:24 +0100816 wl_list_init(&touch->focus_view_listener.link);
817 touch->focus_view_listener.notify = touch_focus_view_destroyed;
818 wl_list_init(&touch->focus_resource_listener.link);
819 touch->focus_resource_listener.notify = touch_focus_resource_destroyed;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400820 touch->default_grab.interface = &default_touch_grab_interface;
821 touch->default_grab.touch = touch;
822 touch->grab = &touch->default_grab;
823 wl_signal_init(&touch->focus_signal);
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400824
825 return touch;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400826}
827
828WL_EXPORT void
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400829weston_touch_destroy(struct weston_touch *touch)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400830{
831 /* XXX: What about touch->resource_list? */
Neil Roberts96d790e2013-09-19 17:32:00 +0100832
Giulio Camuffo576fe2a2013-11-20 18:00:24 +0100833 wl_list_remove(&touch->focus_view_listener.link);
834 wl_list_remove(&touch->focus_resource_listener.link);
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400835 free(touch);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400836}
837
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400838static void
Kristian Høgsberge3148752013-05-06 23:19:49 -0400839seat_send_updated_caps(struct weston_seat *seat)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400840{
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400841 enum wl_seat_capability caps = 0;
Rob Bradford6e737f52013-09-06 17:48:19 +0100842 struct wl_resource *resource;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400843
Jonas Ådahld6e1c342013-10-17 23:04:05 +0200844 if (seat->pointer_device_count > 0)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400845 caps |= WL_SEAT_CAPABILITY_POINTER;
Jonas Ådahld6e1c342013-10-17 23:04:05 +0200846 if (seat->keyboard_device_count > 0)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400847 caps |= WL_SEAT_CAPABILITY_KEYBOARD;
Jonas Ådahld6e1c342013-10-17 23:04:05 +0200848 if (seat->touch_device_count > 0)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400849 caps |= WL_SEAT_CAPABILITY_TOUCH;
850
Rob Bradford6e737f52013-09-06 17:48:19 +0100851 wl_resource_for_each(resource, &seat->base_resource_list) {
852 wl_seat_send_capabilities(resource, caps);
Jason Ekstrand44a38632013-06-14 10:08:00 -0500853 }
Jason Ekstranda4ab5422014-04-02 19:53:45 -0500854 wl_signal_emit(&seat->updated_caps_signal, seat);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400855}
856
Derek Foremanf9318d12015-05-11 15:40:11 -0500857
858/** Clear the pointer focus
859 *
860 * \param pointer the pointer to clear focus for.
861 *
862 * This can be used to unset pointer focus and set the co-ordinates to the
863 * arbitrary values we use for the no focus case.
864 *
865 * There's no requirement to use this function. For example, passing the
866 * results of a weston_compositor_pick_view() directly to
867 * weston_pointer_set_focus() will do the right thing when no view is found.
868 */
869WL_EXPORT void
870weston_pointer_clear_focus(struct weston_pointer *pointer)
871{
872 weston_pointer_set_focus(pointer, NULL,
873 wl_fixed_from_int(-1000000),
874 wl_fixed_from_int(-1000000));
875}
876
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400877WL_EXPORT void
Kristian Høgsberg02bbabb2013-05-06 22:15:05 -0400878weston_pointer_set_focus(struct weston_pointer *pointer,
Jason Ekstranda7af7042013-10-12 22:38:11 -0500879 struct weston_view *view,
Kristian Høgsberg02bbabb2013-05-06 22:15:05 -0400880 wl_fixed_t sx, wl_fixed_t sy)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400881{
Jonas Ådahl2cbf2932015-07-22 12:05:38 +0800882 struct weston_pointer_client *pointer_client;
Derek Foreman1281a362015-07-31 16:55:32 -0500883 struct weston_keyboard *kbd = weston_seat_get_keyboard(pointer->seat);
Neil Roberts96d790e2013-09-19 17:32:00 +0100884 struct wl_resource *resource;
Jonas Ådahl2cbf2932015-07-22 12:05:38 +0800885 struct wl_resource *surface_resource;
Rob Bradford880ebc72013-07-22 17:31:38 +0100886 struct wl_display *display = pointer->seat->compositor->wl_display;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400887 uint32_t serial;
Neil Roberts96d790e2013-09-19 17:32:00 +0100888 struct wl_list *focus_resource_list;
Kristian Høgsbergdb1fccb2014-02-05 17:14:42 -0800889 int refocus = 0;
Jason Ekstranda7af7042013-10-12 22:38:11 -0500890
891 if ((!pointer->focus && view) ||
892 (pointer->focus && !view) ||
Kristian Høgsbergdb1fccb2014-02-05 17:14:42 -0800893 (pointer->focus && pointer->focus->surface != view->surface) ||
894 pointer->sx != sx || pointer->sy != sy)
895 refocus = 1;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400896
Jonas Ådahl2cbf2932015-07-22 12:05:38 +0800897 if (pointer->focus_client && refocus) {
898 focus_resource_list = &pointer->focus_client->pointer_resources;
899 if (!wl_list_empty(focus_resource_list)) {
900 serial = wl_display_next_serial(display);
901 surface_resource = pointer->focus->surface->resource;
902 wl_resource_for_each(resource, focus_resource_list) {
903 wl_pointer_send_leave(resource, serial,
904 surface_resource);
Peter Hutterer87743e92016-01-18 16:38:22 +1000905 pointer_send_frame(resource);
Jonas Ådahl2cbf2932015-07-22 12:05:38 +0800906 }
Neil Roberts96d790e2013-09-19 17:32:00 +0100907 }
908
Jonas Ådahl2cbf2932015-07-22 12:05:38 +0800909 pointer->focus_client = NULL;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400910 }
911
Jonas Ådahl2cbf2932015-07-22 12:05:38 +0800912 pointer_client = find_pointer_client_for_view(pointer, view);
913 if (pointer_client && refocus) {
914 struct wl_client *surface_client = pointer_client->client;
Neil Roberts96d790e2013-09-19 17:32:00 +0100915
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400916 serial = wl_display_next_serial(display);
Neil Roberts96d790e2013-09-19 17:32:00 +0100917
Jason Ekstranda7af7042013-10-12 22:38:11 -0500918 if (kbd && kbd->focus != view->surface)
Kristian Høgsbergcb406f12013-10-09 10:54:03 -0700919 send_modifiers_to_client_in_list(surface_client,
920 &kbd->resource_list,
921 serial,
922 kbd);
923
Jonas Ådahl2cbf2932015-07-22 12:05:38 +0800924 pointer->focus_client = pointer_client;
Neil Roberts96d790e2013-09-19 17:32:00 +0100925
Jonas Ådahl2cbf2932015-07-22 12:05:38 +0800926 focus_resource_list = &pointer->focus_client->pointer_resources;
Neil Roberts96d790e2013-09-19 17:32:00 +0100927 wl_resource_for_each(resource, focus_resource_list) {
928 wl_pointer_send_enter(resource,
929 serial,
Jason Ekstranda7af7042013-10-12 22:38:11 -0500930 view->surface->resource,
Neil Roberts96d790e2013-09-19 17:32:00 +0100931 sx, sy);
Peter Hutterer87743e92016-01-18 16:38:22 +1000932 pointer_send_frame(resource);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400933 }
Neil Roberts96d790e2013-09-19 17:32:00 +0100934
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400935 pointer->focus_serial = serial;
936 }
937
Giulio Camuffo65a07f82013-12-06 12:46:27 +0100938 wl_list_remove(&pointer->focus_view_listener.link);
939 wl_list_init(&pointer->focus_view_listener.link);
940 wl_list_remove(&pointer->focus_resource_listener.link);
941 wl_list_init(&pointer->focus_resource_listener.link);
Emilio Pozuelo Monfortaa7a4762013-11-19 11:37:15 +0100942 if (view)
Giulio Camuffo576fe2a2013-11-20 18:00:24 +0100943 wl_signal_add(&view->destroy_signal, &pointer->focus_view_listener);
Giulio Camuffo65a07f82013-12-06 12:46:27 +0100944 if (view && view->surface->resource)
945 wl_resource_add_destroy_listener(view->surface->resource,
946 &pointer->focus_resource_listener);
947
948 pointer->focus = view;
949 pointer->focus_view_listener.notify = pointer_focus_view_destroyed;
Kristian Høgsbergdb1fccb2014-02-05 17:14:42 -0800950 pointer->sx = sx;
951 pointer->sy = sy;
952
Derek Foremanf9318d12015-05-11 15:40:11 -0500953 assert(view || sx == wl_fixed_from_int(-1000000));
954 assert(view || sy == wl_fixed_from_int(-1000000));
955
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400956 wl_signal_emit(&pointer->focus_signal, pointer);
957}
958
Neil Roberts96d790e2013-09-19 17:32:00 +0100959static void
960send_enter_to_resource_list(struct wl_list *list,
961 struct weston_keyboard *keyboard,
962 struct weston_surface *surface,
963 uint32_t serial)
964{
965 struct wl_resource *resource;
966
967 wl_resource_for_each(resource, list) {
968 send_modifiers_to_resource(keyboard, resource, serial);
969 wl_keyboard_send_enter(resource, serial,
970 surface->resource,
971 &keyboard->keys);
972 }
973}
974
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400975WL_EXPORT void
Kristian Høgsberg29139d42013-04-18 15:25:39 -0400976weston_keyboard_set_focus(struct weston_keyboard *keyboard,
Kristian Høgsbergfe7aa902013-05-08 09:54:37 -0400977 struct weston_surface *surface)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400978{
979 struct wl_resource *resource;
Rob Bradford880ebc72013-07-22 17:31:38 +0100980 struct wl_display *display = keyboard->seat->compositor->wl_display;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400981 uint32_t serial;
Neil Roberts96d790e2013-09-19 17:32:00 +0100982 struct wl_list *focus_resource_list;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400983
Neil Roberts96d790e2013-09-19 17:32:00 +0100984 focus_resource_list = &keyboard->focus_resource_list;
985
986 if (!wl_list_empty(focus_resource_list) && keyboard->focus != surface) {
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400987 serial = wl_display_next_serial(display);
Neil Roberts96d790e2013-09-19 17:32:00 +0100988 wl_resource_for_each(resource, focus_resource_list) {
989 wl_keyboard_send_leave(resource, serial,
990 keyboard->focus->resource);
991 }
992 move_resources(&keyboard->resource_list, focus_resource_list);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400993 }
994
Neil Roberts96d790e2013-09-19 17:32:00 +0100995 if (find_resource_for_surface(&keyboard->resource_list, surface) &&
996 keyboard->focus != surface) {
997 struct wl_client *surface_client =
998 wl_resource_get_client(surface->resource);
999
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001000 serial = wl_display_next_serial(display);
Neil Roberts96d790e2013-09-19 17:32:00 +01001001
1002 move_resources_for_client(focus_resource_list,
1003 &keyboard->resource_list,
1004 surface_client);
1005 send_enter_to_resource_list(focus_resource_list,
1006 keyboard,
1007 surface,
1008 serial);
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001009 keyboard->focus_serial = serial;
Giulio Camuffo65a07f82013-12-06 12:46:27 +01001010 }
1011
1012 wl_list_remove(&keyboard->focus_resource_listener.link);
1013 wl_list_init(&keyboard->focus_resource_listener.link);
1014 if (surface && surface->resource)
Giulio Camuffo576fe2a2013-11-20 18:00:24 +01001015 wl_resource_add_destroy_listener(surface->resource,
1016 &keyboard->focus_resource_listener);
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001017
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001018 keyboard->focus = surface;
1019 wl_signal_emit(&keyboard->focus_signal, keyboard);
1020}
1021
Giulio Camuffoa20ca812014-11-22 11:16:56 +02001022/* Users of this function must manually manage the keyboard focus */
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001023WL_EXPORT void
Kristian Høgsberg29139d42013-04-18 15:25:39 -04001024weston_keyboard_start_grab(struct weston_keyboard *keyboard,
1025 struct weston_keyboard_grab *grab)
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001026{
1027 keyboard->grab = grab;
1028 grab->keyboard = keyboard;
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001029}
1030
1031WL_EXPORT void
Kristian Høgsberg29139d42013-04-18 15:25:39 -04001032weston_keyboard_end_grab(struct weston_keyboard *keyboard)
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001033{
1034 keyboard->grab = &keyboard->default_grab;
1035}
1036
Jonas Ådahl1ea343e2013-10-25 23:18:05 +02001037static void
1038weston_keyboard_cancel_grab(struct weston_keyboard *keyboard)
1039{
1040 keyboard->grab->interface->cancel(keyboard->grab);
1041}
1042
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001043WL_EXPORT void
Kristian Høgsberg02bbabb2013-05-06 22:15:05 -04001044weston_pointer_start_grab(struct weston_pointer *pointer,
1045 struct weston_pointer_grab *grab)
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001046{
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001047 pointer->grab = grab;
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001048 grab->pointer = pointer;
Kristian Høgsbergda751b82013-07-04 00:58:07 -04001049 pointer->grab->interface->focus(pointer->grab);
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001050}
1051
1052WL_EXPORT void
Kristian Høgsberg02bbabb2013-05-06 22:15:05 -04001053weston_pointer_end_grab(struct weston_pointer *pointer)
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001054{
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001055 pointer->grab = &pointer->default_grab;
Kristian Høgsbergda751b82013-07-04 00:58:07 -04001056 pointer->grab->interface->focus(pointer->grab);
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001057}
1058
Jonas Ådahl1ea343e2013-10-25 23:18:05 +02001059static void
1060weston_pointer_cancel_grab(struct weston_pointer *pointer)
1061{
1062 pointer->grab->interface->cancel(pointer->grab);
1063}
1064
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001065WL_EXPORT void
Kristian Høgsberge329f362013-05-06 22:19:57 -04001066weston_touch_start_grab(struct weston_touch *touch, struct weston_touch_grab *grab)
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001067{
1068 touch->grab = grab;
1069 grab->touch = touch;
1070}
1071
1072WL_EXPORT void
Kristian Høgsberge329f362013-05-06 22:19:57 -04001073weston_touch_end_grab(struct weston_touch *touch)
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001074{
1075 touch->grab = &touch->default_grab;
1076}
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001077
Jonas Ådahl1ea343e2013-10-25 23:18:05 +02001078static void
1079weston_touch_cancel_grab(struct weston_touch *touch)
1080{
1081 touch->grab->interface->cancel(touch->grab);
1082}
1083
Ander Conselvan de Oliveira54e90c72013-12-13 22:10:56 +02001084static void
1085weston_pointer_clamp_for_output(struct weston_pointer *pointer,
1086 struct weston_output *output,
1087 wl_fixed_t *fx, wl_fixed_t *fy)
1088{
1089 int x, y;
1090
1091 x = wl_fixed_to_int(*fx);
1092 y = wl_fixed_to_int(*fy);
1093
1094 if (x < output->x)
1095 *fx = wl_fixed_from_int(output->x);
1096 else if (x >= output->x + output->width)
1097 *fx = wl_fixed_from_int(output->x +
1098 output->width - 1);
1099 if (y < output->y)
1100 *fy = wl_fixed_from_int(output->y);
1101 else if (y >= output->y + output->height)
1102 *fy = wl_fixed_from_int(output->y +
1103 output->height - 1);
1104}
1105
Rob Bradford806d8c02013-06-25 18:56:41 +01001106WL_EXPORT void
1107weston_pointer_clamp(struct weston_pointer *pointer, wl_fixed_t *fx, wl_fixed_t *fy)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001108{
Rob Bradford806d8c02013-06-25 18:56:41 +01001109 struct weston_compositor *ec = pointer->seat->compositor;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001110 struct weston_output *output, *prev = NULL;
1111 int x, y, old_x, old_y, valid = 0;
1112
1113 x = wl_fixed_to_int(*fx);
1114 y = wl_fixed_to_int(*fy);
Rob Bradford806d8c02013-06-25 18:56:41 +01001115 old_x = wl_fixed_to_int(pointer->x);
1116 old_y = wl_fixed_to_int(pointer->y);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001117
1118 wl_list_for_each(output, &ec->output_list, link) {
Rob Bradford66bd9f52013-06-25 18:56:42 +01001119 if (pointer->seat->output && pointer->seat->output != output)
1120 continue;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001121 if (pixman_region32_contains_point(&output->region,
1122 x, y, NULL))
1123 valid = 1;
1124 if (pixman_region32_contains_point(&output->region,
1125 old_x, old_y, NULL))
1126 prev = output;
1127 }
1128
Rob Bradford66bd9f52013-06-25 18:56:42 +01001129 if (!prev)
1130 prev = pointer->seat->output;
1131
Ander Conselvan de Oliveira54e90c72013-12-13 22:10:56 +02001132 if (prev && !valid)
1133 weston_pointer_clamp_for_output(pointer, prev, fx, fy);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001134}
1135
Jonas Ådahld2510102014-10-05 21:39:14 +02001136static void
1137weston_pointer_move_to(struct weston_pointer *pointer,
1138 wl_fixed_t x, wl_fixed_t y)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001139{
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001140 int32_t ix, iy;
1141
Rob Bradford806d8c02013-06-25 18:56:41 +01001142 weston_pointer_clamp (pointer, &x, &y);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001143
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001144 pointer->x = x;
1145 pointer->y = y;
1146
1147 ix = wl_fixed_to_int(x);
1148 iy = wl_fixed_to_int(y);
1149
Kristian Høgsberg195b8692013-05-08 15:02:05 -04001150 if (pointer->sprite) {
Jason Ekstranda7af7042013-10-12 22:38:11 -05001151 weston_view_set_position(pointer->sprite,
1152 ix - pointer->hotspot_x,
1153 iy - pointer->hotspot_y);
1154 weston_view_schedule_repaint(pointer->sprite);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001155 }
Giulio Camuffo6fcb3782013-11-14 23:42:50 +01001156
Giulio Camuffo1959ab82013-11-14 23:42:52 +01001157 pointer->grab->interface->focus(pointer->grab);
Giulio Camuffo6fcb3782013-11-14 23:42:50 +01001158 wl_signal_emit(&pointer->motion_signal, pointer);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001159}
1160
Jonas Ådahld2510102014-10-05 21:39:14 +02001161WL_EXPORT void
1162weston_pointer_motion_to_abs(struct weston_pointer *pointer,
1163 struct weston_pointer_motion_event *event,
1164 wl_fixed_t *x, wl_fixed_t *y)
1165{
1166 if (event->mask & WESTON_POINTER_MOTION_ABS) {
1167 *x = wl_fixed_from_double(event->x);
1168 *y = wl_fixed_from_double(event->y);
1169 } else if (event->mask & WESTON_POINTER_MOTION_REL) {
1170 *x = pointer->x + wl_fixed_from_double(event->dx);
1171 *y = pointer->y + wl_fixed_from_double(event->dy);
1172 } else {
1173 assert(!"invalid motion event");
1174 *x = *y = 0;
1175 }
1176}
1177
1178WL_EXPORT void
1179weston_pointer_move(struct weston_pointer *pointer,
1180 struct weston_pointer_motion_event *event)
1181{
1182 wl_fixed_t x, y;
1183
1184 weston_pointer_motion_to_abs(pointer, event, &x, &y);
1185 weston_pointer_move_to(pointer, x, y);
1186}
1187
Ander Conselvan de Oliveira54e90c72013-12-13 22:10:56 +02001188/** Verify if the pointer is in a valid position and move it if it isn't.
1189 */
Ander Conselvan de Oliveiraf84327a2014-01-29 18:47:51 +02001190static void
1191weston_pointer_handle_output_destroy(struct wl_listener *listener, void *data)
Ander Conselvan de Oliveira54e90c72013-12-13 22:10:56 +02001192{
Ander Conselvan de Oliveiraf84327a2014-01-29 18:47:51 +02001193 struct weston_pointer *pointer;
1194 struct weston_compositor *ec;
Ander Conselvan de Oliveira54e90c72013-12-13 22:10:56 +02001195 struct weston_output *output, *closest = NULL;
1196 int x, y, distance, min = INT_MAX;
1197 wl_fixed_t fx, fy;
1198
Ander Conselvan de Oliveiraf84327a2014-01-29 18:47:51 +02001199 pointer = container_of(listener, struct weston_pointer,
1200 output_destroy_listener);
1201 ec = pointer->seat->compositor;
1202
Ander Conselvan de Oliveira54e90c72013-12-13 22:10:56 +02001203 x = wl_fixed_to_int(pointer->x);
1204 y = wl_fixed_to_int(pointer->y);
1205
1206 wl_list_for_each(output, &ec->output_list, link) {
1207 if (pixman_region32_contains_point(&output->region,
1208 x, y, NULL))
1209 return;
1210
1211 /* Aproximante the distance from the pointer to the center of
1212 * the output. */
1213 distance = abs(output->x + output->width / 2 - x) +
1214 abs(output->y + output->height / 2 - y);
1215 if (distance < min) {
1216 min = distance;
1217 closest = output;
1218 }
1219 }
1220
1221 /* Nothing to do if there's no output left. */
1222 if (!closest)
1223 return;
1224
1225 fx = pointer->x;
1226 fy = pointer->y;
1227
1228 weston_pointer_clamp_for_output(pointer, closest, &fx, &fy);
Jonas Ådahld2510102014-10-05 21:39:14 +02001229 weston_pointer_move_to(pointer, fx, fy);
Ander Conselvan de Oliveira54e90c72013-12-13 22:10:56 +02001230}
1231
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001232WL_EXPORT void
1233notify_motion(struct weston_seat *seat,
Jonas Ådahld2510102014-10-05 21:39:14 +02001234 uint32_t time,
1235 struct weston_pointer_motion_event *event)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001236{
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001237 struct weston_compositor *ec = seat->compositor;
Derek Foreman1281a362015-07-31 16:55:32 -05001238 struct weston_pointer *pointer = weston_seat_get_pointer(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001239
1240 weston_compositor_wake(ec);
Jonas Ådahld2510102014-10-05 21:39:14 +02001241 pointer->grab->interface->motion(pointer->grab, time, event);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001242}
1243
Daniel Stone96d47c02013-11-19 11:37:12 +01001244static void
1245run_modifier_bindings(struct weston_seat *seat, uint32_t old, uint32_t new)
1246{
1247 struct weston_compositor *compositor = seat->compositor;
Derek Foreman1281a362015-07-31 16:55:32 -05001248 struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
Daniel Stone96d47c02013-11-19 11:37:12 +01001249 uint32_t diff;
1250 unsigned int i;
1251 struct {
1252 uint32_t xkb;
1253 enum weston_keyboard_modifier weston;
1254 } mods[] = {
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001255 { keyboard->xkb_info->ctrl_mod, MODIFIER_CTRL },
1256 { keyboard->xkb_info->alt_mod, MODIFIER_ALT },
1257 { keyboard->xkb_info->super_mod, MODIFIER_SUPER },
1258 { keyboard->xkb_info->shift_mod, MODIFIER_SHIFT },
Daniel Stone96d47c02013-11-19 11:37:12 +01001259 };
1260
1261 diff = new & ~old;
1262 for (i = 0; i < ARRAY_LENGTH(mods); i++) {
1263 if (diff & (1 << mods[i].xkb))
1264 weston_compositor_run_modifier_binding(compositor,
Derek Foreman99a6a2d2015-07-15 13:00:43 -05001265 keyboard,
Daniel Stone96d47c02013-11-19 11:37:12 +01001266 mods[i].weston,
1267 WL_KEYBOARD_KEY_STATE_PRESSED);
1268 }
1269
1270 diff = old & ~new;
1271 for (i = 0; i < ARRAY_LENGTH(mods); i++) {
1272 if (diff & (1 << mods[i].xkb))
1273 weston_compositor_run_modifier_binding(compositor,
Derek Foreman99a6a2d2015-07-15 13:00:43 -05001274 keyboard,
Daniel Stone96d47c02013-11-19 11:37:12 +01001275 mods[i].weston,
1276 WL_KEYBOARD_KEY_STATE_RELEASED);
1277 }
1278}
1279
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001280WL_EXPORT void
1281notify_motion_absolute(struct weston_seat *seat,
Giulio Camuffo90a6fc62016-03-22 17:44:54 +02001282 uint32_t time, double x, double y)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001283{
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001284 struct weston_compositor *ec = seat->compositor;
Derek Foreman1281a362015-07-31 16:55:32 -05001285 struct weston_pointer *pointer = weston_seat_get_pointer(seat);
Jonas Ådahld2510102014-10-05 21:39:14 +02001286 struct weston_pointer_motion_event event = { 0 };
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001287
1288 weston_compositor_wake(ec);
Jonas Ådahld2510102014-10-05 21:39:14 +02001289
1290 event = (struct weston_pointer_motion_event) {
1291 .mask = WESTON_POINTER_MOTION_ABS,
Giulio Camuffo90a6fc62016-03-22 17:44:54 +02001292 .x = x,
1293 .y = y,
Jonas Ådahld2510102014-10-05 21:39:14 +02001294 };
1295
1296 pointer->grab->interface->motion(pointer->grab, time, &event);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001297}
1298
Jonas Ådahl94e2e2d2014-10-18 18:42:19 +02001299static unsigned int
1300peek_next_activate_serial(struct weston_compositor *c)
1301{
1302 unsigned serial = c->activate_serial + 1;
1303
1304 return serial == 0 ? 1 : serial;
1305}
1306
1307static void
1308inc_activate_serial(struct weston_compositor *c)
1309{
1310 c->activate_serial = peek_next_activate_serial (c);
1311}
1312
1313WL_EXPORT void
1314weston_view_activate(struct weston_view *view,
1315 struct weston_seat *seat,
1316 uint32_t flags)
1317{
1318 struct weston_compositor *compositor = seat->compositor;
1319
1320 if (flags & WESTON_ACTIVATE_FLAG_CLICKED) {
1321 view->click_to_activate_serial =
1322 peek_next_activate_serial(compositor);
1323 }
1324
1325 weston_seat_set_keyboard_focus(seat, view->surface);
1326}
1327
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001328WL_EXPORT void
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001329notify_button(struct weston_seat *seat, uint32_t time, int32_t button,
1330 enum wl_pointer_button_state state)
1331{
1332 struct weston_compositor *compositor = seat->compositor;
Derek Foreman1281a362015-07-31 16:55:32 -05001333 struct weston_pointer *pointer = weston_seat_get_pointer(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001334
1335 if (state == WL_POINTER_BUTTON_STATE_PRESSED) {
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001336 weston_compositor_idle_inhibit(compositor);
1337 if (pointer->button_count == 0) {
1338 pointer->grab_button = button;
1339 pointer->grab_time = time;
1340 pointer->grab_x = pointer->x;
1341 pointer->grab_y = pointer->y;
1342 }
1343 pointer->button_count++;
1344 } else {
1345 weston_compositor_idle_release(compositor);
1346 pointer->button_count--;
1347 }
1348
Derek Foreman99a6a2d2015-07-15 13:00:43 -05001349 weston_compositor_run_button_binding(compositor, pointer, time, button,
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001350 state);
1351
1352 pointer->grab->interface->button(pointer->grab, time, button, state);
1353
1354 if (pointer->button_count == 1)
1355 pointer->grab_serial =
1356 wl_display_get_serial(compositor->wl_display);
1357}
1358
1359WL_EXPORT void
Peter Hutterer89b6a492016-01-18 15:58:17 +10001360notify_axis(struct weston_seat *seat, uint32_t time,
1361 struct weston_pointer_axis_event *event)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001362{
1363 struct weston_compositor *compositor = seat->compositor;
Derek Foreman1281a362015-07-31 16:55:32 -05001364 struct weston_pointer *pointer = weston_seat_get_pointer(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001365
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001366 weston_compositor_wake(compositor);
1367
Derek Foreman99a6a2d2015-07-15 13:00:43 -05001368 if (weston_compositor_run_axis_binding(compositor, pointer,
Peter Hutterer89b6a492016-01-18 15:58:17 +10001369 time, event))
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001370 return;
1371
Peter Hutterer89b6a492016-01-18 15:58:17 +10001372 pointer->grab->interface->axis(pointer->grab, time, event);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001373}
1374
Peter Hutterer87743e92016-01-18 16:38:22 +10001375WL_EXPORT void
1376notify_axis_source(struct weston_seat *seat, uint32_t source)
1377{
1378 struct weston_compositor *compositor = seat->compositor;
1379 struct weston_pointer *pointer = weston_seat_get_pointer(seat);
1380
1381 weston_compositor_wake(compositor);
1382
1383 pointer->grab->interface->axis_source(pointer->grab, source);
1384}
1385
1386WL_EXPORT void
1387notify_pointer_frame(struct weston_seat *seat)
1388{
1389 struct weston_compositor *compositor = seat->compositor;
1390 struct weston_pointer *pointer = weston_seat_get_pointer(seat);
1391
1392 weston_compositor_wake(compositor);
1393
1394 pointer->grab->interface->frame(pointer->grab);
1395}
1396
Giulio Camuffo6ef444d2014-08-28 19:44:09 +03001397WL_EXPORT int
1398weston_keyboard_set_locks(struct weston_keyboard *keyboard,
1399 uint32_t mask, uint32_t value)
1400{
1401#ifdef ENABLE_XKBCOMMON
1402 uint32_t serial;
1403 xkb_mod_mask_t mods_depressed, mods_latched, mods_locked, group;
1404 xkb_mod_mask_t num, caps;
1405
1406 /* We don't want the leds to go out of sync with the actual state
1407 * so if the backend has no way to change the leds don't try to
1408 * change the state */
1409 if (!keyboard->seat->led_update)
1410 return -1;
1411
1412 mods_depressed = xkb_state_serialize_mods(keyboard->xkb_state.state,
1413 XKB_STATE_DEPRESSED);
1414 mods_latched = xkb_state_serialize_mods(keyboard->xkb_state.state,
1415 XKB_STATE_LATCHED);
1416 mods_locked = xkb_state_serialize_mods(keyboard->xkb_state.state,
1417 XKB_STATE_LOCKED);
1418 group = xkb_state_serialize_group(keyboard->xkb_state.state,
1419 XKB_STATE_EFFECTIVE);
1420
1421 num = (1 << keyboard->xkb_info->mod2_mod);
1422 caps = (1 << keyboard->xkb_info->caps_mod);
1423 if (mask & WESTON_NUM_LOCK) {
1424 if (value & WESTON_NUM_LOCK)
1425 mods_locked |= num;
1426 else
1427 mods_locked &= ~num;
1428 }
1429 if (mask & WESTON_CAPS_LOCK) {
1430 if (value & WESTON_CAPS_LOCK)
1431 mods_locked |= caps;
1432 else
1433 mods_locked &= ~caps;
1434 }
1435
1436 xkb_state_update_mask(keyboard->xkb_state.state, mods_depressed,
1437 mods_latched, mods_locked, 0, 0, group);
1438
1439 serial = wl_display_next_serial(
1440 keyboard->seat->compositor->wl_display);
1441 notify_modifiers(keyboard->seat, serial);
1442
1443 return 0;
1444#else
1445 return -1;
1446#endif
1447}
1448
Rob Bradford382ff462013-06-24 16:52:45 +01001449#ifdef ENABLE_XKBCOMMON
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001450WL_EXPORT void
1451notify_modifiers(struct weston_seat *seat, uint32_t serial)
1452{
Derek Foreman1281a362015-07-31 16:55:32 -05001453 struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001454 struct weston_keyboard_grab *grab = keyboard->grab;
1455 uint32_t mods_depressed, mods_latched, mods_locked, group;
1456 uint32_t mods_lookup;
1457 enum weston_led leds = 0;
1458 int changed = 0;
1459
1460 /* Serialize and update our internal state, checking to see if it's
1461 * different to the previous state. */
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001462 mods_depressed = xkb_state_serialize_mods(keyboard->xkb_state.state,
Ran Benita2e1968f2014-08-19 23:59:51 +03001463 XKB_STATE_MODS_DEPRESSED);
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001464 mods_latched = xkb_state_serialize_mods(keyboard->xkb_state.state,
Ran Benita2e1968f2014-08-19 23:59:51 +03001465 XKB_STATE_MODS_LATCHED);
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001466 mods_locked = xkb_state_serialize_mods(keyboard->xkb_state.state,
Ran Benita2e1968f2014-08-19 23:59:51 +03001467 XKB_STATE_MODS_LOCKED);
1468 group = xkb_state_serialize_layout(keyboard->xkb_state.state,
1469 XKB_STATE_LAYOUT_EFFECTIVE);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001470
Derek Foreman244e99e2015-06-03 15:53:26 -05001471 if (mods_depressed != keyboard->modifiers.mods_depressed ||
1472 mods_latched != keyboard->modifiers.mods_latched ||
1473 mods_locked != keyboard->modifiers.mods_locked ||
1474 group != keyboard->modifiers.group)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001475 changed = 1;
1476
Derek Foreman244e99e2015-06-03 15:53:26 -05001477 run_modifier_bindings(seat, keyboard->modifiers.mods_depressed,
Daniel Stone96d47c02013-11-19 11:37:12 +01001478 mods_depressed);
1479
Derek Foreman244e99e2015-06-03 15:53:26 -05001480 keyboard->modifiers.mods_depressed = mods_depressed;
1481 keyboard->modifiers.mods_latched = mods_latched;
1482 keyboard->modifiers.mods_locked = mods_locked;
1483 keyboard->modifiers.group = group;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001484
1485 /* And update the modifier_state for bindings. */
1486 mods_lookup = mods_depressed | mods_latched;
1487 seat->modifier_state = 0;
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001488 if (mods_lookup & (1 << keyboard->xkb_info->ctrl_mod))
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001489 seat->modifier_state |= MODIFIER_CTRL;
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001490 if (mods_lookup & (1 << keyboard->xkb_info->alt_mod))
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001491 seat->modifier_state |= MODIFIER_ALT;
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001492 if (mods_lookup & (1 << keyboard->xkb_info->super_mod))
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001493 seat->modifier_state |= MODIFIER_SUPER;
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001494 if (mods_lookup & (1 << keyboard->xkb_info->shift_mod))
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001495 seat->modifier_state |= MODIFIER_SHIFT;
1496
1497 /* Finally, notify the compositor that LEDs have changed. */
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001498 if (xkb_state_led_index_is_active(keyboard->xkb_state.state,
1499 keyboard->xkb_info->num_led))
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001500 leds |= LED_NUM_LOCK;
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001501 if (xkb_state_led_index_is_active(keyboard->xkb_state.state,
1502 keyboard->xkb_info->caps_led))
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001503 leds |= LED_CAPS_LOCK;
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001504 if (xkb_state_led_index_is_active(keyboard->xkb_state.state,
1505 keyboard->xkb_info->scroll_led))
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001506 leds |= LED_SCROLL_LOCK;
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001507 if (leds != keyboard->xkb_state.leds && seat->led_update)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001508 seat->led_update(seat, leds);
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001509 keyboard->xkb_state.leds = leds;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001510
1511 if (changed) {
1512 grab->interface->modifiers(grab,
1513 serial,
1514 keyboard->modifiers.mods_depressed,
1515 keyboard->modifiers.mods_latched,
1516 keyboard->modifiers.mods_locked,
1517 keyboard->modifiers.group);
1518 }
1519}
1520
1521static void
1522update_modifier_state(struct weston_seat *seat, uint32_t serial, uint32_t key,
1523 enum wl_keyboard_key_state state)
1524{
Derek Foreman1281a362015-07-31 16:55:32 -05001525 struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001526 enum xkb_key_direction direction;
1527
Matt Roper01a92732013-06-24 16:52:44 +01001528 /* Keyboard modifiers don't exist in raw keyboard mode */
1529 if (!seat->compositor->use_xkbcommon)
1530 return;
1531
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001532 if (state == WL_KEYBOARD_KEY_STATE_PRESSED)
1533 direction = XKB_KEY_DOWN;
1534 else
1535 direction = XKB_KEY_UP;
1536
1537 /* Offset the keycode by 8, as the evdev XKB rules reflect X's
1538 * broken keycode system, which starts at 8. */
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001539 xkb_state_update_key(keyboard->xkb_state.state, key + 8, direction);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001540
1541 notify_modifiers(seat, serial);
1542}
Rui Matos65196bc2013-10-10 19:44:19 +02001543
1544static void
1545send_keymap(struct wl_resource *resource, struct weston_xkb_info *xkb_info)
1546{
1547 wl_keyboard_send_keymap(resource,
1548 WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1,
1549 xkb_info->keymap_fd,
1550 xkb_info->keymap_size);
1551}
1552
1553static void
1554send_modifiers(struct wl_resource *resource, uint32_t serial, struct weston_keyboard *keyboard)
1555{
1556 wl_keyboard_send_modifiers(resource, serial,
1557 keyboard->modifiers.mods_depressed,
1558 keyboard->modifiers.mods_latched,
1559 keyboard->modifiers.mods_locked,
1560 keyboard->modifiers.group);
1561}
1562
1563static struct weston_xkb_info *
1564weston_xkb_info_create(struct xkb_keymap *keymap);
Rui Matos65196bc2013-10-10 19:44:19 +02001565
1566static void
1567update_keymap(struct weston_seat *seat)
1568{
Derek Foreman1281a362015-07-31 16:55:32 -05001569 struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
Rui Matos65196bc2013-10-10 19:44:19 +02001570 struct wl_resource *resource;
1571 struct weston_xkb_info *xkb_info;
1572 struct xkb_state *state;
1573 xkb_mod_mask_t latched_mods;
1574 xkb_mod_mask_t locked_mods;
1575
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001576 xkb_info = weston_xkb_info_create(keyboard->pending_keymap);
Rui Matos65196bc2013-10-10 19:44:19 +02001577
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001578 xkb_keymap_unref(keyboard->pending_keymap);
1579 keyboard->pending_keymap = NULL;
Rui Matos65196bc2013-10-10 19:44:19 +02001580
1581 if (!xkb_info) {
1582 weston_log("failed to create XKB info\n");
1583 return;
1584 }
1585
1586 state = xkb_state_new(xkb_info->keymap);
1587 if (!state) {
1588 weston_log("failed to initialise XKB state\n");
1589 weston_xkb_info_destroy(xkb_info);
1590 return;
1591 }
1592
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001593 latched_mods = xkb_state_serialize_mods(keyboard->xkb_state.state,
1594 XKB_STATE_MODS_LATCHED);
1595 locked_mods = xkb_state_serialize_mods(keyboard->xkb_state.state,
1596 XKB_STATE_MODS_LOCKED);
Rui Matos65196bc2013-10-10 19:44:19 +02001597 xkb_state_update_mask(state,
1598 0, /* depressed */
1599 latched_mods,
1600 locked_mods,
1601 0, 0, 0);
1602
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001603 weston_xkb_info_destroy(keyboard->xkb_info);
1604 keyboard->xkb_info = xkb_info;
Rui Matos65196bc2013-10-10 19:44:19 +02001605
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001606 xkb_state_unref(keyboard->xkb_state.state);
1607 keyboard->xkb_state.state = state;
Rui Matos65196bc2013-10-10 19:44:19 +02001608
Derek Foremanbc91e542015-06-03 15:53:27 -05001609 wl_resource_for_each(resource, &keyboard->resource_list)
Rui Matos65196bc2013-10-10 19:44:19 +02001610 send_keymap(resource, xkb_info);
Derek Foremanbc91e542015-06-03 15:53:27 -05001611 wl_resource_for_each(resource, &keyboard->focus_resource_list)
Rui Matos65196bc2013-10-10 19:44:19 +02001612 send_keymap(resource, xkb_info);
1613
1614 notify_modifiers(seat, wl_display_next_serial(seat->compositor->wl_display));
1615
1616 if (!latched_mods && !locked_mods)
1617 return;
1618
Derek Foremanbc91e542015-06-03 15:53:27 -05001619 wl_resource_for_each(resource, &keyboard->resource_list)
1620 send_modifiers(resource, wl_display_get_serial(seat->compositor->wl_display), keyboard);
1621 wl_resource_for_each(resource, &keyboard->focus_resource_list)
1622 send_modifiers(resource, wl_display_get_serial(seat->compositor->wl_display), keyboard);
Rui Matos65196bc2013-10-10 19:44:19 +02001623}
Rob Bradford382ff462013-06-24 16:52:45 +01001624#else
1625WL_EXPORT void
1626notify_modifiers(struct weston_seat *seat, uint32_t serial)
1627{
1628}
1629
1630static void
1631update_modifier_state(struct weston_seat *seat, uint32_t serial, uint32_t key,
1632 enum wl_keyboard_key_state state)
1633{
1634}
Rui Matos65196bc2013-10-10 19:44:19 +02001635
1636static void
1637update_keymap(struct weston_seat *seat)
1638{
1639}
Rob Bradford382ff462013-06-24 16:52:45 +01001640#endif
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001641
1642WL_EXPORT void
1643notify_key(struct weston_seat *seat, uint32_t time, uint32_t key,
1644 enum wl_keyboard_key_state state,
1645 enum weston_key_state_update update_state)
1646{
1647 struct weston_compositor *compositor = seat->compositor;
Derek Foreman1281a362015-07-31 16:55:32 -05001648 struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001649 struct weston_keyboard_grab *grab = keyboard->grab;
Pekka Paalanen86b53962014-11-19 13:43:32 +02001650 uint32_t *k, *end;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001651
1652 if (state == WL_KEYBOARD_KEY_STATE_PRESSED) {
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001653 weston_compositor_idle_inhibit(compositor);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001654 } else {
1655 weston_compositor_idle_release(compositor);
1656 }
1657
Pekka Paalanen86b53962014-11-19 13:43:32 +02001658 end = keyboard->keys.data + keyboard->keys.size;
1659 for (k = keyboard->keys.data; k < end; k++) {
1660 if (*k == key) {
1661 /* Ignore server-generated repeats. */
1662 if (state == WL_KEYBOARD_KEY_STATE_PRESSED)
1663 return;
1664 *k = *--end;
1665 }
1666 }
1667 keyboard->keys.size = (void *) end - keyboard->keys.data;
1668 if (state == WL_KEYBOARD_KEY_STATE_PRESSED) {
1669 k = wl_array_add(&keyboard->keys, sizeof *k);
1670 *k = key;
1671 }
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001672
1673 if (grab == &keyboard->default_grab ||
1674 grab == &keyboard->input_method_grab) {
Derek Foreman99a6a2d2015-07-15 13:00:43 -05001675 weston_compositor_run_key_binding(compositor, keyboard, time,
1676 key, state);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001677 grab = keyboard->grab;
1678 }
1679
1680 grab->interface->key(grab, time, key, state);
1681
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001682 if (keyboard->pending_keymap &&
Pekka Paalanen86b53962014-11-19 13:43:32 +02001683 keyboard->keys.size == 0)
Rui Matos65196bc2013-10-10 19:44:19 +02001684 update_keymap(seat);
1685
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001686 if (update_state == STATE_UPDATE_AUTOMATIC) {
1687 update_modifier_state(seat,
1688 wl_display_get_serial(compositor->wl_display),
1689 key,
1690 state);
1691 }
Giulio Camuffob6ddf6c2015-02-06 19:06:54 +02001692
1693 if (state == WL_KEYBOARD_KEY_STATE_PRESSED) {
1694 keyboard->grab_serial =
1695 wl_display_get_serial(compositor->wl_display);
1696 keyboard->grab_time = time;
1697 keyboard->grab_key = key;
1698 }
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001699}
1700
1701WL_EXPORT void
1702notify_pointer_focus(struct weston_seat *seat, struct weston_output *output,
Giulio Camuffo90a6fc62016-03-22 17:44:54 +02001703 double x, double y)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001704{
Derek Foreman1281a362015-07-31 16:55:32 -05001705 struct weston_pointer *pointer = weston_seat_get_pointer(seat);
1706
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001707 if (output) {
Giulio Camuffo90a6fc62016-03-22 17:44:54 +02001708 weston_pointer_move_to(pointer,
1709 wl_fixed_from_double(x),
1710 wl_fixed_from_double(y));
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001711 } else {
Kristian Høgsberg02bbabb2013-05-06 22:15:05 -04001712 /* FIXME: We should call weston_pointer_set_focus(seat,
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001713 * NULL) here, but somehow that breaks re-entry... */
1714 }
1715}
1716
1717static void
1718destroy_device_saved_kbd_focus(struct wl_listener *listener, void *data)
1719{
1720 struct weston_seat *ws;
1721
1722 ws = container_of(listener, struct weston_seat,
1723 saved_kbd_focus_listener);
1724
1725 ws->saved_kbd_focus = NULL;
1726}
1727
1728WL_EXPORT void
1729notify_keyboard_focus_in(struct weston_seat *seat, struct wl_array *keys,
1730 enum weston_key_state_update update_state)
1731{
1732 struct weston_compositor *compositor = seat->compositor;
Derek Foreman1281a362015-07-31 16:55:32 -05001733 struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
Kristian Høgsbergfe7aa902013-05-08 09:54:37 -04001734 struct weston_surface *surface;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001735 uint32_t *k, serial;
1736
1737 serial = wl_display_next_serial(compositor->wl_display);
1738 wl_array_copy(&keyboard->keys, keys);
1739 wl_array_for_each(k, &keyboard->keys) {
1740 weston_compositor_idle_inhibit(compositor);
1741 if (update_state == STATE_UPDATE_AUTOMATIC)
1742 update_modifier_state(seat, serial, *k,
1743 WL_KEYBOARD_KEY_STATE_PRESSED);
1744 }
1745
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001746 surface = seat->saved_kbd_focus;
1747
1748 if (surface) {
1749 wl_list_remove(&seat->saved_kbd_focus_listener.link);
1750 weston_keyboard_set_focus(keyboard, surface);
1751 seat->saved_kbd_focus = NULL;
1752 }
1753}
1754
1755WL_EXPORT void
1756notify_keyboard_focus_out(struct weston_seat *seat)
1757{
1758 struct weston_compositor *compositor = seat->compositor;
Derek Foreman1281a362015-07-31 16:55:32 -05001759 struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
1760 struct weston_pointer *pointer = weston_seat_get_pointer(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001761 uint32_t *k, serial;
1762
1763 serial = wl_display_next_serial(compositor->wl_display);
1764 wl_array_for_each(k, &keyboard->keys) {
1765 weston_compositor_idle_release(compositor);
1766 update_modifier_state(seat, serial, *k,
1767 WL_KEYBOARD_KEY_STATE_RELEASED);
1768 }
1769
1770 seat->modifier_state = 0;
1771
1772 if (keyboard->focus) {
1773 seat->saved_kbd_focus = keyboard->focus;
1774 seat->saved_kbd_focus_listener.notify =
1775 destroy_device_saved_kbd_focus;
Jason Ekstrand26ed73c2013-06-06 22:34:41 -05001776 wl_signal_add(&keyboard->focus->destroy_signal,
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001777 &seat->saved_kbd_focus_listener);
1778 }
1779
1780 weston_keyboard_set_focus(keyboard, NULL);
Jonas Ådahl1ea343e2013-10-25 23:18:05 +02001781 weston_keyboard_cancel_grab(keyboard);
Derek Foreman1281a362015-07-31 16:55:32 -05001782 if (pointer)
1783 weston_pointer_cancel_grab(pointer);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001784}
1785
Michael Fua2bb7912013-07-23 15:51:06 +08001786WL_EXPORT void
Derek Foreman4c93c082015-04-30 16:45:41 -05001787weston_touch_set_focus(struct weston_touch *touch, struct weston_view *view)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001788{
Neil Roberts96d790e2013-09-19 17:32:00 +01001789 struct wl_list *focus_resource_list;
1790
Derek Foreman4c93c082015-04-30 16:45:41 -05001791 focus_resource_list = &touch->focus_resource_list;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001792
Derek Foreman4c93c082015-04-30 16:45:41 -05001793 if (view && touch->focus &&
1794 touch->focus->surface == view->surface) {
1795 touch->focus = view;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001796 return;
Jason Ekstranda7af7042013-10-12 22:38:11 -05001797 }
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001798
Derek Foreman4c93c082015-04-30 16:45:41 -05001799 wl_list_remove(&touch->focus_resource_listener.link);
1800 wl_list_init(&touch->focus_resource_listener.link);
1801 wl_list_remove(&touch->focus_view_listener.link);
1802 wl_list_init(&touch->focus_view_listener.link);
Giulio Camuffo576fe2a2013-11-20 18:00:24 +01001803
Neil Roberts96d790e2013-09-19 17:32:00 +01001804 if (!wl_list_empty(focus_resource_list)) {
Derek Foreman4c93c082015-04-30 16:45:41 -05001805 move_resources(&touch->resource_list,
Neil Roberts96d790e2013-09-19 17:32:00 +01001806 focus_resource_list);
1807 }
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001808
Jason Ekstranda7af7042013-10-12 22:38:11 -05001809 if (view) {
Derek Foreman362656b2014-09-04 10:23:05 -05001810 struct wl_client *surface_client;
1811
1812 if (!view->surface->resource) {
Derek Foreman4c93c082015-04-30 16:45:41 -05001813 touch->focus = NULL;
Derek Foreman362656b2014-09-04 10:23:05 -05001814 return;
1815 }
1816
1817 surface_client = wl_resource_get_client(view->surface->resource);
Neil Roberts96d790e2013-09-19 17:32:00 +01001818 move_resources_for_client(focus_resource_list,
Derek Foreman4c93c082015-04-30 16:45:41 -05001819 &touch->resource_list,
Neil Roberts96d790e2013-09-19 17:32:00 +01001820 surface_client);
Giulio Camuffo576fe2a2013-11-20 18:00:24 +01001821 wl_resource_add_destroy_listener(view->surface->resource,
Derek Foreman4c93c082015-04-30 16:45:41 -05001822 &touch->focus_resource_listener);
1823 wl_signal_add(&view->destroy_signal, &touch->focus_view_listener);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001824 }
Derek Foreman4c93c082015-04-30 16:45:41 -05001825 touch->focus = view;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001826}
1827
1828/**
1829 * notify_touch - emulates button touches and notifies surfaces accordingly.
1830 *
1831 * It assumes always the correct cycle sequence until it gets here: touch_down
1832 * → touch_update → ... → touch_update → touch_end. The driver is responsible
1833 * for sending along such order.
1834 *
1835 */
1836WL_EXPORT void
1837notify_touch(struct weston_seat *seat, uint32_t time, int touch_id,
Giulio Camuffo90a6fc62016-03-22 17:44:54 +02001838 double double_x, double double_y, int touch_type)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001839{
1840 struct weston_compositor *ec = seat->compositor;
Derek Foreman1281a362015-07-31 16:55:32 -05001841 struct weston_touch *touch = weston_seat_get_touch(seat);
Kristian Høgsberge329f362013-05-06 22:19:57 -04001842 struct weston_touch_grab *grab = touch->grab;
Jason Ekstranda7af7042013-10-12 22:38:11 -05001843 struct weston_view *ev;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001844 wl_fixed_t sx, sy;
Giulio Camuffo90a6fc62016-03-22 17:44:54 +02001845 wl_fixed_t x = wl_fixed_from_double(double_x);
1846 wl_fixed_t y = wl_fixed_from_double(double_y);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001847
1848 /* Update grab's global coordinates. */
Neil Roberts306fe082013-10-03 16:43:06 +01001849 if (touch_id == touch->grab_touch_id && touch_type != WL_TOUCH_UP) {
1850 touch->grab_x = x;
1851 touch->grab_y = y;
1852 }
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001853
1854 switch (touch_type) {
1855 case WL_TOUCH_DOWN:
1856 weston_compositor_idle_inhibit(ec);
1857
Jonas Ådahl9484b692013-12-02 22:05:03 +01001858 touch->num_tp++;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001859
Jason Ekstranda7af7042013-10-12 22:38:11 -05001860 /* the first finger down picks the view, and all further go
1861 * to that view for the remainder of the touch session i.e.
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001862 * until all touch points are up again. */
Jonas Ådahl9484b692013-12-02 22:05:03 +01001863 if (touch->num_tp == 1) {
Jason Ekstranda7af7042013-10-12 22:38:11 -05001864 ev = weston_compositor_pick_view(ec, x, y, &sx, &sy);
Derek Foreman4c93c082015-04-30 16:45:41 -05001865 weston_touch_set_focus(touch, ev);
Giulio Camuffo61ed7b62015-07-08 11:55:28 +03001866 } else if (!touch->focus) {
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001867 /* Unexpected condition: We have non-initial touch but
1868 * there is no focused surface.
1869 */
Chris Michael3f607d32015-10-07 11:59:49 -04001870 weston_log("touch event received with %d points down "
Jonas Ådahl9484b692013-12-02 22:05:03 +01001871 "but no surface focused\n", touch->num_tp);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001872 return;
1873 }
1874
Derek Foreman99a6a2d2015-07-15 13:00:43 -05001875 weston_compositor_run_touch_binding(ec, touch,
Kristian Høgsbergc8964012014-02-05 14:25:18 -08001876 time, touch_type);
1877
Giulio Camuffo61ed7b62015-07-08 11:55:28 +03001878 grab->interface->down(grab, time, touch_id, x, y);
Jonas Ådahl9484b692013-12-02 22:05:03 +01001879 if (touch->num_tp == 1) {
Rusty Lynchf1407ff2013-08-08 21:13:57 -07001880 touch->grab_serial =
1881 wl_display_get_serial(ec->wl_display);
Neil Roberts306fe082013-10-03 16:43:06 +01001882 touch->grab_touch_id = touch_id;
Rusty Lynchf1407ff2013-08-08 21:13:57 -07001883 touch->grab_time = time;
1884 touch->grab_x = x;
1885 touch->grab_y = y;
1886 }
1887
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001888 break;
1889 case WL_TOUCH_MOTION:
Jason Ekstranda7af7042013-10-12 22:38:11 -05001890 ev = touch->focus;
1891 if (!ev)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001892 break;
1893
Giulio Camuffo61ed7b62015-07-08 11:55:28 +03001894 grab->interface->motion(grab, time, touch_id, x, y);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001895 break;
1896 case WL_TOUCH_UP:
Kristian Høgsberga30e29a2014-01-08 22:29:20 -08001897 if (touch->num_tp == 0) {
1898 /* This can happen if we start out with one or
1899 * more fingers on the touch screen, in which
1900 * case we didn't get the corresponding down
1901 * event. */
1902 weston_log("unmatched touch up event\n");
1903 break;
1904 }
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001905 weston_compositor_idle_release(ec);
Jonas Ådahl9484b692013-12-02 22:05:03 +01001906 touch->num_tp--;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001907
1908 grab->interface->up(grab, time, touch_id);
Jonas Ådahl9484b692013-12-02 22:05:03 +01001909 if (touch->num_tp == 0)
Derek Foreman4c93c082015-04-30 16:45:41 -05001910 weston_touch_set_focus(touch, NULL);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001911 break;
1912 }
1913}
1914
Jonas Ådahl1679f232014-04-12 09:39:51 +02001915WL_EXPORT void
1916notify_touch_frame(struct weston_seat *seat)
1917{
Derek Foreman1281a362015-07-31 16:55:32 -05001918 struct weston_touch *touch = weston_seat_get_touch(seat);
Jonas Ådahl1679f232014-04-12 09:39:51 +02001919 struct weston_touch_grab *grab = touch->grab;
1920
1921 grab->interface->frame(grab);
1922}
1923
Derek Foreman3cc004a2015-11-06 15:56:09 -06001924WL_EXPORT void
1925notify_touch_cancel(struct weston_seat *seat)
1926{
1927 struct weston_touch *touch = weston_seat_get_touch(seat);
1928 struct weston_touch_grab *grab = touch->grab;
1929
1930 grab->interface->cancel(grab);
1931}
1932
Pekka Paalanen8274d902014-08-06 19:36:51 +03001933static int
1934pointer_cursor_surface_get_label(struct weston_surface *surface,
1935 char *buf, size_t len)
1936{
1937 return snprintf(buf, len, "cursor");
1938}
1939
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001940static void
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001941pointer_cursor_surface_configure(struct weston_surface *es,
Jason Ekstrand918f2dd2013-12-02 21:01:53 -06001942 int32_t dx, int32_t dy)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001943{
Kristian Høgsberg195b8692013-05-08 15:02:05 -04001944 struct weston_pointer *pointer = es->configure_private;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001945 int x, y;
1946
Jason Ekstrand918f2dd2013-12-02 21:01:53 -06001947 if (es->width == 0)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001948 return;
1949
Jason Ekstranda7af7042013-10-12 22:38:11 -05001950 assert(es == pointer->sprite->surface);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001951
Kristian Høgsberg195b8692013-05-08 15:02:05 -04001952 pointer->hotspot_x -= dx;
1953 pointer->hotspot_y -= dy;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001954
Kristian Høgsberg195b8692013-05-08 15:02:05 -04001955 x = wl_fixed_to_int(pointer->x) - pointer->hotspot_x;
1956 y = wl_fixed_to_int(pointer->y) - pointer->hotspot_y;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001957
Jason Ekstrand918f2dd2013-12-02 21:01:53 -06001958 weston_view_set_position(pointer->sprite, x, y);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001959
1960 empty_region(&es->pending.input);
Ander Conselvan de Oliveira23900f72014-01-31 16:07:51 +02001961 empty_region(&es->input);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001962
1963 if (!weston_surface_is_mapped(es)) {
Giulio Camuffo412e6a52014-07-09 22:12:56 +03001964 weston_layer_entry_insert(&es->compositor->cursor_layer.view_list,
1965 &pointer->sprite->layer_link);
Jason Ekstranda7af7042013-10-12 22:38:11 -05001966 weston_view_update_transform(pointer->sprite);
Armin Krezovićf8486c32016-06-30 06:04:28 +02001967 es->is_mapped = true;
1968 pointer->sprite->is_mapped = true;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001969 }
1970}
1971
1972static void
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001973pointer_set_cursor(struct wl_client *client, struct wl_resource *resource,
1974 uint32_t serial, struct wl_resource *surface_resource,
1975 int32_t x, int32_t y)
1976{
Jason Ekstrand44a38632013-06-14 10:08:00 -05001977 struct weston_pointer *pointer = wl_resource_get_user_data(resource);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001978 struct weston_surface *surface = NULL;
1979
1980 if (surface_resource)
Jason Ekstrand0f2ef7e2013-06-14 10:07:53 -05001981 surface = wl_resource_get_user_data(surface_resource);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001982
Kristian Høgsberg195b8692013-05-08 15:02:05 -04001983 if (pointer->focus == NULL)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001984 return;
Jason Ekstranda7af7042013-10-12 22:38:11 -05001985 /* pointer->focus->surface->resource can be NULL. Surfaces like the
Giulio Camuffo1fd4b012013-06-20 18:13:07 +02001986 black_surface used in shell.c for fullscreen don't have
1987 a resource, but can still have focus */
Jason Ekstranda7af7042013-10-12 22:38:11 -05001988 if (pointer->focus->surface->resource == NULL)
Giulio Camuffo1fd4b012013-06-20 18:13:07 +02001989 return;
Jason Ekstranda7af7042013-10-12 22:38:11 -05001990 if (wl_resource_get_client(pointer->focus->surface->resource) != client)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001991 return;
Kristian Høgsberg195b8692013-05-08 15:02:05 -04001992 if (pointer->focus_serial - serial > UINT32_MAX / 2)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001993 return;
1994
Derek Foreman4e53c532015-03-23 10:55:32 -05001995 if (!surface) {
1996 if (pointer->sprite)
1997 pointer_unmap_sprite(pointer);
1998 return;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001999 }
2000
Jonas Ådahlb4070242015-03-18 15:08:03 +08002001 if (pointer->sprite && pointer->sprite->surface == surface &&
2002 pointer->hotspot_x == x && pointer->hotspot_y == y)
2003 return;
2004
Derek Foreman4e53c532015-03-23 10:55:32 -05002005 if (!pointer->sprite || pointer->sprite->surface != surface) {
2006 if (weston_surface_set_role(surface, "wl_pointer-cursor",
2007 resource,
2008 WL_POINTER_ERROR_ROLE) < 0)
2009 return;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002010
Derek Foreman4e53c532015-03-23 10:55:32 -05002011 if (pointer->sprite)
2012 pointer_unmap_sprite(pointer);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002013
Derek Foreman4e53c532015-03-23 10:55:32 -05002014 wl_signal_add(&surface->destroy_signal,
2015 &pointer->sprite_destroy_listener);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002016
Derek Foreman4e53c532015-03-23 10:55:32 -05002017 surface->configure = pointer_cursor_surface_configure;
2018 surface->configure_private = pointer;
2019 weston_surface_set_label_func(surface,
2020 pointer_cursor_surface_get_label);
2021 pointer->sprite = weston_view_create(surface);
2022 }
2023
Kristian Høgsberg195b8692013-05-08 15:02:05 -04002024 pointer->hotspot_x = x;
2025 pointer->hotspot_y = y;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002026
Jonas Ådahl16fe4dc2014-09-08 19:33:41 +02002027 if (surface->buffer_ref.buffer) {
Jason Ekstrand918f2dd2013-12-02 21:01:53 -06002028 pointer_cursor_surface_configure(surface, 0, 0);
Jonas Ådahl16fe4dc2014-09-08 19:33:41 +02002029 weston_view_schedule_repaint(pointer->sprite);
2030 }
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002031}
2032
Kristian Høgsberg69e25fc2013-08-13 20:11:02 +01002033static void
2034pointer_release(struct wl_client *client, struct wl_resource *resource)
2035{
2036 wl_resource_destroy(resource);
2037}
2038
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002039static const struct wl_pointer_interface pointer_interface = {
Kristian Høgsberg69e25fc2013-08-13 20:11:02 +01002040 pointer_set_cursor,
2041 pointer_release
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002042};
2043
2044static void
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002045seat_get_pointer(struct wl_client *client, struct wl_resource *resource,
2046 uint32_t id)
2047{
Jason Ekstrand44a38632013-06-14 10:08:00 -05002048 struct weston_seat *seat = wl_resource_get_user_data(resource);
Derek Foreman1281a362015-07-31 16:55:32 -05002049 /* We use the pointer_state directly, which means we'll
2050 * give a wl_pointer if the seat has ever had one - even though
2051 * the spec explicitly states that this request only takes effect
2052 * if the seat has the pointer capability.
2053 *
2054 * This prevents a race between the compositor sending new
2055 * capabilities and the client trying to use the old ones.
2056 */
2057 struct weston_pointer *pointer = seat->pointer_state;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002058 struct wl_resource *cr;
Jonas Ådahl2cbf2932015-07-22 12:05:38 +08002059 struct weston_pointer_client *pointer_client;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002060
Derek Foreman1281a362015-07-31 16:55:32 -05002061 if (!pointer)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002062 return;
2063
Jason Ekstranda85118c2013-06-27 20:17:02 -05002064 cr = wl_resource_create(client, &wl_pointer_interface,
2065 wl_resource_get_version(resource), id);
Kristian Høgsberg0ff79082013-08-06 16:46:25 -07002066 if (cr == NULL) {
2067 wl_client_post_no_memory(client);
2068 return;
2069 }
2070
Jonas Ådahl2cbf2932015-07-22 12:05:38 +08002071 pointer_client = weston_pointer_ensure_pointer_client(pointer, client);
2072 if (!pointer_client) {
2073 wl_client_post_no_memory(client);
2074 return;
2075 }
2076
2077 wl_list_insert(&pointer_client->pointer_resources,
2078 wl_resource_get_link(cr));
Derek Foreman1281a362015-07-31 16:55:32 -05002079 wl_resource_set_implementation(cr, &pointer_interface, pointer,
Jonas Ådahl2cbf2932015-07-22 12:05:38 +08002080 unbind_pointer_client_resource);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002081
Derek Foreman1281a362015-07-31 16:55:32 -05002082 if (pointer->focus && pointer->focus->surface->resource &&
2083 wl_resource_get_client(pointer->focus->surface->resource) == client) {
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002084 wl_fixed_t sx, sy;
2085
Derek Foreman1281a362015-07-31 16:55:32 -05002086 weston_view_from_global_fixed(pointer->focus,
2087 pointer->x,
2088 pointer->y,
Jason Ekstranda7af7042013-10-12 22:38:11 -05002089 &sx, &sy);
Neil Roberts96d790e2013-09-19 17:32:00 +01002090
Neil Roberts96d790e2013-09-19 17:32:00 +01002091 wl_pointer_send_enter(cr,
Derek Foreman1281a362015-07-31 16:55:32 -05002092 pointer->focus_serial,
2093 pointer->focus->surface->resource,
Neil Roberts96d790e2013-09-19 17:32:00 +01002094 sx, sy);
Peter Hutterer87743e92016-01-18 16:38:22 +10002095 pointer_send_frame(cr);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002096 }
2097}
2098
2099static void
Kristian Høgsberg69e25fc2013-08-13 20:11:02 +01002100keyboard_release(struct wl_client *client, struct wl_resource *resource)
2101{
2102 wl_resource_destroy(resource);
2103}
2104
2105static const struct wl_keyboard_interface keyboard_interface = {
2106 keyboard_release
2107};
2108
Derek Foreman280e7dd2014-10-03 13:13:42 -05002109static bool
Neil Roberts96d790e2013-09-19 17:32:00 +01002110should_send_modifiers_to_client(struct weston_seat *seat,
2111 struct wl_client *client)
2112{
Derek Foreman1281a362015-07-31 16:55:32 -05002113 struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
2114 struct weston_pointer *pointer = weston_seat_get_pointer(seat);
2115
2116 if (keyboard &&
2117 keyboard->focus &&
2118 keyboard->focus->resource &&
2119 wl_resource_get_client(keyboard->focus->resource) == client)
Derek Foreman280e7dd2014-10-03 13:13:42 -05002120 return true;
Neil Roberts96d790e2013-09-19 17:32:00 +01002121
Derek Foreman1281a362015-07-31 16:55:32 -05002122 if (pointer &&
2123 pointer->focus &&
2124 pointer->focus->surface->resource &&
2125 wl_resource_get_client(pointer->focus->surface->resource) == client)
Derek Foreman280e7dd2014-10-03 13:13:42 -05002126 return true;
Neil Roberts96d790e2013-09-19 17:32:00 +01002127
Derek Foreman280e7dd2014-10-03 13:13:42 -05002128 return false;
Neil Roberts96d790e2013-09-19 17:32:00 +01002129}
2130
Kristian Høgsberg69e25fc2013-08-13 20:11:02 +01002131static void
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002132seat_get_keyboard(struct wl_client *client, struct wl_resource *resource,
2133 uint32_t id)
2134{
Jason Ekstrand44a38632013-06-14 10:08:00 -05002135 struct weston_seat *seat = wl_resource_get_user_data(resource);
Derek Foreman1281a362015-07-31 16:55:32 -05002136 /* We use the keyboard_state directly, which means we'll
2137 * give a wl_keyboard if the seat has ever had one - even though
2138 * the spec explicitly states that this request only takes effect
2139 * if the seat has the keyboard capability.
2140 *
2141 * This prevents a race between the compositor sending new
2142 * capabilities and the client trying to use the old ones.
2143 */
2144 struct weston_keyboard *keyboard = seat->keyboard_state;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002145 struct wl_resource *cr;
2146
Derek Foreman345c9f32015-06-03 15:53:28 -05002147 if (!keyboard)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002148 return;
2149
Jason Ekstranda85118c2013-06-27 20:17:02 -05002150 cr = wl_resource_create(client, &wl_keyboard_interface,
2151 wl_resource_get_version(resource), id);
Kristian Høgsberg0ff79082013-08-06 16:46:25 -07002152 if (cr == NULL) {
2153 wl_client_post_no_memory(client);
2154 return;
2155 }
2156
Neil Roberts96d790e2013-09-19 17:32:00 +01002157 /* May be moved to focused list later by either
2158 * weston_keyboard_set_focus or directly if this client is already
2159 * focused */
Derek Foreman345c9f32015-06-03 15:53:28 -05002160 wl_list_insert(&keyboard->resource_list, wl_resource_get_link(cr));
Kristian Høgsberg69e25fc2013-08-13 20:11:02 +01002161 wl_resource_set_implementation(cr, &keyboard_interface,
2162 seat, unbind_resource);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002163
Jonny Lamb66a41a02014-08-12 14:58:25 +02002164 if (wl_resource_get_version(cr) >= WL_KEYBOARD_REPEAT_INFO_SINCE_VERSION) {
2165 wl_keyboard_send_repeat_info(cr,
2166 seat->compositor->kb_repeat_rate,
2167 seat->compositor->kb_repeat_delay);
2168 }
Jasper St. Pierred8c6aeb2014-08-04 13:43:24 -04002169
Matt Roper01a92732013-06-24 16:52:44 +01002170 if (seat->compositor->use_xkbcommon) {
2171 wl_keyboard_send_keymap(cr, WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1,
Jonas Ådahl7395ea02013-12-03 09:14:26 +01002172 keyboard->xkb_info->keymap_fd,
2173 keyboard->xkb_info->keymap_size);
Matt Roper01a92732013-06-24 16:52:44 +01002174 } else {
2175 int null_fd = open("/dev/null", O_RDONLY);
2176 wl_keyboard_send_keymap(cr, WL_KEYBOARD_KEYMAP_FORMAT_NO_KEYMAP,
2177 null_fd,
2178 0);
2179 close(null_fd);
2180 }
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002181
Neil Roberts96d790e2013-09-19 17:32:00 +01002182 if (should_send_modifiers_to_client(seat, client)) {
Derek Foreman345c9f32015-06-03 15:53:28 -05002183 send_modifiers_to_resource(keyboard,
Neil Roberts96d790e2013-09-19 17:32:00 +01002184 cr,
Derek Foreman345c9f32015-06-03 15:53:28 -05002185 keyboard->focus_serial);
Neil Roberts96d790e2013-09-19 17:32:00 +01002186 }
2187
Derek Foreman345c9f32015-06-03 15:53:28 -05002188 if (keyboard->focus && keyboard->focus->resource &&
2189 wl_resource_get_client(keyboard->focus->resource) == client) {
Neil Roberts96d790e2013-09-19 17:32:00 +01002190 struct weston_surface *surface =
Derek Foreman345c9f32015-06-03 15:53:28 -05002191 (struct weston_surface *)keyboard->focus;
Neil Roberts96d790e2013-09-19 17:32:00 +01002192
2193 wl_list_remove(wl_resource_get_link(cr));
Derek Foreman345c9f32015-06-03 15:53:28 -05002194 wl_list_insert(&keyboard->focus_resource_list,
Neil Roberts96d790e2013-09-19 17:32:00 +01002195 wl_resource_get_link(cr));
2196 wl_keyboard_send_enter(cr,
Derek Foreman345c9f32015-06-03 15:53:28 -05002197 keyboard->focus_serial,
Neil Roberts96d790e2013-09-19 17:32:00 +01002198 surface->resource,
Derek Foreman345c9f32015-06-03 15:53:28 -05002199 &keyboard->keys);
Neil Roberts96d790e2013-09-19 17:32:00 +01002200
2201 /* If this is the first keyboard resource for this
2202 * client... */
Derek Foreman345c9f32015-06-03 15:53:28 -05002203 if (keyboard->focus_resource_list.prev ==
Neil Roberts96d790e2013-09-19 17:32:00 +01002204 wl_resource_get_link(cr))
2205 wl_data_device_set_keyboard_focus(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002206 }
2207}
2208
2209static void
Kristian Høgsberg69e25fc2013-08-13 20:11:02 +01002210touch_release(struct wl_client *client, struct wl_resource *resource)
2211{
2212 wl_resource_destroy(resource);
2213}
2214
2215static const struct wl_touch_interface touch_interface = {
2216 touch_release
2217};
2218
2219static void
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002220seat_get_touch(struct wl_client *client, struct wl_resource *resource,
2221 uint32_t id)
2222{
Jason Ekstrand44a38632013-06-14 10:08:00 -05002223 struct weston_seat *seat = wl_resource_get_user_data(resource);
Derek Foreman1281a362015-07-31 16:55:32 -05002224 /* We use the touch_state directly, which means we'll
2225 * give a wl_touch if the seat has ever had one - even though
2226 * the spec explicitly states that this request only takes effect
2227 * if the seat has the touch capability.
2228 *
2229 * This prevents a race between the compositor sending new
2230 * capabilities and the client trying to use the old ones.
2231 */
2232 struct weston_touch *touch = seat->touch_state;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002233 struct wl_resource *cr;
2234
Derek Foreman1281a362015-07-31 16:55:32 -05002235 if (!touch)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002236 return;
2237
Jason Ekstranda85118c2013-06-27 20:17:02 -05002238 cr = wl_resource_create(client, &wl_touch_interface,
2239 wl_resource_get_version(resource), id);
Kristian Høgsberg0ff79082013-08-06 16:46:25 -07002240 if (cr == NULL) {
2241 wl_client_post_no_memory(client);
2242 return;
2243 }
2244
Derek Foreman1281a362015-07-31 16:55:32 -05002245 if (touch->focus &&
2246 wl_resource_get_client(touch->focus->surface->resource) == client) {
Chokshi, Mituld6697142015-10-09 08:28:47 +00002247 wl_list_insert(&touch->focus_resource_list,
Neil Roberts96d790e2013-09-19 17:32:00 +01002248 wl_resource_get_link(cr));
2249 } else {
Chokshi, Mituld6697142015-10-09 08:28:47 +00002250 wl_list_insert(&touch->resource_list,
Neil Roberts96d790e2013-09-19 17:32:00 +01002251 wl_resource_get_link(cr));
2252 }
Kristian Høgsberg69e25fc2013-08-13 20:11:02 +01002253 wl_resource_set_implementation(cr, &touch_interface,
2254 seat, unbind_resource);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002255}
2256
Quentin Glidicaab1d362016-03-13 17:49:08 +01002257static void
2258seat_release(struct wl_client *client, struct wl_resource *resource)
2259{
2260 wl_resource_destroy(resource);
2261}
2262
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002263static const struct wl_seat_interface seat_interface = {
2264 seat_get_pointer,
2265 seat_get_keyboard,
2266 seat_get_touch,
Quentin Glidicaab1d362016-03-13 17:49:08 +01002267 seat_release,
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002268};
2269
2270static void
2271bind_seat(struct wl_client *client, void *data, uint32_t version, uint32_t id)
2272{
Kristian Høgsberge3148752013-05-06 23:19:49 -04002273 struct weston_seat *seat = data;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002274 struct wl_resource *resource;
2275 enum wl_seat_capability caps = 0;
2276
Jason Ekstranda85118c2013-06-27 20:17:02 -05002277 resource = wl_resource_create(client,
Derek Foreman1909c102015-11-26 14:17:47 -06002278 &wl_seat_interface, version, id);
Jason Ekstrand44a38632013-06-14 10:08:00 -05002279 wl_list_insert(&seat->base_resource_list, wl_resource_get_link(resource));
Jason Ekstranda85118c2013-06-27 20:17:02 -05002280 wl_resource_set_implementation(resource, &seat_interface, data,
2281 unbind_resource);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002282
Derek Foreman1281a362015-07-31 16:55:32 -05002283 if (weston_seat_get_pointer(seat))
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002284 caps |= WL_SEAT_CAPABILITY_POINTER;
Derek Foreman1281a362015-07-31 16:55:32 -05002285 if (weston_seat_get_keyboard(seat))
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002286 caps |= WL_SEAT_CAPABILITY_KEYBOARD;
Derek Foreman1281a362015-07-31 16:55:32 -05002287 if (weston_seat_get_touch(seat))
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002288 caps |= WL_SEAT_CAPABILITY_TOUCH;
2289
2290 wl_seat_send_capabilities(resource, caps);
Jasper St. Pierre0013a292014-08-07 16:43:11 -04002291 if (version >= WL_SEAT_NAME_SINCE_VERSION)
Rob Bradforde445ae62013-05-31 18:09:51 +01002292 wl_seat_send_name(resource, seat->seat_name);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002293}
2294
Rob Bradford382ff462013-06-24 16:52:45 +01002295#ifdef ENABLE_XKBCOMMON
Giulio Camuffo0358af42016-06-02 21:48:08 +03002296WL_EXPORT int
2297weston_compositor_set_xkb_rule_names(struct weston_compositor *ec,
2298 struct xkb_rule_names *names)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002299{
Rob Bradford382ff462013-06-24 16:52:45 +01002300 ec->use_xkbcommon = 1;
Matt Roper01a92732013-06-24 16:52:44 +01002301
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002302 if (ec->xkb_context == NULL) {
2303 ec->xkb_context = xkb_context_new(0);
2304 if (ec->xkb_context == NULL) {
2305 weston_log("failed to create XKB context\n");
2306 return -1;
2307 }
2308 }
2309
2310 if (names)
2311 ec->xkb_names = *names;
2312 if (!ec->xkb_names.rules)
2313 ec->xkb_names.rules = strdup("evdev");
2314 if (!ec->xkb_names.model)
2315 ec->xkb_names.model = strdup("pc105");
2316 if (!ec->xkb_names.layout)
2317 ec->xkb_names.layout = strdup("us");
2318
2319 return 0;
2320}
2321
Stefan Schmidtfda26522013-09-17 10:54:09 +01002322static void
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00002323weston_xkb_info_destroy(struct weston_xkb_info *xkb_info)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002324{
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00002325 if (--xkb_info->ref_count > 0)
2326 return;
2327
Ran Benitac9c74152014-08-19 23:59:52 +03002328 xkb_keymap_unref(xkb_info->keymap);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002329
2330 if (xkb_info->keymap_area)
2331 munmap(xkb_info->keymap_area, xkb_info->keymap_size);
2332 if (xkb_info->keymap_fd >= 0)
2333 close(xkb_info->keymap_fd);
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00002334 free(xkb_info);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002335}
2336
2337void
2338weston_compositor_xkb_destroy(struct weston_compositor *ec)
2339{
Matt Roper01a92732013-06-24 16:52:44 +01002340 /*
2341 * If we're operating in raw keyboard mode, we never initialized
2342 * libxkbcommon so there's no cleanup to do either.
2343 */
2344 if (!ec->use_xkbcommon)
2345 return;
2346
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002347 free((char *) ec->xkb_names.rules);
2348 free((char *) ec->xkb_names.model);
2349 free((char *) ec->xkb_names.layout);
2350 free((char *) ec->xkb_names.variant);
2351 free((char *) ec->xkb_names.options);
Stefan Schmidtfda26522013-09-17 10:54:09 +01002352
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00002353 if (ec->xkb_info)
2354 weston_xkb_info_destroy(ec->xkb_info);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002355 xkb_context_unref(ec->xkb_context);
2356}
2357
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00002358static struct weston_xkb_info *
2359weston_xkb_info_create(struct xkb_keymap *keymap)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002360{
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00002361 struct weston_xkb_info *xkb_info = zalloc(sizeof *xkb_info);
2362 if (xkb_info == NULL)
2363 return NULL;
2364
Ran Benita2e1968f2014-08-19 23:59:51 +03002365 xkb_info->keymap = xkb_keymap_ref(keymap);
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00002366 xkb_info->ref_count = 1;
2367
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002368 char *keymap_str;
2369
Ran Benita2e1968f2014-08-19 23:59:51 +03002370 xkb_info->shift_mod = xkb_keymap_mod_get_index(xkb_info->keymap,
2371 XKB_MOD_NAME_SHIFT);
2372 xkb_info->caps_mod = xkb_keymap_mod_get_index(xkb_info->keymap,
2373 XKB_MOD_NAME_CAPS);
2374 xkb_info->ctrl_mod = xkb_keymap_mod_get_index(xkb_info->keymap,
2375 XKB_MOD_NAME_CTRL);
2376 xkb_info->alt_mod = xkb_keymap_mod_get_index(xkb_info->keymap,
2377 XKB_MOD_NAME_ALT);
2378 xkb_info->mod2_mod = xkb_keymap_mod_get_index(xkb_info->keymap,
2379 "Mod2");
2380 xkb_info->mod3_mod = xkb_keymap_mod_get_index(xkb_info->keymap,
2381 "Mod3");
2382 xkb_info->super_mod = xkb_keymap_mod_get_index(xkb_info->keymap,
2383 XKB_MOD_NAME_LOGO);
2384 xkb_info->mod5_mod = xkb_keymap_mod_get_index(xkb_info->keymap,
2385 "Mod5");
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002386
Ran Benita2e1968f2014-08-19 23:59:51 +03002387 xkb_info->num_led = xkb_keymap_led_get_index(xkb_info->keymap,
2388 XKB_LED_NAME_NUM);
2389 xkb_info->caps_led = xkb_keymap_led_get_index(xkb_info->keymap,
2390 XKB_LED_NAME_CAPS);
2391 xkb_info->scroll_led = xkb_keymap_led_get_index(xkb_info->keymap,
2392 XKB_LED_NAME_SCROLL);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002393
Ran Benita2e1968f2014-08-19 23:59:51 +03002394 keymap_str = xkb_keymap_get_as_string(xkb_info->keymap,
2395 XKB_KEYMAP_FORMAT_TEXT_V1);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002396 if (keymap_str == NULL) {
2397 weston_log("failed to get string version of keymap\n");
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00002398 goto err_keymap;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002399 }
2400 xkb_info->keymap_size = strlen(keymap_str) + 1;
2401
2402 xkb_info->keymap_fd = os_create_anonymous_file(xkb_info->keymap_size);
2403 if (xkb_info->keymap_fd < 0) {
2404 weston_log("creating a keymap file for %lu bytes failed: %m\n",
2405 (unsigned long) xkb_info->keymap_size);
2406 goto err_keymap_str;
2407 }
2408
2409 xkb_info->keymap_area = mmap(NULL, xkb_info->keymap_size,
2410 PROT_READ | PROT_WRITE,
2411 MAP_SHARED, xkb_info->keymap_fd, 0);
2412 if (xkb_info->keymap_area == MAP_FAILED) {
2413 weston_log("failed to mmap() %lu bytes\n",
2414 (unsigned long) xkb_info->keymap_size);
2415 goto err_dev_zero;
2416 }
2417 strcpy(xkb_info->keymap_area, keymap_str);
2418 free(keymap_str);
2419
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00002420 return xkb_info;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002421
2422err_dev_zero:
2423 close(xkb_info->keymap_fd);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002424err_keymap_str:
2425 free(keymap_str);
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00002426err_keymap:
Ran Benita2e1968f2014-08-19 23:59:51 +03002427 xkb_keymap_unref(xkb_info->keymap);
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00002428 free(xkb_info);
2429 return NULL;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002430}
2431
2432static int
2433weston_compositor_build_global_keymap(struct weston_compositor *ec)
2434{
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00002435 struct xkb_keymap *keymap;
2436
2437 if (ec->xkb_info != NULL)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002438 return 0;
2439
Ran Benita2e1968f2014-08-19 23:59:51 +03002440 keymap = xkb_keymap_new_from_names(ec->xkb_context,
2441 &ec->xkb_names,
2442 0);
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00002443 if (keymap == NULL) {
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002444 weston_log("failed to compile global XKB keymap\n");
2445 weston_log(" tried rules %s, model %s, layout %s, variant %s, "
2446 "options %s\n",
2447 ec->xkb_names.rules, ec->xkb_names.model,
2448 ec->xkb_names.layout, ec->xkb_names.variant,
2449 ec->xkb_names.options);
2450 return -1;
2451 }
2452
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00002453 ec->xkb_info = weston_xkb_info_create(keymap);
Rui Matos73d93952013-10-24 19:28:41 +02002454 xkb_keymap_unref(keymap);
Stefan Schmidtfda26522013-09-17 10:54:09 +01002455 if (ec->xkb_info == NULL)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002456 return -1;
2457
2458 return 0;
2459}
Rob Bradford382ff462013-06-24 16:52:45 +01002460#else
Giulio Camuffo0358af42016-06-02 21:48:08 +03002461WL_EXPORT int
2462weston_compositor_set_xkb_rule_names(struct weston_compositor *ec,
2463 struct xkb_rule_names *names)
Rob Bradford382ff462013-06-24 16:52:45 +01002464{
2465 return 0;
2466}
2467
2468void
2469weston_compositor_xkb_destroy(struct weston_compositor *ec)
2470{
2471}
2472#endif
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002473
Rui Matos65196bc2013-10-10 19:44:19 +02002474WL_EXPORT void
2475weston_seat_update_keymap(struct weston_seat *seat, struct xkb_keymap *keymap)
2476{
Derek Foreman1281a362015-07-31 16:55:32 -05002477 struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
2478
2479 if (!keyboard || !keymap)
Rui Matos65196bc2013-10-10 19:44:19 +02002480 return;
2481
2482#ifdef ENABLE_XKBCOMMON
2483 if (!seat->compositor->use_xkbcommon)
2484 return;
2485
Derek Foreman1281a362015-07-31 16:55:32 -05002486 xkb_keymap_unref(keyboard->pending_keymap);
2487 keyboard->pending_keymap = xkb_keymap_ref(keymap);
Rui Matos65196bc2013-10-10 19:44:19 +02002488
Derek Foreman1281a362015-07-31 16:55:32 -05002489 if (keyboard->keys.size == 0)
Rui Matos65196bc2013-10-10 19:44:19 +02002490 update_keymap(seat);
2491#endif
2492}
2493
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002494WL_EXPORT int
2495weston_seat_init_keyboard(struct weston_seat *seat, struct xkb_keymap *keymap)
2496{
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04002497 struct weston_keyboard *keyboard;
2498
Derek Foreman1281a362015-07-31 16:55:32 -05002499 if (seat->keyboard_state) {
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002500 seat->keyboard_device_count += 1;
2501 if (seat->keyboard_device_count == 1)
2502 seat_send_updated_caps(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002503 return 0;
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002504 }
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002505
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04002506 keyboard = weston_keyboard_create();
2507 if (keyboard == NULL) {
2508 weston_log("failed to allocate weston keyboard struct\n");
2509 return -1;
2510 }
2511
Jonas Ådahl7395ea02013-12-03 09:14:26 +01002512#ifdef ENABLE_XKBCOMMON
2513 if (seat->compositor->use_xkbcommon) {
2514 if (keymap != NULL) {
2515 keyboard->xkb_info = weston_xkb_info_create(keymap);
2516 if (keyboard->xkb_info == NULL)
Ander Conselvan de Oliveira4d363cf2014-01-31 17:35:45 +02002517 goto err;
Jonas Ådahl7395ea02013-12-03 09:14:26 +01002518 } else {
2519 if (weston_compositor_build_global_keymap(seat->compositor) < 0)
Ander Conselvan de Oliveira4d363cf2014-01-31 17:35:45 +02002520 goto err;
Jonas Ådahl7395ea02013-12-03 09:14:26 +01002521 keyboard->xkb_info = seat->compositor->xkb_info;
2522 keyboard->xkb_info->ref_count++;
2523 }
2524
2525 keyboard->xkb_state.state = xkb_state_new(keyboard->xkb_info->keymap);
2526 if (keyboard->xkb_state.state == NULL) {
2527 weston_log("failed to initialise XKB state\n");
Ander Conselvan de Oliveira4d363cf2014-01-31 17:35:45 +02002528 goto err;
Jonas Ådahl7395ea02013-12-03 09:14:26 +01002529 }
2530
2531 keyboard->xkb_state.leds = 0;
2532 }
2533#endif
2534
Derek Foreman1281a362015-07-31 16:55:32 -05002535 seat->keyboard_state = keyboard;
Ander Conselvan de Oliveira4d363cf2014-01-31 17:35:45 +02002536 seat->keyboard_device_count = 1;
2537 keyboard->seat = seat;
2538
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04002539 seat_send_updated_caps(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002540
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002541 return 0;
Ander Conselvan de Oliveira4d363cf2014-01-31 17:35:45 +02002542
2543err:
2544 if (keyboard->xkb_info)
2545 weston_xkb_info_destroy(keyboard->xkb_info);
2546 free(keyboard);
2547
2548 return -1;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002549}
2550
Jonas Ådahl91fed542013-12-03 09:14:27 +01002551static void
2552weston_keyboard_reset_state(struct weston_keyboard *keyboard)
2553{
2554 struct weston_seat *seat = keyboard->seat;
2555 struct xkb_state *state;
2556
2557#ifdef ENABLE_XKBCOMMON
2558 if (seat->compositor->use_xkbcommon) {
2559 state = xkb_state_new(keyboard->xkb_info->keymap);
2560 if (!state) {
2561 weston_log("failed to reset XKB state\n");
2562 return;
2563 }
2564 xkb_state_unref(keyboard->xkb_state.state);
2565 keyboard->xkb_state.state = state;
2566
2567 keyboard->xkb_state.leds = 0;
2568 }
2569#endif
2570
2571 seat->modifier_state = 0;
2572}
2573
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002574WL_EXPORT void
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002575weston_seat_release_keyboard(struct weston_seat *seat)
2576{
2577 seat->keyboard_device_count--;
Derek Foremand621df22014-11-19 11:04:12 -06002578 assert(seat->keyboard_device_count >= 0);
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002579 if (seat->keyboard_device_count == 0) {
Derek Foreman1281a362015-07-31 16:55:32 -05002580 weston_keyboard_set_focus(seat->keyboard_state, NULL);
2581 weston_keyboard_cancel_grab(seat->keyboard_state);
2582 weston_keyboard_reset_state(seat->keyboard_state);
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002583 seat_send_updated_caps(seat);
2584 }
2585}
2586
2587WL_EXPORT void
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002588weston_seat_init_pointer(struct weston_seat *seat)
2589{
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04002590 struct weston_pointer *pointer;
2591
Derek Foreman1281a362015-07-31 16:55:32 -05002592 if (seat->pointer_state) {
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002593 seat->pointer_device_count += 1;
2594 if (seat->pointer_device_count == 1)
2595 seat_send_updated_caps(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002596 return;
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002597 }
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002598
Giulio Camuffocdb4d292013-11-14 23:42:53 +01002599 pointer = weston_pointer_create(seat);
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04002600 if (pointer == NULL)
2601 return;
2602
Derek Foreman1281a362015-07-31 16:55:32 -05002603 seat->pointer_state = pointer;
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002604 seat->pointer_device_count = 1;
2605 pointer->seat = seat;
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04002606
2607 seat_send_updated_caps(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002608}
2609
2610WL_EXPORT void
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002611weston_seat_release_pointer(struct weston_seat *seat)
2612{
Derek Foreman1281a362015-07-31 16:55:32 -05002613 struct weston_pointer *pointer = seat->pointer_state;
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002614
2615 seat->pointer_device_count--;
2616 if (seat->pointer_device_count == 0) {
Derek Foremanf9318d12015-05-11 15:40:11 -05002617 weston_pointer_clear_focus(pointer);
Jonas Ådahl1ea343e2013-10-25 23:18:05 +02002618 weston_pointer_cancel_grab(pointer);
Jonas Ådahl630bae82013-10-17 23:04:06 +02002619
Jonas Ådahla4932742013-10-17 23:04:07 +02002620 if (pointer->sprite)
2621 pointer_unmap_sprite(pointer);
2622
Jonas Ådahl3e12e632013-12-02 22:05:05 +01002623 weston_pointer_reset_state(pointer);
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002624 seat_send_updated_caps(seat);
Derek Foremanfd5ca512015-01-07 15:00:25 -06002625
2626 /* seat->pointer is intentionally not destroyed so that
2627 * a newly attached pointer on this seat will retain
2628 * the previous cursor co-ordinates.
2629 */
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002630 }
2631}
2632
2633WL_EXPORT void
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002634weston_seat_init_touch(struct weston_seat *seat)
2635{
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04002636 struct weston_touch *touch;
2637
Derek Foreman1281a362015-07-31 16:55:32 -05002638 if (seat->touch_state) {
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002639 seat->touch_device_count += 1;
2640 if (seat->touch_device_count == 1)
2641 seat_send_updated_caps(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002642 return;
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002643 }
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002644
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04002645 touch = weston_touch_create();
2646 if (touch == NULL)
2647 return;
2648
Derek Foreman1281a362015-07-31 16:55:32 -05002649 seat->touch_state = touch;
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002650 seat->touch_device_count = 1;
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04002651 touch->seat = seat;
2652
2653 seat_send_updated_caps(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002654}
2655
2656WL_EXPORT void
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002657weston_seat_release_touch(struct weston_seat *seat)
2658{
2659 seat->touch_device_count--;
2660 if (seat->touch_device_count == 0) {
Derek Foreman1281a362015-07-31 16:55:32 -05002661 weston_touch_set_focus(seat->touch_state, NULL);
2662 weston_touch_cancel_grab(seat->touch_state);
2663 weston_touch_reset_state(seat->touch_state);
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002664 seat_send_updated_caps(seat);
2665 }
2666}
2667
2668WL_EXPORT void
Rob Bradford9af5f9e2013-05-31 18:09:50 +01002669weston_seat_init(struct weston_seat *seat, struct weston_compositor *ec,
2670 const char *seat_name)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002671{
Kristian Høgsberg4a2a2742013-05-06 22:24:50 -04002672 memset(seat, 0, sizeof *seat);
2673
Kristian Høgsberge3148752013-05-06 23:19:49 -04002674 seat->selection_data_source = NULL;
2675 wl_list_init(&seat->base_resource_list);
2676 wl_signal_init(&seat->selection_signal);
2677 wl_list_init(&seat->drag_resource_list);
Kristian Høgsberge3148752013-05-06 23:19:49 -04002678 wl_signal_init(&seat->destroy_signal);
Jason Ekstranda4ab5422014-04-02 19:53:45 -05002679 wl_signal_init(&seat->updated_caps_signal);
Kristian Høgsberg4a2a2742013-05-06 22:24:50 -04002680
Peter Hutterer87743e92016-01-18 16:38:22 +10002681 seat->global = wl_global_create(ec->wl_display, &wl_seat_interface, 5,
Kristian Høgsberg919cddb2013-07-08 19:03:57 -04002682 seat, bind_seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002683
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002684 seat->compositor = ec;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002685 seat->modifier_state = 0;
Rob Bradford9af5f9e2013-05-31 18:09:50 +01002686 seat->seat_name = strdup(seat_name);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002687
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002688 wl_list_insert(ec->seat_list.prev, &seat->link);
2689
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002690 clipboard_create(seat);
2691
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002692 wl_signal_emit(&ec->seat_created_signal, seat);
2693}
2694
2695WL_EXPORT void
2696weston_seat_release(struct weston_seat *seat)
2697{
2698 wl_list_remove(&seat->link);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002699
Jonas Ådahl1afb2382014-01-03 19:46:51 +01002700 if (seat->saved_kbd_focus)
2701 wl_list_remove(&seat->saved_kbd_focus_listener.link);
2702
Derek Foreman1281a362015-07-31 16:55:32 -05002703 if (seat->pointer_state)
2704 weston_pointer_destroy(seat->pointer_state);
2705 if (seat->keyboard_state)
2706 weston_keyboard_destroy(seat->keyboard_state);
2707 if (seat->touch_state)
2708 weston_touch_destroy(seat->touch_state);
Kristian Høgsberg4a2a2742013-05-06 22:24:50 -04002709
Rob Bradford9af5f9e2013-05-31 18:09:50 +01002710 free (seat->seat_name);
2711
Kristian Høgsberg919cddb2013-07-08 19:03:57 -04002712 wl_global_destroy(seat->global);
Kristian Høgsbergaaadc772013-07-08 16:20:31 -04002713
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002714 wl_signal_emit(&seat->destroy_signal, seat);
2715}
Derek Foreman1281a362015-07-31 16:55:32 -05002716
2717/** Get a seat's keyboard pointer
2718 *
2719 * \param seat The seat to query
2720 * \return The seat's keyboard pointer, or NULL if no keyboard is present
2721 *
2722 * The keyboard pointer for a seat isn't freed when all keyboards are removed,
2723 * so it should only be used when the seat's keyboard_device_count is greater
2724 * than zero. This function does that test and only returns a pointer
2725 * when a keyboard is present.
2726 */
2727WL_EXPORT struct weston_keyboard *
2728weston_seat_get_keyboard(struct weston_seat *seat)
2729{
2730 if (!seat)
2731 return NULL;
2732
2733 if (seat->keyboard_device_count)
2734 return seat->keyboard_state;
2735
2736 return NULL;
2737}
2738
2739/** Get a seat's pointer pointer
2740 *
2741 * \param seat The seat to query
2742 * \return The seat's pointer pointer, or NULL if no pointer device is present
2743 *
2744 * The pointer pointer for a seat isn't freed when all mice are removed,
2745 * so it should only be used when the seat's pointer_device_count is greater
2746 * than zero. This function does that test and only returns a pointer
2747 * when a pointing device is present.
2748 */
2749WL_EXPORT struct weston_pointer *
2750weston_seat_get_pointer(struct weston_seat *seat)
2751{
2752 if (!seat)
2753 return NULL;
2754
2755 if (seat->pointer_device_count)
2756 return seat->pointer_state;
2757
2758 return NULL;
2759}
2760
2761/** Get a seat's touch pointer
2762 *
2763 * \param seat The seat to query
2764 * \return The seat's touch pointer, or NULL if no touch device is present
2765 *
2766 * The touch pointer for a seat isn't freed when all touch devices are removed,
2767 * so it should only be used when the seat's touch_device_count is greater
2768 * than zero. This function does that test and only returns a pointer
2769 * when a touch device is present.
2770 */
2771WL_EXPORT struct weston_touch *
2772weston_seat_get_touch(struct weston_seat *seat)
2773{
2774 if (!seat)
2775 return NULL;
2776
2777 if (seat->touch_device_count)
2778 return seat->touch_state;
2779
2780 return NULL;
2781}
Bryce Harrington24f917e2016-06-29 19:04:07 -07002782
2783/** Sets the keyboard focus to the given surface
2784 *
2785 * \param seat The seat to query
2786 */
2787WL_EXPORT void
2788weston_seat_set_keyboard_focus(struct weston_seat *seat,
2789 struct weston_surface *surface)
2790{
2791 struct weston_compositor *compositor = seat->compositor;
2792 struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
2793
Jonas Ådahlef8e1c32016-03-15 20:28:51 +08002794 if (keyboard && keyboard->focus != surface) {
Bryce Harrington24f917e2016-06-29 19:04:07 -07002795 weston_keyboard_set_focus(keyboard, surface);
2796 wl_data_device_set_keyboard_focus(seat);
2797 }
2798
Jonas Ådahl94e2e2d2014-10-18 18:42:19 +02002799 inc_activate_serial(compositor);
Bryce Harrington24f917e2016-06-29 19:04:07 -07002800 wl_signal_emit(&compositor->activate_signal, surface);
2801}