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