aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Auvolat <alex@adnab.me>2017-05-03 18:48:31 +0200
committerAlex Auvolat <alex@adnab.me>2017-05-03 18:48:31 +0200
commit0b583122fb6cfcff991c54836d37cb3958c343b1 (patch)
tree6d576fb36d25af04f6deb788f46fcb1555b9104f
parent1a4eecd6a685e727611bbc1ffec696daa50bbaea (diff)
downloadkogata-0b583122fb6cfcff991c54836d37cb3958c343b1.tar.gz
kogata-0b583122fb6cfcff991c54836d37cb3958c343b1.zip
Stuff ? (keyboard...)
-rw-r--r--src/lib/libkogata/draw.c9
-rw-r--r--src/lib/libkogata/keyboard.c9
-rw-r--r--src/sysapp/login/main.lua89
-rw-r--r--src/sysbin/lx/lxinit.c1
-rw-r--r--src/sysbin/lx/lxkbdlib.c135
-rw-r--r--src/sysbin/lx/lxlib.h3
-rw-r--r--src/syslua/lx/gui.lua100
-rw-r--r--src/syslua/lx/kbdcode.lua77
-rw-r--r--src/syslua/lx/mainloop.lua3
9 files changed, 347 insertions, 79 deletions
diff --git a/src/lib/libkogata/draw.c b/src/lib/libkogata/draw.c
index 2db0d1d..f11903d 100644
--- a/src/lib/libkogata/draw.c
+++ b/src/lib/libkogata/draw.c
@@ -101,9 +101,9 @@ void g_decref_fb(fb_t *fb) {
color_t g_color_rgb(fb_t *f, uint8_t r, uint8_t g, uint8_t b) {
int m = f->geom.memory_model;
- if (m == FB_MM_RGB24 || m == FB_MM_RGB32) return (r << 16) | (g << 8) | b;
+ if (m == FB_MM_RGB24 || m == FB_MM_RGB32 || m == FB_MM_RGBA32) return (r << 16) | (g << 8) | b;
if (m == FB_MM_BGR24 || m == FB_MM_BGR32) return (b << 16) | (g << 8) | r;
- if (m == FB_MM_GREY8) return ((r + g + b) / 3) & 0xFF;
+ if (m == FB_MM_GREY8 || m == FB_MM_GA16) return ((r + g + b) / 3) & 0xFF;
if (m == FB_MM_RGB16 || m == FB_MM_RGB15) return ((r >> 3) << 10) | ((g >> 3) << 5) | (b >> 3);
if (m == FB_MM_BGR16 || m == FB_MM_BGR15) return ((b >> 3) << 10) | ((g >> 3) << 5) | (r >> 3);
return 0; // unknown?
@@ -254,9 +254,6 @@ void g_blit_region(fb_t *dst, int x, int y, fb_t *src, fb_region_t reg) {
if (y + reg.h > dst->geom.height) reg.h = dst->geom.height - y;
if (reg.w <= 0 || reg.h <= 0) return;
- dbg_printf("Src: 0x%p, dst: 0x%p, x: %d, y: %d, rx: %d, ry: %d, rw: %d, rh: %d\n",
- src->data, dst->data, x, y, reg.x, reg.y, reg.w, reg.h);
-
if (src->geom.memory_model == dst->geom.memory_model
&& src->geom.memory_model != FB_MM_RGBA32
&& src->geom.memory_model != FB_MM_GA16) {
@@ -416,7 +413,9 @@ void g_write(fb_t *fb, int x, int y, const char* text, font_t *font, color_t c)
if (id < font->ascii_bitmap.nchars) {
uint8_t *d = font->ascii_bitmap.data + (id * font->ascii_bitmap.ch);
for (int r = 0; r < font->ascii_bitmap.ch; r++) {
+ if (y + r >= fb->geom.height) continue;
for (int j = 0; j < 8; j++) {
+ if (x + j >= fb->geom.width) continue;
if (d[r] & (0x80 >> j)) {
g_plot(fb, x + j, y + r, c);
}
diff --git a/src/lib/libkogata/keyboard.c b/src/lib/libkogata/keyboard.c
index 64569ed..4f59d5d 100644
--- a/src/lib/libkogata/keyboard.c
+++ b/src/lib/libkogata/keyboard.c
@@ -41,7 +41,7 @@ keyboard_t *init_keyboard() {
keyboard_t *kb = (keyboard_t*)malloc(sizeof(keyboard_t));
if (kb == 0) return 0;
- if (!load_keymap(kb, "default")) {
+ if (!load_keymap(kb, "sys:/keymaps/default.km")) {
free(kb);
return 0;
}
@@ -54,12 +54,9 @@ void free_keyboard(keyboard_t *t) {
}
bool load_keymap(keyboard_t *kb, const char* kmname) {
- char buf[128];
- snprintf(buf, 128, "sys:/keymaps/%s.km", kmname);
-
- fd_t f = sc_open(buf, FM_READ);
+ fd_t f = sc_open(kmname, FM_READ);
if (f == 0) {
- dbg_printf("Failed to open keymap %s\n", buf);
+ dbg_printf("Failed to open keymap %s\n", kmname);
return false;
}
diff --git a/src/sysapp/login/main.lua b/src/sysapp/login/main.lua
index 1745064..40aa9d9 100644
--- a/src/sysapp/login/main.lua
+++ b/src/sysapp/login/main.lua
@@ -3,80 +3,43 @@ local sysdef= require 'lx.sysdef'
local ioctl = require 'lx.ioctl'
local draw = require 'lx.draw'
-print("Hello, world!")
+local gui = require 'lx.gui'
+local mainloop = require 'lx.mainloop'
-local vesa_fd = sys.open("io:/display/vesa", sysdef.FM_IOCTL | sysdef.FM_READ | sysdef.FM_WRITE | sysdef.FM_MMAP)
-print("vesa_fd = " .. vesa_fd)
+print("Hello, world!")
-local vesa_info = ioctl.fb_get_info(vesa_fd)
-print("vesa_info = ", vesa_info)
+gui.open()
+gui.load_cursor('sys:/cursors/left_ptr.png')
-local surface = draw.surface_from_fd(vesa_fd, vesa_info)
-for x = 0, 255 do
- for y = 0, 255 do
- surface:plot(x, y, surface:rgb(x, y, 0))
+for x = 0, 255, 16 do
+ for y = 0, 255, 16 do
+ gui.surface:fillrect(x, y, 16, 16, gui.surface:rgb(x, y, 0))
end
end
-local fnt = draw.load_font('sys:/fonts/default.bf')
-
-local mouse_fd = sys.open("io:/input/pcmouse", sysdef.FM_READ)
-print("mouse_fd = " .. mouse_fd)
-
-local cursor = draw.load_image('sys:/cursors/left_ptr.png')
-local csrbkp = draw.new_surface(cursor:width(), cursor:height(), vesa_info.bpp, false)
-csrbkp:blit(0, 0, surface:sub(0, 0, cursor:width(), cursor:height()))
-
-local i = 1
-local mouse_x, mouse_y = 0, 0
-while true do
- local mouse_data, mouse_l = sys.read(mouse_fd, 0, 8)
- if mouse_l > 0 then
- print("mouse_l = ", mouse_l)
- print("mouse_data = ", string.unpack("hhbBBB", mouse_data))
- dx, dy = string.unpack("hhbBBB", mouse_data)
+gui.show_cursor()
- surface:blit(mouse_x, mouse_y, csrbkp)
+local fnt = draw.load_font('sys:/fonts/default.bf')
- mouse_x = mouse_x + dx
- mouse_y = mouse_y - dy
- if mouse_x < 0 then mouse_x = 0 end
- if mouse_y < 0 then mouse_y = 0 end
- if mouse_x >= vesa_info.width then mouse_x = vesa_info.width - 1 end
- if mouse_y >= vesa_info.height then mouse_y = vesa_info.height - 1 end
+local txt_x, txt_y = 0, 0
- csrbkp:blit(0, 0, surface:sub(mouse_x, mouse_y, cursor:width(), cursor:height()))
- surface:blit(mouse_x, mouse_y, cursor)
+gui.on_mouse_down = function (lb, rb, mb)
+ if lb then
+ gui.hide_cursor()
+ gui.surface:write(gui.mouse_x, gui.mouse_y, string.format("Click at %d, %d", gui.mouse_x, gui.mouse_y), fnt, gui.surface:rgb(0, 0, 255))
+ txt_x = gui.mouse_x
+ txt_y = gui.mouse_y + fnt:text_height(" ")
+ gui.show_cursor()
end
+end
-
- --[[
- surface:rect((i*3) % (vesa_info.width-3),
- (i*3) % (vesa_info.height-5),
- 3, 3,
- surface:rgb(i % 256,
- (i + 96) % 256,
- (i + 2*96) % 256))
- i = i + 1
- if i % 10000 == 0 then
- local x0 = math.random(vesa_info.width)-1
- local x1 = math.random(vesa_info.width)-1
- local y0 = math.random(vesa_info.height)-1
- local y1 = math.random(vesa_info.height)-1
- if x0 > x1 then x0, x1 = x1, x0 end
- if y0 > y1 then y0, y1 = y1, y0 end
- local c = surface:rgb(math.random(0, 255), math.random(0, 255), math.random(0, 255))
- surface:fillrect(x0, y0, x1-x0, y1-y0, c)
- end
- if i % 10000 == 0 then
- -- print(i)
- local txt = tostring(i)
- surface:fillrect(0, 0, fnt:text_width(txt),
- fnt:text_height(txt),
- surface:rgb(0, 0, 0))
- surface:write(0, 0, txt, fnt, surface:rgb(255, 0, 0))
- end
- --]]
+gui.on_text_input = function(chr)
+ gui.hide_cursor()
+ gui.surface:write(txt_x, txt_y, chr, fnt, gui.surface:rgb(0, 0, 255))
+ txt_x = txt_x + fnt:text_width(chr)
+ gui.show_cursor()
end
+mainloop.run()
+
os.exit()
diff --git a/src/sysbin/lx/lxinit.c b/src/sysbin/lx/lxinit.c
index 948659b..8170f0c 100644
--- a/src/sysbin/lx/lxinit.c
+++ b/src/sysbin/lx/lxinit.c
@@ -37,6 +37,7 @@ static const luaL_Reg loadedlibs[] = {
{LX_MSGLIBNAME, lx_open_msg},
{LX_IOCTLLIBNAME, lx_open_ioctl},
{LX_DRAWLIBNAME, lx_open_draw},
+ {LX_KBDLIBNAME, lx_open_kbd},
{NULL, NULL}
};
diff --git a/src/sysbin/lx/lxkbdlib.c b/src/sysbin/lx/lxkbdlib.c
new file mode 100644
index 0000000..e5257b8
--- /dev/null
+++ b/src/sysbin/lx/lxkbdlib.c
@@ -0,0 +1,135 @@
+/*
+** Lua eXtended keyboard library
+*/
+
+#define lxkbdlib_c
+#define LUA_LIB
+
+#include <lua/lprefix.h>
+
+
+#include <errno.h>
+#include <locale.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+
+#include <lua/lua.h>
+
+#include <lua/lauxlib.h>
+#include <lua/lualib.h>
+
+#include <kogata/keyboard.h>
+
+#include "lxlib.h"
+
+
+typedef struct {
+ keyboard_t *kbd;
+} kbdlib_t;
+
+#define KEYBOARD "lx.kbd.keyboard"
+
+// ====================================================================
+// FONTS
+
+static int kbd_init(lua_State *L) {
+ keyboard_t *kbd = init_keyboard();
+ if (kbd == NULL)
+ luaL_error(L, "Could not initialize keyboard_t");
+
+ kbdlib_t *k = (kbdlib_t*)lua_newuserdata(L, sizeof(kbdlib_t));
+ luaL_getmetatable(L, KEYBOARD);
+ lua_setmetatable(L, -2);
+
+ k->kbd = kbd;
+
+ return 1;
+}
+
+static int kbd_gc(lua_State *L) {
+ kbdlib_t *k = (kbdlib_t*)luaL_checkudata(L, 1, KEYBOARD);
+
+ if(k->kbd == NULL) {
+ luaL_error(L, "k->kbd == NULL ?");
+ }
+ free_keyboard(k->kbd);
+ k->kbd = NULL;
+
+ return 0;
+}
+
+static int kbd_load_keymap(lua_State *L) {
+ kbdlib_t *k = (kbdlib_t*)luaL_checkudata(L, 1, KEYBOARD);
+ const char* name = luaL_checkstring(L, 2);
+
+ bool ret = load_keymap(k->kbd, name);
+ lua_pushboolean(L, ret);
+
+ return 1;
+}
+
+static int kbd_press(lua_State *L) {
+ kbdlib_t *k = (kbdlib_t*)luaL_checkudata(L, 1, KEYBOARD);
+ int scancode = luaL_checkinteger(L, 2);
+
+ key_t key = keyboard_press(k->kbd, scancode);
+
+ lua_createtable(L, 0, 2);
+ setintfield(L, "flags", key.flags);
+ if (key.flags & KBD_CHAR)
+ setintfield(L, "chr", key.chr);
+ else
+ setintfield(L, "key", key.key);
+
+ return 1;
+}
+
+static int kbd_release(lua_State *L) {
+ kbdlib_t *k = (kbdlib_t*)luaL_checkudata(L, 1, KEYBOARD);
+ int scancode = luaL_checkinteger(L, 2);
+
+ key_t key = keyboard_release(k->kbd, scancode);
+
+ lua_createtable(L, 0, 2);
+ setintfield(L, "flags", key.flags);
+ if (key.flags & KBD_CHAR)
+ setintfield(L, "chr", key.chr);
+ else
+ setintfield(L, "key", key.key);
+
+ return 1;
+}
+
+
+/* }====================================================== */
+
+static const luaL_Reg kbdlib[] = {
+ {"init", kbd_init},
+ {NULL, NULL}
+};
+
+
+static const luaL_Reg keyboard_meta[] = {
+ {"load_keymap", kbd_load_keymap},
+ {"press", kbd_press},
+ {"release", kbd_release},
+ {"__gc", kbd_gc},
+ {NULL, NULL}
+};
+
+
+LUAMOD_API int lx_open_kbd (lua_State *L) {
+ luaL_newlib(L, kbdlib);
+
+ luaL_newmetatable(L, KEYBOARD);
+ luaL_setfuncs(L, keyboard_meta, 0);
+ lua_pushvalue(L, -1);
+ lua_setfield(L, -2, "__index");
+ lua_pop(L, 1);
+
+ return 1;
+}
+
+
+/* vim: set sts=2 ts=2 sw=2 tw=0 et :*/
diff --git a/src/sysbin/lx/lxlib.h b/src/sysbin/lx/lxlib.h
index 643d5c8..dd31ffb 100644
--- a/src/sysbin/lx/lxlib.h
+++ b/src/sysbin/lx/lxlib.h
@@ -28,6 +28,9 @@ LUAMOD_API int (luaopen_cmsgpack) (lua_State *L);
#define LX_DRAWLIBNAME "lx.draw"
LUAMOD_API int (lx_open_draw) (lua_State *L);
+#define LX_KBDLIBNAME "lx.kbd"
+LUAMOD_API int (lx_open_kbd) (lua_State *L);
+
/* open all previous libraries */
LUALIB_API void (lx_openlibs) (lua_State *L);
diff --git a/src/syslua/lx/gui.lua b/src/syslua/lx/gui.lua
index beb382e..23e6cb6 100644
--- a/src/syslua/lx/gui.lua
+++ b/src/syslua/lx/gui.lua
@@ -3,6 +3,9 @@ local sysdef= require 'lx.sysdef'
local ioctl = require 'lx.ioctl'
local draw = require 'lx.draw'
+local kbd = require 'lx.kbd'
+local kbdcode = require 'lx.kbdcode'
+
local mainloop = require 'lx.mainloop'
local gui = {
@@ -14,6 +17,7 @@ local gui = {
mouse_lbtn = false,
mouse_rbtn = false,
mouse_midbtn = false,
+ cursor_visible = false,
}
function gui.open()
@@ -31,8 +35,8 @@ function gui.open_io()
gui.vesa_fd = sys.open("io:/display/vesa", sysdef.FM_IOCTL | sysdef.FM_READ | sysdef.FM_WRITE | sysdef.FM_MMAP)
assert(gui.vesa_fd ~= 0)
- gui.vesa_info = ioctl.fb_get_info(gui.vesa_fd)
- gui.surface = draw.surface_from_fd(gui.vesa_fd, gui.vesa_info)
+ gui.surface_geom = ioctl.fb_get_info(gui.vesa_fd)
+ gui.surface = draw.surface_from_fd(gui.vesa_fd, gui.surface_geom)
-- Open keyboard
gui.pckbd_fd = sys.open("io:/input/pckbd", sysdef.FM_READ)
@@ -47,6 +51,8 @@ function gui.open_io()
end
gui.pckbd_mainloop_fd:expect(4, pckbd_handler)
+ gui.kbdlib = kbd.init()
+
-- Open mouse
gui.pcmouse_fd = sys.open("io:/input/pcmouse", sysdef.FM_READ)
assert(gui.pcmouse_fd ~= 0)
@@ -65,12 +71,98 @@ function gui.open_gip()
-- TODO
end
+function gui.load_cursor(filename)
+ gui.hide_cursor()
+ gui.cursor = draw.load_image(filename)
+ gui.cursor_backup = draw.new_surface(gui.cursor:width(),gui.cursor:height(), gui.surface_geom.bpp, false)
+end
+
+function gui.hide_cursor()
+ if not gui.cursor_visible then return end
+
+ gui.surface:blit(gui.mouse_x, gui.mouse_y, gui.cursor_backup)
+ gui.cursor_visible = false
+end
+
+function gui.show_cursor()
+ if gui.cursor_visible then return end
+ if not gui.cursor then return end
+
+ gui.cursor_backup:blit(0, 0, gui.surface:sub(gui.mouse_x, gui.mouse_y, gui.cursor:width(), gui.cursor:height()))
+ gui.surface:blit(gui.mouse_x, gui.mouse_y, gui.cursor)
+ gui.cursor_visible = true
+end
+
function gui.on_keyboard(scancode, ty)
- -- TODO
+ if ty == kbdcode.event.KEYPRESS then
+ local key = gui.kbdlib:press(scancode)
+ gui.on_key_down(key)
+ if key.chr then
+ gui.on_text_input(string.char(key.chr))
+ end
+ elseif ty == kbdcode.event.KEYRELEASE then
+ local key = gui.kbdlib:release(scancode)
+ gui.on_key_up(key)
+ end
+end
+
+function gui.on_key_down(key)
+ -- Can be replaced :)
+end
+
+function gui.on_text_input(chr)
+ -- Can be replaced :)
+end
+
+function gui.on_key_up(key)
+ -- Can be replaced :)
end
+
function gui.on_mouse(dx, dy, dw, lb, rb, mb)
- -- TODO
+ if dx ~= 0 or dy ~= 0 then
+ local csr = gui.cursor_visible
+ if csr then gui.hide_cursor() end
+
+ gui.mouse_x = gui.mouse_x + dx
+ gui.mouse_y = gui.mouse_y - dy
+ if gui.mouse_x < 0 then gui.mouse_x = 0 end
+ if gui.mouse_y < 0 then gui.mouse_y = 0 end
+ if gui.mouse_x >= gui.surface:width() then gui.mouse_x = gui.surface:width() - 1 end
+ if gui.mouse_y >= gui.surface:height() then gui.mouse_y = gui.surface:height() - 1 end
+
+ if csr then gui.show_cursor() end
+
+ gui.on_mouse_move(gui.mouse_x, gui.mouse_y)
+ end
+
+ if lb == 1 and not gui.mouse_lbtn then
+ gui.mouse_lbtn = true
+ gui.on_mouse_down(true, false, false)
+ elseif lb == 0 and gui.mouse_lbtn then
+ gui.mouse_lbtn = false
+ gui.on_mouse_up(true, false, false)
+ end
+
+ if rb == 1 and not gui.mouse_rbtn then
+ gui.mouse_rbtn = true
+ gui.on_mouse_down(false, true, false)
+ elseif rb == 0 and gui.mouse_rbtn then
+ gui.mouse_rbtn = false
+ gui.on_mouse_up(false, true, false)
+ end
+end
+
+function gui.on_mouse_move(x, y)
+ -- Nothing, can be replaced :)
+end
+
+function gui.on_mouse_down(lb, rb, mb)
+ -- Nothing, can be replaced :)
+end
+
+function gui.on_mouse_up(lb, rb, mb)
+ -- Nothing, can be replaced :)
end
return gui
diff --git a/src/syslua/lx/kbdcode.lua b/src/syslua/lx/kbdcode.lua
new file mode 100644
index 0000000..75f3a91
--- /dev/null
+++ b/src/syslua/lx/kbdcode.lua
@@ -0,0 +1,77 @@
+local kbdcode = {}
+
+kbdcode.event = {
+ KEYRELEASE = 0,
+ KEYPRESS = 1,
+}
+
+kbdcode.code = {
+ ESC = 1,
+ RETURN = 28,
+ BKSP = 14,
+ UP = 200,
+ DOWN = 208,
+ LEFT = 203,
+ RIGHT = 205,
+ HOME = 199,
+ END = 207,
+ PGUP = 201,
+ PGDOWN = 209,
+
+ LSHIFT = 42,
+ RSHIFT = 54,
+ CAPSLOCK = 58,
+ LCTRL = 29,
+ RCTRL = 157,
+ LALT = 56,
+ RALT = 184,
+ LSUPER = 219,
+ RSUPER = 220,
+ MENU = 221,
+ TAB = 15,
+ INS = 210,
+ DEL = 211,
+
+ F1 = 59,
+ F2 = 60,
+ F3 = 61,
+ F4 = 62,
+ F5 = 63,
+ F6 = 64,
+ F7 = 65,
+ F8 = 66,
+ F9 = 67,
+ F10 = 68,
+ F11 = 87,
+ F12 = 88,
+
+ NUMLOCK = 69,
+ SCRLLOCK = 70,
+ PRTSCN = 183,
+ SYSREQ = 84,
+
+ KPHOME = 71,
+ KPUP = 72,
+ KPPGUP = 73,
+ KPLEFT = 75,
+ KP5 = 76,
+ KPRIGHT = 77,
+ KPEND = 79,
+ KPDOWN = 80,
+ KPPGDOWN = 81,
+ KPINS = 82,
+ KPDEL = 83,
+}
+
+kbdcode.flags = {
+ CHAR = 0x01,
+ ALT = 0x02,
+ CTRL = 0x04,
+ SUPER = 0x08,
+ SHIFT = 0x10,
+ CAPS = 0x20,
+ MOD = 0x40,
+}
+
+
+return kbdcode
diff --git a/src/syslua/lx/mainloop.lua b/src/syslua/lx/mainloop.lua
index c2ae88d..b1b3feb 100644
--- a/src/syslua/lx/mainloop.lua
+++ b/src/syslua/lx/mainloop.lua
@@ -21,6 +21,7 @@ function new_fd(fd, error_cb)
function fd:expect(len, cb)
table.insert(self.rd_expect, {len, "", cb})
end
+ return fd
end
function mainloop.add_fd(fd, error_cb)
@@ -55,7 +56,7 @@ function mainloop.run()
local res = sys.select(sel_fds, -1)
assert(res, "select() call failed")
- for i, fd = pairs(fds) do
+ for i, fd in pairs(fds) do
local flags = sel_fds[i][3]
if flags & sysdef.SEL_ERROR ~= 0 then
fd.error_cb(fd)