Subversion Repositories HelenOS

Rev

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