• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright © 2013 Intel Corporation
3  * Copyright 2017-2018 Collabora, Ltd.
4  * Copyright 2017-2018 General Electric Company
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining
7  * a copy of this software and associated documentation files (the
8  * "Software"), to deal in the Software without restriction, including
9  * without limitation the rights to use, copy, modify, merge, publish,
10  * distribute, sublicense, and/or sell copies of the Software, and to
11  * permit persons to whom the Software is furnished to do so, subject to
12  * the following conditions:
13  *
14  * The above copyright notice and this permission notice (including the
15  * next paragraph) shall be included in all copies or substantial
16  * portions of the Software.
17  *
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21  * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
22  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
23  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25  * SOFTWARE.
26  */
27 
28 #include "config.h"
29 
30 #include <stdbool.h>
31 #include <stdlib.h>
32 #include <stdint.h>
33 #include <string.h>
34 #include <sys/mman.h>
35 #include <assert.h>
36 #include <unistd.h>
37 // OHOS no such file
38 //#include <values.h>
39 #include <fcntl.h>
40 #include <limits.h>
41 #include <errno.h>
42 #include <float.h>
43 
44 #include "shared/helpers.h"
45 #include "shared/os-compatibility.h"
46 #include "shared/timespec-util.h"
47 #include <libweston/libweston.h>
48 #include "backend.h"
49 #include "libweston-internal.h"
50 #include "relative-pointer-unstable-v1-server-protocol.h"
51 #include "pointer-constraints-unstable-v1-server-protocol.h"
52 #include "input-timestamps-unstable-v1-server-protocol.h"
53 
54 enum pointer_constraint_type {
55 	POINTER_CONSTRAINT_TYPE_LOCK,
56 	POINTER_CONSTRAINT_TYPE_CONFINE,
57 };
58 
59 enum motion_direction {
60 	MOTION_DIRECTION_POSITIVE_X = 1 << 0,
61 	MOTION_DIRECTION_NEGATIVE_X = 1 << 1,
62 	MOTION_DIRECTION_POSITIVE_Y = 1 << 2,
63 	MOTION_DIRECTION_NEGATIVE_Y = 1 << 3,
64 };
65 
66 struct vec2d {
67 	double x, y;
68 };
69 
70 struct line {
71 	struct vec2d a;
72 	struct vec2d b;
73 };
74 
75 struct border {
76 	struct line line;
77 	enum motion_direction blocking_dir;
78 };
79 
80 static void
81 maybe_warp_confined_pointer(struct weston_pointer_constraint *constraint);
82 
83 static void
empty_region(pixman_region32_t * region)84 empty_region(pixman_region32_t *region)
85 {
86 	pixman_region32_fini(region);
87 	pixman_region32_init(region);
88 }
89 
90 static void
region_init_infinite(pixman_region32_t * region)91 region_init_infinite(pixman_region32_t *region)
92 {
93 	pixman_region32_init_rect(region, INT32_MIN, INT32_MIN,
94 				  UINT32_MAX, UINT32_MAX);
95 }
96 
97 static void
send_timestamp(struct wl_resource * resource,const struct timespec * time)98 send_timestamp(struct wl_resource *resource,
99 	       const struct timespec *time)
100 {
101 	uint32_t tv_sec_hi, tv_sec_lo, tv_nsec;
102 
103 	timespec_to_proto(time, &tv_sec_hi, &tv_sec_lo, &tv_nsec);
104 	zwp_input_timestamps_v1_send_timestamp(resource, tv_sec_hi, tv_sec_lo,
105 					       tv_nsec);
106 }
107 
108 static void
send_timestamps_for_input_resource(struct wl_resource * input_resource,struct wl_list * list,const struct timespec * time)109 send_timestamps_for_input_resource(struct wl_resource *input_resource,
110 				   struct wl_list *list,
111 				   const struct timespec *time)
112 {
113 	struct wl_resource *resource;
114 
115 	wl_resource_for_each(resource, list) {
116 		if (wl_resource_get_user_data(resource) == input_resource)
117 			send_timestamp(resource, time);
118 	}
119 }
120 
121 static void
remove_input_resource_from_timestamps(struct wl_resource * input_resource,struct wl_list * list)122 remove_input_resource_from_timestamps(struct wl_resource *input_resource,
123 				      struct wl_list *list)
124 {
125 	struct wl_resource *resource;
126 
127 	wl_resource_for_each(resource, list) {
128 		if (wl_resource_get_user_data(resource) == input_resource)
129 			wl_resource_set_user_data(resource, NULL);
130 	}
131 }
132 
133 /** Register a touchscreen input device
134  *
135  * \param touch The parent weston_touch that identifies the seat.
136  * \param syspath Unique device name.
137  * \param backend_data Backend private data if necessary.
138  * \param ops Calibration operations, or NULL for not able to run calibration.
139  * \return New touch device, or NULL on failure.
140  */
141 WL_EXPORT struct weston_touch_device *
weston_touch_create_touch_device(struct weston_touch * touch,const char * syspath,void * backend_data,const struct weston_touch_device_ops * ops)142 weston_touch_create_touch_device(struct weston_touch *touch,
143 				 const char *syspath,
144 				 void *backend_data,
145 				 const struct weston_touch_device_ops *ops)
146 {
147 	struct weston_touch_device *device;
148 
149 	assert(syspath);
150 	if (ops) {
151 		assert(ops->get_output);
152 		assert(ops->get_calibration_head_name);
153 		assert(ops->get_calibration);
154 		assert(ops->set_calibration);
155 	}
156 
157 	device = zalloc(sizeof *device);
158 	if (!device)
159 		return NULL;
160 
161 	wl_signal_init(&device->destroy_signal);
162 
163 	device->syspath = strdup(syspath);
164 	if (!device->syspath) {
165 		free(device);
166 		return NULL;
167 	}
168 
169 	device->backend_data = backend_data;
170 	device->ops = ops;
171 
172 	device->aggregate = touch;
173 	wl_list_insert(touch->device_list.prev, &device->link);
174 
175 	return device;
176 }
177 
178 /** Destroy the touch device. */
179 WL_EXPORT void
weston_touch_device_destroy(struct weston_touch_device * device)180 weston_touch_device_destroy(struct weston_touch_device *device)
181 {
182 	wl_list_remove(&device->link);
183 	wl_signal_emit(&device->destroy_signal, device);
184 	free(device->syspath);
185 	free(device);
186 }
187 
188 /** Is it possible to run calibration on this touch device? */
189 WL_EXPORT bool
weston_touch_device_can_calibrate(struct weston_touch_device * device)190 weston_touch_device_can_calibrate(struct weston_touch_device *device)
191 {
192 	return !!device->ops;
193 }
194 
195 static enum weston_touch_mode
weston_touch_device_get_mode(struct weston_touch_device * device)196 weston_touch_device_get_mode(struct weston_touch_device *device)
197 {
198 	return device->aggregate->seat->compositor->touch_mode;
199 }
200 
201 static struct weston_pointer_client *
weston_pointer_client_create(struct wl_client * client)202 weston_pointer_client_create(struct wl_client *client)
203 {
204 	struct weston_pointer_client *pointer_client;
205 
206 	pointer_client = zalloc(sizeof *pointer_client);
207 	if (!pointer_client)
208 		return NULL;
209 
210 	pointer_client->client = client;
211 	wl_list_init(&pointer_client->pointer_resources);
212 	wl_list_init(&pointer_client->relative_pointer_resources);
213 
214 	return pointer_client;
215 }
216 
217 static void
weston_pointer_client_destroy(struct weston_pointer_client * pointer_client)218 weston_pointer_client_destroy(struct weston_pointer_client *pointer_client)
219 {
220 	struct wl_resource *resource;
221 
222 	wl_resource_for_each(resource, &pointer_client->pointer_resources) {
223 		wl_resource_set_user_data(resource, NULL);
224 	}
225 
226 	wl_resource_for_each(resource,
227 			     &pointer_client->relative_pointer_resources) {
228 		wl_resource_set_user_data(resource, NULL);
229 	}
230 
231 	wl_list_remove(&pointer_client->pointer_resources);
232 	wl_list_remove(&pointer_client->relative_pointer_resources);
233 	free(pointer_client);
234 }
235 
236 static bool
weston_pointer_client_is_empty(struct weston_pointer_client * pointer_client)237 weston_pointer_client_is_empty(struct weston_pointer_client *pointer_client)
238 {
239 	return (wl_list_empty(&pointer_client->pointer_resources) &&
240 		wl_list_empty(&pointer_client->relative_pointer_resources));
241 }
242 
243 static struct weston_pointer_client *
weston_pointer_get_pointer_client(struct weston_pointer * pointer,struct wl_client * client)244 weston_pointer_get_pointer_client(struct weston_pointer *pointer,
245 				  struct wl_client *client)
246 {
247 	struct weston_pointer_client *pointer_client;
248 
249 	wl_list_for_each(pointer_client, &pointer->pointer_clients, link) {
250 		if (pointer_client->client == client)
251 			return pointer_client;
252 	}
253 
254 	return NULL;
255 }
256 
257 static struct weston_pointer_client *
weston_pointer_ensure_pointer_client(struct weston_pointer * pointer,struct wl_client * client)258 weston_pointer_ensure_pointer_client(struct weston_pointer *pointer,
259 				     struct wl_client *client)
260 {
261 	struct weston_pointer_client *pointer_client;
262 
263 	pointer_client = weston_pointer_get_pointer_client(pointer, client);
264 	if (pointer_client)
265 		return pointer_client;
266 
267 	pointer_client = weston_pointer_client_create(client);
268 	wl_list_insert(&pointer->pointer_clients, &pointer_client->link);
269 
270 	if (pointer->focus &&
271 	    pointer->focus->surface->resource &&
272 	    wl_resource_get_client(pointer->focus->surface->resource) == client) {
273 		pointer->focus_client = pointer_client;
274 	}
275 
276 	return pointer_client;
277 }
278 
279 static void
weston_pointer_cleanup_pointer_client(struct weston_pointer * pointer,struct weston_pointer_client * pointer_client)280 weston_pointer_cleanup_pointer_client(struct weston_pointer *pointer,
281 				      struct weston_pointer_client *pointer_client)
282 {
283 	if (weston_pointer_client_is_empty(pointer_client)) {
284 		if (pointer->focus_client == pointer_client)
285 			pointer->focus_client = NULL;
286 		wl_list_remove(&pointer_client->link);
287 		weston_pointer_client_destroy(pointer_client);
288 	}
289 }
290 
291 static void
unbind_pointer_client_resource(struct wl_resource * resource)292 unbind_pointer_client_resource(struct wl_resource *resource)
293 {
294 	struct weston_pointer *pointer = wl_resource_get_user_data(resource);
295 	struct wl_client *client = wl_resource_get_client(resource);
296 	struct weston_pointer_client *pointer_client;
297 
298 	wl_list_remove(wl_resource_get_link(resource));
299 
300 	if (pointer) {
301 		pointer_client = weston_pointer_get_pointer_client(pointer,
302 								   client);
303 		assert(pointer_client);
304 		remove_input_resource_from_timestamps(resource,
305 						      &pointer->timestamps_list);
306 		weston_pointer_cleanup_pointer_client(pointer, pointer_client);
307 	}
308 }
309 
unbind_resource(struct wl_resource * resource)310 static void unbind_resource(struct wl_resource *resource)
311 {
312 	wl_list_remove(wl_resource_get_link(resource));
313 }
314 
315 WL_EXPORT void
weston_pointer_motion_to_abs(struct weston_pointer * pointer,struct weston_pointer_motion_event * event,wl_fixed_t * x,wl_fixed_t * y)316 weston_pointer_motion_to_abs(struct weston_pointer *pointer,
317 			     struct weston_pointer_motion_event *event,
318 			     wl_fixed_t *x, wl_fixed_t *y)
319 {
320 	if (event->mask & WESTON_POINTER_MOTION_ABS) {
321 		*x = wl_fixed_from_double(event->x);
322 		*y = wl_fixed_from_double(event->y);
323 	} else if (event->mask & WESTON_POINTER_MOTION_REL) {
324 		*x = pointer->x + wl_fixed_from_double(event->dx);
325 		*y = pointer->y + wl_fixed_from_double(event->dy);
326 	} else {
327 		assert(!"invalid motion event");
328 		*x = *y = 0;
329 	}
330 }
331 
332 static bool
weston_pointer_motion_to_rel(struct weston_pointer * pointer,struct weston_pointer_motion_event * event,double * dx,double * dy,double * dx_unaccel,double * dy_unaccel)333 weston_pointer_motion_to_rel(struct weston_pointer *pointer,
334 			     struct weston_pointer_motion_event *event,
335 			     double *dx, double *dy,
336 			     double *dx_unaccel, double *dy_unaccel)
337 {
338 	if (event->mask & WESTON_POINTER_MOTION_REL &&
339 	    event->mask & WESTON_POINTER_MOTION_REL_UNACCEL) {
340 		*dx = event->dx;
341 		*dy = event->dy;
342 		*dx_unaccel = event->dx_unaccel;
343 		*dy_unaccel = event->dy_unaccel;
344 		return true;
345 	} else if (event->mask & WESTON_POINTER_MOTION_REL) {
346 		*dx_unaccel = *dx = event->dx;
347 		*dy_unaccel = *dy = event->dy;
348 		return true;
349 	} else if (event->mask & WESTON_POINTER_MOTION_REL_UNACCEL) {
350 		*dx_unaccel = *dx = event->dx_unaccel;
351 		*dy_unaccel = *dy = event->dy_unaccel;
352 		return true;
353 	} else {
354 		return false;
355 	}
356 }
357 
358 WL_EXPORT void
weston_seat_repick(struct weston_seat * seat)359 weston_seat_repick(struct weston_seat *seat)
360 {
361 	const struct weston_pointer *pointer = weston_seat_get_pointer(seat);
362 
363 	if (!pointer)
364 		return;
365 
366 	pointer->grab->interface->focus(pointer->grab);
367 }
368 
369 static void
weston_compositor_idle_inhibit(struct weston_compositor * compositor)370 weston_compositor_idle_inhibit(struct weston_compositor *compositor)
371 {
372 	weston_compositor_wake(compositor);
373 	compositor->idle_inhibit++;
374 }
375 
376 static void
weston_compositor_idle_release(struct weston_compositor * compositor)377 weston_compositor_idle_release(struct weston_compositor *compositor)
378 {
379 	compositor->idle_inhibit--;
380 	weston_compositor_wake(compositor);
381 }
382 
383 static void
pointer_focus_view_destroyed(struct wl_listener * listener,void * data)384 pointer_focus_view_destroyed(struct wl_listener *listener, void *data)
385 {
386 	struct weston_pointer *pointer =
387 		container_of(listener, struct weston_pointer,
388 			     focus_view_listener);
389 
390 	weston_pointer_clear_focus(pointer);
391 }
392 
393 static void
pointer_focus_resource_destroyed(struct wl_listener * listener,void * data)394 pointer_focus_resource_destroyed(struct wl_listener *listener, void *data)
395 {
396 	struct weston_pointer *pointer =
397 		container_of(listener, struct weston_pointer,
398 			     focus_resource_listener);
399 
400 	weston_pointer_clear_focus(pointer);
401 }
402 
403 static void
keyboard_focus_resource_destroyed(struct wl_listener * listener,void * data)404 keyboard_focus_resource_destroyed(struct wl_listener *listener, void *data)
405 {
406 	struct weston_keyboard *keyboard =
407 		container_of(listener, struct weston_keyboard,
408 			     focus_resource_listener);
409 
410 	weston_keyboard_set_focus(keyboard, NULL);
411 }
412 
413 static void
touch_focus_view_destroyed(struct wl_listener * listener,void * data)414 touch_focus_view_destroyed(struct wl_listener *listener, void *data)
415 {
416 	struct weston_touch *touch =
417 		container_of(listener, struct weston_touch,
418 			     focus_view_listener);
419 
420 	weston_touch_set_focus(touch, NULL);
421 }
422 
423 static void
touch_focus_resource_destroyed(struct wl_listener * listener,void * data)424 touch_focus_resource_destroyed(struct wl_listener *listener, void *data)
425 {
426 	struct weston_touch *touch =
427 		container_of(listener, struct weston_touch,
428 			     focus_resource_listener);
429 
430 	weston_touch_set_focus(touch, NULL);
431 }
432 
433 static void
move_resources(struct wl_list * destination,struct wl_list * source)434 move_resources(struct wl_list *destination, struct wl_list *source)
435 {
436 	wl_list_insert_list(destination, source);
437 	wl_list_init(source);
438 }
439 
440 static void
move_resources_for_client(struct wl_list * destination,struct wl_list * source,struct wl_client * client)441 move_resources_for_client(struct wl_list *destination,
442 			  struct wl_list *source,
443 			  struct wl_client *client)
444 {
445 	struct wl_resource *resource, *tmp;
446 	wl_resource_for_each_safe(resource, tmp, source) {
447 		if (wl_resource_get_client(resource) == client) {
448 			wl_list_remove(wl_resource_get_link(resource));
449 			wl_list_insert(destination,
450 				       wl_resource_get_link(resource));
451 		}
452 	}
453 }
454 
455 static void
default_grab_pointer_focus(struct weston_pointer_grab * grab)456 default_grab_pointer_focus(struct weston_pointer_grab *grab)
457 {
458 	struct weston_pointer *pointer = grab->pointer;
459 	struct weston_view *view;
460 	wl_fixed_t sx, sy;
461 
462 	if (pointer->button_count > 0)
463 		return;
464 
465 	view = weston_compositor_pick_view(pointer->seat->compositor,
466 					   pointer->x, pointer->y,
467 					   &sx, &sy);
468 
469 	if (pointer->focus != view || pointer->sx != sx || pointer->sy != sy)
470 		weston_pointer_set_focus(pointer, view, sx, sy);
471 }
472 
473 static void
pointer_send_relative_motion(struct weston_pointer * pointer,const struct timespec * time,struct weston_pointer_motion_event * event)474 pointer_send_relative_motion(struct weston_pointer *pointer,
475 			     const struct timespec *time,
476 			     struct weston_pointer_motion_event *event)
477 {
478 	uint64_t time_usec;
479 	double dx, dy, dx_unaccel, dy_unaccel;
480 	wl_fixed_t dxf, dyf, dxf_unaccel, dyf_unaccel;
481 	struct wl_list *resource_list;
482 	struct wl_resource *resource;
483 
484 	if (!pointer->focus_client)
485 		return;
486 
487 	if (!weston_pointer_motion_to_rel(pointer, event,
488 					  &dx, &dy,
489 					  &dx_unaccel, &dy_unaccel))
490 		return;
491 
492 	resource_list = &pointer->focus_client->relative_pointer_resources;
493 	time_usec = timespec_to_usec(&event->time);
494 	if (time_usec == 0)
495 		time_usec = timespec_to_usec(time);
496 
497 	dxf = wl_fixed_from_double(dx);
498 	dyf = wl_fixed_from_double(dy);
499 	dxf_unaccel = wl_fixed_from_double(dx_unaccel);
500 	dyf_unaccel = wl_fixed_from_double(dy_unaccel);
501 
502 	wl_resource_for_each(resource, resource_list) {
503 		zwp_relative_pointer_v1_send_relative_motion(
504 			resource,
505 			(uint32_t) (time_usec >> 32),
506 			(uint32_t) time_usec,
507 			dxf, dyf,
508 			dxf_unaccel, dyf_unaccel);
509 	}
510 }
511 
512 static void
pointer_send_motion(struct weston_pointer * pointer,const struct timespec * time,wl_fixed_t sx,wl_fixed_t sy)513 pointer_send_motion(struct weston_pointer *pointer,
514 		    const struct timespec *time,
515 		    wl_fixed_t sx, wl_fixed_t sy)
516 {
517 	struct wl_list *resource_list;
518 	struct wl_resource *resource;
519 	uint32_t msecs;
520 
521 	if (!pointer->focus_client)
522 		return;
523 
524 	resource_list = &pointer->focus_client->pointer_resources;
525 	msecs = timespec_to_msec(time);
526 	wl_resource_for_each(resource, resource_list) {
527 		send_timestamps_for_input_resource(resource,
528                                                    &pointer->timestamps_list,
529                                                    time);
530 		wl_pointer_send_motion(resource, msecs, sx, sy);
531 	}
532 }
533 
534 WL_EXPORT void
weston_pointer_send_motion(struct weston_pointer * pointer,const struct timespec * time,struct weston_pointer_motion_event * event)535 weston_pointer_send_motion(struct weston_pointer *pointer,
536 			   const struct timespec *time,
537 			   struct weston_pointer_motion_event *event)
538 {
539 	wl_fixed_t x, y;
540 	wl_fixed_t old_sx = pointer->sx;
541 	wl_fixed_t old_sy = pointer->sy;
542 
543 	if (pointer->focus) {
544 		weston_pointer_motion_to_abs(pointer, event, &x, &y);
545 		weston_view_from_global_fixed(pointer->focus, x, y,
546 					      &pointer->sx, &pointer->sy);
547 	}
548 
549 	weston_pointer_move(pointer, event);
550 
551 	if (old_sx != pointer->sx || old_sy != pointer->sy) {
552 		pointer_send_motion(pointer, time,
553 				    pointer->sx, pointer->sy);
554 	}
555 
556 	pointer_send_relative_motion(pointer, time, event);
557 }
558 
559 static void
default_grab_pointer_motion(struct weston_pointer_grab * grab,const struct timespec * time,struct weston_pointer_motion_event * event)560 default_grab_pointer_motion(struct weston_pointer_grab *grab,
561 			    const struct timespec *time,
562 			    struct weston_pointer_motion_event *event)
563 {
564 	weston_pointer_send_motion(grab->pointer, time, event);
565 }
566 
567 /** Check if the pointer has focused resources.
568  *
569  * \param pointer The pointer to check for focused resources.
570  * \return Whether or not this pointer has focused resources
571  */
572 WL_EXPORT bool
weston_pointer_has_focus_resource(struct weston_pointer * pointer)573 weston_pointer_has_focus_resource(struct weston_pointer *pointer)
574 {
575 	if (!pointer->focus_client)
576 		return false;
577 
578 	if (wl_list_empty(&pointer->focus_client->pointer_resources))
579 		return false;
580 
581 	return true;
582 }
583 
584 /** Send wl_pointer.button events to focused resources.
585  *
586  * \param pointer The pointer where the button events originates from.
587  * \param time The timestamp of the event
588  * \param button The button value of the event
589  * \param state The state enum value of the event
590  *
591  * For every resource that is currently in focus, send a wl_pointer.button event
592  * with the passed parameters. The focused resources are the wl_pointer
593  * resources of the client which currently has the surface with pointer focus.
594  */
595 WL_EXPORT void
weston_pointer_send_button(struct weston_pointer * pointer,const struct timespec * time,uint32_t button,enum wl_pointer_button_state state)596 weston_pointer_send_button(struct weston_pointer *pointer,
597 			   const struct timespec *time, uint32_t button,
598 			   enum wl_pointer_button_state state)
599 {
600 	struct wl_display *display = pointer->seat->compositor->wl_display;
601 	struct wl_list *resource_list;
602 	struct wl_resource *resource;
603 	uint32_t serial;
604 	uint32_t msecs;
605 
606 	if (!weston_pointer_has_focus_resource(pointer))
607 		return;
608 
609 	resource_list = &pointer->focus_client->pointer_resources;
610 	serial = wl_display_next_serial(display);
611 	msecs = timespec_to_msec(time);
612 	wl_resource_for_each(resource, resource_list) {
613 		send_timestamps_for_input_resource(resource,
614                                                    &pointer->timestamps_list,
615                                                    time);
616 		wl_pointer_send_button(resource, serial, msecs, button, state);
617 	}
618 }
619 
620 static void
default_grab_pointer_button(struct weston_pointer_grab * grab,const struct timespec * time,uint32_t button,enum wl_pointer_button_state state)621 default_grab_pointer_button(struct weston_pointer_grab *grab,
622 			    const struct timespec *time, uint32_t button,
623 			    enum wl_pointer_button_state state)
624 {
625 	struct weston_pointer *pointer = grab->pointer;
626 	struct weston_compositor *compositor = pointer->seat->compositor;
627 	struct weston_view *view;
628 	wl_fixed_t sx, sy;
629 
630 	weston_pointer_send_button(pointer, time, button, state);
631 
632 	if (pointer->button_count == 0 &&
633 	    state == WL_POINTER_BUTTON_STATE_RELEASED) {
634 		view = weston_compositor_pick_view(compositor,
635 						   pointer->x, pointer->y,
636 						   &sx, &sy);
637 
638 		weston_pointer_set_focus(pointer, view, sx, sy);
639 	}
640 }
641 
642 /** Send wl_pointer.axis events to focused resources.
643  *
644  * \param pointer The pointer where the axis events originates from.
645  * \param time The timestamp of the event
646  * \param event The axis value of the event
647  *
648  * For every resource that is currently in focus, send a wl_pointer.axis event
649  * with the passed parameters. The focused resources are the wl_pointer
650  * resources of the client which currently has the surface with pointer focus.
651  */
652 WL_EXPORT void
weston_pointer_send_axis(struct weston_pointer * pointer,const struct timespec * time,struct weston_pointer_axis_event * event)653 weston_pointer_send_axis(struct weston_pointer *pointer,
654 			 const struct timespec *time,
655 			 struct weston_pointer_axis_event *event)
656 {
657 	struct wl_resource *resource;
658 	struct wl_list *resource_list;
659 	uint32_t msecs;
660 
661 	if (!weston_pointer_has_focus_resource(pointer))
662 		return;
663 
664 	resource_list = &pointer->focus_client->pointer_resources;
665 	msecs = timespec_to_msec(time);
666 	wl_resource_for_each(resource, resource_list) {
667 		if (event->has_discrete &&
668 		    wl_resource_get_version(resource) >=
669 		    WL_POINTER_AXIS_DISCRETE_SINCE_VERSION)
670 			wl_pointer_send_axis_discrete(resource, event->axis,
671 						      event->discrete);
672 
673 		if (event->value) {
674 			send_timestamps_for_input_resource(resource,
675 							   &pointer->timestamps_list,
676 							   time);
677 			wl_pointer_send_axis(resource, msecs,
678 					     event->axis,
679 					     wl_fixed_from_double(event->value));
680 		} else if (wl_resource_get_version(resource) >=
681 			 WL_POINTER_AXIS_STOP_SINCE_VERSION) {
682 			send_timestamps_for_input_resource(resource,
683 							   &pointer->timestamps_list,
684 							   time);
685 			wl_pointer_send_axis_stop(resource, msecs,
686 						  event->axis);
687 		}
688 	}
689 }
690 
691 /** Send wl_pointer.axis_source events to focused resources.
692  *
693  * \param pointer The pointer where the axis_source events originates from.
694  * \param source The axis_source enum value of the event
695  *
696  * For every resource that is currently in focus, send a wl_pointer.axis_source
697  * event with the passed parameter. The focused resources are the wl_pointer
698  * resources of the client which currently has the surface with pointer focus.
699  */
700 WL_EXPORT void
weston_pointer_send_axis_source(struct weston_pointer * pointer,enum wl_pointer_axis_source source)701 weston_pointer_send_axis_source(struct weston_pointer *pointer,
702 				enum wl_pointer_axis_source source)
703 {
704 	struct wl_resource *resource;
705 	struct wl_list *resource_list;
706 
707 	if (!weston_pointer_has_focus_resource(pointer))
708 		return;
709 
710 	resource_list = &pointer->focus_client->pointer_resources;
711 	wl_resource_for_each(resource, resource_list) {
712 		if (wl_resource_get_version(resource) >=
713 		    WL_POINTER_AXIS_SOURCE_SINCE_VERSION) {
714 			wl_pointer_send_axis_source(resource, source);
715 		}
716 	}
717 }
718 
719 static void
pointer_send_frame(struct wl_resource * resource)720 pointer_send_frame(struct wl_resource *resource)
721 {
722 	if (wl_resource_get_version(resource) >=
723 	    WL_POINTER_FRAME_SINCE_VERSION) {
724 		wl_pointer_send_frame(resource);
725 	}
726 }
727 
728 /** Send wl_pointer.frame events to focused resources.
729  *
730  * \param pointer The pointer where the frame events originates from.
731  *
732  * For every resource that is currently in focus, send a wl_pointer.frame event.
733  * The focused resources are the wl_pointer resources of the client which
734  * currently has the surface with pointer focus.
735  */
736 WL_EXPORT void
weston_pointer_send_frame(struct weston_pointer * pointer)737 weston_pointer_send_frame(struct weston_pointer *pointer)
738 {
739 	struct wl_resource *resource;
740 	struct wl_list *resource_list;
741 
742 	if (!weston_pointer_has_focus_resource(pointer))
743 		return;
744 
745 	resource_list = &pointer->focus_client->pointer_resources;
746 	wl_resource_for_each(resource, resource_list)
747 		pointer_send_frame(resource);
748 }
749 
750 static void
default_grab_pointer_axis(struct weston_pointer_grab * grab,const struct timespec * time,struct weston_pointer_axis_event * event)751 default_grab_pointer_axis(struct weston_pointer_grab *grab,
752 			  const struct timespec *time,
753 			  struct weston_pointer_axis_event *event)
754 {
755 	weston_pointer_send_axis(grab->pointer, time, event);
756 }
757 
758 static void
default_grab_pointer_axis_source(struct weston_pointer_grab * grab,enum wl_pointer_axis_source source)759 default_grab_pointer_axis_source(struct weston_pointer_grab *grab,
760 				 enum wl_pointer_axis_source source)
761 {
762 	weston_pointer_send_axis_source(grab->pointer, source);
763 }
764 
765 static void
default_grab_pointer_frame(struct weston_pointer_grab * grab)766 default_grab_pointer_frame(struct weston_pointer_grab *grab)
767 {
768 	weston_pointer_send_frame(grab->pointer);
769 }
770 
771 static void
default_grab_pointer_cancel(struct weston_pointer_grab * grab)772 default_grab_pointer_cancel(struct weston_pointer_grab *grab)
773 {
774 }
775 
776 static const struct weston_pointer_grab_interface
777 				default_pointer_grab_interface = {
778 	default_grab_pointer_focus,
779 	default_grab_pointer_motion,
780 	default_grab_pointer_button,
781 	default_grab_pointer_axis,
782 	default_grab_pointer_axis_source,
783 	default_grab_pointer_frame,
784 	default_grab_pointer_cancel,
785 };
786 
787 /** Check if the touch has focused resources.
788  *
789  * \param touch The touch to check for focused resources.
790  * \return Whether or not this touch has focused resources
791  */
792 WL_EXPORT bool
weston_touch_has_focus_resource(struct weston_touch * touch)793 weston_touch_has_focus_resource(struct weston_touch *touch)
794 {
795 	if (!touch->focus)
796 		return false;
797 
798 	if (wl_list_empty(&touch->focus_resource_list))
799 		return false;
800 
801 	return true;
802 }
803 
804 /** Send wl_touch.down events to focused resources.
805  *
806  * \param touch The touch where the down events originates from.
807  * \param time The timestamp of the event
808  * \param touch_id The touch_id value of the event
809  * \param x The x value of the event
810  * \param y The y value of the event
811  *
812  * For every resource that is currently in focus, send a wl_touch.down event
813  * with the passed parameters. The focused resources are the wl_touch
814  * resources of the client which currently has the surface with touch focus.
815  */
816 WL_EXPORT void
weston_touch_send_down(struct weston_touch * touch,const struct timespec * time,int touch_id,wl_fixed_t x,wl_fixed_t y)817 weston_touch_send_down(struct weston_touch *touch, const struct timespec *time,
818 		       int touch_id, wl_fixed_t x, wl_fixed_t y)
819 {
820 	struct wl_display *display = touch->seat->compositor->wl_display;
821 	uint32_t serial;
822 	struct wl_resource *resource;
823 	struct wl_list *resource_list;
824 	wl_fixed_t sx, sy;
825 	uint32_t msecs;
826 
827 	if (!weston_touch_has_focus_resource(touch))
828 		return;
829 
830 	weston_view_from_global_fixed(touch->focus, x, y, &sx, &sy);
831 
832 	resource_list = &touch->focus_resource_list;
833 	serial = wl_display_next_serial(display);
834 	msecs = timespec_to_msec(time);
835 	wl_resource_for_each(resource, resource_list) {
836 		send_timestamps_for_input_resource(resource,
837 						   &touch->timestamps_list,
838 						   time);
839 		wl_touch_send_down(resource, serial, msecs,
840 				   touch->focus->surface->resource,
841 				   touch_id, sx, sy);
842 	}
843 }
844 
845 static void
default_grab_touch_down(struct weston_touch_grab * grab,const struct timespec * time,int touch_id,wl_fixed_t x,wl_fixed_t y)846 default_grab_touch_down(struct weston_touch_grab *grab,
847 			const struct timespec *time, int touch_id,
848 			wl_fixed_t x, wl_fixed_t y)
849 {
850 	weston_touch_send_down(grab->touch, time, touch_id, x, y);
851 }
852 
853 /** Send wl_touch.up events to focused resources.
854  *
855  * \param touch The touch where the up events originates from.
856  * \param time The timestamp of the event
857  * \param touch_id The touch_id value of the event
858  *
859  * For every resource that is currently in focus, send a wl_touch.up event
860  * with the passed parameters. The focused resources are the wl_touch
861  * resources of the client which currently has the surface with touch focus.
862  */
863 WL_EXPORT void
weston_touch_send_up(struct weston_touch * touch,const struct timespec * time,int touch_id)864 weston_touch_send_up(struct weston_touch *touch, const struct timespec *time,
865 		     int touch_id)
866 {
867 	struct wl_display *display = touch->seat->compositor->wl_display;
868 	uint32_t serial;
869 	struct wl_resource *resource;
870 	struct wl_list *resource_list;
871 	uint32_t msecs;
872 
873 	if (!weston_touch_has_focus_resource(touch))
874 		return;
875 
876 	resource_list = &touch->focus_resource_list;
877 	serial = wl_display_next_serial(display);
878 	msecs = timespec_to_msec(time);
879 	wl_resource_for_each(resource, resource_list) {
880 		send_timestamps_for_input_resource(resource,
881 						   &touch->timestamps_list,
882 						   time);
883 		wl_touch_send_up(resource, serial, msecs, touch_id);
884 	}
885 }
886 
887 static void
default_grab_touch_up(struct weston_touch_grab * grab,const struct timespec * time,int touch_id)888 default_grab_touch_up(struct weston_touch_grab *grab,
889 		      const struct timespec *time, int touch_id)
890 {
891 	weston_touch_send_up(grab->touch, time, touch_id);
892 }
893 
894 /** Send wl_touch.motion events to focused resources.
895  *
896  * \param touch The touch where the motion events originates from.
897  * \param time The timestamp of the event
898  * \param touch_id The touch_id value of the event
899  * \param x The x value of the event
900  * \param y The y value of the event
901  *
902  * For every resource that is currently in focus, send a wl_touch.motion event
903  * with the passed parameters. The focused resources are the wl_touch
904  * resources of the client which currently has the surface with touch focus.
905  */
906 WL_EXPORT void
weston_touch_send_motion(struct weston_touch * touch,const struct timespec * time,int touch_id,wl_fixed_t x,wl_fixed_t y)907 weston_touch_send_motion(struct weston_touch *touch,
908 			 const struct timespec *time, int touch_id,
909 			 wl_fixed_t x, wl_fixed_t y)
910 {
911 	struct wl_resource *resource;
912 	struct wl_list *resource_list;
913 	wl_fixed_t sx, sy;
914 	uint32_t msecs;
915 
916 	if (!weston_touch_has_focus_resource(touch))
917 		return;
918 
919 	weston_view_from_global_fixed(touch->focus, x, y, &sx, &sy);
920 
921 	resource_list = &touch->focus_resource_list;
922 	msecs = timespec_to_msec(time);
923 	wl_resource_for_each(resource, resource_list) {
924 		send_timestamps_for_input_resource(resource,
925 						   &touch->timestamps_list,
926 						   time);
927 		wl_touch_send_motion(resource, msecs,
928 				     touch_id, sx, sy);
929 	}
930 }
931 
932 static void
default_grab_touch_motion(struct weston_touch_grab * grab,const struct timespec * time,int touch_id,wl_fixed_t x,wl_fixed_t y)933 default_grab_touch_motion(struct weston_touch_grab *grab,
934 			  const struct timespec *time, int touch_id,
935 			  wl_fixed_t x, wl_fixed_t y)
936 {
937 	weston_touch_send_motion(grab->touch, time, touch_id, x, y);
938 }
939 
940 
941 /** Send wl_touch.frame events to focused resources.
942  *
943  * \param touch The touch where the frame events originates from.
944  *
945  * For every resource that is currently in focus, send a wl_touch.frame event.
946  * The focused resources are the wl_touch resources of the client which
947  * currently has the surface with touch focus.
948  */
949 WL_EXPORT void
weston_touch_send_frame(struct weston_touch * touch)950 weston_touch_send_frame(struct weston_touch *touch)
951 {
952 	struct wl_resource *resource;
953 
954 	if (!weston_touch_has_focus_resource(touch))
955 		return;
956 
957 	wl_resource_for_each(resource, &touch->focus_resource_list)
958 		wl_touch_send_frame(resource);
959 }
960 
961 static void
default_grab_touch_frame(struct weston_touch_grab * grab)962 default_grab_touch_frame(struct weston_touch_grab *grab)
963 {
964 	weston_touch_send_frame(grab->touch);
965 }
966 
967 static void
default_grab_touch_cancel(struct weston_touch_grab * grab)968 default_grab_touch_cancel(struct weston_touch_grab *grab)
969 {
970 }
971 
972 static const struct weston_touch_grab_interface default_touch_grab_interface = {
973 	default_grab_touch_down,
974 	default_grab_touch_up,
975 	default_grab_touch_motion,
976 	default_grab_touch_frame,
977 	default_grab_touch_cancel,
978 };
979 
980 /** Check if the keyboard has focused resources.
981  *
982  * \param keyboard The keyboard to check for focused resources.
983  * \return Whether or not this keyboard has focused resources
984  */
985 WL_EXPORT bool
weston_keyboard_has_focus_resource(struct weston_keyboard * keyboard)986 weston_keyboard_has_focus_resource(struct weston_keyboard *keyboard)
987 {
988 	if (!keyboard->focus)
989 		return false;
990 
991 	if (wl_list_empty(&keyboard->focus_resource_list))
992 		return false;
993 
994 	return true;
995 }
996 
997 /** Send wl_keyboard.key events to focused resources.
998  *
999  * \param keyboard The keyboard where the key events originates from.
1000  * \param time The timestamp of the event
1001  * \param key The key value of the event
1002  * \param state The state enum value of the event
1003  *
1004  * For every resource that is currently in focus, send a wl_keyboard.key event
1005  * with the passed parameters. The focused resources are the wl_keyboard
1006  * resources of the client which currently has the surface with keyboard focus.
1007  */
1008 WL_EXPORT void
weston_keyboard_send_key(struct weston_keyboard * keyboard,const struct timespec * time,uint32_t key,enum wl_keyboard_key_state state)1009 weston_keyboard_send_key(struct weston_keyboard *keyboard,
1010 			 const struct timespec *time, uint32_t key,
1011 			 enum wl_keyboard_key_state state)
1012 {
1013 	struct wl_resource *resource;
1014 	struct wl_display *display = keyboard->seat->compositor->wl_display;
1015 	uint32_t serial;
1016 	struct wl_list *resource_list;
1017 	uint32_t msecs;
1018 
1019 	if (!weston_keyboard_has_focus_resource(keyboard))
1020 		return;
1021 
1022 	resource_list = &keyboard->focus_resource_list;
1023 	serial = wl_display_next_serial(display);
1024 	msecs = timespec_to_msec(time);
1025 	wl_resource_for_each(resource, resource_list) {
1026 		send_timestamps_for_input_resource(resource,
1027 						   &keyboard->timestamps_list,
1028 						   time);
1029 		wl_keyboard_send_key(resource, serial, msecs, key, state);
1030 	}
1031 };
1032 
1033 static void
default_grab_keyboard_key(struct weston_keyboard_grab * grab,const struct timespec * time,uint32_t key,uint32_t state)1034 default_grab_keyboard_key(struct weston_keyboard_grab *grab,
1035 			  const struct timespec *time, uint32_t key,
1036 			  uint32_t state)
1037 {
1038 	weston_keyboard_send_key(grab->keyboard, time, key, state);
1039 }
1040 
1041 static void
send_modifiers_to_resource(struct weston_keyboard * keyboard,struct wl_resource * resource,uint32_t serial)1042 send_modifiers_to_resource(struct weston_keyboard *keyboard,
1043 			   struct wl_resource *resource,
1044 			   uint32_t serial)
1045 {
1046 	wl_keyboard_send_modifiers(resource,
1047 				   serial,
1048 				   keyboard->modifiers.mods_depressed,
1049 				   keyboard->modifiers.mods_latched,
1050 				   keyboard->modifiers.mods_locked,
1051 				   keyboard->modifiers.group);
1052 }
1053 
1054 static void
send_modifiers_to_client_in_list(struct wl_client * client,struct wl_list * list,uint32_t serial,struct weston_keyboard * keyboard)1055 send_modifiers_to_client_in_list(struct wl_client *client,
1056 				 struct wl_list *list,
1057 				 uint32_t serial,
1058 				 struct weston_keyboard *keyboard)
1059 {
1060 	struct wl_resource *resource;
1061 
1062 	wl_resource_for_each(resource, list) {
1063 		if (wl_resource_get_client(resource) == client)
1064 			send_modifiers_to_resource(keyboard,
1065 						   resource,
1066 						   serial);
1067 	}
1068 }
1069 
1070 static struct weston_pointer_client *
find_pointer_client_for_surface(struct weston_pointer * pointer,struct weston_surface * surface)1071 find_pointer_client_for_surface(struct weston_pointer *pointer,
1072 				struct weston_surface *surface)
1073 {
1074 	struct wl_client *client;
1075 
1076 	if (!surface)
1077 		return NULL;
1078 
1079 	if (!surface->resource)
1080 		return NULL;
1081 
1082 	client = wl_resource_get_client(surface->resource);
1083 	return weston_pointer_get_pointer_client(pointer, client);
1084 }
1085 
1086 static struct weston_pointer_client *
find_pointer_client_for_view(struct weston_pointer * pointer,struct weston_view * view)1087 find_pointer_client_for_view(struct weston_pointer *pointer, struct weston_view *view)
1088 {
1089 	if (!view)
1090 		return NULL;
1091 
1092 	return find_pointer_client_for_surface(pointer, view->surface);
1093 }
1094 
1095 static struct wl_resource *
find_resource_for_surface(struct wl_list * list,struct weston_surface * surface)1096 find_resource_for_surface(struct wl_list *list, struct weston_surface *surface)
1097 {
1098 	if (!surface)
1099 		return NULL;
1100 
1101 	if (!surface->resource)
1102 		return NULL;
1103 
1104 	return wl_resource_find_for_client(list, wl_resource_get_client(surface->resource));
1105 }
1106 
1107 /** Send wl_keyboard.modifiers events to focused resources and pointer
1108  *  focused resources.
1109  *
1110  * \param keyboard The keyboard where the modifiers events originates from.
1111  * \param serial The serial of the event
1112  * \param mods_depressed The mods_depressed value of the event
1113  * \param mods_latched The mods_latched value of the event
1114  * \param mods_locked The mods_locked value of the event
1115  * \param group The group value of the event
1116  *
1117  * For every resource that is currently in focus, send a wl_keyboard.modifiers
1118  * event with the passed parameters. The focused resources are the wl_keyboard
1119  * resources of the client which currently has the surface with keyboard focus.
1120  * This also sends wl_keyboard.modifiers events to the wl_keyboard resources of
1121  * the client having pointer focus (if different from the keyboard focus client).
1122  */
1123 WL_EXPORT void
weston_keyboard_send_modifiers(struct weston_keyboard * keyboard,uint32_t serial,uint32_t mods_depressed,uint32_t mods_latched,uint32_t mods_locked,uint32_t group)1124 weston_keyboard_send_modifiers(struct weston_keyboard *keyboard,
1125 			       uint32_t serial, uint32_t mods_depressed,
1126 			       uint32_t mods_latched,
1127 			       uint32_t mods_locked, uint32_t group)
1128 {
1129 	struct weston_pointer *pointer =
1130 		weston_seat_get_pointer(keyboard->seat);
1131 
1132 	if (weston_keyboard_has_focus_resource(keyboard)) {
1133 		struct wl_list *resource_list;
1134 		struct wl_resource *resource;
1135 
1136 		resource_list = &keyboard->focus_resource_list;
1137 		wl_resource_for_each(resource, resource_list) {
1138 			wl_keyboard_send_modifiers(resource, serial,
1139 						   mods_depressed, mods_latched,
1140 						   mods_locked, group);
1141 		}
1142 	}
1143 
1144 	if (pointer && pointer->focus && pointer->focus->surface->resource &&
1145 	    pointer->focus->surface != keyboard->focus) {
1146 		struct wl_client *pointer_client =
1147 			wl_resource_get_client(pointer->focus->surface->resource);
1148 
1149 		send_modifiers_to_client_in_list(pointer_client,
1150 						 &keyboard->resource_list,
1151 						 serial,
1152 						 keyboard);
1153 	}
1154 }
1155 
1156 static void
default_grab_keyboard_modifiers(struct weston_keyboard_grab * grab,uint32_t serial,uint32_t mods_depressed,uint32_t mods_latched,uint32_t mods_locked,uint32_t group)1157 default_grab_keyboard_modifiers(struct weston_keyboard_grab *grab,
1158 				uint32_t serial, uint32_t mods_depressed,
1159 				uint32_t mods_latched,
1160 				uint32_t mods_locked, uint32_t group)
1161 {
1162 	weston_keyboard_send_modifiers(grab->keyboard, serial, mods_depressed,
1163 				       mods_latched, mods_locked, group);
1164 }
1165 
1166 static void
default_grab_keyboard_cancel(struct weston_keyboard_grab * grab)1167 default_grab_keyboard_cancel(struct weston_keyboard_grab *grab)
1168 {
1169 }
1170 
1171 static const struct weston_keyboard_grab_interface
1172 				default_keyboard_grab_interface = {
1173 	default_grab_keyboard_key,
1174 	default_grab_keyboard_modifiers,
1175 	default_grab_keyboard_cancel,
1176 };
1177 
1178 static void
pointer_unmap_sprite(struct weston_pointer * pointer)1179 pointer_unmap_sprite(struct weston_pointer *pointer)
1180 {
1181 	struct weston_surface *surface = pointer->sprite->surface;
1182 
1183 	if (weston_surface_is_mapped(surface))
1184 		weston_surface_unmap(surface);
1185 
1186 	wl_list_remove(&pointer->sprite_destroy_listener.link);
1187 	surface->committed = NULL;
1188 	surface->committed_private = NULL;
1189 	weston_surface_set_label_func(surface, NULL);
1190 	weston_view_destroy(pointer->sprite);
1191 	pointer->sprite = NULL;
1192 }
1193 
1194 static void
pointer_handle_sprite_destroy(struct wl_listener * listener,void * data)1195 pointer_handle_sprite_destroy(struct wl_listener *listener, void *data)
1196 {
1197 	struct weston_pointer *pointer =
1198 		container_of(listener, struct weston_pointer,
1199 			     sprite_destroy_listener);
1200 
1201 	pointer->sprite = NULL;
1202 }
1203 
1204 static void
weston_pointer_reset_state(struct weston_pointer * pointer)1205 weston_pointer_reset_state(struct weston_pointer *pointer)
1206 {
1207 	pointer->button_count = 0;
1208 }
1209 
1210 static void
1211 weston_pointer_handle_output_destroy(struct wl_listener *listener, void *data);
1212 
1213 static struct weston_pointer *
weston_pointer_create(struct weston_seat * seat)1214 weston_pointer_create(struct weston_seat *seat)
1215 {
1216 	struct weston_pointer *pointer;
1217 
1218 	pointer = zalloc(sizeof *pointer);
1219 	if (pointer == NULL)
1220 		return NULL;
1221 
1222 	wl_list_init(&pointer->pointer_clients);
1223 	weston_pointer_set_default_grab(pointer,
1224 					seat->compositor->default_pointer_grab);
1225 	wl_list_init(&pointer->focus_resource_listener.link);
1226 	pointer->focus_resource_listener.notify = pointer_focus_resource_destroyed;
1227 	pointer->default_grab.pointer = pointer;
1228 	pointer->grab = &pointer->default_grab;
1229 	wl_signal_init(&pointer->motion_signal);
1230 	wl_signal_init(&pointer->focus_signal);
1231 	wl_list_init(&pointer->focus_view_listener.link);
1232 	wl_signal_init(&pointer->destroy_signal);
1233 	wl_list_init(&pointer->timestamps_list);
1234 
1235 	pointer->sprite_destroy_listener.notify = pointer_handle_sprite_destroy;
1236 
1237 	/* FIXME: Pick better co-ords. */
1238 	pointer->x = wl_fixed_from_int(100);
1239 	pointer->y = wl_fixed_from_int(100);
1240 
1241 	pointer->output_destroy_listener.notify =
1242 		weston_pointer_handle_output_destroy;
1243 	wl_signal_add(&seat->compositor->output_destroyed_signal,
1244 		      &pointer->output_destroy_listener);
1245 
1246 	pointer->sx = wl_fixed_from_int(-1000000);
1247 	pointer->sy = wl_fixed_from_int(-1000000);
1248 
1249 	return pointer;
1250 }
1251 
1252 static void
weston_pointer_destroy(struct weston_pointer * pointer)1253 weston_pointer_destroy(struct weston_pointer *pointer)
1254 {
1255 	struct weston_pointer_client *pointer_client, *tmp;
1256 
1257 	wl_signal_emit(&pointer->destroy_signal, pointer);
1258 
1259 	if (pointer->sprite)
1260 		pointer_unmap_sprite(pointer);
1261 
1262 	wl_list_for_each_safe(pointer_client, tmp, &pointer->pointer_clients,
1263 			      link) {
1264 		wl_list_remove(&pointer_client->link);
1265 		weston_pointer_client_destroy(pointer_client);
1266 	}
1267 
1268 	wl_list_remove(&pointer->focus_resource_listener.link);
1269 	wl_list_remove(&pointer->focus_view_listener.link);
1270 	wl_list_remove(&pointer->output_destroy_listener.link);
1271 	wl_list_remove(&pointer->timestamps_list);
1272 	free(pointer);
1273 }
1274 
1275 void
weston_pointer_set_default_grab(struct weston_pointer * pointer,const struct weston_pointer_grab_interface * interface)1276 weston_pointer_set_default_grab(struct weston_pointer *pointer,
1277 		const struct weston_pointer_grab_interface *interface)
1278 {
1279 	if (interface)
1280 		pointer->default_grab.interface = interface;
1281 	else
1282 		pointer->default_grab.interface =
1283 			&default_pointer_grab_interface;
1284 }
1285 
1286 static struct weston_keyboard *
weston_keyboard_create(void)1287 weston_keyboard_create(void)
1288 {
1289 	struct weston_keyboard *keyboard;
1290 
1291 	keyboard = zalloc(sizeof *keyboard);
1292 	if (keyboard == NULL)
1293 	    return NULL;
1294 
1295 	wl_list_init(&keyboard->resource_list);
1296 	wl_list_init(&keyboard->focus_resource_list);
1297 	wl_list_init(&keyboard->focus_resource_listener.link);
1298 	keyboard->focus_resource_listener.notify = keyboard_focus_resource_destroyed;
1299 	wl_array_init(&keyboard->keys);
1300 	keyboard->default_grab.interface = &default_keyboard_grab_interface;
1301 	keyboard->default_grab.keyboard = keyboard;
1302 	keyboard->grab = &keyboard->default_grab;
1303 	wl_signal_init(&keyboard->focus_signal);
1304 	wl_list_init(&keyboard->timestamps_list);
1305 
1306 	return keyboard;
1307 }
1308 
1309 static void
1310 weston_xkb_info_destroy(struct weston_xkb_info *xkb_info);
1311 
1312 static void
weston_keyboard_destroy(struct weston_keyboard * keyboard)1313 weston_keyboard_destroy(struct weston_keyboard *keyboard)
1314 {
1315 	struct wl_resource *resource;
1316 
1317 	wl_resource_for_each(resource, &keyboard->resource_list) {
1318 		wl_resource_set_user_data(resource, NULL);
1319 	}
1320 
1321 	wl_resource_for_each(resource, &keyboard->focus_resource_list) {
1322 		wl_resource_set_user_data(resource, NULL);
1323 	}
1324 
1325 	wl_list_remove(&keyboard->resource_list);
1326 	wl_list_remove(&keyboard->focus_resource_list);
1327 
1328 	xkb_state_unref(keyboard->xkb_state.state);
1329 	if (keyboard->xkb_info)
1330 		weston_xkb_info_destroy(keyboard->xkb_info);
1331 	xkb_keymap_unref(keyboard->pending_keymap);
1332 
1333 	wl_array_release(&keyboard->keys);
1334 	wl_list_remove(&keyboard->focus_resource_listener.link);
1335 	wl_list_remove(&keyboard->timestamps_list);
1336 	free(keyboard);
1337 }
1338 
1339 static void
weston_touch_reset_state(struct weston_touch * touch)1340 weston_touch_reset_state(struct weston_touch *touch)
1341 {
1342 	touch->num_tp = 0;
1343 }
1344 
1345 static struct weston_touch *
weston_touch_create(void)1346 weston_touch_create(void)
1347 {
1348 	struct weston_touch *touch;
1349 
1350 	touch = zalloc(sizeof *touch);
1351 	if (touch == NULL)
1352 		return NULL;
1353 
1354 	wl_list_init(&touch->device_list);
1355 	wl_list_init(&touch->resource_list);
1356 	wl_list_init(&touch->focus_resource_list);
1357 	wl_list_init(&touch->focus_view_listener.link);
1358 	touch->focus_view_listener.notify = touch_focus_view_destroyed;
1359 	wl_list_init(&touch->focus_resource_listener.link);
1360 	touch->focus_resource_listener.notify = touch_focus_resource_destroyed;
1361 	touch->default_grab.interface = &default_touch_grab_interface;
1362 	touch->default_grab.touch = touch;
1363 	touch->grab = &touch->default_grab;
1364 	wl_signal_init(&touch->focus_signal);
1365 	wl_list_init(&touch->timestamps_list);
1366 
1367 	return touch;
1368 }
1369 
1370 static void
weston_touch_destroy(struct weston_touch * touch)1371 weston_touch_destroy(struct weston_touch *touch)
1372 {
1373 	struct wl_resource *resource;
1374 
1375 	assert(wl_list_empty(&touch->device_list));
1376 
1377 	wl_resource_for_each(resource, &touch->resource_list) {
1378 		wl_resource_set_user_data(resource, NULL);
1379 	}
1380 
1381 	wl_resource_for_each(resource, &touch->focus_resource_list) {
1382 		wl_resource_set_user_data(resource, NULL);
1383 	}
1384 
1385 	wl_list_remove(&touch->resource_list);
1386 	wl_list_remove(&touch->focus_resource_list);
1387 	wl_list_remove(&touch->focus_view_listener.link);
1388 	wl_list_remove(&touch->focus_resource_listener.link);
1389 	wl_list_remove(&touch->timestamps_list);
1390 	free(touch);
1391 }
1392 
1393 static void
seat_send_updated_caps(struct weston_seat * seat)1394 seat_send_updated_caps(struct weston_seat *seat)
1395 {
1396 	enum wl_seat_capability caps = 0;
1397 	struct wl_resource *resource;
1398 
1399 	if (seat->pointer_device_count > 0)
1400 		caps |= WL_SEAT_CAPABILITY_POINTER;
1401 	if (seat->keyboard_device_count > 0)
1402 		caps |= WL_SEAT_CAPABILITY_KEYBOARD;
1403 	if (seat->touch_device_count > 0)
1404 		caps |= WL_SEAT_CAPABILITY_TOUCH;
1405 
1406 	wl_resource_for_each(resource, &seat->base_resource_list) {
1407 		wl_seat_send_capabilities(resource, caps);
1408 	}
1409 	wl_signal_emit(&seat->updated_caps_signal, seat);
1410 }
1411 
1412 
1413 /** Clear the pointer focus
1414  *
1415  * \param pointer the pointer to clear focus for.
1416  *
1417  * This can be used to unset pointer focus and set the co-ordinates to the
1418  * arbitrary values we use for the no focus case.
1419  *
1420  * There's no requirement to use this function.  For example, passing the
1421  * results of a weston_compositor_pick_view() directly to
1422  * weston_pointer_set_focus() will do the right thing when no view is found.
1423  */
1424 WL_EXPORT void
weston_pointer_clear_focus(struct weston_pointer * pointer)1425 weston_pointer_clear_focus(struct weston_pointer *pointer)
1426 {
1427 	weston_pointer_set_focus(pointer, NULL,
1428 				 wl_fixed_from_int(-1000000),
1429 				 wl_fixed_from_int(-1000000));
1430 }
1431 
1432 WL_EXPORT void
weston_pointer_set_focus(struct weston_pointer * pointer,struct weston_view * view,wl_fixed_t sx,wl_fixed_t sy)1433 weston_pointer_set_focus(struct weston_pointer *pointer,
1434 			 struct weston_view *view,
1435 			 wl_fixed_t sx, wl_fixed_t sy)
1436 {
1437 	struct weston_pointer_client *pointer_client;
1438 	struct weston_keyboard *kbd = weston_seat_get_keyboard(pointer->seat);
1439 	struct wl_resource *resource;
1440 	struct wl_resource *surface_resource;
1441 	struct wl_display *display = pointer->seat->compositor->wl_display;
1442 	uint32_t serial;
1443 	struct wl_list *focus_resource_list;
1444 	int refocus = 0;
1445 
1446 	if ((!pointer->focus && view) ||
1447 	    (pointer->focus && !view) ||
1448 	    (pointer->focus && pointer->focus->surface != view->surface) ||
1449 	    pointer->sx != sx || pointer->sy != sy)
1450 		refocus = 1;
1451 
1452 	if (pointer->focus_client && refocus) {
1453 		focus_resource_list = &pointer->focus_client->pointer_resources;
1454 		if (!wl_list_empty(focus_resource_list)) {
1455 			serial = wl_display_next_serial(display);
1456 			surface_resource = pointer->focus->surface->resource;
1457 			wl_resource_for_each(resource, focus_resource_list) {
1458 				wl_pointer_send_leave(resource, serial,
1459 						      surface_resource);
1460 				pointer_send_frame(resource);
1461 			}
1462 		}
1463 
1464 		pointer->focus_client = NULL;
1465 	}
1466 
1467 	pointer_client = find_pointer_client_for_view(pointer, view);
1468 	if (pointer_client && refocus) {
1469 		struct wl_client *surface_client = pointer_client->client;
1470 
1471 		serial = wl_display_next_serial(display);
1472 
1473 		if (kbd && kbd->focus != view->surface)
1474 			send_modifiers_to_client_in_list(surface_client,
1475 							 &kbd->resource_list,
1476 							 serial,
1477 							 kbd);
1478 
1479 		pointer->focus_client = pointer_client;
1480 
1481 		focus_resource_list = &pointer->focus_client->pointer_resources;
1482 		wl_resource_for_each(resource, focus_resource_list) {
1483 			wl_pointer_send_enter(resource,
1484 					      serial,
1485 					      view->surface->resource,
1486 					      sx, sy);
1487 			pointer_send_frame(resource);
1488 		}
1489 
1490 		pointer->focus_serial = serial;
1491 	}
1492 
1493 	wl_list_remove(&pointer->focus_view_listener.link);
1494 	wl_list_init(&pointer->focus_view_listener.link);
1495 	wl_list_remove(&pointer->focus_resource_listener.link);
1496 	wl_list_init(&pointer->focus_resource_listener.link);
1497 	if (view)
1498 		wl_signal_add(&view->destroy_signal, &pointer->focus_view_listener);
1499 	if (view && view->surface->resource)
1500 		wl_resource_add_destroy_listener(view->surface->resource,
1501 						 &pointer->focus_resource_listener);
1502 
1503 	pointer->focus = view;
1504 	pointer->focus_view_listener.notify = pointer_focus_view_destroyed;
1505 	pointer->sx = sx;
1506 	pointer->sy = sy;
1507 
1508 	assert(view || sx == wl_fixed_from_int(-1000000));
1509 	assert(view || sy == wl_fixed_from_int(-1000000));
1510 
1511 	wl_signal_emit(&pointer->focus_signal, pointer);
1512 }
1513 
1514 static void
send_enter_to_resource_list(struct wl_list * list,struct weston_keyboard * keyboard,struct weston_surface * surface,uint32_t serial)1515 send_enter_to_resource_list(struct wl_list *list,
1516 			    struct weston_keyboard *keyboard,
1517 			    struct weston_surface *surface,
1518 			    uint32_t serial)
1519 {
1520 	struct wl_resource *resource;
1521 
1522 	wl_resource_for_each(resource, list) {
1523 		wl_keyboard_send_enter(resource, serial,
1524 				       surface->resource,
1525 				       &keyboard->keys);
1526 		send_modifiers_to_resource(keyboard, resource, serial);
1527 	}
1528 }
1529 
1530 WL_EXPORT void
weston_keyboard_set_focus(struct weston_keyboard * keyboard,struct weston_surface * surface)1531 weston_keyboard_set_focus(struct weston_keyboard *keyboard,
1532 			  struct weston_surface *surface)
1533 {
1534 	struct weston_seat *seat = keyboard->seat;
1535 	struct wl_resource *resource;
1536 	struct wl_display *display = keyboard->seat->compositor->wl_display;
1537 	uint32_t serial;
1538 	struct wl_list *focus_resource_list;
1539 
1540 	/* Keyboard focus on a surface without a client is equivalent to NULL
1541 	 * focus as nothing would react to the keyboard events anyway.
1542 	 * Just set focus to NULL instead - the destroy listener hangs on the
1543 	 * wl_resource anyway.
1544 	 */
1545 	if (surface && !surface->resource)
1546 		surface = NULL;
1547 
1548 	focus_resource_list = &keyboard->focus_resource_list;
1549 
1550 	if (!wl_list_empty(focus_resource_list) && keyboard->focus != surface) {
1551 		serial = wl_display_next_serial(display);
1552 		wl_resource_for_each(resource, focus_resource_list) {
1553 			wl_keyboard_send_leave(resource, serial,
1554 					keyboard->focus->resource);
1555 		}
1556 		move_resources(&keyboard->resource_list, focus_resource_list);
1557 	}
1558 
1559 	if (find_resource_for_surface(&keyboard->resource_list, surface) &&
1560 	    keyboard->focus != surface) {
1561 		struct wl_client *surface_client =
1562 			wl_resource_get_client(surface->resource);
1563 
1564 		serial = wl_display_next_serial(display);
1565 
1566 		move_resources_for_client(focus_resource_list,
1567 					  &keyboard->resource_list,
1568 					  surface_client);
1569 		send_enter_to_resource_list(focus_resource_list,
1570 					    keyboard,
1571 					    surface,
1572 					    serial);
1573 		keyboard->focus_serial = serial;
1574 	}
1575 
1576 	if (seat->saved_kbd_focus) {
1577 		wl_list_remove(&seat->saved_kbd_focus_listener.link);
1578 		seat->saved_kbd_focus = NULL;
1579 	}
1580 
1581 	wl_list_remove(&keyboard->focus_resource_listener.link);
1582 	wl_list_init(&keyboard->focus_resource_listener.link);
1583 	if (surface)
1584 		wl_resource_add_destroy_listener(surface->resource,
1585 						 &keyboard->focus_resource_listener);
1586 
1587 	keyboard->focus = surface;
1588 	wl_signal_emit(&keyboard->focus_signal, keyboard);
1589 }
1590 
1591 /* Users of this function must manually manage the keyboard focus */
1592 WL_EXPORT void
weston_keyboard_start_grab(struct weston_keyboard * keyboard,struct weston_keyboard_grab * grab)1593 weston_keyboard_start_grab(struct weston_keyboard *keyboard,
1594 			   struct weston_keyboard_grab *grab)
1595 {
1596 	keyboard->grab = grab;
1597 	grab->keyboard = keyboard;
1598 }
1599 
1600 WL_EXPORT void
weston_keyboard_end_grab(struct weston_keyboard * keyboard)1601 weston_keyboard_end_grab(struct weston_keyboard *keyboard)
1602 {
1603 	keyboard->grab = &keyboard->default_grab;
1604 }
1605 
1606 static void
weston_keyboard_cancel_grab(struct weston_keyboard * keyboard)1607 weston_keyboard_cancel_grab(struct weston_keyboard *keyboard)
1608 {
1609 	keyboard->grab->interface->cancel(keyboard->grab);
1610 }
1611 
1612 WL_EXPORT void
weston_pointer_start_grab(struct weston_pointer * pointer,struct weston_pointer_grab * grab)1613 weston_pointer_start_grab(struct weston_pointer *pointer,
1614 			  struct weston_pointer_grab *grab)
1615 {
1616 	pointer->grab = grab;
1617 	grab->pointer = pointer;
1618 	pointer->grab->interface->focus(pointer->grab);
1619 }
1620 
1621 WL_EXPORT void
weston_pointer_end_grab(struct weston_pointer * pointer)1622 weston_pointer_end_grab(struct weston_pointer *pointer)
1623 {
1624 	pointer->grab = &pointer->default_grab;
1625 	pointer->grab->interface->focus(pointer->grab);
1626 }
1627 
1628 static void
weston_pointer_cancel_grab(struct weston_pointer * pointer)1629 weston_pointer_cancel_grab(struct weston_pointer *pointer)
1630 {
1631 	pointer->grab->interface->cancel(pointer->grab);
1632 }
1633 
1634 WL_EXPORT void
weston_touch_start_grab(struct weston_touch * touch,struct weston_touch_grab * grab)1635 weston_touch_start_grab(struct weston_touch *touch, struct weston_touch_grab *grab)
1636 {
1637 	touch->grab = grab;
1638 	grab->touch = touch;
1639 }
1640 
1641 WL_EXPORT void
weston_touch_end_grab(struct weston_touch * touch)1642 weston_touch_end_grab(struct weston_touch *touch)
1643 {
1644 	touch->grab = &touch->default_grab;
1645 }
1646 
1647 static void
weston_touch_cancel_grab(struct weston_touch * touch)1648 weston_touch_cancel_grab(struct weston_touch *touch)
1649 {
1650 	touch->grab->interface->cancel(touch->grab);
1651 }
1652 
1653 static void
weston_pointer_clamp_for_output(struct weston_pointer * pointer,struct weston_output * output,wl_fixed_t * fx,wl_fixed_t * fy)1654 weston_pointer_clamp_for_output(struct weston_pointer *pointer,
1655 				struct weston_output *output,
1656 				wl_fixed_t *fx, wl_fixed_t *fy)
1657 {
1658 	int x, y;
1659 
1660 	x = wl_fixed_to_int(*fx);
1661 	y = wl_fixed_to_int(*fy);
1662 
1663 	if (x < output->x)
1664 		*fx = wl_fixed_from_int(output->x);
1665 	else if (x >= output->x + output->width)
1666 		*fx = wl_fixed_from_int(output->x +
1667 					output->width - 1);
1668 	if (y < output->y)
1669 		*fy = wl_fixed_from_int(output->y);
1670 	else if (y >= output->y + output->height)
1671 		*fy = wl_fixed_from_int(output->y +
1672 					output->height - 1);
1673 }
1674 
1675 WL_EXPORT void
weston_pointer_clamp(struct weston_pointer * pointer,wl_fixed_t * fx,wl_fixed_t * fy)1676 weston_pointer_clamp(struct weston_pointer *pointer, wl_fixed_t *fx, wl_fixed_t *fy)
1677 {
1678 	struct weston_compositor *ec = pointer->seat->compositor;
1679 	struct weston_output *output, *prev = NULL;
1680 	int x, y, old_x, old_y, valid = 0;
1681 
1682 	x = wl_fixed_to_int(*fx);
1683 	y = wl_fixed_to_int(*fy);
1684 	old_x = wl_fixed_to_int(pointer->x);
1685 	old_y = wl_fixed_to_int(pointer->y);
1686 
1687 	wl_list_for_each(output, &ec->output_list, link) {
1688 		if (pointer->seat->output && pointer->seat->output != output)
1689 			continue;
1690 		if (pixman_region32_contains_point(&output->region,
1691 						   x, y, NULL))
1692 			valid = 1;
1693 		if (pixman_region32_contains_point(&output->region,
1694 						   old_x, old_y, NULL))
1695 			prev = output;
1696 	}
1697 
1698 	if (!prev)
1699 		prev = pointer->seat->output;
1700 
1701 	if (prev && !valid)
1702 		weston_pointer_clamp_for_output(pointer, prev, fx, fy);
1703 }
1704 
1705 static void
weston_pointer_move_to(struct weston_pointer * pointer,wl_fixed_t x,wl_fixed_t y)1706 weston_pointer_move_to(struct weston_pointer *pointer,
1707 		       wl_fixed_t x, wl_fixed_t y)
1708 {
1709 	int32_t ix, iy;
1710 
1711 	weston_pointer_clamp (pointer, &x, &y);
1712 
1713 	pointer->x = x;
1714 	pointer->y = y;
1715 
1716 	ix = wl_fixed_to_int(x);
1717 	iy = wl_fixed_to_int(y);
1718 
1719 	if (pointer->sprite) {
1720 		weston_view_set_position(pointer->sprite,
1721 					 ix - pointer->hotspot_x,
1722 					 iy - pointer->hotspot_y);
1723 		weston_view_schedule_repaint(pointer->sprite);
1724 	}
1725 
1726 	pointer->grab->interface->focus(pointer->grab);
1727 	wl_signal_emit(&pointer->motion_signal, pointer);
1728 }
1729 
1730 WL_EXPORT void
weston_pointer_move(struct weston_pointer * pointer,struct weston_pointer_motion_event * event)1731 weston_pointer_move(struct weston_pointer *pointer,
1732 		    struct weston_pointer_motion_event *event)
1733 {
1734 	wl_fixed_t x, y;
1735 
1736 	weston_pointer_motion_to_abs(pointer, event, &x, &y);
1737 	weston_pointer_move_to(pointer, x, y);
1738 }
1739 
1740 /** Verify if the pointer is in a valid position and move it if it isn't.
1741  */
1742 static void
weston_pointer_handle_output_destroy(struct wl_listener * listener,void * data)1743 weston_pointer_handle_output_destroy(struct wl_listener *listener, void *data)
1744 {
1745 	struct weston_pointer *pointer;
1746 	struct weston_compositor *ec;
1747 	struct weston_output *output, *closest = NULL;
1748 	int x, y, distance, min = INT_MAX;
1749 	wl_fixed_t fx, fy;
1750 
1751 	pointer = container_of(listener, struct weston_pointer,
1752 			       output_destroy_listener);
1753 	ec = pointer->seat->compositor;
1754 
1755 	x = wl_fixed_to_int(pointer->x);
1756 	y = wl_fixed_to_int(pointer->y);
1757 
1758 	wl_list_for_each(output, &ec->output_list, link) {
1759 		if (pixman_region32_contains_point(&output->region,
1760 						   x, y, NULL))
1761 			return;
1762 
1763 		/* Aproximante the distance from the pointer to the center of
1764 		 * the output. */
1765 		distance = abs(output->x + output->width / 2 - x) +
1766 			   abs(output->y + output->height / 2 - y);
1767 		if (distance < min) {
1768 			min = distance;
1769 			closest = output;
1770 		}
1771 	}
1772 
1773 	/* Nothing to do if there's no output left. */
1774 	if (!closest)
1775 		return;
1776 
1777 	fx = pointer->x;
1778 	fy = pointer->y;
1779 
1780 	weston_pointer_clamp_for_output(pointer, closest, &fx, &fy);
1781 	weston_pointer_move_to(pointer, fx, fy);
1782 }
1783 
1784 WL_EXPORT void
notify_motion(struct weston_seat * seat,const struct timespec * time,struct weston_pointer_motion_event * event)1785 notify_motion(struct weston_seat *seat,
1786 	      const struct timespec *time,
1787 	      struct weston_pointer_motion_event *event)
1788 {
1789 	struct weston_compositor *ec = seat->compositor;
1790 	struct weston_pointer *pointer = weston_seat_get_pointer(seat);
1791 
1792 	weston_compositor_wake(ec);
1793 	pointer->grab->interface->motion(pointer->grab, time, event);
1794 }
1795 
1796 static void
run_modifier_bindings(struct weston_seat * seat,uint32_t old,uint32_t new)1797 run_modifier_bindings(struct weston_seat *seat, uint32_t old, uint32_t new)
1798 {
1799 	struct weston_compositor *compositor = seat->compositor;
1800 	struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
1801 	uint32_t diff;
1802 	unsigned int i;
1803 	struct {
1804 		uint32_t xkb;
1805 		enum weston_keyboard_modifier weston;
1806 	} mods[] = {
1807 		{ keyboard->xkb_info->ctrl_mod, MODIFIER_CTRL },
1808 		{ keyboard->xkb_info->alt_mod, MODIFIER_ALT },
1809 		{ keyboard->xkb_info->super_mod, MODIFIER_SUPER },
1810 		{ keyboard->xkb_info->shift_mod, MODIFIER_SHIFT },
1811 	};
1812 
1813 	diff = new & ~old;
1814 	for (i = 0; i < ARRAY_LENGTH(mods); i++) {
1815 		if (diff & (1 << mods[i].xkb))
1816 			weston_compositor_run_modifier_binding(compositor,
1817 			                                       keyboard,
1818 			                                       mods[i].weston,
1819 			                                       WL_KEYBOARD_KEY_STATE_PRESSED);
1820 	}
1821 
1822 	diff = old & ~new;
1823 	for (i = 0; i < ARRAY_LENGTH(mods); i++) {
1824 		if (diff & (1 << mods[i].xkb))
1825 			weston_compositor_run_modifier_binding(compositor,
1826 			                                       keyboard,
1827 			                                       mods[i].weston,
1828 			                                       WL_KEYBOARD_KEY_STATE_RELEASED);
1829 	}
1830 }
1831 
1832 WL_EXPORT void
notify_motion_absolute(struct weston_seat * seat,const struct timespec * time,double x,double y)1833 notify_motion_absolute(struct weston_seat *seat, const struct timespec *time,
1834 		       double x, double y)
1835 {
1836 	struct weston_compositor *ec = seat->compositor;
1837 	struct weston_pointer *pointer = weston_seat_get_pointer(seat);
1838 	struct weston_pointer_motion_event event = { 0 };
1839 
1840 	weston_compositor_wake(ec);
1841 
1842 	event = (struct weston_pointer_motion_event) {
1843 		.mask = WESTON_POINTER_MOTION_ABS,
1844 		.x = x,
1845 		.y = y,
1846 	};
1847 
1848 	pointer->grab->interface->motion(pointer->grab, time, &event);
1849 }
1850 
1851 static unsigned int
peek_next_activate_serial(struct weston_compositor * c)1852 peek_next_activate_serial(struct weston_compositor *c)
1853 {
1854 	unsigned serial = c->activate_serial + 1;
1855 
1856 	return serial == 0 ? 1 : serial;
1857 }
1858 
1859 static void
inc_activate_serial(struct weston_compositor * c)1860 inc_activate_serial(struct weston_compositor *c)
1861 {
1862 	c->activate_serial = peek_next_activate_serial (c);
1863 }
1864 
1865 WL_EXPORT void
weston_view_activate(struct weston_view * view,struct weston_seat * seat,uint32_t flags)1866 weston_view_activate(struct weston_view *view,
1867 		     struct weston_seat *seat,
1868 		     uint32_t flags)
1869 {
1870 	struct weston_compositor *compositor = seat->compositor;
1871 
1872 	if (flags & WESTON_ACTIVATE_FLAG_CLICKED) {
1873 		view->click_to_activate_serial =
1874 			peek_next_activate_serial(compositor);
1875 	}
1876 
1877 	weston_seat_set_keyboard_focus(seat, view->surface);
1878 }
1879 
1880 WL_EXPORT void
notify_button(struct weston_seat * seat,const struct timespec * time,int32_t button,enum wl_pointer_button_state state)1881 notify_button(struct weston_seat *seat, const struct timespec *time,
1882 	      int32_t button, enum wl_pointer_button_state state)
1883 {
1884 	struct weston_compositor *compositor = seat->compositor;
1885 	struct weston_pointer *pointer = weston_seat_get_pointer(seat);
1886 
1887 	if (state == WL_POINTER_BUTTON_STATE_PRESSED) {
1888 		weston_compositor_idle_inhibit(compositor);
1889 		if (pointer->button_count == 0) {
1890 			pointer->grab_button = button;
1891 			pointer->grab_time = *time;
1892 			pointer->grab_x = pointer->x;
1893 			pointer->grab_y = pointer->y;
1894 		}
1895 		pointer->button_count++;
1896 	} else {
1897 		weston_compositor_idle_release(compositor);
1898 		pointer->button_count--;
1899 	}
1900 
1901 	weston_compositor_run_button_binding(compositor, pointer, time, button,
1902 					     state);
1903 
1904 	pointer->grab->interface->button(pointer->grab, time, button, state);
1905 
1906 	if (pointer->button_count == 1)
1907 		pointer->grab_serial =
1908 			wl_display_get_serial(compositor->wl_display);
1909 }
1910 
1911 WL_EXPORT void
notify_axis(struct weston_seat * seat,const struct timespec * time,struct weston_pointer_axis_event * event)1912 notify_axis(struct weston_seat *seat, const struct timespec *time,
1913 	    struct weston_pointer_axis_event *event)
1914 {
1915 	struct weston_compositor *compositor = seat->compositor;
1916 	struct weston_pointer *pointer = weston_seat_get_pointer(seat);
1917 
1918 	weston_compositor_wake(compositor);
1919 
1920 	if (weston_compositor_run_axis_binding(compositor, pointer,
1921 					       time, event))
1922 		return;
1923 
1924 	pointer->grab->interface->axis(pointer->grab, time, event);
1925 }
1926 
1927 WL_EXPORT void
notify_axis_source(struct weston_seat * seat,uint32_t source)1928 notify_axis_source(struct weston_seat *seat, uint32_t source)
1929 {
1930 	struct weston_compositor *compositor = seat->compositor;
1931 	struct weston_pointer *pointer = weston_seat_get_pointer(seat);
1932 
1933 	weston_compositor_wake(compositor);
1934 
1935 	pointer->grab->interface->axis_source(pointer->grab, source);
1936 }
1937 
1938 WL_EXPORT void
notify_pointer_frame(struct weston_seat * seat)1939 notify_pointer_frame(struct weston_seat *seat)
1940 {
1941 	struct weston_compositor *compositor = seat->compositor;
1942 	struct weston_pointer *pointer = weston_seat_get_pointer(seat);
1943 
1944 	weston_compositor_wake(compositor);
1945 
1946 	pointer->grab->interface->frame(pointer->grab);
1947 }
1948 
1949 WL_EXPORT int
weston_keyboard_set_locks(struct weston_keyboard * keyboard,uint32_t mask,uint32_t value)1950 weston_keyboard_set_locks(struct weston_keyboard *keyboard,
1951 			  uint32_t mask, uint32_t value)
1952 {
1953 	uint32_t serial;
1954 	xkb_mod_mask_t mods_depressed, mods_latched, mods_locked, group;
1955 	xkb_mod_mask_t num, caps;
1956 
1957 	/* We don't want the leds to go out of sync with the actual state
1958 	 * so if the backend has no way to change the leds don't try to
1959 	 * change the state */
1960 	if (!keyboard->seat->led_update)
1961 		return -1;
1962 
1963 	mods_depressed = xkb_state_serialize_mods(keyboard->xkb_state.state,
1964 						XKB_STATE_DEPRESSED);
1965 	mods_latched = xkb_state_serialize_mods(keyboard->xkb_state.state,
1966 						XKB_STATE_LATCHED);
1967 	mods_locked = xkb_state_serialize_mods(keyboard->xkb_state.state,
1968 						XKB_STATE_LOCKED);
1969 	group = xkb_state_serialize_group(keyboard->xkb_state.state,
1970                                       XKB_STATE_EFFECTIVE);
1971 
1972 	num = (1 << keyboard->xkb_info->mod2_mod);
1973 	caps = (1 << keyboard->xkb_info->caps_mod);
1974 	if (mask & WESTON_NUM_LOCK) {
1975 		if (value & WESTON_NUM_LOCK)
1976 			mods_locked |= num;
1977 		else
1978 			mods_locked &= ~num;
1979 	}
1980 	if (mask & WESTON_CAPS_LOCK) {
1981 		if (value & WESTON_CAPS_LOCK)
1982 			mods_locked |= caps;
1983 		else
1984 			mods_locked &= ~caps;
1985 	}
1986 
1987 	xkb_state_update_mask(keyboard->xkb_state.state, mods_depressed,
1988 			      mods_latched, mods_locked, 0, 0, group);
1989 
1990 	serial = wl_display_next_serial(
1991 				keyboard->seat->compositor->wl_display);
1992 	notify_modifiers(keyboard->seat, serial);
1993 
1994 	return 0;
1995 }
1996 
1997 WL_EXPORT void
notify_modifiers(struct weston_seat * seat,uint32_t serial)1998 notify_modifiers(struct weston_seat *seat, uint32_t serial)
1999 {
2000 	struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
2001 	struct weston_keyboard_grab *grab = keyboard->grab;
2002 	uint32_t mods_depressed, mods_latched, mods_locked, group;
2003 	uint32_t mods_lookup;
2004 	enum weston_led leds = 0;
2005 	int changed = 0;
2006 
2007 	/* Serialize and update our internal state, checking to see if it's
2008 	 * different to the previous state. */
2009 	mods_depressed = xkb_state_serialize_mods(keyboard->xkb_state.state,
2010 						  XKB_STATE_MODS_DEPRESSED);
2011 	mods_latched = xkb_state_serialize_mods(keyboard->xkb_state.state,
2012 						XKB_STATE_MODS_LATCHED);
2013 	mods_locked = xkb_state_serialize_mods(keyboard->xkb_state.state,
2014 					       XKB_STATE_MODS_LOCKED);
2015 	group = xkb_state_serialize_layout(keyboard->xkb_state.state,
2016 					   XKB_STATE_LAYOUT_EFFECTIVE);
2017 
2018 	if (mods_depressed != keyboard->modifiers.mods_depressed ||
2019 	    mods_latched != keyboard->modifiers.mods_latched ||
2020 	    mods_locked != keyboard->modifiers.mods_locked ||
2021 	    group != keyboard->modifiers.group)
2022 		changed = 1;
2023 
2024 	run_modifier_bindings(seat, keyboard->modifiers.mods_depressed,
2025 	                      mods_depressed);
2026 
2027 	keyboard->modifiers.mods_depressed = mods_depressed;
2028 	keyboard->modifiers.mods_latched = mods_latched;
2029 	keyboard->modifiers.mods_locked = mods_locked;
2030 	keyboard->modifiers.group = group;
2031 
2032 	/* And update the modifier_state for bindings. */
2033 	mods_lookup = mods_depressed | mods_latched;
2034 	seat->modifier_state = 0;
2035 	if (mods_lookup & (1 << keyboard->xkb_info->ctrl_mod))
2036 		seat->modifier_state |= MODIFIER_CTRL;
2037 	if (mods_lookup & (1 << keyboard->xkb_info->alt_mod))
2038 		seat->modifier_state |= MODIFIER_ALT;
2039 	if (mods_lookup & (1 << keyboard->xkb_info->super_mod))
2040 		seat->modifier_state |= MODIFIER_SUPER;
2041 	if (mods_lookup & (1 << keyboard->xkb_info->shift_mod))
2042 		seat->modifier_state |= MODIFIER_SHIFT;
2043 
2044 	/* Finally, notify the compositor that LEDs have changed. */
2045 	if (xkb_state_led_index_is_active(keyboard->xkb_state.state,
2046 					  keyboard->xkb_info->num_led))
2047 		leds |= LED_NUM_LOCK;
2048 	if (xkb_state_led_index_is_active(keyboard->xkb_state.state,
2049 					  keyboard->xkb_info->caps_led))
2050 		leds |= LED_CAPS_LOCK;
2051 	if (xkb_state_led_index_is_active(keyboard->xkb_state.state,
2052 					  keyboard->xkb_info->scroll_led))
2053 		leds |= LED_SCROLL_LOCK;
2054 	if (leds != keyboard->xkb_state.leds && seat->led_update)
2055 		seat->led_update(seat, leds);
2056 	keyboard->xkb_state.leds = leds;
2057 
2058 	if (changed) {
2059 		grab->interface->modifiers(grab,
2060 					   serial,
2061 					   keyboard->modifiers.mods_depressed,
2062 					   keyboard->modifiers.mods_latched,
2063 					   keyboard->modifiers.mods_locked,
2064 					   keyboard->modifiers.group);
2065 	}
2066 }
2067 
2068 static void
update_modifier_state(struct weston_seat * seat,uint32_t serial,uint32_t key,enum wl_keyboard_key_state state)2069 update_modifier_state(struct weston_seat *seat, uint32_t serial, uint32_t key,
2070 		      enum wl_keyboard_key_state state)
2071 {
2072 	struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
2073 	enum xkb_key_direction direction;
2074 
2075 	if (state == WL_KEYBOARD_KEY_STATE_PRESSED)
2076 		direction = XKB_KEY_DOWN;
2077 	else
2078 		direction = XKB_KEY_UP;
2079 
2080 	/* Offset the keycode by 8, as the evdev XKB rules reflect X's
2081 	 * broken keycode system, which starts at 8. */
2082 	xkb_state_update_key(keyboard->xkb_state.state, key + 8, direction);
2083 
2084 	notify_modifiers(seat, serial);
2085 }
2086 
2087 WL_EXPORT void
weston_keyboard_send_keymap(struct weston_keyboard * kbd,struct wl_resource * resource)2088 weston_keyboard_send_keymap(struct weston_keyboard *kbd, struct wl_resource *resource)
2089 {
2090 	struct weston_xkb_info *xkb_info = kbd->xkb_info;
2091 	int fd;
2092 	size_t size;
2093 	enum ro_anonymous_file_mapmode mapmode;
2094 
2095 	if (wl_resource_get_version(resource) < 7)
2096 		mapmode = RO_ANONYMOUS_FILE_MAPMODE_SHARED;
2097 	else
2098 		mapmode = RO_ANONYMOUS_FILE_MAPMODE_PRIVATE;
2099 
2100 	fd = os_ro_anonymous_file_get_fd(xkb_info->keymap_rofile, mapmode);
2101 	size = os_ro_anonymous_file_size(xkb_info->keymap_rofile);
2102 
2103 	if (fd == -1) {
2104 		weston_log("creating a keymap file failed: %s\n",
2105 			   strerror(errno));
2106 		return;
2107 	}
2108 
2109 	wl_keyboard_send_keymap(resource,
2110 				WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1,
2111 				fd,
2112 				size);
2113 
2114 	os_ro_anonymous_file_put_fd(fd);
2115 }
2116 
2117 static void
send_modifiers(struct wl_resource * resource,uint32_t serial,struct weston_keyboard * keyboard)2118 send_modifiers(struct wl_resource *resource, uint32_t serial, struct weston_keyboard *keyboard)
2119 {
2120 	wl_keyboard_send_modifiers(resource, serial,
2121 				   keyboard->modifiers.mods_depressed,
2122 				   keyboard->modifiers.mods_latched,
2123 				   keyboard->modifiers.mods_locked,
2124 				   keyboard->modifiers.group);
2125 }
2126 
2127 static struct weston_xkb_info *
2128 weston_xkb_info_create(struct xkb_keymap *keymap);
2129 
2130 static void
update_keymap(struct weston_seat * seat)2131 update_keymap(struct weston_seat *seat)
2132 {
2133 	struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
2134 	struct wl_resource *resource;
2135 	struct weston_xkb_info *xkb_info;
2136 	struct xkb_state *state;
2137 	xkb_mod_mask_t latched_mods;
2138 	xkb_mod_mask_t locked_mods;
2139 
2140 	xkb_info = weston_xkb_info_create(keyboard->pending_keymap);
2141 
2142 	xkb_keymap_unref(keyboard->pending_keymap);
2143 	keyboard->pending_keymap = NULL;
2144 
2145 	if (!xkb_info) {
2146 		weston_log("failed to create XKB info\n");
2147 		return;
2148 	}
2149 
2150 	state = xkb_state_new(xkb_info->keymap);
2151 	if (!state) {
2152 		weston_log("failed to initialise XKB state\n");
2153 		weston_xkb_info_destroy(xkb_info);
2154 		return;
2155 	}
2156 
2157 	latched_mods = xkb_state_serialize_mods(keyboard->xkb_state.state,
2158 						XKB_STATE_MODS_LATCHED);
2159 	locked_mods = xkb_state_serialize_mods(keyboard->xkb_state.state,
2160 					       XKB_STATE_MODS_LOCKED);
2161 	xkb_state_update_mask(state,
2162 			      0, /* depressed */
2163 			      latched_mods,
2164 			      locked_mods,
2165 			      0, 0, 0);
2166 
2167 	weston_xkb_info_destroy(keyboard->xkb_info);
2168 	keyboard->xkb_info = xkb_info;
2169 
2170 	xkb_state_unref(keyboard->xkb_state.state);
2171 	keyboard->xkb_state.state = state;
2172 
2173 	wl_resource_for_each(resource, &keyboard->resource_list)
2174 		weston_keyboard_send_keymap(keyboard, resource);
2175 	wl_resource_for_each(resource, &keyboard->focus_resource_list)
2176 		weston_keyboard_send_keymap(keyboard, resource);
2177 
2178 	notify_modifiers(seat, wl_display_next_serial(seat->compositor->wl_display));
2179 
2180 	if (!latched_mods && !locked_mods)
2181 		return;
2182 
2183 	wl_resource_for_each(resource, &keyboard->resource_list)
2184 		send_modifiers(resource, wl_display_get_serial(seat->compositor->wl_display), keyboard);
2185 	wl_resource_for_each(resource, &keyboard->focus_resource_list)
2186 		send_modifiers(resource, wl_display_get_serial(seat->compositor->wl_display), keyboard);
2187 }
2188 
2189 WL_EXPORT void
notify_key(struct weston_seat * seat,const struct timespec * time,uint32_t key,enum wl_keyboard_key_state state,enum weston_key_state_update update_state)2190 notify_key(struct weston_seat *seat, const struct timespec *time, uint32_t key,
2191 	   enum wl_keyboard_key_state state,
2192 	   enum weston_key_state_update update_state)
2193 {
2194 	struct weston_compositor *compositor = seat->compositor;
2195 	struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
2196 	struct weston_keyboard_grab *grab = keyboard->grab;
2197 	uint32_t *k, *end;
2198 
2199 	if (state == WL_KEYBOARD_KEY_STATE_PRESSED) {
2200 		weston_compositor_idle_inhibit(compositor);
2201 	} else {
2202 		weston_compositor_idle_release(compositor);
2203 	}
2204 
2205 	end = keyboard->keys.data + keyboard->keys.size;
2206 	for (k = keyboard->keys.data; k < end; k++) {
2207 		if (*k == key) {
2208 			/* Ignore server-generated repeats. */
2209 			if (state == WL_KEYBOARD_KEY_STATE_PRESSED)
2210 				return;
2211 			*k = *--end;
2212 		}
2213 	}
2214 	keyboard->keys.size = (void *) end - keyboard->keys.data;
2215 	if (state == WL_KEYBOARD_KEY_STATE_PRESSED) {
2216 		k = wl_array_add(&keyboard->keys, sizeof *k);
2217 		*k = key;
2218 	}
2219 
2220 	if (grab == &keyboard->default_grab ||
2221 	    grab == &keyboard->input_method_grab) {
2222 		weston_compositor_run_key_binding(compositor, keyboard, time,
2223 						  key, state);
2224 		grab = keyboard->grab;
2225 	}
2226 
2227 	grab->interface->key(grab, time, key, state);
2228 
2229 	if (keyboard->pending_keymap &&
2230 	    keyboard->keys.size == 0)
2231 		update_keymap(seat);
2232 
2233 	if (update_state == STATE_UPDATE_AUTOMATIC) {
2234 		update_modifier_state(seat,
2235 				      wl_display_get_serial(compositor->wl_display),
2236 				      key,
2237 				      state);
2238 	}
2239 
2240 	keyboard->grab_serial = wl_display_get_serial(compositor->wl_display);
2241 	if (state == WL_KEYBOARD_KEY_STATE_PRESSED) {
2242 		keyboard->grab_time = *time;
2243 		keyboard->grab_key = key;
2244 	}
2245 }
2246 
2247 WL_EXPORT void
notify_pointer_focus(struct weston_seat * seat,struct weston_output * output,double x,double y)2248 notify_pointer_focus(struct weston_seat *seat, struct weston_output *output,
2249 		     double x, double y)
2250 {
2251 	struct weston_pointer *pointer = weston_seat_get_pointer(seat);
2252 
2253 	if (output) {
2254 		weston_pointer_move_to(pointer,
2255 				       wl_fixed_from_double(x),
2256 				       wl_fixed_from_double(y));
2257 	} else {
2258 		/* FIXME: We should call weston_pointer_set_focus(seat,
2259 		 * NULL) here, but somehow that breaks re-entry... */
2260 	}
2261 }
2262 
2263 static void
destroy_device_saved_kbd_focus(struct wl_listener * listener,void * data)2264 destroy_device_saved_kbd_focus(struct wl_listener *listener, void *data)
2265 {
2266 	struct weston_seat *ws;
2267 
2268 	ws = container_of(listener, struct weston_seat,
2269 			  saved_kbd_focus_listener);
2270 
2271 	ws->saved_kbd_focus = NULL;
2272 }
2273 
2274 WL_EXPORT void
notify_keyboard_focus_in(struct weston_seat * seat,struct wl_array * keys,enum weston_key_state_update update_state)2275 notify_keyboard_focus_in(struct weston_seat *seat, struct wl_array *keys,
2276 			 enum weston_key_state_update update_state)
2277 {
2278 	struct weston_compositor *compositor = seat->compositor;
2279 	struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
2280 	struct weston_surface *surface;
2281 	uint32_t *k, serial;
2282 
2283 	serial = wl_display_next_serial(compositor->wl_display);
2284 	wl_array_copy(&keyboard->keys, keys);
2285 	wl_array_for_each(k, &keyboard->keys) {
2286 		weston_compositor_idle_inhibit(compositor);
2287 		if (update_state == STATE_UPDATE_AUTOMATIC)
2288 			update_modifier_state(seat, serial, *k,
2289 					      WL_KEYBOARD_KEY_STATE_PRESSED);
2290 	}
2291 
2292 	surface = seat->saved_kbd_focus;
2293 	if (surface) {
2294 		weston_keyboard_set_focus(keyboard, surface);
2295 	}
2296 }
2297 
2298 WL_EXPORT void
notify_keyboard_focus_out(struct weston_seat * seat)2299 notify_keyboard_focus_out(struct weston_seat *seat)
2300 {
2301 	struct weston_compositor *compositor = seat->compositor;
2302 	struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
2303 	struct weston_pointer *pointer = weston_seat_get_pointer(seat);
2304 	struct weston_surface *focus = keyboard->focus;
2305 	uint32_t *k, serial;
2306 
2307 	serial = wl_display_next_serial(compositor->wl_display);
2308 	wl_array_for_each(k, &keyboard->keys) {
2309 		weston_compositor_idle_release(compositor);
2310 		update_modifier_state(seat, serial, *k,
2311 				      WL_KEYBOARD_KEY_STATE_RELEASED);
2312 	}
2313 
2314 	seat->modifier_state = 0;
2315 
2316 	weston_keyboard_set_focus(keyboard, NULL);
2317 	weston_keyboard_cancel_grab(keyboard);
2318 	if (pointer)
2319 		weston_pointer_cancel_grab(pointer);
2320 
2321 	if (focus) {
2322 		seat->saved_kbd_focus = focus;
2323 		seat->saved_kbd_focus_listener.notify =
2324 			destroy_device_saved_kbd_focus;
2325 		wl_signal_add(&focus->destroy_signal,
2326 			      &seat->saved_kbd_focus_listener);
2327 	}
2328 }
2329 
2330 WL_EXPORT void
weston_touch_set_focus(struct weston_touch * touch,struct weston_view * view)2331 weston_touch_set_focus(struct weston_touch *touch, struct weston_view *view)
2332 {
2333 	struct wl_list *focus_resource_list;
2334 
2335 	focus_resource_list = &touch->focus_resource_list;
2336 
2337 	if (view && touch->focus &&
2338 	    touch->focus->surface == view->surface) {
2339 		touch->focus = view;
2340 		return;
2341 	}
2342 
2343 	wl_list_remove(&touch->focus_resource_listener.link);
2344 	wl_list_init(&touch->focus_resource_listener.link);
2345 	wl_list_remove(&touch->focus_view_listener.link);
2346 	wl_list_init(&touch->focus_view_listener.link);
2347 
2348 	if (!wl_list_empty(focus_resource_list)) {
2349 		move_resources(&touch->resource_list,
2350 			       focus_resource_list);
2351 	}
2352 
2353 	if (view) {
2354 		struct wl_client *surface_client;
2355 
2356 		if (!view->surface->resource) {
2357 			touch->focus = NULL;
2358 			return;
2359 		}
2360 
2361 		surface_client = wl_resource_get_client(view->surface->resource);
2362 		move_resources_for_client(focus_resource_list,
2363 					  &touch->resource_list,
2364 					  surface_client);
2365 		wl_resource_add_destroy_listener(view->surface->resource,
2366 						 &touch->focus_resource_listener);
2367 		wl_signal_add(&view->destroy_signal, &touch->focus_view_listener);
2368 	}
2369 	touch->focus = view;
2370 }
2371 
2372 static void
process_touch_normal(struct weston_touch_device * device,const struct timespec * time,int touch_id,double double_x,double double_y,int touch_type)2373 process_touch_normal(struct weston_touch_device *device,
2374 		     const struct timespec *time, int touch_id,
2375 		     double double_x, double double_y, int touch_type)
2376 {
2377 	struct weston_touch *touch = device->aggregate;
2378 	struct weston_touch_grab *grab = device->aggregate->grab;
2379 	struct weston_compositor *ec = device->aggregate->seat->compositor;
2380 	struct weston_view *ev;
2381 	wl_fixed_t sx, sy;
2382 	wl_fixed_t x = wl_fixed_from_double(double_x);
2383 	wl_fixed_t y = wl_fixed_from_double(double_y);
2384 
2385 	/* Update grab's global coordinates. */
2386 	if (touch_id == touch->grab_touch_id && touch_type != WL_TOUCH_UP) {
2387 		touch->grab_x = x;
2388 		touch->grab_y = y;
2389 	}
2390 
2391 	switch (touch_type) {
2392 	case WL_TOUCH_DOWN:
2393 		/* the first finger down picks the view, and all further go
2394 		 * to that view for the remainder of the touch session i.e.
2395 		 * until all touch points are up again. */
2396 		if (touch->num_tp == 1) {
2397 			ev = weston_compositor_pick_view(ec, x, y, &sx, &sy);
2398 			weston_touch_set_focus(touch, ev);
2399 		} else if (!touch->focus) {
2400 			/* Unexpected condition: We have non-initial touch but
2401 			 * there is no focused surface.
2402 			 */
2403 			weston_log("touch event received with %d points down "
2404 				   "but no surface focused\n", touch->num_tp);
2405 			return;
2406 		}
2407 
2408 		weston_compositor_run_touch_binding(ec, touch,
2409 						    time, touch_type);
2410 
2411 		grab->interface->down(grab, time, touch_id, x, y);
2412 		if (touch->num_tp == 1) {
2413 			touch->grab_serial =
2414 				wl_display_get_serial(ec->wl_display);
2415 			touch->grab_touch_id = touch_id;
2416 			touch->grab_time = *time;
2417 			touch->grab_x = x;
2418 			touch->grab_y = y;
2419 		}
2420 
2421 		break;
2422 	case WL_TOUCH_MOTION:
2423 		ev = touch->focus;
2424 		if (!ev)
2425 			break;
2426 
2427 		grab->interface->motion(grab, time, touch_id, x, y);
2428 		break;
2429 	case WL_TOUCH_UP:
2430 		grab->interface->up(grab, time, touch_id);
2431 		if (touch->num_tp == 0)
2432 			weston_touch_set_focus(touch, NULL);
2433 		break;
2434 	}
2435 }
2436 
2437 static enum weston_touch_mode
get_next_touch_mode(enum weston_touch_mode from)2438 get_next_touch_mode(enum weston_touch_mode from)
2439 {
2440 	switch (from) {
2441 	case WESTON_TOUCH_MODE_PREP_NORMAL:
2442 		return WESTON_TOUCH_MODE_NORMAL;
2443 
2444 	case WESTON_TOUCH_MODE_PREP_CALIB:
2445 		return WESTON_TOUCH_MODE_CALIB;
2446 
2447 	case WESTON_TOUCH_MODE_NORMAL:
2448 	case WESTON_TOUCH_MODE_CALIB:
2449 		return from;
2450 	}
2451 
2452 	return WESTON_TOUCH_MODE_NORMAL;
2453 }
2454 
2455 /** Global touch mode update
2456  *
2457  * If no seat has a touch down and the compositor is in a PREP touch mode,
2458  * set the compositor to the goal touch mode.
2459  *
2460  * Calls calibrator if touch mode changed.
2461  */
2462 static void
weston_compositor_update_touch_mode(struct weston_compositor * compositor)2463 weston_compositor_update_touch_mode(struct weston_compositor *compositor)
2464 {
2465 	struct weston_seat *seat;
2466 	struct weston_touch *touch;
2467 	enum weston_touch_mode goal;
2468 
2469 	wl_list_for_each(seat, &compositor->seat_list, link) {
2470 		touch = weston_seat_get_touch(seat);
2471 		if (!touch)
2472 			continue;
2473 
2474 		if (touch->num_tp > 0)
2475 			return;
2476 	}
2477 
2478 	goal = get_next_touch_mode(compositor->touch_mode);
2479 	if (compositor->touch_mode != goal) {
2480 		compositor->touch_mode = goal;
2481 		touch_calibrator_mode_changed(compositor);
2482 	}
2483 }
2484 
2485 /** Start transition to normal touch event handling
2486  *
2487  * The touch event mode changes when all touches on all touch devices have
2488  * been lifted. If no touches are currently down, the transition is immediate.
2489  *
2490  * \sa weston_touch_mode
2491  */
2492 void
weston_compositor_set_touch_mode_normal(struct weston_compositor * compositor)2493 weston_compositor_set_touch_mode_normal(struct weston_compositor *compositor)
2494 {
2495 	switch (compositor->touch_mode) {
2496 	case WESTON_TOUCH_MODE_PREP_NORMAL:
2497 	case WESTON_TOUCH_MODE_NORMAL:
2498 		return;
2499 	case WESTON_TOUCH_MODE_PREP_CALIB:
2500 		compositor->touch_mode = WESTON_TOUCH_MODE_NORMAL;
2501 		touch_calibrator_mode_changed(compositor);
2502 		return;
2503 	case WESTON_TOUCH_MODE_CALIB:
2504 		compositor->touch_mode = WESTON_TOUCH_MODE_PREP_NORMAL;
2505 	}
2506 
2507 	weston_compositor_update_touch_mode(compositor);
2508 }
2509 
2510 /** Start transition to calibrator touch event handling
2511  *
2512  * The touch event mode changes when all touches on all touch devices have
2513  * been lifted. If no touches are currently down, the transition is immediate.
2514  *
2515  * \sa weston_touch_mode
2516  */
2517 void
weston_compositor_set_touch_mode_calib(struct weston_compositor * compositor)2518 weston_compositor_set_touch_mode_calib(struct weston_compositor *compositor)
2519 {
2520 	switch (compositor->touch_mode) {
2521 	case WESTON_TOUCH_MODE_PREP_CALIB:
2522 	case WESTON_TOUCH_MODE_CALIB:
2523 		assert(0);
2524 		return;
2525 	case WESTON_TOUCH_MODE_PREP_NORMAL:
2526 		compositor->touch_mode = WESTON_TOUCH_MODE_CALIB;
2527 		touch_calibrator_mode_changed(compositor);
2528 		return;
2529 	case WESTON_TOUCH_MODE_NORMAL:
2530 		compositor->touch_mode = WESTON_TOUCH_MODE_PREP_CALIB;
2531 	}
2532 
2533 	weston_compositor_update_touch_mode(compositor);
2534 }
2535 
2536 /** Feed in touch down, motion, and up events, calibratable device.
2537  *
2538  * It assumes always the correct cycle sequence until it gets here: touch_down
2539  * → touch_update → ... → touch_update → touch_end. The driver is responsible
2540  * for sending along such order.
2541  *
2542  * \param device The physical device that generated the event.
2543  * \param time The event timestamp.
2544  * \param touch_id ID for the touch point of this event (multi-touch).
2545  * \param x X coordinate in compositor global space.
2546  * \param y Y coordinate in compositor global space.
2547  * \param norm Normalized device X, Y coordinates in calibration space, or NULL.
2548  * \param touch_type Either WL_TOUCH_DOWN, WL_TOUCH_UP, or WL_TOUCH_MOTION.
2549  *
2550  * Coordinates double_x and double_y are used for normal operation.
2551  *
2552  * Coordinates norm are only used for touch device calibration. If and only if
2553  * the weston_touch_device does not support calibrating, norm must be NULL.
2554  *
2555  * The calibration space is the normalized coordinate space
2556  * [0.0, 1.0]×[0.0, 1.0] of the weston_touch_device. This is assumed to
2557  * map to the similar normalized coordinate space of the associated
2558  * weston_output.
2559  */
2560 WL_EXPORT void
notify_touch_normalized(struct weston_touch_device * device,const struct timespec * time,int touch_id,double x,double y,const struct weston_point2d_device_normalized * norm,int touch_type)2561 notify_touch_normalized(struct weston_touch_device *device,
2562 			const struct timespec *time,
2563 			int touch_id,
2564 			double x, double y,
2565 			const struct weston_point2d_device_normalized *norm,
2566 			int touch_type)
2567 {
2568 	struct weston_seat *seat = device->aggregate->seat;
2569 	struct weston_touch *touch = device->aggregate;
2570 
2571 	if (touch_type != WL_TOUCH_UP) {
2572 		if (weston_touch_device_can_calibrate(device))
2573 			assert(norm != NULL);
2574 		else
2575 			assert(norm == NULL);
2576 	}
2577 
2578 	/* Update touchpoints count regardless of the current mode. */
2579 	switch (touch_type) {
2580 	case WL_TOUCH_DOWN:
2581 		weston_compositor_idle_inhibit(seat->compositor);
2582 
2583 		touch->num_tp++;
2584 		break;
2585 	case WL_TOUCH_UP:
2586 		if (touch->num_tp == 0) {
2587 			/* This can happen if we start out with one or
2588 			 * more fingers on the touch screen, in which
2589 			 * case we didn't get the corresponding down
2590 			 * event. */
2591 			weston_log("Unmatched touch up event on seat %s, device %s\n",
2592 				   seat->seat_name, device->syspath);
2593 			return;
2594 		}
2595 		weston_compositor_idle_release(seat->compositor);
2596 
2597 		touch->num_tp--;
2598 		break;
2599 	default:
2600 		break;
2601 	}
2602 
2603 	/* Properly forward the touch event */
2604 	switch (weston_touch_device_get_mode(device)) {
2605 	case WESTON_TOUCH_MODE_NORMAL:
2606 	case WESTON_TOUCH_MODE_PREP_CALIB:
2607 		process_touch_normal(device, time, touch_id, x, y, touch_type);
2608 		break;
2609 	case WESTON_TOUCH_MODE_CALIB:
2610 	case WESTON_TOUCH_MODE_PREP_NORMAL:
2611 		notify_touch_calibrator(device, time, touch_id,
2612 					norm, touch_type);
2613 		break;
2614 	}
2615 }
2616 
2617 WL_EXPORT void
notify_touch_frame(struct weston_touch_device * device)2618 notify_touch_frame(struct weston_touch_device *device)
2619 {
2620 	struct weston_touch_grab *grab;
2621 
2622 	switch (weston_touch_device_get_mode(device)) {
2623 	case WESTON_TOUCH_MODE_NORMAL:
2624 	case WESTON_TOUCH_MODE_PREP_CALIB:
2625 		grab = device->aggregate->grab;
2626 		grab->interface->frame(grab);
2627 		break;
2628 	case WESTON_TOUCH_MODE_CALIB:
2629 	case WESTON_TOUCH_MODE_PREP_NORMAL:
2630 		notify_touch_calibrator_frame(device);
2631 		break;
2632 	}
2633 
2634 	weston_compositor_update_touch_mode(device->aggregate->seat->compositor);
2635 }
2636 
2637 WL_EXPORT void
notify_touch_cancel(struct weston_touch_device * device)2638 notify_touch_cancel(struct weston_touch_device *device)
2639 {
2640 	struct weston_touch_grab *grab;
2641 
2642 	switch (weston_touch_device_get_mode(device)) {
2643 	case WESTON_TOUCH_MODE_NORMAL:
2644 	case WESTON_TOUCH_MODE_PREP_CALIB:
2645 		grab = device->aggregate->grab;
2646 		grab->interface->cancel(grab);
2647 		break;
2648 	case WESTON_TOUCH_MODE_CALIB:
2649 	case WESTON_TOUCH_MODE_PREP_NORMAL:
2650 		notify_touch_calibrator_cancel(device);
2651 		break;
2652 	}
2653 
2654 	weston_compositor_update_touch_mode(device->aggregate->seat->compositor);
2655 }
2656 
2657 static int
pointer_cursor_surface_get_label(struct weston_surface * surface,char * buf,size_t len)2658 pointer_cursor_surface_get_label(struct weston_surface *surface,
2659 				 char *buf, size_t len)
2660 {
2661 	return snprintf(buf, len, "cursor");
2662 }
2663 
2664 static void
pointer_cursor_surface_committed(struct weston_surface * es,int32_t dx,int32_t dy)2665 pointer_cursor_surface_committed(struct weston_surface *es,
2666 				 int32_t dx, int32_t dy)
2667 {
2668 	struct weston_pointer *pointer = es->committed_private;
2669 	int x, y;
2670 
2671 	if (es->width == 0)
2672 		return;
2673 
2674 	assert(es == pointer->sprite->surface);
2675 
2676 	pointer->hotspot_x -= dx;
2677 	pointer->hotspot_y -= dy;
2678 
2679 	x = wl_fixed_to_int(pointer->x) - pointer->hotspot_x;
2680 	y = wl_fixed_to_int(pointer->y) - pointer->hotspot_y;
2681 
2682 	weston_view_set_position(pointer->sprite, x, y);
2683 
2684 	empty_region(&es->pending.input);
2685 	empty_region(&es->input);
2686 
2687 	if (!weston_surface_is_mapped(es)) {
2688 		weston_layer_entry_insert(&es->compositor->cursor_layer.view_list,
2689 					  &pointer->sprite->layer_link);
2690 		weston_view_update_transform(pointer->sprite);
2691 		es->is_mapped = true;
2692 		pointer->sprite->is_mapped = true;
2693 	}
2694 }
2695 
2696 static void
pointer_set_cursor(struct wl_client * client,struct wl_resource * resource,uint32_t serial,struct wl_resource * surface_resource,int32_t x,int32_t y)2697 pointer_set_cursor(struct wl_client *client, struct wl_resource *resource,
2698 		   uint32_t serial, struct wl_resource *surface_resource,
2699 		   int32_t x, int32_t y)
2700 {
2701 	struct weston_pointer *pointer = wl_resource_get_user_data(resource);
2702 	struct weston_surface *surface = NULL;
2703 
2704 	if (!pointer)
2705 		return;
2706 
2707 	if (surface_resource)
2708 		surface = wl_resource_get_user_data(surface_resource);
2709 
2710 	if (pointer->focus == NULL)
2711 		return;
2712 	/* pointer->focus->surface->resource can be NULL. Surfaces like the
2713 	black_surface used in shell.c for fullscreen don't have
2714 	a resource, but can still have focus */
2715 	if (pointer->focus->surface->resource == NULL)
2716 		return;
2717 	if (wl_resource_get_client(pointer->focus->surface->resource) != client)
2718 		return;
2719 	if (pointer->focus_serial - serial > UINT32_MAX / 2)
2720 		return;
2721 
2722 	if (!surface) {
2723 		if (pointer->sprite)
2724 			pointer_unmap_sprite(pointer);
2725 		return;
2726 	}
2727 
2728 	if (pointer->sprite && pointer->sprite->surface == surface &&
2729 	    pointer->hotspot_x == x && pointer->hotspot_y == y)
2730 		return;
2731 
2732 	if (!pointer->sprite || pointer->sprite->surface != surface) {
2733 		if (weston_surface_set_role(surface, "wl_pointer-cursor",
2734 					    resource,
2735 					    WL_POINTER_ERROR_ROLE) < 0)
2736 			return;
2737 
2738 		if (pointer->sprite)
2739 			pointer_unmap_sprite(pointer);
2740 
2741 		wl_signal_add(&surface->destroy_signal,
2742 			      &pointer->sprite_destroy_listener);
2743 
2744 		surface->committed = pointer_cursor_surface_committed;
2745 		surface->committed_private = pointer;
2746 		weston_surface_set_label_func(surface,
2747 					    pointer_cursor_surface_get_label);
2748 		pointer->sprite = weston_view_create(surface);
2749 	}
2750 
2751 	pointer->hotspot_x = x;
2752 	pointer->hotspot_y = y;
2753 
2754 	if (surface->buffer_ref.buffer) {
2755 		pointer_cursor_surface_committed(surface, 0, 0);
2756 		weston_view_schedule_repaint(pointer->sprite);
2757 	}
2758 }
2759 
2760 static void
pointer_release(struct wl_client * client,struct wl_resource * resource)2761 pointer_release(struct wl_client *client, struct wl_resource *resource)
2762 {
2763 	wl_resource_destroy(resource);
2764 }
2765 
2766 static const struct wl_pointer_interface pointer_interface = {
2767 	pointer_set_cursor,
2768 	pointer_release
2769 };
2770 
2771 static void
seat_get_pointer(struct wl_client * client,struct wl_resource * resource,uint32_t id)2772 seat_get_pointer(struct wl_client *client, struct wl_resource *resource,
2773 		 uint32_t id)
2774 {
2775 	struct weston_seat *seat = wl_resource_get_user_data(resource);
2776 	/* We use the pointer_state directly, which means we'll
2777 	 * give a wl_pointer if the seat has ever had one - even though
2778 	 * the spec explicitly states that this request only takes effect
2779 	 * if the seat has the pointer capability.
2780 	 *
2781 	 * This prevents a race between the compositor sending new
2782 	 * capabilities and the client trying to use the old ones.
2783 	 */
2784 	struct weston_pointer *pointer = seat ? seat->pointer_state : NULL;
2785 	struct wl_resource *cr;
2786 	struct weston_pointer_client *pointer_client;
2787 
2788         cr = wl_resource_create(client, &wl_pointer_interface,
2789 				wl_resource_get_version(resource), id);
2790 	if (cr == NULL) {
2791 		wl_client_post_no_memory(client);
2792 		return;
2793 	}
2794 
2795 	wl_list_init(wl_resource_get_link(cr));
2796 	wl_resource_set_implementation(cr, &pointer_interface, pointer,
2797 				       unbind_pointer_client_resource);
2798 
2799 	/* If we don't have a pointer_state, the resource is inert, so there
2800 	 * is nothing more to set up */
2801 	if (!pointer)
2802 		return;
2803 
2804 	pointer_client = weston_pointer_ensure_pointer_client(pointer, client);
2805 	if (!pointer_client) {
2806 		wl_client_post_no_memory(client);
2807 		return;
2808 	}
2809 
2810 	wl_list_insert(&pointer_client->pointer_resources,
2811 		       wl_resource_get_link(cr));
2812 
2813 	if (pointer->focus && pointer->focus->surface->resource &&
2814 	    wl_resource_get_client(pointer->focus->surface->resource) == client) {
2815 		wl_fixed_t sx, sy;
2816 
2817 		weston_view_from_global_fixed(pointer->focus,
2818 					      pointer->x,
2819 					      pointer->y,
2820 					      &sx, &sy);
2821 
2822 		wl_pointer_send_enter(cr,
2823 				      pointer->focus_serial,
2824 				      pointer->focus->surface->resource,
2825 				      sx, sy);
2826 		pointer_send_frame(cr);
2827 	}
2828 }
2829 
2830 static void
destroy_keyboard_resource(struct wl_resource * resource)2831 destroy_keyboard_resource(struct wl_resource *resource)
2832 {
2833 	struct weston_keyboard *keyboard = wl_resource_get_user_data(resource);
2834 
2835 	wl_list_remove(wl_resource_get_link(resource));
2836 
2837 	if (keyboard) {
2838 		remove_input_resource_from_timestamps(resource,
2839 						      &keyboard->timestamps_list);
2840 	}
2841 }
2842 
2843 static void
keyboard_release(struct wl_client * client,struct wl_resource * resource)2844 keyboard_release(struct wl_client *client, struct wl_resource *resource)
2845 {
2846 	wl_resource_destroy(resource);
2847 }
2848 
2849 static const struct wl_keyboard_interface keyboard_interface = {
2850 	keyboard_release
2851 };
2852 
2853 static void
seat_get_keyboard(struct wl_client * client,struct wl_resource * resource,uint32_t id)2854 seat_get_keyboard(struct wl_client *client, struct wl_resource *resource,
2855 		  uint32_t id)
2856 {
2857 	struct weston_seat *seat = wl_resource_get_user_data(resource);
2858 	/* We use the keyboard_state directly, which means we'll
2859 	 * give a wl_keyboard if the seat has ever had one - even though
2860 	 * the spec explicitly states that this request only takes effect
2861 	 * if the seat has the keyboard capability.
2862 	 *
2863 	 * This prevents a race between the compositor sending new
2864 	 * capabilities and the client trying to use the old ones.
2865 	 */
2866 	struct weston_keyboard *keyboard = seat ? seat->keyboard_state : NULL;
2867 	struct wl_resource *cr;
2868 
2869         cr = wl_resource_create(client, &wl_keyboard_interface,
2870 				wl_resource_get_version(resource), id);
2871 	if (cr == NULL) {
2872 		wl_client_post_no_memory(client);
2873 		return;
2874 	}
2875 
2876 	wl_list_init(wl_resource_get_link(cr));
2877 	wl_resource_set_implementation(cr, &keyboard_interface,
2878 				       keyboard, destroy_keyboard_resource);
2879 
2880 	/* If we don't have a keyboard_state, the resource is inert, so there
2881 	 * is nothing more to set up */
2882 	if (!keyboard)
2883 		return;
2884 
2885 	/* May be moved to focused list later by either
2886 	 * weston_keyboard_set_focus or directly if this client is already
2887 	 * focused */
2888 	wl_list_insert(&keyboard->resource_list, wl_resource_get_link(cr));
2889 
2890 	if (wl_resource_get_version(cr) >= WL_KEYBOARD_REPEAT_INFO_SINCE_VERSION) {
2891 		wl_keyboard_send_repeat_info(cr,
2892 					     seat->compositor->kb_repeat_rate,
2893 					     seat->compositor->kb_repeat_delay);
2894 	}
2895 
2896 	weston_keyboard_send_keymap(keyboard, cr);
2897 
2898 	if (keyboard->focus && keyboard->focus->resource &&
2899 	    wl_resource_get_client(keyboard->focus->resource) == client) {
2900 		struct weston_surface *surface =
2901 			(struct weston_surface *)keyboard->focus;
2902 
2903 		wl_list_remove(wl_resource_get_link(cr));
2904 		wl_list_insert(&keyboard->focus_resource_list,
2905 			       wl_resource_get_link(cr));
2906 		wl_keyboard_send_enter(cr,
2907 				       keyboard->focus_serial,
2908 				       surface->resource,
2909 				       &keyboard->keys);
2910 
2911 		send_modifiers_to_resource(keyboard,
2912 					   cr,
2913 					   keyboard->focus_serial);
2914 
2915 		/* If this is the first keyboard resource for this
2916 		 * client... */
2917 		if (keyboard->focus_resource_list.prev ==
2918 		    wl_resource_get_link(cr))
2919 			wl_data_device_set_keyboard_focus(seat);
2920 	}
2921 }
2922 
2923 static void
destroy_touch_resource(struct wl_resource * resource)2924 destroy_touch_resource(struct wl_resource *resource)
2925 {
2926 	struct weston_touch *touch = wl_resource_get_user_data(resource);
2927 
2928 	wl_list_remove(wl_resource_get_link(resource));
2929 
2930 	if (touch) {
2931 		remove_input_resource_from_timestamps(resource,
2932 						      &touch->timestamps_list);
2933 	}
2934 }
2935 
2936 static void
touch_release(struct wl_client * client,struct wl_resource * resource)2937 touch_release(struct wl_client *client, struct wl_resource *resource)
2938 {
2939 	wl_resource_destroy(resource);
2940 }
2941 
2942 static const struct wl_touch_interface touch_interface = {
2943 	touch_release
2944 };
2945 
2946 static void
seat_get_touch(struct wl_client * client,struct wl_resource * resource,uint32_t id)2947 seat_get_touch(struct wl_client *client, struct wl_resource *resource,
2948 	       uint32_t id)
2949 {
2950 	struct weston_seat *seat = wl_resource_get_user_data(resource);
2951 	/* We use the touch_state directly, which means we'll
2952 	 * give a wl_touch if the seat has ever had one - even though
2953 	 * the spec explicitly states that this request only takes effect
2954 	 * if the seat has the touch capability.
2955 	 *
2956 	 * This prevents a race between the compositor sending new
2957 	 * capabilities and the client trying to use the old ones.
2958 	 */
2959 	struct weston_touch *touch = seat ? seat->touch_state : NULL;
2960 	struct wl_resource *cr;
2961 
2962         cr = wl_resource_create(client, &wl_touch_interface,
2963 				wl_resource_get_version(resource), id);
2964 	if (cr == NULL) {
2965 		wl_client_post_no_memory(client);
2966 		return;
2967 	}
2968 
2969 	wl_list_init(wl_resource_get_link(cr));
2970 	wl_resource_set_implementation(cr, &touch_interface,
2971 				       touch, destroy_touch_resource);
2972 
2973 	/* If we don't have a touch_state, the resource is inert, so there
2974 	 * is nothing more to set up */
2975 	if (!touch)
2976 		return;
2977 
2978 	if (touch->focus &&
2979 	    wl_resource_get_client(touch->focus->surface->resource) == client) {
2980 		wl_list_insert(&touch->focus_resource_list,
2981 			       wl_resource_get_link(cr));
2982 	} else {
2983 		wl_list_insert(&touch->resource_list,
2984 			       wl_resource_get_link(cr));
2985 	}
2986 }
2987 
2988 static void
seat_release(struct wl_client * client,struct wl_resource * resource)2989 seat_release(struct wl_client *client, struct wl_resource *resource)
2990 {
2991 	wl_resource_destroy(resource);
2992 }
2993 
2994 static const struct wl_seat_interface seat_interface = {
2995 	seat_get_pointer,
2996 	seat_get_keyboard,
2997 	seat_get_touch,
2998 	seat_release,
2999 };
3000 
3001 static void
bind_seat(struct wl_client * client,void * data,uint32_t version,uint32_t id)3002 bind_seat(struct wl_client *client, void *data, uint32_t version, uint32_t id)
3003 {
3004 	struct weston_seat *seat = data;
3005 	struct wl_resource *resource;
3006 	enum wl_seat_capability caps = 0;
3007 
3008 	resource = wl_resource_create(client,
3009 				      &wl_seat_interface, version, id);
3010 	wl_list_insert(&seat->base_resource_list, wl_resource_get_link(resource));
3011 	wl_resource_set_implementation(resource, &seat_interface, data,
3012 				       unbind_resource);
3013 
3014 	if (weston_seat_get_pointer(seat))
3015 		caps |= WL_SEAT_CAPABILITY_POINTER;
3016 	if (weston_seat_get_keyboard(seat))
3017 		caps |= WL_SEAT_CAPABILITY_KEYBOARD;
3018 	if (weston_seat_get_touch(seat))
3019 		caps |= WL_SEAT_CAPABILITY_TOUCH;
3020 
3021 	wl_seat_send_capabilities(resource, caps);
3022 	if (version >= WL_SEAT_NAME_SINCE_VERSION)
3023 		wl_seat_send_name(resource, seat->seat_name);
3024 }
3025 
3026 static void
relative_pointer_destroy(struct wl_client * client,struct wl_resource * resource)3027 relative_pointer_destroy(struct wl_client *client,
3028 			 struct wl_resource *resource)
3029 {
3030 	wl_resource_destroy(resource);
3031 }
3032 
3033 static const struct zwp_relative_pointer_v1_interface relative_pointer_interface = {
3034 	relative_pointer_destroy
3035 };
3036 
3037 static void
relative_pointer_manager_destroy(struct wl_client * client,struct wl_resource * resource)3038 relative_pointer_manager_destroy(struct wl_client *client,
3039 				 struct wl_resource *resource)
3040 {
3041 	wl_resource_destroy(resource);
3042 }
3043 
3044 static void
relative_pointer_manager_get_relative_pointer(struct wl_client * client,struct wl_resource * resource,uint32_t id,struct wl_resource * pointer_resource)3045 relative_pointer_manager_get_relative_pointer(struct wl_client *client,
3046 					      struct wl_resource *resource,
3047 					      uint32_t id,
3048 					      struct wl_resource *pointer_resource)
3049 {
3050 	struct weston_pointer *pointer =
3051 		wl_resource_get_user_data(pointer_resource);
3052 	struct weston_pointer_client *pointer_client;
3053 	struct wl_resource *cr;
3054 
3055 	cr = wl_resource_create(client, &zwp_relative_pointer_v1_interface,
3056 				wl_resource_get_version(resource), id);
3057 	if (cr == NULL) {
3058 		wl_client_post_no_memory(client);
3059 		return;
3060 	}
3061 
3062 	pointer_client = weston_pointer_ensure_pointer_client(pointer, client);
3063 	if (!pointer_client) {
3064 		wl_client_post_no_memory(client);
3065 		return;
3066 	}
3067 
3068 	wl_list_insert(&pointer_client->relative_pointer_resources,
3069 		       wl_resource_get_link(cr));
3070 	wl_resource_set_implementation(cr, &relative_pointer_interface,
3071 				       pointer,
3072 				       unbind_pointer_client_resource);
3073 }
3074 
3075 static const struct zwp_relative_pointer_manager_v1_interface relative_pointer_manager = {
3076 	relative_pointer_manager_destroy,
3077 	relative_pointer_manager_get_relative_pointer,
3078 };
3079 
3080 static void
bind_relative_pointer_manager(struct wl_client * client,void * data,uint32_t version,uint32_t id)3081 bind_relative_pointer_manager(struct wl_client *client, void *data,
3082 			      uint32_t version, uint32_t id)
3083 {
3084 	struct weston_compositor *compositor = data;
3085 	struct wl_resource *resource;
3086 
3087 	resource = wl_resource_create(client,
3088 				      &zwp_relative_pointer_manager_v1_interface,
3089 				      1, id);
3090 
3091 	wl_resource_set_implementation(resource, &relative_pointer_manager,
3092 				       compositor,
3093 				       NULL);
3094 }
3095 
3096 WL_EXPORT int
weston_compositor_set_xkb_rule_names(struct weston_compositor * ec,struct xkb_rule_names * names)3097 weston_compositor_set_xkb_rule_names(struct weston_compositor *ec,
3098 				     struct xkb_rule_names *names)
3099 {
3100 	if (ec->xkb_context == NULL) {
3101 		ec->xkb_context = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
3102 		if (ec->xkb_context == NULL) {
3103 			weston_log("failed to create XKB context\n");
3104 			return -1;
3105 		}
3106 	}
3107 
3108 	if (names)
3109 		ec->xkb_names = *names;
3110 	if (!ec->xkb_names.rules)
3111 		ec->xkb_names.rules = strdup("evdev");
3112 	if (!ec->xkb_names.model)
3113 		ec->xkb_names.model = strdup("pc105");
3114 	if (!ec->xkb_names.layout)
3115 		ec->xkb_names.layout = strdup("us");
3116 
3117 	return 0;
3118 }
3119 
3120 static void
weston_xkb_info_destroy(struct weston_xkb_info * xkb_info)3121 weston_xkb_info_destroy(struct weston_xkb_info *xkb_info)
3122 {
3123 	if (--xkb_info->ref_count > 0)
3124 		return;
3125 
3126 	xkb_keymap_unref(xkb_info->keymap);
3127 
3128 	os_ro_anonymous_file_destroy(xkb_info->keymap_rofile);
3129 	free(xkb_info);
3130 }
3131 
3132 void
weston_compositor_xkb_destroy(struct weston_compositor * ec)3133 weston_compositor_xkb_destroy(struct weston_compositor *ec)
3134 {
3135 	free((char *) ec->xkb_names.rules);
3136 	free((char *) ec->xkb_names.model);
3137 	free((char *) ec->xkb_names.layout);
3138 	free((char *) ec->xkb_names.variant);
3139 	free((char *) ec->xkb_names.options);
3140 
3141 	if (ec->xkb_info)
3142 		weston_xkb_info_destroy(ec->xkb_info);
3143 	xkb_context_unref(ec->xkb_context);
3144 }
3145 
3146 static struct weston_xkb_info *
weston_xkb_info_create(struct xkb_keymap * keymap)3147 weston_xkb_info_create(struct xkb_keymap *keymap)
3148 {
3149 	char *keymap_string;
3150 	size_t keymap_size;
3151 	struct weston_xkb_info *xkb_info = zalloc(sizeof *xkb_info);
3152 	if (xkb_info == NULL)
3153 		return NULL;
3154 
3155 	xkb_info->keymap = xkb_keymap_ref(keymap);
3156 	xkb_info->ref_count = 1;
3157 
3158 	xkb_info->shift_mod = xkb_keymap_mod_get_index(xkb_info->keymap,
3159 						       XKB_MOD_NAME_SHIFT);
3160 	xkb_info->caps_mod = xkb_keymap_mod_get_index(xkb_info->keymap,
3161 						      XKB_MOD_NAME_CAPS);
3162 	xkb_info->ctrl_mod = xkb_keymap_mod_get_index(xkb_info->keymap,
3163 						      XKB_MOD_NAME_CTRL);
3164 	xkb_info->alt_mod = xkb_keymap_mod_get_index(xkb_info->keymap,
3165 						     XKB_MOD_NAME_ALT);
3166 	xkb_info->mod2_mod = xkb_keymap_mod_get_index(xkb_info->keymap,
3167 						      "Mod2");
3168 	xkb_info->mod3_mod = xkb_keymap_mod_get_index(xkb_info->keymap,
3169 						      "Mod3");
3170 	xkb_info->super_mod = xkb_keymap_mod_get_index(xkb_info->keymap,
3171 						       XKB_MOD_NAME_LOGO);
3172 	xkb_info->mod5_mod = xkb_keymap_mod_get_index(xkb_info->keymap,
3173 						      "Mod5");
3174 
3175 	xkb_info->num_led = xkb_keymap_led_get_index(xkb_info->keymap,
3176 						     XKB_LED_NAME_NUM);
3177 	xkb_info->caps_led = xkb_keymap_led_get_index(xkb_info->keymap,
3178 						      XKB_LED_NAME_CAPS);
3179 	xkb_info->scroll_led = xkb_keymap_led_get_index(xkb_info->keymap,
3180 							XKB_LED_NAME_SCROLL);
3181 
3182 	keymap_string = xkb_keymap_get_as_string(xkb_info->keymap,
3183 							   XKB_KEYMAP_FORMAT_TEXT_V1);
3184 	if (keymap_string == NULL) {
3185 		weston_log("failed to get string version of keymap\n");
3186 		goto err_keymap;
3187 	}
3188 	keymap_size = strlen(keymap_string) + 1;
3189 
3190 	xkb_info->keymap_rofile = os_ro_anonymous_file_create(keymap_size,
3191 							      keymap_string);
3192 	free(keymap_string);
3193 
3194 	if (!xkb_info->keymap_rofile) {
3195 		weston_log("failed to create anonymous file for keymap\n");
3196 		goto err_keymap;
3197 	}
3198 
3199 	return xkb_info;
3200 
3201 err_keymap:
3202 	xkb_keymap_unref(xkb_info->keymap);
3203 	free(xkb_info);
3204 	return NULL;
3205 }
3206 
3207 static int
weston_compositor_build_global_keymap(struct weston_compositor * ec)3208 weston_compositor_build_global_keymap(struct weston_compositor *ec)
3209 {
3210 	struct xkb_keymap *keymap;
3211 
3212 	if (ec->xkb_info != NULL)
3213 		return 0;
3214 
3215 	keymap = xkb_keymap_new_from_names(ec->xkb_context,
3216 					   &ec->xkb_names,
3217 					   0);
3218 	if (keymap == NULL) {
3219 		weston_log("failed to compile global XKB keymap\n");
3220 		weston_log("  tried rules %s, model %s, layout %s, variant %s, "
3221 			"options %s\n",
3222 			ec->xkb_names.rules, ec->xkb_names.model,
3223 			ec->xkb_names.layout, ec->xkb_names.variant,
3224 			ec->xkb_names.options);
3225 		return -1;
3226 	}
3227 
3228 	ec->xkb_info = weston_xkb_info_create(keymap);
3229 	xkb_keymap_unref(keymap);
3230 	if (ec->xkb_info == NULL)
3231 		return -1;
3232 
3233 	return 0;
3234 }
3235 
3236 WL_EXPORT void
weston_seat_update_keymap(struct weston_seat * seat,struct xkb_keymap * keymap)3237 weston_seat_update_keymap(struct weston_seat *seat, struct xkb_keymap *keymap)
3238 {
3239 	struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
3240 
3241 	if (!keyboard || !keymap)
3242 		return;
3243 
3244 	xkb_keymap_unref(keyboard->pending_keymap);
3245 	keyboard->pending_keymap = xkb_keymap_ref(keymap);
3246 
3247 	if (keyboard->keys.size == 0)
3248 		update_keymap(seat);
3249 }
3250 
3251 WL_EXPORT int
weston_seat_init_keyboard(struct weston_seat * seat,struct xkb_keymap * keymap)3252 weston_seat_init_keyboard(struct weston_seat *seat, struct xkb_keymap *keymap)
3253 {
3254 	struct weston_keyboard *keyboard;
3255 
3256 	if (seat->keyboard_state) {
3257 		seat->keyboard_device_count += 1;
3258 		if (seat->keyboard_device_count == 1)
3259 			seat_send_updated_caps(seat);
3260 		return 0;
3261 	}
3262 
3263 	keyboard = weston_keyboard_create();
3264 	if (keyboard == NULL) {
3265 		weston_log("failed to allocate weston keyboard struct\n");
3266 		return -1;
3267 	}
3268 
3269 	if (keymap != NULL) {
3270 		keyboard->xkb_info = weston_xkb_info_create(keymap);
3271 		if (keyboard->xkb_info == NULL)
3272 			goto err;
3273 	} else {
3274 		if (weston_compositor_build_global_keymap(seat->compositor) < 0)
3275 			goto err;
3276 		keyboard->xkb_info = seat->compositor->xkb_info;
3277 		keyboard->xkb_info->ref_count++;
3278 	}
3279 
3280 	keyboard->xkb_state.state = xkb_state_new(keyboard->xkb_info->keymap);
3281 	if (keyboard->xkb_state.state == NULL) {
3282 		weston_log("failed to initialise XKB state\n");
3283 		goto err;
3284 	}
3285 
3286 	keyboard->xkb_state.leds = 0;
3287 
3288 	seat->keyboard_state = keyboard;
3289 	seat->keyboard_device_count = 1;
3290 	keyboard->seat = seat;
3291 
3292 	seat_send_updated_caps(seat);
3293 
3294 	return 0;
3295 
3296 err:
3297 	if (keyboard->xkb_info)
3298 		weston_xkb_info_destroy(keyboard->xkb_info);
3299 	free(keyboard);
3300 
3301 	return -1;
3302 }
3303 
3304 static void
weston_keyboard_reset_state(struct weston_keyboard * keyboard)3305 weston_keyboard_reset_state(struct weston_keyboard *keyboard)
3306 {
3307 	struct weston_seat *seat = keyboard->seat;
3308 	struct xkb_state *state;
3309 
3310 	state = xkb_state_new(keyboard->xkb_info->keymap);
3311 	if (!state) {
3312 		weston_log("failed to reset XKB state\n");
3313 		return;
3314 	}
3315 	xkb_state_unref(keyboard->xkb_state.state);
3316 	keyboard->xkb_state.state = state;
3317 
3318 	keyboard->xkb_state.leds = 0;
3319 
3320 	seat->modifier_state = 0;
3321 }
3322 
3323 WL_EXPORT void
weston_seat_release_keyboard(struct weston_seat * seat)3324 weston_seat_release_keyboard(struct weston_seat *seat)
3325 {
3326 	seat->keyboard_device_count--;
3327 	assert(seat->keyboard_device_count >= 0);
3328 	if (seat->keyboard_device_count == 0) {
3329 		weston_keyboard_set_focus(seat->keyboard_state, NULL);
3330 		weston_keyboard_cancel_grab(seat->keyboard_state);
3331 		weston_keyboard_reset_state(seat->keyboard_state);
3332 		seat_send_updated_caps(seat);
3333 	}
3334 }
3335 
3336 WL_EXPORT void
weston_seat_init_pointer(struct weston_seat * seat)3337 weston_seat_init_pointer(struct weston_seat *seat)
3338 {
3339 	struct weston_pointer *pointer;
3340 
3341 	if (seat->pointer_state) {
3342 		seat->pointer_device_count += 1;
3343 		if (seat->pointer_device_count == 1)
3344 			seat_send_updated_caps(seat);
3345 		return;
3346 	}
3347 
3348 	pointer = weston_pointer_create(seat);
3349 	if (pointer == NULL)
3350 		return;
3351 
3352 	seat->pointer_state = pointer;
3353 	seat->pointer_device_count = 1;
3354 	pointer->seat = seat;
3355 
3356 	seat_send_updated_caps(seat);
3357 }
3358 
3359 WL_EXPORT void
weston_seat_release_pointer(struct weston_seat * seat)3360 weston_seat_release_pointer(struct weston_seat *seat)
3361 {
3362 	struct weston_pointer *pointer = seat->pointer_state;
3363 
3364 	seat->pointer_device_count--;
3365 	if (seat->pointer_device_count == 0) {
3366 		weston_pointer_clear_focus(pointer);
3367 		weston_pointer_cancel_grab(pointer);
3368 
3369 		if (pointer->sprite)
3370 			pointer_unmap_sprite(pointer);
3371 
3372 		weston_pointer_reset_state(pointer);
3373 		seat_send_updated_caps(seat);
3374 
3375 		/* seat->pointer is intentionally not destroyed so that
3376 		 * a newly attached pointer on this seat will retain
3377 		 * the previous cursor co-ordinates.
3378 		 */
3379 	}
3380 }
3381 
3382 WL_EXPORT void
weston_seat_init_touch(struct weston_seat * seat)3383 weston_seat_init_touch(struct weston_seat *seat)
3384 {
3385 	struct weston_touch *touch;
3386 
3387 	if (seat->touch_state) {
3388 		seat->touch_device_count += 1;
3389 		if (seat->touch_device_count == 1)
3390 			seat_send_updated_caps(seat);
3391 		return;
3392 	}
3393 
3394 	touch = weston_touch_create();
3395 	if (touch == NULL)
3396 		return;
3397 
3398 	seat->touch_state = touch;
3399 	seat->touch_device_count = 1;
3400 	touch->seat = seat;
3401 
3402 	seat_send_updated_caps(seat);
3403 }
3404 
3405 WL_EXPORT void
weston_seat_release_touch(struct weston_seat * seat)3406 weston_seat_release_touch(struct weston_seat *seat)
3407 {
3408 	seat->touch_device_count--;
3409 	if (seat->touch_device_count == 0) {
3410 		weston_touch_set_focus(seat->touch_state, NULL);
3411 		weston_touch_cancel_grab(seat->touch_state);
3412 		weston_touch_reset_state(seat->touch_state);
3413 		seat_send_updated_caps(seat);
3414 	}
3415 }
3416 
3417 WL_EXPORT void
weston_seat_init(struct weston_seat * seat,struct weston_compositor * ec,const char * seat_name)3418 weston_seat_init(struct weston_seat *seat, struct weston_compositor *ec,
3419 		 const char *seat_name)
3420 {
3421 	memset(seat, 0, sizeof *seat);
3422 
3423 	seat->selection_data_source = NULL;
3424 	wl_list_init(&seat->base_resource_list);
3425 	wl_signal_init(&seat->selection_signal);
3426 	wl_list_init(&seat->drag_resource_list);
3427 	wl_signal_init(&seat->destroy_signal);
3428 	wl_signal_init(&seat->updated_caps_signal);
3429 
3430 	seat->global = wl_global_create(ec->wl_display, &wl_seat_interface,
3431 					MIN(wl_seat_interface.version, 7),
3432 					seat, bind_seat);
3433 
3434 	seat->compositor = ec;
3435 	seat->modifier_state = 0;
3436 	seat->seat_name = strdup(seat_name);
3437 
3438 	wl_list_insert(ec->seat_list.prev, &seat->link);
3439 
3440 	clipboard_create(seat);
3441 
3442 	wl_signal_emit(&ec->seat_created_signal, seat);
3443 }
3444 
3445 WL_EXPORT void
weston_seat_release(struct weston_seat * seat)3446 weston_seat_release(struct weston_seat *seat)
3447 {
3448 	struct wl_resource *resource;
3449 
3450 	wl_resource_for_each(resource, &seat->base_resource_list) {
3451 		wl_resource_set_user_data(resource, NULL);
3452 	}
3453 
3454 	wl_resource_for_each(resource, &seat->drag_resource_list) {
3455 		wl_resource_set_user_data(resource, NULL);
3456 	}
3457 
3458 	wl_list_remove(&seat->base_resource_list);
3459 	wl_list_remove(&seat->drag_resource_list);
3460 
3461 	wl_list_remove(&seat->link);
3462 
3463 	if (seat->saved_kbd_focus)
3464 		wl_list_remove(&seat->saved_kbd_focus_listener.link);
3465 
3466 	if (seat->pointer_state)
3467 		weston_pointer_destroy(seat->pointer_state);
3468 	if (seat->keyboard_state)
3469 		weston_keyboard_destroy(seat->keyboard_state);
3470 	if (seat->touch_state)
3471 		weston_touch_destroy(seat->touch_state);
3472 
3473 	free (seat->seat_name);
3474 
3475 	wl_global_destroy(seat->global);
3476 
3477 	wl_signal_emit(&seat->destroy_signal, seat);
3478 }
3479 
3480 /** Get a seat's keyboard pointer
3481  *
3482  * \param seat The seat to query
3483  * \return The seat's keyboard pointer, or NULL if no keyboard is present
3484  *
3485  * The keyboard pointer for a seat isn't freed when all keyboards are removed,
3486  * so it should only be used when the seat's keyboard_device_count is greater
3487  * than zero.  This function does that test and only returns a pointer
3488  * when a keyboard is present.
3489  */
3490 WL_EXPORT struct weston_keyboard *
weston_seat_get_keyboard(struct weston_seat * seat)3491 weston_seat_get_keyboard(struct weston_seat *seat)
3492 {
3493 	if (!seat)
3494 		return NULL;
3495 
3496 	if (seat->keyboard_device_count)
3497 		return seat->keyboard_state;
3498 
3499 	return NULL;
3500 }
3501 
3502 /** Get a seat's pointer pointer
3503  *
3504  * \param seat The seat to query
3505  * \return The seat's pointer pointer, or NULL if no pointer device is present
3506  *
3507  * The pointer pointer for a seat isn't freed when all mice are removed,
3508  * so it should only be used when the seat's pointer_device_count is greater
3509  * than zero.  This function does that test and only returns a pointer
3510  * when a pointing device is present.
3511  */
3512 WL_EXPORT struct weston_pointer *
weston_seat_get_pointer(struct weston_seat * seat)3513 weston_seat_get_pointer(struct weston_seat *seat)
3514 {
3515 	if (!seat)
3516 		return NULL;
3517 
3518 	if (seat->pointer_device_count)
3519 		return seat->pointer_state;
3520 
3521 	return NULL;
3522 }
3523 
3524 static const struct zwp_locked_pointer_v1_interface locked_pointer_interface;
3525 static const struct zwp_confined_pointer_v1_interface confined_pointer_interface;
3526 
3527 static enum pointer_constraint_type
pointer_constraint_get_type(struct weston_pointer_constraint * constraint)3528 pointer_constraint_get_type(struct weston_pointer_constraint *constraint)
3529 {
3530 	if (wl_resource_instance_of(constraint->resource,
3531 				    &zwp_locked_pointer_v1_interface,
3532 				    &locked_pointer_interface)) {
3533 		return POINTER_CONSTRAINT_TYPE_LOCK;
3534 	} else if (wl_resource_instance_of(constraint->resource,
3535 					   &zwp_confined_pointer_v1_interface,
3536 					   &confined_pointer_interface)) {
3537 		return POINTER_CONSTRAINT_TYPE_CONFINE;
3538 	}
3539 
3540 	abort();
3541 	return 0;
3542 }
3543 
3544 static void
pointer_constraint_notify_activated(struct weston_pointer_constraint * constraint)3545 pointer_constraint_notify_activated(struct weston_pointer_constraint *constraint)
3546 {
3547 	struct wl_resource *resource = constraint->resource;
3548 
3549 	switch (pointer_constraint_get_type(constraint)) {
3550 	case POINTER_CONSTRAINT_TYPE_LOCK:
3551 		zwp_locked_pointer_v1_send_locked(resource);
3552 		break;
3553 	case POINTER_CONSTRAINT_TYPE_CONFINE:
3554 		zwp_confined_pointer_v1_send_confined(resource);
3555 		break;
3556 	}
3557 }
3558 
3559 static void
pointer_constraint_notify_deactivated(struct weston_pointer_constraint * constraint)3560 pointer_constraint_notify_deactivated(struct weston_pointer_constraint *constraint)
3561 {
3562 	struct wl_resource *resource = constraint->resource;
3563 
3564 	switch (pointer_constraint_get_type(constraint)) {
3565 	case POINTER_CONSTRAINT_TYPE_LOCK:
3566 		zwp_locked_pointer_v1_send_unlocked(resource);
3567 		break;
3568 	case POINTER_CONSTRAINT_TYPE_CONFINE:
3569 		zwp_confined_pointer_v1_send_unconfined(resource);
3570 		break;
3571 	}
3572 }
3573 
3574 static struct weston_pointer_constraint *
get_pointer_constraint_for_pointer(struct weston_surface * surface,struct weston_pointer * pointer)3575 get_pointer_constraint_for_pointer(struct weston_surface *surface,
3576 				   struct weston_pointer *pointer)
3577 {
3578 	struct weston_pointer_constraint *constraint;
3579 
3580 	wl_list_for_each(constraint, &surface->pointer_constraints, link) {
3581 		if (constraint->pointer == pointer)
3582 			return constraint;
3583 	}
3584 
3585 	return NULL;
3586 }
3587 
3588 /** Get a seat's touch pointer
3589  *
3590  * \param seat The seat to query
3591  * \return The seat's touch pointer, or NULL if no touch device is present
3592  *
3593  * The touch pointer for a seat isn't freed when all touch devices are removed,
3594  * so it should only be used when the seat's touch_device_count is greater
3595  * than zero.  This function does that test and only returns a pointer
3596  * when a touch device is present.
3597  */
3598 WL_EXPORT struct weston_touch *
weston_seat_get_touch(struct weston_seat * seat)3599 weston_seat_get_touch(struct weston_seat *seat)
3600 {
3601 	if (!seat)
3602 		return NULL;
3603 
3604 	if (seat->touch_device_count)
3605 		return seat->touch_state;
3606 
3607 	return NULL;
3608 }
3609 
3610 /** Sets the keyboard focus to the given surface
3611  *
3612  * \param surface the surface to focus on
3613  * \param seat The seat to query
3614  */
3615 WL_EXPORT void
weston_seat_set_keyboard_focus(struct weston_seat * seat,struct weston_surface * surface)3616 weston_seat_set_keyboard_focus(struct weston_seat *seat,
3617 			       struct weston_surface *surface)
3618 {
3619 	struct weston_compositor *compositor = seat->compositor;
3620 	struct weston_keyboard *keyboard = weston_seat_get_keyboard(seat);
3621 	struct weston_surface_activation_data activation_data;
3622 
3623 	if (keyboard && keyboard->focus != surface) {
3624 		weston_keyboard_set_focus(keyboard, surface);
3625 		wl_data_device_set_keyboard_focus(seat);
3626 	}
3627 
3628 	inc_activate_serial(compositor);
3629 
3630 	activation_data = (struct weston_surface_activation_data) {
3631 		.surface = surface,
3632 		.seat = seat,
3633 	};
3634 	wl_signal_emit(&compositor->activate_signal, &activation_data);
3635 }
3636 
3637 static void
enable_pointer_constraint(struct weston_pointer_constraint * constraint,struct weston_view * view)3638 enable_pointer_constraint(struct weston_pointer_constraint *constraint,
3639 			  struct weston_view *view)
3640 {
3641 	assert(constraint->view == NULL);
3642 	constraint->view = view;
3643 	pointer_constraint_notify_activated(constraint);
3644 	weston_pointer_start_grab(constraint->pointer, &constraint->grab);
3645 	wl_list_remove(&constraint->surface_destroy_listener.link);
3646 	wl_list_init(&constraint->surface_destroy_listener.link);
3647 }
3648 
3649 static bool
is_pointer_constraint_enabled(struct weston_pointer_constraint * constraint)3650 is_pointer_constraint_enabled(struct weston_pointer_constraint *constraint)
3651 {
3652 	return constraint->view != NULL;
3653 }
3654 
3655 static void
weston_pointer_constraint_disable(struct weston_pointer_constraint * constraint)3656 weston_pointer_constraint_disable(struct weston_pointer_constraint *constraint)
3657 {
3658 	constraint->view = NULL;
3659 	pointer_constraint_notify_deactivated(constraint);
3660 	weston_pointer_end_grab(constraint->grab.pointer);
3661 }
3662 
3663 void
weston_pointer_constraint_destroy(struct weston_pointer_constraint * constraint)3664 weston_pointer_constraint_destroy(struct weston_pointer_constraint *constraint)
3665 {
3666 	if (is_pointer_constraint_enabled(constraint))
3667 		weston_pointer_constraint_disable(constraint);
3668 
3669 	wl_list_remove(&constraint->pointer_destroy_listener.link);
3670 	wl_list_remove(&constraint->surface_destroy_listener.link);
3671 	wl_list_remove(&constraint->surface_commit_listener.link);
3672 	wl_list_remove(&constraint->surface_activate_listener.link);
3673 
3674 	wl_resource_set_user_data(constraint->resource, NULL);
3675 	pixman_region32_fini(&constraint->region);
3676 	wl_list_remove(&constraint->link);
3677 	free(constraint);
3678 }
3679 
3680 static void
disable_pointer_constraint(struct weston_pointer_constraint * constraint)3681 disable_pointer_constraint(struct weston_pointer_constraint *constraint)
3682 {
3683 	switch (constraint->lifetime) {
3684 	case ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_ONESHOT:
3685 		weston_pointer_constraint_destroy(constraint);
3686 		break;
3687 	case ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_PERSISTENT:
3688 		weston_pointer_constraint_disable(constraint);
3689 		break;
3690 	}
3691 }
3692 
3693 static bool
is_within_constraint_region(struct weston_pointer_constraint * constraint,wl_fixed_t sx,wl_fixed_t sy)3694 is_within_constraint_region(struct weston_pointer_constraint *constraint,
3695 			    wl_fixed_t sx, wl_fixed_t sy)
3696 {
3697 	struct weston_surface *surface = constraint->surface;
3698 	pixman_region32_t constraint_region;
3699 	bool result;
3700 
3701 	pixman_region32_init(&constraint_region);
3702 	pixman_region32_intersect(&constraint_region,
3703 				  &surface->input,
3704 				  &constraint->region);
3705 	result = pixman_region32_contains_point(&constraint_region,
3706 						wl_fixed_to_int(sx),
3707 						wl_fixed_to_int(sy),
3708 						NULL);
3709 	pixman_region32_fini(&constraint_region);
3710 
3711 	return result;
3712 }
3713 
3714 static void
maybe_enable_pointer_constraint(struct weston_pointer_constraint * constraint)3715 maybe_enable_pointer_constraint(struct weston_pointer_constraint *constraint)
3716 {
3717 	struct weston_surface *surface = constraint->surface;
3718 	struct weston_view *vit;
3719 	struct weston_view *view = NULL;
3720 	struct weston_pointer *pointer = constraint->pointer;
3721 	struct weston_keyboard *keyboard;
3722 	struct weston_seat *seat = pointer->seat;
3723 	int32_t x, y;
3724 
3725 	/* Postpone if no view of the surface was most recently clicked. */
3726 	wl_list_for_each(vit, &surface->views, surface_link) {
3727 		if (vit->click_to_activate_serial ==
3728 		    surface->compositor->activate_serial) {
3729 			view = vit;
3730 		}
3731 	}
3732 	if (view == NULL)
3733 		return;
3734 
3735 	/* Postpone if surface doesn't have keyboard focus. */
3736 	keyboard = weston_seat_get_keyboard(seat);
3737 	if (!keyboard || keyboard->focus != surface)
3738 		return;
3739 
3740 	/* Postpone constraint if the pointer is not within the
3741 	 * constraint region.
3742 	 */
3743 	weston_view_from_global(view,
3744 				wl_fixed_to_int(pointer->x),
3745 				wl_fixed_to_int(pointer->y),
3746 				&x, &y);
3747 	if (!is_within_constraint_region(constraint,
3748 					 wl_fixed_from_int(x),
3749 					 wl_fixed_from_int(y)))
3750 		return;
3751 
3752 	enable_pointer_constraint(constraint, view);
3753 }
3754 
3755 static void
locked_pointer_grab_pointer_focus(struct weston_pointer_grab * grab)3756 locked_pointer_grab_pointer_focus(struct weston_pointer_grab *grab)
3757 {
3758 }
3759 
3760 static void
locked_pointer_grab_pointer_motion(struct weston_pointer_grab * grab,const struct timespec * time,struct weston_pointer_motion_event * event)3761 locked_pointer_grab_pointer_motion(struct weston_pointer_grab *grab,
3762 				   const struct timespec *time,
3763 				   struct weston_pointer_motion_event *event)
3764 {
3765 	pointer_send_relative_motion(grab->pointer, time, event);
3766 }
3767 
3768 static void
locked_pointer_grab_pointer_button(struct weston_pointer_grab * grab,const struct timespec * time,uint32_t button,uint32_t state_w)3769 locked_pointer_grab_pointer_button(struct weston_pointer_grab *grab,
3770 				   const struct timespec *time,
3771 				   uint32_t button,
3772 				   uint32_t state_w)
3773 {
3774 	weston_pointer_send_button(grab->pointer, time, button, state_w);
3775 }
3776 
3777 static void
locked_pointer_grab_pointer_axis(struct weston_pointer_grab * grab,const struct timespec * time,struct weston_pointer_axis_event * event)3778 locked_pointer_grab_pointer_axis(struct weston_pointer_grab *grab,
3779 				 const struct timespec *time,
3780 				 struct weston_pointer_axis_event *event)
3781 {
3782 	weston_pointer_send_axis(grab->pointer, time, event);
3783 }
3784 
3785 static void
locked_pointer_grab_pointer_axis_source(struct weston_pointer_grab * grab,uint32_t source)3786 locked_pointer_grab_pointer_axis_source(struct weston_pointer_grab *grab,
3787 					uint32_t source)
3788 {
3789 	weston_pointer_send_axis_source(grab->pointer, source);
3790 }
3791 
3792 static void
locked_pointer_grab_pointer_frame(struct weston_pointer_grab * grab)3793 locked_pointer_grab_pointer_frame(struct weston_pointer_grab *grab)
3794 {
3795 	weston_pointer_send_frame(grab->pointer);
3796 }
3797 
3798 static void
locked_pointer_grab_pointer_cancel(struct weston_pointer_grab * grab)3799 locked_pointer_grab_pointer_cancel(struct weston_pointer_grab *grab)
3800 {
3801 	struct weston_pointer_constraint *constraint =
3802 		container_of(grab, struct weston_pointer_constraint, grab);
3803 
3804 	disable_pointer_constraint(constraint);
3805 }
3806 
3807 static const struct weston_pointer_grab_interface
3808 				locked_pointer_grab_interface = {
3809 	locked_pointer_grab_pointer_focus,
3810 	locked_pointer_grab_pointer_motion,
3811 	locked_pointer_grab_pointer_button,
3812 	locked_pointer_grab_pointer_axis,
3813 	locked_pointer_grab_pointer_axis_source,
3814 	locked_pointer_grab_pointer_frame,
3815 	locked_pointer_grab_pointer_cancel,
3816 };
3817 
3818 static void
pointer_constraint_constrain_resource_destroyed(struct wl_resource * resource)3819 pointer_constraint_constrain_resource_destroyed(struct wl_resource *resource)
3820 {
3821 	struct weston_pointer_constraint *constraint =
3822 		wl_resource_get_user_data(resource);
3823 
3824 	if (!constraint)
3825 		return;
3826 
3827 	weston_pointer_constraint_destroy(constraint);
3828 }
3829 
3830 static void
pointer_constraint_surface_activate(struct wl_listener * listener,void * data)3831 pointer_constraint_surface_activate(struct wl_listener *listener, void *data)
3832 {
3833 	struct weston_surface_activation_data *activation = data;
3834 	struct weston_pointer *pointer;
3835 	struct weston_surface *focus = activation->surface;
3836 	struct weston_pointer_constraint *constraint =
3837 		container_of(listener, struct weston_pointer_constraint,
3838 			     surface_activate_listener);
3839 	bool is_constraint_surface;
3840 
3841 	pointer = weston_seat_get_pointer(activation->seat);
3842 	if (!pointer)
3843 		return;
3844 
3845 	is_constraint_surface =
3846 		get_pointer_constraint_for_pointer(focus, pointer) == constraint;
3847 
3848 	if (is_constraint_surface &&
3849 	    !is_pointer_constraint_enabled(constraint))
3850 		maybe_enable_pointer_constraint(constraint);
3851 	else if (!is_constraint_surface &&
3852 		 is_pointer_constraint_enabled(constraint))
3853 		disable_pointer_constraint(constraint);
3854 }
3855 
3856 static void
pointer_constraint_pointer_destroyed(struct wl_listener * listener,void * data)3857 pointer_constraint_pointer_destroyed(struct wl_listener *listener, void *data)
3858 {
3859 	struct weston_pointer_constraint *constraint =
3860 		container_of(listener, struct weston_pointer_constraint,
3861 			     pointer_destroy_listener);
3862 
3863 	weston_pointer_constraint_destroy(constraint);
3864 }
3865 
3866 static void
pointer_constraint_surface_destroyed(struct wl_listener * listener,void * data)3867 pointer_constraint_surface_destroyed(struct wl_listener *listener, void *data)
3868 {
3869 	struct weston_pointer_constraint *constraint =
3870 		container_of(listener, struct weston_pointer_constraint,
3871 			     surface_destroy_listener);
3872 
3873 	weston_pointer_constraint_destroy(constraint);
3874 }
3875 
3876 static void
pointer_constraint_surface_committed(struct wl_listener * listener,void * data)3877 pointer_constraint_surface_committed(struct wl_listener *listener, void *data)
3878 {
3879 	struct weston_pointer_constraint *constraint =
3880 		container_of(listener, struct weston_pointer_constraint,
3881 			     surface_commit_listener);
3882 
3883 	if (constraint->region_is_pending) {
3884 		constraint->region_is_pending = false;
3885 		pixman_region32_copy(&constraint->region,
3886 				     &constraint->region_pending);
3887 		pixman_region32_fini(&constraint->region_pending);
3888 		pixman_region32_init(&constraint->region_pending);
3889 	}
3890 
3891 	if (constraint->hint_is_pending) {
3892 		constraint->hint_is_pending = false;
3893 
3894 		constraint->hint_is_pending = true;
3895 		constraint->hint_x = constraint->hint_x_pending;
3896 		constraint->hint_y = constraint->hint_y_pending;
3897 	}
3898 
3899 	if (pointer_constraint_get_type(constraint) ==
3900 	    POINTER_CONSTRAINT_TYPE_CONFINE &&
3901 	    is_pointer_constraint_enabled(constraint))
3902 		maybe_warp_confined_pointer(constraint);
3903 }
3904 
3905 static struct weston_pointer_constraint *
weston_pointer_constraint_create(struct weston_surface * surface,struct weston_pointer * pointer,struct weston_region * region,enum zwp_pointer_constraints_v1_lifetime lifetime,struct wl_resource * cr,const struct weston_pointer_grab_interface * grab_interface)3906 weston_pointer_constraint_create(struct weston_surface *surface,
3907 				 struct weston_pointer *pointer,
3908 				 struct weston_region *region,
3909 				 enum zwp_pointer_constraints_v1_lifetime lifetime,
3910 				 struct wl_resource *cr,
3911 				 const struct weston_pointer_grab_interface *grab_interface)
3912 {
3913 	struct weston_pointer_constraint *constraint;
3914 
3915 	constraint = zalloc(sizeof *constraint);
3916 	if (!constraint)
3917 		return NULL;
3918 
3919 	constraint->lifetime = lifetime;
3920 	pixman_region32_init(&constraint->region);
3921 	pixman_region32_init(&constraint->region_pending);
3922 	wl_list_insert(&surface->pointer_constraints, &constraint->link);
3923 	constraint->surface = surface;
3924 	constraint->pointer = pointer;
3925 	constraint->resource = cr;
3926 	constraint->grab.interface = grab_interface;
3927 	if (region) {
3928 		pixman_region32_copy(&constraint->region,
3929 				     &region->region);
3930 	} else {
3931 		pixman_region32_fini(&constraint->region);
3932 		region_init_infinite(&constraint->region);
3933 	}
3934 
3935 	constraint->surface_activate_listener.notify =
3936 		pointer_constraint_surface_activate;
3937 	constraint->surface_destroy_listener.notify =
3938 		pointer_constraint_surface_destroyed;
3939 	constraint->surface_commit_listener.notify =
3940 		pointer_constraint_surface_committed;
3941 	constraint->pointer_destroy_listener.notify =
3942 		pointer_constraint_pointer_destroyed;
3943 
3944 	wl_signal_add(&surface->compositor->activate_signal,
3945 		      &constraint->surface_activate_listener);
3946 	wl_signal_add(&pointer->destroy_signal,
3947 		      &constraint->pointer_destroy_listener);
3948 	wl_signal_add(&surface->destroy_signal,
3949 		      &constraint->surface_destroy_listener);
3950 	wl_signal_add(&surface->commit_signal,
3951 		      &constraint->surface_commit_listener);
3952 
3953 	return constraint;
3954 }
3955 
3956 static void
init_pointer_constraint(struct wl_resource * pointer_constraints_resource,uint32_t id,struct weston_surface * surface,struct weston_pointer * pointer,struct weston_region * region,enum zwp_pointer_constraints_v1_lifetime lifetime,const struct wl_interface * interface,const void * implementation,const struct weston_pointer_grab_interface * grab_interface)3957 init_pointer_constraint(struct wl_resource *pointer_constraints_resource,
3958 			uint32_t id,
3959 			struct weston_surface *surface,
3960 			struct weston_pointer *pointer,
3961 			struct weston_region *region,
3962 			enum zwp_pointer_constraints_v1_lifetime lifetime,
3963 			const struct wl_interface *interface,
3964 			const void *implementation,
3965 			const struct weston_pointer_grab_interface *grab_interface)
3966 {
3967 	struct wl_client *client =
3968 		wl_resource_get_client(pointer_constraints_resource);
3969 	struct wl_resource *cr;
3970 	struct weston_pointer_constraint *constraint;
3971 
3972 	if (pointer && get_pointer_constraint_for_pointer(surface, pointer)) {
3973 		wl_resource_post_error(pointer_constraints_resource,
3974 				       ZWP_POINTER_CONSTRAINTS_V1_ERROR_ALREADY_CONSTRAINED,
3975 				       "the pointer has a lock/confine request on this surface");
3976 		return;
3977 	}
3978 
3979 	cr = wl_resource_create(client, interface,
3980 				wl_resource_get_version(pointer_constraints_resource),
3981 				id);
3982 	if (cr == NULL) {
3983 		wl_client_post_no_memory(client);
3984 		return;
3985 	}
3986 
3987 	if (pointer) {
3988 		constraint = weston_pointer_constraint_create(surface, pointer,
3989 							      region, lifetime,
3990 							      cr, grab_interface);
3991 		if (constraint == NULL) {
3992 			wl_client_post_no_memory(client);
3993 			return;
3994 		}
3995 	} else {
3996 		constraint = NULL;
3997 	}
3998 
3999 	wl_resource_set_implementation(cr, implementation, constraint,
4000 				       pointer_constraint_constrain_resource_destroyed);
4001 
4002 	if (constraint)
4003 		maybe_enable_pointer_constraint(constraint);
4004 }
4005 
4006 static void
pointer_constraints_destroy(struct wl_client * client,struct wl_resource * resource)4007 pointer_constraints_destroy(struct wl_client *client,
4008 			    struct wl_resource *resource)
4009 {
4010 	wl_resource_destroy(resource);
4011 }
4012 
4013 static void
locked_pointer_destroy(struct wl_client * client,struct wl_resource * resource)4014 locked_pointer_destroy(struct wl_client *client,
4015 		       struct wl_resource *resource)
4016 {
4017 	struct weston_pointer_constraint *constraint =
4018 		wl_resource_get_user_data(resource);
4019 	wl_fixed_t x, y;
4020 
4021 	if (constraint && constraint->view && constraint->hint_is_pending &&
4022 	    is_within_constraint_region(constraint,
4023 					constraint->hint_x,
4024 					constraint->hint_y)) {
4025 		weston_view_to_global_fixed(constraint->view,
4026 					    constraint->hint_x,
4027 					    constraint->hint_y,
4028 					    &x, &y);
4029 		weston_pointer_move_to(constraint->pointer, x, y);
4030 	}
4031 	wl_resource_destroy(resource);
4032 }
4033 
4034 static void
locked_pointer_set_cursor_position_hint(struct wl_client * client,struct wl_resource * resource,wl_fixed_t surface_x,wl_fixed_t surface_y)4035 locked_pointer_set_cursor_position_hint(struct wl_client *client,
4036 					struct wl_resource *resource,
4037 					wl_fixed_t surface_x,
4038 					wl_fixed_t surface_y)
4039 {
4040 	struct weston_pointer_constraint *constraint =
4041 		wl_resource_get_user_data(resource);
4042 
4043 	/* Ignore a set cursor hint that was sent after the lock was cancelled.
4044 	 */
4045 	if (!constraint ||
4046 	    !constraint->resource ||
4047 	    constraint->resource != resource)
4048 		return;
4049 
4050 	constraint->hint_is_pending = true;
4051 	constraint->hint_x_pending = surface_x;
4052 	constraint->hint_y_pending = surface_y;
4053 }
4054 
4055 static void
locked_pointer_set_region(struct wl_client * client,struct wl_resource * resource,struct wl_resource * region_resource)4056 locked_pointer_set_region(struct wl_client *client,
4057 			  struct wl_resource *resource,
4058 			  struct wl_resource *region_resource)
4059 {
4060 	struct weston_pointer_constraint *constraint =
4061 		wl_resource_get_user_data(resource);
4062 	struct weston_region *region = region_resource ?
4063 		wl_resource_get_user_data(region_resource) : NULL;
4064 
4065 	if (!constraint)
4066 		return;
4067 
4068 	if (region) {
4069 		pixman_region32_copy(&constraint->region_pending,
4070 				     &region->region);
4071 	} else {
4072 		pixman_region32_fini(&constraint->region_pending);
4073 		region_init_infinite(&constraint->region_pending);
4074 	}
4075 	constraint->region_is_pending = true;
4076 }
4077 
4078 
4079 static const struct zwp_locked_pointer_v1_interface locked_pointer_interface = {
4080 	locked_pointer_destroy,
4081 	locked_pointer_set_cursor_position_hint,
4082 	locked_pointer_set_region,
4083 };
4084 
4085 static void
pointer_constraints_lock_pointer(struct wl_client * client,struct wl_resource * resource,uint32_t id,struct wl_resource * surface_resource,struct wl_resource * pointer_resource,struct wl_resource * region_resource,uint32_t lifetime)4086 pointer_constraints_lock_pointer(struct wl_client *client,
4087 				 struct wl_resource *resource,
4088 				 uint32_t id,
4089 				 struct wl_resource *surface_resource,
4090 				 struct wl_resource *pointer_resource,
4091 				 struct wl_resource *region_resource,
4092 				 uint32_t lifetime)
4093 {
4094 	struct weston_surface *surface =
4095 		wl_resource_get_user_data(surface_resource);
4096 	struct weston_pointer *pointer = wl_resource_get_user_data(pointer_resource);
4097 	struct weston_region *region = region_resource ?
4098 		wl_resource_get_user_data(region_resource) : NULL;
4099 
4100 	init_pointer_constraint(resource, id, surface, pointer, region, lifetime,
4101 				&zwp_locked_pointer_v1_interface,
4102 				&locked_pointer_interface,
4103 				&locked_pointer_grab_interface);
4104 }
4105 
4106 static void
confined_pointer_grab_pointer_focus(struct weston_pointer_grab * grab)4107 confined_pointer_grab_pointer_focus(struct weston_pointer_grab *grab)
4108 {
4109 }
4110 
4111 static double
vec2d_cross_product(struct vec2d a,struct vec2d b)4112 vec2d_cross_product(struct vec2d a, struct vec2d b)
4113 {
4114 	return a.x * b.y - a.y * b.x;
4115 }
4116 
4117 static struct vec2d
vec2d_add(struct vec2d a,struct vec2d b)4118 vec2d_add(struct vec2d a, struct vec2d b)
4119 {
4120 	return (struct vec2d) {
4121 		.x = a.x + b.x,
4122 		.y = a.y + b.y,
4123 	};
4124 }
4125 
4126 static struct vec2d
vec2d_subtract(struct vec2d a,struct vec2d b)4127 vec2d_subtract(struct vec2d a, struct vec2d b)
4128 {
4129 	return (struct vec2d) {
4130 		.x = a.x - b.x,
4131 		.y = a.y - b.y,
4132 	};
4133 }
4134 
4135 static struct vec2d
vec2d_multiply_constant(double c,struct vec2d a)4136 vec2d_multiply_constant(double c, struct vec2d a)
4137 {
4138 	return (struct vec2d) {
4139 		.x = c * a.x,
4140 		.y = c * a.y,
4141 	};
4142 }
4143 
4144 static bool
lines_intersect(struct line * line1,struct line * line2,struct vec2d * intersection)4145 lines_intersect(struct line *line1, struct line *line2,
4146 		struct vec2d *intersection)
4147 {
4148 	struct vec2d p = line1->a;
4149 	struct vec2d r = vec2d_subtract(line1->b, line1->a);
4150 	struct vec2d q = line2->a;
4151 	struct vec2d s = vec2d_subtract(line2->b, line2->a);
4152 	double rxs;
4153 	double sxr;
4154 	double t;
4155 	double u;
4156 
4157 	/*
4158 	 * The line (p, r) and (q, s) intersects where
4159 	 *
4160 	 *   p + t r = q + u s
4161 	 *
4162 	 * Calculate t:
4163 	 *
4164 	 *   (p + t r) × s = (q + u s) × s
4165 	 *   p × s + t (r × s) = q × s + u (s × s)
4166 	 *   p × s + t (r × s) = q × s
4167 	 *   t (r × s) = q × s - p × s
4168 	 *   t (r × s) = (q - p) × s
4169 	 *   t = ((q - p) × s) / (r × s)
4170 	 *
4171 	 * Using the same method, for u we get:
4172 	 *
4173 	 *   u = ((p - q) × r) / (s × r)
4174 	 */
4175 
4176 	rxs = vec2d_cross_product(r, s);
4177 	sxr = vec2d_cross_product(s, r);
4178 
4179 	/* If r × s = 0 then the lines are either parallel or collinear. */
4180 	if (fabs(rxs) < DBL_MIN)
4181 		return false;
4182 
4183 	t = vec2d_cross_product(vec2d_subtract(q, p), s) / rxs;
4184 	u = vec2d_cross_product(vec2d_subtract(p, q), r) / sxr;
4185 
4186 	/* The lines only intersect if 0 ≤ t ≤ 1 and 0 ≤ u ≤ 1. */
4187 	if (t < 0.0 || t > 1.0 || u < 0.0 || u > 1.0)
4188 		return false;
4189 
4190 	*intersection = vec2d_add(p, vec2d_multiply_constant(t, r));
4191 	return true;
4192 }
4193 
4194 static struct border *
add_border(struct wl_array * array,double x1,double y1,double x2,double y2,enum motion_direction blocking_dir)4195 add_border(struct wl_array *array,
4196 	   double x1, double y1,
4197 	   double x2, double y2,
4198 	   enum motion_direction blocking_dir)
4199 {
4200 	struct border *border = wl_array_add(array, sizeof *border);
4201 
4202 	*border = (struct border) {
4203 		.line = (struct line) {
4204 			.a = (struct vec2d) {
4205 				.x = x1,
4206 				.y = y1,
4207 			},
4208 			.b = (struct vec2d) {
4209 				.x = x2,
4210 				.y = y2,
4211 			},
4212 		},
4213 		.blocking_dir = blocking_dir,
4214 	};
4215 
4216 	return border;
4217 }
4218 
4219 static int
compare_lines_x(const void * a,const void * b)4220 compare_lines_x(const void *a, const void *b)
4221 {
4222 	const struct border *border_a = a;
4223 	const struct border *border_b = b;
4224 
4225 
4226 	if (border_a->line.a.x == border_b->line.a.x)
4227 		return border_a->line.b.x < border_b->line.b.x;
4228 	else
4229 		return border_a->line.a.x > border_b->line.a.x;
4230 }
4231 
4232 static void
add_non_overlapping_edges(pixman_box32_t * boxes,int band_above_start,int band_below_start,int band_below_end,struct wl_array * borders)4233 add_non_overlapping_edges(pixman_box32_t *boxes,
4234 			  int band_above_start,
4235 			  int band_below_start,
4236 			  int band_below_end,
4237 			  struct wl_array *borders)
4238 {
4239 	int i;
4240 	struct wl_array band_merge;
4241 	struct border *border;
4242 	struct border *prev_border;
4243 	struct border *new_border;
4244 
4245 	wl_array_init(&band_merge);
4246 
4247 	/* Add bottom band of previous row, and top band of current row, and
4248 	 * sort them so lower left x coordinate comes first. If there are two
4249 	 * borders with the same left x coordinate, the wider one comes first.
4250 	 */
4251 	for (i = band_above_start; i < band_below_start; i++) {
4252 		pixman_box32_t *box = &boxes[i];
4253 		add_border(&band_merge, box->x1, box->y2, box->x2, box->y2,
4254 			   MOTION_DIRECTION_POSITIVE_Y);
4255 	}
4256 	for (i = band_below_start; i < band_below_end; i++) {
4257 		pixman_box32_t *box= &boxes[i];
4258 		add_border(&band_merge, box->x1, box->y1, box->x2, box->y1,
4259 			   MOTION_DIRECTION_NEGATIVE_Y);
4260 	}
4261 	qsort(band_merge.data,
4262 	      band_merge.size / sizeof *border,
4263 	      sizeof *border,
4264 	      compare_lines_x);
4265 
4266 	/* Combine the two combined bands so that any overlapping border is
4267 	 * eliminated. */
4268 	prev_border = NULL;
4269 	wl_array_for_each(border, &band_merge) {
4270 		assert(border->line.a.y == border->line.b.y);
4271 		assert(!prev_border ||
4272 		       prev_border->line.a.y == border->line.a.y);
4273 		assert(!prev_border ||
4274 		       (prev_border->line.a.x != border->line.a.x ||
4275 			prev_border->line.b.x != border->line.b.x));
4276 		assert(!prev_border ||
4277 		       prev_border->line.a.x <= border->line.a.x);
4278 
4279 		if (prev_border &&
4280 		    prev_border->line.a.x == border->line.a.x) {
4281 			/*
4282 			 * ------------ +
4283 			 * -------      =
4284 			 * [     ]-----
4285 			 */
4286 			prev_border->line.a.x = border->line.b.x;
4287 		} else if (prev_border &&
4288 			   prev_border->line.b.x == border->line.b.x) {
4289 			/*
4290 			 * ------------ +
4291 			 *       ------ =
4292 			 * ------[    ]
4293 			 */
4294 			prev_border->line.b.x = border->line.a.x;
4295 		} else if (prev_border &&
4296 			   prev_border->line.b.x == border->line.a.x) {
4297 			/*
4298 			 * --------        +
4299 			 *         ------  =
4300 			 * --------------
4301 			 */
4302 			prev_border->line.b.x = border->line.b.x;
4303 		} else if (prev_border &&
4304 			   prev_border->line.b.x >= border->line.a.x) {
4305 			/*
4306 			 * --------------- +
4307 			 *      ------     =
4308 			 * -----[    ]----
4309 			 */
4310 			new_border = add_border(borders,
4311 						border->line.b.x,
4312 						border->line.b.y,
4313 						prev_border->line.b.x,
4314 						prev_border->line.b.y,
4315 						prev_border->blocking_dir);
4316 			prev_border->line.b.x = border->line.a.x;
4317 			prev_border = new_border;
4318 		} else {
4319 			assert(!prev_border ||
4320 			       prev_border->line.b.x < border->line.a.x);
4321 			/*
4322 			 * First border or non-overlapping.
4323 			 *
4324 			 * -----           +
4325 			 *        -----    =
4326 			 * -----  -----
4327 			 */
4328 			new_border = wl_array_add(borders, sizeof *border);
4329 			*new_border = *border;
4330 			prev_border = new_border;
4331 		}
4332 	}
4333 
4334 	wl_array_release(&band_merge);
4335 }
4336 
4337 static void
add_band_bottom_edges(pixman_box32_t * boxes,int band_start,int band_end,struct wl_array * borders)4338 add_band_bottom_edges(pixman_box32_t *boxes,
4339 		      int band_start,
4340 		      int band_end,
4341 		      struct wl_array *borders)
4342 {
4343 	int i;
4344 
4345 	for (i = band_start; i < band_end; i++) {
4346 		add_border(borders,
4347 			   boxes[i].x1, boxes[i].y2,
4348 			   boxes[i].x2, boxes[i].y2,
4349 			   MOTION_DIRECTION_POSITIVE_Y);
4350 	}
4351 }
4352 
4353 static void
region_to_outline(pixman_region32_t * region,struct wl_array * borders)4354 region_to_outline(pixman_region32_t *region, struct wl_array *borders)
4355 {
4356 	pixman_box32_t *boxes;
4357 	int num_boxes;
4358 	int i;
4359 	int top_most, bottom_most;
4360 	int current_roof;
4361 	int prev_top;
4362 	int band_start, prev_band_start;
4363 
4364 	/*
4365 	 * Remove any overlapping lines from the set of rectangles. Note that
4366 	 * pixman regions are grouped as rows of rectangles, where rectangles
4367 	 * in one row never touch or overlap and are all of the same height.
4368 	 *
4369 	 *             -------- ---                   -------- ---
4370 	 *             |      | | |                   |      | | |
4371 	 *   ----------====---- ---         -----------  ----- ---
4372 	 *   |            |            =>   |            |
4373 	 *   ----==========---------        -----        ----------
4374 	 *       |                 |	        |                 |
4375 	 *       -------------------            -------------------
4376 	 *
4377 	 */
4378 
4379 	boxes = pixman_region32_rectangles(region, &num_boxes);
4380 	prev_top = 0;
4381 	top_most = boxes[0].y1;
4382 	current_roof = top_most;
4383 	bottom_most = boxes[num_boxes - 1].y2;
4384 	band_start = 0;
4385 	prev_band_start = 0;
4386 	for (i = 0; i < num_boxes; i++) {
4387 		/* Detect if there is a vertical empty space, and add the lower
4388 		 * level of the previous band if so was the case. */
4389 		if (i > 0 &&
4390 		    boxes[i].y1 != prev_top &&
4391 		    boxes[i].y1 != boxes[i - 1].y2) {
4392 			current_roof = boxes[i].y1;
4393 			add_band_bottom_edges(boxes,
4394 					      band_start,
4395 					      i,
4396 					      borders);
4397 		}
4398 
4399 		/* Special case adding the last band, since it won't be handled
4400 		 * by the band change detection below. */
4401 		if (boxes[i].y1 != current_roof && i == num_boxes - 1) {
4402 			if (boxes[i].y1 != prev_top) {
4403 				/* The last band is a single box, so we don't
4404 				 * have a prev_band_start to tell us when the
4405 				 * previous band started. */
4406 				add_non_overlapping_edges(boxes,
4407 							  band_start,
4408 							  i,
4409 							  i + 1,
4410 							  borders);
4411 			} else {
4412 				add_non_overlapping_edges(boxes,
4413 							  prev_band_start,
4414 							  band_start,
4415 							  i + 1,
4416 							  borders);
4417 			}
4418 		}
4419 
4420 		/* Detect when passing a band and combine the top border of the
4421 		 * just passed band with the bottom band of the previous band.
4422 		 */
4423 		if (boxes[i].y1 != top_most && boxes[i].y1 != prev_top) {
4424 			/* Combine the two passed bands. */
4425 			if (prev_top != current_roof) {
4426 				add_non_overlapping_edges(boxes,
4427 							  prev_band_start,
4428 							  band_start,
4429 							  i,
4430 							  borders);
4431 			}
4432 
4433 			prev_band_start = band_start;
4434 			band_start = i;
4435 		}
4436 
4437 		/* Add the top border if the box is part of the current roof. */
4438 		if (boxes[i].y1 == current_roof) {
4439 			add_border(borders,
4440 				   boxes[i].x1, boxes[i].y1,
4441 				   boxes[i].x2, boxes[i].y1,
4442 				   MOTION_DIRECTION_NEGATIVE_Y);
4443 		}
4444 
4445 		/* Add the bottom border of the last band. */
4446 		if (boxes[i].y2 == bottom_most) {
4447 			add_border(borders,
4448 				   boxes[i].x1, boxes[i].y2,
4449 				   boxes[i].x2, boxes[i].y2,
4450 				   MOTION_DIRECTION_POSITIVE_Y);
4451 		}
4452 
4453 		/* Always add the left border. */
4454 		add_border(borders,
4455 			   boxes[i].x1, boxes[i].y1,
4456 			   boxes[i].x1, boxes[i].y2,
4457 			   MOTION_DIRECTION_NEGATIVE_X);
4458 
4459 		/* Always add the right border. */
4460 		add_border(borders,
4461 			   boxes[i].x2, boxes[i].y1,
4462 			   boxes[i].x2, boxes[i].y2,
4463 			   MOTION_DIRECTION_POSITIVE_X);
4464 
4465 		prev_top = boxes[i].y1;
4466 	}
4467 }
4468 
4469 static bool
is_border_horizontal(struct border * border)4470 is_border_horizontal (struct border *border)
4471 {
4472 	return border->line.a.y == border->line.b.y;
4473 }
4474 
4475 static bool
is_border_blocking_directions(struct border * border,uint32_t directions)4476 is_border_blocking_directions(struct border *border,
4477 			      uint32_t directions)
4478 {
4479 	/* Don't block parallel motions. */
4480 	if (is_border_horizontal(border)) {
4481 		if ((directions & (MOTION_DIRECTION_POSITIVE_Y |
4482 				   MOTION_DIRECTION_NEGATIVE_Y)) == 0)
4483 			return false;
4484 	} else {
4485 		if ((directions & (MOTION_DIRECTION_POSITIVE_X |
4486 				   MOTION_DIRECTION_NEGATIVE_X)) == 0)
4487 			return false;
4488 	}
4489 
4490 	return (~border->blocking_dir & directions) != directions;
4491 }
4492 
4493 static struct border *
get_closest_border(struct wl_array * borders,struct line * motion,uint32_t directions)4494 get_closest_border(struct wl_array *borders,
4495 		   struct line *motion,
4496 		   uint32_t directions)
4497 {
4498 	struct border *border;
4499 	struct vec2d intersection;
4500 	struct vec2d delta;
4501 	double distance_2;
4502 	struct border *closest_border = NULL;
4503 	double closest_distance_2 = DBL_MAX;
4504 
4505 	wl_array_for_each(border, borders) {
4506 		if (!is_border_blocking_directions(border, directions))
4507 			continue;
4508 
4509 		if (!lines_intersect(&border->line, motion, &intersection))
4510 			continue;
4511 
4512 		delta = vec2d_subtract(intersection, motion->a);
4513 		distance_2 = delta.x*delta.x + delta.y*delta.y;
4514 		if (distance_2 < closest_distance_2) {
4515 			closest_border = border;
4516 			closest_distance_2 = distance_2;
4517 		}
4518 	}
4519 
4520 	return closest_border;
4521 }
4522 
4523 static void
clamp_to_border(struct border * border,struct line * motion,uint32_t * motion_dir)4524 clamp_to_border(struct border *border,
4525 		struct line *motion,
4526 		uint32_t *motion_dir)
4527 {
4528 	/*
4529 	 * When clamping either rightward or downward motions, the motion needs
4530 	 * to be clamped so that the destination coordinate does not end up on
4531 	 * the border (see weston_pointer_clamp_event_to_region). Do this by
4532 	 * clamping such motions to the border minus the smallest possible
4533 	 * wl_fixed_t value.
4534 	 */
4535 	if (is_border_horizontal(border)) {
4536 		if (*motion_dir & MOTION_DIRECTION_POSITIVE_Y)
4537 			motion->b.y = border->line.a.y - wl_fixed_to_double(1);
4538 		else
4539 			motion->b.y = border->line.a.y;
4540 		*motion_dir &= ~(MOTION_DIRECTION_POSITIVE_Y |
4541 				 MOTION_DIRECTION_NEGATIVE_Y);
4542 	} else {
4543 		if (*motion_dir & MOTION_DIRECTION_POSITIVE_X)
4544 			motion->b.x = border->line.a.x - wl_fixed_to_double(1);
4545 		else
4546 			motion->b.x = border->line.a.x;
4547 		*motion_dir &= ~(MOTION_DIRECTION_POSITIVE_X |
4548 				 MOTION_DIRECTION_NEGATIVE_X);
4549 	}
4550 }
4551 
4552 static uint32_t
get_motion_directions(struct line * motion)4553 get_motion_directions(struct line *motion)
4554 {
4555 	uint32_t directions = 0;
4556 
4557 	if (motion->a.x < motion->b.x)
4558 		directions |= MOTION_DIRECTION_POSITIVE_X;
4559 	else if (motion->a.x > motion->b.x)
4560 		directions |= MOTION_DIRECTION_NEGATIVE_X;
4561 	if (motion->a.y < motion->b.y)
4562 		directions |= MOTION_DIRECTION_POSITIVE_Y;
4563 	else if (motion->a.y > motion->b.y)
4564 		directions |= MOTION_DIRECTION_NEGATIVE_Y;
4565 
4566 	return directions;
4567 }
4568 
4569 static void
weston_pointer_clamp_event_to_region(struct weston_pointer * pointer,struct weston_pointer_motion_event * event,pixman_region32_t * region,wl_fixed_t * clamped_x,wl_fixed_t * clamped_y)4570 weston_pointer_clamp_event_to_region(struct weston_pointer *pointer,
4571 				     struct weston_pointer_motion_event *event,
4572 				     pixman_region32_t *region,
4573 				     wl_fixed_t *clamped_x,
4574 				     wl_fixed_t *clamped_y)
4575 {
4576 	wl_fixed_t x, y;
4577 	wl_fixed_t sx, sy;
4578 	wl_fixed_t old_sx = pointer->sx;
4579 	wl_fixed_t old_sy = pointer->sy;
4580 	struct wl_array borders;
4581 	struct line motion;
4582 	struct border *closest_border;
4583 	float new_x_f, new_y_f;
4584 	uint32_t directions;
4585 
4586 	weston_pointer_motion_to_abs(pointer, event, &x, &y);
4587 	weston_view_from_global_fixed(pointer->focus, x, y, &sx, &sy);
4588 
4589 	wl_array_init(&borders);
4590 
4591 	/*
4592 	 * Generate borders given the confine region we are to use. The borders
4593 	 * are defined to be the outer region of the allowed area. This means
4594 	 * top/left borders are "within" the allowed area, while bottom/right
4595 	 * borders are outside. This needs to be considered when clamping
4596 	 * confined motion vectors.
4597 	 */
4598 	region_to_outline(region, &borders);
4599 
4600 	motion = (struct line) {
4601 		.a = (struct vec2d) {
4602 			.x = wl_fixed_to_double(old_sx),
4603 			.y = wl_fixed_to_double(old_sy),
4604 		},
4605 		.b = (struct vec2d) {
4606 			.x = wl_fixed_to_double(sx),
4607 			.y = wl_fixed_to_double(sy),
4608 		},
4609 	};
4610 	directions = get_motion_directions(&motion);
4611 
4612 	while (directions) {
4613 		closest_border = get_closest_border(&borders,
4614 						    &motion,
4615 						    directions);
4616 		if (closest_border)
4617 			clamp_to_border(closest_border, &motion, &directions);
4618 		else
4619 			break;
4620 	}
4621 
4622 	weston_view_to_global_float(pointer->focus,
4623 				    (float) motion.b.x, (float) motion.b.y,
4624 				    &new_x_f, &new_y_f);
4625 	*clamped_x = wl_fixed_from_double(new_x_f);
4626 	*clamped_y = wl_fixed_from_double(new_y_f);
4627 
4628 	wl_array_release(&borders);
4629 }
4630 
4631 static double
point_to_border_distance_2(struct border * border,double x,double y)4632 point_to_border_distance_2(struct border *border, double x, double y)
4633 {
4634 	double orig_x, orig_y;
4635 	double dx, dy;
4636 
4637 	if (is_border_horizontal(border)) {
4638 		if (x < border->line.a.x)
4639 			orig_x = border->line.a.x;
4640 		else if (x > border->line.b.x)
4641 			orig_x = border->line.b.x;
4642 		else
4643 			orig_x = x;
4644 		orig_y = border->line.a.y;
4645 	} else {
4646 		if (y < border->line.a.y)
4647 			orig_y = border->line.a.y;
4648 		else if (y > border->line.b.y)
4649 			orig_y = border->line.b.y;
4650 		else
4651 			orig_y = y;
4652 		orig_x = border->line.a.x;
4653 	}
4654 
4655 
4656 	dx = fabs(orig_x - x);
4657 	dy = fabs(orig_y - y);
4658 	return dx*dx + dy*dy;
4659 }
4660 
4661 static void
warp_to_behind_border(struct border * border,wl_fixed_t * sx,wl_fixed_t * sy)4662 warp_to_behind_border(struct border *border, wl_fixed_t *sx, wl_fixed_t *sy)
4663 {
4664 	switch (border->blocking_dir) {
4665 	case MOTION_DIRECTION_POSITIVE_X:
4666 	case MOTION_DIRECTION_NEGATIVE_X:
4667 		if (border->blocking_dir == MOTION_DIRECTION_POSITIVE_X)
4668 			*sx = wl_fixed_from_double(border->line.a.x) - 1;
4669 		else
4670 			*sx = wl_fixed_from_double(border->line.a.x) + 1;
4671 		if (*sy < wl_fixed_from_double(border->line.a.y))
4672 			*sy = wl_fixed_from_double(border->line.a.y) + 1;
4673 		else if (*sy > wl_fixed_from_double(border->line.b.y))
4674 			*sy = wl_fixed_from_double(border->line.b.y) - 1;
4675 		break;
4676 	case MOTION_DIRECTION_POSITIVE_Y:
4677 	case MOTION_DIRECTION_NEGATIVE_Y:
4678 		if (border->blocking_dir == MOTION_DIRECTION_POSITIVE_Y)
4679 			*sy = wl_fixed_from_double(border->line.a.y) - 1;
4680 		else
4681 			*sy = wl_fixed_from_double(border->line.a.y) + 1;
4682 		if (*sx < wl_fixed_from_double(border->line.a.x))
4683 			*sx = wl_fixed_from_double(border->line.a.x) + 1;
4684 		else if (*sx > wl_fixed_from_double(border->line.b.x))
4685 			*sx = wl_fixed_from_double(border->line.b.x) - 1;
4686 		break;
4687 	}
4688 }
4689 
4690 static void
maybe_warp_confined_pointer(struct weston_pointer_constraint * constraint)4691 maybe_warp_confined_pointer(struct weston_pointer_constraint *constraint)
4692 {
4693 	wl_fixed_t x;
4694 	wl_fixed_t y;
4695 	wl_fixed_t sx;
4696 	wl_fixed_t sy;
4697 
4698 	weston_view_from_global_fixed(constraint->view,
4699 				      constraint->pointer->x,
4700 				      constraint->pointer->y,
4701 				      &sx,
4702 				      &sy);
4703 
4704 	if (!is_within_constraint_region(constraint, sx, sy)) {
4705 		double xf = wl_fixed_to_double(sx);
4706 		double yf = wl_fixed_to_double(sy);
4707 		pixman_region32_t confine_region;
4708 		struct wl_array borders;
4709 		struct border *border;
4710 		double closest_distance_2 = DBL_MAX;
4711 		struct border *closest_border = NULL;
4712 
4713 		wl_array_init(&borders);
4714 
4715 		pixman_region32_init(&confine_region);
4716 		pixman_region32_intersect(&confine_region,
4717 					  &constraint->view->surface->input,
4718 					  &constraint->region);
4719 		region_to_outline(&confine_region, &borders);
4720 		pixman_region32_fini(&confine_region);
4721 
4722 		wl_array_for_each(border, &borders) {
4723 			double distance_2;
4724 
4725 			distance_2 = point_to_border_distance_2(border, xf, yf);
4726 			if (distance_2 < closest_distance_2) {
4727 				closest_border = border;
4728 				closest_distance_2 = distance_2;
4729 			}
4730 		}
4731 		assert(closest_border);
4732 
4733 		warp_to_behind_border(closest_border, &sx, &sy);
4734 
4735 		wl_array_release(&borders);
4736 
4737 		weston_view_to_global_fixed(constraint->view, sx, sy, &x, &y);
4738 		weston_pointer_move_to(constraint->pointer, x, y);
4739 	}
4740 }
4741 
4742 static void
confined_pointer_grab_pointer_motion(struct weston_pointer_grab * grab,const struct timespec * time,struct weston_pointer_motion_event * event)4743 confined_pointer_grab_pointer_motion(struct weston_pointer_grab *grab,
4744 				     const struct timespec *time,
4745 				     struct weston_pointer_motion_event *event)
4746 {
4747 	struct weston_pointer_constraint *constraint =
4748 		container_of(grab, struct weston_pointer_constraint, grab);
4749 	struct weston_pointer *pointer = grab->pointer;
4750 	struct weston_surface *surface;
4751 	wl_fixed_t x, y;
4752 	wl_fixed_t old_sx = pointer->sx;
4753 	wl_fixed_t old_sy = pointer->sy;
4754 	pixman_region32_t confine_region;
4755 
4756 	assert(pointer->focus);
4757 	assert(pointer->focus->surface == constraint->surface);
4758 
4759 	surface = pointer->focus->surface;
4760 
4761 	pixman_region32_init(&confine_region);
4762 	pixman_region32_intersect(&confine_region,
4763 				  &surface->input,
4764 				  &constraint->region);
4765 	weston_pointer_clamp_event_to_region(pointer, event,
4766 					     &confine_region, &x, &y);
4767 	weston_pointer_move_to(pointer, x, y);
4768 	pixman_region32_fini(&confine_region);
4769 
4770 	weston_view_from_global_fixed(pointer->focus, x, y,
4771 				      &pointer->sx, &pointer->sy);
4772 
4773 	if (old_sx != pointer->sx || old_sy != pointer->sy) {
4774 		pointer_send_motion(pointer, time,
4775 				    pointer->sx, pointer->sy);
4776 	}
4777 
4778 	pointer_send_relative_motion(pointer, time, event);
4779 }
4780 
4781 static void
confined_pointer_grab_pointer_button(struct weston_pointer_grab * grab,const struct timespec * time,uint32_t button,uint32_t state_w)4782 confined_pointer_grab_pointer_button(struct weston_pointer_grab *grab,
4783 				     const struct timespec *time,
4784 				     uint32_t button,
4785 				     uint32_t state_w)
4786 {
4787 	weston_pointer_send_button(grab->pointer, time, button, state_w);
4788 }
4789 
4790 static void
confined_pointer_grab_pointer_axis(struct weston_pointer_grab * grab,const struct timespec * time,struct weston_pointer_axis_event * event)4791 confined_pointer_grab_pointer_axis(struct weston_pointer_grab *grab,
4792 				   const struct timespec *time,
4793 				   struct weston_pointer_axis_event *event)
4794 {
4795 	weston_pointer_send_axis(grab->pointer, time, event);
4796 }
4797 
4798 static void
confined_pointer_grab_pointer_axis_source(struct weston_pointer_grab * grab,uint32_t source)4799 confined_pointer_grab_pointer_axis_source(struct weston_pointer_grab *grab,
4800 					  uint32_t source)
4801 {
4802 	weston_pointer_send_axis_source(grab->pointer, source);
4803 }
4804 
4805 static void
confined_pointer_grab_pointer_frame(struct weston_pointer_grab * grab)4806 confined_pointer_grab_pointer_frame(struct weston_pointer_grab *grab)
4807 {
4808 	weston_pointer_send_frame(grab->pointer);
4809 }
4810 
4811 static void
confined_pointer_grab_pointer_cancel(struct weston_pointer_grab * grab)4812 confined_pointer_grab_pointer_cancel(struct weston_pointer_grab *grab)
4813 {
4814 	struct weston_pointer_constraint *constraint =
4815 		container_of(grab, struct weston_pointer_constraint, grab);
4816 
4817 	disable_pointer_constraint(constraint);
4818 }
4819 
4820 static const struct weston_pointer_grab_interface
4821 				confined_pointer_grab_interface = {
4822 	confined_pointer_grab_pointer_focus,
4823 	confined_pointer_grab_pointer_motion,
4824 	confined_pointer_grab_pointer_button,
4825 	confined_pointer_grab_pointer_axis,
4826 	confined_pointer_grab_pointer_axis_source,
4827 	confined_pointer_grab_pointer_frame,
4828 	confined_pointer_grab_pointer_cancel,
4829 };
4830 
4831 static void
confined_pointer_destroy(struct wl_client * client,struct wl_resource * resource)4832 confined_pointer_destroy(struct wl_client *client,
4833 			 struct wl_resource *resource)
4834 {
4835 	wl_resource_destroy(resource);
4836 }
4837 
4838 static void
confined_pointer_set_region(struct wl_client * client,struct wl_resource * resource,struct wl_resource * region_resource)4839 confined_pointer_set_region(struct wl_client *client,
4840 			    struct wl_resource *resource,
4841 			    struct wl_resource *region_resource)
4842 {
4843 	struct weston_pointer_constraint *constraint =
4844 		wl_resource_get_user_data(resource);
4845 	struct weston_region *region = region_resource ?
4846 		wl_resource_get_user_data(region_resource) : NULL;
4847 
4848 	if (!constraint)
4849 		return;
4850 
4851 	if (region) {
4852 		pixman_region32_copy(&constraint->region_pending,
4853 				     &region->region);
4854 	} else {
4855 		pixman_region32_fini(&constraint->region_pending);
4856 		region_init_infinite(&constraint->region_pending);
4857 	}
4858 	constraint->region_is_pending = true;
4859 }
4860 
4861 static const struct zwp_confined_pointer_v1_interface confined_pointer_interface = {
4862 	confined_pointer_destroy,
4863 	confined_pointer_set_region,
4864 };
4865 
4866 static void
pointer_constraints_confine_pointer(struct wl_client * client,struct wl_resource * resource,uint32_t id,struct wl_resource * surface_resource,struct wl_resource * pointer_resource,struct wl_resource * region_resource,uint32_t lifetime)4867 pointer_constraints_confine_pointer(struct wl_client *client,
4868 				    struct wl_resource *resource,
4869 				    uint32_t id,
4870 				    struct wl_resource *surface_resource,
4871 				    struct wl_resource *pointer_resource,
4872 				    struct wl_resource *region_resource,
4873 				    uint32_t lifetime)
4874 {
4875 	struct weston_surface *surface =
4876 		wl_resource_get_user_data(surface_resource);
4877 	struct weston_pointer *pointer = wl_resource_get_user_data(pointer_resource);
4878 	struct weston_region *region = region_resource ?
4879 		wl_resource_get_user_data(region_resource) : NULL;
4880 
4881 	init_pointer_constraint(resource, id, surface, pointer, region, lifetime,
4882 				&zwp_confined_pointer_v1_interface,
4883 				&confined_pointer_interface,
4884 				&confined_pointer_grab_interface);
4885 }
4886 
4887 static const struct zwp_pointer_constraints_v1_interface pointer_constraints_interface = {
4888 	pointer_constraints_destroy,
4889 	pointer_constraints_lock_pointer,
4890 	pointer_constraints_confine_pointer,
4891 };
4892 
4893 static void
bind_pointer_constraints(struct wl_client * client,void * data,uint32_t version,uint32_t id)4894 bind_pointer_constraints(struct wl_client *client, void *data,
4895 			 uint32_t version, uint32_t id)
4896 {
4897 	struct wl_resource *resource;
4898 
4899 	resource = wl_resource_create(client,
4900 				      &zwp_pointer_constraints_v1_interface,
4901 				      1, id);
4902 
4903 	wl_resource_set_implementation(resource, &pointer_constraints_interface,
4904 				       NULL, NULL);
4905 }
4906 
4907 static void
input_timestamps_destroy(struct wl_client * client,struct wl_resource * resource)4908 input_timestamps_destroy(struct wl_client *client,
4909 			 struct wl_resource *resource)
4910 {
4911 	wl_resource_destroy(resource);
4912 }
4913 
4914 static const struct zwp_input_timestamps_v1_interface
4915 				input_timestamps_interface = {
4916 	input_timestamps_destroy,
4917 };
4918 
4919 static void
input_timestamps_manager_destroy(struct wl_client * client,struct wl_resource * resource)4920 input_timestamps_manager_destroy(struct wl_client *client,
4921 				 struct wl_resource *resource)
4922 {
4923 	wl_resource_destroy(resource);
4924 }
4925 
4926 static void
input_timestamps_manager_get_keyboard_timestamps(struct wl_client * client,struct wl_resource * resource,uint32_t id,struct wl_resource * keyboard_resource)4927 input_timestamps_manager_get_keyboard_timestamps(struct wl_client *client,
4928 						 struct wl_resource *resource,
4929 						 uint32_t id,
4930 						 struct wl_resource *keyboard_resource)
4931 {
4932 	struct weston_keyboard *keyboard =
4933 		wl_resource_get_user_data(keyboard_resource);
4934 	struct wl_resource *input_ts;
4935 
4936 	input_ts = wl_resource_create(client,
4937 				      &zwp_input_timestamps_v1_interface,
4938 				      1, id);
4939 	if (!input_ts) {
4940 		wl_client_post_no_memory(client);
4941 		return;
4942 	}
4943 
4944 	if (keyboard) {
4945 		wl_list_insert(&keyboard->timestamps_list,
4946 			       wl_resource_get_link(input_ts));
4947 	} else {
4948 		wl_list_init(wl_resource_get_link(input_ts));
4949 	}
4950 
4951 	wl_resource_set_implementation(input_ts,
4952 				       &input_timestamps_interface,
4953 				       keyboard_resource,
4954 				       unbind_resource);
4955 }
4956 
4957 static void
input_timestamps_manager_get_pointer_timestamps(struct wl_client * client,struct wl_resource * resource,uint32_t id,struct wl_resource * pointer_resource)4958 input_timestamps_manager_get_pointer_timestamps(struct wl_client *client,
4959 						struct wl_resource *resource,
4960 						uint32_t id,
4961 						struct wl_resource *pointer_resource)
4962 {
4963 	struct weston_pointer *pointer =
4964 		wl_resource_get_user_data(pointer_resource);
4965 	struct wl_resource *input_ts;
4966 
4967 	input_ts = wl_resource_create(client,
4968 				      &zwp_input_timestamps_v1_interface,
4969 				      1, id);
4970 	if (!input_ts) {
4971 		wl_client_post_no_memory(client);
4972 		return;
4973 	}
4974 
4975 	if (pointer) {
4976 		wl_list_insert(&pointer->timestamps_list,
4977 			       wl_resource_get_link(input_ts));
4978 	} else {
4979 		wl_list_init(wl_resource_get_link(input_ts));
4980 	}
4981 
4982 	wl_resource_set_implementation(input_ts,
4983 				       &input_timestamps_interface,
4984 				       pointer_resource,
4985 				       unbind_resource);
4986 }
4987 
4988 static void
input_timestamps_manager_get_touch_timestamps(struct wl_client * client,struct wl_resource * resource,uint32_t id,struct wl_resource * touch_resource)4989 input_timestamps_manager_get_touch_timestamps(struct wl_client *client,
4990 					      struct wl_resource *resource,
4991 					      uint32_t id,
4992 					      struct wl_resource *touch_resource)
4993 {
4994 	struct weston_touch *touch = wl_resource_get_user_data(touch_resource);
4995 	struct wl_resource *input_ts;
4996 
4997 	input_ts = wl_resource_create(client,
4998 				      &zwp_input_timestamps_v1_interface,
4999 				      1, id);
5000 	if (!input_ts) {
5001 		wl_client_post_no_memory(client);
5002 		return;
5003 	}
5004 
5005 	if (touch) {
5006 		wl_list_insert(&touch->timestamps_list,
5007 			       wl_resource_get_link(input_ts));
5008 	} else {
5009 		wl_list_init(wl_resource_get_link(input_ts));
5010 	}
5011 
5012 	wl_resource_set_implementation(input_ts,
5013 				       &input_timestamps_interface,
5014 				       touch_resource,
5015 				       unbind_resource);
5016 }
5017 
5018 static const struct zwp_input_timestamps_manager_v1_interface
5019 				input_timestamps_manager_interface = {
5020 	input_timestamps_manager_destroy,
5021 	input_timestamps_manager_get_keyboard_timestamps,
5022 	input_timestamps_manager_get_pointer_timestamps,
5023 	input_timestamps_manager_get_touch_timestamps,
5024 };
5025 
5026 static void
bind_input_timestamps_manager(struct wl_client * client,void * data,uint32_t version,uint32_t id)5027 bind_input_timestamps_manager(struct wl_client *client, void *data,
5028 			      uint32_t version, uint32_t id)
5029 {
5030 	struct wl_resource *resource =
5031 		wl_resource_create(client,
5032 				   &zwp_input_timestamps_manager_v1_interface,
5033 				   1, id);
5034 
5035 	if (resource == NULL) {
5036 		wl_client_post_no_memory(client);
5037 		return;
5038 	}
5039 
5040 	wl_resource_set_implementation(resource,
5041 				       &input_timestamps_manager_interface,
5042 				       NULL, NULL);
5043 }
5044 
5045 int
weston_input_init(struct weston_compositor * compositor)5046 weston_input_init(struct weston_compositor *compositor)
5047 {
5048 	if (!wl_global_create(compositor->wl_display,
5049 			      &zwp_relative_pointer_manager_v1_interface, 1,
5050 			      compositor, bind_relative_pointer_manager))
5051 		return -1;
5052 
5053 	if (!wl_global_create(compositor->wl_display,
5054 			      &zwp_pointer_constraints_v1_interface, 1,
5055 			      NULL, bind_pointer_constraints))
5056 		return -1;
5057 
5058 	if (!wl_global_create(compositor->wl_display,
5059 			      &zwp_input_timestamps_manager_v1_interface, 1,
5060 			      NULL, bind_input_timestamps_manager))
5061 		return -1;
5062 
5063 	return 0;
5064 }
5065