diff options
author | Alex Auvolat <alex@adnab.me> | 2015-03-11 19:18:59 +0100 |
---|---|---|
committer | Alex Auvolat <alex@adnab.me> | 2015-03-11 19:18:59 +0100 |
commit | 50b5427a8edbb8d59215334f5a250e7f8d6d7ca7 (patch) | |
tree | 7263505b2a6145256ce1f494108a4ceb853c4de0 /src/lib | |
parent | 0b76aff59b586d87ee0449bc7deda878f4633515 (diff) | |
download | kogata-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.h | 37 | ||||
-rw-r--r-- | src/lib/include/proto/keymap_file.h | 16 | ||||
-rw-r--r-- | src/lib/libkogata/Makefile | 2 | ||||
-rw-r--r-- | src/lib/libkogata/draw.c | 2 | ||||
-rw-r--r-- | src/lib/libkogata/keyboard.c | 148 | ||||
-rw-r--r-- | src/lib/libkogata/mainloop.c | 8 |
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]; |