1 /*
2 * Copyright © 2013 Jonas Ådahl
3 * Copyright © 2013-2018 Red Hat, Inc.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice (including the next
13 * paragraph) shall be included in all copies or substantial portions of the
14 * Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 */
24
25 #include "config.h"
26
27 #include <errno.h>
28 #include <inttypes.h>
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <stdarg.h>
32 #include <string.h>
33 #include <sys/epoll.h>
34 #include <unistd.h>
35 #include <assert.h>
36
37 #include "libinput.h"
38 #include "libinput-private.h"
39 #include "evdev.h"
40 #include "timer.h"
41 #include "quirks.h"
42
43 #define require_event_type(li_, type_, retval_, ...) \
44 if (type_ == LIBINPUT_EVENT_NONE) abort(); \
45 if (!check_event_type(li_, __func__, type_, __VA_ARGS__, -1)) \
46 return retval_; \
47
48 #define ASSERT_INT_SIZE(type_) \
49 static_assert(sizeof(type_) == sizeof(unsigned int), \
50 "sizeof(" #type_ ") must be sizeof(uint)")
51
52 ASSERT_INT_SIZE(enum libinput_log_priority);
53 ASSERT_INT_SIZE(enum libinput_device_capability);
54 ASSERT_INT_SIZE(enum libinput_key_state);
55 ASSERT_INT_SIZE(enum libinput_led);
56 ASSERT_INT_SIZE(enum libinput_button_state);
57 ASSERT_INT_SIZE(enum libinput_pointer_axis);
58 ASSERT_INT_SIZE(enum libinput_pointer_axis_source);
59 ASSERT_INT_SIZE(enum libinput_tablet_pad_ring_axis_source);
60 ASSERT_INT_SIZE(enum libinput_tablet_pad_strip_axis_source);
61 ASSERT_INT_SIZE(enum libinput_tablet_tool_type);
62 ASSERT_INT_SIZE(enum libinput_tablet_tool_proximity_state);
63 ASSERT_INT_SIZE(enum libinput_tablet_tool_tip_state);
64 ASSERT_INT_SIZE(enum libinput_switch_state);
65 ASSERT_INT_SIZE(enum libinput_switch);
66 ASSERT_INT_SIZE(enum libinput_event_type);
67 ASSERT_INT_SIZE(enum libinput_config_status);
68 ASSERT_INT_SIZE(enum libinput_config_tap_state);
69 ASSERT_INT_SIZE(enum libinput_config_tap_button_map);
70 ASSERT_INT_SIZE(enum libinput_config_drag_state);
71 ASSERT_INT_SIZE(enum libinput_config_drag_lock_state);
72 ASSERT_INT_SIZE(enum libinput_config_send_events_mode);
73 ASSERT_INT_SIZE(enum libinput_config_accel_profile);
74 ASSERT_INT_SIZE(enum libinput_config_click_method);
75 ASSERT_INT_SIZE(enum libinput_config_middle_emulation_state);
76 ASSERT_INT_SIZE(enum libinput_config_scroll_method);
77 ASSERT_INT_SIZE(enum libinput_config_dwt_state);
78
79 static inline const char *
event_type_to_str(enum libinput_event_type type)80 event_type_to_str(enum libinput_event_type type)
81 {
82 switch(type) {
83 CASE_RETURN_STRING(LIBINPUT_EVENT_DEVICE_ADDED);
84 CASE_RETURN_STRING(LIBINPUT_EVENT_DEVICE_REMOVED);
85 CASE_RETURN_STRING(LIBINPUT_EVENT_KEYBOARD_KEY);
86 CASE_RETURN_STRING(LIBINPUT_EVENT_POINTER_MOTION);
87 CASE_RETURN_STRING(LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE);
88 CASE_RETURN_STRING(LIBINPUT_EVENT_POINTER_BUTTON);
89 CASE_RETURN_STRING(LIBINPUT_EVENT_POINTER_AXIS);
90 CASE_RETURN_STRING(LIBINPUT_EVENT_POINTER_SCROLL_WHEEL);
91 CASE_RETURN_STRING(LIBINPUT_EVENT_POINTER_SCROLL_FINGER);
92 CASE_RETURN_STRING(LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS);
93 CASE_RETURN_STRING(LIBINPUT_EVENT_TOUCH_DOWN);
94 CASE_RETURN_STRING(LIBINPUT_EVENT_TOUCH_UP);
95 CASE_RETURN_STRING(LIBINPUT_EVENT_TOUCH_MOTION);
96 CASE_RETURN_STRING(LIBINPUT_EVENT_TOUCH_CANCEL);
97 CASE_RETURN_STRING(LIBINPUT_EVENT_TOUCH_FRAME);
98 CASE_RETURN_STRING(LIBINPUT_EVENT_TABLET_TOOL_AXIS);
99 CASE_RETURN_STRING(LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY);
100 CASE_RETURN_STRING(LIBINPUT_EVENT_TABLET_TOOL_TIP);
101 CASE_RETURN_STRING(LIBINPUT_EVENT_TABLET_TOOL_BUTTON);
102 CASE_RETURN_STRING(LIBINPUT_EVENT_TABLET_PAD_BUTTON);
103 CASE_RETURN_STRING(LIBINPUT_EVENT_TABLET_PAD_RING);
104 CASE_RETURN_STRING(LIBINPUT_EVENT_TABLET_PAD_STRIP);
105 CASE_RETURN_STRING(LIBINPUT_EVENT_TABLET_PAD_KEY);
106 CASE_RETURN_STRING(LIBINPUT_EVENT_GESTURE_SWIPE_BEGIN);
107 CASE_RETURN_STRING(LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE);
108 CASE_RETURN_STRING(LIBINPUT_EVENT_GESTURE_SWIPE_END);
109 CASE_RETURN_STRING(LIBINPUT_EVENT_GESTURE_PINCH_BEGIN);
110 CASE_RETURN_STRING(LIBINPUT_EVENT_GESTURE_PINCH_UPDATE);
111 CASE_RETURN_STRING(LIBINPUT_EVENT_GESTURE_PINCH_END);
112 CASE_RETURN_STRING(LIBINPUT_EVENT_GESTURE_HOLD_BEGIN);
113 CASE_RETURN_STRING(LIBINPUT_EVENT_GESTURE_HOLD_END);
114 CASE_RETURN_STRING(LIBINPUT_EVENT_SWITCH_TOGGLE);
115 case LIBINPUT_EVENT_NONE:
116 abort();
117 }
118
119 return NULL;
120 }
121
122 static inline bool
check_event_type(struct libinput * libinput,const char * function_name,unsigned int type_in,...)123 check_event_type(struct libinput *libinput,
124 const char *function_name,
125 unsigned int type_in,
126 ...)
127 {
128 bool rc = false;
129 va_list args;
130 unsigned int type_permitted;
131
132 va_start(args, type_in);
133 type_permitted = va_arg(args, unsigned int);
134
135 while (type_permitted != (unsigned int)-1) {
136 if (type_permitted == type_in) {
137 rc = true;
138 break;
139 }
140 type_permitted = va_arg(args, unsigned int);
141 }
142
143 va_end(args);
144
145 if (!rc) {
146 const char *name = event_type_to_str(type_in);
147 log_bug_client(libinput,
148 "Invalid event type %s (%d) passed to %s()\n",
149 name, type_in, function_name);
150 }
151
152 return rc;
153 }
154
155 struct libinput_source {
156 libinput_source_dispatch_t dispatch;
157 void *user_data;
158 int fd;
159 struct list link;
160 };
161
162 struct libinput_event_device_notify {
163 struct libinput_event base;
164 };
165
166 struct libinput_event_keyboard {
167 struct libinput_event base;
168 uint64_t time;
169 uint32_t key;
170 uint32_t seat_key_count;
171 enum libinput_key_state state;
172 };
173
174 struct libinput_event_pointer {
175 struct libinput_event base;
176 uint64_t time;
177 struct normalized_coords delta;
178 struct device_float_coords delta_raw;
179 struct device_coords absolute;
180 struct discrete_coords discrete;
181 struct wheel_v120 v120;
182 uint32_t button;
183 uint32_t seat_button_count;
184 enum libinput_button_state state;
185 enum libinput_pointer_axis_source source;
186 uint32_t axes;
187 };
188
189 struct libinput_event_touch {
190 struct libinput_event base;
191 uint64_t time;
192 int32_t slot;
193 int32_t seat_slot;
194 struct device_coords point;
195 };
196
197 struct libinput_event_gesture {
198 struct libinput_event base;
199 uint64_t time;
200 int finger_count;
201 int cancelled;
202 struct normalized_coords delta;
203 struct normalized_coords delta_unaccel;
204 double scale;
205 double angle;
206 };
207
208 struct libinput_event_tablet_tool {
209 struct libinput_event base;
210 uint32_t button;
211 enum libinput_button_state state;
212 uint32_t seat_button_count;
213 uint64_t time;
214 struct tablet_axes axes;
215 unsigned char changed_axes[NCHARS(LIBINPUT_TABLET_TOOL_AXIS_MAX + 1)];
216 struct libinput_tablet_tool *tool;
217 enum libinput_tablet_tool_proximity_state proximity_state;
218 enum libinput_tablet_tool_tip_state tip_state;
219 };
220
221 struct libinput_event_tablet_pad {
222 struct libinput_event base;
223 unsigned int mode;
224 struct libinput_tablet_pad_mode_group *mode_group;
225 uint64_t time;
226 struct {
227 uint32_t number;
228 enum libinput_button_state state;
229 } button;
230 struct {
231 uint32_t code;
232 enum libinput_key_state state;
233 } key;
234 struct {
235 enum libinput_tablet_pad_ring_axis_source source;
236 double position;
237 int number;
238 } ring;
239 struct {
240 enum libinput_tablet_pad_strip_axis_source source;
241 double position;
242 int number;
243 } strip;
244 };
245
246 struct libinput_event_switch {
247 struct libinput_event base;
248 uint64_t time;
249 enum libinput_switch sw;
250 enum libinput_switch_state state;
251 };
252
253 LIBINPUT_ATTRIBUTE_PRINTF(3, 0)
254 static void
libinput_default_log_func(struct libinput * libinput,enum libinput_log_priority priority,const char * format,va_list args)255 libinput_default_log_func(struct libinput *libinput,
256 enum libinput_log_priority priority,
257 const char *format, va_list args)
258 {
259 const char *prefix;
260
261 switch(priority) {
262 case LIBINPUT_LOG_PRIORITY_DEBUG: prefix = "debug"; break;
263 case LIBINPUT_LOG_PRIORITY_INFO: prefix = "info"; break;
264 case LIBINPUT_LOG_PRIORITY_ERROR: prefix = "error"; break;
265 default: prefix="<invalid priority>"; break;
266 }
267
268 fprintf(stderr, "libinput %s: ", prefix);
269 vfprintf(stderr, format, args);
270 }
271
272 void
log_msg_va(struct libinput * libinput,enum libinput_log_priority priority,const char * format,va_list args)273 log_msg_va(struct libinput *libinput,
274 enum libinput_log_priority priority,
275 const char *format,
276 va_list args)
277 {
278 if (is_logged(libinput, priority))
279 libinput->log_handler(libinput, priority, format, args);
280 }
281
282 void
log_msg(struct libinput * libinput,enum libinput_log_priority priority,const char * format,...)283 log_msg(struct libinput *libinput,
284 enum libinput_log_priority priority,
285 const char *format, ...)
286 {
287 va_list args;
288
289 va_start(args, format);
290 log_msg_va(libinput, priority, format, args);
291 va_end(args);
292 }
293
294 void
log_msg_ratelimit(struct libinput * libinput,struct ratelimit * ratelimit,enum libinput_log_priority priority,const char * format,...)295 log_msg_ratelimit(struct libinput *libinput,
296 struct ratelimit *ratelimit,
297 enum libinput_log_priority priority,
298 const char *format, ...)
299 {
300 va_list args;
301 enum ratelimit_state state;
302
303 state = ratelimit_test(ratelimit);
304 if (state == RATELIMIT_EXCEEDED)
305 return;
306
307 va_start(args, format);
308 log_msg_va(libinput, priority, format, args);
309 va_end(args);
310
311 if (state == RATELIMIT_THRESHOLD)
312 log_msg(libinput,
313 priority,
314 "WARNING: log rate limit exceeded (%d msgs per %dms). Discarding future messages.\n",
315 ratelimit->burst,
316 us2ms(ratelimit->interval));
317 }
318
319 LIBINPUT_EXPORT void
libinput_log_set_priority(struct libinput * libinput,enum libinput_log_priority priority)320 libinput_log_set_priority(struct libinput *libinput,
321 enum libinput_log_priority priority)
322 {
323 libinput->log_priority = priority;
324 }
325
326 LIBINPUT_EXPORT enum libinput_log_priority
libinput_log_get_priority(const struct libinput * libinput)327 libinput_log_get_priority(const struct libinput *libinput)
328 {
329 return libinput->log_priority;
330 }
331
332 LIBINPUT_EXPORT void
libinput_log_set_handler(struct libinput * libinput,libinput_log_handler log_handler)333 libinput_log_set_handler(struct libinput *libinput,
334 libinput_log_handler log_handler)
335 {
336 libinput->log_handler = log_handler;
337 }
338
339 static void
340 libinput_device_group_destroy(struct libinput_device_group *group);
341
342 static void
343 libinput_post_event(struct libinput *libinput,
344 struct libinput_event *event);
345
346 LIBINPUT_EXPORT enum libinput_event_type
libinput_event_get_type(struct libinput_event * event)347 libinput_event_get_type(struct libinput_event *event)
348 {
349 return event->type;
350 }
351
352 LIBINPUT_EXPORT struct libinput *
libinput_event_get_context(struct libinput_event * event)353 libinput_event_get_context(struct libinput_event *event)
354 {
355 return event->device->seat->libinput;
356 }
357
358 LIBINPUT_EXPORT struct libinput_device *
libinput_event_get_device(struct libinput_event * event)359 libinput_event_get_device(struct libinput_event *event)
360 {
361 return event->device;
362 }
363
364 LIBINPUT_EXPORT struct libinput_event_pointer *
libinput_event_get_pointer_event(struct libinput_event * event)365 libinput_event_get_pointer_event(struct libinput_event *event)
366 {
367 require_event_type(libinput_event_get_context(event),
368 event->type,
369 NULL,
370 LIBINPUT_EVENT_POINTER_MOTION,
371 LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE,
372 LIBINPUT_EVENT_POINTER_BUTTON,
373 LIBINPUT_EVENT_POINTER_SCROLL_WHEEL,
374 LIBINPUT_EVENT_POINTER_SCROLL_FINGER,
375 LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS,
376 LIBINPUT_EVENT_POINTER_AXIS);
377
378 return (struct libinput_event_pointer *) event;
379 }
380
381 LIBINPUT_EXPORT struct libinput_event_keyboard *
libinput_event_get_keyboard_event(struct libinput_event * event)382 libinput_event_get_keyboard_event(struct libinput_event *event)
383 {
384 require_event_type(libinput_event_get_context(event),
385 event->type,
386 NULL,
387 LIBINPUT_EVENT_KEYBOARD_KEY);
388
389 return (struct libinput_event_keyboard *) event;
390 }
391
392 LIBINPUT_EXPORT struct libinput_event_touch *
libinput_event_get_touch_event(struct libinput_event * event)393 libinput_event_get_touch_event(struct libinput_event *event)
394 {
395 require_event_type(libinput_event_get_context(event),
396 event->type,
397 NULL,
398 LIBINPUT_EVENT_TOUCH_DOWN,
399 LIBINPUT_EVENT_TOUCH_UP,
400 LIBINPUT_EVENT_TOUCH_MOTION,
401 LIBINPUT_EVENT_TOUCH_CANCEL,
402 LIBINPUT_EVENT_TOUCH_FRAME);
403 return (struct libinput_event_touch *) event;
404 }
405
406 LIBINPUT_EXPORT struct libinput_event_gesture *
libinput_event_get_gesture_event(struct libinput_event * event)407 libinput_event_get_gesture_event(struct libinput_event *event)
408 {
409 require_event_type(libinput_event_get_context(event),
410 event->type,
411 NULL,
412 LIBINPUT_EVENT_GESTURE_SWIPE_BEGIN,
413 LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE,
414 LIBINPUT_EVENT_GESTURE_SWIPE_END,
415 LIBINPUT_EVENT_GESTURE_PINCH_BEGIN,
416 LIBINPUT_EVENT_GESTURE_PINCH_UPDATE,
417 LIBINPUT_EVENT_GESTURE_PINCH_END,
418 LIBINPUT_EVENT_GESTURE_HOLD_BEGIN,
419 LIBINPUT_EVENT_GESTURE_HOLD_END);
420
421 return (struct libinput_event_gesture *) event;
422 }
423
424 LIBINPUT_EXPORT struct libinput_event_tablet_tool *
libinput_event_get_tablet_tool_event(struct libinput_event * event)425 libinput_event_get_tablet_tool_event(struct libinput_event *event)
426 {
427 require_event_type(libinput_event_get_context(event),
428 event->type,
429 NULL,
430 LIBINPUT_EVENT_TABLET_TOOL_AXIS,
431 LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY,
432 LIBINPUT_EVENT_TABLET_TOOL_TIP,
433 LIBINPUT_EVENT_TABLET_TOOL_BUTTON);
434
435 return (struct libinput_event_tablet_tool *) event;
436 }
437
438 LIBINPUT_EXPORT struct libinput_event_tablet_pad *
libinput_event_get_tablet_pad_event(struct libinput_event * event)439 libinput_event_get_tablet_pad_event(struct libinput_event *event)
440 {
441 require_event_type(libinput_event_get_context(event),
442 event->type,
443 NULL,
444 LIBINPUT_EVENT_TABLET_PAD_RING,
445 LIBINPUT_EVENT_TABLET_PAD_STRIP,
446 LIBINPUT_EVENT_TABLET_PAD_BUTTON,
447 LIBINPUT_EVENT_TABLET_PAD_KEY);
448
449 return (struct libinput_event_tablet_pad *) event;
450 }
451
452 LIBINPUT_EXPORT struct libinput_event_device_notify *
libinput_event_get_device_notify_event(struct libinput_event * event)453 libinput_event_get_device_notify_event(struct libinput_event *event)
454 {
455 require_event_type(libinput_event_get_context(event),
456 event->type,
457 NULL,
458 LIBINPUT_EVENT_DEVICE_ADDED,
459 LIBINPUT_EVENT_DEVICE_REMOVED);
460
461 return (struct libinput_event_device_notify *) event;
462 }
463
464 LIBINPUT_EXPORT struct libinput_event_switch *
libinput_event_get_switch_event(struct libinput_event * event)465 libinput_event_get_switch_event(struct libinput_event *event)
466 {
467 require_event_type(libinput_event_get_context(event),
468 event->type,
469 NULL,
470 LIBINPUT_EVENT_SWITCH_TOGGLE);
471
472 return (struct libinput_event_switch *) event;
473 }
474
475 LIBINPUT_EXPORT uint32_t
libinput_event_keyboard_get_time(struct libinput_event_keyboard * event)476 libinput_event_keyboard_get_time(struct libinput_event_keyboard *event)
477 {
478 require_event_type(libinput_event_get_context(&event->base),
479 event->base.type,
480 0,
481 LIBINPUT_EVENT_KEYBOARD_KEY);
482
483 return us2ms(event->time);
484 }
485
486 LIBINPUT_EXPORT uint64_t
libinput_event_keyboard_get_time_usec(struct libinput_event_keyboard * event)487 libinput_event_keyboard_get_time_usec(struct libinput_event_keyboard *event)
488 {
489 require_event_type(libinput_event_get_context(&event->base),
490 event->base.type,
491 0,
492 LIBINPUT_EVENT_KEYBOARD_KEY);
493
494 return event->time;
495 }
496
497 LIBINPUT_EXPORT uint32_t
libinput_event_keyboard_get_key(struct libinput_event_keyboard * event)498 libinput_event_keyboard_get_key(struct libinput_event_keyboard *event)
499 {
500 require_event_type(libinput_event_get_context(&event->base),
501 event->base.type,
502 0,
503 LIBINPUT_EVENT_KEYBOARD_KEY);
504
505 return event->key;
506 }
507
508 LIBINPUT_EXPORT enum libinput_key_state
libinput_event_keyboard_get_key_state(struct libinput_event_keyboard * event)509 libinput_event_keyboard_get_key_state(struct libinput_event_keyboard *event)
510 {
511 require_event_type(libinput_event_get_context(&event->base),
512 event->base.type,
513 0,
514 LIBINPUT_EVENT_KEYBOARD_KEY);
515
516 return event->state;
517 }
518
519 LIBINPUT_EXPORT uint32_t
libinput_event_keyboard_get_seat_key_count(struct libinput_event_keyboard * event)520 libinput_event_keyboard_get_seat_key_count(
521 struct libinput_event_keyboard *event)
522 {
523 require_event_type(libinput_event_get_context(&event->base),
524 event->base.type,
525 0,
526 LIBINPUT_EVENT_KEYBOARD_KEY);
527
528 return event->seat_key_count;
529 }
530
531 LIBINPUT_EXPORT uint32_t
libinput_event_pointer_get_time(struct libinput_event_pointer * event)532 libinput_event_pointer_get_time(struct libinput_event_pointer *event)
533 {
534 require_event_type(libinput_event_get_context(&event->base),
535 event->base.type,
536 0,
537 LIBINPUT_EVENT_POINTER_MOTION,
538 LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE,
539 LIBINPUT_EVENT_POINTER_BUTTON,
540 LIBINPUT_EVENT_POINTER_SCROLL_WHEEL,
541 LIBINPUT_EVENT_POINTER_SCROLL_FINGER,
542 LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS,
543 LIBINPUT_EVENT_POINTER_AXIS);
544
545 return us2ms(event->time);
546 }
547
548 LIBINPUT_EXPORT uint64_t
libinput_event_pointer_get_time_usec(struct libinput_event_pointer * event)549 libinput_event_pointer_get_time_usec(struct libinput_event_pointer *event)
550 {
551 require_event_type(libinput_event_get_context(&event->base),
552 event->base.type,
553 0,
554 LIBINPUT_EVENT_POINTER_MOTION,
555 LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE,
556 LIBINPUT_EVENT_POINTER_BUTTON,
557 LIBINPUT_EVENT_POINTER_SCROLL_WHEEL,
558 LIBINPUT_EVENT_POINTER_SCROLL_FINGER,
559 LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS,
560 LIBINPUT_EVENT_POINTER_AXIS);
561
562 return event->time;
563 }
564
565 LIBINPUT_EXPORT double
libinput_event_pointer_get_dx(struct libinput_event_pointer * event)566 libinput_event_pointer_get_dx(struct libinput_event_pointer *event)
567 {
568 require_event_type(libinput_event_get_context(&event->base),
569 event->base.type,
570 0,
571 LIBINPUT_EVENT_POINTER_MOTION);
572
573 return event->delta.x;
574 }
575
576 LIBINPUT_EXPORT double
libinput_event_pointer_get_dy(struct libinput_event_pointer * event)577 libinput_event_pointer_get_dy(struct libinput_event_pointer *event)
578 {
579 require_event_type(libinput_event_get_context(&event->base),
580 event->base.type,
581 0,
582 LIBINPUT_EVENT_POINTER_MOTION);
583
584 return event->delta.y;
585 }
586
587 LIBINPUT_EXPORT double
libinput_event_pointer_get_dx_unaccelerated(struct libinput_event_pointer * event)588 libinput_event_pointer_get_dx_unaccelerated(
589 struct libinput_event_pointer *event)
590 {
591 require_event_type(libinput_event_get_context(&event->base),
592 event->base.type,
593 0,
594 LIBINPUT_EVENT_POINTER_MOTION);
595
596 return event->delta_raw.x;
597 }
598
599 LIBINPUT_EXPORT double
libinput_event_pointer_get_dy_unaccelerated(struct libinput_event_pointer * event)600 libinput_event_pointer_get_dy_unaccelerated(
601 struct libinput_event_pointer *event)
602 {
603 require_event_type(libinput_event_get_context(&event->base),
604 event->base.type,
605 0,
606 LIBINPUT_EVENT_POINTER_MOTION);
607
608 return event->delta_raw.y;
609 }
610
611 LIBINPUT_EXPORT double
libinput_event_pointer_get_absolute_x(struct libinput_event_pointer * event)612 libinput_event_pointer_get_absolute_x(struct libinput_event_pointer *event)
613 {
614 struct evdev_device *device = evdev_device(event->base.device);
615
616 require_event_type(libinput_event_get_context(&event->base),
617 event->base.type,
618 0,
619 LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE);
620
621 return evdev_convert_to_mm(device->abs.absinfo_x, event->absolute.x);
622 }
623
624 LIBINPUT_EXPORT double
libinput_event_pointer_get_absolute_y(struct libinput_event_pointer * event)625 libinput_event_pointer_get_absolute_y(struct libinput_event_pointer *event)
626 {
627 struct evdev_device *device = evdev_device(event->base.device);
628
629 require_event_type(libinput_event_get_context(&event->base),
630 event->base.type,
631 0,
632 LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE);
633
634 return evdev_convert_to_mm(device->abs.absinfo_y, event->absolute.y);
635 }
636
637 LIBINPUT_EXPORT double
libinput_event_pointer_get_absolute_x_transformed(struct libinput_event_pointer * event,uint32_t width)638 libinput_event_pointer_get_absolute_x_transformed(
639 struct libinput_event_pointer *event,
640 uint32_t width)
641 {
642 struct evdev_device *device = evdev_device(event->base.device);
643
644 require_event_type(libinput_event_get_context(&event->base),
645 event->base.type,
646 0,
647 LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE);
648
649 return evdev_device_transform_x(device, event->absolute.x, width);
650 }
651
652 LIBINPUT_EXPORT double
libinput_event_pointer_get_absolute_y_transformed(struct libinput_event_pointer * event,uint32_t height)653 libinput_event_pointer_get_absolute_y_transformed(
654 struct libinput_event_pointer *event,
655 uint32_t height)
656 {
657 struct evdev_device *device = evdev_device(event->base.device);
658
659 require_event_type(libinput_event_get_context(&event->base),
660 event->base.type,
661 0,
662 LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE);
663
664 return evdev_device_transform_y(device, event->absolute.y, height);
665 }
666
667 LIBINPUT_EXPORT uint32_t
libinput_event_pointer_get_button(struct libinput_event_pointer * event)668 libinput_event_pointer_get_button(struct libinput_event_pointer *event)
669 {
670 require_event_type(libinput_event_get_context(&event->base),
671 event->base.type,
672 0,
673 LIBINPUT_EVENT_POINTER_BUTTON);
674
675 return event->button;
676 }
677
678 LIBINPUT_EXPORT enum libinput_button_state
libinput_event_pointer_get_button_state(struct libinput_event_pointer * event)679 libinput_event_pointer_get_button_state(struct libinput_event_pointer *event)
680 {
681 require_event_type(libinput_event_get_context(&event->base),
682 event->base.type,
683 0,
684 LIBINPUT_EVENT_POINTER_BUTTON);
685
686 return event->state;
687 }
688
689 LIBINPUT_EXPORT uint32_t
libinput_event_pointer_get_seat_button_count(struct libinput_event_pointer * event)690 libinput_event_pointer_get_seat_button_count(
691 struct libinput_event_pointer *event)
692 {
693 require_event_type(libinput_event_get_context(&event->base),
694 event->base.type,
695 0,
696 LIBINPUT_EVENT_POINTER_BUTTON);
697
698 return event->seat_button_count;
699 }
700
701 LIBINPUT_EXPORT int
libinput_event_pointer_has_axis(struct libinput_event_pointer * event,enum libinput_pointer_axis axis)702 libinput_event_pointer_has_axis(struct libinput_event_pointer *event,
703 enum libinput_pointer_axis axis)
704 {
705 require_event_type(libinput_event_get_context(&event->base),
706 event->base.type,
707 0,
708 LIBINPUT_EVENT_POINTER_SCROLL_WHEEL,
709 LIBINPUT_EVENT_POINTER_SCROLL_FINGER,
710 LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS,
711 LIBINPUT_EVENT_POINTER_AXIS);
712
713 switch (axis) {
714 case LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL:
715 case LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL:
716 return !!(event->axes & bit(axis));
717 }
718
719 return 0;
720 }
721
722 LIBINPUT_EXPORT double
libinput_event_pointer_get_axis_value(struct libinput_event_pointer * event,enum libinput_pointer_axis axis)723 libinput_event_pointer_get_axis_value(struct libinput_event_pointer *event,
724 enum libinput_pointer_axis axis)
725 {
726 struct libinput *libinput = event->base.device->seat->libinput;
727 double value = 0;
728
729 require_event_type(libinput_event_get_context(&event->base),
730 event->base.type,
731 0.0,
732 LIBINPUT_EVENT_POINTER_AXIS);
733
734 if (!libinput_event_pointer_has_axis(event, axis)) {
735 log_bug_client(libinput, "value requested for unset axis\n");
736 } else {
737 switch (axis) {
738 case LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL:
739 value = event->delta.x;
740 break;
741 case LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL:
742 value = event->delta.y;
743 break;
744 }
745 }
746
747 return value;
748 }
749
750 LIBINPUT_EXPORT double
libinput_event_pointer_get_axis_value_discrete(struct libinput_event_pointer * event,enum libinput_pointer_axis axis)751 libinput_event_pointer_get_axis_value_discrete(struct libinput_event_pointer *event,
752 enum libinput_pointer_axis axis)
753 {
754 struct libinput *libinput = event->base.device->seat->libinput;
755 double value = 0;
756
757 require_event_type(libinput_event_get_context(&event->base),
758 event->base.type,
759 0.0,
760 LIBINPUT_EVENT_POINTER_AXIS);
761
762 if (!libinput_event_pointer_has_axis(event, axis)) {
763 log_bug_client(libinput, "value requested for unset axis\n");
764 } else {
765 switch (axis) {
766 case LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL:
767 value = event->discrete.x;
768 break;
769 case LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL:
770 value = event->discrete.y;
771 break;
772 }
773 }
774 return value;
775 }
776
777 LIBINPUT_EXPORT double
libinput_event_pointer_get_scroll_value(struct libinput_event_pointer * event,enum libinput_pointer_axis axis)778 libinput_event_pointer_get_scroll_value(struct libinput_event_pointer *event,
779 enum libinput_pointer_axis axis)
780 {
781 struct libinput *libinput = event->base.device->seat->libinput;
782 double value = 0;
783
784 require_event_type(libinput_event_get_context(&event->base),
785 event->base.type,
786 0.0,
787 LIBINPUT_EVENT_POINTER_SCROLL_WHEEL,
788 LIBINPUT_EVENT_POINTER_SCROLL_FINGER,
789 LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS);
790
791 if (!libinput_event_pointer_has_axis(event, axis)) {
792 log_bug_client(libinput, "value requested for unset axis\n");
793 } else {
794 switch (axis) {
795 case LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL:
796 value = event->delta.x;
797 break;
798 case LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL:
799 value = event->delta.y;
800 break;
801 }
802 }
803 return value;
804 }
805
806 LIBINPUT_EXPORT double
libinput_event_pointer_get_scroll_value_v120(struct libinput_event_pointer * event,enum libinput_pointer_axis axis)807 libinput_event_pointer_get_scroll_value_v120(struct libinput_event_pointer *event,
808 enum libinput_pointer_axis axis)
809 {
810 struct libinput *libinput = event->base.device->seat->libinput;
811 double value = 0;
812
813 require_event_type(libinput_event_get_context(&event->base),
814 event->base.type,
815 0.0,
816 LIBINPUT_EVENT_POINTER_SCROLL_WHEEL);
817
818 if (!libinput_event_pointer_has_axis(event, axis)) {
819 log_bug_client(libinput, "value requested for unset axis\n");
820 } else {
821 switch (axis) {
822 case LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL:
823 value = event->v120.x;
824 break;
825 case LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL:
826 value = event->v120.y;
827 break;
828 }
829 }
830 return value;
831 }
832
833 LIBINPUT_EXPORT enum libinput_pointer_axis_source
libinput_event_pointer_get_axis_source(struct libinput_event_pointer * event)834 libinput_event_pointer_get_axis_source(struct libinput_event_pointer *event)
835 {
836 require_event_type(libinput_event_get_context(&event->base),
837 event->base.type,
838 0,
839 LIBINPUT_EVENT_POINTER_AXIS);
840
841 return event->source;
842 }
843
844 LIBINPUT_EXPORT uint32_t
libinput_event_touch_get_time(struct libinput_event_touch * event)845 libinput_event_touch_get_time(struct libinput_event_touch *event)
846 {
847 require_event_type(libinput_event_get_context(&event->base),
848 event->base.type,
849 0,
850 LIBINPUT_EVENT_TOUCH_DOWN,
851 LIBINPUT_EVENT_TOUCH_UP,
852 LIBINPUT_EVENT_TOUCH_MOTION,
853 LIBINPUT_EVENT_TOUCH_CANCEL,
854 LIBINPUT_EVENT_TOUCH_FRAME);
855
856 return us2ms(event->time);
857 }
858
859 LIBINPUT_EXPORT uint64_t
libinput_event_touch_get_time_usec(struct libinput_event_touch * event)860 libinput_event_touch_get_time_usec(struct libinput_event_touch *event)
861 {
862 require_event_type(libinput_event_get_context(&event->base),
863 event->base.type,
864 0,
865 LIBINPUT_EVENT_TOUCH_DOWN,
866 LIBINPUT_EVENT_TOUCH_UP,
867 LIBINPUT_EVENT_TOUCH_MOTION,
868 LIBINPUT_EVENT_TOUCH_CANCEL,
869 LIBINPUT_EVENT_TOUCH_FRAME);
870
871 return event->time;
872 }
873
874 LIBINPUT_EXPORT int32_t
libinput_event_touch_get_slot(struct libinput_event_touch * event)875 libinput_event_touch_get_slot(struct libinput_event_touch *event)
876 {
877 require_event_type(libinput_event_get_context(&event->base),
878 event->base.type,
879 0,
880 LIBINPUT_EVENT_TOUCH_DOWN,
881 LIBINPUT_EVENT_TOUCH_UP,
882 LIBINPUT_EVENT_TOUCH_MOTION,
883 LIBINPUT_EVENT_TOUCH_CANCEL);
884
885 return event->slot;
886 }
887
888 LIBINPUT_EXPORT int32_t
libinput_event_touch_get_seat_slot(struct libinput_event_touch * event)889 libinput_event_touch_get_seat_slot(struct libinput_event_touch *event)
890 {
891 require_event_type(libinput_event_get_context(&event->base),
892 event->base.type,
893 0,
894 LIBINPUT_EVENT_TOUCH_DOWN,
895 LIBINPUT_EVENT_TOUCH_UP,
896 LIBINPUT_EVENT_TOUCH_MOTION,
897 LIBINPUT_EVENT_TOUCH_CANCEL);
898
899 return event->seat_slot;
900 }
901
902 LIBINPUT_EXPORT double
libinput_event_touch_get_x(struct libinput_event_touch * event)903 libinput_event_touch_get_x(struct libinput_event_touch *event)
904 {
905 struct evdev_device *device = evdev_device(event->base.device);
906
907 require_event_type(libinput_event_get_context(&event->base),
908 event->base.type,
909 0,
910 LIBINPUT_EVENT_TOUCH_DOWN,
911 LIBINPUT_EVENT_TOUCH_MOTION);
912
913 return evdev_convert_to_mm(device->abs.absinfo_x, event->point.x);
914 }
915
916 LIBINPUT_EXPORT double
libinput_event_touch_get_x_transformed(struct libinput_event_touch * event,uint32_t width)917 libinput_event_touch_get_x_transformed(struct libinput_event_touch *event,
918 uint32_t width)
919 {
920 struct evdev_device *device = evdev_device(event->base.device);
921
922 require_event_type(libinput_event_get_context(&event->base),
923 event->base.type,
924 0,
925 LIBINPUT_EVENT_TOUCH_DOWN,
926 LIBINPUT_EVENT_TOUCH_MOTION);
927
928 return evdev_device_transform_x(device, event->point.x, width);
929 }
930
931 LIBINPUT_EXPORT double
libinput_event_touch_get_y_transformed(struct libinput_event_touch * event,uint32_t height)932 libinput_event_touch_get_y_transformed(struct libinput_event_touch *event,
933 uint32_t height)
934 {
935 struct evdev_device *device = evdev_device(event->base.device);
936
937 require_event_type(libinput_event_get_context(&event->base),
938 event->base.type,
939 0,
940 LIBINPUT_EVENT_TOUCH_DOWN,
941 LIBINPUT_EVENT_TOUCH_MOTION);
942
943 return evdev_device_transform_y(device, event->point.y, height);
944 }
945
946 LIBINPUT_EXPORT double
libinput_event_touch_get_y(struct libinput_event_touch * event)947 libinput_event_touch_get_y(struct libinput_event_touch *event)
948 {
949 struct evdev_device *device = evdev_device(event->base.device);
950
951 require_event_type(libinput_event_get_context(&event->base),
952 event->base.type,
953 0,
954 LIBINPUT_EVENT_TOUCH_DOWN,
955 LIBINPUT_EVENT_TOUCH_MOTION);
956
957 return evdev_convert_to_mm(device->abs.absinfo_y, event->point.y);
958 }
959
960 LIBINPUT_EXPORT uint32_t
libinput_event_gesture_get_time(struct libinput_event_gesture * event)961 libinput_event_gesture_get_time(struct libinput_event_gesture *event)
962 {
963 require_event_type(libinput_event_get_context(&event->base),
964 event->base.type,
965 0,
966 LIBINPUT_EVENT_GESTURE_PINCH_BEGIN,
967 LIBINPUT_EVENT_GESTURE_PINCH_UPDATE,
968 LIBINPUT_EVENT_GESTURE_PINCH_END,
969 LIBINPUT_EVENT_GESTURE_SWIPE_BEGIN,
970 LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE,
971 LIBINPUT_EVENT_GESTURE_SWIPE_END,
972 LIBINPUT_EVENT_GESTURE_HOLD_BEGIN,
973 LIBINPUT_EVENT_GESTURE_HOLD_END);
974
975 return us2ms(event->time);
976 }
977
978 LIBINPUT_EXPORT uint64_t
libinput_event_gesture_get_time_usec(struct libinput_event_gesture * event)979 libinput_event_gesture_get_time_usec(struct libinput_event_gesture *event)
980 {
981 require_event_type(libinput_event_get_context(&event->base),
982 event->base.type,
983 0,
984 LIBINPUT_EVENT_GESTURE_PINCH_BEGIN,
985 LIBINPUT_EVENT_GESTURE_PINCH_UPDATE,
986 LIBINPUT_EVENT_GESTURE_PINCH_END,
987 LIBINPUT_EVENT_GESTURE_SWIPE_BEGIN,
988 LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE,
989 LIBINPUT_EVENT_GESTURE_SWIPE_END,
990 LIBINPUT_EVENT_GESTURE_HOLD_BEGIN,
991 LIBINPUT_EVENT_GESTURE_HOLD_END);
992
993 return event->time;
994 }
995
996 LIBINPUT_EXPORT int
libinput_event_gesture_get_finger_count(struct libinput_event_gesture * event)997 libinput_event_gesture_get_finger_count(struct libinput_event_gesture *event)
998 {
999 require_event_type(libinput_event_get_context(&event->base),
1000 event->base.type,
1001 0,
1002 LIBINPUT_EVENT_GESTURE_PINCH_BEGIN,
1003 LIBINPUT_EVENT_GESTURE_PINCH_UPDATE,
1004 LIBINPUT_EVENT_GESTURE_PINCH_END,
1005 LIBINPUT_EVENT_GESTURE_SWIPE_BEGIN,
1006 LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE,
1007 LIBINPUT_EVENT_GESTURE_SWIPE_END,
1008 LIBINPUT_EVENT_GESTURE_HOLD_BEGIN,
1009 LIBINPUT_EVENT_GESTURE_HOLD_END);
1010
1011 return event->finger_count;
1012 }
1013
1014 LIBINPUT_EXPORT int
libinput_event_gesture_get_cancelled(struct libinput_event_gesture * event)1015 libinput_event_gesture_get_cancelled(struct libinput_event_gesture *event)
1016 {
1017 require_event_type(libinput_event_get_context(&event->base),
1018 event->base.type,
1019 0,
1020 LIBINPUT_EVENT_GESTURE_PINCH_END,
1021 LIBINPUT_EVENT_GESTURE_SWIPE_END,
1022 LIBINPUT_EVENT_GESTURE_HOLD_END);
1023
1024 return event->cancelled;
1025 }
1026
1027 LIBINPUT_EXPORT double
libinput_event_gesture_get_dx(struct libinput_event_gesture * event)1028 libinput_event_gesture_get_dx(struct libinput_event_gesture *event)
1029 {
1030 require_event_type(libinput_event_get_context(&event->base),
1031 event->base.type,
1032 0.0,
1033 LIBINPUT_EVENT_GESTURE_PINCH_BEGIN,
1034 LIBINPUT_EVENT_GESTURE_PINCH_UPDATE,
1035 LIBINPUT_EVENT_GESTURE_PINCH_END,
1036 LIBINPUT_EVENT_GESTURE_SWIPE_BEGIN,
1037 LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE,
1038 LIBINPUT_EVENT_GESTURE_SWIPE_END);
1039
1040 return event->delta.x;
1041 }
1042
1043 LIBINPUT_EXPORT double
libinput_event_gesture_get_dy(struct libinput_event_gesture * event)1044 libinput_event_gesture_get_dy(struct libinput_event_gesture *event)
1045 {
1046 require_event_type(libinput_event_get_context(&event->base),
1047 event->base.type,
1048 0.0,
1049 LIBINPUT_EVENT_GESTURE_PINCH_BEGIN,
1050 LIBINPUT_EVENT_GESTURE_PINCH_UPDATE,
1051 LIBINPUT_EVENT_GESTURE_PINCH_END,
1052 LIBINPUT_EVENT_GESTURE_SWIPE_BEGIN,
1053 LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE,
1054 LIBINPUT_EVENT_GESTURE_SWIPE_END);
1055
1056 return event->delta.y;
1057 }
1058
1059 LIBINPUT_EXPORT double
libinput_event_gesture_get_dx_unaccelerated(struct libinput_event_gesture * event)1060 libinput_event_gesture_get_dx_unaccelerated(
1061 struct libinput_event_gesture *event)
1062 {
1063 require_event_type(libinput_event_get_context(&event->base),
1064 event->base.type,
1065 0.0,
1066 LIBINPUT_EVENT_GESTURE_PINCH_BEGIN,
1067 LIBINPUT_EVENT_GESTURE_PINCH_UPDATE,
1068 LIBINPUT_EVENT_GESTURE_PINCH_END,
1069 LIBINPUT_EVENT_GESTURE_SWIPE_BEGIN,
1070 LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE,
1071 LIBINPUT_EVENT_GESTURE_SWIPE_END);
1072
1073 return event->delta_unaccel.x;
1074 }
1075
1076 LIBINPUT_EXPORT double
libinput_event_gesture_get_dy_unaccelerated(struct libinput_event_gesture * event)1077 libinput_event_gesture_get_dy_unaccelerated(
1078 struct libinput_event_gesture *event)
1079 {
1080 require_event_type(libinput_event_get_context(&event->base),
1081 event->base.type,
1082 0.0,
1083 LIBINPUT_EVENT_GESTURE_PINCH_BEGIN,
1084 LIBINPUT_EVENT_GESTURE_PINCH_UPDATE,
1085 LIBINPUT_EVENT_GESTURE_PINCH_END,
1086 LIBINPUT_EVENT_GESTURE_SWIPE_BEGIN,
1087 LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE,
1088 LIBINPUT_EVENT_GESTURE_SWIPE_END);
1089
1090 return event->delta_unaccel.y;
1091 }
1092
1093 LIBINPUT_EXPORT double
libinput_event_gesture_get_scale(struct libinput_event_gesture * event)1094 libinput_event_gesture_get_scale(struct libinput_event_gesture *event)
1095 {
1096 require_event_type(libinput_event_get_context(&event->base),
1097 event->base.type,
1098 0.0,
1099 LIBINPUT_EVENT_GESTURE_PINCH_BEGIN,
1100 LIBINPUT_EVENT_GESTURE_PINCH_UPDATE,
1101 LIBINPUT_EVENT_GESTURE_PINCH_END);
1102
1103 return event->scale;
1104 }
1105
1106 LIBINPUT_EXPORT double
libinput_event_gesture_get_angle_delta(struct libinput_event_gesture * event)1107 libinput_event_gesture_get_angle_delta(struct libinput_event_gesture *event)
1108 {
1109 require_event_type(libinput_event_get_context(&event->base),
1110 event->base.type,
1111 0.0,
1112 LIBINPUT_EVENT_GESTURE_PINCH_BEGIN,
1113 LIBINPUT_EVENT_GESTURE_PINCH_UPDATE,
1114 LIBINPUT_EVENT_GESTURE_PINCH_END);
1115
1116 return event->angle;
1117 }
1118
1119 LIBINPUT_EXPORT int
libinput_event_tablet_tool_x_has_changed(struct libinput_event_tablet_tool * event)1120 libinput_event_tablet_tool_x_has_changed(
1121 struct libinput_event_tablet_tool *event)
1122 {
1123 require_event_type(libinput_event_get_context(&event->base),
1124 event->base.type,
1125 0,
1126 LIBINPUT_EVENT_TABLET_TOOL_AXIS,
1127 LIBINPUT_EVENT_TABLET_TOOL_TIP,
1128 LIBINPUT_EVENT_TABLET_TOOL_BUTTON,
1129 LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY);
1130
1131 return bit_is_set(event->changed_axes,
1132 LIBINPUT_TABLET_TOOL_AXIS_X);
1133 }
1134
1135 LIBINPUT_EXPORT int
libinput_event_tablet_tool_y_has_changed(struct libinput_event_tablet_tool * event)1136 libinput_event_tablet_tool_y_has_changed(
1137 struct libinput_event_tablet_tool *event)
1138 {
1139 require_event_type(libinput_event_get_context(&event->base),
1140 event->base.type,
1141 0,
1142 LIBINPUT_EVENT_TABLET_TOOL_AXIS,
1143 LIBINPUT_EVENT_TABLET_TOOL_TIP,
1144 LIBINPUT_EVENT_TABLET_TOOL_BUTTON,
1145 LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY);
1146
1147 return bit_is_set(event->changed_axes,
1148 LIBINPUT_TABLET_TOOL_AXIS_Y);
1149 }
1150
1151 LIBINPUT_EXPORT int
libinput_event_tablet_tool_pressure_has_changed(struct libinput_event_tablet_tool * event)1152 libinput_event_tablet_tool_pressure_has_changed(
1153 struct libinput_event_tablet_tool *event)
1154 {
1155 require_event_type(libinput_event_get_context(&event->base),
1156 event->base.type,
1157 0,
1158 LIBINPUT_EVENT_TABLET_TOOL_AXIS,
1159 LIBINPUT_EVENT_TABLET_TOOL_TIP,
1160 LIBINPUT_EVENT_TABLET_TOOL_BUTTON,
1161 LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY);
1162
1163 return bit_is_set(event->changed_axes,
1164 LIBINPUT_TABLET_TOOL_AXIS_PRESSURE);
1165 }
1166
1167 LIBINPUT_EXPORT int
libinput_event_tablet_tool_distance_has_changed(struct libinput_event_tablet_tool * event)1168 libinput_event_tablet_tool_distance_has_changed(
1169 struct libinput_event_tablet_tool *event)
1170 {
1171 require_event_type(libinput_event_get_context(&event->base),
1172 event->base.type,
1173 0,
1174 LIBINPUT_EVENT_TABLET_TOOL_AXIS,
1175 LIBINPUT_EVENT_TABLET_TOOL_TIP,
1176 LIBINPUT_EVENT_TABLET_TOOL_BUTTON,
1177 LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY);
1178
1179 return bit_is_set(event->changed_axes,
1180 LIBINPUT_TABLET_TOOL_AXIS_DISTANCE);
1181 }
1182
1183 LIBINPUT_EXPORT int
libinput_event_tablet_tool_tilt_x_has_changed(struct libinput_event_tablet_tool * event)1184 libinput_event_tablet_tool_tilt_x_has_changed(
1185 struct libinput_event_tablet_tool *event)
1186 {
1187 require_event_type(libinput_event_get_context(&event->base),
1188 event->base.type,
1189 0,
1190 LIBINPUT_EVENT_TABLET_TOOL_AXIS,
1191 LIBINPUT_EVENT_TABLET_TOOL_TIP,
1192 LIBINPUT_EVENT_TABLET_TOOL_BUTTON,
1193 LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY);
1194
1195 return bit_is_set(event->changed_axes,
1196 LIBINPUT_TABLET_TOOL_AXIS_TILT_X);
1197 }
1198
1199 LIBINPUT_EXPORT int
libinput_event_tablet_tool_tilt_y_has_changed(struct libinput_event_tablet_tool * event)1200 libinput_event_tablet_tool_tilt_y_has_changed(
1201 struct libinput_event_tablet_tool *event)
1202 {
1203 require_event_type(libinput_event_get_context(&event->base),
1204 event->base.type,
1205 0,
1206 LIBINPUT_EVENT_TABLET_TOOL_AXIS,
1207 LIBINPUT_EVENT_TABLET_TOOL_TIP,
1208 LIBINPUT_EVENT_TABLET_TOOL_BUTTON,
1209 LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY);
1210
1211 return bit_is_set(event->changed_axes,
1212 LIBINPUT_TABLET_TOOL_AXIS_TILT_Y);
1213 }
1214
1215 LIBINPUT_EXPORT int
libinput_event_tablet_tool_rotation_has_changed(struct libinput_event_tablet_tool * event)1216 libinput_event_tablet_tool_rotation_has_changed(
1217 struct libinput_event_tablet_tool *event)
1218 {
1219 require_event_type(libinput_event_get_context(&event->base),
1220 event->base.type,
1221 0,
1222 LIBINPUT_EVENT_TABLET_TOOL_AXIS,
1223 LIBINPUT_EVENT_TABLET_TOOL_TIP,
1224 LIBINPUT_EVENT_TABLET_TOOL_BUTTON,
1225 LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY);
1226
1227 return bit_is_set(event->changed_axes,
1228 LIBINPUT_TABLET_TOOL_AXIS_ROTATION_Z);
1229 }
1230
1231 LIBINPUT_EXPORT int
libinput_event_tablet_tool_slider_has_changed(struct libinput_event_tablet_tool * event)1232 libinput_event_tablet_tool_slider_has_changed(
1233 struct libinput_event_tablet_tool *event)
1234 {
1235 require_event_type(libinput_event_get_context(&event->base),
1236 event->base.type,
1237 0,
1238 LIBINPUT_EVENT_TABLET_TOOL_AXIS,
1239 LIBINPUT_EVENT_TABLET_TOOL_TIP,
1240 LIBINPUT_EVENT_TABLET_TOOL_BUTTON,
1241 LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY);
1242
1243 return bit_is_set(event->changed_axes,
1244 LIBINPUT_TABLET_TOOL_AXIS_SLIDER);
1245 }
1246
1247 LIBINPUT_EXPORT int
libinput_event_tablet_tool_size_major_has_changed(struct libinput_event_tablet_tool * event)1248 libinput_event_tablet_tool_size_major_has_changed(
1249 struct libinput_event_tablet_tool *event)
1250 {
1251 require_event_type(libinput_event_get_context(&event->base),
1252 event->base.type,
1253 0,
1254 LIBINPUT_EVENT_TABLET_TOOL_AXIS,
1255 LIBINPUT_EVENT_TABLET_TOOL_TIP,
1256 LIBINPUT_EVENT_TABLET_TOOL_BUTTON,
1257 LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY);
1258
1259 return bit_is_set(event->changed_axes,
1260 LIBINPUT_TABLET_TOOL_AXIS_SIZE_MAJOR);
1261 }
1262
1263 LIBINPUT_EXPORT int
libinput_event_tablet_tool_size_minor_has_changed(struct libinput_event_tablet_tool * event)1264 libinput_event_tablet_tool_size_minor_has_changed(
1265 struct libinput_event_tablet_tool *event)
1266 {
1267 require_event_type(libinput_event_get_context(&event->base),
1268 event->base.type,
1269 0,
1270 LIBINPUT_EVENT_TABLET_TOOL_AXIS,
1271 LIBINPUT_EVENT_TABLET_TOOL_TIP,
1272 LIBINPUT_EVENT_TABLET_TOOL_BUTTON,
1273 LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY);
1274
1275 return bit_is_set(event->changed_axes,
1276 LIBINPUT_TABLET_TOOL_AXIS_SIZE_MINOR);
1277 }
1278
1279 LIBINPUT_EXPORT int
libinput_event_tablet_tool_wheel_has_changed(struct libinput_event_tablet_tool * event)1280 libinput_event_tablet_tool_wheel_has_changed(
1281 struct libinput_event_tablet_tool *event)
1282 {
1283 require_event_type(libinput_event_get_context(&event->base),
1284 event->base.type,
1285 0,
1286 LIBINPUT_EVENT_TABLET_TOOL_AXIS,
1287 LIBINPUT_EVENT_TABLET_TOOL_TIP,
1288 LIBINPUT_EVENT_TABLET_TOOL_BUTTON,
1289 LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY);
1290
1291 return bit_is_set(event->changed_axes,
1292 LIBINPUT_TABLET_TOOL_AXIS_REL_WHEEL);
1293 }
1294
1295 LIBINPUT_EXPORT double
libinput_event_tablet_tool_get_x(struct libinput_event_tablet_tool * event)1296 libinput_event_tablet_tool_get_x(struct libinput_event_tablet_tool *event)
1297 {
1298 struct evdev_device *device = evdev_device(event->base.device);
1299
1300 require_event_type(libinput_event_get_context(&event->base),
1301 event->base.type,
1302 0,
1303 LIBINPUT_EVENT_TABLET_TOOL_AXIS,
1304 LIBINPUT_EVENT_TABLET_TOOL_TIP,
1305 LIBINPUT_EVENT_TABLET_TOOL_BUTTON,
1306 LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY);
1307
1308 return evdev_convert_to_mm(device->abs.absinfo_x,
1309 event->axes.point.x);
1310 }
1311
1312 LIBINPUT_EXPORT double
libinput_event_tablet_tool_get_y(struct libinput_event_tablet_tool * event)1313 libinput_event_tablet_tool_get_y(struct libinput_event_tablet_tool *event)
1314 {
1315 struct evdev_device *device = evdev_device(event->base.device);
1316
1317 require_event_type(libinput_event_get_context(&event->base),
1318 event->base.type,
1319 0,
1320 LIBINPUT_EVENT_TABLET_TOOL_AXIS,
1321 LIBINPUT_EVENT_TABLET_TOOL_TIP,
1322 LIBINPUT_EVENT_TABLET_TOOL_BUTTON,
1323 LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY);
1324
1325 return evdev_convert_to_mm(device->abs.absinfo_y,
1326 event->axes.point.y);
1327 }
1328
1329 LIBINPUT_EXPORT double
libinput_event_tablet_tool_get_dx(struct libinput_event_tablet_tool * event)1330 libinput_event_tablet_tool_get_dx(struct libinput_event_tablet_tool *event)
1331 {
1332 require_event_type(libinput_event_get_context(&event->base),
1333 event->base.type,
1334 0,
1335 LIBINPUT_EVENT_TABLET_TOOL_AXIS,
1336 LIBINPUT_EVENT_TABLET_TOOL_TIP,
1337 LIBINPUT_EVENT_TABLET_TOOL_BUTTON,
1338 LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY);
1339
1340 return event->axes.delta.x;
1341 }
1342
1343 LIBINPUT_EXPORT double
libinput_event_tablet_tool_get_dy(struct libinput_event_tablet_tool * event)1344 libinput_event_tablet_tool_get_dy(struct libinput_event_tablet_tool *event)
1345 {
1346 require_event_type(libinput_event_get_context(&event->base),
1347 event->base.type,
1348 0,
1349 LIBINPUT_EVENT_TABLET_TOOL_AXIS,
1350 LIBINPUT_EVENT_TABLET_TOOL_TIP,
1351 LIBINPUT_EVENT_TABLET_TOOL_BUTTON,
1352 LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY);
1353
1354 return event->axes.delta.y;
1355 }
1356
1357 LIBINPUT_EXPORT double
libinput_event_tablet_tool_get_pressure(struct libinput_event_tablet_tool * event)1358 libinput_event_tablet_tool_get_pressure(struct libinput_event_tablet_tool *event)
1359 {
1360 require_event_type(libinput_event_get_context(&event->base),
1361 event->base.type,
1362 0,
1363 LIBINPUT_EVENT_TABLET_TOOL_AXIS,
1364 LIBINPUT_EVENT_TABLET_TOOL_TIP,
1365 LIBINPUT_EVENT_TABLET_TOOL_BUTTON,
1366 LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY);
1367
1368 return event->axes.pressure;
1369 }
1370
1371 LIBINPUT_EXPORT double
libinput_event_tablet_tool_get_distance(struct libinput_event_tablet_tool * event)1372 libinput_event_tablet_tool_get_distance(struct libinput_event_tablet_tool *event)
1373 {
1374 require_event_type(libinput_event_get_context(&event->base),
1375 event->base.type,
1376 0,
1377 LIBINPUT_EVENT_TABLET_TOOL_AXIS,
1378 LIBINPUT_EVENT_TABLET_TOOL_TIP,
1379 LIBINPUT_EVENT_TABLET_TOOL_BUTTON,
1380 LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY);
1381
1382 return event->axes.distance;
1383 }
1384
1385 LIBINPUT_EXPORT double
libinput_event_tablet_tool_get_tilt_x(struct libinput_event_tablet_tool * event)1386 libinput_event_tablet_tool_get_tilt_x(struct libinput_event_tablet_tool *event)
1387 {
1388 require_event_type(libinput_event_get_context(&event->base),
1389 event->base.type,
1390 0,
1391 LIBINPUT_EVENT_TABLET_TOOL_AXIS,
1392 LIBINPUT_EVENT_TABLET_TOOL_TIP,
1393 LIBINPUT_EVENT_TABLET_TOOL_BUTTON,
1394 LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY);
1395
1396 return event->axes.tilt.x;
1397 }
1398
1399 LIBINPUT_EXPORT double
libinput_event_tablet_tool_get_tilt_y(struct libinput_event_tablet_tool * event)1400 libinput_event_tablet_tool_get_tilt_y(struct libinput_event_tablet_tool *event)
1401 {
1402 require_event_type(libinput_event_get_context(&event->base),
1403 event->base.type,
1404 0,
1405 LIBINPUT_EVENT_TABLET_TOOL_AXIS,
1406 LIBINPUT_EVENT_TABLET_TOOL_TIP,
1407 LIBINPUT_EVENT_TABLET_TOOL_BUTTON,
1408 LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY);
1409
1410 return event->axes.tilt.y;
1411 }
1412
1413 LIBINPUT_EXPORT double
libinput_event_tablet_tool_get_rotation(struct libinput_event_tablet_tool * event)1414 libinput_event_tablet_tool_get_rotation(struct libinput_event_tablet_tool *event)
1415 {
1416 require_event_type(libinput_event_get_context(&event->base),
1417 event->base.type,
1418 0,
1419 LIBINPUT_EVENT_TABLET_TOOL_AXIS,
1420 LIBINPUT_EVENT_TABLET_TOOL_TIP,
1421 LIBINPUT_EVENT_TABLET_TOOL_BUTTON,
1422 LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY);
1423
1424 return event->axes.rotation;
1425 }
1426
1427 LIBINPUT_EXPORT double
libinput_event_tablet_tool_get_slider_position(struct libinput_event_tablet_tool * event)1428 libinput_event_tablet_tool_get_slider_position(struct libinput_event_tablet_tool *event)
1429 {
1430 require_event_type(libinput_event_get_context(&event->base),
1431 event->base.type,
1432 0,
1433 LIBINPUT_EVENT_TABLET_TOOL_AXIS,
1434 LIBINPUT_EVENT_TABLET_TOOL_TIP,
1435 LIBINPUT_EVENT_TABLET_TOOL_BUTTON,
1436 LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY);
1437
1438 return event->axes.slider;
1439 }
1440
1441 LIBINPUT_EXPORT double
libinput_event_tablet_tool_get_size_major(struct libinput_event_tablet_tool * event)1442 libinput_event_tablet_tool_get_size_major(struct libinput_event_tablet_tool *event)
1443 {
1444 require_event_type(libinput_event_get_context(&event->base),
1445 event->base.type,
1446 0,
1447 LIBINPUT_EVENT_TABLET_TOOL_AXIS,
1448 LIBINPUT_EVENT_TABLET_TOOL_TIP,
1449 LIBINPUT_EVENT_TABLET_TOOL_BUTTON,
1450 LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY);
1451
1452 return event->axes.size.major;
1453 }
1454
1455 LIBINPUT_EXPORT double
libinput_event_tablet_tool_get_size_minor(struct libinput_event_tablet_tool * event)1456 libinput_event_tablet_tool_get_size_minor(struct libinput_event_tablet_tool *event)
1457 {
1458 require_event_type(libinput_event_get_context(&event->base),
1459 event->base.type,
1460 0,
1461 LIBINPUT_EVENT_TABLET_TOOL_AXIS,
1462 LIBINPUT_EVENT_TABLET_TOOL_TIP,
1463 LIBINPUT_EVENT_TABLET_TOOL_BUTTON,
1464 LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY);
1465
1466 return event->axes.size.minor;
1467 }
1468
1469 LIBINPUT_EXPORT double
libinput_event_tablet_tool_get_wheel_delta(struct libinput_event_tablet_tool * event)1470 libinput_event_tablet_tool_get_wheel_delta(struct libinput_event_tablet_tool *event)
1471 {
1472 require_event_type(libinput_event_get_context(&event->base),
1473 event->base.type,
1474 0,
1475 LIBINPUT_EVENT_TABLET_TOOL_AXIS,
1476 LIBINPUT_EVENT_TABLET_TOOL_TIP,
1477 LIBINPUT_EVENT_TABLET_TOOL_BUTTON,
1478 LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY);
1479
1480 return event->axes.wheel;
1481 }
1482
1483 LIBINPUT_EXPORT int
libinput_event_tablet_tool_get_wheel_delta_discrete(struct libinput_event_tablet_tool * event)1484 libinput_event_tablet_tool_get_wheel_delta_discrete(
1485 struct libinput_event_tablet_tool *event)
1486 {
1487 require_event_type(libinput_event_get_context(&event->base),
1488 event->base.type,
1489 0,
1490 LIBINPUT_EVENT_TABLET_TOOL_AXIS,
1491 LIBINPUT_EVENT_TABLET_TOOL_TIP,
1492 LIBINPUT_EVENT_TABLET_TOOL_BUTTON,
1493 LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY);
1494
1495 return event->axes.wheel_discrete;
1496 }
1497
1498 LIBINPUT_EXPORT double
libinput_event_tablet_tool_get_x_transformed(struct libinput_event_tablet_tool * event,uint32_t width)1499 libinput_event_tablet_tool_get_x_transformed(struct libinput_event_tablet_tool *event,
1500 uint32_t width)
1501 {
1502 struct evdev_device *device = evdev_device(event->base.device);
1503
1504 require_event_type(libinput_event_get_context(&event->base),
1505 event->base.type,
1506 0,
1507 LIBINPUT_EVENT_TABLET_TOOL_AXIS,
1508 LIBINPUT_EVENT_TABLET_TOOL_TIP,
1509 LIBINPUT_EVENT_TABLET_TOOL_BUTTON,
1510 LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY);
1511
1512 return evdev_device_transform_x(device,
1513 event->axes.point.x,
1514 width);
1515 }
1516
1517 LIBINPUT_EXPORT double
libinput_event_tablet_tool_get_y_transformed(struct libinput_event_tablet_tool * event,uint32_t height)1518 libinput_event_tablet_tool_get_y_transformed(struct libinput_event_tablet_tool *event,
1519 uint32_t height)
1520 {
1521 struct evdev_device *device = evdev_device(event->base.device);
1522
1523 require_event_type(libinput_event_get_context(&event->base),
1524 event->base.type,
1525 0,
1526 LIBINPUT_EVENT_TABLET_TOOL_AXIS,
1527 LIBINPUT_EVENT_TABLET_TOOL_TIP,
1528 LIBINPUT_EVENT_TABLET_TOOL_BUTTON,
1529 LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY);
1530
1531 return evdev_device_transform_y(device,
1532 event->axes.point.y,
1533 height);
1534 }
1535
1536 LIBINPUT_EXPORT struct libinput_tablet_tool *
libinput_event_tablet_tool_get_tool(struct libinput_event_tablet_tool * event)1537 libinput_event_tablet_tool_get_tool(struct libinput_event_tablet_tool *event)
1538 {
1539 require_event_type(libinput_event_get_context(&event->base),
1540 event->base.type,
1541 0,
1542 LIBINPUT_EVENT_TABLET_TOOL_AXIS,
1543 LIBINPUT_EVENT_TABLET_TOOL_TIP,
1544 LIBINPUT_EVENT_TABLET_TOOL_BUTTON,
1545 LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY);
1546
1547 return event->tool;
1548 }
1549
1550 LIBINPUT_EXPORT enum libinput_tablet_tool_proximity_state
libinput_event_tablet_tool_get_proximity_state(struct libinput_event_tablet_tool * event)1551 libinput_event_tablet_tool_get_proximity_state(struct libinput_event_tablet_tool *event)
1552 {
1553 require_event_type(libinput_event_get_context(&event->base),
1554 event->base.type,
1555 0,
1556 LIBINPUT_EVENT_TABLET_TOOL_AXIS,
1557 LIBINPUT_EVENT_TABLET_TOOL_TIP,
1558 LIBINPUT_EVENT_TABLET_TOOL_BUTTON,
1559 LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY);
1560
1561 return event->proximity_state;
1562 }
1563
1564 LIBINPUT_EXPORT enum libinput_tablet_tool_tip_state
libinput_event_tablet_tool_get_tip_state(struct libinput_event_tablet_tool * event)1565 libinput_event_tablet_tool_get_tip_state(struct libinput_event_tablet_tool *event)
1566 {
1567 require_event_type(libinput_event_get_context(&event->base),
1568 event->base.type,
1569 0,
1570 LIBINPUT_EVENT_TABLET_TOOL_AXIS,
1571 LIBINPUT_EVENT_TABLET_TOOL_TIP,
1572 LIBINPUT_EVENT_TABLET_TOOL_BUTTON,
1573 LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY);
1574
1575 return event->tip_state;
1576 }
1577
1578 LIBINPUT_EXPORT uint32_t
libinput_event_tablet_tool_get_time(struct libinput_event_tablet_tool * event)1579 libinput_event_tablet_tool_get_time(struct libinput_event_tablet_tool *event)
1580 {
1581 require_event_type(libinput_event_get_context(&event->base),
1582 event->base.type,
1583 0,
1584 LIBINPUT_EVENT_TABLET_TOOL_AXIS,
1585 LIBINPUT_EVENT_TABLET_TOOL_TIP,
1586 LIBINPUT_EVENT_TABLET_TOOL_BUTTON,
1587 LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY);
1588
1589 return us2ms(event->time);
1590 }
1591
1592 LIBINPUT_EXPORT uint64_t
libinput_event_tablet_tool_get_time_usec(struct libinput_event_tablet_tool * event)1593 libinput_event_tablet_tool_get_time_usec(struct libinput_event_tablet_tool *event)
1594 {
1595 require_event_type(libinput_event_get_context(&event->base),
1596 event->base.type,
1597 0,
1598 LIBINPUT_EVENT_TABLET_TOOL_AXIS,
1599 LIBINPUT_EVENT_TABLET_TOOL_TIP,
1600 LIBINPUT_EVENT_TABLET_TOOL_BUTTON,
1601 LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY);
1602
1603 return event->time;
1604 }
1605
1606 LIBINPUT_EXPORT uint32_t
libinput_event_tablet_tool_get_button(struct libinput_event_tablet_tool * event)1607 libinput_event_tablet_tool_get_button(struct libinput_event_tablet_tool *event)
1608 {
1609 require_event_type(libinput_event_get_context(&event->base),
1610 event->base.type,
1611 0,
1612 LIBINPUT_EVENT_TABLET_TOOL_BUTTON);
1613
1614 return event->button;
1615 }
1616
1617 LIBINPUT_EXPORT enum libinput_button_state
libinput_event_tablet_tool_get_button_state(struct libinput_event_tablet_tool * event)1618 libinput_event_tablet_tool_get_button_state(struct libinput_event_tablet_tool *event)
1619 {
1620 require_event_type(libinput_event_get_context(&event->base),
1621 event->base.type,
1622 0,
1623 LIBINPUT_EVENT_TABLET_TOOL_BUTTON);
1624
1625 return event->state;
1626 }
1627
1628 LIBINPUT_EXPORT uint32_t
libinput_event_tablet_tool_get_seat_button_count(struct libinput_event_tablet_tool * event)1629 libinput_event_tablet_tool_get_seat_button_count(struct libinput_event_tablet_tool *event)
1630 {
1631 require_event_type(libinput_event_get_context(&event->base),
1632 event->base.type,
1633 0,
1634 LIBINPUT_EVENT_TABLET_TOOL_BUTTON);
1635
1636 return event->seat_button_count;
1637 }
1638
1639 LIBINPUT_EXPORT enum libinput_tablet_tool_type
libinput_tablet_tool_get_type(struct libinput_tablet_tool * tool)1640 libinput_tablet_tool_get_type(struct libinput_tablet_tool *tool)
1641 {
1642 return tool->type;
1643 }
1644
1645 LIBINPUT_EXPORT uint64_t
libinput_tablet_tool_get_tool_id(struct libinput_tablet_tool * tool)1646 libinput_tablet_tool_get_tool_id(struct libinput_tablet_tool *tool)
1647 {
1648 return tool->tool_id;
1649 }
1650
1651 LIBINPUT_EXPORT int
libinput_tablet_tool_is_unique(struct libinput_tablet_tool * tool)1652 libinput_tablet_tool_is_unique(struct libinput_tablet_tool *tool)
1653 {
1654 return tool->serial != 0;
1655 }
1656
1657 LIBINPUT_EXPORT uint64_t
libinput_tablet_tool_get_serial(struct libinput_tablet_tool * tool)1658 libinput_tablet_tool_get_serial(struct libinput_tablet_tool *tool)
1659 {
1660 return tool->serial;
1661 }
1662
1663 LIBINPUT_EXPORT int
libinput_tablet_tool_has_pressure(struct libinput_tablet_tool * tool)1664 libinput_tablet_tool_has_pressure(struct libinput_tablet_tool *tool)
1665 {
1666 return bit_is_set(tool->axis_caps,
1667 LIBINPUT_TABLET_TOOL_AXIS_PRESSURE);
1668 }
1669
1670 LIBINPUT_EXPORT int
libinput_tablet_tool_has_distance(struct libinput_tablet_tool * tool)1671 libinput_tablet_tool_has_distance(struct libinput_tablet_tool *tool)
1672 {
1673 return bit_is_set(tool->axis_caps,
1674 LIBINPUT_TABLET_TOOL_AXIS_DISTANCE);
1675 }
1676
1677 LIBINPUT_EXPORT int
libinput_tablet_tool_has_tilt(struct libinput_tablet_tool * tool)1678 libinput_tablet_tool_has_tilt(struct libinput_tablet_tool *tool)
1679 {
1680 return bit_is_set(tool->axis_caps,
1681 LIBINPUT_TABLET_TOOL_AXIS_TILT_X);
1682 }
1683
1684 LIBINPUT_EXPORT int
libinput_tablet_tool_has_rotation(struct libinput_tablet_tool * tool)1685 libinput_tablet_tool_has_rotation(struct libinput_tablet_tool *tool)
1686 {
1687 return bit_is_set(tool->axis_caps,
1688 LIBINPUT_TABLET_TOOL_AXIS_ROTATION_Z);
1689 }
1690
1691 LIBINPUT_EXPORT int
libinput_tablet_tool_has_slider(struct libinput_tablet_tool * tool)1692 libinput_tablet_tool_has_slider(struct libinput_tablet_tool *tool)
1693 {
1694 return bit_is_set(tool->axis_caps,
1695 LIBINPUT_TABLET_TOOL_AXIS_SLIDER);
1696 }
1697
1698 LIBINPUT_EXPORT int
libinput_tablet_tool_has_wheel(struct libinput_tablet_tool * tool)1699 libinput_tablet_tool_has_wheel(struct libinput_tablet_tool *tool)
1700 {
1701 return bit_is_set(tool->axis_caps,
1702 LIBINPUT_TABLET_TOOL_AXIS_REL_WHEEL);
1703 }
1704
1705 LIBINPUT_EXPORT int
libinput_tablet_tool_has_size(struct libinput_tablet_tool * tool)1706 libinput_tablet_tool_has_size(struct libinput_tablet_tool *tool)
1707 {
1708 return bit_is_set(tool->axis_caps,
1709 LIBINPUT_TABLET_TOOL_AXIS_SIZE_MAJOR);
1710 }
1711
1712 LIBINPUT_EXPORT int
libinput_tablet_tool_has_button(struct libinput_tablet_tool * tool,uint32_t code)1713 libinput_tablet_tool_has_button(struct libinput_tablet_tool *tool,
1714 uint32_t code)
1715 {
1716 if (NCHARS(code) > sizeof(tool->buttons))
1717 return 0;
1718
1719 return bit_is_set(tool->buttons, code);
1720 }
1721
1722 LIBINPUT_EXPORT void
libinput_tablet_tool_set_user_data(struct libinput_tablet_tool * tool,void * user_data)1723 libinput_tablet_tool_set_user_data(struct libinput_tablet_tool *tool,
1724 void *user_data)
1725 {
1726 tool->user_data = user_data;
1727 }
1728
1729 LIBINPUT_EXPORT void *
libinput_tablet_tool_get_user_data(struct libinput_tablet_tool * tool)1730 libinput_tablet_tool_get_user_data(struct libinput_tablet_tool *tool)
1731 {
1732 return tool->user_data;
1733 }
1734
1735 LIBINPUT_EXPORT struct libinput_tablet_tool *
libinput_tablet_tool_ref(struct libinput_tablet_tool * tool)1736 libinput_tablet_tool_ref(struct libinput_tablet_tool *tool)
1737 {
1738 tool->refcount++;
1739 return tool;
1740 }
1741
1742 LIBINPUT_EXPORT struct libinput_tablet_tool *
libinput_tablet_tool_unref(struct libinput_tablet_tool * tool)1743 libinput_tablet_tool_unref(struct libinput_tablet_tool *tool)
1744 {
1745 assert(tool->refcount > 0);
1746
1747 tool->refcount--;
1748 if (tool->refcount > 0)
1749 return tool;
1750
1751 list_remove(&tool->link);
1752 free(tool);
1753 return NULL;
1754 }
1755
1756 LIBINPUT_EXPORT struct libinput_event *
libinput_event_switch_get_base_event(struct libinput_event_switch * event)1757 libinput_event_switch_get_base_event(struct libinput_event_switch *event)
1758 {
1759 require_event_type(libinput_event_get_context(&event->base),
1760 event->base.type,
1761 NULL,
1762 LIBINPUT_EVENT_SWITCH_TOGGLE);
1763
1764 return &event->base;
1765 }
1766
1767 LIBINPUT_EXPORT enum libinput_switch
libinput_event_switch_get_switch(struct libinput_event_switch * event)1768 libinput_event_switch_get_switch(struct libinput_event_switch *event)
1769 {
1770 require_event_type(libinput_event_get_context(&event->base),
1771 event->base.type,
1772 0,
1773 LIBINPUT_EVENT_SWITCH_TOGGLE);
1774
1775 return event->sw;
1776 }
1777
1778 LIBINPUT_EXPORT enum libinput_switch_state
libinput_event_switch_get_switch_state(struct libinput_event_switch * event)1779 libinput_event_switch_get_switch_state(struct libinput_event_switch *event)
1780 {
1781 require_event_type(libinput_event_get_context(&event->base),
1782 event->base.type,
1783 0,
1784 LIBINPUT_EVENT_SWITCH_TOGGLE);
1785
1786 return event->state;
1787 }
1788
1789 LIBINPUT_EXPORT uint32_t
libinput_event_switch_get_time(struct libinput_event_switch * event)1790 libinput_event_switch_get_time(struct libinput_event_switch *event)
1791 {
1792 require_event_type(libinput_event_get_context(&event->base),
1793 event->base.type,
1794 0,
1795 LIBINPUT_EVENT_SWITCH_TOGGLE);
1796
1797 return us2ms(event->time);
1798 }
1799
1800 LIBINPUT_EXPORT uint64_t
libinput_event_switch_get_time_usec(struct libinput_event_switch * event)1801 libinput_event_switch_get_time_usec(struct libinput_event_switch *event)
1802 {
1803 require_event_type(libinput_event_get_context(&event->base),
1804 event->base.type,
1805 0,
1806 LIBINPUT_EVENT_SWITCH_TOGGLE);
1807
1808 return event->time;
1809 }
1810
1811 struct libinput_source *
libinput_add_fd(struct libinput * libinput,int fd,libinput_source_dispatch_t dispatch,void * user_data)1812 libinput_add_fd(struct libinput *libinput,
1813 int fd,
1814 libinput_source_dispatch_t dispatch,
1815 void *user_data)
1816 {
1817 struct libinput_source *source;
1818 struct epoll_event ep;
1819
1820 source = zalloc(sizeof *source);
1821 source->dispatch = dispatch;
1822 source->user_data = user_data;
1823 source->fd = fd;
1824
1825 memset(&ep, 0, sizeof ep);
1826 ep.events = EPOLLIN;
1827 ep.data.ptr = source;
1828
1829 if (epoll_ctl(libinput->epoll_fd, EPOLL_CTL_ADD, fd, &ep) < 0) {
1830 free(source);
1831 return NULL;
1832 }
1833
1834 return source;
1835 }
1836
1837 void
libinput_remove_source(struct libinput * libinput,struct libinput_source * source)1838 libinput_remove_source(struct libinput *libinput,
1839 struct libinput_source *source)
1840 {
1841 epoll_ctl(libinput->epoll_fd, EPOLL_CTL_DEL, source->fd, NULL);
1842 source->fd = -1;
1843 list_insert(&libinput->source_destroy_list, &source->link);
1844 }
1845
1846 int
libinput_init(struct libinput * libinput,const struct libinput_interface * interface,const struct libinput_interface_backend * interface_backend,void * user_data)1847 libinput_init(struct libinput *libinput,
1848 const struct libinput_interface *interface,
1849 const struct libinput_interface_backend *interface_backend,
1850 void *user_data)
1851 {
1852 assert(interface->open_restricted != NULL);
1853 assert(interface->close_restricted != NULL);
1854
1855 libinput->epoll_fd = epoll_create1(EPOLL_CLOEXEC);
1856 if (libinput->epoll_fd < 0)
1857 return -1;
1858
1859 libinput->events_len = 4;
1860 libinput->events = zalloc(libinput->events_len * sizeof(*libinput->events));
1861 libinput->log_handler = libinput_default_log_func;
1862 libinput->log_priority = LIBINPUT_LOG_PRIORITY_ERROR;
1863 libinput->interface = interface;
1864 libinput->interface_backend = interface_backend;
1865 libinput->user_data = user_data;
1866 libinput->refcount = 1;
1867 list_init(&libinput->source_destroy_list);
1868 list_init(&libinput->seat_list);
1869 list_init(&libinput->device_group_list);
1870 list_init(&libinput->tool_list);
1871
1872 if (libinput_timer_subsys_init(libinput) != 0) {
1873 free(libinput->events);
1874 close(libinput->epoll_fd);
1875 return -1;
1876 }
1877
1878 return 0;
1879 }
1880
1881 void
libinput_init_quirks(struct libinput * libinput)1882 libinput_init_quirks(struct libinput *libinput)
1883 {
1884 const char *data_path,
1885 *override_file = NULL;
1886 struct quirks_context *quirks;
1887
1888 if (libinput->quirks_initialized)
1889 return;
1890
1891 /* If we fail, we'll fail next time too */
1892 libinput->quirks_initialized = true;
1893
1894 data_path = getenv("LIBINPUT_QUIRKS_DIR");
1895 if (!data_path) {
1896 data_path = LIBINPUT_QUIRKS_DIR;
1897 override_file = LIBINPUT_QUIRKS_OVERRIDE_FILE;
1898 }
1899
1900 quirks = quirks_init_subsystem(data_path,
1901 override_file,
1902 log_msg_va,
1903 libinput,
1904 QLOG_LIBINPUT_LOGGING);
1905 if (!quirks) {
1906 log_error(libinput,
1907 "Failed to load the device quirks from %s%s%s. "
1908 "This will negatively affect device behavior. "
1909 "See %s/device-quirks.html for details.\n",
1910 data_path,
1911 override_file ? " and " : "",
1912 override_file ? override_file : "",
1913 HTTP_DOC_LINK
1914 );
1915 return;
1916 }
1917
1918 libinput->quirks = quirks;
1919 }
1920
1921 static void
1922 libinput_device_destroy(struct libinput_device *device);
1923
1924 static void
1925 libinput_seat_destroy(struct libinput_seat *seat);
1926
1927 static void
libinput_drop_destroyed_sources(struct libinput * libinput)1928 libinput_drop_destroyed_sources(struct libinput *libinput)
1929 {
1930 struct libinput_source *source;
1931
1932 list_for_each_safe(source, &libinput->source_destroy_list, link)
1933 free(source);
1934 list_init(&libinput->source_destroy_list);
1935 }
1936
1937 LIBINPUT_EXPORT struct libinput *
libinput_ref(struct libinput * libinput)1938 libinput_ref(struct libinput *libinput)
1939 {
1940 libinput->refcount++;
1941 return libinput;
1942 }
1943
1944 LIBINPUT_EXPORT struct libinput *
libinput_unref(struct libinput * libinput)1945 libinput_unref(struct libinput *libinput)
1946 {
1947 struct libinput_event *event;
1948 struct libinput_device *device;
1949 struct libinput_seat *seat;
1950 struct libinput_tablet_tool *tool;
1951 struct libinput_device_group *group;
1952
1953 if (libinput == NULL)
1954 return NULL;
1955
1956 assert(libinput->refcount > 0);
1957 libinput->refcount--;
1958 if (libinput->refcount > 0)
1959 return libinput;
1960
1961 libinput_suspend(libinput);
1962
1963 libinput->interface_backend->destroy(libinput);
1964
1965 while ((event = libinput_get_event(libinput)))
1966 libinput_event_destroy(event);
1967
1968 free(libinput->events);
1969
1970 list_for_each_safe(seat, &libinput->seat_list, link) {
1971 list_for_each_safe(device,
1972 &seat->devices_list,
1973 link)
1974 libinput_device_destroy(device);
1975
1976 libinput_seat_destroy(seat);
1977 }
1978
1979 list_for_each_safe(group,
1980 &libinput->device_group_list,
1981 link) {
1982 libinput_device_group_destroy(group);
1983 }
1984
1985 list_for_each_safe(tool, &libinput->tool_list, link) {
1986 libinput_tablet_tool_unref(tool);
1987 }
1988
1989 libinput_timer_subsys_destroy(libinput);
1990 libinput_drop_destroyed_sources(libinput);
1991 quirks_context_unref(libinput->quirks);
1992 close(libinput->epoll_fd);
1993 free(libinput);
1994
1995 return NULL;
1996 }
1997
1998 static void
libinput_event_tablet_tool_destroy(struct libinput_event_tablet_tool * event)1999 libinput_event_tablet_tool_destroy(struct libinput_event_tablet_tool *event)
2000 {
2001 libinput_tablet_tool_unref(event->tool);
2002 }
2003
2004 static void
libinput_event_tablet_pad_destroy(struct libinput_event_tablet_pad * event)2005 libinput_event_tablet_pad_destroy(struct libinput_event_tablet_pad *event)
2006 {
2007 if (event->base.type != LIBINPUT_EVENT_TABLET_PAD_KEY)
2008 libinput_tablet_pad_mode_group_unref(event->mode_group);
2009 }
2010
2011 LIBINPUT_EXPORT void
libinput_event_destroy(struct libinput_event * event)2012 libinput_event_destroy(struct libinput_event *event)
2013 {
2014 if (event == NULL)
2015 return;
2016
2017 switch(event->type) {
2018 case LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY:
2019 case LIBINPUT_EVENT_TABLET_TOOL_AXIS:
2020 case LIBINPUT_EVENT_TABLET_TOOL_TIP:
2021 case LIBINPUT_EVENT_TABLET_TOOL_BUTTON:
2022 libinput_event_tablet_tool_destroy(
2023 libinput_event_get_tablet_tool_event(event));
2024 break;
2025 case LIBINPUT_EVENT_TABLET_PAD_RING:
2026 case LIBINPUT_EVENT_TABLET_PAD_STRIP:
2027 case LIBINPUT_EVENT_TABLET_PAD_BUTTON:
2028 case LIBINPUT_EVENT_TABLET_PAD_KEY:
2029 libinput_event_tablet_pad_destroy(
2030 libinput_event_get_tablet_pad_event(event));
2031 break;
2032 default:
2033 break;
2034 }
2035
2036 if (event->device)
2037 libinput_device_unref(event->device);
2038
2039 free(event);
2040 }
2041
2042 int
open_restricted(struct libinput * libinput,const char * path,int flags)2043 open_restricted(struct libinput *libinput,
2044 const char *path, int flags)
2045 {
2046 return libinput->interface->open_restricted(path,
2047 flags,
2048 libinput->user_data);
2049 }
2050
2051 void
close_restricted(struct libinput * libinput,int fd)2052 close_restricted(struct libinput *libinput, int fd)
2053 {
2054 libinput->interface->close_restricted(fd, libinput->user_data);
2055 }
2056
2057 bool
ignore_litest_test_suite_device(struct udev_device * device)2058 ignore_litest_test_suite_device(struct udev_device *device)
2059 {
2060 if (!getenv("LIBINPUT_RUNNING_TEST_SUITE") &&
2061 udev_device_get_property_value(device, "LIBINPUT_TEST_DEVICE"))
2062 return true;
2063
2064 return false;
2065 }
2066
2067 void
libinput_seat_init(struct libinput_seat * seat,struct libinput * libinput,const char * physical_name,const char * logical_name,libinput_seat_destroy_func destroy)2068 libinput_seat_init(struct libinput_seat *seat,
2069 struct libinput *libinput,
2070 const char *physical_name,
2071 const char *logical_name,
2072 libinput_seat_destroy_func destroy)
2073 {
2074 seat->refcount = 1;
2075 seat->libinput = libinput;
2076 seat->physical_name = safe_strdup(physical_name);
2077 seat->logical_name = safe_strdup(logical_name);
2078 seat->destroy = destroy;
2079 list_init(&seat->devices_list);
2080 list_insert(&libinput->seat_list, &seat->link);
2081 }
2082
2083 LIBINPUT_EXPORT struct libinput_seat *
libinput_seat_ref(struct libinput_seat * seat)2084 libinput_seat_ref(struct libinput_seat *seat)
2085 {
2086 seat->refcount++;
2087 return seat;
2088 }
2089
2090 static void
libinput_seat_destroy(struct libinput_seat * seat)2091 libinput_seat_destroy(struct libinput_seat *seat)
2092 {
2093 list_remove(&seat->link);
2094 free(seat->logical_name);
2095 free(seat->physical_name);
2096 seat->destroy(seat);
2097 }
2098
2099 LIBINPUT_EXPORT struct libinput_seat *
libinput_seat_unref(struct libinput_seat * seat)2100 libinput_seat_unref(struct libinput_seat *seat)
2101 {
2102 assert(seat->refcount > 0);
2103 seat->refcount--;
2104 if (seat->refcount == 0) {
2105 libinput_seat_destroy(seat);
2106 return NULL;
2107 }
2108
2109 return seat;
2110 }
2111
2112 LIBINPUT_EXPORT void
libinput_seat_set_user_data(struct libinput_seat * seat,void * user_data)2113 libinput_seat_set_user_data(struct libinput_seat *seat, void *user_data)
2114 {
2115 seat->user_data = user_data;
2116 }
2117
2118 LIBINPUT_EXPORT void *
libinput_seat_get_user_data(struct libinput_seat * seat)2119 libinput_seat_get_user_data(struct libinput_seat *seat)
2120 {
2121 return seat->user_data;
2122 }
2123
2124 LIBINPUT_EXPORT struct libinput *
libinput_seat_get_context(struct libinput_seat * seat)2125 libinput_seat_get_context(struct libinput_seat *seat)
2126 {
2127 return seat->libinput;
2128 }
2129
2130 LIBINPUT_EXPORT const char *
libinput_seat_get_physical_name(struct libinput_seat * seat)2131 libinput_seat_get_physical_name(struct libinput_seat *seat)
2132 {
2133 return seat->physical_name;
2134 }
2135
2136 LIBINPUT_EXPORT const char *
libinput_seat_get_logical_name(struct libinput_seat * seat)2137 libinput_seat_get_logical_name(struct libinput_seat *seat)
2138 {
2139 return seat->logical_name;
2140 }
2141
2142 void
libinput_device_init(struct libinput_device * device,struct libinput_seat * seat)2143 libinput_device_init(struct libinput_device *device,
2144 struct libinput_seat *seat)
2145 {
2146 device->seat = seat;
2147 device->refcount = 1;
2148 list_init(&device->event_listeners);
2149 }
2150
2151 LIBINPUT_EXPORT struct libinput_device *
libinput_device_ref(struct libinput_device * device)2152 libinput_device_ref(struct libinput_device *device)
2153 {
2154 device->refcount++;
2155 return device;
2156 }
2157
2158 static void
libinput_device_destroy(struct libinput_device * device)2159 libinput_device_destroy(struct libinput_device *device)
2160 {
2161 assert(list_empty(&device->event_listeners));
2162 evdev_device_destroy(evdev_device(device));
2163 }
2164
2165 LIBINPUT_EXPORT struct libinput_device *
libinput_device_unref(struct libinput_device * device)2166 libinput_device_unref(struct libinput_device *device)
2167 {
2168 assert(device->refcount > 0);
2169 device->refcount--;
2170 if (device->refcount == 0) {
2171 libinput_device_destroy(device);
2172 return NULL;
2173 }
2174
2175 return device;
2176 }
2177
2178 LIBINPUT_EXPORT int
libinput_get_fd(struct libinput * libinput)2179 libinput_get_fd(struct libinput *libinput)
2180 {
2181 return libinput->epoll_fd;
2182 }
2183
2184 LIBINPUT_EXPORT int
libinput_dispatch(struct libinput * libinput)2185 libinput_dispatch(struct libinput *libinput)
2186 {
2187 static uint8_t take_time_snapshot;
2188 struct libinput_source *source;
2189 struct epoll_event ep[32];
2190 int i, count;
2191
2192 /* Every 10 calls to libinput_dispatch() we take the current time so
2193 * we can check the delay between our current time and the event
2194 * timestamps */
2195 if ((++take_time_snapshot % 10) == 0)
2196 libinput->dispatch_time = libinput_now(libinput);
2197 else if (libinput->dispatch_time)
2198 libinput->dispatch_time = 0;
2199
2200 count = epoll_wait(libinput->epoll_fd, ep, ARRAY_LENGTH(ep), 0);
2201 if (count < 0)
2202 return -errno;
2203
2204 for (i = 0; i < count; ++i) {
2205 source = ep[i].data.ptr;
2206 if (source->fd == -1)
2207 continue;
2208
2209 source->dispatch(source->user_data);
2210 }
2211
2212 libinput_drop_destroyed_sources(libinput);
2213
2214 return 0;
2215 }
2216
2217 void
libinput_device_init_event_listener(struct libinput_event_listener * listener)2218 libinput_device_init_event_listener(struct libinput_event_listener *listener)
2219 {
2220 list_init(&listener->link);
2221 }
2222
2223 void
libinput_device_add_event_listener(struct libinput_device * device,struct libinput_event_listener * listener,void (* notify_func)(uint64_t time,struct libinput_event * event,void * notify_func_data),void * notify_func_data)2224 libinput_device_add_event_listener(struct libinput_device *device,
2225 struct libinput_event_listener *listener,
2226 void (*notify_func)(
2227 uint64_t time,
2228 struct libinput_event *event,
2229 void *notify_func_data),
2230 void *notify_func_data)
2231 {
2232 listener->notify_func = notify_func;
2233 listener->notify_func_data = notify_func_data;
2234 list_insert(&device->event_listeners, &listener->link);
2235 }
2236
2237 void
libinput_device_remove_event_listener(struct libinput_event_listener * listener)2238 libinput_device_remove_event_listener(struct libinput_event_listener *listener)
2239 {
2240 list_remove(&listener->link);
2241 }
2242
2243 static uint32_t
update_seat_key_count(struct libinput_seat * seat,int32_t key,enum libinput_key_state state)2244 update_seat_key_count(struct libinput_seat *seat,
2245 int32_t key,
2246 enum libinput_key_state state)
2247 {
2248 assert(key >= 0 && key <= KEY_MAX);
2249
2250 switch (state) {
2251 case LIBINPUT_KEY_STATE_PRESSED:
2252 return ++seat->button_count[key];
2253 case LIBINPUT_KEY_STATE_RELEASED:
2254 /* We might not have received the first PRESSED event. */
2255 if (seat->button_count[key] == 0)
2256 return 0;
2257
2258 return --seat->button_count[key];
2259 }
2260
2261 return 0;
2262 }
2263
2264 static uint32_t
update_seat_button_count(struct libinput_seat * seat,int32_t button,enum libinput_button_state state)2265 update_seat_button_count(struct libinput_seat *seat,
2266 int32_t button,
2267 enum libinput_button_state state)
2268 {
2269 assert(button >= 0 && button <= KEY_MAX);
2270
2271 switch (state) {
2272 case LIBINPUT_BUTTON_STATE_PRESSED:
2273 return ++seat->button_count[button];
2274 case LIBINPUT_BUTTON_STATE_RELEASED:
2275 /* We might not have received the first PRESSED event. */
2276 if (seat->button_count[button] == 0)
2277 return 0;
2278
2279 return --seat->button_count[button];
2280 }
2281
2282 return 0;
2283 }
2284
2285 static void
init_event_base(struct libinput_event * event,struct libinput_device * device,enum libinput_event_type type)2286 init_event_base(struct libinput_event *event,
2287 struct libinput_device *device,
2288 enum libinput_event_type type)
2289 {
2290 event->type = type;
2291 event->device = device;
2292 }
2293
2294 static void
post_base_event(struct libinput_device * device,enum libinput_event_type type,struct libinput_event * event)2295 post_base_event(struct libinput_device *device,
2296 enum libinput_event_type type,
2297 struct libinput_event *event)
2298 {
2299 struct libinput *libinput = device->seat->libinput;
2300 init_event_base(event, device, type);
2301 libinput_post_event(libinput, event);
2302 }
2303
2304 static void
post_device_event(struct libinput_device * device,uint64_t time,enum libinput_event_type type,struct libinput_event * event)2305 post_device_event(struct libinput_device *device,
2306 uint64_t time,
2307 enum libinput_event_type type,
2308 struct libinput_event *event)
2309 {
2310 struct libinput_event_listener *listener;
2311 #if 0
2312 struct libinput *libinput = device->seat->libinput;
2313
2314 if (libinput->last_event_time > time) {
2315 log_bug_libinput(device->seat->libinput,
2316 "out-of-order timestamps for %s time %" PRIu64 "\n",
2317 event_type_to_str(type),
2318 time);
2319 }
2320 libinput->last_event_time = time;
2321 #endif
2322
2323 init_event_base(event, device, type);
2324
2325 list_for_each_safe(listener, &device->event_listeners, link)
2326 listener->notify_func(time, event, listener->notify_func_data);
2327
2328 libinput_post_event(device->seat->libinput, event);
2329 }
2330
2331 void
notify_added_device(struct libinput_device * device)2332 notify_added_device(struct libinput_device *device)
2333 {
2334 struct libinput_event_device_notify *added_device_event;
2335
2336 added_device_event = zalloc(sizeof *added_device_event);
2337
2338 post_base_event(device,
2339 LIBINPUT_EVENT_DEVICE_ADDED,
2340 &added_device_event->base);
2341
2342 #ifdef __clang_analyzer__
2343 /* clang doesn't realize we're not leaking the event here, so
2344 * pretend to free it */
2345 free(added_device_event);
2346 #endif
2347 }
2348
2349 void
notify_removed_device(struct libinput_device * device)2350 notify_removed_device(struct libinput_device *device)
2351 {
2352 struct libinput_event_device_notify *removed_device_event;
2353
2354 removed_device_event = zalloc(sizeof *removed_device_event);
2355
2356 post_base_event(device,
2357 LIBINPUT_EVENT_DEVICE_REMOVED,
2358 &removed_device_event->base);
2359
2360 #ifdef __clang_analyzer__
2361 /* clang doesn't realize we're not leaking the event here, so
2362 * pretend to free it */
2363 free(removed_device_event);
2364 #endif
2365 }
2366
2367 static inline bool
device_has_cap(struct libinput_device * device,enum libinput_device_capability cap)2368 device_has_cap(struct libinput_device *device,
2369 enum libinput_device_capability cap)
2370 {
2371 const char *capability;
2372
2373 if (libinput_device_has_capability(device, cap))
2374 return true;
2375
2376 switch (cap) {
2377 case LIBINPUT_DEVICE_CAP_POINTER:
2378 capability = "CAP_POINTER";
2379 break;
2380 case LIBINPUT_DEVICE_CAP_KEYBOARD:
2381 capability = "CAP_KEYBOARD";
2382 break;
2383 case LIBINPUT_DEVICE_CAP_TOUCH:
2384 capability = "CAP_TOUCH";
2385 break;
2386 case LIBINPUT_DEVICE_CAP_GESTURE:
2387 capability = "CAP_GESTURE";
2388 break;
2389 case LIBINPUT_DEVICE_CAP_TABLET_TOOL:
2390 capability = "CAP_TABLET_TOOL";
2391 break;
2392 case LIBINPUT_DEVICE_CAP_TABLET_PAD:
2393 capability = "CAP_TABLET_PAD";
2394 break;
2395 case LIBINPUT_DEVICE_CAP_SWITCH:
2396 capability = "CAP_SWITCH";
2397 break;
2398 }
2399
2400 log_bug_libinput(device->seat->libinput,
2401 "Event for missing capability %s on device \"%s\"\n",
2402 capability,
2403 libinput_device_get_name(device));
2404
2405 return false;
2406 }
2407
2408 void
keyboard_notify_key(struct libinput_device * device,uint64_t time,uint32_t key,enum libinput_key_state state)2409 keyboard_notify_key(struct libinput_device *device,
2410 uint64_t time,
2411 uint32_t key,
2412 enum libinput_key_state state)
2413 {
2414 struct libinput_event_keyboard *key_event;
2415 uint32_t seat_key_count;
2416
2417 if (!device_has_cap(device, LIBINPUT_DEVICE_CAP_KEYBOARD))
2418 return;
2419
2420 key_event = zalloc(sizeof *key_event);
2421
2422 seat_key_count = update_seat_key_count(device->seat, key, state);
2423
2424 *key_event = (struct libinput_event_keyboard) {
2425 .time = time,
2426 .key = key,
2427 .state = state,
2428 .seat_key_count = seat_key_count,
2429 };
2430
2431 post_device_event(device, time,
2432 LIBINPUT_EVENT_KEYBOARD_KEY,
2433 &key_event->base);
2434 }
2435
2436 void
pointer_notify_motion(struct libinput_device * device,uint64_t time,const struct normalized_coords * delta,const struct device_float_coords * raw)2437 pointer_notify_motion(struct libinput_device *device,
2438 uint64_t time,
2439 const struct normalized_coords *delta,
2440 const struct device_float_coords *raw)
2441 {
2442 struct libinput_event_pointer *motion_event;
2443
2444 if (!device_has_cap(device, LIBINPUT_DEVICE_CAP_POINTER))
2445 return;
2446
2447 motion_event = zalloc(sizeof *motion_event);
2448
2449 *motion_event = (struct libinput_event_pointer) {
2450 .time = time,
2451 .delta = *delta,
2452 .delta_raw = *raw,
2453 };
2454
2455 post_device_event(device, time,
2456 LIBINPUT_EVENT_POINTER_MOTION,
2457 &motion_event->base);
2458 }
2459
2460 void
pointer_notify_motion_absolute(struct libinput_device * device,uint64_t time,const struct device_coords * point)2461 pointer_notify_motion_absolute(struct libinput_device *device,
2462 uint64_t time,
2463 const struct device_coords *point)
2464 {
2465 struct libinput_event_pointer *motion_absolute_event;
2466
2467 if (!device_has_cap(device, LIBINPUT_DEVICE_CAP_POINTER))
2468 return;
2469
2470 motion_absolute_event = zalloc(sizeof *motion_absolute_event);
2471
2472 *motion_absolute_event = (struct libinput_event_pointer) {
2473 .time = time,
2474 .absolute = *point,
2475 };
2476
2477 post_device_event(device, time,
2478 LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE,
2479 &motion_absolute_event->base);
2480 }
2481
2482 void
pointer_notify_button(struct libinput_device * device,uint64_t time,int32_t button,enum libinput_button_state state)2483 pointer_notify_button(struct libinput_device *device,
2484 uint64_t time,
2485 int32_t button,
2486 enum libinput_button_state state)
2487 {
2488 struct libinput_event_pointer *button_event;
2489 int32_t seat_button_count;
2490
2491 if (!device_has_cap(device, LIBINPUT_DEVICE_CAP_POINTER))
2492 return;
2493
2494 button_event = zalloc(sizeof *button_event);
2495
2496 seat_button_count = update_seat_button_count(device->seat,
2497 button,
2498 state);
2499
2500 *button_event = (struct libinput_event_pointer) {
2501 .time = time,
2502 .button = button,
2503 .state = state,
2504 .seat_button_count = seat_button_count,
2505 };
2506
2507 post_device_event(device, time,
2508 LIBINPUT_EVENT_POINTER_BUTTON,
2509 &button_event->base);
2510 }
2511
2512 void
pointer_notify_axis_finger(struct libinput_device * device,uint64_t time,uint32_t axes,const struct normalized_coords * delta)2513 pointer_notify_axis_finger(struct libinput_device *device,
2514 uint64_t time,
2515 uint32_t axes,
2516 const struct normalized_coords *delta)
2517 {
2518 struct libinput_event_pointer *axis_event, *axis_event_legacy;
2519 const struct discrete_coords zero_discrete = {0};
2520 const struct wheel_v120 zero_v120 = {0};
2521
2522 if (!device_has_cap(device, LIBINPUT_DEVICE_CAP_POINTER))
2523 return;
2524
2525 axis_event = zalloc(sizeof *axis_event);
2526 axis_event_legacy = zalloc(sizeof *axis_event_legacy);
2527
2528 *axis_event = (struct libinput_event_pointer) {
2529 .time = time,
2530 .delta = *delta,
2531 .source = LIBINPUT_POINTER_AXIS_SOURCE_FINGER,
2532 .axes = axes,
2533 .discrete = zero_discrete,
2534 .v120 = zero_v120,
2535 };
2536 *axis_event_legacy = *axis_event;
2537
2538 post_device_event(device, time,
2539 LIBINPUT_EVENT_POINTER_SCROLL_FINGER,
2540 &axis_event->base);
2541 post_device_event(device, time,
2542 LIBINPUT_EVENT_POINTER_AXIS,
2543 &axis_event_legacy->base);
2544 }
2545
2546 void
pointer_notify_axis_continuous(struct libinput_device * device,uint64_t time,uint32_t axes,const struct normalized_coords * delta)2547 pointer_notify_axis_continuous(struct libinput_device *device,
2548 uint64_t time,
2549 uint32_t axes,
2550 const struct normalized_coords *delta)
2551 {
2552 struct libinput_event_pointer *axis_event, *axis_event_legacy;
2553 const struct discrete_coords zero_discrete = {0};
2554 const struct wheel_v120 zero_v120 = {0};
2555
2556 if (!device_has_cap(device, LIBINPUT_DEVICE_CAP_POINTER))
2557 return;
2558
2559 axis_event = zalloc(sizeof *axis_event);
2560 axis_event_legacy = zalloc(sizeof *axis_event_legacy);
2561
2562 *axis_event = (struct libinput_event_pointer) {
2563 .time = time,
2564 .delta = *delta,
2565 .source = LIBINPUT_POINTER_AXIS_SOURCE_CONTINUOUS,
2566 .axes = axes,
2567 .discrete = zero_discrete,
2568 .v120 = zero_v120,
2569 };
2570 *axis_event_legacy = *axis_event;
2571
2572 post_device_event(device, time,
2573 LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS,
2574 &axis_event->base);
2575 post_device_event(device, time,
2576 LIBINPUT_EVENT_POINTER_AXIS,
2577 &axis_event_legacy->base);
2578 }
2579
2580 void
pointer_notify_axis_legacy_wheel(struct libinput_device * device,uint64_t time,uint32_t axes,const struct normalized_coords * delta,const struct discrete_coords * discrete)2581 pointer_notify_axis_legacy_wheel(struct libinput_device *device,
2582 uint64_t time,
2583 uint32_t axes,
2584 const struct normalized_coords *delta,
2585 const struct discrete_coords *discrete)
2586 {
2587 struct libinput_event_pointer *axis_event;
2588 const struct wheel_v120 zero_v120 = {0};
2589
2590 if (!device_has_cap(device, LIBINPUT_DEVICE_CAP_POINTER))
2591 return;
2592
2593 axis_event = zalloc(sizeof *axis_event);
2594
2595 *axis_event = (struct libinput_event_pointer) {
2596 .time = time,
2597 .delta = *delta,
2598 .source = LIBINPUT_POINTER_AXIS_SOURCE_WHEEL,
2599 .axes = axes,
2600 .discrete = *discrete,
2601 .v120 = zero_v120,
2602 };
2603
2604 post_device_event(device, time,
2605 LIBINPUT_EVENT_POINTER_AXIS,
2606 &axis_event->base);
2607 }
2608
2609 void
pointer_notify_axis_wheel(struct libinput_device * device,uint64_t time,uint32_t axes,const struct normalized_coords * delta,const struct wheel_v120 * v120)2610 pointer_notify_axis_wheel(struct libinput_device *device,
2611 uint64_t time,
2612 uint32_t axes,
2613 const struct normalized_coords *delta,
2614 const struct wheel_v120 *v120)
2615 {
2616 struct libinput_event_pointer *axis_event;
2617
2618 if (!device_has_cap(device, LIBINPUT_DEVICE_CAP_POINTER))
2619 return;
2620
2621 axis_event = zalloc(sizeof *axis_event);
2622
2623 *axis_event = (struct libinput_event_pointer) {
2624 .time = time,
2625 .delta = *delta,
2626 .source = LIBINPUT_POINTER_AXIS_SOURCE_WHEEL,
2627 .axes = axes,
2628 .discrete.x = 0,
2629 .discrete.y = 0,
2630 .v120 = *v120,
2631 };
2632
2633 post_device_event(device, time,
2634 LIBINPUT_EVENT_POINTER_SCROLL_WHEEL,
2635 &axis_event->base);
2636
2637 /* legacy wheel events are sent separately */
2638 }
2639
2640 void
touch_notify_touch_down(struct libinput_device * device,uint64_t time,int32_t slot,int32_t seat_slot,const struct device_coords * point)2641 touch_notify_touch_down(struct libinput_device *device,
2642 uint64_t time,
2643 int32_t slot,
2644 int32_t seat_slot,
2645 const struct device_coords *point)
2646 {
2647 struct libinput_event_touch *touch_event;
2648
2649 if (!device_has_cap(device, LIBINPUT_DEVICE_CAP_TOUCH))
2650 return;
2651
2652 touch_event = zalloc(sizeof *touch_event);
2653
2654 *touch_event = (struct libinput_event_touch) {
2655 .time = time,
2656 .slot = slot,
2657 .seat_slot = seat_slot,
2658 .point = *point,
2659 };
2660
2661 post_device_event(device, time,
2662 LIBINPUT_EVENT_TOUCH_DOWN,
2663 &touch_event->base);
2664 }
2665
2666 void
touch_notify_touch_motion(struct libinput_device * device,uint64_t time,int32_t slot,int32_t seat_slot,const struct device_coords * point)2667 touch_notify_touch_motion(struct libinput_device *device,
2668 uint64_t time,
2669 int32_t slot,
2670 int32_t seat_slot,
2671 const struct device_coords *point)
2672 {
2673 struct libinput_event_touch *touch_event;
2674
2675 if (!device_has_cap(device, LIBINPUT_DEVICE_CAP_TOUCH))
2676 return;
2677
2678 touch_event = zalloc(sizeof *touch_event);
2679
2680 *touch_event = (struct libinput_event_touch) {
2681 .time = time,
2682 .slot = slot,
2683 .seat_slot = seat_slot,
2684 .point = *point,
2685 };
2686
2687 post_device_event(device, time,
2688 LIBINPUT_EVENT_TOUCH_MOTION,
2689 &touch_event->base);
2690 }
2691
2692 void
touch_notify_touch_up(struct libinput_device * device,uint64_t time,int32_t slot,int32_t seat_slot)2693 touch_notify_touch_up(struct libinput_device *device,
2694 uint64_t time,
2695 int32_t slot,
2696 int32_t seat_slot)
2697 {
2698 struct libinput_event_touch *touch_event;
2699
2700 if (!device_has_cap(device, LIBINPUT_DEVICE_CAP_TOUCH))
2701 return;
2702
2703 touch_event = zalloc(sizeof *touch_event);
2704
2705 *touch_event = (struct libinput_event_touch) {
2706 .time = time,
2707 .slot = slot,
2708 .seat_slot = seat_slot,
2709 };
2710
2711 post_device_event(device, time,
2712 LIBINPUT_EVENT_TOUCH_UP,
2713 &touch_event->base);
2714 }
2715
2716 void
touch_notify_touch_cancel(struct libinput_device * device,uint64_t time,int32_t slot,int32_t seat_slot)2717 touch_notify_touch_cancel(struct libinput_device *device,
2718 uint64_t time,
2719 int32_t slot,
2720 int32_t seat_slot)
2721 {
2722 struct libinput_event_touch *touch_event;
2723
2724 if (!device_has_cap(device, LIBINPUT_DEVICE_CAP_TOUCH))
2725 return;
2726
2727 touch_event = zalloc(sizeof *touch_event);
2728
2729 *touch_event = (struct libinput_event_touch) {
2730 .time = time,
2731 .slot = slot,
2732 .seat_slot = seat_slot,
2733 };
2734
2735 post_device_event(device, time,
2736 LIBINPUT_EVENT_TOUCH_CANCEL,
2737 &touch_event->base);
2738 }
2739
2740 void
touch_notify_frame(struct libinput_device * device,uint64_t time)2741 touch_notify_frame(struct libinput_device *device,
2742 uint64_t time)
2743 {
2744 struct libinput_event_touch *touch_event;
2745
2746 if (!device_has_cap(device, LIBINPUT_DEVICE_CAP_TOUCH))
2747 return;
2748
2749 touch_event = zalloc(sizeof *touch_event);
2750
2751 *touch_event = (struct libinput_event_touch) {
2752 .time = time,
2753 };
2754
2755 post_device_event(device, time,
2756 LIBINPUT_EVENT_TOUCH_FRAME,
2757 &touch_event->base);
2758 }
2759
2760 void
tablet_notify_axis(struct libinput_device * device,uint64_t time,struct libinput_tablet_tool * tool,enum libinput_tablet_tool_tip_state tip_state,unsigned char * changed_axes,const struct tablet_axes * axes)2761 tablet_notify_axis(struct libinput_device *device,
2762 uint64_t time,
2763 struct libinput_tablet_tool *tool,
2764 enum libinput_tablet_tool_tip_state tip_state,
2765 unsigned char *changed_axes,
2766 const struct tablet_axes *axes)
2767 {
2768 struct libinput_event_tablet_tool *axis_event;
2769
2770 axis_event = zalloc(sizeof *axis_event);
2771
2772 *axis_event = (struct libinput_event_tablet_tool) {
2773 .time = time,
2774 .tool = libinput_tablet_tool_ref(tool),
2775 .proximity_state = LIBINPUT_TABLET_TOOL_PROXIMITY_STATE_IN,
2776 .tip_state = tip_state,
2777 .axes = *axes,
2778 };
2779
2780 memcpy(axis_event->changed_axes,
2781 changed_axes,
2782 sizeof(axis_event->changed_axes));
2783
2784 post_device_event(device,
2785 time,
2786 LIBINPUT_EVENT_TABLET_TOOL_AXIS,
2787 &axis_event->base);
2788 }
2789
2790 void
tablet_notify_proximity(struct libinput_device * device,uint64_t time,struct libinput_tablet_tool * tool,enum libinput_tablet_tool_proximity_state proximity_state,unsigned char * changed_axes,const struct tablet_axes * axes)2791 tablet_notify_proximity(struct libinput_device *device,
2792 uint64_t time,
2793 struct libinput_tablet_tool *tool,
2794 enum libinput_tablet_tool_proximity_state proximity_state,
2795 unsigned char *changed_axes,
2796 const struct tablet_axes *axes)
2797 {
2798 struct libinput_event_tablet_tool *proximity_event;
2799
2800 proximity_event = zalloc(sizeof *proximity_event);
2801
2802 *proximity_event = (struct libinput_event_tablet_tool) {
2803 .time = time,
2804 .tool = libinput_tablet_tool_ref(tool),
2805 .tip_state = LIBINPUT_TABLET_TOOL_TIP_UP,
2806 .proximity_state = proximity_state,
2807 .axes = *axes,
2808 };
2809 memcpy(proximity_event->changed_axes,
2810 changed_axes,
2811 sizeof(proximity_event->changed_axes));
2812
2813 post_device_event(device,
2814 time,
2815 LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY,
2816 &proximity_event->base);
2817 }
2818
2819 void
tablet_notify_tip(struct libinput_device * device,uint64_t time,struct libinput_tablet_tool * tool,enum libinput_tablet_tool_tip_state tip_state,unsigned char * changed_axes,const struct tablet_axes * axes)2820 tablet_notify_tip(struct libinput_device *device,
2821 uint64_t time,
2822 struct libinput_tablet_tool *tool,
2823 enum libinput_tablet_tool_tip_state tip_state,
2824 unsigned char *changed_axes,
2825 const struct tablet_axes *axes)
2826 {
2827 struct libinput_event_tablet_tool *tip_event;
2828
2829 tip_event = zalloc(sizeof *tip_event);
2830
2831 *tip_event = (struct libinput_event_tablet_tool) {
2832 .time = time,
2833 .tool = libinput_tablet_tool_ref(tool),
2834 .tip_state = tip_state,
2835 .proximity_state = LIBINPUT_TABLET_TOOL_PROXIMITY_STATE_IN,
2836 .axes = *axes,
2837 };
2838 memcpy(tip_event->changed_axes,
2839 changed_axes,
2840 sizeof(tip_event->changed_axes));
2841
2842 post_device_event(device,
2843 time,
2844 LIBINPUT_EVENT_TABLET_TOOL_TIP,
2845 &tip_event->base);
2846 }
2847
2848 void
tablet_notify_button(struct libinput_device * device,uint64_t time,struct libinput_tablet_tool * tool,enum libinput_tablet_tool_tip_state tip_state,const struct tablet_axes * axes,int32_t button,enum libinput_button_state state)2849 tablet_notify_button(struct libinput_device *device,
2850 uint64_t time,
2851 struct libinput_tablet_tool *tool,
2852 enum libinput_tablet_tool_tip_state tip_state,
2853 const struct tablet_axes *axes,
2854 int32_t button,
2855 enum libinput_button_state state)
2856 {
2857 struct libinput_event_tablet_tool *button_event;
2858 int32_t seat_button_count;
2859
2860 button_event = zalloc(sizeof *button_event);
2861
2862 seat_button_count = update_seat_button_count(device->seat,
2863 button,
2864 state);
2865
2866 *button_event = (struct libinput_event_tablet_tool) {
2867 .time = time,
2868 .tool = libinput_tablet_tool_ref(tool),
2869 .button = button,
2870 .state = state,
2871 .seat_button_count = seat_button_count,
2872 .proximity_state = LIBINPUT_TABLET_TOOL_PROXIMITY_STATE_IN,
2873 .tip_state = tip_state,
2874 .axes = *axes,
2875 };
2876
2877 post_device_event(device,
2878 time,
2879 LIBINPUT_EVENT_TABLET_TOOL_BUTTON,
2880 &button_event->base);
2881 }
2882
2883 void
tablet_pad_notify_button(struct libinput_device * device,uint64_t time,int32_t button,enum libinput_button_state state,struct libinput_tablet_pad_mode_group * group)2884 tablet_pad_notify_button(struct libinput_device *device,
2885 uint64_t time,
2886 int32_t button,
2887 enum libinput_button_state state,
2888 struct libinput_tablet_pad_mode_group *group)
2889 {
2890 struct libinput_event_tablet_pad *button_event;
2891 unsigned int mode;
2892
2893 button_event = zalloc(sizeof *button_event);
2894
2895 mode = libinput_tablet_pad_mode_group_get_mode(group);
2896
2897 *button_event = (struct libinput_event_tablet_pad) {
2898 .time = time,
2899 .button.number = button,
2900 .button.state = state,
2901 .mode_group = libinput_tablet_pad_mode_group_ref(group),
2902 .mode = mode,
2903 };
2904
2905 post_device_event(device,
2906 time,
2907 LIBINPUT_EVENT_TABLET_PAD_BUTTON,
2908 &button_event->base);
2909 }
2910
2911 void
tablet_pad_notify_ring(struct libinput_device * device,uint64_t time,unsigned int number,double value,enum libinput_tablet_pad_ring_axis_source source,struct libinput_tablet_pad_mode_group * group)2912 tablet_pad_notify_ring(struct libinput_device *device,
2913 uint64_t time,
2914 unsigned int number,
2915 double value,
2916 enum libinput_tablet_pad_ring_axis_source source,
2917 struct libinput_tablet_pad_mode_group *group)
2918 {
2919 struct libinput_event_tablet_pad *ring_event;
2920 unsigned int mode;
2921
2922 ring_event = zalloc(sizeof *ring_event);
2923
2924 mode = libinput_tablet_pad_mode_group_get_mode(group);
2925
2926 *ring_event = (struct libinput_event_tablet_pad) {
2927 .time = time,
2928 .ring.number = number,
2929 .ring.position = value,
2930 .ring.source = source,
2931 .mode_group = libinput_tablet_pad_mode_group_ref(group),
2932 .mode = mode,
2933 };
2934
2935 post_device_event(device,
2936 time,
2937 LIBINPUT_EVENT_TABLET_PAD_RING,
2938 &ring_event->base);
2939 }
2940
2941 void
tablet_pad_notify_strip(struct libinput_device * device,uint64_t time,unsigned int number,double value,enum libinput_tablet_pad_strip_axis_source source,struct libinput_tablet_pad_mode_group * group)2942 tablet_pad_notify_strip(struct libinput_device *device,
2943 uint64_t time,
2944 unsigned int number,
2945 double value,
2946 enum libinput_tablet_pad_strip_axis_source source,
2947 struct libinput_tablet_pad_mode_group *group)
2948 {
2949 struct libinput_event_tablet_pad *strip_event;
2950 unsigned int mode;
2951
2952 strip_event = zalloc(sizeof *strip_event);
2953
2954 mode = libinput_tablet_pad_mode_group_get_mode(group);
2955
2956 *strip_event = (struct libinput_event_tablet_pad) {
2957 .time = time,
2958 .strip.number = number,
2959 .strip.position = value,
2960 .strip.source = source,
2961 .mode_group = libinput_tablet_pad_mode_group_ref(group),
2962 .mode = mode,
2963 };
2964
2965 post_device_event(device,
2966 time,
2967 LIBINPUT_EVENT_TABLET_PAD_STRIP,
2968 &strip_event->base);
2969 }
2970
2971 void
tablet_pad_notify_key(struct libinput_device * device,uint64_t time,int32_t key,enum libinput_key_state state)2972 tablet_pad_notify_key(struct libinput_device *device,
2973 uint64_t time,
2974 int32_t key,
2975 enum libinput_key_state state)
2976 {
2977 struct libinput_event_tablet_pad *key_event;
2978
2979 key_event = zalloc(sizeof *key_event);
2980
2981 *key_event = (struct libinput_event_tablet_pad) {
2982 .time = time,
2983 .key.code = key,
2984 .key.state = state,
2985 };
2986
2987 post_device_event(device,
2988 time,
2989 LIBINPUT_EVENT_TABLET_PAD_KEY,
2990 &key_event->base);
2991 }
2992
2993 static void
gesture_notify(struct libinput_device * device,uint64_t time,enum libinput_event_type type,int finger_count,bool cancelled,const struct normalized_coords * delta,const struct normalized_coords * unaccel,double scale,double angle)2994 gesture_notify(struct libinput_device *device,
2995 uint64_t time,
2996 enum libinput_event_type type,
2997 int finger_count,
2998 bool cancelled,
2999 const struct normalized_coords *delta,
3000 const struct normalized_coords *unaccel,
3001 double scale,
3002 double angle)
3003 {
3004 struct libinput_event_gesture *gesture_event;
3005
3006 if (!device_has_cap(device, LIBINPUT_DEVICE_CAP_GESTURE))
3007 return;
3008
3009 gesture_event = zalloc(sizeof *gesture_event);
3010
3011 *gesture_event = (struct libinput_event_gesture) {
3012 .time = time,
3013 .finger_count = finger_count,
3014 .cancelled = cancelled,
3015 .delta = *delta,
3016 .delta_unaccel = *unaccel,
3017 .scale = scale,
3018 .angle = angle,
3019 };
3020
3021 post_device_event(device, time, type,
3022 &gesture_event->base);
3023 }
3024
3025 void
gesture_notify_swipe(struct libinput_device * device,uint64_t time,enum libinput_event_type type,int finger_count,const struct normalized_coords * delta,const struct normalized_coords * unaccel)3026 gesture_notify_swipe(struct libinput_device *device,
3027 uint64_t time,
3028 enum libinput_event_type type,
3029 int finger_count,
3030 const struct normalized_coords *delta,
3031 const struct normalized_coords *unaccel)
3032 {
3033 gesture_notify(device, time, type, finger_count, 0, delta, unaccel,
3034 0.0, 0.0);
3035 }
3036
3037 void
gesture_notify_swipe_end(struct libinput_device * device,uint64_t time,int finger_count,bool cancelled)3038 gesture_notify_swipe_end(struct libinput_device *device,
3039 uint64_t time,
3040 int finger_count,
3041 bool cancelled)
3042 {
3043 const struct normalized_coords zero = { 0.0, 0.0 };
3044
3045 gesture_notify(device, time, LIBINPUT_EVENT_GESTURE_SWIPE_END,
3046 finger_count, cancelled, &zero, &zero, 0.0, 0.0);
3047 }
3048
3049 void
gesture_notify_pinch(struct libinput_device * device,uint64_t time,enum libinput_event_type type,int finger_count,const struct normalized_coords * delta,const struct normalized_coords * unaccel,double scale,double angle)3050 gesture_notify_pinch(struct libinput_device *device,
3051 uint64_t time,
3052 enum libinput_event_type type,
3053 int finger_count,
3054 const struct normalized_coords *delta,
3055 const struct normalized_coords *unaccel,
3056 double scale,
3057 double angle)
3058 {
3059 gesture_notify(device, time, type, finger_count, 0,
3060 delta, unaccel, scale, angle);
3061 }
3062
3063 void
gesture_notify_pinch_end(struct libinput_device * device,uint64_t time,int finger_count,double scale,bool cancelled)3064 gesture_notify_pinch_end(struct libinput_device *device,
3065 uint64_t time,
3066 int finger_count,
3067 double scale,
3068 bool cancelled)
3069 {
3070 const struct normalized_coords zero = { 0.0, 0.0 };
3071
3072 gesture_notify(device, time, LIBINPUT_EVENT_GESTURE_PINCH_END,
3073 finger_count, cancelled, &zero, &zero, scale, 0.0);
3074 }
3075
3076 void
gesture_notify_hold(struct libinput_device * device,uint64_t time,int finger_count)3077 gesture_notify_hold(struct libinput_device *device,
3078 uint64_t time,
3079 int finger_count)
3080 {
3081 const struct normalized_coords zero = { 0.0, 0.0 };
3082
3083 gesture_notify(device, time, LIBINPUT_EVENT_GESTURE_HOLD_BEGIN,
3084 finger_count, 0, &zero, &zero, 0.0, 0.0);
3085 }
3086
3087 void
gesture_notify_hold_end(struct libinput_device * device,uint64_t time,int finger_count,bool cancelled)3088 gesture_notify_hold_end(struct libinput_device *device,
3089 uint64_t time,
3090 int finger_count,
3091 bool cancelled)
3092 {
3093 const struct normalized_coords zero = { 0.0, 0.0 };
3094
3095 gesture_notify(device, time, LIBINPUT_EVENT_GESTURE_HOLD_END,
3096 finger_count, cancelled, &zero, &zero, 0, 0.0);
3097 }
3098
3099 void
switch_notify_toggle(struct libinput_device * device,uint64_t time,enum libinput_switch sw,enum libinput_switch_state state)3100 switch_notify_toggle(struct libinput_device *device,
3101 uint64_t time,
3102 enum libinput_switch sw,
3103 enum libinput_switch_state state)
3104 {
3105 struct libinput_event_switch *switch_event;
3106
3107 if (!device_has_cap(device, LIBINPUT_DEVICE_CAP_SWITCH))
3108 return;
3109
3110 switch_event = zalloc(sizeof *switch_event);
3111
3112 *switch_event = (struct libinput_event_switch) {
3113 .time = time,
3114 .sw = sw,
3115 .state = state,
3116 };
3117
3118 post_device_event(device, time,
3119 LIBINPUT_EVENT_SWITCH_TOGGLE,
3120 &switch_event->base);
3121
3122 #ifdef __clang_analyzer__
3123 /* clang doesn't realize we're not leaking the event here, so
3124 * pretend to free it */
3125 free(switch_event);
3126 #endif
3127 }
3128
3129 static void
libinput_post_event(struct libinput * libinput,struct libinput_event * event)3130 libinput_post_event(struct libinput *libinput,
3131 struct libinput_event *event)
3132 {
3133 struct libinput_event **events = libinput->events;
3134 size_t events_len = libinput->events_len;
3135 size_t events_count = libinput->events_count;
3136 size_t move_len;
3137 size_t new_out;
3138
3139 #if 0
3140 log_debug(libinput, "Queuing %s\n", event_type_to_str(event->type));
3141 #endif
3142
3143 events_count++;
3144 if (events_count > events_len) {
3145 void *tmp;
3146
3147 events_len *= 2;
3148 tmp = realloc(events, events_len * sizeof *events);
3149 if (!tmp) {
3150 log_error(libinput,
3151 "Failed to reallocate event ring buffer. "
3152 "Events may be discarded\n");
3153 return;
3154 }
3155
3156 events = tmp;
3157
3158 if (libinput->events_count > 0 && libinput->events_in == 0) {
3159 libinput->events_in = libinput->events_len;
3160 } else if (libinput->events_count > 0 &&
3161 libinput->events_out >= libinput->events_in) {
3162 move_len = libinput->events_len - libinput->events_out;
3163 new_out = events_len - move_len;
3164 memmove(events + new_out,
3165 events + libinput->events_out,
3166 move_len * sizeof *events);
3167 libinput->events_out = new_out;
3168 }
3169
3170 libinput->events = events;
3171 libinput->events_len = events_len;
3172 }
3173
3174 if (event->device)
3175 libinput_device_ref(event->device);
3176
3177 libinput->events_count = events_count;
3178 events[libinput->events_in] = event;
3179 libinput->events_in = (libinput->events_in + 1) % libinput->events_len;
3180 }
3181
3182 LIBINPUT_EXPORT struct libinput_event *
libinput_get_event(struct libinput * libinput)3183 libinput_get_event(struct libinput *libinput)
3184 {
3185 struct libinput_event *event;
3186
3187 if (libinput->events_count == 0)
3188 return NULL;
3189
3190 event = libinput->events[libinput->events_out];
3191 libinput->events_out =
3192 (libinput->events_out + 1) % libinput->events_len;
3193 libinput->events_count--;
3194
3195 return event;
3196 }
3197
3198 LIBINPUT_EXPORT enum libinput_event_type
libinput_next_event_type(struct libinput * libinput)3199 libinput_next_event_type(struct libinput *libinput)
3200 {
3201 struct libinput_event *event;
3202
3203 if (libinput->events_count == 0)
3204 return LIBINPUT_EVENT_NONE;
3205
3206 event = libinput->events[libinput->events_out];
3207 return event->type;
3208 }
3209
3210 LIBINPUT_EXPORT void
libinput_set_user_data(struct libinput * libinput,void * user_data)3211 libinput_set_user_data(struct libinput *libinput,
3212 void *user_data)
3213 {
3214 libinput->user_data = user_data;
3215 }
3216
3217 LIBINPUT_EXPORT void *
libinput_get_user_data(struct libinput * libinput)3218 libinput_get_user_data(struct libinput *libinput)
3219 {
3220 return libinput->user_data;
3221 }
3222
3223 LIBINPUT_EXPORT int
libinput_resume(struct libinput * libinput)3224 libinput_resume(struct libinput *libinput)
3225 {
3226 return libinput->interface_backend->resume(libinput);
3227 }
3228
3229 LIBINPUT_EXPORT void
libinput_suspend(struct libinput * libinput)3230 libinput_suspend(struct libinput *libinput)
3231 {
3232 libinput->interface_backend->suspend(libinput);
3233 }
3234
3235 LIBINPUT_EXPORT void
libinput_device_set_user_data(struct libinput_device * device,void * user_data)3236 libinput_device_set_user_data(struct libinput_device *device, void *user_data)
3237 {
3238 device->user_data = user_data;
3239 }
3240
3241 LIBINPUT_EXPORT void *
libinput_device_get_user_data(struct libinput_device * device)3242 libinput_device_get_user_data(struct libinput_device *device)
3243 {
3244 return device->user_data;
3245 }
3246
3247 LIBINPUT_EXPORT struct libinput *
libinput_device_get_context(struct libinput_device * device)3248 libinput_device_get_context(struct libinput_device *device)
3249 {
3250 return libinput_seat_get_context(device->seat);
3251 }
3252
3253 LIBINPUT_EXPORT struct libinput_device_group *
libinput_device_get_device_group(struct libinput_device * device)3254 libinput_device_get_device_group(struct libinput_device *device)
3255 {
3256 return device->group;
3257 }
3258
3259 LIBINPUT_EXPORT const char *
libinput_device_get_sysname(struct libinput_device * device)3260 libinput_device_get_sysname(struct libinput_device *device)
3261 {
3262 return evdev_device_get_sysname((struct evdev_device *) device);
3263 }
3264
3265 LIBINPUT_EXPORT const char *
libinput_device_get_name(struct libinput_device * device)3266 libinput_device_get_name(struct libinput_device *device)
3267 {
3268 return evdev_device_get_name((struct evdev_device *) device);
3269 }
3270
3271 LIBINPUT_EXPORT unsigned int
libinput_device_get_id_product(struct libinput_device * device)3272 libinput_device_get_id_product(struct libinput_device *device)
3273 {
3274 return evdev_device_get_id_product((struct evdev_device *) device);
3275 }
3276
3277 LIBINPUT_EXPORT unsigned int
libinput_device_get_id_vendor(struct libinput_device * device)3278 libinput_device_get_id_vendor(struct libinput_device *device)
3279 {
3280 return evdev_device_get_id_vendor((struct evdev_device *) device);
3281 }
3282
3283 LIBINPUT_EXPORT const char *
libinput_device_get_output_name(struct libinput_device * device)3284 libinput_device_get_output_name(struct libinput_device *device)
3285 {
3286 return evdev_device_get_output((struct evdev_device *) device);
3287 }
3288
3289 LIBINPUT_EXPORT struct libinput_seat *
libinput_device_get_seat(struct libinput_device * device)3290 libinput_device_get_seat(struct libinput_device *device)
3291 {
3292 return device->seat;
3293 }
3294
3295 LIBINPUT_EXPORT int
libinput_device_set_seat_logical_name(struct libinput_device * device,const char * name)3296 libinput_device_set_seat_logical_name(struct libinput_device *device,
3297 const char *name)
3298 {
3299 struct libinput *libinput = device->seat->libinput;
3300
3301 if (name == NULL)
3302 return -1;
3303
3304 return libinput->interface_backend->device_change_seat(device,
3305 name);
3306 }
3307
3308 LIBINPUT_EXPORT struct udev_device *
libinput_device_get_udev_device(struct libinput_device * device)3309 libinput_device_get_udev_device(struct libinput_device *device)
3310 {
3311 return evdev_device_get_udev_device((struct evdev_device *)device);
3312 }
3313
3314 LIBINPUT_EXPORT void
libinput_device_led_update(struct libinput_device * device,enum libinput_led leds)3315 libinput_device_led_update(struct libinput_device *device,
3316 enum libinput_led leds)
3317 {
3318 evdev_device_led_update((struct evdev_device *) device, leds);
3319 }
3320
3321 LIBINPUT_EXPORT int
libinput_device_has_capability(struct libinput_device * device,enum libinput_device_capability capability)3322 libinput_device_has_capability(struct libinput_device *device,
3323 enum libinput_device_capability capability)
3324 {
3325 return evdev_device_has_capability((struct evdev_device *) device,
3326 capability);
3327 }
3328
3329 LIBINPUT_EXPORT int
libinput_device_get_size(struct libinput_device * device,double * width,double * height)3330 libinput_device_get_size(struct libinput_device *device,
3331 double *width,
3332 double *height)
3333 {
3334 return evdev_device_get_size((struct evdev_device *)device,
3335 width,
3336 height);
3337 }
3338
3339 LIBINPUT_EXPORT int
libinput_device_pointer_has_button(struct libinput_device * device,uint32_t code)3340 libinput_device_pointer_has_button(struct libinput_device *device, uint32_t code)
3341 {
3342 return evdev_device_has_button((struct evdev_device *)device, code);
3343 }
3344
3345 LIBINPUT_EXPORT int
libinput_device_keyboard_has_key(struct libinput_device * device,uint32_t code)3346 libinput_device_keyboard_has_key(struct libinput_device *device, uint32_t code)
3347 {
3348 return evdev_device_has_key((struct evdev_device *)device, code);
3349 }
3350
3351 LIBINPUT_EXPORT int
libinput_device_touch_get_touch_count(struct libinput_device * device)3352 libinput_device_touch_get_touch_count(struct libinput_device *device)
3353 {
3354 return evdev_device_get_touch_count((struct evdev_device *)device);
3355 }
3356
3357 LIBINPUT_EXPORT int
libinput_device_switch_has_switch(struct libinput_device * device,enum libinput_switch sw)3358 libinput_device_switch_has_switch(struct libinput_device *device,
3359 enum libinput_switch sw)
3360 {
3361 return evdev_device_has_switch((struct evdev_device *)device, sw);
3362 }
3363
3364 LIBINPUT_EXPORT int
libinput_device_tablet_pad_has_key(struct libinput_device * device,uint32_t code)3365 libinput_device_tablet_pad_has_key(struct libinput_device *device, uint32_t code)
3366 {
3367 return evdev_device_tablet_pad_has_key((struct evdev_device *)device,
3368 code);
3369 }
3370
3371 LIBINPUT_EXPORT int
libinput_device_tablet_pad_get_num_buttons(struct libinput_device * device)3372 libinput_device_tablet_pad_get_num_buttons(struct libinput_device *device)
3373 {
3374 return evdev_device_tablet_pad_get_num_buttons((struct evdev_device *)device);
3375 }
3376
3377 LIBINPUT_EXPORT int
libinput_device_tablet_pad_get_num_rings(struct libinput_device * device)3378 libinput_device_tablet_pad_get_num_rings(struct libinput_device *device)
3379 {
3380 return evdev_device_tablet_pad_get_num_rings((struct evdev_device *)device);
3381 }
3382
3383 LIBINPUT_EXPORT int
libinput_device_tablet_pad_get_num_strips(struct libinput_device * device)3384 libinput_device_tablet_pad_get_num_strips(struct libinput_device *device)
3385 {
3386 return evdev_device_tablet_pad_get_num_strips((struct evdev_device *)device);
3387 }
3388
3389 LIBINPUT_EXPORT int
libinput_device_tablet_pad_get_num_mode_groups(struct libinput_device * device)3390 libinput_device_tablet_pad_get_num_mode_groups(struct libinput_device *device)
3391 {
3392 return evdev_device_tablet_pad_get_num_mode_groups((struct evdev_device *)device);
3393 }
3394
3395 LIBINPUT_EXPORT struct libinput_tablet_pad_mode_group*
libinput_device_tablet_pad_get_mode_group(struct libinput_device * device,unsigned int index)3396 libinput_device_tablet_pad_get_mode_group(struct libinput_device *device,
3397 unsigned int index)
3398 {
3399 return evdev_device_tablet_pad_get_mode_group((struct evdev_device *)device,
3400 index);
3401 }
3402
3403 LIBINPUT_EXPORT unsigned int
libinput_tablet_pad_mode_group_get_num_modes(struct libinput_tablet_pad_mode_group * group)3404 libinput_tablet_pad_mode_group_get_num_modes(
3405 struct libinput_tablet_pad_mode_group *group)
3406 {
3407 return group->num_modes;
3408 }
3409
3410 LIBINPUT_EXPORT unsigned int
libinput_tablet_pad_mode_group_get_mode(struct libinput_tablet_pad_mode_group * group)3411 libinput_tablet_pad_mode_group_get_mode(struct libinput_tablet_pad_mode_group *group)
3412 {
3413 return group->current_mode;
3414 }
3415
3416 LIBINPUT_EXPORT unsigned int
libinput_tablet_pad_mode_group_get_index(struct libinput_tablet_pad_mode_group * group)3417 libinput_tablet_pad_mode_group_get_index(struct libinput_tablet_pad_mode_group *group)
3418 {
3419 return group->index;
3420 }
3421
3422 LIBINPUT_EXPORT int
libinput_tablet_pad_mode_group_has_button(struct libinput_tablet_pad_mode_group * group,unsigned int button)3423 libinput_tablet_pad_mode_group_has_button(struct libinput_tablet_pad_mode_group *group,
3424 unsigned int button)
3425 {
3426 if ((int)button >=
3427 libinput_device_tablet_pad_get_num_buttons(group->device))
3428 return 0;
3429
3430 return !!(group->button_mask & (1 << button));
3431 }
3432
3433 LIBINPUT_EXPORT int
libinput_tablet_pad_mode_group_has_ring(struct libinput_tablet_pad_mode_group * group,unsigned int ring)3434 libinput_tablet_pad_mode_group_has_ring(struct libinput_tablet_pad_mode_group *group,
3435 unsigned int ring)
3436 {
3437 if ((int)ring >=
3438 libinput_device_tablet_pad_get_num_rings(group->device))
3439 return 0;
3440
3441 return !!(group->ring_mask & (1 << ring));
3442 }
3443
3444 LIBINPUT_EXPORT int
libinput_tablet_pad_mode_group_has_strip(struct libinput_tablet_pad_mode_group * group,unsigned int strip)3445 libinput_tablet_pad_mode_group_has_strip(struct libinput_tablet_pad_mode_group *group,
3446 unsigned int strip)
3447 {
3448 if ((int)strip >=
3449 libinput_device_tablet_pad_get_num_strips(group->device))
3450 return 0;
3451
3452 return !!(group->strip_mask & (1 << strip));
3453 }
3454
3455 LIBINPUT_EXPORT int
libinput_tablet_pad_mode_group_button_is_toggle(struct libinput_tablet_pad_mode_group * group,unsigned int button)3456 libinput_tablet_pad_mode_group_button_is_toggle(struct libinput_tablet_pad_mode_group *group,
3457 unsigned int button)
3458 {
3459 if ((int)button >=
3460 libinput_device_tablet_pad_get_num_buttons(group->device))
3461 return 0;
3462
3463 return !!(group->toggle_button_mask & (1 << button));
3464 }
3465
3466 LIBINPUT_EXPORT struct libinput_tablet_pad_mode_group *
libinput_tablet_pad_mode_group_ref(struct libinput_tablet_pad_mode_group * group)3467 libinput_tablet_pad_mode_group_ref(
3468 struct libinput_tablet_pad_mode_group *group)
3469 {
3470 group->refcount++;
3471 return group;
3472 }
3473
3474 LIBINPUT_EXPORT struct libinput_tablet_pad_mode_group *
libinput_tablet_pad_mode_group_unref(struct libinput_tablet_pad_mode_group * group)3475 libinput_tablet_pad_mode_group_unref(
3476 struct libinput_tablet_pad_mode_group *group)
3477 {
3478 assert(group->refcount > 0);
3479
3480 group->refcount--;
3481 if (group->refcount > 0)
3482 return group;
3483
3484 list_remove(&group->link);
3485 group->destroy(group);
3486 return NULL;
3487 }
3488
3489 LIBINPUT_EXPORT void
libinput_tablet_pad_mode_group_set_user_data(struct libinput_tablet_pad_mode_group * group,void * user_data)3490 libinput_tablet_pad_mode_group_set_user_data(
3491 struct libinput_tablet_pad_mode_group *group,
3492 void *user_data)
3493 {
3494 group->user_data = user_data;
3495 }
3496
3497 LIBINPUT_EXPORT void *
libinput_tablet_pad_mode_group_get_user_data(struct libinput_tablet_pad_mode_group * group)3498 libinput_tablet_pad_mode_group_get_user_data(
3499 struct libinput_tablet_pad_mode_group *group)
3500 {
3501 return group->user_data;
3502 }
3503
3504 LIBINPUT_EXPORT struct libinput_event *
libinput_event_device_notify_get_base_event(struct libinput_event_device_notify * event)3505 libinput_event_device_notify_get_base_event(struct libinput_event_device_notify *event)
3506 {
3507 require_event_type(libinput_event_get_context(&event->base),
3508 event->base.type,
3509 NULL,
3510 LIBINPUT_EVENT_DEVICE_ADDED,
3511 LIBINPUT_EVENT_DEVICE_REMOVED);
3512
3513 return &event->base;
3514 }
3515
3516 LIBINPUT_EXPORT struct libinput_event *
libinput_event_keyboard_get_base_event(struct libinput_event_keyboard * event)3517 libinput_event_keyboard_get_base_event(struct libinput_event_keyboard *event)
3518 {
3519 require_event_type(libinput_event_get_context(&event->base),
3520 event->base.type,
3521 NULL,
3522 LIBINPUT_EVENT_KEYBOARD_KEY);
3523
3524 return &event->base;
3525 }
3526
3527 LIBINPUT_EXPORT struct libinput_event *
libinput_event_pointer_get_base_event(struct libinput_event_pointer * event)3528 libinput_event_pointer_get_base_event(struct libinput_event_pointer *event)
3529 {
3530 require_event_type(libinput_event_get_context(&event->base),
3531 event->base.type,
3532 NULL,
3533 LIBINPUT_EVENT_POINTER_MOTION,
3534 LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE,
3535 LIBINPUT_EVENT_POINTER_BUTTON,
3536 LIBINPUT_EVENT_POINTER_SCROLL_WHEEL,
3537 LIBINPUT_EVENT_POINTER_SCROLL_FINGER,
3538 LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS,
3539 LIBINPUT_EVENT_POINTER_AXIS);
3540
3541 return &event->base;
3542 }
3543
3544 LIBINPUT_EXPORT struct libinput_event *
libinput_event_touch_get_base_event(struct libinput_event_touch * event)3545 libinput_event_touch_get_base_event(struct libinput_event_touch *event)
3546 {
3547 require_event_type(libinput_event_get_context(&event->base),
3548 event->base.type,
3549 NULL,
3550 LIBINPUT_EVENT_TOUCH_DOWN,
3551 LIBINPUT_EVENT_TOUCH_UP,
3552 LIBINPUT_EVENT_TOUCH_MOTION,
3553 LIBINPUT_EVENT_TOUCH_CANCEL,
3554 LIBINPUT_EVENT_TOUCH_FRAME);
3555
3556 return &event->base;
3557 }
3558
3559 LIBINPUT_EXPORT struct libinput_event *
libinput_event_gesture_get_base_event(struct libinput_event_gesture * event)3560 libinput_event_gesture_get_base_event(struct libinput_event_gesture *event)
3561 {
3562 require_event_type(libinput_event_get_context(&event->base),
3563 event->base.type,
3564 NULL,
3565 LIBINPUT_EVENT_GESTURE_SWIPE_BEGIN,
3566 LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE,
3567 LIBINPUT_EVENT_GESTURE_SWIPE_END,
3568 LIBINPUT_EVENT_GESTURE_PINCH_BEGIN,
3569 LIBINPUT_EVENT_GESTURE_PINCH_UPDATE,
3570 LIBINPUT_EVENT_GESTURE_PINCH_END,
3571 LIBINPUT_EVENT_GESTURE_HOLD_BEGIN,
3572 LIBINPUT_EVENT_GESTURE_HOLD_END);
3573
3574 return &event->base;
3575 }
3576
3577 LIBINPUT_EXPORT struct libinput_event *
libinput_event_tablet_tool_get_base_event(struct libinput_event_tablet_tool * event)3578 libinput_event_tablet_tool_get_base_event(struct libinput_event_tablet_tool *event)
3579 {
3580 require_event_type(libinput_event_get_context(&event->base),
3581 event->base.type,
3582 NULL,
3583 LIBINPUT_EVENT_TABLET_TOOL_AXIS,
3584 LIBINPUT_EVENT_TABLET_TOOL_TIP,
3585 LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY,
3586 LIBINPUT_EVENT_TABLET_TOOL_BUTTON);
3587
3588 return &event->base;
3589 }
3590
3591 LIBINPUT_EXPORT double
libinput_event_tablet_pad_get_ring_position(struct libinput_event_tablet_pad * event)3592 libinput_event_tablet_pad_get_ring_position(struct libinput_event_tablet_pad *event)
3593 {
3594 require_event_type(libinput_event_get_context(&event->base),
3595 event->base.type,
3596 0.0,
3597 LIBINPUT_EVENT_TABLET_PAD_RING);
3598
3599 return event->ring.position;
3600 }
3601
3602 LIBINPUT_EXPORT unsigned int
libinput_event_tablet_pad_get_ring_number(struct libinput_event_tablet_pad * event)3603 libinput_event_tablet_pad_get_ring_number(struct libinput_event_tablet_pad *event)
3604 {
3605 require_event_type(libinput_event_get_context(&event->base),
3606 event->base.type,
3607 0,
3608 LIBINPUT_EVENT_TABLET_PAD_RING);
3609
3610 return event->ring.number;
3611 }
3612
3613 LIBINPUT_EXPORT enum libinput_tablet_pad_ring_axis_source
libinput_event_tablet_pad_get_ring_source(struct libinput_event_tablet_pad * event)3614 libinput_event_tablet_pad_get_ring_source(struct libinput_event_tablet_pad *event)
3615 {
3616 require_event_type(libinput_event_get_context(&event->base),
3617 event->base.type,
3618 LIBINPUT_TABLET_PAD_RING_SOURCE_UNKNOWN,
3619 LIBINPUT_EVENT_TABLET_PAD_RING);
3620
3621 return event->ring.source;
3622 }
3623
3624 LIBINPUT_EXPORT double
libinput_event_tablet_pad_get_strip_position(struct libinput_event_tablet_pad * event)3625 libinput_event_tablet_pad_get_strip_position(struct libinput_event_tablet_pad *event)
3626 {
3627 require_event_type(libinput_event_get_context(&event->base),
3628 event->base.type,
3629 0.0,
3630 LIBINPUT_EVENT_TABLET_PAD_STRIP);
3631
3632 return event->strip.position;
3633 }
3634
3635 LIBINPUT_EXPORT unsigned int
libinput_event_tablet_pad_get_strip_number(struct libinput_event_tablet_pad * event)3636 libinput_event_tablet_pad_get_strip_number(struct libinput_event_tablet_pad *event)
3637 {
3638 require_event_type(libinput_event_get_context(&event->base),
3639 event->base.type,
3640 0,
3641 LIBINPUT_EVENT_TABLET_PAD_STRIP);
3642
3643 return event->strip.number;
3644 }
3645
3646 LIBINPUT_EXPORT enum libinput_tablet_pad_strip_axis_source
libinput_event_tablet_pad_get_strip_source(struct libinput_event_tablet_pad * event)3647 libinput_event_tablet_pad_get_strip_source(struct libinput_event_tablet_pad *event)
3648 {
3649 require_event_type(libinput_event_get_context(&event->base),
3650 event->base.type,
3651 LIBINPUT_TABLET_PAD_STRIP_SOURCE_UNKNOWN,
3652 LIBINPUT_EVENT_TABLET_PAD_STRIP);
3653
3654 return event->strip.source;
3655 }
3656
3657 LIBINPUT_EXPORT uint32_t
libinput_event_tablet_pad_get_button_number(struct libinput_event_tablet_pad * event)3658 libinput_event_tablet_pad_get_button_number(struct libinput_event_tablet_pad *event)
3659 {
3660 require_event_type(libinput_event_get_context(&event->base),
3661 event->base.type,
3662 0,
3663 LIBINPUT_EVENT_TABLET_PAD_BUTTON);
3664
3665 return event->button.number;
3666 }
3667
3668 LIBINPUT_EXPORT enum libinput_button_state
libinput_event_tablet_pad_get_button_state(struct libinput_event_tablet_pad * event)3669 libinput_event_tablet_pad_get_button_state(struct libinput_event_tablet_pad *event)
3670 {
3671 require_event_type(libinput_event_get_context(&event->base),
3672 event->base.type,
3673 LIBINPUT_BUTTON_STATE_RELEASED,
3674 LIBINPUT_EVENT_TABLET_PAD_BUTTON);
3675
3676 return event->button.state;
3677 }
3678
3679 LIBINPUT_EXPORT uint32_t
libinput_event_tablet_pad_get_key(struct libinput_event_tablet_pad * event)3680 libinput_event_tablet_pad_get_key(struct libinput_event_tablet_pad *event)
3681 {
3682 require_event_type(libinput_event_get_context(&event->base),
3683 event->base.type,
3684 0,
3685 LIBINPUT_EVENT_TABLET_PAD_KEY);
3686
3687 return event->key.code;
3688 }
3689
3690 LIBINPUT_EXPORT enum libinput_key_state
libinput_event_tablet_pad_get_key_state(struct libinput_event_tablet_pad * event)3691 libinput_event_tablet_pad_get_key_state(struct libinput_event_tablet_pad *event)
3692 {
3693 require_event_type(libinput_event_get_context(&event->base),
3694 event->base.type,
3695 LIBINPUT_KEY_STATE_RELEASED,
3696 LIBINPUT_EVENT_TABLET_PAD_KEY);
3697
3698 return event->key.state;
3699 }
3700
3701 LIBINPUT_EXPORT unsigned int
libinput_event_tablet_pad_get_mode(struct libinput_event_tablet_pad * event)3702 libinput_event_tablet_pad_get_mode(struct libinput_event_tablet_pad *event)
3703 {
3704 require_event_type(libinput_event_get_context(&event->base),
3705 event->base.type,
3706 0,
3707 LIBINPUT_EVENT_TABLET_PAD_RING,
3708 LIBINPUT_EVENT_TABLET_PAD_STRIP,
3709 LIBINPUT_EVENT_TABLET_PAD_BUTTON);
3710
3711 return event->mode;
3712 }
3713
3714 LIBINPUT_EXPORT struct libinput_tablet_pad_mode_group *
libinput_event_tablet_pad_get_mode_group(struct libinput_event_tablet_pad * event)3715 libinput_event_tablet_pad_get_mode_group(struct libinput_event_tablet_pad *event)
3716 {
3717 require_event_type(libinput_event_get_context(&event->base),
3718 event->base.type,
3719 NULL,
3720 LIBINPUT_EVENT_TABLET_PAD_RING,
3721 LIBINPUT_EVENT_TABLET_PAD_STRIP,
3722 LIBINPUT_EVENT_TABLET_PAD_BUTTON);
3723
3724 return event->mode_group;
3725 }
3726
3727 LIBINPUT_EXPORT uint32_t
libinput_event_tablet_pad_get_time(struct libinput_event_tablet_pad * event)3728 libinput_event_tablet_pad_get_time(struct libinput_event_tablet_pad *event)
3729 {
3730 require_event_type(libinput_event_get_context(&event->base),
3731 event->base.type,
3732 0,
3733 LIBINPUT_EVENT_TABLET_PAD_RING,
3734 LIBINPUT_EVENT_TABLET_PAD_STRIP,
3735 LIBINPUT_EVENT_TABLET_PAD_BUTTON,
3736 LIBINPUT_EVENT_TABLET_PAD_KEY);
3737
3738 return us2ms(event->time);
3739 }
3740
3741 LIBINPUT_EXPORT uint64_t
libinput_event_tablet_pad_get_time_usec(struct libinput_event_tablet_pad * event)3742 libinput_event_tablet_pad_get_time_usec(struct libinput_event_tablet_pad *event)
3743 {
3744 require_event_type(libinput_event_get_context(&event->base),
3745 event->base.type,
3746 0,
3747 LIBINPUT_EVENT_TABLET_PAD_RING,
3748 LIBINPUT_EVENT_TABLET_PAD_STRIP,
3749 LIBINPUT_EVENT_TABLET_PAD_BUTTON,
3750 LIBINPUT_EVENT_TABLET_PAD_KEY);
3751
3752 return event->time;
3753 }
3754
3755 LIBINPUT_EXPORT struct libinput_event *
libinput_event_tablet_pad_get_base_event(struct libinput_event_tablet_pad * event)3756 libinput_event_tablet_pad_get_base_event(struct libinput_event_tablet_pad *event)
3757 {
3758 require_event_type(libinput_event_get_context(&event->base),
3759 event->base.type,
3760 NULL,
3761 LIBINPUT_EVENT_TABLET_PAD_RING,
3762 LIBINPUT_EVENT_TABLET_PAD_STRIP,
3763 LIBINPUT_EVENT_TABLET_PAD_BUTTON,
3764 LIBINPUT_EVENT_TABLET_PAD_KEY);
3765
3766 return &event->base;
3767 }
3768
3769 LIBINPUT_EXPORT struct libinput_device_group *
libinput_device_group_ref(struct libinput_device_group * group)3770 libinput_device_group_ref(struct libinput_device_group *group)
3771 {
3772 group->refcount++;
3773 return group;
3774 }
3775
3776 struct libinput_device_group *
libinput_device_group_create(struct libinput * libinput,const char * identifier)3777 libinput_device_group_create(struct libinput *libinput,
3778 const char *identifier)
3779 {
3780 struct libinput_device_group *group;
3781
3782 group = zalloc(sizeof *group);
3783 group->refcount = 1;
3784 group->identifier = safe_strdup(identifier);
3785
3786 list_init(&group->link);
3787 list_insert(&libinput->device_group_list, &group->link);
3788
3789 return group;
3790 }
3791
3792 struct libinput_device_group *
libinput_device_group_find_group(struct libinput * libinput,const char * identifier)3793 libinput_device_group_find_group(struct libinput *libinput,
3794 const char *identifier)
3795 {
3796 struct libinput_device_group *g = NULL;
3797
3798 list_for_each(g, &libinput->device_group_list, link) {
3799 if (identifier && g->identifier &&
3800 streq(g->identifier, identifier)) {
3801 return g;
3802 }
3803 }
3804
3805 return NULL;
3806 }
3807
3808 void
libinput_device_set_device_group(struct libinput_device * device,struct libinput_device_group * group)3809 libinput_device_set_device_group(struct libinput_device *device,
3810 struct libinput_device_group *group)
3811 {
3812 device->group = group;
3813 libinput_device_group_ref(group);
3814 }
3815
3816 static void
libinput_device_group_destroy(struct libinput_device_group * group)3817 libinput_device_group_destroy(struct libinput_device_group *group)
3818 {
3819 list_remove(&group->link);
3820 free(group->identifier);
3821 free(group);
3822 }
3823
3824 LIBINPUT_EXPORT struct libinput_device_group *
libinput_device_group_unref(struct libinput_device_group * group)3825 libinput_device_group_unref(struct libinput_device_group *group)
3826 {
3827 assert(group->refcount > 0);
3828 group->refcount--;
3829 if (group->refcount == 0) {
3830 libinput_device_group_destroy(group);
3831 return NULL;
3832 }
3833
3834 return group;
3835 }
3836
3837 LIBINPUT_EXPORT void
libinput_device_group_set_user_data(struct libinput_device_group * group,void * user_data)3838 libinput_device_group_set_user_data(struct libinput_device_group *group,
3839 void *user_data)
3840 {
3841 group->user_data = user_data;
3842 }
3843
3844 LIBINPUT_EXPORT void *
libinput_device_group_get_user_data(struct libinput_device_group * group)3845 libinput_device_group_get_user_data(struct libinput_device_group *group)
3846 {
3847 return group->user_data;
3848 }
3849
3850 LIBINPUT_EXPORT const char *
libinput_config_status_to_str(enum libinput_config_status status)3851 libinput_config_status_to_str(enum libinput_config_status status)
3852 {
3853 const char *str = NULL;
3854
3855 switch(status) {
3856 case LIBINPUT_CONFIG_STATUS_SUCCESS:
3857 str = "Success";
3858 break;
3859 case LIBINPUT_CONFIG_STATUS_UNSUPPORTED:
3860 str = "Unsupported configuration option";
3861 break;
3862 case LIBINPUT_CONFIG_STATUS_INVALID:
3863 str = "Invalid argument range";
3864 break;
3865 }
3866
3867 return str;
3868 }
3869
3870 LIBINPUT_EXPORT int
libinput_device_config_tap_get_finger_count(struct libinput_device * device)3871 libinput_device_config_tap_get_finger_count(struct libinput_device *device)
3872 {
3873 return device->config.tap ? device->config.tap->count(device) : 0;
3874 }
3875
3876 LIBINPUT_EXPORT enum libinput_config_status
libinput_device_config_tap_set_enabled(struct libinput_device * device,enum libinput_config_tap_state enable)3877 libinput_device_config_tap_set_enabled(struct libinput_device *device,
3878 enum libinput_config_tap_state enable)
3879 {
3880 if (enable != LIBINPUT_CONFIG_TAP_ENABLED &&
3881 enable != LIBINPUT_CONFIG_TAP_DISABLED)
3882 return LIBINPUT_CONFIG_STATUS_INVALID;
3883
3884 if (libinput_device_config_tap_get_finger_count(device) == 0)
3885 return enable ? LIBINPUT_CONFIG_STATUS_UNSUPPORTED :
3886 LIBINPUT_CONFIG_STATUS_SUCCESS;
3887
3888 return device->config.tap->set_enabled(device, enable);
3889
3890 }
3891
3892 LIBINPUT_EXPORT enum libinput_config_tap_state
libinput_device_config_tap_get_enabled(struct libinput_device * device)3893 libinput_device_config_tap_get_enabled(struct libinput_device *device)
3894 {
3895 if (libinput_device_config_tap_get_finger_count(device) == 0)
3896 return LIBINPUT_CONFIG_TAP_DISABLED;
3897
3898 return device->config.tap->get_enabled(device);
3899 }
3900
3901 LIBINPUT_EXPORT enum libinput_config_tap_state
libinput_device_config_tap_get_default_enabled(struct libinput_device * device)3902 libinput_device_config_tap_get_default_enabled(struct libinput_device *device)
3903 {
3904 if (libinput_device_config_tap_get_finger_count(device) == 0)
3905 return LIBINPUT_CONFIG_TAP_DISABLED;
3906
3907 return device->config.tap->get_default(device);
3908 }
3909
3910 LIBINPUT_EXPORT enum libinput_config_status
libinput_device_config_tap_set_button_map(struct libinput_device * device,enum libinput_config_tap_button_map map)3911 libinput_device_config_tap_set_button_map(struct libinput_device *device,
3912 enum libinput_config_tap_button_map map)
3913 {
3914 switch (map) {
3915 case LIBINPUT_CONFIG_TAP_MAP_LRM:
3916 case LIBINPUT_CONFIG_TAP_MAP_LMR:
3917 break;
3918 default:
3919 return LIBINPUT_CONFIG_STATUS_INVALID;
3920 }
3921
3922 if (libinput_device_config_tap_get_finger_count(device) == 0)
3923 return LIBINPUT_CONFIG_STATUS_UNSUPPORTED;
3924
3925 return device->config.tap->set_map(device, map);
3926 }
3927
3928 LIBINPUT_EXPORT enum libinput_config_tap_button_map
libinput_device_config_tap_get_button_map(struct libinput_device * device)3929 libinput_device_config_tap_get_button_map(struct libinput_device *device)
3930 {
3931 if (libinput_device_config_tap_get_finger_count(device) == 0)
3932 return LIBINPUT_CONFIG_TAP_MAP_LRM;
3933
3934 return device->config.tap->get_map(device);
3935 }
3936
3937 LIBINPUT_EXPORT enum libinput_config_tap_button_map
libinput_device_config_tap_get_default_button_map(struct libinput_device * device)3938 libinput_device_config_tap_get_default_button_map(struct libinput_device *device)
3939 {
3940 if (libinput_device_config_tap_get_finger_count(device) == 0)
3941 return LIBINPUT_CONFIG_TAP_MAP_LRM;
3942
3943 return device->config.tap->get_default_map(device);
3944 }
3945
3946 LIBINPUT_EXPORT enum libinput_config_status
libinput_device_config_tap_set_drag_enabled(struct libinput_device * device,enum libinput_config_drag_state enable)3947 libinput_device_config_tap_set_drag_enabled(struct libinput_device *device,
3948 enum libinput_config_drag_state enable)
3949 {
3950 if (enable != LIBINPUT_CONFIG_DRAG_ENABLED &&
3951 enable != LIBINPUT_CONFIG_DRAG_DISABLED)
3952 return LIBINPUT_CONFIG_STATUS_INVALID;
3953
3954 if (libinput_device_config_tap_get_finger_count(device) == 0)
3955 return enable ? LIBINPUT_CONFIG_STATUS_UNSUPPORTED :
3956 LIBINPUT_CONFIG_STATUS_SUCCESS;
3957
3958 return device->config.tap->set_drag_enabled(device, enable);
3959 }
3960
3961 LIBINPUT_EXPORT enum libinput_config_drag_state
libinput_device_config_tap_get_drag_enabled(struct libinput_device * device)3962 libinput_device_config_tap_get_drag_enabled(struct libinput_device *device)
3963 {
3964 if (libinput_device_config_tap_get_finger_count(device) == 0)
3965 return LIBINPUT_CONFIG_DRAG_DISABLED;
3966
3967 return device->config.tap->get_drag_enabled(device);
3968 }
3969
3970 LIBINPUT_EXPORT enum libinput_config_drag_state
libinput_device_config_tap_get_default_drag_enabled(struct libinput_device * device)3971 libinput_device_config_tap_get_default_drag_enabled(struct libinput_device *device)
3972 {
3973 if (libinput_device_config_tap_get_finger_count(device) == 0)
3974 return LIBINPUT_CONFIG_DRAG_DISABLED;
3975
3976 return device->config.tap->get_default_drag_enabled(device);
3977 }
3978
3979 LIBINPUT_EXPORT enum libinput_config_status
libinput_device_config_tap_set_drag_lock_enabled(struct libinput_device * device,enum libinput_config_drag_lock_state enable)3980 libinput_device_config_tap_set_drag_lock_enabled(struct libinput_device *device,
3981 enum libinput_config_drag_lock_state enable)
3982 {
3983 if (enable != LIBINPUT_CONFIG_DRAG_LOCK_ENABLED &&
3984 enable != LIBINPUT_CONFIG_DRAG_LOCK_DISABLED)
3985 return LIBINPUT_CONFIG_STATUS_INVALID;
3986
3987 if (libinput_device_config_tap_get_finger_count(device) == 0)
3988 return enable ? LIBINPUT_CONFIG_STATUS_UNSUPPORTED :
3989 LIBINPUT_CONFIG_STATUS_SUCCESS;
3990
3991 return device->config.tap->set_draglock_enabled(device, enable);
3992 }
3993
3994 LIBINPUT_EXPORT enum libinput_config_drag_lock_state
libinput_device_config_tap_get_drag_lock_enabled(struct libinput_device * device)3995 libinput_device_config_tap_get_drag_lock_enabled(struct libinput_device *device)
3996 {
3997 if (libinput_device_config_tap_get_finger_count(device) == 0)
3998 return LIBINPUT_CONFIG_DRAG_LOCK_DISABLED;
3999
4000 return device->config.tap->get_draglock_enabled(device);
4001 }
4002
4003 LIBINPUT_EXPORT enum libinput_config_drag_lock_state
libinput_device_config_tap_get_default_drag_lock_enabled(struct libinput_device * device)4004 libinput_device_config_tap_get_default_drag_lock_enabled(struct libinput_device *device)
4005 {
4006 if (libinput_device_config_tap_get_finger_count(device) == 0)
4007 return LIBINPUT_CONFIG_DRAG_LOCK_DISABLED;
4008
4009 return device->config.tap->get_default_draglock_enabled(device);
4010 }
4011
4012 LIBINPUT_EXPORT int
libinput_device_config_calibration_has_matrix(struct libinput_device * device)4013 libinput_device_config_calibration_has_matrix(struct libinput_device *device)
4014 {
4015 return device->config.calibration ?
4016 device->config.calibration->has_matrix(device) : 0;
4017 }
4018
4019 LIBINPUT_EXPORT enum libinput_config_status
libinput_device_config_calibration_set_matrix(struct libinput_device * device,const float matrix[6])4020 libinput_device_config_calibration_set_matrix(struct libinput_device *device,
4021 const float matrix[6])
4022 {
4023 if (!libinput_device_config_calibration_has_matrix(device))
4024 return LIBINPUT_CONFIG_STATUS_UNSUPPORTED;
4025
4026 return device->config.calibration->set_matrix(device, matrix);
4027 }
4028
4029 LIBINPUT_EXPORT int
libinput_device_config_calibration_get_matrix(struct libinput_device * device,float matrix[6])4030 libinput_device_config_calibration_get_matrix(struct libinput_device *device,
4031 float matrix[6])
4032 {
4033 if (!libinput_device_config_calibration_has_matrix(device))
4034 return 0;
4035
4036 return device->config.calibration->get_matrix(device, matrix);
4037 }
4038
4039 LIBINPUT_EXPORT int
libinput_device_config_calibration_get_default_matrix(struct libinput_device * device,float matrix[6])4040 libinput_device_config_calibration_get_default_matrix(struct libinput_device *device,
4041 float matrix[6])
4042 {
4043 if (!libinput_device_config_calibration_has_matrix(device))
4044 return 0;
4045
4046 return device->config.calibration->get_default_matrix(device, matrix);
4047 }
4048
4049 LIBINPUT_EXPORT uint32_t
libinput_device_config_send_events_get_modes(struct libinput_device * device)4050 libinput_device_config_send_events_get_modes(struct libinput_device *device)
4051 {
4052 uint32_t modes = LIBINPUT_CONFIG_SEND_EVENTS_ENABLED;
4053
4054 if (device->config.sendevents)
4055 modes |= device->config.sendevents->get_modes(device);
4056
4057 return modes;
4058 }
4059
4060 LIBINPUT_EXPORT enum libinput_config_status
libinput_device_config_send_events_set_mode(struct libinput_device * device,uint32_t mode)4061 libinput_device_config_send_events_set_mode(struct libinput_device *device,
4062 uint32_t mode)
4063 {
4064 if ((libinput_device_config_send_events_get_modes(device) & mode) != mode)
4065 return LIBINPUT_CONFIG_STATUS_UNSUPPORTED;
4066
4067 if (device->config.sendevents)
4068 return device->config.sendevents->set_mode(device, mode);
4069
4070 /* mode must be _ENABLED to get here */
4071 return LIBINPUT_CONFIG_STATUS_SUCCESS;
4072 }
4073
4074 LIBINPUT_EXPORT uint32_t
libinput_device_config_send_events_get_mode(struct libinput_device * device)4075 libinput_device_config_send_events_get_mode(struct libinput_device *device)
4076 {
4077 if (device->config.sendevents)
4078 return device->config.sendevents->get_mode(device);
4079
4080 return LIBINPUT_CONFIG_SEND_EVENTS_ENABLED;
4081 }
4082
4083 LIBINPUT_EXPORT uint32_t
libinput_device_config_send_events_get_default_mode(struct libinput_device * device)4084 libinput_device_config_send_events_get_default_mode(struct libinput_device *device)
4085 {
4086 return LIBINPUT_CONFIG_SEND_EVENTS_ENABLED;
4087 }
4088
4089 LIBINPUT_EXPORT int
libinput_device_config_accel_is_available(struct libinput_device * device)4090 libinput_device_config_accel_is_available(struct libinput_device *device)
4091 {
4092 return device->config.accel ?
4093 device->config.accel->available(device) : 0;
4094 }
4095
4096 LIBINPUT_EXPORT enum libinput_config_status
libinput_device_config_accel_set_speed(struct libinput_device * device,double speed)4097 libinput_device_config_accel_set_speed(struct libinput_device *device,
4098 double speed)
4099 {
4100 /* Need the negation in case speed is NaN */
4101 if (!(speed >= -1.0 && speed <= 1.0))
4102 return LIBINPUT_CONFIG_STATUS_INVALID;
4103
4104 if (!libinput_device_config_accel_is_available(device))
4105 return LIBINPUT_CONFIG_STATUS_UNSUPPORTED;
4106
4107 return device->config.accel->set_speed(device, speed);
4108 }
4109 LIBINPUT_EXPORT double
libinput_device_config_accel_get_speed(struct libinput_device * device)4110 libinput_device_config_accel_get_speed(struct libinput_device *device)
4111 {
4112 if (!libinput_device_config_accel_is_available(device))
4113 return 0;
4114
4115 return device->config.accel->get_speed(device);
4116 }
4117
4118 LIBINPUT_EXPORT double
libinput_device_config_accel_get_default_speed(struct libinput_device * device)4119 libinput_device_config_accel_get_default_speed(struct libinput_device *device)
4120 {
4121 if (!libinput_device_config_accel_is_available(device))
4122 return 0;
4123
4124 return device->config.accel->get_default_speed(device);
4125 }
4126
4127 LIBINPUT_EXPORT uint32_t
libinput_device_config_accel_get_profiles(struct libinput_device * device)4128 libinput_device_config_accel_get_profiles(struct libinput_device *device)
4129 {
4130 if (!libinput_device_config_accel_is_available(device))
4131 return 0;
4132
4133 return device->config.accel->get_profiles(device);
4134 }
4135
4136 LIBINPUT_EXPORT enum libinput_config_accel_profile
libinput_device_config_accel_get_profile(struct libinput_device * device)4137 libinput_device_config_accel_get_profile(struct libinput_device *device)
4138 {
4139 if (!libinput_device_config_accel_is_available(device))
4140 return LIBINPUT_CONFIG_ACCEL_PROFILE_NONE;
4141
4142 return device->config.accel->get_profile(device);
4143 }
4144
4145 LIBINPUT_EXPORT enum libinput_config_accel_profile
libinput_device_config_accel_get_default_profile(struct libinput_device * device)4146 libinput_device_config_accel_get_default_profile(struct libinput_device *device)
4147 {
4148 if (!libinput_device_config_accel_is_available(device))
4149 return LIBINPUT_CONFIG_ACCEL_PROFILE_NONE;
4150
4151 return device->config.accel->get_default_profile(device);
4152 }
4153
4154 LIBINPUT_EXPORT enum libinput_config_status
libinput_device_config_accel_set_profile(struct libinput_device * device,enum libinput_config_accel_profile profile)4155 libinput_device_config_accel_set_profile(struct libinput_device *device,
4156 enum libinput_config_accel_profile profile)
4157 {
4158 switch (profile) {
4159 case LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT:
4160 case LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE:
4161 break;
4162 default:
4163 return LIBINPUT_CONFIG_STATUS_INVALID;
4164 }
4165
4166 if (!libinput_device_config_accel_is_available(device) ||
4167 (libinput_device_config_accel_get_profiles(device) & profile) == 0)
4168 return LIBINPUT_CONFIG_STATUS_UNSUPPORTED;
4169
4170 return device->config.accel->set_profile(device, profile);
4171 }
4172
4173 LIBINPUT_EXPORT int
libinput_device_config_scroll_has_natural_scroll(struct libinput_device * device)4174 libinput_device_config_scroll_has_natural_scroll(struct libinput_device *device)
4175 {
4176 if (!device->config.natural_scroll)
4177 return 0;
4178
4179 return device->config.natural_scroll->has(device);
4180 }
4181
4182 LIBINPUT_EXPORT enum libinput_config_status
libinput_device_config_scroll_set_natural_scroll_enabled(struct libinput_device * device,int enabled)4183 libinput_device_config_scroll_set_natural_scroll_enabled(struct libinput_device *device,
4184 int enabled)
4185 {
4186 if (!libinput_device_config_scroll_has_natural_scroll(device))
4187 return LIBINPUT_CONFIG_STATUS_UNSUPPORTED;
4188
4189 return device->config.natural_scroll->set_enabled(device, enabled);
4190 }
4191
4192 LIBINPUT_EXPORT int
libinput_device_config_scroll_get_natural_scroll_enabled(struct libinput_device * device)4193 libinput_device_config_scroll_get_natural_scroll_enabled(struct libinput_device *device)
4194 {
4195 if (!device->config.natural_scroll)
4196 return 0;
4197
4198 return device->config.natural_scroll->get_enabled(device);
4199 }
4200
4201 LIBINPUT_EXPORT int
libinput_device_config_scroll_get_default_natural_scroll_enabled(struct libinput_device * device)4202 libinput_device_config_scroll_get_default_natural_scroll_enabled(struct libinput_device *device)
4203 {
4204 if (!device->config.natural_scroll)
4205 return 0;
4206
4207 return device->config.natural_scroll->get_default_enabled(device);
4208 }
4209
4210 LIBINPUT_EXPORT int
libinput_device_config_left_handed_is_available(struct libinput_device * device)4211 libinput_device_config_left_handed_is_available(struct libinput_device *device)
4212 {
4213 if (!device->config.left_handed)
4214 return 0;
4215
4216 return device->config.left_handed->has(device);
4217 }
4218
4219 LIBINPUT_EXPORT enum libinput_config_status
libinput_device_config_left_handed_set(struct libinput_device * device,int left_handed)4220 libinput_device_config_left_handed_set(struct libinput_device *device,
4221 int left_handed)
4222 {
4223 if (!libinput_device_config_left_handed_is_available(device))
4224 return LIBINPUT_CONFIG_STATUS_UNSUPPORTED;
4225
4226 return device->config.left_handed->set(device, left_handed);
4227 }
4228
4229 LIBINPUT_EXPORT int
libinput_device_config_left_handed_get(struct libinput_device * device)4230 libinput_device_config_left_handed_get(struct libinput_device *device)
4231 {
4232 if (!libinput_device_config_left_handed_is_available(device))
4233 return 0;
4234
4235 return device->config.left_handed->get(device);
4236 }
4237
4238 LIBINPUT_EXPORT int
libinput_device_config_left_handed_get_default(struct libinput_device * device)4239 libinput_device_config_left_handed_get_default(struct libinput_device *device)
4240 {
4241 if (!libinput_device_config_left_handed_is_available(device))
4242 return 0;
4243
4244 return device->config.left_handed->get_default(device);
4245 }
4246
4247 LIBINPUT_EXPORT uint32_t
libinput_device_config_click_get_methods(struct libinput_device * device)4248 libinput_device_config_click_get_methods(struct libinput_device *device)
4249 {
4250 if (device->config.click_method)
4251 return device->config.click_method->get_methods(device);
4252
4253 return 0;
4254 }
4255
4256 LIBINPUT_EXPORT enum libinput_config_status
libinput_device_config_click_set_method(struct libinput_device * device,enum libinput_config_click_method method)4257 libinput_device_config_click_set_method(struct libinput_device *device,
4258 enum libinput_config_click_method method)
4259 {
4260 /* Check method is a single valid method */
4261 switch (method) {
4262 case LIBINPUT_CONFIG_CLICK_METHOD_NONE:
4263 case LIBINPUT_CONFIG_CLICK_METHOD_BUTTON_AREAS:
4264 case LIBINPUT_CONFIG_CLICK_METHOD_CLICKFINGER:
4265 break;
4266 default:
4267 return LIBINPUT_CONFIG_STATUS_INVALID;
4268 }
4269
4270 if ((libinput_device_config_click_get_methods(device) & method) != method)
4271 return LIBINPUT_CONFIG_STATUS_UNSUPPORTED;
4272
4273 if (device->config.click_method)
4274 return device->config.click_method->set_method(device, method);
4275
4276 /* method must be _NONE to get here */
4277 return LIBINPUT_CONFIG_STATUS_SUCCESS;
4278 }
4279
4280 LIBINPUT_EXPORT enum libinput_config_click_method
libinput_device_config_click_get_method(struct libinput_device * device)4281 libinput_device_config_click_get_method(struct libinput_device *device)
4282 {
4283 if (device->config.click_method)
4284 return device->config.click_method->get_method(device);
4285
4286 return LIBINPUT_CONFIG_CLICK_METHOD_NONE;
4287 }
4288
4289 LIBINPUT_EXPORT enum libinput_config_click_method
libinput_device_config_click_get_default_method(struct libinput_device * device)4290 libinput_device_config_click_get_default_method(struct libinput_device *device)
4291 {
4292 if (device->config.click_method)
4293 return device->config.click_method->get_default_method(device);
4294
4295 return LIBINPUT_CONFIG_CLICK_METHOD_NONE;
4296 }
4297
4298 LIBINPUT_EXPORT int
libinput_device_config_middle_emulation_is_available(struct libinput_device * device)4299 libinput_device_config_middle_emulation_is_available(
4300 struct libinput_device *device)
4301 {
4302 if (device->config.middle_emulation)
4303 return device->config.middle_emulation->available(device);
4304
4305 return LIBINPUT_CONFIG_MIDDLE_EMULATION_DISABLED;
4306 }
4307
4308 LIBINPUT_EXPORT enum libinput_config_status
libinput_device_config_middle_emulation_set_enabled(struct libinput_device * device,enum libinput_config_middle_emulation_state enable)4309 libinput_device_config_middle_emulation_set_enabled(
4310 struct libinput_device *device,
4311 enum libinput_config_middle_emulation_state enable)
4312 {
4313 int available =
4314 libinput_device_config_middle_emulation_is_available(device);
4315
4316 switch (enable) {
4317 case LIBINPUT_CONFIG_MIDDLE_EMULATION_DISABLED:
4318 if (!available)
4319 return LIBINPUT_CONFIG_STATUS_SUCCESS;
4320 break;
4321 case LIBINPUT_CONFIG_MIDDLE_EMULATION_ENABLED:
4322 if (!available)
4323 return LIBINPUT_CONFIG_STATUS_UNSUPPORTED;
4324 break;
4325 default:
4326 return LIBINPUT_CONFIG_STATUS_INVALID;
4327 }
4328
4329 return device->config.middle_emulation->set(device, enable);
4330 }
4331
4332 LIBINPUT_EXPORT enum libinput_config_middle_emulation_state
libinput_device_config_middle_emulation_get_enabled(struct libinput_device * device)4333 libinput_device_config_middle_emulation_get_enabled(
4334 struct libinput_device *device)
4335 {
4336 if (!libinput_device_config_middle_emulation_is_available(device))
4337 return LIBINPUT_CONFIG_MIDDLE_EMULATION_DISABLED;
4338
4339 return device->config.middle_emulation->get(device);
4340 }
4341
4342 LIBINPUT_EXPORT enum libinput_config_middle_emulation_state
libinput_device_config_middle_emulation_get_default_enabled(struct libinput_device * device)4343 libinput_device_config_middle_emulation_get_default_enabled(
4344 struct libinput_device *device)
4345 {
4346 if (!libinput_device_config_middle_emulation_is_available(device))
4347 return LIBINPUT_CONFIG_MIDDLE_EMULATION_DISABLED;
4348
4349 return device->config.middle_emulation->get_default(device);
4350 }
4351
4352 LIBINPUT_EXPORT uint32_t
libinput_device_config_scroll_get_methods(struct libinput_device * device)4353 libinput_device_config_scroll_get_methods(struct libinput_device *device)
4354 {
4355 if (device->config.scroll_method)
4356 return device->config.scroll_method->get_methods(device);
4357
4358 return 0;
4359 }
4360
4361 LIBINPUT_EXPORT enum libinput_config_status
libinput_device_config_scroll_set_method(struct libinput_device * device,enum libinput_config_scroll_method method)4362 libinput_device_config_scroll_set_method(struct libinput_device *device,
4363 enum libinput_config_scroll_method method)
4364 {
4365 /* Check method is a single valid method */
4366 switch (method) {
4367 case LIBINPUT_CONFIG_SCROLL_NO_SCROLL:
4368 case LIBINPUT_CONFIG_SCROLL_2FG:
4369 case LIBINPUT_CONFIG_SCROLL_EDGE:
4370 case LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN:
4371 break;
4372 default:
4373 return LIBINPUT_CONFIG_STATUS_INVALID;
4374 }
4375
4376 if ((libinput_device_config_scroll_get_methods(device) & method) != method)
4377 return LIBINPUT_CONFIG_STATUS_UNSUPPORTED;
4378
4379 if (device->config.scroll_method)
4380 return device->config.scroll_method->set_method(device, method);
4381
4382 /* method must be _NO_SCROLL to get here */
4383 return LIBINPUT_CONFIG_STATUS_SUCCESS;
4384 }
4385
4386 LIBINPUT_EXPORT enum libinput_config_scroll_method
libinput_device_config_scroll_get_method(struct libinput_device * device)4387 libinput_device_config_scroll_get_method(struct libinput_device *device)
4388 {
4389 if (device->config.scroll_method)
4390 return device->config.scroll_method->get_method(device);
4391
4392 return LIBINPUT_CONFIG_SCROLL_NO_SCROLL;
4393 }
4394
4395 LIBINPUT_EXPORT enum libinput_config_scroll_method
libinput_device_config_scroll_get_default_method(struct libinput_device * device)4396 libinput_device_config_scroll_get_default_method(struct libinput_device *device)
4397 {
4398 if (device->config.scroll_method)
4399 return device->config.scroll_method->get_default_method(device);
4400
4401 return LIBINPUT_CONFIG_SCROLL_NO_SCROLL;
4402 }
4403
4404 LIBINPUT_EXPORT enum libinput_config_status
libinput_device_config_scroll_set_button(struct libinput_device * device,uint32_t button)4405 libinput_device_config_scroll_set_button(struct libinput_device *device,
4406 uint32_t button)
4407 {
4408 if ((libinput_device_config_scroll_get_methods(device) &
4409 LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN) == 0)
4410 return LIBINPUT_CONFIG_STATUS_UNSUPPORTED;
4411
4412 if (button && !libinput_device_pointer_has_button(device, button))
4413 return LIBINPUT_CONFIG_STATUS_INVALID;
4414
4415 return device->config.scroll_method->set_button(device, button);
4416 }
4417
4418 LIBINPUT_EXPORT uint32_t
libinput_device_config_scroll_get_button(struct libinput_device * device)4419 libinput_device_config_scroll_get_button(struct libinput_device *device)
4420 {
4421 if ((libinput_device_config_scroll_get_methods(device) &
4422 LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN) == 0)
4423 return 0;
4424
4425 return device->config.scroll_method->get_button(device);
4426 }
4427
4428 LIBINPUT_EXPORT uint32_t
libinput_device_config_scroll_get_default_button(struct libinput_device * device)4429 libinput_device_config_scroll_get_default_button(struct libinput_device *device)
4430 {
4431 if ((libinput_device_config_scroll_get_methods(device) &
4432 LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN) == 0)
4433 return 0;
4434
4435 return device->config.scroll_method->get_default_button(device);
4436 }
4437
4438 LIBINPUT_EXPORT enum libinput_config_status
libinput_device_config_scroll_set_button_lock(struct libinput_device * device,enum libinput_config_scroll_button_lock_state state)4439 libinput_device_config_scroll_set_button_lock(struct libinput_device *device,
4440 enum libinput_config_scroll_button_lock_state state)
4441 {
4442 if ((libinput_device_config_scroll_get_methods(device) &
4443 LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN) == 0)
4444 return LIBINPUT_CONFIG_STATUS_UNSUPPORTED;
4445
4446 switch (state) {
4447 case LIBINPUT_CONFIG_SCROLL_BUTTON_LOCK_ENABLED:
4448 case LIBINPUT_CONFIG_SCROLL_BUTTON_LOCK_DISABLED:
4449 break;
4450 default:
4451 return LIBINPUT_CONFIG_STATUS_INVALID;
4452 }
4453
4454 return device->config.scroll_method->set_button_lock(device, state);
4455 }
4456
4457 LIBINPUT_EXPORT enum libinput_config_scroll_button_lock_state
libinput_device_config_scroll_get_button_lock(struct libinput_device * device)4458 libinput_device_config_scroll_get_button_lock(struct libinput_device *device)
4459 {
4460 if ((libinput_device_config_scroll_get_methods(device) &
4461 LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN) == 0)
4462 return LIBINPUT_CONFIG_SCROLL_BUTTON_LOCK_DISABLED;
4463
4464 return device->config.scroll_method->get_button_lock(device);
4465 }
4466
4467 LIBINPUT_EXPORT enum libinput_config_scroll_button_lock_state
libinput_device_config_scroll_get_default_button_lock(struct libinput_device * device)4468 libinput_device_config_scroll_get_default_button_lock(struct libinput_device *device)
4469 {
4470 if ((libinput_device_config_scroll_get_methods(device) &
4471 LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN) == 0)
4472 return LIBINPUT_CONFIG_SCROLL_BUTTON_LOCK_DISABLED;
4473
4474 return device->config.scroll_method->get_default_button_lock(device);
4475 }
4476
4477 LIBINPUT_EXPORT int
libinput_device_config_dwt_is_available(struct libinput_device * device)4478 libinput_device_config_dwt_is_available(struct libinput_device *device)
4479 {
4480 if (!device->config.dwt)
4481 return 0;
4482
4483 return device->config.dwt->is_available(device);
4484 }
4485
4486 LIBINPUT_EXPORT enum libinput_config_status
libinput_device_config_dwt_set_enabled(struct libinput_device * device,enum libinput_config_dwt_state enable)4487 libinput_device_config_dwt_set_enabled(struct libinput_device *device,
4488 enum libinput_config_dwt_state enable)
4489 {
4490 if (enable != LIBINPUT_CONFIG_DWT_ENABLED &&
4491 enable != LIBINPUT_CONFIG_DWT_DISABLED)
4492 return LIBINPUT_CONFIG_STATUS_INVALID;
4493
4494 if (!libinput_device_config_dwt_is_available(device))
4495 return enable ? LIBINPUT_CONFIG_STATUS_UNSUPPORTED :
4496 LIBINPUT_CONFIG_STATUS_SUCCESS;
4497
4498 return device->config.dwt->set_enabled(device, enable);
4499 }
4500
4501 LIBINPUT_EXPORT enum libinput_config_dwt_state
libinput_device_config_dwt_get_enabled(struct libinput_device * device)4502 libinput_device_config_dwt_get_enabled(struct libinput_device *device)
4503 {
4504 if (!libinput_device_config_dwt_is_available(device))
4505 return LIBINPUT_CONFIG_DWT_DISABLED;
4506
4507 return device->config.dwt->get_enabled(device);
4508 }
4509
4510 LIBINPUT_EXPORT enum libinput_config_dwt_state
libinput_device_config_dwt_get_default_enabled(struct libinput_device * device)4511 libinput_device_config_dwt_get_default_enabled(struct libinput_device *device)
4512 {
4513 if (!libinput_device_config_dwt_is_available(device))
4514 return LIBINPUT_CONFIG_DWT_DISABLED;
4515
4516 return device->config.dwt->get_default_enabled(device);
4517 }
4518
4519 LIBINPUT_EXPORT int
libinput_device_config_rotation_is_available(struct libinput_device * device)4520 libinput_device_config_rotation_is_available(struct libinput_device *device)
4521 {
4522 if (!device->config.rotation)
4523 return 0;
4524
4525 return device->config.rotation->is_available(device);
4526 }
4527
4528 LIBINPUT_EXPORT enum libinput_config_status
libinput_device_config_rotation_set_angle(struct libinput_device * device,unsigned int degrees_cw)4529 libinput_device_config_rotation_set_angle(struct libinput_device *device,
4530 unsigned int degrees_cw)
4531 {
4532 if (!libinput_device_config_rotation_is_available(device))
4533 return degrees_cw ? LIBINPUT_CONFIG_STATUS_UNSUPPORTED :
4534 LIBINPUT_CONFIG_STATUS_SUCCESS;
4535
4536 if (degrees_cw >= 360 || degrees_cw % 90)
4537 return LIBINPUT_CONFIG_STATUS_INVALID;
4538
4539 return device->config.rotation->set_angle(device, degrees_cw);
4540 }
4541
4542 LIBINPUT_EXPORT unsigned int
libinput_device_config_rotation_get_angle(struct libinput_device * device)4543 libinput_device_config_rotation_get_angle(struct libinput_device *device)
4544 {
4545 if (!libinput_device_config_rotation_is_available(device))
4546 return 0;
4547
4548 return device->config.rotation->get_angle(device);
4549 }
4550
4551 LIBINPUT_EXPORT unsigned int
libinput_device_config_rotation_get_default_angle(struct libinput_device * device)4552 libinput_device_config_rotation_get_default_angle(struct libinput_device *device)
4553 {
4554 if (!libinput_device_config_rotation_is_available(device))
4555 return 0;
4556
4557 return device->config.rotation->get_default_angle(device);
4558 }
4559
4560 #if HAVE_LIBWACOM
4561 WacomDeviceDatabase *
libinput_libwacom_ref(struct libinput * li)4562 libinput_libwacom_ref(struct libinput *li)
4563 {
4564 WacomDeviceDatabase *db = NULL;
4565 if (!li->libwacom.db) {
4566 db = libwacom_database_new();
4567 if (!db) {
4568 log_error(li,
4569 "Failed to initialize libwacom context\n");
4570 return NULL;
4571 }
4572
4573 li->libwacom.db = db;
4574 li->libwacom.refcount = 0;
4575 }
4576
4577 li->libwacom.refcount++;
4578 db = li->libwacom.db;
4579 return db;
4580 }
4581
4582 void
libinput_libwacom_unref(struct libinput * li)4583 libinput_libwacom_unref(struct libinput *li)
4584 {
4585 if (!li->libwacom.db)
4586 return;
4587
4588 assert(li->libwacom.refcount >= 1);
4589
4590 if (--li->libwacom.refcount == 0) {
4591 libwacom_database_destroy(li->libwacom.db);
4592 li->libwacom.db = NULL;
4593 }
4594 }
4595 #endif
4596