xref: /dflybsd-src/sys/dev/misc/evdev/evdev_private.h (revision a162a738eca94f99d45d88429e86cfd0fbfbe95d)
1d3d1dd3eSPeeter Must /*-
2d3d1dd3eSPeeter Must  * Copyright (c) 2014 Jakub Wojciech Klama <jceel@FreeBSD.org>
3d3d1dd3eSPeeter Must  * Copyright (c) 2015-2016 Vladimir Kondratyev <wulf@FreeBSD.org>
4d3d1dd3eSPeeter Must  * All rights reserved.
5d3d1dd3eSPeeter Must  *
6d3d1dd3eSPeeter Must  * Redistribution and use in source and binary forms, with or without
7d3d1dd3eSPeeter Must  * modification, are permitted provided that the following conditions
8d3d1dd3eSPeeter Must  * are met:
9d3d1dd3eSPeeter Must  * 1. Redistributions of source code must retain the above copyright
10d3d1dd3eSPeeter Must  *    notice, this list of conditions and the following disclaimer.
11d3d1dd3eSPeeter Must  * 2. Redistributions in binary form must reproduce the above copyright
12d3d1dd3eSPeeter Must  *    notice, this list of conditions and the following disclaimer in the
13d3d1dd3eSPeeter Must  *    documentation and/or other materials provided with the distribution.
14d3d1dd3eSPeeter Must  *
15d3d1dd3eSPeeter Must  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16d3d1dd3eSPeeter Must  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17d3d1dd3eSPeeter Must  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18d3d1dd3eSPeeter Must  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19d3d1dd3eSPeeter Must  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20d3d1dd3eSPeeter Must  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21d3d1dd3eSPeeter Must  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22d3d1dd3eSPeeter Must  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23d3d1dd3eSPeeter Must  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24d3d1dd3eSPeeter Must  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25d3d1dd3eSPeeter Must  * SUCH DAMAGE.
26d3d1dd3eSPeeter Must  *
27d3d1dd3eSPeeter Must  * $FreeBSD$
28d3d1dd3eSPeeter Must  */
29d3d1dd3eSPeeter Must 
30d3d1dd3eSPeeter Must #ifndef	_DEV_EVDEV_EVDEV_PRIVATE_H
31d3d1dd3eSPeeter Must #define	_DEV_EVDEV_EVDEV_PRIVATE_H
32d3d1dd3eSPeeter Must 
33d3d1dd3eSPeeter Must #include <sys/kbio.h>
34d3d1dd3eSPeeter Must #include <sys/malloc.h>
35d3d1dd3eSPeeter Must #include <sys/queue.h>
36d3d1dd3eSPeeter Must #include <sys/event.h>
37*a162a738SMichael Neumann #include <sys/sysctl.h>
38d3d1dd3eSPeeter Must 
39d3d1dd3eSPeeter Must /* Use a local copy of FreeBSD's bitstring.h. */
40d3d1dd3eSPeeter Must #include "freebsd-bitstring.h"
41d3d1dd3eSPeeter Must 
42d3d1dd3eSPeeter Must #include <dev/misc/evdev/evdev.h>
43d3d1dd3eSPeeter Must #include <dev/misc/evdev/input.h>
44d3d1dd3eSPeeter Must #include <dev/misc/kbd/kbdreg.h>
45d3d1dd3eSPeeter Must 
46d3d1dd3eSPeeter Must #define	NAMELEN		80
47d3d1dd3eSPeeter Must 
48d3d1dd3eSPeeter Must /*
49d3d1dd3eSPeeter Must  * bitstr_t implementation must be identical to one found in EVIOCG*
50d3d1dd3eSPeeter Must  * libevdev ioctls. Our bitstring(3) API is compatible since r299090.
51d3d1dd3eSPeeter Must  */
52d3d1dd3eSPeeter Must 
53d3d1dd3eSPeeter Must /*
54d3d1dd3eSPeeter Must  * Note on DragonFly. We will use a local copy of FreeBSD's bitstring.h
55d3d1dd3eSPeeter Must  * (freebsd-bitstring.h above) to guarantee bitstr_t implementation is
56d3d1dd3eSPeeter Must  * compliant with libevdev ioctls.
57d3d1dd3eSPeeter Must  */
58d3d1dd3eSPeeter Must _Static_assert(sizeof(bitstr_t) == sizeof(unsigned long),
59d3d1dd3eSPeeter Must     "bitstr_t size mismatch");
60d3d1dd3eSPeeter Must 
61d3d1dd3eSPeeter Must MALLOC_DECLARE(M_EVDEV);
62d3d1dd3eSPeeter Must 
63d3d1dd3eSPeeter Must struct evdev_client;
64d3d1dd3eSPeeter Must struct evdev_mt;
65d3d1dd3eSPeeter Must 
66d3d1dd3eSPeeter Must #define	CURRENT_MT_SLOT(evdev)	((evdev)->ev_absinfo[ABS_MT_SLOT].value)
67d3d1dd3eSPeeter Must #define	MAXIMAL_MT_SLOT(evdev)	((evdev)->ev_absinfo[ABS_MT_SLOT].maximum)
68d3d1dd3eSPeeter Must 
69d3d1dd3eSPeeter Must enum evdev_key_events
70d3d1dd3eSPeeter Must {
71d3d1dd3eSPeeter Must 	KEY_EVENT_UP,
72d3d1dd3eSPeeter Must 	KEY_EVENT_DOWN,
73d3d1dd3eSPeeter Must 	KEY_EVENT_REPEAT
74d3d1dd3eSPeeter Must };
75d3d1dd3eSPeeter Must 
76d3d1dd3eSPeeter Must /* evdev clock IDs in Linux semantic */
77d3d1dd3eSPeeter Must enum evdev_clock_id
78d3d1dd3eSPeeter Must {
79d3d1dd3eSPeeter Must 	EV_CLOCK_REALTIME = 0,	/* UTC clock */
80d3d1dd3eSPeeter Must 	EV_CLOCK_MONOTONIC,	/* monotonic, stops on suspend */
81d3d1dd3eSPeeter Must 	EV_CLOCK_BOOTTIME	/* monotonic, suspend-awared */
82d3d1dd3eSPeeter Must };
83d3d1dd3eSPeeter Must 
84d3d1dd3eSPeeter Must enum evdev_lock_type
85d3d1dd3eSPeeter Must {
86d3d1dd3eSPeeter Must 	EV_LOCK_INTERNAL = 0,	/* Internal evdev mutex */
87d3d1dd3eSPeeter Must 	EV_LOCK_MTX,		/* Driver`s mutex */
88d3d1dd3eSPeeter Must };
89d3d1dd3eSPeeter Must 
90d3d1dd3eSPeeter Must struct evdev_dev
91d3d1dd3eSPeeter Must {
92d3d1dd3eSPeeter Must 	char			ev_name[NAMELEN];
93d3d1dd3eSPeeter Must 	char			ev_shortname[NAMELEN];
94d3d1dd3eSPeeter Must 	char			ev_serial[NAMELEN];
95d3d1dd3eSPeeter Must 	cdev_t			ev_cdev;
96d3d1dd3eSPeeter Must 	int			ev_unit;
97d3d1dd3eSPeeter Must 	enum evdev_lock_type	ev_lock_type;
98*a162a738SMichael Neumann 	struct lock *		ev_state_lock;	/* State lock */
99*a162a738SMichael Neumann 	struct lock		ev_mtx;		/* Internal state lock */
100d3d1dd3eSPeeter Must 	struct input_id		ev_id;
101*a162a738SMichael Neumann 	struct evdev_client *	ev_grabber;			/* (s) */
102d3d1dd3eSPeeter Must 	size_t			ev_report_size;
103d3d1dd3eSPeeter Must 
104d3d1dd3eSPeeter Must 	/* Supported features: */
105d3d1dd3eSPeeter Must 	bitstr_t		bit_decl(ev_prop_flags, INPUT_PROP_CNT);
106d3d1dd3eSPeeter Must 	bitstr_t		bit_decl(ev_type_flags, EV_CNT);
107d3d1dd3eSPeeter Must 	bitstr_t		bit_decl(ev_key_flags, KEY_CNT);
108d3d1dd3eSPeeter Must 	bitstr_t		bit_decl(ev_rel_flags, REL_CNT);
109d3d1dd3eSPeeter Must 	bitstr_t		bit_decl(ev_abs_flags, ABS_CNT);
110d3d1dd3eSPeeter Must 	bitstr_t		bit_decl(ev_msc_flags, MSC_CNT);
111d3d1dd3eSPeeter Must 	bitstr_t		bit_decl(ev_led_flags, LED_CNT);
112d3d1dd3eSPeeter Must 	bitstr_t		bit_decl(ev_snd_flags, SND_CNT);
113d3d1dd3eSPeeter Must 	bitstr_t		bit_decl(ev_sw_flags, SW_CNT);
114*a162a738SMichael Neumann 	struct input_absinfo *	ev_absinfo;			/* (s) */
115d3d1dd3eSPeeter Must 	bitstr_t		bit_decl(ev_flags, EVDEV_FLAG_CNT);
116d3d1dd3eSPeeter Must 
117d3d1dd3eSPeeter Must 	/* Repeat parameters & callout: */
118*a162a738SMichael Neumann 	int			ev_rep[REP_CNT];		/* (s) */
119*a162a738SMichael Neumann 	struct callout		ev_rep_callout;			/* (s) */
120*a162a738SMichael Neumann 	uint16_t		ev_rep_key;			/* (s) */
121d3d1dd3eSPeeter Must 
122d3d1dd3eSPeeter Must 	/* State: */
123*a162a738SMichael Neumann 	bitstr_t		bit_decl(ev_key_states, KEY_CNT); /* (s) */
124*a162a738SMichael Neumann 	bitstr_t		bit_decl(ev_led_states, LED_CNT); /* (s) */
125*a162a738SMichael Neumann 	bitstr_t		bit_decl(ev_snd_states, SND_CNT); /* (s) */
126*a162a738SMichael Neumann 	bitstr_t		bit_decl(ev_sw_states, SW_CNT);	/* (s) */
127*a162a738SMichael Neumann 	bool			ev_report_opened;		/* (s) */
128d3d1dd3eSPeeter Must 
129d3d1dd3eSPeeter Must 	/* Multitouch protocol type B state: */
130*a162a738SMichael Neumann 	struct evdev_mt *	ev_mt;				/* (s) */
131d3d1dd3eSPeeter Must 
132d3d1dd3eSPeeter Must 	/* Counters: */
133*a162a738SMichael Neumann 	uint64_t		ev_event_count;			/* (s) */
134*a162a738SMichael Neumann 	uint64_t		ev_report_count;		/* (s) */
135d3d1dd3eSPeeter Must 
136d3d1dd3eSPeeter Must 	/* Parent driver callbacks: */
137d3d1dd3eSPeeter Must 	const struct evdev_methods * ev_methods;
138d3d1dd3eSPeeter Must 	void *			ev_softc;
139d3d1dd3eSPeeter Must 
140*a162a738SMichael Neumann 	/* Sysctl: */
141*a162a738SMichael Neumann 	struct sysctl_ctx_list	ev_sysctl_ctx;
142*a162a738SMichael Neumann 
143d3d1dd3eSPeeter Must 	LIST_ENTRY(evdev_dev) ev_link;
144d3d1dd3eSPeeter Must 	LIST_HEAD(, evdev_client) ev_clients;
145d3d1dd3eSPeeter Must };
146d3d1dd3eSPeeter Must 
147*a162a738SMichael Neumann #define	EVDEV_LOCK(evdev)	 lockmgr((evdev)->ev_state_lock, LK_EXCLUSIVE)
148*a162a738SMichael Neumann #define	EVDEV_UNLOCK(evdev)	 lockmgr((evdev)->ev_state_lock, LK_RELEASE)
149*a162a738SMichael Neumann #define	EVDEV_LOCK_ASSERT(evdev) KKASSERT(lockowned((evdev)->ev_state_lock) != 0)
150d3d1dd3eSPeeter Must #define	EVDEV_ENTER(evdev)  do {					\
151d3d1dd3eSPeeter Must 	if ((evdev)->ev_lock_type == EV_LOCK_INTERNAL)			\
152d3d1dd3eSPeeter Must 		EVDEV_LOCK(evdev);					\
153d3d1dd3eSPeeter Must 	else								\
154d3d1dd3eSPeeter Must 		EVDEV_LOCK_ASSERT(evdev);				\
155d3d1dd3eSPeeter Must } while (0)
156d3d1dd3eSPeeter Must #define	EVDEV_EXIT(evdev)  do {						\
157d3d1dd3eSPeeter Must 	if ((evdev)->ev_lock_type == EV_LOCK_INTERNAL)			\
158d3d1dd3eSPeeter Must 		EVDEV_UNLOCK(evdev);					\
159d3d1dd3eSPeeter Must } while (0)
160d3d1dd3eSPeeter Must 
161d3d1dd3eSPeeter Must struct evdev_client
162d3d1dd3eSPeeter Must {
163d3d1dd3eSPeeter Must 	struct evdev_dev *	ec_evdev;
164*a162a738SMichael Neumann 	struct lock		ec_buffer_mtx;	/* Client queue lock */
165d3d1dd3eSPeeter Must 	size_t			ec_buffer_size;
166*a162a738SMichael Neumann 	size_t			ec_buffer_head;		/* (q) */
167*a162a738SMichael Neumann 	size_t			ec_buffer_tail;		/* (q) */
168*a162a738SMichael Neumann 	size_t			ec_buffer_ready;	/* (q) */
169d3d1dd3eSPeeter Must 	enum evdev_clock_id	ec_clock_id;
170d3d1dd3eSPeeter Must 	struct kqinfo 		kqinfo;
171d3d1dd3eSPeeter Must 	struct sigio *		ec_sigio;
172*a162a738SMichael Neumann 	bool			ec_async;		/* (q) */
173*a162a738SMichael Neumann 	bool			ec_revoked;		/* (l) */
174*a162a738SMichael Neumann 	bool			ec_blocked;		/* (q) */
175*a162a738SMichael Neumann 	bool			ec_selected;		/* (q) */
176d3d1dd3eSPeeter Must 
177*a162a738SMichael Neumann 	LIST_ENTRY(evdev_client) ec_link;		/* (l) */
178d3d1dd3eSPeeter Must 
179*a162a738SMichael Neumann 	struct input_event	ec_buffer[];		/* (q) */
180d3d1dd3eSPeeter Must };
181d3d1dd3eSPeeter Must 
182d3d1dd3eSPeeter Must #define	EVDEV_CLIENT_LOCKQ(client)	lockmgr(&(client)->ec_buffer_mtx, \
183d3d1dd3eSPeeter Must 					    LK_EXCLUSIVE|LK_CANRECURSE)
184d3d1dd3eSPeeter Must #define	EVDEV_CLIENT_UNLOCKQ(client)	lockmgr(&(client)->ec_buffer_mtx, \
185d3d1dd3eSPeeter Must 					    LK_RELEASE)
186d3d1dd3eSPeeter Must #define EVDEV_CLIENT_LOCKQ_ASSERT(client) \
187d3d1dd3eSPeeter Must     KKASSERT(lockowned(&(client)->ec_buffer_mtx) != 0)
188d3d1dd3eSPeeter Must #define	EVDEV_CLIENT_EMPTYQ(client) \
189d3d1dd3eSPeeter Must     ((client)->ec_buffer_head == (client)->ec_buffer_ready)
190d3d1dd3eSPeeter Must #define	EVDEV_CLIENT_SIZEQ(client) \
191d3d1dd3eSPeeter Must     (((client)->ec_buffer_ready + (client)->ec_buffer_size - \
192d3d1dd3eSPeeter Must       (client)->ec_buffer_head) % (client)->ec_buffer_size)
193d3d1dd3eSPeeter Must 
194*a162a738SMichael Neumann /* bitstring(3) helper */
195*a162a738SMichael Neumann static inline void
bit_change(bitstr_t * bitstr,int bit,int value)196*a162a738SMichael Neumann bit_change(bitstr_t *bitstr, int bit, int value)
197*a162a738SMichael Neumann {
198*a162a738SMichael Neumann 	if (value)
199*a162a738SMichael Neumann 		bit_set(bitstr, bit);
200*a162a738SMichael Neumann 	else
201*a162a738SMichael Neumann 		bit_clear(bitstr, bit);
202*a162a738SMichael Neumann }
203*a162a738SMichael Neumann 
204d3d1dd3eSPeeter Must /* Input device interface: */
205d3d1dd3eSPeeter Must void evdev_send_event(struct evdev_dev *, uint16_t, uint16_t, int32_t);
206d3d1dd3eSPeeter Must int evdev_inject_event(struct evdev_dev *, uint16_t, uint16_t, int32_t);
207d3d1dd3eSPeeter Must int evdev_cdev_create(struct evdev_dev *);
208d3d1dd3eSPeeter Must int evdev_cdev_destroy(struct evdev_dev *);
209d3d1dd3eSPeeter Must bool evdev_event_supported(struct evdev_dev *, uint16_t);
210d3d1dd3eSPeeter Must void evdev_set_abs_bit(struct evdev_dev *, uint16_t);
211d3d1dd3eSPeeter Must void evdev_set_absinfo(struct evdev_dev *, uint16_t, struct input_absinfo *);
212d3d1dd3eSPeeter Must 
213d3d1dd3eSPeeter Must /* Client interface: */
214d3d1dd3eSPeeter Must int evdev_register_client(struct evdev_dev *, struct evdev_client *);
215d3d1dd3eSPeeter Must void evdev_dispose_client(struct evdev_dev *, struct evdev_client *);
216d3d1dd3eSPeeter Must int evdev_grab_client(struct evdev_dev *, struct evdev_client *);
217d3d1dd3eSPeeter Must int evdev_release_client(struct evdev_dev *, struct evdev_client *);
218d3d1dd3eSPeeter Must void evdev_client_push(struct evdev_client *, uint16_t, uint16_t, int32_t);
219d3d1dd3eSPeeter Must void evdev_notify_event(struct evdev_client *);
220d3d1dd3eSPeeter Must void evdev_revoke_client(struct evdev_client *);
221d3d1dd3eSPeeter Must 
222d3d1dd3eSPeeter Must /* Multitouch related functions: */
223d3d1dd3eSPeeter Must void evdev_mt_init(struct evdev_dev *);
224d3d1dd3eSPeeter Must void evdev_mt_free(struct evdev_dev *);
225*a162a738SMichael Neumann void evdev_mt_sync_frame(struct evdev_dev *);
226*a162a738SMichael Neumann int evdev_mt_get_last_slot(struct evdev_dev *);
227*a162a738SMichael Neumann void evdev_mt_set_last_slot(struct evdev_dev *, int);
228*a162a738SMichael Neumann int32_t evdev_mt_get_value(struct evdev_dev *, int, int16_t);
229*a162a738SMichael Neumann void evdev_mt_set_value(struct evdev_dev *, int, int16_t, int32_t);
230*a162a738SMichael Neumann int32_t evdev_mt_reassign_id(struct evdev_dev *, int, int32_t);
231*a162a738SMichael Neumann bool evdev_mt_record_event(struct evdev_dev *, uint16_t, uint16_t, int32_t);
232d3d1dd3eSPeeter Must 
233d3d1dd3eSPeeter Must /* Utility functions: */
234d3d1dd3eSPeeter Must void evdev_client_dumpqueue(struct evdev_client *);
235*a162a738SMichael Neumann void evdev_send_nfingers(struct evdev_dev *, int);
236d3d1dd3eSPeeter Must 
237d3d1dd3eSPeeter Must #endif	/* _DEV_EVDEV_EVDEV_PRIVATE_H */
238