Subversion Repositories Kolibri OS

Rev

Rev 3356 | Rev 3598 | 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: 3534 $
  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.         call    wakeup_osloop
  343. .noctrlaltdel:
  344.         test    dl, VKEY_CONTROL ; ctrl on ?
  345.         jz      @f
  346.        
  347.         sub     bl, 0x60
  348. @@:
  349.         test    dl, VKEY_CAPSLOCK        ; caps lock on ?
  350.         jz      .no_caps_lock
  351.        
  352.         test    dl, VKEY_SHIFT   ; shift on ?
  353.         jz      .keymap_shif
  354.        
  355.         jmp     @f
  356. ;--------------------------------------
  357. .no_caps_lock:
  358.         test    dl, VKEY_SHIFT   ; shift on ?
  359.         jz      @f
  360. .keymap_shif:  
  361.         mov     bl, [keymap_shift+eax]
  362. @@:
  363.         test    dl, VKEY_ALT     ; alt on ?
  364.         jz      @f
  365.        
  366.         mov     bl, [keymap_alt+eax]
  367. @@:
  368.         jmp     .writekey
  369. ;--------------------------------------
  370. .modifier:
  371.         test    ch, ch
  372.         js      .modifier.up
  373.         or      [kb_state], eax
  374.         jmp     .writekey
  375. ;--------------------------------------
  376. .modifier.up:
  377.         not     eax
  378.         and     [kb_state], eax
  379.         jmp     .writekey
  380. ;--------------------------------------
  381. .no_key.xor:
  382.         mov     bh, 0
  383.         test    ch, ch
  384.         js      .writekey
  385.        
  386.         xor     [kb_state], eax
  387.         xor     [kb_lights], bl
  388. .writekey:
  389.         pushad
  390. ; test for system hotkeys
  391.         movzx   eax, ch
  392.         cmp     bh, 1
  393.         ja      .nohotkey
  394.         jb      @f
  395.        
  396.         xor     eax, eax
  397. @@:
  398.         mov     eax, [hotkey_scancodes + eax*4]
  399. .hotkey_loop:
  400.         test    eax, eax
  401.         jz      .nohotkey
  402.        
  403.         mov     cl, 0
  404.         call    hotkey_do_test
  405.         jc      .hotkey_cont
  406.        
  407.         mov     cl, 2
  408.         call    hotkey_do_test
  409.         jc      .hotkey_cont
  410.        
  411.         mov     cl, 4
  412.         call    hotkey_do_test
  413.         jnc     .hotkey_found
  414. .hotkey_cont:
  415.         mov     eax, [eax]
  416.         jmp     .hotkey_loop
  417. ;--------------------------------------
  418. .hotkey_found:
  419.         mov     eax, [eax+8]
  420. ; put key in buffer for process in slot eax
  421.         mov     edi, hotkey_buffer
  422. @@:
  423.         cmp     dword [edi], 0
  424.         jz      .found_free
  425.        
  426.         add     edi, 8
  427.         cmp     edi, hotkey_buffer+120*8
  428.         jb      @b
  429. ; no free space - replace first entry
  430.         mov     edi, hotkey_buffer
  431. .found_free:
  432.         mov     [edi], eax
  433.         movzx   eax, ch
  434.         cmp     bh, 1
  435.         jnz     @f
  436.        
  437.         xor     eax, eax
  438. @@:
  439.         mov     [edi+4], ax
  440.         mov     eax, [kb_state]
  441.         mov     [edi+6], ax
  442.  
  443.         cmp     [PID_lock_input], dword 0
  444.         je      .nohotkey
  445.  
  446.         popad
  447.         jmp     .exit.irq1
  448. ;--------------------------------------
  449. .nohotkey:
  450.         popad
  451.  
  452.         cmp     [keyboard_mode], 0; return from keymap
  453.         jne     .scancode
  454.        
  455.         test    bh, bh
  456.         jnz     .exit.irq1
  457.        
  458.         test    bl, bl
  459.         jz      .exit.irq1
  460.  
  461.         test    [kb_state], VKEY_NUMLOCK
  462.         jz      .dowrite
  463.        
  464.         cmp     cl, 0xE0
  465.         jz      .dowrite
  466.        
  467.         cmp     ch, 55
  468.         jnz     @f
  469.        
  470.         mov     bl, 0x2A        ;*
  471.         jmp     .dowrite
  472. ;--------------------------------------
  473. @@:
  474.         cmp     ch, 71
  475.         jb      .dowrite
  476.        
  477.         cmp     ch, 83
  478.         ja      .dowrite
  479.        
  480.         movzx   eax, ch
  481.         mov     bl, [numlock_map + eax - 71]
  482.         jmp     .dowrite
  483. ;--------------------------------------
  484. .scancode:
  485.         mov     bl, ch
  486. .dowrite:
  487.         movzx   eax, byte[KEY_COUNT]
  488.         cmp     al, 120
  489.         jae     .exit.irq1
  490.         inc     eax
  491.         mov     [KEY_COUNT], al
  492.         mov     [KEY_COUNT+eax], bl
  493. .exit.irq1:
  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. proc check_lights_state_has_work?
  530.         mov     al, [kb_lights]
  531.         cmp     al, [old_kb_lights]
  532.         ret
  533. endp
  534.  
  535. check_lights_state:
  536.         call    check_lights_state_has_work?
  537.         jz      .nothing
  538.         mov     [old_kb_lights], al
  539.         call    set_lights
  540. .nothing:
  541.         ret
  542. ;---------------------------------------------------------------------
  543. numlock_map:
  544.     db   0x37   ;Num 7
  545.     db   0x38   ;Num 8
  546.     db   0x39   ;Num 9
  547.     db   0x2D   ;Num -
  548.     db   0x34   ;Num 4
  549.     db   0x35   ;Num 5
  550.     db   0x36   ;Num 6
  551.     db   0x2B   ;Num +
  552.     db   0x31   ;Num 1
  553.     db   0x32   ;Num 2
  554.     db   0x33   ;Num 3
  555.     db   0x30   ;Num 0
  556.     db   0x2E   ;Num .
  557. ;---------------------------------------------------------------------
  558.