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/lxdrawlib.c | |
parent | f8334e283c5eb0efeb4bb8a134041e18388d5f01 (diff) | |
download | kogata-ed153e6a5b9f001bbe49128e6bc53053f55dd37b.tar.gz kogata-ed153e6a5b9f001bbe49128e6bc53053f55dd37b.zip |
Can plot on a surface from lua
Diffstat (limited to 'src/sysbin/lx/lxdrawlib.c')
-rw-r--r-- | src/sysbin/lx/lxdrawlib.c | 160 |
1 files changed, 160 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 :*/ |