/* ** Lua eXtended ioctl library */ #define lxdrawlib_c #define LUA_LIB #include #include #include #include #include #include #include #include #include #include #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 :*/