9 kbListener kbList
[255] = {0};
11 static unsigned int kbd_state
= KBD_NUMLOCK_STATE
, kbd_led_state
= 0;
13 unsigned char lowercase
[128] =
15 0,0,'1','2','3','4','5','6','7','8','9','0','-','+','\b','\t','q','w','e','r','t','y','u','i','o','p','[',']','\n',
16 0,'a','s','d','f','g','h','j','k','l',';','\'','`',0,'\\','z','x','c','v','b','n','m',',','.','/',0,0,0,' ',0,
18 [59] = K_F1
, [60] = K_F2
, [61] = K_F3
, [62] = K_F4
, [63] = K_F5
, [64] = K_F6
, [65] = K_F7
,
19 [66] = K_F8
, [67] = K_F9
, [68] = K_F10
, [69] = K_F11
, [70] = K_F12
,
20 [72] = K_UP
, [75] = K_LEFT
, [77] = K_RIGHT
, [80] = K_DOWN
,
23 unsigned char uppercase
[128] =
25 0,0,'!','@','#','$','%','^','&','*','(',')','_','+','\b','\t','Q','W','E','R','T','Y','U','I','O','P','[',']','\n',
26 0,'A','S','D','F','G','H','J','K','L',':','"','~',0,'|','Z','X','C','V','B','N','M','<','>','?',0,0,0,' ',0,
28 [59] = K_F1
, [60] = K_F2
, [61] = K_F3
, [62] = K_F4
, [63] = K_F5
, [64] = K_F6
, [65] = K_F7
,
29 [66] = K_F8
, [67] = K_F9
, [68] = K_F10
, [69] = K_F11
, [70] = K_F12
,
30 [72] = K_UP
, [75] = K_LEFT
, [77] = K_RIGHT
, [80] = K_DOWN
,
33 // Wait for the keyboard to be ready
39 } while (status
& 0x2);
43 void kb_set_leds(int led_states
)
45 trace("kb_set_leds\n");
47 // Tell the keyboard controller that we want to modify the LEDs
50 outb(0x60, (led_states
/ KBD_CAPSLOCK_STATE
) & 0x7);
52 kbd_led_state
= led_states
;
55 /* Handles the keyboard interrupt */
56 static void kb_int_handler(int vector
, struct interrupt_stack
*is
)
58 uint8_t new_scan_code
= inb(0x60);
63 switch(new_scan_code
) {
65 kbd_state
|= KBD_CTRL_STATE
;
68 kbd_state
&= ~KBD_CTRL_STATE
;
72 kbd_state
|= KBD_ALT_STATE
;
75 kbd_state
&= ~KBD_ALT_STATE
;
78 case 58: /* CAPS LOCK */
79 kbd_state
^= KBD_CAPSLOCK_STATE
;
82 case 69: /* NUM LOCK */
83 kbd_state
^= KBD_NUMLOCK_STATE
;
86 case 70: /* SCROLL LOCK */
87 kbd_state
^= KBD_SCROLLLOCK_STATE
;
92 kbd_state
|= KBD_SHIFT_STATE
;
96 kbd_state
&= ~KBD_SHIFT_STATE
;
100 /* keep parsing if new_scan_code is not a break code */
101 if (!(new_scan_code
& 0x80))
103 new_char
= (kbd_state
& KBD_SHIFT_STATE
? uppercase
: lowercase
)
108 // virtual terminal switching
109 // this isn't really the place to do it...
110 if (kbd_state
& KBD_ALT_STATE
){
111 if (new_char
>= '1' && new_char
<= '4'){
113 vt
= get_vterm(new_char
- '1');
122 /* distribute new_char to our listeners */
123 for (x
= 0; x
< listpos
; x
++)
132 /* if our saved led state does not match our new state, change some lights =) */
133 if ((kbd_state
& (KBD_CAPSLOCK_STATE
| KBD_NUMLOCK_STATE
| KBD_SCROLLLOCK_STATE
))
135 kb_set_leds(kbd_state
& (KBD_CAPSLOCK_STATE
| KBD_NUMLOCK_STATE
| KBD_SCROLLLOCK_STATE
));
138 /* Acknowledge the IRQ, pretty much tells the PIC that we can accept >= priority IRQs now. */
142 void keyboard_init(void)
144 interrupt_set_handler(irq_to_int(1), &kb_int_handler
);
148 void keyboard_register_listener(kbListener nlist
)
150 kbList
[listpos
++] = nlist
;