aboutsummaryrefslogtreecommitdiff
path: root/src/lib
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/lib
parent0b76aff59b586d87ee0449bc7deda878f4633515 (diff)
downloadkogata-50b5427a8edbb8d59215334f5a250e7f8d6d7ca7.tar.gz
kogata-50b5427a8edbb8d59215334f5a250e7f8d6d7ca7.zip
Add keyboard handling code. New font thanks to Muazzam from OSDev!
Diffstat (limited to 'src/lib')
-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
6 files changed, 206 insertions, 7 deletions
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];