Subversion Repositories HelenOS

Rev

Rev 3933 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. /*
  2.  * Copyright (c) 2009 Jiri Svoboda
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  *
  9.  * - Redistributions of source code must retain the above copyright
  10.  *   notice, this list of conditions and the following disclaimer.
  11.  * - 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.  * - The name of the author may not be used to endorse or promote products
  15.  *   derived from this software without specific prior written permission.
  16.  *
  17.  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  18.  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  19.  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  20.  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  21.  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  22.  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  23.  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  24.  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  25.  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  26.  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  27.  */
  28.  
  29. /** @addtogroup kbd_ctl
  30.  * @ingroup kbd
  31.  * @{
  32.  */
  33. /**
  34.  * @file
  35.  * @brief   Serial TTY-like keyboard controller driver.
  36.  */
  37.  
  38. #include <kbd.h>
  39. #include <kbd/kbd.h>
  40. #include <kbd/keycode.h>
  41. #include <kbd_ctl.h>
  42.  
  43. static void parse_ds_start(int scancode);
  44. static void parse_ds_e(int scancode);
  45. static void parse_ds_e1(int scancode);
  46. static void parse_ds_e2(int scancode);
  47. static void parse_ds_e2a(int scancode);
  48. static void parse_ds_e2b(int scancode);
  49.  
  50. static void parse_leaf(int scancode, int (*map)[2], size_t map_length);
  51.  
  52. enum dec_state {
  53.     ds_start,
  54.     ds_e,
  55.     ds_e1,
  56.     ds_e2,
  57.     ds_e2a,
  58.     ds_e2b
  59. };
  60.  
  61. static int map_start[][2] = {
  62.  
  63.     [0x60] = { 0, KC_BACKTICK },
  64.  
  65.     [0x31] = { 0, KC_1 },
  66.     [0x32] = { 0, KC_2 },
  67.     [0x33] = { 0, KC_3 },
  68.     [0x34] = { 0, KC_4 },
  69.     [0x35] = { 0, KC_5 },
  70.     [0x36] = { 0, KC_6 },
  71.     [0x37] = { 0, KC_7 },
  72.     [0x38] = { 0, KC_8 },
  73.     [0x39] = { 0, KC_9 },
  74.     [0x30] = { 0, KC_0 },
  75.  
  76.     [0x2d] = { 0, KC_MINUS },
  77.     [0x3d] = { 0, KC_EQUALS },
  78.     [0x08] = { 0, KC_BACKSPACE },
  79.  
  80.     [0x0f] = { 0, KC_TAB },
  81.  
  82.     [0x71] = { 0, KC_Q },
  83.     [0x77] = { 0, KC_W },
  84.     [0x65] = { 0, KC_E },
  85.     [0x72] = { 0, KC_R },
  86.     [0x74] = { 0, KC_T },
  87.     [0x79] = { 0, KC_Y },
  88.     [0x75] = { 0, KC_U },
  89.     [0x69] = { 0, KC_I },
  90.     [0x6f] = { 0, KC_O },
  91.     [0x70] = { 0, KC_P },
  92.  
  93.     [0x5b] = { 0, KC_LBRACKET },
  94.     [0x5d] = { 0, KC_RBRACKET },
  95.  
  96.     [0x61] = { 0, KC_A },
  97.     [0x73] = { 0, KC_S },
  98.     [0x64] = { 0, KC_D },
  99.     [0x66] = { 0, KC_F },
  100.     [0x67] = { 0, KC_G },
  101.     [0x68] = { 0, KC_H },
  102.     [0x6a] = { 0, KC_J },
  103.     [0x6b] = { 0, KC_K },
  104.     [0x6c] = { 0, KC_L },
  105.  
  106.     [0x3b] = { 0, KC_SEMICOLON },
  107.     [0x27] = { 0, KC_QUOTE },
  108.     [0x5c] = { 0, KC_BACKSLASH },
  109.  
  110.     [0x7a] = { 0, KC_Z },
  111.     [0x78] = { 0, KC_X },
  112.     [0x63] = { 0, KC_C },
  113.     [0x76] = { 0, KC_V },
  114.     [0x62] = { 0, KC_B },
  115.     [0x6e] = { 0, KC_N },
  116.     [0x6d] = { 0, KC_M },
  117.  
  118.     [0x2c] = { 0, KC_COMMA },
  119.     [0x2e] = { 0, KC_PERIOD },
  120.     [0x2f] = { 0, KC_SLASH },
  121.  
  122.     [0x20] = { 0, KC_SPACE },
  123.  
  124.     [0x1b] = { 0, KC_ESCAPE },
  125.  
  126.     [0x0a] = { 0, KC_ENTER },
  127.     [0x0d] = { 0, KC_ENTER },
  128.  
  129.     /* with Shift pressed */
  130.  
  131.     [0x7e] = { KM_LSHIFT, KC_BACKTICK },
  132.  
  133.     [0x21] = { KM_LSHIFT, KC_1 },
  134.     [0x40] = { KM_LSHIFT, KC_2 },
  135.     [0x23] = { KM_LSHIFT, KC_3 },
  136.     [0x24] = { KM_LSHIFT, KC_4 },
  137.     [0x25] = { KM_LSHIFT, KC_5 },
  138.     [0x5e] = { KM_LSHIFT, KC_6 },
  139.     [0x26] = { KM_LSHIFT, KC_7 },
  140.     [0x2a] = { KM_LSHIFT, KC_8 },
  141.     [0x28] = { KM_LSHIFT, KC_9 },
  142.     [0x29] = { KM_LSHIFT, KC_0 },
  143.  
  144.     [0x5f] = { KM_LSHIFT, KC_MINUS },
  145.     [0x2b] = { KM_LSHIFT, KC_EQUALS },
  146.  
  147.     [0x51] = { KM_LSHIFT, KC_Q },
  148.     [0x57] = { KM_LSHIFT, KC_W },
  149.     [0x45] = { KM_LSHIFT, KC_E },
  150.     [0x52] = { KM_LSHIFT, KC_R },
  151.     [0x54] = { KM_LSHIFT, KC_T },
  152.     [0x59] = { KM_LSHIFT, KC_Y },
  153.     [0x55] = { KM_LSHIFT, KC_U },
  154.     [0x49] = { KM_LSHIFT, KC_I },
  155.     [0x4f] = { KM_LSHIFT, KC_O },
  156.     [0x50] = { KM_LSHIFT, KC_P },
  157.  
  158.     [0x7b] = { KM_LSHIFT, KC_LBRACKET },
  159.     [0x7d] = { KM_LSHIFT, KC_RBRACKET },
  160.  
  161.     [0x41] = { KM_LSHIFT, KC_A },
  162.     [0x53] = { KM_LSHIFT, KC_S },
  163.     [0x44] = { KM_LSHIFT, KC_D },
  164.     [0x46] = { KM_LSHIFT, KC_F },
  165.     [0x47] = { KM_LSHIFT, KC_G },
  166.     [0x48] = { KM_LSHIFT, KC_H },
  167.     [0x4a] = { KM_LSHIFT, KC_J },
  168.     [0x4b] = { KM_LSHIFT, KC_K },
  169.     [0x4c] = { KM_LSHIFT, KC_L },
  170.  
  171.     [0x3a] = { KM_LSHIFT, KC_SEMICOLON },
  172.     [0x22] = { KM_LSHIFT, KC_QUOTE },
  173.     [0x7c] = { KM_LSHIFT, KC_BACKSLASH },
  174.  
  175.     [0x5a] = { KM_LSHIFT, KC_Z },
  176.     [0x58] = { KM_LSHIFT, KC_X },
  177.     [0x43] = { KM_LSHIFT, KC_C },
  178.     [0x56] = { KM_LSHIFT, KC_V },
  179.     [0x42] = { KM_LSHIFT, KC_B },
  180.     [0x4e] = { KM_LSHIFT, KC_N },
  181.     [0x4d] = { KM_LSHIFT, KC_M },
  182.  
  183.     [0x3c] = { KM_LSHIFT, KC_COMMA },
  184.     [0x3e] = { KM_LSHIFT, KC_PERIOD },
  185.     [0x3f] = { KM_LSHIFT, KC_SLASH }
  186. };
  187.  
  188. static int map_e1[][2] =
  189. {
  190.     [0x50] = { 0, KC_F1 },
  191.     [0x51] = { 0, KC_F2 },
  192.     [0x52] = { 0, KC_F3 },
  193.     [0x53] = { 0, KC_F4 },
  194. };
  195.  
  196. static int map_e2[][2] =
  197. {
  198.     [0x41] = { 0, KC_UP },
  199.     [0x42] = { 0, KC_DOWN },
  200.     [0x44] = { 0, KC_LEFT },
  201.     [0x43] = { 0, KC_RIGHT },
  202. };
  203.  
  204. static int map_e2a[][2] =
  205. {
  206.     [0x35] = { 0, KC_F5 },
  207.     [0x37] = { 0, KC_F6 },
  208.     [0x38] = { 0, KC_F7 },
  209.     [0x39] = { 0, KC_F8 },
  210. };
  211.  
  212. static int map_e2b[][2] =
  213. {
  214.     [0x30] = { 0, KC_F9 },
  215.     [0x31] = { 0, KC_F10 },
  216.     [0x32] = { 0, KC_F11 },
  217.     [0x33] = { 0, KC_F12 },
  218. };
  219.  
  220. static unsigned int mods_keys[][2] = {
  221.     { KM_LSHIFT, KC_LSHIFT },
  222.     { 0, 0 }
  223. };
  224.  
  225. static enum dec_state ds;
  226.  
  227. void kbd_ctl_parse_scancode(int scancode)
  228. {
  229.     switch (ds) {
  230.     case ds_start:  parse_ds_start(scancode); break;
  231.     case ds_e:  parse_ds_e(scancode); break;
  232.     case ds_e1: parse_ds_e1(scancode); break;
  233.     case ds_e2: parse_ds_e2(scancode); break;
  234.     case ds_e2a:    parse_ds_e2a(scancode); break;
  235.     case ds_e2b:    parse_ds_e2b(scancode); break;
  236.     }
  237. }
  238.  
  239. static void parse_ds_start(int scancode)
  240. {
  241.     if (scancode == 0x1b) {
  242.         ds = ds_e;
  243.         return;
  244.     }
  245.  
  246.     parse_leaf(scancode, map_start, sizeof(map_start) / (2 * sizeof(int)));
  247. }
  248.  
  249. static void parse_ds_e(int scancode)
  250. {
  251.     if (scancode < 0 || scancode >= 0x80) return;
  252.  
  253.     switch (scancode) {
  254.     case 0x4f: ds = ds_e1; return;
  255.     case 0x5b: ds = ds_e2; return;
  256.     case 0x1b: ds = ds_start; break;
  257.     default: ds = ds_start; return;
  258.     }
  259.  
  260.     kbd_push_ev(KE_PRESS, KC_ESCAPE);
  261. }
  262.  
  263. static void parse_ds_e1(int scancode)
  264. {
  265.     parse_leaf(scancode, map_e1, sizeof(map_e1) / (2 * sizeof(int)));
  266. }
  267.  
  268. static void parse_ds_e2(int scancode)
  269. {
  270.     switch (scancode) {
  271.     case 0x31: ds = ds_e2a; break;
  272.     case 0x32: ds = ds_e2b; break;
  273.     default: ds = ds_start; break;
  274.     }
  275.  
  276.     parse_leaf(scancode, map_e2, sizeof(map_e2) / (2 * sizeof(int)));
  277. }
  278.  
  279. static void parse_ds_e2a(int scancode)
  280. {
  281.     parse_leaf(scancode, map_e2a, sizeof(map_e2a) / (2 * sizeof(int)));
  282. }
  283.  
  284. static void parse_ds_e2b(int scancode)
  285. {
  286.     parse_leaf(scancode, map_e2b, sizeof(map_e2b) / (2 * sizeof(int)));
  287. }
  288.  
  289. static void parse_leaf(int scancode, int (*map)[2], size_t map_length)
  290. {
  291.     unsigned int key, mod;
  292.     int i;
  293.  
  294.     ds = ds_start;
  295.  
  296.     if (scancode < 0 || scancode >= map_length)
  297.         return;
  298.  
  299.     mod = map[scancode][0];
  300.     key = map[scancode][1];
  301.  
  302.     /* Simulate modifier pressing. */
  303.     i = 0;
  304.     while (mods_keys[i][0] != 0) {
  305.         if (mod & mods_keys[i][0]) {
  306.             kbd_push_ev(KE_PRESS, mods_keys[i][1]);
  307.         }
  308.         ++i;
  309.     }
  310.  
  311.     if (key != 0) {
  312.         kbd_push_ev(KE_PRESS, key);
  313.         kbd_push_ev(KE_RELEASE, key);
  314.     }
  315.  
  316.     /* Simulate modifier releasing. */
  317.     i = 0;
  318.     while (mods_keys[i][0] != 0) {
  319.         if (mod & mods_keys[i][0]) {
  320.             kbd_push_ev(KE_RELEASE, mods_keys[i][1]);
  321.         }
  322.         ++i;
  323.     }
  324. }
  325.  
  326.  
  327. /**
  328.  * @}
  329.  */
  330.