summaryrefslogtreecommitdiff
path: root/Source/Kernel/DeviceManager
diff options
context:
space:
mode:
Diffstat (limited to 'Source/Kernel/DeviceManager')
-rw-r--r--Source/Kernel/DeviceManager/Kbd.ns.cpp197
-rw-r--r--Source/Kernel/DeviceManager/Kbd.ns.h96
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
+