1 | #include <machine/rtems-bsd-kernel-space.h> |
---|
2 | |
---|
3 | /*- |
---|
4 | * Copyright (c) 2014 Jakub Wojciech Klama <jceel@FreeBSD.org> |
---|
5 | * Copyright (c) 2015-2016 Vladimir Kondratyev <wulf@FreeBSD.org> |
---|
6 | * All rights reserved. |
---|
7 | * |
---|
8 | * Redistribution and use in source and binary forms, with or without |
---|
9 | * modification, are permitted provided that the following conditions |
---|
10 | * are met: |
---|
11 | * 1. Redistributions of source code must retain the above copyright |
---|
12 | * notice, this list of conditions and the following disclaimer. |
---|
13 | * 2. Redistributions in binary form must reproduce the above copyright |
---|
14 | * notice, this list of conditions and the following disclaimer in the |
---|
15 | * documentation and/or other materials provided with the distribution. |
---|
16 | * |
---|
17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND |
---|
18 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
---|
19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
---|
20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE |
---|
21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
---|
22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
---|
23 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
---|
24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
---|
25 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
---|
26 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
---|
27 | * SUCH DAMAGE. |
---|
28 | * |
---|
29 | * $FreeBSD$ |
---|
30 | */ |
---|
31 | |
---|
32 | #include <rtems/bsd/local/opt_evdev.h> |
---|
33 | |
---|
34 | #include <sys/param.h> |
---|
35 | #include <sys/bitstring.h> |
---|
36 | #include <sys/conf.h> |
---|
37 | #include <sys/kdb.h> |
---|
38 | #include <sys/kernel.h> |
---|
39 | #include <sys/malloc.h> |
---|
40 | #include <sys/module.h> |
---|
41 | #include <sys/proc.h> |
---|
42 | #include <sys/sysctl.h> |
---|
43 | #include <sys/systm.h> |
---|
44 | |
---|
45 | #include <dev/evdev/evdev.h> |
---|
46 | #include <dev/evdev/evdev_private.h> |
---|
47 | #include <dev/evdev/input.h> |
---|
48 | |
---|
49 | #ifdef EVDEV_DEBUG |
---|
50 | #define debugf(evdev, fmt, args...) printf("evdev: " fmt "\n", ##args) |
---|
51 | #else |
---|
52 | #define debugf(evdev, fmt, args...) |
---|
53 | #endif |
---|
54 | |
---|
55 | #ifdef FEATURE |
---|
56 | FEATURE(evdev, "Input event devices support"); |
---|
57 | #ifdef EVDEV_SUPPORT |
---|
58 | FEATURE(evdev_support, "Evdev support in hybrid drivers"); |
---|
59 | #endif |
---|
60 | #endif |
---|
61 | |
---|
62 | enum evdev_sparse_result |
---|
63 | { |
---|
64 | EV_SKIP_EVENT, /* Event value not changed */ |
---|
65 | EV_REPORT_EVENT, /* Event value changed */ |
---|
66 | EV_REPORT_MT_SLOT, /* Event value and MT slot number changed */ |
---|
67 | }; |
---|
68 | |
---|
69 | MALLOC_DEFINE(M_EVDEV, "evdev", "evdev memory"); |
---|
70 | |
---|
71 | #ifndef __rtems__ |
---|
72 | int evdev_rcpt_mask = EVDEV_RCPT_SYSMOUSE | EVDEV_RCPT_KBDMUX; |
---|
73 | #else /* __rtems__ */ |
---|
74 | int evdev_rcpt_mask = EVDEV_RCPT_HW_MOUSE | EVDEV_RCPT_HW_KBD; |
---|
75 | #endif /* __rtems__ */ |
---|
76 | int evdev_sysmouse_t_axis = 0; |
---|
77 | |
---|
78 | SYSCTL_NODE(_kern, OID_AUTO, evdev, CTLFLAG_RW, 0, "Evdev args"); |
---|
79 | #ifdef EVDEV_SUPPORT |
---|
80 | SYSCTL_INT(_kern_evdev, OID_AUTO, rcpt_mask, CTLFLAG_RW, &evdev_rcpt_mask, 0, |
---|
81 | "Who is receiving events: bit0 - sysmouse, bit1 - kbdmux, " |
---|
82 | "bit2 - mouse hardware, bit3 - keyboard hardware"); |
---|
83 | SYSCTL_INT(_kern_evdev, OID_AUTO, sysmouse_t_axis, CTLFLAG_RW, |
---|
84 | &evdev_sysmouse_t_axis, 0, "Extract T-axis from 0-none, 1-ums, 2-psm"); |
---|
85 | #endif |
---|
86 | SYSCTL_NODE(_kern_evdev, OID_AUTO, input, CTLFLAG_RD, 0, |
---|
87 | "Evdev input devices"); |
---|
88 | |
---|
89 | static void evdev_start_repeat(struct evdev_dev *, uint16_t); |
---|
90 | static void evdev_stop_repeat(struct evdev_dev *); |
---|
91 | static int evdev_check_event(struct evdev_dev *, uint16_t, uint16_t, int32_t); |
---|
92 | |
---|
93 | static inline void |
---|
94 | bit_change(bitstr_t *bitstr, int bit, int value) |
---|
95 | { |
---|
96 | if (value) |
---|
97 | bit_set(bitstr, bit); |
---|
98 | else |
---|
99 | bit_clear(bitstr, bit); |
---|
100 | } |
---|
101 | |
---|
102 | struct evdev_dev * |
---|
103 | evdev_alloc(void) |
---|
104 | { |
---|
105 | |
---|
106 | return malloc(sizeof(struct evdev_dev), M_EVDEV, M_WAITOK | M_ZERO); |
---|
107 | } |
---|
108 | |
---|
109 | void |
---|
110 | evdev_free(struct evdev_dev *evdev) |
---|
111 | { |
---|
112 | |
---|
113 | if (evdev != NULL && evdev->ev_cdev != NULL && |
---|
114 | evdev->ev_cdev->si_drv1 != NULL) |
---|
115 | evdev_unregister(evdev); |
---|
116 | |
---|
117 | free(evdev, M_EVDEV); |
---|
118 | } |
---|
119 | |
---|
120 | static struct input_absinfo * |
---|
121 | evdev_alloc_absinfo(void) |
---|
122 | { |
---|
123 | |
---|
124 | return (malloc(sizeof(struct input_absinfo) * ABS_CNT, M_EVDEV, |
---|
125 | M_WAITOK | M_ZERO)); |
---|
126 | } |
---|
127 | |
---|
128 | static void |
---|
129 | evdev_free_absinfo(struct input_absinfo *absinfo) |
---|
130 | { |
---|
131 | |
---|
132 | free(absinfo, M_EVDEV); |
---|
133 | } |
---|
134 | |
---|
135 | int |
---|
136 | evdev_set_report_size(struct evdev_dev *evdev, size_t report_size) |
---|
137 | { |
---|
138 | if (report_size > KEY_CNT + REL_CNT + ABS_CNT + MAX_MT_SLOTS * MT_CNT + |
---|
139 | MSC_CNT + LED_CNT + SND_CNT + SW_CNT + FF_CNT) |
---|
140 | return (EINVAL); |
---|
141 | |
---|
142 | evdev->ev_report_size = report_size; |
---|
143 | return (0); |
---|
144 | } |
---|
145 | |
---|
146 | static size_t |
---|
147 | evdev_estimate_report_size(struct evdev_dev *evdev) |
---|
148 | { |
---|
149 | size_t size = 0; |
---|
150 | int res; |
---|
151 | |
---|
152 | /* |
---|
153 | * Keyboards generate one event per report but other devices with |
---|
154 | * buttons like mouses can report events simultaneously |
---|
155 | */ |
---|
156 | bit_ffs_at(evdev->ev_key_flags, KEY_OK, KEY_CNT - KEY_OK, &res); |
---|
157 | if (res == -1) |
---|
158 | bit_ffs(evdev->ev_key_flags, BTN_MISC, &res); |
---|
159 | size += (res != -1); |
---|
160 | bit_count(evdev->ev_key_flags, BTN_MISC, KEY_OK - BTN_MISC, &res); |
---|
161 | size += res; |
---|
162 | |
---|
163 | /* All relative axes can be reported simultaneously */ |
---|
164 | bit_count(evdev->ev_rel_flags, 0, REL_CNT, &res); |
---|
165 | size += res; |
---|
166 | |
---|
167 | /* |
---|
168 | * All absolute axes can be reported simultaneously. |
---|
169 | * Multitouch axes can be reported ABS_MT_SLOT times |
---|
170 | */ |
---|
171 | if (evdev->ev_absinfo != NULL) { |
---|
172 | bit_count(evdev->ev_abs_flags, 0, ABS_CNT, &res); |
---|
173 | size += res; |
---|
174 | bit_count(evdev->ev_abs_flags, ABS_MT_FIRST, MT_CNT, &res); |
---|
175 | if (res > 0) { |
---|
176 | res++; /* ABS_MT_SLOT or SYN_MT_REPORT */ |
---|
177 | if (bit_test(evdev->ev_abs_flags, ABS_MT_SLOT)) |
---|
178 | /* MT type B */ |
---|
179 | size += res * MAXIMAL_MT_SLOT(evdev); |
---|
180 | else |
---|
181 | /* MT type A */ |
---|
182 | size += res * (MAX_MT_REPORTS - 1); |
---|
183 | } |
---|
184 | } |
---|
185 | |
---|
186 | /* All misc events can be reported simultaneously */ |
---|
187 | bit_count(evdev->ev_msc_flags, 0, MSC_CNT, &res); |
---|
188 | size += res; |
---|
189 | |
---|
190 | /* All leds can be reported simultaneously */ |
---|
191 | bit_count(evdev->ev_led_flags, 0, LED_CNT, &res); |
---|
192 | size += res; |
---|
193 | |
---|
194 | /* Assume other events are generated once per report */ |
---|
195 | bit_ffs(evdev->ev_snd_flags, SND_CNT, &res); |
---|
196 | size += (res != -1); |
---|
197 | |
---|
198 | bit_ffs(evdev->ev_sw_flags, SW_CNT, &res); |
---|
199 | size += (res != -1); |
---|
200 | |
---|
201 | /* XXX: FF part is not implemented yet */ |
---|
202 | |
---|
203 | size++; /* SYN_REPORT */ |
---|
204 | return (size); |
---|
205 | } |
---|
206 | |
---|
207 | static void |
---|
208 | evdev_sysctl_create(struct evdev_dev *evdev) |
---|
209 | { |
---|
210 | struct sysctl_oid *ev_sysctl_tree; |
---|
211 | char ev_unit_str[8]; |
---|
212 | |
---|
213 | snprintf(ev_unit_str, sizeof(ev_unit_str), "%d", evdev->ev_unit); |
---|
214 | sysctl_ctx_init(&evdev->ev_sysctl_ctx); |
---|
215 | |
---|
216 | ev_sysctl_tree = SYSCTL_ADD_NODE_WITH_LABEL(&evdev->ev_sysctl_ctx, |
---|
217 | SYSCTL_STATIC_CHILDREN(_kern_evdev_input), OID_AUTO, |
---|
218 | ev_unit_str, CTLFLAG_RD, NULL, "", "device index"); |
---|
219 | |
---|
220 | SYSCTL_ADD_STRING(&evdev->ev_sysctl_ctx, |
---|
221 | SYSCTL_CHILDREN(ev_sysctl_tree), OID_AUTO, "name", CTLFLAG_RD, |
---|
222 | evdev->ev_name, 0, |
---|
223 | "Input device name"); |
---|
224 | |
---|
225 | SYSCTL_ADD_STRUCT(&evdev->ev_sysctl_ctx, |
---|
226 | SYSCTL_CHILDREN(ev_sysctl_tree), OID_AUTO, "id", CTLFLAG_RD, |
---|
227 | &evdev->ev_id, input_id, |
---|
228 | "Input device identification"); |
---|
229 | |
---|
230 | /* ioctl returns ENOENT if phys is not set. sysctl returns "" here */ |
---|
231 | SYSCTL_ADD_STRING(&evdev->ev_sysctl_ctx, |
---|
232 | SYSCTL_CHILDREN(ev_sysctl_tree), OID_AUTO, "phys", CTLFLAG_RD, |
---|
233 | evdev->ev_shortname, 0, |
---|
234 | "Input device short name"); |
---|
235 | |
---|
236 | /* ioctl returns ENOENT if uniq is not set. sysctl returns "" here */ |
---|
237 | SYSCTL_ADD_STRING(&evdev->ev_sysctl_ctx, |
---|
238 | SYSCTL_CHILDREN(ev_sysctl_tree), OID_AUTO, "uniq", CTLFLAG_RD, |
---|
239 | evdev->ev_serial, 0, |
---|
240 | "Input device unique number"); |
---|
241 | |
---|
242 | SYSCTL_ADD_OPAQUE(&evdev->ev_sysctl_ctx, |
---|
243 | SYSCTL_CHILDREN(ev_sysctl_tree), OID_AUTO, "props", CTLFLAG_RD, |
---|
244 | evdev->ev_prop_flags, sizeof(evdev->ev_prop_flags), "", |
---|
245 | "Input device properties"); |
---|
246 | |
---|
247 | SYSCTL_ADD_OPAQUE(&evdev->ev_sysctl_ctx, |
---|
248 | SYSCTL_CHILDREN(ev_sysctl_tree), OID_AUTO, "type_bits", CTLFLAG_RD, |
---|
249 | evdev->ev_type_flags, sizeof(evdev->ev_type_flags), "", |
---|
250 | "Input device supported events types"); |
---|
251 | |
---|
252 | SYSCTL_ADD_OPAQUE(&evdev->ev_sysctl_ctx, |
---|
253 | SYSCTL_CHILDREN(ev_sysctl_tree), OID_AUTO, "key_bits", CTLFLAG_RD, |
---|
254 | evdev->ev_key_flags, sizeof(evdev->ev_key_flags), |
---|
255 | "", "Input device supported keys"); |
---|
256 | |
---|
257 | SYSCTL_ADD_OPAQUE(&evdev->ev_sysctl_ctx, |
---|
258 | SYSCTL_CHILDREN(ev_sysctl_tree), OID_AUTO, "rel_bits", CTLFLAG_RD, |
---|
259 | evdev->ev_rel_flags, sizeof(evdev->ev_rel_flags), "", |
---|
260 | "Input device supported relative events"); |
---|
261 | |
---|
262 | SYSCTL_ADD_OPAQUE(&evdev->ev_sysctl_ctx, |
---|
263 | SYSCTL_CHILDREN(ev_sysctl_tree), OID_AUTO, "abs_bits", CTLFLAG_RD, |
---|
264 | evdev->ev_abs_flags, sizeof(evdev->ev_abs_flags), "", |
---|
265 | "Input device supported absolute events"); |
---|
266 | |
---|
267 | SYSCTL_ADD_OPAQUE(&evdev->ev_sysctl_ctx, |
---|
268 | SYSCTL_CHILDREN(ev_sysctl_tree), OID_AUTO, "msc_bits", CTLFLAG_RD, |
---|
269 | evdev->ev_msc_flags, sizeof(evdev->ev_msc_flags), "", |
---|
270 | "Input device supported miscellaneous events"); |
---|
271 | |
---|
272 | SYSCTL_ADD_OPAQUE(&evdev->ev_sysctl_ctx, |
---|
273 | SYSCTL_CHILDREN(ev_sysctl_tree), OID_AUTO, "led_bits", CTLFLAG_RD, |
---|
274 | evdev->ev_led_flags, sizeof(evdev->ev_led_flags), "", |
---|
275 | "Input device supported LED events"); |
---|
276 | |
---|
277 | SYSCTL_ADD_OPAQUE(&evdev->ev_sysctl_ctx, |
---|
278 | SYSCTL_CHILDREN(ev_sysctl_tree), OID_AUTO, "snd_bits", CTLFLAG_RD, |
---|
279 | evdev->ev_snd_flags, sizeof(evdev->ev_snd_flags), "", |
---|
280 | "Input device supported sound events"); |
---|
281 | |
---|
282 | SYSCTL_ADD_OPAQUE(&evdev->ev_sysctl_ctx, |
---|
283 | SYSCTL_CHILDREN(ev_sysctl_tree), OID_AUTO, "sw_bits", CTLFLAG_RD, |
---|
284 | evdev->ev_sw_flags, sizeof(evdev->ev_sw_flags), "", |
---|
285 | "Input device supported switch events"); |
---|
286 | } |
---|
287 | |
---|
288 | static int |
---|
289 | evdev_register_common(struct evdev_dev *evdev) |
---|
290 | { |
---|
291 | int ret; |
---|
292 | |
---|
293 | debugf(evdev, "%s: registered evdev provider: %s <%s>\n", |
---|
294 | evdev->ev_shortname, evdev->ev_name, evdev->ev_serial); |
---|
295 | |
---|
296 | /* Initialize internal structures */ |
---|
297 | LIST_INIT(&evdev->ev_clients); |
---|
298 | |
---|
299 | if (evdev_event_supported(evdev, EV_REP) && |
---|
300 | bit_test(evdev->ev_flags, EVDEV_FLAG_SOFTREPEAT)) { |
---|
301 | /* Initialize callout */ |
---|
302 | callout_init_mtx(&evdev->ev_rep_callout, &evdev->ev_mtx, 0); |
---|
303 | |
---|
304 | if (evdev->ev_rep[REP_DELAY] == 0 && |
---|
305 | evdev->ev_rep[REP_PERIOD] == 0) { |
---|
306 | /* Supply default values */ |
---|
307 | evdev->ev_rep[REP_DELAY] = 250; |
---|
308 | evdev->ev_rep[REP_PERIOD] = 33; |
---|
309 | } |
---|
310 | } |
---|
311 | |
---|
312 | /* Initialize multitouch protocol type B states */ |
---|
313 | if (bit_test(evdev->ev_abs_flags, ABS_MT_SLOT) && |
---|
314 | evdev->ev_absinfo != NULL && MAXIMAL_MT_SLOT(evdev) > 0) |
---|
315 | evdev_mt_init(evdev); |
---|
316 | |
---|
317 | /* Estimate maximum report size */ |
---|
318 | if (evdev->ev_report_size == 0) { |
---|
319 | ret = evdev_set_report_size(evdev, |
---|
320 | evdev_estimate_report_size(evdev)); |
---|
321 | if (ret != 0) |
---|
322 | goto bail_out; |
---|
323 | } |
---|
324 | |
---|
325 | /* Create char device node */ |
---|
326 | ret = evdev_cdev_create(evdev); |
---|
327 | if (ret != 0) |
---|
328 | goto bail_out; |
---|
329 | |
---|
330 | /* Create sysctls (for device enumeration without /dev/input access rights) */ |
---|
331 | evdev_sysctl_create(evdev); |
---|
332 | |
---|
333 | bail_out: |
---|
334 | return (ret); |
---|
335 | } |
---|
336 | |
---|
337 | int |
---|
338 | evdev_register(struct evdev_dev *evdev) |
---|
339 | { |
---|
340 | int ret; |
---|
341 | |
---|
342 | evdev->ev_lock_type = EV_LOCK_INTERNAL; |
---|
343 | evdev->ev_lock = &evdev->ev_mtx; |
---|
344 | mtx_init(&evdev->ev_mtx, "evmtx", NULL, MTX_DEF); |
---|
345 | |
---|
346 | ret = evdev_register_common(evdev); |
---|
347 | if (ret != 0) |
---|
348 | mtx_destroy(&evdev->ev_mtx); |
---|
349 | |
---|
350 | return (ret); |
---|
351 | } |
---|
352 | |
---|
353 | int |
---|
354 | evdev_register_mtx(struct evdev_dev *evdev, struct mtx *mtx) |
---|
355 | { |
---|
356 | |
---|
357 | evdev->ev_lock_type = EV_LOCK_MTX; |
---|
358 | evdev->ev_lock = mtx; |
---|
359 | return (evdev_register_common(evdev)); |
---|
360 | } |
---|
361 | |
---|
362 | int |
---|
363 | evdev_unregister(struct evdev_dev *evdev) |
---|
364 | { |
---|
365 | struct evdev_client *client; |
---|
366 | int ret; |
---|
367 | debugf(evdev, "%s: unregistered evdev provider: %s\n", |
---|
368 | evdev->ev_shortname, evdev->ev_name); |
---|
369 | |
---|
370 | sysctl_ctx_free(&evdev->ev_sysctl_ctx); |
---|
371 | |
---|
372 | EVDEV_LOCK(evdev); |
---|
373 | evdev->ev_cdev->si_drv1 = NULL; |
---|
374 | /* Wake up sleepers */ |
---|
375 | LIST_FOREACH(client, &evdev->ev_clients, ec_link) { |
---|
376 | evdev_revoke_client(client); |
---|
377 | evdev_dispose_client(evdev, client); |
---|
378 | EVDEV_CLIENT_LOCKQ(client); |
---|
379 | evdev_notify_event(client); |
---|
380 | EVDEV_CLIENT_UNLOCKQ(client); |
---|
381 | } |
---|
382 | EVDEV_UNLOCK(evdev); |
---|
383 | |
---|
384 | /* destroy_dev can sleep so release lock */ |
---|
385 | ret = evdev_cdev_destroy(evdev); |
---|
386 | evdev->ev_cdev = NULL; |
---|
387 | if (ret == 0 && evdev->ev_lock_type == EV_LOCK_INTERNAL) |
---|
388 | mtx_destroy(&evdev->ev_mtx); |
---|
389 | |
---|
390 | evdev_free_absinfo(evdev->ev_absinfo); |
---|
391 | evdev_mt_free(evdev); |
---|
392 | |
---|
393 | return (ret); |
---|
394 | } |
---|
395 | |
---|
396 | inline void |
---|
397 | evdev_set_name(struct evdev_dev *evdev, const char *name) |
---|
398 | { |
---|
399 | |
---|
400 | snprintf(evdev->ev_name, NAMELEN, "%s", name); |
---|
401 | } |
---|
402 | |
---|
403 | inline void |
---|
404 | evdev_set_id(struct evdev_dev *evdev, uint16_t bustype, uint16_t vendor, |
---|
405 | uint16_t product, uint16_t version) |
---|
406 | { |
---|
407 | |
---|
408 | evdev->ev_id = (struct input_id) { |
---|
409 | .bustype = bustype, |
---|
410 | .vendor = vendor, |
---|
411 | .product = product, |
---|
412 | .version = version |
---|
413 | }; |
---|
414 | } |
---|
415 | |
---|
416 | inline void |
---|
417 | evdev_set_phys(struct evdev_dev *evdev, const char *name) |
---|
418 | { |
---|
419 | |
---|
420 | snprintf(evdev->ev_shortname, NAMELEN, "%s", name); |
---|
421 | } |
---|
422 | |
---|
423 | inline void |
---|
424 | evdev_set_serial(struct evdev_dev *evdev, const char *serial) |
---|
425 | { |
---|
426 | |
---|
427 | snprintf(evdev->ev_serial, NAMELEN, "%s", serial); |
---|
428 | } |
---|
429 | |
---|
430 | inline void |
---|
431 | evdev_set_methods(struct evdev_dev *evdev, void *softc, |
---|
432 | const struct evdev_methods *methods) |
---|
433 | { |
---|
434 | |
---|
435 | evdev->ev_methods = methods; |
---|
436 | evdev->ev_softc = softc; |
---|
437 | } |
---|
438 | |
---|
439 | inline void * |
---|
440 | evdev_get_softc(struct evdev_dev *evdev) |
---|
441 | { |
---|
442 | |
---|
443 | return (evdev->ev_softc); |
---|
444 | } |
---|
445 | |
---|
446 | inline void |
---|
447 | evdev_support_prop(struct evdev_dev *evdev, uint16_t prop) |
---|
448 | { |
---|
449 | |
---|
450 | KASSERT(prop < INPUT_PROP_CNT, ("invalid evdev input property")); |
---|
451 | bit_set(evdev->ev_prop_flags, prop); |
---|
452 | } |
---|
453 | |
---|
454 | inline void |
---|
455 | evdev_support_event(struct evdev_dev *evdev, uint16_t type) |
---|
456 | { |
---|
457 | |
---|
458 | KASSERT(type < EV_CNT, ("invalid evdev event property")); |
---|
459 | bit_set(evdev->ev_type_flags, type); |
---|
460 | } |
---|
461 | |
---|
462 | inline void |
---|
463 | evdev_support_key(struct evdev_dev *evdev, uint16_t code) |
---|
464 | { |
---|
465 | |
---|
466 | KASSERT(code < KEY_CNT, ("invalid evdev key property")); |
---|
467 | bit_set(evdev->ev_key_flags, code); |
---|
468 | } |
---|
469 | |
---|
470 | inline void |
---|
471 | evdev_support_rel(struct evdev_dev *evdev, uint16_t code) |
---|
472 | { |
---|
473 | |
---|
474 | KASSERT(code < REL_CNT, ("invalid evdev rel property")); |
---|
475 | bit_set(evdev->ev_rel_flags, code); |
---|
476 | } |
---|
477 | |
---|
478 | inline void |
---|
479 | evdev_support_abs(struct evdev_dev *evdev, uint16_t code, int32_t value, |
---|
480 | int32_t minimum, int32_t maximum, int32_t fuzz, int32_t flat, |
---|
481 | int32_t resolution) |
---|
482 | { |
---|
483 | struct input_absinfo absinfo; |
---|
484 | |
---|
485 | KASSERT(code < ABS_CNT, ("invalid evdev abs property")); |
---|
486 | |
---|
487 | absinfo = (struct input_absinfo) { |
---|
488 | .value = value, |
---|
489 | .minimum = minimum, |
---|
490 | .maximum = maximum, |
---|
491 | .fuzz = fuzz, |
---|
492 | .flat = flat, |
---|
493 | .resolution = resolution, |
---|
494 | }; |
---|
495 | evdev_set_abs_bit(evdev, code); |
---|
496 | evdev_set_absinfo(evdev, code, &absinfo); |
---|
497 | } |
---|
498 | |
---|
499 | inline void |
---|
500 | evdev_set_abs_bit(struct evdev_dev *evdev, uint16_t code) |
---|
501 | { |
---|
502 | |
---|
503 | KASSERT(code < ABS_CNT, ("invalid evdev abs property")); |
---|
504 | if (evdev->ev_absinfo == NULL) |
---|
505 | evdev->ev_absinfo = evdev_alloc_absinfo(); |
---|
506 | bit_set(evdev->ev_abs_flags, code); |
---|
507 | } |
---|
508 | |
---|
509 | inline void |
---|
510 | evdev_support_msc(struct evdev_dev *evdev, uint16_t code) |
---|
511 | { |
---|
512 | |
---|
513 | KASSERT(code < MSC_CNT, ("invalid evdev msc property")); |
---|
514 | bit_set(evdev->ev_msc_flags, code); |
---|
515 | } |
---|
516 | |
---|
517 | |
---|
518 | inline void |
---|
519 | evdev_support_led(struct evdev_dev *evdev, uint16_t code) |
---|
520 | { |
---|
521 | |
---|
522 | KASSERT(code < LED_CNT, ("invalid evdev led property")); |
---|
523 | bit_set(evdev->ev_led_flags, code); |
---|
524 | } |
---|
525 | |
---|
526 | inline void |
---|
527 | evdev_support_snd(struct evdev_dev *evdev, uint16_t code) |
---|
528 | { |
---|
529 | |
---|
530 | KASSERT(code < SND_CNT, ("invalid evdev snd property")); |
---|
531 | bit_set(evdev->ev_snd_flags, code); |
---|
532 | } |
---|
533 | |
---|
534 | inline void |
---|
535 | evdev_support_sw(struct evdev_dev *evdev, uint16_t code) |
---|
536 | { |
---|
537 | |
---|
538 | KASSERT(code < SW_CNT, ("invalid evdev sw property")); |
---|
539 | bit_set(evdev->ev_sw_flags, code); |
---|
540 | } |
---|
541 | |
---|
542 | bool |
---|
543 | evdev_event_supported(struct evdev_dev *evdev, uint16_t type) |
---|
544 | { |
---|
545 | |
---|
546 | KASSERT(type < EV_CNT, ("invalid evdev event property")); |
---|
547 | return (bit_test(evdev->ev_type_flags, type)); |
---|
548 | } |
---|
549 | |
---|
550 | inline void |
---|
551 | evdev_set_absinfo(struct evdev_dev *evdev, uint16_t axis, |
---|
552 | struct input_absinfo *absinfo) |
---|
553 | { |
---|
554 | |
---|
555 | KASSERT(axis < ABS_CNT, ("invalid evdev abs property")); |
---|
556 | |
---|
557 | if (axis == ABS_MT_SLOT && |
---|
558 | (absinfo->maximum < 1 || absinfo->maximum >= MAX_MT_SLOTS)) |
---|
559 | return; |
---|
560 | |
---|
561 | if (evdev->ev_absinfo == NULL) |
---|
562 | evdev->ev_absinfo = evdev_alloc_absinfo(); |
---|
563 | |
---|
564 | if (axis == ABS_MT_SLOT) |
---|
565 | evdev->ev_absinfo[ABS_MT_SLOT].maximum = absinfo->maximum; |
---|
566 | else |
---|
567 | memcpy(&evdev->ev_absinfo[axis], absinfo, |
---|
568 | sizeof(struct input_absinfo)); |
---|
569 | } |
---|
570 | |
---|
571 | inline void |
---|
572 | evdev_set_repeat_params(struct evdev_dev *evdev, uint16_t property, int value) |
---|
573 | { |
---|
574 | |
---|
575 | KASSERT(property < REP_CNT, ("invalid evdev repeat property")); |
---|
576 | evdev->ev_rep[property] = value; |
---|
577 | } |
---|
578 | |
---|
579 | inline void |
---|
580 | evdev_set_flag(struct evdev_dev *evdev, uint16_t flag) |
---|
581 | { |
---|
582 | |
---|
583 | KASSERT(flag < EVDEV_FLAG_CNT, ("invalid evdev flag property")); |
---|
584 | bit_set(evdev->ev_flags, flag); |
---|
585 | } |
---|
586 | |
---|
587 | static int |
---|
588 | evdev_check_event(struct evdev_dev *evdev, uint16_t type, uint16_t code, |
---|
589 | int32_t value) |
---|
590 | { |
---|
591 | |
---|
592 | if (type >= EV_CNT) |
---|
593 | return (EINVAL); |
---|
594 | |
---|
595 | /* Allow SYN events implicitly */ |
---|
596 | if (type != EV_SYN && !evdev_event_supported(evdev, type)) |
---|
597 | return (EINVAL); |
---|
598 | |
---|
599 | switch (type) { |
---|
600 | case EV_SYN: |
---|
601 | if (code >= SYN_CNT) |
---|
602 | return (EINVAL); |
---|
603 | break; |
---|
604 | |
---|
605 | case EV_KEY: |
---|
606 | if (code >= KEY_CNT) |
---|
607 | return (EINVAL); |
---|
608 | if (!bit_test(evdev->ev_key_flags, code)) |
---|
609 | return (EINVAL); |
---|
610 | break; |
---|
611 | |
---|
612 | case EV_REL: |
---|
613 | if (code >= REL_CNT) |
---|
614 | return (EINVAL); |
---|
615 | if (!bit_test(evdev->ev_rel_flags, code)) |
---|
616 | return (EINVAL); |
---|
617 | break; |
---|
618 | |
---|
619 | case EV_ABS: |
---|
620 | if (code >= ABS_CNT) |
---|
621 | return (EINVAL); |
---|
622 | if (!bit_test(evdev->ev_abs_flags, code)) |
---|
623 | return (EINVAL); |
---|
624 | if (code == ABS_MT_SLOT && |
---|
625 | (value < 0 || value > MAXIMAL_MT_SLOT(evdev))) |
---|
626 | return (EINVAL); |
---|
627 | if (ABS_IS_MT(code) && evdev->ev_mt == NULL && |
---|
628 | bit_test(evdev->ev_abs_flags, ABS_MT_SLOT)) |
---|
629 | return (EINVAL); |
---|
630 | break; |
---|
631 | |
---|
632 | case EV_MSC: |
---|
633 | if (code >= MSC_CNT) |
---|
634 | return (EINVAL); |
---|
635 | if (!bit_test(evdev->ev_msc_flags, code)) |
---|
636 | return (EINVAL); |
---|
637 | break; |
---|
638 | |
---|
639 | case EV_LED: |
---|
640 | if (code >= LED_CNT) |
---|
641 | return (EINVAL); |
---|
642 | if (!bit_test(evdev->ev_led_flags, code)) |
---|
643 | return (EINVAL); |
---|
644 | break; |
---|
645 | |
---|
646 | case EV_SND: |
---|
647 | if (code >= SND_CNT) |
---|
648 | return (EINVAL); |
---|
649 | if (!bit_test(evdev->ev_snd_flags, code)) |
---|
650 | return (EINVAL); |
---|
651 | break; |
---|
652 | |
---|
653 | case EV_SW: |
---|
654 | if (code >= SW_CNT) |
---|
655 | return (EINVAL); |
---|
656 | if (!bit_test(evdev->ev_sw_flags, code)) |
---|
657 | return (EINVAL); |
---|
658 | break; |
---|
659 | |
---|
660 | case EV_REP: |
---|
661 | if (code >= REP_CNT) |
---|
662 | return (EINVAL); |
---|
663 | break; |
---|
664 | |
---|
665 | default: |
---|
666 | return (EINVAL); |
---|
667 | } |
---|
668 | |
---|
669 | return (0); |
---|
670 | } |
---|
671 | |
---|
672 | static void |
---|
673 | evdev_modify_event(struct evdev_dev *evdev, uint16_t type, uint16_t code, |
---|
674 | int32_t *value) |
---|
675 | { |
---|
676 | |
---|
677 | EVDEV_LOCK_ASSERT(evdev); |
---|
678 | |
---|
679 | switch (type) { |
---|
680 | case EV_KEY: |
---|
681 | if (!evdev_event_supported(evdev, EV_REP)) |
---|
682 | break; |
---|
683 | |
---|
684 | if (!bit_test(evdev->ev_flags, EVDEV_FLAG_SOFTREPEAT)) { |
---|
685 | /* Detect driver key repeats. */ |
---|
686 | if (bit_test(evdev->ev_key_states, code) && |
---|
687 | *value == KEY_EVENT_DOWN) |
---|
688 | *value = KEY_EVENT_REPEAT; |
---|
689 | } else { |
---|
690 | /* Start/stop callout for evdev repeats */ |
---|
691 | if (bit_test(evdev->ev_key_states, code) == !*value && |
---|
692 | !LIST_EMPTY(&evdev->ev_clients)) { |
---|
693 | if (*value == KEY_EVENT_DOWN) |
---|
694 | evdev_start_repeat(evdev, code); |
---|
695 | else |
---|
696 | evdev_stop_repeat(evdev); |
---|
697 | } |
---|
698 | } |
---|
699 | break; |
---|
700 | |
---|
701 | case EV_ABS: |
---|
702 | /* TBD: implement fuzz */ |
---|
703 | break; |
---|
704 | } |
---|
705 | } |
---|
706 | |
---|
707 | static enum evdev_sparse_result |
---|
708 | evdev_sparse_event(struct evdev_dev *evdev, uint16_t type, uint16_t code, |
---|
709 | int32_t value) |
---|
710 | { |
---|
711 | int32_t last_mt_slot; |
---|
712 | |
---|
713 | EVDEV_LOCK_ASSERT(evdev); |
---|
714 | |
---|
715 | /* |
---|
716 | * For certain event types, update device state bits |
---|
717 | * and convert level reporting to edge reporting |
---|
718 | */ |
---|
719 | switch (type) { |
---|
720 | case EV_KEY: |
---|
721 | switch (value) { |
---|
722 | case KEY_EVENT_UP: |
---|
723 | case KEY_EVENT_DOWN: |
---|
724 | if (bit_test(evdev->ev_key_states, code) == value) |
---|
725 | return (EV_SKIP_EVENT); |
---|
726 | bit_change(evdev->ev_key_states, code, value); |
---|
727 | break; |
---|
728 | |
---|
729 | case KEY_EVENT_REPEAT: |
---|
730 | if (bit_test(evdev->ev_key_states, code) == 0 || |
---|
731 | !evdev_event_supported(evdev, EV_REP)) |
---|
732 | return (EV_SKIP_EVENT); |
---|
733 | break; |
---|
734 | |
---|
735 | default: |
---|
736 | return (EV_SKIP_EVENT); |
---|
737 | } |
---|
738 | break; |
---|
739 | |
---|
740 | case EV_LED: |
---|
741 | if (bit_test(evdev->ev_led_states, code) == value) |
---|
742 | return (EV_SKIP_EVENT); |
---|
743 | bit_change(evdev->ev_led_states, code, value); |
---|
744 | break; |
---|
745 | |
---|
746 | case EV_SND: |
---|
747 | bit_change(evdev->ev_snd_states, code, value); |
---|
748 | break; |
---|
749 | |
---|
750 | case EV_SW: |
---|
751 | if (bit_test(evdev->ev_sw_states, code) == value) |
---|
752 | return (EV_SKIP_EVENT); |
---|
753 | bit_change(evdev->ev_sw_states, code, value); |
---|
754 | break; |
---|
755 | |
---|
756 | case EV_REP: |
---|
757 | if (evdev->ev_rep[code] == value) |
---|
758 | return (EV_SKIP_EVENT); |
---|
759 | evdev_set_repeat_params(evdev, code, value); |
---|
760 | break; |
---|
761 | |
---|
762 | case EV_REL: |
---|
763 | if (value == 0) |
---|
764 | return (EV_SKIP_EVENT); |
---|
765 | break; |
---|
766 | |
---|
767 | /* For EV_ABS, save last value in absinfo and ev_mt_states */ |
---|
768 | case EV_ABS: |
---|
769 | switch (code) { |
---|
770 | case ABS_MT_SLOT: |
---|
771 | /* Postpone ABS_MT_SLOT till next event */ |
---|
772 | evdev_set_last_mt_slot(evdev, value); |
---|
773 | return (EV_SKIP_EVENT); |
---|
774 | |
---|
775 | case ABS_MT_FIRST ... ABS_MT_LAST: |
---|
776 | /* Pass MT protocol type A events as is */ |
---|
777 | if (!bit_test(evdev->ev_abs_flags, ABS_MT_SLOT)) |
---|
778 | break; |
---|
779 | /* Don`t repeat MT protocol type B events */ |
---|
780 | last_mt_slot = evdev_get_last_mt_slot(evdev); |
---|
781 | if (evdev_get_mt_value(evdev, last_mt_slot, code) |
---|
782 | == value) |
---|
783 | return (EV_SKIP_EVENT); |
---|
784 | evdev_set_mt_value(evdev, last_mt_slot, code, value); |
---|
785 | if (last_mt_slot != CURRENT_MT_SLOT(evdev)) { |
---|
786 | CURRENT_MT_SLOT(evdev) = last_mt_slot; |
---|
787 | evdev->ev_report_opened = true; |
---|
788 | return (EV_REPORT_MT_SLOT); |
---|
789 | } |
---|
790 | break; |
---|
791 | |
---|
792 | default: |
---|
793 | if (evdev->ev_absinfo[code].value == value) |
---|
794 | return (EV_SKIP_EVENT); |
---|
795 | evdev->ev_absinfo[code].value = value; |
---|
796 | } |
---|
797 | break; |
---|
798 | |
---|
799 | case EV_SYN: |
---|
800 | if (code == SYN_REPORT) { |
---|
801 | /* Count empty reports as well as non empty */ |
---|
802 | evdev->ev_report_count++; |
---|
803 | /* Skip empty reports */ |
---|
804 | if (!evdev->ev_report_opened) |
---|
805 | return (EV_SKIP_EVENT); |
---|
806 | evdev->ev_report_opened = false; |
---|
807 | return (EV_REPORT_EVENT); |
---|
808 | } |
---|
809 | break; |
---|
810 | } |
---|
811 | |
---|
812 | evdev->ev_report_opened = true; |
---|
813 | return (EV_REPORT_EVENT); |
---|
814 | } |
---|
815 | |
---|
816 | static void |
---|
817 | evdev_propagate_event(struct evdev_dev *evdev, uint16_t type, uint16_t code, |
---|
818 | int32_t value) |
---|
819 | { |
---|
820 | struct evdev_client *client; |
---|
821 | |
---|
822 | debugf(evdev, "%s pushed event %d/%d/%d", |
---|
823 | evdev->ev_shortname, type, code, value); |
---|
824 | |
---|
825 | EVDEV_LOCK_ASSERT(evdev); |
---|
826 | |
---|
827 | /* Propagate event through all clients */ |
---|
828 | LIST_FOREACH(client, &evdev->ev_clients, ec_link) { |
---|
829 | if (evdev->ev_grabber != NULL && evdev->ev_grabber != client) |
---|
830 | continue; |
---|
831 | |
---|
832 | EVDEV_CLIENT_LOCKQ(client); |
---|
833 | evdev_client_push(client, type, code, value); |
---|
834 | if (type == EV_SYN && code == SYN_REPORT) |
---|
835 | evdev_notify_event(client); |
---|
836 | EVDEV_CLIENT_UNLOCKQ(client); |
---|
837 | } |
---|
838 | |
---|
839 | evdev->ev_event_count++; |
---|
840 | } |
---|
841 | |
---|
842 | void |
---|
843 | evdev_send_event(struct evdev_dev *evdev, uint16_t type, uint16_t code, |
---|
844 | int32_t value) |
---|
845 | { |
---|
846 | enum evdev_sparse_result sparse; |
---|
847 | |
---|
848 | EVDEV_LOCK_ASSERT(evdev); |
---|
849 | |
---|
850 | sparse = evdev_sparse_event(evdev, type, code, value); |
---|
851 | switch (sparse) { |
---|
852 | case EV_REPORT_MT_SLOT: |
---|
853 | /* report postponed ABS_MT_SLOT */ |
---|
854 | evdev_propagate_event(evdev, EV_ABS, ABS_MT_SLOT, |
---|
855 | CURRENT_MT_SLOT(evdev)); |
---|
856 | /* FALLTHROUGH */ |
---|
857 | case EV_REPORT_EVENT: |
---|
858 | evdev_propagate_event(evdev, type, code, value); |
---|
859 | /* FALLTHROUGH */ |
---|
860 | case EV_SKIP_EVENT: |
---|
861 | break; |
---|
862 | } |
---|
863 | } |
---|
864 | |
---|
865 | void |
---|
866 | evdev_restore_after_kdb(struct evdev_dev *evdev) |
---|
867 | { |
---|
868 | int code; |
---|
869 | |
---|
870 | EVDEV_LOCK_ASSERT(evdev); |
---|
871 | |
---|
872 | /* Report postponed leds */ |
---|
873 | for (code = 0; code < LED_CNT; code++) |
---|
874 | if (bit_test(evdev->ev_kdb_led_states, code)) |
---|
875 | evdev_send_event(evdev, EV_LED, code, |
---|
876 | !bit_test(evdev->ev_led_states, code)); |
---|
877 | bit_nclear(evdev->ev_kdb_led_states, 0, LED_MAX); |
---|
878 | |
---|
879 | /* Release stuck keys (CTRL + ALT + ESC) */ |
---|
880 | evdev_stop_repeat(evdev); |
---|
881 | for (code = 0; code < KEY_CNT; code++) { |
---|
882 | if (bit_test(evdev->ev_key_states, code)) { |
---|
883 | evdev_send_event(evdev, EV_KEY, code, KEY_EVENT_UP); |
---|
884 | evdev_send_event(evdev, EV_SYN, SYN_REPORT, 1); |
---|
885 | } |
---|
886 | } |
---|
887 | } |
---|
888 | |
---|
889 | int |
---|
890 | evdev_push_event(struct evdev_dev *evdev, uint16_t type, uint16_t code, |
---|
891 | int32_t value) |
---|
892 | { |
---|
893 | |
---|
894 | if (evdev_check_event(evdev, type, code, value) != 0) |
---|
895 | return (EINVAL); |
---|
896 | |
---|
897 | /* |
---|
898 | * Discard all but LEDs kdb events as unrelated to userspace. |
---|
899 | * Aggregate LED updates and postpone reporting until kdb deactivation. |
---|
900 | */ |
---|
901 | if (kdb_active || SCHEDULER_STOPPED()) { |
---|
902 | evdev->ev_kdb_active = true; |
---|
903 | if (type == EV_LED) |
---|
904 | bit_set(evdev->ev_kdb_led_states, |
---|
905 | bit_test(evdev->ev_led_states, code) != value); |
---|
906 | return (0); |
---|
907 | } |
---|
908 | |
---|
909 | EVDEV_ENTER(evdev); |
---|
910 | |
---|
911 | /* Fix evdev state corrupted with discarding of kdb events */ |
---|
912 | if (evdev->ev_kdb_active) { |
---|
913 | evdev->ev_kdb_active = false; |
---|
914 | evdev_restore_after_kdb(evdev); |
---|
915 | } |
---|
916 | |
---|
917 | evdev_modify_event(evdev, type, code, &value); |
---|
918 | if (type == EV_SYN && code == SYN_REPORT && |
---|
919 | bit_test(evdev->ev_flags, EVDEV_FLAG_MT_AUTOREL)) |
---|
920 | evdev_send_mt_autorel(evdev); |
---|
921 | if (type == EV_SYN && code == SYN_REPORT && evdev->ev_report_opened && |
---|
922 | bit_test(evdev->ev_flags, EVDEV_FLAG_MT_STCOMPAT)) |
---|
923 | evdev_send_mt_compat(evdev); |
---|
924 | evdev_send_event(evdev, type, code, value); |
---|
925 | |
---|
926 | EVDEV_EXIT(evdev); |
---|
927 | |
---|
928 | return (0); |
---|
929 | } |
---|
930 | |
---|
931 | int |
---|
932 | evdev_inject_event(struct evdev_dev *evdev, uint16_t type, uint16_t code, |
---|
933 | int32_t value) |
---|
934 | { |
---|
935 | int ret = 0; |
---|
936 | |
---|
937 | switch (type) { |
---|
938 | case EV_REP: |
---|
939 | /* evdev repeats should not be processed by hardware driver */ |
---|
940 | if (bit_test(evdev->ev_flags, EVDEV_FLAG_SOFTREPEAT)) |
---|
941 | goto push; |
---|
942 | /* FALLTHROUGH */ |
---|
943 | case EV_LED: |
---|
944 | case EV_MSC: |
---|
945 | case EV_SND: |
---|
946 | case EV_FF: |
---|
947 | if (evdev->ev_methods != NULL && |
---|
948 | evdev->ev_methods->ev_event != NULL) |
---|
949 | evdev->ev_methods->ev_event(evdev, type, code, value); |
---|
950 | /* |
---|
951 | * Leds and driver repeats should be reported in ev_event |
---|
952 | * method body to interoperate with kbdmux states and rates |
---|
953 | * propagation so both ways (ioctl and evdev) of changing it |
---|
954 | * will produce only one evdev event report to client. |
---|
955 | */ |
---|
956 | if (type == EV_LED || type == EV_REP) |
---|
957 | break; |
---|
958 | /* FALLTHROUGH */ |
---|
959 | case EV_SYN: |
---|
960 | case EV_KEY: |
---|
961 | case EV_REL: |
---|
962 | case EV_ABS: |
---|
963 | case EV_SW: |
---|
964 | push: |
---|
965 | if (evdev->ev_lock_type != EV_LOCK_INTERNAL) |
---|
966 | EVDEV_LOCK(evdev); |
---|
967 | ret = evdev_push_event(evdev, type, code, value); |
---|
968 | if (evdev->ev_lock_type != EV_LOCK_INTERNAL) |
---|
969 | EVDEV_UNLOCK(evdev); |
---|
970 | break; |
---|
971 | |
---|
972 | default: |
---|
973 | ret = EINVAL; |
---|
974 | } |
---|
975 | |
---|
976 | return (ret); |
---|
977 | } |
---|
978 | |
---|
979 | int |
---|
980 | evdev_register_client(struct evdev_dev *evdev, struct evdev_client *client) |
---|
981 | { |
---|
982 | int ret = 0; |
---|
983 | |
---|
984 | debugf(evdev, "adding new client for device %s", evdev->ev_shortname); |
---|
985 | |
---|
986 | EVDEV_LOCK_ASSERT(evdev); |
---|
987 | |
---|
988 | if (LIST_EMPTY(&evdev->ev_clients) && evdev->ev_methods != NULL && |
---|
989 | evdev->ev_methods->ev_open != NULL) { |
---|
990 | debugf(evdev, "calling ev_open() on device %s", |
---|
991 | evdev->ev_shortname); |
---|
992 | ret = evdev->ev_methods->ev_open(evdev); |
---|
993 | } |
---|
994 | if (ret == 0) |
---|
995 | LIST_INSERT_HEAD(&evdev->ev_clients, client, ec_link); |
---|
996 | return (ret); |
---|
997 | } |
---|
998 | |
---|
999 | void |
---|
1000 | evdev_dispose_client(struct evdev_dev *evdev, struct evdev_client *client) |
---|
1001 | { |
---|
1002 | debugf(evdev, "removing client for device %s", evdev->ev_shortname); |
---|
1003 | |
---|
1004 | EVDEV_LOCK_ASSERT(evdev); |
---|
1005 | |
---|
1006 | LIST_REMOVE(client, ec_link); |
---|
1007 | if (LIST_EMPTY(&evdev->ev_clients)) { |
---|
1008 | if (evdev->ev_methods != NULL && |
---|
1009 | evdev->ev_methods->ev_close != NULL) |
---|
1010 | (void)evdev->ev_methods->ev_close(evdev); |
---|
1011 | if (evdev_event_supported(evdev, EV_REP) && |
---|
1012 | bit_test(evdev->ev_flags, EVDEV_FLAG_SOFTREPEAT)) |
---|
1013 | evdev_stop_repeat(evdev); |
---|
1014 | } |
---|
1015 | evdev_release_client(evdev, client); |
---|
1016 | } |
---|
1017 | |
---|
1018 | int |
---|
1019 | evdev_grab_client(struct evdev_dev *evdev, struct evdev_client *client) |
---|
1020 | { |
---|
1021 | |
---|
1022 | EVDEV_LOCK_ASSERT(evdev); |
---|
1023 | |
---|
1024 | if (evdev->ev_grabber != NULL) |
---|
1025 | return (EBUSY); |
---|
1026 | |
---|
1027 | evdev->ev_grabber = client; |
---|
1028 | |
---|
1029 | return (0); |
---|
1030 | } |
---|
1031 | |
---|
1032 | int |
---|
1033 | evdev_release_client(struct evdev_dev *evdev, struct evdev_client *client) |
---|
1034 | { |
---|
1035 | |
---|
1036 | EVDEV_LOCK_ASSERT(evdev); |
---|
1037 | |
---|
1038 | if (evdev->ev_grabber != client) |
---|
1039 | return (EINVAL); |
---|
1040 | |
---|
1041 | evdev->ev_grabber = NULL; |
---|
1042 | |
---|
1043 | return (0); |
---|
1044 | } |
---|
1045 | |
---|
1046 | static void |
---|
1047 | evdev_repeat_callout(void *arg) |
---|
1048 | { |
---|
1049 | struct evdev_dev *evdev = (struct evdev_dev *)arg; |
---|
1050 | |
---|
1051 | evdev_send_event(evdev, EV_KEY, evdev->ev_rep_key, KEY_EVENT_REPEAT); |
---|
1052 | evdev_send_event(evdev, EV_SYN, SYN_REPORT, 1); |
---|
1053 | |
---|
1054 | if (evdev->ev_rep[REP_PERIOD]) |
---|
1055 | callout_reset(&evdev->ev_rep_callout, |
---|
1056 | evdev->ev_rep[REP_PERIOD] * hz / 1000, |
---|
1057 | evdev_repeat_callout, evdev); |
---|
1058 | else |
---|
1059 | evdev->ev_rep_key = KEY_RESERVED; |
---|
1060 | } |
---|
1061 | |
---|
1062 | static void |
---|
1063 | evdev_start_repeat(struct evdev_dev *evdev, uint16_t key) |
---|
1064 | { |
---|
1065 | |
---|
1066 | EVDEV_LOCK_ASSERT(evdev); |
---|
1067 | |
---|
1068 | if (evdev->ev_rep[REP_DELAY]) { |
---|
1069 | evdev->ev_rep_key = key; |
---|
1070 | callout_reset(&evdev->ev_rep_callout, |
---|
1071 | evdev->ev_rep[REP_DELAY] * hz / 1000, |
---|
1072 | evdev_repeat_callout, evdev); |
---|
1073 | } |
---|
1074 | } |
---|
1075 | |
---|
1076 | static void |
---|
1077 | evdev_stop_repeat(struct evdev_dev *evdev) |
---|
1078 | { |
---|
1079 | |
---|
1080 | EVDEV_LOCK_ASSERT(evdev); |
---|
1081 | |
---|
1082 | if (evdev->ev_rep_key != KEY_RESERVED) { |
---|
1083 | callout_stop(&evdev->ev_rep_callout); |
---|
1084 | evdev->ev_rep_key = KEY_RESERVED; |
---|
1085 | } |
---|
1086 | } |
---|
1087 | |
---|
1088 | MODULE_VERSION(evdev, 1); |
---|