aboutsummaryrefslogtreecommitdiffstats
path: root/window.c
diff options
context:
space:
mode:
authorTomasz Kramkowski <tk@the-tk.com>2021-02-11 12:15:12 +0000
committerTomasz Kramkowski <tk@the-tk.com>2021-02-11 14:25:14 +0000
commitbb97e8aaa15217afe1f3fcdc93662ab03b8ae9d9 (patch)
tree64fa5b5ba419e72bc6acaddadbc51c73646295fa /window.c
downloadluiml-bb97e8aaa15217afe1f3fcdc93662ab03b8ae9d9.tar.gz
luiml-bb97e8aaa15217afe1f3fcdc93662ab03b8ae9d9.tar.xz
luiml-bb97e8aaa15217afe1f3fcdc93662ab03b8ae9d9.zip
init commit
Diffstat (limited to 'window.c')
-rw-r--r--window.c179
1 files changed, 179 insertions, 0 deletions
diff --git a/window.c b/window.c
new file mode 100644
index 0000000..314d589
--- /dev/null
+++ b/window.c
@@ -0,0 +1,179 @@
+#include <SDL.h>
+#include <glib-object.h>
+#include <lauxlib.h>
+#include <lua.h>
+#include <pango/pangoft2.h>
+
+#include "window.h"
+#include "sdl.h"
+
+#define UD_WINDOW "libluiml.window"
+
+struct window {
+ SDL_Window *win;
+ SDL_Renderer *ren;
+ PangoContext *pc;
+};
+
+/* window:destroy_window() */
+static int destroy_window(lua_State *L)
+{
+ struct window *w;
+
+ w = luaL_checkudata(L, 1, UD_WINDOW);
+ SDL_DestroyWindow(w->win);
+ g_object_unref(w->pc);
+
+ release_sdl();
+
+ return 0;
+}
+
+#include "window_wait_event.c"
+
+/* window:get_dimensions() -> width, height */
+static int get_dimensions(lua_State *L)
+{
+ struct window *w;
+ int width, height;
+
+ w = luaL_checkudata(L, 1, UD_WINDOW);
+
+ SDL_GetWindowSize(w->win, &width, &height);
+
+ lua_pushnumber(L, width);
+ lua_pushnumber(L, height);
+
+ return 2;
+}
+
+double clamp(double v, double min, double max)
+{
+ if (v < min) return min;
+ if (v > max) return max;
+ return v;
+}
+
+/* window:draw_rect(x, y, width, height, r, g, b) */
+static int draw_rect(lua_State *L)
+{
+ struct window *w;
+ SDL_Rect r;
+ struct {
+ Uint8 r, g, b;
+ } colour;
+
+ w = luaL_checkudata(L, 1, UD_WINDOW);
+ r.x = luaL_checknumber(L, 2);
+ r.y = luaL_checknumber(L, 3);
+ r.w = luaL_checknumber(L, 4);
+ r.h = luaL_checknumber(L, 5);
+ colour.r = round(clamp(luaL_checknumber(L, 6), 0, 1) * 255.0);
+ colour.g = round(clamp(luaL_checknumber(L, 7), 0, 1) * 255.0);
+ colour.b = round(clamp(luaL_checknumber(L, 8), 0, 1) * 255.0);
+
+ SDL_SetRenderDrawColor(w->ren, colour.r, colour.g, colour.b, SDL_ALPHA_OPAQUE);
+ SDL_RenderFillRect(w->ren, &r);
+
+ return 0;
+}
+
+static int draw_text(lua_State *L)
+{
+ PangoRectangle extents;
+ PangoLayout *layout;
+ int width, height;
+ struct window *w;
+ const char *s;
+ SDL_Rect r;
+ size_t l;
+
+ w = luaL_checkudata(L, 1, UD_WINDOW);
+ r.x = luaL_checknumber(L, 2);
+ r.y = luaL_checknumber(L, 3);
+ r.w = luaL_checknumber(L, 4);
+ r.h = luaL_checknumber(L, 5);
+ s = luaL_checklstring(L, 6, &l);
+
+ layout = pango_layout_new(w->pc);
+ pango_layout_set_width(layout, r.w * PANGO_SCALE);
+ pango_layout_set_height(layout, r.h * PANGO_SCALE);
+ pango_layout_set_text(layout, s, l);
+ pango_layout_get_extents(layout, NULL, &extents);
+ width = PANGO_PIXELS(extents.width);
+ height = PANGO_PIXELS(extents.height);
+
+ return 0;
+}
+
+static int show(lua_State *L)
+{
+ struct window *w;
+
+ w = luaL_checkudata(L, 1, UD_WINDOW);
+
+ SDL_RenderPresent(w->ren);
+
+ return 0;
+}
+
+/* create_window(title) -> window */
+int create_window(lua_State *L)
+{
+ static const struct luaL_Reg window_metatable[] = {
+ {"__gc", destroy_window},
+ {"wait_event", wait_event},
+ {"get_dimensions", get_dimensions},
+ {"draw_rect", draw_rect},
+ {"draw_text", draw_text},
+ {"show", show},
+ {NULL, NULL},
+ };
+ PangoFontMap *fontmap;
+ const char *title, *failed;
+ struct window *w;
+
+ if (luaL_newmetatable(L, UD_WINDOW)) {
+ lua_pushstring(L, "__index");
+ lua_pushvalue(L, -2);
+ lua_settable(L, -3);
+ luaL_register(L, NULL, window_metatable);
+ lua_pop(L, 1);
+ }
+
+ title = luaL_checkstring(L, 1);
+
+ acquire_sdl();
+
+ w = lua_newuserdata(L, sizeof *w);
+ w->win = SDL_CreateWindow(title,
+ SDL_WINDOWPOS_UNDEFINED,
+ SDL_WINDOWPOS_UNDEFINED,
+ 640, 480, SDL_WINDOW_RESIZABLE);
+
+ if (w->win == NULL) {
+ failed = "SDL_CreateWindow";
+ goto fail_win;
+ }
+
+ w->ren = SDL_CreateRenderer(w->win, 0, SDL_RENDERER_PRESENTVSYNC);
+
+ if (w->ren == NULL) {
+ failed = "SDL_CreateRenderer";
+ goto fail_ren;
+ }
+
+
+ fontmap = pango_ft2_font_map_new();
+ w->pc = pango_font_map_create_context(fontmap);
+ g_object_unref(fontmap);
+
+ luaL_getmetatable(L, UD_WINDOW);
+ lua_setmetatable(L, -2);
+
+ return 1;
+
+fail_ren: SDL_DestroyWindow(w->win);
+fail_win: release_sdl();
+ return sdl_error(L, failed);
+}