diff options
Diffstat (limited to 'src/kernel/dev/keyboard.cpp')
-rw-r--r-- | src/kernel/dev/keyboard.cpp | 150 |
1 files changed, 150 insertions, 0 deletions
diff --git a/src/kernel/dev/keyboard.cpp b/src/kernel/dev/keyboard.cpp new file mode 100644 index 0000000..479996d --- /dev/null +++ b/src/kernel/dev/keyboard.cpp @@ -0,0 +1,150 @@ +#include "keyboard.h" + +#include <ui/vt.h> + +int ctrlkeys[] = { +/* 0x00 */ 0, KB_ESCAPE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, KB_BACKSPACE, KB_TAB, +/* 0x10 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, KB_ENTER, KB_LCTRL, 0, 0, +/* 0x20 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, KB_LSHIFT, 0, 0, 0, 0, 0, +/* 0x30 */ 0, 0, 0, 0, 0, 0, KB_RSHIFT, 0, KB_ALT, 0, KB_CAPSLOCK, KB_F1, KB_F2, KB_F3, KB_F4, KB_F5, +/* 0x40 */ KB_F6, KB_F7, KB_F8, KB_F9, KB_F10, KB_NUMLOCK, KB_SCRLLOCK, KB_KPHOME, KB_KPUP, KB_KPPGUP, 0, KB_KPLEFT, KB_KP5, KB_KPRIGHT, 0, KB_KPEND, +/* 0x50 */ KB_KPDOWN, KB_KPPGDOWN, KB_KPINS, KB_KPDEL, KB_SYSREQ, 0, 0, KB_F11, KB_F12, 0, 0, 0, 0, 0, 0, 0, +/* 0x60 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +/* 0x70 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +/* 0x80 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +/* 0x90 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, KB_ENTER, KB_RCTRL, 0, 0, +/* 0xA0 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +/* 0xB0 */ 0, 0, 0, 0, 0, 0, 0, KB_PRTSCN, KB_ALTGR, 0, 0, 0, 0, 0, 0, 0, +/* 0xC0 */ 0, 0, 0, 0, 0, 0, 0, KB_HOME, KB_UP, KB_PGUP, 0, KB_LEFT, 0, KB_RIGHT, 0, KB_END, +/* 0xD0 */ KB_DOWN, KB_PGDOWN, KB_INS, KB_DEL, 0, 0, 0, 0, 0, 0, 0, KB_LSUPER, KB_RSUPER, KB_MENU, 0, 0, +/* 0xE0 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +/* 0xF0 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +static keymap default_km = { + { // normal + /* 0x00 */ 0, 0, '&', L'é', '"', '\'', '(', '-', L'è', '_', L'ç', L'à', ')', '=', 0, 0, + /* 0x10 */ 'a', 'z', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '^', '$', 0, 0, 'q', 's', + /* 0x20 */ 'd', 'f', 'g', 'h', 'j', 'k', 'l', 'm', L'ù', L'²', 0, '*', 'w', 'x', 'c', 'v', + /* 0x30 */ 'b', 'n', ',', ';', ':', '!', 0, '*', 0, ' ', 0, 0, 0, 0, 0, 0, + /* 0x40 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '-', 0, 0, 0, '+', 0, + /* 0x50 */ 0, 0, 0, 0, 0, 0, '<', 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 0x60 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 0x70 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }, + { // shift + /* 0x00 */ 0, 0, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', L'°', '+', 0, 0, + /* 0x10 */ 'A', 'Z', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', L'¨', L'£', 0, 0, 'Q', 'S', + /* 0x20 */ 'D', 'F', 'G', 'H', 'J', 'K', 'L', 'M', '%', '~', 0, L'µ', 'W', 'X', 'C', 'V', + /* 0x30 */ 'B', 'N', '?', '.', '/', L'§', 0, '*', 0, ' ', 0, 0, 0, 0, 0, 0, + /* 0x40 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '-', 0, 0, 0, '+', 0, + /* 0x50 */ 0, 0, 0, 0, 0, 0, '>', 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 0x60 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 0x70 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }, + { // caps + /* 0x00 */ 0, 0, '&', L'É', '"', '\'', '(', '-', L'È', '_', L'Ç', L'À', ')', '=', 0, 0, + /* 0x10 */ 'A', 'Z', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', L'¨', '$', 0, 0, 'Q', 'S', + /* 0x20 */ 'D', 'F', 'G', 'H', 'J', 'K', 'L', 'M', L'Ù', L'²', 0, '*', 'W', 'X', 'C', 'V', + /* 0x30 */ 'B', 'N', ',', ';', ':', '!', 0, '*', 0, ' ', 0, 0, 0, 0, 0, 0, + /* 0x40 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '-', 0, 0, 0, '+', 0, + /* 0x50 */ 0, 0, 0, 0, 0, 0, '>', 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 0x60 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 0x70 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }, + { // alt gr + /* 0x00 */ 0, 0, L'¹', '~', '#', '{', '[', '|', '`', '\\', '^', '@', ']', '}', 0, 0, + /* 0x10 */ L'æ', L'«', L'€', L'¶', L'ŧ', L'←', L'↓', L'→', + L'ø', L'þ', L'¨', L'¤', 0, 0, '@', L'ß', + /* 0x20 */ L'ð', L'đ', L'ŋ', L'ħ', 'j', L'ĸ', L'ł', L'µ', + '^', L'¬', 0, '`', L'ł', L'»', L'¢', L'“', + /* 0x30 */ L'”', 'n', L'´', ';', L'·', '!', 0, '*', 0, ' ', 0, 0, 0, 0, 0, 0, + /* 0x40 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '-', 0, 0, 0, '+', 0, + /* 0x50 */ 0, 0, 0, 0, 0, 0, '|', 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 0x60 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 0x70 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + }, + { // shift + alt gr + /* 0x00 */ 0, 0, L'¡', L'⅛', L'£', '$', L'⅜', L'⅝', L'⅞', L'™', L'±', L'°', L'¿', L'˛', 0, 0, + /* 0x10 */ L'Æ', '<', L'¢', L'®', L'Ŧ', L'¥', L'↑', L'ı', L'Ø', L'Þ', L'°', L'¯', 0, 0, L'Ω', L'§', + /* 0x20 */ L'Ð', L'ª', L'Ŋ', L'Ħ', 'J', '&', L'Ł', L'º', L'ˇ', L'¬', 0, L'˘', L'Ł', '>', L'©', L'‘', + /* 0x30 */ L'’', 'N', L'˝', L'×', L'÷', L'˙', 0, '*', 0, ' ', 0, 0, 0, 0, 0, 0, + /* 0x40 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '-', 0, 0, 0, '+', 0, + /* 0x50 */ 0, 0, 0, 0, 0, 0, L'¦', 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 0x60 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 0x70 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + } +}; + +keyboard::keyboard(node *parent) : node(parent, FT_DEV) { + dev_type = DT_KEYBOARD; + + km = &default_km; + num = true; + caps = scroll = false; + shift = altgr = alt = ctrl = false; +} + +void keyboard::handle(int scancode, bool pressed) { + keypress kp; + kp.scancode = scancode; + kp.pressed = pressed; + kp.command = ctrlkeys[scancode]; + if (kp.command == 0) kp.command = ctrlkeys[scancode & 0x7F]; + + if (kp.command == 0) { + kp.command = (alt ? KB_CMD_ALT : 0) | (ctrl ? KB_CMD_CTRL : 0); + if (shift xor caps) { + if (altgr) { + kp.character = km->shiftaltgr[scancode]; + } else { + if (shift) { + kp.character = km->shift[scancode]; + } else { + kp.character = km->caps[scancode]; + } + } + } else { + if (altgr) { + kp.character = km->altgr[scancode]; + } else { + kp.character = km->normal[scancode]; + } + } + } else if (kp.command >= KB_KPDEL && kp.command <= KB_KPPGUP && num) { + if (kp.command == KB_KPDEL) { + kp.character = '.'; + } else { + kp.character = '0' + kp.command - KB_KPINS; + } + kp.command = (alt ? KB_CMD_ALT : 0) | (ctrl ? KB_CMD_CTRL : 0); + } else if (kp.command == KB_ALT) { + alt = pressed; + } else if (kp.command == KB_ALTGR) { + altgr = pressed; + } else if (kp.command == KB_LCTRL || kp.command == KB_RCTRL) { + ctrl = pressed; + } else if (kp.command == KB_LSHIFT || kp.command == KB_RSHIFT) { + shift = pressed; + } else if (kp.command == KB_CAPSLOCK) { + caps = !caps; + updateLeds(); + } else if (kp.command == KB_NUMLOCK) { + num = !num; + updateLeds(); + } else if (kp.command == KB_SCRLLOCK) { + scroll = !scroll; + updateLeds(); + } else if (kp.command == KB_TAB) { + kp.character = '\t'; + } else if (kp.command == KB_BACKSPACE) { + kp.character = '\b'; + } else if (kp.command == KB_ENTER) { + kp.character = '\n'; + } + + // process keypress + if (kp.character && kp.pressed) { + ke_vt->put(kp.character); + } +} |