summaryrefslogtreecommitdiff
path: root/src/kernel/kbd.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/kernel/kbd.c')
-rw-r--r--src/kernel/kbd.c321
1 files changed, 158 insertions, 163 deletions
diff --git a/src/kernel/kbd.c b/src/kernel/kbd.c
index 004706f..ce25397 100644
--- a/src/kernel/kbd.c
+++ b/src/kernel/kbd.c
@@ -125,185 +125,180 @@ void init_kbd() {
drives->free_file(drives, stf);
}
-static uint8_t last_code_byte = 0;
-
-static inline uint8_t get_next_code_byte() {
- uint8_t cb;
- do
- cb = inb(PS2_DATA);
- while (cb == last_code_byte);
- last_code_byte = cb;
- return cb;
-}
-
-static inline uint8_t get_wait() {
- for (uint32_t i = 0; i < 1000000; ++i)
+static inline uint8_t get_next_byte() {
+ while (!(inb(PS2_CMD) & PS2S_CODE_READY))
;
return inb(PS2_DATA);
}
-static enum key_modifiers_t keymods = 0;
+enum key_modifiers_t keymods = 0;
bool last_mouse_one = false;
bool last_mouse_two = false;
bool last_mouse_mid = false;
+static const char *const hextab = "0123456789abcdef";
+
enum kbd_isr_result on_kbd_isr() {
- uint8_t code;
- while ((code = inb(PS2_CMD)) & PS2S_CODE_READY) {
- if (code & PS2S_FROM_MOUSE) {
- const uint8_t first = get_wait();
- const uint8_t x = get_wait();
- const uint8_t y = get_wait();
-
- if (x || y || (first & (MFB_X_SIGN | MFB_Y_SIGN)))
- move_mouse_by((first & MFB_Y_SIGN) ? 256 - y : -y,
- (first & MFB_X_SIGN) ? x - 256 : x);
-
- const bool mouse_one = first & MFB_BUTTON_ONE;
- const bool mouse_two = first & MFB_BUTTON_TWO;
- const bool mouse_mid = first & MFB_BUTTON_MID;
-
- if (mouse_one && !last_mouse_one)
- mouse_button(LEFT, false);
- if (mouse_two && !last_mouse_two)
- mouse_button(RIGHT, false);
- if (mouse_mid && !last_mouse_mid)
- mouse_button(MIDDLE, false);
-
- if (!mouse_one && last_mouse_one)
- mouse_button(LEFT, true);
- if (!mouse_two && last_mouse_two)
- mouse_button(RIGHT, true);
- if (!mouse_mid && last_mouse_mid)
- mouse_button(MIDDLE, true);
-
- last_mouse_one = mouse_one;
- last_mouse_two = mouse_two;
- last_mouse_mid = mouse_mid;
- continue;
- }
+ if (inb(PS2_CMD) & PS2S_FROM_MOUSE) {
+ const uint8_t first = get_next_byte();
+ const uint8_t x = get_next_byte();
+ const uint8_t y = get_next_byte();
+
+ if (x || y || (first & (MFB_X_SIGN | MFB_Y_SIGN)))
+ move_mouse_by((first & MFB_Y_SIGN) ? 256 - y : -y,
+ (first & MFB_X_SIGN) ? x - 256 : x);
+
+ const bool mouse_one = first & MFB_BUTTON_ONE;
+ const bool mouse_two = first & MFB_BUTTON_TWO;
+ const bool mouse_mid = first & MFB_BUTTON_MID;
+
+ if (mouse_one && !last_mouse_one)
+ mouse_button(LEFT, false);
+ if (mouse_two && !last_mouse_two)
+ mouse_button(RIGHT, false);
+ if (mouse_mid && !last_mouse_mid)
+ mouse_button(MIDDLE, false);
+
+ if (!mouse_one && last_mouse_one)
+ mouse_button(LEFT, true);
+ if (!mouse_two && last_mouse_two)
+ mouse_button(RIGHT, true);
+ if (!mouse_mid && last_mouse_mid)
+ mouse_button(MIDDLE, true);
+
+ last_mouse_one = mouse_one;
+ last_mouse_two = mouse_two;
+ last_mouse_mid = mouse_mid;
+ return NORMAL;
+ }
- last_code_byte = 0;
- uint8_t code[256];
- uint8_t code_i = 0;
- sub_table:
- code[code_i] = get_next_code_byte();
- const uint8_t *table;
- for (uint32_t i = 0; i < n_scantabs; ++i) {
- if (scantabs[i].prefix_length != code_i)
- continue;
- for (uint8_t j = 0; j < code_i; ++j)
- if (scantabs[i].prefix[j] != code[j])
- goto next_table;
- table = scantabs[i].scantab;
- goto got_table;
- next_table:;
- }
- PANIC("Couldn't find scantable");
-
- got_table:;
- bool is_up = false;
- flipped_table:;
- uint8_t entry = table[code[code_i]];
- switch (entry) {
- case ST_ILLEGAL:
- PANIC("Illegal scancode encountered");
- case ST_SUBTABLE:
- ++code_i;
- goto sub_table;
- case ST_FLIP:
- if (is_up)
- PANIC("Recursive flip in scantable");
- table += 0x100;
- is_up = true;
- goto flipped_table;
- case ST_SKIP:
+ uint8_t code[256];
+ uint8_t code_i = 0;
+sub_table:
+ code[code_i] = get_next_byte();
+ const uint8_t *table;
+ for (uint32_t i = 0; i < n_scantabs; ++i) {
+ if (scantabs[i].prefix_length != code_i)
continue;
+ for (uint8_t j = 0; j < code_i; ++j)
+ if (scantabs[i].prefix[j] != code[j])
+ goto next_table;
+ table = scantabs[i].scantab;
+ goto got_table;
+ next_table:;
+ }
+ PANIC("Couldn't find scantable");
+
+got_table:;
+ bool is_up = false;
+flipped_table:;
+ uint8_t entry = table[code[code_i]];
+ switch (entry) {
+ char code_str[256 * 3 + 1];
+ case ST_ILLEGAL:
+ for (uint16_t i = 0; i <= code_i; ++i) {
+ code_str[i * 3] = ' ';
+ code_str[i * 3 + 1] = hextab[code[i] >> 4];
+ code_str[i * 3 + 2] = hextab[code[i] & 0xf];
}
+ code_str[(code_i + 1) * 3] = '\0';
+ logf(LOG_ERROR, "Illegal scancode encountered:%s. Ignoring.", code_str);
+ return NORMAL;
+ case ST_SUBTABLE:
+ ++code_i;
+ goto sub_table;
+ case ST_FLIP:
+ if (is_up)
+ PANIC("Recursive flip in scantable");
+ table += 0x100;
+ is_up = true;
+ goto flipped_table;
+ case ST_SKIP:
+ return NORMAL;
+ }
- switch ((enum key_id_t)entry) {
- case KEY_LEFT_SHIFT:
- if (is_up)
- keymods &= ~LSHIFT;
- else
- keymods |= LSHIFT;
- break;
- case KEY_RIGHT_SHIFT:
- if (is_up)
- keymods &= ~RSHIFT;
- else
- keymods |= RSHIFT;
- break;
- case KEY_LEFT_CONTROL:
- if (is_up)
- keymods &= ~LCTRL;
- else
- keymods |= LCTRL;
- break;
- case KEY_RIGHT_CONTROL:
- if (is_up)
- keymods &= ~RCTRL;
- else
- keymods |= RCTRL;
- break;
- case KEY_LEFT_ALT:
- if (is_up)
- keymods &= ~LALT;
- else
- keymods |= LALT;
- break;
- case KEY_RIGHT_ALT:
- if (is_up)
- keymods &= ~RALT;
- else
- keymods |= RALT;
- break;
- case KEY_LEFT_WIN:
- if (is_up)
- keymods &= ~LWIN;
- else
- keymods |= LWIN;
- break;
- case KEY_RIGHT_WIN:
- if (is_up)
- keymods &= ~RWIN;
- else
- keymods |= RWIN;
- break;
- case KEY_CAPS_LOCK:
- if (!is_up)
- keymods ^= CAPS;
- break;
- case KEY_NUM_LOCK:
- if (!is_up)
- keymods ^= NUM;
- break;
- case KEY_SCROLL_LOCK:
- if (!is_up)
- keymods ^= SCROLL;
- break;
- case KEY_INSERT:
- if (!is_up)
- keymods ^= INSERT;
- break;
- default:
- break;
- }
+ switch ((enum key_id_t)entry) {
+ case KEY_LEFT_SHIFT:
+ if (is_up)
+ keymods &= ~LSHIFT;
+ else
+ keymods |= LSHIFT;
+ break;
+ case KEY_RIGHT_SHIFT:
+ if (is_up)
+ keymods &= ~RSHIFT;
+ else
+ keymods |= RSHIFT;
+ break;
+ case KEY_LEFT_CONTROL:
+ if (is_up)
+ keymods &= ~LCTRL;
+ else
+ keymods |= LCTRL;
+ break;
+ case KEY_RIGHT_CONTROL:
+ if (is_up)
+ keymods &= ~RCTRL;
+ else
+ keymods |= RCTRL;
+ break;
+ case KEY_LEFT_ALT:
+ if (is_up)
+ keymods &= ~LALT;
+ else
+ keymods |= LALT;
+ break;
+ case KEY_RIGHT_ALT:
+ if (is_up)
+ keymods &= ~RALT;
+ else
+ keymods |= RALT;
+ break;
+ case KEY_LEFT_WIN:
+ if (is_up)
+ keymods &= ~LWIN;
+ else
+ keymods |= LWIN;
+ break;
+ case KEY_RIGHT_WIN:
+ if (is_up)
+ keymods &= ~RWIN;
+ else
+ keymods |= RWIN;
+ break;
+ case KEY_CAPS_LOCK:
+ if (!is_up)
+ keymods ^= CAPS;
+ break;
+ case KEY_NUM_LOCK:
+ if (!is_up)
+ keymods ^= NUM;
+ break;
+ case KEY_SCROLL_LOCK:
+ if (!is_up)
+ keymods ^= SCROLL;
+ break;
+ case KEY_INSERT:
+ if (!is_up)
+ keymods ^= INSERT;
+ break;
+ default:
+ break;
+ }
- if (!is_up && (entry == KEY_PAUSE) && (keymods & ALTS))
- return (keymods & SHIFTS) ? SHIFT_DUMP : DUMP;
+ if (!is_up && (entry == KEY_PAUSE) && (keymods & ALTS))
+ return (keymods & SHIFTS) ? SHIFT_DUMP : DUMP;
- if (!is_up && (entry == KEY_Q) && (keymods & WINS) && (keymods & SHIFTS))
- shutdown();
+ if (!is_up && (entry == KEY_Q) && (keymods & WINS) && (keymods & SHIFTS))
+ shutdown();
- on_action((struct window_action){
- .action_type = is_up ? KEY_UP : KEY_DOWN,
- .as_key = (struct key_packet){
- .key_id = entry,
- .modifiers = keymods
- }
- });
- }
+ on_action((struct window_action){
+ .action_type = is_up ? KEY_UP : KEY_DOWN,
+ .as_key = (struct key_packet){
+ .key_id = entry,
+ .modifiers = keymods
+ }
+ });
return NORMAL;
}