Subversion Repositories HelenOS

Rev

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

  1. /*
  2.  * Copyright (c) 2006 Jakub Jermar
  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 genarch
  30.  * @{
  31.  */
  32. /**
  33.  * @file
  34.  * @brief   Key processing.
  35.  */
  36.  
  37. #include <genarch/kbd/key.h>
  38. #include <genarch/kbd/scanc.h>
  39. #ifdef CONFIG_I8042
  40. #include <genarch/kbd/scanc_pc.h>
  41. #endif
  42.  
  43. #if (defined(sparc64))
  44. #include <genarch/kbd/scanc_sun.h>
  45. #endif
  46.  
  47. #include <synch/spinlock.h>
  48. #include <console/chardev.h>
  49. #include <macros.h>
  50.  
  51. #define PRESSED_SHIFT       (1<<0)
  52. #define PRESSED_CAPSLOCK    (1<<1)
  53. #define LOCKED_CAPSLOCK     (1<<0)
  54.  
  55. #define ACTIVE_READ_BUFF_SIZE 16    /* Must be power of 2 */
  56.  
  57. chardev_t kbrd;
  58.  
  59. static uint8_t active_read_buff[ACTIVE_READ_BUFF_SIZE];
  60.  
  61. SPINLOCK_INITIALIZE(keylock);       /**< keylock protects keyflags and lockflags. */
  62. static volatile int keyflags;       /**< Tracking of multiple keypresses. */
  63. static volatile int lockflags;      /**< Tracking of multiple keys lockings. */
  64.  
  65. /** Process release of key.
  66.  *
  67.  * @param sc Scancode of the key being released.
  68.  */
  69. void key_released(uint8_t sc)
  70. {
  71.     spinlock_lock(&keylock);
  72.     switch (sc) {
  73.     case SC_LSHIFT:
  74.     case SC_RSHIFT:
  75.         keyflags &= ~PRESSED_SHIFT;
  76.         break;
  77.     case SC_CAPSLOCK:
  78.         keyflags &= ~PRESSED_CAPSLOCK;
  79.         if (lockflags & LOCKED_CAPSLOCK)
  80.             lockflags &= ~LOCKED_CAPSLOCK;
  81.         else
  82.             lockflags |= LOCKED_CAPSLOCK;
  83.         break;
  84.     default:
  85.         break;
  86.     }
  87.     spinlock_unlock(&keylock);
  88. }
  89.  
  90. /** Process keypress.
  91.  *
  92.  * @param sc Scancode of the key being pressed.
  93.  */
  94. void key_pressed(uint8_t sc)
  95. {
  96.     char *map = sc_primary_map;
  97.     char ascii = sc_primary_map[sc];
  98.     bool shift, capslock;
  99.     bool letter = false;
  100.  
  101.     spinlock_lock(&keylock);
  102.     switch (sc) {
  103.     case SC_LSHIFT:
  104.     case SC_RSHIFT:
  105.             keyflags |= PRESSED_SHIFT;
  106.         break;
  107.     case SC_CAPSLOCK:
  108.         keyflags |= PRESSED_CAPSLOCK;
  109.         break;
  110.     case SC_SPEC_ESCAPE:
  111.         break;
  112.     case SC_LEFTARR:
  113.         chardev_push_character(&kbrd, 0x1b);
  114.         chardev_push_character(&kbrd, 0x5b);
  115.         chardev_push_character(&kbrd, 0x44);
  116.         break;
  117.     case SC_RIGHTARR:
  118.         chardev_push_character(&kbrd, 0x1b);
  119.         chardev_push_character(&kbrd, 0x5b);
  120.         chardev_push_character(&kbrd, 0x43);
  121.         break;
  122.     case SC_UPARR:
  123.         chardev_push_character(&kbrd, 0x1b);
  124.         chardev_push_character(&kbrd, 0x5b);
  125.         chardev_push_character(&kbrd, 0x41);
  126.         break;
  127.     case SC_DOWNARR:
  128.         chardev_push_character(&kbrd, 0x1b);
  129.         chardev_push_character(&kbrd, 0x5b);
  130.         chardev_push_character(&kbrd, 0x42);
  131.         break;
  132.     case SC_HOME:
  133.         chardev_push_character(&kbrd, 0x1b);
  134.         chardev_push_character(&kbrd, 0x4f);
  135.         chardev_push_character(&kbrd, 0x48);
  136.         break;
  137.     case SC_END:
  138.         chardev_push_character(&kbrd, 0x1b);
  139.         chardev_push_character(&kbrd, 0x4f);
  140.         chardev_push_character(&kbrd, 0x46);
  141.         break;
  142.     case SC_DELETE:
  143.         chardev_push_character(&kbrd, 0x1b);
  144.         chardev_push_character(&kbrd, 0x5b);
  145.         chardev_push_character(&kbrd, 0x33);
  146.         chardev_push_character(&kbrd, 0x7e);
  147.         break;
  148.     default:
  149.             letter = islower(ascii);
  150.         capslock = (keyflags & PRESSED_CAPSLOCK) ||
  151.             (lockflags & LOCKED_CAPSLOCK);
  152.         shift = keyflags & PRESSED_SHIFT;
  153.         if (letter && capslock)
  154.             shift = !shift;
  155.         if (shift)
  156.             map = sc_secondary_map;
  157.         chardev_push_character(&kbrd, map[sc]);
  158.         break;
  159.     }
  160.     spinlock_unlock(&keylock);
  161. }
  162.  
  163. uint8_t active_read_buff_read(void)
  164. {
  165.     static int i=0;
  166.     i &= (ACTIVE_READ_BUFF_SIZE-1);
  167.     if(!active_read_buff[i]) {
  168.         return 0;
  169.     }
  170.     return active_read_buff[i++];
  171. }
  172.  
  173. void active_read_buff_write(uint8_t ch)
  174. {
  175.     static int i=0;
  176.     active_read_buff[i] = ch;
  177.     i++;
  178.     i &= (ACTIVE_READ_BUFF_SIZE-1);
  179.     active_read_buff[i]=0;
  180. }
  181.  
  182.  
  183. void active_read_key_pressed(uint8_t sc)
  184. {
  185.     char *map = sc_primary_map;
  186.     char ascii = sc_primary_map[sc];
  187.     bool shift, capslock;
  188.     bool letter = false;
  189.  
  190.     /*spinlock_lock(&keylock);*/
  191.     switch (sc) {
  192.     case SC_LSHIFT:
  193.     case SC_RSHIFT:
  194.             keyflags |= PRESSED_SHIFT;
  195.         break;
  196.     case SC_CAPSLOCK:
  197.         keyflags |= PRESSED_CAPSLOCK;
  198.         break;
  199.     case SC_SPEC_ESCAPE:
  200.         break;
  201.     case SC_LEFTARR:
  202.         active_read_buff_write(0x1b);
  203.         active_read_buff_write(0x5b);
  204.         active_read_buff_write(0x44);
  205.         break;
  206.     case SC_RIGHTARR:
  207.         active_read_buff_write(0x1b);
  208.         active_read_buff_write(0x5b);
  209.         active_read_buff_write(0x43);
  210.         break;
  211.     case SC_UPARR:
  212.         active_read_buff_write(0x1b);
  213.         active_read_buff_write(0x5b);
  214.         active_read_buff_write(0x41);
  215.         break;
  216.     case SC_DOWNARR:
  217.         active_read_buff_write(0x1b);
  218.         active_read_buff_write(0x5b);
  219.         active_read_buff_write(0x42);
  220.         break;
  221.     case SC_HOME:
  222.         active_read_buff_write(0x1b);
  223.         active_read_buff_write(0x4f);
  224.         active_read_buff_write(0x48);
  225.         break;
  226.     case SC_END:
  227.         active_read_buff_write(0x1b);
  228.         active_read_buff_write(0x4f);
  229.         active_read_buff_write(0x46);
  230.         break;
  231.     case SC_DELETE:
  232.         active_read_buff_write(0x1b);
  233.         active_read_buff_write(0x5b);
  234.         active_read_buff_write(0x33);
  235.         active_read_buff_write(0x7e);
  236.         break;
  237.     default:
  238.             letter = islower(ascii);
  239.         capslock = (keyflags & PRESSED_CAPSLOCK) ||
  240.             (lockflags & LOCKED_CAPSLOCK);
  241.         shift = keyflags & PRESSED_SHIFT;
  242.         if (letter && capslock)
  243.             shift = !shift;
  244.         if (shift)
  245.             map = sc_secondary_map;
  246.         active_read_buff_write(map[sc]);
  247.         break;
  248.     }
  249.     /*spinlock_unlock(&keylock);*/
  250.  
  251. }
  252.  
  253. /** @}
  254.  */
  255.