Subversion Repositories Kolibri OS

Rev

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

  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;;                                                              ;;
  3. ;; Copyright (C) KolibriOS team 2004-2014. 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: 3598 $
  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.         movi    eax, sizeof.KEYBOARD
  143.         call    malloc
  144.         test    eax, eax
  145.         jz      .nothing
  146.         mov     ecx, [esp+4+4]
  147.         mov     [eax+KEYBOARD.functions], ecx
  148.         mov     ecx, [esp+8+4]
  149.         mov     [eax+KEYBOARD.userdata], ecx
  150.         xchg    eax, ebx
  151.         mov     ecx, keyboard_list_mutex
  152.         call    mutex_lock
  153.         mov     ecx, keyboards
  154.         mov     edx, [ecx+KEYBOARD.prev]
  155.         mov     [ebx+KEYBOARD.next], ecx
  156.         mov     [ebx+KEYBOARD.prev], edx
  157.         mov     [edx+KEYBOARD.next], ebx
  158.         mov     [ecx+KEYBOARD.prev], ebx
  159.         mov     ecx, [ebx+KEYBOARD.functions]
  160.         cmp     [ecx+KBDFUNC.strucsize], KBDFUNC.setlights
  161.         jbe     .unlock
  162.         mov     ecx, [ecx+KBDFUNC.setlights]
  163.         test    ecx, ecx
  164.         jz      .unlock
  165.         stdcall ecx, [ebx+KEYBOARD.userdata], dword [kb_lights]
  166. .unlock:
  167.         mov     ecx, keyboard_list_mutex
  168.         call    mutex_unlock
  169.         xchg    eax, ebx
  170. .nothing:
  171.         pop     ebx
  172.         ret     8
  173.  
  174. delete_keyboard:
  175.         push    ebx
  176.         mov     ebx, [esp+4+4]
  177.         mov     ecx, keyboard_list_mutex
  178.         call    mutex_lock
  179.         mov     eax, [ebx+KEYBOARD.next]
  180.         mov     edx, [ebx+KEYBOARD.prev]
  181.         mov     [eax+KEYBOARD.prev], edx
  182.         mov     [edx+KEYBOARD.next], eax
  183.         call    mutex_unlock
  184.         mov     ecx, [ebx+KEYBOARD.functions]
  185.         cmp     [ecx+KBDFUNC.strucsize], KBDFUNC.close
  186.         jbe     .nothing
  187.         mov     ecx, [ecx+KBDFUNC.close]
  188.         test    ecx, ecx
  189.         jz      .nothing
  190.         stdcall ecx, [ebx+KEYBOARD.userdata]
  191. .nothing:
  192.         pop     ebx
  193.         ret     4
  194. ;---------------------------------------------------------------------
  195. align 4
  196. irq1:
  197.         movzx   eax, word[TASK_COUNT]; top window process
  198.         movzx   eax, word[WIN_POS+eax*2]
  199.         shl     eax, 8
  200.         mov     al, [SLOT_BASE+eax+APPDATA.keyboard_mode]
  201.         mov     [keyboard_mode], al
  202.        
  203.         in      al, 0x60
  204. ;--------------------------------------
  205. send_scancode:
  206.         mov     [keyboard_data], al
  207. ; ch = scancode
  208. ; cl = ext_code
  209. ; bh = 0 - normal key
  210. ; bh = 1 - modifier (Shift/Ctrl/Alt)
  211. ; bh = 2 - extended code
  212.         mov     ch, al
  213.         cmp     al, 0xE0
  214.         je      @f
  215.        
  216.         cmp     al, 0xE1
  217.         jne     .normal_code
  218. @@:
  219.         mov     bh, 2
  220.         mov     [ext_code], al
  221.         jmp     .writekey
  222. ;--------------------------------------
  223. .normal_code:
  224.         mov     cl, 0
  225.         xchg    cl, [ext_code]
  226.         and     al, 0x7F
  227.         mov     bh, 1
  228. ;--------------------------------------
  229. @@:
  230.         cmp     al, 0x5B
  231.         jne     @f
  232.        
  233.         cmp     cl, 0xE0
  234.         jne     @f
  235.        
  236.         mov     eax, VKEY_LWIN
  237.         mov     bh, 0
  238.         jmp     .modifier
  239. ;--------------------------------------
  240. @@:
  241.         cmp     al, 0x5C
  242.         jne     @f
  243.        
  244.         cmp     cl, 0xE0
  245.         jne     @f
  246.        
  247.         mov     eax, VKEY_RWIN
  248.         mov     bh, 0
  249.         jmp     .modifier
  250. ;--------------------------------------
  251. @@:
  252.         cmp     al, 0x2A
  253.         jne     @f
  254.        
  255.         cmp     cl, 0xE0
  256.         je      .writekey
  257.        
  258.         mov     eax, VKEY_LSHIFT
  259.         jmp     .modifier
  260. ;--------------------------------------
  261. @@:
  262.         cmp     al, 0x36
  263.         jne     @f
  264.        
  265.         cmp     cl, 0xE0
  266.         je      .writekey
  267.        
  268.         mov     eax, VKEY_RSHIFT
  269.         jmp     .modifier
  270. ;--------------------------------------
  271. @@:
  272.         cmp     al, 0x38
  273.         jne     @f
  274.        
  275.         mov     eax, VKEY_LALT
  276.         test    cl, cl
  277.         jz      .modifier
  278.        
  279.         mov     al, VKEY_RALT
  280.         jmp     .modifier
  281. ;--------------------------------------
  282. @@:
  283.         cmp     al, 0x1D
  284.         jne     @f
  285.        
  286.         mov     eax, VKEY_LCONTROL
  287.         test    cl, cl
  288.         jz      .modifier
  289.        
  290.         mov     al, VKEY_RCONTROL
  291.         cmp     cl, 0xE0
  292.         jz      .modifier
  293.        
  294.         mov     [ext_code], cl
  295.         jmp     .writekey
  296. ;--------------------------------------
  297. @@:
  298.         cmp     al, 0x3A
  299.         jne     @f
  300.        
  301.         mov     bl, 4
  302.         mov     eax, VKEY_CAPSLOCK
  303.         jmp     .no_key.xor
  304. ;--------------------------------------
  305. @@:
  306.         cmp     al, 0x45
  307.         jne     @f
  308.         test    cl, cl
  309.         jnz     .writekey
  310.        
  311.         mov     bl, 2
  312.         mov     eax, VKEY_NUMLOCK
  313.         jmp     .no_key.xor
  314. ;--------------------------------------
  315. @@:
  316.         cmp     al, 0x46
  317.         jne     @f
  318.        
  319.         mov     bl, 1
  320.         mov     eax, VKEY_SCRLOCK
  321.         jmp     .no_key.xor
  322. ;--------------------------------------
  323. @@:
  324.         xor     ebx, ebx
  325.         test    ch, ch
  326.         js      .writekey
  327.        
  328.         movzx   eax, ch          ; plain key
  329.         mov     bl, [keymap+eax]
  330.         mov     edx, [kb_state]
  331.         test    dl, VKEY_CONTROL ; ctrl alt del
  332.         jz      .noctrlaltdel
  333.        
  334.         test    dl, VKEY_ALT
  335.         jz      .noctrlaltdel
  336.        
  337.         cmp     ch, 53h
  338.         jne     .noctrlaltdel
  339.        
  340.         mov     [ctrl_alt_del], 1
  341.         call    wakeup_osloop
  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.         cmp     cl, 0xE0        ; extended keycode
  461.         jne     @f
  462.  
  463.         cmp     ch, 53
  464.         jne     .dowrite
  465.        
  466.         mov     bl, '/'
  467.         jmp     .dowrite
  468. @@:
  469.        
  470.         cmp     ch, 55
  471.         jne     @f
  472.        
  473.         mov     bl, '*'
  474.         jmp     .dowrite
  475. @@:
  476.  
  477.         cmp     ch, 74
  478.         jne     @f
  479.        
  480.         mov     bl, '-'
  481.         jmp     .dowrite
  482. @@:
  483.  
  484.         cmp     ch, 78
  485.         jne     @f
  486.        
  487.         mov     bl, '+'
  488.         jmp     .dowrite
  489. @@:
  490.  
  491.         test    [kb_state], VKEY_NUMLOCK
  492.         jz      .dowrite
  493.  
  494.         cmp     ch, 71
  495.         jb      .dowrite
  496.        
  497.         cmp     ch, 83
  498.         ja      .dowrite
  499.        
  500.         movzx   eax, ch
  501.         mov     bl, [numlock_map + eax - 71]
  502.         jmp     .dowrite
  503. ;--------------------------------------
  504. .scancode:
  505.         mov     bl, ch
  506. .dowrite:
  507.         movzx   eax, byte[KEY_COUNT]
  508.         cmp     al, 120
  509.         jae     .exit.irq1
  510.         inc     eax
  511.         mov     [KEY_COUNT], al
  512. ; store ascii or scancode
  513.         mov     [KEY_COUNT+eax], bl ; actually KEY_BUFF + EAX - 1
  514. ; store original scancode
  515.         add     eax, 120+2
  516.         push    ecx
  517.         cmp     [keyboard_mode], 0; return from keymap
  518.         je      @f
  519.  
  520.         xor     ch, ch
  521. @@:
  522.         mov     [KEY_COUNT+eax], ch ; actually KEY_BUFF + EAX - 1
  523.         pop     ecx
  524.         sub     eax, 120+2
  525. .exit.irq1:
  526.         ret
  527. ;---------------------------------------------------------------------
  528. set_lights:
  529.         push    ebx esi
  530.         mov     ecx, keyboard_list_mutex
  531.         call    mutex_lock
  532.         mov     esi, keyboards
  533. .loop:
  534.         mov     esi, [esi+KEYBOARD.next]
  535.         cmp     esi, keyboards
  536.         jz      .done
  537.         mov     eax, [esi+KEYBOARD.functions]
  538.         cmp     dword [eax], KBDFUNC.setlights
  539.         jbe     .loop
  540.         mov     eax, [eax+KBDFUNC.setlights]
  541.         test    eax, eax
  542.         jz      .loop
  543.         stdcall eax, [esi+KEYBOARD.userdata], dword [kb_lights]
  544.         jmp     .loop
  545. .done:
  546.         mov     ecx, keyboard_list_mutex
  547.         call    mutex_unlock
  548.         pop     esi ebx
  549.         ret
  550.  
  551. ps2_set_lights:
  552.         stdcall disable_irq, 1
  553.         mov     al, 0xED
  554.         call    kb_write
  555.         mov     al, [esp+8]
  556.         call    kb_write
  557.         stdcall enable_irq, 1
  558.         ret     8
  559.  
  560. ;// mike.dld ]
  561. proc check_lights_state_has_work?
  562.         mov     al, [kb_lights]
  563.         cmp     al, [old_kb_lights]
  564.         ret
  565. endp
  566.  
  567. check_lights_state:
  568.         call    check_lights_state_has_work?
  569.         jz      .nothing
  570.         mov     [old_kb_lights], al
  571.         call    set_lights
  572. .nothing:
  573.         ret
  574. ;---------------------------------------------------------------------
  575. numlock_map:
  576.     db   0x37   ;Num 7
  577.     db   0x38   ;Num 8
  578.     db   0x39   ;Num 9
  579.     db   0x2D   ;Num -
  580.     db   0x34   ;Num 4
  581.     db   0x35   ;Num 5
  582.     db   0x36   ;Num 6
  583.     db   0x2B   ;Num +
  584.     db   0x31   ;Num 1
  585.     db   0x32   ;Num 2
  586.     db   0x33   ;Num 3
  587.     db   0x30   ;Num 0
  588.     db   0x2E   ;Num .
  589. ;---------------------------------------------------------------------
  590.