blob: 9382bb19557319a4717b08d09b37f231bc36917d [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;
Jonas Ådahl0336ca02014-10-04 16:28:29 +0200346 wl_resource_for_each(resource, resource_list)
Peter Hutterer89b6a492016-01-18 15:58:17 +1000347 wl_pointer_send_axis(resource, time,
348 event->axis, event->value);
Jonas Ådahl0336ca02014-10-04 16:28:29 +0200349}
350
351static void
352default_grab_pointer_axis(struct weston_pointer_grab *grab,
Peter Hutterer89b6a492016-01-18 15:58:17 +1000353 uint32_t time,
354 struct weston_pointer_axis_event *event)
Jonas Ådahl0336ca02014-10-04 16:28:29 +0200355{
Peter Hutterer89b6a492016-01-18 15:58:17 +1000356 weston_pointer_send_axis(grab->pointer, time, event);
Jonas Ådahl0336ca02014-10-04 16:28:29 +0200357}
358
Jonas Ådahl1ea343e2013-10-25 23:18:05 +0200359static void
360default_grab_pointer_cancel(struct weston_pointer_grab *grab)
361{
362}
363
Kristian Høgsberg02bbabb2013-05-06 22:15:05 -0400364static const struct weston_pointer_grab_interface
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400365 default_pointer_grab_interface = {
Kristian Høgsbergb27901c2013-10-28 15:32:02 -0700366 default_grab_pointer_focus,
367 default_grab_pointer_motion,
368 default_grab_pointer_button,
Jonas Ådahl0336ca02014-10-04 16:28:29 +0200369 default_grab_pointer_axis,
Jonas Ådahl1ea343e2013-10-25 23:18:05 +0200370 default_grab_pointer_cancel,
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400371};
372
Kristian Høgsberge329f362013-05-06 22:19:57 -0400373static void
374default_grab_touch_down(struct weston_touch_grab *grab, uint32_t time,
Giulio Camuffo61ed7b62015-07-08 11:55:28 +0300375 int touch_id, wl_fixed_t x, wl_fixed_t y)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400376{
Kristian Høgsberge329f362013-05-06 22:19:57 -0400377 struct weston_touch *touch = grab->touch;
Rob Bradford880ebc72013-07-22 17:31:38 +0100378 struct wl_display *display = touch->seat->compositor->wl_display;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400379 uint32_t serial;
Neil Roberts96d790e2013-09-19 17:32:00 +0100380 struct wl_resource *resource;
381 struct wl_list *resource_list;
Giulio Camuffo61ed7b62015-07-08 11:55:28 +0300382 wl_fixed_t sx, sy;
383
384 weston_view_from_global_fixed(touch->focus, x, y, &sx, &sy);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400385
Neil Roberts96d790e2013-09-19 17:32:00 +0100386 resource_list = &touch->focus_resource_list;
387
388 if (!wl_list_empty(resource_list) && touch->focus) {
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400389 serial = wl_display_next_serial(display);
Neil Roberts96d790e2013-09-19 17:32:00 +0100390 wl_resource_for_each(resource, resource_list)
391 wl_touch_send_down(resource, serial, time,
Jason Ekstranda7af7042013-10-12 22:38:11 -0500392 touch->focus->surface->resource,
Neil Roberts96d790e2013-09-19 17:32:00 +0100393 touch_id, sx, sy);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400394 }
395}
396
Kristian Høgsberge329f362013-05-06 22:19:57 -0400397static void
398default_grab_touch_up(struct weston_touch_grab *grab,
399 uint32_t time, int touch_id)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400400{
Kristian Høgsberge329f362013-05-06 22:19:57 -0400401 struct weston_touch *touch = grab->touch;
Rob Bradford880ebc72013-07-22 17:31:38 +0100402 struct wl_display *display = touch->seat->compositor->wl_display;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400403 uint32_t serial;
Neil Roberts96d790e2013-09-19 17:32:00 +0100404 struct wl_resource *resource;
405 struct wl_list *resource_list;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400406
Neil Roberts96d790e2013-09-19 17:32:00 +0100407 resource_list = &touch->focus_resource_list;
408
409 if (!wl_list_empty(resource_list)) {
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400410 serial = wl_display_next_serial(display);
Neil Roberts96d790e2013-09-19 17:32:00 +0100411 wl_resource_for_each(resource, resource_list)
412 wl_touch_send_up(resource, serial, time, touch_id);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400413 }
414}
415
Kristian Høgsberge329f362013-05-06 22:19:57 -0400416static void
417default_grab_touch_motion(struct weston_touch_grab *grab, uint32_t time,
Giulio Camuffo61ed7b62015-07-08 11:55:28 +0300418 int touch_id, wl_fixed_t x, wl_fixed_t y)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400419{
Kristian Høgsberge329f362013-05-06 22:19:57 -0400420 struct weston_touch *touch = grab->touch;
Neil Roberts96d790e2013-09-19 17:32:00 +0100421 struct wl_resource *resource;
422 struct wl_list *resource_list;
Giulio Camuffo61ed7b62015-07-08 11:55:28 +0300423 wl_fixed_t sx, sy;
424
425 weston_view_from_global_fixed(touch->focus, x, y, &sx, &sy);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400426
Neil Roberts96d790e2013-09-19 17:32:00 +0100427 resource_list = &touch->focus_resource_list;
428
429 wl_resource_for_each(resource, resource_list) {
430 wl_touch_send_motion(resource, time,
Kristian Høgsberge329f362013-05-06 22:19:57 -0400431 touch_id, sx, sy);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400432 }
433}
434
Jonas Ådahl1ea343e2013-10-25 23:18:05 +0200435static void
Jonas Ådahl1679f232014-04-12 09:39:51 +0200436default_grab_touch_frame(struct weston_touch_grab *grab)
437{
438 struct wl_resource *resource;
439
440 wl_resource_for_each(resource, &grab->touch->focus_resource_list)
441 wl_touch_send_frame(resource);
442}
443
444static void
Jonas Ådahl1ea343e2013-10-25 23:18:05 +0200445default_grab_touch_cancel(struct weston_touch_grab *grab)
446{
447}
448
Kristian Høgsberge329f362013-05-06 22:19:57 -0400449static const struct weston_touch_grab_interface default_touch_grab_interface = {
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400450 default_grab_touch_down,
451 default_grab_touch_up,
Jonas Ådahl1ea343e2013-10-25 23:18:05 +0200452 default_grab_touch_motion,
Jonas Ådahl1679f232014-04-12 09:39:51 +0200453 default_grab_touch_frame,
Jonas Ådahl1ea343e2013-10-25 23:18:05 +0200454 default_grab_touch_cancel,
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400455};
456
457static void
Kristian Høgsbergb27901c2013-10-28 15:32:02 -0700458default_grab_keyboard_key(struct weston_keyboard_grab *grab,
459 uint32_t time, uint32_t key, uint32_t state)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400460{
Kristian Høgsberg29139d42013-04-18 15:25:39 -0400461 struct weston_keyboard *keyboard = grab->keyboard;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400462 struct wl_resource *resource;
Rob Bradford880ebc72013-07-22 17:31:38 +0100463 struct wl_display *display = keyboard->seat->compositor->wl_display;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400464 uint32_t serial;
Neil Roberts96d790e2013-09-19 17:32:00 +0100465 struct wl_list *resource_list;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400466
Neil Roberts96d790e2013-09-19 17:32:00 +0100467 resource_list = &keyboard->focus_resource_list;
468 if (!wl_list_empty(resource_list)) {
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400469 serial = wl_display_next_serial(display);
Neil Roberts96d790e2013-09-19 17:32:00 +0100470 wl_resource_for_each(resource, resource_list)
471 wl_keyboard_send_key(resource,
472 serial,
473 time,
474 key,
475 state);
476 }
477}
478
479static void
480send_modifiers_to_resource(struct weston_keyboard *keyboard,
481 struct wl_resource *resource,
482 uint32_t serial)
483{
484 wl_keyboard_send_modifiers(resource,
485 serial,
486 keyboard->modifiers.mods_depressed,
487 keyboard->modifiers.mods_latched,
488 keyboard->modifiers.mods_locked,
489 keyboard->modifiers.group);
490}
491
492static void
493send_modifiers_to_client_in_list(struct wl_client *client,
494 struct wl_list *list,
495 uint32_t serial,
496 struct weston_keyboard *keyboard)
497{
498 struct wl_resource *resource;
499
500 wl_resource_for_each(resource, list) {
501 if (wl_resource_get_client(resource) == client)
502 send_modifiers_to_resource(keyboard,
503 resource,
504 serial);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400505 }
506}
507
Jonas Ådahl2cbf2932015-07-22 12:05:38 +0800508static struct weston_pointer_client *
509find_pointer_client_for_surface(struct weston_pointer *pointer,
510 struct weston_surface *surface)
511{
512 struct wl_client *client;
513
514 if (!surface)
515 return NULL;
516
517 if (!surface->resource)
518 return NULL;
519
520 client = wl_resource_get_client(surface->resource);
521 return weston_pointer_get_pointer_client(pointer, client);
522}
523
524static struct weston_pointer_client *
525find_pointer_client_for_view(struct weston_pointer *pointer, struct weston_view *view)
526{
527 if (!view)
528 return NULL;
529
530 return find_pointer_client_for_surface(pointer, view->surface);
531}
532
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400533static struct wl_resource *
Kristian Høgsbergfe7aa902013-05-08 09:54:37 -0400534find_resource_for_surface(struct wl_list *list, struct weston_surface *surface)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400535{
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400536 if (!surface)
537 return NULL;
538
Jason Ekstrand44a38632013-06-14 10:08:00 -0500539 if (!surface->resource)
540 return NULL;
Stefan Schmidtfda26522013-09-17 10:54:09 +0100541
Jason Ekstrand44a38632013-06-14 10:08:00 -0500542 return wl_resource_find_for_client(list, wl_resource_get_client(surface->resource));
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400543}
544
545static void
Kristian Høgsbergb27901c2013-10-28 15:32:02 -0700546default_grab_keyboard_modifiers(struct weston_keyboard_grab *grab,
547 uint32_t serial, uint32_t mods_depressed,
548 uint32_t mods_latched,
549 uint32_t mods_locked, uint32_t group)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400550{
Kristian Høgsberg29139d42013-04-18 15:25:39 -0400551 struct weston_keyboard *keyboard = grab->keyboard;
Derek Foreman1281a362015-07-31 16:55:32 -0500552 struct weston_pointer *pointer =
553 weston_seat_get_pointer(grab->keyboard->seat);
Neil Roberts96d790e2013-09-19 17:32:00 +0100554 struct wl_resource *resource;
555 struct wl_list *resource_list;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400556
Neil Roberts96d790e2013-09-19 17:32:00 +0100557 resource_list = &keyboard->focus_resource_list;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400558
Neil Roberts96d790e2013-09-19 17:32:00 +0100559 wl_resource_for_each(resource, resource_list) {
560 wl_keyboard_send_modifiers(resource, serial, mods_depressed,
561 mods_latched, mods_locked, group);
562 }
Jason Ekstrand42133d42013-11-14 20:06:16 -0600563 if (pointer && pointer->focus && pointer->focus->surface->resource &&
564 pointer->focus->surface != keyboard->focus) {
Neil Roberts96d790e2013-09-19 17:32:00 +0100565 struct wl_client *pointer_client =
Jason Ekstranda7af7042013-10-12 22:38:11 -0500566 wl_resource_get_client(pointer->focus->surface->resource);
Neil Roberts96d790e2013-09-19 17:32:00 +0100567 send_modifiers_to_client_in_list(pointer_client,
568 &keyboard->resource_list,
569 serial,
570 keyboard);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400571 }
572}
573
Jonas Ådahl1ea343e2013-10-25 23:18:05 +0200574static void
575default_grab_keyboard_cancel(struct weston_keyboard_grab *grab)
576{
577}
578
Kristian Høgsberg29139d42013-04-18 15:25:39 -0400579static const struct weston_keyboard_grab_interface
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400580 default_keyboard_grab_interface = {
Kristian Høgsbergb27901c2013-10-28 15:32:02 -0700581 default_grab_keyboard_key,
582 default_grab_keyboard_modifiers,
Jonas Ådahl1ea343e2013-10-25 23:18:05 +0200583 default_grab_keyboard_cancel,
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400584};
585
Kristian Høgsberg195b8692013-05-08 15:02:05 -0400586static void
587pointer_unmap_sprite(struct weston_pointer *pointer)
588{
Pekka Paalanenc557ff72014-11-12 16:42:52 +0200589 struct weston_surface *surface = pointer->sprite->surface;
590
591 if (weston_surface_is_mapped(surface))
592 weston_surface_unmap(surface);
Kristian Høgsberg195b8692013-05-08 15:02:05 -0400593
594 wl_list_remove(&pointer->sprite_destroy_listener.link);
Pekka Paalanenc557ff72014-11-12 16:42:52 +0200595 surface->configure = NULL;
596 surface->configure_private = NULL;
Pekka Paalanen8274d902014-08-06 19:36:51 +0300597 weston_surface_set_label_func(surface, NULL);
Jason Ekstranda7af7042013-10-12 22:38:11 -0500598 weston_view_destroy(pointer->sprite);
Kristian Høgsberg195b8692013-05-08 15:02:05 -0400599 pointer->sprite = NULL;
600}
601
602static void
603pointer_handle_sprite_destroy(struct wl_listener *listener, void *data)
604{
605 struct weston_pointer *pointer =
606 container_of(listener, struct weston_pointer,
607 sprite_destroy_listener);
608
609 pointer->sprite = NULL;
610}
611
Jonas Ådahl3e12e632013-12-02 22:05:05 +0100612static void
613weston_pointer_reset_state(struct weston_pointer *pointer)
614{
615 pointer->button_count = 0;
616}
617
Ander Conselvan de Oliveiraf84327a2014-01-29 18:47:51 +0200618static void
619weston_pointer_handle_output_destroy(struct wl_listener *listener, void *data);
620
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400621WL_EXPORT struct weston_pointer *
Giulio Camuffocdb4d292013-11-14 23:42:53 +0100622weston_pointer_create(struct weston_seat *seat)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400623{
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400624 struct weston_pointer *pointer;
625
Peter Huttererf3d62272013-08-08 11:57:05 +1000626 pointer = zalloc(sizeof *pointer);
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400627 if (pointer == NULL)
628 return NULL;
629
Jonas Ådahl2cbf2932015-07-22 12:05:38 +0800630 wl_list_init(&pointer->pointer_clients);
Giulio Camuffocdb4d292013-11-14 23:42:53 +0100631 weston_pointer_set_default_grab(pointer,
632 seat->compositor->default_pointer_grab);
Giulio Camuffo576fe2a2013-11-20 18:00:24 +0100633 wl_list_init(&pointer->focus_resource_listener.link);
634 pointer->focus_resource_listener.notify = pointer_focus_resource_destroyed;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400635 pointer->default_grab.pointer = pointer;
636 pointer->grab = &pointer->default_grab;
Giulio Camuffo6fcb3782013-11-14 23:42:50 +0100637 wl_signal_init(&pointer->motion_signal);
Emilio Pozuelo Monfortaa7a4762013-11-19 11:37:15 +0100638 wl_signal_init(&pointer->focus_signal);
Giulio Camuffo576fe2a2013-11-20 18:00:24 +0100639 wl_list_init(&pointer->focus_view_listener.link);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400640
Kristian Høgsberg195b8692013-05-08 15:02:05 -0400641 pointer->sprite_destroy_listener.notify = pointer_handle_sprite_destroy;
642
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400643 /* FIXME: Pick better co-ords. */
644 pointer->x = wl_fixed_from_int(100);
645 pointer->y = wl_fixed_from_int(100);
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400646
Ander Conselvan de Oliveiraf84327a2014-01-29 18:47:51 +0200647 pointer->output_destroy_listener.notify =
648 weston_pointer_handle_output_destroy;
649 wl_signal_add(&seat->compositor->output_destroyed_signal,
650 &pointer->output_destroy_listener);
651
Derek Foremanf9318d12015-05-11 15:40:11 -0500652 pointer->sx = wl_fixed_from_int(-1000000);
653 pointer->sy = wl_fixed_from_int(-1000000);
654
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400655 return pointer;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400656}
657
658WL_EXPORT void
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400659weston_pointer_destroy(struct weston_pointer *pointer)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400660{
Kristian Høgsberg195b8692013-05-08 15:02:05 -0400661 if (pointer->sprite)
662 pointer_unmap_sprite(pointer);
663
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400664 /* XXX: What about pointer->resource_list? */
Neil Roberts96d790e2013-09-19 17:32:00 +0100665
Giulio Camuffo576fe2a2013-11-20 18:00:24 +0100666 wl_list_remove(&pointer->focus_resource_listener.link);
667 wl_list_remove(&pointer->focus_view_listener.link);
Ander Conselvan de Oliveiraf84327a2014-01-29 18:47:51 +0200668 wl_list_remove(&pointer->output_destroy_listener.link);
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400669 free(pointer);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400670}
671
Giulio Camuffocdb4d292013-11-14 23:42:53 +0100672void
673weston_pointer_set_default_grab(struct weston_pointer *pointer,
674 const struct weston_pointer_grab_interface *interface)
675{
676 if (interface)
677 pointer->default_grab.interface = interface;
678 else
679 pointer->default_grab.interface =
680 &default_pointer_grab_interface;
681}
682
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400683WL_EXPORT struct weston_keyboard *
684weston_keyboard_create(void)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400685{
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400686 struct weston_keyboard *keyboard;
687
Peter Huttererf3d62272013-08-08 11:57:05 +1000688 keyboard = zalloc(sizeof *keyboard);
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400689 if (keyboard == NULL)
Neil Roberts96d790e2013-09-19 17:32:00 +0100690 return NULL;
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400691
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400692 wl_list_init(&keyboard->resource_list);
Neil Roberts96d790e2013-09-19 17:32:00 +0100693 wl_list_init(&keyboard->focus_resource_list);
Giulio Camuffo576fe2a2013-11-20 18:00:24 +0100694 wl_list_init(&keyboard->focus_resource_listener.link);
695 keyboard->focus_resource_listener.notify = keyboard_focus_resource_destroyed;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400696 wl_array_init(&keyboard->keys);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400697 keyboard->default_grab.interface = &default_keyboard_grab_interface;
698 keyboard->default_grab.keyboard = keyboard;
699 keyboard->grab = &keyboard->default_grab;
700 wl_signal_init(&keyboard->focus_signal);
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400701
702 return keyboard;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400703}
704
Jonas Ådahl7395ea02013-12-03 09:14:26 +0100705static void
706weston_xkb_info_destroy(struct weston_xkb_info *xkb_info);
707
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400708WL_EXPORT void
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400709weston_keyboard_destroy(struct weston_keyboard *keyboard)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400710{
711 /* XXX: What about keyboard->resource_list? */
Neil Roberts96d790e2013-09-19 17:32:00 +0100712
Jonas Ådahl7395ea02013-12-03 09:14:26 +0100713#ifdef ENABLE_XKBCOMMON
714 if (keyboard->seat->compositor->use_xkbcommon) {
Ran Benitac9c74152014-08-19 23:59:52 +0300715 xkb_state_unref(keyboard->xkb_state.state);
Jonas Ådahl7395ea02013-12-03 09:14:26 +0100716 if (keyboard->xkb_info)
717 weston_xkb_info_destroy(keyboard->xkb_info);
Ran Benitac9c74152014-08-19 23:59:52 +0300718 xkb_keymap_unref(keyboard->pending_keymap);
Jonas Ådahl7395ea02013-12-03 09:14:26 +0100719 }
720#endif
721
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400722 wl_array_release(&keyboard->keys);
Giulio Camuffo576fe2a2013-11-20 18:00:24 +0100723 wl_list_remove(&keyboard->focus_resource_listener.link);
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400724 free(keyboard);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400725}
726
Jonas Ådahlcbfa7f72013-12-02 22:05:04 +0100727static void
728weston_touch_reset_state(struct weston_touch *touch)
729{
730 touch->num_tp = 0;
731}
732
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400733WL_EXPORT struct weston_touch *
734weston_touch_create(void)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400735{
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400736 struct weston_touch *touch;
737
Peter Huttererf3d62272013-08-08 11:57:05 +1000738 touch = zalloc(sizeof *touch);
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400739 if (touch == NULL)
740 return NULL;
741
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400742 wl_list_init(&touch->resource_list);
Neil Roberts96d790e2013-09-19 17:32:00 +0100743 wl_list_init(&touch->focus_resource_list);
Giulio Camuffo576fe2a2013-11-20 18:00:24 +0100744 wl_list_init(&touch->focus_view_listener.link);
745 touch->focus_view_listener.notify = touch_focus_view_destroyed;
746 wl_list_init(&touch->focus_resource_listener.link);
747 touch->focus_resource_listener.notify = touch_focus_resource_destroyed;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400748 touch->default_grab.interface = &default_touch_grab_interface;
749 touch->default_grab.touch = touch;
750 touch->grab = &touch->default_grab;
751 wl_signal_init(&touch->focus_signal);
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400752
753 return touch;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400754}
755
756WL_EXPORT void
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400757weston_touch_destroy(struct weston_touch *touch)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400758{
759 /* XXX: What about touch->resource_list? */
Neil Roberts96d790e2013-09-19 17:32:00 +0100760
Giulio Camuffo576fe2a2013-11-20 18:00:24 +0100761 wl_list_remove(&touch->focus_view_listener.link);
762 wl_list_remove(&touch->focus_resource_listener.link);
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400763 free(touch);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400764}
765
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400766static void
Kristian Høgsberge3148752013-05-06 23:19:49 -0400767seat_send_updated_caps(struct weston_seat *seat)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400768{
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400769 enum wl_seat_capability caps = 0;
Rob Bradford6e737f52013-09-06 17:48:19 +0100770 struct wl_resource *resource;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400771
Jonas Ådahld6e1c342013-10-17 23:04:05 +0200772 if (seat->pointer_device_count > 0)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400773 caps |= WL_SEAT_CAPABILITY_POINTER;
Jonas Ådahld6e1c342013-10-17 23:04:05 +0200774 if (seat->keyboard_device_count > 0)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400775 caps |= WL_SEAT_CAPABILITY_KEYBOARD;
Jonas Ådahld6e1c342013-10-17 23:04:05 +0200776 if (seat->touch_device_count > 0)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400777 caps |= WL_SEAT_CAPABILITY_TOUCH;
778
Rob Bradford6e737f52013-09-06 17:48:19 +0100779 wl_resource_for_each(resource, &seat->base_resource_list) {
780 wl_seat_send_capabilities(resource, caps);
Jason Ekstrand44a38632013-06-14 10:08:00 -0500781 }
Jason Ekstranda4ab5422014-04-02 19:53:45 -0500782 wl_signal_emit(&seat->updated_caps_signal, seat);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400783}
784
Derek Foremanf9318d12015-05-11 15:40:11 -0500785
786/** Clear the pointer focus
787 *
788 * \param pointer the pointer to clear focus for.
789 *
790 * This can be used to unset pointer focus and set the co-ordinates to the
791 * arbitrary values we use for the no focus case.
792 *
793 * There's no requirement to use this function. For example, passing the
794 * results of a weston_compositor_pick_view() directly to
795 * weston_pointer_set_focus() will do the right thing when no view is found.
796 */
797WL_EXPORT void
798weston_pointer_clear_focus(struct weston_pointer *pointer)
799{
800 weston_pointer_set_focus(pointer, NULL,
801 wl_fixed_from_int(-1000000),
802 wl_fixed_from_int(-1000000));
803}
804
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400805WL_EXPORT void
Kristian Høgsberg02bbabb2013-05-06 22:15:05 -0400806weston_pointer_set_focus(struct weston_pointer *pointer,
Jason Ekstranda7af7042013-10-12 22:38:11 -0500807 struct weston_view *view,
Kristian Høgsberg02bbabb2013-05-06 22:15:05 -0400808 wl_fixed_t sx, wl_fixed_t sy)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400809{
Jonas Ådahl2cbf2932015-07-22 12:05:38 +0800810 struct weston_pointer_client *pointer_client;
Derek Foreman1281a362015-07-31 16:55:32 -0500811 struct weston_keyboard *kbd = weston_seat_get_keyboard(pointer->seat);
Neil Roberts96d790e2013-09-19 17:32:00 +0100812 struct wl_resource *resource;
Jonas Ådahl2cbf2932015-07-22 12:05:38 +0800813 struct wl_resource *surface_resource;
Rob Bradford880ebc72013-07-22 17:31:38 +0100814 struct wl_display *display = pointer->seat->compositor->wl_display;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400815 uint32_t serial;
Neil Roberts96d790e2013-09-19 17:32:00 +0100816 struct wl_list *focus_resource_list;
Kristian Høgsbergdb1fccb2014-02-05 17:14:42 -0800817 int refocus = 0;
Jason Ekstranda7af7042013-10-12 22:38:11 -0500818
819 if ((!pointer->focus && view) ||
820 (pointer->focus && !view) ||
Kristian Høgsbergdb1fccb2014-02-05 17:14:42 -0800821 (pointer->focus && pointer->focus->surface != view->surface) ||
822 pointer->sx != sx || pointer->sy != sy)
823 refocus = 1;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400824
Jonas Ådahl2cbf2932015-07-22 12:05:38 +0800825 if (pointer->focus_client && refocus) {
826 focus_resource_list = &pointer->focus_client->pointer_resources;
827 if (!wl_list_empty(focus_resource_list)) {
828 serial = wl_display_next_serial(display);
829 surface_resource = pointer->focus->surface->resource;
830 wl_resource_for_each(resource, focus_resource_list) {
831 wl_pointer_send_leave(resource, serial,
832 surface_resource);
833 }
Neil Roberts96d790e2013-09-19 17:32:00 +0100834 }
835
Jonas Ådahl2cbf2932015-07-22 12:05:38 +0800836 pointer->focus_client = NULL;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400837 }
838
Jonas Ådahl2cbf2932015-07-22 12:05:38 +0800839 pointer_client = find_pointer_client_for_view(pointer, view);
840 if (pointer_client && refocus) {
841 struct wl_client *surface_client = pointer_client->client;
Neil Roberts96d790e2013-09-19 17:32:00 +0100842
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400843 serial = wl_display_next_serial(display);
Neil Roberts96d790e2013-09-19 17:32:00 +0100844
Jason Ekstranda7af7042013-10-12 22:38:11 -0500845 if (kbd && kbd->focus != view->surface)
Kristian Høgsbergcb406f12013-10-09 10:54:03 -0700846 send_modifiers_to_client_in_list(surface_client,
847 &kbd->resource_list,
848 serial,
849 kbd);
850
Jonas Ådahl2cbf2932015-07-22 12:05:38 +0800851 pointer->focus_client = pointer_client;
Neil Roberts96d790e2013-09-19 17:32:00 +0100852
Jonas Ådahl2cbf2932015-07-22 12:05:38 +0800853 focus_resource_list = &pointer->focus_client->pointer_resources;
Neil Roberts96d790e2013-09-19 17:32:00 +0100854 wl_resource_for_each(resource, focus_resource_list) {
855 wl_pointer_send_enter(resource,
856 serial,
Jason Ekstranda7af7042013-10-12 22:38:11 -0500857 view->surface->resource,
Neil Roberts96d790e2013-09-19 17:32:00 +0100858 sx, sy);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400859 }
Neil Roberts96d790e2013-09-19 17:32:00 +0100860
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400861 pointer->focus_serial = serial;
862 }
863
Giulio Camuffo65a07f82013-12-06 12:46:27 +0100864 wl_list_remove(&pointer->focus_view_listener.link);
865 wl_list_init(&pointer->focus_view_listener.link);
866 wl_list_remove(&pointer->focus_resource_listener.link);
867 wl_list_init(&pointer->focus_resource_listener.link);
Emilio Pozuelo Monfortaa7a4762013-11-19 11:37:15 +0100868 if (view)
Giulio Camuffo576fe2a2013-11-20 18:00:24 +0100869 wl_signal_add(&view->destroy_signal, &pointer->focus_view_listener);
Giulio Camuffo65a07f82013-12-06 12:46:27 +0100870 if (view && view->surface->resource)
871 wl_resource_add_destroy_listener(view->surface->resource,
872 &pointer->focus_resource_listener);
873
874 pointer->focus = view;
875 pointer->focus_view_listener.notify = pointer_focus_view_destroyed;
Kristian Høgsbergdb1fccb2014-02-05 17:14:42 -0800876 pointer->sx = sx;
877 pointer->sy = sy;
878
Derek Foremanf9318d12015-05-11 15:40:11 -0500879 assert(view || sx == wl_fixed_from_int(-1000000));
880 assert(view || sy == wl_fixed_from_int(-1000000));
881
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400882 wl_signal_emit(&pointer->focus_signal, pointer);
883}
884
Neil Roberts96d790e2013-09-19 17:32:00 +0100885static void
886send_enter_to_resource_list(struct wl_list *list,
887 struct weston_keyboard *keyboard,
888 struct weston_surface *surface,
889 uint32_t serial)
890{
891 struct wl_resource *resource;
892
893 wl_resource_for_each(resource, list) {
894 send_modifiers_to_resource(keyboard, resource, serial);
895 wl_keyboard_send_enter(resource, serial,
896 surface->resource,
897 &keyboard->keys);
898 }
899}
900
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400901WL_EXPORT void
Kristian Høgsberg29139d42013-04-18 15:25:39 -0400902weston_keyboard_set_focus(struct weston_keyboard *keyboard,
Kristian Høgsbergfe7aa902013-05-08 09:54:37 -0400903 struct weston_surface *surface)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400904{
905 struct wl_resource *resource;
Rob Bradford880ebc72013-07-22 17:31:38 +0100906 struct wl_display *display = keyboard->seat->compositor->wl_display;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400907 uint32_t serial;
Neil Roberts96d790e2013-09-19 17:32:00 +0100908 struct wl_list *focus_resource_list;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400909
Neil Roberts96d790e2013-09-19 17:32:00 +0100910 focus_resource_list = &keyboard->focus_resource_list;
911
912 if (!wl_list_empty(focus_resource_list) && keyboard->focus != surface) {
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400913 serial = wl_display_next_serial(display);
Neil Roberts96d790e2013-09-19 17:32:00 +0100914 wl_resource_for_each(resource, focus_resource_list) {
915 wl_keyboard_send_leave(resource, serial,
916 keyboard->focus->resource);
917 }
918 move_resources(&keyboard->resource_list, focus_resource_list);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400919 }
920
Neil Roberts96d790e2013-09-19 17:32:00 +0100921 if (find_resource_for_surface(&keyboard->resource_list, surface) &&
922 keyboard->focus != surface) {
923 struct wl_client *surface_client =
924 wl_resource_get_client(surface->resource);
925
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400926 serial = wl_display_next_serial(display);
Neil Roberts96d790e2013-09-19 17:32:00 +0100927
928 move_resources_for_client(focus_resource_list,
929 &keyboard->resource_list,
930 surface_client);
931 send_enter_to_resource_list(focus_resource_list,
932 keyboard,
933 surface,
934 serial);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400935 keyboard->focus_serial = serial;
Giulio Camuffo65a07f82013-12-06 12:46:27 +0100936 }
937
938 wl_list_remove(&keyboard->focus_resource_listener.link);
939 wl_list_init(&keyboard->focus_resource_listener.link);
940 if (surface && surface->resource)
Giulio Camuffo576fe2a2013-11-20 18:00:24 +0100941 wl_resource_add_destroy_listener(surface->resource,
942 &keyboard->focus_resource_listener);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400943
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400944 keyboard->focus = surface;
945 wl_signal_emit(&keyboard->focus_signal, keyboard);
946}
947
Giulio Camuffoa20ca812014-11-22 11:16:56 +0200948/* Users of this function must manually manage the keyboard focus */
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400949WL_EXPORT void
Kristian Høgsberg29139d42013-04-18 15:25:39 -0400950weston_keyboard_start_grab(struct weston_keyboard *keyboard,
951 struct weston_keyboard_grab *grab)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400952{
953 keyboard->grab = grab;
954 grab->keyboard = keyboard;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400955}
956
957WL_EXPORT void
Kristian Høgsberg29139d42013-04-18 15:25:39 -0400958weston_keyboard_end_grab(struct weston_keyboard *keyboard)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400959{
960 keyboard->grab = &keyboard->default_grab;
961}
962
Jonas Ådahl1ea343e2013-10-25 23:18:05 +0200963static void
964weston_keyboard_cancel_grab(struct weston_keyboard *keyboard)
965{
966 keyboard->grab->interface->cancel(keyboard->grab);
967}
968
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400969WL_EXPORT void
Kristian Høgsberg02bbabb2013-05-06 22:15:05 -0400970weston_pointer_start_grab(struct weston_pointer *pointer,
971 struct weston_pointer_grab *grab)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400972{
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400973 pointer->grab = grab;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400974 grab->pointer = pointer;
Kristian Høgsbergda751b82013-07-04 00:58:07 -0400975 pointer->grab->interface->focus(pointer->grab);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400976}
977
978WL_EXPORT void
Kristian Høgsberg02bbabb2013-05-06 22:15:05 -0400979weston_pointer_end_grab(struct weston_pointer *pointer)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400980{
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400981 pointer->grab = &pointer->default_grab;
Kristian Høgsbergda751b82013-07-04 00:58:07 -0400982 pointer->grab->interface->focus(pointer->grab);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400983}
984
Jonas Ådahl1ea343e2013-10-25 23:18:05 +0200985static void
986weston_pointer_cancel_grab(struct weston_pointer *pointer)
987{
988 pointer->grab->interface->cancel(pointer->grab);
989}
990
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400991WL_EXPORT void
Kristian Høgsberge329f362013-05-06 22:19:57 -0400992weston_touch_start_grab(struct weston_touch *touch, struct weston_touch_grab *grab)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400993{
994 touch->grab = grab;
995 grab->touch = touch;
996}
997
998WL_EXPORT void
Kristian Høgsberge329f362013-05-06 22:19:57 -0400999weston_touch_end_grab(struct weston_touch *touch)
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001000{
1001 touch->grab = &touch->default_grab;
1002}
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001003
Jonas Ådahl1ea343e2013-10-25 23:18:05 +02001004static void
1005weston_touch_cancel_grab(struct weston_touch *touch)
1006{
1007 touch->grab->interface->cancel(touch->grab);
1008}
1009
Ander Conselvan de Oliveira54e90c72013-12-13 22:10:56 +02001010static void
1011weston_pointer_clamp_for_output(struct weston_pointer *pointer,
1012 struct weston_output *output,
1013 wl_fixed_t *fx, wl_fixed_t *fy)
1014{
1015 int x, y;
1016
1017 x = wl_fixed_to_int(*fx);
1018 y = wl_fixed_to_int(*fy);
1019
1020 if (x < output->x)
1021 *fx = wl_fixed_from_int(output->x);
1022 else if (x >= output->x + output->width)
1023 *fx = wl_fixed_from_int(output->x +
1024 output->width - 1);
1025 if (y < output->y)
1026 *fy = wl_fixed_from_int(output->y);
1027 else if (y >= output->y + output->height)
1028 *fy = wl_fixed_from_int(output->y +
1029 output->height - 1);
1030}
1031
Rob Bradford806d8c02013-06-25 18:56:41 +01001032WL_EXPORT void
1033weston_pointer_clamp(struct weston_pointer *pointer, wl_fixed_t *fx, wl_fixed_t *fy)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001034{
Rob Bradford806d8c02013-06-25 18:56:41 +01001035 struct weston_compositor *ec = pointer->seat->compositor;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001036 struct weston_output *output, *prev = NULL;
1037 int x, y, old_x, old_y, valid = 0;
1038
1039 x = wl_fixed_to_int(*fx);
1040 y = wl_fixed_to_int(*fy);
Rob Bradford806d8c02013-06-25 18:56:41 +01001041 old_x = wl_fixed_to_int(pointer->x);
1042 old_y = wl_fixed_to_int(pointer->y);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001043
1044 wl_list_for_each(output, &ec->output_list, link) {
Rob Bradford66bd9f52013-06-25 18:56:42 +01001045 if (pointer->seat->output && pointer->seat->output != output)
1046 continue;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001047 if (pixman_region32_contains_point(&output->region,
1048 x, y, NULL))
1049 valid = 1;
1050 if (pixman_region32_contains_point(&output->region,
1051 old_x, old_y, NULL))
1052 prev = output;
1053 }
1054
Rob Bradford66bd9f52013-06-25 18:56:42 +01001055 if (!prev)
1056 prev = pointer->seat->output;
1057
Ander Conselvan de Oliveira54e90c72013-12-13 22:10:56 +02001058 if (prev && !valid)
1059 weston_pointer_clamp_for_output(pointer, prev, fx, fy);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001060}
1061
Jonas Ådahld2510102014-10-05 21:39:14 +02001062static void
1063weston_pointer_move_to(struct weston_pointer *pointer,
1064 wl_fixed_t x, wl_fixed_t y)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001065{
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001066 int32_t ix, iy;
1067
Rob Bradford806d8c02013-06-25 18:56:41 +01001068 weston_pointer_clamp (pointer, &x, &y);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001069
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001070 pointer->x = x;
1071 pointer->y = y;
1072
1073 ix = wl_fixed_to_int(x);
1074 iy = wl_fixed_to_int(y);
1075
Kristian Høgsberg195b8692013-05-08 15:02:05 -04001076 if (pointer->sprite) {
Jason Ekstranda7af7042013-10-12 22:38:11 -05001077 weston_view_set_position(pointer->sprite,
1078 ix - pointer->hotspot_x,
1079 iy - pointer->hotspot_y);
1080 weston_view_schedule_repaint(pointer->sprite);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001081 }
Giulio Camuffo6fcb3782013-11-14 23:42:50 +01001082
Giulio Camuffo1959ab82013-11-14 23:42:52 +01001083 pointer->grab->interface->focus(pointer->grab);
Giulio Camuffo6fcb3782013-11-14 23:42:50 +01001084 wl_signal_emit(&pointer->motion_signal, pointer);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001085}
1086
Jonas Ådahld2510102014-10-05 21:39:14 +02001087WL_EXPORT void
1088weston_pointer_motion_to_abs(struct weston_pointer *pointer,
1089 struct weston_pointer_motion_event *event,
1090 wl_fixed_t *x, wl_fixed_t *y)
1091{
1092 if (event->mask & WESTON_POINTER_MOTION_ABS) {
1093 *x = wl_fixed_from_double(event->x);
1094 *y = wl_fixed_from_double(event->y);
1095 } else if (event->mask & WESTON_POINTER_MOTION_REL) {
1096 *x = pointer->x + wl_fixed_from_double(event->dx);
1097 *y = pointer->y + wl_fixed_from_double(event->dy);
1098 } else {
1099 assert(!"invalid motion event");
1100 *x = *y = 0;
1101 }
1102}
1103
1104WL_EXPORT void
1105weston_pointer_move(struct weston_pointer *pointer,
1106 struct weston_pointer_motion_event *event)
1107{
1108 wl_fixed_t x, y;
1109
1110 weston_pointer_motion_to_abs(pointer, event, &x, &y);
1111 weston_pointer_move_to(pointer, x, y);
1112}
1113
Ander Conselvan de Oliveira54e90c72013-12-13 22:10:56 +02001114/** Verify if the pointer is in a valid position and move it if it isn't.
1115 */
Ander Conselvan de Oliveiraf84327a2014-01-29 18:47:51 +02001116static void
1117weston_pointer_handle_output_destroy(struct wl_listener *listener, void *data)
Ander Conselvan de Oliveira54e90c72013-12-13 22:10:56 +02001118{
Ander Conselvan de Oliveiraf84327a2014-01-29 18:47:51 +02001119 struct weston_pointer *pointer;
1120 struct weston_compositor *ec;
Ander Conselvan de Oliveira54e90c72013-12-13 22:10:56 +02001121 struct weston_output *output, *closest = NULL;
1122 int x, y, distance, min = INT_MAX;
1123 wl_fixed_t fx, fy;
1124
Ander Conselvan de Oliveiraf84327a2014-01-29 18:47:51 +02001125 pointer = container_of(listener, struct weston_pointer,
1126 output_destroy_listener);
1127 ec = pointer->seat->compositor;
1128
Ander Conselvan de Oliveira54e90c72013-12-13 22:10:56 +02001129 x = wl_fixed_to_int(pointer->x);
1130 y = wl_fixed_to_int(pointer->y);
1131
1132 wl_list_for_each(output, &ec->output_list, link) {
1133 if (pixman_region32_contains_point(&output->region,
1134 x, y, NULL))
1135 return;
1136
1137 /* Aproximante the distance from the pointer to the center of
1138 * the output. */
1139 distance = abs(output->x + output->width / 2 - x) +
1140 abs(output->y + output->height / 2 - y);
1141 if (distance < min) {
1142 min = distance;
1143 closest = output;
1144 }
1145 }
1146
1147 /* Nothing to do if there's no output left. */
1148 if (!closest)
1149 return;
1150
1151 fx = pointer->x;
1152 fy = pointer->y;
1153
1154 weston_pointer_clamp_for_output(pointer, closest, &fx, &fy);
Jonas Ådahld2510102014-10-05 21:39:14 +02001155 weston_pointer_move_to(pointer, fx, fy);
Ander Conselvan de Oliveira54e90c72013-12-13 22:10:56 +02001156}
1157
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001158WL_EXPORT void
1159notify_motion(struct weston_seat *seat,
Jonas Ådahld2510102014-10-05 21:39:14 +02001160 uint32_t time,
1161 struct weston_pointer_motion_event *event)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001162{
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001163 struct weston_compositor *ec = seat->compositor;
Derek Foreman1281a362015-07-31 16:55:32 -05001164 struct weston_pointer *pointer = weston_seat_get_pointer(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001165
1166 weston_compositor_wake(ec);
Jonas Ådahld2510102014-10-05 21:39:14 +02001167 pointer->grab->interface->motion(pointer->grab, time, event);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001168}
1169
Daniel Stone96d47c02013-11-19 11:37:12 +01001170static void
1171run_modifier_bindings(struct weston_seat *seat, uint32_t old, uint32_t new)
1172{
1173 struct weston_compositor *compositor = seat->compositor;
Derek Foreman1281a362015-07-31 16:55:32 -05001174 struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
Daniel Stone96d47c02013-11-19 11:37:12 +01001175 uint32_t diff;
1176 unsigned int i;
1177 struct {
1178 uint32_t xkb;
1179 enum weston_keyboard_modifier weston;
1180 } mods[] = {
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001181 { keyboard->xkb_info->ctrl_mod, MODIFIER_CTRL },
1182 { keyboard->xkb_info->alt_mod, MODIFIER_ALT },
1183 { keyboard->xkb_info->super_mod, MODIFIER_SUPER },
1184 { keyboard->xkb_info->shift_mod, MODIFIER_SHIFT },
Daniel Stone96d47c02013-11-19 11:37:12 +01001185 };
1186
1187 diff = new & ~old;
1188 for (i = 0; i < ARRAY_LENGTH(mods); i++) {
1189 if (diff & (1 << mods[i].xkb))
1190 weston_compositor_run_modifier_binding(compositor,
Derek Foreman99a6a2d2015-07-15 13:00:43 -05001191 keyboard,
Daniel Stone96d47c02013-11-19 11:37:12 +01001192 mods[i].weston,
1193 WL_KEYBOARD_KEY_STATE_PRESSED);
1194 }
1195
1196 diff = old & ~new;
1197 for (i = 0; i < ARRAY_LENGTH(mods); i++) {
1198 if (diff & (1 << mods[i].xkb))
1199 weston_compositor_run_modifier_binding(compositor,
Derek Foreman99a6a2d2015-07-15 13:00:43 -05001200 keyboard,
Daniel Stone96d47c02013-11-19 11:37:12 +01001201 mods[i].weston,
1202 WL_KEYBOARD_KEY_STATE_RELEASED);
1203 }
1204}
1205
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001206WL_EXPORT void
1207notify_motion_absolute(struct weston_seat *seat,
1208 uint32_t time, wl_fixed_t x, wl_fixed_t y)
1209{
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001210 struct weston_compositor *ec = seat->compositor;
Derek Foreman1281a362015-07-31 16:55:32 -05001211 struct weston_pointer *pointer = weston_seat_get_pointer(seat);
Jonas Ådahld2510102014-10-05 21:39:14 +02001212 struct weston_pointer_motion_event event = { 0 };
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001213
1214 weston_compositor_wake(ec);
Jonas Ådahld2510102014-10-05 21:39:14 +02001215
1216 event = (struct weston_pointer_motion_event) {
1217 .mask = WESTON_POINTER_MOTION_ABS,
1218 .x = wl_fixed_to_double(x),
1219 .y = wl_fixed_to_double(y),
1220 };
1221
1222 pointer->grab->interface->motion(pointer->grab, time, &event);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001223}
1224
1225WL_EXPORT void
1226weston_surface_activate(struct weston_surface *surface,
1227 struct weston_seat *seat)
1228{
1229 struct weston_compositor *compositor = seat->compositor;
Derek Foreman1281a362015-07-31 16:55:32 -05001230 struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001231
Derek Foreman1281a362015-07-31 16:55:32 -05001232 if (keyboard) {
1233 weston_keyboard_set_focus(keyboard, surface);
Kristian Høgsberge3148752013-05-06 23:19:49 -04001234 wl_data_device_set_keyboard_focus(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001235 }
1236
1237 wl_signal_emit(&compositor->activate_signal, surface);
1238}
1239
1240WL_EXPORT void
1241notify_button(struct weston_seat *seat, uint32_t time, int32_t button,
1242 enum wl_pointer_button_state state)
1243{
1244 struct weston_compositor *compositor = seat->compositor;
Derek Foreman1281a362015-07-31 16:55:32 -05001245 struct weston_pointer *pointer = weston_seat_get_pointer(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001246
1247 if (state == WL_POINTER_BUTTON_STATE_PRESSED) {
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001248 weston_compositor_idle_inhibit(compositor);
1249 if (pointer->button_count == 0) {
1250 pointer->grab_button = button;
1251 pointer->grab_time = time;
1252 pointer->grab_x = pointer->x;
1253 pointer->grab_y = pointer->y;
1254 }
1255 pointer->button_count++;
1256 } else {
1257 weston_compositor_idle_release(compositor);
1258 pointer->button_count--;
1259 }
1260
Derek Foreman99a6a2d2015-07-15 13:00:43 -05001261 weston_compositor_run_button_binding(compositor, pointer, time, button,
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001262 state);
1263
1264 pointer->grab->interface->button(pointer->grab, time, button, state);
1265
1266 if (pointer->button_count == 1)
1267 pointer->grab_serial =
1268 wl_display_get_serial(compositor->wl_display);
1269}
1270
1271WL_EXPORT void
Peter Hutterer89b6a492016-01-18 15:58:17 +10001272notify_axis(struct weston_seat *seat, uint32_t time,
1273 struct weston_pointer_axis_event *event)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001274{
1275 struct weston_compositor *compositor = seat->compositor;
Derek Foreman1281a362015-07-31 16:55:32 -05001276 struct weston_pointer *pointer = weston_seat_get_pointer(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001277
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001278 weston_compositor_wake(compositor);
1279
Peter Hutterer89b6a492016-01-18 15:58:17 +10001280 if (!event->value)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001281 return;
1282
Derek Foreman99a6a2d2015-07-15 13:00:43 -05001283 if (weston_compositor_run_axis_binding(compositor, pointer,
Peter Hutterer89b6a492016-01-18 15:58:17 +10001284 time, event))
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001285 return;
1286
Peter Hutterer89b6a492016-01-18 15:58:17 +10001287 pointer->grab->interface->axis(pointer->grab, time, event);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001288}
1289
Giulio Camuffo6ef444d2014-08-28 19:44:09 +03001290WL_EXPORT int
1291weston_keyboard_set_locks(struct weston_keyboard *keyboard,
1292 uint32_t mask, uint32_t value)
1293{
1294#ifdef ENABLE_XKBCOMMON
1295 uint32_t serial;
1296 xkb_mod_mask_t mods_depressed, mods_latched, mods_locked, group;
1297 xkb_mod_mask_t num, caps;
1298
1299 /* We don't want the leds to go out of sync with the actual state
1300 * so if the backend has no way to change the leds don't try to
1301 * change the state */
1302 if (!keyboard->seat->led_update)
1303 return -1;
1304
1305 mods_depressed = xkb_state_serialize_mods(keyboard->xkb_state.state,
1306 XKB_STATE_DEPRESSED);
1307 mods_latched = xkb_state_serialize_mods(keyboard->xkb_state.state,
1308 XKB_STATE_LATCHED);
1309 mods_locked = xkb_state_serialize_mods(keyboard->xkb_state.state,
1310 XKB_STATE_LOCKED);
1311 group = xkb_state_serialize_group(keyboard->xkb_state.state,
1312 XKB_STATE_EFFECTIVE);
1313
1314 num = (1 << keyboard->xkb_info->mod2_mod);
1315 caps = (1 << keyboard->xkb_info->caps_mod);
1316 if (mask & WESTON_NUM_LOCK) {
1317 if (value & WESTON_NUM_LOCK)
1318 mods_locked |= num;
1319 else
1320 mods_locked &= ~num;
1321 }
1322 if (mask & WESTON_CAPS_LOCK) {
1323 if (value & WESTON_CAPS_LOCK)
1324 mods_locked |= caps;
1325 else
1326 mods_locked &= ~caps;
1327 }
1328
1329 xkb_state_update_mask(keyboard->xkb_state.state, mods_depressed,
1330 mods_latched, mods_locked, 0, 0, group);
1331
1332 serial = wl_display_next_serial(
1333 keyboard->seat->compositor->wl_display);
1334 notify_modifiers(keyboard->seat, serial);
1335
1336 return 0;
1337#else
1338 return -1;
1339#endif
1340}
1341
Rob Bradford382ff462013-06-24 16:52:45 +01001342#ifdef ENABLE_XKBCOMMON
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001343WL_EXPORT void
1344notify_modifiers(struct weston_seat *seat, uint32_t serial)
1345{
Derek Foreman1281a362015-07-31 16:55:32 -05001346 struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001347 struct weston_keyboard_grab *grab = keyboard->grab;
1348 uint32_t mods_depressed, mods_latched, mods_locked, group;
1349 uint32_t mods_lookup;
1350 enum weston_led leds = 0;
1351 int changed = 0;
1352
1353 /* Serialize and update our internal state, checking to see if it's
1354 * different to the previous state. */
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001355 mods_depressed = xkb_state_serialize_mods(keyboard->xkb_state.state,
Ran Benita2e1968f2014-08-19 23:59:51 +03001356 XKB_STATE_MODS_DEPRESSED);
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001357 mods_latched = xkb_state_serialize_mods(keyboard->xkb_state.state,
Ran Benita2e1968f2014-08-19 23:59:51 +03001358 XKB_STATE_MODS_LATCHED);
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001359 mods_locked = xkb_state_serialize_mods(keyboard->xkb_state.state,
Ran Benita2e1968f2014-08-19 23:59:51 +03001360 XKB_STATE_MODS_LOCKED);
1361 group = xkb_state_serialize_layout(keyboard->xkb_state.state,
1362 XKB_STATE_LAYOUT_EFFECTIVE);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001363
Derek Foreman244e99e2015-06-03 15:53:26 -05001364 if (mods_depressed != keyboard->modifiers.mods_depressed ||
1365 mods_latched != keyboard->modifiers.mods_latched ||
1366 mods_locked != keyboard->modifiers.mods_locked ||
1367 group != keyboard->modifiers.group)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001368 changed = 1;
1369
Derek Foreman244e99e2015-06-03 15:53:26 -05001370 run_modifier_bindings(seat, keyboard->modifiers.mods_depressed,
Daniel Stone96d47c02013-11-19 11:37:12 +01001371 mods_depressed);
1372
Derek Foreman244e99e2015-06-03 15:53:26 -05001373 keyboard->modifiers.mods_depressed = mods_depressed;
1374 keyboard->modifiers.mods_latched = mods_latched;
1375 keyboard->modifiers.mods_locked = mods_locked;
1376 keyboard->modifiers.group = group;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001377
1378 /* And update the modifier_state for bindings. */
1379 mods_lookup = mods_depressed | mods_latched;
1380 seat->modifier_state = 0;
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001381 if (mods_lookup & (1 << keyboard->xkb_info->ctrl_mod))
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001382 seat->modifier_state |= MODIFIER_CTRL;
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001383 if (mods_lookup & (1 << keyboard->xkb_info->alt_mod))
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001384 seat->modifier_state |= MODIFIER_ALT;
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001385 if (mods_lookup & (1 << keyboard->xkb_info->super_mod))
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001386 seat->modifier_state |= MODIFIER_SUPER;
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001387 if (mods_lookup & (1 << keyboard->xkb_info->shift_mod))
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001388 seat->modifier_state |= MODIFIER_SHIFT;
1389
1390 /* Finally, notify the compositor that LEDs have changed. */
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001391 if (xkb_state_led_index_is_active(keyboard->xkb_state.state,
1392 keyboard->xkb_info->num_led))
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001393 leds |= LED_NUM_LOCK;
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001394 if (xkb_state_led_index_is_active(keyboard->xkb_state.state,
1395 keyboard->xkb_info->caps_led))
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001396 leds |= LED_CAPS_LOCK;
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001397 if (xkb_state_led_index_is_active(keyboard->xkb_state.state,
1398 keyboard->xkb_info->scroll_led))
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001399 leds |= LED_SCROLL_LOCK;
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001400 if (leds != keyboard->xkb_state.leds && seat->led_update)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001401 seat->led_update(seat, leds);
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001402 keyboard->xkb_state.leds = leds;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001403
1404 if (changed) {
1405 grab->interface->modifiers(grab,
1406 serial,
1407 keyboard->modifiers.mods_depressed,
1408 keyboard->modifiers.mods_latched,
1409 keyboard->modifiers.mods_locked,
1410 keyboard->modifiers.group);
1411 }
1412}
1413
1414static void
1415update_modifier_state(struct weston_seat *seat, uint32_t serial, uint32_t key,
1416 enum wl_keyboard_key_state state)
1417{
Derek Foreman1281a362015-07-31 16:55:32 -05001418 struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001419 enum xkb_key_direction direction;
1420
Matt Roper01a92732013-06-24 16:52:44 +01001421 /* Keyboard modifiers don't exist in raw keyboard mode */
1422 if (!seat->compositor->use_xkbcommon)
1423 return;
1424
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001425 if (state == WL_KEYBOARD_KEY_STATE_PRESSED)
1426 direction = XKB_KEY_DOWN;
1427 else
1428 direction = XKB_KEY_UP;
1429
1430 /* Offset the keycode by 8, as the evdev XKB rules reflect X's
1431 * broken keycode system, which starts at 8. */
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001432 xkb_state_update_key(keyboard->xkb_state.state, key + 8, direction);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001433
1434 notify_modifiers(seat, serial);
1435}
Rui Matos65196bc2013-10-10 19:44:19 +02001436
1437static void
1438send_keymap(struct wl_resource *resource, struct weston_xkb_info *xkb_info)
1439{
1440 wl_keyboard_send_keymap(resource,
1441 WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1,
1442 xkb_info->keymap_fd,
1443 xkb_info->keymap_size);
1444}
1445
1446static void
1447send_modifiers(struct wl_resource *resource, uint32_t serial, struct weston_keyboard *keyboard)
1448{
1449 wl_keyboard_send_modifiers(resource, serial,
1450 keyboard->modifiers.mods_depressed,
1451 keyboard->modifiers.mods_latched,
1452 keyboard->modifiers.mods_locked,
1453 keyboard->modifiers.group);
1454}
1455
1456static struct weston_xkb_info *
1457weston_xkb_info_create(struct xkb_keymap *keymap);
Rui Matos65196bc2013-10-10 19:44:19 +02001458
1459static void
1460update_keymap(struct weston_seat *seat)
1461{
Derek Foreman1281a362015-07-31 16:55:32 -05001462 struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
Rui Matos65196bc2013-10-10 19:44:19 +02001463 struct wl_resource *resource;
1464 struct weston_xkb_info *xkb_info;
1465 struct xkb_state *state;
1466 xkb_mod_mask_t latched_mods;
1467 xkb_mod_mask_t locked_mods;
1468
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001469 xkb_info = weston_xkb_info_create(keyboard->pending_keymap);
Rui Matos65196bc2013-10-10 19:44:19 +02001470
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001471 xkb_keymap_unref(keyboard->pending_keymap);
1472 keyboard->pending_keymap = NULL;
Rui Matos65196bc2013-10-10 19:44:19 +02001473
1474 if (!xkb_info) {
1475 weston_log("failed to create XKB info\n");
1476 return;
1477 }
1478
1479 state = xkb_state_new(xkb_info->keymap);
1480 if (!state) {
1481 weston_log("failed to initialise XKB state\n");
1482 weston_xkb_info_destroy(xkb_info);
1483 return;
1484 }
1485
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001486 latched_mods = xkb_state_serialize_mods(keyboard->xkb_state.state,
1487 XKB_STATE_MODS_LATCHED);
1488 locked_mods = xkb_state_serialize_mods(keyboard->xkb_state.state,
1489 XKB_STATE_MODS_LOCKED);
Rui Matos65196bc2013-10-10 19:44:19 +02001490 xkb_state_update_mask(state,
1491 0, /* depressed */
1492 latched_mods,
1493 locked_mods,
1494 0, 0, 0);
1495
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001496 weston_xkb_info_destroy(keyboard->xkb_info);
1497 keyboard->xkb_info = xkb_info;
Rui Matos65196bc2013-10-10 19:44:19 +02001498
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001499 xkb_state_unref(keyboard->xkb_state.state);
1500 keyboard->xkb_state.state = state;
Rui Matos65196bc2013-10-10 19:44:19 +02001501
Derek Foremanbc91e542015-06-03 15:53:27 -05001502 wl_resource_for_each(resource, &keyboard->resource_list)
Rui Matos65196bc2013-10-10 19:44:19 +02001503 send_keymap(resource, xkb_info);
Derek Foremanbc91e542015-06-03 15:53:27 -05001504 wl_resource_for_each(resource, &keyboard->focus_resource_list)
Rui Matos65196bc2013-10-10 19:44:19 +02001505 send_keymap(resource, xkb_info);
1506
1507 notify_modifiers(seat, wl_display_next_serial(seat->compositor->wl_display));
1508
1509 if (!latched_mods && !locked_mods)
1510 return;
1511
Derek Foremanbc91e542015-06-03 15:53:27 -05001512 wl_resource_for_each(resource, &keyboard->resource_list)
1513 send_modifiers(resource, wl_display_get_serial(seat->compositor->wl_display), keyboard);
1514 wl_resource_for_each(resource, &keyboard->focus_resource_list)
1515 send_modifiers(resource, wl_display_get_serial(seat->compositor->wl_display), keyboard);
Rui Matos65196bc2013-10-10 19:44:19 +02001516}
Rob Bradford382ff462013-06-24 16:52:45 +01001517#else
1518WL_EXPORT void
1519notify_modifiers(struct weston_seat *seat, uint32_t serial)
1520{
1521}
1522
1523static void
1524update_modifier_state(struct weston_seat *seat, uint32_t serial, uint32_t key,
1525 enum wl_keyboard_key_state state)
1526{
1527}
Rui Matos65196bc2013-10-10 19:44:19 +02001528
1529static void
1530update_keymap(struct weston_seat *seat)
1531{
1532}
Rob Bradford382ff462013-06-24 16:52:45 +01001533#endif
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001534
1535WL_EXPORT void
1536notify_key(struct weston_seat *seat, uint32_t time, uint32_t key,
1537 enum wl_keyboard_key_state state,
1538 enum weston_key_state_update update_state)
1539{
1540 struct weston_compositor *compositor = seat->compositor;
Derek Foreman1281a362015-07-31 16:55:32 -05001541 struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001542 struct weston_keyboard_grab *grab = keyboard->grab;
Pekka Paalanen86b53962014-11-19 13:43:32 +02001543 uint32_t *k, *end;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001544
1545 if (state == WL_KEYBOARD_KEY_STATE_PRESSED) {
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001546 weston_compositor_idle_inhibit(compositor);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001547 } else {
1548 weston_compositor_idle_release(compositor);
1549 }
1550
Pekka Paalanen86b53962014-11-19 13:43:32 +02001551 end = keyboard->keys.data + keyboard->keys.size;
1552 for (k = keyboard->keys.data; k < end; k++) {
1553 if (*k == key) {
1554 /* Ignore server-generated repeats. */
1555 if (state == WL_KEYBOARD_KEY_STATE_PRESSED)
1556 return;
1557 *k = *--end;
1558 }
1559 }
1560 keyboard->keys.size = (void *) end - keyboard->keys.data;
1561 if (state == WL_KEYBOARD_KEY_STATE_PRESSED) {
1562 k = wl_array_add(&keyboard->keys, sizeof *k);
1563 *k = key;
1564 }
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001565
1566 if (grab == &keyboard->default_grab ||
1567 grab == &keyboard->input_method_grab) {
Derek Foreman99a6a2d2015-07-15 13:00:43 -05001568 weston_compositor_run_key_binding(compositor, keyboard, time,
1569 key, state);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001570 grab = keyboard->grab;
1571 }
1572
1573 grab->interface->key(grab, time, key, state);
1574
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001575 if (keyboard->pending_keymap &&
Pekka Paalanen86b53962014-11-19 13:43:32 +02001576 keyboard->keys.size == 0)
Rui Matos65196bc2013-10-10 19:44:19 +02001577 update_keymap(seat);
1578
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001579 if (update_state == STATE_UPDATE_AUTOMATIC) {
1580 update_modifier_state(seat,
1581 wl_display_get_serial(compositor->wl_display),
1582 key,
1583 state);
1584 }
Giulio Camuffob6ddf6c2015-02-06 19:06:54 +02001585
1586 if (state == WL_KEYBOARD_KEY_STATE_PRESSED) {
1587 keyboard->grab_serial =
1588 wl_display_get_serial(compositor->wl_display);
1589 keyboard->grab_time = time;
1590 keyboard->grab_key = key;
1591 }
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001592}
1593
1594WL_EXPORT void
1595notify_pointer_focus(struct weston_seat *seat, struct weston_output *output,
1596 wl_fixed_t x, wl_fixed_t y)
1597{
Derek Foreman1281a362015-07-31 16:55:32 -05001598 struct weston_pointer *pointer = weston_seat_get_pointer(seat);
1599
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001600 if (output) {
Jonas Ådahld2510102014-10-05 21:39:14 +02001601 weston_pointer_move_to(pointer, x, y);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001602 } else {
Kristian Høgsberg02bbabb2013-05-06 22:15:05 -04001603 /* FIXME: We should call weston_pointer_set_focus(seat,
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001604 * NULL) here, but somehow that breaks re-entry... */
1605 }
1606}
1607
1608static void
1609destroy_device_saved_kbd_focus(struct wl_listener *listener, void *data)
1610{
1611 struct weston_seat *ws;
1612
1613 ws = container_of(listener, struct weston_seat,
1614 saved_kbd_focus_listener);
1615
1616 ws->saved_kbd_focus = NULL;
1617}
1618
1619WL_EXPORT void
1620notify_keyboard_focus_in(struct weston_seat *seat, struct wl_array *keys,
1621 enum weston_key_state_update update_state)
1622{
1623 struct weston_compositor *compositor = seat->compositor;
Derek Foreman1281a362015-07-31 16:55:32 -05001624 struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
Kristian Høgsbergfe7aa902013-05-08 09:54:37 -04001625 struct weston_surface *surface;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001626 uint32_t *k, serial;
1627
1628 serial = wl_display_next_serial(compositor->wl_display);
1629 wl_array_copy(&keyboard->keys, keys);
1630 wl_array_for_each(k, &keyboard->keys) {
1631 weston_compositor_idle_inhibit(compositor);
1632 if (update_state == STATE_UPDATE_AUTOMATIC)
1633 update_modifier_state(seat, serial, *k,
1634 WL_KEYBOARD_KEY_STATE_PRESSED);
1635 }
1636
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001637 surface = seat->saved_kbd_focus;
1638
1639 if (surface) {
1640 wl_list_remove(&seat->saved_kbd_focus_listener.link);
1641 weston_keyboard_set_focus(keyboard, surface);
1642 seat->saved_kbd_focus = NULL;
1643 }
1644}
1645
1646WL_EXPORT void
1647notify_keyboard_focus_out(struct weston_seat *seat)
1648{
1649 struct weston_compositor *compositor = seat->compositor;
Derek Foreman1281a362015-07-31 16:55:32 -05001650 struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
1651 struct weston_pointer *pointer = weston_seat_get_pointer(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001652 uint32_t *k, serial;
1653
1654 serial = wl_display_next_serial(compositor->wl_display);
1655 wl_array_for_each(k, &keyboard->keys) {
1656 weston_compositor_idle_release(compositor);
1657 update_modifier_state(seat, serial, *k,
1658 WL_KEYBOARD_KEY_STATE_RELEASED);
1659 }
1660
1661 seat->modifier_state = 0;
1662
1663 if (keyboard->focus) {
1664 seat->saved_kbd_focus = keyboard->focus;
1665 seat->saved_kbd_focus_listener.notify =
1666 destroy_device_saved_kbd_focus;
Jason Ekstrand26ed73c2013-06-06 22:34:41 -05001667 wl_signal_add(&keyboard->focus->destroy_signal,
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001668 &seat->saved_kbd_focus_listener);
1669 }
1670
1671 weston_keyboard_set_focus(keyboard, NULL);
Jonas Ådahl1ea343e2013-10-25 23:18:05 +02001672 weston_keyboard_cancel_grab(keyboard);
Derek Foreman1281a362015-07-31 16:55:32 -05001673 if (pointer)
1674 weston_pointer_cancel_grab(pointer);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001675}
1676
Michael Fua2bb7912013-07-23 15:51:06 +08001677WL_EXPORT void
Derek Foreman4c93c082015-04-30 16:45:41 -05001678weston_touch_set_focus(struct weston_touch *touch, struct weston_view *view)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001679{
Neil Roberts96d790e2013-09-19 17:32:00 +01001680 struct wl_list *focus_resource_list;
1681
Derek Foreman4c93c082015-04-30 16:45:41 -05001682 focus_resource_list = &touch->focus_resource_list;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001683
Derek Foreman4c93c082015-04-30 16:45:41 -05001684 if (view && touch->focus &&
1685 touch->focus->surface == view->surface) {
1686 touch->focus = view;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001687 return;
Jason Ekstranda7af7042013-10-12 22:38:11 -05001688 }
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001689
Derek Foreman4c93c082015-04-30 16:45:41 -05001690 wl_list_remove(&touch->focus_resource_listener.link);
1691 wl_list_init(&touch->focus_resource_listener.link);
1692 wl_list_remove(&touch->focus_view_listener.link);
1693 wl_list_init(&touch->focus_view_listener.link);
Giulio Camuffo576fe2a2013-11-20 18:00:24 +01001694
Neil Roberts96d790e2013-09-19 17:32:00 +01001695 if (!wl_list_empty(focus_resource_list)) {
Derek Foreman4c93c082015-04-30 16:45:41 -05001696 move_resources(&touch->resource_list,
Neil Roberts96d790e2013-09-19 17:32:00 +01001697 focus_resource_list);
1698 }
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001699
Jason Ekstranda7af7042013-10-12 22:38:11 -05001700 if (view) {
Derek Foreman362656b2014-09-04 10:23:05 -05001701 struct wl_client *surface_client;
1702
1703 if (!view->surface->resource) {
Derek Foreman4c93c082015-04-30 16:45:41 -05001704 touch->focus = NULL;
Derek Foreman362656b2014-09-04 10:23:05 -05001705 return;
1706 }
1707
1708 surface_client = wl_resource_get_client(view->surface->resource);
Neil Roberts96d790e2013-09-19 17:32:00 +01001709 move_resources_for_client(focus_resource_list,
Derek Foreman4c93c082015-04-30 16:45:41 -05001710 &touch->resource_list,
Neil Roberts96d790e2013-09-19 17:32:00 +01001711 surface_client);
Giulio Camuffo576fe2a2013-11-20 18:00:24 +01001712 wl_resource_add_destroy_listener(view->surface->resource,
Derek Foreman4c93c082015-04-30 16:45:41 -05001713 &touch->focus_resource_listener);
1714 wl_signal_add(&view->destroy_signal, &touch->focus_view_listener);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001715 }
Derek Foreman4c93c082015-04-30 16:45:41 -05001716 touch->focus = view;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001717}
1718
1719/**
1720 * notify_touch - emulates button touches and notifies surfaces accordingly.
1721 *
1722 * It assumes always the correct cycle sequence until it gets here: touch_down
1723 * → touch_update → ... → touch_update → touch_end. The driver is responsible
1724 * for sending along such order.
1725 *
1726 */
1727WL_EXPORT void
1728notify_touch(struct weston_seat *seat, uint32_t time, int touch_id,
1729 wl_fixed_t x, wl_fixed_t y, int touch_type)
1730{
1731 struct weston_compositor *ec = seat->compositor;
Derek Foreman1281a362015-07-31 16:55:32 -05001732 struct weston_touch *touch = weston_seat_get_touch(seat);
Kristian Høgsberge329f362013-05-06 22:19:57 -04001733 struct weston_touch_grab *grab = touch->grab;
Jason Ekstranda7af7042013-10-12 22:38:11 -05001734 struct weston_view *ev;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001735 wl_fixed_t sx, sy;
1736
1737 /* Update grab's global coordinates. */
Neil Roberts306fe082013-10-03 16:43:06 +01001738 if (touch_id == touch->grab_touch_id && touch_type != WL_TOUCH_UP) {
1739 touch->grab_x = x;
1740 touch->grab_y = y;
1741 }
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001742
1743 switch (touch_type) {
1744 case WL_TOUCH_DOWN:
1745 weston_compositor_idle_inhibit(ec);
1746
Jonas Ådahl9484b692013-12-02 22:05:03 +01001747 touch->num_tp++;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001748
Jason Ekstranda7af7042013-10-12 22:38:11 -05001749 /* the first finger down picks the view, and all further go
1750 * to that view for the remainder of the touch session i.e.
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001751 * until all touch points are up again. */
Jonas Ådahl9484b692013-12-02 22:05:03 +01001752 if (touch->num_tp == 1) {
Jason Ekstranda7af7042013-10-12 22:38:11 -05001753 ev = weston_compositor_pick_view(ec, x, y, &sx, &sy);
Derek Foreman4c93c082015-04-30 16:45:41 -05001754 weston_touch_set_focus(touch, ev);
Giulio Camuffo61ed7b62015-07-08 11:55:28 +03001755 } else if (!touch->focus) {
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001756 /* Unexpected condition: We have non-initial touch but
1757 * there is no focused surface.
1758 */
Chris Michael3f607d32015-10-07 11:59:49 -04001759 weston_log("touch event received with %d points down "
Jonas Ådahl9484b692013-12-02 22:05:03 +01001760 "but no surface focused\n", touch->num_tp);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001761 return;
1762 }
1763
Derek Foreman99a6a2d2015-07-15 13:00:43 -05001764 weston_compositor_run_touch_binding(ec, touch,
Kristian Høgsbergc8964012014-02-05 14:25:18 -08001765 time, touch_type);
1766
Giulio Camuffo61ed7b62015-07-08 11:55:28 +03001767 grab->interface->down(grab, time, touch_id, x, y);
Jonas Ådahl9484b692013-12-02 22:05:03 +01001768 if (touch->num_tp == 1) {
Rusty Lynchf1407ff2013-08-08 21:13:57 -07001769 touch->grab_serial =
1770 wl_display_get_serial(ec->wl_display);
Neil Roberts306fe082013-10-03 16:43:06 +01001771 touch->grab_touch_id = touch_id;
Rusty Lynchf1407ff2013-08-08 21:13:57 -07001772 touch->grab_time = time;
1773 touch->grab_x = x;
1774 touch->grab_y = y;
1775 }
1776
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001777 break;
1778 case WL_TOUCH_MOTION:
Jason Ekstranda7af7042013-10-12 22:38:11 -05001779 ev = touch->focus;
1780 if (!ev)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001781 break;
1782
Giulio Camuffo61ed7b62015-07-08 11:55:28 +03001783 grab->interface->motion(grab, time, touch_id, x, y);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001784 break;
1785 case WL_TOUCH_UP:
Kristian Høgsberga30e29a2014-01-08 22:29:20 -08001786 if (touch->num_tp == 0) {
1787 /* This can happen if we start out with one or
1788 * more fingers on the touch screen, in which
1789 * case we didn't get the corresponding down
1790 * event. */
1791 weston_log("unmatched touch up event\n");
1792 break;
1793 }
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001794 weston_compositor_idle_release(ec);
Jonas Ådahl9484b692013-12-02 22:05:03 +01001795 touch->num_tp--;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001796
1797 grab->interface->up(grab, time, touch_id);
Jonas Ådahl9484b692013-12-02 22:05:03 +01001798 if (touch->num_tp == 0)
Derek Foreman4c93c082015-04-30 16:45:41 -05001799 weston_touch_set_focus(touch, NULL);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001800 break;
1801 }
1802}
1803
Jonas Ådahl1679f232014-04-12 09:39:51 +02001804WL_EXPORT void
1805notify_touch_frame(struct weston_seat *seat)
1806{
Derek Foreman1281a362015-07-31 16:55:32 -05001807 struct weston_touch *touch = weston_seat_get_touch(seat);
Jonas Ådahl1679f232014-04-12 09:39:51 +02001808 struct weston_touch_grab *grab = touch->grab;
1809
1810 grab->interface->frame(grab);
1811}
1812
Derek Foreman3cc004a2015-11-06 15:56:09 -06001813WL_EXPORT void
1814notify_touch_cancel(struct weston_seat *seat)
1815{
1816 struct weston_touch *touch = weston_seat_get_touch(seat);
1817 struct weston_touch_grab *grab = touch->grab;
1818
1819 grab->interface->cancel(grab);
1820}
1821
Pekka Paalanen8274d902014-08-06 19:36:51 +03001822static int
1823pointer_cursor_surface_get_label(struct weston_surface *surface,
1824 char *buf, size_t len)
1825{
1826 return snprintf(buf, len, "cursor");
1827}
1828
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001829static void
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001830pointer_cursor_surface_configure(struct weston_surface *es,
Jason Ekstrand918f2dd2013-12-02 21:01:53 -06001831 int32_t dx, int32_t dy)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001832{
Kristian Høgsberg195b8692013-05-08 15:02:05 -04001833 struct weston_pointer *pointer = es->configure_private;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001834 int x, y;
1835
Jason Ekstrand918f2dd2013-12-02 21:01:53 -06001836 if (es->width == 0)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001837 return;
1838
Jason Ekstranda7af7042013-10-12 22:38:11 -05001839 assert(es == pointer->sprite->surface);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001840
Kristian Høgsberg195b8692013-05-08 15:02:05 -04001841 pointer->hotspot_x -= dx;
1842 pointer->hotspot_y -= dy;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001843
Kristian Høgsberg195b8692013-05-08 15:02:05 -04001844 x = wl_fixed_to_int(pointer->x) - pointer->hotspot_x;
1845 y = wl_fixed_to_int(pointer->y) - pointer->hotspot_y;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001846
Jason Ekstrand918f2dd2013-12-02 21:01:53 -06001847 weston_view_set_position(pointer->sprite, x, y);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001848
1849 empty_region(&es->pending.input);
Ander Conselvan de Oliveira23900f72014-01-31 16:07:51 +02001850 empty_region(&es->input);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001851
1852 if (!weston_surface_is_mapped(es)) {
Giulio Camuffo412e6a52014-07-09 22:12:56 +03001853 weston_layer_entry_insert(&es->compositor->cursor_layer.view_list,
1854 &pointer->sprite->layer_link);
Jason Ekstranda7af7042013-10-12 22:38:11 -05001855 weston_view_update_transform(pointer->sprite);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001856 }
1857}
1858
1859static void
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001860pointer_set_cursor(struct wl_client *client, struct wl_resource *resource,
1861 uint32_t serial, struct wl_resource *surface_resource,
1862 int32_t x, int32_t y)
1863{
Jason Ekstrand44a38632013-06-14 10:08:00 -05001864 struct weston_pointer *pointer = wl_resource_get_user_data(resource);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001865 struct weston_surface *surface = NULL;
1866
1867 if (surface_resource)
Jason Ekstrand0f2ef7e2013-06-14 10:07:53 -05001868 surface = wl_resource_get_user_data(surface_resource);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001869
Kristian Høgsberg195b8692013-05-08 15:02:05 -04001870 if (pointer->focus == NULL)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001871 return;
Jason Ekstranda7af7042013-10-12 22:38:11 -05001872 /* pointer->focus->surface->resource can be NULL. Surfaces like the
Giulio Camuffo1fd4b012013-06-20 18:13:07 +02001873 black_surface used in shell.c for fullscreen don't have
1874 a resource, but can still have focus */
Jason Ekstranda7af7042013-10-12 22:38:11 -05001875 if (pointer->focus->surface->resource == NULL)
Giulio Camuffo1fd4b012013-06-20 18:13:07 +02001876 return;
Jason Ekstranda7af7042013-10-12 22:38:11 -05001877 if (wl_resource_get_client(pointer->focus->surface->resource) != client)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001878 return;
Kristian Høgsberg195b8692013-05-08 15:02:05 -04001879 if (pointer->focus_serial - serial > UINT32_MAX / 2)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001880 return;
1881
Derek Foreman4e53c532015-03-23 10:55:32 -05001882 if (!surface) {
1883 if (pointer->sprite)
1884 pointer_unmap_sprite(pointer);
1885 return;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001886 }
1887
Jonas Ådahlb4070242015-03-18 15:08:03 +08001888 if (pointer->sprite && pointer->sprite->surface == surface &&
1889 pointer->hotspot_x == x && pointer->hotspot_y == y)
1890 return;
1891
Derek Foreman4e53c532015-03-23 10:55:32 -05001892 if (!pointer->sprite || pointer->sprite->surface != surface) {
1893 if (weston_surface_set_role(surface, "wl_pointer-cursor",
1894 resource,
1895 WL_POINTER_ERROR_ROLE) < 0)
1896 return;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001897
Derek Foreman4e53c532015-03-23 10:55:32 -05001898 if (pointer->sprite)
1899 pointer_unmap_sprite(pointer);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001900
Derek Foreman4e53c532015-03-23 10:55:32 -05001901 wl_signal_add(&surface->destroy_signal,
1902 &pointer->sprite_destroy_listener);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001903
Derek Foreman4e53c532015-03-23 10:55:32 -05001904 surface->configure = pointer_cursor_surface_configure;
1905 surface->configure_private = pointer;
1906 weston_surface_set_label_func(surface,
1907 pointer_cursor_surface_get_label);
1908 pointer->sprite = weston_view_create(surface);
1909 }
1910
Kristian Høgsberg195b8692013-05-08 15:02:05 -04001911 pointer->hotspot_x = x;
1912 pointer->hotspot_y = y;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001913
Jonas Ådahl16fe4dc2014-09-08 19:33:41 +02001914 if (surface->buffer_ref.buffer) {
Jason Ekstrand918f2dd2013-12-02 21:01:53 -06001915 pointer_cursor_surface_configure(surface, 0, 0);
Jonas Ådahl16fe4dc2014-09-08 19:33:41 +02001916 weston_view_schedule_repaint(pointer->sprite);
1917 }
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001918}
1919
Kristian Høgsberg69e25fc2013-08-13 20:11:02 +01001920static void
1921pointer_release(struct wl_client *client, struct wl_resource *resource)
1922{
1923 wl_resource_destroy(resource);
1924}
1925
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001926static const struct wl_pointer_interface pointer_interface = {
Kristian Høgsberg69e25fc2013-08-13 20:11:02 +01001927 pointer_set_cursor,
1928 pointer_release
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001929};
1930
1931static void
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001932seat_get_pointer(struct wl_client *client, struct wl_resource *resource,
1933 uint32_t id)
1934{
Jason Ekstrand44a38632013-06-14 10:08:00 -05001935 struct weston_seat *seat = wl_resource_get_user_data(resource);
Derek Foreman1281a362015-07-31 16:55:32 -05001936 /* We use the pointer_state directly, which means we'll
1937 * give a wl_pointer if the seat has ever had one - even though
1938 * the spec explicitly states that this request only takes effect
1939 * if the seat has the pointer capability.
1940 *
1941 * This prevents a race between the compositor sending new
1942 * capabilities and the client trying to use the old ones.
1943 */
1944 struct weston_pointer *pointer = seat->pointer_state;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001945 struct wl_resource *cr;
Jonas Ådahl2cbf2932015-07-22 12:05:38 +08001946 struct weston_pointer_client *pointer_client;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001947
Derek Foreman1281a362015-07-31 16:55:32 -05001948 if (!pointer)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001949 return;
1950
Jason Ekstranda85118c2013-06-27 20:17:02 -05001951 cr = wl_resource_create(client, &wl_pointer_interface,
1952 wl_resource_get_version(resource), id);
Kristian Høgsberg0ff79082013-08-06 16:46:25 -07001953 if (cr == NULL) {
1954 wl_client_post_no_memory(client);
1955 return;
1956 }
1957
Jonas Ådahl2cbf2932015-07-22 12:05:38 +08001958 pointer_client = weston_pointer_ensure_pointer_client(pointer, client);
1959 if (!pointer_client) {
1960 wl_client_post_no_memory(client);
1961 return;
1962 }
1963
1964 wl_list_insert(&pointer_client->pointer_resources,
1965 wl_resource_get_link(cr));
Derek Foreman1281a362015-07-31 16:55:32 -05001966 wl_resource_set_implementation(cr, &pointer_interface, pointer,
Jonas Ådahl2cbf2932015-07-22 12:05:38 +08001967 unbind_pointer_client_resource);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001968
Derek Foreman1281a362015-07-31 16:55:32 -05001969 if (pointer->focus && pointer->focus->surface->resource &&
1970 wl_resource_get_client(pointer->focus->surface->resource) == client) {
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001971 wl_fixed_t sx, sy;
1972
Derek Foreman1281a362015-07-31 16:55:32 -05001973 weston_view_from_global_fixed(pointer->focus,
1974 pointer->x,
1975 pointer->y,
Jason Ekstranda7af7042013-10-12 22:38:11 -05001976 &sx, &sy);
Neil Roberts96d790e2013-09-19 17:32:00 +01001977
Neil Roberts96d790e2013-09-19 17:32:00 +01001978 wl_pointer_send_enter(cr,
Derek Foreman1281a362015-07-31 16:55:32 -05001979 pointer->focus_serial,
1980 pointer->focus->surface->resource,
Neil Roberts96d790e2013-09-19 17:32:00 +01001981 sx, sy);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001982 }
1983}
1984
1985static void
Kristian Høgsberg69e25fc2013-08-13 20:11:02 +01001986keyboard_release(struct wl_client *client, struct wl_resource *resource)
1987{
1988 wl_resource_destroy(resource);
1989}
1990
1991static const struct wl_keyboard_interface keyboard_interface = {
1992 keyboard_release
1993};
1994
Derek Foreman280e7dd2014-10-03 13:13:42 -05001995static bool
Neil Roberts96d790e2013-09-19 17:32:00 +01001996should_send_modifiers_to_client(struct weston_seat *seat,
1997 struct wl_client *client)
1998{
Derek Foreman1281a362015-07-31 16:55:32 -05001999 struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
2000 struct weston_pointer *pointer = weston_seat_get_pointer(seat);
2001
2002 if (keyboard &&
2003 keyboard->focus &&
2004 keyboard->focus->resource &&
2005 wl_resource_get_client(keyboard->focus->resource) == client)
Derek Foreman280e7dd2014-10-03 13:13:42 -05002006 return true;
Neil Roberts96d790e2013-09-19 17:32:00 +01002007
Derek Foreman1281a362015-07-31 16:55:32 -05002008 if (pointer &&
2009 pointer->focus &&
2010 pointer->focus->surface->resource &&
2011 wl_resource_get_client(pointer->focus->surface->resource) == client)
Derek Foreman280e7dd2014-10-03 13:13:42 -05002012 return true;
Neil Roberts96d790e2013-09-19 17:32:00 +01002013
Derek Foreman280e7dd2014-10-03 13:13:42 -05002014 return false;
Neil Roberts96d790e2013-09-19 17:32:00 +01002015}
2016
Kristian Høgsberg69e25fc2013-08-13 20:11:02 +01002017static void
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002018seat_get_keyboard(struct wl_client *client, struct wl_resource *resource,
2019 uint32_t id)
2020{
Jason Ekstrand44a38632013-06-14 10:08:00 -05002021 struct weston_seat *seat = wl_resource_get_user_data(resource);
Derek Foreman1281a362015-07-31 16:55:32 -05002022 /* We use the keyboard_state directly, which means we'll
2023 * give a wl_keyboard if the seat has ever had one - even though
2024 * the spec explicitly states that this request only takes effect
2025 * if the seat has the keyboard capability.
2026 *
2027 * This prevents a race between the compositor sending new
2028 * capabilities and the client trying to use the old ones.
2029 */
2030 struct weston_keyboard *keyboard = seat->keyboard_state;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002031 struct wl_resource *cr;
2032
Derek Foreman345c9f32015-06-03 15:53:28 -05002033 if (!keyboard)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002034 return;
2035
Jason Ekstranda85118c2013-06-27 20:17:02 -05002036 cr = wl_resource_create(client, &wl_keyboard_interface,
2037 wl_resource_get_version(resource), id);
Kristian Høgsberg0ff79082013-08-06 16:46:25 -07002038 if (cr == NULL) {
2039 wl_client_post_no_memory(client);
2040 return;
2041 }
2042
Neil Roberts96d790e2013-09-19 17:32:00 +01002043 /* May be moved to focused list later by either
2044 * weston_keyboard_set_focus or directly if this client is already
2045 * focused */
Derek Foreman345c9f32015-06-03 15:53:28 -05002046 wl_list_insert(&keyboard->resource_list, wl_resource_get_link(cr));
Kristian Høgsberg69e25fc2013-08-13 20:11:02 +01002047 wl_resource_set_implementation(cr, &keyboard_interface,
2048 seat, unbind_resource);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002049
Jonny Lamb66a41a02014-08-12 14:58:25 +02002050 if (wl_resource_get_version(cr) >= WL_KEYBOARD_REPEAT_INFO_SINCE_VERSION) {
2051 wl_keyboard_send_repeat_info(cr,
2052 seat->compositor->kb_repeat_rate,
2053 seat->compositor->kb_repeat_delay);
2054 }
Jasper St. Pierred8c6aeb2014-08-04 13:43:24 -04002055
Matt Roper01a92732013-06-24 16:52:44 +01002056 if (seat->compositor->use_xkbcommon) {
2057 wl_keyboard_send_keymap(cr, WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1,
Jonas Ådahl7395ea02013-12-03 09:14:26 +01002058 keyboard->xkb_info->keymap_fd,
2059 keyboard->xkb_info->keymap_size);
Matt Roper01a92732013-06-24 16:52:44 +01002060 } else {
2061 int null_fd = open("/dev/null", O_RDONLY);
2062 wl_keyboard_send_keymap(cr, WL_KEYBOARD_KEYMAP_FORMAT_NO_KEYMAP,
2063 null_fd,
2064 0);
2065 close(null_fd);
2066 }
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002067
Neil Roberts96d790e2013-09-19 17:32:00 +01002068 if (should_send_modifiers_to_client(seat, client)) {
Derek Foreman345c9f32015-06-03 15:53:28 -05002069 send_modifiers_to_resource(keyboard,
Neil Roberts96d790e2013-09-19 17:32:00 +01002070 cr,
Derek Foreman345c9f32015-06-03 15:53:28 -05002071 keyboard->focus_serial);
Neil Roberts96d790e2013-09-19 17:32:00 +01002072 }
2073
Derek Foreman345c9f32015-06-03 15:53:28 -05002074 if (keyboard->focus && keyboard->focus->resource &&
2075 wl_resource_get_client(keyboard->focus->resource) == client) {
Neil Roberts96d790e2013-09-19 17:32:00 +01002076 struct weston_surface *surface =
Derek Foreman345c9f32015-06-03 15:53:28 -05002077 (struct weston_surface *)keyboard->focus;
Neil Roberts96d790e2013-09-19 17:32:00 +01002078
2079 wl_list_remove(wl_resource_get_link(cr));
Derek Foreman345c9f32015-06-03 15:53:28 -05002080 wl_list_insert(&keyboard->focus_resource_list,
Neil Roberts96d790e2013-09-19 17:32:00 +01002081 wl_resource_get_link(cr));
2082 wl_keyboard_send_enter(cr,
Derek Foreman345c9f32015-06-03 15:53:28 -05002083 keyboard->focus_serial,
Neil Roberts96d790e2013-09-19 17:32:00 +01002084 surface->resource,
Derek Foreman345c9f32015-06-03 15:53:28 -05002085 &keyboard->keys);
Neil Roberts96d790e2013-09-19 17:32:00 +01002086
2087 /* If this is the first keyboard resource for this
2088 * client... */
Derek Foreman345c9f32015-06-03 15:53:28 -05002089 if (keyboard->focus_resource_list.prev ==
Neil Roberts96d790e2013-09-19 17:32:00 +01002090 wl_resource_get_link(cr))
2091 wl_data_device_set_keyboard_focus(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002092 }
2093}
2094
2095static void
Kristian Høgsberg69e25fc2013-08-13 20:11:02 +01002096touch_release(struct wl_client *client, struct wl_resource *resource)
2097{
2098 wl_resource_destroy(resource);
2099}
2100
2101static const struct wl_touch_interface touch_interface = {
2102 touch_release
2103};
2104
2105static void
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002106seat_get_touch(struct wl_client *client, struct wl_resource *resource,
2107 uint32_t id)
2108{
Jason Ekstrand44a38632013-06-14 10:08:00 -05002109 struct weston_seat *seat = wl_resource_get_user_data(resource);
Derek Foreman1281a362015-07-31 16:55:32 -05002110 /* We use the touch_state directly, which means we'll
2111 * give a wl_touch if the seat has ever had one - even though
2112 * the spec explicitly states that this request only takes effect
2113 * if the seat has the touch capability.
2114 *
2115 * This prevents a race between the compositor sending new
2116 * capabilities and the client trying to use the old ones.
2117 */
2118 struct weston_touch *touch = seat->touch_state;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002119 struct wl_resource *cr;
2120
Derek Foreman1281a362015-07-31 16:55:32 -05002121 if (!touch)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002122 return;
2123
Jason Ekstranda85118c2013-06-27 20:17:02 -05002124 cr = wl_resource_create(client, &wl_touch_interface,
2125 wl_resource_get_version(resource), id);
Kristian Høgsberg0ff79082013-08-06 16:46:25 -07002126 if (cr == NULL) {
2127 wl_client_post_no_memory(client);
2128 return;
2129 }
2130
Derek Foreman1281a362015-07-31 16:55:32 -05002131 if (touch->focus &&
2132 wl_resource_get_client(touch->focus->surface->resource) == client) {
Chokshi, Mituld6697142015-10-09 08:28:47 +00002133 wl_list_insert(&touch->focus_resource_list,
Neil Roberts96d790e2013-09-19 17:32:00 +01002134 wl_resource_get_link(cr));
2135 } else {
Chokshi, Mituld6697142015-10-09 08:28:47 +00002136 wl_list_insert(&touch->resource_list,
Neil Roberts96d790e2013-09-19 17:32:00 +01002137 wl_resource_get_link(cr));
2138 }
Kristian Høgsberg69e25fc2013-08-13 20:11:02 +01002139 wl_resource_set_implementation(cr, &touch_interface,
2140 seat, unbind_resource);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002141}
2142
2143static const struct wl_seat_interface seat_interface = {
2144 seat_get_pointer,
2145 seat_get_keyboard,
2146 seat_get_touch,
2147};
2148
2149static void
2150bind_seat(struct wl_client *client, void *data, uint32_t version, uint32_t id)
2151{
Kristian Høgsberge3148752013-05-06 23:19:49 -04002152 struct weston_seat *seat = data;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002153 struct wl_resource *resource;
2154 enum wl_seat_capability caps = 0;
2155
Jason Ekstranda85118c2013-06-27 20:17:02 -05002156 resource = wl_resource_create(client,
Derek Foreman1909c102015-11-26 14:17:47 -06002157 &wl_seat_interface, version, id);
Jason Ekstrand44a38632013-06-14 10:08:00 -05002158 wl_list_insert(&seat->base_resource_list, wl_resource_get_link(resource));
Jason Ekstranda85118c2013-06-27 20:17:02 -05002159 wl_resource_set_implementation(resource, &seat_interface, data,
2160 unbind_resource);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002161
Derek Foreman1281a362015-07-31 16:55:32 -05002162 if (weston_seat_get_pointer(seat))
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002163 caps |= WL_SEAT_CAPABILITY_POINTER;
Derek Foreman1281a362015-07-31 16:55:32 -05002164 if (weston_seat_get_keyboard(seat))
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002165 caps |= WL_SEAT_CAPABILITY_KEYBOARD;
Derek Foreman1281a362015-07-31 16:55:32 -05002166 if (weston_seat_get_touch(seat))
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002167 caps |= WL_SEAT_CAPABILITY_TOUCH;
2168
2169 wl_seat_send_capabilities(resource, caps);
Jasper St. Pierre0013a292014-08-07 16:43:11 -04002170 if (version >= WL_SEAT_NAME_SINCE_VERSION)
Rob Bradforde445ae62013-05-31 18:09:51 +01002171 wl_seat_send_name(resource, seat->seat_name);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002172}
2173
Rob Bradford382ff462013-06-24 16:52:45 +01002174#ifdef ENABLE_XKBCOMMON
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002175int
2176weston_compositor_xkb_init(struct weston_compositor *ec,
2177 struct xkb_rule_names *names)
2178{
Rob Bradford382ff462013-06-24 16:52:45 +01002179 ec->use_xkbcommon = 1;
Matt Roper01a92732013-06-24 16:52:44 +01002180
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002181 if (ec->xkb_context == NULL) {
2182 ec->xkb_context = xkb_context_new(0);
2183 if (ec->xkb_context == NULL) {
2184 weston_log("failed to create XKB context\n");
2185 return -1;
2186 }
2187 }
2188
2189 if (names)
2190 ec->xkb_names = *names;
2191 if (!ec->xkb_names.rules)
2192 ec->xkb_names.rules = strdup("evdev");
2193 if (!ec->xkb_names.model)
2194 ec->xkb_names.model = strdup("pc105");
2195 if (!ec->xkb_names.layout)
2196 ec->xkb_names.layout = strdup("us");
2197
2198 return 0;
2199}
2200
Stefan Schmidtfda26522013-09-17 10:54:09 +01002201static void
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00002202weston_xkb_info_destroy(struct weston_xkb_info *xkb_info)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002203{
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00002204 if (--xkb_info->ref_count > 0)
2205 return;
2206
Ran Benitac9c74152014-08-19 23:59:52 +03002207 xkb_keymap_unref(xkb_info->keymap);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002208
2209 if (xkb_info->keymap_area)
2210 munmap(xkb_info->keymap_area, xkb_info->keymap_size);
2211 if (xkb_info->keymap_fd >= 0)
2212 close(xkb_info->keymap_fd);
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00002213 free(xkb_info);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002214}
2215
2216void
2217weston_compositor_xkb_destroy(struct weston_compositor *ec)
2218{
Matt Roper01a92732013-06-24 16:52:44 +01002219 /*
2220 * If we're operating in raw keyboard mode, we never initialized
2221 * libxkbcommon so there's no cleanup to do either.
2222 */
2223 if (!ec->use_xkbcommon)
2224 return;
2225
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002226 free((char *) ec->xkb_names.rules);
2227 free((char *) ec->xkb_names.model);
2228 free((char *) ec->xkb_names.layout);
2229 free((char *) ec->xkb_names.variant);
2230 free((char *) ec->xkb_names.options);
Stefan Schmidtfda26522013-09-17 10:54:09 +01002231
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00002232 if (ec->xkb_info)
2233 weston_xkb_info_destroy(ec->xkb_info);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002234 xkb_context_unref(ec->xkb_context);
2235}
2236
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00002237static struct weston_xkb_info *
2238weston_xkb_info_create(struct xkb_keymap *keymap)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002239{
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00002240 struct weston_xkb_info *xkb_info = zalloc(sizeof *xkb_info);
2241 if (xkb_info == NULL)
2242 return NULL;
2243
Ran Benita2e1968f2014-08-19 23:59:51 +03002244 xkb_info->keymap = xkb_keymap_ref(keymap);
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00002245 xkb_info->ref_count = 1;
2246
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002247 char *keymap_str;
2248
Ran Benita2e1968f2014-08-19 23:59:51 +03002249 xkb_info->shift_mod = xkb_keymap_mod_get_index(xkb_info->keymap,
2250 XKB_MOD_NAME_SHIFT);
2251 xkb_info->caps_mod = xkb_keymap_mod_get_index(xkb_info->keymap,
2252 XKB_MOD_NAME_CAPS);
2253 xkb_info->ctrl_mod = xkb_keymap_mod_get_index(xkb_info->keymap,
2254 XKB_MOD_NAME_CTRL);
2255 xkb_info->alt_mod = xkb_keymap_mod_get_index(xkb_info->keymap,
2256 XKB_MOD_NAME_ALT);
2257 xkb_info->mod2_mod = xkb_keymap_mod_get_index(xkb_info->keymap,
2258 "Mod2");
2259 xkb_info->mod3_mod = xkb_keymap_mod_get_index(xkb_info->keymap,
2260 "Mod3");
2261 xkb_info->super_mod = xkb_keymap_mod_get_index(xkb_info->keymap,
2262 XKB_MOD_NAME_LOGO);
2263 xkb_info->mod5_mod = xkb_keymap_mod_get_index(xkb_info->keymap,
2264 "Mod5");
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002265
Ran Benita2e1968f2014-08-19 23:59:51 +03002266 xkb_info->num_led = xkb_keymap_led_get_index(xkb_info->keymap,
2267 XKB_LED_NAME_NUM);
2268 xkb_info->caps_led = xkb_keymap_led_get_index(xkb_info->keymap,
2269 XKB_LED_NAME_CAPS);
2270 xkb_info->scroll_led = xkb_keymap_led_get_index(xkb_info->keymap,
2271 XKB_LED_NAME_SCROLL);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002272
Ran Benita2e1968f2014-08-19 23:59:51 +03002273 keymap_str = xkb_keymap_get_as_string(xkb_info->keymap,
2274 XKB_KEYMAP_FORMAT_TEXT_V1);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002275 if (keymap_str == NULL) {
2276 weston_log("failed to get string version of keymap\n");
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00002277 goto err_keymap;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002278 }
2279 xkb_info->keymap_size = strlen(keymap_str) + 1;
2280
2281 xkb_info->keymap_fd = os_create_anonymous_file(xkb_info->keymap_size);
2282 if (xkb_info->keymap_fd < 0) {
2283 weston_log("creating a keymap file for %lu bytes failed: %m\n",
2284 (unsigned long) xkb_info->keymap_size);
2285 goto err_keymap_str;
2286 }
2287
2288 xkb_info->keymap_area = mmap(NULL, xkb_info->keymap_size,
2289 PROT_READ | PROT_WRITE,
2290 MAP_SHARED, xkb_info->keymap_fd, 0);
2291 if (xkb_info->keymap_area == MAP_FAILED) {
2292 weston_log("failed to mmap() %lu bytes\n",
2293 (unsigned long) xkb_info->keymap_size);
2294 goto err_dev_zero;
2295 }
2296 strcpy(xkb_info->keymap_area, keymap_str);
2297 free(keymap_str);
2298
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00002299 return xkb_info;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002300
2301err_dev_zero:
2302 close(xkb_info->keymap_fd);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002303err_keymap_str:
2304 free(keymap_str);
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00002305err_keymap:
Ran Benita2e1968f2014-08-19 23:59:51 +03002306 xkb_keymap_unref(xkb_info->keymap);
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00002307 free(xkb_info);
2308 return NULL;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002309}
2310
2311static int
2312weston_compositor_build_global_keymap(struct weston_compositor *ec)
2313{
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00002314 struct xkb_keymap *keymap;
2315
2316 if (ec->xkb_info != NULL)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002317 return 0;
2318
Ran Benita2e1968f2014-08-19 23:59:51 +03002319 keymap = xkb_keymap_new_from_names(ec->xkb_context,
2320 &ec->xkb_names,
2321 0);
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00002322 if (keymap == NULL) {
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002323 weston_log("failed to compile global XKB keymap\n");
2324 weston_log(" tried rules %s, model %s, layout %s, variant %s, "
2325 "options %s\n",
2326 ec->xkb_names.rules, ec->xkb_names.model,
2327 ec->xkb_names.layout, ec->xkb_names.variant,
2328 ec->xkb_names.options);
2329 return -1;
2330 }
2331
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00002332 ec->xkb_info = weston_xkb_info_create(keymap);
Rui Matos73d93952013-10-24 19:28:41 +02002333 xkb_keymap_unref(keymap);
Stefan Schmidtfda26522013-09-17 10:54:09 +01002334 if (ec->xkb_info == NULL)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002335 return -1;
2336
2337 return 0;
2338}
Rob Bradford382ff462013-06-24 16:52:45 +01002339#else
2340int
2341weston_compositor_xkb_init(struct weston_compositor *ec,
2342 struct xkb_rule_names *names)
2343{
2344 return 0;
2345}
2346
2347void
2348weston_compositor_xkb_destroy(struct weston_compositor *ec)
2349{
2350}
2351#endif
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002352
Rui Matos65196bc2013-10-10 19:44:19 +02002353WL_EXPORT void
2354weston_seat_update_keymap(struct weston_seat *seat, struct xkb_keymap *keymap)
2355{
Derek Foreman1281a362015-07-31 16:55:32 -05002356 struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
2357
2358 if (!keyboard || !keymap)
Rui Matos65196bc2013-10-10 19:44:19 +02002359 return;
2360
2361#ifdef ENABLE_XKBCOMMON
2362 if (!seat->compositor->use_xkbcommon)
2363 return;
2364
Derek Foreman1281a362015-07-31 16:55:32 -05002365 xkb_keymap_unref(keyboard->pending_keymap);
2366 keyboard->pending_keymap = xkb_keymap_ref(keymap);
Rui Matos65196bc2013-10-10 19:44:19 +02002367
Derek Foreman1281a362015-07-31 16:55:32 -05002368 if (keyboard->keys.size == 0)
Rui Matos65196bc2013-10-10 19:44:19 +02002369 update_keymap(seat);
2370#endif
2371}
2372
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002373WL_EXPORT int
2374weston_seat_init_keyboard(struct weston_seat *seat, struct xkb_keymap *keymap)
2375{
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04002376 struct weston_keyboard *keyboard;
2377
Derek Foreman1281a362015-07-31 16:55:32 -05002378 if (seat->keyboard_state) {
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002379 seat->keyboard_device_count += 1;
2380 if (seat->keyboard_device_count == 1)
2381 seat_send_updated_caps(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002382 return 0;
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002383 }
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002384
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04002385 keyboard = weston_keyboard_create();
2386 if (keyboard == NULL) {
2387 weston_log("failed to allocate weston keyboard struct\n");
2388 return -1;
2389 }
2390
Jonas Ådahl7395ea02013-12-03 09:14:26 +01002391#ifdef ENABLE_XKBCOMMON
2392 if (seat->compositor->use_xkbcommon) {
2393 if (keymap != NULL) {
2394 keyboard->xkb_info = weston_xkb_info_create(keymap);
2395 if (keyboard->xkb_info == NULL)
Ander Conselvan de Oliveira4d363cf2014-01-31 17:35:45 +02002396 goto err;
Jonas Ådahl7395ea02013-12-03 09:14:26 +01002397 } else {
2398 if (weston_compositor_build_global_keymap(seat->compositor) < 0)
Ander Conselvan de Oliveira4d363cf2014-01-31 17:35:45 +02002399 goto err;
Jonas Ådahl7395ea02013-12-03 09:14:26 +01002400 keyboard->xkb_info = seat->compositor->xkb_info;
2401 keyboard->xkb_info->ref_count++;
2402 }
2403
2404 keyboard->xkb_state.state = xkb_state_new(keyboard->xkb_info->keymap);
2405 if (keyboard->xkb_state.state == NULL) {
2406 weston_log("failed to initialise XKB state\n");
Ander Conselvan de Oliveira4d363cf2014-01-31 17:35:45 +02002407 goto err;
Jonas Ådahl7395ea02013-12-03 09:14:26 +01002408 }
2409
2410 keyboard->xkb_state.leds = 0;
2411 }
2412#endif
2413
Derek Foreman1281a362015-07-31 16:55:32 -05002414 seat->keyboard_state = keyboard;
Ander Conselvan de Oliveira4d363cf2014-01-31 17:35:45 +02002415 seat->keyboard_device_count = 1;
2416 keyboard->seat = seat;
2417
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04002418 seat_send_updated_caps(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002419
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002420 return 0;
Ander Conselvan de Oliveira4d363cf2014-01-31 17:35:45 +02002421
2422err:
2423 if (keyboard->xkb_info)
2424 weston_xkb_info_destroy(keyboard->xkb_info);
2425 free(keyboard);
2426
2427 return -1;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002428}
2429
Jonas Ådahl91fed542013-12-03 09:14:27 +01002430static void
2431weston_keyboard_reset_state(struct weston_keyboard *keyboard)
2432{
2433 struct weston_seat *seat = keyboard->seat;
2434 struct xkb_state *state;
2435
2436#ifdef ENABLE_XKBCOMMON
2437 if (seat->compositor->use_xkbcommon) {
2438 state = xkb_state_new(keyboard->xkb_info->keymap);
2439 if (!state) {
2440 weston_log("failed to reset XKB state\n");
2441 return;
2442 }
2443 xkb_state_unref(keyboard->xkb_state.state);
2444 keyboard->xkb_state.state = state;
2445
2446 keyboard->xkb_state.leds = 0;
2447 }
2448#endif
2449
2450 seat->modifier_state = 0;
2451}
2452
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002453WL_EXPORT void
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002454weston_seat_release_keyboard(struct weston_seat *seat)
2455{
2456 seat->keyboard_device_count--;
Derek Foremand621df22014-11-19 11:04:12 -06002457 assert(seat->keyboard_device_count >= 0);
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002458 if (seat->keyboard_device_count == 0) {
Derek Foreman1281a362015-07-31 16:55:32 -05002459 weston_keyboard_set_focus(seat->keyboard_state, NULL);
2460 weston_keyboard_cancel_grab(seat->keyboard_state);
2461 weston_keyboard_reset_state(seat->keyboard_state);
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002462 seat_send_updated_caps(seat);
2463 }
2464}
2465
2466WL_EXPORT void
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002467weston_seat_init_pointer(struct weston_seat *seat)
2468{
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04002469 struct weston_pointer *pointer;
2470
Derek Foreman1281a362015-07-31 16:55:32 -05002471 if (seat->pointer_state) {
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002472 seat->pointer_device_count += 1;
2473 if (seat->pointer_device_count == 1)
2474 seat_send_updated_caps(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002475 return;
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002476 }
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002477
Giulio Camuffocdb4d292013-11-14 23:42:53 +01002478 pointer = weston_pointer_create(seat);
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04002479 if (pointer == NULL)
2480 return;
2481
Derek Foreman1281a362015-07-31 16:55:32 -05002482 seat->pointer_state = pointer;
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002483 seat->pointer_device_count = 1;
2484 pointer->seat = seat;
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04002485
2486 seat_send_updated_caps(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002487}
2488
2489WL_EXPORT void
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002490weston_seat_release_pointer(struct weston_seat *seat)
2491{
Derek Foreman1281a362015-07-31 16:55:32 -05002492 struct weston_pointer *pointer = seat->pointer_state;
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002493
2494 seat->pointer_device_count--;
2495 if (seat->pointer_device_count == 0) {
Derek Foremanf9318d12015-05-11 15:40:11 -05002496 weston_pointer_clear_focus(pointer);
Jonas Ådahl1ea343e2013-10-25 23:18:05 +02002497 weston_pointer_cancel_grab(pointer);
Jonas Ådahl630bae82013-10-17 23:04:06 +02002498
Jonas Ådahla4932742013-10-17 23:04:07 +02002499 if (pointer->sprite)
2500 pointer_unmap_sprite(pointer);
2501
Jonas Ådahl3e12e632013-12-02 22:05:05 +01002502 weston_pointer_reset_state(pointer);
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002503 seat_send_updated_caps(seat);
Derek Foremanfd5ca512015-01-07 15:00:25 -06002504
2505 /* seat->pointer is intentionally not destroyed so that
2506 * a newly attached pointer on this seat will retain
2507 * the previous cursor co-ordinates.
2508 */
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002509 }
2510}
2511
2512WL_EXPORT void
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002513weston_seat_init_touch(struct weston_seat *seat)
2514{
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04002515 struct weston_touch *touch;
2516
Derek Foreman1281a362015-07-31 16:55:32 -05002517 if (seat->touch_state) {
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002518 seat->touch_device_count += 1;
2519 if (seat->touch_device_count == 1)
2520 seat_send_updated_caps(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002521 return;
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002522 }
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002523
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04002524 touch = weston_touch_create();
2525 if (touch == NULL)
2526 return;
2527
Derek Foreman1281a362015-07-31 16:55:32 -05002528 seat->touch_state = touch;
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002529 seat->touch_device_count = 1;
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04002530 touch->seat = seat;
2531
2532 seat_send_updated_caps(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002533}
2534
2535WL_EXPORT void
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002536weston_seat_release_touch(struct weston_seat *seat)
2537{
2538 seat->touch_device_count--;
2539 if (seat->touch_device_count == 0) {
Derek Foreman1281a362015-07-31 16:55:32 -05002540 weston_touch_set_focus(seat->touch_state, NULL);
2541 weston_touch_cancel_grab(seat->touch_state);
2542 weston_touch_reset_state(seat->touch_state);
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002543 seat_send_updated_caps(seat);
2544 }
2545}
2546
2547WL_EXPORT void
Rob Bradford9af5f9e2013-05-31 18:09:50 +01002548weston_seat_init(struct weston_seat *seat, struct weston_compositor *ec,
2549 const char *seat_name)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002550{
Kristian Høgsberg4a2a2742013-05-06 22:24:50 -04002551 memset(seat, 0, sizeof *seat);
2552
Kristian Høgsberge3148752013-05-06 23:19:49 -04002553 seat->selection_data_source = NULL;
2554 wl_list_init(&seat->base_resource_list);
2555 wl_signal_init(&seat->selection_signal);
2556 wl_list_init(&seat->drag_resource_list);
Kristian Høgsberge3148752013-05-06 23:19:49 -04002557 wl_signal_init(&seat->destroy_signal);
Jason Ekstranda4ab5422014-04-02 19:53:45 -05002558 wl_signal_init(&seat->updated_caps_signal);
Kristian Høgsberg4a2a2742013-05-06 22:24:50 -04002559
Jasper St. Pierred8c6aeb2014-08-04 13:43:24 -04002560 seat->global = wl_global_create(ec->wl_display, &wl_seat_interface, 4,
Kristian Høgsberg919cddb2013-07-08 19:03:57 -04002561 seat, bind_seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002562
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002563 seat->compositor = ec;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002564 seat->modifier_state = 0;
Rob Bradford9af5f9e2013-05-31 18:09:50 +01002565 seat->seat_name = strdup(seat_name);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002566
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002567 wl_list_insert(ec->seat_list.prev, &seat->link);
2568
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002569 clipboard_create(seat);
2570
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002571 wl_signal_emit(&ec->seat_created_signal, seat);
2572}
2573
2574WL_EXPORT void
2575weston_seat_release(struct weston_seat *seat)
2576{
2577 wl_list_remove(&seat->link);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002578
Jonas Ådahl1afb2382014-01-03 19:46:51 +01002579 if (seat->saved_kbd_focus)
2580 wl_list_remove(&seat->saved_kbd_focus_listener.link);
2581
Derek Foreman1281a362015-07-31 16:55:32 -05002582 if (seat->pointer_state)
2583 weston_pointer_destroy(seat->pointer_state);
2584 if (seat->keyboard_state)
2585 weston_keyboard_destroy(seat->keyboard_state);
2586 if (seat->touch_state)
2587 weston_touch_destroy(seat->touch_state);
Kristian Høgsberg4a2a2742013-05-06 22:24:50 -04002588
Rob Bradford9af5f9e2013-05-31 18:09:50 +01002589 free (seat->seat_name);
2590
Kristian Høgsberg919cddb2013-07-08 19:03:57 -04002591 wl_global_destroy(seat->global);
Kristian Høgsbergaaadc772013-07-08 16:20:31 -04002592
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002593 wl_signal_emit(&seat->destroy_signal, seat);
2594}
Derek Foreman1281a362015-07-31 16:55:32 -05002595
2596/** Get a seat's keyboard pointer
2597 *
2598 * \param seat The seat to query
2599 * \return The seat's keyboard pointer, or NULL if no keyboard is present
2600 *
2601 * The keyboard pointer for a seat isn't freed when all keyboards are removed,
2602 * so it should only be used when the seat's keyboard_device_count is greater
2603 * than zero. This function does that test and only returns a pointer
2604 * when a keyboard is present.
2605 */
2606WL_EXPORT struct weston_keyboard *
2607weston_seat_get_keyboard(struct weston_seat *seat)
2608{
2609 if (!seat)
2610 return NULL;
2611
2612 if (seat->keyboard_device_count)
2613 return seat->keyboard_state;
2614
2615 return NULL;
2616}
2617
2618/** Get a seat's pointer pointer
2619 *
2620 * \param seat The seat to query
2621 * \return The seat's pointer pointer, or NULL if no pointer device is present
2622 *
2623 * The pointer pointer for a seat isn't freed when all mice are removed,
2624 * so it should only be used when the seat's pointer_device_count is greater
2625 * than zero. This function does that test and only returns a pointer
2626 * when a pointing device is present.
2627 */
2628WL_EXPORT struct weston_pointer *
2629weston_seat_get_pointer(struct weston_seat *seat)
2630{
2631 if (!seat)
2632 return NULL;
2633
2634 if (seat->pointer_device_count)
2635 return seat->pointer_state;
2636
2637 return NULL;
2638}
2639
2640/** Get a seat's touch pointer
2641 *
2642 * \param seat The seat to query
2643 * \return The seat's touch pointer, or NULL if no touch device is present
2644 *
2645 * The touch pointer for a seat isn't freed when all touch devices are removed,
2646 * so it should only be used when the seat's touch_device_count is greater
2647 * than zero. This function does that test and only returns a pointer
2648 * when a touch device is present.
2649 */
2650WL_EXPORT struct weston_touch *
2651weston_seat_get_touch(struct weston_seat *seat)
2652{
2653 if (!seat)
2654 return NULL;
2655
2656 if (seat->touch_device_count)
2657 return seat->touch_state;
2658
2659 return NULL;
2660}