summaryrefslogtreecommitdiff
path: root/src/glfw
diff options
context:
space:
mode:
Diffstat (limited to 'src/glfw')
-rw-r--r--src/glfw/CMakeLists.txt11
-rw-r--r--src/glfw/bind47
-rw-r--r--src/glfw/bind.bind439
-rw-r--r--src/glfw/context.c49
-rw-r--r--src/glfw/init.c58
-rw-r--r--src/glfw/input.c586
-rw-r--r--src/glfw/monitor.c250
-rw-r--r--src/glfw/setup.c33
-rw-r--r--src/glfw/setup.h419
-rw-r--r--src/glfw/window.c588
10 files changed, 2480 insertions, 0 deletions
diff --git a/src/glfw/CMakeLists.txt b/src/glfw/CMakeLists.txt
new file mode 100644
index 0000000..6637d2b
--- /dev/null
+++ b/src/glfw/CMakeLists.txt
@@ -0,0 +1,11 @@
+project(honey-engine)
+
+
+target_sources(honey PUBLIC
+ ${CMAKE_CURRENT_LIST_DIR}/setup.c
+ ${CMAKE_CURRENT_LIST_DIR}/context.c
+ ${CMAKE_CURRENT_LIST_DIR}/init.c
+ ${CMAKE_CURRENT_LIST_DIR}/input.c
+ ${CMAKE_CURRENT_LIST_DIR}/monitor.c
+ ${CMAKE_CURRENT_LIST_DIR}/window.c
+)
diff --git a/src/glfw/bind b/src/glfw/bind
new file mode 100644
index 0000000..ce1aace
--- /dev/null
+++ b/src/glfw/bind
@@ -0,0 +1,47 @@
+void glfwDefaultWindowHints ()
+void glfwWindowHint (int hint, int value)
+void glfwWindowHintString (int hint, const char *value)
+GLFWwindow * glfwCreateWindow (int width, int height, const char *title, GLFWmonitor *monitor, GLFWwindow *share)
+void glfwDestroyWindow (GLFWwindow *window)
+int glfwWindowShouldClose (GLFWwindow *window)
+void glfwSetWindowShouldClose (GLFWwindow *window, int value)
+void glfwSetWindowTitle (GLFWwindow *window, const char *title)
+void glfwSetWindowIcon (GLFWwindow *window, int count, const GLFWimage *images)
+void glfwGetWindowPos (GLFWwindow *window, int *xpos, int *ypos)
+void glfwSetWindowPos (GLFWwindow *window, int xpos, int ypos)
+void glfwGetWindowSize (GLFWwindow *window, int *width, int *height)
+void glfwSetWindowSizeLimits (GLFWwindow *window, int minwidth, int minheight, int maxwidth, int maxheight)
+void glfwSetWindowAspectRatio (GLFWwindow *window, int numer, int denom)
+void glfwSetWindowSize (GLFWwindow *window, int width, int height)
+void glfwGetFramebufferSize (GLFWwindow *window, int *width, int *height)
+void glfwGetWindowFrameSize (GLFWwindow *window, int *left, int *top, int *right, int *bottom)
+void glfwGetWindowContentScale (GLFWwindow *window, float *xscale, float *yscale)
+float glfwGetWindowOpacity (GLFWwindow *window)
+void glfwSetWindowOpacity (GLFWwindow *window, float opacity)
+void glfwIconifyWindow (GLFWwindow *window)
+void glfwRestoreWindow (GLFWwindow *window)
+void glfwMaximizeWindow (GLFWwindow *window)
+void glfwShowWindow (GLFWwindow *window)
+void glfwHideWindow (GLFWwindow *window)
+void glfwFocusWindow (GLFWwindow *window)
+void glfwRequestWindowAttention (GLFWwindow *window)
+GLFWmonitor * glfwGetWindowMonitor (GLFWwindow *window)
+void glfwSetWindowMonitor (GLFWwindow *window, GLFWmonitor *monitor, int xpos, int ypos, int width, int height, int refreshRate)
+int glfwGetWindowAttrib (GLFWwindow *window, int attrib)
+void glfwSetWindowAttrib (GLFWwindow *window, int attrib, int value)
+void glfwSetWindowUserPointer (GLFWwindow *window, void *pointer)
+void * glfwGetWindowUserPointer (GLFWwindow *window)
+GLFWwindowposfun glfwSetWindowPosCallback (GLFWwindow *window, GLFWwindowposfun callback)
+GLFWwindowsizefun glfwSetWindowSizeCallback (GLFWwindow *window, GLFWwindowsizefun callback)
+GLFWwindowclosefun glfwSetWindowCloseCallback (GLFWwindow *window, GLFWwindowclosefun callback)
+GLFWwindowrefreshfun glfwSetWindowRefreshCallback (GLFWwindow *window, GLFWwindowrefreshfun callback)
+GLFWwindowfocusfun glfwSetWindowFocusCallback (GLFWwindow *window, GLFWwindowfocusfun callback)
+GLFWwindowiconifyfun glfwSetWindowIconifyCallback (GLFWwindow *window, GLFWwindowiconifyfun callback)
+GLFWwindowmaximizefun glfwSetWindowMaximizeCallback (GLFWwindow *window, GLFWwindowmaximizefun callback)
+GLFWframebuffersizefun glfwSetFramebufferSizeCallback (GLFWwindow *window, GLFWframebuffersizefun callback)
+GLFWwindowcontentscalefun glfwSetWindowContentScaleCallback (GLFWwindow *window, GLFWwindowcontentscalefun callback)
+void glfwPollEvents ()
+void glfwWaitEvents ()
+void glfwWaitEventsTimeout (double timeout)
+void glfwPostEmptyEvent ()
+void glfwSwapBuffers (GLFWwindow *window)
diff --git a/src/glfw/bind.bind b/src/glfw/bind.bind
new file mode 100644
index 0000000..b75587a
--- /dev/null
+++ b/src/glfw/bind.bind
@@ -0,0 +1,439 @@
+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 = get: GLFWmonitor *
+ GLFWwindow * share = get: GLFWwindow *
+ GLFWwindow * bind_result = glfwCreateWindow(width, height, title, monitor, share);
+ /* push result */
+ return /* count */;
+}
+
+
+int glfwDestroyWindow_bind(lua_State *L)
+{
+ GLFWwindow * window = get: GLFWwindow *
+ glfwDestroyWindow(window);
+ return 0;
+}
+
+
+int glfwWindowShouldClose_bind(lua_State *L)
+{
+ GLFWwindow * window = get: GLFWwindow *
+ int bind_result = glfwWindowShouldClose(window);
+ lua_pushinteger(L, bind_result);
+ return 1;
+}
+
+
+int glfwSetWindowShouldClose_bind(lua_State *L)
+{
+ GLFWwindow * window = get: GLFWwindow *
+ int value = luaL_checkinteger(L, 2);
+ glfwSetWindowShouldClose(window, value);
+ return 0;
+}
+
+
+int glfwSetWindowTitle_bind(lua_State *L)
+{
+ GLFWwindow * window = get: GLFWwindow *
+ const char * title = luaL_checkstring(L, 2);
+ glfwSetWindowTitle(window, title);
+ return 0;
+}
+
+
+int glfwSetWindowIcon_bind(lua_State *L)
+{
+ GLFWwindow * window = get: GLFWwindow *
+ int count = luaL_checkinteger(L, 2);
+ const GLFWimage * images = get: const GLFWimage *
+ glfwSetWindowIcon(window, count, images);
+ return 0;
+}
+
+
+int glfwGetWindowPos_bind(lua_State *L)
+{
+ GLFWwindow * window = get: GLFWwindow *
+ int * xpos = get: int *
+ int * ypos = get: int *
+ glfwGetWindowPos(window, xpos, ypos);
+ return 0;
+}
+
+
+int glfwSetWindowPos_bind(lua_State *L)
+{
+ GLFWwindow * window = get: GLFWwindow *
+ 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 = get: GLFWwindow *
+ int * width = get: int *
+ int * height = get: int *
+ glfwGetWindowSize(window, width, height);
+ return 0;
+}
+
+
+int glfwSetWindowSizeLimits_bind(lua_State *L)
+{
+ GLFWwindow * window = get: GLFWwindow *
+ 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 = get: GLFWwindow *
+ 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 = get: GLFWwindow *
+ 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 = get: GLFWwindow *
+ int * width = get: int *
+ int * height = get: int *
+ glfwGetFramebufferSize(window, width, height);
+ return 0;
+}
+
+
+int glfwGetWindowFrameSize_bind(lua_State *L)
+{
+ GLFWwindow * window = get: GLFWwindow *
+ int * left = get: int *
+ int * top = get: int *
+ int * right = get: int *
+ int * bottom = get: int *
+ glfwGetWindowFrameSize(window, left, top, right, bottom);
+ return 0;
+}
+
+
+int glfwGetWindowContentScale_bind(lua_State *L)
+{
+ GLFWwindow * window = get: GLFWwindow *
+ float * xscale = get: float *
+ float * yscale = get: float *
+ glfwGetWindowContentScale(window, xscale, yscale);
+ return 0;
+}
+
+
+int glfwGetWindowOpacity_bind(lua_State *L)
+{
+ GLFWwindow * window = get: GLFWwindow *
+ float bind_result = glfwGetWindowOpacity(window);
+ lua_pushnumber(L, bind_result);
+ return 1;
+}
+
+
+int glfwSetWindowOpacity_bind(lua_State *L)
+{
+ GLFWwindow * window = get: GLFWwindow *
+ float opacity = luaL_checknumber(L, 2);
+ glfwSetWindowOpacity(window, opacity);
+ return 0;
+}
+
+
+int glfwIconifyWindow_bind(lua_State *L)
+{
+ GLFWwindow * window = get: GLFWwindow *
+ glfwIconifyWindow(window);
+ return 0;
+}
+
+
+int glfwRestoreWindow_bind(lua_State *L)
+{
+ GLFWwindow * window = get: GLFWwindow *
+ glfwRestoreWindow(window);
+ return 0;
+}
+
+
+int glfwMaximizeWindow_bind(lua_State *L)
+{
+ GLFWwindow * window = get: GLFWwindow *
+ glfwMaximizeWindow(window);
+ return 0;
+}
+
+
+int glfwShowWindow_bind(lua_State *L)
+{
+ GLFWwindow * window = get: GLFWwindow *
+ glfwShowWindow(window);
+ return 0;
+}
+
+
+int glfwHideWindow_bind(lua_State *L)
+{
+ GLFWwindow * window = get: GLFWwindow *
+ glfwHideWindow(window);
+ return 0;
+}
+
+
+int glfwFocusWindow_bind(lua_State *L)
+{
+ GLFWwindow * window = get: GLFWwindow *
+ glfwFocusWindow(window);
+ return 0;
+}
+
+
+int glfwRequestWindowAttention_bind(lua_State *L)
+{
+ GLFWwindow * window = get: GLFWwindow *
+ glfwRequestWindowAttention(window);
+ return 0;
+}
+
+
+int glfwGetWindowMonitor_bind(lua_State *L)
+{
+ GLFWwindow * window = get: GLFWwindow *
+ GLFWmonitor * bind_result = glfwGetWindowMonitor(window);
+ /* push result */
+ return /* count */;
+}
+
+
+int glfwSetWindowMonitor_bind(lua_State *L)
+{
+ GLFWwindow * window = get: GLFWwindow *
+ GLFWmonitor * monitor = get: GLFWmonitor *
+ 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 = get: GLFWwindow *
+ 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 = get: GLFWwindow *
+ int attrib = luaL_checkinteger(L, 2);
+ int value = luaL_checkinteger(L, 3);
+ glfwSetWindowAttrib(window, attrib, value);
+ return 0;
+}
+
+
+int glfwSetWindowUserPointer_bind(lua_State *L)
+{
+ GLFWwindow * window = get: GLFWwindow *
+ void * pointer = get: void *
+ glfwSetWindowUserPointer(window, pointer);
+ return 0;
+}
+
+
+int glfwGetWindowUserPointer_bind(lua_State *L)
+{
+ GLFWwindow * window = get: GLFWwindow *
+ void * bind_result = glfwGetWindowUserPointer(window);
+ /* push result */
+ return /* count */;
+}
+
+
+int glfwSetWindowPosCallback_bind(lua_State *L)
+{
+ GLFWwindow * window = get: GLFWwindow *
+ GLFWwindowposfun callback = get: GLFWwindowposfun
+ GLFWwindowposfun bind_result = glfwSetWindowPosCallback(window, callback);
+ /* push result */
+ return /* count */;
+}
+
+
+int glfwSetWindowSizeCallback_bind(lua_State *L)
+{
+ GLFWwindow * window = get: GLFWwindow *
+ GLFWwindowsizefun callback = get: GLFWwindowsizefun
+ GLFWwindowsizefun bind_result = glfwSetWindowSizeCallback(window, callback);
+ /* push result */
+ return /* count */;
+}
+
+
+int glfwSetWindowCloseCallback_bind(lua_State *L)
+{
+ GLFWwindow * window = get: GLFWwindow *
+ GLFWwindowclosefun callback = get: GLFWwindowclosefun
+ GLFWwindowclosefun bind_result = glfwSetWindowCloseCallback(window, callback);
+ /* push result */
+ return /* count */;
+}
+
+
+int glfwSetWindowRefreshCallback_bind(lua_State *L)
+{
+ GLFWwindow * window = get: GLFWwindow *
+ GLFWwindowrefreshfun callback = get: GLFWwindowrefreshfun
+ GLFWwindowrefreshfun bind_result = glfwSetWindowRefreshCallback(window, callback);
+ /* push result */
+ return /* count */;
+}
+
+
+int glfwSetWindowFocusCallback_bind(lua_State *L)
+{
+ GLFWwindow * window = get: GLFWwindow *
+ GLFWwindowfocusfun callback = get: GLFWwindowfocusfun
+ GLFWwindowfocusfun bind_result = glfwSetWindowFocusCallback(window, callback);
+ /* push result */
+ return /* count */;
+}
+
+
+int glfwSetWindowIconifyCallback_bind(lua_State *L)
+{
+ GLFWwindow * window = get: GLFWwindow *
+ GLFWwindowiconifyfun callback = get: GLFWwindowiconifyfun
+ GLFWwindowiconifyfun bind_result = glfwSetWindowIconifyCallback(window, callback);
+ /* push result */
+ return /* count */;
+}
+
+
+int glfwSetWindowMaximizeCallback_bind(lua_State *L)
+{
+ GLFWwindow * window = get: GLFWwindow *
+ GLFWwindowmaximizefun callback = get: GLFWwindowmaximizefun
+ GLFWwindowmaximizefun bind_result = glfwSetWindowMaximizeCallback(window, callback);
+ /* push result */
+ return /* count */;
+}
+
+
+int glfwSetFramebufferSizeCallback_bind(lua_State *L)
+{
+ GLFWwindow * window = get: GLFWwindow *
+ GLFWframebuffersizefun callback = get: GLFWframebuffersizefun
+ GLFWframebuffersizefun bind_result = glfwSetFramebufferSizeCallback(window, callback);
+ /* push result */
+ return /* count */;
+}
+
+
+int glfwSetWindowContentScaleCallback_bind(lua_State *L)
+{
+ GLFWwindow * window = get: GLFWwindow *
+ GLFWwindowcontentscalefun callback = get: GLFWwindowcontentscalefun
+ GLFWwindowcontentscalefun bind_result = glfwSetWindowContentScaleCallback(window, callback);
+ /* push result */
+ return /* count */;
+}
+
+
+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 = get: GLFWwindow *
+ glfwSwapBuffers(window);
+ return 0;
+}
+
+
diff --git a/src/glfw/context.c b/src/glfw/context.c
new file mode 100644
index 0000000..e22533e
--- /dev/null
+++ b/src/glfw/context.c
@@ -0,0 +1,49 @@
+#include <lua.h>
+#include <lauxlib.h>
+#include <GLFW/glfw3.h>
+#include "setup.h"
+
+
+int glfwMakeContextCurrent_bind(lua_State *L)
+{
+ GLFWwindow ** window = luaL_checkudata(L, 1, glfw_window_tname);
+ glfwMakeContextCurrent(*window);
+ return 0;
+}
+
+
+int glfwGetCurrentContext_bind(lua_State *L)
+{
+ GLFWwindow * bind_result = glfwGetCurrentContext();
+ struct h_glfw_window_data_t *data = glfwGetWindowUserPointer(bind_result);
+ lua_rawgeti(L, LUA_REGISTRYINDEX, data->self_ref);
+ return 1;
+}
+
+
+int glfwSwapInterval_bind(lua_State *L)
+{
+ int interval = luaL_checkinteger(L, 1);
+ glfwSwapInterval(interval);
+ return 0;
+}
+
+
+int glfwExtensionSupported_bind(lua_State *L)
+{
+ const char * extension = luaL_checkstring(L, 1);
+ int bind_result = glfwExtensionSupported(extension);
+ lua_pushinteger(L, bind_result);
+ return 1;
+}
+
+
+int glfwGetProcAddress_bind(lua_State *L)
+{
+ const char * procname = luaL_checkstring(L, 1);
+ GLFWglproc bind_result = glfwGetProcAddress(procname);
+ lua_pushlightuserdata(L, bind_result);
+ return 1;
+}
+
+
diff --git a/src/glfw/init.c b/src/glfw/init.c
new file mode 100644
index 0000000..6d91d28
--- /dev/null
+++ b/src/glfw/init.c
@@ -0,0 +1,58 @@
+#include <lua.h>
+#include <lauxlib.h>
+#include <glad/glad.h>
+#include <GLFW/glfw3.h>
+#include "setup.h"
+
+
+int glfwInit_bind(lua_State *L)
+{
+ int bind_result = glfwInit();
+ lua_pushinteger(L, bind_result);
+ return 1;
+}
+
+
+int glfwTerminate_bind(lua_State *L)
+{
+ glfwTerminate();
+ return 0;
+}
+
+
+int glfwInitHint_bind(lua_State *L)
+{
+ int hint = luaL_checkinteger(L, 1);
+ int value = luaL_checkinteger(L, 2);
+ glfwInitHint(hint, value);
+ return 0;
+}
+
+
+int glfwGetVersion_bind(lua_State *L)
+{
+ int major, minor, rev;
+ glfwGetVersion(&major, &minor, &rev);
+ lua_pushinteger(L, major);
+ lua_pushinteger(L, minor);
+ lua_pushinteger(L, rev);
+ return 3;
+}
+
+
+int glfwGetVersionString_bind(lua_State *L)
+{
+ const char * bind_result = glfwGetVersionString();
+ lua_pushstring(L, bind_result);
+ return 1;
+}
+
+
+int glfwGetError_bind(lua_State *L)
+{
+ const char * description;
+ int bind_result = glfwGetError(&description);
+ lua_pushinteger(L, bind_result);
+ lua_pushstring(L, description);
+ return 2;
+}
diff --git a/src/glfw/input.c b/src/glfw/input.c
new file mode 100644
index 0000000..4233d56
--- /dev/null
+++ b/src/glfw/input.c
@@ -0,0 +1,586 @@
+#include <lua.h>
+#include <lauxlib.h>
+#include <GLFW/glfw3.h>
+#include "setup.h"
+
+
+int glfwGetInputMode_bind(lua_State *L)
+{
+ GLFWwindow ** window = luaL_checkudata(L, 1, glfw_window_tname);
+ int mode = luaL_checkinteger(L, 2);
+ int bind_result = glfwGetInputMode(*window, mode);
+ lua_pushinteger(L, bind_result);
+ return 1;
+}
+
+
+int glfwSetInputMode_bind(lua_State *L)
+{
+ GLFWwindow ** window = luaL_checkudata(L, 1, glfw_window_tname);
+ int mode = luaL_checkinteger(L, 2);
+ int value = luaL_checkinteger(L, 3);
+ glfwSetInputMode(*window, mode, value);
+ return 0;
+}
+
+
+int glfwRawMouseMotionSupported_bind(lua_State *L)
+{
+ int bind_result = glfwRawMouseMotionSupported();
+ lua_pushinteger(L, bind_result);
+ return 1;
+}
+
+
+int glfwGetKeyName_bind(lua_State *L)
+{
+ int key = luaL_checkinteger(L, 1);
+ int scancode = luaL_checkinteger(L, 2);
+ const char * bind_result = glfwGetKeyName(key, scancode);
+ lua_pushstring(L, bind_result);
+ return 1;
+}
+
+
+int glfwGetKeyScancode_bind(lua_State *L)
+{
+ int key = luaL_checkinteger(L, 1);
+ int bind_result = glfwGetKeyScancode(key);
+ lua_pushinteger(L, bind_result);
+ return 1;
+}
+
+
+int glfwGetKey_bind(lua_State *L)
+{
+ GLFWwindow ** window = luaL_checkudata(L, 1, glfw_window_tname);
+ int key = luaL_checkinteger(L, 2);
+ int bind_result = glfwGetKey(*window, key);
+ lua_pushinteger(L, bind_result);
+ return 1;
+}
+
+
+int glfwGetMouseButton_bind(lua_State *L)
+{
+ GLFWwindow ** window = luaL_checkudata(L, 1, glfw_window_tname);
+ int button = luaL_checkinteger(L, 2);
+ int bind_result = glfwGetMouseButton(*window, button);
+ lua_pushinteger(L, bind_result);
+ return 1;
+}
+
+
+int glfwGetCursorPos_bind(lua_State *L)
+{
+ GLFWwindow ** window = luaL_checkudata(L, 1, glfw_window_tname);
+ double xpos, ypos;
+ glfwGetCursorPos(*window, &xpos, &ypos);
+ lua_pushnumber(L, xpos);
+ lua_pushnumber(L, ypos);
+ return 2;
+}
+
+
+int glfwSetCursorPos_bind(lua_State *L)
+{
+ GLFWwindow ** window = luaL_checkudata(L, 1, glfw_window_tname);
+ double xpos = luaL_checknumber(L, 2);
+ double ypos = luaL_checknumber(L, 3);
+ glfwSetCursorPos(*window, xpos, ypos);
+ return 0;
+}
+
+
+static GLFWcursor ** create_cursor(lua_State *L)
+{
+ GLFWcursor **cursor = lua_newuserdata(L, sizeof(GLFWcursor *));
+ luaL_getmetatable(L, glfw_cursor_tname);
+ lua_setmetatable(L, -2);
+}
+
+int glfwCreateCursor_bind(lua_State *L)
+{
+ const GLFWimage * image = lua_touserdata(L, 1);
+ int xhot = luaL_checkinteger(L, 2);
+ int yhot = luaL_checkinteger(L, 3);
+
+ GLFWcursor **cursor = create_cursor(L);
+ *cursor = glfwCreateCursor(image, xhot, yhot);
+ return 1;
+}
+
+
+int glfwCreateStandardCursor_bind(lua_State *L)
+{
+ int shape = luaL_checkinteger(L, 1);
+ GLFWcursor **cursor = create_cursor(L);
+ *cursor = glfwCreateStandardCursor(shape);
+ return 1;
+}
+
+
+int glfwDestroyCursor_bind(lua_State *L)
+{
+ GLFWcursor ** cursor = luaL_checkudata(L, 1, glfw_cursor_tname);
+ glfwDestroyCursor(*cursor);
+ return 0;
+}
+
+
+int glfwSetCursor_bind(lua_State *L)
+{
+ GLFWwindow ** window = luaL_checkudata(L, 1, glfw_window_tname);
+ GLFWcursor ** cursor = luaL_checkudata(L, 2, glfw_cursor_tname);
+ glfwSetCursor(*window, *cursor);
+ 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_key_cb(
+ GLFWwindow *window,
+ int key, int scancode,
+ int action, int mods)
+{
+ RETRIEVE_CALLBACK(window, key_cb_ref);
+ /* push arguments */
+ lua_rawgeti(L, LUA_REGISTRYINDEX, data->self_ref);
+ lua_pushinteger(L, key);
+ lua_pushinteger(L, scancode);
+ lua_pushinteger(L, action);
+ lua_pushinteger(L, mods);
+ /* call */
+ lua_call(L, 5, 0);
+}
+int glfwSetKeyCallback_bind(lua_State *L)
+{
+ GLFWwindow **window = check_callback_args(L);
+ SET_CALLBACK(
+ L, *window,
+ glfwSetKeyCallback,
+ h_key_cb, key_cb_ref
+ );
+ return 1;
+}
+
+
+static void h_char_cb(GLFWwindow *window, unsigned int codepoint)
+{
+ RETRIEVE_CALLBACK(window, char_cb_ref);
+ /* push arguments */
+ lua_rawgeti(L, LUA_REGISTRYINDEX, data->self_ref);
+ lua_pushinteger(L, codepoint);
+ /* call */
+ lua_call(L, 2, 0);
+}
+int glfwSetCharCallback_bind(lua_State *L)
+{
+ GLFWwindow **window = check_callback_args(L);
+ SET_CALLBACK(
+ L, *window,
+ glfwSetCharCallback,
+ h_char_cb, char_cb_ref
+ );
+ return 1;
+}
+
+
+static void h_char_mods_cb(GLFWwindow *window, unsigned int codepoint, int mods)
+{
+ RETRIEVE_CALLBACK(window, char_mods_cb_ref);
+ /* push arguments */
+ lua_rawgeti(L, LUA_REGISTRYINDEX, data->self_ref);
+ lua_pushinteger(L, codepoint);
+ lua_pushinteger(L, mods);
+ /* call */
+ lua_call(L, 3, 0);
+}
+int glfwSetCharModsCallback_bind(lua_State *L)
+{
+ GLFWwindow **window = check_callback_args(L);
+ SET_CALLBACK(
+ L, *window,
+ glfwSetCharModsCallback,
+ h_char_mods_cb, char_mods_cb_ref
+ );
+ return 1;
+}
+
+
+static void h_mouse_button_cb(GLFWwindow *window, int button, int action, int mods)
+{
+ RETRIEVE_CALLBACK(window, char_mods_cb_ref);
+ /* push arguments */
+ lua_rawgeti(L, LUA_REGISTRYINDEX, data->self_ref);
+ lua_pushinteger(L, button);
+ lua_pushinteger(L, action);
+ lua_pushinteger(L, mods);
+ /* call */
+ lua_call(L, 4, 0);
+}
+int glfwSetMouseButtonCallback_bind(lua_State *L)
+{
+ GLFWwindow **window = check_callback_args(L);
+ SET_CALLBACK(
+ L, *window,
+ glfwSetMouseButtonCallback,
+ h_mouse_button_cb, mouse_button_cb_ref
+ );
+ return 1;
+}
+
+
+static void h_cursor_pos_cb(GLFWwindow *window, double xpos, double ypos)
+{
+ RETRIEVE_CALLBACK(window, cursor_pos_cb_ref);
+ /* push_arguments */
+ lua_rawgeti(L, LUA_REGISTRYINDEX, data->self_ref);
+ lua_pushnumber(L, xpos);
+ lua_pushnumber(L, ypos);
+ /* call */
+ lua_call(L, 3, 0);
+}
+int glfwSetCursorPosCallback_bind(lua_State *L)
+{
+ GLFWwindow **window = check_callback_args(L);
+ SET_CALLBACK(
+ L, *window,
+ glfwSetCursorPosCallback,
+ h_cursor_pos_cb, cursor_pos_cb_ref
+ );
+ return 1;
+}
+
+
+static void h_cursor_enter_cb(GLFWwindow *window, int entered)
+{
+ RETRIEVE_CALLBACK(window, cursor_enter_cb_ref);
+ /* push_arguments */
+ lua_rawgeti(L, LUA_REGISTRYINDEX, data->self_ref);
+ lua_pushinteger(L, entered);
+ /* call */
+ lua_call(L, 2, 0);
+}
+int glfwSetCursorEnterCallback_bind(lua_State *L)
+{
+ GLFWwindow **window = check_callback_args(L);
+ SET_CALLBACK(
+ L, *window,
+ glfwSetCursorEnterCallback,
+ h_cursor_enter_cb, cursor_enter_cb_ref
+ );
+ return 1;
+}
+
+
+static void h_scroll_cb(GLFWwindow *window, double xoffset, double yoffset)
+{
+ RETRIEVE_CALLBACK(window, scroll_cb_ref);
+ /* push_arguments */
+ lua_rawgeti(L, LUA_REGISTRYINDEX, data->self_ref);
+ lua_pushnumber(L, xoffset);
+ lua_pushnumber(L, yoffset);
+ /* call */
+ lua_call(L, 3, 0);
+
+}
+int glfwSetScrollCallback_bind(lua_State *L)
+{
+ GLFWwindow **window = check_callback_args(L);
+ SET_CALLBACK(
+ L, *window,
+ glfwSetScrollCallback,
+ h_scroll_cb, scroll_cb_ref
+ );
+ return 1;
+}
+
+
+static void h_drop_cb(GLFWwindow *window, int path_count, const char **paths)
+{
+ RETRIEVE_CALLBACK(window, drop_cb_ref);
+ /* push_arguments */
+ lua_rawgeti(L, LUA_REGISTRYINDEX, data->self_ref);
+ lua_createtable(L, path_count, 0);
+ int tbl = lua_gettop(L);
+ for (int i=0; i<path_count; i++) {
+ lua_pushstring(L, paths[i]);
+ lua_rawseti(L, tbl, i+1);
+ }
+ /* call */
+ lua_call(L, 2, 0);
+
+}
+int glfwSetDropCallback_bind(lua_State *L)
+{
+ GLFWwindow **window = check_callback_args(L);
+ SET_CALLBACK(
+ L, *window,
+ glfwSetDropCallback,
+ h_drop_cb, drop_cb_ref
+ );
+ return 1;
+}
+
+
+int glfwJoystickPresent_bind(lua_State *L)
+{
+ int jid = luaL_checkinteger(L, 1);
+ int bind_result = glfwJoystickPresent(jid);
+ lua_pushinteger(L, bind_result);
+ return 1;
+}
+
+
+int glfwGetJoystickAxes_bind(lua_State *L)
+{
+ int jid = luaL_checkinteger(L, 1);
+ int count;
+ const float * bind_result = glfwGetJoystickAxes(jid, &count);
+
+ lua_createtable(L, count, 0);
+ int tbl = lua_gettop(L);
+ for (int i=0; i<count; i++) {
+ lua_pushnumber(L, bind_result[i]);
+ lua_rawseti(L, tbl, i+1);
+ }
+ return 1;
+}
+
+
+int glfwGetJoystickButtons_bind(lua_State *L)
+{
+ int jid = luaL_checkinteger(L, 1);
+ int count;
+ const unsigned char * bind_result = glfwGetJoystickButtons(jid, &count);
+
+ lua_createtable(L, count, 0);
+ int tbl = lua_gettop(L);
+ for (int i=0; i<count; i++) {
+ lua_pushinteger(L, bind_result[i]);
+ lua_rawseti(L, tbl, i+1);
+ }
+ return 1;
+}
+
+
+int glfwGetJoystickHats_bind(lua_State *L)
+{
+ int jid = luaL_checkinteger(L, 1);
+ int count;
+ const unsigned char * bind_result = glfwGetJoystickHats(jid, &count);
+
+ lua_createtable(L, count, 0);
+ int tbl = lua_gettop(L);
+ for (int i=0; i<count; i++) {
+ lua_pushinteger(L, bind_result[i]);
+ lua_rawseti(L, tbl, i+1);
+ }
+ return 1;
+}
+
+
+int glfwGetJoystickName_bind(lua_State *L)
+{
+ int jid = luaL_checkinteger(L, 1);
+ const char * bind_result = glfwGetJoystickName(jid);
+ lua_pushstring(L, bind_result);
+ return 1;
+}
+
+
+int glfwGetJoystickGUID_bind(lua_State *L)
+{
+ int jid = luaL_checkinteger(L, 1);
+ const char * bind_result = glfwGetJoystickGUID(jid);
+ lua_pushstring(L, bind_result);
+ return 1;
+}
+
+
+int glfwJoystickIsGamepad_bind(lua_State *L)
+{
+ int jid = luaL_checkinteger(L, 1);
+ int bind_result = glfwJoystickIsGamepad(jid);
+ lua_pushinteger(L, bind_result);
+ return 1;
+}
+
+
+struct h_js_data_t {
+ lua_State *L;
+ int cb_ref;
+} static h_js_data = { NULL, LUA_NOREF };
+static void h_joystick_cb(int jid, int event)
+{
+ if (h_js_data.cb_ref == LUA_NOREF) { return; }
+
+ lua_State *L = h_js_data.L;
+ lua_rawgeti(L, LUA_REGISTRYINDEX, h_js_data.cb_ref);
+ lua_pushinteger(L, jid);
+ lua_pushinteger(L, event);
+ lua_call(L, 2, 0);
+}
+int glfwSetJoystickCallback_bind(lua_State *L)
+{
+ int type = lua_type(L, 1);
+ if (type != LUA_TNIL && type != LUA_TFUNCTION) {
+ return luaL_typerror(L, 1, "function or nil");
+ }
+
+ /* push old cb */
+ h_js_data.L = L;
+ lua_rawgeti(L, LUA_REGISTRYINDEX, h_js_data.cb_ref);
+
+ /* set new cb */
+ if (type == LUA_TNIL) {
+ glfwSetJoystickCallback(NULL);
+ h_js_data.cb_ref = LUA_NOREF;
+ }
+ else {
+ glfwSetJoystickCallback(h_joystick_cb);
+ lua_pushvalue(L, 1);
+ h_js_data.cb_ref = luaL_ref(L, LUA_REGISTRYINDEX);
+ }
+
+ return 1;
+}
+
+
+int glfwUpdateGamepadMappings_bind(lua_State *L)
+{
+ const char * string = luaL_checkstring(L, 1);
+ int bind_result = glfwUpdateGamepadMappings(string);
+ lua_pushinteger(L, bind_result);
+ return 1;
+}
+
+
+int glfwGetGamepadName_bind(lua_State *L)
+{
+ int jid = luaL_checkinteger(L, 1);
+ const char * bind_result = glfwGetGamepadName(jid);
+ lua_pushstring(L, bind_result);
+ return 1;
+}
+
+
+int glfwGetGamepadState_bind(lua_State *L)
+{
+ int jid = luaL_checkinteger(L, 1);
+ GLFWgamepadstate state;
+ int bind_result = glfwGetGamepadState(jid, &state);
+ lua_pushinteger(L, bind_result);
+ if (bind_result == GLFW_FALSE) {
+ lua_pushnil(L);
+ lua_pushnil(L);
+ }
+ else {
+ lua_createtable(L, 15, 0);
+ int buttons = lua_gettop(L);
+ for (int i=0; i<15; i++) {
+ lua_pushinteger(L, state.buttons[i]);
+ lua_rawseti(L, buttons, i+1);
+ }
+ lua_createtable(L, 6, 0);
+ int axes = lua_gettop(L);
+ for (int i=0; i<6; i++) {
+ lua_pushnumber(L, state.axes[i]);
+ lua_rawseti(L, axes, i+1);
+ }
+ }
+
+ return 3;
+}
+
+
+int glfwSetClipboardString_bind(lua_State *L)
+{
+ GLFWwindow ** window = luaL_checkudata(L, 1, glfw_window_tname);
+ const char * string = luaL_checkstring(L, 2);
+ glfwSetClipboardString(*window, string);
+ return 0;
+}
+
+
+int glfwGetClipboardString_bind(lua_State *L)
+{
+ GLFWwindow ** window = luaL_checkudata(L, 1, glfw_window_tname);
+ const char * bind_result = glfwGetClipboardString(*window);
+ lua_pushstring(L, bind_result);
+ return 1;
+}
+
+
+int glfwGetTime_bind(lua_State *L)
+{
+ double bind_result = glfwGetTime();
+ lua_pushnumber(L, bind_result);
+ return 1;
+}
+
+
+int glfwSetTime_bind(lua_State *L)
+{
+ double time = luaL_checknumber(L, 1);
+ glfwSetTime(time);
+ return 0;
+}
+
+
+int glfwGetTimerValue_bind(lua_State *L)
+{
+ uint64_t bind_result = glfwGetTimerValue();
+ lua_pushinteger(L, bind_result);
+ return 1;
+}
+
+
+int glfwGetTimerFrequency_bind(lua_State *L)
+{
+ uint64_t bind_result = glfwGetTimerFrequency();
+ lua_pushinteger(L, bind_result);
+ return 1;
+}
diff --git a/src/glfw/monitor.c b/src/glfw/monitor.c
new file mode 100644
index 0000000..0f1b3fc
--- /dev/null
+++ b/src/glfw/monitor.c
@@ -0,0 +1,250 @@
+#include <stdlib.h>
+#include <lua.h>
+#include <lauxlib.h>
+#include <GLFW/glfw3.h>
+#include "setup.h"
+
+
+GLFWmonitor ** create_monitor(lua_State *L)
+{
+ GLFWmonitor ** monitor = lua_newuserdata(L, sizeof(GLFWmonitor *));
+ luaL_getmetatable(L, glfw_monitor_tname);
+ lua_setmetatable(L, -2);
+ return monitor;
+}
+
+int glfwGetMonitors_bind(lua_State *L)
+{
+ int count;
+ GLFWmonitor ** bind_result = glfwGetMonitors(&count);
+ lua_createtable(L, count, 0);
+ int tbl = lua_gettop(L);
+ for (int i=0; i<count; i++) {
+ GLFWmonitor **monitor = create_monitor(L);
+ *monitor = bind_result[i];
+ lua_rawseti(L, tbl, i+1);
+ }
+ return 1;
+}
+
+
+int glfwGetPrimaryMonitor_bind(lua_State *L)
+{
+ GLFWmonitor **monitor = create_monitor(L);
+ *monitor = glfwGetPrimaryMonitor();
+ return 1;
+}
+
+
+int glfwGetMonitorPos_bind(lua_State *L)
+{
+ GLFWmonitor * monitor = luaL_checkudata(L, 1, glfw_monitor_tname);
+ int xpos, ypos;
+ glfwGetMonitorPos(monitor, &xpos, &ypos);
+ lua_pushinteger(L, xpos);
+ lua_pushinteger(L, ypos);
+ return 2;
+}
+
+
+int glfwGetMonitorWorkarea_bind(lua_State *L)
+{
+ GLFWmonitor * monitor = luaL_checkudata(L, 1, glfw_monitor_tname);
+ int xpos, ypos, width, height;
+ glfwGetMonitorWorkarea(monitor, &xpos, &ypos, &width, &height);
+ lua_pushinteger(L, xpos);
+ lua_pushinteger(L, ypos);
+ lua_pushinteger(L, width);
+ lua_pushinteger(L, height);
+ return 4;
+}
+
+
+int glfwGetMonitorPhysicalSize_bind(lua_State *L)
+{
+ GLFWmonitor * monitor = luaL_checkudata(L, 1, glfw_monitor_tname);
+ int widthMM, heightMM;
+ glfwGetMonitorPhysicalSize(monitor, &widthMM, &heightMM);
+ lua_pushinteger(L, widthMM);
+ lua_pushinteger(L, heightMM);
+ return 2;
+}
+
+
+int glfwGetMonitorContentScale_bind(lua_State *L)
+{
+ GLFWmonitor * monitor = luaL_checkudata(L, 1, glfw_monitor_tname);
+ float xscale, yscale;
+ glfwGetMonitorContentScale(monitor, &xscale, &yscale);
+ lua_pushnumber(L, xscale);
+ lua_pushnumber(L, yscale);
+ return 2;
+}
+
+
+int glfwGetMonitorName_bind(lua_State *L)
+{
+ GLFWmonitor * monitor = luaL_checkudata(L, 1, glfw_monitor_tname);
+ const char * bind_result = glfwGetMonitorName(monitor);
+ lua_pushstring(L, bind_result);
+ return 1;
+}
+
+
+struct h_glfw_monitor_data_t {
+ lua_State *L;
+ int cb_ref;
+} static h_monitor_data = { NULL, LUA_NOREF };
+static void h_monitor_cb(GLFWmonitor *monitor, int event)
+{
+ if (h_monitor_data.cb_ref == LUA_NOREF) { return; }
+
+ lua_State *L = h_monitor_data.L;
+ lua_rawgeti(L, LUA_REGISTRYINDEX, h_monitor_data.cb_ref);
+ GLFWmonitor **m = create_monitor(L);
+ *m = monitor;
+ lua_pushinteger(L, event);
+ lua_call(L, 2, 0);
+}
+
+int glfwSetMonitorCallback_bind(lua_State *L)
+{
+ int type = lua_type(L, 1);
+ if (type != LUA_TNIL && type != LUA_TFUNCTION) {
+ return luaL_typerror(L, 1, "function or nil");
+ }
+
+ /* push old cb */
+ h_monitor_data.L = L;
+ lua_rawgeti(L, LUA_REGISTRYINDEX, h_monitor_data.cb_ref);
+
+ /* set new cb */
+ if (type == LUA_TNIL) {
+ glfwSetMonitorCallback(NULL);
+ h_monitor_data.cb_ref = LUA_NOREF;
+ }
+ else {
+ glfwSetMonitorCallback(h_monitor_cb);
+ lua_pushvalue(L, 1);
+ h_monitor_data.cb_ref = luaL_ref(L, LUA_REGISTRYINDEX);
+ }
+
+ return 1;
+}
+
+
+static void push_vidmode(lua_State *L, GLFWvidmode mode)
+{
+ lua_createtable(L, 0, 6);
+ int tbl = lua_gettop(L);
+
+ lua_pushinteger(L, mode.width);
+ lua_setfield(L, tbl, "width");
+ lua_pushinteger(L, mode.height);
+ lua_setfield(L, tbl, "height");
+ lua_pushinteger(L, mode.redBits);
+ lua_setfield(L, tbl, "redBits");
+ lua_pushinteger(L, mode.greenBits);
+ lua_setfield(L, tbl, "greenBits");
+ lua_pushinteger(L, mode.blueBits);
+ lua_setfield(L, tbl, "blueBits");
+ lua_pushinteger(L, mode.refreshRate);
+ lua_setfield(L, tbl, "refreshRate");
+}
+int glfwGetVideoModes_bind(lua_State *L)
+{
+ GLFWmonitor * monitor = luaL_checkudata(L, 1, glfw_monitor_tname);
+ int count;
+ const GLFWvidmode * bind_result = glfwGetVideoModes(monitor, &count);
+
+ lua_createtable(L, count, 0);
+ int tbl = lua_gettop(L);
+ for (int i=0; i<count; i++) {
+ push_vidmode(L, bind_result[i]);
+ lua_rawseti(L, tbl, i+1);
+ }
+ return 1;
+}
+
+
+int glfwGetVideoMode_bind(lua_State *L)
+{
+ GLFWmonitor * monitor = luaL_checkudata(L, 1, glfw_monitor_tname);
+ const GLFWvidmode * bind_result = glfwGetVideoMode(monitor);
+ push_vidmode(L, *bind_result);
+ return 1;
+}
+
+
+int glfwSetGamma_bind(lua_State *L)
+{
+ GLFWmonitor * monitor = luaL_checkudata(L, 1, glfw_monitor_tname);
+ float gamma = luaL_checknumber(L, 2);
+ glfwSetGamma(monitor, gamma);
+ return 0;
+}
+
+
+int glfwGetGammaRamp_bind(lua_State *L)
+{
+ GLFWmonitor * monitor = luaL_checkudata(L, 1, glfw_monitor_tname);
+ const GLFWgammaramp * ramp = glfwGetGammaRamp(monitor);
+ lua_createtable(L, ramp->size, 0);
+ int ramp_tbl = lua_gettop(L);
+ for (int i=0; i<ramp->size; i++) {
+ lua_createtable(L, 3, 0);
+ int tbl = lua_gettop(L);
+ lua_pushinteger(L, ramp->red[i]);
+ lua_rawseti(L, tbl, 1);
+ lua_pushinteger(L, ramp->green[i]);
+ lua_rawseti(L, tbl, 2);
+ lua_pushinteger(L, ramp->blue[i]);
+ lua_rawseti(L, tbl, 3);
+ lua_rawseti(L, ramp_tbl, i+1);
+ }
+
+ return 1;
+}
+
+
+int glfwSetGammaRamp_bind(lua_State *L)
+{
+ GLFWmonitor * monitor = luaL_checkudata(L, 1, glfw_monitor_tname);
+ luaL_checktype(L, 2, LUA_TTABLE);
+
+ GLFWgammaramp ramp = { NULL, NULL, NULL, 0 };
+ size_t len = lua_objlen(L, 2);
+ ramp.red = malloc(len * sizeof(unsigned short));
+ ramp.green = malloc(len * sizeof(unsigned short));
+ ramp.blue = malloc(len * sizeof(unsigned short));
+ ramp.size = len;
+ if (
+ ramp.red == NULL ||
+ ramp.green == NULL ||
+ ramp.blue == NULL
+ ) {
+ return luaL_error(
+ L,
+ "failed to allocate one or more gamma ramp "
+ "color buffers of %lu bytes each",
+ len * sizeof(unsigned short)
+ );
+ }
+
+ for (int i=0; i<len; i++) {
+ lua_rawgeti(L, 2, i+1);
+ int tbl = lua_gettop(L);
+ lua_rawgeti(L, tbl, 1);
+ ramp.red[i] = lua_tonumber(L, -1);
+ lua_rawgeti(L, tbl, 2);
+ ramp.green[i] = lua_tonumber(L, -1);
+ lua_rawgeti(L, tbl, 3);
+ ramp.blue[i] = lua_tonumber(L, -1);
+ lua_pop(L, 4);
+ }
+
+ glfwSetGammaRamp(monitor, &ramp);
+ return 0;
+}
+
+
diff --git a/src/glfw/setup.c b/src/glfw/setup.c
new file mode 100644
index 0000000..0abab35
--- /dev/null
+++ b/src/glfw/setup.c
@@ -0,0 +1,33 @@
+#include <lua.h>
+#include <lauxlib.h>
+#include "util/util.h"
+#include "setup.h"
+
+
+#define X(str, mt) const char *glfw_ ## mt ## _tname = str;
+H_GLFW_METATABLES
+#undef X
+
+
+void setup_glfw(lua_State *L, int honey_tbl)
+{
+ /* create metatables */
+ #define X(str, mt) luaL_newmetatable(L, glfw_ ## mt ## _tname); lua_pop(L, 1);
+ H_GLFW_METATABLES
+ #undef X
+
+ struct honey_tbl_t tbl[] = {
+ #define X(name, val) H_INT(name, val),
+ H_GLFW_ENUM
+ #undef X
+
+ #define X(name, func) H_FUNC(name, func),
+ H_GLFW_FUNCTIONS
+ #undef X
+
+ H_END
+ };
+
+ create_table(L, tbl);
+ lua_setfield(L, honey_tbl, "glfw");
+}
diff --git a/src/glfw/setup.h b/src/glfw/setup.h
new file mode 100644
index 0000000..1b30728
--- /dev/null
+++ b/src/glfw/setup.h
@@ -0,0 +1,419 @@
+#ifndef HONEY_GLFW_SETUP_H
+#define HONEY_GLFW_SETUP_H
+
+#include <lua.h>
+#include <GLFW/glfw3.h>
+
+struct h_glfw_window_data_t {
+ lua_State *L;
+ int self_ref;
+
+ /* callbacks */
+ int key_cb_ref;
+ int char_cb_ref;
+ int char_mods_cb_ref;
+ int mouse_button_cb_ref;
+ int cursor_pos_cb_ref;
+ int cursor_enter_cb_ref;
+ int scroll_cb_ref;
+ int drop_cb_ref;
+ int pos_cb_ref;
+ int size_cb_ref;
+ int close_cb_ref;
+ int refresh_cb_ref;
+ int focus_cb_ref;
+ int iconify_cb_ref;
+ int maximize_cb_ref;
+ int framebuffer_size_cb_ref;
+ int content_scale_cb_ref;
+};
+
+
+GLFWmonitor ** create_monitor(lua_State *L);
+
+
+#define H_GLFW_METATABLES \
+ X("glfw.window", window) \
+ X("glfw.cursor", cursor) \
+ X("glfw.monitor", monitor) \
+
+#define X(str, name) extern const char *glfw_ ## name ## _tname;
+H_GLFW_METATABLES
+#undef X
+
+
+#define H_GLFW_FUNCTIONS \
+ /* context */ \
+ X("MakeContextCurrent", glfwMakeContextCurrent_bind) \
+ X("GetCurrentContext", glfwGetCurrentContext_bind) \
+ X("SwapInterval", glfwSwapInterval_bind) \
+ X("ExtensionSupported", glfwExtensionSupported_bind) \
+ X("GetProcAddress", glfwGetProcAddress_bind) \
+\
+ /* setup/error */ \
+ X("Init", glfwInit_bind) \
+ X("Terminate", glfwTerminate_bind) \
+ X("InitHint", glfwInitHint_bind) \
+ X("GetVersion", glfwGetVersion_bind) \
+ X("GetVersionString", glfwGetVersionString_bind) \
+ X("GetError", glfwGetError_bind) \
+\
+ /* input */ \
+ X("GetInputMode", glfwGetInputMode_bind) \
+ X("SetInputMode", glfwSetInputMode_bind) \
+ X("RawMouseMotionSupported", glfwRawMouseMotionSupported_bind) \
+ X("GetKeyName", glfwGetKeyName_bind) \
+ X("GetKeyScancode", glfwGetKeyScancode_bind) \
+ X("GetKey", glfwGetKey_bind) \
+ X("GetMouseButton", glfwGetMouseButton_bind) \
+ X("GetCursorPos", glfwGetCursorPos_bind) \
+ X("SetCursorPos", glfwSetCursorPos_bind) \
+ X("CreateCursor", glfwCreateCursor_bind) \
+ X("CreateStandardCursor", glfwCreateStandardCursor_bind) \
+ X("DestroyCursor", glfwDestroyCursor_bind) \
+ X("SetCursor", glfwSetCursor_bind) \
+ X("SetKeyCallback", glfwSetKeyCallback_bind) \
+ X("SetCharCallback", glfwSetCharCallback_bind) \
+ X("SetCharModsCallback", glfwSetCharModsCallback_bind) \
+ X("SetMouseButtonCallback", glfwSetMouseButtonCallback_bind) \
+ X("SetCursorPosCallback", glfwSetCursorPosCallback_bind) \
+ X("SetCursorEnterCallback", glfwSetCursorEnterCallback_bind) \
+ X("SetScrollCallback", glfwSetScrollCallback_bind) \
+ X("SetDropCallback", glfwSetDropCallback_bind) \
+ X("JoystickPresent", glfwJoystickPresent_bind) \
+ X("GetJoystickAxes", glfwGetJoystickAxes_bind) \
+ X("GetJoystickButtons", glfwGetJoystickButtons_bind) \
+ X("GetJoystickHats", glfwGetJoystickHats_bind) \
+ X("GetJoystickName", glfwGetJoystickName_bind) \
+ X("GetJoystickGUID", glfwGetJoystickGUID_bind) \
+ X("JoystickIsGamepad", glfwJoystickIsGamepad_bind) \
+ X("SetJoystickCallback", glfwSetJoystickCallback_bind) \
+ X("UpdateGamepadMappings", glfwUpdateGamepadMappings_bind) \
+ X("GetGamepadName", glfwGetGamepadName_bind) \
+ X("GetGamepadState", glfwGetGamepadState_bind) \
+ X("SetClipboardString", glfwSetClipboardString_bind) \
+ X("GetClipboardString", glfwGetClipboardString_bind) \
+ X("GetTime", glfwGetTime_bind) \
+ X("SetTime", glfwSetTime_bind) \
+ X("GetTimerValue", glfwGetTimerValue_bind) \
+ X("GetTimerFrequency", glfwGetTimerFrequency_bind) \
+\
+ /* monitor */ \
+ X("GetMonitors", glfwGetMonitors_bind) \
+ X("GetPrimaryMonitor", glfwGetPrimaryMonitor_bind) \
+ X("GetMonitorPos", glfwGetMonitorPos_bind) \
+ X("GetMonitorWorkarea", glfwGetMonitorWorkarea_bind) \
+ X("GetMonitorPhysicalSize", glfwGetMonitorPhysicalSize_bind) \
+ X("GetMonitorContentScale", glfwGetMonitorContentScale_bind) \
+ X("GetMonitorName", glfwGetMonitorName_bind) \
+ X("SetMonitorCallback", glfwSetMonitorCallback_bind) \
+ X("GetVideoModes", glfwGetVideoModes_bind) \
+ X("GetVideoMode", glfwGetVideoMode_bind) \
+ X("SetGamma", glfwSetGamma_bind) \
+ X("GetGammaRamp", glfwGetGammaRamp_bind) \
+ X("SetGammaRamp", glfwSetGammaRamp_bind) \
+\
+ /* window */ \
+ X("DefaultWindowHints", glfwDefaultWindowHints_bind) \
+ X("WindowHint", glfwWindowHint_bind) \
+ X("WindowHintString", glfwWindowHintString_bind) \
+ X("CreateWindow", glfwCreateWindow_bind) \
+ X("DestroyWindow", glfwDestroyWindow_bind) \
+ X("WindowShouldClose", glfwWindowShouldClose_bind) \
+ X("SetWindowShouldClose", glfwSetWindowShouldClose_bind) \
+ X("SetWindowTitle", glfwSetWindowTitle_bind) \
+ X("SetWindowIcon", glfwSetWindowIcon_bind) \
+ X("GetWindowPos", glfwGetWindowPos_bind) \
+ X("SetWindowPos", glfwSetWindowPos_bind) \
+ X("GetWindowSize", glfwGetWindowSize_bind) \
+ X("SetWindowSizeLimits", glfwSetWindowSizeLimits_bind) \
+ X("SetWindowAspectRatio", glfwSetWindowAspectRatio_bind) \
+ X("SetWindowSize", glfwSetWindowSize_bind) \
+ X("GetFramebufferSize", glfwGetFramebufferSize_bind) \
+ X("GetWindowFrameSize", glfwGetWindowFrameSize_bind) \
+ X("GetWindowContentScale", glfwGetWindowContentScale_bind) \
+ X("GetWindowOpacity", glfwGetWindowOpacity_bind) \
+ X("SetWindowOpacity", glfwSetWindowOpacity_bind) \
+ X("IconifyWindow", glfwIconifyWindow_bind) \
+ X("RestoreWindow", glfwRestoreWindow_bind) \
+ X("MaximizeWindow", glfwMaximizeWindow_bind) \
+ X("ShowWindow", glfwShowWindow_bind) \
+ X("HideWindow", glfwHideWindow_bind) \
+ X("FocusWindow", glfwFocusWindow_bind) \
+ X("RequestWindowAttention", glfwRequestWindowAttention_bind) \
+ X("GetWindowMonitor", glfwGetWindowMonitor_bind) \
+ X("SetWindowMonitor", glfwSetWindowMonitor_bind) \
+ X("GetWindowAttrib", glfwGetWindowAttrib_bind) \
+ X("SetWindowAttrib", glfwSetWindowAttrib_bind) \
+ X("SetWindowPosCallback", glfwSetWindowPosCallback_bind) \
+ X("SetWindowSizeCallback", glfwSetWindowSizeCallback_bind) \
+ X("SetWindowCloseCallback", glfwSetWindowCloseCallback_bind) \
+ X("SetWindowRefreshCallback", glfwSetWindowRefreshCallback_bind) \
+ X("SetWindowFocusCallback", glfwSetWindowFocusCallback_bind) \
+ X("SetWindowIconifyCallback", glfwSetWindowIconifyCallback_bind) \
+ X("SetWindowMaximizeCallback", glfwSetWindowMaximizeCallback_bind) \
+ X("SetFramebufferSizeCallback", glfwSetFramebufferSizeCallback_bind) \
+ X("SetWindowContentScaleCallback", glfwSetWindowContentScaleCallback_bind) \
+ X("PollEvents", glfwPollEvents_bind) \
+ X("WaitEvents", glfwWaitEvents_bind) \
+ X("WaitEventsTimeout", glfwWaitEventsTimeout_bind) \
+ X("PostEmptyEvent", glfwPostEmptyEvent_bind) \
+ X("SwapBuffers", glfwSwapBuffers_bind) \
+
+
+#define X(name, func) int func(lua_State *L);
+H_GLFW_FUNCTIONS
+#undef X
+
+
+#define H_GLFW_ENUM \
+ X("FOCUSED", GLFW_FOCUSED) \
+ X("ICONIFIED", GLFW_ICONIFIED) \
+ X("RESIZABLE", GLFW_RESIZABLE) \
+ X("VISIBLE", GLFW_VISIBLE) \
+ X("DECORATED", GLFW_DECORATED) \
+ X("GLFW_AUTO_ICONIFY", GLFW_AUTO_ICONIFY) \
+ X("FLOATING", GLFW_FLOATING) \
+ X("MAXIMIZED", GLFW_MAXIMIZED) \
+ X("CENTER_CURSOR", GLFW_CENTER_CURSOR) \
+ X("TRANSPARENT_FRAMEBUFFER", GLFW_TRANSPARENT_FRAMEBUFFER) \
+ X("HOVERED", GLFW_HOVERED) \
+ X("FOCUS_ON_SHOW", GLFW_FOCUS_ON_SHOW) \
+ X("RED_BITS", GLFW_RED_BITS) \
+ X("GREEN_BITS", GLFW_GREEN_BITS) \
+ X("BLUE_BITS", GLFW_BLUE_BITS) \
+ X("ALPHA_BITS", GLFW_ALPHA_BITS) \
+ X("DEPTH_BITS", GLFW_DEPTH_BITS) \
+ X("STENCIL_BITS", GLFW_STENCIL_BITS) \
+ X("ACCUM_RED_BITS", GLFW_ACCUM_RED_BITS) \
+ X("ACCUM_GREEN_BITS", GLFW_ACCUM_GREEN_BITS) \
+ X("ACCUM_BLUE_BITS", GLFW_ACCUM_BLUE_BITS) \
+ X("ACCUM_ALPHA_BITS", GLFW_ACCUM_ALPHA_BITS) \
+ X("AUX_BUFFERS", GLFW_AUX_BUFFERS) \
+ X("STEREO", GLFW_STEREO) \
+ X("SAMPLES", GLFW_SAMPLES) \
+ X("SRGB_CAPABLE", GLFW_SRGB_CAPABLE) \
+ X("REFRESH_RATE", GLFW_REFRESH_RATE) \
+ X("DOUBLEBUFFER", GLFW_DOUBLEBUFFER) \
+ X("CLIENT_API", GLFW_CLIENT_API) \
+ X("CONTEXT_VERSION_MAJOR", GLFW_CONTEXT_VERSION_MAJOR) \
+ X("CONTEXT_VERSION_MINOR", GLFW_CONTEXT_VERSION_MINOR) \
+ X("CONTEXT_REVISION", GLFW_CONTEXT_REVISION) \
+ X("CONTEXT_ROBUSTNESS", GLFW_CONTEXT_ROBUSTNESS) \
+ X("OPENGL_FORWARD_COMPAT", GLFW_OPENGL_FORWARD_COMPAT) \
+ X("OPENGL_DEBUG_CONTEXT", GLFW_OPENGL_DEBUG_CONTEXT) \
+ X("OPENGL_PROFILE", GLFW_OPENGL_PROFILE) \
+ X("CONTEXT_RELEASE_BEHAVIOR", GLFW_CONTEXT_RELEASE_BEHAVIOR) \
+ X("CONTEXT_NO_ERROR", GLFW_CONTEXT_NO_ERROR) \
+ X("CONTEXT_CREATION_API", GLFW_CONTEXT_CREATION_API) \
+ X("SCALE_TO_MONITOR", GLFW_SCALE_TO_MONITOR) \
+ X("COCOA_RETINA_FRAMEBUFFER", GLFW_COCOA_RETINA_FRAMEBUFFER) \
+ X("COCOA_FRAME_NAME", GLFW_COCOA_FRAME_NAME) \
+ X("COCOA_GRAPHICS_SWITCHING", GLFW_COCOA_GRAPHICS_SWITCHING) \
+ X("X11_CLASS_NAME", GLFW_X11_CLASS_NAME) \
+ X("X11_INSTANCE_NAME", GLFW_X11_INSTANCE_NAME) \
+ X("GAMEPAD_AXIS_LEFT_X", GLFW_GAMEPAD_AXIS_LEFT_X) \
+ X("GAMEPAD_AXIS_LEFT_Y", GLFW_GAMEPAD_AXIS_LEFT_Y) \
+ X("GAMEPAD_AXIS_RIGHT_X", GLFW_GAMEPAD_AXIS_RIGHT_X) \
+ X("GAMEPAD_AXIS_RIGHT_Y", GLFW_GAMEPAD_AXIS_RIGHT_Y) \
+ X("GAMEPAD_AXIS_LEFT_TRIGGER", GLFW_GAMEPAD_AXIS_LEFT_TRIGGER) \
+ X("GAMEPAD_AXIS_RIGHT_TRIGGER", GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER) \
+ X("GAMEPAD_AXIS_LAST", GLFW_GAMEPAD_AXIS_LAST) \
+ X("GAMEPAD_AXIS_LEFT_X", GLFW_GAMEPAD_AXIS_LEFT_X) \
+ X("GAMEPAD_AXIS_LEFT_Y", GLFW_GAMEPAD_AXIS_LEFT_Y) \
+ X("GAMEPAD_AXIS_RIGHT_X", GLFW_GAMEPAD_AXIS_RIGHT_X) \
+ X("GAMEPAD_AXIS_RIGHT_Y", GLFW_GAMEPAD_AXIS_RIGHT_Y) \
+ X("GAMEPAD_AXIS_LEFT_TRIGGER", GLFW_GAMEPAD_AXIS_LEFT_TRIGGER) \
+ X("GAMEPAD_AXIS_RIGHT_TRIGGER", GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER) \
+ X("GAMEPAD_AXIS_LAST", GLFW_GAMEPAD_AXIS_LAST) \
+ X("HAT_CENTERED", GLFW_HAT_CENTERED) \
+ X("HAT_UP", GLFW_HAT_UP) \
+ X("HAT_RIGHT", GLFW_HAT_RIGHT) \
+ X("HAT_DOWN", GLFW_HAT_DOWN) \
+ X("HAT_LEFT", GLFW_HAT_LEFT) \
+ X("HAT_RIGHT_UP", GLFW_HAT_RIGHT_UP) \
+ X("HAT_RIGHT_DOWN", GLFW_HAT_RIGHT_DOWN) \
+ X("HAT_LEFT_UP", GLFW_HAT_LEFT_UP) \
+ X("HAT_LEFT_DOWN", GLFW_HAT_LEFT_DOWN) \
+ X("JOYSTICK_1", GLFW_JOYSTICK_1) \
+ X("JOYSTICK_2", GLFW_JOYSTICK_2) \
+ X("JOYSTICK_3", GLFW_JOYSTICK_3) \
+ X("JOYSTICK_4", GLFW_JOYSTICK_4) \
+ X("JOYSTICK_5", GLFW_JOYSTICK_5) \
+ X("JOYSTICK_6", GLFW_JOYSTICK_6) \
+ X("JOYSTICK_7", GLFW_JOYSTICK_7) \
+ X("JOYSTICK_8", GLFW_JOYSTICK_8) \
+ X("JOYSTICK_9", GLFW_JOYSTICK_9) \
+ X("JOYSTICK_10", GLFW_JOYSTICK_10) \
+ X("JOYSTICK_11", GLFW_JOYSTICK_11) \
+ X("JOYSTICK_12", GLFW_JOYSTICK_12) \
+ X("JOYSTICK_13", GLFW_JOYSTICK_13) \
+ X("JOYSTICK_14", GLFW_JOYSTICK_14) \
+ X("JOYSTICK_15", GLFW_JOYSTICK_15) \
+ X("JOYSTICK_16", GLFW_JOYSTICK_16) \
+ X("JOYSTICK_LAST", GLFW_JOYSTICK_LAST) \
+ X("KEY_UNKNOWN", GLFW_KEY_UNKNOWN) \
+ X("KEY_SPACE", GLFW_KEY_SPACE) \
+ X("KEY_APOSTROPHE", GLFW_KEY_APOSTROPHE) \
+ X("KEY_COMMA", GLFW_KEY_COMMA) \
+ X("KEY_MINUS", GLFW_KEY_MINUS) \
+ X("KEY_PERIOD", GLFW_KEY_PERIOD) \
+ X("KEY_SLASH", GLFW_KEY_SLASH) \
+ X("KEY_0", GLFW_KEY_0) \
+ X("KEY_1", GLFW_KEY_1) \
+ X("KEY_2", GLFW_KEY_2) \
+ X("KEY_3", GLFW_KEY_3) \
+ X("KEY_4", GLFW_KEY_4) \
+ X("KEY_5", GLFW_KEY_5) \
+ X("KEY_6", GLFW_KEY_6) \
+ X("KEY_7", GLFW_KEY_7) \
+ X("KEY_8", GLFW_KEY_8) \
+ X("KEY_9", GLFW_KEY_9) \
+ X("KEY_SEMICOLON", GLFW_KEY_SEMICOLON) \
+ X("KEY_EQUAL", GLFW_KEY_EQUAL) \
+ X("KEY_A", GLFW_KEY_A) \
+ X("KEY_B", GLFW_KEY_B) \
+ X("KEY_C", GLFW_KEY_C) \
+ X("KEY_D", GLFW_KEY_D) \
+ X("KEY_E", GLFW_KEY_E) \
+ X("KEY_F", GLFW_KEY_F) \
+ X("KEY_G", GLFW_KEY_G) \
+ X("KEY_H", GLFW_KEY_H) \
+ X("KEY_I", GLFW_KEY_I) \
+ X("KEY_J", GLFW_KEY_J) \
+ X("KEY_K", GLFW_KEY_K) \
+ X("KEY_L", GLFW_KEY_L) \
+ X("KEY_M", GLFW_KEY_M) \
+ X("KEY_N", GLFW_KEY_N) \
+ X("KEY_O", GLFW_KEY_O) \
+ X("KEY_P", GLFW_KEY_P) \
+ X("KEY_Q", GLFW_KEY_Q) \
+ X("KEY_R", GLFW_KEY_R) \
+ X("KEY_S", GLFW_KEY_S) \
+ X("KEY_T", GLFW_KEY_T) \
+ X("KEY_U", GLFW_KEY_U) \
+ X("KEY_V", GLFW_KEY_V) \
+ X("KEY_W", GLFW_KEY_W) \
+ X("KEY_X", GLFW_KEY_X) \
+ X("KEY_Y", GLFW_KEY_Y) \
+ X("KEY_Z", GLFW_KEY_Z) \
+ X("KEY_LEFT_BRACKET", GLFW_KEY_LEFT_BRACKET) \
+ X("KEY_BACKSLASH", GLFW_KEY_BACKSLASH) \
+ X("KEY_RIGHT_BRACKET", GLFW_KEY_RIGHT_BRACKET) \
+ X("KEY_GRAVE_ACCENT", GLFW_KEY_GRAVE_ACCENT) \
+ X("KEY_WORLD_1", GLFW_KEY_WORLD_1) \
+ X("KEY_WORLD_2", GLFW_KEY_WORLD_2) \
+ X("KEY_ESCAPE", GLFW_KEY_ESCAPE) \
+ X("KEY_ENTER", GLFW_KEY_ENTER) \
+ X("KEY_TAB", GLFW_KEY_TAB) \
+ X("KEY_BACKSPACE", GLFW_KEY_BACKSPACE) \
+ X("KEY_INSERT", GLFW_KEY_INSERT) \
+ X("KEY_DELETE", GLFW_KEY_DELETE) \
+ X("KEY_RIGHT", GLFW_KEY_RIGHT) \
+ X("KEY_LEFT", GLFW_KEY_LEFT) \
+ X("KEY_DOWN", GLFW_KEY_DOWN) \
+ X("KEY_UP", GLFW_KEY_UP) \
+ X("KEY_PAGE_UP", GLFW_KEY_PAGE_UP) \
+ X("KEY_PAGE_DOWN", GLFW_KEY_PAGE_DOWN) \
+ X("KEY_HOME", GLFW_KEY_HOME) \
+ X("KEY_END", GLFW_KEY_END) \
+ X("KEY_CAPS_LOCK", GLFW_KEY_CAPS_LOCK) \
+ X("KEY_SCROLL_LOCK", GLFW_KEY_SCROLL_LOCK) \
+ X("KEY_NUM_LOCK", GLFW_KEY_NUM_LOCK) \
+ X("KEY_PRINT_SCREEN", GLFW_KEY_PRINT_SCREEN) \
+ X("KEY_PAUSE", GLFW_KEY_PAUSE) \
+ X("KEY_F1", GLFW_KEY_F1) \
+ X("KEY_F2", GLFW_KEY_F2) \
+ X("KEY_F3", GLFW_KEY_F3) \
+ X("KEY_F4", GLFW_KEY_F4) \
+ X("KEY_F5", GLFW_KEY_F5) \
+ X("KEY_F6", GLFW_KEY_F6) \
+ X("KEY_F7", GLFW_KEY_F7) \
+ X("KEY_F8", GLFW_KEY_F8) \
+ X("KEY_F9", GLFW_KEY_F9) \
+ X("KEY_F10", GLFW_KEY_F10) \
+ X("KEY_F11", GLFW_KEY_F11) \
+ X("KEY_F12", GLFW_KEY_F12) \
+ X("KEY_F13", GLFW_KEY_F13) \
+ X("KEY_F14", GLFW_KEY_F14) \
+ X("KEY_F15", GLFW_KEY_F15) \
+ X("KEY_F16", GLFW_KEY_F16) \
+ X("KEY_F17", GLFW_KEY_F17) \
+ X("KEY_F18", GLFW_KEY_F18) \
+ X("KEY_F19", GLFW_KEY_F19) \
+ X("KEY_F20", GLFW_KEY_F20) \
+ X("KEY_F21", GLFW_KEY_F21) \
+ X("KEY_F22", GLFW_KEY_F22) \
+ X("KEY_F23", GLFW_KEY_F23) \
+ X("KEY_F24", GLFW_KEY_F24) \
+ X("KEY_F25", GLFW_KEY_F25) \
+ X("KEY_KP_0", GLFW_KEY_KP_0) \
+ X("KEY_KP_1", GLFW_KEY_KP_1) \
+ X("KEY_KP_2", GLFW_KEY_KP_2) \
+ X("KEY_KP_3", GLFW_KEY_KP_3) \
+ X("KEY_KP_4", GLFW_KEY_KP_4) \
+ X("KEY_KP_5", GLFW_KEY_KP_5) \
+ X("KEY_KP_6", GLFW_KEY_KP_6) \
+ X("KEY_KP_7", GLFW_KEY_KP_7) \
+ X("KEY_KP_8", GLFW_KEY_KP_8) \
+ X("KEY_KP_9", GLFW_KEY_KP_9) \
+ X("KEY_KP_DECIMAL", GLFW_KEY_KP_DECIMAL) \
+ X("KEY_KP_DIVIDE", GLFW_KEY_KP_DIVIDE) \
+ X("KEY_KP_MULTIPLY", GLFW_KEY_KP_MULTIPLY) \
+ X("KEY_KP_SUBTRACT", GLFW_KEY_KP_SUBTRACT) \
+ X("KEY_KP_ADD", GLFW_KEY_KP_ADD) \
+ X("KEY_KP_ENTER", GLFW_KEY_KP_ENTER) \
+ X("KEY_KP_EQUAL", GLFW_KEY_KP_EQUAL) \
+ X("KEY_LEFT_SHIFT", GLFW_KEY_LEFT_SHIFT) \
+ X("KEY_LEFT_CONTROL", GLFW_KEY_LEFT_CONTROL) \
+ X("KEY_LEFT_ALT", GLFW_KEY_LEFT_ALT) \
+ X("KEY_LEFT_SUPER", GLFW_KEY_LEFT_SUPER) \
+ X("KEY_RIGHT_SHIFT", GLFW_KEY_RIGHT_SHIFT) \
+ X("KEY_RIGHT_CONTROL", GLFW_KEY_RIGHT_CONTROL) \
+ X("KEY_RIGHT_ALT", GLFW_KEY_RIGHT_ALT) \
+ X("KEY_RIGHT_SUPER", GLFW_KEY_RIGHT_SUPER) \
+ X("KEY_MENU", GLFW_KEY_MENU) \
+ X("KEY_LAST", GLFW_KEY_LAST) \
+ X("MOD_SHIFT", GLFW_MOD_SHIFT) \
+ X("MOD_CONTROL", GLFW_MOD_CONTROL) \
+ X("MOD_ALT", GLFW_MOD_ALT) \
+ X("MOD_SUPER", GLFW_MOD_SUPER) \
+ X("MOD_CAPS_LOCK", GLFW_MOD_CAPS_LOCK) \
+ X("MOD_NUM_LOCK", GLFW_MOD_NUM_LOCK) \
+ X("MOUSE_BUTTON_1", GLFW_MOUSE_BUTTON_1) \
+ X("MOUSE_BUTTON_2", GLFW_MOUSE_BUTTON_2) \
+ X("MOUSE_BUTTON_3", GLFW_MOUSE_BUTTON_3) \
+ X("MOUSE_BUTTON_4", GLFW_MOUSE_BUTTON_4) \
+ X("MOUSE_BUTTON_5", GLFW_MOUSE_BUTTON_5) \
+ X("MOUSE_BUTTON_6", GLFW_MOUSE_BUTTON_6) \
+ X("MOUSE_BUTTON_7", GLFW_MOUSE_BUTTON_7) \
+ X("MOUSE_BUTTON_8", GLFW_MOUSE_BUTTON_8) \
+ X("MOUSE_BUTTON_LAST", GLFW_MOUSE_BUTTON_LAST) \
+ X("MOUSE_BUTTON_LEFT", GLFW_MOUSE_BUTTON_LEFT) \
+ X("MOUSE_BUTTON_RIGHT", GLFW_MOUSE_BUTTON_RIGHT) \
+ X("MOUSE_BUTTON_MIDDLE", GLFW_MOUSE_BUTTON_MIDDLE) \
+ X("ARROW_CURSOR", GLFW_ARROW_CURSOR) \
+ X("IBEAM_CURSOR", GLFW_IBEAM_CURSOR) \
+ X("CROSSHAIR_CURSOR", GLFW_CROSSHAIR_CURSOR) \
+ X("HAND_CURSOR", GLFW_HAND_CURSOR) \
+ X("HRESIZE_CURSOR", GLFW_HRESIZE_CURSOR) \
+ X("VRESIZE_CURSOR", GLFW_VRESIZE_CURSOR) \
+ X("TRUE", GLFW_TRUE) \
+ X("FALSE", GLFW_FALSE) \
+ X("JOYSTICK_HAT_BUTTONS", GLFW_JOYSTICK_HAT_BUTTONS) \
+ X("COCOA_CHDIR_RESOURCES", GLFW_COCOA_CHDIR_RESOURCES) \
+ X("COCOA_MENUBAR", GLFW_COCOA_MENUBAR) \
+ X("NO_ERROR", GLFW_NO_ERROR) \
+ X("NOT_INITIALIZED", GLFW_NOT_INITIALIZED) \
+ X("NO_CURRENT_CONTEXT", GLFW_NO_CURRENT_CONTEXT) \
+ X("INVALID_ENUM", GLFW_INVALID_ENUM) \
+ X("INVALID_VALUE", GLFW_INVALID_VALUE) \
+ X("OUT_OF_MEMORY", GLFW_OUT_OF_MEMORY) \
+ X("API_UNAVAILABLE", GLFW_API_UNAVAILABLE) \
+ X("VERSION_UNAVAILABLE", GLFW_VERSION_UNAVAILABLE) \
+ X("PLATFORM_ERROR", GLFW_PLATFORM_ERROR) \
+ X("FORMAT_UNAVAILABLE", GLFW_FORMAT_UNAVAILABLE) \
+ X("NO_WINDOW_CONTEXT", GLFW_NO_WINDOW_CONTEXT) \
+
+
+#endif
diff --git a/src/glfw/window.c b/src/glfw/window.c
new file mode 100644
index 0000000..1aafeb4
--- /dev/null
+++ b/src/glfw/window.c
@@ -0,0 +1,588 @@
+#include <lua.h>
+#include <lauxlib.h>
+#include <GLFW/glfw3.h>
+#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;
+}