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