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