aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlex Auvolat <alex@adnab.me>2015-03-11 19:18:59 +0100
committerAlex Auvolat <alex@adnab.me>2015-03-11 19:18:59 +0100
commit50b5427a8edbb8d59215334f5a250e7f8d6d7ca7 (patch)
tree7263505b2a6145256ce1f494108a4ceb853c4de0 /src
parent0b76aff59b586d87ee0449bc7deda878f4633515 (diff)
downloadkogata-50b5427a8edbb8d59215334f5a250e7f8d6d7ca7.tar.gz
kogata-50b5427a8edbb8d59215334f5a250e7f8d6d7ca7.zip
Add keyboard handling code. New font thanks to Muazzam from OSDev!
Diffstat (limited to 'src')
-rw-r--r--src/common/include/proto/keyboard.h20
-rw-r--r--src/kernel/core/idt.c2
-rw-r--r--src/lib/include/keyboard.h37
-rw-r--r--src/lib/include/proto/keymap_file.h16
-rw-r--r--src/lib/libkogata/Makefile2
-rw-r--r--src/lib/libkogata/draw.c2
-rw-r--r--src/lib/libkogata/keyboard.c148
-rw-r--r--src/lib/libkogata/mainloop.c8
-rw-r--r--src/sysbin/login/main.c8
9 files changed, 234 insertions, 9 deletions
diff --git a/src/common/include/proto/keyboard.h b/src/common/include/proto/keyboard.h
index 8d9543f..c7a2ef8 100644
--- a/src/common/include/proto/keyboard.h
+++ b/src/common/include/proto/keyboard.h
@@ -36,7 +36,8 @@ typedef struct {
#define KBD_CODE_RCTRL 157
#define KBD_CODE_LALT 56
#define KBD_CODE_RALT 184
-#define KBD_CODE_SUPER 219
+#define KBD_CODE_LSUPER 219
+#define KBD_CODE_RSUPER 220
#define KBD_CODE_MENU 221
#define KBD_CODE_TAB 15
#define KBD_CODE_INS 210
@@ -55,4 +56,21 @@ typedef struct {
#define KBD_CODE_F11 87
#define KBD_CODE_F12 88
+#define KBD_CODE_NUMLOCK 69
+#define KBD_CODE_SCRLLOCK 70
+#define KBD_CODE_PRTSCN 183
+#define KBD_CODE_SYSREQ 84
+
+#define KBD_CODE_KPHOME 71
+#define KBD_CODE_KPUP 72
+#define KBD_CODE_KPPGUP 73
+#define KBD_CODE_KPLEFT 75
+#define KBD_CODE_KP5 76
+#define KBD_CODE_KPRIGHT 77
+#define KBD_CODE_KPEND 79
+#define KBD_CODE_KPDOWN 80
+#define KBD_CODE_KPPGDOWN 81
+#define KBD_CODE_KPINS 82
+#define KBD_CODE_KPDEL 83
+
/* vim: set ts=4 sw=4 tw=0 noet :*/
diff --git a/src/kernel/core/idt.c b/src/kernel/core/idt.c
index 457e5ae..e2c4bf0 100644
--- a/src/kernel/core/idt.c
+++ b/src/kernel/core/idt.c
@@ -116,7 +116,7 @@ void idt_ex_handler(registers_t *regs) {
void idt_irq_handler(registers_t *regs) {
int st = enter_critical(CL_EXCL); // if someone tries to yield(), an assert will fail
- if (regs->err_code != 0) dbg_printf("irq%d.", regs->err_code);
+ /*if (regs->err_code != 0) dbg_printf("irq%d.", regs->err_code);*/
if (regs->err_code > 7) {
outb(0xA0, 0x20);
diff --git a/src/lib/include/keyboard.h b/src/lib/include/keyboard.h
new file mode 100644
index 0000000..2842936
--- /dev/null
+++ b/src/lib/include/keyboard.h
@@ -0,0 +1,37 @@
+#pragma once
+
+#include <proto/keymap_file.h>
+
+
+#define KBD_CHAR 0x01
+#define KBD_ALT 0x02
+#define KBD_CTRL 0x04
+#define KBD_SUPER 0x08
+#define KBD_SHIFT 0x10
+#define KBD_CAPS 0x20
+#define KBD_MOD 0x40
+
+typedef struct {
+ union {
+ int chr; // if flags & KBD_CHAR, chr is a character number
+ int key; // if !(flags & KBD_CHAR), key is one of KBD_CODE_* defined in <proto/keyboard.h>
+ };
+ uint32_t flags; // one of kbd_*
+} key_t;
+
+typedef struct {
+ keymap_t km;
+ uint32_t status; // mask of alt/ctrl/super
+} keyboard_t;
+
+keyboard_t *init_keyboard();
+void free_keyboard(keyboard_t *t);
+
+bool load_keymap(keyboard_t *kb, const char* kmname);
+
+key_t keyboard_press(keyboard_t *t, int scancode); // what key is pressed?
+key_t keyboard_release(keyboard_t *t, int scancode); // what key is released?
+
+
+
+/* vim: set ts=4 sw=4 tw=0 noet :*/
diff --git a/src/lib/include/proto/keymap_file.h b/src/lib/include/proto/keymap_file.h
new file mode 100644
index 0000000..53ffeb7
--- /dev/null
+++ b/src/lib/include/proto/keymap_file.h
@@ -0,0 +1,16 @@
+#pragma once
+
+#include <stdint.h>
+#include <stddef.h>
+#include <stdbool.h>
+
+typedef struct {
+ int normal[128];
+ int shift[128];
+ int caps[128];
+ int mod[128];
+ int shiftmod[128];
+ bool ralt_is_mod; // true: right alt = alt-gr
+} keymap_t;
+
+/* vim: set ts=4 sw=4 tw=0 noet :*/
diff --git a/src/lib/libkogata/Makefile b/src/lib/libkogata/Makefile
index a8df419..a02a862 100644
--- a/src/lib/libkogata/Makefile
+++ b/src/lib/libkogata/Makefile
@@ -1,5 +1,5 @@
OBJ = start.o malloc.o debug.o syscall.o user_region.o \
- mainloop.o gip.o draw.o
+ mainloop.o gip.o draw.o keyboard.o
LIB = ../../common/libkogata/libkogata.lib ../../common/libalgo/libalgo.lib ../../common/libc/libc.lib
diff --git a/src/lib/libkogata/draw.c b/src/lib/libkogata/draw.c
index 911fe0d..b9ef9bc 100644
--- a/src/lib/libkogata/draw.c
+++ b/src/lib/libkogata/draw.c
@@ -239,13 +239,11 @@ font_t *g_load_ascii_bitmap_font(fd_t f) {
if (font == 0) goto error;
memset(font, 0, sizeof(font_t));
-
font->type = FONT_ASCII_BITMAP;
font->ascii_bitmap.cw = h.cw;
font->ascii_bitmap.ch = h.ch;
font->ascii_bitmap.nchars = h.nchars;
-
font->ascii_bitmap.data = (uint8_t*)malloc(h.ch * h.nchars);
if (font->ascii_bitmap.data == 0) goto error;
diff --git a/src/lib/libkogata/keyboard.c b/src/lib/libkogata/keyboard.c
new file mode 100644
index 0000000..7e3c376
--- /dev/null
+++ b/src/lib/libkogata/keyboard.c
@@ -0,0 +1,148 @@
+#include <malloc.h>
+#include <string.h>
+#include <printf.h>
+
+#include <syscall.h>
+
+#include <proto/keyboard.h>
+#include <keyboard.h>
+
+// ---- Control keys that are not KBD_CHAR-able
+
+int ctrlkeys[] = {
+/* 0x00 */ 0, KBD_CODE_ESC, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, KBD_CODE_BKSP, KBD_CODE_TAB,
+/* 0x10 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, KBD_CODE_RETURN, KBD_CODE_LCTRL, 0, 0,
+/* 0x20 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, KBD_CODE_LSHIFT, 0, 0, 0, 0, 0,
+/* 0x30 */ 0, 0, 0, 0, 0, 0, KBD_CODE_RSHIFT, 0, KBD_CODE_LALT, 0,
+ KBD_CODE_CAPSLOCK, KBD_CODE_F1, KBD_CODE_F2, KBD_CODE_F3, KBD_CODE_F4, KBD_CODE_F5,
+/* 0x40 */ KBD_CODE_F6, KBD_CODE_F7, KBD_CODE_F8, KBD_CODE_F9, KBD_CODE_F10, KBD_CODE_NUMLOCK,
+ KBD_CODE_SCRLLOCK, KBD_CODE_KPHOME, KBD_CODE_KPUP, KBD_CODE_KPPGUP, 0, KBD_CODE_KPLEFT,
+ KBD_CODE_KP5, KBD_CODE_KPRIGHT, 0, KBD_CODE_KPEND,
+/* 0x50 */ KBD_CODE_KPDOWN, KBD_CODE_KPPGDOWN, KBD_CODE_KPINS, KBD_CODE_KPDEL,
+ KBD_CODE_SYSREQ, 0, 0, KBD_CODE_F11, KBD_CODE_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, KBD_CODE_RETURN, KBD_CODE_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, KBD_CODE_PRTSCN, KBD_CODE_RALT, 0, 0, 0, 0, 0, 0, 0,
+/* 0xC0 */ 0, 0, 0, 0, 0, 0, 0, KBD_CODE_HOME, KBD_CODE_UP, KBD_CODE_PGUP, 0,
+ KBD_CODE_LEFT, 0, KBD_CODE_RIGHT, 0, KBD_CODE_END,
+/* 0xD0 */ KBD_CODE_DOWN, KBD_CODE_PGDOWN, KBD_CODE_INS, KBD_CODE_DEL, 0, 0, 0, 0, 0,
+ 0, 0, KBD_CODE_LSUPER, KBD_CODE_RSUPER, KBD_CODE_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
+};
+
+// ---- The code
+
+keyboard_t *init_keyboard() {
+ keyboard_t *kb = (keyboard_t*)malloc(sizeof(keyboard_t));
+ if (kb == 0) return 0;
+
+ if (!load_keymap(kb, "default")) {
+ free(kb);
+ return 0;
+ }
+
+ return kb;
+}
+
+void free_keyboard(keyboard_t *t) {
+ free(t);
+}
+
+bool load_keymap(keyboard_t *kb, const char* kmname) {
+ char buf[128];
+ snprintf(buf, 128, "sys:/keymaps/%s.km", kmname);
+
+ fd_t f = open(buf, FM_READ);
+ if (f == 0) {
+ dbg_printf("Failed to open keymap %s\n", buf);
+ return false;
+ }
+
+ keymap_t km;
+ size_t rd = read(f, 0, sizeof(keymap_t), (char*)&km);
+
+ bool ok = (rd == sizeof(keymap_t));
+
+ if (ok) {
+ memcpy(&kb->km, &km, sizeof(keymap_t));
+ kb->status = 0;
+ }
+
+ close(f);
+
+ return ok;
+}
+
+int key_chr(keyboard_t *kb, int k) {
+ if (kb->status & KBD_MOD) {
+ if ((kb->status & KBD_SHIFT) | (kb->status & KBD_CAPS)) {
+ return kb->km.shiftmod[k];
+ } else {
+ return kb->km.mod[k];
+ }
+ } else if ((kb->status & KBD_CAPS) && (kb->status & KBD_SHIFT)) {
+ return kb->km.normal[k];
+ } else if (kb->status & KBD_SHIFT) {
+ return kb->km.shift[k];
+ } else if (kb->status & KBD_CAPS) {
+ return kb->km.caps[k];
+ } else {
+ return kb->km.normal[k];
+ }
+}
+
+key_t make_key(keyboard_t *kb, int k) {
+ key_t x;
+ x.flags = kb->status;
+
+ x.key = 0;
+ if (k >= 128) return x;
+
+ x.key = ctrlkeys[k];
+ if (x.key != 0) return x;
+
+ x.flags |= KBD_CHAR;
+ x.chr = key_chr(kb, k);
+ return x;
+
+}
+
+key_t keyboard_press(keyboard_t *kb, int k) {
+ if (k == KBD_CODE_LSHIFT || k == KBD_CODE_RSHIFT) {
+ kb->status |= KBD_SHIFT;
+ } else if (k == KBD_CODE_LCTRL || k == KBD_CODE_RCTRL) {
+ kb->status |= KBD_CTRL;
+ } else if (k == KBD_CODE_LSUPER || k == KBD_CODE_RSUPER) {
+ kb->status |= KBD_SUPER;
+ } else if (k == KBD_CODE_LALT || (!kb->km.ralt_is_mod && k == KBD_CODE_RALT)) {
+ kb->status |= KBD_ALT;
+ } else if (kb->km.ralt_is_mod && k == KBD_CODE_RALT) {
+ kb->status |= KBD_MOD;
+ } else if (kb->km.ralt_is_mod && k == KBD_CODE_CAPSLOCK) {
+ kb->status ^= KBD_CAPS;
+ }
+
+ return make_key(kb, k);
+}
+
+key_t keyboard_release(keyboard_t *kb, int k) {
+ if (k == KBD_CODE_LSHIFT || k == KBD_CODE_RSHIFT) {
+ kb->status &= ~KBD_SHIFT;
+ } else if (k == KBD_CODE_LCTRL || k == KBD_CODE_RCTRL) {
+ kb->status &= ~KBD_CTRL;
+ } else if (k == KBD_CODE_LSUPER || k == KBD_CODE_RSUPER) {
+ kb->status &= ~KBD_SUPER;
+ } else if (k == KBD_CODE_LALT || (!kb->km.ralt_is_mod && k == KBD_CODE_RALT)) {
+ kb->status &= ~KBD_ALT;
+ } else if (kb->km.ralt_is_mod && k == KBD_CODE_RALT) {
+ kb->status &= ~KBD_MOD;
+ }
+
+ return make_key(kb, k);
+}
+
+/* vim: set ts=4 sw=4 tw=0 noet :*/
diff --git a/src/lib/libkogata/mainloop.c b/src/lib/libkogata/mainloop.c
index e7fdfa4..ece7672 100644
--- a/src/lib/libkogata/mainloop.c
+++ b/src/lib/libkogata/mainloop.c
@@ -88,14 +88,14 @@ void mainloop_run() {
}
// ---- Do the select
- dbg_printf("(mainloop) begin select\n");
+ /*dbg_printf("(mainloop) begin select\n");*/
bool ok = select(sel_arg, nfds, -1);
if (!ok) {
dbg_printf("(mainloop) Failed to select.\n");
free(sel_arg);
return;
}
- dbg_printf("(mainloop) end select\n");
+ /*dbg_printf("(mainloop) end select\n");*/
{ // Parse result
int i = 0;
@@ -107,7 +107,7 @@ void mainloop_run() {
fd->rd_buf_filled +=
read(fd->fd, 0, fd->rd_buf_expect_size - fd->rd_buf_filled, fd->rd_buf + fd->rd_buf_filled);
if (fd->rd_buf_filled == fd->rd_buf_expect_size) {
- dbg_printf("(mainloop) finish read %d\n", fd->rd_buf_expect_size);
+ /*dbg_printf("(mainloop) finish read %d\n", fd->rd_buf_expect_size);*/
fd->rd_buf_filled = 0;
ASSERT(fd->rd_on_full != 0);
fd->rd_on_full(fd);
@@ -119,7 +119,7 @@ void mainloop_run() {
fd->wr_bufs[0].written += write(fd->fd, 0, remain_size, write_ptr);
if (fd->wr_bufs[0].written == fd->wr_bufs[0].size) {
- dbg_printf("(mainloop) finish write %d\n", fd->wr_bufs[0].size);
+ /*dbg_printf("(mainloop) finish write %d\n", fd->wr_bufs[0].size);*/
if (fd->wr_bufs[0].must_free) free(fd->wr_bufs[0].buf);
for (int i = 1; i < MAINLOOP_MAX_WR_BUFS; i++) {
fd->wr_bufs[i-1] = fd->wr_bufs[i];
diff --git a/src/sysbin/login/main.c b/src/sysbin/login/main.c
index e6e5290..3c02a4b 100644
--- a/src/sysbin/login/main.c
+++ b/src/sysbin/login/main.c
@@ -5,6 +5,7 @@
#include <gip.h>
#include <draw.h>
+#include <keyboard.h>
typedef struct {
fb_info_t mode;
@@ -40,9 +41,13 @@ gip_handler_callbacks_t loginc_cb = {
.fd_error = c_fd_error,
};
+keyboard_t *kb;
+
int main(int argc, char **argv) {
dbg_print("[login] Starting up.\n");
+ kb = init_keyboard();
+
loginc_t loginc;
memset(&loginc, 0, sizeof(loginc));
@@ -103,9 +108,12 @@ void c_buffer_info(gip_handler_t *s, gip_msg_header *p, gip_buffer_info_msg *m)
}
void c_key_down(gip_handler_t *s, gip_msg_header *p) {
+ keyboard_press(kb, p->arg);
}
void c_key_up(gip_handler_t *s, gip_msg_header *p) {
+ key_t k = keyboard_release(kb, p->arg);
+ if (k.chr) dbg_printf("%c", k.chr);
}
void c_unknown_msg(gip_handler_t *s, gip_msg_header *p) {