]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/dev/evdev/evdev_utils.c
evdev: change USB scancode 0x54 from KEY_SLASH to KEY_KPSLASH
[FreeBSD/FreeBSD.git] / sys / dev / evdev / evdev_utils.c
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/lock.h>
36 #include <sys/malloc.h>
37 #include <sys/mutex.h>
38 #include <sys/systm.h>
39
40 #include <dev/evdev/evdev.h>
41 #include <dev/evdev/input.h>
42
43 #include <dev/kbd/kbdreg.h>
44
45 #define NONE    KEY_RESERVED
46
47 static uint16_t evdev_usb_scancodes[256] = {
48         /* 0x00 - 0x27 */
49         NONE,   NONE,   NONE,   NONE,   KEY_A,  KEY_B,  KEY_C,  KEY_D,
50         KEY_E,  KEY_F,  KEY_G,  KEY_H,  KEY_I,  KEY_J,  KEY_K,  KEY_L,
51         KEY_M,  KEY_N,  KEY_O,  KEY_P,  KEY_Q,  KEY_R,  KEY_S,  KEY_T,
52         KEY_U,  KEY_V,  KEY_W,  KEY_X,  KEY_Y,  KEY_Z,  KEY_1,  KEY_2,
53         KEY_3,  KEY_4,  KEY_5,  KEY_6,  KEY_7,  KEY_8,  KEY_9,  KEY_0,
54         /* 0x28 - 0x3f */
55         KEY_ENTER,      KEY_ESC,        KEY_BACKSPACE,  KEY_TAB,
56         KEY_SPACE,      KEY_MINUS,      KEY_EQUAL,      KEY_LEFTBRACE,
57         KEY_RIGHTBRACE, KEY_BACKSLASH,  KEY_BACKSLASH,  KEY_SEMICOLON,
58         KEY_APOSTROPHE, KEY_GRAVE,      KEY_COMMA,      KEY_DOT,
59         KEY_SLASH,      KEY_CAPSLOCK,   KEY_F1,         KEY_F2,
60         KEY_F3,         KEY_F4,         KEY_F5,         KEY_F6,
61         /* 0x40 - 0x5f */
62         KEY_F7,         KEY_F8,         KEY_F9,         KEY_F10,
63         KEY_F11,        KEY_F12,        KEY_SYSRQ,      KEY_SCROLLLOCK,
64         KEY_PAUSE,      KEY_INSERT,     KEY_HOME,       KEY_PAGEUP,
65         KEY_DELETE,     KEY_END,        KEY_PAGEDOWN,   KEY_RIGHT,
66         KEY_LEFT,       KEY_DOWN,       KEY_UP,         KEY_NUMLOCK,
67         KEY_KPSLASH,    KEY_KPASTERISK, KEY_KPMINUS,    KEY_KPPLUS,
68         KEY_KPENTER,    KEY_KP1,        KEY_KP2,        KEY_KP3,
69         KEY_KP4,        KEY_KP5,        KEY_KP6,        KEY_KP7,
70         /* 0x60 - 0x7f */
71         KEY_KP8,        KEY_KP9,        KEY_KP0,        KEY_KPDOT,
72         KEY_102ND,      KEY_COMPOSE,    KEY_POWER,      KEY_KPEQUAL,
73         KEY_F13,        KEY_F14,        KEY_F15,        KEY_F16,
74         KEY_F17,        KEY_F18,        KEY_F19,        KEY_F20,
75         KEY_F21,        KEY_F22,        KEY_F23,        KEY_F24,
76         KEY_OPEN,       KEY_HELP,       KEY_PROPS,      KEY_FRONT,
77         KEY_STOP,       KEY_AGAIN,      KEY_UNDO,       KEY_CUT,
78         KEY_COPY,       KEY_PASTE,      KEY_FIND,       KEY_MUTE,
79         /* 0x80 - 0x9f */
80         KEY_VOLUMEUP,   KEY_VOLUMEDOWN, NONE,           NONE,
81         NONE,           KEY_KPCOMMA,    NONE,           KEY_RO,
82         KEY_KATAKANAHIRAGANA,   KEY_YEN,KEY_HENKAN,     KEY_MUHENKAN,
83         KEY_KPJPCOMMA,  NONE,           NONE,           NONE,
84         KEY_HANGEUL,    KEY_HANJA,      KEY_KATAKANA,   KEY_HIRAGANA,
85         KEY_ZENKAKUHANKAKU,     NONE,   NONE,           NONE,
86         NONE,           NONE,           NONE,           NONE,
87         NONE,           NONE,           NONE,           NONE,
88         /* 0xa0 - 0xbf */
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         NONE,           NONE,           NONE,           NONE,
96         NONE,           NONE,           NONE,           NONE,
97         /* 0xc0 - 0xdf */
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         NONE,           NONE,           NONE,           NONE,
105         NONE,           NONE,           NONE,           NONE,
106         /* 0xe0 - 0xff */
107         KEY_LEFTCTRL,   KEY_LEFTSHIFT,  KEY_LEFTALT,    KEY_LEFTMETA,
108         KEY_RIGHTCTRL,  KEY_RIGHTSHIFT, KEY_RIGHTALT,   KEY_RIGHTMETA,
109         KEY_PLAYPAUSE,  KEY_STOPCD,     KEY_PREVIOUSSONG,KEY_NEXTSONG,
110         KEY_EJECTCD,    KEY_VOLUMEUP,   KEY_VOLUMEDOWN, KEY_MUTE,
111         KEY_WWW,        KEY_BACK,       KEY_FORWARD,    KEY_STOP,
112         KEY_FIND,       KEY_SCROLLUP,   KEY_SCROLLDOWN, KEY_EDIT,
113         KEY_SLEEP,      KEY_COFFEE,     KEY_REFRESH,    KEY_CALC,
114         NONE,           NONE,           NONE,           NONE,
115
116 };
117
118 static uint16_t evdev_at_set1_scancodes[] = {
119         /* 0x00 - 0x1f */
120         NONE,           KEY_ESC,        KEY_1,          KEY_2,
121         KEY_3,          KEY_4,          KEY_5,          KEY_6,
122         KEY_7,          KEY_8,          KEY_9,          KEY_0,
123         KEY_MINUS,      KEY_EQUAL,      KEY_BACKSPACE,  KEY_TAB,
124         KEY_Q,          KEY_W,          KEY_E,          KEY_R,
125         KEY_T,          KEY_Y,          KEY_U,          KEY_I,
126         KEY_O,          KEY_P,          KEY_LEFTBRACE,  KEY_RIGHTBRACE,
127         KEY_ENTER,      KEY_LEFTCTRL,   KEY_A,          KEY_S,
128         /* 0x20 - 0x3f */
129         KEY_D,          KEY_F,          KEY_G,          KEY_H,
130         KEY_J,          KEY_K,          KEY_L,          KEY_SEMICOLON,
131         KEY_APOSTROPHE, KEY_GRAVE,      KEY_LEFTSHIFT,  KEY_BACKSLASH,
132         KEY_Z,          KEY_X,          KEY_C,          KEY_V,
133         KEY_B,          KEY_N,          KEY_M,          KEY_COMMA,
134         KEY_DOT,        KEY_SLASH,      KEY_RIGHTSHIFT, KEY_KPASTERISK,
135         KEY_LEFTALT,    KEY_SPACE,      KEY_CAPSLOCK,   KEY_F1,
136         KEY_F2,         KEY_F3,         KEY_F4,         KEY_F5,
137         /* 0x40 - 0x5f */
138         KEY_F6,         KEY_F7,         KEY_F8,         KEY_F9,
139         KEY_F10,        KEY_NUMLOCK,    KEY_SCROLLLOCK, KEY_KP7,
140         KEY_KP8,        KEY_KP9,        KEY_KPMINUS,    KEY_KP4,
141         KEY_KP5,        KEY_KP6,        KEY_KPPLUS,     KEY_KP1,
142         KEY_KP2,        KEY_KP3,        KEY_KP0,        KEY_KPDOT,
143         NONE,           NONE,           KEY_102ND,      KEY_F11,
144         KEY_F12,        NONE,           NONE,           NONE,
145         NONE,           NONE,           NONE,           NONE,
146         /* 0x60 - 0x7f */
147         NONE,           NONE,           NONE,           NONE,
148         NONE,           NONE,           NONE,           NONE,
149         NONE,           NONE,           NONE,           NONE,
150         NONE,           NONE,           NONE,           NONE,
151         KEY_KATAKANAHIRAGANA,   NONE,   NONE,           KEY_RO,
152         NONE,           NONE,   KEY_ZENKAKUHANKAKU,     KEY_HIRAGANA,
153         KEY_KATAKANA,   KEY_HENKAN,     NONE,           KEY_MUHENKAN,
154         NONE,           KEY_YEN,        KEY_KPCOMMA,    NONE,
155         /* 0x00 - 0x1f. 0xE0 prefixed */
156         NONE,           NONE,           NONE,           NONE,
157         NONE,           NONE,           NONE,           NONE,
158         NONE,           NONE,           NONE,           NONE,
159         NONE,           NONE,           NONE,           NONE,
160         KEY_PREVIOUSSONG,       NONE,   NONE,           NONE,
161         NONE,           NONE,           NONE,           NONE,
162         NONE,           KEY_NEXTSONG,   NONE,           NONE,
163         KEY_KPENTER,    KEY_RIGHTCTRL,  NONE,           NONE,
164         /* 0x20 - 0x3f. 0xE0 prefixed */
165         KEY_MUTE,       KEY_CALC,       KEY_PLAYPAUSE,  NONE,
166         KEY_STOPCD,     NONE,           NONE,           NONE,
167         NONE,           NONE,           NONE,           NONE,
168         NONE,           NONE,           KEY_VOLUMEDOWN, NONE,
169         KEY_VOLUMEUP,   NONE,           KEY_HOMEPAGE,   NONE,
170         NONE,           KEY_KPSLASH,    NONE,           KEY_SYSRQ,
171         KEY_RIGHTALT,   NONE,           NONE,           NONE,
172         NONE,           NONE,           NONE,           NONE,
173         /* 0x40 - 0x5f. 0xE0 prefixed */
174         NONE,           NONE,           NONE,           NONE,
175         NONE,           NONE,           KEY_PAUSE,      KEY_HOME,
176         KEY_UP,         KEY_PAGEUP,     NONE,           KEY_LEFT,
177         NONE,           KEY_RIGHT,      NONE,           KEY_END,
178         KEY_DOWN,       KEY_PAGEDOWN,   KEY_INSERT,     KEY_DELETE,
179         NONE,           NONE,           NONE,           NONE,
180         NONE,           NONE,           NONE,           KEY_LEFTMETA,
181         KEY_RIGHTMETA,  KEY_MENU,       KEY_POWER,      KEY_SLEEP,
182         /* 0x60 - 0x7f. 0xE0 prefixed */
183         NONE,           NONE,           NONE,           KEY_WAKEUP,
184         NONE,           KEY_SEARCH,     KEY_BOOKMARKS,  KEY_REFRESH,
185         KEY_STOP,       KEY_FORWARD,    KEY_BACK,       KEY_COMPUTER,
186         KEY_MAIL,       KEY_MEDIA,      NONE,           NONE,
187         NONE,           NONE,           NONE,           NONE,
188         NONE,           NONE,           NONE,           NONE,
189         NONE,           NONE,           NONE,           NONE,
190         NONE,           NONE,           NONE,           NONE,
191 };
192
193 static uint16_t evdev_mouse_button_codes[] = {
194         BTN_LEFT,
195         BTN_MIDDLE,
196         BTN_RIGHT,
197         BTN_SIDE,
198         BTN_EXTRA,
199         BTN_FORWARD,
200         BTN_BACK,
201         BTN_TASK,
202 };
203
204 static uint16_t evdev_led_codes[] = {
205         LED_CAPSL,      /* CLKED */
206         LED_NUML,       /* NLKED */
207         LED_SCROLLL,    /* SLKED */
208 };
209
210 uint16_t
211 evdev_hid2key(int scancode)
212 {
213         return evdev_usb_scancodes[scancode];
214 }
215
216 void
217 evdev_support_all_known_keys(struct evdev_dev *evdev)
218 {
219         size_t i;
220
221         for (i = KEY_RESERVED; i < nitems(evdev_at_set1_scancodes); i++)
222                 if (evdev_at_set1_scancodes[i] != NONE)
223                         evdev_support_key(evdev, evdev_at_set1_scancodes[i]);
224 }
225
226 uint16_t
227 evdev_scancode2key(int *state, int scancode)
228 {
229         uint16_t keycode;
230
231         /* translate the scan code into a keycode */
232         keycode = evdev_at_set1_scancodes[scancode & 0x7f];
233         switch (*state) {
234         case 0x00:      /* normal scancode */
235                 switch(scancode) {
236                 case 0xE0:
237                 case 0xE1:
238                         *state = scancode;
239                         return (NONE);
240                 }
241                 break;
242         case 0xE0:              /* 0xE0 prefix */
243                 *state = 0;
244                 keycode = evdev_at_set1_scancodes[0x80 + (scancode & 0x7f)];
245                 break;
246         case 0xE1:      /* 0xE1 prefix */
247                 /*
248                  * The pause/break key on the 101 keyboard produces:
249                  * E1-1D-45 E1-9D-C5
250                  * Ctrl-pause/break produces:
251                  * E0-46 E0-C6 (See above.)
252                  */
253                 *state = 0;
254                 if ((scancode & 0x7f) == 0x1D)
255                         *state = 0x1D;
256                 return (NONE);
257                 /* NOT REACHED */
258         case 0x1D:      /* pause / break */
259                 *state = 0;
260                 if (scancode != 0x45)
261                         return (NONE);
262                 keycode = KEY_PAUSE;
263                 break;
264         }
265
266         return (keycode);
267 }
268
269 void
270 evdev_push_mouse_btn(struct evdev_dev *evdev, int buttons)
271 {
272         size_t i;
273
274         for (i = 0; i < nitems(evdev_mouse_button_codes); i++)
275                 evdev_push_key(evdev, evdev_mouse_button_codes[i],
276                     buttons & (1 << i));
277 }
278
279 void
280 evdev_push_leds(struct evdev_dev *evdev, int leds)
281 {
282         size_t i;
283
284         /* Some drivers initialize leds before evdev */
285         if (evdev == NULL)
286                 return;
287
288         for (i = 0; i < nitems(evdev_led_codes); i++)
289                 evdev_push_led(evdev, evdev_led_codes[i], leds & (1 << i));
290 }
291
292 void
293 evdev_push_repeats(struct evdev_dev *evdev, keyboard_t *kbd)
294 {
295         /* Some drivers initialize typematics before evdev */
296         if (evdev == NULL)
297                 return;
298
299         evdev_push_event(evdev, EV_REP, REP_DELAY, kbd->kb_delay1);
300         evdev_push_event(evdev, EV_REP, REP_PERIOD, kbd->kb_delay2);
301 }
302
303 void
304 evdev_ev_kbd_event(struct evdev_dev *evdev, void *softc, uint16_t type,
305     uint16_t code, int32_t value)
306 {
307         keyboard_t *kbd = (keyboard_t *)softc;
308         int delay[2], leds, oleds;
309         size_t i;
310
311         if (type == EV_LED) {
312                 leds = oleds = KBD_LED_VAL(kbd);
313                 for (i = 0; i < nitems(evdev_led_codes); i++) {
314                         if (evdev_led_codes[i] == code) {
315                                 if (value)
316                                         leds |= 1 << i;
317                                 else
318                                         leds &= ~(1 << i);
319                                 if (leds != oleds) {
320                                         mtx_lock(&Giant);
321                                         kbdd_ioctl(kbd, KDSETLED,
322                                             (caddr_t)&leds);
323                                         mtx_unlock(&Giant);
324                                 }
325                                 break;
326                         }
327                 }
328         } else if (type == EV_REP && code == REP_DELAY) {
329                 delay[0] = value;
330                 delay[1] = kbd->kb_delay2;
331                 mtx_lock(&Giant);
332                 kbdd_ioctl(kbd, KDSETREPEAT, (caddr_t)delay);
333                 mtx_unlock(&Giant);
334         } else if (type == EV_REP && code == REP_PERIOD) {
335                 delay[0] = kbd->kb_delay1;
336                 delay[1] = value;
337                 mtx_lock(&Giant);
338                 kbdd_ioctl(kbd, KDSETREPEAT, (caddr_t)delay);
339                 mtx_unlock(&Giant);
340         }
341 }