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@cicgroup.ru> |
---|
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/types.h> |
---|
35 | #include <sys/systm.h> |
---|
36 | #include <rtems/bsd/sys/param.h> |
---|
37 | #include <sys/kernel.h> |
---|
38 | #include <sys/module.h> |
---|
39 | #include <sys/conf.h> |
---|
40 | #include <sys/malloc.h> |
---|
41 | #include <sys/bitstring.h> |
---|
42 | #include <sys/sysctl.h> |
---|
43 | |
---|
44 | #include <dev/evdev/input.h> |
---|
45 | #include <dev/evdev/evdev.h> |
---|
46 | #include <dev/evdev/evdev_private.h> |
---|
47 | |
---|
48 | #ifdef EVDEV_DEBUG |
---|
49 | #define debugf(evdev, fmt, args...) printf("evdev: " fmt "\n", ##args) |
---|
50 | #else |
---|
51 | #define debugf(evdev, fmt, args...) |
---|
52 | #endif |
---|
53 | |
---|
54 | #ifdef FEATURE |
---|
55 | FEATURE(evdev, "Input event devices support"); |
---|
56 | #endif |
---|
57 | |
---|
58 | enum evdev_sparse_result |
---|
59 | { |
---|
60 | EV_SKIP_EVENT, /* Event value not changed */ |
---|
61 | EV_REPORT_EVENT, /* Event value changed */ |
---|
62 | EV_REPORT_MT_SLOT, /* Event value and MT slot number changed */ |
---|
63 | }; |
---|
64 | |
---|
65 | MALLOC_DEFINE(M_EVDEV, "evdev", "evdev memory"); |
---|
66 | |
---|
67 | int evdev_rcpt_mask = EVDEV_RCPT_SYSMOUSE | EVDEV_RCPT_KBDMUX; |
---|
68 | int evdev_sysmouse_t_axis = 0; |
---|
69 | |
---|
70 | SYSCTL_NODE(_kern, OID_AUTO, evdev, CTLFLAG_RW, 0, "Evdev args"); |
---|
71 | SYSCTL_INT(_kern_evdev, OID_AUTO, rcpt_mask, CTLFLAG_RW, &evdev_rcpt_mask, 0, |
---|
72 | "Who is receiving events: bit0 - sysmouse, bit1 - kbdmux, " |
---|
73 | "bit2 - mouse hardware, bit3 - keyboard hardware"); |
---|
74 | SYSCTL_INT(_kern_evdev, OID_AUTO, sysmouse_t_axis, CTLFLAG_RW, |
---|
75 | &evdev_sysmouse_t_axis, 0, "Extract T-axis from 0-none, 1-ums, 2-psm"); |
---|
76 | |
---|
77 | static void evdev_start_repeat(struct evdev_dev *, uint16_t); |
---|
78 | static void evdev_stop_repeat(struct evdev_dev *); |
---|
79 | static int evdev_check_event(struct evdev_dev *, uint16_t, uint16_t, int32_t); |
---|
80 | |
---|
81 | static inline void |
---|
82 | bit_change(bitstr_t *bitstr, int bit, int value) |
---|
83 | { |
---|
84 | if (value) |
---|
85 | bit_set(bitstr, bit); |
---|
86 | else |
---|
87 | bit_clear(bitstr, bit); |
---|
88 | } |
---|
89 | |
---|
90 | struct evdev_dev * |
---|
91 | evdev_alloc(void) |
---|
92 | { |
---|
93 | |
---|
94 | return malloc(sizeof(struct evdev_dev), M_EVDEV, M_WAITOK | M_ZERO); |
---|
95 | } |
---|
96 | |
---|
97 | void |
---|
98 | evdev_free(struct evdev_dev *evdev) |
---|
99 | { |
---|
100 | |
---|
101 | if (evdev != NULL && evdev->ev_cdev != NULL && |
---|
102 | evdev->ev_cdev->si_drv1 != NULL) |
---|
103 | evdev_unregister(evdev); |
---|
104 | |
---|
105 | free(evdev, M_EVDEV); |
---|
106 | } |
---|
107 | |
---|
108 | static struct input_absinfo * |
---|
109 | evdev_alloc_absinfo(void) |
---|
110 | { |
---|
111 | |
---|
112 | return (malloc(sizeof(struct input_absinfo) * ABS_CNT, M_EVDEV, |
---|
113 | M_WAITOK | M_ZERO)); |
---|
114 | } |
---|
115 | |
---|
116 | static void |
---|
117 | evdev_free_absinfo(struct input_absinfo *absinfo) |
---|
118 | { |
---|
119 | |
---|
120 | free(absinfo, M_EVDEV); |
---|
121 | } |
---|
122 | |
---|
123 | int |
---|
124 | evdev_set_report_size(struct evdev_dev *evdev, size_t report_size) |
---|
125 | { |
---|
126 | if (report_size > KEY_CNT + REL_CNT + ABS_CNT + MAX_MT_SLOTS * MT_CNT + |
---|
127 | MSC_CNT + LED_CNT + SND_CNT + SW_CNT + FF_CNT) |
---|
128 | return (EINVAL); |
---|
129 | |
---|
130 | evdev->ev_report_size = report_size; |
---|
131 | return (0); |
---|
132 | } |
---|
133 | |
---|
134 | static size_t |
---|
135 | evdev_estimate_report_size(struct evdev_dev *evdev) |
---|
136 | { |
---|
137 | size_t size = 0; |
---|
138 | int res; |
---|
139 | |
---|
140 | /* |
---|
141 | * Keyboards generate one event per report but other devices with |
---|
142 | * buttons like mouses can report events simultaneously |
---|
143 | */ |
---|
144 | bit_ffs_at(evdev->ev_key_flags, KEY_OK, KEY_CNT - KEY_OK, &res); |
---|
145 | if (res == -1) |
---|
146 | bit_ffs(evdev->ev_key_flags, BTN_MISC, &res); |
---|
147 | size += (res != -1); |
---|
148 | bit_count(evdev->ev_key_flags, BTN_MISC, KEY_OK - BTN_MISC, &res); |
---|
149 | size += res; |
---|
150 | |
---|
151 | /* All relative axes can be reported simultaneously */ |
---|
152 | bit_count(evdev->ev_rel_flags, 0, REL_CNT, &res); |
---|
153 | size += res; |
---|
154 | |
---|
155 | /* |
---|
156 | * All absolute axes can be reported simultaneously. |
---|
157 | * Multitouch axes can be reported ABS_MT_SLOT times |
---|
158 | */ |
---|
159 | if (evdev->ev_absinfo != NULL) { |
---|
160 | bit_count(evdev->ev_abs_flags, 0, ABS_CNT, &res); |
---|
161 | size += res; |
---|
162 | bit_count(evdev->ev_abs_flags, ABS_MT_FIRST, MT_CNT, &res); |
---|
163 | if (res > 0) { |
---|
164 | res++; /* ABS_MT_SLOT or SYN_MT_REPORT */ |
---|
165 | if (bit_test(evdev->ev_abs_flags, ABS_MT_SLOT)) |
---|
166 | /* MT type B */ |
---|
167 | size += res * MAXIMAL_MT_SLOT(evdev); |
---|
168 | else |
---|
169 | /* MT type A */ |
---|
170 | size += res * (MAX_MT_REPORTS - 1); |
---|
171 | } |
---|
172 | } |
---|
173 | |
---|
174 | /* All misc events can be reported simultaneously */ |
---|
175 | bit_count(evdev->ev_msc_flags, 0, MSC_CNT, &res); |
---|
176 | size += res; |
---|
177 | |
---|
178 | /* All leds can be reported simultaneously */ |
---|
179 | bit_count(evdev->ev_led_flags, 0, LED_CNT, &res); |
---|
180 | size += res; |
---|
181 | |
---|
182 | /* Assume other events are generated once per report */ |
---|
183 | bit_ffs(evdev->ev_snd_flags, SND_CNT, &res); |
---|
184 | size += (res != -1); |
---|
185 | |
---|
186 | bit_ffs(evdev->ev_sw_flags, SW_CNT, &res); |
---|
187 | size += (res != -1); |
---|
188 | |
---|
189 | /* XXX: FF part is not implemented yet */ |
---|
190 | |
---|
191 | size++; /* SYN_REPORT */ |
---|
192 | return (size); |
---|
193 | } |
---|
194 | |
---|
195 | static int |
---|
196 | evdev_register_common(struct evdev_dev *evdev) |
---|
197 | { |
---|
198 | int ret; |
---|
199 | |
---|
200 | debugf(evdev, "%s: registered evdev provider: %s <%s>\n", |
---|
201 | evdev->ev_shortname, evdev->ev_name, evdev->ev_serial); |
---|
202 | |
---|
203 | /* Initialize internal structures */ |
---|
204 | LIST_INIT(&evdev->ev_clients); |
---|
205 | |
---|
206 | if (evdev_event_supported(evdev, EV_REP) && |
---|
207 | bit_test(evdev->ev_flags, EVDEV_FLAG_SOFTREPEAT)) { |
---|
208 | /* Initialize callout */ |
---|
209 | callout_init_mtx(&evdev->ev_rep_callout, &evdev->ev_mtx, 0); |
---|
210 | |
---|
211 | if (evdev->ev_rep[REP_DELAY] == 0 && |
---|
212 | evdev->ev_rep[REP_PERIOD] == 0) { |
---|
213 | /* Supply default values */ |
---|
214 | evdev->ev_rep[REP_DELAY] = 250; |
---|
215 | evdev->ev_rep[REP_PERIOD] = 33; |
---|
216 | } |
---|
217 | } |
---|
218 | |
---|
219 | /* Initialize multitouch protocol type B states */ |
---|
220 | if (bit_test(evdev->ev_abs_flags, ABS_MT_SLOT) && |
---|
221 | evdev->ev_absinfo != NULL && MAXIMAL_MT_SLOT(evdev) > 0) |
---|
222 | evdev_mt_init(evdev); |
---|
223 | |
---|
224 | /* Estimate maximum report size */ |
---|
225 | if (evdev->ev_report_size == 0) { |
---|
226 | ret = evdev_set_report_size(evdev, |
---|
227 | evdev_estimate_report_size(evdev)); |
---|
228 | if (ret != 0) |
---|
229 | goto bail_out; |
---|
230 | } |
---|
231 | |
---|
232 | /* Create char device node */ |
---|
233 | ret = evdev_cdev_create(evdev); |
---|
234 | bail_out: |
---|
235 | return (ret); |
---|
236 | } |
---|
237 | |
---|
238 | int |
---|
239 | evdev_register(struct evdev_dev *evdev) |
---|
240 | { |
---|
241 | int ret; |
---|
242 | |
---|
243 | evdev->ev_lock_type = EV_LOCK_INTERNAL; |
---|
244 | evdev->ev_lock = &evdev->ev_mtx; |
---|
245 | mtx_init(&evdev->ev_mtx, "evmtx", NULL, MTX_DEF); |
---|
246 | |
---|
247 | ret = evdev_register_common(evdev); |
---|
248 | if (ret != 0) |
---|
249 | mtx_destroy(&evdev->ev_mtx); |
---|
250 | |
---|
251 | return (ret); |
---|
252 | } |
---|
253 | |
---|
254 | int |
---|
255 | evdev_register_mtx(struct evdev_dev *evdev, struct mtx *mtx) |
---|
256 | { |
---|
257 | |
---|
258 | evdev->ev_lock_type = EV_LOCK_MTX; |
---|
259 | evdev->ev_lock = mtx; |
---|
260 | return (evdev_register_common(evdev)); |
---|
261 | } |
---|
262 | |
---|
263 | int |
---|
264 | evdev_unregister(struct evdev_dev *evdev) |
---|
265 | { |
---|
266 | struct evdev_client *client; |
---|
267 | int ret; |
---|
268 | debugf(evdev, "%s: unregistered evdev provider: %s\n", |
---|
269 | evdev->ev_shortname, evdev->ev_name); |
---|
270 | |
---|
271 | EVDEV_LOCK(evdev); |
---|
272 | evdev->ev_cdev->si_drv1 = NULL; |
---|
273 | /* Wake up sleepers */ |
---|
274 | LIST_FOREACH(client, &evdev->ev_clients, ec_link) { |
---|
275 | evdev_revoke_client(client); |
---|
276 | evdev_dispose_client(evdev, client); |
---|
277 | EVDEV_CLIENT_LOCKQ(client); |
---|
278 | evdev_notify_event(client); |
---|
279 | EVDEV_CLIENT_UNLOCKQ(client); |
---|
280 | } |
---|
281 | EVDEV_UNLOCK(evdev); |
---|
282 | |
---|
283 | /* destroy_dev can sleep so release lock */ |
---|
284 | ret = evdev_cdev_destroy(evdev); |
---|
285 | evdev->ev_cdev = NULL; |
---|
286 | if (ret == 0 && evdev->ev_lock_type == EV_LOCK_INTERNAL) |
---|
287 | mtx_destroy(&evdev->ev_mtx); |
---|
288 | |
---|
289 | evdev_free_absinfo(evdev->ev_absinfo); |
---|
290 | evdev_mt_free(evdev); |
---|
291 | |
---|
292 | return (ret); |
---|
293 | } |
---|
294 | |
---|
295 | inline void |
---|
296 | evdev_set_name(struct evdev_dev *evdev, const char *name) |
---|
297 | { |
---|
298 | |
---|
299 | snprintf(evdev->ev_name, NAMELEN, "%s", name); |
---|
300 | } |
---|
301 | |
---|
302 | inline void |
---|
303 | evdev_set_id(struct evdev_dev *evdev, uint16_t bustype, uint16_t vendor, |
---|
304 | uint16_t product, uint16_t version) |
---|
305 | { |
---|
306 | |
---|
307 | evdev->ev_id = (struct input_id) { |
---|
308 | .bustype = bustype, |
---|
309 | .vendor = vendor, |
---|
310 | .product = product, |
---|
311 | .version = version |
---|
312 | }; |
---|
313 | } |
---|
314 | |
---|
315 | inline void |
---|
316 | evdev_set_phys(struct evdev_dev *evdev, const char *name) |
---|
317 | { |
---|
318 | |
---|
319 | snprintf(evdev->ev_shortname, NAMELEN, "%s", name); |
---|
320 | } |
---|
321 | |
---|
322 | inline void |
---|
323 | evdev_set_serial(struct evdev_dev *evdev, const char *serial) |
---|
324 | { |
---|
325 | |
---|
326 | snprintf(evdev->ev_serial, NAMELEN, "%s", serial); |
---|
327 | } |
---|
328 | |
---|
329 | inline void |
---|
330 | evdev_set_methods(struct evdev_dev *evdev, void *softc, |
---|
331 | const struct evdev_methods *methods) |
---|
332 | { |
---|
333 | |
---|
334 | evdev->ev_methods = methods; |
---|
335 | evdev->ev_softc = softc; |
---|
336 | } |
---|
337 | |
---|
338 | inline void |
---|
339 | evdev_support_prop(struct evdev_dev *evdev, uint16_t prop) |
---|
340 | { |
---|
341 | |
---|
342 | KASSERT(prop < INPUT_PROP_CNT, ("invalid evdev input property")); |
---|
343 | bit_set(evdev->ev_prop_flags, prop); |
---|
344 | } |
---|
345 | |
---|
346 | inline void |
---|
347 | evdev_support_event(struct evdev_dev *evdev, uint16_t type) |
---|
348 | { |
---|
349 | |
---|
350 | KASSERT(type < EV_CNT, ("invalid evdev event property")); |
---|
351 | bit_set(evdev->ev_type_flags, type); |
---|
352 | } |
---|
353 | |
---|
354 | inline void |
---|
355 | evdev_support_key(struct evdev_dev *evdev, uint16_t code) |
---|
356 | { |
---|
357 | |
---|
358 | KASSERT(code < KEY_CNT, ("invalid evdev key property")); |
---|
359 | bit_set(evdev->ev_key_flags, code); |
---|
360 | } |
---|
361 | |
---|
362 | inline void |
---|
363 | evdev_support_rel(struct evdev_dev *evdev, uint16_t code) |
---|
364 | { |
---|
365 | |
---|
366 | KASSERT(code < REL_CNT, ("invalid evdev rel property")); |
---|
367 | bit_set(evdev->ev_rel_flags, code); |
---|
368 | } |
---|
369 | |
---|
370 | inline void |
---|
371 | evdev_support_abs(struct evdev_dev *evdev, uint16_t code, int32_t value, |
---|
372 | int32_t minimum, int32_t maximum, int32_t fuzz, int32_t flat, |
---|
373 | int32_t resolution) |
---|
374 | { |
---|
375 | struct input_absinfo absinfo; |
---|
376 | |
---|
377 | KASSERT(code < ABS_CNT, ("invalid evdev abs property")); |
---|
378 | |
---|
379 | absinfo = (struct input_absinfo) { |
---|
380 | .value = value, |
---|
381 | .minimum = minimum, |
---|
382 | .maximum = maximum, |
---|
383 | .fuzz = fuzz, |
---|
384 | .flat = flat, |
---|
385 | .resolution = resolution, |
---|
386 | }; |
---|
387 | evdev_set_abs_bit(evdev, code); |
---|
388 | evdev_set_absinfo(evdev, code, &absinfo); |
---|
389 | } |
---|
390 | |
---|
391 | inline void |
---|
392 | evdev_set_abs_bit(struct evdev_dev *evdev, uint16_t code) |
---|
393 | { |
---|
394 | |
---|
395 | KASSERT(code < ABS_CNT, ("invalid evdev abs property")); |
---|
396 | if (evdev->ev_absinfo == NULL) |
---|
397 | evdev->ev_absinfo = evdev_alloc_absinfo(); |
---|
398 | bit_set(evdev->ev_abs_flags, code); |
---|
399 | } |
---|
400 | |
---|
401 | inline void |
---|
402 | evdev_support_msc(struct evdev_dev *evdev, uint16_t code) |
---|
403 | { |
---|
404 | |
---|
405 | KASSERT(code < MSC_CNT, ("invalid evdev msc property")); |
---|
406 | bit_set(evdev->ev_msc_flags, code); |
---|
407 | } |
---|
408 | |
---|
409 | |
---|
410 | inline void |
---|
411 | evdev_support_led(struct evdev_dev *evdev, uint16_t code) |
---|
412 | { |
---|
413 | |
---|
414 | KASSERT(code < LED_CNT, ("invalid evdev led property")); |
---|
415 | bit_set(evdev->ev_led_flags, code); |
---|
416 | } |
---|
417 | |
---|
418 | inline void |
---|
419 | evdev_support_snd(struct evdev_dev *evdev, uint16_t code) |
---|
420 | { |
---|
421 | |
---|
422 | KASSERT(code < SND_CNT, ("invalid evdev snd property")); |
---|
423 | bit_set(evdev->ev_snd_flags, code); |
---|
424 | } |
---|
425 | |
---|
426 | inline void |
---|
427 | evdev_support_sw(struct evdev_dev *evdev, uint16_t code) |
---|
428 | { |
---|
429 | |
---|
430 | KASSERT(code < SW_CNT, ("invalid evdev sw property")); |
---|
431 | bit_set(evdev->ev_sw_flags, code); |
---|
432 | } |
---|
433 | |
---|
434 | bool |
---|
435 | evdev_event_supported(struct evdev_dev *evdev, uint16_t type) |
---|
436 | { |
---|
437 | |
---|
438 | KASSERT(type < EV_CNT, ("invalid evdev event property")); |
---|
439 | return (bit_test(evdev->ev_type_flags, type)); |
---|
440 | } |
---|
441 | |
---|
442 | inline void |
---|
443 | evdev_set_absinfo(struct evdev_dev *evdev, uint16_t axis, |
---|
444 | struct input_absinfo *absinfo) |
---|
445 | { |
---|
446 | |
---|
447 | KASSERT(axis < ABS_CNT, ("invalid evdev abs property")); |
---|
448 | |
---|
449 | if (axis == ABS_MT_SLOT && |
---|
450 | (absinfo->maximum < 1 || absinfo->maximum >= MAX_MT_SLOTS)) |
---|
451 | return; |
---|
452 | |
---|
453 | if (evdev->ev_absinfo == NULL) |
---|
454 | evdev->ev_absinfo = evdev_alloc_absinfo(); |
---|
455 | |
---|
456 | if (axis == ABS_MT_SLOT) |
---|
457 | evdev->ev_absinfo[ABS_MT_SLOT].maximum = absinfo->maximum; |
---|
458 | else |
---|
459 | memcpy(&evdev->ev_absinfo[axis], absinfo, |
---|
460 | sizeof(struct input_absinfo)); |
---|
461 | } |
---|
462 | |
---|
463 | inline void |
---|
464 | evdev_set_repeat_params(struct evdev_dev *evdev, uint16_t property, int value) |
---|
465 | { |
---|
466 | |
---|
467 | KASSERT(property < REP_CNT, ("invalid evdev repeat property")); |
---|
468 | evdev->ev_rep[property] = value; |
---|
469 | } |
---|
470 | |
---|
471 | inline void |
---|
472 | evdev_set_flag(struct evdev_dev *evdev, uint16_t flag) |
---|
473 | { |
---|
474 | |
---|
475 | KASSERT(flag < EVDEV_FLAG_CNT, ("invalid evdev flag property")); |
---|
476 | bit_set(evdev->ev_flags, flag); |
---|
477 | } |
---|
478 | |
---|
479 | static int |
---|
480 | evdev_check_event(struct evdev_dev *evdev, uint16_t type, uint16_t code, |
---|
481 | int32_t value) |
---|
482 | { |
---|
483 | |
---|
484 | if (type >= EV_CNT) |
---|
485 | return (EINVAL); |
---|
486 | |
---|
487 | /* Allow SYN events implicitly */ |
---|
488 | if (type != EV_SYN && !evdev_event_supported(evdev, type)) |
---|
489 | return (EINVAL); |
---|
490 | |
---|
491 | switch (type) { |
---|
492 | case EV_SYN: |
---|
493 | if (code >= SYN_CNT) |
---|
494 | return (EINVAL); |
---|
495 | break; |
---|
496 | |
---|
497 | case EV_KEY: |
---|
498 | if (code >= KEY_CNT) |
---|
499 | return (EINVAL); |
---|
500 | if (!bit_test(evdev->ev_key_flags, code)) |
---|
501 | return (EINVAL); |
---|
502 | break; |
---|
503 | |
---|
504 | case EV_REL: |
---|
505 | if (code >= REL_CNT) |
---|
506 | return (EINVAL); |
---|
507 | if (!bit_test(evdev->ev_rel_flags, code)) |
---|
508 | return (EINVAL); |
---|
509 | break; |
---|
510 | |
---|
511 | case EV_ABS: |
---|
512 | if (code >= ABS_CNT) |
---|
513 | return (EINVAL); |
---|
514 | if (!bit_test(evdev->ev_abs_flags, code)) |
---|
515 | return (EINVAL); |
---|
516 | if (code == ABS_MT_SLOT && |
---|
517 | (value < 0 || value > MAXIMAL_MT_SLOT(evdev))) |
---|
518 | return (EINVAL); |
---|
519 | if (ABS_IS_MT(code) && evdev->ev_mt == NULL && |
---|
520 | bit_test(evdev->ev_abs_flags, ABS_MT_SLOT)) |
---|
521 | return (EINVAL); |
---|
522 | break; |
---|
523 | |
---|
524 | case EV_MSC: |
---|
525 | if (code >= MSC_CNT) |
---|
526 | return (EINVAL); |
---|
527 | if (!bit_test(evdev->ev_msc_flags, code)) |
---|
528 | return (EINVAL); |
---|
529 | break; |
---|
530 | |
---|
531 | case EV_LED: |
---|
532 | if (code >= LED_CNT) |
---|
533 | return (EINVAL); |
---|
534 | if (!bit_test(evdev->ev_led_flags, code)) |
---|
535 | return (EINVAL); |
---|
536 | break; |
---|
537 | |
---|
538 | case EV_SND: |
---|
539 | if (code >= SND_CNT) |
---|
540 | return (EINVAL); |
---|
541 | if (!bit_test(evdev->ev_snd_flags, code)) |
---|
542 | return (EINVAL); |
---|
543 | break; |
---|
544 | |
---|
545 | case EV_SW: |
---|
546 | if (code >= SW_CNT) |
---|
547 | return (EINVAL); |
---|
548 | if (!bit_test(evdev->ev_sw_flags, code)) |
---|
549 | return (EINVAL); |
---|
550 | break; |
---|
551 | |
---|
552 | case EV_REP: |
---|
553 | if (code >= REP_CNT) |
---|
554 | return (EINVAL); |
---|
555 | break; |
---|
556 | |
---|
557 | default: |
---|
558 | return (EINVAL); |
---|
559 | } |
---|
560 | |
---|
561 | return (0); |
---|
562 | } |
---|
563 | |
---|
564 | static void |
---|
565 | evdev_modify_event(struct evdev_dev *evdev, uint16_t type, uint16_t code, |
---|
566 | int32_t *value) |
---|
567 | { |
---|
568 | |
---|
569 | EVDEV_LOCK_ASSERT(evdev); |
---|
570 | |
---|
571 | switch (type) { |
---|
572 | case EV_KEY: |
---|
573 | if (!evdev_event_supported(evdev, EV_REP)) |
---|
574 | break; |
---|
575 | |
---|
576 | if (!bit_test(evdev->ev_flags, EVDEV_FLAG_SOFTREPEAT)) { |
---|
577 | /* Detect driver key repeats. */ |
---|
578 | if (bit_test(evdev->ev_key_states, code) && |
---|
579 | *value == KEY_EVENT_DOWN) |
---|
580 | *value = KEY_EVENT_REPEAT; |
---|
581 | } else { |
---|
582 | /* Start/stop callout for evdev repeats */ |
---|
583 | if (bit_test(evdev->ev_key_states, code) == !*value) { |
---|
584 | if (*value == KEY_EVENT_DOWN) |
---|
585 | evdev_start_repeat(evdev, code); |
---|
586 | else |
---|
587 | evdev_stop_repeat(evdev); |
---|
588 | } |
---|
589 | } |
---|
590 | break; |
---|
591 | |
---|
592 | case EV_ABS: |
---|
593 | /* TBD: implement fuzz */ |
---|
594 | break; |
---|
595 | } |
---|
596 | } |
---|
597 | |
---|
598 | static enum evdev_sparse_result |
---|
599 | evdev_sparse_event(struct evdev_dev *evdev, uint16_t type, uint16_t code, |
---|
600 | int32_t value) |
---|
601 | { |
---|
602 | int32_t last_mt_slot; |
---|
603 | |
---|
604 | EVDEV_LOCK_ASSERT(evdev); |
---|
605 | |
---|
606 | /* |
---|
607 | * For certain event types, update device state bits |
---|
608 | * and convert level reporting to edge reporting |
---|
609 | */ |
---|
610 | switch (type) { |
---|
611 | case EV_KEY: |
---|
612 | switch (value) { |
---|
613 | case KEY_EVENT_UP: |
---|
614 | case KEY_EVENT_DOWN: |
---|
615 | if (bit_test(evdev->ev_key_states, code) == value) |
---|
616 | return (EV_SKIP_EVENT); |
---|
617 | bit_change(evdev->ev_key_states, code, value); |
---|
618 | break; |
---|
619 | |
---|
620 | case KEY_EVENT_REPEAT: |
---|
621 | if (bit_test(evdev->ev_key_states, code) == 0 || |
---|
622 | !evdev_event_supported(evdev, EV_REP)) |
---|
623 | return (EV_SKIP_EVENT); |
---|
624 | break; |
---|
625 | |
---|
626 | default: |
---|
627 | return (EV_SKIP_EVENT); |
---|
628 | } |
---|
629 | break; |
---|
630 | |
---|
631 | case EV_LED: |
---|
632 | if (bit_test(evdev->ev_led_states, code) == value) |
---|
633 | return (EV_SKIP_EVENT); |
---|
634 | bit_change(evdev->ev_led_states, code, value); |
---|
635 | break; |
---|
636 | |
---|
637 | case EV_SND: |
---|
638 | if (bit_test(evdev->ev_snd_states, code) == value) |
---|
639 | return (EV_SKIP_EVENT); |
---|
640 | bit_change(evdev->ev_snd_states, code, value); |
---|
641 | break; |
---|
642 | |
---|
643 | case EV_SW: |
---|
644 | if (bit_test(evdev->ev_sw_states, code) == value) |
---|
645 | return (EV_SKIP_EVENT); |
---|
646 | bit_change(evdev->ev_sw_states, code, value); |
---|
647 | break; |
---|
648 | |
---|
649 | case EV_REP: |
---|
650 | if (evdev->ev_rep[code] == value) |
---|
651 | return (EV_SKIP_EVENT); |
---|
652 | evdev_set_repeat_params(evdev, code, value); |
---|
653 | break; |
---|
654 | |
---|
655 | case EV_REL: |
---|
656 | if (value == 0) |
---|
657 | return (EV_SKIP_EVENT); |
---|
658 | break; |
---|
659 | |
---|
660 | /* For EV_ABS, save last value in absinfo and ev_mt_states */ |
---|
661 | case EV_ABS: |
---|
662 | switch (code) { |
---|
663 | case ABS_MT_SLOT: |
---|
664 | /* Postpone ABS_MT_SLOT till next event */ |
---|
665 | evdev_set_last_mt_slot(evdev, value); |
---|
666 | return (EV_SKIP_EVENT); |
---|
667 | |
---|
668 | case ABS_MT_FIRST ... ABS_MT_LAST: |
---|
669 | /* Pass MT protocol type A events as is */ |
---|
670 | if (!bit_test(evdev->ev_abs_flags, ABS_MT_SLOT)) |
---|
671 | break; |
---|
672 | /* Don`t repeat MT protocol type B events */ |
---|
673 | last_mt_slot = evdev_get_last_mt_slot(evdev); |
---|
674 | if (evdev_get_mt_value(evdev, last_mt_slot, code) |
---|
675 | == value) |
---|
676 | return (EV_SKIP_EVENT); |
---|
677 | evdev_set_mt_value(evdev, last_mt_slot, code, value); |
---|
678 | if (last_mt_slot != CURRENT_MT_SLOT(evdev)) { |
---|
679 | CURRENT_MT_SLOT(evdev) = last_mt_slot; |
---|
680 | evdev->ev_report_opened = true; |
---|
681 | return (EV_REPORT_MT_SLOT); |
---|
682 | } |
---|
683 | break; |
---|
684 | |
---|
685 | default: |
---|
686 | if (evdev->ev_absinfo[code].value == value) |
---|
687 | return (EV_SKIP_EVENT); |
---|
688 | evdev->ev_absinfo[code].value = value; |
---|
689 | } |
---|
690 | break; |
---|
691 | |
---|
692 | case EV_SYN: |
---|
693 | if (code == SYN_REPORT) { |
---|
694 | /* Count empty reports as well as non empty */ |
---|
695 | evdev->ev_report_count++; |
---|
696 | /* Skip empty reports */ |
---|
697 | if (!evdev->ev_report_opened) |
---|
698 | return (EV_SKIP_EVENT); |
---|
699 | evdev->ev_report_opened = false; |
---|
700 | return (EV_REPORT_EVENT); |
---|
701 | } |
---|
702 | break; |
---|
703 | } |
---|
704 | |
---|
705 | evdev->ev_report_opened = true; |
---|
706 | return (EV_REPORT_EVENT); |
---|
707 | } |
---|
708 | |
---|
709 | static void |
---|
710 | evdev_propagate_event(struct evdev_dev *evdev, uint16_t type, uint16_t code, |
---|
711 | int32_t value) |
---|
712 | { |
---|
713 | struct evdev_client *client; |
---|
714 | |
---|
715 | debugf(evdev, "%s pushed event %d/%d/%d", |
---|
716 | evdev->ev_shortname, type, code, value); |
---|
717 | |
---|
718 | EVDEV_LOCK_ASSERT(evdev); |
---|
719 | |
---|
720 | /* Propagate event through all clients */ |
---|
721 | LIST_FOREACH(client, &evdev->ev_clients, ec_link) { |
---|
722 | if (evdev->ev_grabber != NULL && evdev->ev_grabber != client) |
---|
723 | continue; |
---|
724 | |
---|
725 | EVDEV_CLIENT_LOCKQ(client); |
---|
726 | evdev_client_push(client, type, code, value); |
---|
727 | if (type == EV_SYN && code == SYN_REPORT) |
---|
728 | evdev_notify_event(client); |
---|
729 | EVDEV_CLIENT_UNLOCKQ(client); |
---|
730 | } |
---|
731 | |
---|
732 | evdev->ev_event_count++; |
---|
733 | } |
---|
734 | |
---|
735 | void |
---|
736 | evdev_send_event(struct evdev_dev *evdev, uint16_t type, uint16_t code, |
---|
737 | int32_t value) |
---|
738 | { |
---|
739 | enum evdev_sparse_result sparse; |
---|
740 | |
---|
741 | EVDEV_LOCK_ASSERT(evdev); |
---|
742 | |
---|
743 | sparse = evdev_sparse_event(evdev, type, code, value); |
---|
744 | switch (sparse) { |
---|
745 | case EV_REPORT_MT_SLOT: |
---|
746 | /* report postponed ABS_MT_SLOT */ |
---|
747 | evdev_propagate_event(evdev, EV_ABS, ABS_MT_SLOT, |
---|
748 | CURRENT_MT_SLOT(evdev)); |
---|
749 | /* FALLTHROUGH */ |
---|
750 | case EV_REPORT_EVENT: |
---|
751 | evdev_propagate_event(evdev, type, code, value); |
---|
752 | /* FALLTHROUGH */ |
---|
753 | case EV_SKIP_EVENT: |
---|
754 | break; |
---|
755 | } |
---|
756 | } |
---|
757 | |
---|
758 | int |
---|
759 | evdev_push_event(struct evdev_dev *evdev, uint16_t type, uint16_t code, |
---|
760 | int32_t value) |
---|
761 | { |
---|
762 | |
---|
763 | if (evdev->ev_lock_type != EV_LOCK_INTERNAL) |
---|
764 | EVDEV_LOCK_ASSERT(evdev); |
---|
765 | |
---|
766 | if (evdev_check_event(evdev, type, code, value) != 0) |
---|
767 | return (EINVAL); |
---|
768 | |
---|
769 | if (evdev->ev_lock_type == EV_LOCK_INTERNAL) |
---|
770 | EVDEV_LOCK(evdev); |
---|
771 | evdev_modify_event(evdev, type, code, &value); |
---|
772 | if (type == EV_SYN && code == SYN_REPORT && |
---|
773 | bit_test(evdev->ev_flags, EVDEV_FLAG_MT_AUTOREL)) |
---|
774 | evdev_send_mt_autorel(evdev); |
---|
775 | if (type == EV_SYN && code == SYN_REPORT && evdev->ev_report_opened && |
---|
776 | bit_test(evdev->ev_flags, EVDEV_FLAG_MT_STCOMPAT)) |
---|
777 | evdev_send_mt_compat(evdev); |
---|
778 | evdev_send_event(evdev, type, code, value); |
---|
779 | if (evdev->ev_lock_type == EV_LOCK_INTERNAL) |
---|
780 | EVDEV_UNLOCK(evdev); |
---|
781 | |
---|
782 | return (0); |
---|
783 | } |
---|
784 | |
---|
785 | int |
---|
786 | evdev_inject_event(struct evdev_dev *evdev, uint16_t type, uint16_t code, |
---|
787 | int32_t value) |
---|
788 | { |
---|
789 | int ret = 0; |
---|
790 | |
---|
791 | switch (type) { |
---|
792 | case EV_REP: |
---|
793 | /* evdev repeats should not be processed by hardware driver */ |
---|
794 | if (bit_test(evdev->ev_flags, EVDEV_FLAG_SOFTREPEAT)) |
---|
795 | goto push; |
---|
796 | /* FALLTHROUGH */ |
---|
797 | case EV_LED: |
---|
798 | case EV_MSC: |
---|
799 | case EV_SND: |
---|
800 | case EV_FF: |
---|
801 | if (evdev->ev_methods != NULL && |
---|
802 | evdev->ev_methods->ev_event != NULL) |
---|
803 | evdev->ev_methods->ev_event(evdev, evdev->ev_softc, |
---|
804 | type, code, value); |
---|
805 | /* |
---|
806 | * Leds and driver repeats should be reported in ev_event |
---|
807 | * method body to interoperate with kbdmux states and rates |
---|
808 | * propagation so both ways (ioctl and evdev) of changing it |
---|
809 | * will produce only one evdev event report to client. |
---|
810 | */ |
---|
811 | if (type == EV_LED || type == EV_REP) |
---|
812 | break; |
---|
813 | /* FALLTHROUGH */ |
---|
814 | case EV_SYN: |
---|
815 | case EV_KEY: |
---|
816 | case EV_REL: |
---|
817 | case EV_ABS: |
---|
818 | case EV_SW: |
---|
819 | push: |
---|
820 | ret = evdev_push_event(evdev, type, code, value); |
---|
821 | break; |
---|
822 | |
---|
823 | default: |
---|
824 | ret = EINVAL; |
---|
825 | } |
---|
826 | |
---|
827 | return (ret); |
---|
828 | } |
---|
829 | |
---|
830 | int |
---|
831 | evdev_register_client(struct evdev_dev *evdev, struct evdev_client *client) |
---|
832 | { |
---|
833 | int ret = 0; |
---|
834 | |
---|
835 | debugf(evdev, "adding new client for device %s", evdev->ev_shortname); |
---|
836 | |
---|
837 | EVDEV_LOCK_ASSERT(evdev); |
---|
838 | |
---|
839 | if (LIST_EMPTY(&evdev->ev_clients) && evdev->ev_methods != NULL && |
---|
840 | evdev->ev_methods->ev_open != NULL) { |
---|
841 | debugf(evdev, "calling ev_open() on device %s", |
---|
842 | evdev->ev_shortname); |
---|
843 | ret = evdev->ev_methods->ev_open(evdev, evdev->ev_softc); |
---|
844 | } |
---|
845 | if (ret == 0) |
---|
846 | LIST_INSERT_HEAD(&evdev->ev_clients, client, ec_link); |
---|
847 | return (ret); |
---|
848 | } |
---|
849 | |
---|
850 | void |
---|
851 | evdev_dispose_client(struct evdev_dev *evdev, struct evdev_client *client) |
---|
852 | { |
---|
853 | debugf(evdev, "removing client for device %s", evdev->ev_shortname); |
---|
854 | |
---|
855 | EVDEV_LOCK_ASSERT(evdev); |
---|
856 | |
---|
857 | LIST_REMOVE(client, ec_link); |
---|
858 | if (LIST_EMPTY(&evdev->ev_clients)) { |
---|
859 | if (evdev->ev_methods != NULL && |
---|
860 | evdev->ev_methods->ev_close != NULL) |
---|
861 | evdev->ev_methods->ev_close(evdev, evdev->ev_softc); |
---|
862 | if (evdev_event_supported(evdev, EV_REP) && |
---|
863 | bit_test(evdev->ev_flags, EVDEV_FLAG_SOFTREPEAT)) |
---|
864 | evdev_stop_repeat(evdev); |
---|
865 | } |
---|
866 | evdev_release_client(evdev, client); |
---|
867 | } |
---|
868 | |
---|
869 | int |
---|
870 | evdev_grab_client(struct evdev_dev *evdev, struct evdev_client *client) |
---|
871 | { |
---|
872 | |
---|
873 | EVDEV_LOCK_ASSERT(evdev); |
---|
874 | |
---|
875 | if (evdev->ev_grabber != NULL) |
---|
876 | return (EBUSY); |
---|
877 | |
---|
878 | evdev->ev_grabber = client; |
---|
879 | |
---|
880 | return (0); |
---|
881 | } |
---|
882 | |
---|
883 | int |
---|
884 | evdev_release_client(struct evdev_dev *evdev, struct evdev_client *client) |
---|
885 | { |
---|
886 | |
---|
887 | EVDEV_LOCK_ASSERT(evdev); |
---|
888 | |
---|
889 | if (evdev->ev_grabber != client) |
---|
890 | return (EINVAL); |
---|
891 | |
---|
892 | evdev->ev_grabber = NULL; |
---|
893 | |
---|
894 | return (0); |
---|
895 | } |
---|
896 | |
---|
897 | static void |
---|
898 | evdev_repeat_callout(void *arg) |
---|
899 | { |
---|
900 | struct evdev_dev *evdev = (struct evdev_dev *)arg; |
---|
901 | |
---|
902 | evdev_send_event(evdev, EV_KEY, evdev->ev_rep_key, KEY_EVENT_REPEAT); |
---|
903 | evdev_send_event(evdev, EV_SYN, SYN_REPORT, 1); |
---|
904 | |
---|
905 | if (evdev->ev_rep[REP_PERIOD]) |
---|
906 | callout_reset(&evdev->ev_rep_callout, |
---|
907 | evdev->ev_rep[REP_PERIOD] * hz / 1000, |
---|
908 | evdev_repeat_callout, evdev); |
---|
909 | else |
---|
910 | evdev->ev_rep_key = KEY_RESERVED; |
---|
911 | } |
---|
912 | |
---|
913 | static void |
---|
914 | evdev_start_repeat(struct evdev_dev *evdev, uint16_t key) |
---|
915 | { |
---|
916 | |
---|
917 | EVDEV_LOCK_ASSERT(evdev); |
---|
918 | |
---|
919 | if (evdev->ev_rep[REP_DELAY]) { |
---|
920 | evdev->ev_rep_key = key; |
---|
921 | callout_reset(&evdev->ev_rep_callout, |
---|
922 | evdev->ev_rep[REP_DELAY] * hz / 1000, |
---|
923 | evdev_repeat_callout, evdev); |
---|
924 | } |
---|
925 | } |
---|
926 | |
---|
927 | static void |
---|
928 | evdev_stop_repeat(struct evdev_dev *evdev) |
---|
929 | { |
---|
930 | |
---|
931 | EVDEV_LOCK_ASSERT(evdev); |
---|
932 | |
---|
933 | if (evdev->ev_rep_key != KEY_RESERVED) { |
---|
934 | callout_stop(&evdev->ev_rep_callout); |
---|
935 | evdev->ev_rep_key = KEY_RESERVED; |
---|
936 | } |
---|
937 | } |
---|
938 | |
---|
939 | MODULE_VERSION(evdev, 1); |
---|