blob: 9ef3949fe2bc44d278f48a7195dcdbe14fb2e335 [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"
Jonas Ådahl30d61d82014-10-22 21:21:17 +020040#include "protocol/relative-pointer-unstable-v1-server-protocol.h"
Kristian Høgsberg2158a882013-04-18 15:07:39 -040041
Kristian Høgsbergb5e26102013-04-18 15:40:10 -040042static void
43empty_region(pixman_region32_t *region)
44{
45 pixman_region32_fini(region);
46 pixman_region32_init(region);
47}
48
Jonas Ådahl2cbf2932015-07-22 12:05:38 +080049static struct weston_pointer_client *
50weston_pointer_client_create(struct wl_client *client)
51{
52 struct weston_pointer_client *pointer_client;
53
54 pointer_client = zalloc(sizeof *pointer_client);
55 if (!pointer_client)
56 return NULL;
57
58 pointer_client->client = client;
59 wl_list_init(&pointer_client->pointer_resources);
Jonas Ådahl30d61d82014-10-22 21:21:17 +020060 wl_list_init(&pointer_client->relative_pointer_resources);
Jonas Ådahl2cbf2932015-07-22 12:05:38 +080061
62 return pointer_client;
63}
64
65static void
66weston_pointer_client_destroy(struct weston_pointer_client *pointer_client)
67{
68 free(pointer_client);
69}
70
71static bool
72weston_pointer_client_is_empty(struct weston_pointer_client *pointer_client)
73{
Jonas Ådahl30d61d82014-10-22 21:21:17 +020074 return (wl_list_empty(&pointer_client->pointer_resources) &&
75 wl_list_empty(&pointer_client->relative_pointer_resources));
Jonas Ådahl2cbf2932015-07-22 12:05:38 +080076}
77
78static struct weston_pointer_client *
79weston_pointer_get_pointer_client(struct weston_pointer *pointer,
80 struct wl_client *client)
81{
82 struct weston_pointer_client *pointer_client;
83
84 wl_list_for_each(pointer_client, &pointer->pointer_clients, link) {
85 if (pointer_client->client == client)
86 return pointer_client;
87 }
88
89 return NULL;
90}
91
92static struct weston_pointer_client *
93weston_pointer_ensure_pointer_client(struct weston_pointer *pointer,
94 struct wl_client *client)
95{
96 struct weston_pointer_client *pointer_client;
97
98 pointer_client = weston_pointer_get_pointer_client(pointer, client);
99 if (pointer_client)
100 return pointer_client;
101
102 pointer_client = weston_pointer_client_create(client);
103 wl_list_insert(&pointer->pointer_clients, &pointer_client->link);
104
105 if (pointer->focus &&
106 pointer->focus->surface->resource &&
107 wl_resource_get_client(pointer->focus->surface->resource) == client) {
108 pointer->focus_client = pointer_client;
109 }
110
111 return pointer_client;
112}
113
114static void
115weston_pointer_cleanup_pointer_client(struct weston_pointer *pointer,
116 struct weston_pointer_client *pointer_client)
117{
118 if (weston_pointer_client_is_empty(pointer_client)) {
119 if (pointer->focus_client == pointer_client)
120 pointer->focus_client = NULL;
121 wl_list_remove(&pointer_client->link);
122 weston_pointer_client_destroy(pointer_client);
123 }
124}
125
126static void
127unbind_pointer_client_resource(struct wl_resource *resource)
128{
129 struct weston_pointer *pointer = wl_resource_get_user_data(resource);
130 struct wl_client *client = wl_resource_get_client(resource);
131 struct weston_pointer_client *pointer_client;
132
133 pointer_client = weston_pointer_get_pointer_client(pointer, client);
134 assert(pointer_client);
135
136 wl_list_remove(wl_resource_get_link(resource));
137 weston_pointer_cleanup_pointer_client(pointer, pointer_client);
138}
139
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400140static void unbind_resource(struct wl_resource *resource)
141{
Jason Ekstrand44a38632013-06-14 10:08:00 -0500142 wl_list_remove(wl_resource_get_link(resource));
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400143}
144
Jonas Ådahl3042ffe2013-10-17 23:04:08 +0200145WL_EXPORT void
Jonas Ådahl30d61d82014-10-22 21:21:17 +0200146weston_pointer_motion_to_abs(struct weston_pointer *pointer,
147 struct weston_pointer_motion_event *event,
148 wl_fixed_t *x, wl_fixed_t *y)
149{
150 if (event->mask & WESTON_POINTER_MOTION_ABS) {
151 *x = wl_fixed_from_double(event->x);
152 *y = wl_fixed_from_double(event->y);
153 } else if (event->mask & WESTON_POINTER_MOTION_REL) {
154 *x = pointer->x + wl_fixed_from_double(event->dx);
155 *y = pointer->y + wl_fixed_from_double(event->dy);
156 } else {
157 assert(!"invalid motion event");
158 *x = *y = 0;
159 }
160}
161
162static bool
163weston_pointer_motion_to_rel(struct weston_pointer *pointer,
164 struct weston_pointer_motion_event *event,
165 double *dx, double *dy,
166 double *dx_unaccel, double *dy_unaccel)
167{
168 if (event->mask & WESTON_POINTER_MOTION_REL &&
169 event->mask & WESTON_POINTER_MOTION_REL_UNACCEL) {
170 *dx = event->dx;
171 *dy = event->dy;
172 *dx_unaccel = event->dx_unaccel;
173 *dy_unaccel = event->dy_unaccel;
174 return true;
175 } else if (event->mask & WESTON_POINTER_MOTION_REL) {
176 *dx_unaccel = *dx = event->dx;
177 *dy_unaccel = *dy = event->dy;
178 return true;
179 } else if (event->mask & WESTON_POINTER_MOTION_REL_UNACCEL) {
180 *dx_unaccel = *dx = event->dx_unaccel;
181 *dy_unaccel = *dy = event->dy_unaccel;
182 return true;
183 } else {
184 return false;
185 }
186}
187
188WL_EXPORT void
Kristian Høgsberga71e8b22013-05-06 21:51:21 -0400189weston_seat_repick(struct weston_seat *seat)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400190{
Derek Foreman1281a362015-07-31 16:55:32 -0500191 const struct weston_pointer *pointer = weston_seat_get_pointer(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400192
Derek Foreman1b786ee2015-06-03 15:53:23 -0500193 if (!pointer)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400194 return;
195
Derek Foreman1b786ee2015-06-03 15:53:23 -0500196 pointer->grab->interface->focus(pointer->grab);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -0400197}
198
199static void
200weston_compositor_idle_inhibit(struct weston_compositor *compositor)
201{
202 weston_compositor_wake(compositor);
203 compositor->idle_inhibit++;
204}
205
206static void
207weston_compositor_idle_release(struct weston_compositor *compositor)
208{
209 compositor->idle_inhibit--;
210 weston_compositor_wake(compositor);
211}
212
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400213static void
Giulio Camuffo576fe2a2013-11-20 18:00:24 +0100214pointer_focus_view_destroyed(struct wl_listener *listener, void *data)
215{
216 struct weston_pointer *pointer =
217 container_of(listener, struct weston_pointer,
218 focus_view_listener);
219
Derek Foremanf9318d12015-05-11 15:40:11 -0500220 weston_pointer_clear_focus(pointer);
Giulio Camuffo576fe2a2013-11-20 18:00:24 +0100221}
222
223static void
224pointer_focus_resource_destroyed(struct wl_listener *listener, void *data)
225{
226 struct weston_pointer *pointer =
227 container_of(listener, struct weston_pointer,
228 focus_resource_listener);
229
Derek Foremanf9318d12015-05-11 15:40:11 -0500230 weston_pointer_clear_focus(pointer);
Giulio Camuffo576fe2a2013-11-20 18:00:24 +0100231}
232
233static void
234keyboard_focus_resource_destroyed(struct wl_listener *listener, void *data)
235{
236 struct weston_keyboard *keyboard =
237 container_of(listener, struct weston_keyboard,
238 focus_resource_listener);
239
240 weston_keyboard_set_focus(keyboard, NULL);
241}
242
243static void
244touch_focus_view_destroyed(struct wl_listener *listener, void *data)
245{
246 struct weston_touch *touch =
247 container_of(listener, struct weston_touch,
248 focus_view_listener);
249
Derek Foreman4c93c082015-04-30 16:45:41 -0500250 weston_touch_set_focus(touch, NULL);
Giulio Camuffo576fe2a2013-11-20 18:00:24 +0100251}
252
253static void
254touch_focus_resource_destroyed(struct wl_listener *listener, void *data)
255{
256 struct weston_touch *touch =
257 container_of(listener, struct weston_touch,
258 focus_resource_listener);
259
Derek Foreman4c93c082015-04-30 16:45:41 -0500260 weston_touch_set_focus(touch, NULL);
Giulio Camuffo576fe2a2013-11-20 18:00:24 +0100261}
262
263static void
Neil Roberts96d790e2013-09-19 17:32:00 +0100264move_resources(struct wl_list *destination, struct wl_list *source)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400265{
Neil Roberts96d790e2013-09-19 17:32:00 +0100266 wl_list_insert_list(destination, source);
267 wl_list_init(source);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400268}
269
270static void
Neil Roberts96d790e2013-09-19 17:32:00 +0100271move_resources_for_client(struct wl_list *destination,
272 struct wl_list *source,
273 struct wl_client *client)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400274{
Neil Roberts96d790e2013-09-19 17:32:00 +0100275 struct wl_resource *resource, *tmp;
276 wl_resource_for_each_safe(resource, tmp, source) {
277 if (wl_resource_get_client(resource) == client) {
278 wl_list_remove(wl_resource_get_link(resource));
279 wl_list_insert(destination,
280 wl_resource_get_link(resource));
281 }
282 }
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400283}
284
285static void
Kristian Høgsbergb27901c2013-10-28 15:32:02 -0700286default_grab_pointer_focus(struct weston_pointer_grab *grab)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400287{
Kristian Høgsberg02bbabb2013-05-06 22:15:05 -0400288 struct weston_pointer *pointer = grab->pointer;
Jason Ekstranda7af7042013-10-12 22:38:11 -0500289 struct weston_view *view;
Kristian Høgsberg6848c252013-05-08 22:02:59 -0400290 wl_fixed_t sx, sy;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400291
292 if (pointer->button_count > 0)
293 return;
294
Jason Ekstranda7af7042013-10-12 22:38:11 -0500295 view = weston_compositor_pick_view(pointer->seat->compositor,
296 pointer->x, pointer->y,
297 &sx, &sy);
Kristian Høgsberg6848c252013-05-08 22:02:59 -0400298
Kristian Høgsbergdb1fccb2014-02-05 17:14:42 -0800299 if (pointer->focus != view || pointer->sx != sx || pointer->sy != sy)
Jason Ekstranda7af7042013-10-12 22:38:11 -0500300 weston_pointer_set_focus(pointer, view, sx, sy);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400301}
302
303static void
Jonas Ådahl30d61d82014-10-22 21:21:17 +0200304weston_pointer_send_relative_motion(struct weston_pointer *pointer,
305 uint32_t time,
306 struct weston_pointer_motion_event *event)
307{
308 uint64_t time_usec;
309 double dx, dy, dx_unaccel, dy_unaccel;
310 wl_fixed_t dxf, dyf, dxf_unaccel, dyf_unaccel;
311 struct wl_list *resource_list;
312 struct wl_resource *resource;
313
314 if (!pointer->focus_client)
315 return;
316
317 if (!weston_pointer_motion_to_rel(pointer, event,
318 &dx, &dy,
319 &dx_unaccel, &dy_unaccel))
320 return;
321
322 resource_list = &pointer->focus_client->relative_pointer_resources;
323 time_usec = event->time_usec;
324 if (time_usec == 0)
325 time_usec = time * 1000ULL;
326
327 dxf = wl_fixed_from_double(dx);
328 dyf = wl_fixed_from_double(dy);
329 dxf_unaccel = wl_fixed_from_double(dx_unaccel);
330 dyf_unaccel = wl_fixed_from_double(dy_unaccel);
331
332 wl_resource_for_each(resource, resource_list) {
333 zwp_relative_pointer_v1_send_relative_motion(
334 resource,
335 (uint32_t) (time_usec >> 32),
336 (uint32_t) time_usec,
337 dxf, dyf,
338 dxf_unaccel, dyf_unaccel);
339 }
340}
341
342static void
Giulio Camuffo1959ab82013-11-14 23:42:52 +0100343default_grab_pointer_motion(struct weston_pointer_grab *grab, uint32_t time,
Jonas Ådahld2510102014-10-05 21:39:14 +0200344 struct weston_pointer_motion_event *event)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400345{
Kristian Høgsbergbe6403e2013-05-08 21:03:21 -0400346 struct weston_pointer *pointer = grab->pointer;
Neil Roberts96d790e2013-09-19 17:32:00 +0100347 struct wl_list *resource_list;
348 struct wl_resource *resource;
Jonas Ådahld2510102014-10-05 21:39:14 +0200349 wl_fixed_t x, y;
Jonas Ådahl8283c342015-04-24 15:26:17 +0800350 wl_fixed_t old_sx = pointer->sx;
351 wl_fixed_t old_sy = pointer->sy;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400352
Jonas Ådahld2510102014-10-05 21:39:14 +0200353 if (pointer->focus) {
354 weston_pointer_motion_to_abs(pointer, event, &x, &y);
Kristian Høgsbergdb1fccb2014-02-05 17:14:42 -0800355 weston_view_from_global_fixed(pointer->focus, x, y,
356 &pointer->sx, &pointer->sy);
Jonas Ådahld2510102014-10-05 21:39:14 +0200357 }
Kristian Høgsbergdb1fccb2014-02-05 17:14:42 -0800358
Jonas Ådahld2510102014-10-05 21:39:14 +0200359 weston_pointer_move(pointer, event);
Giulio Camuffo1959ab82013-11-14 23:42:52 +0100360
Jonas Ådahl2cbf2932015-07-22 12:05:38 +0800361 if (pointer->focus_client &&
362 (old_sx != pointer->sx || old_sy != pointer->sy)) {
363 resource_list = &pointer->focus_client->pointer_resources;
Jonas Ådahl8283c342015-04-24 15:26:17 +0800364 wl_resource_for_each(resource, resource_list) {
365 wl_pointer_send_motion(resource, time,
366 pointer->sx, pointer->sy);
367 }
Kristian Høgsbergbe6403e2013-05-08 21:03:21 -0400368 }
Jonas Ådahl30d61d82014-10-22 21:21:17 +0200369
370 weston_pointer_send_relative_motion(pointer, time, event);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400371}
372
373static void
Kristian Høgsbergb27901c2013-10-28 15:32:02 -0700374default_grab_pointer_button(struct weston_pointer_grab *grab,
375 uint32_t time, uint32_t button, uint32_t state_w)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400376{
Kristian Høgsberg02bbabb2013-05-06 22:15:05 -0400377 struct weston_pointer *pointer = grab->pointer;
Kristian Høgsberge122b7b2013-05-08 16:47:00 -0400378 struct weston_compositor *compositor = pointer->seat->compositor;
Jason Ekstranda7af7042013-10-12 22:38:11 -0500379 struct weston_view *view;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400380 struct wl_resource *resource;
381 uint32_t serial;
382 enum wl_pointer_button_state state = state_w;
Rob Bradford880ebc72013-07-22 17:31:38 +0100383 struct wl_display *display = compositor->wl_display;
Kristian Høgsberge122b7b2013-05-08 16:47:00 -0400384 wl_fixed_t sx, sy;
Jonas Ådahl2cbf2932015-07-22 12:05:38 +0800385 struct wl_list *resource_list = NULL;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400386
Jonas Ådahl2cbf2932015-07-22 12:05:38 +0800387 if (pointer->focus_client)
388 resource_list = &pointer->focus_client->pointer_resources;
389 if (resource_list && !wl_list_empty(resource_list)) {
390 resource_list = &pointer->focus_client->pointer_resources;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400391 serial = wl_display_next_serial(display);
Neil Roberts96d790e2013-09-19 17:32:00 +0100392 wl_resource_for_each(resource, resource_list)
393 wl_pointer_send_button(resource,
394 serial,
395 time,
396 button,
397 state_w);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400398 }
399
400 if (pointer->button_count == 0 &&
Kristian Høgsberge122b7b2013-05-08 16:47:00 -0400401 state == WL_POINTER_BUTTON_STATE_RELEASED) {
Jason Ekstranda7af7042013-10-12 22:38:11 -0500402 view = weston_compositor_pick_view(compositor,
403 pointer->x, pointer->y,
404 &sx, &sy);
Kristian Høgsberge122b7b2013-05-08 16:47:00 -0400405
Jason Ekstranda7af7042013-10-12 22:38:11 -0500406 weston_pointer_set_focus(pointer, view, sx, sy);
Kristian Høgsberge122b7b2013-05-08 16:47:00 -0400407 }
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400408}
409
Jonas Ådahl0336ca02014-10-04 16:28:29 +0200410/** Send wl_pointer.axis events to focused resources.
411 *
412 * \param pointer The pointer where the axis events originates from.
413 * \param time The timestamp of the event
414 * \param axis The axis enum value of the event
415 * \param value The axis value of the event
416 *
417 * For every resource that is currently in focus, send a wl_pointer.axis event
418 * with the passed parameters. The focused resources are the wl_pointer
419 * resources of the client which currently has the surface with pointer focus.
420 */
421WL_EXPORT void
422weston_pointer_send_axis(struct weston_pointer *pointer,
Peter Hutterer89b6a492016-01-18 15:58:17 +1000423 uint32_t time,
424 struct weston_pointer_axis_event *event)
Jonas Ådahl0336ca02014-10-04 16:28:29 +0200425{
426 struct wl_resource *resource;
427 struct wl_list *resource_list;
428
Jonas Ådahl2cbf2932015-07-22 12:05:38 +0800429 if (!pointer->focus_client)
430 return;
431
432 resource_list = &pointer->focus_client->pointer_resources;
Peter Hutterer87743e92016-01-18 16:38:22 +1000433 wl_resource_for_each(resource, resource_list) {
434 if (event->has_discrete &&
435 wl_resource_get_version(resource) >=
436 WL_POINTER_AXIS_DISCRETE_SINCE_VERSION)
437 wl_pointer_send_axis_discrete(resource, event->axis,
438 event->discrete);
439
440 if (event->value)
441 wl_pointer_send_axis(resource, time,
Giulio Camuffo90a6fc62016-03-22 17:44:54 +0200442 event->axis,
443 wl_fixed_from_double(event->value));
Peter Hutterer87743e92016-01-18 16:38:22 +1000444 else if (wl_resource_get_version(resource) >=
445 WL_POINTER_AXIS_STOP_SINCE_VERSION)
446 wl_pointer_send_axis_stop(resource, time,
447 event->axis);
448 }
449}
450
451WL_EXPORT void
452weston_pointer_send_axis_source(struct weston_pointer *pointer, uint32_t source)
453{
454 struct wl_resource *resource;
455 struct wl_list *resource_list;
456
Jonas Ådahled6014a2016-04-21 10:21:48 +0800457 if (!pointer->focus_client)
458 return;
459
Peter Hutterer87743e92016-01-18 16:38:22 +1000460 resource_list = &pointer->focus_client->pointer_resources;
461 wl_resource_for_each(resource, resource_list) {
462 if (wl_resource_get_version(resource) >=
463 WL_POINTER_AXIS_SOURCE_SINCE_VERSION) {
464 wl_pointer_send_axis_source(resource, source);
465 }
466 }
467}
468
469static void
470pointer_send_frame(struct wl_resource *resource)
471{
472 if (wl_resource_get_version(resource) >=
473 WL_POINTER_FRAME_SINCE_VERSION) {
474 wl_pointer_send_frame(resource);
475 }
476}
477
478WL_EXPORT void
479weston_pointer_send_frame(struct weston_pointer *pointer)
480{
481 struct wl_resource *resource;
482 struct wl_list *resource_list;
483
Derek Foreman8efa31b2016-01-29 10:29:46 -0600484 if (!pointer->focus_client)
485 return;
486
Peter Hutterer87743e92016-01-18 16:38:22 +1000487 resource_list = &pointer->focus_client->pointer_resources;
Jonas Ådahl0336ca02014-10-04 16:28:29 +0200488 wl_resource_for_each(resource, resource_list)
Peter Hutterer87743e92016-01-18 16:38:22 +1000489 pointer_send_frame(resource);
Jonas Ådahl0336ca02014-10-04 16:28:29 +0200490}
491
492static void
493default_grab_pointer_axis(struct weston_pointer_grab *grab,
Peter Hutterer89b6a492016-01-18 15:58:17 +1000494 uint32_t time,
495 struct weston_pointer_axis_event *event)
Jonas Ådahl0336ca02014-10-04 16:28:29 +0200496{
Peter Hutterer89b6a492016-01-18 15:58:17 +1000497 weston_pointer_send_axis(grab->pointer, time, event);
Jonas Ådahl0336ca02014-10-04 16:28:29 +0200498}
499
Jonas Ådahl1ea343e2013-10-25 23:18:05 +0200500static void
Peter Hutterer87743e92016-01-18 16:38:22 +1000501default_grab_pointer_axis_source(struct weston_pointer_grab *grab,
502 uint32_t source)
503{
504 weston_pointer_send_axis_source(grab->pointer, source);
505}
506
507static void
508default_grab_pointer_frame(struct weston_pointer_grab *grab)
509{
510 weston_pointer_send_frame(grab->pointer);
511}
512
513static void
Jonas Ådahl1ea343e2013-10-25 23:18:05 +0200514default_grab_pointer_cancel(struct weston_pointer_grab *grab)
515{
516}
517
Kristian Høgsberg02bbabb2013-05-06 22:15:05 -0400518static const struct weston_pointer_grab_interface
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400519 default_pointer_grab_interface = {
Kristian Høgsbergb27901c2013-10-28 15:32:02 -0700520 default_grab_pointer_focus,
521 default_grab_pointer_motion,
522 default_grab_pointer_button,
Jonas Ådahl0336ca02014-10-04 16:28:29 +0200523 default_grab_pointer_axis,
Peter Hutterer87743e92016-01-18 16:38:22 +1000524 default_grab_pointer_axis_source,
525 default_grab_pointer_frame,
Jonas Ådahl1ea343e2013-10-25 23:18:05 +0200526 default_grab_pointer_cancel,
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400527};
528
Kristian Høgsberge329f362013-05-06 22:19:57 -0400529static void
530default_grab_touch_down(struct weston_touch_grab *grab, uint32_t time,
Giulio Camuffo61ed7b62015-07-08 11:55:28 +0300531 int touch_id, wl_fixed_t x, wl_fixed_t y)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400532{
Kristian Høgsberge329f362013-05-06 22:19:57 -0400533 struct weston_touch *touch = grab->touch;
Rob Bradford880ebc72013-07-22 17:31:38 +0100534 struct wl_display *display = touch->seat->compositor->wl_display;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400535 uint32_t serial;
Neil Roberts96d790e2013-09-19 17:32:00 +0100536 struct wl_resource *resource;
537 struct wl_list *resource_list;
Giulio Camuffo61ed7b62015-07-08 11:55:28 +0300538 wl_fixed_t sx, sy;
539
Bryce Harrington2c40d1d2016-02-02 10:18:48 -0800540 if (!touch->focus)
541 return;
542
Giulio Camuffo61ed7b62015-07-08 11:55:28 +0300543 weston_view_from_global_fixed(touch->focus, x, y, &sx, &sy);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400544
Neil Roberts96d790e2013-09-19 17:32:00 +0100545 resource_list = &touch->focus_resource_list;
546
Bryce Harrington2c40d1d2016-02-02 10:18:48 -0800547 if (!wl_list_empty(resource_list)) {
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400548 serial = wl_display_next_serial(display);
Neil Roberts96d790e2013-09-19 17:32:00 +0100549 wl_resource_for_each(resource, resource_list)
550 wl_touch_send_down(resource, serial, time,
Jason Ekstranda7af7042013-10-12 22:38:11 -0500551 touch->focus->surface->resource,
Neil Roberts96d790e2013-09-19 17:32:00 +0100552 touch_id, sx, sy);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400553 }
554}
555
Kristian Høgsberge329f362013-05-06 22:19:57 -0400556static void
557default_grab_touch_up(struct weston_touch_grab *grab,
558 uint32_t time, int touch_id)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400559{
Kristian Høgsberge329f362013-05-06 22:19:57 -0400560 struct weston_touch *touch = grab->touch;
Rob Bradford880ebc72013-07-22 17:31:38 +0100561 struct wl_display *display = touch->seat->compositor->wl_display;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400562 uint32_t serial;
Neil Roberts96d790e2013-09-19 17:32:00 +0100563 struct wl_resource *resource;
564 struct wl_list *resource_list;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400565
Neil Roberts96d790e2013-09-19 17:32:00 +0100566 resource_list = &touch->focus_resource_list;
567
568 if (!wl_list_empty(resource_list)) {
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400569 serial = wl_display_next_serial(display);
Neil Roberts96d790e2013-09-19 17:32:00 +0100570 wl_resource_for_each(resource, resource_list)
571 wl_touch_send_up(resource, serial, time, touch_id);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400572 }
573}
574
Kristian Høgsberge329f362013-05-06 22:19:57 -0400575static void
576default_grab_touch_motion(struct weston_touch_grab *grab, uint32_t time,
Giulio Camuffo61ed7b62015-07-08 11:55:28 +0300577 int touch_id, wl_fixed_t x, wl_fixed_t y)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400578{
Kristian Høgsberge329f362013-05-06 22:19:57 -0400579 struct weston_touch *touch = grab->touch;
Neil Roberts96d790e2013-09-19 17:32:00 +0100580 struct wl_resource *resource;
581 struct wl_list *resource_list;
Giulio Camuffo61ed7b62015-07-08 11:55:28 +0300582 wl_fixed_t sx, sy;
583
584 weston_view_from_global_fixed(touch->focus, x, y, &sx, &sy);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400585
Neil Roberts96d790e2013-09-19 17:32:00 +0100586 resource_list = &touch->focus_resource_list;
587
588 wl_resource_for_each(resource, resource_list) {
589 wl_touch_send_motion(resource, time,
Kristian Høgsberge329f362013-05-06 22:19:57 -0400590 touch_id, sx, sy);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400591 }
592}
593
Jonas Ådahl1ea343e2013-10-25 23:18:05 +0200594static void
Jonas Ådahl1679f232014-04-12 09:39:51 +0200595default_grab_touch_frame(struct weston_touch_grab *grab)
596{
597 struct wl_resource *resource;
598
599 wl_resource_for_each(resource, &grab->touch->focus_resource_list)
600 wl_touch_send_frame(resource);
601}
602
603static void
Jonas Ådahl1ea343e2013-10-25 23:18:05 +0200604default_grab_touch_cancel(struct weston_touch_grab *grab)
605{
606}
607
Kristian Høgsberge329f362013-05-06 22:19:57 -0400608static const struct weston_touch_grab_interface default_touch_grab_interface = {
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400609 default_grab_touch_down,
610 default_grab_touch_up,
Jonas Ådahl1ea343e2013-10-25 23:18:05 +0200611 default_grab_touch_motion,
Jonas Ådahl1679f232014-04-12 09:39:51 +0200612 default_grab_touch_frame,
Jonas Ådahl1ea343e2013-10-25 23:18:05 +0200613 default_grab_touch_cancel,
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400614};
615
616static void
Kristian Høgsbergb27901c2013-10-28 15:32:02 -0700617default_grab_keyboard_key(struct weston_keyboard_grab *grab,
618 uint32_t time, uint32_t key, uint32_t state)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400619{
Kristian Høgsberg29139d42013-04-18 15:25:39 -0400620 struct weston_keyboard *keyboard = grab->keyboard;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400621 struct wl_resource *resource;
Rob Bradford880ebc72013-07-22 17:31:38 +0100622 struct wl_display *display = keyboard->seat->compositor->wl_display;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400623 uint32_t serial;
Neil Roberts96d790e2013-09-19 17:32:00 +0100624 struct wl_list *resource_list;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400625
Neil Roberts96d790e2013-09-19 17:32:00 +0100626 resource_list = &keyboard->focus_resource_list;
627 if (!wl_list_empty(resource_list)) {
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400628 serial = wl_display_next_serial(display);
Neil Roberts96d790e2013-09-19 17:32:00 +0100629 wl_resource_for_each(resource, resource_list)
630 wl_keyboard_send_key(resource,
631 serial,
632 time,
633 key,
634 state);
635 }
636}
637
638static void
639send_modifiers_to_resource(struct weston_keyboard *keyboard,
640 struct wl_resource *resource,
641 uint32_t serial)
642{
643 wl_keyboard_send_modifiers(resource,
644 serial,
645 keyboard->modifiers.mods_depressed,
646 keyboard->modifiers.mods_latched,
647 keyboard->modifiers.mods_locked,
648 keyboard->modifiers.group);
649}
650
651static void
652send_modifiers_to_client_in_list(struct wl_client *client,
653 struct wl_list *list,
654 uint32_t serial,
655 struct weston_keyboard *keyboard)
656{
657 struct wl_resource *resource;
658
659 wl_resource_for_each(resource, list) {
660 if (wl_resource_get_client(resource) == client)
661 send_modifiers_to_resource(keyboard,
662 resource,
663 serial);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400664 }
665}
666
Jonas Ådahl2cbf2932015-07-22 12:05:38 +0800667static struct weston_pointer_client *
668find_pointer_client_for_surface(struct weston_pointer *pointer,
669 struct weston_surface *surface)
670{
671 struct wl_client *client;
672
673 if (!surface)
674 return NULL;
675
676 if (!surface->resource)
677 return NULL;
678
679 client = wl_resource_get_client(surface->resource);
680 return weston_pointer_get_pointer_client(pointer, client);
681}
682
683static struct weston_pointer_client *
684find_pointer_client_for_view(struct weston_pointer *pointer, struct weston_view *view)
685{
686 if (!view)
687 return NULL;
688
689 return find_pointer_client_for_surface(pointer, view->surface);
690}
691
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400692static struct wl_resource *
Kristian Høgsbergfe7aa902013-05-08 09:54:37 -0400693find_resource_for_surface(struct wl_list *list, struct weston_surface *surface)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400694{
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400695 if (!surface)
696 return NULL;
697
Jason Ekstrand44a38632013-06-14 10:08:00 -0500698 if (!surface->resource)
699 return NULL;
Stefan Schmidtfda26522013-09-17 10:54:09 +0100700
Jason Ekstrand44a38632013-06-14 10:08:00 -0500701 return wl_resource_find_for_client(list, wl_resource_get_client(surface->resource));
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400702}
703
704static void
Kristian Høgsbergb27901c2013-10-28 15:32:02 -0700705default_grab_keyboard_modifiers(struct weston_keyboard_grab *grab,
706 uint32_t serial, uint32_t mods_depressed,
707 uint32_t mods_latched,
708 uint32_t mods_locked, uint32_t group)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400709{
Kristian Høgsberg29139d42013-04-18 15:25:39 -0400710 struct weston_keyboard *keyboard = grab->keyboard;
Derek Foreman1281a362015-07-31 16:55:32 -0500711 struct weston_pointer *pointer =
712 weston_seat_get_pointer(grab->keyboard->seat);
Neil Roberts96d790e2013-09-19 17:32:00 +0100713 struct wl_resource *resource;
714 struct wl_list *resource_list;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400715
Neil Roberts96d790e2013-09-19 17:32:00 +0100716 resource_list = &keyboard->focus_resource_list;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400717
Neil Roberts96d790e2013-09-19 17:32:00 +0100718 wl_resource_for_each(resource, resource_list) {
719 wl_keyboard_send_modifiers(resource, serial, mods_depressed,
720 mods_latched, mods_locked, group);
721 }
Jason Ekstrand42133d42013-11-14 20:06:16 -0600722 if (pointer && pointer->focus && pointer->focus->surface->resource &&
723 pointer->focus->surface != keyboard->focus) {
Neil Roberts96d790e2013-09-19 17:32:00 +0100724 struct wl_client *pointer_client =
Jason Ekstranda7af7042013-10-12 22:38:11 -0500725 wl_resource_get_client(pointer->focus->surface->resource);
Neil Roberts96d790e2013-09-19 17:32:00 +0100726 send_modifiers_to_client_in_list(pointer_client,
727 &keyboard->resource_list,
728 serial,
729 keyboard);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400730 }
731}
732
Jonas Ådahl1ea343e2013-10-25 23:18:05 +0200733static void
734default_grab_keyboard_cancel(struct weston_keyboard_grab *grab)
735{
736}
737
Kristian Høgsberg29139d42013-04-18 15:25:39 -0400738static const struct weston_keyboard_grab_interface
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400739 default_keyboard_grab_interface = {
Kristian Høgsbergb27901c2013-10-28 15:32:02 -0700740 default_grab_keyboard_key,
741 default_grab_keyboard_modifiers,
Jonas Ådahl1ea343e2013-10-25 23:18:05 +0200742 default_grab_keyboard_cancel,
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400743};
744
Kristian Høgsberg195b8692013-05-08 15:02:05 -0400745static void
746pointer_unmap_sprite(struct weston_pointer *pointer)
747{
Pekka Paalanenc557ff72014-11-12 16:42:52 +0200748 struct weston_surface *surface = pointer->sprite->surface;
749
750 if (weston_surface_is_mapped(surface))
751 weston_surface_unmap(surface);
Kristian Høgsberg195b8692013-05-08 15:02:05 -0400752
753 wl_list_remove(&pointer->sprite_destroy_listener.link);
Pekka Paalanenc557ff72014-11-12 16:42:52 +0200754 surface->configure = NULL;
755 surface->configure_private = NULL;
Pekka Paalanen8274d902014-08-06 19:36:51 +0300756 weston_surface_set_label_func(surface, NULL);
Jason Ekstranda7af7042013-10-12 22:38:11 -0500757 weston_view_destroy(pointer->sprite);
Kristian Høgsberg195b8692013-05-08 15:02:05 -0400758 pointer->sprite = NULL;
759}
760
761static void
762pointer_handle_sprite_destroy(struct wl_listener *listener, void *data)
763{
764 struct weston_pointer *pointer =
765 container_of(listener, struct weston_pointer,
766 sprite_destroy_listener);
767
768 pointer->sprite = NULL;
769}
770
Jonas Ådahl3e12e632013-12-02 22:05:05 +0100771static void
772weston_pointer_reset_state(struct weston_pointer *pointer)
773{
774 pointer->button_count = 0;
775}
776
Ander Conselvan de Oliveiraf84327a2014-01-29 18:47:51 +0200777static void
778weston_pointer_handle_output_destroy(struct wl_listener *listener, void *data);
779
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400780WL_EXPORT struct weston_pointer *
Giulio Camuffocdb4d292013-11-14 23:42:53 +0100781weston_pointer_create(struct weston_seat *seat)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400782{
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400783 struct weston_pointer *pointer;
784
Peter Huttererf3d62272013-08-08 11:57:05 +1000785 pointer = zalloc(sizeof *pointer);
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400786 if (pointer == NULL)
787 return NULL;
788
Jonas Ådahl2cbf2932015-07-22 12:05:38 +0800789 wl_list_init(&pointer->pointer_clients);
Giulio Camuffocdb4d292013-11-14 23:42:53 +0100790 weston_pointer_set_default_grab(pointer,
791 seat->compositor->default_pointer_grab);
Giulio Camuffo576fe2a2013-11-20 18:00:24 +0100792 wl_list_init(&pointer->focus_resource_listener.link);
793 pointer->focus_resource_listener.notify = pointer_focus_resource_destroyed;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400794 pointer->default_grab.pointer = pointer;
795 pointer->grab = &pointer->default_grab;
Giulio Camuffo6fcb3782013-11-14 23:42:50 +0100796 wl_signal_init(&pointer->motion_signal);
Emilio Pozuelo Monfortaa7a4762013-11-19 11:37:15 +0100797 wl_signal_init(&pointer->focus_signal);
Giulio Camuffo576fe2a2013-11-20 18:00:24 +0100798 wl_list_init(&pointer->focus_view_listener.link);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400799
Kristian Høgsberg195b8692013-05-08 15:02:05 -0400800 pointer->sprite_destroy_listener.notify = pointer_handle_sprite_destroy;
801
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400802 /* FIXME: Pick better co-ords. */
803 pointer->x = wl_fixed_from_int(100);
804 pointer->y = wl_fixed_from_int(100);
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400805
Ander Conselvan de Oliveiraf84327a2014-01-29 18:47:51 +0200806 pointer->output_destroy_listener.notify =
807 weston_pointer_handle_output_destroy;
808 wl_signal_add(&seat->compositor->output_destroyed_signal,
809 &pointer->output_destroy_listener);
810
Derek Foremanf9318d12015-05-11 15:40:11 -0500811 pointer->sx = wl_fixed_from_int(-1000000);
812 pointer->sy = wl_fixed_from_int(-1000000);
813
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400814 return pointer;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400815}
816
817WL_EXPORT void
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400818weston_pointer_destroy(struct weston_pointer *pointer)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400819{
Kristian Høgsberg195b8692013-05-08 15:02:05 -0400820 if (pointer->sprite)
821 pointer_unmap_sprite(pointer);
822
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400823 /* XXX: What about pointer->resource_list? */
Neil Roberts96d790e2013-09-19 17:32:00 +0100824
Giulio Camuffo576fe2a2013-11-20 18:00:24 +0100825 wl_list_remove(&pointer->focus_resource_listener.link);
826 wl_list_remove(&pointer->focus_view_listener.link);
Ander Conselvan de Oliveiraf84327a2014-01-29 18:47:51 +0200827 wl_list_remove(&pointer->output_destroy_listener.link);
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400828 free(pointer);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400829}
830
Giulio Camuffocdb4d292013-11-14 23:42:53 +0100831void
832weston_pointer_set_default_grab(struct weston_pointer *pointer,
833 const struct weston_pointer_grab_interface *interface)
834{
835 if (interface)
836 pointer->default_grab.interface = interface;
837 else
838 pointer->default_grab.interface =
839 &default_pointer_grab_interface;
840}
841
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400842WL_EXPORT struct weston_keyboard *
843weston_keyboard_create(void)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400844{
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400845 struct weston_keyboard *keyboard;
846
Peter Huttererf3d62272013-08-08 11:57:05 +1000847 keyboard = zalloc(sizeof *keyboard);
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400848 if (keyboard == NULL)
Neil Roberts96d790e2013-09-19 17:32:00 +0100849 return NULL;
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400850
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400851 wl_list_init(&keyboard->resource_list);
Neil Roberts96d790e2013-09-19 17:32:00 +0100852 wl_list_init(&keyboard->focus_resource_list);
Giulio Camuffo576fe2a2013-11-20 18:00:24 +0100853 wl_list_init(&keyboard->focus_resource_listener.link);
854 keyboard->focus_resource_listener.notify = keyboard_focus_resource_destroyed;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400855 wl_array_init(&keyboard->keys);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400856 keyboard->default_grab.interface = &default_keyboard_grab_interface;
857 keyboard->default_grab.keyboard = keyboard;
858 keyboard->grab = &keyboard->default_grab;
859 wl_signal_init(&keyboard->focus_signal);
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400860
861 return keyboard;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400862}
863
Jonas Ådahl7395ea02013-12-03 09:14:26 +0100864static void
865weston_xkb_info_destroy(struct weston_xkb_info *xkb_info);
866
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400867WL_EXPORT void
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400868weston_keyboard_destroy(struct weston_keyboard *keyboard)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400869{
870 /* XXX: What about keyboard->resource_list? */
Neil Roberts96d790e2013-09-19 17:32:00 +0100871
Jonas Ådahl7395ea02013-12-03 09:14:26 +0100872#ifdef ENABLE_XKBCOMMON
873 if (keyboard->seat->compositor->use_xkbcommon) {
Ran Benitac9c74152014-08-19 23:59:52 +0300874 xkb_state_unref(keyboard->xkb_state.state);
Jonas Ådahl7395ea02013-12-03 09:14:26 +0100875 if (keyboard->xkb_info)
876 weston_xkb_info_destroy(keyboard->xkb_info);
Ran Benitac9c74152014-08-19 23:59:52 +0300877 xkb_keymap_unref(keyboard->pending_keymap);
Jonas Ådahl7395ea02013-12-03 09:14:26 +0100878 }
879#endif
880
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400881 wl_array_release(&keyboard->keys);
Giulio Camuffo576fe2a2013-11-20 18:00:24 +0100882 wl_list_remove(&keyboard->focus_resource_listener.link);
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400883 free(keyboard);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400884}
885
Jonas Ådahlcbfa7f72013-12-02 22:05:04 +0100886static void
887weston_touch_reset_state(struct weston_touch *touch)
888{
889 touch->num_tp = 0;
890}
891
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400892WL_EXPORT struct weston_touch *
893weston_touch_create(void)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400894{
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400895 struct weston_touch *touch;
896
Peter Huttererf3d62272013-08-08 11:57:05 +1000897 touch = zalloc(sizeof *touch);
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400898 if (touch == NULL)
899 return NULL;
900
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400901 wl_list_init(&touch->resource_list);
Neil Roberts96d790e2013-09-19 17:32:00 +0100902 wl_list_init(&touch->focus_resource_list);
Giulio Camuffo576fe2a2013-11-20 18:00:24 +0100903 wl_list_init(&touch->focus_view_listener.link);
904 touch->focus_view_listener.notify = touch_focus_view_destroyed;
905 wl_list_init(&touch->focus_resource_listener.link);
906 touch->focus_resource_listener.notify = touch_focus_resource_destroyed;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400907 touch->default_grab.interface = &default_touch_grab_interface;
908 touch->default_grab.touch = touch;
909 touch->grab = &touch->default_grab;
910 wl_signal_init(&touch->focus_signal);
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400911
912 return touch;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400913}
914
915WL_EXPORT void
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400916weston_touch_destroy(struct weston_touch *touch)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400917{
918 /* XXX: What about touch->resource_list? */
Neil Roberts96d790e2013-09-19 17:32:00 +0100919
Giulio Camuffo576fe2a2013-11-20 18:00:24 +0100920 wl_list_remove(&touch->focus_view_listener.link);
921 wl_list_remove(&touch->focus_resource_listener.link);
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400922 free(touch);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400923}
924
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400925static void
Kristian Høgsberge3148752013-05-06 23:19:49 -0400926seat_send_updated_caps(struct weston_seat *seat)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400927{
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400928 enum wl_seat_capability caps = 0;
Rob Bradford6e737f52013-09-06 17:48:19 +0100929 struct wl_resource *resource;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400930
Jonas Ådahld6e1c342013-10-17 23:04:05 +0200931 if (seat->pointer_device_count > 0)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400932 caps |= WL_SEAT_CAPABILITY_POINTER;
Jonas Ådahld6e1c342013-10-17 23:04:05 +0200933 if (seat->keyboard_device_count > 0)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400934 caps |= WL_SEAT_CAPABILITY_KEYBOARD;
Jonas Ådahld6e1c342013-10-17 23:04:05 +0200935 if (seat->touch_device_count > 0)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400936 caps |= WL_SEAT_CAPABILITY_TOUCH;
937
Rob Bradford6e737f52013-09-06 17:48:19 +0100938 wl_resource_for_each(resource, &seat->base_resource_list) {
939 wl_seat_send_capabilities(resource, caps);
Jason Ekstrand44a38632013-06-14 10:08:00 -0500940 }
Jason Ekstranda4ab5422014-04-02 19:53:45 -0500941 wl_signal_emit(&seat->updated_caps_signal, seat);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400942}
943
Derek Foremanf9318d12015-05-11 15:40:11 -0500944
945/** Clear the pointer focus
946 *
947 * \param pointer the pointer to clear focus for.
948 *
949 * This can be used to unset pointer focus and set the co-ordinates to the
950 * arbitrary values we use for the no focus case.
951 *
952 * There's no requirement to use this function. For example, passing the
953 * results of a weston_compositor_pick_view() directly to
954 * weston_pointer_set_focus() will do the right thing when no view is found.
955 */
956WL_EXPORT void
957weston_pointer_clear_focus(struct weston_pointer *pointer)
958{
959 weston_pointer_set_focus(pointer, NULL,
960 wl_fixed_from_int(-1000000),
961 wl_fixed_from_int(-1000000));
962}
963
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400964WL_EXPORT void
Kristian Høgsberg02bbabb2013-05-06 22:15:05 -0400965weston_pointer_set_focus(struct weston_pointer *pointer,
Jason Ekstranda7af7042013-10-12 22:38:11 -0500966 struct weston_view *view,
Kristian Høgsberg02bbabb2013-05-06 22:15:05 -0400967 wl_fixed_t sx, wl_fixed_t sy)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400968{
Jonas Ådahl2cbf2932015-07-22 12:05:38 +0800969 struct weston_pointer_client *pointer_client;
Derek Foreman1281a362015-07-31 16:55:32 -0500970 struct weston_keyboard *kbd = weston_seat_get_keyboard(pointer->seat);
Neil Roberts96d790e2013-09-19 17:32:00 +0100971 struct wl_resource *resource;
Jonas Ådahl2cbf2932015-07-22 12:05:38 +0800972 struct wl_resource *surface_resource;
Rob Bradford880ebc72013-07-22 17:31:38 +0100973 struct wl_display *display = pointer->seat->compositor->wl_display;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400974 uint32_t serial;
Neil Roberts96d790e2013-09-19 17:32:00 +0100975 struct wl_list *focus_resource_list;
Kristian Høgsbergdb1fccb2014-02-05 17:14:42 -0800976 int refocus = 0;
Jason Ekstranda7af7042013-10-12 22:38:11 -0500977
978 if ((!pointer->focus && view) ||
979 (pointer->focus && !view) ||
Kristian Høgsbergdb1fccb2014-02-05 17:14:42 -0800980 (pointer->focus && pointer->focus->surface != view->surface) ||
981 pointer->sx != sx || pointer->sy != sy)
982 refocus = 1;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400983
Jonas Ådahl2cbf2932015-07-22 12:05:38 +0800984 if (pointer->focus_client && refocus) {
985 focus_resource_list = &pointer->focus_client->pointer_resources;
986 if (!wl_list_empty(focus_resource_list)) {
987 serial = wl_display_next_serial(display);
988 surface_resource = pointer->focus->surface->resource;
989 wl_resource_for_each(resource, focus_resource_list) {
990 wl_pointer_send_leave(resource, serial,
991 surface_resource);
Peter Hutterer87743e92016-01-18 16:38:22 +1000992 pointer_send_frame(resource);
Jonas Ådahl2cbf2932015-07-22 12:05:38 +0800993 }
Neil Roberts96d790e2013-09-19 17:32:00 +0100994 }
995
Jonas Ådahl2cbf2932015-07-22 12:05:38 +0800996 pointer->focus_client = NULL;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400997 }
998
Jonas Ådahl2cbf2932015-07-22 12:05:38 +0800999 pointer_client = find_pointer_client_for_view(pointer, view);
1000 if (pointer_client && refocus) {
1001 struct wl_client *surface_client = pointer_client->client;
Neil Roberts96d790e2013-09-19 17:32:00 +01001002
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001003 serial = wl_display_next_serial(display);
Neil Roberts96d790e2013-09-19 17:32:00 +01001004
Jason Ekstranda7af7042013-10-12 22:38:11 -05001005 if (kbd && kbd->focus != view->surface)
Kristian Høgsbergcb406f12013-10-09 10:54:03 -07001006 send_modifiers_to_client_in_list(surface_client,
1007 &kbd->resource_list,
1008 serial,
1009 kbd);
1010
Jonas Ådahl2cbf2932015-07-22 12:05:38 +08001011 pointer->focus_client = pointer_client;
Neil Roberts96d790e2013-09-19 17:32:00 +01001012
Jonas Ådahl2cbf2932015-07-22 12:05:38 +08001013 focus_resource_list = &pointer->focus_client->pointer_resources;
Neil Roberts96d790e2013-09-19 17:32:00 +01001014 wl_resource_for_each(resource, focus_resource_list) {
1015 wl_pointer_send_enter(resource,
1016 serial,
Jason Ekstranda7af7042013-10-12 22:38:11 -05001017 view->surface->resource,
Neil Roberts96d790e2013-09-19 17:32:00 +01001018 sx, sy);
Peter Hutterer87743e92016-01-18 16:38:22 +10001019 pointer_send_frame(resource);
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001020 }
Neil Roberts96d790e2013-09-19 17:32:00 +01001021
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001022 pointer->focus_serial = serial;
1023 }
1024
Giulio Camuffo65a07f82013-12-06 12:46:27 +01001025 wl_list_remove(&pointer->focus_view_listener.link);
1026 wl_list_init(&pointer->focus_view_listener.link);
1027 wl_list_remove(&pointer->focus_resource_listener.link);
1028 wl_list_init(&pointer->focus_resource_listener.link);
Emilio Pozuelo Monfortaa7a4762013-11-19 11:37:15 +01001029 if (view)
Giulio Camuffo576fe2a2013-11-20 18:00:24 +01001030 wl_signal_add(&view->destroy_signal, &pointer->focus_view_listener);
Giulio Camuffo65a07f82013-12-06 12:46:27 +01001031 if (view && view->surface->resource)
1032 wl_resource_add_destroy_listener(view->surface->resource,
1033 &pointer->focus_resource_listener);
1034
1035 pointer->focus = view;
1036 pointer->focus_view_listener.notify = pointer_focus_view_destroyed;
Kristian Høgsbergdb1fccb2014-02-05 17:14:42 -08001037 pointer->sx = sx;
1038 pointer->sy = sy;
1039
Derek Foremanf9318d12015-05-11 15:40:11 -05001040 assert(view || sx == wl_fixed_from_int(-1000000));
1041 assert(view || sy == wl_fixed_from_int(-1000000));
1042
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001043 wl_signal_emit(&pointer->focus_signal, pointer);
1044}
1045
Neil Roberts96d790e2013-09-19 17:32:00 +01001046static void
1047send_enter_to_resource_list(struct wl_list *list,
1048 struct weston_keyboard *keyboard,
1049 struct weston_surface *surface,
1050 uint32_t serial)
1051{
1052 struct wl_resource *resource;
1053
1054 wl_resource_for_each(resource, list) {
1055 send_modifiers_to_resource(keyboard, resource, serial);
1056 wl_keyboard_send_enter(resource, serial,
1057 surface->resource,
1058 &keyboard->keys);
1059 }
1060}
1061
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001062WL_EXPORT void
Kristian Høgsberg29139d42013-04-18 15:25:39 -04001063weston_keyboard_set_focus(struct weston_keyboard *keyboard,
Kristian Høgsbergfe7aa902013-05-08 09:54:37 -04001064 struct weston_surface *surface)
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001065{
1066 struct wl_resource *resource;
Rob Bradford880ebc72013-07-22 17:31:38 +01001067 struct wl_display *display = keyboard->seat->compositor->wl_display;
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001068 uint32_t serial;
Neil Roberts96d790e2013-09-19 17:32:00 +01001069 struct wl_list *focus_resource_list;
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001070
Neil Roberts96d790e2013-09-19 17:32:00 +01001071 focus_resource_list = &keyboard->focus_resource_list;
1072
1073 if (!wl_list_empty(focus_resource_list) && keyboard->focus != surface) {
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001074 serial = wl_display_next_serial(display);
Neil Roberts96d790e2013-09-19 17:32:00 +01001075 wl_resource_for_each(resource, focus_resource_list) {
1076 wl_keyboard_send_leave(resource, serial,
1077 keyboard->focus->resource);
1078 }
1079 move_resources(&keyboard->resource_list, focus_resource_list);
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001080 }
1081
Neil Roberts96d790e2013-09-19 17:32:00 +01001082 if (find_resource_for_surface(&keyboard->resource_list, surface) &&
1083 keyboard->focus != surface) {
1084 struct wl_client *surface_client =
1085 wl_resource_get_client(surface->resource);
1086
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001087 serial = wl_display_next_serial(display);
Neil Roberts96d790e2013-09-19 17:32:00 +01001088
1089 move_resources_for_client(focus_resource_list,
1090 &keyboard->resource_list,
1091 surface_client);
1092 send_enter_to_resource_list(focus_resource_list,
1093 keyboard,
1094 surface,
1095 serial);
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001096 keyboard->focus_serial = serial;
Giulio Camuffo65a07f82013-12-06 12:46:27 +01001097 }
1098
1099 wl_list_remove(&keyboard->focus_resource_listener.link);
1100 wl_list_init(&keyboard->focus_resource_listener.link);
1101 if (surface && surface->resource)
Giulio Camuffo576fe2a2013-11-20 18:00:24 +01001102 wl_resource_add_destroy_listener(surface->resource,
1103 &keyboard->focus_resource_listener);
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001104
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001105 keyboard->focus = surface;
1106 wl_signal_emit(&keyboard->focus_signal, keyboard);
1107}
1108
Giulio Camuffoa20ca812014-11-22 11:16:56 +02001109/* Users of this function must manually manage the keyboard focus */
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001110WL_EXPORT void
Kristian Høgsberg29139d42013-04-18 15:25:39 -04001111weston_keyboard_start_grab(struct weston_keyboard *keyboard,
1112 struct weston_keyboard_grab *grab)
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001113{
1114 keyboard->grab = grab;
1115 grab->keyboard = keyboard;
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001116}
1117
1118WL_EXPORT void
Kristian Høgsberg29139d42013-04-18 15:25:39 -04001119weston_keyboard_end_grab(struct weston_keyboard *keyboard)
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001120{
1121 keyboard->grab = &keyboard->default_grab;
1122}
1123
Jonas Ådahl1ea343e2013-10-25 23:18:05 +02001124static void
1125weston_keyboard_cancel_grab(struct weston_keyboard *keyboard)
1126{
1127 keyboard->grab->interface->cancel(keyboard->grab);
1128}
1129
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001130WL_EXPORT void
Kristian Høgsberg02bbabb2013-05-06 22:15:05 -04001131weston_pointer_start_grab(struct weston_pointer *pointer,
1132 struct weston_pointer_grab *grab)
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001133{
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001134 pointer->grab = grab;
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001135 grab->pointer = pointer;
Kristian Høgsbergda751b82013-07-04 00:58:07 -04001136 pointer->grab->interface->focus(pointer->grab);
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001137}
1138
1139WL_EXPORT void
Kristian Høgsberg02bbabb2013-05-06 22:15:05 -04001140weston_pointer_end_grab(struct weston_pointer *pointer)
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001141{
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001142 pointer->grab = &pointer->default_grab;
Kristian Høgsbergda751b82013-07-04 00:58:07 -04001143 pointer->grab->interface->focus(pointer->grab);
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001144}
1145
Jonas Ådahl1ea343e2013-10-25 23:18:05 +02001146static void
1147weston_pointer_cancel_grab(struct weston_pointer *pointer)
1148{
1149 pointer->grab->interface->cancel(pointer->grab);
1150}
1151
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001152WL_EXPORT void
Kristian Høgsberge329f362013-05-06 22:19:57 -04001153weston_touch_start_grab(struct weston_touch *touch, struct weston_touch_grab *grab)
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001154{
1155 touch->grab = grab;
1156 grab->touch = touch;
1157}
1158
1159WL_EXPORT void
Kristian Høgsberge329f362013-05-06 22:19:57 -04001160weston_touch_end_grab(struct weston_touch *touch)
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001161{
1162 touch->grab = &touch->default_grab;
1163}
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001164
Jonas Ådahl1ea343e2013-10-25 23:18:05 +02001165static void
1166weston_touch_cancel_grab(struct weston_touch *touch)
1167{
1168 touch->grab->interface->cancel(touch->grab);
1169}
1170
Ander Conselvan de Oliveira54e90c72013-12-13 22:10:56 +02001171static void
1172weston_pointer_clamp_for_output(struct weston_pointer *pointer,
1173 struct weston_output *output,
1174 wl_fixed_t *fx, wl_fixed_t *fy)
1175{
1176 int x, y;
1177
1178 x = wl_fixed_to_int(*fx);
1179 y = wl_fixed_to_int(*fy);
1180
1181 if (x < output->x)
1182 *fx = wl_fixed_from_int(output->x);
1183 else if (x >= output->x + output->width)
1184 *fx = wl_fixed_from_int(output->x +
1185 output->width - 1);
1186 if (y < output->y)
1187 *fy = wl_fixed_from_int(output->y);
1188 else if (y >= output->y + output->height)
1189 *fy = wl_fixed_from_int(output->y +
1190 output->height - 1);
1191}
1192
Rob Bradford806d8c02013-06-25 18:56:41 +01001193WL_EXPORT void
1194weston_pointer_clamp(struct weston_pointer *pointer, wl_fixed_t *fx, wl_fixed_t *fy)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001195{
Rob Bradford806d8c02013-06-25 18:56:41 +01001196 struct weston_compositor *ec = pointer->seat->compositor;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001197 struct weston_output *output, *prev = NULL;
1198 int x, y, old_x, old_y, valid = 0;
1199
1200 x = wl_fixed_to_int(*fx);
1201 y = wl_fixed_to_int(*fy);
Rob Bradford806d8c02013-06-25 18:56:41 +01001202 old_x = wl_fixed_to_int(pointer->x);
1203 old_y = wl_fixed_to_int(pointer->y);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001204
1205 wl_list_for_each(output, &ec->output_list, link) {
Rob Bradford66bd9f52013-06-25 18:56:42 +01001206 if (pointer->seat->output && pointer->seat->output != output)
1207 continue;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001208 if (pixman_region32_contains_point(&output->region,
1209 x, y, NULL))
1210 valid = 1;
1211 if (pixman_region32_contains_point(&output->region,
1212 old_x, old_y, NULL))
1213 prev = output;
1214 }
1215
Rob Bradford66bd9f52013-06-25 18:56:42 +01001216 if (!prev)
1217 prev = pointer->seat->output;
1218
Ander Conselvan de Oliveira54e90c72013-12-13 22:10:56 +02001219 if (prev && !valid)
1220 weston_pointer_clamp_for_output(pointer, prev, fx, fy);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001221}
1222
Jonas Ådahld2510102014-10-05 21:39:14 +02001223static void
1224weston_pointer_move_to(struct weston_pointer *pointer,
1225 wl_fixed_t x, wl_fixed_t y)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001226{
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001227 int32_t ix, iy;
1228
Rob Bradford806d8c02013-06-25 18:56:41 +01001229 weston_pointer_clamp (pointer, &x, &y);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001230
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001231 pointer->x = x;
1232 pointer->y = y;
1233
1234 ix = wl_fixed_to_int(x);
1235 iy = wl_fixed_to_int(y);
1236
Kristian Høgsberg195b8692013-05-08 15:02:05 -04001237 if (pointer->sprite) {
Jason Ekstranda7af7042013-10-12 22:38:11 -05001238 weston_view_set_position(pointer->sprite,
1239 ix - pointer->hotspot_x,
1240 iy - pointer->hotspot_y);
1241 weston_view_schedule_repaint(pointer->sprite);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001242 }
Giulio Camuffo6fcb3782013-11-14 23:42:50 +01001243
Giulio Camuffo1959ab82013-11-14 23:42:52 +01001244 pointer->grab->interface->focus(pointer->grab);
Giulio Camuffo6fcb3782013-11-14 23:42:50 +01001245 wl_signal_emit(&pointer->motion_signal, pointer);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001246}
1247
Jonas Ådahld2510102014-10-05 21:39:14 +02001248WL_EXPORT void
Jonas Ådahld2510102014-10-05 21:39:14 +02001249weston_pointer_move(struct weston_pointer *pointer,
1250 struct weston_pointer_motion_event *event)
1251{
1252 wl_fixed_t x, y;
1253
1254 weston_pointer_motion_to_abs(pointer, event, &x, &y);
1255 weston_pointer_move_to(pointer, x, y);
1256}
1257
Ander Conselvan de Oliveira54e90c72013-12-13 22:10:56 +02001258/** Verify if the pointer is in a valid position and move it if it isn't.
1259 */
Ander Conselvan de Oliveiraf84327a2014-01-29 18:47:51 +02001260static void
1261weston_pointer_handle_output_destroy(struct wl_listener *listener, void *data)
Ander Conselvan de Oliveira54e90c72013-12-13 22:10:56 +02001262{
Ander Conselvan de Oliveiraf84327a2014-01-29 18:47:51 +02001263 struct weston_pointer *pointer;
1264 struct weston_compositor *ec;
Ander Conselvan de Oliveira54e90c72013-12-13 22:10:56 +02001265 struct weston_output *output, *closest = NULL;
1266 int x, y, distance, min = INT_MAX;
1267 wl_fixed_t fx, fy;
1268
Ander Conselvan de Oliveiraf84327a2014-01-29 18:47:51 +02001269 pointer = container_of(listener, struct weston_pointer,
1270 output_destroy_listener);
1271 ec = pointer->seat->compositor;
1272
Ander Conselvan de Oliveira54e90c72013-12-13 22:10:56 +02001273 x = wl_fixed_to_int(pointer->x);
1274 y = wl_fixed_to_int(pointer->y);
1275
1276 wl_list_for_each(output, &ec->output_list, link) {
1277 if (pixman_region32_contains_point(&output->region,
1278 x, y, NULL))
1279 return;
1280
1281 /* Aproximante the distance from the pointer to the center of
1282 * the output. */
1283 distance = abs(output->x + output->width / 2 - x) +
1284 abs(output->y + output->height / 2 - y);
1285 if (distance < min) {
1286 min = distance;
1287 closest = output;
1288 }
1289 }
1290
1291 /* Nothing to do if there's no output left. */
1292 if (!closest)
1293 return;
1294
1295 fx = pointer->x;
1296 fy = pointer->y;
1297
1298 weston_pointer_clamp_for_output(pointer, closest, &fx, &fy);
Jonas Ådahld2510102014-10-05 21:39:14 +02001299 weston_pointer_move_to(pointer, fx, fy);
Ander Conselvan de Oliveira54e90c72013-12-13 22:10:56 +02001300}
1301
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001302WL_EXPORT void
1303notify_motion(struct weston_seat *seat,
Jonas Ådahld2510102014-10-05 21:39:14 +02001304 uint32_t time,
1305 struct weston_pointer_motion_event *event)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001306{
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001307 struct weston_compositor *ec = seat->compositor;
Derek Foreman1281a362015-07-31 16:55:32 -05001308 struct weston_pointer *pointer = weston_seat_get_pointer(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001309
1310 weston_compositor_wake(ec);
Jonas Ådahld2510102014-10-05 21:39:14 +02001311 pointer->grab->interface->motion(pointer->grab, time, event);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001312}
1313
Daniel Stone96d47c02013-11-19 11:37:12 +01001314static void
1315run_modifier_bindings(struct weston_seat *seat, uint32_t old, uint32_t new)
1316{
1317 struct weston_compositor *compositor = seat->compositor;
Derek Foreman1281a362015-07-31 16:55:32 -05001318 struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
Daniel Stone96d47c02013-11-19 11:37:12 +01001319 uint32_t diff;
1320 unsigned int i;
1321 struct {
1322 uint32_t xkb;
1323 enum weston_keyboard_modifier weston;
1324 } mods[] = {
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001325 { keyboard->xkb_info->ctrl_mod, MODIFIER_CTRL },
1326 { keyboard->xkb_info->alt_mod, MODIFIER_ALT },
1327 { keyboard->xkb_info->super_mod, MODIFIER_SUPER },
1328 { keyboard->xkb_info->shift_mod, MODIFIER_SHIFT },
Daniel Stone96d47c02013-11-19 11:37:12 +01001329 };
1330
1331 diff = new & ~old;
1332 for (i = 0; i < ARRAY_LENGTH(mods); i++) {
1333 if (diff & (1 << mods[i].xkb))
1334 weston_compositor_run_modifier_binding(compositor,
Derek Foreman99a6a2d2015-07-15 13:00:43 -05001335 keyboard,
Daniel Stone96d47c02013-11-19 11:37:12 +01001336 mods[i].weston,
1337 WL_KEYBOARD_KEY_STATE_PRESSED);
1338 }
1339
1340 diff = old & ~new;
1341 for (i = 0; i < ARRAY_LENGTH(mods); i++) {
1342 if (diff & (1 << mods[i].xkb))
1343 weston_compositor_run_modifier_binding(compositor,
Derek Foreman99a6a2d2015-07-15 13:00:43 -05001344 keyboard,
Daniel Stone96d47c02013-11-19 11:37:12 +01001345 mods[i].weston,
1346 WL_KEYBOARD_KEY_STATE_RELEASED);
1347 }
1348}
1349
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001350WL_EXPORT void
1351notify_motion_absolute(struct weston_seat *seat,
Giulio Camuffo90a6fc62016-03-22 17:44:54 +02001352 uint32_t time, double x, double y)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001353{
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001354 struct weston_compositor *ec = seat->compositor;
Derek Foreman1281a362015-07-31 16:55:32 -05001355 struct weston_pointer *pointer = weston_seat_get_pointer(seat);
Jonas Ådahld2510102014-10-05 21:39:14 +02001356 struct weston_pointer_motion_event event = { 0 };
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001357
1358 weston_compositor_wake(ec);
Jonas Ådahld2510102014-10-05 21:39:14 +02001359
1360 event = (struct weston_pointer_motion_event) {
1361 .mask = WESTON_POINTER_MOTION_ABS,
Giulio Camuffo90a6fc62016-03-22 17:44:54 +02001362 .x = x,
1363 .y = y,
Jonas Ådahld2510102014-10-05 21:39:14 +02001364 };
1365
1366 pointer->grab->interface->motion(pointer->grab, time, &event);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001367}
1368
Jonas Ådahl94e2e2d2014-10-18 18:42:19 +02001369static unsigned int
1370peek_next_activate_serial(struct weston_compositor *c)
1371{
1372 unsigned serial = c->activate_serial + 1;
1373
1374 return serial == 0 ? 1 : serial;
1375}
1376
1377static void
1378inc_activate_serial(struct weston_compositor *c)
1379{
1380 c->activate_serial = peek_next_activate_serial (c);
1381}
1382
1383WL_EXPORT void
1384weston_view_activate(struct weston_view *view,
1385 struct weston_seat *seat,
1386 uint32_t flags)
1387{
1388 struct weston_compositor *compositor = seat->compositor;
1389
1390 if (flags & WESTON_ACTIVATE_FLAG_CLICKED) {
1391 view->click_to_activate_serial =
1392 peek_next_activate_serial(compositor);
1393 }
1394
1395 weston_seat_set_keyboard_focus(seat, view->surface);
1396}
1397
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001398WL_EXPORT void
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001399notify_button(struct weston_seat *seat, uint32_t time, int32_t button,
1400 enum wl_pointer_button_state state)
1401{
1402 struct weston_compositor *compositor = seat->compositor;
Derek Foreman1281a362015-07-31 16:55:32 -05001403 struct weston_pointer *pointer = weston_seat_get_pointer(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001404
1405 if (state == WL_POINTER_BUTTON_STATE_PRESSED) {
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001406 weston_compositor_idle_inhibit(compositor);
1407 if (pointer->button_count == 0) {
1408 pointer->grab_button = button;
1409 pointer->grab_time = time;
1410 pointer->grab_x = pointer->x;
1411 pointer->grab_y = pointer->y;
1412 }
1413 pointer->button_count++;
1414 } else {
1415 weston_compositor_idle_release(compositor);
1416 pointer->button_count--;
1417 }
1418
Derek Foreman99a6a2d2015-07-15 13:00:43 -05001419 weston_compositor_run_button_binding(compositor, pointer, time, button,
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001420 state);
1421
1422 pointer->grab->interface->button(pointer->grab, time, button, state);
1423
1424 if (pointer->button_count == 1)
1425 pointer->grab_serial =
1426 wl_display_get_serial(compositor->wl_display);
1427}
1428
1429WL_EXPORT void
Peter Hutterer89b6a492016-01-18 15:58:17 +10001430notify_axis(struct weston_seat *seat, uint32_t time,
1431 struct weston_pointer_axis_event *event)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001432{
1433 struct weston_compositor *compositor = seat->compositor;
Derek Foreman1281a362015-07-31 16:55:32 -05001434 struct weston_pointer *pointer = weston_seat_get_pointer(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001435
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001436 weston_compositor_wake(compositor);
1437
Derek Foreman99a6a2d2015-07-15 13:00:43 -05001438 if (weston_compositor_run_axis_binding(compositor, pointer,
Peter Hutterer89b6a492016-01-18 15:58:17 +10001439 time, event))
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001440 return;
1441
Peter Hutterer89b6a492016-01-18 15:58:17 +10001442 pointer->grab->interface->axis(pointer->grab, time, event);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001443}
1444
Peter Hutterer87743e92016-01-18 16:38:22 +10001445WL_EXPORT void
1446notify_axis_source(struct weston_seat *seat, uint32_t source)
1447{
1448 struct weston_compositor *compositor = seat->compositor;
1449 struct weston_pointer *pointer = weston_seat_get_pointer(seat);
1450
1451 weston_compositor_wake(compositor);
1452
1453 pointer->grab->interface->axis_source(pointer->grab, source);
1454}
1455
1456WL_EXPORT void
1457notify_pointer_frame(struct weston_seat *seat)
1458{
1459 struct weston_compositor *compositor = seat->compositor;
1460 struct weston_pointer *pointer = weston_seat_get_pointer(seat);
1461
1462 weston_compositor_wake(compositor);
1463
1464 pointer->grab->interface->frame(pointer->grab);
1465}
1466
Giulio Camuffo6ef444d2014-08-28 19:44:09 +03001467WL_EXPORT int
1468weston_keyboard_set_locks(struct weston_keyboard *keyboard,
1469 uint32_t mask, uint32_t value)
1470{
1471#ifdef ENABLE_XKBCOMMON
1472 uint32_t serial;
1473 xkb_mod_mask_t mods_depressed, mods_latched, mods_locked, group;
1474 xkb_mod_mask_t num, caps;
1475
1476 /* We don't want the leds to go out of sync with the actual state
1477 * so if the backend has no way to change the leds don't try to
1478 * change the state */
1479 if (!keyboard->seat->led_update)
1480 return -1;
1481
1482 mods_depressed = xkb_state_serialize_mods(keyboard->xkb_state.state,
1483 XKB_STATE_DEPRESSED);
1484 mods_latched = xkb_state_serialize_mods(keyboard->xkb_state.state,
1485 XKB_STATE_LATCHED);
1486 mods_locked = xkb_state_serialize_mods(keyboard->xkb_state.state,
1487 XKB_STATE_LOCKED);
1488 group = xkb_state_serialize_group(keyboard->xkb_state.state,
1489 XKB_STATE_EFFECTIVE);
1490
1491 num = (1 << keyboard->xkb_info->mod2_mod);
1492 caps = (1 << keyboard->xkb_info->caps_mod);
1493 if (mask & WESTON_NUM_LOCK) {
1494 if (value & WESTON_NUM_LOCK)
1495 mods_locked |= num;
1496 else
1497 mods_locked &= ~num;
1498 }
1499 if (mask & WESTON_CAPS_LOCK) {
1500 if (value & WESTON_CAPS_LOCK)
1501 mods_locked |= caps;
1502 else
1503 mods_locked &= ~caps;
1504 }
1505
1506 xkb_state_update_mask(keyboard->xkb_state.state, mods_depressed,
1507 mods_latched, mods_locked, 0, 0, group);
1508
1509 serial = wl_display_next_serial(
1510 keyboard->seat->compositor->wl_display);
1511 notify_modifiers(keyboard->seat, serial);
1512
1513 return 0;
1514#else
1515 return -1;
1516#endif
1517}
1518
Rob Bradford382ff462013-06-24 16:52:45 +01001519#ifdef ENABLE_XKBCOMMON
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001520WL_EXPORT void
1521notify_modifiers(struct weston_seat *seat, uint32_t serial)
1522{
Derek Foreman1281a362015-07-31 16:55:32 -05001523 struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001524 struct weston_keyboard_grab *grab = keyboard->grab;
1525 uint32_t mods_depressed, mods_latched, mods_locked, group;
1526 uint32_t mods_lookup;
1527 enum weston_led leds = 0;
1528 int changed = 0;
1529
1530 /* Serialize and update our internal state, checking to see if it's
1531 * different to the previous state. */
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001532 mods_depressed = xkb_state_serialize_mods(keyboard->xkb_state.state,
Ran Benita2e1968f2014-08-19 23:59:51 +03001533 XKB_STATE_MODS_DEPRESSED);
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001534 mods_latched = xkb_state_serialize_mods(keyboard->xkb_state.state,
Ran Benita2e1968f2014-08-19 23:59:51 +03001535 XKB_STATE_MODS_LATCHED);
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001536 mods_locked = xkb_state_serialize_mods(keyboard->xkb_state.state,
Ran Benita2e1968f2014-08-19 23:59:51 +03001537 XKB_STATE_MODS_LOCKED);
1538 group = xkb_state_serialize_layout(keyboard->xkb_state.state,
1539 XKB_STATE_LAYOUT_EFFECTIVE);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001540
Derek Foreman244e99e2015-06-03 15:53:26 -05001541 if (mods_depressed != keyboard->modifiers.mods_depressed ||
1542 mods_latched != keyboard->modifiers.mods_latched ||
1543 mods_locked != keyboard->modifiers.mods_locked ||
1544 group != keyboard->modifiers.group)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001545 changed = 1;
1546
Derek Foreman244e99e2015-06-03 15:53:26 -05001547 run_modifier_bindings(seat, keyboard->modifiers.mods_depressed,
Daniel Stone96d47c02013-11-19 11:37:12 +01001548 mods_depressed);
1549
Derek Foreman244e99e2015-06-03 15:53:26 -05001550 keyboard->modifiers.mods_depressed = mods_depressed;
1551 keyboard->modifiers.mods_latched = mods_latched;
1552 keyboard->modifiers.mods_locked = mods_locked;
1553 keyboard->modifiers.group = group;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001554
1555 /* And update the modifier_state for bindings. */
1556 mods_lookup = mods_depressed | mods_latched;
1557 seat->modifier_state = 0;
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001558 if (mods_lookup & (1 << keyboard->xkb_info->ctrl_mod))
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001559 seat->modifier_state |= MODIFIER_CTRL;
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001560 if (mods_lookup & (1 << keyboard->xkb_info->alt_mod))
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001561 seat->modifier_state |= MODIFIER_ALT;
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001562 if (mods_lookup & (1 << keyboard->xkb_info->super_mod))
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001563 seat->modifier_state |= MODIFIER_SUPER;
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001564 if (mods_lookup & (1 << keyboard->xkb_info->shift_mod))
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001565 seat->modifier_state |= MODIFIER_SHIFT;
1566
1567 /* Finally, notify the compositor that LEDs have changed. */
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001568 if (xkb_state_led_index_is_active(keyboard->xkb_state.state,
1569 keyboard->xkb_info->num_led))
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001570 leds |= LED_NUM_LOCK;
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001571 if (xkb_state_led_index_is_active(keyboard->xkb_state.state,
1572 keyboard->xkb_info->caps_led))
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001573 leds |= LED_CAPS_LOCK;
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001574 if (xkb_state_led_index_is_active(keyboard->xkb_state.state,
1575 keyboard->xkb_info->scroll_led))
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001576 leds |= LED_SCROLL_LOCK;
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001577 if (leds != keyboard->xkb_state.leds && seat->led_update)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001578 seat->led_update(seat, leds);
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001579 keyboard->xkb_state.leds = leds;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001580
1581 if (changed) {
1582 grab->interface->modifiers(grab,
1583 serial,
1584 keyboard->modifiers.mods_depressed,
1585 keyboard->modifiers.mods_latched,
1586 keyboard->modifiers.mods_locked,
1587 keyboard->modifiers.group);
1588 }
1589}
1590
1591static void
1592update_modifier_state(struct weston_seat *seat, uint32_t serial, uint32_t key,
1593 enum wl_keyboard_key_state state)
1594{
Derek Foreman1281a362015-07-31 16:55:32 -05001595 struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001596 enum xkb_key_direction direction;
1597
Matt Roper01a92732013-06-24 16:52:44 +01001598 /* Keyboard modifiers don't exist in raw keyboard mode */
1599 if (!seat->compositor->use_xkbcommon)
1600 return;
1601
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001602 if (state == WL_KEYBOARD_KEY_STATE_PRESSED)
1603 direction = XKB_KEY_DOWN;
1604 else
1605 direction = XKB_KEY_UP;
1606
1607 /* Offset the keycode by 8, as the evdev XKB rules reflect X's
1608 * broken keycode system, which starts at 8. */
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001609 xkb_state_update_key(keyboard->xkb_state.state, key + 8, direction);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001610
1611 notify_modifiers(seat, serial);
1612}
Rui Matos65196bc2013-10-10 19:44:19 +02001613
1614static void
1615send_keymap(struct wl_resource *resource, struct weston_xkb_info *xkb_info)
1616{
1617 wl_keyboard_send_keymap(resource,
1618 WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1,
1619 xkb_info->keymap_fd,
1620 xkb_info->keymap_size);
1621}
1622
1623static void
1624send_modifiers(struct wl_resource *resource, uint32_t serial, struct weston_keyboard *keyboard)
1625{
1626 wl_keyboard_send_modifiers(resource, serial,
1627 keyboard->modifiers.mods_depressed,
1628 keyboard->modifiers.mods_latched,
1629 keyboard->modifiers.mods_locked,
1630 keyboard->modifiers.group);
1631}
1632
1633static struct weston_xkb_info *
1634weston_xkb_info_create(struct xkb_keymap *keymap);
Rui Matos65196bc2013-10-10 19:44:19 +02001635
1636static void
1637update_keymap(struct weston_seat *seat)
1638{
Derek Foreman1281a362015-07-31 16:55:32 -05001639 struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
Rui Matos65196bc2013-10-10 19:44:19 +02001640 struct wl_resource *resource;
1641 struct weston_xkb_info *xkb_info;
1642 struct xkb_state *state;
1643 xkb_mod_mask_t latched_mods;
1644 xkb_mod_mask_t locked_mods;
1645
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001646 xkb_info = weston_xkb_info_create(keyboard->pending_keymap);
Rui Matos65196bc2013-10-10 19:44:19 +02001647
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001648 xkb_keymap_unref(keyboard->pending_keymap);
1649 keyboard->pending_keymap = NULL;
Rui Matos65196bc2013-10-10 19:44:19 +02001650
1651 if (!xkb_info) {
1652 weston_log("failed to create XKB info\n");
1653 return;
1654 }
1655
1656 state = xkb_state_new(xkb_info->keymap);
1657 if (!state) {
1658 weston_log("failed to initialise XKB state\n");
1659 weston_xkb_info_destroy(xkb_info);
1660 return;
1661 }
1662
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001663 latched_mods = xkb_state_serialize_mods(keyboard->xkb_state.state,
1664 XKB_STATE_MODS_LATCHED);
1665 locked_mods = xkb_state_serialize_mods(keyboard->xkb_state.state,
1666 XKB_STATE_MODS_LOCKED);
Rui Matos65196bc2013-10-10 19:44:19 +02001667 xkb_state_update_mask(state,
1668 0, /* depressed */
1669 latched_mods,
1670 locked_mods,
1671 0, 0, 0);
1672
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001673 weston_xkb_info_destroy(keyboard->xkb_info);
1674 keyboard->xkb_info = xkb_info;
Rui Matos65196bc2013-10-10 19:44:19 +02001675
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001676 xkb_state_unref(keyboard->xkb_state.state);
1677 keyboard->xkb_state.state = state;
Rui Matos65196bc2013-10-10 19:44:19 +02001678
Derek Foremanbc91e542015-06-03 15:53:27 -05001679 wl_resource_for_each(resource, &keyboard->resource_list)
Rui Matos65196bc2013-10-10 19:44:19 +02001680 send_keymap(resource, xkb_info);
Derek Foremanbc91e542015-06-03 15:53:27 -05001681 wl_resource_for_each(resource, &keyboard->focus_resource_list)
Rui Matos65196bc2013-10-10 19:44:19 +02001682 send_keymap(resource, xkb_info);
1683
1684 notify_modifiers(seat, wl_display_next_serial(seat->compositor->wl_display));
1685
1686 if (!latched_mods && !locked_mods)
1687 return;
1688
Derek Foremanbc91e542015-06-03 15:53:27 -05001689 wl_resource_for_each(resource, &keyboard->resource_list)
1690 send_modifiers(resource, wl_display_get_serial(seat->compositor->wl_display), keyboard);
1691 wl_resource_for_each(resource, &keyboard->focus_resource_list)
1692 send_modifiers(resource, wl_display_get_serial(seat->compositor->wl_display), keyboard);
Rui Matos65196bc2013-10-10 19:44:19 +02001693}
Rob Bradford382ff462013-06-24 16:52:45 +01001694#else
1695WL_EXPORT void
1696notify_modifiers(struct weston_seat *seat, uint32_t serial)
1697{
1698}
1699
1700static void
1701update_modifier_state(struct weston_seat *seat, uint32_t serial, uint32_t key,
1702 enum wl_keyboard_key_state state)
1703{
1704}
Rui Matos65196bc2013-10-10 19:44:19 +02001705
1706static void
1707update_keymap(struct weston_seat *seat)
1708{
1709}
Rob Bradford382ff462013-06-24 16:52:45 +01001710#endif
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001711
1712WL_EXPORT void
1713notify_key(struct weston_seat *seat, uint32_t time, uint32_t key,
1714 enum wl_keyboard_key_state state,
1715 enum weston_key_state_update update_state)
1716{
1717 struct weston_compositor *compositor = seat->compositor;
Derek Foreman1281a362015-07-31 16:55:32 -05001718 struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001719 struct weston_keyboard_grab *grab = keyboard->grab;
Pekka Paalanen86b53962014-11-19 13:43:32 +02001720 uint32_t *k, *end;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001721
1722 if (state == WL_KEYBOARD_KEY_STATE_PRESSED) {
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001723 weston_compositor_idle_inhibit(compositor);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001724 } else {
1725 weston_compositor_idle_release(compositor);
1726 }
1727
Pekka Paalanen86b53962014-11-19 13:43:32 +02001728 end = keyboard->keys.data + keyboard->keys.size;
1729 for (k = keyboard->keys.data; k < end; k++) {
1730 if (*k == key) {
1731 /* Ignore server-generated repeats. */
1732 if (state == WL_KEYBOARD_KEY_STATE_PRESSED)
1733 return;
1734 *k = *--end;
1735 }
1736 }
1737 keyboard->keys.size = (void *) end - keyboard->keys.data;
1738 if (state == WL_KEYBOARD_KEY_STATE_PRESSED) {
1739 k = wl_array_add(&keyboard->keys, sizeof *k);
1740 *k = key;
1741 }
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001742
1743 if (grab == &keyboard->default_grab ||
1744 grab == &keyboard->input_method_grab) {
Derek Foreman99a6a2d2015-07-15 13:00:43 -05001745 weston_compositor_run_key_binding(compositor, keyboard, time,
1746 key, state);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001747 grab = keyboard->grab;
1748 }
1749
1750 grab->interface->key(grab, time, key, state);
1751
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001752 if (keyboard->pending_keymap &&
Pekka Paalanen86b53962014-11-19 13:43:32 +02001753 keyboard->keys.size == 0)
Rui Matos65196bc2013-10-10 19:44:19 +02001754 update_keymap(seat);
1755
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001756 if (update_state == STATE_UPDATE_AUTOMATIC) {
1757 update_modifier_state(seat,
1758 wl_display_get_serial(compositor->wl_display),
1759 key,
1760 state);
1761 }
Giulio Camuffob6ddf6c2015-02-06 19:06:54 +02001762
1763 if (state == WL_KEYBOARD_KEY_STATE_PRESSED) {
1764 keyboard->grab_serial =
1765 wl_display_get_serial(compositor->wl_display);
1766 keyboard->grab_time = time;
1767 keyboard->grab_key = key;
1768 }
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001769}
1770
1771WL_EXPORT void
1772notify_pointer_focus(struct weston_seat *seat, struct weston_output *output,
Giulio Camuffo90a6fc62016-03-22 17:44:54 +02001773 double x, double y)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001774{
Derek Foreman1281a362015-07-31 16:55:32 -05001775 struct weston_pointer *pointer = weston_seat_get_pointer(seat);
1776
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001777 if (output) {
Giulio Camuffo90a6fc62016-03-22 17:44:54 +02001778 weston_pointer_move_to(pointer,
1779 wl_fixed_from_double(x),
1780 wl_fixed_from_double(y));
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001781 } else {
Kristian Høgsberg02bbabb2013-05-06 22:15:05 -04001782 /* FIXME: We should call weston_pointer_set_focus(seat,
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001783 * NULL) here, but somehow that breaks re-entry... */
1784 }
1785}
1786
1787static void
1788destroy_device_saved_kbd_focus(struct wl_listener *listener, void *data)
1789{
1790 struct weston_seat *ws;
1791
1792 ws = container_of(listener, struct weston_seat,
1793 saved_kbd_focus_listener);
1794
1795 ws->saved_kbd_focus = NULL;
1796}
1797
1798WL_EXPORT void
1799notify_keyboard_focus_in(struct weston_seat *seat, struct wl_array *keys,
1800 enum weston_key_state_update update_state)
1801{
1802 struct weston_compositor *compositor = seat->compositor;
Derek Foreman1281a362015-07-31 16:55:32 -05001803 struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
Kristian Høgsbergfe7aa902013-05-08 09:54:37 -04001804 struct weston_surface *surface;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001805 uint32_t *k, serial;
1806
1807 serial = wl_display_next_serial(compositor->wl_display);
1808 wl_array_copy(&keyboard->keys, keys);
1809 wl_array_for_each(k, &keyboard->keys) {
1810 weston_compositor_idle_inhibit(compositor);
1811 if (update_state == STATE_UPDATE_AUTOMATIC)
1812 update_modifier_state(seat, serial, *k,
1813 WL_KEYBOARD_KEY_STATE_PRESSED);
1814 }
1815
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001816 surface = seat->saved_kbd_focus;
1817
1818 if (surface) {
1819 wl_list_remove(&seat->saved_kbd_focus_listener.link);
1820 weston_keyboard_set_focus(keyboard, surface);
1821 seat->saved_kbd_focus = NULL;
1822 }
1823}
1824
1825WL_EXPORT void
1826notify_keyboard_focus_out(struct weston_seat *seat)
1827{
1828 struct weston_compositor *compositor = seat->compositor;
Derek Foreman1281a362015-07-31 16:55:32 -05001829 struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
1830 struct weston_pointer *pointer = weston_seat_get_pointer(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001831 uint32_t *k, serial;
1832
1833 serial = wl_display_next_serial(compositor->wl_display);
1834 wl_array_for_each(k, &keyboard->keys) {
1835 weston_compositor_idle_release(compositor);
1836 update_modifier_state(seat, serial, *k,
1837 WL_KEYBOARD_KEY_STATE_RELEASED);
1838 }
1839
1840 seat->modifier_state = 0;
1841
1842 if (keyboard->focus) {
1843 seat->saved_kbd_focus = keyboard->focus;
1844 seat->saved_kbd_focus_listener.notify =
1845 destroy_device_saved_kbd_focus;
Jason Ekstrand26ed73c2013-06-06 22:34:41 -05001846 wl_signal_add(&keyboard->focus->destroy_signal,
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001847 &seat->saved_kbd_focus_listener);
1848 }
1849
1850 weston_keyboard_set_focus(keyboard, NULL);
Jonas Ådahl1ea343e2013-10-25 23:18:05 +02001851 weston_keyboard_cancel_grab(keyboard);
Derek Foreman1281a362015-07-31 16:55:32 -05001852 if (pointer)
1853 weston_pointer_cancel_grab(pointer);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001854}
1855
Michael Fua2bb7912013-07-23 15:51:06 +08001856WL_EXPORT void
Derek Foreman4c93c082015-04-30 16:45:41 -05001857weston_touch_set_focus(struct weston_touch *touch, struct weston_view *view)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001858{
Neil Roberts96d790e2013-09-19 17:32:00 +01001859 struct wl_list *focus_resource_list;
1860
Derek Foreman4c93c082015-04-30 16:45:41 -05001861 focus_resource_list = &touch->focus_resource_list;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001862
Derek Foreman4c93c082015-04-30 16:45:41 -05001863 if (view && touch->focus &&
1864 touch->focus->surface == view->surface) {
1865 touch->focus = view;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001866 return;
Jason Ekstranda7af7042013-10-12 22:38:11 -05001867 }
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001868
Derek Foreman4c93c082015-04-30 16:45:41 -05001869 wl_list_remove(&touch->focus_resource_listener.link);
1870 wl_list_init(&touch->focus_resource_listener.link);
1871 wl_list_remove(&touch->focus_view_listener.link);
1872 wl_list_init(&touch->focus_view_listener.link);
Giulio Camuffo576fe2a2013-11-20 18:00:24 +01001873
Neil Roberts96d790e2013-09-19 17:32:00 +01001874 if (!wl_list_empty(focus_resource_list)) {
Derek Foreman4c93c082015-04-30 16:45:41 -05001875 move_resources(&touch->resource_list,
Neil Roberts96d790e2013-09-19 17:32:00 +01001876 focus_resource_list);
1877 }
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001878
Jason Ekstranda7af7042013-10-12 22:38:11 -05001879 if (view) {
Derek Foreman362656b2014-09-04 10:23:05 -05001880 struct wl_client *surface_client;
1881
1882 if (!view->surface->resource) {
Derek Foreman4c93c082015-04-30 16:45:41 -05001883 touch->focus = NULL;
Derek Foreman362656b2014-09-04 10:23:05 -05001884 return;
1885 }
1886
1887 surface_client = wl_resource_get_client(view->surface->resource);
Neil Roberts96d790e2013-09-19 17:32:00 +01001888 move_resources_for_client(focus_resource_list,
Derek Foreman4c93c082015-04-30 16:45:41 -05001889 &touch->resource_list,
Neil Roberts96d790e2013-09-19 17:32:00 +01001890 surface_client);
Giulio Camuffo576fe2a2013-11-20 18:00:24 +01001891 wl_resource_add_destroy_listener(view->surface->resource,
Derek Foreman4c93c082015-04-30 16:45:41 -05001892 &touch->focus_resource_listener);
1893 wl_signal_add(&view->destroy_signal, &touch->focus_view_listener);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001894 }
Derek Foreman4c93c082015-04-30 16:45:41 -05001895 touch->focus = view;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001896}
1897
1898/**
1899 * notify_touch - emulates button touches and notifies surfaces accordingly.
1900 *
1901 * It assumes always the correct cycle sequence until it gets here: touch_down
1902 * → touch_update → ... → touch_update → touch_end. The driver is responsible
1903 * for sending along such order.
1904 *
1905 */
1906WL_EXPORT void
1907notify_touch(struct weston_seat *seat, uint32_t time, int touch_id,
Giulio Camuffo90a6fc62016-03-22 17:44:54 +02001908 double double_x, double double_y, int touch_type)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001909{
1910 struct weston_compositor *ec = seat->compositor;
Derek Foreman1281a362015-07-31 16:55:32 -05001911 struct weston_touch *touch = weston_seat_get_touch(seat);
Kristian Høgsberge329f362013-05-06 22:19:57 -04001912 struct weston_touch_grab *grab = touch->grab;
Jason Ekstranda7af7042013-10-12 22:38:11 -05001913 struct weston_view *ev;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001914 wl_fixed_t sx, sy;
Giulio Camuffo90a6fc62016-03-22 17:44:54 +02001915 wl_fixed_t x = wl_fixed_from_double(double_x);
1916 wl_fixed_t y = wl_fixed_from_double(double_y);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001917
1918 /* Update grab's global coordinates. */
Neil Roberts306fe082013-10-03 16:43:06 +01001919 if (touch_id == touch->grab_touch_id && touch_type != WL_TOUCH_UP) {
1920 touch->grab_x = x;
1921 touch->grab_y = y;
1922 }
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001923
1924 switch (touch_type) {
1925 case WL_TOUCH_DOWN:
1926 weston_compositor_idle_inhibit(ec);
1927
Jonas Ådahl9484b692013-12-02 22:05:03 +01001928 touch->num_tp++;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001929
Jason Ekstranda7af7042013-10-12 22:38:11 -05001930 /* the first finger down picks the view, and all further go
1931 * to that view for the remainder of the touch session i.e.
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001932 * until all touch points are up again. */
Jonas Ådahl9484b692013-12-02 22:05:03 +01001933 if (touch->num_tp == 1) {
Jason Ekstranda7af7042013-10-12 22:38:11 -05001934 ev = weston_compositor_pick_view(ec, x, y, &sx, &sy);
Derek Foreman4c93c082015-04-30 16:45:41 -05001935 weston_touch_set_focus(touch, ev);
Giulio Camuffo61ed7b62015-07-08 11:55:28 +03001936 } else if (!touch->focus) {
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001937 /* Unexpected condition: We have non-initial touch but
1938 * there is no focused surface.
1939 */
Chris Michael3f607d32015-10-07 11:59:49 -04001940 weston_log("touch event received with %d points down "
Jonas Ådahl9484b692013-12-02 22:05:03 +01001941 "but no surface focused\n", touch->num_tp);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001942 return;
1943 }
1944
Derek Foreman99a6a2d2015-07-15 13:00:43 -05001945 weston_compositor_run_touch_binding(ec, touch,
Kristian Høgsbergc8964012014-02-05 14:25:18 -08001946 time, touch_type);
1947
Giulio Camuffo61ed7b62015-07-08 11:55:28 +03001948 grab->interface->down(grab, time, touch_id, x, y);
Jonas Ådahl9484b692013-12-02 22:05:03 +01001949 if (touch->num_tp == 1) {
Rusty Lynchf1407ff2013-08-08 21:13:57 -07001950 touch->grab_serial =
1951 wl_display_get_serial(ec->wl_display);
Neil Roberts306fe082013-10-03 16:43:06 +01001952 touch->grab_touch_id = touch_id;
Rusty Lynchf1407ff2013-08-08 21:13:57 -07001953 touch->grab_time = time;
1954 touch->grab_x = x;
1955 touch->grab_y = y;
1956 }
1957
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001958 break;
1959 case WL_TOUCH_MOTION:
Jason Ekstranda7af7042013-10-12 22:38:11 -05001960 ev = touch->focus;
1961 if (!ev)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001962 break;
1963
Giulio Camuffo61ed7b62015-07-08 11:55:28 +03001964 grab->interface->motion(grab, time, touch_id, x, y);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001965 break;
1966 case WL_TOUCH_UP:
Kristian Høgsberga30e29a2014-01-08 22:29:20 -08001967 if (touch->num_tp == 0) {
1968 /* This can happen if we start out with one or
1969 * more fingers on the touch screen, in which
1970 * case we didn't get the corresponding down
1971 * event. */
1972 weston_log("unmatched touch up event\n");
1973 break;
1974 }
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001975 weston_compositor_idle_release(ec);
Jonas Ådahl9484b692013-12-02 22:05:03 +01001976 touch->num_tp--;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001977
1978 grab->interface->up(grab, time, touch_id);
Jonas Ådahl9484b692013-12-02 22:05:03 +01001979 if (touch->num_tp == 0)
Derek Foreman4c93c082015-04-30 16:45:41 -05001980 weston_touch_set_focus(touch, NULL);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001981 break;
1982 }
1983}
1984
Jonas Ådahl1679f232014-04-12 09:39:51 +02001985WL_EXPORT void
1986notify_touch_frame(struct weston_seat *seat)
1987{
Derek Foreman1281a362015-07-31 16:55:32 -05001988 struct weston_touch *touch = weston_seat_get_touch(seat);
Jonas Ådahl1679f232014-04-12 09:39:51 +02001989 struct weston_touch_grab *grab = touch->grab;
1990
1991 grab->interface->frame(grab);
1992}
1993
Derek Foreman3cc004a2015-11-06 15:56:09 -06001994WL_EXPORT void
1995notify_touch_cancel(struct weston_seat *seat)
1996{
1997 struct weston_touch *touch = weston_seat_get_touch(seat);
1998 struct weston_touch_grab *grab = touch->grab;
1999
2000 grab->interface->cancel(grab);
2001}
2002
Pekka Paalanen8274d902014-08-06 19:36:51 +03002003static int
2004pointer_cursor_surface_get_label(struct weston_surface *surface,
2005 char *buf, size_t len)
2006{
2007 return snprintf(buf, len, "cursor");
2008}
2009
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002010static void
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002011pointer_cursor_surface_configure(struct weston_surface *es,
Jason Ekstrand918f2dd2013-12-02 21:01:53 -06002012 int32_t dx, int32_t dy)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002013{
Kristian Høgsberg195b8692013-05-08 15:02:05 -04002014 struct weston_pointer *pointer = es->configure_private;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002015 int x, y;
2016
Jason Ekstrand918f2dd2013-12-02 21:01:53 -06002017 if (es->width == 0)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002018 return;
2019
Jason Ekstranda7af7042013-10-12 22:38:11 -05002020 assert(es == pointer->sprite->surface);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002021
Kristian Høgsberg195b8692013-05-08 15:02:05 -04002022 pointer->hotspot_x -= dx;
2023 pointer->hotspot_y -= dy;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002024
Kristian Høgsberg195b8692013-05-08 15:02:05 -04002025 x = wl_fixed_to_int(pointer->x) - pointer->hotspot_x;
2026 y = wl_fixed_to_int(pointer->y) - pointer->hotspot_y;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002027
Jason Ekstrand918f2dd2013-12-02 21:01:53 -06002028 weston_view_set_position(pointer->sprite, x, y);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002029
2030 empty_region(&es->pending.input);
Ander Conselvan de Oliveira23900f72014-01-31 16:07:51 +02002031 empty_region(&es->input);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002032
2033 if (!weston_surface_is_mapped(es)) {
Giulio Camuffo412e6a52014-07-09 22:12:56 +03002034 weston_layer_entry_insert(&es->compositor->cursor_layer.view_list,
2035 &pointer->sprite->layer_link);
Jason Ekstranda7af7042013-10-12 22:38:11 -05002036 weston_view_update_transform(pointer->sprite);
Armin Krezovićf8486c32016-06-30 06:04:28 +02002037 es->is_mapped = true;
2038 pointer->sprite->is_mapped = true;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002039 }
2040}
2041
2042static void
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002043pointer_set_cursor(struct wl_client *client, struct wl_resource *resource,
2044 uint32_t serial, struct wl_resource *surface_resource,
2045 int32_t x, int32_t y)
2046{
Jason Ekstrand44a38632013-06-14 10:08:00 -05002047 struct weston_pointer *pointer = wl_resource_get_user_data(resource);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002048 struct weston_surface *surface = NULL;
2049
2050 if (surface_resource)
Jason Ekstrand0f2ef7e2013-06-14 10:07:53 -05002051 surface = wl_resource_get_user_data(surface_resource);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002052
Kristian Høgsberg195b8692013-05-08 15:02:05 -04002053 if (pointer->focus == NULL)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002054 return;
Jason Ekstranda7af7042013-10-12 22:38:11 -05002055 /* pointer->focus->surface->resource can be NULL. Surfaces like the
Giulio Camuffo1fd4b012013-06-20 18:13:07 +02002056 black_surface used in shell.c for fullscreen don't have
2057 a resource, but can still have focus */
Jason Ekstranda7af7042013-10-12 22:38:11 -05002058 if (pointer->focus->surface->resource == NULL)
Giulio Camuffo1fd4b012013-06-20 18:13:07 +02002059 return;
Jason Ekstranda7af7042013-10-12 22:38:11 -05002060 if (wl_resource_get_client(pointer->focus->surface->resource) != client)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002061 return;
Kristian Høgsberg195b8692013-05-08 15:02:05 -04002062 if (pointer->focus_serial - serial > UINT32_MAX / 2)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002063 return;
2064
Derek Foreman4e53c532015-03-23 10:55:32 -05002065 if (!surface) {
2066 if (pointer->sprite)
2067 pointer_unmap_sprite(pointer);
2068 return;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002069 }
2070
Jonas Ådahlb4070242015-03-18 15:08:03 +08002071 if (pointer->sprite && pointer->sprite->surface == surface &&
2072 pointer->hotspot_x == x && pointer->hotspot_y == y)
2073 return;
2074
Derek Foreman4e53c532015-03-23 10:55:32 -05002075 if (!pointer->sprite || pointer->sprite->surface != surface) {
2076 if (weston_surface_set_role(surface, "wl_pointer-cursor",
2077 resource,
2078 WL_POINTER_ERROR_ROLE) < 0)
2079 return;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002080
Derek Foreman4e53c532015-03-23 10:55:32 -05002081 if (pointer->sprite)
2082 pointer_unmap_sprite(pointer);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002083
Derek Foreman4e53c532015-03-23 10:55:32 -05002084 wl_signal_add(&surface->destroy_signal,
2085 &pointer->sprite_destroy_listener);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002086
Derek Foreman4e53c532015-03-23 10:55:32 -05002087 surface->configure = pointer_cursor_surface_configure;
2088 surface->configure_private = pointer;
2089 weston_surface_set_label_func(surface,
2090 pointer_cursor_surface_get_label);
2091 pointer->sprite = weston_view_create(surface);
2092 }
2093
Kristian Høgsberg195b8692013-05-08 15:02:05 -04002094 pointer->hotspot_x = x;
2095 pointer->hotspot_y = y;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002096
Jonas Ådahl16fe4dc2014-09-08 19:33:41 +02002097 if (surface->buffer_ref.buffer) {
Jason Ekstrand918f2dd2013-12-02 21:01:53 -06002098 pointer_cursor_surface_configure(surface, 0, 0);
Jonas Ådahl16fe4dc2014-09-08 19:33:41 +02002099 weston_view_schedule_repaint(pointer->sprite);
2100 }
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002101}
2102
Kristian Høgsberg69e25fc2013-08-13 20:11:02 +01002103static void
2104pointer_release(struct wl_client *client, struct wl_resource *resource)
2105{
2106 wl_resource_destroy(resource);
2107}
2108
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002109static const struct wl_pointer_interface pointer_interface = {
Kristian Høgsberg69e25fc2013-08-13 20:11:02 +01002110 pointer_set_cursor,
2111 pointer_release
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002112};
2113
2114static void
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002115seat_get_pointer(struct wl_client *client, struct wl_resource *resource,
2116 uint32_t id)
2117{
Jason Ekstrand44a38632013-06-14 10:08:00 -05002118 struct weston_seat *seat = wl_resource_get_user_data(resource);
Derek Foreman1281a362015-07-31 16:55:32 -05002119 /* We use the pointer_state directly, which means we'll
2120 * give a wl_pointer if the seat has ever had one - even though
2121 * the spec explicitly states that this request only takes effect
2122 * if the seat has the pointer capability.
2123 *
2124 * This prevents a race between the compositor sending new
2125 * capabilities and the client trying to use the old ones.
2126 */
2127 struct weston_pointer *pointer = seat->pointer_state;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002128 struct wl_resource *cr;
Jonas Ådahl2cbf2932015-07-22 12:05:38 +08002129 struct weston_pointer_client *pointer_client;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002130
Derek Foreman1281a362015-07-31 16:55:32 -05002131 if (!pointer)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002132 return;
2133
Jason Ekstranda85118c2013-06-27 20:17:02 -05002134 cr = wl_resource_create(client, &wl_pointer_interface,
2135 wl_resource_get_version(resource), id);
Kristian Høgsberg0ff79082013-08-06 16:46:25 -07002136 if (cr == NULL) {
2137 wl_client_post_no_memory(client);
2138 return;
2139 }
2140
Jonas Ådahl2cbf2932015-07-22 12:05:38 +08002141 pointer_client = weston_pointer_ensure_pointer_client(pointer, client);
2142 if (!pointer_client) {
2143 wl_client_post_no_memory(client);
2144 return;
2145 }
2146
2147 wl_list_insert(&pointer_client->pointer_resources,
2148 wl_resource_get_link(cr));
Derek Foreman1281a362015-07-31 16:55:32 -05002149 wl_resource_set_implementation(cr, &pointer_interface, pointer,
Jonas Ådahl2cbf2932015-07-22 12:05:38 +08002150 unbind_pointer_client_resource);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002151
Derek Foreman1281a362015-07-31 16:55:32 -05002152 if (pointer->focus && pointer->focus->surface->resource &&
2153 wl_resource_get_client(pointer->focus->surface->resource) == client) {
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002154 wl_fixed_t sx, sy;
2155
Derek Foreman1281a362015-07-31 16:55:32 -05002156 weston_view_from_global_fixed(pointer->focus,
2157 pointer->x,
2158 pointer->y,
Jason Ekstranda7af7042013-10-12 22:38:11 -05002159 &sx, &sy);
Neil Roberts96d790e2013-09-19 17:32:00 +01002160
Neil Roberts96d790e2013-09-19 17:32:00 +01002161 wl_pointer_send_enter(cr,
Derek Foreman1281a362015-07-31 16:55:32 -05002162 pointer->focus_serial,
2163 pointer->focus->surface->resource,
Neil Roberts96d790e2013-09-19 17:32:00 +01002164 sx, sy);
Peter Hutterer87743e92016-01-18 16:38:22 +10002165 pointer_send_frame(cr);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002166 }
2167}
2168
2169static void
Kristian Høgsberg69e25fc2013-08-13 20:11:02 +01002170keyboard_release(struct wl_client *client, struct wl_resource *resource)
2171{
2172 wl_resource_destroy(resource);
2173}
2174
2175static const struct wl_keyboard_interface keyboard_interface = {
2176 keyboard_release
2177};
2178
Derek Foreman280e7dd2014-10-03 13:13:42 -05002179static bool
Neil Roberts96d790e2013-09-19 17:32:00 +01002180should_send_modifiers_to_client(struct weston_seat *seat,
2181 struct wl_client *client)
2182{
Derek Foreman1281a362015-07-31 16:55:32 -05002183 struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
2184 struct weston_pointer *pointer = weston_seat_get_pointer(seat);
2185
2186 if (keyboard &&
2187 keyboard->focus &&
2188 keyboard->focus->resource &&
2189 wl_resource_get_client(keyboard->focus->resource) == client)
Derek Foreman280e7dd2014-10-03 13:13:42 -05002190 return true;
Neil Roberts96d790e2013-09-19 17:32:00 +01002191
Derek Foreman1281a362015-07-31 16:55:32 -05002192 if (pointer &&
2193 pointer->focus &&
2194 pointer->focus->surface->resource &&
2195 wl_resource_get_client(pointer->focus->surface->resource) == client)
Derek Foreman280e7dd2014-10-03 13:13:42 -05002196 return true;
Neil Roberts96d790e2013-09-19 17:32:00 +01002197
Derek Foreman280e7dd2014-10-03 13:13:42 -05002198 return false;
Neil Roberts96d790e2013-09-19 17:32:00 +01002199}
2200
Kristian Høgsberg69e25fc2013-08-13 20:11:02 +01002201static void
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002202seat_get_keyboard(struct wl_client *client, struct wl_resource *resource,
2203 uint32_t id)
2204{
Jason Ekstrand44a38632013-06-14 10:08:00 -05002205 struct weston_seat *seat = wl_resource_get_user_data(resource);
Derek Foreman1281a362015-07-31 16:55:32 -05002206 /* We use the keyboard_state directly, which means we'll
2207 * give a wl_keyboard if the seat has ever had one - even though
2208 * the spec explicitly states that this request only takes effect
2209 * if the seat has the keyboard capability.
2210 *
2211 * This prevents a race between the compositor sending new
2212 * capabilities and the client trying to use the old ones.
2213 */
2214 struct weston_keyboard *keyboard = seat->keyboard_state;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002215 struct wl_resource *cr;
2216
Derek Foreman345c9f32015-06-03 15:53:28 -05002217 if (!keyboard)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002218 return;
2219
Jason Ekstranda85118c2013-06-27 20:17:02 -05002220 cr = wl_resource_create(client, &wl_keyboard_interface,
2221 wl_resource_get_version(resource), id);
Kristian Høgsberg0ff79082013-08-06 16:46:25 -07002222 if (cr == NULL) {
2223 wl_client_post_no_memory(client);
2224 return;
2225 }
2226
Neil Roberts96d790e2013-09-19 17:32:00 +01002227 /* May be moved to focused list later by either
2228 * weston_keyboard_set_focus or directly if this client is already
2229 * focused */
Derek Foreman345c9f32015-06-03 15:53:28 -05002230 wl_list_insert(&keyboard->resource_list, wl_resource_get_link(cr));
Kristian Høgsberg69e25fc2013-08-13 20:11:02 +01002231 wl_resource_set_implementation(cr, &keyboard_interface,
2232 seat, unbind_resource);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002233
Jonny Lamb66a41a02014-08-12 14:58:25 +02002234 if (wl_resource_get_version(cr) >= WL_KEYBOARD_REPEAT_INFO_SINCE_VERSION) {
2235 wl_keyboard_send_repeat_info(cr,
2236 seat->compositor->kb_repeat_rate,
2237 seat->compositor->kb_repeat_delay);
2238 }
Jasper St. Pierred8c6aeb2014-08-04 13:43:24 -04002239
Matt Roper01a92732013-06-24 16:52:44 +01002240 if (seat->compositor->use_xkbcommon) {
2241 wl_keyboard_send_keymap(cr, WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1,
Jonas Ådahl7395ea02013-12-03 09:14:26 +01002242 keyboard->xkb_info->keymap_fd,
2243 keyboard->xkb_info->keymap_size);
Matt Roper01a92732013-06-24 16:52:44 +01002244 } else {
2245 int null_fd = open("/dev/null", O_RDONLY);
2246 wl_keyboard_send_keymap(cr, WL_KEYBOARD_KEYMAP_FORMAT_NO_KEYMAP,
2247 null_fd,
2248 0);
2249 close(null_fd);
2250 }
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002251
Neil Roberts96d790e2013-09-19 17:32:00 +01002252 if (should_send_modifiers_to_client(seat, client)) {
Derek Foreman345c9f32015-06-03 15:53:28 -05002253 send_modifiers_to_resource(keyboard,
Neil Roberts96d790e2013-09-19 17:32:00 +01002254 cr,
Derek Foreman345c9f32015-06-03 15:53:28 -05002255 keyboard->focus_serial);
Neil Roberts96d790e2013-09-19 17:32:00 +01002256 }
2257
Derek Foreman345c9f32015-06-03 15:53:28 -05002258 if (keyboard->focus && keyboard->focus->resource &&
2259 wl_resource_get_client(keyboard->focus->resource) == client) {
Neil Roberts96d790e2013-09-19 17:32:00 +01002260 struct weston_surface *surface =
Derek Foreman345c9f32015-06-03 15:53:28 -05002261 (struct weston_surface *)keyboard->focus;
Neil Roberts96d790e2013-09-19 17:32:00 +01002262
2263 wl_list_remove(wl_resource_get_link(cr));
Derek Foreman345c9f32015-06-03 15:53:28 -05002264 wl_list_insert(&keyboard->focus_resource_list,
Neil Roberts96d790e2013-09-19 17:32:00 +01002265 wl_resource_get_link(cr));
2266 wl_keyboard_send_enter(cr,
Derek Foreman345c9f32015-06-03 15:53:28 -05002267 keyboard->focus_serial,
Neil Roberts96d790e2013-09-19 17:32:00 +01002268 surface->resource,
Derek Foreman345c9f32015-06-03 15:53:28 -05002269 &keyboard->keys);
Neil Roberts96d790e2013-09-19 17:32:00 +01002270
2271 /* If this is the first keyboard resource for this
2272 * client... */
Derek Foreman345c9f32015-06-03 15:53:28 -05002273 if (keyboard->focus_resource_list.prev ==
Neil Roberts96d790e2013-09-19 17:32:00 +01002274 wl_resource_get_link(cr))
2275 wl_data_device_set_keyboard_focus(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002276 }
2277}
2278
2279static void
Kristian Høgsberg69e25fc2013-08-13 20:11:02 +01002280touch_release(struct wl_client *client, struct wl_resource *resource)
2281{
2282 wl_resource_destroy(resource);
2283}
2284
2285static const struct wl_touch_interface touch_interface = {
2286 touch_release
2287};
2288
2289static void
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002290seat_get_touch(struct wl_client *client, struct wl_resource *resource,
2291 uint32_t id)
2292{
Jason Ekstrand44a38632013-06-14 10:08:00 -05002293 struct weston_seat *seat = wl_resource_get_user_data(resource);
Derek Foreman1281a362015-07-31 16:55:32 -05002294 /* We use the touch_state directly, which means we'll
2295 * give a wl_touch if the seat has ever had one - even though
2296 * the spec explicitly states that this request only takes effect
2297 * if the seat has the touch capability.
2298 *
2299 * This prevents a race between the compositor sending new
2300 * capabilities and the client trying to use the old ones.
2301 */
2302 struct weston_touch *touch = seat->touch_state;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002303 struct wl_resource *cr;
2304
Derek Foreman1281a362015-07-31 16:55:32 -05002305 if (!touch)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002306 return;
2307
Jason Ekstranda85118c2013-06-27 20:17:02 -05002308 cr = wl_resource_create(client, &wl_touch_interface,
2309 wl_resource_get_version(resource), id);
Kristian Høgsberg0ff79082013-08-06 16:46:25 -07002310 if (cr == NULL) {
2311 wl_client_post_no_memory(client);
2312 return;
2313 }
2314
Derek Foreman1281a362015-07-31 16:55:32 -05002315 if (touch->focus &&
2316 wl_resource_get_client(touch->focus->surface->resource) == client) {
Chokshi, Mituld6697142015-10-09 08:28:47 +00002317 wl_list_insert(&touch->focus_resource_list,
Neil Roberts96d790e2013-09-19 17:32:00 +01002318 wl_resource_get_link(cr));
2319 } else {
Chokshi, Mituld6697142015-10-09 08:28:47 +00002320 wl_list_insert(&touch->resource_list,
Neil Roberts96d790e2013-09-19 17:32:00 +01002321 wl_resource_get_link(cr));
2322 }
Kristian Høgsberg69e25fc2013-08-13 20:11:02 +01002323 wl_resource_set_implementation(cr, &touch_interface,
2324 seat, unbind_resource);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002325}
2326
Quentin Glidicaab1d362016-03-13 17:49:08 +01002327static void
2328seat_release(struct wl_client *client, struct wl_resource *resource)
2329{
2330 wl_resource_destroy(resource);
2331}
2332
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002333static const struct wl_seat_interface seat_interface = {
2334 seat_get_pointer,
2335 seat_get_keyboard,
2336 seat_get_touch,
Quentin Glidicaab1d362016-03-13 17:49:08 +01002337 seat_release,
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002338};
2339
2340static void
2341bind_seat(struct wl_client *client, void *data, uint32_t version, uint32_t id)
2342{
Kristian Høgsberge3148752013-05-06 23:19:49 -04002343 struct weston_seat *seat = data;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002344 struct wl_resource *resource;
2345 enum wl_seat_capability caps = 0;
2346
Jason Ekstranda85118c2013-06-27 20:17:02 -05002347 resource = wl_resource_create(client,
Derek Foreman1909c102015-11-26 14:17:47 -06002348 &wl_seat_interface, version, id);
Jason Ekstrand44a38632013-06-14 10:08:00 -05002349 wl_list_insert(&seat->base_resource_list, wl_resource_get_link(resource));
Jason Ekstranda85118c2013-06-27 20:17:02 -05002350 wl_resource_set_implementation(resource, &seat_interface, data,
2351 unbind_resource);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002352
Derek Foreman1281a362015-07-31 16:55:32 -05002353 if (weston_seat_get_pointer(seat))
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002354 caps |= WL_SEAT_CAPABILITY_POINTER;
Derek Foreman1281a362015-07-31 16:55:32 -05002355 if (weston_seat_get_keyboard(seat))
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002356 caps |= WL_SEAT_CAPABILITY_KEYBOARD;
Derek Foreman1281a362015-07-31 16:55:32 -05002357 if (weston_seat_get_touch(seat))
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002358 caps |= WL_SEAT_CAPABILITY_TOUCH;
2359
2360 wl_seat_send_capabilities(resource, caps);
Jasper St. Pierre0013a292014-08-07 16:43:11 -04002361 if (version >= WL_SEAT_NAME_SINCE_VERSION)
Rob Bradforde445ae62013-05-31 18:09:51 +01002362 wl_seat_send_name(resource, seat->seat_name);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002363}
2364
Jonas Ådahl30d61d82014-10-22 21:21:17 +02002365static void
2366relative_pointer_destroy(struct wl_client *client,
2367 struct wl_resource *resource)
2368{
2369 wl_resource_destroy(resource);
2370}
2371
2372static const struct zwp_relative_pointer_v1_interface relative_pointer_interface = {
2373 relative_pointer_destroy
2374};
2375
2376static void
2377relative_pointer_manager_destroy(struct wl_client *client,
2378 struct wl_resource *resource)
2379{
2380 wl_resource_destroy(resource);
2381}
2382
2383static void
2384relative_pointer_manager_get_relative_pointer(struct wl_client *client,
2385 struct wl_resource *resource,
2386 uint32_t id,
2387 struct wl_resource *pointer_resource)
2388{
2389 struct weston_pointer *pointer =
2390 wl_resource_get_user_data(pointer_resource);
2391 struct weston_pointer_client *pointer_client;
2392 struct wl_resource *cr;
2393
2394 cr = wl_resource_create(client, &zwp_relative_pointer_v1_interface,
2395 wl_resource_get_version(resource), id);
2396 if (cr == NULL) {
2397 wl_client_post_no_memory(client);
2398 return;
2399 }
2400
2401 pointer_client = weston_pointer_ensure_pointer_client(pointer, client);
2402 if (!pointer_client) {
2403 wl_client_post_no_memory(client);
2404 return;
2405 }
2406
2407 wl_list_insert(&pointer_client->relative_pointer_resources,
2408 wl_resource_get_link(cr));
2409 wl_resource_set_implementation(cr, &relative_pointer_interface,
2410 pointer,
2411 unbind_pointer_client_resource);
2412}
2413
2414static const struct zwp_relative_pointer_manager_v1_interface relative_pointer_manager = {
2415 relative_pointer_manager_destroy,
2416 relative_pointer_manager_get_relative_pointer,
2417};
2418
2419static void
2420bind_relative_pointer_manager(struct wl_client *client, void *data,
2421 uint32_t version, uint32_t id)
2422{
2423 struct weston_compositor *compositor = data;
2424 struct wl_resource *resource;
2425
2426 resource = wl_resource_create(client,
2427 &zwp_relative_pointer_manager_v1_interface,
2428 1, id);
2429
2430 wl_resource_set_implementation(resource, &relative_pointer_manager,
2431 compositor,
2432 NULL);
2433}
2434
Rob Bradford382ff462013-06-24 16:52:45 +01002435#ifdef ENABLE_XKBCOMMON
Giulio Camuffo0358af42016-06-02 21:48:08 +03002436WL_EXPORT int
2437weston_compositor_set_xkb_rule_names(struct weston_compositor *ec,
2438 struct xkb_rule_names *names)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002439{
Rob Bradford382ff462013-06-24 16:52:45 +01002440 ec->use_xkbcommon = 1;
Matt Roper01a92732013-06-24 16:52:44 +01002441
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002442 if (ec->xkb_context == NULL) {
2443 ec->xkb_context = xkb_context_new(0);
2444 if (ec->xkb_context == NULL) {
2445 weston_log("failed to create XKB context\n");
2446 return -1;
2447 }
2448 }
2449
2450 if (names)
2451 ec->xkb_names = *names;
2452 if (!ec->xkb_names.rules)
2453 ec->xkb_names.rules = strdup("evdev");
2454 if (!ec->xkb_names.model)
2455 ec->xkb_names.model = strdup("pc105");
2456 if (!ec->xkb_names.layout)
2457 ec->xkb_names.layout = strdup("us");
2458
2459 return 0;
2460}
2461
Stefan Schmidtfda26522013-09-17 10:54:09 +01002462static void
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00002463weston_xkb_info_destroy(struct weston_xkb_info *xkb_info)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002464{
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00002465 if (--xkb_info->ref_count > 0)
2466 return;
2467
Ran Benitac9c74152014-08-19 23:59:52 +03002468 xkb_keymap_unref(xkb_info->keymap);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002469
2470 if (xkb_info->keymap_area)
2471 munmap(xkb_info->keymap_area, xkb_info->keymap_size);
2472 if (xkb_info->keymap_fd >= 0)
2473 close(xkb_info->keymap_fd);
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00002474 free(xkb_info);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002475}
2476
2477void
2478weston_compositor_xkb_destroy(struct weston_compositor *ec)
2479{
Matt Roper01a92732013-06-24 16:52:44 +01002480 /*
2481 * If we're operating in raw keyboard mode, we never initialized
2482 * libxkbcommon so there's no cleanup to do either.
2483 */
2484 if (!ec->use_xkbcommon)
2485 return;
2486
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002487 free((char *) ec->xkb_names.rules);
2488 free((char *) ec->xkb_names.model);
2489 free((char *) ec->xkb_names.layout);
2490 free((char *) ec->xkb_names.variant);
2491 free((char *) ec->xkb_names.options);
Stefan Schmidtfda26522013-09-17 10:54:09 +01002492
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00002493 if (ec->xkb_info)
2494 weston_xkb_info_destroy(ec->xkb_info);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002495 xkb_context_unref(ec->xkb_context);
2496}
2497
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00002498static struct weston_xkb_info *
2499weston_xkb_info_create(struct xkb_keymap *keymap)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002500{
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00002501 struct weston_xkb_info *xkb_info = zalloc(sizeof *xkb_info);
2502 if (xkb_info == NULL)
2503 return NULL;
2504
Ran Benita2e1968f2014-08-19 23:59:51 +03002505 xkb_info->keymap = xkb_keymap_ref(keymap);
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00002506 xkb_info->ref_count = 1;
2507
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002508 char *keymap_str;
2509
Ran Benita2e1968f2014-08-19 23:59:51 +03002510 xkb_info->shift_mod = xkb_keymap_mod_get_index(xkb_info->keymap,
2511 XKB_MOD_NAME_SHIFT);
2512 xkb_info->caps_mod = xkb_keymap_mod_get_index(xkb_info->keymap,
2513 XKB_MOD_NAME_CAPS);
2514 xkb_info->ctrl_mod = xkb_keymap_mod_get_index(xkb_info->keymap,
2515 XKB_MOD_NAME_CTRL);
2516 xkb_info->alt_mod = xkb_keymap_mod_get_index(xkb_info->keymap,
2517 XKB_MOD_NAME_ALT);
2518 xkb_info->mod2_mod = xkb_keymap_mod_get_index(xkb_info->keymap,
2519 "Mod2");
2520 xkb_info->mod3_mod = xkb_keymap_mod_get_index(xkb_info->keymap,
2521 "Mod3");
2522 xkb_info->super_mod = xkb_keymap_mod_get_index(xkb_info->keymap,
2523 XKB_MOD_NAME_LOGO);
2524 xkb_info->mod5_mod = xkb_keymap_mod_get_index(xkb_info->keymap,
2525 "Mod5");
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002526
Ran Benita2e1968f2014-08-19 23:59:51 +03002527 xkb_info->num_led = xkb_keymap_led_get_index(xkb_info->keymap,
2528 XKB_LED_NAME_NUM);
2529 xkb_info->caps_led = xkb_keymap_led_get_index(xkb_info->keymap,
2530 XKB_LED_NAME_CAPS);
2531 xkb_info->scroll_led = xkb_keymap_led_get_index(xkb_info->keymap,
2532 XKB_LED_NAME_SCROLL);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002533
Ran Benita2e1968f2014-08-19 23:59:51 +03002534 keymap_str = xkb_keymap_get_as_string(xkb_info->keymap,
2535 XKB_KEYMAP_FORMAT_TEXT_V1);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002536 if (keymap_str == NULL) {
2537 weston_log("failed to get string version of keymap\n");
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00002538 goto err_keymap;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002539 }
2540 xkb_info->keymap_size = strlen(keymap_str) + 1;
2541
2542 xkb_info->keymap_fd = os_create_anonymous_file(xkb_info->keymap_size);
2543 if (xkb_info->keymap_fd < 0) {
2544 weston_log("creating a keymap file for %lu bytes failed: %m\n",
2545 (unsigned long) xkb_info->keymap_size);
2546 goto err_keymap_str;
2547 }
2548
2549 xkb_info->keymap_area = mmap(NULL, xkb_info->keymap_size,
2550 PROT_READ | PROT_WRITE,
2551 MAP_SHARED, xkb_info->keymap_fd, 0);
2552 if (xkb_info->keymap_area == MAP_FAILED) {
2553 weston_log("failed to mmap() %lu bytes\n",
2554 (unsigned long) xkb_info->keymap_size);
2555 goto err_dev_zero;
2556 }
2557 strcpy(xkb_info->keymap_area, keymap_str);
2558 free(keymap_str);
2559
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00002560 return xkb_info;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002561
2562err_dev_zero:
2563 close(xkb_info->keymap_fd);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002564err_keymap_str:
2565 free(keymap_str);
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00002566err_keymap:
Ran Benita2e1968f2014-08-19 23:59:51 +03002567 xkb_keymap_unref(xkb_info->keymap);
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00002568 free(xkb_info);
2569 return NULL;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002570}
2571
2572static int
2573weston_compositor_build_global_keymap(struct weston_compositor *ec)
2574{
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00002575 struct xkb_keymap *keymap;
2576
2577 if (ec->xkb_info != NULL)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002578 return 0;
2579
Ran Benita2e1968f2014-08-19 23:59:51 +03002580 keymap = xkb_keymap_new_from_names(ec->xkb_context,
2581 &ec->xkb_names,
2582 0);
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00002583 if (keymap == NULL) {
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002584 weston_log("failed to compile global XKB keymap\n");
2585 weston_log(" tried rules %s, model %s, layout %s, variant %s, "
2586 "options %s\n",
2587 ec->xkb_names.rules, ec->xkb_names.model,
2588 ec->xkb_names.layout, ec->xkb_names.variant,
2589 ec->xkb_names.options);
2590 return -1;
2591 }
2592
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00002593 ec->xkb_info = weston_xkb_info_create(keymap);
Rui Matos73d93952013-10-24 19:28:41 +02002594 xkb_keymap_unref(keymap);
Stefan Schmidtfda26522013-09-17 10:54:09 +01002595 if (ec->xkb_info == NULL)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002596 return -1;
2597
2598 return 0;
2599}
Rob Bradford382ff462013-06-24 16:52:45 +01002600#else
Giulio Camuffo0358af42016-06-02 21:48:08 +03002601WL_EXPORT int
2602weston_compositor_set_xkb_rule_names(struct weston_compositor *ec,
2603 struct xkb_rule_names *names)
Rob Bradford382ff462013-06-24 16:52:45 +01002604{
2605 return 0;
2606}
2607
2608void
2609weston_compositor_xkb_destroy(struct weston_compositor *ec)
2610{
2611}
2612#endif
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002613
Rui Matos65196bc2013-10-10 19:44:19 +02002614WL_EXPORT void
2615weston_seat_update_keymap(struct weston_seat *seat, struct xkb_keymap *keymap)
2616{
Derek Foreman1281a362015-07-31 16:55:32 -05002617 struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
2618
2619 if (!keyboard || !keymap)
Rui Matos65196bc2013-10-10 19:44:19 +02002620 return;
2621
2622#ifdef ENABLE_XKBCOMMON
2623 if (!seat->compositor->use_xkbcommon)
2624 return;
2625
Derek Foreman1281a362015-07-31 16:55:32 -05002626 xkb_keymap_unref(keyboard->pending_keymap);
2627 keyboard->pending_keymap = xkb_keymap_ref(keymap);
Rui Matos65196bc2013-10-10 19:44:19 +02002628
Derek Foreman1281a362015-07-31 16:55:32 -05002629 if (keyboard->keys.size == 0)
Rui Matos65196bc2013-10-10 19:44:19 +02002630 update_keymap(seat);
2631#endif
2632}
2633
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002634WL_EXPORT int
2635weston_seat_init_keyboard(struct weston_seat *seat, struct xkb_keymap *keymap)
2636{
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04002637 struct weston_keyboard *keyboard;
2638
Derek Foreman1281a362015-07-31 16:55:32 -05002639 if (seat->keyboard_state) {
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002640 seat->keyboard_device_count += 1;
2641 if (seat->keyboard_device_count == 1)
2642 seat_send_updated_caps(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002643 return 0;
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002644 }
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002645
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04002646 keyboard = weston_keyboard_create();
2647 if (keyboard == NULL) {
2648 weston_log("failed to allocate weston keyboard struct\n");
2649 return -1;
2650 }
2651
Jonas Ådahl7395ea02013-12-03 09:14:26 +01002652#ifdef ENABLE_XKBCOMMON
2653 if (seat->compositor->use_xkbcommon) {
2654 if (keymap != NULL) {
2655 keyboard->xkb_info = weston_xkb_info_create(keymap);
2656 if (keyboard->xkb_info == NULL)
Ander Conselvan de Oliveira4d363cf2014-01-31 17:35:45 +02002657 goto err;
Jonas Ådahl7395ea02013-12-03 09:14:26 +01002658 } else {
2659 if (weston_compositor_build_global_keymap(seat->compositor) < 0)
Ander Conselvan de Oliveira4d363cf2014-01-31 17:35:45 +02002660 goto err;
Jonas Ådahl7395ea02013-12-03 09:14:26 +01002661 keyboard->xkb_info = seat->compositor->xkb_info;
2662 keyboard->xkb_info->ref_count++;
2663 }
2664
2665 keyboard->xkb_state.state = xkb_state_new(keyboard->xkb_info->keymap);
2666 if (keyboard->xkb_state.state == NULL) {
2667 weston_log("failed to initialise XKB state\n");
Ander Conselvan de Oliveira4d363cf2014-01-31 17:35:45 +02002668 goto err;
Jonas Ådahl7395ea02013-12-03 09:14:26 +01002669 }
2670
2671 keyboard->xkb_state.leds = 0;
2672 }
2673#endif
2674
Derek Foreman1281a362015-07-31 16:55:32 -05002675 seat->keyboard_state = keyboard;
Ander Conselvan de Oliveira4d363cf2014-01-31 17:35:45 +02002676 seat->keyboard_device_count = 1;
2677 keyboard->seat = seat;
2678
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04002679 seat_send_updated_caps(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002680
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002681 return 0;
Ander Conselvan de Oliveira4d363cf2014-01-31 17:35:45 +02002682
2683err:
2684 if (keyboard->xkb_info)
2685 weston_xkb_info_destroy(keyboard->xkb_info);
2686 free(keyboard);
2687
2688 return -1;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002689}
2690
Jonas Ådahl91fed542013-12-03 09:14:27 +01002691static void
2692weston_keyboard_reset_state(struct weston_keyboard *keyboard)
2693{
2694 struct weston_seat *seat = keyboard->seat;
2695 struct xkb_state *state;
2696
2697#ifdef ENABLE_XKBCOMMON
2698 if (seat->compositor->use_xkbcommon) {
2699 state = xkb_state_new(keyboard->xkb_info->keymap);
2700 if (!state) {
2701 weston_log("failed to reset XKB state\n");
2702 return;
2703 }
2704 xkb_state_unref(keyboard->xkb_state.state);
2705 keyboard->xkb_state.state = state;
2706
2707 keyboard->xkb_state.leds = 0;
2708 }
2709#endif
2710
2711 seat->modifier_state = 0;
2712}
2713
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002714WL_EXPORT void
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002715weston_seat_release_keyboard(struct weston_seat *seat)
2716{
2717 seat->keyboard_device_count--;
Derek Foremand621df22014-11-19 11:04:12 -06002718 assert(seat->keyboard_device_count >= 0);
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002719 if (seat->keyboard_device_count == 0) {
Derek Foreman1281a362015-07-31 16:55:32 -05002720 weston_keyboard_set_focus(seat->keyboard_state, NULL);
2721 weston_keyboard_cancel_grab(seat->keyboard_state);
2722 weston_keyboard_reset_state(seat->keyboard_state);
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002723 seat_send_updated_caps(seat);
2724 }
2725}
2726
2727WL_EXPORT void
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002728weston_seat_init_pointer(struct weston_seat *seat)
2729{
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04002730 struct weston_pointer *pointer;
2731
Derek Foreman1281a362015-07-31 16:55:32 -05002732 if (seat->pointer_state) {
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002733 seat->pointer_device_count += 1;
2734 if (seat->pointer_device_count == 1)
2735 seat_send_updated_caps(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002736 return;
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002737 }
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002738
Giulio Camuffocdb4d292013-11-14 23:42:53 +01002739 pointer = weston_pointer_create(seat);
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04002740 if (pointer == NULL)
2741 return;
2742
Derek Foreman1281a362015-07-31 16:55:32 -05002743 seat->pointer_state = pointer;
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002744 seat->pointer_device_count = 1;
2745 pointer->seat = seat;
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04002746
2747 seat_send_updated_caps(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002748}
2749
2750WL_EXPORT void
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002751weston_seat_release_pointer(struct weston_seat *seat)
2752{
Derek Foreman1281a362015-07-31 16:55:32 -05002753 struct weston_pointer *pointer = seat->pointer_state;
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002754
2755 seat->pointer_device_count--;
2756 if (seat->pointer_device_count == 0) {
Derek Foremanf9318d12015-05-11 15:40:11 -05002757 weston_pointer_clear_focus(pointer);
Jonas Ådahl1ea343e2013-10-25 23:18:05 +02002758 weston_pointer_cancel_grab(pointer);
Jonas Ådahl630bae82013-10-17 23:04:06 +02002759
Jonas Ådahla4932742013-10-17 23:04:07 +02002760 if (pointer->sprite)
2761 pointer_unmap_sprite(pointer);
2762
Jonas Ådahl3e12e632013-12-02 22:05:05 +01002763 weston_pointer_reset_state(pointer);
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002764 seat_send_updated_caps(seat);
Derek Foremanfd5ca512015-01-07 15:00:25 -06002765
2766 /* seat->pointer is intentionally not destroyed so that
2767 * a newly attached pointer on this seat will retain
2768 * the previous cursor co-ordinates.
2769 */
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002770 }
2771}
2772
2773WL_EXPORT void
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002774weston_seat_init_touch(struct weston_seat *seat)
2775{
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04002776 struct weston_touch *touch;
2777
Derek Foreman1281a362015-07-31 16:55:32 -05002778 if (seat->touch_state) {
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002779 seat->touch_device_count += 1;
2780 if (seat->touch_device_count == 1)
2781 seat_send_updated_caps(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002782 return;
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002783 }
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002784
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04002785 touch = weston_touch_create();
2786 if (touch == NULL)
2787 return;
2788
Derek Foreman1281a362015-07-31 16:55:32 -05002789 seat->touch_state = touch;
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002790 seat->touch_device_count = 1;
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04002791 touch->seat = seat;
2792
2793 seat_send_updated_caps(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002794}
2795
2796WL_EXPORT void
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002797weston_seat_release_touch(struct weston_seat *seat)
2798{
2799 seat->touch_device_count--;
2800 if (seat->touch_device_count == 0) {
Derek Foreman1281a362015-07-31 16:55:32 -05002801 weston_touch_set_focus(seat->touch_state, NULL);
2802 weston_touch_cancel_grab(seat->touch_state);
2803 weston_touch_reset_state(seat->touch_state);
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002804 seat_send_updated_caps(seat);
2805 }
2806}
2807
2808WL_EXPORT void
Rob Bradford9af5f9e2013-05-31 18:09:50 +01002809weston_seat_init(struct weston_seat *seat, struct weston_compositor *ec,
2810 const char *seat_name)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002811{
Kristian Høgsberg4a2a2742013-05-06 22:24:50 -04002812 memset(seat, 0, sizeof *seat);
2813
Kristian Høgsberge3148752013-05-06 23:19:49 -04002814 seat->selection_data_source = NULL;
2815 wl_list_init(&seat->base_resource_list);
2816 wl_signal_init(&seat->selection_signal);
2817 wl_list_init(&seat->drag_resource_list);
Kristian Høgsberge3148752013-05-06 23:19:49 -04002818 wl_signal_init(&seat->destroy_signal);
Jason Ekstranda4ab5422014-04-02 19:53:45 -05002819 wl_signal_init(&seat->updated_caps_signal);
Kristian Høgsberg4a2a2742013-05-06 22:24:50 -04002820
Peter Hutterer87743e92016-01-18 16:38:22 +10002821 seat->global = wl_global_create(ec->wl_display, &wl_seat_interface, 5,
Kristian Høgsberg919cddb2013-07-08 19:03:57 -04002822 seat, bind_seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002823
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002824 seat->compositor = ec;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002825 seat->modifier_state = 0;
Rob Bradford9af5f9e2013-05-31 18:09:50 +01002826 seat->seat_name = strdup(seat_name);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002827
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002828 wl_list_insert(ec->seat_list.prev, &seat->link);
2829
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002830 clipboard_create(seat);
2831
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002832 wl_signal_emit(&ec->seat_created_signal, seat);
2833}
2834
2835WL_EXPORT void
2836weston_seat_release(struct weston_seat *seat)
2837{
2838 wl_list_remove(&seat->link);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002839
Jonas Ådahl1afb2382014-01-03 19:46:51 +01002840 if (seat->saved_kbd_focus)
2841 wl_list_remove(&seat->saved_kbd_focus_listener.link);
2842
Derek Foreman1281a362015-07-31 16:55:32 -05002843 if (seat->pointer_state)
2844 weston_pointer_destroy(seat->pointer_state);
2845 if (seat->keyboard_state)
2846 weston_keyboard_destroy(seat->keyboard_state);
2847 if (seat->touch_state)
2848 weston_touch_destroy(seat->touch_state);
Kristian Høgsberg4a2a2742013-05-06 22:24:50 -04002849
Rob Bradford9af5f9e2013-05-31 18:09:50 +01002850 free (seat->seat_name);
2851
Kristian Høgsberg919cddb2013-07-08 19:03:57 -04002852 wl_global_destroy(seat->global);
Kristian Høgsbergaaadc772013-07-08 16:20:31 -04002853
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002854 wl_signal_emit(&seat->destroy_signal, seat);
2855}
Derek Foreman1281a362015-07-31 16:55:32 -05002856
2857/** Get a seat's keyboard pointer
2858 *
2859 * \param seat The seat to query
2860 * \return The seat's keyboard pointer, or NULL if no keyboard is present
2861 *
2862 * The keyboard pointer for a seat isn't freed when all keyboards are removed,
2863 * so it should only be used when the seat's keyboard_device_count is greater
2864 * than zero. This function does that test and only returns a pointer
2865 * when a keyboard is present.
2866 */
2867WL_EXPORT struct weston_keyboard *
2868weston_seat_get_keyboard(struct weston_seat *seat)
2869{
2870 if (!seat)
2871 return NULL;
2872
2873 if (seat->keyboard_device_count)
2874 return seat->keyboard_state;
2875
2876 return NULL;
2877}
2878
2879/** Get a seat's pointer pointer
2880 *
2881 * \param seat The seat to query
2882 * \return The seat's pointer pointer, or NULL if no pointer device is present
2883 *
2884 * The pointer pointer for a seat isn't freed when all mice are removed,
2885 * so it should only be used when the seat's pointer_device_count is greater
2886 * than zero. This function does that test and only returns a pointer
2887 * when a pointing device is present.
2888 */
2889WL_EXPORT struct weston_pointer *
2890weston_seat_get_pointer(struct weston_seat *seat)
2891{
2892 if (!seat)
2893 return NULL;
2894
2895 if (seat->pointer_device_count)
2896 return seat->pointer_state;
2897
2898 return NULL;
2899}
2900
2901/** Get a seat's touch pointer
2902 *
2903 * \param seat The seat to query
2904 * \return The seat's touch pointer, or NULL if no touch device is present
2905 *
2906 * The touch pointer for a seat isn't freed when all touch devices are removed,
2907 * so it should only be used when the seat's touch_device_count is greater
2908 * than zero. This function does that test and only returns a pointer
2909 * when a touch device is present.
2910 */
2911WL_EXPORT struct weston_touch *
2912weston_seat_get_touch(struct weston_seat *seat)
2913{
2914 if (!seat)
2915 return NULL;
2916
2917 if (seat->touch_device_count)
2918 return seat->touch_state;
2919
2920 return NULL;
2921}
Bryce Harrington24f917e2016-06-29 19:04:07 -07002922
2923/** Sets the keyboard focus to the given surface
2924 *
2925 * \param seat The seat to query
2926 */
2927WL_EXPORT void
2928weston_seat_set_keyboard_focus(struct weston_seat *seat,
2929 struct weston_surface *surface)
2930{
2931 struct weston_compositor *compositor = seat->compositor;
2932 struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
2933
Jonas Ådahlef8e1c32016-03-15 20:28:51 +08002934 if (keyboard && keyboard->focus != surface) {
Bryce Harrington24f917e2016-06-29 19:04:07 -07002935 weston_keyboard_set_focus(keyboard, surface);
2936 wl_data_device_set_keyboard_focus(seat);
2937 }
2938
Jonas Ådahl94e2e2d2014-10-18 18:42:19 +02002939 inc_activate_serial(compositor);
Bryce Harrington24f917e2016-06-29 19:04:07 -07002940 wl_signal_emit(&compositor->activate_signal, surface);
2941}
Jonas Ådahl30d61d82014-10-22 21:21:17 +02002942
2943int
2944weston_input_init(struct weston_compositor *compositor)
2945{
2946 if (!wl_global_create(compositor->wl_display,
2947 &zwp_relative_pointer_manager_v1_interface, 1,
2948 compositor, bind_relative_pointer_manager))
2949 return -1;
2950
2951 return 0;
2952}