Subversion Repositories Kolibri OS

Rev

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

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