xref: /third_party/libinput/src/evdev-fallback.h (revision a46c0ec8)
1/*
2 * Copyright © 2010 Intel Corporation
3 * Copyright © 2013 Jonas Ådahl
4 * Copyright © 2013-2017 Red Hat, Inc.
5 * Copyright © 2017 James Ye <jye836@gmail.com>
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the next
15 * paragraph) shall be included in all copies or substantial portions of the
16 * Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
21 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24 * DEALINGS IN THE SOFTWARE.
25 */
26
27#include "config.h"
28
29#ifndef EVDEV_FALLBACK_H
30#define EVDEV_FALLBACK_H
31
32#include "evdev.h"
33
34enum debounce_state {
35	DEBOUNCE_STATE_IS_UP = 100,
36	DEBOUNCE_STATE_IS_DOWN,
37	DEBOUNCE_STATE_IS_DOWN_WAITING,
38	DEBOUNCE_STATE_IS_UP_DELAYING,
39	DEBOUNCE_STATE_IS_UP_DELAYING_SPURIOUS,
40	DEBOUNCE_STATE_IS_UP_DETECTING_SPURIOUS,
41	DEBOUNCE_STATE_IS_DOWN_DETECTING_SPURIOUS,
42	DEBOUNCE_STATE_IS_UP_WAITING,
43	DEBOUNCE_STATE_IS_DOWN_DELAYING,
44
45	DEBOUNCE_STATE_DISABLED = 999,
46};
47
48enum mt_slot_state {
49	SLOT_STATE_NONE,
50	SLOT_STATE_BEGIN,
51	SLOT_STATE_UPDATE,
52	SLOT_STATE_END,
53};
54
55enum palm_state {
56	PALM_NONE,
57	PALM_NEW,
58	PALM_IS_PALM,
59	PALM_WAS_PALM, /* this touch sequence was a palm but isn't now */
60};
61
62enum wheel_state {
63	WHEEL_STATE_NONE,
64	WHEEL_STATE_ACCUMULATING_SCROLL,
65	WHEEL_STATE_SCROLLING,
66};
67
68enum wheel_direction {
69	WHEEL_DIR_UNKNOW,
70	WHEEL_DIR_VPOS,
71	WHEEL_DIR_VNEG,
72	WHEEL_DIR_HPOS,
73	WHEEL_DIR_HNEG,
74};
75
76struct mt_slot {
77	bool dirty;
78	enum mt_slot_state state;
79	int32_t seat_slot;
80	struct device_coords point;
81	struct device_coords hysteresis_center;
82	enum palm_state palm_state;
83};
84
85struct fallback_dispatch {
86	struct evdev_dispatch base;
87	struct evdev_device *device;
88
89	struct libinput_device_config_calibration calibration;
90
91	struct {
92		int angle;
93		struct matrix matrix;
94		struct libinput_device_config_rotation config;
95	} rotation;
96
97	struct {
98		struct device_coords point;
99		int32_t seat_slot;
100	} abs;
101
102	struct {
103		int slot;
104		struct mt_slot *slots;
105		size_t slots_len;
106		bool want_hysteresis;
107		struct device_coords hysteresis_margin;
108		bool has_palm;
109	} mt;
110
111	struct device_coords rel;
112
113	struct {
114		enum wheel_state state;
115		struct device_coords lo_res;
116		struct device_coords hi_res;
117		bool emulate_hi_res_wheel;
118		bool hi_res_event_received;
119		struct libinput_timer scroll_timer;
120		enum wheel_direction dir;
121	} wheel;
122
123	struct {
124		/* The struct for the tablet mode switch device itself */
125		struct {
126			int state;
127		} sw;
128		/* The struct for other devices listening to the tablet mode
129		   switch */
130		struct {
131			struct evdev_device *sw_device;
132			struct libinput_event_listener listener;
133		} other;
134	} tablet_mode;
135
136	/* Bitmask of pressed keys used to ignore initial release events from
137	 * the kernel. */
138	unsigned long hw_key_mask[NLONGS(KEY_CNT)];
139	unsigned long last_hw_key_mask[NLONGS(KEY_CNT)];
140
141	enum evdev_event_type pending_event;
142
143	struct {
144		unsigned int button_code;
145		uint64_t button_time;
146		struct libinput_timer timer;
147		struct libinput_timer timer_short;
148		enum debounce_state state;
149		bool spurious_enabled;
150	} debounce;
151
152	struct {
153		enum switch_reliability reliability;
154
155		bool is_closed;
156		bool is_closed_client_state;
157
158		/* We allow multiple paired keyboards for the lid switch
159		 * listener. Only one keyboard should exist, but that can
160		 * have more than one event node. And it's a list because
161		 * otherwise the test suite run fails too often.
162		 */
163		struct list paired_keyboard_list;
164	} lid;
165
166	/* pen/touch arbitration has a delayed state,
167	 * in_arbitration is what decides when to filter.
168	 */
169	struct {
170		enum evdev_arbitration_state state;
171		bool in_arbitration;
172		struct device_coord_rect rect;
173		struct libinput_timer arbitration_timer;
174	} arbitration;
175};
176
177static inline struct fallback_dispatch*
178fallback_dispatch(struct evdev_dispatch *dispatch)
179{
180	evdev_verify_dispatch_type(dispatch, DISPATCH_FALLBACK);
181
182	return container_of(dispatch, struct fallback_dispatch, base);
183}
184
185enum key_type {
186	KEY_TYPE_NONE,
187	KEY_TYPE_KEY,
188	KEY_TYPE_BUTTON,
189};
190
191static inline enum key_type
192get_key_type(uint16_t code)
193{
194	switch (code) {
195	case BTN_TOOL_PEN:
196	case BTN_TOOL_RUBBER:
197	case BTN_TOOL_BRUSH:
198	case BTN_TOOL_PENCIL:
199	case BTN_TOOL_AIRBRUSH:
200	case BTN_TOOL_MOUSE:
201	case BTN_TOOL_LENS:
202	case BTN_TOOL_QUINTTAP:
203	case BTN_TOOL_DOUBLETAP:
204	case BTN_TOOL_TRIPLETAP:
205	case BTN_TOOL_QUADTAP:
206	case BTN_TOOL_FINGER:
207	case BTN_TOUCH:
208		return KEY_TYPE_NONE;
209	}
210
211	if (code >= KEY_ESC && code <= KEY_MICMUTE)
212		return KEY_TYPE_KEY;
213	if (code >= BTN_MISC && code <= BTN_GEAR_UP)
214		return KEY_TYPE_BUTTON;
215	if (code >= KEY_OK && code <= KEY_LIGHTS_TOGGLE)
216		return KEY_TYPE_KEY;
217	if (code >= BTN_DPAD_UP && code <= BTN_DPAD_RIGHT)
218		return KEY_TYPE_BUTTON;
219	if (code >= KEY_ALS_TOGGLE && code < BTN_TRIGGER_HAPPY)
220		return KEY_TYPE_KEY;
221	if (code >= BTN_TRIGGER_HAPPY && code <= BTN_TRIGGER_HAPPY40)
222		return KEY_TYPE_BUTTON;
223	return KEY_TYPE_NONE;
224}
225
226static inline void
227hw_set_key_down(struct fallback_dispatch *dispatch, int code, int pressed)
228{
229	long_set_bit_state(dispatch->hw_key_mask, code, pressed);
230}
231
232static inline bool
233hw_key_has_changed(struct fallback_dispatch *dispatch, int code)
234{
235	return long_bit_is_set(dispatch->hw_key_mask, code) !=
236		long_bit_is_set(dispatch->last_hw_key_mask, code);
237}
238
239static inline void
240hw_key_update_last_state(struct fallback_dispatch *dispatch)
241{
242	static_assert(sizeof(dispatch->hw_key_mask) ==
243		      sizeof(dispatch->last_hw_key_mask),
244		      "Mismatching key mask size");
245
246	memcpy(dispatch->last_hw_key_mask,
247	       dispatch->hw_key_mask,
248	       sizeof(dispatch->hw_key_mask));
249}
250
251static inline bool
252hw_is_key_down(struct fallback_dispatch *dispatch, int code)
253{
254	return long_bit_is_set(dispatch->hw_key_mask, code);
255}
256
257static inline int
258get_key_down_count(struct evdev_device *device, int code)
259{
260	return device->key_count[code];
261}
262
263void fallback_init_debounce(struct fallback_dispatch *dispatch);
264void fallback_debounce_handle_state(struct fallback_dispatch *dispatch,
265				    uint64_t time);
266void
267fallback_notify_physical_button(struct fallback_dispatch *dispatch,
268				struct evdev_device *device,
269				uint64_t time,
270				int button,
271				enum libinput_button_state state);
272
273void
274fallback_init_wheel(struct fallback_dispatch *dispatch,
275		    struct evdev_device *device);
276
277void
278fallback_wheel_process_relative(struct fallback_dispatch *dispatch,
279				struct evdev_device *device,
280				struct input_event *e, uint64_t time);
281
282void
283fallback_wheel_handle_state(struct fallback_dispatch *dispatch,
284			    struct evdev_device *device,
285			    uint64_t time);
286
287#endif
288