#include "misc/Scancodes.h" #define SCANCODE_EXTENDED 0xE0 bool scancode_filter_released(unsigned char* scancode) { if (*scancode > 0x80) { *scancode -= 0x80; return true; } return false; } static bool next_key_ignored = false; // FIXME: Do not ignore extended scancodes. static bool left_shifted = false; static bool right_shifted = false; static bool capslock = false; static bool should_shift() { if (capslock) return !(left_shifted || right_shifted); return left_shifted || right_shifted; } #define SCANCODE_LEFT_SHIFT 0x2A #define SCANCODE_RIGHT_SHIFT 0x36 #define SCANCODE_CAPS_LOCK 0x3A #define SCANCODE_LEFT_CONTROL 0x1D #define SCANCODE_TAB 0x0F #define SCANCODE_LEFT_ALT 0x38 #define SCANCODE_F11 0x57 #define SCANCODE_F12 0x58 static bool should_ignore_key(char scancode) { return (scancode > 0x3A && scancode < 0x47) || scancode == SCANCODE_LEFT_CONTROL || scancode == SCANCODE_TAB || scancode == SCANCODE_LEFT_ALT || scancode == SCANCODE_F11 || scancode == SCANCODE_F12; } char keys_normal[] = { '\0', '\1', // escape '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', '\b', '\0', // tab 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']', '\n', '\0', // left ctrl 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '\'', '`', '\0', // left shift '\\', 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/', '\0', // right shift '*', // keypad * '\0', // left alt ' ', '\0', // caps lock '\0', // f1 '\0', // f2 '\0', // f3 '\0', // f4 '\0', // f5 '\0', // f6 '\0', // f7 '\0', // f8 '\0', // f9 '\0', // f10 '\0', // num lock '\0', // scroll lock '7', // keypad 7 '8', // keypad 8 '9', // keypad 9 '-', // keypad - '4', // keypad 4 '5', // keypad 5 '6', // keypad 6 '+', // keypad + '1', // keypad 1 '2', // keypad 2 '3', // keypad 3 '0', // keypad 0 '.', // keypad . }; char keys_shifted[] = { '\0', '\1', // escape '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+', '\b', '\0', // tab 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '{', '}', '\n', '\0', // left ctrl 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', '"', '~', '\0', // left shift '|', 'Z', 'X', 'C', 'V', 'B', 'N', 'M', '<', '>', '?', '\0', // right shift '*', // keypad * '\0', // left alt ' ', '\0', // caps lock '\0', // f1 '\0', // f2 '\0', // f3 '\0', // f4 '\0', // f5 '\0', // f6 '\0', // f7 '\0', // f8 '\0', // f9 '\0', // f10 '\0', // num lock '\0', // scroll lock '7', // keypad 7 '8', // keypad 8 '9', // keypad 9 '-', // keypad - '4', // keypad 4 '5', // keypad 5 '6', // keypad 6 '+', // keypad + '1', // keypad 1 '2', // keypad 2 '3', // keypad 3 '0', // keypad 0 '.', // keypad . }; char translate_scancode(unsigned char scancode, bool* ignore) { if (next_key_ignored) { next_key_ignored = false; *ignore = true; return 0; } if (scancode == SCANCODE_EXTENDED) { next_key_ignored = true; *ignore = true; return 0; } bool released = scancode_filter_released(&scancode); if (scancode == SCANCODE_CAPS_LOCK) { if (!released) { capslock = !capslock; } *ignore = true; return 0; } if (scancode == SCANCODE_LEFT_SHIFT) { left_shifted = !released; *ignore = true; return 0; } if (scancode == SCANCODE_RIGHT_SHIFT) { right_shifted = !released; *ignore = true; return 0; } if (released || should_ignore_key(scancode)) { *ignore = true; return 0; } *ignore = false; if (should_shift()) { return keys_shifted[scancode]; } return keys_normal[scancode]; }