blob: 91813ec2fc4a051fbb4918f43fc1116ae235184a [file] [log] [blame]
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001/*
2 * Copyright © 2013 Intel Corporation
3 *
Bryce Harringtona0bbfea2015-06-11 15:35:43 -07004 * Permission is hereby granted, free of charge, to any person obtaining
5 * a copy of this software and associated documentation files (the
6 * "Software"), to deal in the Software without restriction, including
7 * without limitation the rights to use, copy, modify, merge, publish,
8 * distribute, sublicense, and/or sell copies of the Software, and to
9 * permit persons to whom the Software is furnished to do so, subject to
10 * the following conditions:
Kristian Høgsberg2158a882013-04-18 15:07:39 -040011 *
Bryce Harringtona0bbfea2015-06-11 15:35:43 -070012 * The above copyright notice and this permission notice (including the
13 * next paragraph) shall be included in all copies or substantial
14 * portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
20 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
21 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 * SOFTWARE.
Kristian Høgsberg2158a882013-04-18 15:07:39 -040024 */
25
Daniel Stone8e7a8bd2013-08-15 01:10:24 +010026#include "config.h"
27
Kristian Høgsberg2158a882013-04-18 15:07:39 -040028#include <stdlib.h>
29#include <stdint.h>
30#include <string.h>
Kristian Høgsbergb5e26102013-04-18 15:40:10 -040031#include <sys/mman.h>
32#include <assert.h>
33#include <unistd.h>
Matt Roper01a92732013-06-24 16:52:44 +010034#include <fcntl.h>
Ander Conselvan de Oliveira54e90c72013-12-13 22:10:56 +020035#include <limits.h>
Kristian Høgsberg2158a882013-04-18 15:07:39 -040036
Jon Cruz35b2eaa2015-06-15 15:37:08 -070037#include "shared/helpers.h"
Jon Cruz4678bab2015-06-15 15:37:07 -070038#include "shared/os-compatibility.h"
Kristian Høgsberg2158a882013-04-18 15:07:39 -040039#include "compositor.h"
40
Kristian Høgsbergb5e26102013-04-18 15:40:10 -040041static void
42empty_region(pixman_region32_t *region)
43{
44 pixman_region32_fini(region);
45 pixman_region32_init(region);
46}
47
Jonas Ådahl2cbf2932015-07-22 12:05:38 +080048static struct weston_pointer_client *
49weston_pointer_client_create(struct wl_client *client)
50{
51 struct weston_pointer_client *pointer_client;
52
53 pointer_client = zalloc(sizeof *pointer_client);
54 if (!pointer_client)
55 return NULL;
56
57 pointer_client->client = client;
58 wl_list_init(&pointer_client->pointer_resources);
59
60 return pointer_client;
61}
62
63static void
64weston_pointer_client_destroy(struct weston_pointer_client *pointer_client)
65{
66 free(pointer_client);
67}
68
69static bool
70weston_pointer_client_is_empty(struct weston_pointer_client *pointer_client)
71{
72 return wl_list_empty(&pointer_client->pointer_resources);
73}
74
75static struct weston_pointer_client *
76weston_pointer_get_pointer_client(struct weston_pointer *pointer,
77 struct wl_client *client)
78{
79 struct weston_pointer_client *pointer_client;
80
81 wl_list_for_each(pointer_client, &pointer->pointer_clients, link) {
82 if (pointer_client->client == client)
83 return pointer_client;
84 }
85
86 return NULL;
87}
88
89static struct weston_pointer_client *
90weston_pointer_ensure_pointer_client(struct weston_pointer *pointer,
91 struct wl_client *client)
92{
93 struct weston_pointer_client *pointer_client;
94
95 pointer_client = weston_pointer_get_pointer_client(pointer, client);
96 if (pointer_client)
97 return pointer_client;
98
99 pointer_client = weston_pointer_client_create(client);
100 wl_list_insert(&pointer->pointer_clients, &pointer_client->link);
101
102 if (pointer->focus &&
103 pointer->focus->surface->resource &&
104 wl_resource_get_client(pointer->focus->surface->resource) == client) {
105 pointer->focus_client = pointer_client;
106 }
107
108 return pointer_client;
109}
110
111static void
112weston_pointer_cleanup_pointer_client(struct weston_pointer *pointer,
113 struct weston_pointer_client *pointer_client)
114{
115 if (weston_pointer_client_is_empty(pointer_client)) {
116 if (pointer->focus_client == pointer_client)
117 pointer->focus_client = NULL;
118 wl_list_remove(&pointer_client->link);
119 weston_pointer_client_destroy(pointer_client);
120 }
121}
122
123static void
124unbind_pointer_client_resource(struct wl_resource *resource)
125{
126 struct weston_pointer *pointer = wl_resource_get_user_data(resource);
127 struct wl_client *client = wl_resource_get_client(resource);
128 struct weston_pointer_client *pointer_client;
129
130 pointer_client = weston_pointer_get_pointer_client(pointer, client);
131 assert(pointer_client);
132
133 wl_list_remove(wl_resource_get_link(resource));
134 weston_pointer_cleanup_pointer_client(pointer, pointer_client);
135}
136
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400137static void unbind_resource(struct wl_resource *resource)
138{
Jason Ekstrand44a38632013-06-14 10:08:00 -0500139 wl_list_remove(wl_resource_get_link(resource));
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400140}
141
Jonas Ådahl3042ffe2013-10-17 23:04:08 +0200142WL_EXPORT void
Kristian Høgsberga71e8b22013-05-06 21:51:21 -0400143weston_seat_repick(struct weston_seat *seat)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400144{
Derek Foreman1281a362015-07-31 16:55:32 -0500145 const struct weston_pointer *pointer = weston_seat_get_pointer(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400146
Derek Foreman1b786ee2015-06-03 15:53:23 -0500147 if (!pointer)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400148 return;
149
Derek Foreman1b786ee2015-06-03 15:53:23 -0500150 pointer->grab->interface->focus(pointer->grab);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400151}
152
153static void
154weston_compositor_idle_inhibit(struct weston_compositor *compositor)
155{
156 weston_compositor_wake(compositor);
157 compositor->idle_inhibit++;
158}
159
160static void
161weston_compositor_idle_release(struct weston_compositor *compositor)
162{
163 compositor->idle_inhibit--;
164 weston_compositor_wake(compositor);
165}
166
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400167static void
Giulio Camuffo576fe2a2013-11-20 18:00:24 +0100168pointer_focus_view_destroyed(struct wl_listener *listener, void *data)
169{
170 struct weston_pointer *pointer =
171 container_of(listener, struct weston_pointer,
172 focus_view_listener);
173
Derek Foremanf9318d12015-05-11 15:40:11 -0500174 weston_pointer_clear_focus(pointer);
Giulio Camuffo576fe2a2013-11-20 18:00:24 +0100175}
176
177static void
178pointer_focus_resource_destroyed(struct wl_listener *listener, void *data)
179{
180 struct weston_pointer *pointer =
181 container_of(listener, struct weston_pointer,
182 focus_resource_listener);
183
Derek Foremanf9318d12015-05-11 15:40:11 -0500184 weston_pointer_clear_focus(pointer);
Giulio Camuffo576fe2a2013-11-20 18:00:24 +0100185}
186
187static void
188keyboard_focus_resource_destroyed(struct wl_listener *listener, void *data)
189{
190 struct weston_keyboard *keyboard =
191 container_of(listener, struct weston_keyboard,
192 focus_resource_listener);
193
194 weston_keyboard_set_focus(keyboard, NULL);
195}
196
197static void
198touch_focus_view_destroyed(struct wl_listener *listener, void *data)
199{
200 struct weston_touch *touch =
201 container_of(listener, struct weston_touch,
202 focus_view_listener);
203
Derek Foreman4c93c082015-04-30 16:45:41 -0500204 weston_touch_set_focus(touch, NULL);
Giulio Camuffo576fe2a2013-11-20 18:00:24 +0100205}
206
207static void
208touch_focus_resource_destroyed(struct wl_listener *listener, void *data)
209{
210 struct weston_touch *touch =
211 container_of(listener, struct weston_touch,
212 focus_resource_listener);
213
Derek Foreman4c93c082015-04-30 16:45:41 -0500214 weston_touch_set_focus(touch, NULL);
Giulio Camuffo576fe2a2013-11-20 18:00:24 +0100215}
216
217static void
Neil Roberts96d790e2013-09-19 17:32:00 +0100218move_resources(struct wl_list *destination, struct wl_list *source)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400219{
Neil Roberts96d790e2013-09-19 17:32:00 +0100220 wl_list_insert_list(destination, source);
221 wl_list_init(source);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400222}
223
224static void
Neil Roberts96d790e2013-09-19 17:32:00 +0100225move_resources_for_client(struct wl_list *destination,
226 struct wl_list *source,
227 struct wl_client *client)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400228{
Neil Roberts96d790e2013-09-19 17:32:00 +0100229 struct wl_resource *resource, *tmp;
230 wl_resource_for_each_safe(resource, tmp, source) {
231 if (wl_resource_get_client(resource) == client) {
232 wl_list_remove(wl_resource_get_link(resource));
233 wl_list_insert(destination,
234 wl_resource_get_link(resource));
235 }
236 }
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400237}
238
239static void
Kristian Høgsbergb27901c2013-10-28 15:32:02 -0700240default_grab_pointer_focus(struct weston_pointer_grab *grab)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400241{
Kristian Høgsberg02bbabb2013-05-06 22:15:05 -0400242 struct weston_pointer *pointer = grab->pointer;
Jason Ekstranda7af7042013-10-12 22:38:11 -0500243 struct weston_view *view;
Kristian Høgsberg6848c252013-05-08 22:02:59 -0400244 wl_fixed_t sx, sy;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400245
246 if (pointer->button_count > 0)
247 return;
248
Jason Ekstranda7af7042013-10-12 22:38:11 -0500249 view = weston_compositor_pick_view(pointer->seat->compositor,
250 pointer->x, pointer->y,
251 &sx, &sy);
Kristian Høgsberg6848c252013-05-08 22:02:59 -0400252
Kristian Høgsbergdb1fccb2014-02-05 17:14:42 -0800253 if (pointer->focus != view || pointer->sx != sx || pointer->sy != sy)
Jason Ekstranda7af7042013-10-12 22:38:11 -0500254 weston_pointer_set_focus(pointer, view, sx, sy);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400255}
256
257static void
Giulio Camuffo1959ab82013-11-14 23:42:52 +0100258default_grab_pointer_motion(struct weston_pointer_grab *grab, uint32_t time,
Jonas Ådahld2510102014-10-05 21:39:14 +0200259 struct weston_pointer_motion_event *event)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400260{
Kristian Høgsbergbe6403e2013-05-08 21:03:21 -0400261 struct weston_pointer *pointer = grab->pointer;
Neil Roberts96d790e2013-09-19 17:32:00 +0100262 struct wl_list *resource_list;
263 struct wl_resource *resource;
Jonas Ådahld2510102014-10-05 21:39:14 +0200264 wl_fixed_t x, y;
Jonas Ådahl8283c342015-04-24 15:26:17 +0800265 wl_fixed_t old_sx = pointer->sx;
266 wl_fixed_t old_sy = pointer->sy;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400267
Jonas Ådahld2510102014-10-05 21:39:14 +0200268 if (pointer->focus) {
269 weston_pointer_motion_to_abs(pointer, event, &x, &y);
Kristian Høgsbergdb1fccb2014-02-05 17:14:42 -0800270 weston_view_from_global_fixed(pointer->focus, x, y,
271 &pointer->sx, &pointer->sy);
Jonas Ådahld2510102014-10-05 21:39:14 +0200272 }
Kristian Høgsbergdb1fccb2014-02-05 17:14:42 -0800273
Jonas Ådahld2510102014-10-05 21:39:14 +0200274 weston_pointer_move(pointer, event);
Giulio Camuffo1959ab82013-11-14 23:42:52 +0100275
Jonas Ådahl2cbf2932015-07-22 12:05:38 +0800276 if (pointer->focus_client &&
277 (old_sx != pointer->sx || old_sy != pointer->sy)) {
278 resource_list = &pointer->focus_client->pointer_resources;
Jonas Ådahl8283c342015-04-24 15:26:17 +0800279 wl_resource_for_each(resource, resource_list) {
280 wl_pointer_send_motion(resource, time,
281 pointer->sx, pointer->sy);
282 }
Kristian Høgsbergbe6403e2013-05-08 21:03:21 -0400283 }
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400284}
285
286static void
Kristian Høgsbergb27901c2013-10-28 15:32:02 -0700287default_grab_pointer_button(struct weston_pointer_grab *grab,
288 uint32_t time, uint32_t button, uint32_t state_w)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400289{
Kristian Høgsberg02bbabb2013-05-06 22:15:05 -0400290 struct weston_pointer *pointer = grab->pointer;
Kristian Høgsberge122b7b2013-05-08 16:47:00 -0400291 struct weston_compositor *compositor = pointer->seat->compositor;
Jason Ekstranda7af7042013-10-12 22:38:11 -0500292 struct weston_view *view;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400293 struct wl_resource *resource;
294 uint32_t serial;
295 enum wl_pointer_button_state state = state_w;
Rob Bradford880ebc72013-07-22 17:31:38 +0100296 struct wl_display *display = compositor->wl_display;
Kristian Høgsberge122b7b2013-05-08 16:47:00 -0400297 wl_fixed_t sx, sy;
Jonas Ådahl2cbf2932015-07-22 12:05:38 +0800298 struct wl_list *resource_list = NULL;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400299
Jonas Ådahl2cbf2932015-07-22 12:05:38 +0800300 if (pointer->focus_client)
301 resource_list = &pointer->focus_client->pointer_resources;
302 if (resource_list && !wl_list_empty(resource_list)) {
303 resource_list = &pointer->focus_client->pointer_resources;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400304 serial = wl_display_next_serial(display);
Neil Roberts96d790e2013-09-19 17:32:00 +0100305 wl_resource_for_each(resource, resource_list)
306 wl_pointer_send_button(resource,
307 serial,
308 time,
309 button,
310 state_w);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400311 }
312
313 if (pointer->button_count == 0 &&
Kristian Høgsberge122b7b2013-05-08 16:47:00 -0400314 state == WL_POINTER_BUTTON_STATE_RELEASED) {
Jason Ekstranda7af7042013-10-12 22:38:11 -0500315 view = weston_compositor_pick_view(compositor,
316 pointer->x, pointer->y,
317 &sx, &sy);
Kristian Høgsberge122b7b2013-05-08 16:47:00 -0400318
Jason Ekstranda7af7042013-10-12 22:38:11 -0500319 weston_pointer_set_focus(pointer, view, sx, sy);
Kristian Høgsberge122b7b2013-05-08 16:47:00 -0400320 }
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400321}
322
Jonas Ådahl0336ca02014-10-04 16:28:29 +0200323/** Send wl_pointer.axis events to focused resources.
324 *
325 * \param pointer The pointer where the axis events originates from.
326 * \param time The timestamp of the event
327 * \param axis The axis enum value of the event
328 * \param value The axis value of the event
329 *
330 * For every resource that is currently in focus, send a wl_pointer.axis event
331 * with the passed parameters. The focused resources are the wl_pointer
332 * resources of the client which currently has the surface with pointer focus.
333 */
334WL_EXPORT void
335weston_pointer_send_axis(struct weston_pointer *pointer,
Peter Hutterer89b6a492016-01-18 15:58:17 +1000336 uint32_t time,
337 struct weston_pointer_axis_event *event)
Jonas Ådahl0336ca02014-10-04 16:28:29 +0200338{
339 struct wl_resource *resource;
340 struct wl_list *resource_list;
341
Jonas Ådahl2cbf2932015-07-22 12:05:38 +0800342 if (!pointer->focus_client)
343 return;
344
345 resource_list = &pointer->focus_client->pointer_resources;
Peter Hutterer87743e92016-01-18 16:38:22 +1000346 wl_resource_for_each(resource, resource_list) {
347 if (event->has_discrete &&
348 wl_resource_get_version(resource) >=
349 WL_POINTER_AXIS_DISCRETE_SINCE_VERSION)
350 wl_pointer_send_axis_discrete(resource, event->axis,
351 event->discrete);
352
353 if (event->value)
354 wl_pointer_send_axis(resource, time,
355 event->axis, event->value);
356 else if (wl_resource_get_version(resource) >=
357 WL_POINTER_AXIS_STOP_SINCE_VERSION)
358 wl_pointer_send_axis_stop(resource, time,
359 event->axis);
360 }
361}
362
363WL_EXPORT void
364weston_pointer_send_axis_source(struct weston_pointer *pointer, uint32_t source)
365{
366 struct wl_resource *resource;
367 struct wl_list *resource_list;
368
369 resource_list = &pointer->focus_client->pointer_resources;
370 wl_resource_for_each(resource, resource_list) {
371 if (wl_resource_get_version(resource) >=
372 WL_POINTER_AXIS_SOURCE_SINCE_VERSION) {
373 wl_pointer_send_axis_source(resource, source);
374 }
375 }
376}
377
378static void
379pointer_send_frame(struct wl_resource *resource)
380{
381 if (wl_resource_get_version(resource) >=
382 WL_POINTER_FRAME_SINCE_VERSION) {
383 wl_pointer_send_frame(resource);
384 }
385}
386
387WL_EXPORT void
388weston_pointer_send_frame(struct weston_pointer *pointer)
389{
390 struct wl_resource *resource;
391 struct wl_list *resource_list;
392
393 resource_list = &pointer->focus_client->pointer_resources;
Jonas Ådahl0336ca02014-10-04 16:28:29 +0200394 wl_resource_for_each(resource, resource_list)
Peter Hutterer87743e92016-01-18 16:38:22 +1000395 pointer_send_frame(resource);
Jonas Ådahl0336ca02014-10-04 16:28:29 +0200396}
397
398static void
399default_grab_pointer_axis(struct weston_pointer_grab *grab,
Peter Hutterer89b6a492016-01-18 15:58:17 +1000400 uint32_t time,
401 struct weston_pointer_axis_event *event)
Jonas Ådahl0336ca02014-10-04 16:28:29 +0200402{
Peter Hutterer89b6a492016-01-18 15:58:17 +1000403 weston_pointer_send_axis(grab->pointer, time, event);
Jonas Ådahl0336ca02014-10-04 16:28:29 +0200404}
405
Jonas Ådahl1ea343e2013-10-25 23:18:05 +0200406static void
Peter Hutterer87743e92016-01-18 16:38:22 +1000407default_grab_pointer_axis_source(struct weston_pointer_grab *grab,
408 uint32_t source)
409{
410 weston_pointer_send_axis_source(grab->pointer, source);
411}
412
413static void
414default_grab_pointer_frame(struct weston_pointer_grab *grab)
415{
416 weston_pointer_send_frame(grab->pointer);
417}
418
419static void
Jonas Ådahl1ea343e2013-10-25 23:18:05 +0200420default_grab_pointer_cancel(struct weston_pointer_grab *grab)
421{
422}
423
Kristian Høgsberg02bbabb2013-05-06 22:15:05 -0400424static const struct weston_pointer_grab_interface
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400425 default_pointer_grab_interface = {
Kristian Høgsbergb27901c2013-10-28 15:32:02 -0700426 default_grab_pointer_focus,
427 default_grab_pointer_motion,
428 default_grab_pointer_button,
Jonas Ådahl0336ca02014-10-04 16:28:29 +0200429 default_grab_pointer_axis,
Peter Hutterer87743e92016-01-18 16:38:22 +1000430 default_grab_pointer_axis_source,
431 default_grab_pointer_frame,
Jonas Ådahl1ea343e2013-10-25 23:18:05 +0200432 default_grab_pointer_cancel,
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400433};
434
Kristian Høgsberge329f362013-05-06 22:19:57 -0400435static void
436default_grab_touch_down(struct weston_touch_grab *grab, uint32_t time,
Giulio Camuffo61ed7b62015-07-08 11:55:28 +0300437 int touch_id, wl_fixed_t x, wl_fixed_t y)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400438{
Kristian Høgsberge329f362013-05-06 22:19:57 -0400439 struct weston_touch *touch = grab->touch;
Rob Bradford880ebc72013-07-22 17:31:38 +0100440 struct wl_display *display = touch->seat->compositor->wl_display;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400441 uint32_t serial;
Neil Roberts96d790e2013-09-19 17:32:00 +0100442 struct wl_resource *resource;
443 struct wl_list *resource_list;
Giulio Camuffo61ed7b62015-07-08 11:55:28 +0300444 wl_fixed_t sx, sy;
445
446 weston_view_from_global_fixed(touch->focus, x, y, &sx, &sy);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400447
Neil Roberts96d790e2013-09-19 17:32:00 +0100448 resource_list = &touch->focus_resource_list;
449
450 if (!wl_list_empty(resource_list) && touch->focus) {
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400451 serial = wl_display_next_serial(display);
Neil Roberts96d790e2013-09-19 17:32:00 +0100452 wl_resource_for_each(resource, resource_list)
453 wl_touch_send_down(resource, serial, time,
Jason Ekstranda7af7042013-10-12 22:38:11 -0500454 touch->focus->surface->resource,
Neil Roberts96d790e2013-09-19 17:32:00 +0100455 touch_id, sx, sy);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400456 }
457}
458
Kristian Høgsberge329f362013-05-06 22:19:57 -0400459static void
460default_grab_touch_up(struct weston_touch_grab *grab,
461 uint32_t time, int touch_id)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400462{
Kristian Høgsberge329f362013-05-06 22:19:57 -0400463 struct weston_touch *touch = grab->touch;
Rob Bradford880ebc72013-07-22 17:31:38 +0100464 struct wl_display *display = touch->seat->compositor->wl_display;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400465 uint32_t serial;
Neil Roberts96d790e2013-09-19 17:32:00 +0100466 struct wl_resource *resource;
467 struct wl_list *resource_list;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400468
Neil Roberts96d790e2013-09-19 17:32:00 +0100469 resource_list = &touch->focus_resource_list;
470
471 if (!wl_list_empty(resource_list)) {
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400472 serial = wl_display_next_serial(display);
Neil Roberts96d790e2013-09-19 17:32:00 +0100473 wl_resource_for_each(resource, resource_list)
474 wl_touch_send_up(resource, serial, time, touch_id);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400475 }
476}
477
Kristian Høgsberge329f362013-05-06 22:19:57 -0400478static void
479default_grab_touch_motion(struct weston_touch_grab *grab, uint32_t time,
Giulio Camuffo61ed7b62015-07-08 11:55:28 +0300480 int touch_id, wl_fixed_t x, wl_fixed_t y)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400481{
Kristian Høgsberge329f362013-05-06 22:19:57 -0400482 struct weston_touch *touch = grab->touch;
Neil Roberts96d790e2013-09-19 17:32:00 +0100483 struct wl_resource *resource;
484 struct wl_list *resource_list;
Giulio Camuffo61ed7b62015-07-08 11:55:28 +0300485 wl_fixed_t sx, sy;
486
487 weston_view_from_global_fixed(touch->focus, x, y, &sx, &sy);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400488
Neil Roberts96d790e2013-09-19 17:32:00 +0100489 resource_list = &touch->focus_resource_list;
490
491 wl_resource_for_each(resource, resource_list) {
492 wl_touch_send_motion(resource, time,
Kristian Høgsberge329f362013-05-06 22:19:57 -0400493 touch_id, sx, sy);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400494 }
495}
496
Jonas Ådahl1ea343e2013-10-25 23:18:05 +0200497static void
Jonas Ådahl1679f232014-04-12 09:39:51 +0200498default_grab_touch_frame(struct weston_touch_grab *grab)
499{
500 struct wl_resource *resource;
501
502 wl_resource_for_each(resource, &grab->touch->focus_resource_list)
503 wl_touch_send_frame(resource);
504}
505
506static void
Jonas Ådahl1ea343e2013-10-25 23:18:05 +0200507default_grab_touch_cancel(struct weston_touch_grab *grab)
508{
509}
510
Kristian Høgsberge329f362013-05-06 22:19:57 -0400511static const struct weston_touch_grab_interface default_touch_grab_interface = {
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400512 default_grab_touch_down,
513 default_grab_touch_up,
Jonas Ådahl1ea343e2013-10-25 23:18:05 +0200514 default_grab_touch_motion,
Jonas Ådahl1679f232014-04-12 09:39:51 +0200515 default_grab_touch_frame,
Jonas Ådahl1ea343e2013-10-25 23:18:05 +0200516 default_grab_touch_cancel,
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400517};
518
519static void
Kristian Høgsbergb27901c2013-10-28 15:32:02 -0700520default_grab_keyboard_key(struct weston_keyboard_grab *grab,
521 uint32_t time, uint32_t key, uint32_t state)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400522{
Kristian Høgsberg29139d42013-04-18 15:25:39 -0400523 struct weston_keyboard *keyboard = grab->keyboard;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400524 struct wl_resource *resource;
Rob Bradford880ebc72013-07-22 17:31:38 +0100525 struct wl_display *display = keyboard->seat->compositor->wl_display;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400526 uint32_t serial;
Neil Roberts96d790e2013-09-19 17:32:00 +0100527 struct wl_list *resource_list;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400528
Neil Roberts96d790e2013-09-19 17:32:00 +0100529 resource_list = &keyboard->focus_resource_list;
530 if (!wl_list_empty(resource_list)) {
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400531 serial = wl_display_next_serial(display);
Neil Roberts96d790e2013-09-19 17:32:00 +0100532 wl_resource_for_each(resource, resource_list)
533 wl_keyboard_send_key(resource,
534 serial,
535 time,
536 key,
537 state);
538 }
539}
540
541static void
542send_modifiers_to_resource(struct weston_keyboard *keyboard,
543 struct wl_resource *resource,
544 uint32_t serial)
545{
546 wl_keyboard_send_modifiers(resource,
547 serial,
548 keyboard->modifiers.mods_depressed,
549 keyboard->modifiers.mods_latched,
550 keyboard->modifiers.mods_locked,
551 keyboard->modifiers.group);
552}
553
554static void
555send_modifiers_to_client_in_list(struct wl_client *client,
556 struct wl_list *list,
557 uint32_t serial,
558 struct weston_keyboard *keyboard)
559{
560 struct wl_resource *resource;
561
562 wl_resource_for_each(resource, list) {
563 if (wl_resource_get_client(resource) == client)
564 send_modifiers_to_resource(keyboard,
565 resource,
566 serial);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400567 }
568}
569
Jonas Ådahl2cbf2932015-07-22 12:05:38 +0800570static struct weston_pointer_client *
571find_pointer_client_for_surface(struct weston_pointer *pointer,
572 struct weston_surface *surface)
573{
574 struct wl_client *client;
575
576 if (!surface)
577 return NULL;
578
579 if (!surface->resource)
580 return NULL;
581
582 client = wl_resource_get_client(surface->resource);
583 return weston_pointer_get_pointer_client(pointer, client);
584}
585
586static struct weston_pointer_client *
587find_pointer_client_for_view(struct weston_pointer *pointer, struct weston_view *view)
588{
589 if (!view)
590 return NULL;
591
592 return find_pointer_client_for_surface(pointer, view->surface);
593}
594
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400595static struct wl_resource *
Kristian Høgsbergfe7aa902013-05-08 09:54:37 -0400596find_resource_for_surface(struct wl_list *list, struct weston_surface *surface)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400597{
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400598 if (!surface)
599 return NULL;
600
Jason Ekstrand44a38632013-06-14 10:08:00 -0500601 if (!surface->resource)
602 return NULL;
Stefan Schmidtfda26522013-09-17 10:54:09 +0100603
Jason Ekstrand44a38632013-06-14 10:08:00 -0500604 return wl_resource_find_for_client(list, wl_resource_get_client(surface->resource));
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400605}
606
607static void
Kristian Høgsbergb27901c2013-10-28 15:32:02 -0700608default_grab_keyboard_modifiers(struct weston_keyboard_grab *grab,
609 uint32_t serial, uint32_t mods_depressed,
610 uint32_t mods_latched,
611 uint32_t mods_locked, uint32_t group)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400612{
Kristian Høgsberg29139d42013-04-18 15:25:39 -0400613 struct weston_keyboard *keyboard = grab->keyboard;
Derek Foreman1281a362015-07-31 16:55:32 -0500614 struct weston_pointer *pointer =
615 weston_seat_get_pointer(grab->keyboard->seat);
Neil Roberts96d790e2013-09-19 17:32:00 +0100616 struct wl_resource *resource;
617 struct wl_list *resource_list;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400618
Neil Roberts96d790e2013-09-19 17:32:00 +0100619 resource_list = &keyboard->focus_resource_list;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400620
Neil Roberts96d790e2013-09-19 17:32:00 +0100621 wl_resource_for_each(resource, resource_list) {
622 wl_keyboard_send_modifiers(resource, serial, mods_depressed,
623 mods_latched, mods_locked, group);
624 }
Jason Ekstrand42133d42013-11-14 20:06:16 -0600625 if (pointer && pointer->focus && pointer->focus->surface->resource &&
626 pointer->focus->surface != keyboard->focus) {
Neil Roberts96d790e2013-09-19 17:32:00 +0100627 struct wl_client *pointer_client =
Jason Ekstranda7af7042013-10-12 22:38:11 -0500628 wl_resource_get_client(pointer->focus->surface->resource);
Neil Roberts96d790e2013-09-19 17:32:00 +0100629 send_modifiers_to_client_in_list(pointer_client,
630 &keyboard->resource_list,
631 serial,
632 keyboard);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400633 }
634}
635
Jonas Ådahl1ea343e2013-10-25 23:18:05 +0200636static void
637default_grab_keyboard_cancel(struct weston_keyboard_grab *grab)
638{
639}
640
Kristian Høgsberg29139d42013-04-18 15:25:39 -0400641static const struct weston_keyboard_grab_interface
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400642 default_keyboard_grab_interface = {
Kristian Høgsbergb27901c2013-10-28 15:32:02 -0700643 default_grab_keyboard_key,
644 default_grab_keyboard_modifiers,
Jonas Ådahl1ea343e2013-10-25 23:18:05 +0200645 default_grab_keyboard_cancel,
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400646};
647
Kristian Høgsberg195b8692013-05-08 15:02:05 -0400648static void
649pointer_unmap_sprite(struct weston_pointer *pointer)
650{
Pekka Paalanenc557ff72014-11-12 16:42:52 +0200651 struct weston_surface *surface = pointer->sprite->surface;
652
653 if (weston_surface_is_mapped(surface))
654 weston_surface_unmap(surface);
Kristian Høgsberg195b8692013-05-08 15:02:05 -0400655
656 wl_list_remove(&pointer->sprite_destroy_listener.link);
Pekka Paalanenc557ff72014-11-12 16:42:52 +0200657 surface->configure = NULL;
658 surface->configure_private = NULL;
Pekka Paalanen8274d902014-08-06 19:36:51 +0300659 weston_surface_set_label_func(surface, NULL);
Jason Ekstranda7af7042013-10-12 22:38:11 -0500660 weston_view_destroy(pointer->sprite);
Kristian Høgsberg195b8692013-05-08 15:02:05 -0400661 pointer->sprite = NULL;
662}
663
664static void
665pointer_handle_sprite_destroy(struct wl_listener *listener, void *data)
666{
667 struct weston_pointer *pointer =
668 container_of(listener, struct weston_pointer,
669 sprite_destroy_listener);
670
671 pointer->sprite = NULL;
672}
673
Jonas Ådahl3e12e632013-12-02 22:05:05 +0100674static void
675weston_pointer_reset_state(struct weston_pointer *pointer)
676{
677 pointer->button_count = 0;
678}
679
Ander Conselvan de Oliveiraf84327a2014-01-29 18:47:51 +0200680static void
681weston_pointer_handle_output_destroy(struct wl_listener *listener, void *data);
682
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400683WL_EXPORT struct weston_pointer *
Giulio Camuffocdb4d292013-11-14 23:42:53 +0100684weston_pointer_create(struct weston_seat *seat)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400685{
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400686 struct weston_pointer *pointer;
687
Peter Huttererf3d62272013-08-08 11:57:05 +1000688 pointer = zalloc(sizeof *pointer);
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400689 if (pointer == NULL)
690 return NULL;
691
Jonas Ådahl2cbf2932015-07-22 12:05:38 +0800692 wl_list_init(&pointer->pointer_clients);
Giulio Camuffocdb4d292013-11-14 23:42:53 +0100693 weston_pointer_set_default_grab(pointer,
694 seat->compositor->default_pointer_grab);
Giulio Camuffo576fe2a2013-11-20 18:00:24 +0100695 wl_list_init(&pointer->focus_resource_listener.link);
696 pointer->focus_resource_listener.notify = pointer_focus_resource_destroyed;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400697 pointer->default_grab.pointer = pointer;
698 pointer->grab = &pointer->default_grab;
Giulio Camuffo6fcb3782013-11-14 23:42:50 +0100699 wl_signal_init(&pointer->motion_signal);
Emilio Pozuelo Monfortaa7a4762013-11-19 11:37:15 +0100700 wl_signal_init(&pointer->focus_signal);
Giulio Camuffo576fe2a2013-11-20 18:00:24 +0100701 wl_list_init(&pointer->focus_view_listener.link);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400702
Kristian Høgsberg195b8692013-05-08 15:02:05 -0400703 pointer->sprite_destroy_listener.notify = pointer_handle_sprite_destroy;
704
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400705 /* FIXME: Pick better co-ords. */
706 pointer->x = wl_fixed_from_int(100);
707 pointer->y = wl_fixed_from_int(100);
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400708
Ander Conselvan de Oliveiraf84327a2014-01-29 18:47:51 +0200709 pointer->output_destroy_listener.notify =
710 weston_pointer_handle_output_destroy;
711 wl_signal_add(&seat->compositor->output_destroyed_signal,
712 &pointer->output_destroy_listener);
713
Derek Foremanf9318d12015-05-11 15:40:11 -0500714 pointer->sx = wl_fixed_from_int(-1000000);
715 pointer->sy = wl_fixed_from_int(-1000000);
716
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400717 return pointer;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400718}
719
720WL_EXPORT void
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400721weston_pointer_destroy(struct weston_pointer *pointer)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400722{
Kristian Høgsberg195b8692013-05-08 15:02:05 -0400723 if (pointer->sprite)
724 pointer_unmap_sprite(pointer);
725
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400726 /* XXX: What about pointer->resource_list? */
Neil Roberts96d790e2013-09-19 17:32:00 +0100727
Giulio Camuffo576fe2a2013-11-20 18:00:24 +0100728 wl_list_remove(&pointer->focus_resource_listener.link);
729 wl_list_remove(&pointer->focus_view_listener.link);
Ander Conselvan de Oliveiraf84327a2014-01-29 18:47:51 +0200730 wl_list_remove(&pointer->output_destroy_listener.link);
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400731 free(pointer);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400732}
733
Giulio Camuffocdb4d292013-11-14 23:42:53 +0100734void
735weston_pointer_set_default_grab(struct weston_pointer *pointer,
736 const struct weston_pointer_grab_interface *interface)
737{
738 if (interface)
739 pointer->default_grab.interface = interface;
740 else
741 pointer->default_grab.interface =
742 &default_pointer_grab_interface;
743}
744
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400745WL_EXPORT struct weston_keyboard *
746weston_keyboard_create(void)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400747{
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400748 struct weston_keyboard *keyboard;
749
Peter Huttererf3d62272013-08-08 11:57:05 +1000750 keyboard = zalloc(sizeof *keyboard);
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400751 if (keyboard == NULL)
Neil Roberts96d790e2013-09-19 17:32:00 +0100752 return NULL;
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400753
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400754 wl_list_init(&keyboard->resource_list);
Neil Roberts96d790e2013-09-19 17:32:00 +0100755 wl_list_init(&keyboard->focus_resource_list);
Giulio Camuffo576fe2a2013-11-20 18:00:24 +0100756 wl_list_init(&keyboard->focus_resource_listener.link);
757 keyboard->focus_resource_listener.notify = keyboard_focus_resource_destroyed;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400758 wl_array_init(&keyboard->keys);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400759 keyboard->default_grab.interface = &default_keyboard_grab_interface;
760 keyboard->default_grab.keyboard = keyboard;
761 keyboard->grab = &keyboard->default_grab;
762 wl_signal_init(&keyboard->focus_signal);
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400763
764 return keyboard;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400765}
766
Jonas Ådahl7395ea02013-12-03 09:14:26 +0100767static void
768weston_xkb_info_destroy(struct weston_xkb_info *xkb_info);
769
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400770WL_EXPORT void
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400771weston_keyboard_destroy(struct weston_keyboard *keyboard)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400772{
773 /* XXX: What about keyboard->resource_list? */
Neil Roberts96d790e2013-09-19 17:32:00 +0100774
Jonas Ådahl7395ea02013-12-03 09:14:26 +0100775#ifdef ENABLE_XKBCOMMON
776 if (keyboard->seat->compositor->use_xkbcommon) {
Ran Benitac9c74152014-08-19 23:59:52 +0300777 xkb_state_unref(keyboard->xkb_state.state);
Jonas Ådahl7395ea02013-12-03 09:14:26 +0100778 if (keyboard->xkb_info)
779 weston_xkb_info_destroy(keyboard->xkb_info);
Ran Benitac9c74152014-08-19 23:59:52 +0300780 xkb_keymap_unref(keyboard->pending_keymap);
Jonas Ådahl7395ea02013-12-03 09:14:26 +0100781 }
782#endif
783
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400784 wl_array_release(&keyboard->keys);
Giulio Camuffo576fe2a2013-11-20 18:00:24 +0100785 wl_list_remove(&keyboard->focus_resource_listener.link);
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400786 free(keyboard);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400787}
788
Jonas Ådahlcbfa7f72013-12-02 22:05:04 +0100789static void
790weston_touch_reset_state(struct weston_touch *touch)
791{
792 touch->num_tp = 0;
793}
794
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400795WL_EXPORT struct weston_touch *
796weston_touch_create(void)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400797{
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400798 struct weston_touch *touch;
799
Peter Huttererf3d62272013-08-08 11:57:05 +1000800 touch = zalloc(sizeof *touch);
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400801 if (touch == NULL)
802 return NULL;
803
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400804 wl_list_init(&touch->resource_list);
Neil Roberts96d790e2013-09-19 17:32:00 +0100805 wl_list_init(&touch->focus_resource_list);
Giulio Camuffo576fe2a2013-11-20 18:00:24 +0100806 wl_list_init(&touch->focus_view_listener.link);
807 touch->focus_view_listener.notify = touch_focus_view_destroyed;
808 wl_list_init(&touch->focus_resource_listener.link);
809 touch->focus_resource_listener.notify = touch_focus_resource_destroyed;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400810 touch->default_grab.interface = &default_touch_grab_interface;
811 touch->default_grab.touch = touch;
812 touch->grab = &touch->default_grab;
813 wl_signal_init(&touch->focus_signal);
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400814
815 return touch;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400816}
817
818WL_EXPORT void
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400819weston_touch_destroy(struct weston_touch *touch)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400820{
821 /* XXX: What about touch->resource_list? */
Neil Roberts96d790e2013-09-19 17:32:00 +0100822
Giulio Camuffo576fe2a2013-11-20 18:00:24 +0100823 wl_list_remove(&touch->focus_view_listener.link);
824 wl_list_remove(&touch->focus_resource_listener.link);
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400825 free(touch);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400826}
827
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400828static void
Kristian Høgsberge3148752013-05-06 23:19:49 -0400829seat_send_updated_caps(struct weston_seat *seat)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400830{
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400831 enum wl_seat_capability caps = 0;
Rob Bradford6e737f52013-09-06 17:48:19 +0100832 struct wl_resource *resource;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400833
Jonas Ådahld6e1c342013-10-17 23:04:05 +0200834 if (seat->pointer_device_count > 0)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400835 caps |= WL_SEAT_CAPABILITY_POINTER;
Jonas Ådahld6e1c342013-10-17 23:04:05 +0200836 if (seat->keyboard_device_count > 0)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400837 caps |= WL_SEAT_CAPABILITY_KEYBOARD;
Jonas Ådahld6e1c342013-10-17 23:04:05 +0200838 if (seat->touch_device_count > 0)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400839 caps |= WL_SEAT_CAPABILITY_TOUCH;
840
Rob Bradford6e737f52013-09-06 17:48:19 +0100841 wl_resource_for_each(resource, &seat->base_resource_list) {
842 wl_seat_send_capabilities(resource, caps);
Jason Ekstrand44a38632013-06-14 10:08:00 -0500843 }
Jason Ekstranda4ab5422014-04-02 19:53:45 -0500844 wl_signal_emit(&seat->updated_caps_signal, seat);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400845}
846
Derek Foremanf9318d12015-05-11 15:40:11 -0500847
848/** Clear the pointer focus
849 *
850 * \param pointer the pointer to clear focus for.
851 *
852 * This can be used to unset pointer focus and set the co-ordinates to the
853 * arbitrary values we use for the no focus case.
854 *
855 * There's no requirement to use this function. For example, passing the
856 * results of a weston_compositor_pick_view() directly to
857 * weston_pointer_set_focus() will do the right thing when no view is found.
858 */
859WL_EXPORT void
860weston_pointer_clear_focus(struct weston_pointer *pointer)
861{
862 weston_pointer_set_focus(pointer, NULL,
863 wl_fixed_from_int(-1000000),
864 wl_fixed_from_int(-1000000));
865}
866
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400867WL_EXPORT void
Kristian Høgsberg02bbabb2013-05-06 22:15:05 -0400868weston_pointer_set_focus(struct weston_pointer *pointer,
Jason Ekstranda7af7042013-10-12 22:38:11 -0500869 struct weston_view *view,
Kristian Høgsberg02bbabb2013-05-06 22:15:05 -0400870 wl_fixed_t sx, wl_fixed_t sy)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400871{
Jonas Ådahl2cbf2932015-07-22 12:05:38 +0800872 struct weston_pointer_client *pointer_client;
Derek Foreman1281a362015-07-31 16:55:32 -0500873 struct weston_keyboard *kbd = weston_seat_get_keyboard(pointer->seat);
Neil Roberts96d790e2013-09-19 17:32:00 +0100874 struct wl_resource *resource;
Jonas Ådahl2cbf2932015-07-22 12:05:38 +0800875 struct wl_resource *surface_resource;
Rob Bradford880ebc72013-07-22 17:31:38 +0100876 struct wl_display *display = pointer->seat->compositor->wl_display;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400877 uint32_t serial;
Neil Roberts96d790e2013-09-19 17:32:00 +0100878 struct wl_list *focus_resource_list;
Kristian Høgsbergdb1fccb2014-02-05 17:14:42 -0800879 int refocus = 0;
Jason Ekstranda7af7042013-10-12 22:38:11 -0500880
881 if ((!pointer->focus && view) ||
882 (pointer->focus && !view) ||
Kristian Høgsbergdb1fccb2014-02-05 17:14:42 -0800883 (pointer->focus && pointer->focus->surface != view->surface) ||
884 pointer->sx != sx || pointer->sy != sy)
885 refocus = 1;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400886
Jonas Ådahl2cbf2932015-07-22 12:05:38 +0800887 if (pointer->focus_client && refocus) {
888 focus_resource_list = &pointer->focus_client->pointer_resources;
889 if (!wl_list_empty(focus_resource_list)) {
890 serial = wl_display_next_serial(display);
891 surface_resource = pointer->focus->surface->resource;
892 wl_resource_for_each(resource, focus_resource_list) {
893 wl_pointer_send_leave(resource, serial,
894 surface_resource);
Peter Hutterer87743e92016-01-18 16:38:22 +1000895 pointer_send_frame(resource);
Jonas Ådahl2cbf2932015-07-22 12:05:38 +0800896 }
Neil Roberts96d790e2013-09-19 17:32:00 +0100897 }
898
Jonas Ådahl2cbf2932015-07-22 12:05:38 +0800899 pointer->focus_client = NULL;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400900 }
901
Jonas Ådahl2cbf2932015-07-22 12:05:38 +0800902 pointer_client = find_pointer_client_for_view(pointer, view);
903 if (pointer_client && refocus) {
904 struct wl_client *surface_client = pointer_client->client;
Neil Roberts96d790e2013-09-19 17:32:00 +0100905
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400906 serial = wl_display_next_serial(display);
Neil Roberts96d790e2013-09-19 17:32:00 +0100907
Jason Ekstranda7af7042013-10-12 22:38:11 -0500908 if (kbd && kbd->focus != view->surface)
Kristian Høgsbergcb406f12013-10-09 10:54:03 -0700909 send_modifiers_to_client_in_list(surface_client,
910 &kbd->resource_list,
911 serial,
912 kbd);
913
Jonas Ådahl2cbf2932015-07-22 12:05:38 +0800914 pointer->focus_client = pointer_client;
Neil Roberts96d790e2013-09-19 17:32:00 +0100915
Jonas Ådahl2cbf2932015-07-22 12:05:38 +0800916 focus_resource_list = &pointer->focus_client->pointer_resources;
Neil Roberts96d790e2013-09-19 17:32:00 +0100917 wl_resource_for_each(resource, focus_resource_list) {
918 wl_pointer_send_enter(resource,
919 serial,
Jason Ekstranda7af7042013-10-12 22:38:11 -0500920 view->surface->resource,
Neil Roberts96d790e2013-09-19 17:32:00 +0100921 sx, sy);
Peter Hutterer87743e92016-01-18 16:38:22 +1000922 pointer_send_frame(resource);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400923 }
Neil Roberts96d790e2013-09-19 17:32:00 +0100924
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400925 pointer->focus_serial = serial;
926 }
927
Giulio Camuffo65a07f82013-12-06 12:46:27 +0100928 wl_list_remove(&pointer->focus_view_listener.link);
929 wl_list_init(&pointer->focus_view_listener.link);
930 wl_list_remove(&pointer->focus_resource_listener.link);
931 wl_list_init(&pointer->focus_resource_listener.link);
Emilio Pozuelo Monfortaa7a4762013-11-19 11:37:15 +0100932 if (view)
Giulio Camuffo576fe2a2013-11-20 18:00:24 +0100933 wl_signal_add(&view->destroy_signal, &pointer->focus_view_listener);
Giulio Camuffo65a07f82013-12-06 12:46:27 +0100934 if (view && view->surface->resource)
935 wl_resource_add_destroy_listener(view->surface->resource,
936 &pointer->focus_resource_listener);
937
938 pointer->focus = view;
939 pointer->focus_view_listener.notify = pointer_focus_view_destroyed;
Kristian Høgsbergdb1fccb2014-02-05 17:14:42 -0800940 pointer->sx = sx;
941 pointer->sy = sy;
942
Derek Foremanf9318d12015-05-11 15:40:11 -0500943 assert(view || sx == wl_fixed_from_int(-1000000));
944 assert(view || sy == wl_fixed_from_int(-1000000));
945
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400946 wl_signal_emit(&pointer->focus_signal, pointer);
947}
948
Neil Roberts96d790e2013-09-19 17:32:00 +0100949static void
950send_enter_to_resource_list(struct wl_list *list,
951 struct weston_keyboard *keyboard,
952 struct weston_surface *surface,
953 uint32_t serial)
954{
955 struct wl_resource *resource;
956
957 wl_resource_for_each(resource, list) {
958 send_modifiers_to_resource(keyboard, resource, serial);
959 wl_keyboard_send_enter(resource, serial,
960 surface->resource,
961 &keyboard->keys);
962 }
963}
964
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400965WL_EXPORT void
Kristian Høgsberg29139d42013-04-18 15:25:39 -0400966weston_keyboard_set_focus(struct weston_keyboard *keyboard,
Kristian Høgsbergfe7aa902013-05-08 09:54:37 -0400967 struct weston_surface *surface)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400968{
969 struct wl_resource *resource;
Rob Bradford880ebc72013-07-22 17:31:38 +0100970 struct wl_display *display = keyboard->seat->compositor->wl_display;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400971 uint32_t serial;
Neil Roberts96d790e2013-09-19 17:32:00 +0100972 struct wl_list *focus_resource_list;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400973
Neil Roberts96d790e2013-09-19 17:32:00 +0100974 focus_resource_list = &keyboard->focus_resource_list;
975
976 if (!wl_list_empty(focus_resource_list) && keyboard->focus != surface) {
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400977 serial = wl_display_next_serial(display);
Neil Roberts96d790e2013-09-19 17:32:00 +0100978 wl_resource_for_each(resource, focus_resource_list) {
979 wl_keyboard_send_leave(resource, serial,
980 keyboard->focus->resource);
981 }
982 move_resources(&keyboard->resource_list, focus_resource_list);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400983 }
984
Neil Roberts96d790e2013-09-19 17:32:00 +0100985 if (find_resource_for_surface(&keyboard->resource_list, surface) &&
986 keyboard->focus != surface) {
987 struct wl_client *surface_client =
988 wl_resource_get_client(surface->resource);
989
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400990 serial = wl_display_next_serial(display);
Neil Roberts96d790e2013-09-19 17:32:00 +0100991
992 move_resources_for_client(focus_resource_list,
993 &keyboard->resource_list,
994 surface_client);
995 send_enter_to_resource_list(focus_resource_list,
996 keyboard,
997 surface,
998 serial);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400999 keyboard->focus_serial = serial;
Giulio Camuffo65a07f82013-12-06 12:46:27 +01001000 }
1001
1002 wl_list_remove(&keyboard->focus_resource_listener.link);
1003 wl_list_init(&keyboard->focus_resource_listener.link);
1004 if (surface && surface->resource)
Giulio Camuffo576fe2a2013-11-20 18:00:24 +01001005 wl_resource_add_destroy_listener(surface->resource,
1006 &keyboard->focus_resource_listener);
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001007
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001008 keyboard->focus = surface;
1009 wl_signal_emit(&keyboard->focus_signal, keyboard);
1010}
1011
Giulio Camuffoa20ca812014-11-22 11:16:56 +02001012/* Users of this function must manually manage the keyboard focus */
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001013WL_EXPORT void
Kristian Høgsberg29139d42013-04-18 15:25:39 -04001014weston_keyboard_start_grab(struct weston_keyboard *keyboard,
1015 struct weston_keyboard_grab *grab)
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001016{
1017 keyboard->grab = grab;
1018 grab->keyboard = keyboard;
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001019}
1020
1021WL_EXPORT void
Kristian Høgsberg29139d42013-04-18 15:25:39 -04001022weston_keyboard_end_grab(struct weston_keyboard *keyboard)
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001023{
1024 keyboard->grab = &keyboard->default_grab;
1025}
1026
Jonas Ådahl1ea343e2013-10-25 23:18:05 +02001027static void
1028weston_keyboard_cancel_grab(struct weston_keyboard *keyboard)
1029{
1030 keyboard->grab->interface->cancel(keyboard->grab);
1031}
1032
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001033WL_EXPORT void
Kristian Høgsberg02bbabb2013-05-06 22:15:05 -04001034weston_pointer_start_grab(struct weston_pointer *pointer,
1035 struct weston_pointer_grab *grab)
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001036{
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001037 pointer->grab = grab;
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001038 grab->pointer = pointer;
Kristian Høgsbergda751b82013-07-04 00:58:07 -04001039 pointer->grab->interface->focus(pointer->grab);
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001040}
1041
1042WL_EXPORT void
Kristian Høgsberg02bbabb2013-05-06 22:15:05 -04001043weston_pointer_end_grab(struct weston_pointer *pointer)
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001044{
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001045 pointer->grab = &pointer->default_grab;
Kristian Høgsbergda751b82013-07-04 00:58:07 -04001046 pointer->grab->interface->focus(pointer->grab);
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001047}
1048
Jonas Ådahl1ea343e2013-10-25 23:18:05 +02001049static void
1050weston_pointer_cancel_grab(struct weston_pointer *pointer)
1051{
1052 pointer->grab->interface->cancel(pointer->grab);
1053}
1054
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001055WL_EXPORT void
Kristian Høgsberge329f362013-05-06 22:19:57 -04001056weston_touch_start_grab(struct weston_touch *touch, struct weston_touch_grab *grab)
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001057{
1058 touch->grab = grab;
1059 grab->touch = touch;
1060}
1061
1062WL_EXPORT void
Kristian Høgsberge329f362013-05-06 22:19:57 -04001063weston_touch_end_grab(struct weston_touch *touch)
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001064{
1065 touch->grab = &touch->default_grab;
1066}
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001067
Jonas Ådahl1ea343e2013-10-25 23:18:05 +02001068static void
1069weston_touch_cancel_grab(struct weston_touch *touch)
1070{
1071 touch->grab->interface->cancel(touch->grab);
1072}
1073
Ander Conselvan de Oliveira54e90c72013-12-13 22:10:56 +02001074static void
1075weston_pointer_clamp_for_output(struct weston_pointer *pointer,
1076 struct weston_output *output,
1077 wl_fixed_t *fx, wl_fixed_t *fy)
1078{
1079 int x, y;
1080
1081 x = wl_fixed_to_int(*fx);
1082 y = wl_fixed_to_int(*fy);
1083
1084 if (x < output->x)
1085 *fx = wl_fixed_from_int(output->x);
1086 else if (x >= output->x + output->width)
1087 *fx = wl_fixed_from_int(output->x +
1088 output->width - 1);
1089 if (y < output->y)
1090 *fy = wl_fixed_from_int(output->y);
1091 else if (y >= output->y + output->height)
1092 *fy = wl_fixed_from_int(output->y +
1093 output->height - 1);
1094}
1095
Rob Bradford806d8c02013-06-25 18:56:41 +01001096WL_EXPORT void
1097weston_pointer_clamp(struct weston_pointer *pointer, wl_fixed_t *fx, wl_fixed_t *fy)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001098{
Rob Bradford806d8c02013-06-25 18:56:41 +01001099 struct weston_compositor *ec = pointer->seat->compositor;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001100 struct weston_output *output, *prev = NULL;
1101 int x, y, old_x, old_y, valid = 0;
1102
1103 x = wl_fixed_to_int(*fx);
1104 y = wl_fixed_to_int(*fy);
Rob Bradford806d8c02013-06-25 18:56:41 +01001105 old_x = wl_fixed_to_int(pointer->x);
1106 old_y = wl_fixed_to_int(pointer->y);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001107
1108 wl_list_for_each(output, &ec->output_list, link) {
Rob Bradford66bd9f52013-06-25 18:56:42 +01001109 if (pointer->seat->output && pointer->seat->output != output)
1110 continue;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001111 if (pixman_region32_contains_point(&output->region,
1112 x, y, NULL))
1113 valid = 1;
1114 if (pixman_region32_contains_point(&output->region,
1115 old_x, old_y, NULL))
1116 prev = output;
1117 }
1118
Rob Bradford66bd9f52013-06-25 18:56:42 +01001119 if (!prev)
1120 prev = pointer->seat->output;
1121
Ander Conselvan de Oliveira54e90c72013-12-13 22:10:56 +02001122 if (prev && !valid)
1123 weston_pointer_clamp_for_output(pointer, prev, fx, fy);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001124}
1125
Jonas Ådahld2510102014-10-05 21:39:14 +02001126static void
1127weston_pointer_move_to(struct weston_pointer *pointer,
1128 wl_fixed_t x, wl_fixed_t y)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001129{
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001130 int32_t ix, iy;
1131
Rob Bradford806d8c02013-06-25 18:56:41 +01001132 weston_pointer_clamp (pointer, &x, &y);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001133
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001134 pointer->x = x;
1135 pointer->y = y;
1136
1137 ix = wl_fixed_to_int(x);
1138 iy = wl_fixed_to_int(y);
1139
Kristian Høgsberg195b8692013-05-08 15:02:05 -04001140 if (pointer->sprite) {
Jason Ekstranda7af7042013-10-12 22:38:11 -05001141 weston_view_set_position(pointer->sprite,
1142 ix - pointer->hotspot_x,
1143 iy - pointer->hotspot_y);
1144 weston_view_schedule_repaint(pointer->sprite);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001145 }
Giulio Camuffo6fcb3782013-11-14 23:42:50 +01001146
Giulio Camuffo1959ab82013-11-14 23:42:52 +01001147 pointer->grab->interface->focus(pointer->grab);
Giulio Camuffo6fcb3782013-11-14 23:42:50 +01001148 wl_signal_emit(&pointer->motion_signal, pointer);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001149}
1150
Jonas Ådahld2510102014-10-05 21:39:14 +02001151WL_EXPORT void
1152weston_pointer_motion_to_abs(struct weston_pointer *pointer,
1153 struct weston_pointer_motion_event *event,
1154 wl_fixed_t *x, wl_fixed_t *y)
1155{
1156 if (event->mask & WESTON_POINTER_MOTION_ABS) {
1157 *x = wl_fixed_from_double(event->x);
1158 *y = wl_fixed_from_double(event->y);
1159 } else if (event->mask & WESTON_POINTER_MOTION_REL) {
1160 *x = pointer->x + wl_fixed_from_double(event->dx);
1161 *y = pointer->y + wl_fixed_from_double(event->dy);
1162 } else {
1163 assert(!"invalid motion event");
1164 *x = *y = 0;
1165 }
1166}
1167
1168WL_EXPORT void
1169weston_pointer_move(struct weston_pointer *pointer,
1170 struct weston_pointer_motion_event *event)
1171{
1172 wl_fixed_t x, y;
1173
1174 weston_pointer_motion_to_abs(pointer, event, &x, &y);
1175 weston_pointer_move_to(pointer, x, y);
1176}
1177
Ander Conselvan de Oliveira54e90c72013-12-13 22:10:56 +02001178/** Verify if the pointer is in a valid position and move it if it isn't.
1179 */
Ander Conselvan de Oliveiraf84327a2014-01-29 18:47:51 +02001180static void
1181weston_pointer_handle_output_destroy(struct wl_listener *listener, void *data)
Ander Conselvan de Oliveira54e90c72013-12-13 22:10:56 +02001182{
Ander Conselvan de Oliveiraf84327a2014-01-29 18:47:51 +02001183 struct weston_pointer *pointer;
1184 struct weston_compositor *ec;
Ander Conselvan de Oliveira54e90c72013-12-13 22:10:56 +02001185 struct weston_output *output, *closest = NULL;
1186 int x, y, distance, min = INT_MAX;
1187 wl_fixed_t fx, fy;
1188
Ander Conselvan de Oliveiraf84327a2014-01-29 18:47:51 +02001189 pointer = container_of(listener, struct weston_pointer,
1190 output_destroy_listener);
1191 ec = pointer->seat->compositor;
1192
Ander Conselvan de Oliveira54e90c72013-12-13 22:10:56 +02001193 x = wl_fixed_to_int(pointer->x);
1194 y = wl_fixed_to_int(pointer->y);
1195
1196 wl_list_for_each(output, &ec->output_list, link) {
1197 if (pixman_region32_contains_point(&output->region,
1198 x, y, NULL))
1199 return;
1200
1201 /* Aproximante the distance from the pointer to the center of
1202 * the output. */
1203 distance = abs(output->x + output->width / 2 - x) +
1204 abs(output->y + output->height / 2 - y);
1205 if (distance < min) {
1206 min = distance;
1207 closest = output;
1208 }
1209 }
1210
1211 /* Nothing to do if there's no output left. */
1212 if (!closest)
1213 return;
1214
1215 fx = pointer->x;
1216 fy = pointer->y;
1217
1218 weston_pointer_clamp_for_output(pointer, closest, &fx, &fy);
Jonas Ådahld2510102014-10-05 21:39:14 +02001219 weston_pointer_move_to(pointer, fx, fy);
Ander Conselvan de Oliveira54e90c72013-12-13 22:10:56 +02001220}
1221
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001222WL_EXPORT void
1223notify_motion(struct weston_seat *seat,
Jonas Ådahld2510102014-10-05 21:39:14 +02001224 uint32_t time,
1225 struct weston_pointer_motion_event *event)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001226{
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001227 struct weston_compositor *ec = seat->compositor;
Derek Foreman1281a362015-07-31 16:55:32 -05001228 struct weston_pointer *pointer = weston_seat_get_pointer(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001229
1230 weston_compositor_wake(ec);
Jonas Ådahld2510102014-10-05 21:39:14 +02001231 pointer->grab->interface->motion(pointer->grab, time, event);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001232}
1233
Daniel Stone96d47c02013-11-19 11:37:12 +01001234static void
1235run_modifier_bindings(struct weston_seat *seat, uint32_t old, uint32_t new)
1236{
1237 struct weston_compositor *compositor = seat->compositor;
Derek Foreman1281a362015-07-31 16:55:32 -05001238 struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
Daniel Stone96d47c02013-11-19 11:37:12 +01001239 uint32_t diff;
1240 unsigned int i;
1241 struct {
1242 uint32_t xkb;
1243 enum weston_keyboard_modifier weston;
1244 } mods[] = {
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001245 { keyboard->xkb_info->ctrl_mod, MODIFIER_CTRL },
1246 { keyboard->xkb_info->alt_mod, MODIFIER_ALT },
1247 { keyboard->xkb_info->super_mod, MODIFIER_SUPER },
1248 { keyboard->xkb_info->shift_mod, MODIFIER_SHIFT },
Daniel Stone96d47c02013-11-19 11:37:12 +01001249 };
1250
1251 diff = new & ~old;
1252 for (i = 0; i < ARRAY_LENGTH(mods); i++) {
1253 if (diff & (1 << mods[i].xkb))
1254 weston_compositor_run_modifier_binding(compositor,
Derek Foreman99a6a2d2015-07-15 13:00:43 -05001255 keyboard,
Daniel Stone96d47c02013-11-19 11:37:12 +01001256 mods[i].weston,
1257 WL_KEYBOARD_KEY_STATE_PRESSED);
1258 }
1259
1260 diff = old & ~new;
1261 for (i = 0; i < ARRAY_LENGTH(mods); i++) {
1262 if (diff & (1 << mods[i].xkb))
1263 weston_compositor_run_modifier_binding(compositor,
Derek Foreman99a6a2d2015-07-15 13:00:43 -05001264 keyboard,
Daniel Stone96d47c02013-11-19 11:37:12 +01001265 mods[i].weston,
1266 WL_KEYBOARD_KEY_STATE_RELEASED);
1267 }
1268}
1269
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001270WL_EXPORT void
1271notify_motion_absolute(struct weston_seat *seat,
1272 uint32_t time, wl_fixed_t x, wl_fixed_t y)
1273{
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001274 struct weston_compositor *ec = seat->compositor;
Derek Foreman1281a362015-07-31 16:55:32 -05001275 struct weston_pointer *pointer = weston_seat_get_pointer(seat);
Jonas Ådahld2510102014-10-05 21:39:14 +02001276 struct weston_pointer_motion_event event = { 0 };
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001277
1278 weston_compositor_wake(ec);
Jonas Ådahld2510102014-10-05 21:39:14 +02001279
1280 event = (struct weston_pointer_motion_event) {
1281 .mask = WESTON_POINTER_MOTION_ABS,
1282 .x = wl_fixed_to_double(x),
1283 .y = wl_fixed_to_double(y),
1284 };
1285
1286 pointer->grab->interface->motion(pointer->grab, time, &event);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001287}
1288
1289WL_EXPORT void
1290weston_surface_activate(struct weston_surface *surface,
1291 struct weston_seat *seat)
1292{
1293 struct weston_compositor *compositor = seat->compositor;
Derek Foreman1281a362015-07-31 16:55:32 -05001294 struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001295
Derek Foreman1281a362015-07-31 16:55:32 -05001296 if (keyboard) {
1297 weston_keyboard_set_focus(keyboard, surface);
Kristian Høgsberge3148752013-05-06 23:19:49 -04001298 wl_data_device_set_keyboard_focus(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001299 }
1300
1301 wl_signal_emit(&compositor->activate_signal, surface);
1302}
1303
1304WL_EXPORT void
1305notify_button(struct weston_seat *seat, uint32_t time, int32_t button,
1306 enum wl_pointer_button_state state)
1307{
1308 struct weston_compositor *compositor = seat->compositor;
Derek Foreman1281a362015-07-31 16:55:32 -05001309 struct weston_pointer *pointer = weston_seat_get_pointer(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001310
1311 if (state == WL_POINTER_BUTTON_STATE_PRESSED) {
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001312 weston_compositor_idle_inhibit(compositor);
1313 if (pointer->button_count == 0) {
1314 pointer->grab_button = button;
1315 pointer->grab_time = time;
1316 pointer->grab_x = pointer->x;
1317 pointer->grab_y = pointer->y;
1318 }
1319 pointer->button_count++;
1320 } else {
1321 weston_compositor_idle_release(compositor);
1322 pointer->button_count--;
1323 }
1324
Derek Foreman99a6a2d2015-07-15 13:00:43 -05001325 weston_compositor_run_button_binding(compositor, pointer, time, button,
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001326 state);
1327
1328 pointer->grab->interface->button(pointer->grab, time, button, state);
1329
1330 if (pointer->button_count == 1)
1331 pointer->grab_serial =
1332 wl_display_get_serial(compositor->wl_display);
1333}
1334
1335WL_EXPORT void
Peter Hutterer89b6a492016-01-18 15:58:17 +10001336notify_axis(struct weston_seat *seat, uint32_t time,
1337 struct weston_pointer_axis_event *event)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001338{
1339 struct weston_compositor *compositor = seat->compositor;
Derek Foreman1281a362015-07-31 16:55:32 -05001340 struct weston_pointer *pointer = weston_seat_get_pointer(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001341
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001342 weston_compositor_wake(compositor);
1343
Derek Foreman99a6a2d2015-07-15 13:00:43 -05001344 if (weston_compositor_run_axis_binding(compositor, pointer,
Peter Hutterer89b6a492016-01-18 15:58:17 +10001345 time, event))
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001346 return;
1347
Peter Hutterer89b6a492016-01-18 15:58:17 +10001348 pointer->grab->interface->axis(pointer->grab, time, event);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001349}
1350
Peter Hutterer87743e92016-01-18 16:38:22 +10001351WL_EXPORT void
1352notify_axis_source(struct weston_seat *seat, uint32_t source)
1353{
1354 struct weston_compositor *compositor = seat->compositor;
1355 struct weston_pointer *pointer = weston_seat_get_pointer(seat);
1356
1357 weston_compositor_wake(compositor);
1358
1359 pointer->grab->interface->axis_source(pointer->grab, source);
1360}
1361
1362WL_EXPORT void
1363notify_pointer_frame(struct weston_seat *seat)
1364{
1365 struct weston_compositor *compositor = seat->compositor;
1366 struct weston_pointer *pointer = weston_seat_get_pointer(seat);
1367
1368 weston_compositor_wake(compositor);
1369
1370 pointer->grab->interface->frame(pointer->grab);
1371}
1372
Giulio Camuffo6ef444d2014-08-28 19:44:09 +03001373WL_EXPORT int
1374weston_keyboard_set_locks(struct weston_keyboard *keyboard,
1375 uint32_t mask, uint32_t value)
1376{
1377#ifdef ENABLE_XKBCOMMON
1378 uint32_t serial;
1379 xkb_mod_mask_t mods_depressed, mods_latched, mods_locked, group;
1380 xkb_mod_mask_t num, caps;
1381
1382 /* We don't want the leds to go out of sync with the actual state
1383 * so if the backend has no way to change the leds don't try to
1384 * change the state */
1385 if (!keyboard->seat->led_update)
1386 return -1;
1387
1388 mods_depressed = xkb_state_serialize_mods(keyboard->xkb_state.state,
1389 XKB_STATE_DEPRESSED);
1390 mods_latched = xkb_state_serialize_mods(keyboard->xkb_state.state,
1391 XKB_STATE_LATCHED);
1392 mods_locked = xkb_state_serialize_mods(keyboard->xkb_state.state,
1393 XKB_STATE_LOCKED);
1394 group = xkb_state_serialize_group(keyboard->xkb_state.state,
1395 XKB_STATE_EFFECTIVE);
1396
1397 num = (1 << keyboard->xkb_info->mod2_mod);
1398 caps = (1 << keyboard->xkb_info->caps_mod);
1399 if (mask & WESTON_NUM_LOCK) {
1400 if (value & WESTON_NUM_LOCK)
1401 mods_locked |= num;
1402 else
1403 mods_locked &= ~num;
1404 }
1405 if (mask & WESTON_CAPS_LOCK) {
1406 if (value & WESTON_CAPS_LOCK)
1407 mods_locked |= caps;
1408 else
1409 mods_locked &= ~caps;
1410 }
1411
1412 xkb_state_update_mask(keyboard->xkb_state.state, mods_depressed,
1413 mods_latched, mods_locked, 0, 0, group);
1414
1415 serial = wl_display_next_serial(
1416 keyboard->seat->compositor->wl_display);
1417 notify_modifiers(keyboard->seat, serial);
1418
1419 return 0;
1420#else
1421 return -1;
1422#endif
1423}
1424
Rob Bradford382ff462013-06-24 16:52:45 +01001425#ifdef ENABLE_XKBCOMMON
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001426WL_EXPORT void
1427notify_modifiers(struct weston_seat *seat, uint32_t serial)
1428{
Derek Foreman1281a362015-07-31 16:55:32 -05001429 struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001430 struct weston_keyboard_grab *grab = keyboard->grab;
1431 uint32_t mods_depressed, mods_latched, mods_locked, group;
1432 uint32_t mods_lookup;
1433 enum weston_led leds = 0;
1434 int changed = 0;
1435
1436 /* Serialize and update our internal state, checking to see if it's
1437 * different to the previous state. */
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001438 mods_depressed = xkb_state_serialize_mods(keyboard->xkb_state.state,
Ran Benita2e1968f2014-08-19 23:59:51 +03001439 XKB_STATE_MODS_DEPRESSED);
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001440 mods_latched = xkb_state_serialize_mods(keyboard->xkb_state.state,
Ran Benita2e1968f2014-08-19 23:59:51 +03001441 XKB_STATE_MODS_LATCHED);
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001442 mods_locked = xkb_state_serialize_mods(keyboard->xkb_state.state,
Ran Benita2e1968f2014-08-19 23:59:51 +03001443 XKB_STATE_MODS_LOCKED);
1444 group = xkb_state_serialize_layout(keyboard->xkb_state.state,
1445 XKB_STATE_LAYOUT_EFFECTIVE);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001446
Derek Foreman244e99e2015-06-03 15:53:26 -05001447 if (mods_depressed != keyboard->modifiers.mods_depressed ||
1448 mods_latched != keyboard->modifiers.mods_latched ||
1449 mods_locked != keyboard->modifiers.mods_locked ||
1450 group != keyboard->modifiers.group)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001451 changed = 1;
1452
Derek Foreman244e99e2015-06-03 15:53:26 -05001453 run_modifier_bindings(seat, keyboard->modifiers.mods_depressed,
Daniel Stone96d47c02013-11-19 11:37:12 +01001454 mods_depressed);
1455
Derek Foreman244e99e2015-06-03 15:53:26 -05001456 keyboard->modifiers.mods_depressed = mods_depressed;
1457 keyboard->modifiers.mods_latched = mods_latched;
1458 keyboard->modifiers.mods_locked = mods_locked;
1459 keyboard->modifiers.group = group;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001460
1461 /* And update the modifier_state for bindings. */
1462 mods_lookup = mods_depressed | mods_latched;
1463 seat->modifier_state = 0;
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001464 if (mods_lookup & (1 << keyboard->xkb_info->ctrl_mod))
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001465 seat->modifier_state |= MODIFIER_CTRL;
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001466 if (mods_lookup & (1 << keyboard->xkb_info->alt_mod))
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001467 seat->modifier_state |= MODIFIER_ALT;
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001468 if (mods_lookup & (1 << keyboard->xkb_info->super_mod))
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001469 seat->modifier_state |= MODIFIER_SUPER;
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001470 if (mods_lookup & (1 << keyboard->xkb_info->shift_mod))
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001471 seat->modifier_state |= MODIFIER_SHIFT;
1472
1473 /* Finally, notify the compositor that LEDs have changed. */
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001474 if (xkb_state_led_index_is_active(keyboard->xkb_state.state,
1475 keyboard->xkb_info->num_led))
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001476 leds |= LED_NUM_LOCK;
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001477 if (xkb_state_led_index_is_active(keyboard->xkb_state.state,
1478 keyboard->xkb_info->caps_led))
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001479 leds |= LED_CAPS_LOCK;
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001480 if (xkb_state_led_index_is_active(keyboard->xkb_state.state,
1481 keyboard->xkb_info->scroll_led))
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001482 leds |= LED_SCROLL_LOCK;
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001483 if (leds != keyboard->xkb_state.leds && seat->led_update)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001484 seat->led_update(seat, leds);
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001485 keyboard->xkb_state.leds = leds;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001486
1487 if (changed) {
1488 grab->interface->modifiers(grab,
1489 serial,
1490 keyboard->modifiers.mods_depressed,
1491 keyboard->modifiers.mods_latched,
1492 keyboard->modifiers.mods_locked,
1493 keyboard->modifiers.group);
1494 }
1495}
1496
1497static void
1498update_modifier_state(struct weston_seat *seat, uint32_t serial, uint32_t key,
1499 enum wl_keyboard_key_state state)
1500{
Derek Foreman1281a362015-07-31 16:55:32 -05001501 struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001502 enum xkb_key_direction direction;
1503
Matt Roper01a92732013-06-24 16:52:44 +01001504 /* Keyboard modifiers don't exist in raw keyboard mode */
1505 if (!seat->compositor->use_xkbcommon)
1506 return;
1507
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001508 if (state == WL_KEYBOARD_KEY_STATE_PRESSED)
1509 direction = XKB_KEY_DOWN;
1510 else
1511 direction = XKB_KEY_UP;
1512
1513 /* Offset the keycode by 8, as the evdev XKB rules reflect X's
1514 * broken keycode system, which starts at 8. */
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001515 xkb_state_update_key(keyboard->xkb_state.state, key + 8, direction);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001516
1517 notify_modifiers(seat, serial);
1518}
Rui Matos65196bc2013-10-10 19:44:19 +02001519
1520static void
1521send_keymap(struct wl_resource *resource, struct weston_xkb_info *xkb_info)
1522{
1523 wl_keyboard_send_keymap(resource,
1524 WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1,
1525 xkb_info->keymap_fd,
1526 xkb_info->keymap_size);
1527}
1528
1529static void
1530send_modifiers(struct wl_resource *resource, uint32_t serial, struct weston_keyboard *keyboard)
1531{
1532 wl_keyboard_send_modifiers(resource, serial,
1533 keyboard->modifiers.mods_depressed,
1534 keyboard->modifiers.mods_latched,
1535 keyboard->modifiers.mods_locked,
1536 keyboard->modifiers.group);
1537}
1538
1539static struct weston_xkb_info *
1540weston_xkb_info_create(struct xkb_keymap *keymap);
Rui Matos65196bc2013-10-10 19:44:19 +02001541
1542static void
1543update_keymap(struct weston_seat *seat)
1544{
Derek Foreman1281a362015-07-31 16:55:32 -05001545 struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
Rui Matos65196bc2013-10-10 19:44:19 +02001546 struct wl_resource *resource;
1547 struct weston_xkb_info *xkb_info;
1548 struct xkb_state *state;
1549 xkb_mod_mask_t latched_mods;
1550 xkb_mod_mask_t locked_mods;
1551
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001552 xkb_info = weston_xkb_info_create(keyboard->pending_keymap);
Rui Matos65196bc2013-10-10 19:44:19 +02001553
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001554 xkb_keymap_unref(keyboard->pending_keymap);
1555 keyboard->pending_keymap = NULL;
Rui Matos65196bc2013-10-10 19:44:19 +02001556
1557 if (!xkb_info) {
1558 weston_log("failed to create XKB info\n");
1559 return;
1560 }
1561
1562 state = xkb_state_new(xkb_info->keymap);
1563 if (!state) {
1564 weston_log("failed to initialise XKB state\n");
1565 weston_xkb_info_destroy(xkb_info);
1566 return;
1567 }
1568
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001569 latched_mods = xkb_state_serialize_mods(keyboard->xkb_state.state,
1570 XKB_STATE_MODS_LATCHED);
1571 locked_mods = xkb_state_serialize_mods(keyboard->xkb_state.state,
1572 XKB_STATE_MODS_LOCKED);
Rui Matos65196bc2013-10-10 19:44:19 +02001573 xkb_state_update_mask(state,
1574 0, /* depressed */
1575 latched_mods,
1576 locked_mods,
1577 0, 0, 0);
1578
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001579 weston_xkb_info_destroy(keyboard->xkb_info);
1580 keyboard->xkb_info = xkb_info;
Rui Matos65196bc2013-10-10 19:44:19 +02001581
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001582 xkb_state_unref(keyboard->xkb_state.state);
1583 keyboard->xkb_state.state = state;
Rui Matos65196bc2013-10-10 19:44:19 +02001584
Derek Foremanbc91e542015-06-03 15:53:27 -05001585 wl_resource_for_each(resource, &keyboard->resource_list)
Rui Matos65196bc2013-10-10 19:44:19 +02001586 send_keymap(resource, xkb_info);
Derek Foremanbc91e542015-06-03 15:53:27 -05001587 wl_resource_for_each(resource, &keyboard->focus_resource_list)
Rui Matos65196bc2013-10-10 19:44:19 +02001588 send_keymap(resource, xkb_info);
1589
1590 notify_modifiers(seat, wl_display_next_serial(seat->compositor->wl_display));
1591
1592 if (!latched_mods && !locked_mods)
1593 return;
1594
Derek Foremanbc91e542015-06-03 15:53:27 -05001595 wl_resource_for_each(resource, &keyboard->resource_list)
1596 send_modifiers(resource, wl_display_get_serial(seat->compositor->wl_display), keyboard);
1597 wl_resource_for_each(resource, &keyboard->focus_resource_list)
1598 send_modifiers(resource, wl_display_get_serial(seat->compositor->wl_display), keyboard);
Rui Matos65196bc2013-10-10 19:44:19 +02001599}
Rob Bradford382ff462013-06-24 16:52:45 +01001600#else
1601WL_EXPORT void
1602notify_modifiers(struct weston_seat *seat, uint32_t serial)
1603{
1604}
1605
1606static void
1607update_modifier_state(struct weston_seat *seat, uint32_t serial, uint32_t key,
1608 enum wl_keyboard_key_state state)
1609{
1610}
Rui Matos65196bc2013-10-10 19:44:19 +02001611
1612static void
1613update_keymap(struct weston_seat *seat)
1614{
1615}
Rob Bradford382ff462013-06-24 16:52:45 +01001616#endif
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001617
1618WL_EXPORT void
1619notify_key(struct weston_seat *seat, uint32_t time, uint32_t key,
1620 enum wl_keyboard_key_state state,
1621 enum weston_key_state_update update_state)
1622{
1623 struct weston_compositor *compositor = seat->compositor;
Derek Foreman1281a362015-07-31 16:55:32 -05001624 struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001625 struct weston_keyboard_grab *grab = keyboard->grab;
Pekka Paalanen86b53962014-11-19 13:43:32 +02001626 uint32_t *k, *end;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001627
1628 if (state == WL_KEYBOARD_KEY_STATE_PRESSED) {
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001629 weston_compositor_idle_inhibit(compositor);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001630 } else {
1631 weston_compositor_idle_release(compositor);
1632 }
1633
Pekka Paalanen86b53962014-11-19 13:43:32 +02001634 end = keyboard->keys.data + keyboard->keys.size;
1635 for (k = keyboard->keys.data; k < end; k++) {
1636 if (*k == key) {
1637 /* Ignore server-generated repeats. */
1638 if (state == WL_KEYBOARD_KEY_STATE_PRESSED)
1639 return;
1640 *k = *--end;
1641 }
1642 }
1643 keyboard->keys.size = (void *) end - keyboard->keys.data;
1644 if (state == WL_KEYBOARD_KEY_STATE_PRESSED) {
1645 k = wl_array_add(&keyboard->keys, sizeof *k);
1646 *k = key;
1647 }
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001648
1649 if (grab == &keyboard->default_grab ||
1650 grab == &keyboard->input_method_grab) {
Derek Foreman99a6a2d2015-07-15 13:00:43 -05001651 weston_compositor_run_key_binding(compositor, keyboard, time,
1652 key, state);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001653 grab = keyboard->grab;
1654 }
1655
1656 grab->interface->key(grab, time, key, state);
1657
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001658 if (keyboard->pending_keymap &&
Pekka Paalanen86b53962014-11-19 13:43:32 +02001659 keyboard->keys.size == 0)
Rui Matos65196bc2013-10-10 19:44:19 +02001660 update_keymap(seat);
1661
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001662 if (update_state == STATE_UPDATE_AUTOMATIC) {
1663 update_modifier_state(seat,
1664 wl_display_get_serial(compositor->wl_display),
1665 key,
1666 state);
1667 }
Giulio Camuffob6ddf6c2015-02-06 19:06:54 +02001668
1669 if (state == WL_KEYBOARD_KEY_STATE_PRESSED) {
1670 keyboard->grab_serial =
1671 wl_display_get_serial(compositor->wl_display);
1672 keyboard->grab_time = time;
1673 keyboard->grab_key = key;
1674 }
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001675}
1676
1677WL_EXPORT void
1678notify_pointer_focus(struct weston_seat *seat, struct weston_output *output,
1679 wl_fixed_t x, wl_fixed_t y)
1680{
Derek Foreman1281a362015-07-31 16:55:32 -05001681 struct weston_pointer *pointer = weston_seat_get_pointer(seat);
1682
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001683 if (output) {
Jonas Ådahld2510102014-10-05 21:39:14 +02001684 weston_pointer_move_to(pointer, x, y);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001685 } else {
Kristian Høgsberg02bbabb2013-05-06 22:15:05 -04001686 /* FIXME: We should call weston_pointer_set_focus(seat,
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001687 * NULL) here, but somehow that breaks re-entry... */
1688 }
1689}
1690
1691static void
1692destroy_device_saved_kbd_focus(struct wl_listener *listener, void *data)
1693{
1694 struct weston_seat *ws;
1695
1696 ws = container_of(listener, struct weston_seat,
1697 saved_kbd_focus_listener);
1698
1699 ws->saved_kbd_focus = NULL;
1700}
1701
1702WL_EXPORT void
1703notify_keyboard_focus_in(struct weston_seat *seat, struct wl_array *keys,
1704 enum weston_key_state_update update_state)
1705{
1706 struct weston_compositor *compositor = seat->compositor;
Derek Foreman1281a362015-07-31 16:55:32 -05001707 struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
Kristian Høgsbergfe7aa902013-05-08 09:54:37 -04001708 struct weston_surface *surface;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001709 uint32_t *k, serial;
1710
1711 serial = wl_display_next_serial(compositor->wl_display);
1712 wl_array_copy(&keyboard->keys, keys);
1713 wl_array_for_each(k, &keyboard->keys) {
1714 weston_compositor_idle_inhibit(compositor);
1715 if (update_state == STATE_UPDATE_AUTOMATIC)
1716 update_modifier_state(seat, serial, *k,
1717 WL_KEYBOARD_KEY_STATE_PRESSED);
1718 }
1719
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001720 surface = seat->saved_kbd_focus;
1721
1722 if (surface) {
1723 wl_list_remove(&seat->saved_kbd_focus_listener.link);
1724 weston_keyboard_set_focus(keyboard, surface);
1725 seat->saved_kbd_focus = NULL;
1726 }
1727}
1728
1729WL_EXPORT void
1730notify_keyboard_focus_out(struct weston_seat *seat)
1731{
1732 struct weston_compositor *compositor = seat->compositor;
Derek Foreman1281a362015-07-31 16:55:32 -05001733 struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
1734 struct weston_pointer *pointer = weston_seat_get_pointer(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001735 uint32_t *k, serial;
1736
1737 serial = wl_display_next_serial(compositor->wl_display);
1738 wl_array_for_each(k, &keyboard->keys) {
1739 weston_compositor_idle_release(compositor);
1740 update_modifier_state(seat, serial, *k,
1741 WL_KEYBOARD_KEY_STATE_RELEASED);
1742 }
1743
1744 seat->modifier_state = 0;
1745
1746 if (keyboard->focus) {
1747 seat->saved_kbd_focus = keyboard->focus;
1748 seat->saved_kbd_focus_listener.notify =
1749 destroy_device_saved_kbd_focus;
Jason Ekstrand26ed73c2013-06-06 22:34:41 -05001750 wl_signal_add(&keyboard->focus->destroy_signal,
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001751 &seat->saved_kbd_focus_listener);
1752 }
1753
1754 weston_keyboard_set_focus(keyboard, NULL);
Jonas Ådahl1ea343e2013-10-25 23:18:05 +02001755 weston_keyboard_cancel_grab(keyboard);
Derek Foreman1281a362015-07-31 16:55:32 -05001756 if (pointer)
1757 weston_pointer_cancel_grab(pointer);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001758}
1759
Michael Fua2bb7912013-07-23 15:51:06 +08001760WL_EXPORT void
Derek Foreman4c93c082015-04-30 16:45:41 -05001761weston_touch_set_focus(struct weston_touch *touch, struct weston_view *view)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001762{
Neil Roberts96d790e2013-09-19 17:32:00 +01001763 struct wl_list *focus_resource_list;
1764
Derek Foreman4c93c082015-04-30 16:45:41 -05001765 focus_resource_list = &touch->focus_resource_list;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001766
Derek Foreman4c93c082015-04-30 16:45:41 -05001767 if (view && touch->focus &&
1768 touch->focus->surface == view->surface) {
1769 touch->focus = view;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001770 return;
Jason Ekstranda7af7042013-10-12 22:38:11 -05001771 }
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001772
Derek Foreman4c93c082015-04-30 16:45:41 -05001773 wl_list_remove(&touch->focus_resource_listener.link);
1774 wl_list_init(&touch->focus_resource_listener.link);
1775 wl_list_remove(&touch->focus_view_listener.link);
1776 wl_list_init(&touch->focus_view_listener.link);
Giulio Camuffo576fe2a2013-11-20 18:00:24 +01001777
Neil Roberts96d790e2013-09-19 17:32:00 +01001778 if (!wl_list_empty(focus_resource_list)) {
Derek Foreman4c93c082015-04-30 16:45:41 -05001779 move_resources(&touch->resource_list,
Neil Roberts96d790e2013-09-19 17:32:00 +01001780 focus_resource_list);
1781 }
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001782
Jason Ekstranda7af7042013-10-12 22:38:11 -05001783 if (view) {
Derek Foreman362656b2014-09-04 10:23:05 -05001784 struct wl_client *surface_client;
1785
1786 if (!view->surface->resource) {
Derek Foreman4c93c082015-04-30 16:45:41 -05001787 touch->focus = NULL;
Derek Foreman362656b2014-09-04 10:23:05 -05001788 return;
1789 }
1790
1791 surface_client = wl_resource_get_client(view->surface->resource);
Neil Roberts96d790e2013-09-19 17:32:00 +01001792 move_resources_for_client(focus_resource_list,
Derek Foreman4c93c082015-04-30 16:45:41 -05001793 &touch->resource_list,
Neil Roberts96d790e2013-09-19 17:32:00 +01001794 surface_client);
Giulio Camuffo576fe2a2013-11-20 18:00:24 +01001795 wl_resource_add_destroy_listener(view->surface->resource,
Derek Foreman4c93c082015-04-30 16:45:41 -05001796 &touch->focus_resource_listener);
1797 wl_signal_add(&view->destroy_signal, &touch->focus_view_listener);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001798 }
Derek Foreman4c93c082015-04-30 16:45:41 -05001799 touch->focus = view;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001800}
1801
1802/**
1803 * notify_touch - emulates button touches and notifies surfaces accordingly.
1804 *
1805 * It assumes always the correct cycle sequence until it gets here: touch_down
1806 * → touch_update → ... → touch_update → touch_end. The driver is responsible
1807 * for sending along such order.
1808 *
1809 */
1810WL_EXPORT void
1811notify_touch(struct weston_seat *seat, uint32_t time, int touch_id,
1812 wl_fixed_t x, wl_fixed_t y, int touch_type)
1813{
1814 struct weston_compositor *ec = seat->compositor;
Derek Foreman1281a362015-07-31 16:55:32 -05001815 struct weston_touch *touch = weston_seat_get_touch(seat);
Kristian Høgsberge329f362013-05-06 22:19:57 -04001816 struct weston_touch_grab *grab = touch->grab;
Jason Ekstranda7af7042013-10-12 22:38:11 -05001817 struct weston_view *ev;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001818 wl_fixed_t sx, sy;
1819
1820 /* Update grab's global coordinates. */
Neil Roberts306fe082013-10-03 16:43:06 +01001821 if (touch_id == touch->grab_touch_id && touch_type != WL_TOUCH_UP) {
1822 touch->grab_x = x;
1823 touch->grab_y = y;
1824 }
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001825
1826 switch (touch_type) {
1827 case WL_TOUCH_DOWN:
1828 weston_compositor_idle_inhibit(ec);
1829
Jonas Ådahl9484b692013-12-02 22:05:03 +01001830 touch->num_tp++;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001831
Jason Ekstranda7af7042013-10-12 22:38:11 -05001832 /* the first finger down picks the view, and all further go
1833 * to that view for the remainder of the touch session i.e.
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001834 * until all touch points are up again. */
Jonas Ådahl9484b692013-12-02 22:05:03 +01001835 if (touch->num_tp == 1) {
Jason Ekstranda7af7042013-10-12 22:38:11 -05001836 ev = weston_compositor_pick_view(ec, x, y, &sx, &sy);
Derek Foreman4c93c082015-04-30 16:45:41 -05001837 weston_touch_set_focus(touch, ev);
Giulio Camuffo61ed7b62015-07-08 11:55:28 +03001838 } else if (!touch->focus) {
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001839 /* Unexpected condition: We have non-initial touch but
1840 * there is no focused surface.
1841 */
Chris Michael3f607d32015-10-07 11:59:49 -04001842 weston_log("touch event received with %d points down "
Jonas Ådahl9484b692013-12-02 22:05:03 +01001843 "but no surface focused\n", touch->num_tp);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001844 return;
1845 }
1846
Derek Foreman99a6a2d2015-07-15 13:00:43 -05001847 weston_compositor_run_touch_binding(ec, touch,
Kristian Høgsbergc8964012014-02-05 14:25:18 -08001848 time, touch_type);
1849
Giulio Camuffo61ed7b62015-07-08 11:55:28 +03001850 grab->interface->down(grab, time, touch_id, x, y);
Jonas Ådahl9484b692013-12-02 22:05:03 +01001851 if (touch->num_tp == 1) {
Rusty Lynchf1407ff2013-08-08 21:13:57 -07001852 touch->grab_serial =
1853 wl_display_get_serial(ec->wl_display);
Neil Roberts306fe082013-10-03 16:43:06 +01001854 touch->grab_touch_id = touch_id;
Rusty Lynchf1407ff2013-08-08 21:13:57 -07001855 touch->grab_time = time;
1856 touch->grab_x = x;
1857 touch->grab_y = y;
1858 }
1859
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001860 break;
1861 case WL_TOUCH_MOTION:
Jason Ekstranda7af7042013-10-12 22:38:11 -05001862 ev = touch->focus;
1863 if (!ev)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001864 break;
1865
Giulio Camuffo61ed7b62015-07-08 11:55:28 +03001866 grab->interface->motion(grab, time, touch_id, x, y);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001867 break;
1868 case WL_TOUCH_UP:
Kristian Høgsberga30e29a2014-01-08 22:29:20 -08001869 if (touch->num_tp == 0) {
1870 /* This can happen if we start out with one or
1871 * more fingers on the touch screen, in which
1872 * case we didn't get the corresponding down
1873 * event. */
1874 weston_log("unmatched touch up event\n");
1875 break;
1876 }
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001877 weston_compositor_idle_release(ec);
Jonas Ådahl9484b692013-12-02 22:05:03 +01001878 touch->num_tp--;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001879
1880 grab->interface->up(grab, time, touch_id);
Jonas Ådahl9484b692013-12-02 22:05:03 +01001881 if (touch->num_tp == 0)
Derek Foreman4c93c082015-04-30 16:45:41 -05001882 weston_touch_set_focus(touch, NULL);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001883 break;
1884 }
1885}
1886
Jonas Ådahl1679f232014-04-12 09:39:51 +02001887WL_EXPORT void
1888notify_touch_frame(struct weston_seat *seat)
1889{
Derek Foreman1281a362015-07-31 16:55:32 -05001890 struct weston_touch *touch = weston_seat_get_touch(seat);
Jonas Ådahl1679f232014-04-12 09:39:51 +02001891 struct weston_touch_grab *grab = touch->grab;
1892
1893 grab->interface->frame(grab);
1894}
1895
Derek Foreman3cc004a2015-11-06 15:56:09 -06001896WL_EXPORT void
1897notify_touch_cancel(struct weston_seat *seat)
1898{
1899 struct weston_touch *touch = weston_seat_get_touch(seat);
1900 struct weston_touch_grab *grab = touch->grab;
1901
1902 grab->interface->cancel(grab);
1903}
1904
Pekka Paalanen8274d902014-08-06 19:36:51 +03001905static int
1906pointer_cursor_surface_get_label(struct weston_surface *surface,
1907 char *buf, size_t len)
1908{
1909 return snprintf(buf, len, "cursor");
1910}
1911
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001912static void
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001913pointer_cursor_surface_configure(struct weston_surface *es,
Jason Ekstrand918f2dd2013-12-02 21:01:53 -06001914 int32_t dx, int32_t dy)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001915{
Kristian Høgsberg195b8692013-05-08 15:02:05 -04001916 struct weston_pointer *pointer = es->configure_private;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001917 int x, y;
1918
Jason Ekstrand918f2dd2013-12-02 21:01:53 -06001919 if (es->width == 0)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001920 return;
1921
Jason Ekstranda7af7042013-10-12 22:38:11 -05001922 assert(es == pointer->sprite->surface);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001923
Kristian Høgsberg195b8692013-05-08 15:02:05 -04001924 pointer->hotspot_x -= dx;
1925 pointer->hotspot_y -= dy;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001926
Kristian Høgsberg195b8692013-05-08 15:02:05 -04001927 x = wl_fixed_to_int(pointer->x) - pointer->hotspot_x;
1928 y = wl_fixed_to_int(pointer->y) - pointer->hotspot_y;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001929
Jason Ekstrand918f2dd2013-12-02 21:01:53 -06001930 weston_view_set_position(pointer->sprite, x, y);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001931
1932 empty_region(&es->pending.input);
Ander Conselvan de Oliveira23900f72014-01-31 16:07:51 +02001933 empty_region(&es->input);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001934
1935 if (!weston_surface_is_mapped(es)) {
Giulio Camuffo412e6a52014-07-09 22:12:56 +03001936 weston_layer_entry_insert(&es->compositor->cursor_layer.view_list,
1937 &pointer->sprite->layer_link);
Jason Ekstranda7af7042013-10-12 22:38:11 -05001938 weston_view_update_transform(pointer->sprite);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001939 }
1940}
1941
1942static void
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001943pointer_set_cursor(struct wl_client *client, struct wl_resource *resource,
1944 uint32_t serial, struct wl_resource *surface_resource,
1945 int32_t x, int32_t y)
1946{
Jason Ekstrand44a38632013-06-14 10:08:00 -05001947 struct weston_pointer *pointer = wl_resource_get_user_data(resource);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001948 struct weston_surface *surface = NULL;
1949
1950 if (surface_resource)
Jason Ekstrand0f2ef7e2013-06-14 10:07:53 -05001951 surface = wl_resource_get_user_data(surface_resource);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001952
Kristian Høgsberg195b8692013-05-08 15:02:05 -04001953 if (pointer->focus == NULL)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001954 return;
Jason Ekstranda7af7042013-10-12 22:38:11 -05001955 /* pointer->focus->surface->resource can be NULL. Surfaces like the
Giulio Camuffo1fd4b012013-06-20 18:13:07 +02001956 black_surface used in shell.c for fullscreen don't have
1957 a resource, but can still have focus */
Jason Ekstranda7af7042013-10-12 22:38:11 -05001958 if (pointer->focus->surface->resource == NULL)
Giulio Camuffo1fd4b012013-06-20 18:13:07 +02001959 return;
Jason Ekstranda7af7042013-10-12 22:38:11 -05001960 if (wl_resource_get_client(pointer->focus->surface->resource) != client)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001961 return;
Kristian Høgsberg195b8692013-05-08 15:02:05 -04001962 if (pointer->focus_serial - serial > UINT32_MAX / 2)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001963 return;
1964
Derek Foreman4e53c532015-03-23 10:55:32 -05001965 if (!surface) {
1966 if (pointer->sprite)
1967 pointer_unmap_sprite(pointer);
1968 return;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001969 }
1970
Jonas Ådahlb4070242015-03-18 15:08:03 +08001971 if (pointer->sprite && pointer->sprite->surface == surface &&
1972 pointer->hotspot_x == x && pointer->hotspot_y == y)
1973 return;
1974
Derek Foreman4e53c532015-03-23 10:55:32 -05001975 if (!pointer->sprite || pointer->sprite->surface != surface) {
1976 if (weston_surface_set_role(surface, "wl_pointer-cursor",
1977 resource,
1978 WL_POINTER_ERROR_ROLE) < 0)
1979 return;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001980
Derek Foreman4e53c532015-03-23 10:55:32 -05001981 if (pointer->sprite)
1982 pointer_unmap_sprite(pointer);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001983
Derek Foreman4e53c532015-03-23 10:55:32 -05001984 wl_signal_add(&surface->destroy_signal,
1985 &pointer->sprite_destroy_listener);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001986
Derek Foreman4e53c532015-03-23 10:55:32 -05001987 surface->configure = pointer_cursor_surface_configure;
1988 surface->configure_private = pointer;
1989 weston_surface_set_label_func(surface,
1990 pointer_cursor_surface_get_label);
1991 pointer->sprite = weston_view_create(surface);
1992 }
1993
Kristian Høgsberg195b8692013-05-08 15:02:05 -04001994 pointer->hotspot_x = x;
1995 pointer->hotspot_y = y;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001996
Jonas Ådahl16fe4dc2014-09-08 19:33:41 +02001997 if (surface->buffer_ref.buffer) {
Jason Ekstrand918f2dd2013-12-02 21:01:53 -06001998 pointer_cursor_surface_configure(surface, 0, 0);
Jonas Ådahl16fe4dc2014-09-08 19:33:41 +02001999 weston_view_schedule_repaint(pointer->sprite);
2000 }
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002001}
2002
Kristian Høgsberg69e25fc2013-08-13 20:11:02 +01002003static void
2004pointer_release(struct wl_client *client, struct wl_resource *resource)
2005{
2006 wl_resource_destroy(resource);
2007}
2008
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002009static const struct wl_pointer_interface pointer_interface = {
Kristian Høgsberg69e25fc2013-08-13 20:11:02 +01002010 pointer_set_cursor,
2011 pointer_release
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002012};
2013
2014static void
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002015seat_get_pointer(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 pointer_state directly, which means we'll
2020 * give a wl_pointer 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 pointer 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_pointer *pointer = seat->pointer_state;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002028 struct wl_resource *cr;
Jonas Ådahl2cbf2932015-07-22 12:05:38 +08002029 struct weston_pointer_client *pointer_client;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002030
Derek Foreman1281a362015-07-31 16:55:32 -05002031 if (!pointer)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002032 return;
2033
Jason Ekstranda85118c2013-06-27 20:17:02 -05002034 cr = wl_resource_create(client, &wl_pointer_interface,
2035 wl_resource_get_version(resource), id);
Kristian Høgsberg0ff79082013-08-06 16:46:25 -07002036 if (cr == NULL) {
2037 wl_client_post_no_memory(client);
2038 return;
2039 }
2040
Jonas Ådahl2cbf2932015-07-22 12:05:38 +08002041 pointer_client = weston_pointer_ensure_pointer_client(pointer, client);
2042 if (!pointer_client) {
2043 wl_client_post_no_memory(client);
2044 return;
2045 }
2046
2047 wl_list_insert(&pointer_client->pointer_resources,
2048 wl_resource_get_link(cr));
Derek Foreman1281a362015-07-31 16:55:32 -05002049 wl_resource_set_implementation(cr, &pointer_interface, pointer,
Jonas Ådahl2cbf2932015-07-22 12:05:38 +08002050 unbind_pointer_client_resource);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002051
Derek Foreman1281a362015-07-31 16:55:32 -05002052 if (pointer->focus && pointer->focus->surface->resource &&
2053 wl_resource_get_client(pointer->focus->surface->resource) == client) {
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002054 wl_fixed_t sx, sy;
2055
Derek Foreman1281a362015-07-31 16:55:32 -05002056 weston_view_from_global_fixed(pointer->focus,
2057 pointer->x,
2058 pointer->y,
Jason Ekstranda7af7042013-10-12 22:38:11 -05002059 &sx, &sy);
Neil Roberts96d790e2013-09-19 17:32:00 +01002060
Neil Roberts96d790e2013-09-19 17:32:00 +01002061 wl_pointer_send_enter(cr,
Derek Foreman1281a362015-07-31 16:55:32 -05002062 pointer->focus_serial,
2063 pointer->focus->surface->resource,
Neil Roberts96d790e2013-09-19 17:32:00 +01002064 sx, sy);
Peter Hutterer87743e92016-01-18 16:38:22 +10002065 pointer_send_frame(cr);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002066 }
2067}
2068
2069static void
Kristian Høgsberg69e25fc2013-08-13 20:11:02 +01002070keyboard_release(struct wl_client *client, struct wl_resource *resource)
2071{
2072 wl_resource_destroy(resource);
2073}
2074
2075static const struct wl_keyboard_interface keyboard_interface = {
2076 keyboard_release
2077};
2078
Derek Foreman280e7dd2014-10-03 13:13:42 -05002079static bool
Neil Roberts96d790e2013-09-19 17:32:00 +01002080should_send_modifiers_to_client(struct weston_seat *seat,
2081 struct wl_client *client)
2082{
Derek Foreman1281a362015-07-31 16:55:32 -05002083 struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
2084 struct weston_pointer *pointer = weston_seat_get_pointer(seat);
2085
2086 if (keyboard &&
2087 keyboard->focus &&
2088 keyboard->focus->resource &&
2089 wl_resource_get_client(keyboard->focus->resource) == client)
Derek Foreman280e7dd2014-10-03 13:13:42 -05002090 return true;
Neil Roberts96d790e2013-09-19 17:32:00 +01002091
Derek Foreman1281a362015-07-31 16:55:32 -05002092 if (pointer &&
2093 pointer->focus &&
2094 pointer->focus->surface->resource &&
2095 wl_resource_get_client(pointer->focus->surface->resource) == client)
Derek Foreman280e7dd2014-10-03 13:13:42 -05002096 return true;
Neil Roberts96d790e2013-09-19 17:32:00 +01002097
Derek Foreman280e7dd2014-10-03 13:13:42 -05002098 return false;
Neil Roberts96d790e2013-09-19 17:32:00 +01002099}
2100
Kristian Høgsberg69e25fc2013-08-13 20:11:02 +01002101static void
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002102seat_get_keyboard(struct wl_client *client, struct wl_resource *resource,
2103 uint32_t id)
2104{
Jason Ekstrand44a38632013-06-14 10:08:00 -05002105 struct weston_seat *seat = wl_resource_get_user_data(resource);
Derek Foreman1281a362015-07-31 16:55:32 -05002106 /* We use the keyboard_state directly, which means we'll
2107 * give a wl_keyboard if the seat has ever had one - even though
2108 * the spec explicitly states that this request only takes effect
2109 * if the seat has the keyboard capability.
2110 *
2111 * This prevents a race between the compositor sending new
2112 * capabilities and the client trying to use the old ones.
2113 */
2114 struct weston_keyboard *keyboard = seat->keyboard_state;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002115 struct wl_resource *cr;
2116
Derek Foreman345c9f32015-06-03 15:53:28 -05002117 if (!keyboard)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002118 return;
2119
Jason Ekstranda85118c2013-06-27 20:17:02 -05002120 cr = wl_resource_create(client, &wl_keyboard_interface,
2121 wl_resource_get_version(resource), id);
Kristian Høgsberg0ff79082013-08-06 16:46:25 -07002122 if (cr == NULL) {
2123 wl_client_post_no_memory(client);
2124 return;
2125 }
2126
Neil Roberts96d790e2013-09-19 17:32:00 +01002127 /* May be moved to focused list later by either
2128 * weston_keyboard_set_focus or directly if this client is already
2129 * focused */
Derek Foreman345c9f32015-06-03 15:53:28 -05002130 wl_list_insert(&keyboard->resource_list, wl_resource_get_link(cr));
Kristian Høgsberg69e25fc2013-08-13 20:11:02 +01002131 wl_resource_set_implementation(cr, &keyboard_interface,
2132 seat, unbind_resource);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002133
Jonny Lamb66a41a02014-08-12 14:58:25 +02002134 if (wl_resource_get_version(cr) >= WL_KEYBOARD_REPEAT_INFO_SINCE_VERSION) {
2135 wl_keyboard_send_repeat_info(cr,
2136 seat->compositor->kb_repeat_rate,
2137 seat->compositor->kb_repeat_delay);
2138 }
Jasper St. Pierred8c6aeb2014-08-04 13:43:24 -04002139
Matt Roper01a92732013-06-24 16:52:44 +01002140 if (seat->compositor->use_xkbcommon) {
2141 wl_keyboard_send_keymap(cr, WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1,
Jonas Ådahl7395ea02013-12-03 09:14:26 +01002142 keyboard->xkb_info->keymap_fd,
2143 keyboard->xkb_info->keymap_size);
Matt Roper01a92732013-06-24 16:52:44 +01002144 } else {
2145 int null_fd = open("/dev/null", O_RDONLY);
2146 wl_keyboard_send_keymap(cr, WL_KEYBOARD_KEYMAP_FORMAT_NO_KEYMAP,
2147 null_fd,
2148 0);
2149 close(null_fd);
2150 }
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002151
Neil Roberts96d790e2013-09-19 17:32:00 +01002152 if (should_send_modifiers_to_client(seat, client)) {
Derek Foreman345c9f32015-06-03 15:53:28 -05002153 send_modifiers_to_resource(keyboard,
Neil Roberts96d790e2013-09-19 17:32:00 +01002154 cr,
Derek Foreman345c9f32015-06-03 15:53:28 -05002155 keyboard->focus_serial);
Neil Roberts96d790e2013-09-19 17:32:00 +01002156 }
2157
Derek Foreman345c9f32015-06-03 15:53:28 -05002158 if (keyboard->focus && keyboard->focus->resource &&
2159 wl_resource_get_client(keyboard->focus->resource) == client) {
Neil Roberts96d790e2013-09-19 17:32:00 +01002160 struct weston_surface *surface =
Derek Foreman345c9f32015-06-03 15:53:28 -05002161 (struct weston_surface *)keyboard->focus;
Neil Roberts96d790e2013-09-19 17:32:00 +01002162
2163 wl_list_remove(wl_resource_get_link(cr));
Derek Foreman345c9f32015-06-03 15:53:28 -05002164 wl_list_insert(&keyboard->focus_resource_list,
Neil Roberts96d790e2013-09-19 17:32:00 +01002165 wl_resource_get_link(cr));
2166 wl_keyboard_send_enter(cr,
Derek Foreman345c9f32015-06-03 15:53:28 -05002167 keyboard->focus_serial,
Neil Roberts96d790e2013-09-19 17:32:00 +01002168 surface->resource,
Derek Foreman345c9f32015-06-03 15:53:28 -05002169 &keyboard->keys);
Neil Roberts96d790e2013-09-19 17:32:00 +01002170
2171 /* If this is the first keyboard resource for this
2172 * client... */
Derek Foreman345c9f32015-06-03 15:53:28 -05002173 if (keyboard->focus_resource_list.prev ==
Neil Roberts96d790e2013-09-19 17:32:00 +01002174 wl_resource_get_link(cr))
2175 wl_data_device_set_keyboard_focus(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002176 }
2177}
2178
2179static void
Kristian Høgsberg69e25fc2013-08-13 20:11:02 +01002180touch_release(struct wl_client *client, struct wl_resource *resource)
2181{
2182 wl_resource_destroy(resource);
2183}
2184
2185static const struct wl_touch_interface touch_interface = {
2186 touch_release
2187};
2188
2189static void
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002190seat_get_touch(struct wl_client *client, struct wl_resource *resource,
2191 uint32_t id)
2192{
Jason Ekstrand44a38632013-06-14 10:08:00 -05002193 struct weston_seat *seat = wl_resource_get_user_data(resource);
Derek Foreman1281a362015-07-31 16:55:32 -05002194 /* We use the touch_state directly, which means we'll
2195 * give a wl_touch if the seat has ever had one - even though
2196 * the spec explicitly states that this request only takes effect
2197 * if the seat has the touch capability.
2198 *
2199 * This prevents a race between the compositor sending new
2200 * capabilities and the client trying to use the old ones.
2201 */
2202 struct weston_touch *touch = seat->touch_state;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002203 struct wl_resource *cr;
2204
Derek Foreman1281a362015-07-31 16:55:32 -05002205 if (!touch)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002206 return;
2207
Jason Ekstranda85118c2013-06-27 20:17:02 -05002208 cr = wl_resource_create(client, &wl_touch_interface,
2209 wl_resource_get_version(resource), id);
Kristian Høgsberg0ff79082013-08-06 16:46:25 -07002210 if (cr == NULL) {
2211 wl_client_post_no_memory(client);
2212 return;
2213 }
2214
Derek Foreman1281a362015-07-31 16:55:32 -05002215 if (touch->focus &&
2216 wl_resource_get_client(touch->focus->surface->resource) == client) {
Chokshi, Mituld6697142015-10-09 08:28:47 +00002217 wl_list_insert(&touch->focus_resource_list,
Neil Roberts96d790e2013-09-19 17:32:00 +01002218 wl_resource_get_link(cr));
2219 } else {
Chokshi, Mituld6697142015-10-09 08:28:47 +00002220 wl_list_insert(&touch->resource_list,
Neil Roberts96d790e2013-09-19 17:32:00 +01002221 wl_resource_get_link(cr));
2222 }
Kristian Høgsberg69e25fc2013-08-13 20:11:02 +01002223 wl_resource_set_implementation(cr, &touch_interface,
2224 seat, unbind_resource);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002225}
2226
2227static const struct wl_seat_interface seat_interface = {
2228 seat_get_pointer,
2229 seat_get_keyboard,
2230 seat_get_touch,
2231};
2232
2233static void
2234bind_seat(struct wl_client *client, void *data, uint32_t version, uint32_t id)
2235{
Kristian Høgsberge3148752013-05-06 23:19:49 -04002236 struct weston_seat *seat = data;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002237 struct wl_resource *resource;
2238 enum wl_seat_capability caps = 0;
2239
Jason Ekstranda85118c2013-06-27 20:17:02 -05002240 resource = wl_resource_create(client,
Derek Foreman1909c102015-11-26 14:17:47 -06002241 &wl_seat_interface, version, id);
Jason Ekstrand44a38632013-06-14 10:08:00 -05002242 wl_list_insert(&seat->base_resource_list, wl_resource_get_link(resource));
Jason Ekstranda85118c2013-06-27 20:17:02 -05002243 wl_resource_set_implementation(resource, &seat_interface, data,
2244 unbind_resource);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002245
Derek Foreman1281a362015-07-31 16:55:32 -05002246 if (weston_seat_get_pointer(seat))
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002247 caps |= WL_SEAT_CAPABILITY_POINTER;
Derek Foreman1281a362015-07-31 16:55:32 -05002248 if (weston_seat_get_keyboard(seat))
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002249 caps |= WL_SEAT_CAPABILITY_KEYBOARD;
Derek Foreman1281a362015-07-31 16:55:32 -05002250 if (weston_seat_get_touch(seat))
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002251 caps |= WL_SEAT_CAPABILITY_TOUCH;
2252
2253 wl_seat_send_capabilities(resource, caps);
Jasper St. Pierre0013a292014-08-07 16:43:11 -04002254 if (version >= WL_SEAT_NAME_SINCE_VERSION)
Rob Bradforde445ae62013-05-31 18:09:51 +01002255 wl_seat_send_name(resource, seat->seat_name);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002256}
2257
Rob Bradford382ff462013-06-24 16:52:45 +01002258#ifdef ENABLE_XKBCOMMON
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002259int
2260weston_compositor_xkb_init(struct weston_compositor *ec,
2261 struct xkb_rule_names *names)
2262{
Rob Bradford382ff462013-06-24 16:52:45 +01002263 ec->use_xkbcommon = 1;
Matt Roper01a92732013-06-24 16:52:44 +01002264
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002265 if (ec->xkb_context == NULL) {
2266 ec->xkb_context = xkb_context_new(0);
2267 if (ec->xkb_context == NULL) {
2268 weston_log("failed to create XKB context\n");
2269 return -1;
2270 }
2271 }
2272
2273 if (names)
2274 ec->xkb_names = *names;
2275 if (!ec->xkb_names.rules)
2276 ec->xkb_names.rules = strdup("evdev");
2277 if (!ec->xkb_names.model)
2278 ec->xkb_names.model = strdup("pc105");
2279 if (!ec->xkb_names.layout)
2280 ec->xkb_names.layout = strdup("us");
2281
2282 return 0;
2283}
2284
Stefan Schmidtfda26522013-09-17 10:54:09 +01002285static void
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00002286weston_xkb_info_destroy(struct weston_xkb_info *xkb_info)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002287{
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00002288 if (--xkb_info->ref_count > 0)
2289 return;
2290
Ran Benitac9c74152014-08-19 23:59:52 +03002291 xkb_keymap_unref(xkb_info->keymap);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002292
2293 if (xkb_info->keymap_area)
2294 munmap(xkb_info->keymap_area, xkb_info->keymap_size);
2295 if (xkb_info->keymap_fd >= 0)
2296 close(xkb_info->keymap_fd);
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00002297 free(xkb_info);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002298}
2299
2300void
2301weston_compositor_xkb_destroy(struct weston_compositor *ec)
2302{
Matt Roper01a92732013-06-24 16:52:44 +01002303 /*
2304 * If we're operating in raw keyboard mode, we never initialized
2305 * libxkbcommon so there's no cleanup to do either.
2306 */
2307 if (!ec->use_xkbcommon)
2308 return;
2309
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002310 free((char *) ec->xkb_names.rules);
2311 free((char *) ec->xkb_names.model);
2312 free((char *) ec->xkb_names.layout);
2313 free((char *) ec->xkb_names.variant);
2314 free((char *) ec->xkb_names.options);
Stefan Schmidtfda26522013-09-17 10:54:09 +01002315
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00002316 if (ec->xkb_info)
2317 weston_xkb_info_destroy(ec->xkb_info);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002318 xkb_context_unref(ec->xkb_context);
2319}
2320
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00002321static struct weston_xkb_info *
2322weston_xkb_info_create(struct xkb_keymap *keymap)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002323{
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00002324 struct weston_xkb_info *xkb_info = zalloc(sizeof *xkb_info);
2325 if (xkb_info == NULL)
2326 return NULL;
2327
Ran Benita2e1968f2014-08-19 23:59:51 +03002328 xkb_info->keymap = xkb_keymap_ref(keymap);
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00002329 xkb_info->ref_count = 1;
2330
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002331 char *keymap_str;
2332
Ran Benita2e1968f2014-08-19 23:59:51 +03002333 xkb_info->shift_mod = xkb_keymap_mod_get_index(xkb_info->keymap,
2334 XKB_MOD_NAME_SHIFT);
2335 xkb_info->caps_mod = xkb_keymap_mod_get_index(xkb_info->keymap,
2336 XKB_MOD_NAME_CAPS);
2337 xkb_info->ctrl_mod = xkb_keymap_mod_get_index(xkb_info->keymap,
2338 XKB_MOD_NAME_CTRL);
2339 xkb_info->alt_mod = xkb_keymap_mod_get_index(xkb_info->keymap,
2340 XKB_MOD_NAME_ALT);
2341 xkb_info->mod2_mod = xkb_keymap_mod_get_index(xkb_info->keymap,
2342 "Mod2");
2343 xkb_info->mod3_mod = xkb_keymap_mod_get_index(xkb_info->keymap,
2344 "Mod3");
2345 xkb_info->super_mod = xkb_keymap_mod_get_index(xkb_info->keymap,
2346 XKB_MOD_NAME_LOGO);
2347 xkb_info->mod5_mod = xkb_keymap_mod_get_index(xkb_info->keymap,
2348 "Mod5");
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002349
Ran Benita2e1968f2014-08-19 23:59:51 +03002350 xkb_info->num_led = xkb_keymap_led_get_index(xkb_info->keymap,
2351 XKB_LED_NAME_NUM);
2352 xkb_info->caps_led = xkb_keymap_led_get_index(xkb_info->keymap,
2353 XKB_LED_NAME_CAPS);
2354 xkb_info->scroll_led = xkb_keymap_led_get_index(xkb_info->keymap,
2355 XKB_LED_NAME_SCROLL);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002356
Ran Benita2e1968f2014-08-19 23:59:51 +03002357 keymap_str = xkb_keymap_get_as_string(xkb_info->keymap,
2358 XKB_KEYMAP_FORMAT_TEXT_V1);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002359 if (keymap_str == NULL) {
2360 weston_log("failed to get string version of keymap\n");
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00002361 goto err_keymap;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002362 }
2363 xkb_info->keymap_size = strlen(keymap_str) + 1;
2364
2365 xkb_info->keymap_fd = os_create_anonymous_file(xkb_info->keymap_size);
2366 if (xkb_info->keymap_fd < 0) {
2367 weston_log("creating a keymap file for %lu bytes failed: %m\n",
2368 (unsigned long) xkb_info->keymap_size);
2369 goto err_keymap_str;
2370 }
2371
2372 xkb_info->keymap_area = mmap(NULL, xkb_info->keymap_size,
2373 PROT_READ | PROT_WRITE,
2374 MAP_SHARED, xkb_info->keymap_fd, 0);
2375 if (xkb_info->keymap_area == MAP_FAILED) {
2376 weston_log("failed to mmap() %lu bytes\n",
2377 (unsigned long) xkb_info->keymap_size);
2378 goto err_dev_zero;
2379 }
2380 strcpy(xkb_info->keymap_area, keymap_str);
2381 free(keymap_str);
2382
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00002383 return xkb_info;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002384
2385err_dev_zero:
2386 close(xkb_info->keymap_fd);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002387err_keymap_str:
2388 free(keymap_str);
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00002389err_keymap:
Ran Benita2e1968f2014-08-19 23:59:51 +03002390 xkb_keymap_unref(xkb_info->keymap);
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00002391 free(xkb_info);
2392 return NULL;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002393}
2394
2395static int
2396weston_compositor_build_global_keymap(struct weston_compositor *ec)
2397{
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00002398 struct xkb_keymap *keymap;
2399
2400 if (ec->xkb_info != NULL)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002401 return 0;
2402
Ran Benita2e1968f2014-08-19 23:59:51 +03002403 keymap = xkb_keymap_new_from_names(ec->xkb_context,
2404 &ec->xkb_names,
2405 0);
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00002406 if (keymap == NULL) {
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002407 weston_log("failed to compile global XKB keymap\n");
2408 weston_log(" tried rules %s, model %s, layout %s, variant %s, "
2409 "options %s\n",
2410 ec->xkb_names.rules, ec->xkb_names.model,
2411 ec->xkb_names.layout, ec->xkb_names.variant,
2412 ec->xkb_names.options);
2413 return -1;
2414 }
2415
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00002416 ec->xkb_info = weston_xkb_info_create(keymap);
Rui Matos73d93952013-10-24 19:28:41 +02002417 xkb_keymap_unref(keymap);
Stefan Schmidtfda26522013-09-17 10:54:09 +01002418 if (ec->xkb_info == NULL)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002419 return -1;
2420
2421 return 0;
2422}
Rob Bradford382ff462013-06-24 16:52:45 +01002423#else
2424int
2425weston_compositor_xkb_init(struct weston_compositor *ec,
2426 struct xkb_rule_names *names)
2427{
2428 return 0;
2429}
2430
2431void
2432weston_compositor_xkb_destroy(struct weston_compositor *ec)
2433{
2434}
2435#endif
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002436
Rui Matos65196bc2013-10-10 19:44:19 +02002437WL_EXPORT void
2438weston_seat_update_keymap(struct weston_seat *seat, struct xkb_keymap *keymap)
2439{
Derek Foreman1281a362015-07-31 16:55:32 -05002440 struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
2441
2442 if (!keyboard || !keymap)
Rui Matos65196bc2013-10-10 19:44:19 +02002443 return;
2444
2445#ifdef ENABLE_XKBCOMMON
2446 if (!seat->compositor->use_xkbcommon)
2447 return;
2448
Derek Foreman1281a362015-07-31 16:55:32 -05002449 xkb_keymap_unref(keyboard->pending_keymap);
2450 keyboard->pending_keymap = xkb_keymap_ref(keymap);
Rui Matos65196bc2013-10-10 19:44:19 +02002451
Derek Foreman1281a362015-07-31 16:55:32 -05002452 if (keyboard->keys.size == 0)
Rui Matos65196bc2013-10-10 19:44:19 +02002453 update_keymap(seat);
2454#endif
2455}
2456
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002457WL_EXPORT int
2458weston_seat_init_keyboard(struct weston_seat *seat, struct xkb_keymap *keymap)
2459{
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04002460 struct weston_keyboard *keyboard;
2461
Derek Foreman1281a362015-07-31 16:55:32 -05002462 if (seat->keyboard_state) {
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002463 seat->keyboard_device_count += 1;
2464 if (seat->keyboard_device_count == 1)
2465 seat_send_updated_caps(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002466 return 0;
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002467 }
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002468
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04002469 keyboard = weston_keyboard_create();
2470 if (keyboard == NULL) {
2471 weston_log("failed to allocate weston keyboard struct\n");
2472 return -1;
2473 }
2474
Jonas Ådahl7395ea02013-12-03 09:14:26 +01002475#ifdef ENABLE_XKBCOMMON
2476 if (seat->compositor->use_xkbcommon) {
2477 if (keymap != NULL) {
2478 keyboard->xkb_info = weston_xkb_info_create(keymap);
2479 if (keyboard->xkb_info == NULL)
Ander Conselvan de Oliveira4d363cf2014-01-31 17:35:45 +02002480 goto err;
Jonas Ådahl7395ea02013-12-03 09:14:26 +01002481 } else {
2482 if (weston_compositor_build_global_keymap(seat->compositor) < 0)
Ander Conselvan de Oliveira4d363cf2014-01-31 17:35:45 +02002483 goto err;
Jonas Ådahl7395ea02013-12-03 09:14:26 +01002484 keyboard->xkb_info = seat->compositor->xkb_info;
2485 keyboard->xkb_info->ref_count++;
2486 }
2487
2488 keyboard->xkb_state.state = xkb_state_new(keyboard->xkb_info->keymap);
2489 if (keyboard->xkb_state.state == NULL) {
2490 weston_log("failed to initialise XKB state\n");
Ander Conselvan de Oliveira4d363cf2014-01-31 17:35:45 +02002491 goto err;
Jonas Ådahl7395ea02013-12-03 09:14:26 +01002492 }
2493
2494 keyboard->xkb_state.leds = 0;
2495 }
2496#endif
2497
Derek Foreman1281a362015-07-31 16:55:32 -05002498 seat->keyboard_state = keyboard;
Ander Conselvan de Oliveira4d363cf2014-01-31 17:35:45 +02002499 seat->keyboard_device_count = 1;
2500 keyboard->seat = seat;
2501
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04002502 seat_send_updated_caps(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002503
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002504 return 0;
Ander Conselvan de Oliveira4d363cf2014-01-31 17:35:45 +02002505
2506err:
2507 if (keyboard->xkb_info)
2508 weston_xkb_info_destroy(keyboard->xkb_info);
2509 free(keyboard);
2510
2511 return -1;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002512}
2513
Jonas Ådahl91fed542013-12-03 09:14:27 +01002514static void
2515weston_keyboard_reset_state(struct weston_keyboard *keyboard)
2516{
2517 struct weston_seat *seat = keyboard->seat;
2518 struct xkb_state *state;
2519
2520#ifdef ENABLE_XKBCOMMON
2521 if (seat->compositor->use_xkbcommon) {
2522 state = xkb_state_new(keyboard->xkb_info->keymap);
2523 if (!state) {
2524 weston_log("failed to reset XKB state\n");
2525 return;
2526 }
2527 xkb_state_unref(keyboard->xkb_state.state);
2528 keyboard->xkb_state.state = state;
2529
2530 keyboard->xkb_state.leds = 0;
2531 }
2532#endif
2533
2534 seat->modifier_state = 0;
2535}
2536
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002537WL_EXPORT void
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002538weston_seat_release_keyboard(struct weston_seat *seat)
2539{
2540 seat->keyboard_device_count--;
Derek Foremand621df22014-11-19 11:04:12 -06002541 assert(seat->keyboard_device_count >= 0);
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002542 if (seat->keyboard_device_count == 0) {
Derek Foreman1281a362015-07-31 16:55:32 -05002543 weston_keyboard_set_focus(seat->keyboard_state, NULL);
2544 weston_keyboard_cancel_grab(seat->keyboard_state);
2545 weston_keyboard_reset_state(seat->keyboard_state);
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002546 seat_send_updated_caps(seat);
2547 }
2548}
2549
2550WL_EXPORT void
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002551weston_seat_init_pointer(struct weston_seat *seat)
2552{
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04002553 struct weston_pointer *pointer;
2554
Derek Foreman1281a362015-07-31 16:55:32 -05002555 if (seat->pointer_state) {
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002556 seat->pointer_device_count += 1;
2557 if (seat->pointer_device_count == 1)
2558 seat_send_updated_caps(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002559 return;
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002560 }
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002561
Giulio Camuffocdb4d292013-11-14 23:42:53 +01002562 pointer = weston_pointer_create(seat);
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04002563 if (pointer == NULL)
2564 return;
2565
Derek Foreman1281a362015-07-31 16:55:32 -05002566 seat->pointer_state = pointer;
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002567 seat->pointer_device_count = 1;
2568 pointer->seat = seat;
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04002569
2570 seat_send_updated_caps(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002571}
2572
2573WL_EXPORT void
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002574weston_seat_release_pointer(struct weston_seat *seat)
2575{
Derek Foreman1281a362015-07-31 16:55:32 -05002576 struct weston_pointer *pointer = seat->pointer_state;
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002577
2578 seat->pointer_device_count--;
2579 if (seat->pointer_device_count == 0) {
Derek Foremanf9318d12015-05-11 15:40:11 -05002580 weston_pointer_clear_focus(pointer);
Jonas Ådahl1ea343e2013-10-25 23:18:05 +02002581 weston_pointer_cancel_grab(pointer);
Jonas Ådahl630bae82013-10-17 23:04:06 +02002582
Jonas Ådahla4932742013-10-17 23:04:07 +02002583 if (pointer->sprite)
2584 pointer_unmap_sprite(pointer);
2585
Jonas Ådahl3e12e632013-12-02 22:05:05 +01002586 weston_pointer_reset_state(pointer);
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002587 seat_send_updated_caps(seat);
Derek Foremanfd5ca512015-01-07 15:00:25 -06002588
2589 /* seat->pointer is intentionally not destroyed so that
2590 * a newly attached pointer on this seat will retain
2591 * the previous cursor co-ordinates.
2592 */
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002593 }
2594}
2595
2596WL_EXPORT void
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002597weston_seat_init_touch(struct weston_seat *seat)
2598{
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04002599 struct weston_touch *touch;
2600
Derek Foreman1281a362015-07-31 16:55:32 -05002601 if (seat->touch_state) {
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002602 seat->touch_device_count += 1;
2603 if (seat->touch_device_count == 1)
2604 seat_send_updated_caps(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002605 return;
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002606 }
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002607
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04002608 touch = weston_touch_create();
2609 if (touch == NULL)
2610 return;
2611
Derek Foreman1281a362015-07-31 16:55:32 -05002612 seat->touch_state = touch;
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002613 seat->touch_device_count = 1;
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04002614 touch->seat = seat;
2615
2616 seat_send_updated_caps(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002617}
2618
2619WL_EXPORT void
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002620weston_seat_release_touch(struct weston_seat *seat)
2621{
2622 seat->touch_device_count--;
2623 if (seat->touch_device_count == 0) {
Derek Foreman1281a362015-07-31 16:55:32 -05002624 weston_touch_set_focus(seat->touch_state, NULL);
2625 weston_touch_cancel_grab(seat->touch_state);
2626 weston_touch_reset_state(seat->touch_state);
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002627 seat_send_updated_caps(seat);
2628 }
2629}
2630
2631WL_EXPORT void
Rob Bradford9af5f9e2013-05-31 18:09:50 +01002632weston_seat_init(struct weston_seat *seat, struct weston_compositor *ec,
2633 const char *seat_name)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002634{
Kristian Høgsberg4a2a2742013-05-06 22:24:50 -04002635 memset(seat, 0, sizeof *seat);
2636
Kristian Høgsberge3148752013-05-06 23:19:49 -04002637 seat->selection_data_source = NULL;
2638 wl_list_init(&seat->base_resource_list);
2639 wl_signal_init(&seat->selection_signal);
2640 wl_list_init(&seat->drag_resource_list);
Kristian Høgsberge3148752013-05-06 23:19:49 -04002641 wl_signal_init(&seat->destroy_signal);
Jason Ekstranda4ab5422014-04-02 19:53:45 -05002642 wl_signal_init(&seat->updated_caps_signal);
Kristian Høgsberg4a2a2742013-05-06 22:24:50 -04002643
Peter Hutterer87743e92016-01-18 16:38:22 +10002644 seat->global = wl_global_create(ec->wl_display, &wl_seat_interface, 5,
Kristian Høgsberg919cddb2013-07-08 19:03:57 -04002645 seat, bind_seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002646
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002647 seat->compositor = ec;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002648 seat->modifier_state = 0;
Rob Bradford9af5f9e2013-05-31 18:09:50 +01002649 seat->seat_name = strdup(seat_name);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002650
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002651 wl_list_insert(ec->seat_list.prev, &seat->link);
2652
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002653 clipboard_create(seat);
2654
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002655 wl_signal_emit(&ec->seat_created_signal, seat);
2656}
2657
2658WL_EXPORT void
2659weston_seat_release(struct weston_seat *seat)
2660{
2661 wl_list_remove(&seat->link);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002662
Jonas Ådahl1afb2382014-01-03 19:46:51 +01002663 if (seat->saved_kbd_focus)
2664 wl_list_remove(&seat->saved_kbd_focus_listener.link);
2665
Derek Foreman1281a362015-07-31 16:55:32 -05002666 if (seat->pointer_state)
2667 weston_pointer_destroy(seat->pointer_state);
2668 if (seat->keyboard_state)
2669 weston_keyboard_destroy(seat->keyboard_state);
2670 if (seat->touch_state)
2671 weston_touch_destroy(seat->touch_state);
Kristian Høgsberg4a2a2742013-05-06 22:24:50 -04002672
Rob Bradford9af5f9e2013-05-31 18:09:50 +01002673 free (seat->seat_name);
2674
Kristian Høgsberg919cddb2013-07-08 19:03:57 -04002675 wl_global_destroy(seat->global);
Kristian Høgsbergaaadc772013-07-08 16:20:31 -04002676
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002677 wl_signal_emit(&seat->destroy_signal, seat);
2678}
Derek Foreman1281a362015-07-31 16:55:32 -05002679
2680/** Get a seat's keyboard pointer
2681 *
2682 * \param seat The seat to query
2683 * \return The seat's keyboard pointer, or NULL if no keyboard is present
2684 *
2685 * The keyboard pointer for a seat isn't freed when all keyboards are removed,
2686 * so it should only be used when the seat's keyboard_device_count is greater
2687 * than zero. This function does that test and only returns a pointer
2688 * when a keyboard is present.
2689 */
2690WL_EXPORT struct weston_keyboard *
2691weston_seat_get_keyboard(struct weston_seat *seat)
2692{
2693 if (!seat)
2694 return NULL;
2695
2696 if (seat->keyboard_device_count)
2697 return seat->keyboard_state;
2698
2699 return NULL;
2700}
2701
2702/** Get a seat's pointer pointer
2703 *
2704 * \param seat The seat to query
2705 * \return The seat's pointer pointer, or NULL if no pointer device is present
2706 *
2707 * The pointer pointer for a seat isn't freed when all mice are removed,
2708 * so it should only be used when the seat's pointer_device_count is greater
2709 * than zero. This function does that test and only returns a pointer
2710 * when a pointing device is present.
2711 */
2712WL_EXPORT struct weston_pointer *
2713weston_seat_get_pointer(struct weston_seat *seat)
2714{
2715 if (!seat)
2716 return NULL;
2717
2718 if (seat->pointer_device_count)
2719 return seat->pointer_state;
2720
2721 return NULL;
2722}
2723
2724/** Get a seat's touch pointer
2725 *
2726 * \param seat The seat to query
2727 * \return The seat's touch pointer, or NULL if no touch device is present
2728 *
2729 * The touch pointer for a seat isn't freed when all touch devices are removed,
2730 * so it should only be used when the seat's touch_device_count is greater
2731 * than zero. This function does that test and only returns a pointer
2732 * when a touch device is present.
2733 */
2734WL_EXPORT struct weston_touch *
2735weston_seat_get_touch(struct weston_seat *seat)
2736{
2737 if (!seat)
2738 return NULL;
2739
2740 if (seat->touch_device_count)
2741 return seat->touch_state;
2742
2743 return NULL;
2744}