blob: f5bb54e1c9ec9f576ca8e1c9bf62adcd923ae7eb [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,
336 uint32_t time, uint32_t axis, wl_fixed_t value)
337{
338 struct wl_resource *resource;
339 struct wl_list *resource_list;
340
Jonas Ådahl2cbf2932015-07-22 12:05:38 +0800341 if (!pointer->focus_client)
342 return;
343
344 resource_list = &pointer->focus_client->pointer_resources;
Jonas Ådahl0336ca02014-10-04 16:28:29 +0200345 wl_resource_for_each(resource, resource_list)
346 wl_pointer_send_axis(resource, time, axis, value);
347}
348
349static void
350default_grab_pointer_axis(struct weston_pointer_grab *grab,
351 uint32_t time, uint32_t axis, wl_fixed_t value)
352{
353 weston_pointer_send_axis(grab->pointer, time, axis, value);
354}
355
Jonas Ådahl1ea343e2013-10-25 23:18:05 +0200356static void
357default_grab_pointer_cancel(struct weston_pointer_grab *grab)
358{
359}
360
Kristian Høgsberg02bbabb2013-05-06 22:15:05 -0400361static const struct weston_pointer_grab_interface
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400362 default_pointer_grab_interface = {
Kristian Høgsbergb27901c2013-10-28 15:32:02 -0700363 default_grab_pointer_focus,
364 default_grab_pointer_motion,
365 default_grab_pointer_button,
Jonas Ådahl0336ca02014-10-04 16:28:29 +0200366 default_grab_pointer_axis,
Jonas Ådahl1ea343e2013-10-25 23:18:05 +0200367 default_grab_pointer_cancel,
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400368};
369
Kristian Høgsberge329f362013-05-06 22:19:57 -0400370static void
371default_grab_touch_down(struct weston_touch_grab *grab, uint32_t time,
Giulio Camuffo61ed7b62015-07-08 11:55:28 +0300372 int touch_id, wl_fixed_t x, wl_fixed_t y)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400373{
Kristian Høgsberge329f362013-05-06 22:19:57 -0400374 struct weston_touch *touch = grab->touch;
Rob Bradford880ebc72013-07-22 17:31:38 +0100375 struct wl_display *display = touch->seat->compositor->wl_display;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400376 uint32_t serial;
Neil Roberts96d790e2013-09-19 17:32:00 +0100377 struct wl_resource *resource;
378 struct wl_list *resource_list;
Giulio Camuffo61ed7b62015-07-08 11:55:28 +0300379 wl_fixed_t sx, sy;
380
381 weston_view_from_global_fixed(touch->focus, x, y, &sx, &sy);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400382
Neil Roberts96d790e2013-09-19 17:32:00 +0100383 resource_list = &touch->focus_resource_list;
384
385 if (!wl_list_empty(resource_list) && touch->focus) {
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400386 serial = wl_display_next_serial(display);
Neil Roberts96d790e2013-09-19 17:32:00 +0100387 wl_resource_for_each(resource, resource_list)
388 wl_touch_send_down(resource, serial, time,
Jason Ekstranda7af7042013-10-12 22:38:11 -0500389 touch->focus->surface->resource,
Neil Roberts96d790e2013-09-19 17:32:00 +0100390 touch_id, sx, sy);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400391 }
392}
393
Kristian Høgsberge329f362013-05-06 22:19:57 -0400394static void
395default_grab_touch_up(struct weston_touch_grab *grab,
396 uint32_t time, int touch_id)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400397{
Kristian Høgsberge329f362013-05-06 22:19:57 -0400398 struct weston_touch *touch = grab->touch;
Rob Bradford880ebc72013-07-22 17:31:38 +0100399 struct wl_display *display = touch->seat->compositor->wl_display;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400400 uint32_t serial;
Neil Roberts96d790e2013-09-19 17:32:00 +0100401 struct wl_resource *resource;
402 struct wl_list *resource_list;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400403
Neil Roberts96d790e2013-09-19 17:32:00 +0100404 resource_list = &touch->focus_resource_list;
405
406 if (!wl_list_empty(resource_list)) {
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400407 serial = wl_display_next_serial(display);
Neil Roberts96d790e2013-09-19 17:32:00 +0100408 wl_resource_for_each(resource, resource_list)
409 wl_touch_send_up(resource, serial, time, touch_id);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400410 }
411}
412
Kristian Høgsberge329f362013-05-06 22:19:57 -0400413static void
414default_grab_touch_motion(struct weston_touch_grab *grab, uint32_t time,
Giulio Camuffo61ed7b62015-07-08 11:55:28 +0300415 int touch_id, wl_fixed_t x, wl_fixed_t y)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400416{
Kristian Høgsberge329f362013-05-06 22:19:57 -0400417 struct weston_touch *touch = grab->touch;
Neil Roberts96d790e2013-09-19 17:32:00 +0100418 struct wl_resource *resource;
419 struct wl_list *resource_list;
Giulio Camuffo61ed7b62015-07-08 11:55:28 +0300420 wl_fixed_t sx, sy;
421
422 weston_view_from_global_fixed(touch->focus, x, y, &sx, &sy);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400423
Neil Roberts96d790e2013-09-19 17:32:00 +0100424 resource_list = &touch->focus_resource_list;
425
426 wl_resource_for_each(resource, resource_list) {
427 wl_touch_send_motion(resource, time,
Kristian Høgsberge329f362013-05-06 22:19:57 -0400428 touch_id, sx, sy);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400429 }
430}
431
Jonas Ådahl1ea343e2013-10-25 23:18:05 +0200432static void
Jonas Ådahl1679f232014-04-12 09:39:51 +0200433default_grab_touch_frame(struct weston_touch_grab *grab)
434{
435 struct wl_resource *resource;
436
437 wl_resource_for_each(resource, &grab->touch->focus_resource_list)
438 wl_touch_send_frame(resource);
439}
440
441static void
Jonas Ådahl1ea343e2013-10-25 23:18:05 +0200442default_grab_touch_cancel(struct weston_touch_grab *grab)
443{
444}
445
Kristian Høgsberge329f362013-05-06 22:19:57 -0400446static const struct weston_touch_grab_interface default_touch_grab_interface = {
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400447 default_grab_touch_down,
448 default_grab_touch_up,
Jonas Ådahl1ea343e2013-10-25 23:18:05 +0200449 default_grab_touch_motion,
Jonas Ådahl1679f232014-04-12 09:39:51 +0200450 default_grab_touch_frame,
Jonas Ådahl1ea343e2013-10-25 23:18:05 +0200451 default_grab_touch_cancel,
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400452};
453
454static void
Kristian Høgsbergb27901c2013-10-28 15:32:02 -0700455default_grab_keyboard_key(struct weston_keyboard_grab *grab,
456 uint32_t time, uint32_t key, uint32_t state)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400457{
Kristian Høgsberg29139d42013-04-18 15:25:39 -0400458 struct weston_keyboard *keyboard = grab->keyboard;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400459 struct wl_resource *resource;
Rob Bradford880ebc72013-07-22 17:31:38 +0100460 struct wl_display *display = keyboard->seat->compositor->wl_display;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400461 uint32_t serial;
Neil Roberts96d790e2013-09-19 17:32:00 +0100462 struct wl_list *resource_list;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400463
Neil Roberts96d790e2013-09-19 17:32:00 +0100464 resource_list = &keyboard->focus_resource_list;
465 if (!wl_list_empty(resource_list)) {
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400466 serial = wl_display_next_serial(display);
Neil Roberts96d790e2013-09-19 17:32:00 +0100467 wl_resource_for_each(resource, resource_list)
468 wl_keyboard_send_key(resource,
469 serial,
470 time,
471 key,
472 state);
473 }
474}
475
476static void
477send_modifiers_to_resource(struct weston_keyboard *keyboard,
478 struct wl_resource *resource,
479 uint32_t serial)
480{
481 wl_keyboard_send_modifiers(resource,
482 serial,
483 keyboard->modifiers.mods_depressed,
484 keyboard->modifiers.mods_latched,
485 keyboard->modifiers.mods_locked,
486 keyboard->modifiers.group);
487}
488
489static void
490send_modifiers_to_client_in_list(struct wl_client *client,
491 struct wl_list *list,
492 uint32_t serial,
493 struct weston_keyboard *keyboard)
494{
495 struct wl_resource *resource;
496
497 wl_resource_for_each(resource, list) {
498 if (wl_resource_get_client(resource) == client)
499 send_modifiers_to_resource(keyboard,
500 resource,
501 serial);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400502 }
503}
504
Jonas Ådahl2cbf2932015-07-22 12:05:38 +0800505static struct weston_pointer_client *
506find_pointer_client_for_surface(struct weston_pointer *pointer,
507 struct weston_surface *surface)
508{
509 struct wl_client *client;
510
511 if (!surface)
512 return NULL;
513
514 if (!surface->resource)
515 return NULL;
516
517 client = wl_resource_get_client(surface->resource);
518 return weston_pointer_get_pointer_client(pointer, client);
519}
520
521static struct weston_pointer_client *
522find_pointer_client_for_view(struct weston_pointer *pointer, struct weston_view *view)
523{
524 if (!view)
525 return NULL;
526
527 return find_pointer_client_for_surface(pointer, view->surface);
528}
529
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400530static struct wl_resource *
Kristian Høgsbergfe7aa902013-05-08 09:54:37 -0400531find_resource_for_surface(struct wl_list *list, struct weston_surface *surface)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400532{
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400533 if (!surface)
534 return NULL;
535
Jason Ekstrand44a38632013-06-14 10:08:00 -0500536 if (!surface->resource)
537 return NULL;
Stefan Schmidtfda26522013-09-17 10:54:09 +0100538
Jason Ekstrand44a38632013-06-14 10:08:00 -0500539 return wl_resource_find_for_client(list, wl_resource_get_client(surface->resource));
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400540}
541
542static void
Kristian Høgsbergb27901c2013-10-28 15:32:02 -0700543default_grab_keyboard_modifiers(struct weston_keyboard_grab *grab,
544 uint32_t serial, uint32_t mods_depressed,
545 uint32_t mods_latched,
546 uint32_t mods_locked, uint32_t group)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400547{
Kristian Høgsberg29139d42013-04-18 15:25:39 -0400548 struct weston_keyboard *keyboard = grab->keyboard;
Derek Foreman1281a362015-07-31 16:55:32 -0500549 struct weston_pointer *pointer =
550 weston_seat_get_pointer(grab->keyboard->seat);
Neil Roberts96d790e2013-09-19 17:32:00 +0100551 struct wl_resource *resource;
552 struct wl_list *resource_list;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400553
Neil Roberts96d790e2013-09-19 17:32:00 +0100554 resource_list = &keyboard->focus_resource_list;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400555
Neil Roberts96d790e2013-09-19 17:32:00 +0100556 wl_resource_for_each(resource, resource_list) {
557 wl_keyboard_send_modifiers(resource, serial, mods_depressed,
558 mods_latched, mods_locked, group);
559 }
Jason Ekstrand42133d42013-11-14 20:06:16 -0600560 if (pointer && pointer->focus && pointer->focus->surface->resource &&
561 pointer->focus->surface != keyboard->focus) {
Neil Roberts96d790e2013-09-19 17:32:00 +0100562 struct wl_client *pointer_client =
Jason Ekstranda7af7042013-10-12 22:38:11 -0500563 wl_resource_get_client(pointer->focus->surface->resource);
Neil Roberts96d790e2013-09-19 17:32:00 +0100564 send_modifiers_to_client_in_list(pointer_client,
565 &keyboard->resource_list,
566 serial,
567 keyboard);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400568 }
569}
570
Jonas Ådahl1ea343e2013-10-25 23:18:05 +0200571static void
572default_grab_keyboard_cancel(struct weston_keyboard_grab *grab)
573{
574}
575
Kristian Høgsberg29139d42013-04-18 15:25:39 -0400576static const struct weston_keyboard_grab_interface
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400577 default_keyboard_grab_interface = {
Kristian Høgsbergb27901c2013-10-28 15:32:02 -0700578 default_grab_keyboard_key,
579 default_grab_keyboard_modifiers,
Jonas Ådahl1ea343e2013-10-25 23:18:05 +0200580 default_grab_keyboard_cancel,
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400581};
582
Kristian Høgsberg195b8692013-05-08 15:02:05 -0400583static void
584pointer_unmap_sprite(struct weston_pointer *pointer)
585{
Pekka Paalanenc557ff72014-11-12 16:42:52 +0200586 struct weston_surface *surface = pointer->sprite->surface;
587
588 if (weston_surface_is_mapped(surface))
589 weston_surface_unmap(surface);
Kristian Høgsberg195b8692013-05-08 15:02:05 -0400590
591 wl_list_remove(&pointer->sprite_destroy_listener.link);
Pekka Paalanenc557ff72014-11-12 16:42:52 +0200592 surface->configure = NULL;
593 surface->configure_private = NULL;
Pekka Paalanen8274d902014-08-06 19:36:51 +0300594 weston_surface_set_label_func(surface, NULL);
Jason Ekstranda7af7042013-10-12 22:38:11 -0500595 weston_view_destroy(pointer->sprite);
Kristian Høgsberg195b8692013-05-08 15:02:05 -0400596 pointer->sprite = NULL;
597}
598
599static void
600pointer_handle_sprite_destroy(struct wl_listener *listener, void *data)
601{
602 struct weston_pointer *pointer =
603 container_of(listener, struct weston_pointer,
604 sprite_destroy_listener);
605
606 pointer->sprite = NULL;
607}
608
Jonas Ådahl3e12e632013-12-02 22:05:05 +0100609static void
610weston_pointer_reset_state(struct weston_pointer *pointer)
611{
612 pointer->button_count = 0;
613}
614
Ander Conselvan de Oliveiraf84327a2014-01-29 18:47:51 +0200615static void
616weston_pointer_handle_output_destroy(struct wl_listener *listener, void *data);
617
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400618WL_EXPORT struct weston_pointer *
Giulio Camuffocdb4d292013-11-14 23:42:53 +0100619weston_pointer_create(struct weston_seat *seat)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400620{
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400621 struct weston_pointer *pointer;
622
Peter Huttererf3d62272013-08-08 11:57:05 +1000623 pointer = zalloc(sizeof *pointer);
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400624 if (pointer == NULL)
625 return NULL;
626
Jonas Ådahl2cbf2932015-07-22 12:05:38 +0800627 wl_list_init(&pointer->pointer_clients);
Giulio Camuffocdb4d292013-11-14 23:42:53 +0100628 weston_pointer_set_default_grab(pointer,
629 seat->compositor->default_pointer_grab);
Giulio Camuffo576fe2a2013-11-20 18:00:24 +0100630 wl_list_init(&pointer->focus_resource_listener.link);
631 pointer->focus_resource_listener.notify = pointer_focus_resource_destroyed;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400632 pointer->default_grab.pointer = pointer;
633 pointer->grab = &pointer->default_grab;
Giulio Camuffo6fcb3782013-11-14 23:42:50 +0100634 wl_signal_init(&pointer->motion_signal);
Emilio Pozuelo Monfortaa7a4762013-11-19 11:37:15 +0100635 wl_signal_init(&pointer->focus_signal);
Giulio Camuffo576fe2a2013-11-20 18:00:24 +0100636 wl_list_init(&pointer->focus_view_listener.link);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400637
Kristian Høgsberg195b8692013-05-08 15:02:05 -0400638 pointer->sprite_destroy_listener.notify = pointer_handle_sprite_destroy;
639
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400640 /* FIXME: Pick better co-ords. */
641 pointer->x = wl_fixed_from_int(100);
642 pointer->y = wl_fixed_from_int(100);
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400643
Ander Conselvan de Oliveiraf84327a2014-01-29 18:47:51 +0200644 pointer->output_destroy_listener.notify =
645 weston_pointer_handle_output_destroy;
646 wl_signal_add(&seat->compositor->output_destroyed_signal,
647 &pointer->output_destroy_listener);
648
Derek Foremanf9318d12015-05-11 15:40:11 -0500649 pointer->sx = wl_fixed_from_int(-1000000);
650 pointer->sy = wl_fixed_from_int(-1000000);
651
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400652 return pointer;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400653}
654
655WL_EXPORT void
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400656weston_pointer_destroy(struct weston_pointer *pointer)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400657{
Kristian Høgsberg195b8692013-05-08 15:02:05 -0400658 if (pointer->sprite)
659 pointer_unmap_sprite(pointer);
660
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400661 /* XXX: What about pointer->resource_list? */
Neil Roberts96d790e2013-09-19 17:32:00 +0100662
Giulio Camuffo576fe2a2013-11-20 18:00:24 +0100663 wl_list_remove(&pointer->focus_resource_listener.link);
664 wl_list_remove(&pointer->focus_view_listener.link);
Ander Conselvan de Oliveiraf84327a2014-01-29 18:47:51 +0200665 wl_list_remove(&pointer->output_destroy_listener.link);
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400666 free(pointer);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400667}
668
Giulio Camuffocdb4d292013-11-14 23:42:53 +0100669void
670weston_pointer_set_default_grab(struct weston_pointer *pointer,
671 const struct weston_pointer_grab_interface *interface)
672{
673 if (interface)
674 pointer->default_grab.interface = interface;
675 else
676 pointer->default_grab.interface =
677 &default_pointer_grab_interface;
678}
679
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400680WL_EXPORT struct weston_keyboard *
681weston_keyboard_create(void)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400682{
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400683 struct weston_keyboard *keyboard;
684
Peter Huttererf3d62272013-08-08 11:57:05 +1000685 keyboard = zalloc(sizeof *keyboard);
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400686 if (keyboard == NULL)
Neil Roberts96d790e2013-09-19 17:32:00 +0100687 return NULL;
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400688
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400689 wl_list_init(&keyboard->resource_list);
Neil Roberts96d790e2013-09-19 17:32:00 +0100690 wl_list_init(&keyboard->focus_resource_list);
Giulio Camuffo576fe2a2013-11-20 18:00:24 +0100691 wl_list_init(&keyboard->focus_resource_listener.link);
692 keyboard->focus_resource_listener.notify = keyboard_focus_resource_destroyed;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400693 wl_array_init(&keyboard->keys);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400694 keyboard->default_grab.interface = &default_keyboard_grab_interface;
695 keyboard->default_grab.keyboard = keyboard;
696 keyboard->grab = &keyboard->default_grab;
697 wl_signal_init(&keyboard->focus_signal);
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400698
699 return keyboard;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400700}
701
Jonas Ådahl7395ea02013-12-03 09:14:26 +0100702static void
703weston_xkb_info_destroy(struct weston_xkb_info *xkb_info);
704
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400705WL_EXPORT void
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400706weston_keyboard_destroy(struct weston_keyboard *keyboard)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400707{
708 /* XXX: What about keyboard->resource_list? */
Neil Roberts96d790e2013-09-19 17:32:00 +0100709
Jonas Ådahl7395ea02013-12-03 09:14:26 +0100710#ifdef ENABLE_XKBCOMMON
711 if (keyboard->seat->compositor->use_xkbcommon) {
Ran Benitac9c74152014-08-19 23:59:52 +0300712 xkb_state_unref(keyboard->xkb_state.state);
Jonas Ådahl7395ea02013-12-03 09:14:26 +0100713 if (keyboard->xkb_info)
714 weston_xkb_info_destroy(keyboard->xkb_info);
Ran Benitac9c74152014-08-19 23:59:52 +0300715 xkb_keymap_unref(keyboard->pending_keymap);
Jonas Ådahl7395ea02013-12-03 09:14:26 +0100716 }
717#endif
718
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400719 wl_array_release(&keyboard->keys);
Giulio Camuffo576fe2a2013-11-20 18:00:24 +0100720 wl_list_remove(&keyboard->focus_resource_listener.link);
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400721 free(keyboard);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400722}
723
Jonas Ådahlcbfa7f72013-12-02 22:05:04 +0100724static void
725weston_touch_reset_state(struct weston_touch *touch)
726{
727 touch->num_tp = 0;
728}
729
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400730WL_EXPORT struct weston_touch *
731weston_touch_create(void)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400732{
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400733 struct weston_touch *touch;
734
Peter Huttererf3d62272013-08-08 11:57:05 +1000735 touch = zalloc(sizeof *touch);
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400736 if (touch == NULL)
737 return NULL;
738
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400739 wl_list_init(&touch->resource_list);
Neil Roberts96d790e2013-09-19 17:32:00 +0100740 wl_list_init(&touch->focus_resource_list);
Giulio Camuffo576fe2a2013-11-20 18:00:24 +0100741 wl_list_init(&touch->focus_view_listener.link);
742 touch->focus_view_listener.notify = touch_focus_view_destroyed;
743 wl_list_init(&touch->focus_resource_listener.link);
744 touch->focus_resource_listener.notify = touch_focus_resource_destroyed;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400745 touch->default_grab.interface = &default_touch_grab_interface;
746 touch->default_grab.touch = touch;
747 touch->grab = &touch->default_grab;
748 wl_signal_init(&touch->focus_signal);
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400749
750 return touch;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400751}
752
753WL_EXPORT void
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400754weston_touch_destroy(struct weston_touch *touch)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400755{
756 /* XXX: What about touch->resource_list? */
Neil Roberts96d790e2013-09-19 17:32:00 +0100757
Giulio Camuffo576fe2a2013-11-20 18:00:24 +0100758 wl_list_remove(&touch->focus_view_listener.link);
759 wl_list_remove(&touch->focus_resource_listener.link);
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400760 free(touch);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400761}
762
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400763static void
Kristian Høgsberge3148752013-05-06 23:19:49 -0400764seat_send_updated_caps(struct weston_seat *seat)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400765{
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400766 enum wl_seat_capability caps = 0;
Rob Bradford6e737f52013-09-06 17:48:19 +0100767 struct wl_resource *resource;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400768
Jonas Ådahld6e1c342013-10-17 23:04:05 +0200769 if (seat->pointer_device_count > 0)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400770 caps |= WL_SEAT_CAPABILITY_POINTER;
Jonas Ådahld6e1c342013-10-17 23:04:05 +0200771 if (seat->keyboard_device_count > 0)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400772 caps |= WL_SEAT_CAPABILITY_KEYBOARD;
Jonas Ådahld6e1c342013-10-17 23:04:05 +0200773 if (seat->touch_device_count > 0)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400774 caps |= WL_SEAT_CAPABILITY_TOUCH;
775
Rob Bradford6e737f52013-09-06 17:48:19 +0100776 wl_resource_for_each(resource, &seat->base_resource_list) {
777 wl_seat_send_capabilities(resource, caps);
Jason Ekstrand44a38632013-06-14 10:08:00 -0500778 }
Jason Ekstranda4ab5422014-04-02 19:53:45 -0500779 wl_signal_emit(&seat->updated_caps_signal, seat);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400780}
781
Derek Foremanf9318d12015-05-11 15:40:11 -0500782
783/** Clear the pointer focus
784 *
785 * \param pointer the pointer to clear focus for.
786 *
787 * This can be used to unset pointer focus and set the co-ordinates to the
788 * arbitrary values we use for the no focus case.
789 *
790 * There's no requirement to use this function. For example, passing the
791 * results of a weston_compositor_pick_view() directly to
792 * weston_pointer_set_focus() will do the right thing when no view is found.
793 */
794WL_EXPORT void
795weston_pointer_clear_focus(struct weston_pointer *pointer)
796{
797 weston_pointer_set_focus(pointer, NULL,
798 wl_fixed_from_int(-1000000),
799 wl_fixed_from_int(-1000000));
800}
801
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400802WL_EXPORT void
Kristian Høgsberg02bbabb2013-05-06 22:15:05 -0400803weston_pointer_set_focus(struct weston_pointer *pointer,
Jason Ekstranda7af7042013-10-12 22:38:11 -0500804 struct weston_view *view,
Kristian Høgsberg02bbabb2013-05-06 22:15:05 -0400805 wl_fixed_t sx, wl_fixed_t sy)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400806{
Jonas Ådahl2cbf2932015-07-22 12:05:38 +0800807 struct weston_pointer_client *pointer_client;
Derek Foreman1281a362015-07-31 16:55:32 -0500808 struct weston_keyboard *kbd = weston_seat_get_keyboard(pointer->seat);
Neil Roberts96d790e2013-09-19 17:32:00 +0100809 struct wl_resource *resource;
Jonas Ådahl2cbf2932015-07-22 12:05:38 +0800810 struct wl_resource *surface_resource;
Rob Bradford880ebc72013-07-22 17:31:38 +0100811 struct wl_display *display = pointer->seat->compositor->wl_display;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400812 uint32_t serial;
Neil Roberts96d790e2013-09-19 17:32:00 +0100813 struct wl_list *focus_resource_list;
Kristian Høgsbergdb1fccb2014-02-05 17:14:42 -0800814 int refocus = 0;
Jason Ekstranda7af7042013-10-12 22:38:11 -0500815
816 if ((!pointer->focus && view) ||
817 (pointer->focus && !view) ||
Kristian Høgsbergdb1fccb2014-02-05 17:14:42 -0800818 (pointer->focus && pointer->focus->surface != view->surface) ||
819 pointer->sx != sx || pointer->sy != sy)
820 refocus = 1;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400821
Jonas Ådahl2cbf2932015-07-22 12:05:38 +0800822 if (pointer->focus_client && refocus) {
823 focus_resource_list = &pointer->focus_client->pointer_resources;
824 if (!wl_list_empty(focus_resource_list)) {
825 serial = wl_display_next_serial(display);
826 surface_resource = pointer->focus->surface->resource;
827 wl_resource_for_each(resource, focus_resource_list) {
828 wl_pointer_send_leave(resource, serial,
829 surface_resource);
830 }
Neil Roberts96d790e2013-09-19 17:32:00 +0100831 }
832
Jonas Ådahl2cbf2932015-07-22 12:05:38 +0800833 pointer->focus_client = NULL;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400834 }
835
Jonas Ådahl2cbf2932015-07-22 12:05:38 +0800836 pointer_client = find_pointer_client_for_view(pointer, view);
837 if (pointer_client && refocus) {
838 struct wl_client *surface_client = pointer_client->client;
Neil Roberts96d790e2013-09-19 17:32:00 +0100839
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400840 serial = wl_display_next_serial(display);
Neil Roberts96d790e2013-09-19 17:32:00 +0100841
Jason Ekstranda7af7042013-10-12 22:38:11 -0500842 if (kbd && kbd->focus != view->surface)
Kristian Høgsbergcb406f12013-10-09 10:54:03 -0700843 send_modifiers_to_client_in_list(surface_client,
844 &kbd->resource_list,
845 serial,
846 kbd);
847
Jonas Ådahl2cbf2932015-07-22 12:05:38 +0800848 pointer->focus_client = pointer_client;
Neil Roberts96d790e2013-09-19 17:32:00 +0100849
Jonas Ådahl2cbf2932015-07-22 12:05:38 +0800850 focus_resource_list = &pointer->focus_client->pointer_resources;
Neil Roberts96d790e2013-09-19 17:32:00 +0100851 wl_resource_for_each(resource, focus_resource_list) {
852 wl_pointer_send_enter(resource,
853 serial,
Jason Ekstranda7af7042013-10-12 22:38:11 -0500854 view->surface->resource,
Neil Roberts96d790e2013-09-19 17:32:00 +0100855 sx, sy);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400856 }
Neil Roberts96d790e2013-09-19 17:32:00 +0100857
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400858 pointer->focus_serial = serial;
859 }
860
Giulio Camuffo65a07f82013-12-06 12:46:27 +0100861 wl_list_remove(&pointer->focus_view_listener.link);
862 wl_list_init(&pointer->focus_view_listener.link);
863 wl_list_remove(&pointer->focus_resource_listener.link);
864 wl_list_init(&pointer->focus_resource_listener.link);
Emilio Pozuelo Monfortaa7a4762013-11-19 11:37:15 +0100865 if (view)
Giulio Camuffo576fe2a2013-11-20 18:00:24 +0100866 wl_signal_add(&view->destroy_signal, &pointer->focus_view_listener);
Giulio Camuffo65a07f82013-12-06 12:46:27 +0100867 if (view && view->surface->resource)
868 wl_resource_add_destroy_listener(view->surface->resource,
869 &pointer->focus_resource_listener);
870
871 pointer->focus = view;
872 pointer->focus_view_listener.notify = pointer_focus_view_destroyed;
Kristian Høgsbergdb1fccb2014-02-05 17:14:42 -0800873 pointer->sx = sx;
874 pointer->sy = sy;
875
Derek Foremanf9318d12015-05-11 15:40:11 -0500876 assert(view || sx == wl_fixed_from_int(-1000000));
877 assert(view || sy == wl_fixed_from_int(-1000000));
878
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400879 wl_signal_emit(&pointer->focus_signal, pointer);
880}
881
Neil Roberts96d790e2013-09-19 17:32:00 +0100882static void
883send_enter_to_resource_list(struct wl_list *list,
884 struct weston_keyboard *keyboard,
885 struct weston_surface *surface,
886 uint32_t serial)
887{
888 struct wl_resource *resource;
889
890 wl_resource_for_each(resource, list) {
891 send_modifiers_to_resource(keyboard, resource, serial);
892 wl_keyboard_send_enter(resource, serial,
893 surface->resource,
894 &keyboard->keys);
895 }
896}
897
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400898WL_EXPORT void
Kristian Høgsberg29139d42013-04-18 15:25:39 -0400899weston_keyboard_set_focus(struct weston_keyboard *keyboard,
Kristian Høgsbergfe7aa902013-05-08 09:54:37 -0400900 struct weston_surface *surface)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400901{
902 struct wl_resource *resource;
Rob Bradford880ebc72013-07-22 17:31:38 +0100903 struct wl_display *display = keyboard->seat->compositor->wl_display;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400904 uint32_t serial;
Neil Roberts96d790e2013-09-19 17:32:00 +0100905 struct wl_list *focus_resource_list;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400906
Neil Roberts96d790e2013-09-19 17:32:00 +0100907 focus_resource_list = &keyboard->focus_resource_list;
908
909 if (!wl_list_empty(focus_resource_list) && keyboard->focus != surface) {
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400910 serial = wl_display_next_serial(display);
Neil Roberts96d790e2013-09-19 17:32:00 +0100911 wl_resource_for_each(resource, focus_resource_list) {
912 wl_keyboard_send_leave(resource, serial,
913 keyboard->focus->resource);
914 }
915 move_resources(&keyboard->resource_list, focus_resource_list);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400916 }
917
Neil Roberts96d790e2013-09-19 17:32:00 +0100918 if (find_resource_for_surface(&keyboard->resource_list, surface) &&
919 keyboard->focus != surface) {
920 struct wl_client *surface_client =
921 wl_resource_get_client(surface->resource);
922
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400923 serial = wl_display_next_serial(display);
Neil Roberts96d790e2013-09-19 17:32:00 +0100924
925 move_resources_for_client(focus_resource_list,
926 &keyboard->resource_list,
927 surface_client);
928 send_enter_to_resource_list(focus_resource_list,
929 keyboard,
930 surface,
931 serial);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400932 keyboard->focus_serial = serial;
Giulio Camuffo65a07f82013-12-06 12:46:27 +0100933 }
934
935 wl_list_remove(&keyboard->focus_resource_listener.link);
936 wl_list_init(&keyboard->focus_resource_listener.link);
937 if (surface && surface->resource)
Giulio Camuffo576fe2a2013-11-20 18:00:24 +0100938 wl_resource_add_destroy_listener(surface->resource,
939 &keyboard->focus_resource_listener);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400940
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400941 keyboard->focus = surface;
942 wl_signal_emit(&keyboard->focus_signal, keyboard);
943}
944
Giulio Camuffoa20ca812014-11-22 11:16:56 +0200945/* Users of this function must manually manage the keyboard focus */
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400946WL_EXPORT void
Kristian Høgsberg29139d42013-04-18 15:25:39 -0400947weston_keyboard_start_grab(struct weston_keyboard *keyboard,
948 struct weston_keyboard_grab *grab)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400949{
950 keyboard->grab = grab;
951 grab->keyboard = keyboard;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400952}
953
954WL_EXPORT void
Kristian Høgsberg29139d42013-04-18 15:25:39 -0400955weston_keyboard_end_grab(struct weston_keyboard *keyboard)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400956{
957 keyboard->grab = &keyboard->default_grab;
958}
959
Jonas Ådahl1ea343e2013-10-25 23:18:05 +0200960static void
961weston_keyboard_cancel_grab(struct weston_keyboard *keyboard)
962{
963 keyboard->grab->interface->cancel(keyboard->grab);
964}
965
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400966WL_EXPORT void
Kristian Høgsberg02bbabb2013-05-06 22:15:05 -0400967weston_pointer_start_grab(struct weston_pointer *pointer,
968 struct weston_pointer_grab *grab)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400969{
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400970 pointer->grab = grab;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400971 grab->pointer = pointer;
Kristian Høgsbergda751b82013-07-04 00:58:07 -0400972 pointer->grab->interface->focus(pointer->grab);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400973}
974
975WL_EXPORT void
Kristian Høgsberg02bbabb2013-05-06 22:15:05 -0400976weston_pointer_end_grab(struct weston_pointer *pointer)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400977{
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400978 pointer->grab = &pointer->default_grab;
Kristian Høgsbergda751b82013-07-04 00:58:07 -0400979 pointer->grab->interface->focus(pointer->grab);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400980}
981
Jonas Ådahl1ea343e2013-10-25 23:18:05 +0200982static void
983weston_pointer_cancel_grab(struct weston_pointer *pointer)
984{
985 pointer->grab->interface->cancel(pointer->grab);
986}
987
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400988WL_EXPORT void
Kristian Høgsberge329f362013-05-06 22:19:57 -0400989weston_touch_start_grab(struct weston_touch *touch, struct weston_touch_grab *grab)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400990{
991 touch->grab = grab;
992 grab->touch = touch;
993}
994
995WL_EXPORT void
Kristian Høgsberge329f362013-05-06 22:19:57 -0400996weston_touch_end_grab(struct weston_touch *touch)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400997{
998 touch->grab = &touch->default_grab;
999}
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001000
Jonas Ådahl1ea343e2013-10-25 23:18:05 +02001001static void
1002weston_touch_cancel_grab(struct weston_touch *touch)
1003{
1004 touch->grab->interface->cancel(touch->grab);
1005}
1006
Ander Conselvan de Oliveira54e90c72013-12-13 22:10:56 +02001007static void
1008weston_pointer_clamp_for_output(struct weston_pointer *pointer,
1009 struct weston_output *output,
1010 wl_fixed_t *fx, wl_fixed_t *fy)
1011{
1012 int x, y;
1013
1014 x = wl_fixed_to_int(*fx);
1015 y = wl_fixed_to_int(*fy);
1016
1017 if (x < output->x)
1018 *fx = wl_fixed_from_int(output->x);
1019 else if (x >= output->x + output->width)
1020 *fx = wl_fixed_from_int(output->x +
1021 output->width - 1);
1022 if (y < output->y)
1023 *fy = wl_fixed_from_int(output->y);
1024 else if (y >= output->y + output->height)
1025 *fy = wl_fixed_from_int(output->y +
1026 output->height - 1);
1027}
1028
Rob Bradford806d8c02013-06-25 18:56:41 +01001029WL_EXPORT void
1030weston_pointer_clamp(struct weston_pointer *pointer, wl_fixed_t *fx, wl_fixed_t *fy)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001031{
Rob Bradford806d8c02013-06-25 18:56:41 +01001032 struct weston_compositor *ec = pointer->seat->compositor;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001033 struct weston_output *output, *prev = NULL;
1034 int x, y, old_x, old_y, valid = 0;
1035
1036 x = wl_fixed_to_int(*fx);
1037 y = wl_fixed_to_int(*fy);
Rob Bradford806d8c02013-06-25 18:56:41 +01001038 old_x = wl_fixed_to_int(pointer->x);
1039 old_y = wl_fixed_to_int(pointer->y);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001040
1041 wl_list_for_each(output, &ec->output_list, link) {
Rob Bradford66bd9f52013-06-25 18:56:42 +01001042 if (pointer->seat->output && pointer->seat->output != output)
1043 continue;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001044 if (pixman_region32_contains_point(&output->region,
1045 x, y, NULL))
1046 valid = 1;
1047 if (pixman_region32_contains_point(&output->region,
1048 old_x, old_y, NULL))
1049 prev = output;
1050 }
1051
Rob Bradford66bd9f52013-06-25 18:56:42 +01001052 if (!prev)
1053 prev = pointer->seat->output;
1054
Ander Conselvan de Oliveira54e90c72013-12-13 22:10:56 +02001055 if (prev && !valid)
1056 weston_pointer_clamp_for_output(pointer, prev, fx, fy);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001057}
1058
Jonas Ådahld2510102014-10-05 21:39:14 +02001059static void
1060weston_pointer_move_to(struct weston_pointer *pointer,
1061 wl_fixed_t x, wl_fixed_t y)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001062{
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001063 int32_t ix, iy;
1064
Rob Bradford806d8c02013-06-25 18:56:41 +01001065 weston_pointer_clamp (pointer, &x, &y);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001066
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001067 pointer->x = x;
1068 pointer->y = y;
1069
1070 ix = wl_fixed_to_int(x);
1071 iy = wl_fixed_to_int(y);
1072
Kristian Høgsberg195b8692013-05-08 15:02:05 -04001073 if (pointer->sprite) {
Jason Ekstranda7af7042013-10-12 22:38:11 -05001074 weston_view_set_position(pointer->sprite,
1075 ix - pointer->hotspot_x,
1076 iy - pointer->hotspot_y);
1077 weston_view_schedule_repaint(pointer->sprite);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001078 }
Giulio Camuffo6fcb3782013-11-14 23:42:50 +01001079
Giulio Camuffo1959ab82013-11-14 23:42:52 +01001080 pointer->grab->interface->focus(pointer->grab);
Giulio Camuffo6fcb3782013-11-14 23:42:50 +01001081 wl_signal_emit(&pointer->motion_signal, pointer);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001082}
1083
Jonas Ådahld2510102014-10-05 21:39:14 +02001084WL_EXPORT void
1085weston_pointer_motion_to_abs(struct weston_pointer *pointer,
1086 struct weston_pointer_motion_event *event,
1087 wl_fixed_t *x, wl_fixed_t *y)
1088{
1089 if (event->mask & WESTON_POINTER_MOTION_ABS) {
1090 *x = wl_fixed_from_double(event->x);
1091 *y = wl_fixed_from_double(event->y);
1092 } else if (event->mask & WESTON_POINTER_MOTION_REL) {
1093 *x = pointer->x + wl_fixed_from_double(event->dx);
1094 *y = pointer->y + wl_fixed_from_double(event->dy);
1095 } else {
1096 assert(!"invalid motion event");
1097 *x = *y = 0;
1098 }
1099}
1100
1101WL_EXPORT void
1102weston_pointer_move(struct weston_pointer *pointer,
1103 struct weston_pointer_motion_event *event)
1104{
1105 wl_fixed_t x, y;
1106
1107 weston_pointer_motion_to_abs(pointer, event, &x, &y);
1108 weston_pointer_move_to(pointer, x, y);
1109}
1110
Ander Conselvan de Oliveira54e90c72013-12-13 22:10:56 +02001111/** Verify if the pointer is in a valid position and move it if it isn't.
1112 */
Ander Conselvan de Oliveiraf84327a2014-01-29 18:47:51 +02001113static void
1114weston_pointer_handle_output_destroy(struct wl_listener *listener, void *data)
Ander Conselvan de Oliveira54e90c72013-12-13 22:10:56 +02001115{
Ander Conselvan de Oliveiraf84327a2014-01-29 18:47:51 +02001116 struct weston_pointer *pointer;
1117 struct weston_compositor *ec;
Ander Conselvan de Oliveira54e90c72013-12-13 22:10:56 +02001118 struct weston_output *output, *closest = NULL;
1119 int x, y, distance, min = INT_MAX;
1120 wl_fixed_t fx, fy;
1121
Ander Conselvan de Oliveiraf84327a2014-01-29 18:47:51 +02001122 pointer = container_of(listener, struct weston_pointer,
1123 output_destroy_listener);
1124 ec = pointer->seat->compositor;
1125
Ander Conselvan de Oliveira54e90c72013-12-13 22:10:56 +02001126 x = wl_fixed_to_int(pointer->x);
1127 y = wl_fixed_to_int(pointer->y);
1128
1129 wl_list_for_each(output, &ec->output_list, link) {
1130 if (pixman_region32_contains_point(&output->region,
1131 x, y, NULL))
1132 return;
1133
1134 /* Aproximante the distance from the pointer to the center of
1135 * the output. */
1136 distance = abs(output->x + output->width / 2 - x) +
1137 abs(output->y + output->height / 2 - y);
1138 if (distance < min) {
1139 min = distance;
1140 closest = output;
1141 }
1142 }
1143
1144 /* Nothing to do if there's no output left. */
1145 if (!closest)
1146 return;
1147
1148 fx = pointer->x;
1149 fy = pointer->y;
1150
1151 weston_pointer_clamp_for_output(pointer, closest, &fx, &fy);
Jonas Ådahld2510102014-10-05 21:39:14 +02001152 weston_pointer_move_to(pointer, fx, fy);
Ander Conselvan de Oliveira54e90c72013-12-13 22:10:56 +02001153}
1154
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001155WL_EXPORT void
1156notify_motion(struct weston_seat *seat,
Jonas Ådahld2510102014-10-05 21:39:14 +02001157 uint32_t time,
1158 struct weston_pointer_motion_event *event)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001159{
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001160 struct weston_compositor *ec = seat->compositor;
Derek Foreman1281a362015-07-31 16:55:32 -05001161 struct weston_pointer *pointer = weston_seat_get_pointer(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001162
1163 weston_compositor_wake(ec);
Jonas Ådahld2510102014-10-05 21:39:14 +02001164 pointer->grab->interface->motion(pointer->grab, time, event);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001165}
1166
Daniel Stone96d47c02013-11-19 11:37:12 +01001167static void
1168run_modifier_bindings(struct weston_seat *seat, uint32_t old, uint32_t new)
1169{
1170 struct weston_compositor *compositor = seat->compositor;
Derek Foreman1281a362015-07-31 16:55:32 -05001171 struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
Daniel Stone96d47c02013-11-19 11:37:12 +01001172 uint32_t diff;
1173 unsigned int i;
1174 struct {
1175 uint32_t xkb;
1176 enum weston_keyboard_modifier weston;
1177 } mods[] = {
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001178 { keyboard->xkb_info->ctrl_mod, MODIFIER_CTRL },
1179 { keyboard->xkb_info->alt_mod, MODIFIER_ALT },
1180 { keyboard->xkb_info->super_mod, MODIFIER_SUPER },
1181 { keyboard->xkb_info->shift_mod, MODIFIER_SHIFT },
Daniel Stone96d47c02013-11-19 11:37:12 +01001182 };
1183
1184 diff = new & ~old;
1185 for (i = 0; i < ARRAY_LENGTH(mods); i++) {
1186 if (diff & (1 << mods[i].xkb))
1187 weston_compositor_run_modifier_binding(compositor,
Derek Foreman99a6a2d2015-07-15 13:00:43 -05001188 keyboard,
Daniel Stone96d47c02013-11-19 11:37:12 +01001189 mods[i].weston,
1190 WL_KEYBOARD_KEY_STATE_PRESSED);
1191 }
1192
1193 diff = old & ~new;
1194 for (i = 0; i < ARRAY_LENGTH(mods); i++) {
1195 if (diff & (1 << mods[i].xkb))
1196 weston_compositor_run_modifier_binding(compositor,
Derek Foreman99a6a2d2015-07-15 13:00:43 -05001197 keyboard,
Daniel Stone96d47c02013-11-19 11:37:12 +01001198 mods[i].weston,
1199 WL_KEYBOARD_KEY_STATE_RELEASED);
1200 }
1201}
1202
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001203WL_EXPORT void
1204notify_motion_absolute(struct weston_seat *seat,
1205 uint32_t time, wl_fixed_t x, wl_fixed_t y)
1206{
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001207 struct weston_compositor *ec = seat->compositor;
Derek Foreman1281a362015-07-31 16:55:32 -05001208 struct weston_pointer *pointer = weston_seat_get_pointer(seat);
Jonas Ådahld2510102014-10-05 21:39:14 +02001209 struct weston_pointer_motion_event event = { 0 };
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001210
1211 weston_compositor_wake(ec);
Jonas Ådahld2510102014-10-05 21:39:14 +02001212
1213 event = (struct weston_pointer_motion_event) {
1214 .mask = WESTON_POINTER_MOTION_ABS,
1215 .x = wl_fixed_to_double(x),
1216 .y = wl_fixed_to_double(y),
1217 };
1218
1219 pointer->grab->interface->motion(pointer->grab, time, &event);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001220}
1221
1222WL_EXPORT void
1223weston_surface_activate(struct weston_surface *surface,
1224 struct weston_seat *seat)
1225{
1226 struct weston_compositor *compositor = seat->compositor;
Derek Foreman1281a362015-07-31 16:55:32 -05001227 struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001228
Derek Foreman1281a362015-07-31 16:55:32 -05001229 if (keyboard) {
1230 weston_keyboard_set_focus(keyboard, surface);
Kristian Høgsberge3148752013-05-06 23:19:49 -04001231 wl_data_device_set_keyboard_focus(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001232 }
1233
1234 wl_signal_emit(&compositor->activate_signal, surface);
1235}
1236
1237WL_EXPORT void
1238notify_button(struct weston_seat *seat, uint32_t time, int32_t button,
1239 enum wl_pointer_button_state state)
1240{
1241 struct weston_compositor *compositor = seat->compositor;
Derek Foreman1281a362015-07-31 16:55:32 -05001242 struct weston_pointer *pointer = weston_seat_get_pointer(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001243
1244 if (state == WL_POINTER_BUTTON_STATE_PRESSED) {
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001245 weston_compositor_idle_inhibit(compositor);
1246 if (pointer->button_count == 0) {
1247 pointer->grab_button = button;
1248 pointer->grab_time = time;
1249 pointer->grab_x = pointer->x;
1250 pointer->grab_y = pointer->y;
1251 }
1252 pointer->button_count++;
1253 } else {
1254 weston_compositor_idle_release(compositor);
1255 pointer->button_count--;
1256 }
1257
Derek Foreman99a6a2d2015-07-15 13:00:43 -05001258 weston_compositor_run_button_binding(compositor, pointer, time, button,
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001259 state);
1260
1261 pointer->grab->interface->button(pointer->grab, time, button, state);
1262
1263 if (pointer->button_count == 1)
1264 pointer->grab_serial =
1265 wl_display_get_serial(compositor->wl_display);
1266}
1267
1268WL_EXPORT void
1269notify_axis(struct weston_seat *seat, uint32_t time, uint32_t axis,
1270 wl_fixed_t value)
1271{
1272 struct weston_compositor *compositor = seat->compositor;
Derek Foreman1281a362015-07-31 16:55:32 -05001273 struct weston_pointer *pointer = weston_seat_get_pointer(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001274
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001275 weston_compositor_wake(compositor);
1276
1277 if (!value)
1278 return;
1279
Derek Foreman99a6a2d2015-07-15 13:00:43 -05001280 if (weston_compositor_run_axis_binding(compositor, pointer,
1281 time, axis, value))
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001282 return;
1283
Jonas Ådahl0336ca02014-10-04 16:28:29 +02001284 pointer->grab->interface->axis(pointer->grab, time, axis, value);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001285}
1286
Giulio Camuffo6ef444d2014-08-28 19:44:09 +03001287WL_EXPORT int
1288weston_keyboard_set_locks(struct weston_keyboard *keyboard,
1289 uint32_t mask, uint32_t value)
1290{
1291#ifdef ENABLE_XKBCOMMON
1292 uint32_t serial;
1293 xkb_mod_mask_t mods_depressed, mods_latched, mods_locked, group;
1294 xkb_mod_mask_t num, caps;
1295
1296 /* We don't want the leds to go out of sync with the actual state
1297 * so if the backend has no way to change the leds don't try to
1298 * change the state */
1299 if (!keyboard->seat->led_update)
1300 return -1;
1301
1302 mods_depressed = xkb_state_serialize_mods(keyboard->xkb_state.state,
1303 XKB_STATE_DEPRESSED);
1304 mods_latched = xkb_state_serialize_mods(keyboard->xkb_state.state,
1305 XKB_STATE_LATCHED);
1306 mods_locked = xkb_state_serialize_mods(keyboard->xkb_state.state,
1307 XKB_STATE_LOCKED);
1308 group = xkb_state_serialize_group(keyboard->xkb_state.state,
1309 XKB_STATE_EFFECTIVE);
1310
1311 num = (1 << keyboard->xkb_info->mod2_mod);
1312 caps = (1 << keyboard->xkb_info->caps_mod);
1313 if (mask & WESTON_NUM_LOCK) {
1314 if (value & WESTON_NUM_LOCK)
1315 mods_locked |= num;
1316 else
1317 mods_locked &= ~num;
1318 }
1319 if (mask & WESTON_CAPS_LOCK) {
1320 if (value & WESTON_CAPS_LOCK)
1321 mods_locked |= caps;
1322 else
1323 mods_locked &= ~caps;
1324 }
1325
1326 xkb_state_update_mask(keyboard->xkb_state.state, mods_depressed,
1327 mods_latched, mods_locked, 0, 0, group);
1328
1329 serial = wl_display_next_serial(
1330 keyboard->seat->compositor->wl_display);
1331 notify_modifiers(keyboard->seat, serial);
1332
1333 return 0;
1334#else
1335 return -1;
1336#endif
1337}
1338
Rob Bradford382ff462013-06-24 16:52:45 +01001339#ifdef ENABLE_XKBCOMMON
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001340WL_EXPORT void
1341notify_modifiers(struct weston_seat *seat, uint32_t serial)
1342{
Derek Foreman1281a362015-07-31 16:55:32 -05001343 struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001344 struct weston_keyboard_grab *grab = keyboard->grab;
1345 uint32_t mods_depressed, mods_latched, mods_locked, group;
1346 uint32_t mods_lookup;
1347 enum weston_led leds = 0;
1348 int changed = 0;
1349
1350 /* Serialize and update our internal state, checking to see if it's
1351 * different to the previous state. */
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001352 mods_depressed = xkb_state_serialize_mods(keyboard->xkb_state.state,
Ran Benita2e1968f2014-08-19 23:59:51 +03001353 XKB_STATE_MODS_DEPRESSED);
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001354 mods_latched = xkb_state_serialize_mods(keyboard->xkb_state.state,
Ran Benita2e1968f2014-08-19 23:59:51 +03001355 XKB_STATE_MODS_LATCHED);
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001356 mods_locked = xkb_state_serialize_mods(keyboard->xkb_state.state,
Ran Benita2e1968f2014-08-19 23:59:51 +03001357 XKB_STATE_MODS_LOCKED);
1358 group = xkb_state_serialize_layout(keyboard->xkb_state.state,
1359 XKB_STATE_LAYOUT_EFFECTIVE);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001360
Derek Foreman244e99e2015-06-03 15:53:26 -05001361 if (mods_depressed != keyboard->modifiers.mods_depressed ||
1362 mods_latched != keyboard->modifiers.mods_latched ||
1363 mods_locked != keyboard->modifiers.mods_locked ||
1364 group != keyboard->modifiers.group)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001365 changed = 1;
1366
Derek Foreman244e99e2015-06-03 15:53:26 -05001367 run_modifier_bindings(seat, keyboard->modifiers.mods_depressed,
Daniel Stone96d47c02013-11-19 11:37:12 +01001368 mods_depressed);
1369
Derek Foreman244e99e2015-06-03 15:53:26 -05001370 keyboard->modifiers.mods_depressed = mods_depressed;
1371 keyboard->modifiers.mods_latched = mods_latched;
1372 keyboard->modifiers.mods_locked = mods_locked;
1373 keyboard->modifiers.group = group;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001374
1375 /* And update the modifier_state for bindings. */
1376 mods_lookup = mods_depressed | mods_latched;
1377 seat->modifier_state = 0;
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001378 if (mods_lookup & (1 << keyboard->xkb_info->ctrl_mod))
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001379 seat->modifier_state |= MODIFIER_CTRL;
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001380 if (mods_lookup & (1 << keyboard->xkb_info->alt_mod))
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001381 seat->modifier_state |= MODIFIER_ALT;
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001382 if (mods_lookup & (1 << keyboard->xkb_info->super_mod))
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001383 seat->modifier_state |= MODIFIER_SUPER;
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001384 if (mods_lookup & (1 << keyboard->xkb_info->shift_mod))
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001385 seat->modifier_state |= MODIFIER_SHIFT;
1386
1387 /* Finally, notify the compositor that LEDs have changed. */
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001388 if (xkb_state_led_index_is_active(keyboard->xkb_state.state,
1389 keyboard->xkb_info->num_led))
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001390 leds |= LED_NUM_LOCK;
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001391 if (xkb_state_led_index_is_active(keyboard->xkb_state.state,
1392 keyboard->xkb_info->caps_led))
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001393 leds |= LED_CAPS_LOCK;
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001394 if (xkb_state_led_index_is_active(keyboard->xkb_state.state,
1395 keyboard->xkb_info->scroll_led))
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001396 leds |= LED_SCROLL_LOCK;
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001397 if (leds != keyboard->xkb_state.leds && seat->led_update)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001398 seat->led_update(seat, leds);
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001399 keyboard->xkb_state.leds = leds;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001400
1401 if (changed) {
1402 grab->interface->modifiers(grab,
1403 serial,
1404 keyboard->modifiers.mods_depressed,
1405 keyboard->modifiers.mods_latched,
1406 keyboard->modifiers.mods_locked,
1407 keyboard->modifiers.group);
1408 }
1409}
1410
1411static void
1412update_modifier_state(struct weston_seat *seat, uint32_t serial, uint32_t key,
1413 enum wl_keyboard_key_state state)
1414{
Derek Foreman1281a362015-07-31 16:55:32 -05001415 struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001416 enum xkb_key_direction direction;
1417
Matt Roper01a92732013-06-24 16:52:44 +01001418 /* Keyboard modifiers don't exist in raw keyboard mode */
1419 if (!seat->compositor->use_xkbcommon)
1420 return;
1421
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001422 if (state == WL_KEYBOARD_KEY_STATE_PRESSED)
1423 direction = XKB_KEY_DOWN;
1424 else
1425 direction = XKB_KEY_UP;
1426
1427 /* Offset the keycode by 8, as the evdev XKB rules reflect X's
1428 * broken keycode system, which starts at 8. */
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001429 xkb_state_update_key(keyboard->xkb_state.state, key + 8, direction);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001430
1431 notify_modifiers(seat, serial);
1432}
Rui Matos65196bc2013-10-10 19:44:19 +02001433
1434static void
1435send_keymap(struct wl_resource *resource, struct weston_xkb_info *xkb_info)
1436{
1437 wl_keyboard_send_keymap(resource,
1438 WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1,
1439 xkb_info->keymap_fd,
1440 xkb_info->keymap_size);
1441}
1442
1443static void
1444send_modifiers(struct wl_resource *resource, uint32_t serial, struct weston_keyboard *keyboard)
1445{
1446 wl_keyboard_send_modifiers(resource, serial,
1447 keyboard->modifiers.mods_depressed,
1448 keyboard->modifiers.mods_latched,
1449 keyboard->modifiers.mods_locked,
1450 keyboard->modifiers.group);
1451}
1452
1453static struct weston_xkb_info *
1454weston_xkb_info_create(struct xkb_keymap *keymap);
Rui Matos65196bc2013-10-10 19:44:19 +02001455
1456static void
1457update_keymap(struct weston_seat *seat)
1458{
Derek Foreman1281a362015-07-31 16:55:32 -05001459 struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
Rui Matos65196bc2013-10-10 19:44:19 +02001460 struct wl_resource *resource;
1461 struct weston_xkb_info *xkb_info;
1462 struct xkb_state *state;
1463 xkb_mod_mask_t latched_mods;
1464 xkb_mod_mask_t locked_mods;
1465
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001466 xkb_info = weston_xkb_info_create(keyboard->pending_keymap);
Rui Matos65196bc2013-10-10 19:44:19 +02001467
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001468 xkb_keymap_unref(keyboard->pending_keymap);
1469 keyboard->pending_keymap = NULL;
Rui Matos65196bc2013-10-10 19:44:19 +02001470
1471 if (!xkb_info) {
1472 weston_log("failed to create XKB info\n");
1473 return;
1474 }
1475
1476 state = xkb_state_new(xkb_info->keymap);
1477 if (!state) {
1478 weston_log("failed to initialise XKB state\n");
1479 weston_xkb_info_destroy(xkb_info);
1480 return;
1481 }
1482
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001483 latched_mods = xkb_state_serialize_mods(keyboard->xkb_state.state,
1484 XKB_STATE_MODS_LATCHED);
1485 locked_mods = xkb_state_serialize_mods(keyboard->xkb_state.state,
1486 XKB_STATE_MODS_LOCKED);
Rui Matos65196bc2013-10-10 19:44:19 +02001487 xkb_state_update_mask(state,
1488 0, /* depressed */
1489 latched_mods,
1490 locked_mods,
1491 0, 0, 0);
1492
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001493 weston_xkb_info_destroy(keyboard->xkb_info);
1494 keyboard->xkb_info = xkb_info;
Rui Matos65196bc2013-10-10 19:44:19 +02001495
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001496 xkb_state_unref(keyboard->xkb_state.state);
1497 keyboard->xkb_state.state = state;
Rui Matos65196bc2013-10-10 19:44:19 +02001498
Derek Foremanbc91e542015-06-03 15:53:27 -05001499 wl_resource_for_each(resource, &keyboard->resource_list)
Rui Matos65196bc2013-10-10 19:44:19 +02001500 send_keymap(resource, xkb_info);
Derek Foremanbc91e542015-06-03 15:53:27 -05001501 wl_resource_for_each(resource, &keyboard->focus_resource_list)
Rui Matos65196bc2013-10-10 19:44:19 +02001502 send_keymap(resource, xkb_info);
1503
1504 notify_modifiers(seat, wl_display_next_serial(seat->compositor->wl_display));
1505
1506 if (!latched_mods && !locked_mods)
1507 return;
1508
Derek Foremanbc91e542015-06-03 15:53:27 -05001509 wl_resource_for_each(resource, &keyboard->resource_list)
1510 send_modifiers(resource, wl_display_get_serial(seat->compositor->wl_display), keyboard);
1511 wl_resource_for_each(resource, &keyboard->focus_resource_list)
1512 send_modifiers(resource, wl_display_get_serial(seat->compositor->wl_display), keyboard);
Rui Matos65196bc2013-10-10 19:44:19 +02001513}
Rob Bradford382ff462013-06-24 16:52:45 +01001514#else
1515WL_EXPORT void
1516notify_modifiers(struct weston_seat *seat, uint32_t serial)
1517{
1518}
1519
1520static void
1521update_modifier_state(struct weston_seat *seat, uint32_t serial, uint32_t key,
1522 enum wl_keyboard_key_state state)
1523{
1524}
Rui Matos65196bc2013-10-10 19:44:19 +02001525
1526static void
1527update_keymap(struct weston_seat *seat)
1528{
1529}
Rob Bradford382ff462013-06-24 16:52:45 +01001530#endif
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001531
1532WL_EXPORT void
1533notify_key(struct weston_seat *seat, uint32_t time, uint32_t key,
1534 enum wl_keyboard_key_state state,
1535 enum weston_key_state_update update_state)
1536{
1537 struct weston_compositor *compositor = seat->compositor;
Derek Foreman1281a362015-07-31 16:55:32 -05001538 struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001539 struct weston_keyboard_grab *grab = keyboard->grab;
Pekka Paalanen86b53962014-11-19 13:43:32 +02001540 uint32_t *k, *end;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001541
1542 if (state == WL_KEYBOARD_KEY_STATE_PRESSED) {
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001543 weston_compositor_idle_inhibit(compositor);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001544 } else {
1545 weston_compositor_idle_release(compositor);
1546 }
1547
Pekka Paalanen86b53962014-11-19 13:43:32 +02001548 end = keyboard->keys.data + keyboard->keys.size;
1549 for (k = keyboard->keys.data; k < end; k++) {
1550 if (*k == key) {
1551 /* Ignore server-generated repeats. */
1552 if (state == WL_KEYBOARD_KEY_STATE_PRESSED)
1553 return;
1554 *k = *--end;
1555 }
1556 }
1557 keyboard->keys.size = (void *) end - keyboard->keys.data;
1558 if (state == WL_KEYBOARD_KEY_STATE_PRESSED) {
1559 k = wl_array_add(&keyboard->keys, sizeof *k);
1560 *k = key;
1561 }
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001562
1563 if (grab == &keyboard->default_grab ||
1564 grab == &keyboard->input_method_grab) {
Derek Foreman99a6a2d2015-07-15 13:00:43 -05001565 weston_compositor_run_key_binding(compositor, keyboard, time,
1566 key, state);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001567 grab = keyboard->grab;
1568 }
1569
1570 grab->interface->key(grab, time, key, state);
1571
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001572 if (keyboard->pending_keymap &&
Pekka Paalanen86b53962014-11-19 13:43:32 +02001573 keyboard->keys.size == 0)
Rui Matos65196bc2013-10-10 19:44:19 +02001574 update_keymap(seat);
1575
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001576 if (update_state == STATE_UPDATE_AUTOMATIC) {
1577 update_modifier_state(seat,
1578 wl_display_get_serial(compositor->wl_display),
1579 key,
1580 state);
1581 }
Giulio Camuffob6ddf6c2015-02-06 19:06:54 +02001582
1583 if (state == WL_KEYBOARD_KEY_STATE_PRESSED) {
1584 keyboard->grab_serial =
1585 wl_display_get_serial(compositor->wl_display);
1586 keyboard->grab_time = time;
1587 keyboard->grab_key = key;
1588 }
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001589}
1590
1591WL_EXPORT void
1592notify_pointer_focus(struct weston_seat *seat, struct weston_output *output,
1593 wl_fixed_t x, wl_fixed_t y)
1594{
Derek Foreman1281a362015-07-31 16:55:32 -05001595 struct weston_pointer *pointer = weston_seat_get_pointer(seat);
1596
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001597 if (output) {
Jonas Ådahld2510102014-10-05 21:39:14 +02001598 weston_pointer_move_to(pointer, x, y);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001599 } else {
Kristian Høgsberg02bbabb2013-05-06 22:15:05 -04001600 /* FIXME: We should call weston_pointer_set_focus(seat,
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001601 * NULL) here, but somehow that breaks re-entry... */
1602 }
1603}
1604
1605static void
1606destroy_device_saved_kbd_focus(struct wl_listener *listener, void *data)
1607{
1608 struct weston_seat *ws;
1609
1610 ws = container_of(listener, struct weston_seat,
1611 saved_kbd_focus_listener);
1612
1613 ws->saved_kbd_focus = NULL;
1614}
1615
1616WL_EXPORT void
1617notify_keyboard_focus_in(struct weston_seat *seat, struct wl_array *keys,
1618 enum weston_key_state_update update_state)
1619{
1620 struct weston_compositor *compositor = seat->compositor;
Derek Foreman1281a362015-07-31 16:55:32 -05001621 struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
Kristian Høgsbergfe7aa902013-05-08 09:54:37 -04001622 struct weston_surface *surface;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001623 uint32_t *k, serial;
1624
1625 serial = wl_display_next_serial(compositor->wl_display);
1626 wl_array_copy(&keyboard->keys, keys);
1627 wl_array_for_each(k, &keyboard->keys) {
1628 weston_compositor_idle_inhibit(compositor);
1629 if (update_state == STATE_UPDATE_AUTOMATIC)
1630 update_modifier_state(seat, serial, *k,
1631 WL_KEYBOARD_KEY_STATE_PRESSED);
1632 }
1633
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001634 surface = seat->saved_kbd_focus;
1635
1636 if (surface) {
1637 wl_list_remove(&seat->saved_kbd_focus_listener.link);
1638 weston_keyboard_set_focus(keyboard, surface);
1639 seat->saved_kbd_focus = NULL;
1640 }
1641}
1642
1643WL_EXPORT void
1644notify_keyboard_focus_out(struct weston_seat *seat)
1645{
1646 struct weston_compositor *compositor = seat->compositor;
Derek Foreman1281a362015-07-31 16:55:32 -05001647 struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
1648 struct weston_pointer *pointer = weston_seat_get_pointer(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001649 uint32_t *k, serial;
1650
1651 serial = wl_display_next_serial(compositor->wl_display);
1652 wl_array_for_each(k, &keyboard->keys) {
1653 weston_compositor_idle_release(compositor);
1654 update_modifier_state(seat, serial, *k,
1655 WL_KEYBOARD_KEY_STATE_RELEASED);
1656 }
1657
1658 seat->modifier_state = 0;
1659
1660 if (keyboard->focus) {
1661 seat->saved_kbd_focus = keyboard->focus;
1662 seat->saved_kbd_focus_listener.notify =
1663 destroy_device_saved_kbd_focus;
Jason Ekstrand26ed73c2013-06-06 22:34:41 -05001664 wl_signal_add(&keyboard->focus->destroy_signal,
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001665 &seat->saved_kbd_focus_listener);
1666 }
1667
1668 weston_keyboard_set_focus(keyboard, NULL);
Jonas Ådahl1ea343e2013-10-25 23:18:05 +02001669 weston_keyboard_cancel_grab(keyboard);
Derek Foreman1281a362015-07-31 16:55:32 -05001670 if (pointer)
1671 weston_pointer_cancel_grab(pointer);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001672}
1673
Michael Fua2bb7912013-07-23 15:51:06 +08001674WL_EXPORT void
Derek Foreman4c93c082015-04-30 16:45:41 -05001675weston_touch_set_focus(struct weston_touch *touch, struct weston_view *view)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001676{
Neil Roberts96d790e2013-09-19 17:32:00 +01001677 struct wl_list *focus_resource_list;
1678
Derek Foreman4c93c082015-04-30 16:45:41 -05001679 focus_resource_list = &touch->focus_resource_list;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001680
Derek Foreman4c93c082015-04-30 16:45:41 -05001681 if (view && touch->focus &&
1682 touch->focus->surface == view->surface) {
1683 touch->focus = view;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001684 return;
Jason Ekstranda7af7042013-10-12 22:38:11 -05001685 }
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001686
Derek Foreman4c93c082015-04-30 16:45:41 -05001687 wl_list_remove(&touch->focus_resource_listener.link);
1688 wl_list_init(&touch->focus_resource_listener.link);
1689 wl_list_remove(&touch->focus_view_listener.link);
1690 wl_list_init(&touch->focus_view_listener.link);
Giulio Camuffo576fe2a2013-11-20 18:00:24 +01001691
Neil Roberts96d790e2013-09-19 17:32:00 +01001692 if (!wl_list_empty(focus_resource_list)) {
Derek Foreman4c93c082015-04-30 16:45:41 -05001693 move_resources(&touch->resource_list,
Neil Roberts96d790e2013-09-19 17:32:00 +01001694 focus_resource_list);
1695 }
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001696
Jason Ekstranda7af7042013-10-12 22:38:11 -05001697 if (view) {
Derek Foreman362656b2014-09-04 10:23:05 -05001698 struct wl_client *surface_client;
1699
1700 if (!view->surface->resource) {
Derek Foreman4c93c082015-04-30 16:45:41 -05001701 touch->focus = NULL;
Derek Foreman362656b2014-09-04 10:23:05 -05001702 return;
1703 }
1704
1705 surface_client = wl_resource_get_client(view->surface->resource);
Neil Roberts96d790e2013-09-19 17:32:00 +01001706 move_resources_for_client(focus_resource_list,
Derek Foreman4c93c082015-04-30 16:45:41 -05001707 &touch->resource_list,
Neil Roberts96d790e2013-09-19 17:32:00 +01001708 surface_client);
Giulio Camuffo576fe2a2013-11-20 18:00:24 +01001709 wl_resource_add_destroy_listener(view->surface->resource,
Derek Foreman4c93c082015-04-30 16:45:41 -05001710 &touch->focus_resource_listener);
1711 wl_signal_add(&view->destroy_signal, &touch->focus_view_listener);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001712 }
Derek Foreman4c93c082015-04-30 16:45:41 -05001713 touch->focus = view;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001714}
1715
1716/**
1717 * notify_touch - emulates button touches and notifies surfaces accordingly.
1718 *
1719 * It assumes always the correct cycle sequence until it gets here: touch_down
1720 * → touch_update → ... → touch_update → touch_end. The driver is responsible
1721 * for sending along such order.
1722 *
1723 */
1724WL_EXPORT void
1725notify_touch(struct weston_seat *seat, uint32_t time, int touch_id,
1726 wl_fixed_t x, wl_fixed_t y, int touch_type)
1727{
1728 struct weston_compositor *ec = seat->compositor;
Derek Foreman1281a362015-07-31 16:55:32 -05001729 struct weston_touch *touch = weston_seat_get_touch(seat);
Kristian Høgsberge329f362013-05-06 22:19:57 -04001730 struct weston_touch_grab *grab = touch->grab;
Jason Ekstranda7af7042013-10-12 22:38:11 -05001731 struct weston_view *ev;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001732 wl_fixed_t sx, sy;
1733
1734 /* Update grab's global coordinates. */
Neil Roberts306fe082013-10-03 16:43:06 +01001735 if (touch_id == touch->grab_touch_id && touch_type != WL_TOUCH_UP) {
1736 touch->grab_x = x;
1737 touch->grab_y = y;
1738 }
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001739
1740 switch (touch_type) {
1741 case WL_TOUCH_DOWN:
1742 weston_compositor_idle_inhibit(ec);
1743
Jonas Ådahl9484b692013-12-02 22:05:03 +01001744 touch->num_tp++;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001745
Jason Ekstranda7af7042013-10-12 22:38:11 -05001746 /* the first finger down picks the view, and all further go
1747 * to that view for the remainder of the touch session i.e.
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001748 * until all touch points are up again. */
Jonas Ådahl9484b692013-12-02 22:05:03 +01001749 if (touch->num_tp == 1) {
Jason Ekstranda7af7042013-10-12 22:38:11 -05001750 ev = weston_compositor_pick_view(ec, x, y, &sx, &sy);
Derek Foreman4c93c082015-04-30 16:45:41 -05001751 weston_touch_set_focus(touch, ev);
Giulio Camuffo61ed7b62015-07-08 11:55:28 +03001752 } else if (!touch->focus) {
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001753 /* Unexpected condition: We have non-initial touch but
1754 * there is no focused surface.
1755 */
Chris Michael3f607d32015-10-07 11:59:49 -04001756 weston_log("touch event received with %d points down "
Jonas Ådahl9484b692013-12-02 22:05:03 +01001757 "but no surface focused\n", touch->num_tp);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001758 return;
1759 }
1760
Derek Foreman99a6a2d2015-07-15 13:00:43 -05001761 weston_compositor_run_touch_binding(ec, touch,
Kristian Høgsbergc8964012014-02-05 14:25:18 -08001762 time, touch_type);
1763
Giulio Camuffo61ed7b62015-07-08 11:55:28 +03001764 grab->interface->down(grab, time, touch_id, x, y);
Jonas Ådahl9484b692013-12-02 22:05:03 +01001765 if (touch->num_tp == 1) {
Rusty Lynchf1407ff2013-08-08 21:13:57 -07001766 touch->grab_serial =
1767 wl_display_get_serial(ec->wl_display);
Neil Roberts306fe082013-10-03 16:43:06 +01001768 touch->grab_touch_id = touch_id;
Rusty Lynchf1407ff2013-08-08 21:13:57 -07001769 touch->grab_time = time;
1770 touch->grab_x = x;
1771 touch->grab_y = y;
1772 }
1773
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001774 break;
1775 case WL_TOUCH_MOTION:
Jason Ekstranda7af7042013-10-12 22:38:11 -05001776 ev = touch->focus;
1777 if (!ev)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001778 break;
1779
Giulio Camuffo61ed7b62015-07-08 11:55:28 +03001780 grab->interface->motion(grab, time, touch_id, x, y);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001781 break;
1782 case WL_TOUCH_UP:
Kristian Høgsberga30e29a2014-01-08 22:29:20 -08001783 if (touch->num_tp == 0) {
1784 /* This can happen if we start out with one or
1785 * more fingers on the touch screen, in which
1786 * case we didn't get the corresponding down
1787 * event. */
1788 weston_log("unmatched touch up event\n");
1789 break;
1790 }
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001791 weston_compositor_idle_release(ec);
Jonas Ådahl9484b692013-12-02 22:05:03 +01001792 touch->num_tp--;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001793
1794 grab->interface->up(grab, time, touch_id);
Jonas Ådahl9484b692013-12-02 22:05:03 +01001795 if (touch->num_tp == 0)
Derek Foreman4c93c082015-04-30 16:45:41 -05001796 weston_touch_set_focus(touch, NULL);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001797 break;
1798 }
1799}
1800
Jonas Ådahl1679f232014-04-12 09:39:51 +02001801WL_EXPORT void
1802notify_touch_frame(struct weston_seat *seat)
1803{
Derek Foreman1281a362015-07-31 16:55:32 -05001804 struct weston_touch *touch = weston_seat_get_touch(seat);
Jonas Ådahl1679f232014-04-12 09:39:51 +02001805 struct weston_touch_grab *grab = touch->grab;
1806
1807 grab->interface->frame(grab);
1808}
1809
Derek Foreman3cc004a2015-11-06 15:56:09 -06001810WL_EXPORT void
1811notify_touch_cancel(struct weston_seat *seat)
1812{
1813 struct weston_touch *touch = weston_seat_get_touch(seat);
1814 struct weston_touch_grab *grab = touch->grab;
1815
1816 grab->interface->cancel(grab);
1817}
1818
Pekka Paalanen8274d902014-08-06 19:36:51 +03001819static int
1820pointer_cursor_surface_get_label(struct weston_surface *surface,
1821 char *buf, size_t len)
1822{
1823 return snprintf(buf, len, "cursor");
1824}
1825
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001826static void
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001827pointer_cursor_surface_configure(struct weston_surface *es,
Jason Ekstrand918f2dd2013-12-02 21:01:53 -06001828 int32_t dx, int32_t dy)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001829{
Kristian Høgsberg195b8692013-05-08 15:02:05 -04001830 struct weston_pointer *pointer = es->configure_private;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001831 int x, y;
1832
Jason Ekstrand918f2dd2013-12-02 21:01:53 -06001833 if (es->width == 0)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001834 return;
1835
Jason Ekstranda7af7042013-10-12 22:38:11 -05001836 assert(es == pointer->sprite->surface);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001837
Kristian Høgsberg195b8692013-05-08 15:02:05 -04001838 pointer->hotspot_x -= dx;
1839 pointer->hotspot_y -= dy;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001840
Kristian Høgsberg195b8692013-05-08 15:02:05 -04001841 x = wl_fixed_to_int(pointer->x) - pointer->hotspot_x;
1842 y = wl_fixed_to_int(pointer->y) - pointer->hotspot_y;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001843
Jason Ekstrand918f2dd2013-12-02 21:01:53 -06001844 weston_view_set_position(pointer->sprite, x, y);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001845
1846 empty_region(&es->pending.input);
Ander Conselvan de Oliveira23900f72014-01-31 16:07:51 +02001847 empty_region(&es->input);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001848
1849 if (!weston_surface_is_mapped(es)) {
Giulio Camuffo412e6a52014-07-09 22:12:56 +03001850 weston_layer_entry_insert(&es->compositor->cursor_layer.view_list,
1851 &pointer->sprite->layer_link);
Jason Ekstranda7af7042013-10-12 22:38:11 -05001852 weston_view_update_transform(pointer->sprite);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001853 }
1854}
1855
1856static void
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001857pointer_set_cursor(struct wl_client *client, struct wl_resource *resource,
1858 uint32_t serial, struct wl_resource *surface_resource,
1859 int32_t x, int32_t y)
1860{
Jason Ekstrand44a38632013-06-14 10:08:00 -05001861 struct weston_pointer *pointer = wl_resource_get_user_data(resource);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001862 struct weston_surface *surface = NULL;
1863
1864 if (surface_resource)
Jason Ekstrand0f2ef7e2013-06-14 10:07:53 -05001865 surface = wl_resource_get_user_data(surface_resource);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001866
Kristian Høgsberg195b8692013-05-08 15:02:05 -04001867 if (pointer->focus == NULL)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001868 return;
Jason Ekstranda7af7042013-10-12 22:38:11 -05001869 /* pointer->focus->surface->resource can be NULL. Surfaces like the
Giulio Camuffo1fd4b012013-06-20 18:13:07 +02001870 black_surface used in shell.c for fullscreen don't have
1871 a resource, but can still have focus */
Jason Ekstranda7af7042013-10-12 22:38:11 -05001872 if (pointer->focus->surface->resource == NULL)
Giulio Camuffo1fd4b012013-06-20 18:13:07 +02001873 return;
Jason Ekstranda7af7042013-10-12 22:38:11 -05001874 if (wl_resource_get_client(pointer->focus->surface->resource) != client)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001875 return;
Kristian Høgsberg195b8692013-05-08 15:02:05 -04001876 if (pointer->focus_serial - serial > UINT32_MAX / 2)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001877 return;
1878
Derek Foreman4e53c532015-03-23 10:55:32 -05001879 if (!surface) {
1880 if (pointer->sprite)
1881 pointer_unmap_sprite(pointer);
1882 return;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001883 }
1884
Jonas Ådahlb4070242015-03-18 15:08:03 +08001885 if (pointer->sprite && pointer->sprite->surface == surface &&
1886 pointer->hotspot_x == x && pointer->hotspot_y == y)
1887 return;
1888
Derek Foreman4e53c532015-03-23 10:55:32 -05001889 if (!pointer->sprite || pointer->sprite->surface != surface) {
1890 if (weston_surface_set_role(surface, "wl_pointer-cursor",
1891 resource,
1892 WL_POINTER_ERROR_ROLE) < 0)
1893 return;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001894
Derek Foreman4e53c532015-03-23 10:55:32 -05001895 if (pointer->sprite)
1896 pointer_unmap_sprite(pointer);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001897
Derek Foreman4e53c532015-03-23 10:55:32 -05001898 wl_signal_add(&surface->destroy_signal,
1899 &pointer->sprite_destroy_listener);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001900
Derek Foreman4e53c532015-03-23 10:55:32 -05001901 surface->configure = pointer_cursor_surface_configure;
1902 surface->configure_private = pointer;
1903 weston_surface_set_label_func(surface,
1904 pointer_cursor_surface_get_label);
1905 pointer->sprite = weston_view_create(surface);
1906 }
1907
Kristian Høgsberg195b8692013-05-08 15:02:05 -04001908 pointer->hotspot_x = x;
1909 pointer->hotspot_y = y;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001910
Jonas Ådahl16fe4dc2014-09-08 19:33:41 +02001911 if (surface->buffer_ref.buffer) {
Jason Ekstrand918f2dd2013-12-02 21:01:53 -06001912 pointer_cursor_surface_configure(surface, 0, 0);
Jonas Ådahl16fe4dc2014-09-08 19:33:41 +02001913 weston_view_schedule_repaint(pointer->sprite);
1914 }
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001915}
1916
Kristian Høgsberg69e25fc2013-08-13 20:11:02 +01001917static void
1918pointer_release(struct wl_client *client, struct wl_resource *resource)
1919{
1920 wl_resource_destroy(resource);
1921}
1922
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001923static const struct wl_pointer_interface pointer_interface = {
Kristian Høgsberg69e25fc2013-08-13 20:11:02 +01001924 pointer_set_cursor,
1925 pointer_release
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001926};
1927
1928static void
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001929seat_get_pointer(struct wl_client *client, struct wl_resource *resource,
1930 uint32_t id)
1931{
Jason Ekstrand44a38632013-06-14 10:08:00 -05001932 struct weston_seat *seat = wl_resource_get_user_data(resource);
Derek Foreman1281a362015-07-31 16:55:32 -05001933 /* We use the pointer_state directly, which means we'll
1934 * give a wl_pointer if the seat has ever had one - even though
1935 * the spec explicitly states that this request only takes effect
1936 * if the seat has the pointer capability.
1937 *
1938 * This prevents a race between the compositor sending new
1939 * capabilities and the client trying to use the old ones.
1940 */
1941 struct weston_pointer *pointer = seat->pointer_state;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001942 struct wl_resource *cr;
Jonas Ådahl2cbf2932015-07-22 12:05:38 +08001943 struct weston_pointer_client *pointer_client;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001944
Derek Foreman1281a362015-07-31 16:55:32 -05001945 if (!pointer)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001946 return;
1947
Jason Ekstranda85118c2013-06-27 20:17:02 -05001948 cr = wl_resource_create(client, &wl_pointer_interface,
1949 wl_resource_get_version(resource), id);
Kristian Høgsberg0ff79082013-08-06 16:46:25 -07001950 if (cr == NULL) {
1951 wl_client_post_no_memory(client);
1952 return;
1953 }
1954
Jonas Ådahl2cbf2932015-07-22 12:05:38 +08001955 pointer_client = weston_pointer_ensure_pointer_client(pointer, client);
1956 if (!pointer_client) {
1957 wl_client_post_no_memory(client);
1958 return;
1959 }
1960
1961 wl_list_insert(&pointer_client->pointer_resources,
1962 wl_resource_get_link(cr));
Derek Foreman1281a362015-07-31 16:55:32 -05001963 wl_resource_set_implementation(cr, &pointer_interface, pointer,
Jonas Ådahl2cbf2932015-07-22 12:05:38 +08001964 unbind_pointer_client_resource);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001965
Derek Foreman1281a362015-07-31 16:55:32 -05001966 if (pointer->focus && pointer->focus->surface->resource &&
1967 wl_resource_get_client(pointer->focus->surface->resource) == client) {
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001968 wl_fixed_t sx, sy;
1969
Derek Foreman1281a362015-07-31 16:55:32 -05001970 weston_view_from_global_fixed(pointer->focus,
1971 pointer->x,
1972 pointer->y,
Jason Ekstranda7af7042013-10-12 22:38:11 -05001973 &sx, &sy);
Neil Roberts96d790e2013-09-19 17:32:00 +01001974
Neil Roberts96d790e2013-09-19 17:32:00 +01001975 wl_pointer_send_enter(cr,
Derek Foreman1281a362015-07-31 16:55:32 -05001976 pointer->focus_serial,
1977 pointer->focus->surface->resource,
Neil Roberts96d790e2013-09-19 17:32:00 +01001978 sx, sy);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001979 }
1980}
1981
1982static void
Kristian Høgsberg69e25fc2013-08-13 20:11:02 +01001983keyboard_release(struct wl_client *client, struct wl_resource *resource)
1984{
1985 wl_resource_destroy(resource);
1986}
1987
1988static const struct wl_keyboard_interface keyboard_interface = {
1989 keyboard_release
1990};
1991
Derek Foreman280e7dd2014-10-03 13:13:42 -05001992static bool
Neil Roberts96d790e2013-09-19 17:32:00 +01001993should_send_modifiers_to_client(struct weston_seat *seat,
1994 struct wl_client *client)
1995{
Derek Foreman1281a362015-07-31 16:55:32 -05001996 struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
1997 struct weston_pointer *pointer = weston_seat_get_pointer(seat);
1998
1999 if (keyboard &&
2000 keyboard->focus &&
2001 keyboard->focus->resource &&
2002 wl_resource_get_client(keyboard->focus->resource) == client)
Derek Foreman280e7dd2014-10-03 13:13:42 -05002003 return true;
Neil Roberts96d790e2013-09-19 17:32:00 +01002004
Derek Foreman1281a362015-07-31 16:55:32 -05002005 if (pointer &&
2006 pointer->focus &&
2007 pointer->focus->surface->resource &&
2008 wl_resource_get_client(pointer->focus->surface->resource) == client)
Derek Foreman280e7dd2014-10-03 13:13:42 -05002009 return true;
Neil Roberts96d790e2013-09-19 17:32:00 +01002010
Derek Foreman280e7dd2014-10-03 13:13:42 -05002011 return false;
Neil Roberts96d790e2013-09-19 17:32:00 +01002012}
2013
Kristian Høgsberg69e25fc2013-08-13 20:11:02 +01002014static void
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002015seat_get_keyboard(struct wl_client *client, struct wl_resource *resource,
2016 uint32_t id)
2017{
Jason Ekstrand44a38632013-06-14 10:08:00 -05002018 struct weston_seat *seat = wl_resource_get_user_data(resource);
Derek Foreman1281a362015-07-31 16:55:32 -05002019 /* We use the keyboard_state directly, which means we'll
2020 * give a wl_keyboard if the seat has ever had one - even though
2021 * the spec explicitly states that this request only takes effect
2022 * if the seat has the keyboard capability.
2023 *
2024 * This prevents a race between the compositor sending new
2025 * capabilities and the client trying to use the old ones.
2026 */
2027 struct weston_keyboard *keyboard = seat->keyboard_state;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002028 struct wl_resource *cr;
2029
Derek Foreman345c9f32015-06-03 15:53:28 -05002030 if (!keyboard)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002031 return;
2032
Jason Ekstranda85118c2013-06-27 20:17:02 -05002033 cr = wl_resource_create(client, &wl_keyboard_interface,
2034 wl_resource_get_version(resource), id);
Kristian Høgsberg0ff79082013-08-06 16:46:25 -07002035 if (cr == NULL) {
2036 wl_client_post_no_memory(client);
2037 return;
2038 }
2039
Neil Roberts96d790e2013-09-19 17:32:00 +01002040 /* May be moved to focused list later by either
2041 * weston_keyboard_set_focus or directly if this client is already
2042 * focused */
Derek Foreman345c9f32015-06-03 15:53:28 -05002043 wl_list_insert(&keyboard->resource_list, wl_resource_get_link(cr));
Kristian Høgsberg69e25fc2013-08-13 20:11:02 +01002044 wl_resource_set_implementation(cr, &keyboard_interface,
2045 seat, unbind_resource);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002046
Jonny Lamb66a41a02014-08-12 14:58:25 +02002047 if (wl_resource_get_version(cr) >= WL_KEYBOARD_REPEAT_INFO_SINCE_VERSION) {
2048 wl_keyboard_send_repeat_info(cr,
2049 seat->compositor->kb_repeat_rate,
2050 seat->compositor->kb_repeat_delay);
2051 }
Jasper St. Pierred8c6aeb2014-08-04 13:43:24 -04002052
Matt Roper01a92732013-06-24 16:52:44 +01002053 if (seat->compositor->use_xkbcommon) {
2054 wl_keyboard_send_keymap(cr, WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1,
Jonas Ådahl7395ea02013-12-03 09:14:26 +01002055 keyboard->xkb_info->keymap_fd,
2056 keyboard->xkb_info->keymap_size);
Matt Roper01a92732013-06-24 16:52:44 +01002057 } else {
2058 int null_fd = open("/dev/null", O_RDONLY);
2059 wl_keyboard_send_keymap(cr, WL_KEYBOARD_KEYMAP_FORMAT_NO_KEYMAP,
2060 null_fd,
2061 0);
2062 close(null_fd);
2063 }
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002064
Neil Roberts96d790e2013-09-19 17:32:00 +01002065 if (should_send_modifiers_to_client(seat, client)) {
Derek Foreman345c9f32015-06-03 15:53:28 -05002066 send_modifiers_to_resource(keyboard,
Neil Roberts96d790e2013-09-19 17:32:00 +01002067 cr,
Derek Foreman345c9f32015-06-03 15:53:28 -05002068 keyboard->focus_serial);
Neil Roberts96d790e2013-09-19 17:32:00 +01002069 }
2070
Derek Foreman345c9f32015-06-03 15:53:28 -05002071 if (keyboard->focus && keyboard->focus->resource &&
2072 wl_resource_get_client(keyboard->focus->resource) == client) {
Neil Roberts96d790e2013-09-19 17:32:00 +01002073 struct weston_surface *surface =
Derek Foreman345c9f32015-06-03 15:53:28 -05002074 (struct weston_surface *)keyboard->focus;
Neil Roberts96d790e2013-09-19 17:32:00 +01002075
2076 wl_list_remove(wl_resource_get_link(cr));
Derek Foreman345c9f32015-06-03 15:53:28 -05002077 wl_list_insert(&keyboard->focus_resource_list,
Neil Roberts96d790e2013-09-19 17:32:00 +01002078 wl_resource_get_link(cr));
2079 wl_keyboard_send_enter(cr,
Derek Foreman345c9f32015-06-03 15:53:28 -05002080 keyboard->focus_serial,
Neil Roberts96d790e2013-09-19 17:32:00 +01002081 surface->resource,
Derek Foreman345c9f32015-06-03 15:53:28 -05002082 &keyboard->keys);
Neil Roberts96d790e2013-09-19 17:32:00 +01002083
2084 /* If this is the first keyboard resource for this
2085 * client... */
Derek Foreman345c9f32015-06-03 15:53:28 -05002086 if (keyboard->focus_resource_list.prev ==
Neil Roberts96d790e2013-09-19 17:32:00 +01002087 wl_resource_get_link(cr))
2088 wl_data_device_set_keyboard_focus(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002089 }
2090}
2091
2092static void
Kristian Høgsberg69e25fc2013-08-13 20:11:02 +01002093touch_release(struct wl_client *client, struct wl_resource *resource)
2094{
2095 wl_resource_destroy(resource);
2096}
2097
2098static const struct wl_touch_interface touch_interface = {
2099 touch_release
2100};
2101
2102static void
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002103seat_get_touch(struct wl_client *client, struct wl_resource *resource,
2104 uint32_t id)
2105{
Jason Ekstrand44a38632013-06-14 10:08:00 -05002106 struct weston_seat *seat = wl_resource_get_user_data(resource);
Derek Foreman1281a362015-07-31 16:55:32 -05002107 /* We use the touch_state directly, which means we'll
2108 * give a wl_touch if the seat has ever had one - even though
2109 * the spec explicitly states that this request only takes effect
2110 * if the seat has the touch capability.
2111 *
2112 * This prevents a race between the compositor sending new
2113 * capabilities and the client trying to use the old ones.
2114 */
2115 struct weston_touch *touch = seat->touch_state;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002116 struct wl_resource *cr;
2117
Derek Foreman1281a362015-07-31 16:55:32 -05002118 if (!touch)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002119 return;
2120
Jason Ekstranda85118c2013-06-27 20:17:02 -05002121 cr = wl_resource_create(client, &wl_touch_interface,
2122 wl_resource_get_version(resource), id);
Kristian Høgsberg0ff79082013-08-06 16:46:25 -07002123 if (cr == NULL) {
2124 wl_client_post_no_memory(client);
2125 return;
2126 }
2127
Derek Foreman1281a362015-07-31 16:55:32 -05002128 if (touch->focus &&
2129 wl_resource_get_client(touch->focus->surface->resource) == client) {
Chokshi, Mituld6697142015-10-09 08:28:47 +00002130 wl_list_insert(&touch->focus_resource_list,
Neil Roberts96d790e2013-09-19 17:32:00 +01002131 wl_resource_get_link(cr));
2132 } else {
Chokshi, Mituld6697142015-10-09 08:28:47 +00002133 wl_list_insert(&touch->resource_list,
Neil Roberts96d790e2013-09-19 17:32:00 +01002134 wl_resource_get_link(cr));
2135 }
Kristian Høgsberg69e25fc2013-08-13 20:11:02 +01002136 wl_resource_set_implementation(cr, &touch_interface,
2137 seat, unbind_resource);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002138}
2139
2140static const struct wl_seat_interface seat_interface = {
2141 seat_get_pointer,
2142 seat_get_keyboard,
2143 seat_get_touch,
2144};
2145
2146static void
2147bind_seat(struct wl_client *client, void *data, uint32_t version, uint32_t id)
2148{
Kristian Høgsberge3148752013-05-06 23:19:49 -04002149 struct weston_seat *seat = data;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002150 struct wl_resource *resource;
2151 enum wl_seat_capability caps = 0;
2152
Jason Ekstranda85118c2013-06-27 20:17:02 -05002153 resource = wl_resource_create(client,
Derek Foreman1909c102015-11-26 14:17:47 -06002154 &wl_seat_interface, version, id);
Jason Ekstrand44a38632013-06-14 10:08:00 -05002155 wl_list_insert(&seat->base_resource_list, wl_resource_get_link(resource));
Jason Ekstranda85118c2013-06-27 20:17:02 -05002156 wl_resource_set_implementation(resource, &seat_interface, data,
2157 unbind_resource);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002158
Derek Foreman1281a362015-07-31 16:55:32 -05002159 if (weston_seat_get_pointer(seat))
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002160 caps |= WL_SEAT_CAPABILITY_POINTER;
Derek Foreman1281a362015-07-31 16:55:32 -05002161 if (weston_seat_get_keyboard(seat))
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002162 caps |= WL_SEAT_CAPABILITY_KEYBOARD;
Derek Foreman1281a362015-07-31 16:55:32 -05002163 if (weston_seat_get_touch(seat))
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002164 caps |= WL_SEAT_CAPABILITY_TOUCH;
2165
2166 wl_seat_send_capabilities(resource, caps);
Jasper St. Pierre0013a292014-08-07 16:43:11 -04002167 if (version >= WL_SEAT_NAME_SINCE_VERSION)
Rob Bradforde445ae62013-05-31 18:09:51 +01002168 wl_seat_send_name(resource, seat->seat_name);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002169}
2170
Rob Bradford382ff462013-06-24 16:52:45 +01002171#ifdef ENABLE_XKBCOMMON
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002172int
2173weston_compositor_xkb_init(struct weston_compositor *ec,
2174 struct xkb_rule_names *names)
2175{
Rob Bradford382ff462013-06-24 16:52:45 +01002176 ec->use_xkbcommon = 1;
Matt Roper01a92732013-06-24 16:52:44 +01002177
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002178 if (ec->xkb_context == NULL) {
2179 ec->xkb_context = xkb_context_new(0);
2180 if (ec->xkb_context == NULL) {
2181 weston_log("failed to create XKB context\n");
2182 return -1;
2183 }
2184 }
2185
2186 if (names)
2187 ec->xkb_names = *names;
2188 if (!ec->xkb_names.rules)
2189 ec->xkb_names.rules = strdup("evdev");
2190 if (!ec->xkb_names.model)
2191 ec->xkb_names.model = strdup("pc105");
2192 if (!ec->xkb_names.layout)
2193 ec->xkb_names.layout = strdup("us");
2194
2195 return 0;
2196}
2197
Stefan Schmidtfda26522013-09-17 10:54:09 +01002198static void
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00002199weston_xkb_info_destroy(struct weston_xkb_info *xkb_info)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002200{
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00002201 if (--xkb_info->ref_count > 0)
2202 return;
2203
Ran Benitac9c74152014-08-19 23:59:52 +03002204 xkb_keymap_unref(xkb_info->keymap);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002205
2206 if (xkb_info->keymap_area)
2207 munmap(xkb_info->keymap_area, xkb_info->keymap_size);
2208 if (xkb_info->keymap_fd >= 0)
2209 close(xkb_info->keymap_fd);
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00002210 free(xkb_info);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002211}
2212
2213void
2214weston_compositor_xkb_destroy(struct weston_compositor *ec)
2215{
Matt Roper01a92732013-06-24 16:52:44 +01002216 /*
2217 * If we're operating in raw keyboard mode, we never initialized
2218 * libxkbcommon so there's no cleanup to do either.
2219 */
2220 if (!ec->use_xkbcommon)
2221 return;
2222
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002223 free((char *) ec->xkb_names.rules);
2224 free((char *) ec->xkb_names.model);
2225 free((char *) ec->xkb_names.layout);
2226 free((char *) ec->xkb_names.variant);
2227 free((char *) ec->xkb_names.options);
Stefan Schmidtfda26522013-09-17 10:54:09 +01002228
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00002229 if (ec->xkb_info)
2230 weston_xkb_info_destroy(ec->xkb_info);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002231 xkb_context_unref(ec->xkb_context);
2232}
2233
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00002234static struct weston_xkb_info *
2235weston_xkb_info_create(struct xkb_keymap *keymap)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002236{
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00002237 struct weston_xkb_info *xkb_info = zalloc(sizeof *xkb_info);
2238 if (xkb_info == NULL)
2239 return NULL;
2240
Ran Benita2e1968f2014-08-19 23:59:51 +03002241 xkb_info->keymap = xkb_keymap_ref(keymap);
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00002242 xkb_info->ref_count = 1;
2243
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002244 char *keymap_str;
2245
Ran Benita2e1968f2014-08-19 23:59:51 +03002246 xkb_info->shift_mod = xkb_keymap_mod_get_index(xkb_info->keymap,
2247 XKB_MOD_NAME_SHIFT);
2248 xkb_info->caps_mod = xkb_keymap_mod_get_index(xkb_info->keymap,
2249 XKB_MOD_NAME_CAPS);
2250 xkb_info->ctrl_mod = xkb_keymap_mod_get_index(xkb_info->keymap,
2251 XKB_MOD_NAME_CTRL);
2252 xkb_info->alt_mod = xkb_keymap_mod_get_index(xkb_info->keymap,
2253 XKB_MOD_NAME_ALT);
2254 xkb_info->mod2_mod = xkb_keymap_mod_get_index(xkb_info->keymap,
2255 "Mod2");
2256 xkb_info->mod3_mod = xkb_keymap_mod_get_index(xkb_info->keymap,
2257 "Mod3");
2258 xkb_info->super_mod = xkb_keymap_mod_get_index(xkb_info->keymap,
2259 XKB_MOD_NAME_LOGO);
2260 xkb_info->mod5_mod = xkb_keymap_mod_get_index(xkb_info->keymap,
2261 "Mod5");
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002262
Ran Benita2e1968f2014-08-19 23:59:51 +03002263 xkb_info->num_led = xkb_keymap_led_get_index(xkb_info->keymap,
2264 XKB_LED_NAME_NUM);
2265 xkb_info->caps_led = xkb_keymap_led_get_index(xkb_info->keymap,
2266 XKB_LED_NAME_CAPS);
2267 xkb_info->scroll_led = xkb_keymap_led_get_index(xkb_info->keymap,
2268 XKB_LED_NAME_SCROLL);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002269
Ran Benita2e1968f2014-08-19 23:59:51 +03002270 keymap_str = xkb_keymap_get_as_string(xkb_info->keymap,
2271 XKB_KEYMAP_FORMAT_TEXT_V1);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002272 if (keymap_str == NULL) {
2273 weston_log("failed to get string version of keymap\n");
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00002274 goto err_keymap;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002275 }
2276 xkb_info->keymap_size = strlen(keymap_str) + 1;
2277
2278 xkb_info->keymap_fd = os_create_anonymous_file(xkb_info->keymap_size);
2279 if (xkb_info->keymap_fd < 0) {
2280 weston_log("creating a keymap file for %lu bytes failed: %m\n",
2281 (unsigned long) xkb_info->keymap_size);
2282 goto err_keymap_str;
2283 }
2284
2285 xkb_info->keymap_area = mmap(NULL, xkb_info->keymap_size,
2286 PROT_READ | PROT_WRITE,
2287 MAP_SHARED, xkb_info->keymap_fd, 0);
2288 if (xkb_info->keymap_area == MAP_FAILED) {
2289 weston_log("failed to mmap() %lu bytes\n",
2290 (unsigned long) xkb_info->keymap_size);
2291 goto err_dev_zero;
2292 }
2293 strcpy(xkb_info->keymap_area, keymap_str);
2294 free(keymap_str);
2295
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00002296 return xkb_info;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002297
2298err_dev_zero:
2299 close(xkb_info->keymap_fd);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002300err_keymap_str:
2301 free(keymap_str);
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00002302err_keymap:
Ran Benita2e1968f2014-08-19 23:59:51 +03002303 xkb_keymap_unref(xkb_info->keymap);
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00002304 free(xkb_info);
2305 return NULL;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002306}
2307
2308static int
2309weston_compositor_build_global_keymap(struct weston_compositor *ec)
2310{
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00002311 struct xkb_keymap *keymap;
2312
2313 if (ec->xkb_info != NULL)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002314 return 0;
2315
Ran Benita2e1968f2014-08-19 23:59:51 +03002316 keymap = xkb_keymap_new_from_names(ec->xkb_context,
2317 &ec->xkb_names,
2318 0);
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00002319 if (keymap == NULL) {
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002320 weston_log("failed to compile global XKB keymap\n");
2321 weston_log(" tried rules %s, model %s, layout %s, variant %s, "
2322 "options %s\n",
2323 ec->xkb_names.rules, ec->xkb_names.model,
2324 ec->xkb_names.layout, ec->xkb_names.variant,
2325 ec->xkb_names.options);
2326 return -1;
2327 }
2328
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00002329 ec->xkb_info = weston_xkb_info_create(keymap);
Rui Matos73d93952013-10-24 19:28:41 +02002330 xkb_keymap_unref(keymap);
Stefan Schmidtfda26522013-09-17 10:54:09 +01002331 if (ec->xkb_info == NULL)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002332 return -1;
2333
2334 return 0;
2335}
Rob Bradford382ff462013-06-24 16:52:45 +01002336#else
2337int
2338weston_compositor_xkb_init(struct weston_compositor *ec,
2339 struct xkb_rule_names *names)
2340{
2341 return 0;
2342}
2343
2344void
2345weston_compositor_xkb_destroy(struct weston_compositor *ec)
2346{
2347}
2348#endif
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002349
Rui Matos65196bc2013-10-10 19:44:19 +02002350WL_EXPORT void
2351weston_seat_update_keymap(struct weston_seat *seat, struct xkb_keymap *keymap)
2352{
Derek Foreman1281a362015-07-31 16:55:32 -05002353 struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
2354
2355 if (!keyboard || !keymap)
Rui Matos65196bc2013-10-10 19:44:19 +02002356 return;
2357
2358#ifdef ENABLE_XKBCOMMON
2359 if (!seat->compositor->use_xkbcommon)
2360 return;
2361
Derek Foreman1281a362015-07-31 16:55:32 -05002362 xkb_keymap_unref(keyboard->pending_keymap);
2363 keyboard->pending_keymap = xkb_keymap_ref(keymap);
Rui Matos65196bc2013-10-10 19:44:19 +02002364
Derek Foreman1281a362015-07-31 16:55:32 -05002365 if (keyboard->keys.size == 0)
Rui Matos65196bc2013-10-10 19:44:19 +02002366 update_keymap(seat);
2367#endif
2368}
2369
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002370WL_EXPORT int
2371weston_seat_init_keyboard(struct weston_seat *seat, struct xkb_keymap *keymap)
2372{
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04002373 struct weston_keyboard *keyboard;
2374
Derek Foreman1281a362015-07-31 16:55:32 -05002375 if (seat->keyboard_state) {
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002376 seat->keyboard_device_count += 1;
2377 if (seat->keyboard_device_count == 1)
2378 seat_send_updated_caps(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002379 return 0;
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002380 }
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002381
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04002382 keyboard = weston_keyboard_create();
2383 if (keyboard == NULL) {
2384 weston_log("failed to allocate weston keyboard struct\n");
2385 return -1;
2386 }
2387
Jonas Ådahl7395ea02013-12-03 09:14:26 +01002388#ifdef ENABLE_XKBCOMMON
2389 if (seat->compositor->use_xkbcommon) {
2390 if (keymap != NULL) {
2391 keyboard->xkb_info = weston_xkb_info_create(keymap);
2392 if (keyboard->xkb_info == NULL)
Ander Conselvan de Oliveira4d363cf2014-01-31 17:35:45 +02002393 goto err;
Jonas Ådahl7395ea02013-12-03 09:14:26 +01002394 } else {
2395 if (weston_compositor_build_global_keymap(seat->compositor) < 0)
Ander Conselvan de Oliveira4d363cf2014-01-31 17:35:45 +02002396 goto err;
Jonas Ådahl7395ea02013-12-03 09:14:26 +01002397 keyboard->xkb_info = seat->compositor->xkb_info;
2398 keyboard->xkb_info->ref_count++;
2399 }
2400
2401 keyboard->xkb_state.state = xkb_state_new(keyboard->xkb_info->keymap);
2402 if (keyboard->xkb_state.state == NULL) {
2403 weston_log("failed to initialise XKB state\n");
Ander Conselvan de Oliveira4d363cf2014-01-31 17:35:45 +02002404 goto err;
Jonas Ådahl7395ea02013-12-03 09:14:26 +01002405 }
2406
2407 keyboard->xkb_state.leds = 0;
2408 }
2409#endif
2410
Derek Foreman1281a362015-07-31 16:55:32 -05002411 seat->keyboard_state = keyboard;
Ander Conselvan de Oliveira4d363cf2014-01-31 17:35:45 +02002412 seat->keyboard_device_count = 1;
2413 keyboard->seat = seat;
2414
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04002415 seat_send_updated_caps(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002416
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002417 return 0;
Ander Conselvan de Oliveira4d363cf2014-01-31 17:35:45 +02002418
2419err:
2420 if (keyboard->xkb_info)
2421 weston_xkb_info_destroy(keyboard->xkb_info);
2422 free(keyboard);
2423
2424 return -1;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002425}
2426
Jonas Ådahl91fed542013-12-03 09:14:27 +01002427static void
2428weston_keyboard_reset_state(struct weston_keyboard *keyboard)
2429{
2430 struct weston_seat *seat = keyboard->seat;
2431 struct xkb_state *state;
2432
2433#ifdef ENABLE_XKBCOMMON
2434 if (seat->compositor->use_xkbcommon) {
2435 state = xkb_state_new(keyboard->xkb_info->keymap);
2436 if (!state) {
2437 weston_log("failed to reset XKB state\n");
2438 return;
2439 }
2440 xkb_state_unref(keyboard->xkb_state.state);
2441 keyboard->xkb_state.state = state;
2442
2443 keyboard->xkb_state.leds = 0;
2444 }
2445#endif
2446
2447 seat->modifier_state = 0;
2448}
2449
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002450WL_EXPORT void
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002451weston_seat_release_keyboard(struct weston_seat *seat)
2452{
2453 seat->keyboard_device_count--;
Derek Foremand621df22014-11-19 11:04:12 -06002454 assert(seat->keyboard_device_count >= 0);
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002455 if (seat->keyboard_device_count == 0) {
Derek Foreman1281a362015-07-31 16:55:32 -05002456 weston_keyboard_set_focus(seat->keyboard_state, NULL);
2457 weston_keyboard_cancel_grab(seat->keyboard_state);
2458 weston_keyboard_reset_state(seat->keyboard_state);
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002459 seat_send_updated_caps(seat);
2460 }
2461}
2462
2463WL_EXPORT void
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002464weston_seat_init_pointer(struct weston_seat *seat)
2465{
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04002466 struct weston_pointer *pointer;
2467
Derek Foreman1281a362015-07-31 16:55:32 -05002468 if (seat->pointer_state) {
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002469 seat->pointer_device_count += 1;
2470 if (seat->pointer_device_count == 1)
2471 seat_send_updated_caps(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002472 return;
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002473 }
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002474
Giulio Camuffocdb4d292013-11-14 23:42:53 +01002475 pointer = weston_pointer_create(seat);
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04002476 if (pointer == NULL)
2477 return;
2478
Derek Foreman1281a362015-07-31 16:55:32 -05002479 seat->pointer_state = pointer;
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002480 seat->pointer_device_count = 1;
2481 pointer->seat = seat;
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04002482
2483 seat_send_updated_caps(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002484}
2485
2486WL_EXPORT void
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002487weston_seat_release_pointer(struct weston_seat *seat)
2488{
Derek Foreman1281a362015-07-31 16:55:32 -05002489 struct weston_pointer *pointer = seat->pointer_state;
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002490
2491 seat->pointer_device_count--;
2492 if (seat->pointer_device_count == 0) {
Derek Foremanf9318d12015-05-11 15:40:11 -05002493 weston_pointer_clear_focus(pointer);
Jonas Ådahl1ea343e2013-10-25 23:18:05 +02002494 weston_pointer_cancel_grab(pointer);
Jonas Ådahl630bae82013-10-17 23:04:06 +02002495
Jonas Ådahla4932742013-10-17 23:04:07 +02002496 if (pointer->sprite)
2497 pointer_unmap_sprite(pointer);
2498
Jonas Ådahl3e12e632013-12-02 22:05:05 +01002499 weston_pointer_reset_state(pointer);
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002500 seat_send_updated_caps(seat);
Derek Foremanfd5ca512015-01-07 15:00:25 -06002501
2502 /* seat->pointer is intentionally not destroyed so that
2503 * a newly attached pointer on this seat will retain
2504 * the previous cursor co-ordinates.
2505 */
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002506 }
2507}
2508
2509WL_EXPORT void
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002510weston_seat_init_touch(struct weston_seat *seat)
2511{
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04002512 struct weston_touch *touch;
2513
Derek Foreman1281a362015-07-31 16:55:32 -05002514 if (seat->touch_state) {
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002515 seat->touch_device_count += 1;
2516 if (seat->touch_device_count == 1)
2517 seat_send_updated_caps(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002518 return;
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002519 }
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002520
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04002521 touch = weston_touch_create();
2522 if (touch == NULL)
2523 return;
2524
Derek Foreman1281a362015-07-31 16:55:32 -05002525 seat->touch_state = touch;
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002526 seat->touch_device_count = 1;
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04002527 touch->seat = seat;
2528
2529 seat_send_updated_caps(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002530}
2531
2532WL_EXPORT void
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002533weston_seat_release_touch(struct weston_seat *seat)
2534{
2535 seat->touch_device_count--;
2536 if (seat->touch_device_count == 0) {
Derek Foreman1281a362015-07-31 16:55:32 -05002537 weston_touch_set_focus(seat->touch_state, NULL);
2538 weston_touch_cancel_grab(seat->touch_state);
2539 weston_touch_reset_state(seat->touch_state);
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002540 seat_send_updated_caps(seat);
2541 }
2542}
2543
2544WL_EXPORT void
Rob Bradford9af5f9e2013-05-31 18:09:50 +01002545weston_seat_init(struct weston_seat *seat, struct weston_compositor *ec,
2546 const char *seat_name)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002547{
Kristian Høgsberg4a2a2742013-05-06 22:24:50 -04002548 memset(seat, 0, sizeof *seat);
2549
Kristian Høgsberge3148752013-05-06 23:19:49 -04002550 seat->selection_data_source = NULL;
2551 wl_list_init(&seat->base_resource_list);
2552 wl_signal_init(&seat->selection_signal);
2553 wl_list_init(&seat->drag_resource_list);
Kristian Høgsberge3148752013-05-06 23:19:49 -04002554 wl_signal_init(&seat->destroy_signal);
Jason Ekstranda4ab5422014-04-02 19:53:45 -05002555 wl_signal_init(&seat->updated_caps_signal);
Kristian Høgsberg4a2a2742013-05-06 22:24:50 -04002556
Jasper St. Pierred8c6aeb2014-08-04 13:43:24 -04002557 seat->global = wl_global_create(ec->wl_display, &wl_seat_interface, 4,
Kristian Høgsberg919cddb2013-07-08 19:03:57 -04002558 seat, bind_seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002559
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002560 seat->compositor = ec;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002561 seat->modifier_state = 0;
Rob Bradford9af5f9e2013-05-31 18:09:50 +01002562 seat->seat_name = strdup(seat_name);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002563
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002564 wl_list_insert(ec->seat_list.prev, &seat->link);
2565
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002566 clipboard_create(seat);
2567
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002568 wl_signal_emit(&ec->seat_created_signal, seat);
2569}
2570
2571WL_EXPORT void
2572weston_seat_release(struct weston_seat *seat)
2573{
2574 wl_list_remove(&seat->link);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002575
Jonas Ådahl1afb2382014-01-03 19:46:51 +01002576 if (seat->saved_kbd_focus)
2577 wl_list_remove(&seat->saved_kbd_focus_listener.link);
2578
Derek Foreman1281a362015-07-31 16:55:32 -05002579 if (seat->pointer_state)
2580 weston_pointer_destroy(seat->pointer_state);
2581 if (seat->keyboard_state)
2582 weston_keyboard_destroy(seat->keyboard_state);
2583 if (seat->touch_state)
2584 weston_touch_destroy(seat->touch_state);
Kristian Høgsberg4a2a2742013-05-06 22:24:50 -04002585
Rob Bradford9af5f9e2013-05-31 18:09:50 +01002586 free (seat->seat_name);
2587
Kristian Høgsberg919cddb2013-07-08 19:03:57 -04002588 wl_global_destroy(seat->global);
Kristian Høgsbergaaadc772013-07-08 16:20:31 -04002589
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002590 wl_signal_emit(&seat->destroy_signal, seat);
2591}
Derek Foreman1281a362015-07-31 16:55:32 -05002592
2593/** Get a seat's keyboard pointer
2594 *
2595 * \param seat The seat to query
2596 * \return The seat's keyboard pointer, or NULL if no keyboard is present
2597 *
2598 * The keyboard pointer for a seat isn't freed when all keyboards are removed,
2599 * so it should only be used when the seat's keyboard_device_count is greater
2600 * than zero. This function does that test and only returns a pointer
2601 * when a keyboard is present.
2602 */
2603WL_EXPORT struct weston_keyboard *
2604weston_seat_get_keyboard(struct weston_seat *seat)
2605{
2606 if (!seat)
2607 return NULL;
2608
2609 if (seat->keyboard_device_count)
2610 return seat->keyboard_state;
2611
2612 return NULL;
2613}
2614
2615/** Get a seat's pointer pointer
2616 *
2617 * \param seat The seat to query
2618 * \return The seat's pointer pointer, or NULL if no pointer device is present
2619 *
2620 * The pointer pointer for a seat isn't freed when all mice are removed,
2621 * so it should only be used when the seat's pointer_device_count is greater
2622 * than zero. This function does that test and only returns a pointer
2623 * when a pointing device is present.
2624 */
2625WL_EXPORT struct weston_pointer *
2626weston_seat_get_pointer(struct weston_seat *seat)
2627{
2628 if (!seat)
2629 return NULL;
2630
2631 if (seat->pointer_device_count)
2632 return seat->pointer_state;
2633
2634 return NULL;
2635}
2636
2637/** Get a seat's touch pointer
2638 *
2639 * \param seat The seat to query
2640 * \return The seat's touch pointer, or NULL if no touch device is present
2641 *
2642 * The touch pointer for a seat isn't freed when all touch devices are removed,
2643 * so it should only be used when the seat's touch_device_count is greater
2644 * than zero. This function does that test and only returns a pointer
2645 * when a touch device is present.
2646 */
2647WL_EXPORT struct weston_touch *
2648weston_seat_get_touch(struct weston_seat *seat)
2649{
2650 if (!seat)
2651 return NULL;
2652
2653 if (seat->touch_device_count)
2654 return seat->touch_state;
2655
2656 return NULL;
2657}