Subversion Repositories HelenOS

Rev

Rev 2337 | Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. /*
  2.  * Copyright (c) 2007 Michal Kebrt
  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 kbdarm32gxemul GXemul
  30.  * @brief   HelenOS arm32 GXEmul uspace keyboard handler.
  31.  * @ingroup  kbdarm32
  32.  * @{
  33.  */
  34. /** @file
  35.  *  @brief GXemul uspace keyboard handler.
  36.  */
  37.  
  38. #include <ipc/ipc.h>
  39. #include <sysinfo.h>
  40. #include <kbd.h>
  41. #include <keys.h>
  42.  
  43. #define GXEMUL_KEY_F1  0x504f1bL
  44. #define GXEMUL_KEY_F2  0x514f1bL
  45. #define GXEMUL_KEY_F3  0x524f1bL
  46. #define GXEMUL_KEY_F4  0x534f1bL
  47. #define GXEMUL_KEY_F5  0x35315b1bL
  48. #define GXEMUL_KEY_F6  0x37315b1bL
  49. #define GXEMUL_KEY_F7  0x38315b1bL
  50. #define GXEMUL_KEY_F8  0x39315b1bL
  51. #define GXEMUL_KEY_F9  0x30325b1bL
  52. #define GXEMUL_KEY_F10 0x31325b1bL
  53. #define GXEMUL_KEY_F11 0x33325d1bL
  54. #define GXEMUL_KEY_F12 0x34325b1bL
  55.  
  56. /** Function keys start code (F1=0x101) */
  57. #define FUNCTION_KEYS 0x100
  58.  
  59. irq_cmd_t gxemul_cmds[] = {
  60.     {
  61.         CMD_MEM_READ_1,
  62.         (void *) 0,
  63.         0,
  64.         2
  65.     }
  66. };
  67.  
  68. irq_code_t gxemul_kbd = {
  69.     1,
  70.     gxemul_cmds
  71. };
  72.  
  73.  
  74. /*
  75. // Please preserve this code (it can be used to determine scancodes)
  76. int to_hex(int v)
  77. {
  78.         return "0123456789ABCDEF"[v];
  79. }
  80. */
  81.  
  82.  
  83. /** Process data sent when a key is pressed.
  84.  *  
  85.  *  @param keybuffer Buffer of scan codes.
  86.  *  @param scan_code Scan code.
  87.  *
  88.  *  @return Code of the pressed key.
  89.  */
  90. static int gxemul_process_no_fb(keybuffer_t *keybuffer, int scan_code)
  91. {
  92.  
  93.     static unsigned long buf = 0;
  94.     static int count = 0;  
  95.  
  96.     /* Preserve for detecting scan codes.
  97.     keybuffer_push(keybuffer, to_hex((scan_code>>4)&0xf));
  98.     keybuffer_push(keybuffer, to_hex(scan_code&0xf));
  99.     keybuffer_push(keybuffer, 'X');
  100.     keybuffer_push(keybuffer, 'Y');
  101.     return 1;
  102.     */
  103.  
  104.     if (scan_code == '\r')
  105.         scan_code = '\n';
  106.  
  107.     if(scan_code == 0x7e) {
  108.         switch (buf) {
  109.         case GXEMUL_KEY_F5:
  110.             keybuffer_push(keybuffer,FUNCTION_KEYS | 5);
  111.             buf = count = 0;
  112.             return 1;
  113.         case GXEMUL_KEY_F6:
  114.             keybuffer_push(keybuffer,FUNCTION_KEYS | 6);
  115.             buf = count = 0;
  116.             return 1;
  117.         case GXEMUL_KEY_F7:
  118.             keybuffer_push(keybuffer,FUNCTION_KEYS | 7);
  119.             buf = count = 0;
  120.             return 1;
  121.         case GXEMUL_KEY_F8:
  122.             keybuffer_push(keybuffer,FUNCTION_KEYS | 8);
  123.             buf = count = 0;
  124.             return 1;
  125.         case GXEMUL_KEY_F9:
  126.             keybuffer_push(keybuffer,FUNCTION_KEYS | 9);
  127.             buf = count = 0;
  128.             return 1;
  129.         case GXEMUL_KEY_F10:
  130.             keybuffer_push(keybuffer,FUNCTION_KEYS | 10);
  131.             buf = count = 0;
  132.             return 1;
  133.         case GXEMUL_KEY_F11:
  134.             keybuffer_push(keybuffer,FUNCTION_KEYS | 11);
  135.             buf = count = 0;
  136.             return 1;
  137.         case GXEMUL_KEY_F12:
  138.             keybuffer_push(keybuffer,FUNCTION_KEYS | 12);
  139.             buf = count = 0;
  140.             return 1;
  141.         default:
  142.             keybuffer_push(keybuffer, buf & 0xff);
  143.             keybuffer_push(keybuffer, (buf >> 8) &0xff);
  144.             keybuffer_push(keybuffer, (buf >> 16) &0xff);
  145.             keybuffer_push(keybuffer, (buf >> 24) &0xff);
  146.             keybuffer_push(keybuffer, scan_code);
  147.             buf = count = 0;
  148.             return 1;
  149.         }
  150.     }
  151.  
  152.     buf |= ((unsigned long) scan_code)<<(8*(count++));
  153.    
  154.     if((buf & 0xff) != (GXEMUL_KEY_F1 & 0xff)) {
  155.         keybuffer_push(keybuffer, buf);
  156.         buf = count = 0;
  157.         return 1;
  158.     }
  159.  
  160.     if (count <= 1)
  161.         return 1;
  162.  
  163.     if ((buf & 0xffff) != (GXEMUL_KEY_F1 & 0xffff)
  164.         && (buf & 0xffff) != (GXEMUL_KEY_F5 & 0xffff) ) {
  165.  
  166.         keybuffer_push(keybuffer, buf & 0xff);
  167.         keybuffer_push(keybuffer, (buf >> 8) &0xff);
  168.         buf = count = 0;
  169.         return 1;
  170.     }
  171.  
  172.     if (count <= 2)
  173.         return 1;
  174.  
  175.     switch (buf) {
  176.     case GXEMUL_KEY_F1:
  177.         keybuffer_push(keybuffer,FUNCTION_KEYS | 1);
  178.         buf = count = 0;
  179.         return 1;
  180.     case GXEMUL_KEY_F2:
  181.         keybuffer_push(keybuffer,FUNCTION_KEYS | 2);
  182.         buf = count = 0;
  183.         return 1;
  184.     case GXEMUL_KEY_F3:
  185.         keybuffer_push(keybuffer,FUNCTION_KEYS | 3);
  186.         buf = count = 0;
  187.         return 1;
  188.     case GXEMUL_KEY_F4:
  189.         keybuffer_push(keybuffer,FUNCTION_KEYS | 4);
  190.         buf = count = 0;
  191.         return 1;
  192.     }
  193.  
  194.  
  195.     if((buf & 0xffffff) != (GXEMUL_KEY_F5 & 0xffffff)
  196.         && (buf & 0xffffff) != (GXEMUL_KEY_F9 & 0xffffff)) {
  197.  
  198.         keybuffer_push(keybuffer, buf & 0xff);
  199.         keybuffer_push(keybuffer, (buf >> 8) & 0xff);
  200.         keybuffer_push(keybuffer, (buf >> 16) & 0xff);
  201.         buf=count=0;
  202.         return 1;
  203.     }
  204.  
  205.     if (count <= 3)
  206.         return 1;
  207.    
  208.     switch (buf) {
  209.     case GXEMUL_KEY_F5:
  210.     case GXEMUL_KEY_F6:
  211.     case GXEMUL_KEY_F7:
  212.     case GXEMUL_KEY_F8:
  213.     case GXEMUL_KEY_F9:
  214.     case GXEMUL_KEY_F10:
  215.     case GXEMUL_KEY_F11:
  216.     case GXEMUL_KEY_F12:
  217.         return 1;
  218.     default:
  219.         keybuffer_push(keybuffer, buf & 0xff);
  220.         keybuffer_push(keybuffer, (buf >> 8) &0xff);
  221.         keybuffer_push(keybuffer, (buf >> 16) &0xff);
  222.         keybuffer_push(keybuffer, (buf >> 24) &0xff);
  223.         buf = count = 0;
  224.         return 1;
  225.     }
  226.     return 1;
  227. }
  228.  
  229.  
  230. /** Initializes keyboard handler. */
  231. int kbd_arch_init(void)
  232. {
  233.     gxemul_cmds[0].addr = (void *) sysinfo_value("kbd.address.virtual");
  234.     ipc_register_irq(sysinfo_value("kbd.inr"), sysinfo_value("kbd.devno"), 0, &gxemul_kbd);
  235.     return 0;
  236. }
  237.  
  238.  
  239. /** Process data sent when a key is pressed.
  240.  *  
  241.  *  @param keybuffer Buffer of scan codes.
  242.  *  @param call      IPC call.
  243.  *
  244.  *  @return Code of the pressed key.
  245.  */
  246. int kbd_arch_process(keybuffer_t *keybuffer, ipc_call_t *call)
  247. {
  248.     int scan_code = IPC_GET_ARG2(*call);
  249.     static int esc_count = 0;
  250.  
  251.     if (scan_code == 0x1b) {
  252.         esc_count++;
  253.         if (esc_count == 3) {
  254.             __SYSCALL0(SYS_DEBUG_ENABLE_CONSOLE);
  255.         }
  256.     } else {
  257.         esc_count = 0;
  258.     }
  259.  
  260.     return gxemul_process_no_fb(keybuffer, scan_code);
  261. }
  262.  
  263. /** @}
  264.  */
  265.