#include "keyboard.h" #include 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, KB_KPSLASH, 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]; kp.character = 0; 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); scancode = scancode & 0x7F; if ((shift || caps) && !(shift && 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 && kp.pressed) { caps = !caps; updateLeds(); } else if (kp.command == KB_NUMLOCK && kp.pressed) { num = !num; updateLeds(); } else if (kp.command == KB_SCRLLOCK && kp.pressed) { 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'; } else if (kp.command == KB_KPSLASH) { kp.character = '/'; kp.command = 0; } // process keypress if (output != 0) { output->keyboardInput(kp, this); } else { // TODO: enable reading directly keypresses from keyboard device } } void keyboard::outputTo(vt *vt) { output = vt; } int keyboard::link(node* to, int mode) { if (mode == LM_OUTPUT_TO) { vt *v = to->as_vt(); if (v != 0) { outputTo(v); return 0; } } return E_NOT_IMPLEMENTED; }