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