]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/dev/evdev/evdev_utils.c
Create files.x86
[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 #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,           NONE,           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,   NONE,   NONE,           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,           NONE,
170         NONE,           NONE,           NONE,           NONE,
171         /* 0x40 - 0x5f. 0xE0 prefixed */
172         NONE,           NONE,           NONE,           NONE,
173         NONE,           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,           NONE,
178         NONE,           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 uint16_t
209 evdev_hid2key(int scancode)
210 {
211         return evdev_usb_scancodes[scancode];
212 }
213
214 void
215 evdev_support_all_known_keys(struct evdev_dev *evdev)
216 {
217         size_t i;
218
219         for (i = KEY_RESERVED; i < nitems(evdev_at_set1_scancodes); i++)
220                 if (evdev_at_set1_scancodes[i] != NONE)
221                         evdev_support_key(evdev, evdev_at_set1_scancodes[i]);
222 }
223
224 uint16_t
225 evdev_scancode2key(int *state, int scancode)
226 {
227         uint16_t keycode;
228
229         /* translate the scan code into a keycode */
230         keycode = evdev_at_set1_scancodes[scancode & 0x7f];
231         switch (*state) {
232         case 0x00:      /* normal scancode */
233                 switch(scancode) {
234                 case 0xE0:
235                 case 0xE1:
236                         *state = scancode;
237                         return (NONE);
238                 }
239                 break;
240         case 0xE0:              /* 0xE0 prefix */
241                 *state = 0;
242                 keycode = evdev_at_set1_scancodes[0x80 + (scancode & 0x7f)];
243                 break;
244         case 0xE1:      /* 0xE1 prefix */
245                 /*
246                  * The pause/break key on the 101 keyboard produces:
247                  * E1-1D-45 E1-9D-C5
248                  * Ctrl-pause/break produces:
249                  * E0-46 E0-C6 (See above.)
250                  */
251                 *state = 0;
252                 if ((scancode & 0x7f) == 0x1D)
253                         *state = scancode;
254                 return (NONE);
255                 /* NOT REACHED */
256         case 0x1D:      /* pause / break */
257         case 0x9D:
258                 if ((*state ^ scancode) & 0x80)
259                         return (NONE);
260                 *state = 0;
261                 if ((scancode & 0x7f) != 0x45)
262                         return (NONE);
263                 keycode = KEY_PAUSE;
264                 break;
265         }
266
267         return (keycode);
268 }
269
270 void
271 evdev_push_mouse_btn(struct evdev_dev *evdev, int buttons)
272 {
273         size_t i;
274
275         for (i = 0; i < nitems(evdev_mouse_button_codes); i++)
276                 evdev_push_key(evdev, evdev_mouse_button_codes[i],
277                     buttons & (1 << i));
278 }
279
280 void
281 evdev_push_leds(struct evdev_dev *evdev, int leds)
282 {
283         size_t i;
284
285         /* Some drivers initialize leds before evdev */
286         if (evdev == NULL)
287                 return;
288
289         for (i = 0; i < nitems(evdev_led_codes); i++)
290                 evdev_push_led(evdev, evdev_led_codes[i], leds & (1 << i));
291 }
292
293 void
294 evdev_push_repeats(struct evdev_dev *evdev, keyboard_t *kbd)
295 {
296         /* Some drivers initialize typematics before evdev */
297         if (evdev == NULL)
298                 return;
299
300         evdev_push_event(evdev, EV_REP, REP_DELAY, kbd->kb_delay1);
301         evdev_push_event(evdev, EV_REP, REP_PERIOD, kbd->kb_delay2);
302 }