diff options
-rw-r--r-- | src/lib/libkogata/draw.c | 9 | ||||
-rw-r--r-- | src/lib/libkogata/keyboard.c | 9 | ||||
-rw-r--r-- | src/sysapp/login/main.lua | 89 | ||||
-rw-r--r-- | src/sysbin/lx/lxinit.c | 1 | ||||
-rw-r--r-- | src/sysbin/lx/lxkbdlib.c | 135 | ||||
-rw-r--r-- | src/sysbin/lx/lxlib.h | 3 | ||||
-rw-r--r-- | src/syslua/lx/gui.lua | 100 | ||||
-rw-r--r-- | src/syslua/lx/kbdcode.lua | 77 | ||||
-rw-r--r-- | src/syslua/lx/mainloop.lua | 3 |
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) |