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