Luna/kernel/src/misc/Scancodes.cpp

168 lines
3.9 KiB
C++

#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];
}