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