diff options
author | Alex Auvolat <alex@adnab.me> | 2017-04-21 18:26:22 +0200 |
---|---|---|
committer | Alex Auvolat <alex@adnab.me> | 2017-04-21 18:26:22 +0200 |
commit | ed153e6a5b9f001bbe49128e6bc53053f55dd37b (patch) | |
tree | 9a9bbe3551ea1b5de71aa3c358fd13f46c603191 /src/sysbin/lx | |
parent | f8334e283c5eb0efeb4bb8a134041e18388d5f01 (diff) | |
download | kogata-ed153e6a5b9f001bbe49128e6bc53053f55dd37b.tar.gz kogata-ed153e6a5b9f001bbe49128e6bc53053f55dd37b.zip |
Can plot on a surface from lua
Diffstat (limited to 'src/sysbin/lx')
-rw-r--r-- | src/sysbin/lx/lxdrawlib.c | 160 | ||||
-rw-r--r-- | src/sysbin/lx/lxinit.c | 1 | ||||
-rw-r--r-- | src/sysbin/lx/lxlib.c | 14 | ||||
-rw-r--r-- | src/sysbin/lx/lxlib.h | 6 |
4 files changed, 181 insertions, 0 deletions
diff --git a/src/sysbin/lx/lxdrawlib.c b/src/sysbin/lx/lxdrawlib.c new file mode 100644 index 0000000..71c9819 --- /dev/null +++ b/src/sysbin/lx/lxdrawlib.c @@ -0,0 +1,160 @@ +/* +** Lua eXtended ioctl library +*/ + +#define lxdrawlib_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/draw.h> + +#include "lxlib.h" + + +typedef struct { + fb_t *fb; + fb_region_t subregion; + bool has_subregion; +} drawlib_surface; + +#define SURFACE "lx.draw.surface" + +static int draw_from_fd(lua_State *L) { + int fd = luaL_checkinteger(L, 1); + luaL_checktype(L, 2, LUA_TTABLE); + + fb_info_t geom; + geom.width = getintfield(L, 2, "width"); + geom.height = getintfield(L, 2, "height"); + geom.bpp = getintfield(L, 2, "bpp"); + geom.pitch = getintfield(L, 2, "pitch"); + geom.memory_model = getintfield(L, 2, "memory_model"); + + drawlib_surface *s = (drawlib_surface*)lua_newuserdata(L, sizeof(drawlib_surface)); + luaL_getmetatable(L, SURFACE); + lua_setmetatable(L, -2); + + s->fb = g_fb_from_file(fd, &geom); + if (s->fb == NULL) { + lua_pop(L, 1); + lua_pushnil(L); + } else { + s->subregion.x = s->subregion.y = 0; + s->subregion.w = geom.width; + s->subregion.h = geom.height; + s->has_subregion = false; + } + return 1; +} + +static int surface_gc(lua_State *L) { + drawlib_surface *s = (drawlib_surface*)luaL_checkudata(L, 1, SURFACE); + + if(s->fb == NULL) { + luaL_error(L, "s->fb == NULL ?"); + } + g_decref_fb(s->fb); + s->fb = NULL; + + return 0; +} + +static int surface_sub(lua_State *L) { + drawlib_surface *s = (drawlib_surface*)luaL_checkudata(L, 1, SURFACE); + int x = luaL_checkinteger(L, 2); + int y = luaL_checkinteger(L, 3); + int w, h; + if (lua_isinteger(L, 4)) { + w = luaL_checkinteger(L, 4); + } else { + w = s->subregion.w - x; + } + if (lua_isinteger(L, 5)) { + h = luaL_checkinteger(L, 5); + } else { + h = s->subregion.h - y; + } + + if (x < 0 || y < 0 || w < 0 || h < 0) + luaL_error(L, "negative argument is invalid"); + if (x+w > (int)s->subregion.w) luaL_error(L, "w too big"); + if (y+h > (int)s->subregion.h) luaL_error(L, "h too big"); + + drawlib_surface *s2 = (drawlib_surface*)lua_newuserdata(L, sizeof(drawlib_surface)); + luaL_getmetatable(L, SURFACE); + lua_setmetatable(L, -2); + + s2->fb = s->fb; + s2->has_subregion = true; + s2->subregion.x = s->subregion.x + x; + s2->subregion.y = s->subregion.y + y; + s2->subregion.w = w; + s2->subregion.h = h; + + return 1; +} + +static int surface_rgb(lua_State *L) { + drawlib_surface *s = (drawlib_surface*)luaL_checkudata(L, 1, SURFACE); + int r = luaL_checkinteger(L, 2); + int g = luaL_checkinteger(L, 3); + int b = luaL_checkinteger(L, 4); + + color_t c = g_color_rgb(s->fb, r, g, b); + lua_pushlightuserdata(L, (void*)c); + return 1; +} + +static int surface_plot(lua_State *L) { + drawlib_surface *s = (drawlib_surface*)luaL_checkudata(L, 1, SURFACE); + int x = luaL_checkinteger(L, 2); + int y = luaL_checkinteger(L, 3); + color_t c = (color_t)lx_checklightudata(L, 4); + + g_plot(s->fb, x, y, c); + return 0; +} + +/* }====================================================== */ + +static const luaL_Reg drawlib[] = { + {"from_fd", draw_from_fd}, + {NULL, NULL} +}; + +static const luaL_Reg surface_meta[] = { + {"sub", surface_sub}, + {"rgb", surface_rgb}, + {"plot", surface_plot}, + {"__gc", surface_gc}, + {NULL, NULL} +}; + + +LUAMOD_API int lx_open_draw (lua_State *L) { + luaL_newlib(L, drawlib); + + luaL_newmetatable(L, SURFACE); + luaL_setfuncs(L, surface_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/lxinit.c b/src/sysbin/lx/lxinit.c index b727ccd..948659b 100644 --- a/src/sysbin/lx/lxinit.c +++ b/src/sysbin/lx/lxinit.c @@ -36,6 +36,7 @@ static const luaL_Reg loadedlibs[] = { {LX_SYSLIBNAME, lx_open_sys}, {LX_MSGLIBNAME, lx_open_msg}, {LX_IOCTLLIBNAME, lx_open_ioctl}, + {LX_DRAWLIBNAME, lx_open_draw}, {NULL, NULL} }; diff --git a/src/sysbin/lx/lxlib.c b/src/sysbin/lx/lxlib.c index 9f6843b..ed266f7 100644 --- a/src/sysbin/lx/lxlib.c +++ b/src/sysbin/lx/lxlib.c @@ -29,6 +29,13 @@ bool lx_checkboolean(lua_State *L, int arg) { return lua_toboolean(L, arg); } +void* lx_checklightudata(lua_State *L, int arg) { + if (!lua_islightuserdata(L, arg)) { + luaL_argerror(L, arg, "expected light userdata"); + } + return lua_touserdata(L, arg); +} + void setintfield (lua_State *L, const char *key, int value) { lua_pushinteger(L, value); @@ -39,3 +46,10 @@ void setstrfield (lua_State *L, const char *key, const char* value) { lua_pushstring(L, value); lua_setfield(L, -2, key); } + +int getintfield(lua_State *L, int arg, const char *key) { + lua_getfield(L, arg, key); + int v = luaL_checkinteger(L, -1); + lua_pop(L, 1); + return v; +} diff --git a/src/sysbin/lx/lxlib.h b/src/sysbin/lx/lxlib.h index 260db97..643d5c8 100644 --- a/src/sysbin/lx/lxlib.h +++ b/src/sysbin/lx/lxlib.h @@ -8,9 +8,12 @@ // Helper for libraries bool lx_checkboolean(lua_State *L, int arg); +void* lx_checklightudata(lua_State *L, int arg); void setintfield (lua_State *L, const char *key, int value); void setstrfield (lua_State *L, const char *key, const char* value); +int getintfield(lua_State *L, int arg, const char *key); + #define LX_SYSLIBNAME "lx.sys" LUAMOD_API int (lx_open_sys) (lua_State *L); @@ -22,6 +25,9 @@ LUAMOD_API int (lx_open_ioctl) (lua_State *L); LUAMOD_API int (luaopen_cmsgpack) (lua_State *L); #define lx_open_msg luaopen_cmsgpack +#define LX_DRAWLIBNAME "lx.draw" +LUAMOD_API int (lx_open_draw) (lua_State *L); + /* open all previous libraries */ LUALIB_API void (lx_openlibs) (lua_State *L); |