Subversion Repositories Kolibri OS

Rev

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

  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;;                                                              ;;
  3. ;; Copyright (C) KolibriOS team 2004-2011. All rights reserved. ;;
  4. ;; Copyright (C) MenuetOS 2000-2004 Ville Mikael Turjanmaa      ;;
  5. ;; Distributed under terms of the GNU General Public License    ;;
  6. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  7.  
  8. $Revision: 3500 $
  9.  
  10.  
  11. VKEY_LSHIFT   = 0000000000000001b
  12. VKEY_RSHIFT   = 0000000000000010b
  13. VKEY_LCONTROL = 0000000000000100b
  14. VKEY_RCONTROL = 0000000000001000b
  15. VKEY_LALT     = 0000000000010000b
  16. VKEY_RALT     = 0000000000100000b
  17. VKEY_CAPSLOCK = 0000000001000000b
  18. VKEY_NUMLOCK  = 0000000010000000b
  19. VKEY_SCRLOCK  = 0000000100000000b
  20. VKEY_LWIN     = 0000001000000000b
  21. VKEY_RWIN     = 0000010000000000b
  22.  
  23. VKEY_SHIFT    = 0000000000000011b
  24. VKEY_CONTROL  = 0000000000001100b
  25. VKEY_ALT      = 0000000000110000b
  26.  
  27. uglobal
  28.   align 4
  29.   kb_state      dd 0
  30.   ext_code      db 0
  31.  
  32.   keyboard_mode db 0
  33.   keyboard_data db 0
  34.  
  35.   altmouseb     db 0
  36.   ctrl_alt_del  db 0
  37.  
  38.   kb_lights     db 0
  39.   old_kb_lights db 0
  40.  
  41. align 4
  42.         hotkey_scancodes        rd      256     ; we have 256 scancodes
  43.         hotkey_list             rd      256*4   ; max 256 defined hotkeys
  44.         hotkey_buffer           rd      120*2   ; buffer for 120 hotkeys
  45. endg
  46.  
  47. iglobal
  48. hotkey_tests    dd      hotkey_test0
  49.                 dd      hotkey_test1
  50.                 dd      hotkey_test2
  51.                 dd      hotkey_test3
  52.                 dd      hotkey_test4
  53. hotkey_tests_num = 5
  54. endg
  55. ;---------------------------------------------------------------------
  56. hotkey_test0:
  57.         test    al, al
  58.         setz    al
  59.         ret
  60. ;---------------------------------------------------------------------
  61. hotkey_test1:
  62.         test    al, al
  63.         setnp   al
  64.         ret
  65. ;---------------------------------------------------------------------
  66. hotkey_test2:
  67.         cmp     al, 3
  68.         setz    al
  69.         ret
  70. ;---------------------------------------------------------------------
  71. hotkey_test3:
  72.         cmp     al, 1
  73.         setz    al
  74.         ret
  75. ;---------------------------------------------------------------------
  76. hotkey_test4:
  77.         cmp     al, 2
  78.         setz    al
  79.         ret
  80. ;---------------------------------------------------------------------
  81. hotkey_do_test:
  82.         push    eax
  83.         mov     edx, [kb_state]
  84.         shr     edx, cl
  85.         add     cl, cl
  86.         mov     eax, [eax+4]
  87.         shr     eax, cl
  88.         and     eax, 15
  89.         cmp     al, hotkey_tests_num
  90.         jae     .fail
  91.        
  92.         xchg    eax, edx
  93.         and     al, 3
  94.         call    [hotkey_tests + edx*4]
  95.         cmp     al, 1
  96.         pop     eax
  97.         ret
  98. ;--------------------------------------
  99. .fail:
  100.         stc
  101.         pop     eax
  102.         ret
  103. ;---------------------------------------------------------------------
  104. align 4
  105. set_keyboard_data:
  106.         movzx   eax, word[TASK_COUNT]; top window process
  107.         movzx   eax, word[WIN_POS+eax*2]
  108.         shl     eax, 8
  109.         mov     al, [SLOT_BASE+eax+APPDATA.keyboard_mode]
  110.         mov     [keyboard_mode], al
  111.        
  112.         mov     eax, ecx
  113.        
  114.         push    ebx esi edi ebp
  115.         call    send_scancode
  116.         pop     ebp edi esi ebx
  117.         ret
  118. ;---------------------------------------------------------------------
  119. struct KEYBOARD
  120. next           dd      ?
  121. prev           dd      ?
  122. functions      dd      ?
  123. userdata       dd      ?
  124. ends
  125. struct KBDFUNC
  126. strucsize      dd      ?
  127. close          dd      ?
  128. setlights      dd      ?
  129. ends
  130.  
  131. iglobal
  132. keyboards:
  133.         dd      keyboards
  134.         dd      keyboards
  135. endg
  136. uglobal
  137. keyboard_list_mutex     MUTEX
  138. endg
  139.  
  140. register_keyboard:
  141.         push    ebx
  142.         push    sizeof.KEYBOARD
  143.         pop     eax
  144.         call    malloc
  145.         test    eax, eax
  146.         jz      .nothing
  147.         mov     ecx, [esp+4+4]
  148.         mov     [eax+KEYBOARD.functions], ecx
  149.         mov     ecx, [esp+8+4]
  150.         mov     [eax+KEYBOARD.userdata], ecx
  151.         xchg    eax, ebx
  152.         mov     ecx, keyboard_list_mutex
  153.         call    mutex_lock
  154.         mov     ecx, keyboards
  155.         mov     edx, [ecx+KEYBOARD.prev]
  156.         mov     [ebx+KEYBOARD.next], ecx
  157.         mov     [ebx+KEYBOARD.prev], edx
  158.         mov     [edx+KEYBOARD.next], ebx
  159.         mov     [ecx+KEYBOARD.prev], ebx
  160.         mov     ecx, [ebx+KEYBOARD.functions]
  161.         cmp     [ecx+KBDFUNC.strucsize], KBDFUNC.setlights
  162.         jbe     .unlock
  163.         mov     ecx, [ecx+KBDFUNC.setlights]
  164.         test    ecx, ecx
  165.         jz      .unlock
  166.         stdcall ecx, [ebx+KEYBOARD.userdata], dword [kb_lights]
  167. .unlock:
  168.         mov     ecx, keyboard_list_mutex
  169.         call    mutex_unlock
  170.         xchg    eax, ebx
  171. .nothing:
  172.         pop     ebx
  173.         ret     8
  174.  
  175. delete_keyboard:
  176.         push    ebx
  177.         mov     ebx, [esp+4+4]
  178.         mov     ecx, keyboard_list_mutex
  179.         call    mutex_lock
  180.         mov     eax, [ebx+KEYBOARD.next]
  181.         mov     edx, [ebx+KEYBOARD.prev]
  182.         mov     [eax+KEYBOARD.prev], edx
  183.         mov     [edx+KEYBOARD.next], eax
  184.         call    mutex_unlock
  185.         mov     ecx, [ebx+KEYBOARD.functions]
  186.         cmp     [ecx+KBDFUNC.strucsize], KBDFUNC.close
  187.         jbe     .nothing
  188.         mov     ecx, [ecx+KBDFUNC.close]
  189.         test    ecx, ecx
  190.         jz      .nothing
  191.         stdcall ecx, [ebx+KEYBOARD.userdata]
  192. .nothing:
  193.         pop     ebx
  194.         ret     4
  195. ;---------------------------------------------------------------------
  196. align 4
  197. irq1:
  198.         movzx   eax, word[TASK_COUNT]; top window process
  199.         movzx   eax, word[WIN_POS+eax*2]
  200.         shl     eax, 8
  201.         mov     al, [SLOT_BASE+eax+APPDATA.keyboard_mode]
  202.         mov     [keyboard_mode], al
  203.        
  204.         in      al, 0x60
  205. ;--------------------------------------
  206. send_scancode:
  207.         mov     [keyboard_data], al
  208. ; ch = scancode
  209. ; cl = ext_code
  210. ; bh = 0 - normal key
  211. ; bh = 1 - modifier (Shift/Ctrl/Alt)
  212. ; bh = 2 - extended code
  213.         mov     ch, al
  214.         cmp     al, 0xE0
  215.         je      @f
  216.        
  217.         cmp     al, 0xE1
  218.         jne     .normal_code
  219. @@:
  220.         mov     bh, 2
  221.         mov     [ext_code], al
  222.         jmp     .writekey
  223. ;--------------------------------------
  224. .normal_code:
  225.         mov     cl, 0
  226.         xchg    cl, [ext_code]
  227.         and     al, 0x7F
  228.         mov     bh, 1
  229. ;--------------------------------------
  230. @@:
  231.         cmp     al, 0x5B
  232.         jne     @f
  233.        
  234.         cmp     cl, 0xE0
  235.         jne     @f
  236.        
  237.         mov     eax, VKEY_LWIN
  238.         mov     bh, 0
  239.         jmp     .modifier
  240. ;--------------------------------------
  241. @@:
  242.         cmp     al, 0x5C
  243.         jne     @f
  244.        
  245.         cmp     cl, 0xE0
  246.         jne     @f
  247.        
  248.         mov     eax, VKEY_RWIN
  249.         mov     bh, 0
  250.         jmp     .modifier
  251. ;--------------------------------------
  252. @@:
  253.         cmp     al, 0x2A
  254.         jne     @f
  255.        
  256.         cmp     cl, 0xE0
  257.         je      .writekey
  258.        
  259.         mov     eax, VKEY_LSHIFT
  260.         jmp     .modifier
  261. ;--------------------------------------
  262. @@:
  263.         cmp     al, 0x36
  264.         jne     @f
  265.        
  266.         cmp     cl, 0xE0
  267.         je      .writekey
  268.        
  269.         mov     eax, VKEY_RSHIFT
  270.         jmp     .modifier
  271. ;--------------------------------------
  272. @@:
  273.         cmp     al, 0x38
  274.         jne     @f
  275.        
  276.         mov     eax, VKEY_LALT
  277.         test    cl, cl
  278.         jz      .modifier
  279.        
  280.         mov     al, VKEY_RALT
  281.         jmp     .modifier
  282. ;--------------------------------------
  283. @@:
  284.         cmp     al, 0x1D
  285.         jne     @f
  286.        
  287.         mov     eax, VKEY_LCONTROL
  288.         test    cl, cl
  289.         jz      .modifier
  290.        
  291.         mov     al, VKEY_RCONTROL
  292.         cmp     cl, 0xE0
  293.         jz      .modifier
  294.        
  295.         mov     [ext_code], cl
  296.         jmp     .writekey
  297. ;--------------------------------------
  298. @@:
  299.         cmp     al, 0x3A
  300.         jne     @f
  301.        
  302.         mov     bl, 4
  303.         mov     eax, VKEY_CAPSLOCK
  304.         jmp     .no_key.xor
  305. ;--------------------------------------
  306. @@:
  307.         cmp     al, 0x45
  308.         jne     @f
  309.         test    cl, cl
  310.         jnz     .writekey
  311.        
  312.         mov     bl, 2
  313.         mov     eax, VKEY_NUMLOCK
  314.         jmp     .no_key.xor
  315. ;--------------------------------------
  316. @@:
  317.         cmp     al, 0x46
  318.         jne     @f
  319.        
  320.         mov     bl, 1
  321.         mov     eax, VKEY_SCRLOCK
  322.         jmp     .no_key.xor
  323. ;--------------------------------------
  324. @@:
  325.         xor     ebx, ebx
  326.         test    ch, ch
  327.         js      .writekey
  328.        
  329.         movzx   eax, ch          ; plain key
  330.         mov     bl, [keymap+eax]
  331.         mov     edx, [kb_state]
  332.         test    dl, VKEY_CONTROL ; ctrl alt del
  333.         jz      .noctrlaltdel
  334.        
  335.         test    dl, VKEY_ALT
  336.         jz      .noctrlaltdel
  337.        
  338.         cmp     ch, 53h
  339.         jne     .noctrlaltdel
  340.        
  341.         mov     [ctrl_alt_del], 1
  342. .noctrlaltdel:
  343.         test    dl, VKEY_CONTROL ; ctrl on ?
  344.         jz      @f
  345.        
  346.         sub     bl, 0x60
  347. @@:
  348.         test    dl, VKEY_CAPSLOCK        ; caps lock on ?
  349.         jz      .no_caps_lock
  350.        
  351.         test    dl, VKEY_SHIFT   ; shift on ?
  352.         jz      .keymap_shif
  353.        
  354.         jmp     @f
  355. ;--------------------------------------
  356. .no_caps_lock:
  357.         test    dl, VKEY_SHIFT   ; shift on ?
  358.         jz      @f
  359. .keymap_shif:  
  360.         mov     bl, [keymap_shift+eax]
  361. @@:
  362.         test    dl, VKEY_ALT     ; alt on ?
  363.         jz      @f
  364.        
  365.         mov     bl, [keymap_alt+eax]
  366. @@:
  367.         jmp     .writekey
  368. ;--------------------------------------
  369. .modifier:
  370.         test    ch, ch
  371.         js      .modifier.up
  372.         or      [kb_state], eax
  373.         jmp     .writekey
  374. ;--------------------------------------
  375. .modifier.up:
  376.         not     eax
  377.         and     [kb_state], eax
  378.         jmp     .writekey
  379. ;--------------------------------------
  380. .no_key.xor:
  381.         mov     bh, 0
  382.         test    ch, ch
  383.         js      .writekey
  384.        
  385.         xor     [kb_state], eax
  386.         xor     [kb_lights], bl
  387. .writekey:
  388.         pushad
  389. ; test for system hotkeys
  390.         movzx   eax, ch
  391.         cmp     bh, 1
  392.         ja      .nohotkey
  393.         jb      @f
  394.        
  395.         xor     eax, eax
  396. @@:
  397.         mov     eax, [hotkey_scancodes + eax*4]
  398. .hotkey_loop:
  399.         test    eax, eax
  400.         jz      .nohotkey
  401.        
  402.         mov     cl, 0
  403.         call    hotkey_do_test
  404.         jc      .hotkey_cont
  405.        
  406.         mov     cl, 2
  407.         call    hotkey_do_test
  408.         jc      .hotkey_cont
  409.        
  410.         mov     cl, 4
  411.         call    hotkey_do_test
  412.         jnc     .hotkey_found
  413. .hotkey_cont:
  414.         mov     eax, [eax]
  415.         jmp     .hotkey_loop
  416. ;--------------------------------------
  417. .hotkey_found:
  418.         mov     eax, [eax+8]
  419. ; put key in buffer for process in slot eax
  420.         mov     edi, hotkey_buffer
  421. @@:
  422.         cmp     dword [edi], 0
  423.         jz      .found_free
  424.        
  425.         add     edi, 8
  426.         cmp     edi, hotkey_buffer+120*8
  427.         jb      @b
  428. ; no free space - replace first entry
  429.         mov     edi, hotkey_buffer
  430. .found_free:
  431.         mov     [edi], eax
  432.         movzx   eax, ch
  433.         cmp     bh, 1
  434.         jnz     @f
  435.        
  436.         xor     eax, eax
  437. @@:
  438.         mov     [edi+4], ax
  439.         mov     eax, [kb_state]
  440.         mov     [edi+6], ax
  441.  
  442.         cmp     [PID_lock_input], dword 0
  443.         je      .nohotkey
  444.  
  445.         popad
  446.         jmp     .exit.irq1
  447. ;--------------------------------------
  448. .nohotkey:
  449.         popad
  450.  
  451.         cmp     [keyboard_mode], 0; return from keymap
  452.         jne     .scancode
  453.        
  454.         test    bh, bh
  455.         jnz     .exit.irq1
  456.        
  457.         test    bl, bl
  458.         jz      .exit.irq1
  459.  
  460.         test    [kb_state], VKEY_NUMLOCK
  461.         jz      .dowrite
  462.        
  463.         cmp     cl, 0xE0
  464.         jz      .dowrite
  465.        
  466.         cmp     ch, 55
  467.         jnz     @f
  468.        
  469.         mov     bl, 0x2A        ;*
  470.         jmp     .dowrite
  471. ;--------------------------------------
  472. @@:
  473.         cmp     ch, 71
  474.         jb      .dowrite
  475.        
  476.         cmp     ch, 83
  477.         ja      .dowrite
  478.        
  479.         movzx   eax, ch
  480.         mov     bl, [numlock_map + eax - 71]
  481.         jmp     .dowrite
  482. ;--------------------------------------
  483. .scancode:
  484.         mov     bl, ch
  485. .dowrite:
  486.         movzx   eax, byte[KEY_COUNT]
  487.         cmp     al, 120
  488.         jae     .exit.irq1
  489.         inc     eax
  490.         mov     [KEY_COUNT], al
  491.         mov     [KEY_COUNT+eax], bl
  492. .exit.irq1:
  493.         mov     [check_idle_semaphore], 5
  494.         ret
  495. ;---------------------------------------------------------------------
  496. set_lights:
  497.         push    ebx esi
  498.         mov     ecx, keyboard_list_mutex
  499.         call    mutex_lock
  500.         mov     esi, keyboards
  501. .loop:
  502.         mov     esi, [esi+KEYBOARD.next]
  503.         cmp     esi, keyboards
  504.         jz      .done
  505.         mov     eax, [esi+KEYBOARD.functions]
  506.         cmp     dword [eax], KBDFUNC.setlights
  507.         jbe     .loop
  508.         mov     eax, [eax+KBDFUNC.setlights]
  509.         test    eax, eax
  510.         jz      .loop
  511.         stdcall eax, [esi+KEYBOARD.userdata], dword [kb_lights]
  512.         jmp     .loop
  513. .done:
  514.         mov     ecx, keyboard_list_mutex
  515.         call    mutex_unlock
  516.         pop     esi ebx
  517.         ret
  518.  
  519. ps2_set_lights:
  520.         stdcall disable_irq, 1
  521.         mov     al, 0xED
  522.         call    kb_write
  523.         mov     al, [esp+8]
  524.         call    kb_write
  525.         stdcall enable_irq, 1
  526.         ret     8
  527.  
  528. ;// mike.dld ]
  529. check_lights_state:
  530.         mov     al, [kb_lights]
  531.         cmp     al, [old_kb_lights]
  532.         jz      .nothing
  533.         mov     [old_kb_lights], al
  534.         call    set_lights
  535. .nothing:
  536.         ret
  537. ;---------------------------------------------------------------------
  538. numlock_map:
  539.     db   0x37   ;Num 7
  540.     db   0x38   ;Num 8
  541.     db   0x39   ;Num 9
  542.     db   0x2D   ;Num -
  543.     db   0x34   ;Num 4
  544.     db   0x35   ;Num 5
  545.     db   0x36   ;Num 6
  546.     db   0x2B   ;Num +
  547.     db   0x31   ;Num 1
  548.     db   0x32   ;Num 2
  549.     db   0x33   ;Num 3
  550.     db   0x30   ;Num 0
  551.     db   0x2E   ;Num .
  552. ;---------------------------------------------------------------------
  553.