xref: /dragonfly/sys/dev/misc/evdev/evdev_utils.c (revision a162a738eca94f99d45d88429e86cfd0fbfbe95d)
1 /*-
2  * Copyright (c) 2014 Jakub Wojciech Klama <jceel@FreeBSD.org>
3  * Copyright (c) 2015-2016 Vladimir Kondratyev <wulf@FreeBSD.org>
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25  * SUCH DAMAGE.
26  *
27  * $FreeBSD$
28  */
29 
30 #include <sys/param.h>
31 #include <sys/bus.h>
32 #include <sys/conf.h>
33 #include <sys/kbio.h>
34 #include <sys/kernel.h>
35 #include <sys/malloc.h>
36 #include <sys/systm.h>
37 
38 #include <dev/misc/evdev/evdev.h>
39 #include <dev/misc/evdev/evdev_private.h>
40 #include <dev/misc/evdev/input.h>
41 #include <dev/misc/kbd/kbdreg.h>
42 
43 #define   NONE      KEY_RESERVED
44 
45 static uint16_t evdev_usb_scancodes[256] = {
46           /* 0x00 - 0x27 */
47           NONE,     NONE,     NONE,     NONE,     KEY_A,    KEY_B,    KEY_C,    KEY_D,
48           KEY_E,    KEY_F,    KEY_G,    KEY_H,    KEY_I,    KEY_J,    KEY_K,    KEY_L,
49           KEY_M,    KEY_N,    KEY_O,    KEY_P,    KEY_Q,    KEY_R,    KEY_S,    KEY_T,
50           KEY_U,    KEY_V,    KEY_W,    KEY_X,    KEY_Y,    KEY_Z,    KEY_1,    KEY_2,
51           KEY_3,    KEY_4,    KEY_5,    KEY_6,    KEY_7,    KEY_8,    KEY_9,    KEY_0,
52           /* 0x28 - 0x3f */
53           KEY_ENTER,          KEY_ESC,  KEY_BACKSPACE,      KEY_TAB,
54           KEY_SPACE,          KEY_MINUS,          KEY_EQUAL,          KEY_LEFTBRACE,
55           KEY_RIGHTBRACE,     KEY_BACKSLASH,      KEY_BACKSLASH,      KEY_SEMICOLON,
56           KEY_APOSTROPHE,     KEY_GRAVE,          KEY_COMMA,          KEY_DOT,
57           KEY_SLASH,          KEY_CAPSLOCK,       KEY_F1,             KEY_F2,
58           KEY_F3,             KEY_F4,             KEY_F5,             KEY_F6,
59           /* 0x40 - 0x5f */
60           KEY_F7,             KEY_F8,             KEY_F9,             KEY_F10,
61           KEY_F11,  KEY_F12,  KEY_SYSRQ,          KEY_SCROLLLOCK,
62           KEY_PAUSE,          KEY_INSERT,         KEY_HOME, KEY_PAGEUP,
63           KEY_DELETE,         KEY_END,  KEY_PAGEDOWN,       KEY_RIGHT,
64           KEY_LEFT, KEY_DOWN, KEY_UP,             KEY_NUMLOCK,
65           KEY_KPSLASH,        KEY_KPASTERISK,     KEY_KPMINUS,        KEY_KPPLUS,
66           KEY_KPENTER,        KEY_KP1,  KEY_KP2,  KEY_KP3,
67           KEY_KP4,  KEY_KP5,  KEY_KP6,  KEY_KP7,
68           /* 0x60 - 0x7f */
69           KEY_KP8,  KEY_KP9,  KEY_KP0,  KEY_KPDOT,
70           KEY_102ND,          KEY_COMPOSE,        KEY_POWER,          KEY_KPEQUAL,
71           KEY_F13,  KEY_F14,  KEY_F15,  KEY_F16,
72           KEY_F17,  KEY_F18,  KEY_F19,  KEY_F20,
73           KEY_F21,  KEY_F22,  KEY_F23,  KEY_F24,
74           KEY_OPEN, KEY_HELP, KEY_PROPS,          KEY_FRONT,
75           KEY_STOP, KEY_AGAIN,          KEY_UNDO, KEY_CUT,
76           KEY_COPY, KEY_PASTE,          KEY_FIND, KEY_MUTE,
77           /* 0x80 - 0x9f */
78           KEY_VOLUMEUP,       KEY_VOLUMEDOWN,     NONE,               NONE,
79           NONE,               KEY_KPCOMMA,        NONE,               KEY_RO,
80           KEY_KATAKANAHIRAGANA,         KEY_YEN,KEY_HENKAN, KEY_MUHENKAN,
81           KEY_KPJPCOMMA,      NONE,               NONE,               NONE,
82           KEY_HANGEUL,        KEY_HANJA,          KEY_KATAKANA,       KEY_HIRAGANA,
83           KEY_ZENKAKUHANKAKU, NONE,     NONE,               NONE,
84           NONE,               NONE,               NONE,               NONE,
85           NONE,               NONE,               NONE,               NONE,
86           /* 0xa0 - 0xbf */
87           NONE,               NONE,               NONE,               NONE,
88           NONE,               NONE,               NONE,               NONE,
89           NONE,               NONE,               NONE,               NONE,
90           NONE,               NONE,               NONE,               NONE,
91           NONE,               NONE,               NONE,               NONE,
92           NONE,               NONE,               NONE,               NONE,
93           NONE,               NONE,               NONE,               NONE,
94           NONE,               NONE,               NONE,               NONE,
95           /* 0xc0 - 0xdf */
96           NONE,               NONE,               NONE,               NONE,
97           NONE,               NONE,               NONE,               NONE,
98           NONE,               NONE,               NONE,               NONE,
99           NONE,               NONE,               NONE,               NONE,
100           NONE,               NONE,               NONE,               NONE,
101           NONE,               NONE,               NONE,               NONE,
102           NONE,               NONE,               NONE,               NONE,
103           NONE,               NONE,               NONE,               NONE,
104           /* 0xe0 - 0xff */
105           KEY_LEFTCTRL,       KEY_LEFTSHIFT,      KEY_LEFTALT,        KEY_LEFTMETA,
106           KEY_RIGHTCTRL,      KEY_RIGHTSHIFT,     KEY_RIGHTALT,       KEY_RIGHTMETA,
107           KEY_PLAYPAUSE,      KEY_STOPCD,         KEY_PREVIOUSSONG,KEY_NEXTSONG,
108           KEY_EJECTCD,        KEY_VOLUMEUP,       KEY_VOLUMEDOWN,     KEY_MUTE,
109           KEY_WWW,  KEY_BACK, KEY_FORWARD,        KEY_STOP,
110           KEY_FIND, KEY_SCROLLUP,       KEY_SCROLLDOWN,     KEY_EDIT,
111           KEY_SLEEP,          KEY_COFFEE,         KEY_REFRESH,        KEY_CALC,
112           NONE,               NONE,               NONE,               NONE,
113 
114 };
115 
116 static uint16_t evdev_at_set1_scancodes[] = {
117           /* 0x00 - 0x1f */
118           NONE,               KEY_ESC,  KEY_1,              KEY_2,
119           KEY_3,              KEY_4,              KEY_5,              KEY_6,
120           KEY_7,              KEY_8,              KEY_9,              KEY_0,
121           KEY_MINUS,          KEY_EQUAL,          KEY_BACKSPACE,      KEY_TAB,
122           KEY_Q,              KEY_W,              KEY_E,              KEY_R,
123           KEY_T,              KEY_Y,              KEY_U,              KEY_I,
124           KEY_O,              KEY_P,              KEY_LEFTBRACE,      KEY_RIGHTBRACE,
125           KEY_ENTER,          KEY_LEFTCTRL,       KEY_A,              KEY_S,
126           /* 0x20 - 0x3f */
127           KEY_D,              KEY_F,              KEY_G,              KEY_H,
128           KEY_J,              KEY_K,              KEY_L,              KEY_SEMICOLON,
129           KEY_APOSTROPHE,     KEY_GRAVE,          KEY_LEFTSHIFT,      KEY_BACKSLASH,
130           KEY_Z,              KEY_X,              KEY_C,              KEY_V,
131           KEY_B,              KEY_N,              KEY_M,              KEY_COMMA,
132           KEY_DOT,  KEY_SLASH,          KEY_RIGHTSHIFT,     KEY_KPASTERISK,
133           KEY_LEFTALT,        KEY_SPACE,          KEY_CAPSLOCK,       KEY_F1,
134           KEY_F2,             KEY_F3,             KEY_F4,             KEY_F5,
135           /* 0x40 - 0x5f */
136           KEY_F6,             KEY_F7,             KEY_F8,             KEY_F9,
137           KEY_F10,  KEY_NUMLOCK,        KEY_SCROLLLOCK,     KEY_KP7,
138           KEY_KP8,  KEY_KP9,  KEY_KPMINUS,        KEY_KP4,
139           KEY_KP5,  KEY_KP6,  KEY_KPPLUS,         KEY_KP1,
140           KEY_KP2,  KEY_KP3,  KEY_KP0,  KEY_KPDOT,
141           NONE,               NONE,               KEY_102ND,          KEY_F11,
142           KEY_F12,  NONE,               NONE,               NONE,
143           NONE,               KEY_F13,  NONE,               NONE,
144           /* 0x60 - 0x7f */
145           NONE,               NONE,               NONE,               NONE,
146           NONE,               NONE,               NONE,               NONE,
147           NONE,               NONE,               NONE,               NONE,
148           NONE,               NONE,               NONE,               NONE,
149           KEY_KATAKANAHIRAGANA,         KEY_HANJA,          KEY_HANGEUL,        KEY_RO,
150           NONE,               NONE,     KEY_ZENKAKUHANKAKU, KEY_HIRAGANA,
151           KEY_KATAKANA,       KEY_HENKAN,         NONE,               KEY_MUHENKAN,
152           NONE,               KEY_YEN,  KEY_KPCOMMA,        NONE,
153           /* 0x00 - 0x1f. 0xE0 prefixed */
154           NONE,               NONE,               NONE,               NONE,
155           NONE,               NONE,               NONE,               NONE,
156           NONE,               NONE,               NONE,               NONE,
157           NONE,               NONE,               NONE,               NONE,
158           KEY_PREVIOUSSONG,   NONE,     NONE,               NONE,
159           NONE,               NONE,               NONE,               NONE,
160           NONE,               KEY_NEXTSONG,       NONE,               NONE,
161           KEY_KPENTER,        KEY_RIGHTCTRL,      NONE,               NONE,
162           /* 0x20 - 0x3f. 0xE0 prefixed */
163           KEY_MUTE, KEY_CALC, KEY_PLAYPAUSE,      NONE,
164           KEY_STOPCD,         NONE,               NONE,               NONE,
165           NONE,               NONE,               NONE,               NONE,
166           NONE,               NONE,               KEY_VOLUMEDOWN,     NONE,
167           KEY_VOLUMEUP,       NONE,               KEY_HOMEPAGE,       NONE,
168           NONE,               KEY_KPSLASH,        NONE,               KEY_SYSRQ,
169           KEY_RIGHTALT,       NONE,               NONE,               KEY_F13,
170           KEY_F14,  KEY_F15,  KEY_F16,  KEY_F17,
171           /* 0x40 - 0x5f. 0xE0 prefixed */
172           KEY_F18,  KEY_F19,  KEY_F20,  KEY_F21,
173           KEY_F22,  NONE,               KEY_PAUSE,          KEY_HOME,
174           KEY_UP,             KEY_PAGEUP,         NONE,               KEY_LEFT,
175           NONE,               KEY_RIGHT,          NONE,               KEY_END,
176           KEY_DOWN, KEY_PAGEDOWN,       KEY_INSERT,         KEY_DELETE,
177           NONE,               NONE,               NONE,               KEY_F23,
178           KEY_F24,  NONE,               NONE,               KEY_LEFTMETA,
179           KEY_RIGHTMETA,      KEY_MENU, KEY_POWER,          KEY_SLEEP,
180           /* 0x60 - 0x7f. 0xE0 prefixed */
181           NONE,               NONE,               NONE,               KEY_WAKEUP,
182           NONE,               KEY_SEARCH,         KEY_BOOKMARKS,      KEY_REFRESH,
183           KEY_STOP, KEY_FORWARD,        KEY_BACK, KEY_COMPUTER,
184           KEY_MAIL, KEY_MEDIA,          NONE,               NONE,
185           NONE,               NONE,               NONE,               NONE,
186           NONE,               NONE,               NONE,               NONE,
187           NONE,               NONE,               NONE,               NONE,
188           NONE,               NONE,               NONE,               NONE,
189 };
190 
191 static uint16_t evdev_mouse_button_codes[] = {
192           BTN_LEFT,
193           BTN_MIDDLE,
194           BTN_RIGHT,
195           BTN_SIDE,
196           BTN_EXTRA,
197           BTN_FORWARD,
198           BTN_BACK,
199           BTN_TASK,
200 };
201 
202 static uint16_t evdev_led_codes[] = {
203           LED_CAPSL,          /* CLKED */
204           LED_NUML, /* NLKED */
205           LED_SCROLLL,        /* SLKED */
206 };
207 
208 static uint16_t evdev_nfinger_codes[] = {
209           BTN_TOOL_FINGER,
210           BTN_TOOL_DOUBLETAP,
211           BTN_TOOL_TRIPLETAP,
212           BTN_TOOL_QUADTAP,
213           BTN_TOOL_QUINTTAP,
214 };
215 
216 uint16_t
evdev_hid2key(int scancode)217 evdev_hid2key(int scancode)
218 {
219           return evdev_usb_scancodes[scancode];
220 }
221 
222 void
evdev_support_all_known_keys(struct evdev_dev * evdev)223 evdev_support_all_known_keys(struct evdev_dev *evdev)
224 {
225           size_t i;
226 
227           for (i = KEY_RESERVED; i < nitems(evdev_at_set1_scancodes); i++)
228                     if (evdev_at_set1_scancodes[i] != NONE)
229                               evdev_support_key(evdev, evdev_at_set1_scancodes[i]);
230 }
231 
232 uint16_t
evdev_scancode2key(int * state,int scancode)233 evdev_scancode2key(int *state, int scancode)
234 {
235           uint16_t keycode;
236 
237           /* translate the scan code into a keycode */
238           keycode = evdev_at_set1_scancodes[scancode & 0x7f];
239           switch (*state) {
240           case 0x00:          /* normal scancode */
241                     switch(scancode) {
242                     case 0xE0:
243                     case 0xE1:
244                               *state = scancode;
245                               return (NONE);
246                     }
247                     break;
248           case 0xE0:                    /* 0xE0 prefix */
249                     *state = 0;
250                     keycode = evdev_at_set1_scancodes[0x80 + (scancode & 0x7f)];
251                     break;
252           case 0xE1:          /* 0xE1 prefix */
253                     /*
254                      * The pause/break key on the 101 keyboard produces:
255                      * E1-1D-45 E1-9D-C5
256                      * Ctrl-pause/break produces:
257                      * E0-46 E0-C6 (See above.)
258                      */
259                     *state = 0;
260                     if ((scancode & 0x7f) == 0x1D)
261                               *state = scancode;
262                     return (NONE);
263                     /* NOT REACHED */
264           case 0x1D:          /* pause / break */
265           case 0x9D:
266                     if ((*state ^ scancode) & 0x80)
267                               return (NONE);
268                     *state = 0;
269                     if ((scancode & 0x7f) != 0x45)
270                               return (NONE);
271                     keycode = KEY_PAUSE;
272                     break;
273           }
274 
275           return (keycode);
276 }
277 
278 void
evdev_push_mouse_btn(struct evdev_dev * evdev,int buttons)279 evdev_push_mouse_btn(struct evdev_dev *evdev, int buttons)
280 {
281           size_t i;
282 
283           for (i = 0; i < nitems(evdev_mouse_button_codes); i++)
284                     evdev_push_key(evdev, evdev_mouse_button_codes[i],
285                         buttons & (1 << i));
286 }
287 
288 void
evdev_push_leds(struct evdev_dev * evdev,int leds)289 evdev_push_leds(struct evdev_dev *evdev, int leds)
290 {
291           size_t i;
292 
293           /* Some drivers initialize leds before evdev */
294           if (evdev == NULL)
295                     return;
296 
297           for (i = 0; i < nitems(evdev_led_codes); i++)
298                     evdev_push_led(evdev, evdev_led_codes[i], leds & (1 << i));
299 }
300 
301 void
evdev_push_repeats(struct evdev_dev * evdev,keyboard_t * kbd)302 evdev_push_repeats(struct evdev_dev *evdev, keyboard_t *kbd)
303 {
304           /* Some drivers initialize typematics before evdev */
305           if (evdev == NULL)
306                     return;
307 
308           evdev_push_event(evdev, EV_REP, REP_DELAY, kbd->kb_delay1);
309           evdev_push_event(evdev, EV_REP, REP_PERIOD, kbd->kb_delay2);
310 }
311 
312 void
evdev_support_nfingers(struct evdev_dev * evdev,int nfingers)313 evdev_support_nfingers(struct evdev_dev *evdev, int nfingers)
314 {
315           int i;
316 
317           for (i = 0; i < MIN(nitems(evdev_nfinger_codes), nfingers); i++)
318                     evdev_support_key(evdev, evdev_nfinger_codes[i]);
319 }
320 
321 void
evdev_send_nfingers(struct evdev_dev * evdev,int nfingers)322 evdev_send_nfingers(struct evdev_dev *evdev, int nfingers)
323 {
324           int i;
325 
326           EVDEV_LOCK_ASSERT(evdev);
327 
328           if (nfingers > nitems(evdev_nfinger_codes))
329                     nfingers = nitems(evdev_nfinger_codes);
330 
331           for (i = 0; i < nitems(evdev_nfinger_codes); i++)
332                     evdev_send_event(evdev, EV_KEY, evdev_nfinger_codes[i],
333                               nfingers == i + 1);
334 }
335 
336 void
evdev_push_nfingers(struct evdev_dev * evdev,int nfingers)337 evdev_push_nfingers(struct evdev_dev *evdev, int nfingers)
338 {
339           EVDEV_ENTER(evdev);
340           evdev_send_nfingers(evdev, nfingers);
341           EVDEV_EXIT(evdev);
342 }
343 
344 void
evdev_ev_kbd_event(struct evdev_dev * evdev,uint16_t type,uint16_t code,int32_t value)345 evdev_ev_kbd_event(struct evdev_dev *evdev, uint16_t type,
346     uint16_t code, int32_t value)
347 {
348           keyboard_t *kbd = (keyboard_t *)evdev_get_softc(evdev);
349           int delay[2], leds, oleds;
350           size_t i;
351 
352           if (type == EV_LED) {
353                     leds = oleds = KBD_LED_VAL(kbd);
354                     for (i = 0; i < nitems(evdev_led_codes); i++) {
355                               if (evdev_led_codes[i] == code) {
356                                         if (value)
357                                                   leds |= 1 << i;
358                                         else
359                                                   leds &= ~(1 << i);
360                                         if (leds != oleds)
361                                                   kbd_ioctl(kbd, KDSETLED,
362                                                       (caddr_t)&leds);
363                                         break;
364                               }
365                     }
366           } else if (type == EV_REP && code == REP_DELAY) {
367                     delay[0] = value;
368                     delay[1] = kbd->kb_delay2;
369                     kbd_ioctl(kbd, KDSETREPEAT, (caddr_t)delay);
370           } else if (type == EV_REP && code == REP_PERIOD) {
371                     delay[0] = kbd->kb_delay1;
372                     delay[1] = value;
373                     kbd_ioctl(kbd, KDSETREPEAT, (caddr_t)delay);
374           }
375 }
376