#include #include #include #ifdef __TESTING__ #include #include #endif #include #include bool is_shift_down = false; queue kb_cmd_queue; // current plan is to create a a multi d array // // // 16 entries each for each scan code... so // 0x01..0x0F (15)/ this is the top row, so esc - 1..0, etc // 0x10..0x1F (16) ... // 0x20..0x2F ... // these arrays will keep a 0/1 flag to see if these keys are pressed // as a stort of state machine // this will also let us tell multiple keys pressed // // another more simple version, which i could start with // // is do a Single character as currently pressed // and a bitflag we can mask for leftshift, leftctrl, right shift, right ctrl, alt, etc being pressed down // // // struct keyboard_state keyb_state; void init_kb(void) { #ifdef __TESTING__ puts("Initializing keyboard driver!"); #endif keyb_state.ready = false; init_queue(&kb_cmd_queue); keyb_state.leds = 0; keyb_state.flags = 0; queue_kb_command(KEYB_CMD_ENABLE_SCANNING); queue_kb_command(KEYB_CMD_SET_TYPEMATIC); queue_kb_command(0x1F); send_kb_commands(); keyb_state.ready = true; #ifdef __TESTING__ puts("Initialized keyboard driver!"); #endif } void queue_kb_command(uint8_t command) {enqueue(&kb_cmd_queue, command);} void send_kb_commands(void) { int i; uint8_t resp, cmd; while (!queue_is_empty(&kb_cmd_queue)) { cmd = queue_peek(&kb_cmd_queue); for (i = 0; i < KEYB_CMD_RETRIES; i++) { outb(KEYB_PORT, cmd); io_wait(); resp = inb(KEYB_PORT); io_wait(); switch(resp) { case KEYB_RESP_ACK: break; case KEYB_RESP_RESEND: continue; default: break; } } dequeue(&kb_cmd_queue); } } kb_key_code_t decode_scancode(uint8_t scancode) {return (kb_key_code_t) scancode;} key_press_t do_keypress(kb_key_code_t keycode) { key_press_t packet; if (!keyb_state.ready) { packet.key_code = KEY_NONE; return packet; } if (keycode >= KEY_ESC_R) { packet.key_code = keycode - KEY_PRESS_RELEASE_DIFF; packet.release = true; } else { packet.key_code = keycode; packet.release = false; } switch (keycode) { case KEY_LEFT_SHIFT: keyb_state.flags |= (STATUS_FLAG_LSHIFT); break; case KEY_LEFT_SHIFT_R: keyb_state.flags &= ~(STATUS_FLAG_LSHIFT); break; case KEY_RIGHT_SHIFT: keyb_state.flags |= (STATUS_FLAG_RSHIFT); break; case KEY_RIGHT_SHIFT_R: keyb_state.flags &= ~(STATUS_FLAG_RSHIFT); break; case KEY_LEFT_CTRL: keyb_state.flags |= (STATUS_FLAG_CTRL); break; case KEY_LEFT_CTRL_R: keyb_state.flags &= ~(STATUS_FLAG_CTRL); break; case KEY_LEFT_ALT: keyb_state.flags |= (STATUS_FLAG_ALT); break; case KEY_LEFT_ALT_R: keyb_state.flags &= ~(STATUS_FLAG_ALT); break; case KEY_CAPSLOCK: keyb_state.flags ^= (STATUS_FLAG_CAPS_LOCK); keyb_state.leds ^= (KEYB_LED_CAP_LCK); queue_kb_command(KEYB_CMD_SET_LEDS); queue_kb_command(keyb_state.leds); break; case KEY_NUMLOCK: keyb_state.flags ^= (STATUS_FLAG_NUM_LOCK); keyb_state.leds ^= (KEYB_LED_NUM_LCK); queue_kb_command(KEYB_CMD_SET_LEDS); queue_kb_command(keyb_state.leds); break; case KEY_SCROLLLOCK: keyb_state.flags ^= (STATUS_FLAG_NUM_LOCK); keyb_state.leds ^= (KEYB_LED_SCRL_LCK); queue_kb_command(KEYB_CMD_SET_LEDS); queue_kb_command(keyb_state.leds); break; // case KEY_INSERT TODO: this shit baby default: break; } send_kb_commands(); packet.flags = keyb_state.flags; return packet; } /** * shift * ctrl * alt * caps * num * scroll */