xref: /dragonfly/sys/dev/misc/evdev/evdev_utils.c (revision a162a738)
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