The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/evdev/evdev_utils.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

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

Cache object: 3db62231a3a7a40e50c682349e289dd2


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.