diff options
author | Benji Dial <benji6283@gmail.com> | 2021-03-04 19:55:23 -0500 |
---|---|---|
committer | Benji Dial <benji6283@gmail.com> | 2021-03-04 19:55:23 -0500 |
commit | 5e5e524f08ad653a7bf5d6e97f3a49f6c27d08fa (patch) | |
tree | 6ac8f6bfb0b4bee7edcb47adf1dd88c6c73fc49a /src/kernel/kbd.c | |
parent | 406af09ade55553e2b064506c3ba3c89bd965d73 (diff) | |
download | portland-os-5e5e524f08ad653a7bf5d6e97f3a49f6c27d08fa.tar.gz |
tweaking ps/2 driver and wm bindings
Diffstat (limited to 'src/kernel/kbd.c')
-rw-r--r-- | src/kernel/kbd.c | 321 |
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; } |