Subversion Repositories HelenOS

Rev

Rev 2350 | Rev 2409 | Go to most recent revision | Blame | Compare with Previous | 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. #include <bool.h>
  43.  
  44.  
  45. #define GXEMUL_KEY_F1  0x504f1bL
  46. #define GXEMUL_KEY_F2  0x514f1bL
  47. #define GXEMUL_KEY_F3  0x524f1bL
  48. #define GXEMUL_KEY_F4  0x534f1bL
  49. #define GXEMUL_KEY_F5  0x35315b1bL
  50. #define GXEMUL_KEY_F6  0x37315b1bL
  51. #define GXEMUL_KEY_F7  0x38315b1bL
  52. #define GXEMUL_KEY_F8  0x39315b1bL
  53. #define GXEMUL_KEY_F9  0x30325b1bL
  54. #define GXEMUL_KEY_F10 0x31325b1bL
  55. #define GXEMUL_KEY_F11 0x33325d1bL
  56. #define GXEMUL_KEY_F12 0x34325b1bL
  57.  
  58.  
  59. #define GXEMUL_FB_KEY_F1 0x504f5b1bL
  60. #define GXEMUL_FB_KEY_F2 0x514f5b1bL
  61. #define GXEMUL_FB_KEY_F3 0x524f5b1bL
  62. #define GXEMUL_FB_KEY_F4 0x534f5b1bL
  63. #define GXEMUL_FB_KEY_F5 0x35315b1bL
  64. #define GXEMUL_FB_KEY_F6 0x37315b1bL
  65. #define GXEMUL_FB_KEY_F7 0x38315b1bL
  66. #define GXEMUL_FB_KEY_F8 0x39315b1bL
  67. #define GXEMUL_FB_KEY_F9 0x38325b1bL
  68. #define GXEMUL_FB_KEY_F10 0x39325b1bL
  69. #define GXEMUL_FB_KEY_F11 0x33325b1bL
  70. #define GXEMUL_FB_KEY_F12 0x34325b1bL
  71.  
  72.  
  73. /** Function keys start code (F1=0x101) */
  74. #define FUNCTION_KEYS 0x100
  75.  
  76. static irq_cmd_t gxemul_cmds[] = {
  77.     {
  78.         CMD_MEM_READ_1,
  79.         (void *) 0,
  80.         0,
  81.         2
  82.     }
  83. };
  84.  
  85. static irq_code_t gxemul_kbd = {
  86.     1,
  87.     gxemul_cmds
  88. };
  89.  
  90.  
  91. /** Framebuffer switched on. */
  92. static bool fb;
  93.  
  94.  
  95. /*
  96. // Please preserve this code (it can be used to determine scancodes)
  97. int to_hex(int v)
  98. {
  99.         return "0123456789ABCDEF"[v];
  100. }
  101. */
  102.  
  103.  
  104. /** Process data sent when a key is pressed (in no-framebuffer mode).
  105.  *  
  106.  *  @param keybuffer Buffer of scan codes.
  107.  *  @param scan_code Scan code.
  108.  *
  109.  *  @return Code of the pressed key.
  110.  */
  111. static int gxemul_process_no_fb(keybuffer_t *keybuffer, int scan_code)
  112. {
  113.  
  114.     static unsigned long buf = 0;
  115.     static int count = 0;  
  116.  
  117.     // Preserve for detecting scan codes.
  118.     // keybuffer_push(keybuffer, to_hex((scan_code>>4)&0xf));
  119.     // keybuffer_push(keybuffer, to_hex(scan_code&0xf));
  120.     // keybuffer_push(keybuffer, 'X');
  121.     // keybuffer_push(keybuffer, 'Y');
  122.     // return 1;
  123.  
  124.     if (scan_code == '\r')
  125.         scan_code = '\n';
  126.  
  127.     if(scan_code == 0x7e) {
  128.         switch (buf) {
  129.         case GXEMUL_KEY_F5:
  130.             keybuffer_push(keybuffer,FUNCTION_KEYS | 5);
  131.             buf = count = 0;
  132.             return 1;
  133.         case GXEMUL_KEY_F6:
  134.             keybuffer_push(keybuffer,FUNCTION_KEYS | 6);
  135.             buf = count = 0;
  136.             return 1;
  137.         case GXEMUL_KEY_F7:
  138.             keybuffer_push(keybuffer,FUNCTION_KEYS | 7);
  139.             buf = count = 0;
  140.             return 1;
  141.         case GXEMUL_KEY_F8:
  142.             keybuffer_push(keybuffer,FUNCTION_KEYS | 8);
  143.             buf = count = 0;
  144.             return 1;
  145.         case GXEMUL_KEY_F9:
  146.             keybuffer_push(keybuffer,FUNCTION_KEYS | 9);
  147.             buf = count = 0;
  148.             return 1;
  149.         case GXEMUL_KEY_F10:
  150.             keybuffer_push(keybuffer,FUNCTION_KEYS | 10);
  151.             buf = count = 0;
  152.             return 1;
  153.         case GXEMUL_KEY_F11:
  154.             keybuffer_push(keybuffer,FUNCTION_KEYS | 11);
  155.             buf = count = 0;
  156.             return 1;
  157.         case GXEMUL_KEY_F12:
  158.             keybuffer_push(keybuffer,FUNCTION_KEYS | 12);
  159.             buf = count = 0;
  160.             return 1;
  161.         default:
  162.             keybuffer_push(keybuffer, buf & 0xff);
  163.             keybuffer_push(keybuffer, (buf >> 8) &0xff);
  164.             keybuffer_push(keybuffer, (buf >> 16) &0xff);
  165.             keybuffer_push(keybuffer, (buf >> 24) &0xff);
  166.             keybuffer_push(keybuffer, scan_code);
  167.             buf = count = 0;
  168.             return 1;
  169.         }
  170.     }
  171.  
  172.     buf |= ((unsigned long) scan_code)<<(8*(count++));
  173.    
  174.     if((buf & 0xff) != (GXEMUL_KEY_F1 & 0xff)) {
  175.         keybuffer_push(keybuffer, buf);
  176.         buf = count = 0;
  177.         return 1;
  178.     }
  179.  
  180.     if (count <= 1)
  181.         return 1;
  182.  
  183.     if ((buf & 0xffff) != (GXEMUL_KEY_F1 & 0xffff)
  184.         && (buf & 0xffff) != (GXEMUL_KEY_F5 & 0xffff) ) {
  185.  
  186.         keybuffer_push(keybuffer, buf & 0xff);
  187.         keybuffer_push(keybuffer, (buf >> 8) &0xff);
  188.         buf = count = 0;
  189.         return 1;
  190.     }
  191.  
  192.     if (count <= 2)
  193.         return 1;
  194.  
  195.     switch (buf) {
  196.     case GXEMUL_KEY_F1:
  197.         keybuffer_push(keybuffer,FUNCTION_KEYS | 1);
  198.         buf = count = 0;
  199.         return 1;
  200.     case GXEMUL_KEY_F2:
  201.         keybuffer_push(keybuffer,FUNCTION_KEYS | 2);
  202.         buf = count = 0;
  203.         return 1;
  204.     case GXEMUL_KEY_F3:
  205.         keybuffer_push(keybuffer,FUNCTION_KEYS | 3);
  206.         buf = count = 0;
  207.         return 1;
  208.     case GXEMUL_KEY_F4:
  209.         keybuffer_push(keybuffer,FUNCTION_KEYS | 4);
  210.         buf = count = 0;
  211.         return 1;
  212.     }
  213.  
  214.  
  215.     if((buf & 0xffffff) != (GXEMUL_KEY_F5 & 0xffffff)
  216.         && (buf & 0xffffff) != (GXEMUL_KEY_F9 & 0xffffff)) {
  217.  
  218.         keybuffer_push(keybuffer, buf & 0xff);
  219.         keybuffer_push(keybuffer, (buf >> 8) & 0xff);
  220.         keybuffer_push(keybuffer, (buf >> 16) & 0xff);
  221.         buf=count=0;
  222.         return 1;
  223.     }
  224.  
  225.     if (count <= 3)
  226.         return 1;
  227.    
  228.     switch (buf) {
  229.     case GXEMUL_KEY_F5:
  230.     case GXEMUL_KEY_F6:
  231.     case GXEMUL_KEY_F7:
  232.     case GXEMUL_KEY_F8:
  233.     case GXEMUL_KEY_F9:
  234.     case GXEMUL_KEY_F10:
  235.     case GXEMUL_KEY_F11:
  236.     case GXEMUL_KEY_F12:
  237.         return 1;
  238.     default:
  239.         keybuffer_push(keybuffer, buf & 0xff);
  240.         keybuffer_push(keybuffer, (buf >> 8) &0xff);
  241.         keybuffer_push(keybuffer, (buf >> 16) &0xff);
  242.         keybuffer_push(keybuffer, (buf >> 24) &0xff);
  243.         buf = count = 0;
  244.         return 1;
  245.     }
  246.     return 1;
  247. }
  248.  
  249.  
  250. /** Process data sent when a key is pressed (in framebuffer mode).
  251.  *  
  252.  *  @param keybuffer Buffer of scan codes.
  253.  *  @param scan_code Scan code.
  254.  *
  255.  *  @return Code of the pressed key.
  256.  */
  257. static int gxemul_process_fb(keybuffer_t *keybuffer, int scan_code)
  258. {
  259.     static unsigned long buf = 0;
  260.     static int count = 0;
  261.  
  262.     /* Please preserve this code (it can be used to determine scancodes)
  263.    
  264.     keybuffer_push(keybuffer, to_hex((scan_code>>4)&0xf));
  265.     keybuffer_push(keybuffer, to_hex(scan_code&0xf));
  266.     keybuffer_push(keybuffer, ' ');
  267.     keybuffer_push(keybuffer, ' ');
  268.    
  269.     return 1;
  270.     */
  271.    
  272.     if (scan_code == '\r')
  273.         scan_code = '\n';
  274.    
  275.     buf |= ((unsigned long) scan_code)<<(8*(count++));
  276.    
  277.    
  278.     if ((buf & 0xff) != (GXEMUL_FB_KEY_F1 & 0xff)) {
  279.         keybuffer_push(keybuffer, buf);
  280.         buf = count = 0;
  281.         return 1;
  282.     }
  283.  
  284.     if (count <= 1)
  285.         return 1;
  286.  
  287.     if ((buf & 0xffff) != (GXEMUL_FB_KEY_F1 & 0xffff)) {
  288.         keybuffer_push(keybuffer, buf & 0xff);
  289.         keybuffer_push(keybuffer, (buf >> 8) &0xff);
  290.         buf = count = 0;
  291.         return 1;
  292.     }
  293.  
  294.     if (count <= 2)
  295.         return 1;
  296.  
  297.  
  298.     if ((buf & 0xffffff) != (GXEMUL_FB_KEY_F1 & 0xffffff)
  299.         && (buf & 0xffffff) != (GXEMUL_FB_KEY_F5 & 0xffffff)
  300.         && (buf & 0xffffff) != (GXEMUL_FB_KEY_F9 & 0xffffff)) {
  301.  
  302.         keybuffer_push(keybuffer, buf & 0xff);
  303.         keybuffer_push(keybuffer, (buf >> 8) & 0xff);
  304.         keybuffer_push(keybuffer, (buf >> 16) & 0xff);
  305.         buf = count = 0;
  306.         return 1;
  307.     }
  308.  
  309.     if ( count <= 3 )
  310.         return 1;
  311.    
  312.  
  313.     switch (buf) {
  314.     case GXEMUL_FB_KEY_F1:
  315.         keybuffer_push(keybuffer,FUNCTION_KEYS | 1 );
  316.         buf=count=0;
  317.         return 1;
  318.     case GXEMUL_FB_KEY_F2:
  319.         keybuffer_push(keybuffer,FUNCTION_KEYS | 2 );
  320.         buf=count=0;
  321.         return 1;
  322.     case GXEMUL_FB_KEY_F3:
  323.         keybuffer_push(keybuffer,FUNCTION_KEYS | 3 );
  324.         buf=count=0;
  325.         return 1;
  326.     case GXEMUL_FB_KEY_F4:
  327.         keybuffer_push(keybuffer,FUNCTION_KEYS | 4 );
  328.         buf=count=0;
  329.         return 1;
  330.     case GXEMUL_FB_KEY_F5:
  331.         keybuffer_push(keybuffer,FUNCTION_KEYS | 5 );
  332.         buf=count=0;
  333.         return 1;
  334.     case GXEMUL_FB_KEY_F6:
  335.         keybuffer_push(keybuffer,FUNCTION_KEYS | 6 );
  336.         buf=count=0;
  337.         return 1;
  338.     case GXEMUL_FB_KEY_F7:
  339.         keybuffer_push(keybuffer,FUNCTION_KEYS | 7 );
  340.         buf=count=0;
  341.         return 1;
  342.     case GXEMUL_FB_KEY_F8:
  343.         keybuffer_push(keybuffer,FUNCTION_KEYS | 8 );
  344.         buf=count=0;
  345.         return 1;
  346.     case GXEMUL_FB_KEY_F9:
  347.         keybuffer_push(keybuffer,FUNCTION_KEYS | 9 );
  348.         buf=count=0;
  349.         return 1;
  350.     case GXEMUL_FB_KEY_F10:
  351.         keybuffer_push(keybuffer,FUNCTION_KEYS | 10 );
  352.         buf=count=0;
  353.         return 1;
  354.     case GXEMUL_FB_KEY_F11:
  355.         keybuffer_push(keybuffer,FUNCTION_KEYS | 11 );
  356.         buf=count=0;
  357.         return 1;
  358.     case GXEMUL_FB_KEY_F12:
  359.         keybuffer_push(keybuffer,FUNCTION_KEYS | 12 );
  360.         buf=count=0;
  361.         return 1;
  362.     default:
  363.         keybuffer_push(keybuffer, buf & 0xff );
  364.         keybuffer_push(keybuffer, (buf >> 8) &0xff );
  365.         keybuffer_push(keybuffer, (buf >> 16) &0xff );
  366.         keybuffer_push(keybuffer, (buf >> 24) &0xff );
  367.         buf=count=0;
  368.         return 1;
  369.     }
  370.     return 1;
  371. }
  372.  
  373.  
  374. /** Initializes keyboard handler. */
  375. int kbd_arch_init(void)
  376. {
  377.     fb = (sysinfo_value("fb.kind") == 1);
  378.     gxemul_cmds[0].addr = (void *) sysinfo_value("kbd.address.virtual");
  379.     ipc_register_irq(sysinfo_value("kbd.inr"), sysinfo_value("kbd.devno"), 0, &gxemul_kbd);
  380.     return 0;
  381. }
  382.  
  383.  
  384. /** Process data sent when a key is pressed.
  385.  *  
  386.  *  @param keybuffer Buffer of scan codes.
  387.  *  @param call      IPC call.
  388.  *
  389.  *  @return Code of the pressed key.
  390.  */
  391. int kbd_arch_process(keybuffer_t *keybuffer, ipc_call_t *call)
  392. {
  393.     int scan_code = IPC_GET_ARG2(*call);
  394.     static int esc_count = 0;
  395.  
  396.     if (scan_code == 0x1b) {
  397.         esc_count++;
  398.         if (esc_count == 3) {
  399.             __SYSCALL0(SYS_DEBUG_ENABLE_CONSOLE);
  400.         }
  401.     } else {
  402.         esc_count = 0;
  403.     }
  404.  
  405.     if (fb) {
  406.         return gxemul_process_fb(keybuffer, scan_code);
  407.     } else {
  408.         return gxemul_process_no_fb(keybuffer, scan_code);
  409.     }
  410.  
  411. }
  412.  
  413. /** @}
  414.  */
  415.