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