#include #include #include #include "setup.h" struct window_data_t { GLFWwindow * window; struct h_glfw_window_data_t data; }; GLFWwindow ** create_window(lua_State *L) { /* allocate userdata memory */ struct window_data_t *d = lua_newuserdata(L, sizeof(struct window_data_t)); GLFWwindow ** window = &(d->window); /* set metatable */ int self = lua_gettop(L); luaL_getmetatable(L, glfw_window_tname); lua_setmetatable(L, -2); /* configure window data struct */ d->data.L = L; lua_pushvalue(L, self); d->data.self_ref = luaL_ref(L, LUA_REGISTRYINDEX); d->data.key_cb_ref = LUA_NOREF; d->data.char_cb_ref = LUA_NOREF; d->data.char_mods_cb_ref = LUA_NOREF; d->data.mouse_button_cb_ref = LUA_NOREF; d->data.cursor_pos_cb_ref = LUA_NOREF; d->data.cursor_enter_cb_ref = LUA_NOREF; d->data.scroll_cb_ref = LUA_NOREF; d->data.drop_cb_ref = LUA_NOREF; d->data.pos_cb_ref = LUA_NOREF; d->data.size_cb_ref = LUA_NOREF; d->data.close_cb_ref = LUA_NOREF; d->data.refresh_cb_ref = LUA_NOREF; d->data.focus_cb_ref = LUA_NOREF; d->data.iconify_cb_ref = LUA_NOREF; d->data.maximize_cb_ref = LUA_NOREF; d->data.framebuffer_size_cb_ref = LUA_NOREF; d->data.content_scale_cb_ref = LUA_NOREF; glfwSetWindowUserPointer(*window, &(d->data)); return window; } int glfwDefaultWindowHints_bind(lua_State *L) { glfwDefaultWindowHints(); return 0; } int glfwWindowHint_bind(lua_State *L) { int hint = luaL_checkinteger(L, 1); int value = luaL_checkinteger(L, 2); glfwWindowHint(hint, value); return 0; } int glfwWindowHintString_bind(lua_State *L) { int hint = luaL_checkinteger(L, 1); const char * value = luaL_checkstring(L, 2); glfwWindowHintString(hint, value); return 0; } int glfwCreateWindow_bind(lua_State *L) { int width = luaL_checkinteger(L, 1); int height = luaL_checkinteger(L, 2); const char * title = luaL_checkstring(L, 3); GLFWmonitor ** monitor = luaL_checkudata(L, 4, glfw_monitor_tname); GLFWwindow ** share = luaL_checkudata(L, 5, glfw_window_tname); GLFWwindow ** window = create_window(L); *window = glfwCreateWindow(width, height, title, *monitor, *share); return 1; } int glfwDestroyWindow_bind(lua_State *L) { GLFWwindow ** window = luaL_checkudata(L, 1, glfw_window_tname); glfwDestroyWindow(*window); return 0; } int glfwWindowShouldClose_bind(lua_State *L) { GLFWwindow ** window = luaL_checkudata(L, 1, glfw_window_tname); int bind_result = glfwWindowShouldClose(*window); lua_pushinteger(L, bind_result); return 1; } int glfwSetWindowShouldClose_bind(lua_State *L) { GLFWwindow ** window = luaL_checkudata(L, 1, glfw_window_tname); int value = luaL_checkinteger(L, 2); glfwSetWindowShouldClose(*window, value); return 0; } int glfwSetWindowTitle_bind(lua_State *L) { GLFWwindow ** window = luaL_checkudata(L, 1, glfw_window_tname); const char * title = luaL_checkstring(L, 2); glfwSetWindowTitle(*window, title); return 0; } int glfwSetWindowIcon_bind(lua_State *L) { GLFWwindow ** window = luaL_checkudata(L, 1, glfw_window_tname); int count = luaL_checkinteger(L, 2); const GLFWimage * images = lua_touserdata(L, 3); glfwSetWindowIcon(*window, count, images); return 0; } int glfwGetWindowPos_bind(lua_State *L) { GLFWwindow ** window = luaL_checkudata(L, 1, glfw_window_tname); int xpos, ypos; glfwGetWindowPos(*window, &xpos, &ypos); lua_pushinteger(L, xpos); lua_pushinteger(L, ypos); return 2; } int glfwSetWindowPos_bind(lua_State *L) { GLFWwindow ** window = luaL_checkudata(L, 1, glfw_window_tname); int xpos = luaL_checkinteger(L, 2); int ypos = luaL_checkinteger(L, 3); glfwSetWindowPos(*window, xpos, ypos); return 0; } int glfwGetWindowSize_bind(lua_State *L) { GLFWwindow ** window = luaL_checkudata(L, 1, glfw_window_tname); int width, height; glfwGetWindowSize(*window, &width, &height); lua_pushinteger(L, width); lua_pushinteger(L, height); return 2; } int glfwSetWindowSizeLimits_bind(lua_State *L) { GLFWwindow ** window = luaL_checkudata(L, 1, glfw_window_tname); int minwidth = luaL_checkinteger(L, 2); int minheight = luaL_checkinteger(L, 3); int maxwidth = luaL_checkinteger(L, 4); int maxheight = luaL_checkinteger(L, 5); glfwSetWindowSizeLimits(*window, minwidth, minheight, maxwidth, maxheight); return 0; } int glfwSetWindowAspectRatio_bind(lua_State *L) { GLFWwindow ** window = luaL_checkudata(L, 1, glfw_window_tname); int numer = luaL_checkinteger(L, 2); int denom = luaL_checkinteger(L, 3); glfwSetWindowAspectRatio(*window, numer, denom); return 0; } int glfwSetWindowSize_bind(lua_State *L) { GLFWwindow ** window = luaL_checkudata(L, 1, glfw_window_tname); int width = luaL_checkinteger(L, 2); int height = luaL_checkinteger(L, 3); glfwSetWindowSize(*window, width, height); return 0; } int glfwGetFramebufferSize_bind(lua_State *L) { GLFWwindow ** window = luaL_checkudata(L, 1, glfw_window_tname); int width, height; glfwGetFramebufferSize(*window, &width, &height); lua_pushinteger(L, width); lua_pushinteger(L, height); return 2; } int glfwGetWindowFrameSize_bind(lua_State *L) { GLFWwindow ** window = luaL_checkudata(L, 1, glfw_window_tname); int left; int top; int right; int bottom; glfwGetWindowFrameSize(*window, &left, &top, &right, &bottom); lua_pushnumber(L, left); lua_pushnumber(L, top); lua_pushnumber(L, right); lua_pushnumber(L, bottom); return 4; } int glfwGetWindowContentScale_bind(lua_State *L) { GLFWwindow ** window = luaL_checkudata(L, 1, glfw_window_tname); float xscale; float yscale; glfwGetWindowContentScale(*window, &xscale, &yscale); lua_pushnumber(L, xscale); lua_pushnumber(L, yscale); return 0; } int glfwGetWindowOpacity_bind(lua_State *L) { GLFWwindow ** window = luaL_checkudata(L, 1, glfw_window_tname); float bind_result = glfwGetWindowOpacity(*window); lua_pushnumber(L, bind_result); return 1; } int glfwSetWindowOpacity_bind(lua_State *L) { GLFWwindow ** window = luaL_checkudata(L, 1, glfw_window_tname); float opacity = luaL_checknumber(L, 2); glfwSetWindowOpacity(*window, opacity); return 0; } int glfwIconifyWindow_bind(lua_State *L) { GLFWwindow ** window = luaL_checkudata(L, 1, glfw_window_tname); glfwIconifyWindow(*window); return 0; } int glfwRestoreWindow_bind(lua_State *L) { GLFWwindow ** window = luaL_checkudata(L, 1, glfw_window_tname); glfwRestoreWindow(*window); return 0; } int glfwMaximizeWindow_bind(lua_State *L) { GLFWwindow ** window = luaL_checkudata(L, 1, glfw_window_tname); glfwMaximizeWindow(*window); return 0; } int glfwShowWindow_bind(lua_State *L) { GLFWwindow ** window = luaL_checkudata(L, 1, glfw_window_tname); glfwShowWindow(*window); return 0; } int glfwHideWindow_bind(lua_State *L) { GLFWwindow ** window = luaL_checkudata(L, 1, glfw_window_tname); glfwHideWindow(*window); return 0; } int glfwFocusWindow_bind(lua_State *L) { GLFWwindow ** window = luaL_checkudata(L, 1, glfw_window_tname); glfwFocusWindow(*window); return 0; } int glfwRequestWindowAttention_bind(lua_State *L) { GLFWwindow ** window = luaL_checkudata(L, 1, glfw_window_tname); glfwRequestWindowAttention(*window); return 0; } int glfwGetWindowMonitor_bind(lua_State *L) { GLFWwindow ** window = luaL_checkudata(L, 1, glfw_window_tname); GLFWmonitor **monitor = create_monitor(L); *monitor = glfwGetWindowMonitor(*window); return 1; } int glfwSetWindowMonitor_bind(lua_State *L) { GLFWwindow ** window = luaL_checkudata(L, 1, glfw_window_tname); GLFWmonitor ** monitor = luaL_checkudata(L, 2, glfw_monitor_tname); int xpos = luaL_checkinteger(L, 3); int ypos = luaL_checkinteger(L, 4); int width = luaL_checkinteger(L, 5); int height = luaL_checkinteger(L, 6); int refreshRate = luaL_checkinteger(L, 7); glfwSetWindowMonitor(*window, *monitor, xpos, ypos, width, height, refreshRate); return 0; } int glfwGetWindowAttrib_bind(lua_State *L) { GLFWwindow ** window = luaL_checkudata(L, 1, glfw_window_tname); int attrib = luaL_checkinteger(L, 2); int bind_result = glfwGetWindowAttrib(*window, attrib); lua_pushinteger(L, bind_result); return 1; } int glfwSetWindowAttrib_bind(lua_State *L) { GLFWwindow ** window = luaL_checkudata(L, 1, glfw_window_tname); int attrib = luaL_checkinteger(L, 2); int value = luaL_checkinteger(L, 3); glfwSetWindowAttrib(*window, attrib, value); return 0; } /* helpers for creating callback setter binds */ static GLFWwindow ** check_callback_args(lua_State *L) { GLFWwindow ** window = luaL_checkudata(L, 1, glfw_window_tname); int type = lua_type(L, 2); if (type == LUA_TNIL || type == LUA_TFUNCTION) { return window; } else { luaL_typerror(L, 2, "nil or function"); } } #define SET_CALLBACK(L, win, setter, cb, key) \ do { \ /* get window data */ \ struct h_glfw_window_data_t *data = glfwGetWindowUserPointer(win); \ \ /* push old callback */ \ lua_rawgeti(L, LUA_REGISTRYINDEX, data->key); \ \ /* set new callback */ \ if (lua_isnil(L, 2)) { \ /* new "callback" is nil, unset */ \ setter(win, NULL); \ data->key = LUA_NOREF; \ } \ else { \ /* new callback is function */ \ setter(win, cb); \ lua_pushvalue(L, 2); \ data->key = luaL_ref(L, LUA_REGISTRYINDEX); \ } \ } while(0) #define RETRIEVE_CALLBACK(win, key) \ struct h_glfw_window_data_t *data = glfwGetWindowUserPointer(win); \ if (data->key == LUA_NOREF) { return; } \ lua_State *L = data->L; \ lua_rawgeti(L, LUA_REGISTRYINDEX, data->key); static void h_pos_cb(GLFWwindow *window, int xpos, int ypos) { RETRIEVE_CALLBACK(window, pos_cb_ref); lua_rawgeti(L, LUA_REGISTRYINDEX, data->self_ref); lua_pushinteger(L, xpos); lua_pushinteger(L, ypos); lua_call(L, 3, 0); } int glfwSetWindowPosCallback_bind(lua_State *L) { GLFWwindow ** window = check_callback_args(L); SET_CALLBACK(L, *window, glfwSetWindowPosCallback, h_pos_cb, pos_cb_ref); return 1; } static void h_size_cb(GLFWwindow *window, int width, int height) { RETRIEVE_CALLBACK(window, size_cb_ref); lua_rawgeti(L, LUA_REGISTRYINDEX, data->self_ref); lua_pushinteger(L, width); lua_pushinteger(L, height); lua_call(L, 3, 0); } int glfwSetWindowSizeCallback_bind(lua_State *L) { GLFWwindow ** window = check_callback_args(L); SET_CALLBACK(L, *window, glfwSetWindowSizeCallback, h_size_cb, size_cb_ref); return 1; } static void h_close_cb(GLFWwindow *window) { RETRIEVE_CALLBACK(window, close_cb_ref); lua_rawgeti(L, LUA_REGISTRYINDEX, data->self_ref); lua_call(L, 1, 0); } int glfwSetWindowCloseCallback_bind(lua_State *L) { GLFWwindow ** window = check_callback_args(L); SET_CALLBACK(L, *window, glfwSetWindowCloseCallback, h_close_cb, close_cb_ref); return 1; } static void h_refresh_cb(GLFWwindow *window) { RETRIEVE_CALLBACK(window, refresh_cb_ref); lua_rawgeti(L, LUA_REGISTRYINDEX, data->self_ref); lua_call(L, 1, 0); } int glfwSetWindowRefreshCallback_bind(lua_State *L) { GLFWwindow ** window = check_callback_args(L); SET_CALLBACK(L, *window, glfwSetWindowRefreshCallback, h_refresh_cb, refresh_cb_ref); return 1; } static void h_focus_cb(GLFWwindow *window, int focused) { RETRIEVE_CALLBACK(window, focus_cb_ref); lua_rawgeti(L, LUA_REGISTRYINDEX, data->self_ref); lua_pushinteger(L, focused); lua_call(L, 2, 0); } int glfwSetWindowFocusCallback_bind(lua_State *L) { GLFWwindow ** window = check_callback_args(L); SET_CALLBACK( L, *window, glfwSetWindowFocusCallback, h_focus_cb, focus_cb_ref ); return 1; } static void h_iconify_cb(GLFWwindow *window, int iconified) { RETRIEVE_CALLBACK(window, iconify_cb_ref); lua_rawgeti(L, LUA_REGISTRYINDEX, data->self_ref); lua_pushinteger(L, iconified); lua_call(L, 2, 0); } int glfwSetWindowIconifyCallback_bind(lua_State *L) { GLFWwindow ** window = check_callback_args(L); SET_CALLBACK( L, *window, glfwSetWindowIconifyCallback, h_iconify_cb, iconify_cb_ref ); return 1; } static void h_maximize_cb(GLFWwindow *window, int maximized) { RETRIEVE_CALLBACK(window, maximize_cb_ref); lua_rawgeti(L, LUA_REGISTRYINDEX, data->self_ref); lua_pushinteger(L, maximized); lua_call(L, 2, 0); } int glfwSetWindowMaximizeCallback_bind(lua_State *L) { GLFWwindow ** window = check_callback_args(L); SET_CALLBACK( L, *window, glfwSetWindowMaximizeCallback, h_maximize_cb, maximize_cb_ref ); return 1; } static void h_framebuffer_size_cb(GLFWwindow *window, int width, int height) { RETRIEVE_CALLBACK(window, framebuffer_size_cb_ref); lua_rawgeti(L, LUA_REGISTRYINDEX, data->self_ref); lua_pushinteger(L, width); lua_pushinteger(L, height); lua_call(L, 3, 0); } int glfwSetFramebufferSizeCallback_bind(lua_State *L) { GLFWwindow ** window = check_callback_args(L); SET_CALLBACK( L, *window, glfwSetFramebufferSizeCallback, h_framebuffer_size_cb, framebuffer_size_cb_ref ); return 1; } static void h_content_scale_cb(GLFWwindow *window, float xscale, float yscale) { RETRIEVE_CALLBACK(window, content_scale_cb_ref); lua_rawgeti(L, LUA_REGISTRYINDEX, data->self_ref); lua_pushnumber(L, xscale); lua_pushnumber(L, yscale); lua_call(L, 3, 0); } int glfwSetWindowContentScaleCallback_bind(lua_State *L) { GLFWwindow ** window = check_callback_args(L); SET_CALLBACK( L, *window, glfwSetWindowContentScaleCallback, h_content_scale_cb, content_scale_cb_ref ); return 1; } int glfwPollEvents_bind(lua_State *L) { glfwPollEvents(); return 0; } int glfwWaitEvents_bind(lua_State *L) { glfwWaitEvents(); return 0; } int glfwWaitEventsTimeout_bind(lua_State *L) { double timeout = luaL_checknumber(L, 1); glfwWaitEventsTimeout(timeout); return 0; } int glfwPostEmptyEvent_bind(lua_State *L) { glfwPostEmptyEvent(); return 0; } int glfwSwapBuffers_bind(lua_State *L) { GLFWwindow ** window = luaL_checkudata(L, 1, glfw_window_tname); glfwSwapBuffers(*window); return 0; }