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