diff options
Diffstat (limited to 'Source/Kernel/DeviceManager')
-rw-r--r-- | Source/Kernel/DeviceManager/Kbd.ns.cpp | 197 | ||||
-rw-r--r-- | Source/Kernel/DeviceManager/Kbd.ns.h | 96 |
2 files changed, 293 insertions, 0 deletions
diff --git a/Source/Kernel/DeviceManager/Kbd.ns.cpp b/Source/Kernel/DeviceManager/Kbd.ns.cpp new file mode 100644 index 0000000..1743e0c --- /dev/null +++ b/Source/Kernel/DeviceManager/Kbd.ns.cpp @@ -0,0 +1,197 @@ +#include "Kbd.ns.h" +#include <DeviceManager/Dev.ns.h> +#include <Library/Vector.class.h> +#include <Devices/Keyboard/Keyboard.proto.h> +#include <VTManager/VirtualTerminal.class.h> + +namespace Kbd { + +//These are arbitrarily decided codes given to each scancode +u8int ctrlkeys[] = { +/* 0x00 */ 0, KBDC_ESCAPE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, KBDC_BACKSPACE, KBDC_TAB, +/* 0x10 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, KBDC_ENTER, KBDC_LEFTCTRL, 0, 0, +/* 0x20 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, KBDC_LEFTSHIFT, 0, 0, 0, 0, 0, +/* 0x30 */ 0, 0, 0, 0, 0, 0, KBDC_RIGHTSHIFT, 0, KBDC_ALT, 0, KBDC_CAPSLOCK, KBDC_F1, KBDC_F2, KBDC_F3, KBDC_F4, KBDC_F5, +/* 0x40 */ KBDC_F6, KBDC_F7, KBDC_F8, KBDC_F9, KBDC_F10, KBDC_NUMLOCK, KBDC_SCRLLOCK, KBDC_KPHOME, KBDC_KPUP, KBDC_KPPGUP, 0, KBDC_KPLEFT, KBDC_KP5, KBDC_KPRIGHT, 0, KBDC_KPEND, +/* 0x50 */ KBDC_KPDOWN, KBDC_KPPGDOWN, KBDC_KPINSERT, KBDC_KPDEL, KBDC_SYSREQ, 0, 0, KBDC_F11, KBDC_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, KBDC_ENTER, KBDC_RIGHTCTRL, 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, KBDC_KPSLASH, 0, KBDC_PRTSCN, KBDC_ALTGR, 0, 0, 0, 0, 0, 0, 0, +/* 0xC0 */ 0, 0, 0, 0, 0, 0, 0, KBDC_HOME, KBDC_UP, KBDC_PGUP, 0, KBDC_LEFT, 0, KBDC_RIGHT, 0, KBDC_END, +/* 0xD0 */ KBDC_DOWN, KBDC_PGDOWN, KBDC_INSERT, KBDC_DEL, 0, 0, 0, 0, 0, 0, 0, KBDC_LEFTSUP, KBDC_RIGHTSUP, KBDC_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 +}; + +wchar *keymapNormal = NULL, *keymapShift = NULL, *keymapAltgr = NULL, *keymapShiftAltgr = NULL; +u8int kbdstatus = 0; +VirtualTerminal *focusedVT = NULL; //This is the VT that must receive the character + +void process(keypress_t kp) { //This routine sends the information of a keypress to someone + /* String r("Key press "); + String n = String::number(kp.pressed); + r += n; + r += ", hascmd="; + n = String::number(kp.hascmd); + r += n; + r += ", cmd="; + n = String::number(kp.command); + r += n; + r += ", haschar="; + n = String::number(kp.haschar); + r += n; + r += ", char='"; + r += kp.character; + r += "'"; + DEBUG(r); */ + if (focusedVT != NULL) { + if (((kp.haschar and kp.character != 0) or (kp.hascmd and kp.command < 100)) and kp.pressed) { + focusedVT->keyPress(kp); + } + } +} + +void setFocus(VirtualTerminal* vt) { + focusedVT = vt; +} + +void setKeymap(wchar* kmNormal, wchar* kmShift, wchar* kmAltgr, wchar* kmShiftAltgr) { + keymapNormal = kmNormal; + keymapShift = kmShift; + keymapAltgr = kmAltgr; + keymapShiftAltgr = kmShiftAltgr; +} + +void updateLeds() { + Vector<Device*> kbds = Dev::findDevice("keyboard"); + for (u32int i = 0; i < kbds.size(); i++) { + ((Keyboard*)(kbds[i]))->updateLeds(kbdstatus); + } +} + +void keyPress(u8int scancode) { + keypress_t kp; + kp.pressed = true; + u8int cmd = ctrlkeys[scancode]; + scancode &= 0x7F; + if (cmd == 0) cmd = ctrlkeys[scancode]; + if (cmd == 0) { + kp.haschar = true; + kp.character = 0; + if ((kbdstatus & STATUS_ALT) or (kbdstatus & STATUS_CTRL)) { + kp.hascmd = true; + kp.command = kbdstatus & 0x0F; + } + if ((kbdstatus & STATUS_SHIFT) xor (kbdstatus & STATUS_CAPS)) { + if (kbdstatus & STATUS_ALTGR) { + if (keymapShiftAltgr != NULL) kp.character = keymapShiftAltgr[scancode]; + } else { + if (keymapShift != NULL) kp.character = keymapShift[scancode]; + } + } else { + if (kbdstatus & STATUS_ALTGR) { + if (keymapAltgr != NULL) kp.character = keymapAltgr[scancode]; + } else { + if (keymapNormal != NULL) kp.character = keymapNormal[scancode]; + } + } + } else if (cmd >= KBDC_KPINSERT and cmd <= KBDC_KPDEL and (kbdstatus & STATUS_NUM)) { + kp.haschar = true; + if ((kbdstatus & STATUS_ALT) or (kbdstatus & STATUS_CTRL)) { + kp.hascmd = true; + kp.command = kbdstatus & 0xF0; + } + if (cmd == KBDC_KPDEL) { + kp.character = (u32int)'.'; + } else { + kp.character = (u32int)'0' + (cmd - KBDC_KPINSERT); + } + } else if (cmd == KBDC_KPSLASH) { + kp.haschar = true; + if ((kbdstatus & STATUS_ALT) or (kbdstatus & STATUS_CTRL)) { + kp.hascmd = true; + kp.command = kbdstatus & 0xF0; + } + kp.character = (u32int)'/'; + } else if (cmd == KBDC_ALT) { + kbdstatus |= STATUS_ALT; + } else if (cmd == KBDC_ALTGR) { + kbdstatus |= STATUS_ALTGR; + } else if (cmd == KBDC_LEFTCTRL or cmd == KBDC_RIGHTCTRL) { + kbdstatus |= STATUS_CTRL; + } else if (cmd == KBDC_LEFTSHIFT or cmd == KBDC_RIGHTSHIFT) { + kbdstatus |= STATUS_SHIFT; + } else if (cmd == KBDC_CAPSLOCK) { + kbdstatus ^= STATUS_CAPS; + updateLeds(); + } else if (cmd == KBDC_NUMLOCK) { + kbdstatus ^= STATUS_NUM; + updateLeds(); + } else if (cmd == KBDC_SCRLLOCK) { + kbdstatus ^= STATUS_SCRL; + updateLeds(); + } + if (!kp.haschar) { + kp.hascmd = true; + kp.command = cmd; + } + process(kp); +} + +void keyRelease(u8int scancode) { + keypress_t kp; + kp.pressed = false; + u8int cmd = ctrlkeys[scancode]; + scancode &= 0x7F; + if (cmd == 0) cmd = ctrlkeys[scancode]; + if (cmd == 0) { + kp.haschar = true; + kp.character = 0; + if ((kbdstatus & STATUS_ALT) or (kbdstatus & STATUS_CTRL)) { + kp.hascmd = true; + kp.command = kbdstatus & 0x0F; + } + if ((kbdstatus & STATUS_SHIFT) xor (kbdstatus & STATUS_CAPS)) { + if (kbdstatus & STATUS_ALTGR) { + if (keymapShiftAltgr != NULL) kp.character = keymapShiftAltgr[scancode]; + } else { + if (keymapShift != NULL) kp.character = keymapShift[scancode]; + } + } else { + if (kbdstatus & STATUS_ALTGR) { + if (keymapAltgr != NULL) kp.character = keymapAltgr[scancode]; + } else { + if (keymapNormal != NULL) kp.character = keymapNormal[scancode]; + } + } + } else if (cmd >= KBDC_KPINSERT and cmd <= KBDC_KPDEL and (kbdstatus & STATUS_NUM)) { + kp.haschar = true; + if ((kbdstatus & STATUS_ALT) or (kbdstatus & STATUS_CTRL)) { + kp.hascmd = true; + kp.command = kbdstatus & 0xF0; + } + if (cmd == KBDC_KPDEL) { + kp.character = (u32int)'.'; + } else { + kp.character = (u32int)'0' + (cmd - KBDC_KPINSERT); + } + } else if (cmd == KBDC_ALT) { + kbdstatus &= ~STATUS_ALT; + } else if (cmd == KBDC_ALTGR) { + kbdstatus &= ~STATUS_ALTGR; + } else if (cmd == KBDC_LEFTCTRL or cmd == KBDC_RIGHTCTRL) { + kbdstatus &= ~STATUS_CTRL; + } else if (cmd == KBDC_LEFTSHIFT or cmd == KBDC_RIGHTSHIFT) { + kbdstatus &= ~STATUS_SHIFT; + } + if (!kp.haschar) { + kp.hascmd = true; + kp.command = cmd; + } + process(kp); +} + +} diff --git a/Source/Kernel/DeviceManager/Kbd.ns.h b/Source/Kernel/DeviceManager/Kbd.ns.h new file mode 100644 index 0000000..ee73414 --- /dev/null +++ b/Source/Kernel/DeviceManager/Kbd.ns.h @@ -0,0 +1,96 @@ +#ifndef DEF_KBD_NS_H +#define DEF_KBD_NS_H + +#include <Core/common.wtf.h> +#include <Library/wchar.class.h> + +//Used by variable kbdstatus +#define STATUS_SCRL 0x40 +#define STATUS_NUM 0x20 +#define STATUS_CAPS 0x10 +#define STATUS_SHIFT 0x08 +#define STATUS_CTRL 0x04 +#define STATUS_ALT 0x02 +#define STATUS_ALTGR 0x01 + +//Used in control keys keymap. The ones > 100 are modifiers and are not supposed to be sent to applications. +#define KBDC_LEFTCTRL 101 +#define KBDC_RIGHTCTRL 102 +#define KBDC_ALT 103 +#define KBDC_ALTGR 104 +#define KBDC_LEFTSUP 5 //Super = windows +#define KBDC_RIGHTSUP 6 +#define KBDC_MENU 7 +#define KBDC_LEFTSHIFT 108 +#define KBDC_RIGHTSHIFT 109 +#define KBDC_CAPSLOCK 110 +#define KBDC_TAB 11 +#define KBDC_ENTER 12 +#define KBDC_BACKSPACE 13 + +#define KBDC_KPINSERT 14 //Key 0/insert +#define KBDC_KPEND 15 //Key 1/end +#define KBDC_KPDOWN 16 //Key 2/down +#define KBDC_KPPGDOWN 17 //Key 3/pgdown +#define KBDC_KPLEFT 18 //Key 4/left +#define KBDC_KP5 19 //Key 5 this is sent to receiving application, but must be ignored +#define KBDC_KPRIGHT 20 //Key 6/right +#define KBDC_KPHOME 21 //Key 7/home +#define KBDC_KPUP 22 //Key 8/up +#define KBDC_KPPGUP 23 //Key 9/pgup +#define KBDC_KPDEL 24 //Key ./del + +#define KBDC_HOME 25 +#define KBDC_END 26 +#define KBDC_INSERT 27 +#define KBDC_DEL 28 +#define KBDC_PGUP 29 +#define KBDC_PGDOWN 30 +#define KBDC_UP 31 +#define KBDC_DOWN 32 +#define KBDC_LEFT 33 +#define KBDC_RIGHT 34 + +#define KBDC_NUMLOCK 135 +#define KBDC_SCRLLOCK 136 +#define KBDC_PRTSCN 37 //Print screen +#define KBDC_SYSREQ 38 + +#define KBDC_ESCAPE 40 +#define KBDC_F1 41 +#define KBDC_F2 42 +#define KBDC_F3 43 +#define KBDC_F4 44 +#define KBDC_F5 45 +#define KBDC_F6 46 +#define KBDC_F7 47 +#define KBDC_F8 48 +#define KBDC_F9 49 +#define KBDC_F10 50 +#define KBDC_F11 51 +#define KBDC_F12 52 + +//This is a special case. Keycode is escaped, Keyboard:: will send a 0xB5 keycode, that must not be mixed up with 0x35 +#define KBDC_KPSLASH 53 + +class VirtualTerminal; + +namespace Kbd { + struct keypress_t { + bool pressed; + bool hascmd; + bool haschar; + u8int command; //is 0 if !hascmd, is one of KBDC_* if !haschar, and is a mask of STATUS_* if haschar + wchar character; //is 0 if !haschar + keypress_t() : hascmd(false), haschar(false), command(0), character('\0') {}; + }; + + void setFocus(VirtualTerminal* vt); + void setKeymap(wchar* kmNormal, wchar* kmShift, wchar* kmAltgr, wchar* kmShiftAltgr = NULL); + void updateLeds(); + void keyPress(u8int scancode); + void keyRelease(u8int scancode); +} + +#endif + |