Subversion Repositories Kolibri OS

Rev

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

  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;;                                                              ;;
  3. ;; Copyright (C) KolibriOS team 2004-2022. 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: 9828 $
  9.  
  10.  
  11. VKEY_LSHIFT   = 00000000_00000001b
  12. VKEY_RSHIFT   = 00000000_00000010b
  13. VKEY_LCONTROL = 00000000_00000100b
  14. VKEY_RCONTROL = 00000000_00001000b
  15. VKEY_LALT     = 00000000_00010000b
  16. VKEY_RALT     = 00000000_00100000b
  17. VKEY_CAPSLOCK = 00000000_01000000b
  18. VKEY_NUMLOCK  = 00000000_10000000b
  19. VKEY_SCRLOCK  = 00000001_00000000b
  20. VKEY_LWIN     = 00000010_00000000b
  21. VKEY_RWIN     = 00000100_00000000b
  22.  
  23. VKEY_SHIFT    = VKEY_LSHIFT + VKEY_RSHIFT
  24. VKEY_CONTROL  = VKEY_LCONTROL + VKEY_RCONTROL
  25. VKEY_ALT      = VKEY_LALT + VKEY_RALT
  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[thread_count]; top window process
  107.         movzx   eax, word[WIN_POS + eax*2]
  108.         shl     eax, BSF sizeof.APPDATA
  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[thread_count]; top window process
  198.         movzx   eax, word[WIN_POS + eax*2]
  199.         shl     eax, BSF sizeof.APPDATA
  200.         mov     al, [SLOT_BASE + eax + APPDATA.keyboard_mode]
  201.         mov     [keyboard_mode], al
  202.        
  203.         in      al, 0x60
  204. ;--------------------------------------
  205. send_scancode:
  206.         ;DEBUGF  1, "K : Scan code: %x \n", al
  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.         cmp     cl, 0xE0        ; extended keycode
  462.         jne     @f
  463.  
  464.         cmp     ch, 53
  465.         jne     .dowrite
  466.        
  467.         mov     bl, '/'
  468.         jmp     .dowrite
  469. @@:
  470.  
  471.         cmp     ch, 55
  472.         jne     @f
  473.        
  474.         mov     bl, '*'
  475.         jmp     .dowrite
  476. @@:
  477.  
  478.         cmp     ch, 74
  479.         jne     @f
  480.        
  481.         mov     bl, '-'
  482.         jmp     .dowrite
  483. @@:
  484.  
  485.         cmp     ch, 78
  486.         jne     @f
  487.        
  488.         mov     bl, '+'
  489.         jmp     .dowrite
  490. @@:
  491.  
  492.         test    [kb_state], VKEY_NUMLOCK
  493.         jz      .dowrite
  494.  
  495.         cmp     ch, 71
  496.         jb      .dowrite
  497.        
  498.         cmp     ch, 83
  499.         ja      .dowrite
  500.        
  501.         movzx   eax, ch
  502.         mov     bl, [numlock_map + eax - 71]
  503.         jmp     .dowrite
  504. ;--------------------------------------
  505. .scancode:
  506.         mov     bl, ch
  507. .dowrite:
  508.         movzx   eax, byte[KEY_COUNT]
  509.         cmp     al, 120
  510.         jae     .exit.irq1
  511.         inc     eax
  512.         mov     [KEY_COUNT], al
  513. ; store ascii or scancode
  514.         mov     [KEY_BUFF + eax -1], bl
  515. ; store original scancode
  516.         add     eax, 120+2
  517.         push    ecx
  518.         cmp     [keyboard_mode], 0; return from keymap
  519.         je      @f
  520.  
  521.         xor     ch, ch
  522. @@:
  523.         mov     [KEY_BUFF + eax -1], ch
  524.         pop     ecx
  525.         sub     eax, 120+2
  526. .exit.irq1:
  527.         ret
  528. ;---------------------------------------------------------------------
  529. set_lights:
  530.         push    ebx esi
  531.         mov     ecx, keyboard_list_mutex
  532.         call    mutex_lock
  533.         mov     esi, keyboards
  534. .loop:
  535.         mov     esi, [esi + KEYBOARD.next]
  536.         cmp     esi, keyboards
  537.         jz      .done
  538.         mov     eax, [esi + KEYBOARD.functions]
  539.         cmp     dword [eax], KBDFUNC.setlights
  540.         jbe     .loop
  541.         mov     eax, [eax + KBDFUNC.setlights]
  542.         test    eax, eax
  543.         jz      .loop
  544.         stdcall eax, [esi + KEYBOARD.userdata], dword [kb_lights]
  545.         jmp     .loop
  546. .done:
  547.         mov     ecx, keyboard_list_mutex
  548.         call    mutex_unlock
  549.         pop     esi ebx
  550.         ret
  551.  
  552. ps2_set_lights:
  553.         stdcall disable_irq, 1
  554.         mov     al, 0xED
  555.         call    kb_write_wait_ack
  556.         mov     al, [esp+8]
  557.         call    kb_write_wait_ack
  558.         stdcall enable_irq, 1
  559.         ret     8
  560.  
  561. ;// mike.dld ]
  562. proc check_lights_state_has_work?
  563.         mov     al, [kb_lights]
  564.         cmp     al, [old_kb_lights]
  565.         ret
  566. endp
  567.  
  568. check_lights_state:
  569.         call    check_lights_state_has_work?
  570.         jz      .nothing
  571.         mov     [old_kb_lights], al
  572.         call    set_lights
  573. .nothing:
  574.         ret
  575. ;---------------------------------------------------------------------
  576. iglobal
  577. numlock_map db '789-456+1230.'
  578. endg
  579. ;---------------------------------------------------------------------
  580.