blob: d98cc557093b593061684fb5330d911ac751bea6 [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
Jonas Ådahlf44942e2016-07-22 17:54:55 +0800343weston_pointer_send_motion(struct weston_pointer *pointer, uint32_t time,
344 wl_fixed_t sx, wl_fixed_t sy)
345{
346 struct wl_list *resource_list;
347 struct wl_resource *resource;
348
349 if (!pointer->focus_client)
350 return;
351
352 resource_list = &pointer->focus_client->pointer_resources;
353 wl_resource_for_each(resource, resource_list)
354 wl_pointer_send_motion(resource, time, sx, sy);
355}
356
357static void
Giulio Camuffo1959ab82013-11-14 23:42:52 +0100358default_grab_pointer_motion(struct weston_pointer_grab *grab, uint32_t time,
Jonas Ådahld2510102014-10-05 21:39:14 +0200359 struct weston_pointer_motion_event *event)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400360{
Kristian Høgsbergbe6403e2013-05-08 21:03:21 -0400361 struct weston_pointer *pointer = grab->pointer;
Jonas Ådahld2510102014-10-05 21:39:14 +0200362 wl_fixed_t x, y;
Jonas Ådahl8283c342015-04-24 15:26:17 +0800363 wl_fixed_t old_sx = pointer->sx;
364 wl_fixed_t old_sy = pointer->sy;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400365
Jonas Ådahld2510102014-10-05 21:39:14 +0200366 if (pointer->focus) {
367 weston_pointer_motion_to_abs(pointer, event, &x, &y);
Kristian Høgsbergdb1fccb2014-02-05 17:14:42 -0800368 weston_view_from_global_fixed(pointer->focus, x, y,
369 &pointer->sx, &pointer->sy);
Jonas Ådahld2510102014-10-05 21:39:14 +0200370 }
Kristian Høgsbergdb1fccb2014-02-05 17:14:42 -0800371
Jonas Ådahld2510102014-10-05 21:39:14 +0200372 weston_pointer_move(pointer, event);
Giulio Camuffo1959ab82013-11-14 23:42:52 +0100373
Jonas Ådahlf44942e2016-07-22 17:54:55 +0800374 if (old_sx != pointer->sx || old_sy != pointer->sy) {
375 weston_pointer_send_motion(pointer, time,
376 pointer->sx, pointer->sy);
Kristian Høgsbergbe6403e2013-05-08 21:03:21 -0400377 }
Jonas Ådahl30d61d82014-10-22 21:21:17 +0200378
379 weston_pointer_send_relative_motion(pointer, time, event);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400380}
381
382static void
Jonas Ådahlc02ac112016-07-22 17:55:43 +0800383weston_pointer_send_button(struct weston_pointer *pointer,
384 uint32_t time, uint32_t button, uint32_t state_w)
385{
386 struct wl_display *display = pointer->seat->compositor->wl_display;
387 struct wl_list *resource_list;
388 struct wl_resource *resource;
389 uint32_t serial;
390
391 if (!pointer->focus_client)
392 return;
393
394 resource_list = &pointer->focus_client->pointer_resources;
395 if (resource_list && !wl_list_empty(resource_list)) {
396 resource_list = &pointer->focus_client->pointer_resources;
397 serial = wl_display_next_serial(display);
398 wl_resource_for_each(resource, resource_list) {
399 wl_pointer_send_button(resource,
400 serial,
401 time,
402 button,
403 state_w);
404 }
405 }
406}
407
408static void
Kristian Høgsbergb27901c2013-10-28 15:32:02 -0700409default_grab_pointer_button(struct weston_pointer_grab *grab,
410 uint32_t time, uint32_t button, uint32_t state_w)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400411{
Kristian Høgsberg02bbabb2013-05-06 22:15:05 -0400412 struct weston_pointer *pointer = grab->pointer;
Kristian Høgsberge122b7b2013-05-08 16:47:00 -0400413 struct weston_compositor *compositor = pointer->seat->compositor;
Jason Ekstranda7af7042013-10-12 22:38:11 -0500414 struct weston_view *view;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400415 enum wl_pointer_button_state state = state_w;
Kristian Høgsberge122b7b2013-05-08 16:47:00 -0400416 wl_fixed_t sx, sy;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400417
Jonas Ådahlc02ac112016-07-22 17:55:43 +0800418 weston_pointer_send_button(pointer, time, button, state_w);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400419
420 if (pointer->button_count == 0 &&
Kristian Høgsberge122b7b2013-05-08 16:47:00 -0400421 state == WL_POINTER_BUTTON_STATE_RELEASED) {
Jason Ekstranda7af7042013-10-12 22:38:11 -0500422 view = weston_compositor_pick_view(compositor,
423 pointer->x, pointer->y,
424 &sx, &sy);
Kristian Høgsberge122b7b2013-05-08 16:47:00 -0400425
Jason Ekstranda7af7042013-10-12 22:38:11 -0500426 weston_pointer_set_focus(pointer, view, sx, sy);
Kristian Høgsberge122b7b2013-05-08 16:47:00 -0400427 }
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400428}
429
Jonas Ådahl0336ca02014-10-04 16:28:29 +0200430/** Send wl_pointer.axis events to focused resources.
431 *
432 * \param pointer The pointer where the axis events originates from.
433 * \param time The timestamp of the event
434 * \param axis The axis enum value of the event
435 * \param value The axis value of the event
436 *
437 * For every resource that is currently in focus, send a wl_pointer.axis event
438 * with the passed parameters. The focused resources are the wl_pointer
439 * resources of the client which currently has the surface with pointer focus.
440 */
441WL_EXPORT void
442weston_pointer_send_axis(struct weston_pointer *pointer,
Peter Hutterer89b6a492016-01-18 15:58:17 +1000443 uint32_t time,
444 struct weston_pointer_axis_event *event)
Jonas Ådahl0336ca02014-10-04 16:28:29 +0200445{
446 struct wl_resource *resource;
447 struct wl_list *resource_list;
448
Jonas Ådahl2cbf2932015-07-22 12:05:38 +0800449 if (!pointer->focus_client)
450 return;
451
452 resource_list = &pointer->focus_client->pointer_resources;
Peter Hutterer87743e92016-01-18 16:38:22 +1000453 wl_resource_for_each(resource, resource_list) {
454 if (event->has_discrete &&
455 wl_resource_get_version(resource) >=
456 WL_POINTER_AXIS_DISCRETE_SINCE_VERSION)
457 wl_pointer_send_axis_discrete(resource, event->axis,
458 event->discrete);
459
460 if (event->value)
461 wl_pointer_send_axis(resource, time,
Giulio Camuffo90a6fc62016-03-22 17:44:54 +0200462 event->axis,
463 wl_fixed_from_double(event->value));
Peter Hutterer87743e92016-01-18 16:38:22 +1000464 else if (wl_resource_get_version(resource) >=
465 WL_POINTER_AXIS_STOP_SINCE_VERSION)
466 wl_pointer_send_axis_stop(resource, time,
467 event->axis);
468 }
469}
470
471WL_EXPORT void
472weston_pointer_send_axis_source(struct weston_pointer *pointer, uint32_t source)
473{
474 struct wl_resource *resource;
475 struct wl_list *resource_list;
476
Jonas Ådahled6014a2016-04-21 10:21:48 +0800477 if (!pointer->focus_client)
478 return;
479
Peter Hutterer87743e92016-01-18 16:38:22 +1000480 resource_list = &pointer->focus_client->pointer_resources;
481 wl_resource_for_each(resource, resource_list) {
482 if (wl_resource_get_version(resource) >=
483 WL_POINTER_AXIS_SOURCE_SINCE_VERSION) {
484 wl_pointer_send_axis_source(resource, source);
485 }
486 }
487}
488
489static void
490pointer_send_frame(struct wl_resource *resource)
491{
492 if (wl_resource_get_version(resource) >=
493 WL_POINTER_FRAME_SINCE_VERSION) {
494 wl_pointer_send_frame(resource);
495 }
496}
497
498WL_EXPORT void
499weston_pointer_send_frame(struct weston_pointer *pointer)
500{
501 struct wl_resource *resource;
502 struct wl_list *resource_list;
503
Derek Foreman8efa31b2016-01-29 10:29:46 -0600504 if (!pointer->focus_client)
505 return;
506
Peter Hutterer87743e92016-01-18 16:38:22 +1000507 resource_list = &pointer->focus_client->pointer_resources;
Jonas Ådahl0336ca02014-10-04 16:28:29 +0200508 wl_resource_for_each(resource, resource_list)
Peter Hutterer87743e92016-01-18 16:38:22 +1000509 pointer_send_frame(resource);
Jonas Ådahl0336ca02014-10-04 16:28:29 +0200510}
511
512static void
513default_grab_pointer_axis(struct weston_pointer_grab *grab,
Peter Hutterer89b6a492016-01-18 15:58:17 +1000514 uint32_t time,
515 struct weston_pointer_axis_event *event)
Jonas Ådahl0336ca02014-10-04 16:28:29 +0200516{
Peter Hutterer89b6a492016-01-18 15:58:17 +1000517 weston_pointer_send_axis(grab->pointer, time, event);
Jonas Ådahl0336ca02014-10-04 16:28:29 +0200518}
519
Jonas Ådahl1ea343e2013-10-25 23:18:05 +0200520static void
Peter Hutterer87743e92016-01-18 16:38:22 +1000521default_grab_pointer_axis_source(struct weston_pointer_grab *grab,
522 uint32_t source)
523{
524 weston_pointer_send_axis_source(grab->pointer, source);
525}
526
527static void
528default_grab_pointer_frame(struct weston_pointer_grab *grab)
529{
530 weston_pointer_send_frame(grab->pointer);
531}
532
533static void
Jonas Ådahl1ea343e2013-10-25 23:18:05 +0200534default_grab_pointer_cancel(struct weston_pointer_grab *grab)
535{
536}
537
Kristian Høgsberg02bbabb2013-05-06 22:15:05 -0400538static const struct weston_pointer_grab_interface
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400539 default_pointer_grab_interface = {
Kristian Høgsbergb27901c2013-10-28 15:32:02 -0700540 default_grab_pointer_focus,
541 default_grab_pointer_motion,
542 default_grab_pointer_button,
Jonas Ådahl0336ca02014-10-04 16:28:29 +0200543 default_grab_pointer_axis,
Peter Hutterer87743e92016-01-18 16:38:22 +1000544 default_grab_pointer_axis_source,
545 default_grab_pointer_frame,
Jonas Ådahl1ea343e2013-10-25 23:18:05 +0200546 default_grab_pointer_cancel,
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400547};
548
Kristian Høgsberge329f362013-05-06 22:19:57 -0400549static void
550default_grab_touch_down(struct weston_touch_grab *grab, uint32_t time,
Giulio Camuffo61ed7b62015-07-08 11:55:28 +0300551 int touch_id, wl_fixed_t x, wl_fixed_t y)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400552{
Kristian Høgsberge329f362013-05-06 22:19:57 -0400553 struct weston_touch *touch = grab->touch;
Rob Bradford880ebc72013-07-22 17:31:38 +0100554 struct wl_display *display = touch->seat->compositor->wl_display;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400555 uint32_t serial;
Neil Roberts96d790e2013-09-19 17:32:00 +0100556 struct wl_resource *resource;
557 struct wl_list *resource_list;
Giulio Camuffo61ed7b62015-07-08 11:55:28 +0300558 wl_fixed_t sx, sy;
559
Bryce Harrington2c40d1d2016-02-02 10:18:48 -0800560 if (!touch->focus)
561 return;
562
Giulio Camuffo61ed7b62015-07-08 11:55:28 +0300563 weston_view_from_global_fixed(touch->focus, x, y, &sx, &sy);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400564
Neil Roberts96d790e2013-09-19 17:32:00 +0100565 resource_list = &touch->focus_resource_list;
566
Bryce Harrington2c40d1d2016-02-02 10:18:48 -0800567 if (!wl_list_empty(resource_list)) {
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400568 serial = wl_display_next_serial(display);
Neil Roberts96d790e2013-09-19 17:32:00 +0100569 wl_resource_for_each(resource, resource_list)
570 wl_touch_send_down(resource, serial, time,
Jason Ekstranda7af7042013-10-12 22:38:11 -0500571 touch->focus->surface->resource,
Neil Roberts96d790e2013-09-19 17:32:00 +0100572 touch_id, sx, sy);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400573 }
574}
575
Kristian Høgsberge329f362013-05-06 22:19:57 -0400576static void
577default_grab_touch_up(struct weston_touch_grab *grab,
578 uint32_t time, int touch_id)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400579{
Kristian Høgsberge329f362013-05-06 22:19:57 -0400580 struct weston_touch *touch = grab->touch;
Rob Bradford880ebc72013-07-22 17:31:38 +0100581 struct wl_display *display = touch->seat->compositor->wl_display;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400582 uint32_t serial;
Neil Roberts96d790e2013-09-19 17:32:00 +0100583 struct wl_resource *resource;
584 struct wl_list *resource_list;
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 if (!wl_list_empty(resource_list)) {
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400589 serial = wl_display_next_serial(display);
Neil Roberts96d790e2013-09-19 17:32:00 +0100590 wl_resource_for_each(resource, resource_list)
591 wl_touch_send_up(resource, serial, time, touch_id);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400592 }
593}
594
Kristian Høgsberge329f362013-05-06 22:19:57 -0400595static void
596default_grab_touch_motion(struct weston_touch_grab *grab, uint32_t time,
Giulio Camuffo61ed7b62015-07-08 11:55:28 +0300597 int touch_id, wl_fixed_t x, wl_fixed_t y)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400598{
Kristian Høgsberge329f362013-05-06 22:19:57 -0400599 struct weston_touch *touch = grab->touch;
Neil Roberts96d790e2013-09-19 17:32:00 +0100600 struct wl_resource *resource;
601 struct wl_list *resource_list;
Giulio Camuffo61ed7b62015-07-08 11:55:28 +0300602 wl_fixed_t sx, sy;
603
604 weston_view_from_global_fixed(touch->focus, x, y, &sx, &sy);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400605
Neil Roberts96d790e2013-09-19 17:32:00 +0100606 resource_list = &touch->focus_resource_list;
607
608 wl_resource_for_each(resource, resource_list) {
609 wl_touch_send_motion(resource, time,
Kristian Høgsberge329f362013-05-06 22:19:57 -0400610 touch_id, sx, sy);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400611 }
612}
613
Jonas Ådahl1ea343e2013-10-25 23:18:05 +0200614static void
Jonas Ådahl1679f232014-04-12 09:39:51 +0200615default_grab_touch_frame(struct weston_touch_grab *grab)
616{
617 struct wl_resource *resource;
618
619 wl_resource_for_each(resource, &grab->touch->focus_resource_list)
620 wl_touch_send_frame(resource);
621}
622
623static void
Jonas Ådahl1ea343e2013-10-25 23:18:05 +0200624default_grab_touch_cancel(struct weston_touch_grab *grab)
625{
626}
627
Kristian Høgsberge329f362013-05-06 22:19:57 -0400628static const struct weston_touch_grab_interface default_touch_grab_interface = {
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400629 default_grab_touch_down,
630 default_grab_touch_up,
Jonas Ådahl1ea343e2013-10-25 23:18:05 +0200631 default_grab_touch_motion,
Jonas Ådahl1679f232014-04-12 09:39:51 +0200632 default_grab_touch_frame,
Jonas Ådahl1ea343e2013-10-25 23:18:05 +0200633 default_grab_touch_cancel,
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400634};
635
636static void
Kristian Høgsbergb27901c2013-10-28 15:32:02 -0700637default_grab_keyboard_key(struct weston_keyboard_grab *grab,
638 uint32_t time, uint32_t key, uint32_t state)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400639{
Kristian Høgsberg29139d42013-04-18 15:25:39 -0400640 struct weston_keyboard *keyboard = grab->keyboard;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400641 struct wl_resource *resource;
Rob Bradford880ebc72013-07-22 17:31:38 +0100642 struct wl_display *display = keyboard->seat->compositor->wl_display;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400643 uint32_t serial;
Neil Roberts96d790e2013-09-19 17:32:00 +0100644 struct wl_list *resource_list;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400645
Neil Roberts96d790e2013-09-19 17:32:00 +0100646 resource_list = &keyboard->focus_resource_list;
647 if (!wl_list_empty(resource_list)) {
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400648 serial = wl_display_next_serial(display);
Neil Roberts96d790e2013-09-19 17:32:00 +0100649 wl_resource_for_each(resource, resource_list)
650 wl_keyboard_send_key(resource,
651 serial,
652 time,
653 key,
654 state);
655 }
656}
657
658static void
659send_modifiers_to_resource(struct weston_keyboard *keyboard,
660 struct wl_resource *resource,
661 uint32_t serial)
662{
663 wl_keyboard_send_modifiers(resource,
664 serial,
665 keyboard->modifiers.mods_depressed,
666 keyboard->modifiers.mods_latched,
667 keyboard->modifiers.mods_locked,
668 keyboard->modifiers.group);
669}
670
671static void
672send_modifiers_to_client_in_list(struct wl_client *client,
673 struct wl_list *list,
674 uint32_t serial,
675 struct weston_keyboard *keyboard)
676{
677 struct wl_resource *resource;
678
679 wl_resource_for_each(resource, list) {
680 if (wl_resource_get_client(resource) == client)
681 send_modifiers_to_resource(keyboard,
682 resource,
683 serial);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400684 }
685}
686
Jonas Ådahl2cbf2932015-07-22 12:05:38 +0800687static struct weston_pointer_client *
688find_pointer_client_for_surface(struct weston_pointer *pointer,
689 struct weston_surface *surface)
690{
691 struct wl_client *client;
692
693 if (!surface)
694 return NULL;
695
696 if (!surface->resource)
697 return NULL;
698
699 client = wl_resource_get_client(surface->resource);
700 return weston_pointer_get_pointer_client(pointer, client);
701}
702
703static struct weston_pointer_client *
704find_pointer_client_for_view(struct weston_pointer *pointer, struct weston_view *view)
705{
706 if (!view)
707 return NULL;
708
709 return find_pointer_client_for_surface(pointer, view->surface);
710}
711
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400712static struct wl_resource *
Kristian Høgsbergfe7aa902013-05-08 09:54:37 -0400713find_resource_for_surface(struct wl_list *list, struct weston_surface *surface)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400714{
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400715 if (!surface)
716 return NULL;
717
Jason Ekstrand44a38632013-06-14 10:08:00 -0500718 if (!surface->resource)
719 return NULL;
Stefan Schmidtfda26522013-09-17 10:54:09 +0100720
Jason Ekstrand44a38632013-06-14 10:08:00 -0500721 return wl_resource_find_for_client(list, wl_resource_get_client(surface->resource));
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400722}
723
724static void
Kristian Høgsbergb27901c2013-10-28 15:32:02 -0700725default_grab_keyboard_modifiers(struct weston_keyboard_grab *grab,
726 uint32_t serial, uint32_t mods_depressed,
727 uint32_t mods_latched,
728 uint32_t mods_locked, uint32_t group)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400729{
Kristian Høgsberg29139d42013-04-18 15:25:39 -0400730 struct weston_keyboard *keyboard = grab->keyboard;
Derek Foreman1281a362015-07-31 16:55:32 -0500731 struct weston_pointer *pointer =
732 weston_seat_get_pointer(grab->keyboard->seat);
Neil Roberts96d790e2013-09-19 17:32:00 +0100733 struct wl_resource *resource;
734 struct wl_list *resource_list;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400735
Neil Roberts96d790e2013-09-19 17:32:00 +0100736 resource_list = &keyboard->focus_resource_list;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400737
Neil Roberts96d790e2013-09-19 17:32:00 +0100738 wl_resource_for_each(resource, resource_list) {
739 wl_keyboard_send_modifiers(resource, serial, mods_depressed,
740 mods_latched, mods_locked, group);
741 }
Jason Ekstrand42133d42013-11-14 20:06:16 -0600742 if (pointer && pointer->focus && pointer->focus->surface->resource &&
743 pointer->focus->surface != keyboard->focus) {
Neil Roberts96d790e2013-09-19 17:32:00 +0100744 struct wl_client *pointer_client =
Jason Ekstranda7af7042013-10-12 22:38:11 -0500745 wl_resource_get_client(pointer->focus->surface->resource);
Neil Roberts96d790e2013-09-19 17:32:00 +0100746 send_modifiers_to_client_in_list(pointer_client,
747 &keyboard->resource_list,
748 serial,
749 keyboard);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400750 }
751}
752
Jonas Ådahl1ea343e2013-10-25 23:18:05 +0200753static void
754default_grab_keyboard_cancel(struct weston_keyboard_grab *grab)
755{
756}
757
Kristian Høgsberg29139d42013-04-18 15:25:39 -0400758static const struct weston_keyboard_grab_interface
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400759 default_keyboard_grab_interface = {
Kristian Høgsbergb27901c2013-10-28 15:32:02 -0700760 default_grab_keyboard_key,
761 default_grab_keyboard_modifiers,
Jonas Ådahl1ea343e2013-10-25 23:18:05 +0200762 default_grab_keyboard_cancel,
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400763};
764
Kristian Høgsberg195b8692013-05-08 15:02:05 -0400765static void
766pointer_unmap_sprite(struct weston_pointer *pointer)
767{
Pekka Paalanenc557ff72014-11-12 16:42:52 +0200768 struct weston_surface *surface = pointer->sprite->surface;
769
770 if (weston_surface_is_mapped(surface))
771 weston_surface_unmap(surface);
Kristian Høgsberg195b8692013-05-08 15:02:05 -0400772
773 wl_list_remove(&pointer->sprite_destroy_listener.link);
Pekka Paalanenc557ff72014-11-12 16:42:52 +0200774 surface->configure = NULL;
775 surface->configure_private = NULL;
Pekka Paalanen8274d902014-08-06 19:36:51 +0300776 weston_surface_set_label_func(surface, NULL);
Jason Ekstranda7af7042013-10-12 22:38:11 -0500777 weston_view_destroy(pointer->sprite);
Kristian Høgsberg195b8692013-05-08 15:02:05 -0400778 pointer->sprite = NULL;
779}
780
781static void
782pointer_handle_sprite_destroy(struct wl_listener *listener, void *data)
783{
784 struct weston_pointer *pointer =
785 container_of(listener, struct weston_pointer,
786 sprite_destroy_listener);
787
788 pointer->sprite = NULL;
789}
790
Jonas Ådahl3e12e632013-12-02 22:05:05 +0100791static void
792weston_pointer_reset_state(struct weston_pointer *pointer)
793{
794 pointer->button_count = 0;
795}
796
Ander Conselvan de Oliveiraf84327a2014-01-29 18:47:51 +0200797static void
798weston_pointer_handle_output_destroy(struct wl_listener *listener, void *data);
799
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400800WL_EXPORT struct weston_pointer *
Giulio Camuffocdb4d292013-11-14 23:42:53 +0100801weston_pointer_create(struct weston_seat *seat)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400802{
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400803 struct weston_pointer *pointer;
804
Peter Huttererf3d62272013-08-08 11:57:05 +1000805 pointer = zalloc(sizeof *pointer);
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400806 if (pointer == NULL)
807 return NULL;
808
Jonas Ådahl2cbf2932015-07-22 12:05:38 +0800809 wl_list_init(&pointer->pointer_clients);
Giulio Camuffocdb4d292013-11-14 23:42:53 +0100810 weston_pointer_set_default_grab(pointer,
811 seat->compositor->default_pointer_grab);
Giulio Camuffo576fe2a2013-11-20 18:00:24 +0100812 wl_list_init(&pointer->focus_resource_listener.link);
813 pointer->focus_resource_listener.notify = pointer_focus_resource_destroyed;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400814 pointer->default_grab.pointer = pointer;
815 pointer->grab = &pointer->default_grab;
Giulio Camuffo6fcb3782013-11-14 23:42:50 +0100816 wl_signal_init(&pointer->motion_signal);
Emilio Pozuelo Monfortaa7a4762013-11-19 11:37:15 +0100817 wl_signal_init(&pointer->focus_signal);
Giulio Camuffo576fe2a2013-11-20 18:00:24 +0100818 wl_list_init(&pointer->focus_view_listener.link);
Jonas Ådahl3eb4ddd2016-07-22 17:52:58 +0800819 wl_signal_init(&pointer->destroy_signal);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400820
Kristian Høgsberg195b8692013-05-08 15:02:05 -0400821 pointer->sprite_destroy_listener.notify = pointer_handle_sprite_destroy;
822
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400823 /* FIXME: Pick better co-ords. */
824 pointer->x = wl_fixed_from_int(100);
825 pointer->y = wl_fixed_from_int(100);
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400826
Ander Conselvan de Oliveiraf84327a2014-01-29 18:47:51 +0200827 pointer->output_destroy_listener.notify =
828 weston_pointer_handle_output_destroy;
829 wl_signal_add(&seat->compositor->output_destroyed_signal,
830 &pointer->output_destroy_listener);
831
Derek Foremanf9318d12015-05-11 15:40:11 -0500832 pointer->sx = wl_fixed_from_int(-1000000);
833 pointer->sy = wl_fixed_from_int(-1000000);
834
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400835 return pointer;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400836}
837
838WL_EXPORT void
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400839weston_pointer_destroy(struct weston_pointer *pointer)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400840{
Jonas Ådahl3eb4ddd2016-07-22 17:52:58 +0800841 wl_signal_emit(&pointer->destroy_signal, pointer);
842
Kristian Høgsberg195b8692013-05-08 15:02:05 -0400843 if (pointer->sprite)
844 pointer_unmap_sprite(pointer);
845
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400846 /* XXX: What about pointer->resource_list? */
Neil Roberts96d790e2013-09-19 17:32:00 +0100847
Giulio Camuffo576fe2a2013-11-20 18:00:24 +0100848 wl_list_remove(&pointer->focus_resource_listener.link);
849 wl_list_remove(&pointer->focus_view_listener.link);
Ander Conselvan de Oliveiraf84327a2014-01-29 18:47:51 +0200850 wl_list_remove(&pointer->output_destroy_listener.link);
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400851 free(pointer);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400852}
853
Giulio Camuffocdb4d292013-11-14 23:42:53 +0100854void
855weston_pointer_set_default_grab(struct weston_pointer *pointer,
856 const struct weston_pointer_grab_interface *interface)
857{
858 if (interface)
859 pointer->default_grab.interface = interface;
860 else
861 pointer->default_grab.interface =
862 &default_pointer_grab_interface;
863}
864
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400865WL_EXPORT struct weston_keyboard *
866weston_keyboard_create(void)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400867{
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400868 struct weston_keyboard *keyboard;
869
Peter Huttererf3d62272013-08-08 11:57:05 +1000870 keyboard = zalloc(sizeof *keyboard);
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400871 if (keyboard == NULL)
Neil Roberts96d790e2013-09-19 17:32:00 +0100872 return NULL;
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400873
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400874 wl_list_init(&keyboard->resource_list);
Neil Roberts96d790e2013-09-19 17:32:00 +0100875 wl_list_init(&keyboard->focus_resource_list);
Giulio Camuffo576fe2a2013-11-20 18:00:24 +0100876 wl_list_init(&keyboard->focus_resource_listener.link);
877 keyboard->focus_resource_listener.notify = keyboard_focus_resource_destroyed;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400878 wl_array_init(&keyboard->keys);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400879 keyboard->default_grab.interface = &default_keyboard_grab_interface;
880 keyboard->default_grab.keyboard = keyboard;
881 keyboard->grab = &keyboard->default_grab;
882 wl_signal_init(&keyboard->focus_signal);
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400883
884 return keyboard;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400885}
886
Jonas Ådahl7395ea02013-12-03 09:14:26 +0100887static void
888weston_xkb_info_destroy(struct weston_xkb_info *xkb_info);
889
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400890WL_EXPORT void
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400891weston_keyboard_destroy(struct weston_keyboard *keyboard)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400892{
893 /* XXX: What about keyboard->resource_list? */
Neil Roberts96d790e2013-09-19 17:32:00 +0100894
Jonas Ådahl7395ea02013-12-03 09:14:26 +0100895#ifdef ENABLE_XKBCOMMON
896 if (keyboard->seat->compositor->use_xkbcommon) {
Ran Benitac9c74152014-08-19 23:59:52 +0300897 xkb_state_unref(keyboard->xkb_state.state);
Jonas Ådahl7395ea02013-12-03 09:14:26 +0100898 if (keyboard->xkb_info)
899 weston_xkb_info_destroy(keyboard->xkb_info);
Ran Benitac9c74152014-08-19 23:59:52 +0300900 xkb_keymap_unref(keyboard->pending_keymap);
Jonas Ådahl7395ea02013-12-03 09:14:26 +0100901 }
902#endif
903
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400904 wl_array_release(&keyboard->keys);
Giulio Camuffo576fe2a2013-11-20 18:00:24 +0100905 wl_list_remove(&keyboard->focus_resource_listener.link);
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400906 free(keyboard);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400907}
908
Jonas Ådahlcbfa7f72013-12-02 22:05:04 +0100909static void
910weston_touch_reset_state(struct weston_touch *touch)
911{
912 touch->num_tp = 0;
913}
914
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400915WL_EXPORT struct weston_touch *
916weston_touch_create(void)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400917{
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400918 struct weston_touch *touch;
919
Peter Huttererf3d62272013-08-08 11:57:05 +1000920 touch = zalloc(sizeof *touch);
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400921 if (touch == NULL)
922 return NULL;
923
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400924 wl_list_init(&touch->resource_list);
Neil Roberts96d790e2013-09-19 17:32:00 +0100925 wl_list_init(&touch->focus_resource_list);
Giulio Camuffo576fe2a2013-11-20 18:00:24 +0100926 wl_list_init(&touch->focus_view_listener.link);
927 touch->focus_view_listener.notify = touch_focus_view_destroyed;
928 wl_list_init(&touch->focus_resource_listener.link);
929 touch->focus_resource_listener.notify = touch_focus_resource_destroyed;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400930 touch->default_grab.interface = &default_touch_grab_interface;
931 touch->default_grab.touch = touch;
932 touch->grab = &touch->default_grab;
933 wl_signal_init(&touch->focus_signal);
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400934
935 return touch;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400936}
937
938WL_EXPORT void
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400939weston_touch_destroy(struct weston_touch *touch)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400940{
941 /* XXX: What about touch->resource_list? */
Neil Roberts96d790e2013-09-19 17:32:00 +0100942
Giulio Camuffo576fe2a2013-11-20 18:00:24 +0100943 wl_list_remove(&touch->focus_view_listener.link);
944 wl_list_remove(&touch->focus_resource_listener.link);
Kristian Høgsberga4036bb2013-05-07 23:52:07 -0400945 free(touch);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400946}
947
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400948static void
Kristian Høgsberge3148752013-05-06 23:19:49 -0400949seat_send_updated_caps(struct weston_seat *seat)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400950{
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400951 enum wl_seat_capability caps = 0;
Rob Bradford6e737f52013-09-06 17:48:19 +0100952 struct wl_resource *resource;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400953
Jonas Ådahld6e1c342013-10-17 23:04:05 +0200954 if (seat->pointer_device_count > 0)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400955 caps |= WL_SEAT_CAPABILITY_POINTER;
Jonas Ådahld6e1c342013-10-17 23:04:05 +0200956 if (seat->keyboard_device_count > 0)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400957 caps |= WL_SEAT_CAPABILITY_KEYBOARD;
Jonas Ådahld6e1c342013-10-17 23:04:05 +0200958 if (seat->touch_device_count > 0)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400959 caps |= WL_SEAT_CAPABILITY_TOUCH;
960
Rob Bradford6e737f52013-09-06 17:48:19 +0100961 wl_resource_for_each(resource, &seat->base_resource_list) {
962 wl_seat_send_capabilities(resource, caps);
Jason Ekstrand44a38632013-06-14 10:08:00 -0500963 }
Jason Ekstranda4ab5422014-04-02 19:53:45 -0500964 wl_signal_emit(&seat->updated_caps_signal, seat);
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400965}
966
Derek Foremanf9318d12015-05-11 15:40:11 -0500967
968/** Clear the pointer focus
969 *
970 * \param pointer the pointer to clear focus for.
971 *
972 * This can be used to unset pointer focus and set the co-ordinates to the
973 * arbitrary values we use for the no focus case.
974 *
975 * There's no requirement to use this function. For example, passing the
976 * results of a weston_compositor_pick_view() directly to
977 * weston_pointer_set_focus() will do the right thing when no view is found.
978 */
979WL_EXPORT void
980weston_pointer_clear_focus(struct weston_pointer *pointer)
981{
982 weston_pointer_set_focus(pointer, NULL,
983 wl_fixed_from_int(-1000000),
984 wl_fixed_from_int(-1000000));
985}
986
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400987WL_EXPORT void
Kristian Høgsberg02bbabb2013-05-06 22:15:05 -0400988weston_pointer_set_focus(struct weston_pointer *pointer,
Jason Ekstranda7af7042013-10-12 22:38:11 -0500989 struct weston_view *view,
Kristian Høgsberg02bbabb2013-05-06 22:15:05 -0400990 wl_fixed_t sx, wl_fixed_t sy)
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400991{
Jonas Ådahl2cbf2932015-07-22 12:05:38 +0800992 struct weston_pointer_client *pointer_client;
Derek Foreman1281a362015-07-31 16:55:32 -0500993 struct weston_keyboard *kbd = weston_seat_get_keyboard(pointer->seat);
Neil Roberts96d790e2013-09-19 17:32:00 +0100994 struct wl_resource *resource;
Jonas Ådahl2cbf2932015-07-22 12:05:38 +0800995 struct wl_resource *surface_resource;
Rob Bradford880ebc72013-07-22 17:31:38 +0100996 struct wl_display *display = pointer->seat->compositor->wl_display;
Kristian Høgsberg2158a882013-04-18 15:07:39 -0400997 uint32_t serial;
Neil Roberts96d790e2013-09-19 17:32:00 +0100998 struct wl_list *focus_resource_list;
Kristian Høgsbergdb1fccb2014-02-05 17:14:42 -0800999 int refocus = 0;
Jason Ekstranda7af7042013-10-12 22:38:11 -05001000
1001 if ((!pointer->focus && view) ||
1002 (pointer->focus && !view) ||
Kristian Høgsbergdb1fccb2014-02-05 17:14:42 -08001003 (pointer->focus && pointer->focus->surface != view->surface) ||
1004 pointer->sx != sx || pointer->sy != sy)
1005 refocus = 1;
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001006
Jonas Ådahl2cbf2932015-07-22 12:05:38 +08001007 if (pointer->focus_client && refocus) {
1008 focus_resource_list = &pointer->focus_client->pointer_resources;
1009 if (!wl_list_empty(focus_resource_list)) {
1010 serial = wl_display_next_serial(display);
1011 surface_resource = pointer->focus->surface->resource;
1012 wl_resource_for_each(resource, focus_resource_list) {
1013 wl_pointer_send_leave(resource, serial,
1014 surface_resource);
Peter Hutterer87743e92016-01-18 16:38:22 +10001015 pointer_send_frame(resource);
Jonas Ådahl2cbf2932015-07-22 12:05:38 +08001016 }
Neil Roberts96d790e2013-09-19 17:32:00 +01001017 }
1018
Jonas Ådahl2cbf2932015-07-22 12:05:38 +08001019 pointer->focus_client = NULL;
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001020 }
1021
Jonas Ådahl2cbf2932015-07-22 12:05:38 +08001022 pointer_client = find_pointer_client_for_view(pointer, view);
1023 if (pointer_client && refocus) {
1024 struct wl_client *surface_client = pointer_client->client;
Neil Roberts96d790e2013-09-19 17:32:00 +01001025
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001026 serial = wl_display_next_serial(display);
Neil Roberts96d790e2013-09-19 17:32:00 +01001027
Jason Ekstranda7af7042013-10-12 22:38:11 -05001028 if (kbd && kbd->focus != view->surface)
Kristian Høgsbergcb406f12013-10-09 10:54:03 -07001029 send_modifiers_to_client_in_list(surface_client,
1030 &kbd->resource_list,
1031 serial,
1032 kbd);
1033
Jonas Ådahl2cbf2932015-07-22 12:05:38 +08001034 pointer->focus_client = pointer_client;
Neil Roberts96d790e2013-09-19 17:32:00 +01001035
Jonas Ådahl2cbf2932015-07-22 12:05:38 +08001036 focus_resource_list = &pointer->focus_client->pointer_resources;
Neil Roberts96d790e2013-09-19 17:32:00 +01001037 wl_resource_for_each(resource, focus_resource_list) {
1038 wl_pointer_send_enter(resource,
1039 serial,
Jason Ekstranda7af7042013-10-12 22:38:11 -05001040 view->surface->resource,
Neil Roberts96d790e2013-09-19 17:32:00 +01001041 sx, sy);
Peter Hutterer87743e92016-01-18 16:38:22 +10001042 pointer_send_frame(resource);
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001043 }
Neil Roberts96d790e2013-09-19 17:32:00 +01001044
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001045 pointer->focus_serial = serial;
1046 }
1047
Giulio Camuffo65a07f82013-12-06 12:46:27 +01001048 wl_list_remove(&pointer->focus_view_listener.link);
1049 wl_list_init(&pointer->focus_view_listener.link);
1050 wl_list_remove(&pointer->focus_resource_listener.link);
1051 wl_list_init(&pointer->focus_resource_listener.link);
Emilio Pozuelo Monfortaa7a4762013-11-19 11:37:15 +01001052 if (view)
Giulio Camuffo576fe2a2013-11-20 18:00:24 +01001053 wl_signal_add(&view->destroy_signal, &pointer->focus_view_listener);
Giulio Camuffo65a07f82013-12-06 12:46:27 +01001054 if (view && view->surface->resource)
1055 wl_resource_add_destroy_listener(view->surface->resource,
1056 &pointer->focus_resource_listener);
1057
1058 pointer->focus = view;
1059 pointer->focus_view_listener.notify = pointer_focus_view_destroyed;
Kristian Høgsbergdb1fccb2014-02-05 17:14:42 -08001060 pointer->sx = sx;
1061 pointer->sy = sy;
1062
Derek Foremanf9318d12015-05-11 15:40:11 -05001063 assert(view || sx == wl_fixed_from_int(-1000000));
1064 assert(view || sy == wl_fixed_from_int(-1000000));
1065
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001066 wl_signal_emit(&pointer->focus_signal, pointer);
1067}
1068
Neil Roberts96d790e2013-09-19 17:32:00 +01001069static void
1070send_enter_to_resource_list(struct wl_list *list,
1071 struct weston_keyboard *keyboard,
1072 struct weston_surface *surface,
1073 uint32_t serial)
1074{
1075 struct wl_resource *resource;
1076
1077 wl_resource_for_each(resource, list) {
1078 send_modifiers_to_resource(keyboard, resource, serial);
1079 wl_keyboard_send_enter(resource, serial,
1080 surface->resource,
1081 &keyboard->keys);
1082 }
1083}
1084
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001085WL_EXPORT void
Kristian Høgsberg29139d42013-04-18 15:25:39 -04001086weston_keyboard_set_focus(struct weston_keyboard *keyboard,
Kristian Høgsbergfe7aa902013-05-08 09:54:37 -04001087 struct weston_surface *surface)
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001088{
1089 struct wl_resource *resource;
Rob Bradford880ebc72013-07-22 17:31:38 +01001090 struct wl_display *display = keyboard->seat->compositor->wl_display;
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001091 uint32_t serial;
Neil Roberts96d790e2013-09-19 17:32:00 +01001092 struct wl_list *focus_resource_list;
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001093
Neil Roberts96d790e2013-09-19 17:32:00 +01001094 focus_resource_list = &keyboard->focus_resource_list;
1095
1096 if (!wl_list_empty(focus_resource_list) && keyboard->focus != surface) {
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001097 serial = wl_display_next_serial(display);
Neil Roberts96d790e2013-09-19 17:32:00 +01001098 wl_resource_for_each(resource, focus_resource_list) {
1099 wl_keyboard_send_leave(resource, serial,
1100 keyboard->focus->resource);
1101 }
1102 move_resources(&keyboard->resource_list, focus_resource_list);
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001103 }
1104
Neil Roberts96d790e2013-09-19 17:32:00 +01001105 if (find_resource_for_surface(&keyboard->resource_list, surface) &&
1106 keyboard->focus != surface) {
1107 struct wl_client *surface_client =
1108 wl_resource_get_client(surface->resource);
1109
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001110 serial = wl_display_next_serial(display);
Neil Roberts96d790e2013-09-19 17:32:00 +01001111
1112 move_resources_for_client(focus_resource_list,
1113 &keyboard->resource_list,
1114 surface_client);
1115 send_enter_to_resource_list(focus_resource_list,
1116 keyboard,
1117 surface,
1118 serial);
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001119 keyboard->focus_serial = serial;
Giulio Camuffo65a07f82013-12-06 12:46:27 +01001120 }
1121
1122 wl_list_remove(&keyboard->focus_resource_listener.link);
1123 wl_list_init(&keyboard->focus_resource_listener.link);
1124 if (surface && surface->resource)
Giulio Camuffo576fe2a2013-11-20 18:00:24 +01001125 wl_resource_add_destroy_listener(surface->resource,
1126 &keyboard->focus_resource_listener);
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001127
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001128 keyboard->focus = surface;
1129 wl_signal_emit(&keyboard->focus_signal, keyboard);
1130}
1131
Giulio Camuffoa20ca812014-11-22 11:16:56 +02001132/* Users of this function must manually manage the keyboard focus */
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001133WL_EXPORT void
Kristian Høgsberg29139d42013-04-18 15:25:39 -04001134weston_keyboard_start_grab(struct weston_keyboard *keyboard,
1135 struct weston_keyboard_grab *grab)
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001136{
1137 keyboard->grab = grab;
1138 grab->keyboard = keyboard;
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001139}
1140
1141WL_EXPORT void
Kristian Høgsberg29139d42013-04-18 15:25:39 -04001142weston_keyboard_end_grab(struct weston_keyboard *keyboard)
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001143{
1144 keyboard->grab = &keyboard->default_grab;
1145}
1146
Jonas Ådahl1ea343e2013-10-25 23:18:05 +02001147static void
1148weston_keyboard_cancel_grab(struct weston_keyboard *keyboard)
1149{
1150 keyboard->grab->interface->cancel(keyboard->grab);
1151}
1152
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001153WL_EXPORT void
Kristian Høgsberg02bbabb2013-05-06 22:15:05 -04001154weston_pointer_start_grab(struct weston_pointer *pointer,
1155 struct weston_pointer_grab *grab)
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001156{
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001157 pointer->grab = grab;
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001158 grab->pointer = pointer;
Kristian Høgsbergda751b82013-07-04 00:58:07 -04001159 pointer->grab->interface->focus(pointer->grab);
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001160}
1161
1162WL_EXPORT void
Kristian Høgsberg02bbabb2013-05-06 22:15:05 -04001163weston_pointer_end_grab(struct weston_pointer *pointer)
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001164{
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001165 pointer->grab = &pointer->default_grab;
Kristian Høgsbergda751b82013-07-04 00:58:07 -04001166 pointer->grab->interface->focus(pointer->grab);
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001167}
1168
Jonas Ådahl1ea343e2013-10-25 23:18:05 +02001169static void
1170weston_pointer_cancel_grab(struct weston_pointer *pointer)
1171{
1172 pointer->grab->interface->cancel(pointer->grab);
1173}
1174
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001175WL_EXPORT void
Kristian Høgsberge329f362013-05-06 22:19:57 -04001176weston_touch_start_grab(struct weston_touch *touch, struct weston_touch_grab *grab)
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001177{
1178 touch->grab = grab;
1179 grab->touch = touch;
1180}
1181
1182WL_EXPORT void
Kristian Høgsberge329f362013-05-06 22:19:57 -04001183weston_touch_end_grab(struct weston_touch *touch)
Kristian Høgsberg2158a882013-04-18 15:07:39 -04001184{
1185 touch->grab = &touch->default_grab;
1186}
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001187
Jonas Ådahl1ea343e2013-10-25 23:18:05 +02001188static void
1189weston_touch_cancel_grab(struct weston_touch *touch)
1190{
1191 touch->grab->interface->cancel(touch->grab);
1192}
1193
Ander Conselvan de Oliveira54e90c72013-12-13 22:10:56 +02001194static void
1195weston_pointer_clamp_for_output(struct weston_pointer *pointer,
1196 struct weston_output *output,
1197 wl_fixed_t *fx, wl_fixed_t *fy)
1198{
1199 int x, y;
1200
1201 x = wl_fixed_to_int(*fx);
1202 y = wl_fixed_to_int(*fy);
1203
1204 if (x < output->x)
1205 *fx = wl_fixed_from_int(output->x);
1206 else if (x >= output->x + output->width)
1207 *fx = wl_fixed_from_int(output->x +
1208 output->width - 1);
1209 if (y < output->y)
1210 *fy = wl_fixed_from_int(output->y);
1211 else if (y >= output->y + output->height)
1212 *fy = wl_fixed_from_int(output->y +
1213 output->height - 1);
1214}
1215
Rob Bradford806d8c02013-06-25 18:56:41 +01001216WL_EXPORT void
1217weston_pointer_clamp(struct weston_pointer *pointer, wl_fixed_t *fx, wl_fixed_t *fy)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001218{
Rob Bradford806d8c02013-06-25 18:56:41 +01001219 struct weston_compositor *ec = pointer->seat->compositor;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001220 struct weston_output *output, *prev = NULL;
1221 int x, y, old_x, old_y, valid = 0;
1222
1223 x = wl_fixed_to_int(*fx);
1224 y = wl_fixed_to_int(*fy);
Rob Bradford806d8c02013-06-25 18:56:41 +01001225 old_x = wl_fixed_to_int(pointer->x);
1226 old_y = wl_fixed_to_int(pointer->y);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001227
1228 wl_list_for_each(output, &ec->output_list, link) {
Rob Bradford66bd9f52013-06-25 18:56:42 +01001229 if (pointer->seat->output && pointer->seat->output != output)
1230 continue;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001231 if (pixman_region32_contains_point(&output->region,
1232 x, y, NULL))
1233 valid = 1;
1234 if (pixman_region32_contains_point(&output->region,
1235 old_x, old_y, NULL))
1236 prev = output;
1237 }
1238
Rob Bradford66bd9f52013-06-25 18:56:42 +01001239 if (!prev)
1240 prev = pointer->seat->output;
1241
Ander Conselvan de Oliveira54e90c72013-12-13 22:10:56 +02001242 if (prev && !valid)
1243 weston_pointer_clamp_for_output(pointer, prev, fx, fy);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001244}
1245
Jonas Ådahld2510102014-10-05 21:39:14 +02001246static void
1247weston_pointer_move_to(struct weston_pointer *pointer,
1248 wl_fixed_t x, wl_fixed_t y)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001249{
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001250 int32_t ix, iy;
1251
Rob Bradford806d8c02013-06-25 18:56:41 +01001252 weston_pointer_clamp (pointer, &x, &y);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001253
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001254 pointer->x = x;
1255 pointer->y = y;
1256
1257 ix = wl_fixed_to_int(x);
1258 iy = wl_fixed_to_int(y);
1259
Kristian Høgsberg195b8692013-05-08 15:02:05 -04001260 if (pointer->sprite) {
Jason Ekstranda7af7042013-10-12 22:38:11 -05001261 weston_view_set_position(pointer->sprite,
1262 ix - pointer->hotspot_x,
1263 iy - pointer->hotspot_y);
1264 weston_view_schedule_repaint(pointer->sprite);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001265 }
Giulio Camuffo6fcb3782013-11-14 23:42:50 +01001266
Giulio Camuffo1959ab82013-11-14 23:42:52 +01001267 pointer->grab->interface->focus(pointer->grab);
Giulio Camuffo6fcb3782013-11-14 23:42:50 +01001268 wl_signal_emit(&pointer->motion_signal, pointer);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001269}
1270
Jonas Ådahld2510102014-10-05 21:39:14 +02001271WL_EXPORT void
Jonas Ådahld2510102014-10-05 21:39:14 +02001272weston_pointer_move(struct weston_pointer *pointer,
1273 struct weston_pointer_motion_event *event)
1274{
1275 wl_fixed_t x, y;
1276
1277 weston_pointer_motion_to_abs(pointer, event, &x, &y);
1278 weston_pointer_move_to(pointer, x, y);
1279}
1280
Ander Conselvan de Oliveira54e90c72013-12-13 22:10:56 +02001281/** Verify if the pointer is in a valid position and move it if it isn't.
1282 */
Ander Conselvan de Oliveiraf84327a2014-01-29 18:47:51 +02001283static void
1284weston_pointer_handle_output_destroy(struct wl_listener *listener, void *data)
Ander Conselvan de Oliveira54e90c72013-12-13 22:10:56 +02001285{
Ander Conselvan de Oliveiraf84327a2014-01-29 18:47:51 +02001286 struct weston_pointer *pointer;
1287 struct weston_compositor *ec;
Ander Conselvan de Oliveira54e90c72013-12-13 22:10:56 +02001288 struct weston_output *output, *closest = NULL;
1289 int x, y, distance, min = INT_MAX;
1290 wl_fixed_t fx, fy;
1291
Ander Conselvan de Oliveiraf84327a2014-01-29 18:47:51 +02001292 pointer = container_of(listener, struct weston_pointer,
1293 output_destroy_listener);
1294 ec = pointer->seat->compositor;
1295
Ander Conselvan de Oliveira54e90c72013-12-13 22:10:56 +02001296 x = wl_fixed_to_int(pointer->x);
1297 y = wl_fixed_to_int(pointer->y);
1298
1299 wl_list_for_each(output, &ec->output_list, link) {
1300 if (pixman_region32_contains_point(&output->region,
1301 x, y, NULL))
1302 return;
1303
1304 /* Aproximante the distance from the pointer to the center of
1305 * the output. */
1306 distance = abs(output->x + output->width / 2 - x) +
1307 abs(output->y + output->height / 2 - y);
1308 if (distance < min) {
1309 min = distance;
1310 closest = output;
1311 }
1312 }
1313
1314 /* Nothing to do if there's no output left. */
1315 if (!closest)
1316 return;
1317
1318 fx = pointer->x;
1319 fy = pointer->y;
1320
1321 weston_pointer_clamp_for_output(pointer, closest, &fx, &fy);
Jonas Ådahld2510102014-10-05 21:39:14 +02001322 weston_pointer_move_to(pointer, fx, fy);
Ander Conselvan de Oliveira54e90c72013-12-13 22:10:56 +02001323}
1324
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001325WL_EXPORT void
1326notify_motion(struct weston_seat *seat,
Jonas Ådahld2510102014-10-05 21:39:14 +02001327 uint32_t time,
1328 struct weston_pointer_motion_event *event)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001329{
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001330 struct weston_compositor *ec = seat->compositor;
Derek Foreman1281a362015-07-31 16:55:32 -05001331 struct weston_pointer *pointer = weston_seat_get_pointer(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001332
1333 weston_compositor_wake(ec);
Jonas Ådahld2510102014-10-05 21:39:14 +02001334 pointer->grab->interface->motion(pointer->grab, time, event);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001335}
1336
Daniel Stone96d47c02013-11-19 11:37:12 +01001337static void
1338run_modifier_bindings(struct weston_seat *seat, uint32_t old, uint32_t new)
1339{
1340 struct weston_compositor *compositor = seat->compositor;
Derek Foreman1281a362015-07-31 16:55:32 -05001341 struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
Daniel Stone96d47c02013-11-19 11:37:12 +01001342 uint32_t diff;
1343 unsigned int i;
1344 struct {
1345 uint32_t xkb;
1346 enum weston_keyboard_modifier weston;
1347 } mods[] = {
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001348 { keyboard->xkb_info->ctrl_mod, MODIFIER_CTRL },
1349 { keyboard->xkb_info->alt_mod, MODIFIER_ALT },
1350 { keyboard->xkb_info->super_mod, MODIFIER_SUPER },
1351 { keyboard->xkb_info->shift_mod, MODIFIER_SHIFT },
Daniel Stone96d47c02013-11-19 11:37:12 +01001352 };
1353
1354 diff = new & ~old;
1355 for (i = 0; i < ARRAY_LENGTH(mods); i++) {
1356 if (diff & (1 << mods[i].xkb))
1357 weston_compositor_run_modifier_binding(compositor,
Derek Foreman99a6a2d2015-07-15 13:00:43 -05001358 keyboard,
Daniel Stone96d47c02013-11-19 11:37:12 +01001359 mods[i].weston,
1360 WL_KEYBOARD_KEY_STATE_PRESSED);
1361 }
1362
1363 diff = old & ~new;
1364 for (i = 0; i < ARRAY_LENGTH(mods); i++) {
1365 if (diff & (1 << mods[i].xkb))
1366 weston_compositor_run_modifier_binding(compositor,
Derek Foreman99a6a2d2015-07-15 13:00:43 -05001367 keyboard,
Daniel Stone96d47c02013-11-19 11:37:12 +01001368 mods[i].weston,
1369 WL_KEYBOARD_KEY_STATE_RELEASED);
1370 }
1371}
1372
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001373WL_EXPORT void
1374notify_motion_absolute(struct weston_seat *seat,
Giulio Camuffo90a6fc62016-03-22 17:44:54 +02001375 uint32_t time, double x, double y)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001376{
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001377 struct weston_compositor *ec = seat->compositor;
Derek Foreman1281a362015-07-31 16:55:32 -05001378 struct weston_pointer *pointer = weston_seat_get_pointer(seat);
Jonas Ådahld2510102014-10-05 21:39:14 +02001379 struct weston_pointer_motion_event event = { 0 };
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001380
1381 weston_compositor_wake(ec);
Jonas Ådahld2510102014-10-05 21:39:14 +02001382
1383 event = (struct weston_pointer_motion_event) {
1384 .mask = WESTON_POINTER_MOTION_ABS,
Giulio Camuffo90a6fc62016-03-22 17:44:54 +02001385 .x = x,
1386 .y = y,
Jonas Ådahld2510102014-10-05 21:39:14 +02001387 };
1388
1389 pointer->grab->interface->motion(pointer->grab, time, &event);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001390}
1391
Jonas Ådahl94e2e2d2014-10-18 18:42:19 +02001392static unsigned int
1393peek_next_activate_serial(struct weston_compositor *c)
1394{
1395 unsigned serial = c->activate_serial + 1;
1396
1397 return serial == 0 ? 1 : serial;
1398}
1399
1400static void
1401inc_activate_serial(struct weston_compositor *c)
1402{
1403 c->activate_serial = peek_next_activate_serial (c);
1404}
1405
1406WL_EXPORT void
1407weston_view_activate(struct weston_view *view,
1408 struct weston_seat *seat,
1409 uint32_t flags)
1410{
1411 struct weston_compositor *compositor = seat->compositor;
1412
1413 if (flags & WESTON_ACTIVATE_FLAG_CLICKED) {
1414 view->click_to_activate_serial =
1415 peek_next_activate_serial(compositor);
1416 }
1417
1418 weston_seat_set_keyboard_focus(seat, view->surface);
1419}
1420
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001421WL_EXPORT void
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001422notify_button(struct weston_seat *seat, uint32_t time, int32_t button,
1423 enum wl_pointer_button_state state)
1424{
1425 struct weston_compositor *compositor = seat->compositor;
Derek Foreman1281a362015-07-31 16:55:32 -05001426 struct weston_pointer *pointer = weston_seat_get_pointer(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001427
1428 if (state == WL_POINTER_BUTTON_STATE_PRESSED) {
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001429 weston_compositor_idle_inhibit(compositor);
1430 if (pointer->button_count == 0) {
1431 pointer->grab_button = button;
1432 pointer->grab_time = time;
1433 pointer->grab_x = pointer->x;
1434 pointer->grab_y = pointer->y;
1435 }
1436 pointer->button_count++;
1437 } else {
1438 weston_compositor_idle_release(compositor);
1439 pointer->button_count--;
1440 }
1441
Derek Foreman99a6a2d2015-07-15 13:00:43 -05001442 weston_compositor_run_button_binding(compositor, pointer, time, button,
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001443 state);
1444
1445 pointer->grab->interface->button(pointer->grab, time, button, state);
1446
1447 if (pointer->button_count == 1)
1448 pointer->grab_serial =
1449 wl_display_get_serial(compositor->wl_display);
1450}
1451
1452WL_EXPORT void
Peter Hutterer89b6a492016-01-18 15:58:17 +10001453notify_axis(struct weston_seat *seat, uint32_t time,
1454 struct weston_pointer_axis_event *event)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001455{
1456 struct weston_compositor *compositor = seat->compositor;
Derek Foreman1281a362015-07-31 16:55:32 -05001457 struct weston_pointer *pointer = weston_seat_get_pointer(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001458
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001459 weston_compositor_wake(compositor);
1460
Derek Foreman99a6a2d2015-07-15 13:00:43 -05001461 if (weston_compositor_run_axis_binding(compositor, pointer,
Peter Hutterer89b6a492016-01-18 15:58:17 +10001462 time, event))
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001463 return;
1464
Peter Hutterer89b6a492016-01-18 15:58:17 +10001465 pointer->grab->interface->axis(pointer->grab, time, event);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001466}
1467
Peter Hutterer87743e92016-01-18 16:38:22 +10001468WL_EXPORT void
1469notify_axis_source(struct weston_seat *seat, uint32_t source)
1470{
1471 struct weston_compositor *compositor = seat->compositor;
1472 struct weston_pointer *pointer = weston_seat_get_pointer(seat);
1473
1474 weston_compositor_wake(compositor);
1475
1476 pointer->grab->interface->axis_source(pointer->grab, source);
1477}
1478
1479WL_EXPORT void
1480notify_pointer_frame(struct weston_seat *seat)
1481{
1482 struct weston_compositor *compositor = seat->compositor;
1483 struct weston_pointer *pointer = weston_seat_get_pointer(seat);
1484
1485 weston_compositor_wake(compositor);
1486
1487 pointer->grab->interface->frame(pointer->grab);
1488}
1489
Giulio Camuffo6ef444d2014-08-28 19:44:09 +03001490WL_EXPORT int
1491weston_keyboard_set_locks(struct weston_keyboard *keyboard,
1492 uint32_t mask, uint32_t value)
1493{
1494#ifdef ENABLE_XKBCOMMON
1495 uint32_t serial;
1496 xkb_mod_mask_t mods_depressed, mods_latched, mods_locked, group;
1497 xkb_mod_mask_t num, caps;
1498
1499 /* We don't want the leds to go out of sync with the actual state
1500 * so if the backend has no way to change the leds don't try to
1501 * change the state */
1502 if (!keyboard->seat->led_update)
1503 return -1;
1504
1505 mods_depressed = xkb_state_serialize_mods(keyboard->xkb_state.state,
1506 XKB_STATE_DEPRESSED);
1507 mods_latched = xkb_state_serialize_mods(keyboard->xkb_state.state,
1508 XKB_STATE_LATCHED);
1509 mods_locked = xkb_state_serialize_mods(keyboard->xkb_state.state,
1510 XKB_STATE_LOCKED);
1511 group = xkb_state_serialize_group(keyboard->xkb_state.state,
1512 XKB_STATE_EFFECTIVE);
1513
1514 num = (1 << keyboard->xkb_info->mod2_mod);
1515 caps = (1 << keyboard->xkb_info->caps_mod);
1516 if (mask & WESTON_NUM_LOCK) {
1517 if (value & WESTON_NUM_LOCK)
1518 mods_locked |= num;
1519 else
1520 mods_locked &= ~num;
1521 }
1522 if (mask & WESTON_CAPS_LOCK) {
1523 if (value & WESTON_CAPS_LOCK)
1524 mods_locked |= caps;
1525 else
1526 mods_locked &= ~caps;
1527 }
1528
1529 xkb_state_update_mask(keyboard->xkb_state.state, mods_depressed,
1530 mods_latched, mods_locked, 0, 0, group);
1531
1532 serial = wl_display_next_serial(
1533 keyboard->seat->compositor->wl_display);
1534 notify_modifiers(keyboard->seat, serial);
1535
1536 return 0;
1537#else
1538 return -1;
1539#endif
1540}
1541
Rob Bradford382ff462013-06-24 16:52:45 +01001542#ifdef ENABLE_XKBCOMMON
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001543WL_EXPORT void
1544notify_modifiers(struct weston_seat *seat, uint32_t serial)
1545{
Derek Foreman1281a362015-07-31 16:55:32 -05001546 struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001547 struct weston_keyboard_grab *grab = keyboard->grab;
1548 uint32_t mods_depressed, mods_latched, mods_locked, group;
1549 uint32_t mods_lookup;
1550 enum weston_led leds = 0;
1551 int changed = 0;
1552
1553 /* Serialize and update our internal state, checking to see if it's
1554 * different to the previous state. */
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001555 mods_depressed = xkb_state_serialize_mods(keyboard->xkb_state.state,
Ran Benita2e1968f2014-08-19 23:59:51 +03001556 XKB_STATE_MODS_DEPRESSED);
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001557 mods_latched = xkb_state_serialize_mods(keyboard->xkb_state.state,
Ran Benita2e1968f2014-08-19 23:59:51 +03001558 XKB_STATE_MODS_LATCHED);
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001559 mods_locked = xkb_state_serialize_mods(keyboard->xkb_state.state,
Ran Benita2e1968f2014-08-19 23:59:51 +03001560 XKB_STATE_MODS_LOCKED);
1561 group = xkb_state_serialize_layout(keyboard->xkb_state.state,
1562 XKB_STATE_LAYOUT_EFFECTIVE);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001563
Derek Foreman244e99e2015-06-03 15:53:26 -05001564 if (mods_depressed != keyboard->modifiers.mods_depressed ||
1565 mods_latched != keyboard->modifiers.mods_latched ||
1566 mods_locked != keyboard->modifiers.mods_locked ||
1567 group != keyboard->modifiers.group)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001568 changed = 1;
1569
Derek Foreman244e99e2015-06-03 15:53:26 -05001570 run_modifier_bindings(seat, keyboard->modifiers.mods_depressed,
Daniel Stone96d47c02013-11-19 11:37:12 +01001571 mods_depressed);
1572
Derek Foreman244e99e2015-06-03 15:53:26 -05001573 keyboard->modifiers.mods_depressed = mods_depressed;
1574 keyboard->modifiers.mods_latched = mods_latched;
1575 keyboard->modifiers.mods_locked = mods_locked;
1576 keyboard->modifiers.group = group;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001577
1578 /* And update the modifier_state for bindings. */
1579 mods_lookup = mods_depressed | mods_latched;
1580 seat->modifier_state = 0;
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001581 if (mods_lookup & (1 << keyboard->xkb_info->ctrl_mod))
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001582 seat->modifier_state |= MODIFIER_CTRL;
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001583 if (mods_lookup & (1 << keyboard->xkb_info->alt_mod))
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001584 seat->modifier_state |= MODIFIER_ALT;
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001585 if (mods_lookup & (1 << keyboard->xkb_info->super_mod))
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001586 seat->modifier_state |= MODIFIER_SUPER;
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001587 if (mods_lookup & (1 << keyboard->xkb_info->shift_mod))
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001588 seat->modifier_state |= MODIFIER_SHIFT;
1589
1590 /* Finally, notify the compositor that LEDs have changed. */
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001591 if (xkb_state_led_index_is_active(keyboard->xkb_state.state,
1592 keyboard->xkb_info->num_led))
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001593 leds |= LED_NUM_LOCK;
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001594 if (xkb_state_led_index_is_active(keyboard->xkb_state.state,
1595 keyboard->xkb_info->caps_led))
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001596 leds |= LED_CAPS_LOCK;
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001597 if (xkb_state_led_index_is_active(keyboard->xkb_state.state,
1598 keyboard->xkb_info->scroll_led))
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001599 leds |= LED_SCROLL_LOCK;
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001600 if (leds != keyboard->xkb_state.leds && seat->led_update)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001601 seat->led_update(seat, leds);
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001602 keyboard->xkb_state.leds = leds;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001603
1604 if (changed) {
1605 grab->interface->modifiers(grab,
1606 serial,
1607 keyboard->modifiers.mods_depressed,
1608 keyboard->modifiers.mods_latched,
1609 keyboard->modifiers.mods_locked,
1610 keyboard->modifiers.group);
1611 }
1612}
1613
1614static void
1615update_modifier_state(struct weston_seat *seat, uint32_t serial, uint32_t key,
1616 enum wl_keyboard_key_state state)
1617{
Derek Foreman1281a362015-07-31 16:55:32 -05001618 struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001619 enum xkb_key_direction direction;
1620
Matt Roper01a92732013-06-24 16:52:44 +01001621 /* Keyboard modifiers don't exist in raw keyboard mode */
1622 if (!seat->compositor->use_xkbcommon)
1623 return;
1624
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001625 if (state == WL_KEYBOARD_KEY_STATE_PRESSED)
1626 direction = XKB_KEY_DOWN;
1627 else
1628 direction = XKB_KEY_UP;
1629
1630 /* Offset the keycode by 8, as the evdev XKB rules reflect X's
1631 * broken keycode system, which starts at 8. */
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001632 xkb_state_update_key(keyboard->xkb_state.state, key + 8, direction);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001633
1634 notify_modifiers(seat, serial);
1635}
Rui Matos65196bc2013-10-10 19:44:19 +02001636
1637static void
1638send_keymap(struct wl_resource *resource, struct weston_xkb_info *xkb_info)
1639{
1640 wl_keyboard_send_keymap(resource,
1641 WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1,
1642 xkb_info->keymap_fd,
1643 xkb_info->keymap_size);
1644}
1645
1646static void
1647send_modifiers(struct wl_resource *resource, uint32_t serial, struct weston_keyboard *keyboard)
1648{
1649 wl_keyboard_send_modifiers(resource, serial,
1650 keyboard->modifiers.mods_depressed,
1651 keyboard->modifiers.mods_latched,
1652 keyboard->modifiers.mods_locked,
1653 keyboard->modifiers.group);
1654}
1655
1656static struct weston_xkb_info *
1657weston_xkb_info_create(struct xkb_keymap *keymap);
Rui Matos65196bc2013-10-10 19:44:19 +02001658
1659static void
1660update_keymap(struct weston_seat *seat)
1661{
Derek Foreman1281a362015-07-31 16:55:32 -05001662 struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
Rui Matos65196bc2013-10-10 19:44:19 +02001663 struct wl_resource *resource;
1664 struct weston_xkb_info *xkb_info;
1665 struct xkb_state *state;
1666 xkb_mod_mask_t latched_mods;
1667 xkb_mod_mask_t locked_mods;
1668
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001669 xkb_info = weston_xkb_info_create(keyboard->pending_keymap);
Rui Matos65196bc2013-10-10 19:44:19 +02001670
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001671 xkb_keymap_unref(keyboard->pending_keymap);
1672 keyboard->pending_keymap = NULL;
Rui Matos65196bc2013-10-10 19:44:19 +02001673
1674 if (!xkb_info) {
1675 weston_log("failed to create XKB info\n");
1676 return;
1677 }
1678
1679 state = xkb_state_new(xkb_info->keymap);
1680 if (!state) {
1681 weston_log("failed to initialise XKB state\n");
1682 weston_xkb_info_destroy(xkb_info);
1683 return;
1684 }
1685
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001686 latched_mods = xkb_state_serialize_mods(keyboard->xkb_state.state,
1687 XKB_STATE_MODS_LATCHED);
1688 locked_mods = xkb_state_serialize_mods(keyboard->xkb_state.state,
1689 XKB_STATE_MODS_LOCKED);
Rui Matos65196bc2013-10-10 19:44:19 +02001690 xkb_state_update_mask(state,
1691 0, /* depressed */
1692 latched_mods,
1693 locked_mods,
1694 0, 0, 0);
1695
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001696 weston_xkb_info_destroy(keyboard->xkb_info);
1697 keyboard->xkb_info = xkb_info;
Rui Matos65196bc2013-10-10 19:44:19 +02001698
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001699 xkb_state_unref(keyboard->xkb_state.state);
1700 keyboard->xkb_state.state = state;
Rui Matos65196bc2013-10-10 19:44:19 +02001701
Derek Foremanbc91e542015-06-03 15:53:27 -05001702 wl_resource_for_each(resource, &keyboard->resource_list)
Rui Matos65196bc2013-10-10 19:44:19 +02001703 send_keymap(resource, xkb_info);
Derek Foremanbc91e542015-06-03 15:53:27 -05001704 wl_resource_for_each(resource, &keyboard->focus_resource_list)
Rui Matos65196bc2013-10-10 19:44:19 +02001705 send_keymap(resource, xkb_info);
1706
1707 notify_modifiers(seat, wl_display_next_serial(seat->compositor->wl_display));
1708
1709 if (!latched_mods && !locked_mods)
1710 return;
1711
Derek Foremanbc91e542015-06-03 15:53:27 -05001712 wl_resource_for_each(resource, &keyboard->resource_list)
1713 send_modifiers(resource, wl_display_get_serial(seat->compositor->wl_display), keyboard);
1714 wl_resource_for_each(resource, &keyboard->focus_resource_list)
1715 send_modifiers(resource, wl_display_get_serial(seat->compositor->wl_display), keyboard);
Rui Matos65196bc2013-10-10 19:44:19 +02001716}
Rob Bradford382ff462013-06-24 16:52:45 +01001717#else
1718WL_EXPORT void
1719notify_modifiers(struct weston_seat *seat, uint32_t serial)
1720{
1721}
1722
1723static void
1724update_modifier_state(struct weston_seat *seat, uint32_t serial, uint32_t key,
1725 enum wl_keyboard_key_state state)
1726{
1727}
Rui Matos65196bc2013-10-10 19:44:19 +02001728
1729static void
1730update_keymap(struct weston_seat *seat)
1731{
1732}
Rob Bradford382ff462013-06-24 16:52:45 +01001733#endif
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001734
1735WL_EXPORT void
1736notify_key(struct weston_seat *seat, uint32_t time, uint32_t key,
1737 enum wl_keyboard_key_state state,
1738 enum weston_key_state_update update_state)
1739{
1740 struct weston_compositor *compositor = seat->compositor;
Derek Foreman1281a362015-07-31 16:55:32 -05001741 struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001742 struct weston_keyboard_grab *grab = keyboard->grab;
Pekka Paalanen86b53962014-11-19 13:43:32 +02001743 uint32_t *k, *end;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001744
1745 if (state == WL_KEYBOARD_KEY_STATE_PRESSED) {
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001746 weston_compositor_idle_inhibit(compositor);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001747 } else {
1748 weston_compositor_idle_release(compositor);
1749 }
1750
Pekka Paalanen86b53962014-11-19 13:43:32 +02001751 end = keyboard->keys.data + keyboard->keys.size;
1752 for (k = keyboard->keys.data; k < end; k++) {
1753 if (*k == key) {
1754 /* Ignore server-generated repeats. */
1755 if (state == WL_KEYBOARD_KEY_STATE_PRESSED)
1756 return;
1757 *k = *--end;
1758 }
1759 }
1760 keyboard->keys.size = (void *) end - keyboard->keys.data;
1761 if (state == WL_KEYBOARD_KEY_STATE_PRESSED) {
1762 k = wl_array_add(&keyboard->keys, sizeof *k);
1763 *k = key;
1764 }
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001765
1766 if (grab == &keyboard->default_grab ||
1767 grab == &keyboard->input_method_grab) {
Derek Foreman99a6a2d2015-07-15 13:00:43 -05001768 weston_compositor_run_key_binding(compositor, keyboard, time,
1769 key, state);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001770 grab = keyboard->grab;
1771 }
1772
1773 grab->interface->key(grab, time, key, state);
1774
Jonas Ådahl7395ea02013-12-03 09:14:26 +01001775 if (keyboard->pending_keymap &&
Pekka Paalanen86b53962014-11-19 13:43:32 +02001776 keyboard->keys.size == 0)
Rui Matos65196bc2013-10-10 19:44:19 +02001777 update_keymap(seat);
1778
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001779 if (update_state == STATE_UPDATE_AUTOMATIC) {
1780 update_modifier_state(seat,
1781 wl_display_get_serial(compositor->wl_display),
1782 key,
1783 state);
1784 }
Giulio Camuffob6ddf6c2015-02-06 19:06:54 +02001785
1786 if (state == WL_KEYBOARD_KEY_STATE_PRESSED) {
1787 keyboard->grab_serial =
1788 wl_display_get_serial(compositor->wl_display);
1789 keyboard->grab_time = time;
1790 keyboard->grab_key = key;
1791 }
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001792}
1793
1794WL_EXPORT void
1795notify_pointer_focus(struct weston_seat *seat, struct weston_output *output,
Giulio Camuffo90a6fc62016-03-22 17:44:54 +02001796 double x, double y)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001797{
Derek Foreman1281a362015-07-31 16:55:32 -05001798 struct weston_pointer *pointer = weston_seat_get_pointer(seat);
1799
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001800 if (output) {
Giulio Camuffo90a6fc62016-03-22 17:44:54 +02001801 weston_pointer_move_to(pointer,
1802 wl_fixed_from_double(x),
1803 wl_fixed_from_double(y));
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001804 } else {
Kristian Høgsberg02bbabb2013-05-06 22:15:05 -04001805 /* FIXME: We should call weston_pointer_set_focus(seat,
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001806 * NULL) here, but somehow that breaks re-entry... */
1807 }
1808}
1809
1810static void
1811destroy_device_saved_kbd_focus(struct wl_listener *listener, void *data)
1812{
1813 struct weston_seat *ws;
1814
1815 ws = container_of(listener, struct weston_seat,
1816 saved_kbd_focus_listener);
1817
1818 ws->saved_kbd_focus = NULL;
1819}
1820
1821WL_EXPORT void
1822notify_keyboard_focus_in(struct weston_seat *seat, struct wl_array *keys,
1823 enum weston_key_state_update update_state)
1824{
1825 struct weston_compositor *compositor = seat->compositor;
Derek Foreman1281a362015-07-31 16:55:32 -05001826 struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
Kristian Høgsbergfe7aa902013-05-08 09:54:37 -04001827 struct weston_surface *surface;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001828 uint32_t *k, serial;
1829
1830 serial = wl_display_next_serial(compositor->wl_display);
1831 wl_array_copy(&keyboard->keys, keys);
1832 wl_array_for_each(k, &keyboard->keys) {
1833 weston_compositor_idle_inhibit(compositor);
1834 if (update_state == STATE_UPDATE_AUTOMATIC)
1835 update_modifier_state(seat, serial, *k,
1836 WL_KEYBOARD_KEY_STATE_PRESSED);
1837 }
1838
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001839 surface = seat->saved_kbd_focus;
1840
1841 if (surface) {
1842 wl_list_remove(&seat->saved_kbd_focus_listener.link);
1843 weston_keyboard_set_focus(keyboard, surface);
1844 seat->saved_kbd_focus = NULL;
1845 }
1846}
1847
1848WL_EXPORT void
1849notify_keyboard_focus_out(struct weston_seat *seat)
1850{
1851 struct weston_compositor *compositor = seat->compositor;
Derek Foreman1281a362015-07-31 16:55:32 -05001852 struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
1853 struct weston_pointer *pointer = weston_seat_get_pointer(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001854 uint32_t *k, serial;
1855
1856 serial = wl_display_next_serial(compositor->wl_display);
1857 wl_array_for_each(k, &keyboard->keys) {
1858 weston_compositor_idle_release(compositor);
1859 update_modifier_state(seat, serial, *k,
1860 WL_KEYBOARD_KEY_STATE_RELEASED);
1861 }
1862
1863 seat->modifier_state = 0;
1864
1865 if (keyboard->focus) {
1866 seat->saved_kbd_focus = keyboard->focus;
1867 seat->saved_kbd_focus_listener.notify =
1868 destroy_device_saved_kbd_focus;
Jason Ekstrand26ed73c2013-06-06 22:34:41 -05001869 wl_signal_add(&keyboard->focus->destroy_signal,
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001870 &seat->saved_kbd_focus_listener);
1871 }
1872
1873 weston_keyboard_set_focus(keyboard, NULL);
Jonas Ådahl1ea343e2013-10-25 23:18:05 +02001874 weston_keyboard_cancel_grab(keyboard);
Derek Foreman1281a362015-07-31 16:55:32 -05001875 if (pointer)
1876 weston_pointer_cancel_grab(pointer);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001877}
1878
Michael Fua2bb7912013-07-23 15:51:06 +08001879WL_EXPORT void
Derek Foreman4c93c082015-04-30 16:45:41 -05001880weston_touch_set_focus(struct weston_touch *touch, struct weston_view *view)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001881{
Neil Roberts96d790e2013-09-19 17:32:00 +01001882 struct wl_list *focus_resource_list;
1883
Derek Foreman4c93c082015-04-30 16:45:41 -05001884 focus_resource_list = &touch->focus_resource_list;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001885
Derek Foreman4c93c082015-04-30 16:45:41 -05001886 if (view && touch->focus &&
1887 touch->focus->surface == view->surface) {
1888 touch->focus = view;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001889 return;
Jason Ekstranda7af7042013-10-12 22:38:11 -05001890 }
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001891
Derek Foreman4c93c082015-04-30 16:45:41 -05001892 wl_list_remove(&touch->focus_resource_listener.link);
1893 wl_list_init(&touch->focus_resource_listener.link);
1894 wl_list_remove(&touch->focus_view_listener.link);
1895 wl_list_init(&touch->focus_view_listener.link);
Giulio Camuffo576fe2a2013-11-20 18:00:24 +01001896
Neil Roberts96d790e2013-09-19 17:32:00 +01001897 if (!wl_list_empty(focus_resource_list)) {
Derek Foreman4c93c082015-04-30 16:45:41 -05001898 move_resources(&touch->resource_list,
Neil Roberts96d790e2013-09-19 17:32:00 +01001899 focus_resource_list);
1900 }
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001901
Jason Ekstranda7af7042013-10-12 22:38:11 -05001902 if (view) {
Derek Foreman362656b2014-09-04 10:23:05 -05001903 struct wl_client *surface_client;
1904
1905 if (!view->surface->resource) {
Derek Foreman4c93c082015-04-30 16:45:41 -05001906 touch->focus = NULL;
Derek Foreman362656b2014-09-04 10:23:05 -05001907 return;
1908 }
1909
1910 surface_client = wl_resource_get_client(view->surface->resource);
Neil Roberts96d790e2013-09-19 17:32:00 +01001911 move_resources_for_client(focus_resource_list,
Derek Foreman4c93c082015-04-30 16:45:41 -05001912 &touch->resource_list,
Neil Roberts96d790e2013-09-19 17:32:00 +01001913 surface_client);
Giulio Camuffo576fe2a2013-11-20 18:00:24 +01001914 wl_resource_add_destroy_listener(view->surface->resource,
Derek Foreman4c93c082015-04-30 16:45:41 -05001915 &touch->focus_resource_listener);
1916 wl_signal_add(&view->destroy_signal, &touch->focus_view_listener);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001917 }
Derek Foreman4c93c082015-04-30 16:45:41 -05001918 touch->focus = view;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001919}
1920
1921/**
1922 * notify_touch - emulates button touches and notifies surfaces accordingly.
1923 *
1924 * It assumes always the correct cycle sequence until it gets here: touch_down
1925 * → touch_update → ... → touch_update → touch_end. The driver is responsible
1926 * for sending along such order.
1927 *
1928 */
1929WL_EXPORT void
1930notify_touch(struct weston_seat *seat, uint32_t time, int touch_id,
Giulio Camuffo90a6fc62016-03-22 17:44:54 +02001931 double double_x, double double_y, int touch_type)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001932{
1933 struct weston_compositor *ec = seat->compositor;
Derek Foreman1281a362015-07-31 16:55:32 -05001934 struct weston_touch *touch = weston_seat_get_touch(seat);
Kristian Høgsberge329f362013-05-06 22:19:57 -04001935 struct weston_touch_grab *grab = touch->grab;
Jason Ekstranda7af7042013-10-12 22:38:11 -05001936 struct weston_view *ev;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001937 wl_fixed_t sx, sy;
Giulio Camuffo90a6fc62016-03-22 17:44:54 +02001938 wl_fixed_t x = wl_fixed_from_double(double_x);
1939 wl_fixed_t y = wl_fixed_from_double(double_y);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001940
1941 /* Update grab's global coordinates. */
Neil Roberts306fe082013-10-03 16:43:06 +01001942 if (touch_id == touch->grab_touch_id && touch_type != WL_TOUCH_UP) {
1943 touch->grab_x = x;
1944 touch->grab_y = y;
1945 }
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001946
1947 switch (touch_type) {
1948 case WL_TOUCH_DOWN:
1949 weston_compositor_idle_inhibit(ec);
1950
Jonas Ådahl9484b692013-12-02 22:05:03 +01001951 touch->num_tp++;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001952
Jason Ekstranda7af7042013-10-12 22:38:11 -05001953 /* the first finger down picks the view, and all further go
1954 * to that view for the remainder of the touch session i.e.
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001955 * until all touch points are up again. */
Jonas Ådahl9484b692013-12-02 22:05:03 +01001956 if (touch->num_tp == 1) {
Jason Ekstranda7af7042013-10-12 22:38:11 -05001957 ev = weston_compositor_pick_view(ec, x, y, &sx, &sy);
Derek Foreman4c93c082015-04-30 16:45:41 -05001958 weston_touch_set_focus(touch, ev);
Giulio Camuffo61ed7b62015-07-08 11:55:28 +03001959 } else if (!touch->focus) {
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001960 /* Unexpected condition: We have non-initial touch but
1961 * there is no focused surface.
1962 */
Chris Michael3f607d32015-10-07 11:59:49 -04001963 weston_log("touch event received with %d points down "
Jonas Ådahl9484b692013-12-02 22:05:03 +01001964 "but no surface focused\n", touch->num_tp);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001965 return;
1966 }
1967
Derek Foreman99a6a2d2015-07-15 13:00:43 -05001968 weston_compositor_run_touch_binding(ec, touch,
Kristian Høgsbergc8964012014-02-05 14:25:18 -08001969 time, touch_type);
1970
Giulio Camuffo61ed7b62015-07-08 11:55:28 +03001971 grab->interface->down(grab, time, touch_id, x, y);
Jonas Ådahl9484b692013-12-02 22:05:03 +01001972 if (touch->num_tp == 1) {
Rusty Lynchf1407ff2013-08-08 21:13:57 -07001973 touch->grab_serial =
1974 wl_display_get_serial(ec->wl_display);
Neil Roberts306fe082013-10-03 16:43:06 +01001975 touch->grab_touch_id = touch_id;
Rusty Lynchf1407ff2013-08-08 21:13:57 -07001976 touch->grab_time = time;
1977 touch->grab_x = x;
1978 touch->grab_y = y;
1979 }
1980
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001981 break;
1982 case WL_TOUCH_MOTION:
Jason Ekstranda7af7042013-10-12 22:38:11 -05001983 ev = touch->focus;
1984 if (!ev)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001985 break;
1986
Giulio Camuffo61ed7b62015-07-08 11:55:28 +03001987 grab->interface->motion(grab, time, touch_id, x, y);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001988 break;
1989 case WL_TOUCH_UP:
Kristian Høgsberga30e29a2014-01-08 22:29:20 -08001990 if (touch->num_tp == 0) {
1991 /* This can happen if we start out with one or
1992 * more fingers on the touch screen, in which
1993 * case we didn't get the corresponding down
1994 * event. */
1995 weston_log("unmatched touch up event\n");
1996 break;
1997 }
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04001998 weston_compositor_idle_release(ec);
Jonas Ådahl9484b692013-12-02 22:05:03 +01001999 touch->num_tp--;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002000
2001 grab->interface->up(grab, time, touch_id);
Jonas Ådahl9484b692013-12-02 22:05:03 +01002002 if (touch->num_tp == 0)
Derek Foreman4c93c082015-04-30 16:45:41 -05002003 weston_touch_set_focus(touch, NULL);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002004 break;
2005 }
2006}
2007
Jonas Ådahl1679f232014-04-12 09:39:51 +02002008WL_EXPORT void
2009notify_touch_frame(struct weston_seat *seat)
2010{
Derek Foreman1281a362015-07-31 16:55:32 -05002011 struct weston_touch *touch = weston_seat_get_touch(seat);
Jonas Ådahl1679f232014-04-12 09:39:51 +02002012 struct weston_touch_grab *grab = touch->grab;
2013
2014 grab->interface->frame(grab);
2015}
2016
Derek Foreman3cc004a2015-11-06 15:56:09 -06002017WL_EXPORT void
2018notify_touch_cancel(struct weston_seat *seat)
2019{
2020 struct weston_touch *touch = weston_seat_get_touch(seat);
2021 struct weston_touch_grab *grab = touch->grab;
2022
2023 grab->interface->cancel(grab);
2024}
2025
Pekka Paalanen8274d902014-08-06 19:36:51 +03002026static int
2027pointer_cursor_surface_get_label(struct weston_surface *surface,
2028 char *buf, size_t len)
2029{
2030 return snprintf(buf, len, "cursor");
2031}
2032
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002033static void
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002034pointer_cursor_surface_configure(struct weston_surface *es,
Jason Ekstrand918f2dd2013-12-02 21:01:53 -06002035 int32_t dx, int32_t dy)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002036{
Kristian Høgsberg195b8692013-05-08 15:02:05 -04002037 struct weston_pointer *pointer = es->configure_private;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002038 int x, y;
2039
Jason Ekstrand918f2dd2013-12-02 21:01:53 -06002040 if (es->width == 0)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002041 return;
2042
Jason Ekstranda7af7042013-10-12 22:38:11 -05002043 assert(es == pointer->sprite->surface);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002044
Kristian Høgsberg195b8692013-05-08 15:02:05 -04002045 pointer->hotspot_x -= dx;
2046 pointer->hotspot_y -= dy;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002047
Kristian Høgsberg195b8692013-05-08 15:02:05 -04002048 x = wl_fixed_to_int(pointer->x) - pointer->hotspot_x;
2049 y = wl_fixed_to_int(pointer->y) - pointer->hotspot_y;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002050
Jason Ekstrand918f2dd2013-12-02 21:01:53 -06002051 weston_view_set_position(pointer->sprite, x, y);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002052
2053 empty_region(&es->pending.input);
Ander Conselvan de Oliveira23900f72014-01-31 16:07:51 +02002054 empty_region(&es->input);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002055
2056 if (!weston_surface_is_mapped(es)) {
Giulio Camuffo412e6a52014-07-09 22:12:56 +03002057 weston_layer_entry_insert(&es->compositor->cursor_layer.view_list,
2058 &pointer->sprite->layer_link);
Jason Ekstranda7af7042013-10-12 22:38:11 -05002059 weston_view_update_transform(pointer->sprite);
Armin Krezovićf8486c32016-06-30 06:04:28 +02002060 es->is_mapped = true;
2061 pointer->sprite->is_mapped = true;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002062 }
2063}
2064
2065static void
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002066pointer_set_cursor(struct wl_client *client, struct wl_resource *resource,
2067 uint32_t serial, struct wl_resource *surface_resource,
2068 int32_t x, int32_t y)
2069{
Jason Ekstrand44a38632013-06-14 10:08:00 -05002070 struct weston_pointer *pointer = wl_resource_get_user_data(resource);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002071 struct weston_surface *surface = NULL;
2072
2073 if (surface_resource)
Jason Ekstrand0f2ef7e2013-06-14 10:07:53 -05002074 surface = wl_resource_get_user_data(surface_resource);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002075
Kristian Høgsberg195b8692013-05-08 15:02:05 -04002076 if (pointer->focus == NULL)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002077 return;
Jason Ekstranda7af7042013-10-12 22:38:11 -05002078 /* pointer->focus->surface->resource can be NULL. Surfaces like the
Giulio Camuffo1fd4b012013-06-20 18:13:07 +02002079 black_surface used in shell.c for fullscreen don't have
2080 a resource, but can still have focus */
Jason Ekstranda7af7042013-10-12 22:38:11 -05002081 if (pointer->focus->surface->resource == NULL)
Giulio Camuffo1fd4b012013-06-20 18:13:07 +02002082 return;
Jason Ekstranda7af7042013-10-12 22:38:11 -05002083 if (wl_resource_get_client(pointer->focus->surface->resource) != client)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002084 return;
Kristian Høgsberg195b8692013-05-08 15:02:05 -04002085 if (pointer->focus_serial - serial > UINT32_MAX / 2)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002086 return;
2087
Derek Foreman4e53c532015-03-23 10:55:32 -05002088 if (!surface) {
2089 if (pointer->sprite)
2090 pointer_unmap_sprite(pointer);
2091 return;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002092 }
2093
Jonas Ådahlb4070242015-03-18 15:08:03 +08002094 if (pointer->sprite && pointer->sprite->surface == surface &&
2095 pointer->hotspot_x == x && pointer->hotspot_y == y)
2096 return;
2097
Derek Foreman4e53c532015-03-23 10:55:32 -05002098 if (!pointer->sprite || pointer->sprite->surface != surface) {
2099 if (weston_surface_set_role(surface, "wl_pointer-cursor",
2100 resource,
2101 WL_POINTER_ERROR_ROLE) < 0)
2102 return;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002103
Derek Foreman4e53c532015-03-23 10:55:32 -05002104 if (pointer->sprite)
2105 pointer_unmap_sprite(pointer);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002106
Derek Foreman4e53c532015-03-23 10:55:32 -05002107 wl_signal_add(&surface->destroy_signal,
2108 &pointer->sprite_destroy_listener);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002109
Derek Foreman4e53c532015-03-23 10:55:32 -05002110 surface->configure = pointer_cursor_surface_configure;
2111 surface->configure_private = pointer;
2112 weston_surface_set_label_func(surface,
2113 pointer_cursor_surface_get_label);
2114 pointer->sprite = weston_view_create(surface);
2115 }
2116
Kristian Høgsberg195b8692013-05-08 15:02:05 -04002117 pointer->hotspot_x = x;
2118 pointer->hotspot_y = y;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002119
Jonas Ådahl16fe4dc2014-09-08 19:33:41 +02002120 if (surface->buffer_ref.buffer) {
Jason Ekstrand918f2dd2013-12-02 21:01:53 -06002121 pointer_cursor_surface_configure(surface, 0, 0);
Jonas Ådahl16fe4dc2014-09-08 19:33:41 +02002122 weston_view_schedule_repaint(pointer->sprite);
2123 }
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002124}
2125
Kristian Høgsberg69e25fc2013-08-13 20:11:02 +01002126static void
2127pointer_release(struct wl_client *client, struct wl_resource *resource)
2128{
2129 wl_resource_destroy(resource);
2130}
2131
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002132static const struct wl_pointer_interface pointer_interface = {
Kristian Høgsberg69e25fc2013-08-13 20:11:02 +01002133 pointer_set_cursor,
2134 pointer_release
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002135};
2136
2137static void
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002138seat_get_pointer(struct wl_client *client, struct wl_resource *resource,
2139 uint32_t id)
2140{
Jason Ekstrand44a38632013-06-14 10:08:00 -05002141 struct weston_seat *seat = wl_resource_get_user_data(resource);
Derek Foreman1281a362015-07-31 16:55:32 -05002142 /* We use the pointer_state directly, which means we'll
2143 * give a wl_pointer if the seat has ever had one - even though
2144 * the spec explicitly states that this request only takes effect
2145 * if the seat has the pointer capability.
2146 *
2147 * This prevents a race between the compositor sending new
2148 * capabilities and the client trying to use the old ones.
2149 */
2150 struct weston_pointer *pointer = seat->pointer_state;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002151 struct wl_resource *cr;
Jonas Ådahl2cbf2932015-07-22 12:05:38 +08002152 struct weston_pointer_client *pointer_client;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002153
Derek Foreman1281a362015-07-31 16:55:32 -05002154 if (!pointer)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002155 return;
2156
Jason Ekstranda85118c2013-06-27 20:17:02 -05002157 cr = wl_resource_create(client, &wl_pointer_interface,
2158 wl_resource_get_version(resource), id);
Kristian Høgsberg0ff79082013-08-06 16:46:25 -07002159 if (cr == NULL) {
2160 wl_client_post_no_memory(client);
2161 return;
2162 }
2163
Jonas Ådahl2cbf2932015-07-22 12:05:38 +08002164 pointer_client = weston_pointer_ensure_pointer_client(pointer, client);
2165 if (!pointer_client) {
2166 wl_client_post_no_memory(client);
2167 return;
2168 }
2169
2170 wl_list_insert(&pointer_client->pointer_resources,
2171 wl_resource_get_link(cr));
Derek Foreman1281a362015-07-31 16:55:32 -05002172 wl_resource_set_implementation(cr, &pointer_interface, pointer,
Jonas Ådahl2cbf2932015-07-22 12:05:38 +08002173 unbind_pointer_client_resource);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002174
Derek Foreman1281a362015-07-31 16:55:32 -05002175 if (pointer->focus && pointer->focus->surface->resource &&
2176 wl_resource_get_client(pointer->focus->surface->resource) == client) {
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002177 wl_fixed_t sx, sy;
2178
Derek Foreman1281a362015-07-31 16:55:32 -05002179 weston_view_from_global_fixed(pointer->focus,
2180 pointer->x,
2181 pointer->y,
Jason Ekstranda7af7042013-10-12 22:38:11 -05002182 &sx, &sy);
Neil Roberts96d790e2013-09-19 17:32:00 +01002183
Neil Roberts96d790e2013-09-19 17:32:00 +01002184 wl_pointer_send_enter(cr,
Derek Foreman1281a362015-07-31 16:55:32 -05002185 pointer->focus_serial,
2186 pointer->focus->surface->resource,
Neil Roberts96d790e2013-09-19 17:32:00 +01002187 sx, sy);
Peter Hutterer87743e92016-01-18 16:38:22 +10002188 pointer_send_frame(cr);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002189 }
2190}
2191
2192static void
Kristian Høgsberg69e25fc2013-08-13 20:11:02 +01002193keyboard_release(struct wl_client *client, struct wl_resource *resource)
2194{
2195 wl_resource_destroy(resource);
2196}
2197
2198static const struct wl_keyboard_interface keyboard_interface = {
2199 keyboard_release
2200};
2201
Derek Foreman280e7dd2014-10-03 13:13:42 -05002202static bool
Neil Roberts96d790e2013-09-19 17:32:00 +01002203should_send_modifiers_to_client(struct weston_seat *seat,
2204 struct wl_client *client)
2205{
Derek Foreman1281a362015-07-31 16:55:32 -05002206 struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
2207 struct weston_pointer *pointer = weston_seat_get_pointer(seat);
2208
2209 if (keyboard &&
2210 keyboard->focus &&
2211 keyboard->focus->resource &&
2212 wl_resource_get_client(keyboard->focus->resource) == client)
Derek Foreman280e7dd2014-10-03 13:13:42 -05002213 return true;
Neil Roberts96d790e2013-09-19 17:32:00 +01002214
Derek Foreman1281a362015-07-31 16:55:32 -05002215 if (pointer &&
2216 pointer->focus &&
2217 pointer->focus->surface->resource &&
2218 wl_resource_get_client(pointer->focus->surface->resource) == client)
Derek Foreman280e7dd2014-10-03 13:13:42 -05002219 return true;
Neil Roberts96d790e2013-09-19 17:32:00 +01002220
Derek Foreman280e7dd2014-10-03 13:13:42 -05002221 return false;
Neil Roberts96d790e2013-09-19 17:32:00 +01002222}
2223
Kristian Høgsberg69e25fc2013-08-13 20:11:02 +01002224static void
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002225seat_get_keyboard(struct wl_client *client, struct wl_resource *resource,
2226 uint32_t id)
2227{
Jason Ekstrand44a38632013-06-14 10:08:00 -05002228 struct weston_seat *seat = wl_resource_get_user_data(resource);
Derek Foreman1281a362015-07-31 16:55:32 -05002229 /* We use the keyboard_state directly, which means we'll
2230 * give a wl_keyboard if the seat has ever had one - even though
2231 * the spec explicitly states that this request only takes effect
2232 * if the seat has the keyboard capability.
2233 *
2234 * This prevents a race between the compositor sending new
2235 * capabilities and the client trying to use the old ones.
2236 */
2237 struct weston_keyboard *keyboard = seat->keyboard_state;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002238 struct wl_resource *cr;
2239
Derek Foreman345c9f32015-06-03 15:53:28 -05002240 if (!keyboard)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002241 return;
2242
Jason Ekstranda85118c2013-06-27 20:17:02 -05002243 cr = wl_resource_create(client, &wl_keyboard_interface,
2244 wl_resource_get_version(resource), id);
Kristian Høgsberg0ff79082013-08-06 16:46:25 -07002245 if (cr == NULL) {
2246 wl_client_post_no_memory(client);
2247 return;
2248 }
2249
Neil Roberts96d790e2013-09-19 17:32:00 +01002250 /* May be moved to focused list later by either
2251 * weston_keyboard_set_focus or directly if this client is already
2252 * focused */
Derek Foreman345c9f32015-06-03 15:53:28 -05002253 wl_list_insert(&keyboard->resource_list, wl_resource_get_link(cr));
Kristian Høgsberg69e25fc2013-08-13 20:11:02 +01002254 wl_resource_set_implementation(cr, &keyboard_interface,
2255 seat, unbind_resource);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002256
Jonny Lamb66a41a02014-08-12 14:58:25 +02002257 if (wl_resource_get_version(cr) >= WL_KEYBOARD_REPEAT_INFO_SINCE_VERSION) {
2258 wl_keyboard_send_repeat_info(cr,
2259 seat->compositor->kb_repeat_rate,
2260 seat->compositor->kb_repeat_delay);
2261 }
Jasper St. Pierred8c6aeb2014-08-04 13:43:24 -04002262
Matt Roper01a92732013-06-24 16:52:44 +01002263 if (seat->compositor->use_xkbcommon) {
2264 wl_keyboard_send_keymap(cr, WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1,
Jonas Ådahl7395ea02013-12-03 09:14:26 +01002265 keyboard->xkb_info->keymap_fd,
2266 keyboard->xkb_info->keymap_size);
Matt Roper01a92732013-06-24 16:52:44 +01002267 } else {
2268 int null_fd = open("/dev/null", O_RDONLY);
2269 wl_keyboard_send_keymap(cr, WL_KEYBOARD_KEYMAP_FORMAT_NO_KEYMAP,
2270 null_fd,
2271 0);
2272 close(null_fd);
2273 }
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002274
Neil Roberts96d790e2013-09-19 17:32:00 +01002275 if (should_send_modifiers_to_client(seat, client)) {
Derek Foreman345c9f32015-06-03 15:53:28 -05002276 send_modifiers_to_resource(keyboard,
Neil Roberts96d790e2013-09-19 17:32:00 +01002277 cr,
Derek Foreman345c9f32015-06-03 15:53:28 -05002278 keyboard->focus_serial);
Neil Roberts96d790e2013-09-19 17:32:00 +01002279 }
2280
Derek Foreman345c9f32015-06-03 15:53:28 -05002281 if (keyboard->focus && keyboard->focus->resource &&
2282 wl_resource_get_client(keyboard->focus->resource) == client) {
Neil Roberts96d790e2013-09-19 17:32:00 +01002283 struct weston_surface *surface =
Derek Foreman345c9f32015-06-03 15:53:28 -05002284 (struct weston_surface *)keyboard->focus;
Neil Roberts96d790e2013-09-19 17:32:00 +01002285
2286 wl_list_remove(wl_resource_get_link(cr));
Derek Foreman345c9f32015-06-03 15:53:28 -05002287 wl_list_insert(&keyboard->focus_resource_list,
Neil Roberts96d790e2013-09-19 17:32:00 +01002288 wl_resource_get_link(cr));
2289 wl_keyboard_send_enter(cr,
Derek Foreman345c9f32015-06-03 15:53:28 -05002290 keyboard->focus_serial,
Neil Roberts96d790e2013-09-19 17:32:00 +01002291 surface->resource,
Derek Foreman345c9f32015-06-03 15:53:28 -05002292 &keyboard->keys);
Neil Roberts96d790e2013-09-19 17:32:00 +01002293
2294 /* If this is the first keyboard resource for this
2295 * client... */
Derek Foreman345c9f32015-06-03 15:53:28 -05002296 if (keyboard->focus_resource_list.prev ==
Neil Roberts96d790e2013-09-19 17:32:00 +01002297 wl_resource_get_link(cr))
2298 wl_data_device_set_keyboard_focus(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002299 }
2300}
2301
2302static void
Kristian Høgsberg69e25fc2013-08-13 20:11:02 +01002303touch_release(struct wl_client *client, struct wl_resource *resource)
2304{
2305 wl_resource_destroy(resource);
2306}
2307
2308static const struct wl_touch_interface touch_interface = {
2309 touch_release
2310};
2311
2312static void
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002313seat_get_touch(struct wl_client *client, struct wl_resource *resource,
2314 uint32_t id)
2315{
Jason Ekstrand44a38632013-06-14 10:08:00 -05002316 struct weston_seat *seat = wl_resource_get_user_data(resource);
Derek Foreman1281a362015-07-31 16:55:32 -05002317 /* We use the touch_state directly, which means we'll
2318 * give a wl_touch if the seat has ever had one - even though
2319 * the spec explicitly states that this request only takes effect
2320 * if the seat has the touch capability.
2321 *
2322 * This prevents a race between the compositor sending new
2323 * capabilities and the client trying to use the old ones.
2324 */
2325 struct weston_touch *touch = seat->touch_state;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002326 struct wl_resource *cr;
2327
Derek Foreman1281a362015-07-31 16:55:32 -05002328 if (!touch)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002329 return;
2330
Jason Ekstranda85118c2013-06-27 20:17:02 -05002331 cr = wl_resource_create(client, &wl_touch_interface,
2332 wl_resource_get_version(resource), id);
Kristian Høgsberg0ff79082013-08-06 16:46:25 -07002333 if (cr == NULL) {
2334 wl_client_post_no_memory(client);
2335 return;
2336 }
2337
Derek Foreman1281a362015-07-31 16:55:32 -05002338 if (touch->focus &&
2339 wl_resource_get_client(touch->focus->surface->resource) == client) {
Chokshi, Mituld6697142015-10-09 08:28:47 +00002340 wl_list_insert(&touch->focus_resource_list,
Neil Roberts96d790e2013-09-19 17:32:00 +01002341 wl_resource_get_link(cr));
2342 } else {
Chokshi, Mituld6697142015-10-09 08:28:47 +00002343 wl_list_insert(&touch->resource_list,
Neil Roberts96d790e2013-09-19 17:32:00 +01002344 wl_resource_get_link(cr));
2345 }
Kristian Høgsberg69e25fc2013-08-13 20:11:02 +01002346 wl_resource_set_implementation(cr, &touch_interface,
2347 seat, unbind_resource);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002348}
2349
Quentin Glidicaab1d362016-03-13 17:49:08 +01002350static void
2351seat_release(struct wl_client *client, struct wl_resource *resource)
2352{
2353 wl_resource_destroy(resource);
2354}
2355
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002356static const struct wl_seat_interface seat_interface = {
2357 seat_get_pointer,
2358 seat_get_keyboard,
2359 seat_get_touch,
Quentin Glidicaab1d362016-03-13 17:49:08 +01002360 seat_release,
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002361};
2362
2363static void
2364bind_seat(struct wl_client *client, void *data, uint32_t version, uint32_t id)
2365{
Kristian Høgsberge3148752013-05-06 23:19:49 -04002366 struct weston_seat *seat = data;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002367 struct wl_resource *resource;
2368 enum wl_seat_capability caps = 0;
2369
Jason Ekstranda85118c2013-06-27 20:17:02 -05002370 resource = wl_resource_create(client,
Derek Foreman1909c102015-11-26 14:17:47 -06002371 &wl_seat_interface, version, id);
Jason Ekstrand44a38632013-06-14 10:08:00 -05002372 wl_list_insert(&seat->base_resource_list, wl_resource_get_link(resource));
Jason Ekstranda85118c2013-06-27 20:17:02 -05002373 wl_resource_set_implementation(resource, &seat_interface, data,
2374 unbind_resource);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002375
Derek Foreman1281a362015-07-31 16:55:32 -05002376 if (weston_seat_get_pointer(seat))
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002377 caps |= WL_SEAT_CAPABILITY_POINTER;
Derek Foreman1281a362015-07-31 16:55:32 -05002378 if (weston_seat_get_keyboard(seat))
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002379 caps |= WL_SEAT_CAPABILITY_KEYBOARD;
Derek Foreman1281a362015-07-31 16:55:32 -05002380 if (weston_seat_get_touch(seat))
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002381 caps |= WL_SEAT_CAPABILITY_TOUCH;
2382
2383 wl_seat_send_capabilities(resource, caps);
Jasper St. Pierre0013a292014-08-07 16:43:11 -04002384 if (version >= WL_SEAT_NAME_SINCE_VERSION)
Rob Bradforde445ae62013-05-31 18:09:51 +01002385 wl_seat_send_name(resource, seat->seat_name);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002386}
2387
Jonas Ådahl30d61d82014-10-22 21:21:17 +02002388static void
2389relative_pointer_destroy(struct wl_client *client,
2390 struct wl_resource *resource)
2391{
2392 wl_resource_destroy(resource);
2393}
2394
2395static const struct zwp_relative_pointer_v1_interface relative_pointer_interface = {
2396 relative_pointer_destroy
2397};
2398
2399static void
2400relative_pointer_manager_destroy(struct wl_client *client,
2401 struct wl_resource *resource)
2402{
2403 wl_resource_destroy(resource);
2404}
2405
2406static void
2407relative_pointer_manager_get_relative_pointer(struct wl_client *client,
2408 struct wl_resource *resource,
2409 uint32_t id,
2410 struct wl_resource *pointer_resource)
2411{
2412 struct weston_pointer *pointer =
2413 wl_resource_get_user_data(pointer_resource);
2414 struct weston_pointer_client *pointer_client;
2415 struct wl_resource *cr;
2416
2417 cr = wl_resource_create(client, &zwp_relative_pointer_v1_interface,
2418 wl_resource_get_version(resource), id);
2419 if (cr == NULL) {
2420 wl_client_post_no_memory(client);
2421 return;
2422 }
2423
2424 pointer_client = weston_pointer_ensure_pointer_client(pointer, client);
2425 if (!pointer_client) {
2426 wl_client_post_no_memory(client);
2427 return;
2428 }
2429
2430 wl_list_insert(&pointer_client->relative_pointer_resources,
2431 wl_resource_get_link(cr));
2432 wl_resource_set_implementation(cr, &relative_pointer_interface,
2433 pointer,
2434 unbind_pointer_client_resource);
2435}
2436
2437static const struct zwp_relative_pointer_manager_v1_interface relative_pointer_manager = {
2438 relative_pointer_manager_destroy,
2439 relative_pointer_manager_get_relative_pointer,
2440};
2441
2442static void
2443bind_relative_pointer_manager(struct wl_client *client, void *data,
2444 uint32_t version, uint32_t id)
2445{
2446 struct weston_compositor *compositor = data;
2447 struct wl_resource *resource;
2448
2449 resource = wl_resource_create(client,
2450 &zwp_relative_pointer_manager_v1_interface,
2451 1, id);
2452
2453 wl_resource_set_implementation(resource, &relative_pointer_manager,
2454 compositor,
2455 NULL);
2456}
2457
Rob Bradford382ff462013-06-24 16:52:45 +01002458#ifdef ENABLE_XKBCOMMON
Giulio Camuffo0358af42016-06-02 21:48:08 +03002459WL_EXPORT int
2460weston_compositor_set_xkb_rule_names(struct weston_compositor *ec,
2461 struct xkb_rule_names *names)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002462{
Rob Bradford382ff462013-06-24 16:52:45 +01002463 ec->use_xkbcommon = 1;
Matt Roper01a92732013-06-24 16:52:44 +01002464
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002465 if (ec->xkb_context == NULL) {
2466 ec->xkb_context = xkb_context_new(0);
2467 if (ec->xkb_context == NULL) {
2468 weston_log("failed to create XKB context\n");
2469 return -1;
2470 }
2471 }
2472
2473 if (names)
2474 ec->xkb_names = *names;
2475 if (!ec->xkb_names.rules)
2476 ec->xkb_names.rules = strdup("evdev");
2477 if (!ec->xkb_names.model)
2478 ec->xkb_names.model = strdup("pc105");
2479 if (!ec->xkb_names.layout)
2480 ec->xkb_names.layout = strdup("us");
2481
2482 return 0;
2483}
2484
Stefan Schmidtfda26522013-09-17 10:54:09 +01002485static void
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00002486weston_xkb_info_destroy(struct weston_xkb_info *xkb_info)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002487{
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00002488 if (--xkb_info->ref_count > 0)
2489 return;
2490
Ran Benitac9c74152014-08-19 23:59:52 +03002491 xkb_keymap_unref(xkb_info->keymap);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002492
2493 if (xkb_info->keymap_area)
2494 munmap(xkb_info->keymap_area, xkb_info->keymap_size);
2495 if (xkb_info->keymap_fd >= 0)
2496 close(xkb_info->keymap_fd);
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00002497 free(xkb_info);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002498}
2499
2500void
2501weston_compositor_xkb_destroy(struct weston_compositor *ec)
2502{
Matt Roper01a92732013-06-24 16:52:44 +01002503 /*
2504 * If we're operating in raw keyboard mode, we never initialized
2505 * libxkbcommon so there's no cleanup to do either.
2506 */
2507 if (!ec->use_xkbcommon)
2508 return;
2509
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002510 free((char *) ec->xkb_names.rules);
2511 free((char *) ec->xkb_names.model);
2512 free((char *) ec->xkb_names.layout);
2513 free((char *) ec->xkb_names.variant);
2514 free((char *) ec->xkb_names.options);
Stefan Schmidtfda26522013-09-17 10:54:09 +01002515
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00002516 if (ec->xkb_info)
2517 weston_xkb_info_destroy(ec->xkb_info);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002518 xkb_context_unref(ec->xkb_context);
2519}
2520
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00002521static struct weston_xkb_info *
2522weston_xkb_info_create(struct xkb_keymap *keymap)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002523{
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00002524 struct weston_xkb_info *xkb_info = zalloc(sizeof *xkb_info);
2525 if (xkb_info == NULL)
2526 return NULL;
2527
Ran Benita2e1968f2014-08-19 23:59:51 +03002528 xkb_info->keymap = xkb_keymap_ref(keymap);
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00002529 xkb_info->ref_count = 1;
2530
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002531 char *keymap_str;
2532
Ran Benita2e1968f2014-08-19 23:59:51 +03002533 xkb_info->shift_mod = xkb_keymap_mod_get_index(xkb_info->keymap,
2534 XKB_MOD_NAME_SHIFT);
2535 xkb_info->caps_mod = xkb_keymap_mod_get_index(xkb_info->keymap,
2536 XKB_MOD_NAME_CAPS);
2537 xkb_info->ctrl_mod = xkb_keymap_mod_get_index(xkb_info->keymap,
2538 XKB_MOD_NAME_CTRL);
2539 xkb_info->alt_mod = xkb_keymap_mod_get_index(xkb_info->keymap,
2540 XKB_MOD_NAME_ALT);
2541 xkb_info->mod2_mod = xkb_keymap_mod_get_index(xkb_info->keymap,
2542 "Mod2");
2543 xkb_info->mod3_mod = xkb_keymap_mod_get_index(xkb_info->keymap,
2544 "Mod3");
2545 xkb_info->super_mod = xkb_keymap_mod_get_index(xkb_info->keymap,
2546 XKB_MOD_NAME_LOGO);
2547 xkb_info->mod5_mod = xkb_keymap_mod_get_index(xkb_info->keymap,
2548 "Mod5");
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002549
Ran Benita2e1968f2014-08-19 23:59:51 +03002550 xkb_info->num_led = xkb_keymap_led_get_index(xkb_info->keymap,
2551 XKB_LED_NAME_NUM);
2552 xkb_info->caps_led = xkb_keymap_led_get_index(xkb_info->keymap,
2553 XKB_LED_NAME_CAPS);
2554 xkb_info->scroll_led = xkb_keymap_led_get_index(xkb_info->keymap,
2555 XKB_LED_NAME_SCROLL);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002556
Ran Benita2e1968f2014-08-19 23:59:51 +03002557 keymap_str = xkb_keymap_get_as_string(xkb_info->keymap,
2558 XKB_KEYMAP_FORMAT_TEXT_V1);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002559 if (keymap_str == NULL) {
2560 weston_log("failed to get string version of keymap\n");
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00002561 goto err_keymap;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002562 }
2563 xkb_info->keymap_size = strlen(keymap_str) + 1;
2564
2565 xkb_info->keymap_fd = os_create_anonymous_file(xkb_info->keymap_size);
2566 if (xkb_info->keymap_fd < 0) {
2567 weston_log("creating a keymap file for %lu bytes failed: %m\n",
2568 (unsigned long) xkb_info->keymap_size);
2569 goto err_keymap_str;
2570 }
2571
2572 xkb_info->keymap_area = mmap(NULL, xkb_info->keymap_size,
2573 PROT_READ | PROT_WRITE,
2574 MAP_SHARED, xkb_info->keymap_fd, 0);
2575 if (xkb_info->keymap_area == MAP_FAILED) {
2576 weston_log("failed to mmap() %lu bytes\n",
2577 (unsigned long) xkb_info->keymap_size);
2578 goto err_dev_zero;
2579 }
2580 strcpy(xkb_info->keymap_area, keymap_str);
2581 free(keymap_str);
2582
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00002583 return xkb_info;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002584
2585err_dev_zero:
2586 close(xkb_info->keymap_fd);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002587err_keymap_str:
2588 free(keymap_str);
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00002589err_keymap:
Ran Benita2e1968f2014-08-19 23:59:51 +03002590 xkb_keymap_unref(xkb_info->keymap);
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00002591 free(xkb_info);
2592 return NULL;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002593}
2594
2595static int
2596weston_compositor_build_global_keymap(struct weston_compositor *ec)
2597{
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00002598 struct xkb_keymap *keymap;
2599
2600 if (ec->xkb_info != NULL)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002601 return 0;
2602
Ran Benita2e1968f2014-08-19 23:59:51 +03002603 keymap = xkb_keymap_new_from_names(ec->xkb_context,
2604 &ec->xkb_names,
2605 0);
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00002606 if (keymap == NULL) {
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002607 weston_log("failed to compile global XKB keymap\n");
2608 weston_log(" tried rules %s, model %s, layout %s, variant %s, "
2609 "options %s\n",
2610 ec->xkb_names.rules, ec->xkb_names.model,
2611 ec->xkb_names.layout, ec->xkb_names.variant,
2612 ec->xkb_names.options);
2613 return -1;
2614 }
2615
Andrew Wedgbury9a6f02a2013-09-05 13:31:40 +00002616 ec->xkb_info = weston_xkb_info_create(keymap);
Rui Matos73d93952013-10-24 19:28:41 +02002617 xkb_keymap_unref(keymap);
Stefan Schmidtfda26522013-09-17 10:54:09 +01002618 if (ec->xkb_info == NULL)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002619 return -1;
2620
2621 return 0;
2622}
Rob Bradford382ff462013-06-24 16:52:45 +01002623#else
Giulio Camuffo0358af42016-06-02 21:48:08 +03002624WL_EXPORT int
2625weston_compositor_set_xkb_rule_names(struct weston_compositor *ec,
2626 struct xkb_rule_names *names)
Rob Bradford382ff462013-06-24 16:52:45 +01002627{
2628 return 0;
2629}
2630
2631void
2632weston_compositor_xkb_destroy(struct weston_compositor *ec)
2633{
2634}
2635#endif
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002636
Rui Matos65196bc2013-10-10 19:44:19 +02002637WL_EXPORT void
2638weston_seat_update_keymap(struct weston_seat *seat, struct xkb_keymap *keymap)
2639{
Derek Foreman1281a362015-07-31 16:55:32 -05002640 struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
2641
2642 if (!keyboard || !keymap)
Rui Matos65196bc2013-10-10 19:44:19 +02002643 return;
2644
2645#ifdef ENABLE_XKBCOMMON
2646 if (!seat->compositor->use_xkbcommon)
2647 return;
2648
Derek Foreman1281a362015-07-31 16:55:32 -05002649 xkb_keymap_unref(keyboard->pending_keymap);
2650 keyboard->pending_keymap = xkb_keymap_ref(keymap);
Rui Matos65196bc2013-10-10 19:44:19 +02002651
Derek Foreman1281a362015-07-31 16:55:32 -05002652 if (keyboard->keys.size == 0)
Rui Matos65196bc2013-10-10 19:44:19 +02002653 update_keymap(seat);
2654#endif
2655}
2656
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002657WL_EXPORT int
2658weston_seat_init_keyboard(struct weston_seat *seat, struct xkb_keymap *keymap)
2659{
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04002660 struct weston_keyboard *keyboard;
2661
Derek Foreman1281a362015-07-31 16:55:32 -05002662 if (seat->keyboard_state) {
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002663 seat->keyboard_device_count += 1;
2664 if (seat->keyboard_device_count == 1)
2665 seat_send_updated_caps(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002666 return 0;
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002667 }
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002668
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04002669 keyboard = weston_keyboard_create();
2670 if (keyboard == NULL) {
2671 weston_log("failed to allocate weston keyboard struct\n");
2672 return -1;
2673 }
2674
Jonas Ådahl7395ea02013-12-03 09:14:26 +01002675#ifdef ENABLE_XKBCOMMON
2676 if (seat->compositor->use_xkbcommon) {
2677 if (keymap != NULL) {
2678 keyboard->xkb_info = weston_xkb_info_create(keymap);
2679 if (keyboard->xkb_info == NULL)
Ander Conselvan de Oliveira4d363cf2014-01-31 17:35:45 +02002680 goto err;
Jonas Ådahl7395ea02013-12-03 09:14:26 +01002681 } else {
2682 if (weston_compositor_build_global_keymap(seat->compositor) < 0)
Ander Conselvan de Oliveira4d363cf2014-01-31 17:35:45 +02002683 goto err;
Jonas Ådahl7395ea02013-12-03 09:14:26 +01002684 keyboard->xkb_info = seat->compositor->xkb_info;
2685 keyboard->xkb_info->ref_count++;
2686 }
2687
2688 keyboard->xkb_state.state = xkb_state_new(keyboard->xkb_info->keymap);
2689 if (keyboard->xkb_state.state == NULL) {
2690 weston_log("failed to initialise XKB state\n");
Ander Conselvan de Oliveira4d363cf2014-01-31 17:35:45 +02002691 goto err;
Jonas Ådahl7395ea02013-12-03 09:14:26 +01002692 }
2693
2694 keyboard->xkb_state.leds = 0;
2695 }
2696#endif
2697
Derek Foreman1281a362015-07-31 16:55:32 -05002698 seat->keyboard_state = keyboard;
Ander Conselvan de Oliveira4d363cf2014-01-31 17:35:45 +02002699 seat->keyboard_device_count = 1;
2700 keyboard->seat = seat;
2701
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04002702 seat_send_updated_caps(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002703
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002704 return 0;
Ander Conselvan de Oliveira4d363cf2014-01-31 17:35:45 +02002705
2706err:
2707 if (keyboard->xkb_info)
2708 weston_xkb_info_destroy(keyboard->xkb_info);
2709 free(keyboard);
2710
2711 return -1;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002712}
2713
Jonas Ådahl91fed542013-12-03 09:14:27 +01002714static void
2715weston_keyboard_reset_state(struct weston_keyboard *keyboard)
2716{
2717 struct weston_seat *seat = keyboard->seat;
2718 struct xkb_state *state;
2719
2720#ifdef ENABLE_XKBCOMMON
2721 if (seat->compositor->use_xkbcommon) {
2722 state = xkb_state_new(keyboard->xkb_info->keymap);
2723 if (!state) {
2724 weston_log("failed to reset XKB state\n");
2725 return;
2726 }
2727 xkb_state_unref(keyboard->xkb_state.state);
2728 keyboard->xkb_state.state = state;
2729
2730 keyboard->xkb_state.leds = 0;
2731 }
2732#endif
2733
2734 seat->modifier_state = 0;
2735}
2736
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002737WL_EXPORT void
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002738weston_seat_release_keyboard(struct weston_seat *seat)
2739{
2740 seat->keyboard_device_count--;
Derek Foremand621df22014-11-19 11:04:12 -06002741 assert(seat->keyboard_device_count >= 0);
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002742 if (seat->keyboard_device_count == 0) {
Derek Foreman1281a362015-07-31 16:55:32 -05002743 weston_keyboard_set_focus(seat->keyboard_state, NULL);
2744 weston_keyboard_cancel_grab(seat->keyboard_state);
2745 weston_keyboard_reset_state(seat->keyboard_state);
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002746 seat_send_updated_caps(seat);
2747 }
2748}
2749
2750WL_EXPORT void
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002751weston_seat_init_pointer(struct weston_seat *seat)
2752{
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04002753 struct weston_pointer *pointer;
2754
Derek Foreman1281a362015-07-31 16:55:32 -05002755 if (seat->pointer_state) {
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002756 seat->pointer_device_count += 1;
2757 if (seat->pointer_device_count == 1)
2758 seat_send_updated_caps(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002759 return;
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002760 }
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002761
Giulio Camuffocdb4d292013-11-14 23:42:53 +01002762 pointer = weston_pointer_create(seat);
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04002763 if (pointer == NULL)
2764 return;
2765
Derek Foreman1281a362015-07-31 16:55:32 -05002766 seat->pointer_state = pointer;
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002767 seat->pointer_device_count = 1;
2768 pointer->seat = seat;
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04002769
2770 seat_send_updated_caps(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002771}
2772
2773WL_EXPORT void
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002774weston_seat_release_pointer(struct weston_seat *seat)
2775{
Derek Foreman1281a362015-07-31 16:55:32 -05002776 struct weston_pointer *pointer = seat->pointer_state;
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002777
2778 seat->pointer_device_count--;
2779 if (seat->pointer_device_count == 0) {
Derek Foremanf9318d12015-05-11 15:40:11 -05002780 weston_pointer_clear_focus(pointer);
Jonas Ådahl1ea343e2013-10-25 23:18:05 +02002781 weston_pointer_cancel_grab(pointer);
Jonas Ådahl630bae82013-10-17 23:04:06 +02002782
Jonas Ådahla4932742013-10-17 23:04:07 +02002783 if (pointer->sprite)
2784 pointer_unmap_sprite(pointer);
2785
Jonas Ådahl3e12e632013-12-02 22:05:05 +01002786 weston_pointer_reset_state(pointer);
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002787 seat_send_updated_caps(seat);
Derek Foremanfd5ca512015-01-07 15:00:25 -06002788
2789 /* seat->pointer is intentionally not destroyed so that
2790 * a newly attached pointer on this seat will retain
2791 * the previous cursor co-ordinates.
2792 */
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002793 }
2794}
2795
2796WL_EXPORT void
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002797weston_seat_init_touch(struct weston_seat *seat)
2798{
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04002799 struct weston_touch *touch;
2800
Derek Foreman1281a362015-07-31 16:55:32 -05002801 if (seat->touch_state) {
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002802 seat->touch_device_count += 1;
2803 if (seat->touch_device_count == 1)
2804 seat_send_updated_caps(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002805 return;
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002806 }
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002807
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04002808 touch = weston_touch_create();
2809 if (touch == NULL)
2810 return;
2811
Derek Foreman1281a362015-07-31 16:55:32 -05002812 seat->touch_state = touch;
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002813 seat->touch_device_count = 1;
Kristian Høgsberga4036bb2013-05-07 23:52:07 -04002814 touch->seat = seat;
2815
2816 seat_send_updated_caps(seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002817}
2818
2819WL_EXPORT void
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002820weston_seat_release_touch(struct weston_seat *seat)
2821{
2822 seat->touch_device_count--;
2823 if (seat->touch_device_count == 0) {
Derek Foreman1281a362015-07-31 16:55:32 -05002824 weston_touch_set_focus(seat->touch_state, NULL);
2825 weston_touch_cancel_grab(seat->touch_state);
2826 weston_touch_reset_state(seat->touch_state);
Jonas Ådahld6e1c342013-10-17 23:04:05 +02002827 seat_send_updated_caps(seat);
2828 }
2829}
2830
2831WL_EXPORT void
Rob Bradford9af5f9e2013-05-31 18:09:50 +01002832weston_seat_init(struct weston_seat *seat, struct weston_compositor *ec,
2833 const char *seat_name)
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002834{
Kristian Høgsberg4a2a2742013-05-06 22:24:50 -04002835 memset(seat, 0, sizeof *seat);
2836
Kristian Høgsberge3148752013-05-06 23:19:49 -04002837 seat->selection_data_source = NULL;
2838 wl_list_init(&seat->base_resource_list);
2839 wl_signal_init(&seat->selection_signal);
2840 wl_list_init(&seat->drag_resource_list);
Kristian Høgsberge3148752013-05-06 23:19:49 -04002841 wl_signal_init(&seat->destroy_signal);
Jason Ekstranda4ab5422014-04-02 19:53:45 -05002842 wl_signal_init(&seat->updated_caps_signal);
Kristian Høgsberg4a2a2742013-05-06 22:24:50 -04002843
Peter Hutterer87743e92016-01-18 16:38:22 +10002844 seat->global = wl_global_create(ec->wl_display, &wl_seat_interface, 5,
Kristian Høgsberg919cddb2013-07-08 19:03:57 -04002845 seat, bind_seat);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002846
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002847 seat->compositor = ec;
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002848 seat->modifier_state = 0;
Rob Bradford9af5f9e2013-05-31 18:09:50 +01002849 seat->seat_name = strdup(seat_name);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002850
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002851 wl_list_insert(ec->seat_list.prev, &seat->link);
2852
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002853 clipboard_create(seat);
2854
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002855 wl_signal_emit(&ec->seat_created_signal, seat);
2856}
2857
2858WL_EXPORT void
2859weston_seat_release(struct weston_seat *seat)
2860{
2861 wl_list_remove(&seat->link);
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002862
Jonas Ådahl1afb2382014-01-03 19:46:51 +01002863 if (seat->saved_kbd_focus)
2864 wl_list_remove(&seat->saved_kbd_focus_listener.link);
2865
Derek Foreman1281a362015-07-31 16:55:32 -05002866 if (seat->pointer_state)
2867 weston_pointer_destroy(seat->pointer_state);
2868 if (seat->keyboard_state)
2869 weston_keyboard_destroy(seat->keyboard_state);
2870 if (seat->touch_state)
2871 weston_touch_destroy(seat->touch_state);
Kristian Høgsberg4a2a2742013-05-06 22:24:50 -04002872
Rob Bradford9af5f9e2013-05-31 18:09:50 +01002873 free (seat->seat_name);
2874
Kristian Høgsberg919cddb2013-07-08 19:03:57 -04002875 wl_global_destroy(seat->global);
Kristian Høgsbergaaadc772013-07-08 16:20:31 -04002876
Kristian Høgsbergb5e26102013-04-18 15:40:10 -04002877 wl_signal_emit(&seat->destroy_signal, seat);
2878}
Derek Foreman1281a362015-07-31 16:55:32 -05002879
2880/** Get a seat's keyboard pointer
2881 *
2882 * \param seat The seat to query
2883 * \return The seat's keyboard pointer, or NULL if no keyboard is present
2884 *
2885 * The keyboard pointer for a seat isn't freed when all keyboards are removed,
2886 * so it should only be used when the seat's keyboard_device_count is greater
2887 * than zero. This function does that test and only returns a pointer
2888 * when a keyboard is present.
2889 */
2890WL_EXPORT struct weston_keyboard *
2891weston_seat_get_keyboard(struct weston_seat *seat)
2892{
2893 if (!seat)
2894 return NULL;
2895
2896 if (seat->keyboard_device_count)
2897 return seat->keyboard_state;
2898
2899 return NULL;
2900}
2901
2902/** Get a seat's pointer pointer
2903 *
2904 * \param seat The seat to query
2905 * \return The seat's pointer pointer, or NULL if no pointer device is present
2906 *
2907 * The pointer pointer for a seat isn't freed when all mice are removed,
2908 * so it should only be used when the seat's pointer_device_count is greater
2909 * than zero. This function does that test and only returns a pointer
2910 * when a pointing device is present.
2911 */
2912WL_EXPORT struct weston_pointer *
2913weston_seat_get_pointer(struct weston_seat *seat)
2914{
2915 if (!seat)
2916 return NULL;
2917
2918 if (seat->pointer_device_count)
2919 return seat->pointer_state;
2920
2921 return NULL;
2922}
2923
2924/** Get a seat's touch pointer
2925 *
2926 * \param seat The seat to query
2927 * \return The seat's touch pointer, or NULL if no touch device is present
2928 *
2929 * The touch pointer for a seat isn't freed when all touch devices are removed,
2930 * so it should only be used when the seat's touch_device_count is greater
2931 * than zero. This function does that test and only returns a pointer
2932 * when a touch device is present.
2933 */
2934WL_EXPORT struct weston_touch *
2935weston_seat_get_touch(struct weston_seat *seat)
2936{
2937 if (!seat)
2938 return NULL;
2939
2940 if (seat->touch_device_count)
2941 return seat->touch_state;
2942
2943 return NULL;
2944}
Bryce Harrington24f917e2016-06-29 19:04:07 -07002945
2946/** Sets the keyboard focus to the given surface
2947 *
2948 * \param seat The seat to query
2949 */
2950WL_EXPORT void
2951weston_seat_set_keyboard_focus(struct weston_seat *seat,
2952 struct weston_surface *surface)
2953{
2954 struct weston_compositor *compositor = seat->compositor;
2955 struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
Jonas Ådahlf7deb6a2016-07-22 17:50:26 +08002956 struct weston_surface_activation_data activation_data;
Bryce Harrington24f917e2016-06-29 19:04:07 -07002957
Jonas Ådahlef8e1c32016-03-15 20:28:51 +08002958 if (keyboard && keyboard->focus != surface) {
Bryce Harrington24f917e2016-06-29 19:04:07 -07002959 weston_keyboard_set_focus(keyboard, surface);
2960 wl_data_device_set_keyboard_focus(seat);
2961 }
2962
Jonas Ådahl94e2e2d2014-10-18 18:42:19 +02002963 inc_activate_serial(compositor);
Jonas Ådahlf7deb6a2016-07-22 17:50:26 +08002964
2965 activation_data = (struct weston_surface_activation_data) {
2966 .surface = surface,
2967 .seat = seat,
2968 };
2969 wl_signal_emit(&compositor->activate_signal, &activation_data);
Bryce Harrington24f917e2016-06-29 19:04:07 -07002970}
Jonas Ådahl30d61d82014-10-22 21:21:17 +02002971
2972int
2973weston_input_init(struct weston_compositor *compositor)
2974{
2975 if (!wl_global_create(compositor->wl_display,
2976 &zwp_relative_pointer_manager_v1_interface, 1,
2977 compositor, bind_relative_pointer_manager))
2978 return -1;
2979
2980 return 0;
2981}