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