1 #define _POSIX_C_SOURCE 200809L
2
3 #include <assert.h>
4 #include <stdint.h>
5 #include <stdlib.h>
6 #include <string.h>
7 #include <time.h>
8 #include <unistd.h>
9
10 #include <wayland-client.h>
11
12 #include <wlr/interfaces/wlr_input_device.h>
13 #include <wlr/interfaces/wlr_keyboard.h>
14 #include <wlr/interfaces/wlr_output.h>
15 #include <wlr/interfaces/wlr_pointer.h>
16 #include <wlr/interfaces/wlr_touch.h>
17 #include <wlr/util/log.h>
18
19 #include "pointer-gestures-unstable-v1-client-protocol.h"
20 #include "relative-pointer-unstable-v1-client-protocol.h"
21 #include "backend/wayland.h"
22 #include "util/signal.h"
23 #include "util/time.h"
24
output_get_pointer(struct wlr_wl_output * output)25 static struct wlr_wl_pointer *output_get_pointer(struct wlr_wl_output *output) {
26 struct wlr_input_device *wlr_dev;
27 wl_list_for_each(wlr_dev, &output->backend->devices, link) {
28 if (wlr_dev->type != WLR_INPUT_DEVICE_POINTER) {
29 continue;
30 }
31 struct wlr_wl_pointer *pointer = pointer_get_wl(wlr_dev->pointer);
32 if (pointer->output == output) {
33 return pointer;
34 }
35 }
36
37 return NULL;
38 }
39
pointer_handle_enter(void * data,struct wl_pointer * wl_pointer,uint32_t serial,struct wl_surface * surface,wl_fixed_t sx,wl_fixed_t sy)40 static void pointer_handle_enter(void *data, struct wl_pointer *wl_pointer,
41 uint32_t serial, struct wl_surface *surface, wl_fixed_t sx,
42 wl_fixed_t sy) {
43 struct wlr_wl_backend *backend = data;
44 if (surface == NULL) {
45 return;
46 }
47
48 struct wlr_wl_output *output = wl_surface_get_user_data(surface);
49 assert(output);
50 struct wlr_wl_pointer *pointer = output_get_pointer(output);
51 assert(!backend->current_pointer || backend->current_pointer == pointer);
52
53 output->enter_serial = serial;
54 backend->current_pointer = pointer;
55 update_wl_output_cursor(output);
56 }
57
pointer_handle_leave(void * data,struct wl_pointer * wl_pointer,uint32_t serial,struct wl_surface * surface)58 static void pointer_handle_leave(void *data, struct wl_pointer *wl_pointer,
59 uint32_t serial, struct wl_surface *surface) {
60 struct wlr_wl_backend *backend = data;
61 if (surface == NULL) {
62 return;
63 }
64
65 struct wlr_wl_output *output = wl_surface_get_user_data(surface);
66 assert(output);
67 output->enter_serial = 0;
68
69 if (backend->current_pointer == NULL ||
70 backend->current_pointer->output != output) {
71 return;
72 }
73
74 backend->current_pointer = NULL;
75 }
76
pointer_handle_motion(void * data,struct wl_pointer * wl_pointer,uint32_t time,wl_fixed_t sx,wl_fixed_t sy)77 static void pointer_handle_motion(void *data, struct wl_pointer *wl_pointer,
78 uint32_t time, wl_fixed_t sx, wl_fixed_t sy) {
79 struct wlr_wl_backend *backend = data;
80 struct wlr_wl_pointer *pointer = backend->current_pointer;
81 if (pointer == NULL) {
82 return;
83 }
84
85 struct wlr_output *wlr_output = &pointer->output->wlr_output;
86 struct wlr_event_pointer_motion_absolute event = {
87 .device = &pointer->input_device->wlr_input_device,
88 .time_msec = time,
89 .x = wl_fixed_to_double(sx) / wlr_output->width,
90 .y = wl_fixed_to_double(sy) / wlr_output->height,
91 };
92 wlr_signal_emit_safe(&pointer->wlr_pointer.events.motion_absolute, &event);
93 }
94
pointer_handle_button(void * data,struct wl_pointer * wl_pointer,uint32_t serial,uint32_t time,uint32_t button,uint32_t state)95 static void pointer_handle_button(void *data, struct wl_pointer *wl_pointer,
96 uint32_t serial, uint32_t time, uint32_t button, uint32_t state) {
97 struct wlr_wl_backend *backend = data;
98 struct wlr_wl_pointer *pointer = backend->current_pointer;
99 if (pointer == NULL) {
100 return;
101 }
102
103 struct wlr_event_pointer_button event = {
104 .device = &pointer->input_device->wlr_input_device,
105 .button = button,
106 .state = state,
107 .time_msec = time,
108 };
109 wlr_signal_emit_safe(&pointer->wlr_pointer.events.button, &event);
110 }
111
pointer_handle_axis(void * data,struct wl_pointer * wl_pointer,uint32_t time,uint32_t axis,wl_fixed_t value)112 static void pointer_handle_axis(void *data, struct wl_pointer *wl_pointer,
113 uint32_t time, uint32_t axis, wl_fixed_t value) {
114 struct wlr_wl_backend *backend = data;
115 struct wlr_wl_pointer *pointer = backend->current_pointer;
116 if (pointer == NULL) {
117 return;
118 }
119
120 struct wlr_event_pointer_axis event = {
121 .device = &pointer->input_device->wlr_input_device,
122 .delta = wl_fixed_to_double(value),
123 .delta_discrete = pointer->axis_discrete,
124 .orientation = axis,
125 .time_msec = time,
126 .source = pointer->axis_source,
127 };
128 wlr_signal_emit_safe(&pointer->wlr_pointer.events.axis, &event);
129
130 pointer->axis_discrete = 0;
131 }
132
pointer_handle_frame(void * data,struct wl_pointer * wl_pointer)133 static void pointer_handle_frame(void *data, struct wl_pointer *wl_pointer) {
134 struct wlr_wl_backend *backend = data;
135 struct wlr_wl_pointer *pointer = backend->current_pointer;
136 if (pointer == NULL) {
137 return;
138 }
139
140 wlr_signal_emit_safe(&pointer->wlr_pointer.events.frame,
141 &pointer->wlr_pointer);
142 }
143
pointer_handle_axis_source(void * data,struct wl_pointer * wl_pointer,uint32_t axis_source)144 static void pointer_handle_axis_source(void *data,
145 struct wl_pointer *wl_pointer, uint32_t axis_source) {
146 struct wlr_wl_backend *backend = data;
147 struct wlr_wl_pointer *pointer = backend->current_pointer;
148 if (pointer == NULL) {
149 return;
150 }
151
152 pointer->axis_source = axis_source;
153 }
154
pointer_handle_axis_stop(void * data,struct wl_pointer * wl_pointer,uint32_t time,uint32_t axis)155 static void pointer_handle_axis_stop(void *data, struct wl_pointer *wl_pointer,
156 uint32_t time, uint32_t axis) {
157 struct wlr_wl_backend *backend = data;
158 struct wlr_wl_pointer *pointer = backend->current_pointer;
159 if (pointer == NULL) {
160 return;
161 }
162
163 struct wlr_event_pointer_axis event = {
164 .device = &pointer->input_device->wlr_input_device,
165 .delta = 0,
166 .delta_discrete = 0,
167 .orientation = axis,
168 .time_msec = time,
169 .source = pointer->axis_source,
170 };
171 wlr_signal_emit_safe(&pointer->wlr_pointer.events.axis, &event);
172 }
173
pointer_handle_axis_discrete(void * data,struct wl_pointer * wl_pointer,uint32_t axis,int32_t discrete)174 static void pointer_handle_axis_discrete(void *data,
175 struct wl_pointer *wl_pointer, uint32_t axis, int32_t discrete) {
176 struct wlr_wl_backend *backend = data;
177 struct wlr_wl_pointer *pointer = backend->current_pointer;
178 if (pointer == NULL) {
179 return;
180 }
181
182 pointer->axis_discrete = discrete;
183 }
184
185 static const struct wl_pointer_listener pointer_listener = {
186 .enter = pointer_handle_enter,
187 .leave = pointer_handle_leave,
188 .motion = pointer_handle_motion,
189 .button = pointer_handle_button,
190 .axis = pointer_handle_axis,
191 .frame = pointer_handle_frame,
192 .axis_source = pointer_handle_axis_source,
193 .axis_stop = pointer_handle_axis_stop,
194 .axis_discrete = pointer_handle_axis_discrete,
195 };
196
keyboard_handle_keymap(void * data,struct wl_keyboard * wl_keyboard,uint32_t format,int32_t fd,uint32_t size)197 static void keyboard_handle_keymap(void *data, struct wl_keyboard *wl_keyboard,
198 uint32_t format, int32_t fd, uint32_t size) {
199 close(fd);
200 }
201
keyboard_handle_enter(void * data,struct wl_keyboard * wl_keyboard,uint32_t serial,struct wl_surface * surface,struct wl_array * keys)202 static void keyboard_handle_enter(void *data, struct wl_keyboard *wl_keyboard,
203 uint32_t serial, struct wl_surface *surface, struct wl_array *keys) {
204 struct wlr_input_device *dev = data;
205
206 uint32_t time = get_current_time_msec();
207
208 uint32_t *keycode_ptr;
209 wl_array_for_each(keycode_ptr, keys) {
210 struct wlr_event_keyboard_key event = {
211 .keycode = *keycode_ptr,
212 .state = WLR_KEY_PRESSED,
213 .time_msec = time,
214 .update_state = false,
215 };
216 wlr_keyboard_notify_key(dev->keyboard, &event);
217 }
218 }
219
keyboard_handle_leave(void * data,struct wl_keyboard * wl_keyboard,uint32_t serial,struct wl_surface * surface)220 static void keyboard_handle_leave(void *data, struct wl_keyboard *wl_keyboard,
221 uint32_t serial, struct wl_surface *surface) {
222 struct wlr_input_device *dev = data;
223
224 uint32_t time = get_current_time_msec();
225
226 uint32_t pressed[dev->keyboard->num_keycodes + 1];
227 memcpy(pressed, dev->keyboard->keycodes,
228 dev->keyboard->num_keycodes * sizeof(uint32_t));
229
230 for (size_t i = 0; i < sizeof(pressed)/sizeof(pressed[0]); ++i) {
231 uint32_t keycode = pressed[i];
232
233 struct wlr_event_keyboard_key event = {
234 .keycode = keycode,
235 .state = WLR_KEY_RELEASED,
236 .time_msec = time,
237 .update_state = false,
238 };
239 wlr_keyboard_notify_key(dev->keyboard, &event);
240 }
241 }
242
keyboard_handle_key(void * data,struct wl_keyboard * wl_keyboard,uint32_t serial,uint32_t time,uint32_t key,uint32_t state)243 static void keyboard_handle_key(void *data, struct wl_keyboard *wl_keyboard,
244 uint32_t serial, uint32_t time, uint32_t key, uint32_t state) {
245 struct wlr_input_device *dev = data;
246 assert(dev && dev->keyboard);
247
248 struct wlr_event_keyboard_key wlr_event = {
249 .keycode = key,
250 .state = state,
251 .time_msec = time,
252 .update_state = false,
253 };
254 wlr_keyboard_notify_key(dev->keyboard, &wlr_event);
255 }
256
keyboard_handle_modifiers(void * data,struct wl_keyboard * wl_keyboard,uint32_t serial,uint32_t mods_depressed,uint32_t mods_latched,uint32_t mods_locked,uint32_t group)257 static void keyboard_handle_modifiers(void *data, struct wl_keyboard *wl_keyboard,
258 uint32_t serial, uint32_t mods_depressed, uint32_t mods_latched,
259 uint32_t mods_locked, uint32_t group) {
260 struct wlr_input_device *dev = data;
261 assert(dev && dev->keyboard);
262 wlr_keyboard_notify_modifiers(dev->keyboard, mods_depressed, mods_latched,
263 mods_locked, group);
264 }
265
keyboard_handle_repeat_info(void * data,struct wl_keyboard * wl_keyboard,int32_t rate,int32_t delay)266 static void keyboard_handle_repeat_info(void *data,
267 struct wl_keyboard *wl_keyboard, int32_t rate, int32_t delay) {
268 // This space is intentionally left blank
269 }
270
271 static struct wl_keyboard_listener keyboard_listener = {
272 .keymap = keyboard_handle_keymap,
273 .enter = keyboard_handle_enter,
274 .leave = keyboard_handle_leave,
275 .key = keyboard_handle_key,
276 .modifiers = keyboard_handle_modifiers,
277 .repeat_info = keyboard_handle_repeat_info
278 };
279
touch_coordinates_to_absolute(struct wlr_wl_input_device * device,wl_fixed_t x,wl_fixed_t y,double * sx,double * sy)280 static void touch_coordinates_to_absolute(struct wlr_wl_input_device *device,
281 wl_fixed_t x, wl_fixed_t y, double *sx, double *sy) {
282 // TODO: each output needs its own touch
283 struct wlr_wl_output *output, *tmp;
284 wl_list_for_each_safe(output, tmp, &device->backend->outputs, link) {
285 *sx = wl_fixed_to_double(x) / output->wlr_output.width;
286 *sy = wl_fixed_to_double(y) / output->wlr_output.height;
287 return; // Choose the first output in the list
288 }
289
290 *sx = *sy = 0;
291 }
292
touch_handle_down(void * data,struct wl_touch * wl_touch,uint32_t serial,uint32_t time,struct wl_surface * surface,int32_t id,wl_fixed_t x,wl_fixed_t y)293 static void touch_handle_down(void *data, struct wl_touch *wl_touch,
294 uint32_t serial, uint32_t time, struct wl_surface *surface,
295 int32_t id, wl_fixed_t x, wl_fixed_t y) {
296 struct wlr_wl_input_device *device = data;
297 assert(device && device->wlr_input_device.touch);
298
299 double sx, sy;
300 touch_coordinates_to_absolute(device, x, y, &sx, &sy);
301 struct wlr_event_touch_down event = {
302 .device = &device->wlr_input_device,
303 .time_msec = time,
304 .touch_id = id,
305 .x = sx,
306 .y = sy
307 };
308 wlr_signal_emit_safe(&device->wlr_input_device.touch->events.down, &event);
309 }
310
touch_handle_up(void * data,struct wl_touch * wl_touch,uint32_t serial,uint32_t time,int32_t id)311 static void touch_handle_up(void *data, struct wl_touch *wl_touch,
312 uint32_t serial, uint32_t time, int32_t id) {
313 struct wlr_wl_input_device *device = data;
314 assert(device && device->wlr_input_device.touch);
315
316 struct wlr_event_touch_up event = {
317 .device = &device->wlr_input_device,
318 .time_msec = time,
319 .touch_id = id,
320 };
321 wlr_signal_emit_safe(&device->wlr_input_device.touch->events.up, &event);
322 }
323
touch_handle_motion(void * data,struct wl_touch * wl_touch,uint32_t time,int32_t id,wl_fixed_t x,wl_fixed_t y)324 static void touch_handle_motion(void *data, struct wl_touch *wl_touch,
325 uint32_t time, int32_t id, wl_fixed_t x, wl_fixed_t y) {
326 struct wlr_wl_input_device *device = data;
327 assert(device && device->wlr_input_device.touch);
328
329 double sx, sy;
330 touch_coordinates_to_absolute(device, x, y, &sx, &sy);
331 struct wlr_event_touch_motion event = {
332 .device = &device->wlr_input_device,
333 .time_msec = time,
334 .touch_id = id,
335 .x = sx,
336 .y = sy
337 };
338 wlr_signal_emit_safe(&device->wlr_input_device.touch->events.motion, &event);
339 }
340
touch_handle_frame(void * data,struct wl_touch * wl_touch)341 static void touch_handle_frame(void *data, struct wl_touch *wl_touch) {
342 // no-op
343 }
344
touch_handle_cancel(void * data,struct wl_touch * wl_touch)345 static void touch_handle_cancel(void *data, struct wl_touch *wl_touch) {
346 // no-op
347 }
348
touch_handle_shape(void * data,struct wl_touch * wl_touch,int32_t id,wl_fixed_t major,wl_fixed_t minor)349 static void touch_handle_shape(void *data, struct wl_touch *wl_touch,
350 int32_t id, wl_fixed_t major, wl_fixed_t minor) {
351 // no-op
352 }
353
touch_handle_orientation(void * data,struct wl_touch * wl_touch,int32_t id,wl_fixed_t orientation)354 static void touch_handle_orientation(void *data, struct wl_touch *wl_touch,
355 int32_t id, wl_fixed_t orientation) {
356 // no-op
357 }
358
359 static struct wl_touch_listener touch_listener = {
360 .down = touch_handle_down,
361 .up = touch_handle_up,
362 .motion = touch_handle_motion,
363 .frame = touch_handle_frame,
364 .cancel = touch_handle_cancel,
365 .shape = touch_handle_shape,
366 .orientation = touch_handle_orientation,
367 };
368
get_wl_input_device_from_input_device(struct wlr_input_device * wlr_dev)369 static struct wlr_wl_input_device *get_wl_input_device_from_input_device(
370 struct wlr_input_device *wlr_dev) {
371 assert(wlr_input_device_is_wl(wlr_dev));
372 return (struct wlr_wl_input_device *)wlr_dev;
373 }
374
create_wl_seat(struct wl_seat * wl_seat,struct wlr_wl_backend * wl)375 bool create_wl_seat(struct wl_seat *wl_seat, struct wlr_wl_backend *wl) {
376 assert(!wl->seat); // only one seat supported at the moment
377 struct wlr_wl_seat *seat = calloc(1, sizeof(struct wlr_wl_seat));
378 if (!seat) {
379 wlr_log_errno(WLR_ERROR, "Allocation failed");
380 return false;
381 }
382 seat->wl_seat = wl_seat;
383 wl->seat = seat;
384 wl_seat_add_listener(wl_seat, &seat_listener, wl);
385 return true;
386 }
387
destroy_wl_seats(struct wlr_wl_backend * wl)388 void destroy_wl_seats(struct wlr_wl_backend *wl) {
389 struct wlr_wl_seat *seat = wl->seat;
390 if (!seat) {
391 return;
392 }
393
394 if (seat->touch) {
395 wl_touch_destroy(seat->touch);
396 }
397 if (seat->pointer) {
398 wl_pointer_destroy(seat->pointer);
399 }
400 if (seat->keyboard && !wl->started) {
401 // early termination will not be handled by input_device_destroy
402 wl_keyboard_destroy(seat->keyboard);
403 }
404 free(seat->name);
405 if (seat->wl_seat) {
406 wl_seat_destroy(seat->wl_seat);
407 }
408 free(seat);
409 }
410
backend_get_seat(struct wlr_wl_backend * backend,struct wl_seat * wl_seat)411 static struct wlr_wl_seat *backend_get_seat(struct wlr_wl_backend *backend, struct wl_seat *wl_seat) {
412 assert(backend->seat && backend->seat->wl_seat == wl_seat);
413 return backend->seat;
414 }
415
input_device_get_seat(struct wlr_input_device * wlr_dev)416 static struct wlr_wl_seat *input_device_get_seat(struct wlr_input_device *wlr_dev) {
417 struct wlr_wl_input_device *dev =
418 get_wl_input_device_from_input_device(wlr_dev);
419 assert(dev->backend->seat);
420 return dev->backend->seat;
421 }
422
input_device_destroy(struct wlr_input_device * wlr_dev)423 static void input_device_destroy(struct wlr_input_device *wlr_dev) {
424 struct wlr_wl_input_device *dev =
425 get_wl_input_device_from_input_device(wlr_dev);
426 if (dev->wlr_input_device.type == WLR_INPUT_DEVICE_KEYBOARD) {
427 struct wlr_wl_seat *seat = input_device_get_seat(wlr_dev);
428 wl_keyboard_release(seat->keyboard);
429 seat->keyboard = NULL;
430 }
431 wl_list_remove(&dev->wlr_input_device.link);
432 free(dev);
433 }
434
435 static struct wlr_input_device_impl input_device_impl = {
436 .destroy = input_device_destroy,
437 };
438
wlr_input_device_is_wl(struct wlr_input_device * dev)439 bool wlr_input_device_is_wl(struct wlr_input_device *dev) {
440 return dev->impl == &input_device_impl;
441 }
442
create_wl_input_device(struct wlr_wl_backend * backend,enum wlr_input_device_type type)443 struct wlr_wl_input_device *create_wl_input_device(
444 struct wlr_wl_backend *backend, enum wlr_input_device_type type) {
445 struct wlr_wl_input_device *dev =
446 calloc(1, sizeof(struct wlr_wl_input_device));
447 if (dev == NULL) {
448 wlr_log_errno(WLR_ERROR, "Allocation failed");
449 return NULL;
450 }
451 dev->backend = backend;
452
453 struct wlr_input_device *wlr_dev = &dev->wlr_input_device;
454
455 unsigned int vendor = 0, product = 0;
456 const char *name = "wayland";
457 wlr_input_device_init(wlr_dev, type, &input_device_impl, name, vendor,
458 product);
459 wl_list_insert(&backend->devices, &wlr_dev->link);
460 return dev;
461 }
462
463 static struct wlr_pointer_impl pointer_impl;
464
pointer_get_wl(struct wlr_pointer * wlr_pointer)465 struct wlr_wl_pointer *pointer_get_wl(struct wlr_pointer *wlr_pointer) {
466 assert(wlr_pointer->impl == &pointer_impl);
467 return (struct wlr_wl_pointer *)wlr_pointer;
468 }
469
pointer_destroy(struct wlr_pointer * wlr_pointer)470 static void pointer_destroy(struct wlr_pointer *wlr_pointer) {
471 struct wlr_wl_pointer *pointer = pointer_get_wl(wlr_pointer);
472
473 if (pointer->output->backend->current_pointer == pointer) {
474 pointer->output->backend->current_pointer = NULL;
475 }
476
477 wl_list_remove(&pointer->output_destroy.link);
478 free(pointer);
479 }
480
481 static struct wlr_pointer_impl pointer_impl = {
482 .destroy = pointer_destroy,
483 };
484
gesture_swipe_begin(void * data,struct zwp_pointer_gesture_swipe_v1 * zwp_pointer_gesture_swipe_v1,uint32_t serial,uint32_t time,struct wl_surface * surface,uint32_t fingers)485 static void gesture_swipe_begin(void *data,
486 struct zwp_pointer_gesture_swipe_v1 *zwp_pointer_gesture_swipe_v1,
487 uint32_t serial, uint32_t time,
488 struct wl_surface *surface, uint32_t fingers) {
489 struct wlr_wl_input_device *input_device = (struct wlr_wl_input_device *)data;
490 struct wlr_input_device *wlr_dev = &input_device->wlr_input_device;
491 struct wlr_event_pointer_swipe_begin wlr_event = {
492 .device = wlr_dev,
493 .time_msec = time,
494 .fingers = fingers,
495 };
496 input_device->fingers = fingers;
497 wlr_signal_emit_safe(&wlr_dev->pointer->events.swipe_begin, &wlr_event);
498 }
499
gesture_swipe_update(void * data,struct zwp_pointer_gesture_swipe_v1 * zwp_pointer_gesture_swipe_v1,uint32_t time,wl_fixed_t dx,wl_fixed_t dy)500 static void gesture_swipe_update(void *data,
501 struct zwp_pointer_gesture_swipe_v1 *zwp_pointer_gesture_swipe_v1,
502 uint32_t time, wl_fixed_t dx, wl_fixed_t dy) {
503 struct wlr_wl_input_device *input_device = (struct wlr_wl_input_device *)data;
504 struct wlr_input_device *wlr_dev = &input_device->wlr_input_device;
505 struct wlr_event_pointer_swipe_update wlr_event = {
506 .device = wlr_dev,
507 .time_msec = time,
508 .fingers = input_device->fingers,
509 .dx = wl_fixed_to_double(dx),
510 .dy = wl_fixed_to_double(dy),
511 };
512 wlr_signal_emit_safe(&wlr_dev->pointer->events.swipe_update, &wlr_event);
513 }
514
gesture_swipe_end(void * data,struct zwp_pointer_gesture_swipe_v1 * zwp_pointer_gesture_swipe_v1,uint32_t serial,uint32_t time,int32_t cancelled)515 static void gesture_swipe_end(void *data,
516 struct zwp_pointer_gesture_swipe_v1 *zwp_pointer_gesture_swipe_v1,
517 uint32_t serial, uint32_t time, int32_t cancelled) {
518 struct wlr_wl_input_device *input_device = (struct wlr_wl_input_device *)data;
519 struct wlr_input_device *wlr_dev = &input_device->wlr_input_device;
520 struct wlr_event_pointer_swipe_end wlr_event = {
521 .device = wlr_dev,
522 .time_msec = time,
523 .cancelled = cancelled,
524 };
525 wlr_signal_emit_safe(&wlr_dev->pointer->events.swipe_end, &wlr_event);
526 }
527
528 static struct zwp_pointer_gesture_swipe_v1_listener gesture_swipe_impl = {
529 .begin = gesture_swipe_begin,
530 .update = gesture_swipe_update,
531 .end = gesture_swipe_end,
532 };
533
gesture_pinch_begin(void * data,struct zwp_pointer_gesture_pinch_v1 * zwp_pointer_gesture_pinch_v1,uint32_t serial,uint32_t time,struct wl_surface * surface,uint32_t fingers)534 static void gesture_pinch_begin(void *data,
535 struct zwp_pointer_gesture_pinch_v1 *zwp_pointer_gesture_pinch_v1,
536 uint32_t serial, uint32_t time,
537 struct wl_surface *surface, uint32_t fingers) {
538 struct wlr_wl_input_device *input_device = (struct wlr_wl_input_device *)data;
539 struct wlr_input_device *wlr_dev = &input_device->wlr_input_device;
540 struct wlr_event_pointer_pinch_begin wlr_event = {
541 .device = wlr_dev,
542 .time_msec = time,
543 .fingers = fingers,
544 };
545 input_device->fingers = fingers;
546 wlr_signal_emit_safe(&wlr_dev->pointer->events.pinch_begin, &wlr_event);
547 }
548
gesture_pinch_update(void * data,struct zwp_pointer_gesture_pinch_v1 * zwp_pointer_gesture_pinch_v1,uint32_t time,wl_fixed_t dx,wl_fixed_t dy,wl_fixed_t scale,wl_fixed_t rotation)549 static void gesture_pinch_update(void *data,
550 struct zwp_pointer_gesture_pinch_v1 *zwp_pointer_gesture_pinch_v1,
551 uint32_t time, wl_fixed_t dx, wl_fixed_t dy, wl_fixed_t scale, wl_fixed_t rotation) {
552 struct wlr_wl_input_device *input_device = (struct wlr_wl_input_device *)data;
553 struct wlr_input_device *wlr_dev = &input_device->wlr_input_device;
554 struct wlr_event_pointer_pinch_update wlr_event = {
555 .device = wlr_dev,
556 .time_msec = time,
557 .fingers = input_device->fingers,
558 .dx = wl_fixed_to_double(dx),
559 .dy = wl_fixed_to_double(dy),
560 .scale = wl_fixed_to_double(scale),
561 .rotation = wl_fixed_to_double(rotation),
562 };
563 wlr_signal_emit_safe(&wlr_dev->pointer->events.pinch_update, &wlr_event);
564 }
565
gesture_pinch_end(void * data,struct zwp_pointer_gesture_pinch_v1 * zwp_pointer_gesture_pinch_v1,uint32_t serial,uint32_t time,int32_t cancelled)566 static void gesture_pinch_end(void *data,
567 struct zwp_pointer_gesture_pinch_v1 *zwp_pointer_gesture_pinch_v1,
568 uint32_t serial, uint32_t time, int32_t cancelled) {
569 struct wlr_wl_input_device *input_device = (struct wlr_wl_input_device *)data;
570 struct wlr_input_device *wlr_dev = &input_device->wlr_input_device;
571 struct wlr_event_pointer_pinch_end wlr_event = {
572 .device = wlr_dev,
573 .time_msec = time,
574 .cancelled = cancelled,
575 };
576 wlr_signal_emit_safe(&wlr_dev->pointer->events.pinch_end, &wlr_event);
577 }
578
579 static struct zwp_pointer_gesture_pinch_v1_listener gesture_pinch_impl = {
580 .begin = gesture_pinch_begin,
581 .update = gesture_pinch_update,
582 .end = gesture_pinch_end,
583 };
584
585
relative_pointer_handle_relative_motion(void * data,struct zwp_relative_pointer_v1 * relative_pointer,uint32_t utime_hi,uint32_t utime_lo,wl_fixed_t dx,wl_fixed_t dy,wl_fixed_t dx_unaccel,wl_fixed_t dy_unaccel)586 static void relative_pointer_handle_relative_motion(void *data,
587 struct zwp_relative_pointer_v1 *relative_pointer, uint32_t utime_hi,
588 uint32_t utime_lo, wl_fixed_t dx, wl_fixed_t dy, wl_fixed_t dx_unaccel,
589 wl_fixed_t dy_unaccel) {
590 struct wlr_wl_input_device *input_device = data;
591 struct wlr_input_device *wlr_dev = &input_device->wlr_input_device;
592 if (pointer_get_wl(wlr_dev->pointer) != input_device->backend->current_pointer) {
593 return;
594 }
595
596 uint64_t time_usec = (uint64_t)utime_hi << 32 | utime_lo;
597
598 struct wlr_event_pointer_motion wlr_event = {
599 .device = wlr_dev,
600 .time_msec = (uint32_t)(time_usec / 1000),
601 .delta_x = wl_fixed_to_double(dx),
602 .delta_y = wl_fixed_to_double(dy),
603 .unaccel_dx = wl_fixed_to_double(dx_unaccel),
604 .unaccel_dy = wl_fixed_to_double(dy_unaccel),
605 };
606 wlr_signal_emit_safe(&wlr_dev->pointer->events.motion, &wlr_event);
607 }
608
609 static const struct zwp_relative_pointer_v1_listener relative_pointer_listener = {
610 .relative_motion = relative_pointer_handle_relative_motion,
611 };
612
613
pointer_handle_output_destroy(struct wl_listener * listener,void * data)614 static void pointer_handle_output_destroy(struct wl_listener *listener,
615 void *data) {
616 struct wlr_wl_pointer *pointer =
617 wl_container_of(listener, pointer, output_destroy);
618 if (pointer->relative_pointer) {
619 zwp_relative_pointer_v1_destroy(pointer->relative_pointer);
620 }
621 wlr_input_device_destroy(&pointer->input_device->wlr_input_device);
622 }
623
create_wl_pointer(struct wl_pointer * wl_pointer,struct wlr_wl_output * output)624 void create_wl_pointer(struct wl_pointer *wl_pointer, struct wlr_wl_output *output) {
625 struct wlr_wl_backend *backend = output->backend;
626
627 struct wlr_input_device *wlr_dev;
628 wl_list_for_each(wlr_dev, &output->backend->devices, link) {
629 if (wlr_dev->type != WLR_INPUT_DEVICE_POINTER) {
630 continue;
631 }
632 struct wlr_wl_pointer *pointer = pointer_get_wl(wlr_dev->pointer);
633 if (pointer->output == output) {
634 return;
635 }
636 }
637
638 struct wlr_wl_pointer *pointer = calloc(1, sizeof(struct wlr_wl_pointer));
639 if (pointer == NULL) {
640 wlr_log(WLR_ERROR, "Allocation failed");
641 return;
642 }
643 pointer->wl_pointer = wl_pointer;
644 pointer->output = output;
645
646 struct wlr_wl_input_device *dev =
647 create_wl_input_device(backend, WLR_INPUT_DEVICE_POINTER);
648 if (dev == NULL) {
649 free(pointer);
650 wlr_log(WLR_ERROR, "Allocation failed");
651 return;
652 }
653 pointer->input_device = dev;
654
655 wl_signal_add(&output->wlr_output.events.destroy, &pointer->output_destroy);
656 pointer->output_destroy.notify = pointer_handle_output_destroy;
657
658 wlr_dev = &dev->wlr_input_device;
659 wlr_dev->pointer = &pointer->wlr_pointer;
660 wlr_dev->output_name = strdup(output->wlr_output.name);
661 wlr_pointer_init(wlr_dev->pointer, &pointer_impl);
662
663 if (backend->zwp_pointer_gestures_v1) {
664 pointer->gesture_swipe = zwp_pointer_gestures_v1_get_swipe_gesture(
665 backend->zwp_pointer_gestures_v1, wl_pointer);
666 zwp_pointer_gesture_swipe_v1_add_listener(pointer->gesture_swipe, &gesture_swipe_impl, dev);
667 pointer->gesture_pinch = zwp_pointer_gestures_v1_get_pinch_gesture(
668 backend->zwp_pointer_gestures_v1, wl_pointer);
669 zwp_pointer_gesture_pinch_v1_add_listener(pointer->gesture_pinch, &gesture_pinch_impl, dev);
670 }
671
672 if (backend->zwp_relative_pointer_manager_v1) {
673 pointer->relative_pointer =
674 zwp_relative_pointer_manager_v1_get_relative_pointer(
675 backend->zwp_relative_pointer_manager_v1, wl_pointer);
676 zwp_relative_pointer_v1_add_listener(pointer->relative_pointer,
677 &relative_pointer_listener, dev);
678 }
679
680 wl_pointer_add_listener(wl_pointer, &pointer_listener, backend);
681 wlr_signal_emit_safe(&backend->backend.events.new_input, wlr_dev);
682 }
683
create_wl_keyboard(struct wl_keyboard * wl_keyboard,struct wlr_wl_backend * wl)684 void create_wl_keyboard(struct wl_keyboard *wl_keyboard, struct wlr_wl_backend *wl) {
685 struct wlr_wl_input_device *dev =
686 create_wl_input_device(wl, WLR_INPUT_DEVICE_KEYBOARD);
687 if (!dev) {
688 return;
689 }
690
691 struct wlr_input_device *wlr_dev = &dev->wlr_input_device;
692
693 wlr_dev->keyboard = calloc(1, sizeof(*wlr_dev->keyboard));
694 if (!wlr_dev->keyboard) {
695 wlr_log_errno(WLR_ERROR, "Allocation failed");
696 wlr_input_device_destroy(wlr_dev);
697 return;
698 }
699 wlr_keyboard_init(wlr_dev->keyboard, NULL);
700
701 wl_keyboard_add_listener(wl_keyboard, &keyboard_listener, wlr_dev);
702 wlr_signal_emit_safe(&wl->backend.events.new_input, wlr_dev);
703 }
704
create_wl_touch(struct wl_touch * wl_touch,struct wlr_wl_backend * wl)705 void create_wl_touch(struct wl_touch *wl_touch, struct wlr_wl_backend *wl) {
706 struct wlr_wl_input_device *dev =
707 create_wl_input_device(wl, WLR_INPUT_DEVICE_TOUCH);
708 if (!dev) {
709 return;
710 }
711
712 struct wlr_input_device *wlr_dev = &dev->wlr_input_device;
713
714 wlr_dev->touch = calloc(1, sizeof(*wlr_dev->touch));
715 if (!wlr_dev->touch) {
716 wlr_log_errno(WLR_ERROR, "Allocation failed");
717 wlr_input_device_destroy(wlr_dev);
718 return;
719 }
720 wlr_touch_init(wlr_dev->touch, NULL);
721
722 wl_touch_add_listener(wl_touch, &touch_listener, dev);
723 wlr_signal_emit_safe(&wl->backend.events.new_input, wlr_dev);
724 }
725
726
seat_handle_capabilities(void * data,struct wl_seat * wl_seat,enum wl_seat_capability caps)727 static void seat_handle_capabilities(void *data, struct wl_seat *wl_seat,
728 enum wl_seat_capability caps) {
729 struct wlr_wl_backend *backend = data;
730 struct wlr_wl_seat *seat = backend_get_seat(backend, wl_seat);
731
732 if ((caps & WL_SEAT_CAPABILITY_POINTER) && seat->pointer == NULL) {
733 wlr_log(WLR_DEBUG, "seat %p offered pointer", (void *)wl_seat);
734
735 struct wl_pointer *wl_pointer = wl_seat_get_pointer(wl_seat);
736 seat->pointer = wl_pointer;
737
738 struct wlr_wl_output *output;
739 wl_list_for_each(output, &backend->outputs, link) {
740 create_wl_pointer(wl_pointer, output);
741 }
742 }
743 if (!(caps & WL_SEAT_CAPABILITY_POINTER) && seat->pointer != NULL) {
744 wlr_log(WLR_DEBUG, "seat %p dropped pointer", (void *)wl_seat);
745
746 struct wlr_input_device *device, *tmp;
747 wl_list_for_each_safe(device, tmp, &backend->devices, link) {
748 if (device->type == WLR_INPUT_DEVICE_POINTER) {
749 wlr_input_device_destroy(device);
750 }
751 }
752
753 wl_pointer_release(seat->pointer);
754 seat->pointer = NULL;
755 }
756
757 if ((caps & WL_SEAT_CAPABILITY_KEYBOARD) && seat->keyboard == NULL) {
758 wlr_log(WLR_DEBUG, "seat %p offered keyboard", (void *)wl_seat);
759
760 struct wl_keyboard *wl_keyboard = wl_seat_get_keyboard(wl_seat);
761 seat->keyboard = wl_keyboard;
762
763 if (backend->started) {
764 create_wl_keyboard(wl_keyboard, backend);
765 }
766 }
767 if (!(caps & WL_SEAT_CAPABILITY_KEYBOARD) && seat->keyboard != NULL) {
768 wlr_log(WLR_DEBUG, "seat %p dropped keyboard", (void *)wl_seat);
769
770 struct wlr_input_device *device, *tmp;
771 wl_list_for_each_safe(device, tmp, &backend->devices, link) {
772 if (device->type == WLR_INPUT_DEVICE_KEYBOARD) {
773 wlr_input_device_destroy(device);
774 }
775 }
776 assert(seat->keyboard == NULL); // free'ed by input_device_destroy
777 }
778
779 if ((caps & WL_SEAT_CAPABILITY_TOUCH) && seat->touch == NULL) {
780 wlr_log(WLR_DEBUG, "seat %p offered touch", (void *)wl_seat);
781
782 seat->touch = wl_seat_get_touch(wl_seat);
783 if (backend->started) {
784 create_wl_touch(seat->touch, backend);
785 }
786 }
787 if (!(caps & WL_SEAT_CAPABILITY_TOUCH) && seat->touch != NULL) {
788 wlr_log(WLR_DEBUG, "seat %p dropped touch", (void *)wl_seat);
789
790 struct wlr_input_device *device, *tmp;
791 wl_list_for_each_safe(device, tmp, &backend->devices, link) {
792 if (device->type == WLR_INPUT_DEVICE_TOUCH) {
793 wlr_input_device_destroy(device);
794 }
795 }
796
797 wl_touch_release(seat->touch);
798 seat->touch = NULL;
799 }
800 }
801
seat_handle_name(void * data,struct wl_seat * wl_seat,const char * name)802 static void seat_handle_name(void *data, struct wl_seat *wl_seat,
803 const char *name) {
804 struct wlr_wl_backend *backend = data;
805 struct wlr_wl_seat *seat = backend_get_seat(backend, wl_seat);
806 free(seat->name);
807 seat->name = strdup(name);
808 }
809
810 const struct wl_seat_listener seat_listener = {
811 .capabilities = seat_handle_capabilities,
812 .name = seat_handle_name,
813 };
814
wlr_wl_input_device_get_seat(struct wlr_input_device * wlr_dev)815 struct wl_seat *wlr_wl_input_device_get_seat(struct wlr_input_device *wlr_dev) {
816 return input_device_get_seat(wlr_dev)->wl_seat;
817 }
818