import { print } from "./helpers"
import { read, dlopen, FFIType, suffix, CString, JSCallback } from "bun:ffi";
// These are hand crafted bindings made with love. But not love2d.
// Might be little mistakes, please let me know if so.
// Some functions work slightly differently than C.
// Like, destructuring assignments in TS leverage array returns.
export default {}
const path = `libglfw.${suffix}`;
print(`GLFW3: ${path}`)
const libcPath = `libc.${suffix}.6`
print(libcPath)
//* This is a helper function to automatically null (\0) terminate a string.
function toBuffer(input: string) {
return Buffer.from(input + '\0')
}
//* https://www.glfw.org/docs/latest/group__window.html
export const GLFW_FOCUSED = 0x00020001
export const GLFW_ICONIFIED = 0x00020002
export const GLFW_RESIZABLE = 0x00020003
export const GLFW_VISIBLE = 0x00020004
export const GLFW_DECORATED = 0x00020005
export const GLFW_AUTO_ICONIFY = 0x00020006
export const GLFW_FLOATING = 0x00020007
export const GLFW_MAXIMIZED = 0x00020008
export const GLFW_CENTER_CURSOR = 0x00020009
export const GLFW_TRANSPARENT_FRAMEBUFFER = 0x0002000A
export const GLFW_HOVERED = 0x0002000B
export const GLFW_FOCUS_ON_SHOW = 0x0002000C
export const GLFW_RED_BITS = 0x00021001
export const GLFW_GREEN_BITS = 0x00021002
export const GLFW_BLUE_BITS = 0x00021003
export const GLFW_ALPHA_BITS = 0x00021004
export const GLFW_DEPTH_BITS = 0x00021005
export const GLFW_STENCIL_BITS = 0x00021006
export const GLFW_ACCUM_RED_BITS = 0x00021007
export const GLFW_ACCUM_GREEN_BITS = 0x00021008
export const GLFW_ACCUM_BLUE_BITS = 0x00021009
export const GLFW_ACCUM_ALPHA_BITS = 0x0002100A
export const GLFW_AUX_BUFFERS = 0x0002100B
export const GLFW_STEREO = 0x0002100C
export const GLFW_SAMPLES = 0x0002100D
export const GLFW_SRGB_CAPABLE = 0x0002100E
export const GLFW_REFRESH_RATE = 0x0002100F
export const GLFW_DOUBLEBUFFER = 0x00021010
export const GLFW_CLIENT_API = 0x00022001
export const GLFW_CONTEXT_VERSION_MAJOR = 0x00022002
export const GLFW_CONTEXT_VERSION_MINOR = 0x00022003
export const GLFW_CONTEXT_REVISION = 0x00022004
export const GLFW_CONTEXT_ROBUSTNESS = 0x00022005
export const GLFW_OPENGL_FORWARD_COMPAT = 0x00022006
export const GLFW_OPENGL_DEBUG_CONTEXT = 0x00022007
export const GLFW_OPENGL_PROFILE = 0x00022008
export const GLFW_CONTEXT_RELEASE_BEHAVIOR = 0x00022009
export const GLFW_CONTEXT_NO_ERROR = 0x0002200A
export const GLFW_CONTEXT_CREATION_API = 0x0002200B
export const GLFW_SCALE_TO_MONITOR = 0x0002200C
export const GLFW_COCOA_RETINA_FRAMEBUFFER = 0x00023001
export const GLFW_COCOA_FRAME_NAME = 0x00023002
export const GLFW_COCOA_GRAPHICS_SWITCHING = 0x00023003
export const GLFW_X11_CLASS_NAME = 0x00024001
export const GLFW_X11_INSTANCE_NAME = 0x00024002
//* Error codes
export const GLFW_NO_ERROR = 0
export const GLFW_NOT_INITIALIZED = 0x00010001
export const GLFW_NO_CURRENT_CONTEXT = 0x00010002
export const GLFW_INVALID_ENUM = 0x00010003
export const GLFW_INVALID_VALUE = 0x00010004
export const GLFW_OUT_OF_MEMORY = 0x00010005
export const GLFW_API_UNAVAILABLE = 0x00010006
export const GLFW_VERSION_UNAVAILABLE = 0x00010007
export const GLFW_PLATFORM_ERROR = 0x00010008
export const GLFW_FORMAT_UNAVAILABLE = 0x00010009
export const GLFW_NO_WINDOW_CONTEXT = 0x0001000A
//* Whatever this is https://www.glfw.org/docs/latest/group__init.html
export const GLFW_TRUE = 1
export const GLFW_FALSE = 0
export const GLFW_JOYSTICK_HAT_BUTTONS = 0x00050001
export const GLFW_COCOA_CHDIR_RESOURCES = 0x00051001
export const GLFW_COCOA_MENUBAR = 0x00051002
//* https://www.glfw.org/docs/latest/group__gamepad__axes.html
export const GLFW_GAMEPAD_AXIS_LEFT_X = 0
export const GLFW_GAMEPAD_AXIS_LEFT_Y = 1
export const GLFW_GAMEPAD_AXIS_RIGHT_X = 2
export const GLFW_GAMEPAD_AXIS_RIGHT_Y = 3
export const GLFW_GAMEPAD_AXIS_LEFT_TRIGGER = 4
export const GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER = 5
export const GLFW_GAMEPAD_AXIS_LAST = GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER
//* https://www.glfw.org/docs/latest/group__gamepad__buttons.html
export const GLFW_GAMEPAD_BUTTON_A = 0
export const GLFW_GAMEPAD_BUTTON_B = 1
export const GLFW_GAMEPAD_BUTTON_X = 2
export const GLFW_GAMEPAD_BUTTON_Y = 3
export const GLFW_GAMEPAD_BUTTON_LEFT_BUMPER = 4
export const GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER = 5
export const GLFW_GAMEPAD_BUTTON_BACK = 6
export const GLFW_GAMEPAD_BUTTON_START = 7
export const GLFW_GAMEPAD_BUTTON_GUIDE = 8
export const GLFW_GAMEPAD_BUTTON_LEFT_THUMB = 9
export const GLFW_GAMEPAD_BUTTON_RIGHT_THUMB = 10
export const GLFW_GAMEPAD_BUTTON_DPAD_UP = 11
export const GLFW_GAMEPAD_BUTTON_DPAD_RIGHT = 12
export const GLFW_GAMEPAD_BUTTON_DPAD_DOWN = 13
export const GLFW_GAMEPAD_BUTTON_DPAD_LEFT = 14
export const GLFW_GAMEPAD_BUTTON_LAST = GLFW_GAMEPAD_BUTTON_DPAD_LEFT
export const GLFW_GAMEPAD_BUTTON_CROSS = GLFW_GAMEPAD_BUTTON_A
export const GLFW_GAMEPAD_BUTTON_CIRCLE = GLFW_GAMEPAD_BUTTON_B
export const GLFW_GAMEPAD_BUTTON_SQUARE = GLFW_GAMEPAD_BUTTON_X
export const GLFW_GAMEPAD_BUTTON_TRIANGLE = GLFW_GAMEPAD_BUTTON_Y
//* https://www.glfw.org/docs/latest/group__hat__state.html
export const GLFW_HAT_CENTERED = 0
export const GLFW_HAT_UP = 1
export const GLFW_HAT_RIGHT = 2
export const GLFW_HAT_DOWN = 4
export const GLFW_HAT_LEFT = 8
export const GLFW_HAT_RIGHT_UP = (GLFW_HAT_RIGHT | GLFW_HAT_UP)
export const GLFW_HAT_RIGHT_DOWN = (GLFW_HAT_RIGHT | GLFW_HAT_DOWN)
export const GLFW_HAT_LEFT_UP = (GLFW_HAT_LEFT | GLFW_HAT_UP)
export const GLFW_HAT_LEFT_DOWN = (GLFW_HAT_LEFT | GLFW_HAT_DOWN)
//* https://www.glfw.org/docs/latest/group__joysticks.html
export const GLFW_JOYSTICK_1 = 0
export const GLFW_JOYSTICK_2 = 1
export const GLFW_JOYSTICK_3 = 2
export const GLFW_JOYSTICK_4 = 3
export const GLFW_JOYSTICK_5 = 4
export const GLFW_JOYSTICK_6 = 5
export const GLFW_JOYSTICK_7 = 6
export const GLFW_JOYSTICK_8 = 7
export const GLFW_JOYSTICK_9 = 8
export const GLFW_JOYSTICK_10 = 9
export const GLFW_JOYSTICK_11 = 10
export const GLFW_JOYSTICK_12 = 11
export const GLFW_JOYSTICK_13 = 12
export const GLFW_JOYSTICK_14 = 13
export const GLFW_JOYSTICK_15 = 14
export const GLFW_JOYSTICK_16 = 15
export const GLFW_JOYSTICK_LAST = GLFW_JOYSTICK_16
//* https://www.glfw.org/docs/latest/group__keys.html
export const GLFW_KEY_UNKNOWN = -1
export const GLFW_KEY_SPACE = 32
export const GLFW_KEY_APOSTROPHE = 39 /* ' */
export const GLFW_KEY_COMMA = 44 /* , */
export const GLFW_KEY_MINUS = 45 /* - */
export const GLFW_KEY_PERIOD = 46 /* . */
export const GLFW_KEY_SLASH = 47 /* / */
export const GLFW_KEY_0 = 48
export const GLFW_KEY_1 = 49
export const GLFW_KEY_2 = 50
export const GLFW_KEY_3 = 51
export const GLFW_KEY_4 = 52
export const GLFW_KEY_5 = 53
export const GLFW_KEY_6 = 54
export const GLFW_KEY_7 = 55
export const GLFW_KEY_8 = 56
export const GLFW_KEY_9 = 57
export const GLFW_KEY_SEMICOLON = 59 /* ; */
export const GLFW_KEY_EQUAL = 61 /* = */
export const GLFW_KEY_A = 65
export const GLFW_KEY_B = 66
export const GLFW_KEY_C = 67
export const GLFW_KEY_D = 68
export const GLFW_KEY_E = 69
export const GLFW_KEY_F = 70
export const GLFW_KEY_G = 71
export const GLFW_KEY_H = 72
export const GLFW_KEY_I = 73
export const GLFW_KEY_J = 74
export const GLFW_KEY_K = 75
export const GLFW_KEY_L = 76
export const GLFW_KEY_M = 77
export const GLFW_KEY_N = 78
export const GLFW_KEY_O = 79
export const GLFW_KEY_P = 80
export const GLFW_KEY_Q = 81
export const GLFW_KEY_R = 82
export const GLFW_KEY_S = 83
export const GLFW_KEY_T = 84
export const GLFW_KEY_U = 85
export const GLFW_KEY_V = 86
export const GLFW_KEY_W = 87
export const GLFW_KEY_X = 88
export const GLFW_KEY_Y = 89
export const GLFW_KEY_Z = 90
export const GLFW_KEY_LEFT_BRACKET = 91 /* [ */
export const GLFW_KEY_BACKSLASH = 92 /* \ */
export const GLFW_KEY_RIGHT_BRACKET = 93 /* ] */
export const GLFW_KEY_GRAVE_ACCENT = 96 /* ` */
export const GLFW_KEY_WORLD_1 = 161 /* non-US #1 */
export const GLFW_KEY_WORLD_2 = 162 /* non-US #2 */
export const GLFW_KEY_ESCAPE = 256
export const GLFW_KEY_ENTER = 257
export const GLFW_KEY_TAB = 258
export const GLFW_KEY_BACKSPACE = 259
export const GLFW_KEY_INSERT = 260
export const GLFW_KEY_DELETE = 261
export const GLFW_KEY_RIGHT = 262
export const GLFW_KEY_LEFT = 263
export const GLFW_KEY_DOWN = 264
export const GLFW_KEY_UP = 265
export const GLFW_KEY_PAGE_UP = 266
export const GLFW_KEY_PAGE_DOWN = 267
export const GLFW_KEY_HOME = 268
export const GLFW_KEY_END = 269
export const GLFW_KEY_CAPS_LOCK = 280
export const GLFW_KEY_SCROLL_LOCK = 281
export const GLFW_KEY_NUM_LOCK = 282
export const GLFW_KEY_PRINT_SCREEN = 283
export const GLFW_KEY_PAUSE = 284
export const GLFW_KEY_F1 = 290
export const GLFW_KEY_F2 = 291
export const GLFW_KEY_F3 = 292
export const GLFW_KEY_F4 = 293
export const GLFW_KEY_F5 = 294
export const GLFW_KEY_F6 = 295
export const GLFW_KEY_F7 = 296
export const GLFW_KEY_F8 = 297
export const GLFW_KEY_F9 = 298
export const GLFW_KEY_F10 = 299
export const GLFW_KEY_F11 = 300
export const GLFW_KEY_F12 = 301
export const GLFW_KEY_F13 = 302
export const GLFW_KEY_F14 = 303
export const GLFW_KEY_F15 = 304
export const GLFW_KEY_F16 = 305
export const GLFW_KEY_F17 = 306
export const GLFW_KEY_F18 = 307
export const GLFW_KEY_F19 = 308
export const GLFW_KEY_F20 = 309
export const GLFW_KEY_F21 = 310
export const GLFW_KEY_F22 = 311
export const GLFW_KEY_F23 = 312
export const GLFW_KEY_F24 = 313
export const GLFW_KEY_F25 = 314
export const GLFW_KEY_KP_0 = 320
export const GLFW_KEY_KP_1 = 321
export const GLFW_KEY_KP_2 = 322
export const GLFW_KEY_KP_3 = 323
export const GLFW_KEY_KP_4 = 324
export const GLFW_KEY_KP_5 = 325
export const GLFW_KEY_KP_6 = 326
export const GLFW_KEY_KP_7 = 327
export const GLFW_KEY_KP_8 = 328
export const GLFW_KEY_KP_9 = 329
export const GLFW_KEY_KP_DECIMAL = 330
export const GLFW_KEY_KP_DIVIDE = 331
export const GLFW_KEY_KP_MULTIPLY = 332
export const GLFW_KEY_KP_SUBTRACT = 333
export const GLFW_KEY_KP_ADD = 334
export const GLFW_KEY_KP_ENTER = 335
export const GLFW_KEY_KP_EQUAL = 336
export const GLFW_KEY_LEFT_SHIFT = 340
export const GLFW_KEY_LEFT_CONTROL = 341
export const GLFW_KEY_LEFT_ALT = 342
export const GLFW_KEY_LEFT_SUPER = 343
export const GLFW_KEY_RIGHT_SHIFT = 344
export const GLFW_KEY_RIGHT_CONTROL = 345
export const GLFW_KEY_RIGHT_ALT = 346
export const GLFW_KEY_RIGHT_SUPER = 347
export const GLFW_KEY_MENU = 348
export const GLFW_KEY_LAST = GLFW_KEY_MENU
//* https://www.glfw.org/docs/latest/group__mods.html
export const GLFW_MOD_SHIFT = 0x0001
export const GLFW_MOD_CONTROL = 0x0002
export const GLFW_MOD_ALT = 0x0004
export const GLFW_MOD_SUPER = 0x0008
export const GLFW_MOD_CAPS_LOCK = 0x0010
export const GLFW_MOD_NUM_LOCK = 0x0020
//* https://www.glfw.org/docs/latest/group__buttons.html
export const GLFW_MOUSE_BUTTON_1 = 0
export const GLFW_MOUSE_BUTTON_2 = 1
export const GLFW_MOUSE_BUTTON_3 = 2
export const GLFW_MOUSE_BUTTON_4 = 3
export const GLFW_MOUSE_BUTTON_5 = 4
export const GLFW_MOUSE_BUTTON_6 = 5
export const GLFW_MOUSE_BUTTON_7 = 6
export const GLFW_MOUSE_BUTTON_8 = 7
export const GLFW_MOUSE_BUTTON_LAST = GLFW_MOUSE_BUTTON_8
export const GLFW_MOUSE_BUTTON_LEFT = GLFW_MOUSE_BUTTON_1
export const GLFW_MOUSE_BUTTON_RIGHT = GLFW_MOUSE_BUTTON_2
export const GLFW_MOUSE_BUTTON_MIDDLE = GLFW_MOUSE_BUTTON_3
//* https://www.glfw.org/docs/latest/group__shapes.html
export const GLFW_ARROW_CURSOR = 0x00036001
export const GLFW_IBEAM_CURSOR = 0x00036002
export const GLFW_CROSSHAIR_CURSOR = 0x00036003
export const GLFW_HAND_CURSOR = 0x00036004
export const GLFW_HRESIZE_CURSOR = 0x00036005
export const GLFW_VRESIZE_CURSOR = 0x00036006
//* https://www.glfw.org/docs/latest/group__input.html
export const GLFW_RELEASE = 0
export const GLFW_PRESS = 1
export const GLFW_REPEAT = 2
// Let's load that library.
const {
symbols: {
glfwInit,
glfwTerminate,
glfwGetVersion,
glfwGetVersionString,
glfwDefaultWindowHints,
glfwWindowHint,
glfwWindowHintString,
glfwCreateWindow,
glfwDestroyWindow,
glfwWindowShouldClose,
glfwSetWindowShouldClose,
glfwSetWindowTitle,
glfwSetWindowIcon,
glfwGetWindowPos,
glfwSetWindowPos,
glfwGetWindowSize,
glfwSetWindowSizeLimits,
glfwSetWindowAspectRatio,
glfwSetWindowSize,
glfwGetFramebufferSize,
glfwGetWindowFrameSize,
glfwGetWindowContentScale,
glfwGetWindowOpacity,
glfwSetWindowOpacity,
glfwIconifyWindow,
glfwRestoreWindow,
glfwMaximizeWindow,
glfwShowWindow,
glfwHideWindow,
glfwFocusWindow,
glfwRequestWindowAttention,
glfwGetWindowMonitor,
glfwSetWindowMonitor,
glfwGetWindowAttrib,
glfwSetWindowAttrib,
glfwSetWindowUserPointer,
glfwGetWindowUserPointer,
glfwSetWindowPosCallback,
glfwSetWindowSizeCallback,
glfwSetWindowCloseCallback,
glfwSetWindowRefreshCallback,
glfwSetWindowFocusCallback,
glfwSetWindowIconifyCallback,
glfwSetWindowMaximizeCallback,
glfwSetFramebufferSizeCallback,
glfwSetWindowContentScaleCallback,
glfwPollEvents,
glfwWaitEvents,
glfwWaitEventsTimeout,
glfwPostEmptyEvent,
glfwSwapBuffers,
glfwGetMonitors,
glfwGetPrimaryMonitor,
glfwGetMonitorPos,
glfwGetMonitorWorkarea,
glfwGetMonitorPhysicalSize,
glfwGetMonitorContentScale,
glfwGetMonitorName,
glfwSetMonitorUserPointer,
glfwGetMonitorUserPointer,
glfwSetMonitorCallback,
glfwGetVideoModes,
glfwGetVideoMode
},
} = dlopen(path, {
//* Begin: https://www.glfw.org/docs/latest/group__init.html
glfwInit: {
args: [],
returns: FFIType.bool,
},
glfwTerminate: {
args: [],
returns: FFIType.bool,
},
glfwGetVersion: {
args: [FFIType.ptr, FFIType.ptr, FFIType.ptr],
returns: FFIType.void,
},
glfwGetVersionString: {
args: [],
returns: FFIType.ptr,
},
//* BEGIN: https://www.glfw.org/docs/latest/group__window.html#ga3555a418df92ad53f917597fe2f64aeb
//? BEGIN WINDOW
glfwDefaultWindowHints: {
args: [],
returns: FFIType.void
},
glfwWindowHint: {
args: [FFIType.int, FFIType.int],
returns: FFIType.void
},
glfwWindowHintString: {
args: [FFIType.int, FFIType.cstring],
returns: FFIType.void
},
glfwCreateWindow: {
//* width , height , title , monitor , share (null = false)
args: [FFIType.int, FFIType.int, FFIType.ptr, FFIType.ptr, FFIType.ptr],
returns: FFIType.ptr
},
glfwDestroyWindow: {
args: [FFIType.ptr],
returns: FFIType.void
},
glfwWindowShouldClose: {
args: [FFIType.ptr],
returns: FFIType.int
},
glfwSetWindowShouldClose: {
args: [FFIType.ptr, FFIType.int],
returns: FFIType.void
},
glfwSetWindowTitle: {
args: [FFIType.ptr, FFIType.cstring],
returns: FFIType.void
},
glfwSetWindowIcon: {
//* window , count , GLFWimage*
args: [FFIType.ptr, FFIType.int, FFIType.ptr],
returns: FFIType.void
},
glfwGetWindowPos: {
args: [FFIType.ptr, FFIType.ptr, FFIType.ptr],
returns: FFIType.void
},
glfwSetWindowPos: {
args: [FFIType.ptr, FFIType.int, FFIType.int],
returns: FFIType.void
},
glfwGetWindowSize: {
args: [FFIType.ptr, FFIType.ptr, FFIType.ptr],
returns: FFIType.void
},
glfwSetWindowSizeLimits: {
args: [FFIType.ptr, FFIType.int, FFIType.int, FFIType.int, FFIType.int],
returns: FFIType.void
},
glfwSetWindowAspectRatio: {
args: [FFIType.ptr, FFIType.int, FFIType.int],
returns: FFIType.void
},
glfwSetWindowSize: {
args: [FFIType.ptr, FFIType.int, FFIType.int],
returns: FFIType.void
},
glfwGetFramebufferSize: {
args: [FFIType.ptr, FFIType.ptr, FFIType.ptr],
returns: FFIType.void
},
glfwGetWindowFrameSize: {
args: [FFIType.ptr, FFIType.ptr, FFIType.ptr, FFIType.ptr, FFIType.ptr],
returns: FFIType.void
},
glfwGetWindowContentScale: {
args: [FFIType.ptr, FFIType.ptr, FFIType.ptr],
returns: FFIType.void
},
glfwGetWindowOpacity: {
args: [FFIType.ptr],
returns: FFIType.float
},
glfwSetWindowOpacity: {
args: [FFIType.ptr, FFIType.float],
returns: FFIType.void
},
glfwIconifyWindow: {
args: [FFIType.ptr],
returns: FFIType.void
},
glfwRestoreWindow: {
args: [FFIType.ptr],
returns: FFIType.void
},
glfwMaximizeWindow: {
args: [FFIType.ptr],
returns: FFIType.void
},
glfwShowWindow: {
args: [FFIType.ptr],
returns: FFIType.void
},
glfwHideWindow: {
args: [FFIType.ptr],
returns: FFIType.void
},
glfwFocusWindow: {
args: [FFIType.ptr],
returns: FFIType.void
},
glfwRequestWindowAttention: {
args: [FFIType.ptr],
returns: FFIType.void
},
glfwGetWindowMonitor: {
args: [FFIType.ptr],
//* Returning a GLFWmonitor pointer.
returns: FFIType.ptr
},
glfwSetWindowMonitor: {
args: [FFIType.ptr, FFIType.ptr, FFIType.int, FFIType.int, FFIType.int, FFIType.int, FFIType.int],
returns: FFIType.void
},
glfwGetWindowAttrib: {
args: [FFIType.ptr, FFIType.int],
returns: FFIType.int
},
glfwSetWindowAttrib: {
args: [FFIType.ptr, FFIType.int, FFIType.int],
returns: FFIType.void
},
glfwSetWindowUserPointer: {
//! This function is very dangerous.
args: [FFIType.ptr, FFIType.ptr],
returns: FFIType.void
},
glfwGetWindowUserPointer: {
args: [FFIType.ptr],
returns: FFIType.ptr
},
//! BEGIN CALLBACKS!
//* note: A callback is a pointer. See line 14613 of types.d.ts!
//? Void returns instead of function pointers
//? because bun has a different style of memory
//? management.
glfwSetWindowPosCallback: {
args: [FFIType.ptr, FFIType.ptr],
returns: FFIType.void
},
glfwSetWindowSizeCallback: {
args: [FFIType.ptr, FFIType.ptr],
returns: FFIType.void
},
glfwSetWindowCloseCallback: {
args: [FFIType.ptr, FFIType.ptr],
returns: FFIType.void
},
glfwSetWindowRefreshCallback: {
args: [FFIType.ptr, FFIType.ptr],
returns: FFIType.void
},
glfwSetWindowFocusCallback: {
args: [FFIType.ptr, FFIType.ptr],
returns: FFIType.void
},
glfwSetWindowIconifyCallback: {
args: [FFIType.ptr, FFIType.ptr],
returns: FFIType.void
},
glfwSetWindowMaximizeCallback: {
args: [FFIType.ptr, FFIType.ptr],
returns: FFIType.void
},
glfwSetFramebufferSizeCallback: {
args: [FFIType.ptr, FFIType.ptr],
returns: FFIType.void
},
glfwSetWindowContentScaleCallback: {
args: [FFIType.ptr, FFIType.ptr],
returns: FFIType.void
},
//! END CALLBACKS
glfwPollEvents: {
args: [],
returns: FFIType.void
},
glfwWaitEvents: {
args: [],
returns: FFIType.void
},
glfwWaitEventsTimeout: {
args: [FFIType.double],
returns: FFIType.void
},
glfwPostEmptyEvent: {
args: [],
returns: FFIType.void
},
glfwSwapBuffers: {
args: [FFIType.ptr],
returns: FFIType.void
},
//* Begin https://www.glfw.org/docs/latest/group__monitor.html
//? BEGIN MONITOR
glfwGetMonitors: {
args: [FFIType.ptr],
returns: FFIType.ptr
},
glfwGetPrimaryMonitor: {
args: [],
returns: FFIType.ptr
},
glfwGetMonitorPos: {
args: [FFIType.ptr, FFIType.ptr, FFIType.ptr],
returns: FFIType.void
},
glfwGetMonitorWorkarea: {
args: [FFIType.ptr, FFIType.ptr, FFIType.ptr, FFIType.ptr, FFIType.ptr],
returns: FFIType.void
},
glfwGetMonitorPhysicalSize: {
args: [FFIType.ptr, FFIType.ptr, FFIType.ptr],
returns: FFIType.void
},
glfwGetMonitorContentScale: {
args: [FFIType.ptr, FFIType.ptr, FFIType.ptr],
returns: FFIType.void
},
glfwGetMonitorName: {
args: [FFIType.ptr],
returns: FFIType.ptr
},
glfwSetMonitorUserPointer: {
args: [FFIType.ptr, FFIType.ptr],
returns: FFIType.void
},
glfwGetMonitorUserPointer: {
args: [FFIType.ptr],
returns: FFIType.ptr
},
glfwSetMonitorCallback: {
args: [FFIType.ptr],
returns: FFIType.void
},
glfwGetVideoModes: {
args: [FFIType.ptr, FFIType.ptr],
returns: FFIType.ptr
},
glfwGetVideoMode: {
args: [FFIType.ptr],
returns: FFIType.ptr
},
})
//* dlopen has a limit of 64 functions per call, so move into next scope.
const {
symbols: {
glfwSetGamma,
glfwGetGammaRamp,
glfwSetGammaRamp,
glfwMakeContextCurrent,
glfwGetCurrentContext,
glfwSwapInterval,
glfwExtensionSupported,
glfwGetProcAddress,
glfwInitHint,
glfwGetError,
glfwSetErrorCallback,
glfwGetInputMode,
glfwSetInputMode,
glfwRawMouseMotionSupported,
glfwGetKeyName,
glfwGetKeyScancode,
glfwGetKey,
glfwGetMouseButton,
glfwGetCursorPos,
glfwSetCursorPos,
glfwCreateCursor,
glfwCreateStandardCursor,
glfwDestroyCursor,
glfwSetCursor,
glfwSetKeyCallback,
glfwSetCharCallback,
glfwSetCharModsCallback,
glfwSetMouseButtonCallback,
glfwSetCursorPosCallback,
glfwSetCursorEnterCallback,
glfwSetScrollCallback,
glfwSetDropCallback,
glfwJoystickPresent,
glfwGetJoystickAxes,
glfwGetJoystickButtons,
glfwGetJoystickHats,
glfwGetJoystickName,
glfwGetJoystickGUID,
glfwSetJoystickUserPointer,
glfwGetJoystickUserPointer,
glfwJoystickIsGamepad,
glfwSetJoystickCallback,
glfwUpdateGamepadMappings,
glfwGetGamepadName,
glfwGetGamepadState,
glfwSetClipboardString,
glfwGetClipboardString,
glfwGetTime,
glfwSetTime,
glfwGetTimerValue,
glfwGetTimerFrequency
},
} = dlopen(path, {
glfwSetGamma: {
args: [FFIType.ptr, FFIType.float],
returns: FFIType.void
},
glfwGetGammaRamp: {
args: [FFIType.ptr],
returns: FFIType.ptr
},
glfwSetGammaRamp: {
args: [FFIType.ptr, FFIType.ptr],
returns: FFIType.void
},
//* Begin: https://www.glfw.org/docs/latest/group__context.html
glfwMakeContextCurrent: {
args: [FFIType.ptr],
returns: FFIType.void
},
glfwGetCurrentContext: {
args: [],
returns: FFIType.ptr
},
glfwSwapInterval: {
args: [FFIType.int],
returns: FFIType.void
},
glfwExtensionSupported: {
args: [FFIType.cstring],
returns: FFIType.int
},
glfwGetProcAddress: {
args: [FFIType.cstring],
returns: FFIType.ptr
},
//* Begin: https://www.glfw.org/docs/latest/group__init.html
glfwInitHint: {
args: [FFIType.int, FFIType.int],
returns: FFIType.void
},
glfwGetError: {
args: [FFIType.ptr],
returns: FFIType.int
},
glfwSetErrorCallback: {
args: [FFIType.ptr],
returns: FFIType.ptr
},
//* Begin: https://www.glfw.org/docs/latest/group__input.html
glfwGetInputMode: {
args: [FFIType.ptr, FFIType.int],
returns: FFIType.int
},
glfwSetInputMode: {
args: [FFIType.ptr, FFIType.int, FFIType.int],
returns: FFIType.void
},
glfwRawMouseMotionSupported: {
args: [],
returns: FFIType.int
},
glfwGetKeyName: {
args: [FFIType.int, FFIType.int],
returns: FFIType.ptr
},
glfwGetKeyScancode: {
args: [FFIType.int],
returns: FFIType.int
},
glfwGetKey: {
args: [FFIType.ptr, FFIType.int],
returns: FFIType.int
},
glfwGetMouseButton: {
args: [FFIType.int, FFIType.int],
returns: FFIType.int
},
glfwGetCursorPos: {
args: [FFIType.ptr, FFIType.ptr, FFIType.ptr],
returns: FFIType.void
},
glfwSetCursorPos: {
args: [FFIType.ptr, FFIType.double, FFIType.double],
returns: FFIType.void
},
glfwCreateCursor: {
args: [FFIType.ptr, FFIType.int, FFIType.int],
returns: FFIType.ptr
},
glfwCreateStandardCursor: {
args: [FFIType.int],
returns: FFIType.ptr
},
glfwDestroyCursor: {
args: [FFIType.ptr],
returns: FFIType.void
},
glfwSetCursor: {
args: [FFIType.ptr, FFIType.ptr],
returns: FFIType.void
},
glfwSetKeyCallback: {
args: [FFIType.ptr, FFIType.ptr],
returns: FFIType.ptr
},
glfwSetCharCallback: {
args: [FFIType.ptr, FFIType.ptr],
returns: FFIType.ptr
},
glfwSetCharModsCallback: {
args: [FFIType.ptr, FFIType.ptr],
returns: FFIType.ptr
},
glfwSetMouseButtonCallback: {
args: [FFIType.ptr, FFIType.ptr],
returns: FFIType.ptr
},
glfwSetCursorPosCallback: {
args: [FFIType.ptr, FFIType.ptr],
returns: FFIType.ptr
},
glfwSetCursorEnterCallback: {
args: [FFIType.ptr, FFIType.ptr],
returns: FFIType.ptr
},
glfwSetScrollCallback: {
args: [FFIType.ptr, FFIType.ptr],
returns: FFIType.ptr
},
glfwSetDropCallback: {
args: [FFIType.ptr, FFIType.ptr],
returns: FFIType.ptr
},
glfwJoystickPresent: {
args: [FFIType.int],
returns: FFIType.int
},
glfwGetJoystickAxes: {
args: [FFIType.int, FFIType.ptr],
returns: FFIType.ptr
},
glfwGetJoystickButtons: {
args: [FFIType.int, FFIType.ptr],
returns: FFIType.ptr
},
glfwGetJoystickHats: {
args: [FFIType.int, FFIType.ptr],
returns: FFIType.ptr
},
glfwGetJoystickName: {
args: [FFIType.int],
returns: FFIType.ptr
},
glfwGetJoystickGUID: {
args: [FFIType.int],
returns: FFIType.ptr
},
glfwSetJoystickUserPointer: {
args: [FFIType.int, FFIType.ptr],
returns: FFIType.void
},
glfwGetJoystickUserPointer: {
args: [FFIType.int],
returns: FFIType.ptr
},
glfwJoystickIsGamepad: {
args: [FFIType.int],
returns: FFIType.int
},
glfwSetJoystickCallback: {
args: [FFIType.ptr],
returns: FFIType.ptr
},
glfwUpdateGamepadMappings: {
args: [FFIType.ptr],
returns: FFIType.int
},
glfwGetGamepadName: {
args: [FFIType.int],
returns: FFIType.ptr
},
glfwGetGamepadState: {
args: [FFIType.int, FFIType.ptr],
returns: FFIType.int
},
glfwSetClipboardString: {
args: [FFIType.ptr, FFIType.ptr],
returns: FFIType.void
},
glfwGetClipboardString: {
args: [FFIType.ptr],
returns: FFIType.ptr
},
glfwGetTime: {
args: [],
returns: FFIType.double
},
glfwSetTime: {
args: [FFIType.double],
returns: FFIType.void
},
glfwGetTimerValue: {
args: [],
returns: FFIType.uint64_t
},
glfwGetTimerFrequency: {
args: [],
returns: FFIType.uint64_t
},
})
// Everything is wrapped for safety and so I don't have to tear my hair out.
export function init(): boolean {
return glfwInit()
}
export function terminate(): boolean {
return glfwTerminate()
}
export function getVersion(): number[] {
// Have internal pointers, auto referenced into C function.
let major = new Int32Array(1)
let minor = new Int32Array(1)
let revision = new Int32Array(1)
glfwGetVersion(major, minor, revision)
return [major[0], minor[0], revision[0]]
}
export function getVersionString(): CString {
let versionStringPointer = glfwGetVersionString()
if (versionStringPointer == null) {
throw new Error("GLFW ERROR! version string was null!")
}
return new CString(versionStringPointer)
}
//? BEGIN WINDOW
export function defaultWindowHints() {
glfwDefaultWindowHints()
}
export function windowHint(hint: number, value: number) {
glfwWindowHint(hint, value)
}
export function windowHintString(hint: number, value: string) {
const hintBuffer = toBuffer(value)
glfwWindowHintString(hint, hintBuffer)
}
export function createWindow(width: number, height: number, title: string, monitor: FFIType.ptr | null, share: FFIType.ptr | null): FFIType.ptr | null {
const titleBuffer = toBuffer(title)
return glfwCreateWindow(width, height, titleBuffer, monitor, share)
}
export function destroyWindow(window: FFIType.ptr) {
glfwDestroyWindow(window)
}
export function windowShouldClose(window: FFIType.ptr): boolean {
return glfwWindowShouldClose(window) == GLFW_TRUE
}
export function setWindowShouldClose(window: FFIType.ptr, shouldClose: boolean) {
glfwSetWindowShouldClose(window, shouldClose ? 1 : 0)
}
export function setWindowTitle(window: FFIType.ptr, title: string) {
const titleBuffer = toBuffer(title)
glfwSetWindowTitle(window, titleBuffer)
}
export function setWindowIcon(window: FFIType.ptr, count: number, images: FFIType.ptr) {
glfwSetWindowIcon(window, count, images)
}
export function getWindowPos(window: FFIType.ptr): number[] {
let xpos = new Int32Array(1)
let ypos = new Int32Array(1)
glfwGetWindowPos(window, xpos, ypos)
return [xpos[0], ypos[0]]
}
export function setWindowPos(window: FFIType.ptr, xpos: number, ypos: number) {
glfwSetWindowPos(window, xpos, ypos)
}
export function getWindowSize(window: FFIType.ptr): number[] {
let width = new Int32Array(1)
let height = new Int32Array(1)
glfwGetWindowSize(window, width, height)
return [width[0], height[0]]
}
export function setWindowSizeLimits(window: FFIType.ptr, minwidth: number, minheight: number, maxwidth: number, maxheight: number) {
glfwSetWindowSizeLimits(window, minwidth, minheight, maxwidth, maxheight)
}
export function setWindowAspectRatio(window: FFIType.ptr, numer: number, denom: number) {
glfwSetWindowAspectRatio(window, numer, denom)
}
export function setWindowSize(window: FFIType.ptr, width: number, height: number) {
glfwSetWindowSize(window, width, height)
}
export function getFramebufferSize(window: FFIType.ptr): number[] {
let width = new Int32Array(1)
let height = new Int32Array(1)
glfwGetFramebufferSize(window, width, height)
return [width[0], height[0]]
}
export function getWindowFrameSize(window: FFIType.ptr): number[] {
let left = new Int32Array(1)
let top = new Int32Array(1)
let right = new Int32Array(1)
let bottom = new Int32Array(1)
glfwGetWindowFrameSize(window, left, top, right, bottom)
return [left[0], top[0], right[0], bottom[0]]
}
export function getWindowContentScale(window: FFIType.ptr): number[] {
let xscale = new Int32Array(1)
let yscale = new Int32Array(1)
glfwGetWindowContentScale(window, xscale, yscale)
return [xscale[0], yscale[0]]
}
export function getWindowOpacity(window: FFIType.ptr): number {
return glfwGetWindowOpacity(window)
}
export function setWindowOpacity(window: FFIType, opacity: number) {
glfwSetWindowOpacity(window, opacity)
}
export function iconifyWindow(window: FFIType.ptr) {
glfwIconifyWindow(window)
}
export function restoreWindow(window: FFIType.ptr) {
glfwRestoreWindow(window)
}
export function maximizeWindow(window: FFIType.ptr) {
glfwMaximizeWindow(window)
}
export function showWindow(window: FFIType.ptr) {
glfwShowWindow(window)
}
export function hideWindow(window: FFIType.ptr) {
glfwHideWindow(window)
}
export function focusWindow(window: FFIType.ptr) {
glfwFocusWindow(window)
}
export function requestWindowAttention(window: FFIType.ptr) {
glfwRequestWindowAttention(window)
}
//* Returns a GLFWmonitor pointer. Or null. Very dramatic.
export function getWindowMonitor(window: FFIType.ptr): FFIType.ptr | null {
return glfwGetWindowMonitor(window)
}
export function setWindowMonitor(window: FFIType.ptr, monitor: FFIType.ptr, xpos: number, ypos: number, width: number, height: number, refreshRate: number) {
glfwSetWindowMonitor(window, monitor, xpos, ypos, width, height, refreshRate)
}
export function getWindowAttrib(window: FFIType.ptr, attrib: number): number {
return glfwGetWindowAttrib(window, attrib)
}
export function setWindowAttrib(window: FFIType.ptr, attrib: number, value: number) {
glfwSetWindowAttrib(window, attrib, value)
}
export function setWindowUserPointer(window: FFIType.ptr, pointer: FFIType.ptr) {
//! This function is very dangerous.
glfwSetWindowUserPointer(window, pointer)
}
export function getWindowUserPointer(window: FFIType.ptr): FFIType.ptr | null {
return glfwGetWindowUserPointer(window)
}
//! BEGIN CALLBACKS!
//* note: A callback is a pointer. See line 14613 of types.d.ts!
// You pass this a lambda and you get a nice safe object you can wait until the end to free.
// TODO: Document this like a normal person.
export function setWindowPosCallback(window: FFIType.ptr, callback: (window: FFIType.ptr, xpos: number, ypos: number) => void): JSCallback {
const callbackObject = new JSCallback(
callback,
{
args: [FFIType.ptr, FFIType.int, FFIType.int],
returns: FFIType.void,
}
)
glfwSetWindowPosCallback(window, callbackObject.ptr)
// And now you can keep it safe until you want to free it. :)
//! Make sure you free (close()) the old callback before you set a new one
//! or else, you'll have a memory leak.
return callbackObject
}
//* That's all the documentation I'm going to do for an example.
//* This will be redocumented with JSDoc or TSDoc or whatever it's called.
export function setWindowSizeCallback(window: FFIType.ptr, callback: (window: FFIType.ptr, width: number, height: number) => void): JSCallback {
const callbackObject = new JSCallback(
callback,
{
args: [FFIType.ptr, FFIType.int, FFIType.int],
returns: FFIType.void,
}
)
glfwSetWindowSizeCallback(window, callbackObject.ptr)
return callbackObject
}
export function setWindowCloseCallback(window: FFIType.ptr, callback: (window: FFIType.ptr) => void): JSCallback {
const callbackObject = new JSCallback(
callback,
{
args: [FFIType.ptr],
returns: FFIType.void,
}
)
glfwSetWindowCloseCallback(window, callbackObject.ptr)
return callbackObject
}
export function setWindowRefreshCallback(window: FFIType.ptr, callback: (window: FFIType.ptr) => void): JSCallback {
const callbackObject = new JSCallback(
callback,
{
args: [FFIType.ptr],
returns: FFIType.void,
}
)
glfwSetWindowRefreshCallback(window, callbackObject.ptr)
return callbackObject
}
export function setWindowFocusCallback(window: FFIType.ptr, callback: (window: FFIType.ptr, focused: FFIType.int) => void): JSCallback {
const callbackObject = new JSCallback(
callback,
{
args: [FFIType.ptr, FFIType.int],
returns: FFIType.void,
}
)
glfwSetWindowFocusCallback(window, callbackObject.ptr)
return callbackObject
}
export function setWindowIconifyCallback(window: FFIType.ptr, callback: (window: FFIType.ptr, iconified: FFIType.int) => void): JSCallback {
const callbackObject = new JSCallback(
callback,
{
args: [FFIType.ptr, FFIType.int],
returns: FFIType.void,
}
)
glfwSetWindowIconifyCallback(window, callbackObject.ptr)
return callbackObject
}
export function setWindowMaximizeCallback(window: FFIType.ptr, callback: (window: FFIType.ptr, maximized: FFIType.int) => void): JSCallback {
const callbackObject = new JSCallback(
callback,
{
args: [FFIType.ptr, FFIType.int],
returns: FFIType.void,
}
)
glfwSetWindowMaximizeCallback(window, callbackObject.ptr)
return callbackObject
}
export function setFramebufferSizeCallback(window: FFIType.ptr, callback: (window: FFIType.ptr, width: FFIType.int, height: FFIType.int) => void): JSCallback {
const callbackObject = new JSCallback(
callback,
{
args: [FFIType.ptr, FFIType.int, FFIType.int],
returns: FFIType.void,
}
)
glfwSetFramebufferSizeCallback(window, callbackObject.ptr)
return callbackObject
}
export function setWindowContentScaleCallback(window: FFIType.ptr, callback: (window: FFIType.ptr, xscale: FFIType.float, yscale: FFIType.float) => void): JSCallback {
const callbackObject = new JSCallback(
callback,
{
args: [FFIType.ptr, FFIType.float, FFIType.float],
returns: FFIType.void,
}
)
glfwSetWindowContentScaleCallback(window, callbackObject.ptr)
return callbackObject
}
//! END CALLBACKS
export function pollEvents() {
glfwPollEvents()
}
export function waitEvents() {
glfwWaitEvents()
}
export function waitEventsTimeout(timeout: number) {
glfwWaitEventsTimeout(timeout)
}
export function postEmptyEvent() {
glfwPostEmptyEvent()
}
export function swapBuffers(window: FFIType.ptr) {
glfwSwapBuffers(window)
}
//? BEGIN MONITORS
export function getMonitors(): FFIType.ptr[] | null {
//TODO: test this thing. Make a safety wrapper! This is too raw!
//FIXME: https://media.tenor.com/YHKWHhNCDOsAAAAC/ramsay-raw.gif
let count = new Int32Array(1)
let pointerArrayPointer = glfwGetMonitors(count)
// I have no idea if this works.
//TODO: test this garbage!
if (count[0] == 0 || pointerArrayPointer == null) {
// You don't have any monitors?!
return null
}
let pointerArray = new Array(count[0])
for (let i = 0; i < count[0]; i++) {
// I heard you like to just pile on unsafeness, here you go.
//* Assume 64 bit operating system because it's 2023
pointerArray[i] = read.ptr(pointerArrayPointer, 8 * i)
}
// You use this by indexing into the table, and it
//...hopefully gives you a monitor pointer
return pointerArray
}
// See this is a bit more sane, just a normal monitor pointer
export function getPrimaryMonitor(): FFIType.ptr | null {
return glfwGetPrimaryMonitor()
}
export function getMonitorPos(monitor: FFIType.ptr): number[] {
let xpos = new Int32Array(1)
let ypos = new Int32Array(1)
glfwGetMonitorPos(monitor, xpos, ypos)
return [xpos[0], ypos[0]]
}
export function getMonitorWorkarea(monitor: FFIType.ptr): number[] {
let xpos = new Int32Array(1)
let ypos = new Int32Array(1)
let width = new Int32Array(1)
let height = new Int32Array(1)
glfwGetMonitorWorkarea(monitor, xpos, ypos, width, height)
return [xpos[0], ypos[0], width[0], height[0]]
}
export function getMonitorPhysicalSize(monitor: FFIType.ptr): number[] {
let widthMM = new Int32Array(1)
let heightMM = new Int32Array(1)
glfwGetMonitorPhysicalSize(monitor, widthMM, heightMM)
return [widthMM[0], heightMM[0]]
}
export function getMonitorContentScale(monitor: FFIType.ptr): number[] {
let xscale = new Int32Array(1)
let yscale = new Int32Array(1)
glfwGetMonitorContentScale(monitor, xscale, yscale)
return [xscale[0], yscale[0]]
}
export function getMonitorName(monitor: FFIType.ptr): CString {
let monitorNamePointer = glfwGetMonitorName(monitor)
if (monitorNamePointer == null) {
throw new Error("GLFW ERROR: monitor name is null!")
}
return new CString(monitorNamePointer)
}
export function setMonitorUserPointer(monitor: FFIType.ptr, pointer: FFIType.ptr) {
glfwSetMonitorUserPointer(monitor, pointer)
}
export function getMonitorUserPointer(monitor: FFIType.ptr): FFIType.ptr | null {
return glfwGetMonitorUserPointer(monitor)
}
export function setMonitorCallback(callback: (monitor: FFIType.ptr, event: number) => void): JSCallback {
const callbackObject = new JSCallback(
callback,
{
args: [FFIType.ptr, FFIType.int],
returns: FFIType.void,
}
)
glfwSetMonitorCallback(callbackObject.ptr)
return callbackObject
}
export function getVideoModes(monitor: FFIType.ptr): number[] | null {
let count = new Int32Array(1)
let vidModeArrayPointer = glfwGetVideoModes(monitor, count)
if (count[0] == 0 || vidModeArrayPointer == null) {
return null
}
let modeArray = new Array(count[0])
for (let i = 0; i < count[0]; i++) {
// I heard you like to just pile on unsafeness, here you go.
//* Assume 64 bit operating system because it's 2023
modeArray[i] = read.ptr(vidModeArrayPointer, 8 * i)
}
// Returning an array of available modes.
return modeArray
}
export function getVideoMode(monitor: FFIType.ptr): FFIType.ptr | null {
return glfwGetVideoMode(monitor)
}
export function setGamma(monitor: FFIType.ptr, gamma: number) {
glfwSetGamma(monitor, gamma)
}
export function getGammaRamp(monitor: FFIType.ptr): FFIType.ptr | null {
return glfwGetGammaRamp(monitor)
}
export function setGammaRamp(monitor: FFIType.ptr, ramp: FFIType.ptr) {
glfwSetGammaRamp(monitor, ramp)
}
//* begin https://www.glfw.org/docs/latest/group__context.html
export function makeContextCurrent(window: FFIType.ptr) {
glfwMakeContextCurrent(window)
}
export function getCurrentContext(): FFIType.ptr | null {
return glfwGetCurrentContext()
}
export function swapInterval(interval: number) {
glfwSwapInterval(interval)
}
export function extensionSupported(extension: string): boolean {
let extensionBuffer = toBuffer(extension)
return glfwExtensionSupported(extensionBuffer) == GLFW_TRUE
}
export function getProcAddress(procname: string): FFIType.ptr | null {
let procnameBuffer = toBuffer(procname)
return glfwGetProcAddress(procnameBuffer)
}
//* Begin: https://www.glfw.org/docs/latest/group__init.html
export function initHint(hint: number, value: number) {
glfwInitHint(hint, value)
}
export function getError(): [number, string] {
//* This will return [GLFW_ERROR, error explanation]
let rawBuffer = Buffer.alloc(1024, " ")
let glfwError = glfwGetError(rawBuffer)
let usableString = rawBuffer.toString()
return [glfwError, usableString]
}
export function setErrorCallback(callback: (error_code: number, description: FFIType.ptr) => void): JSCallback {
const callbackObject = new JSCallback(
callback,
{
args: [FFIType.int, FFIType.ptr],
returns: FFIType.void,
}
)
glfwSetErrorCallback(callbackObject.ptr)
return callbackObject
}
//* Begin: https://www.glfw.org/docs/3.3/group__input.html
export function getInputMode(window: FFIType.ptr, mode: number): number {
return glfwGetInputMode(window, mode)
}
export function setInputMode(window: FFIType.ptr, mode: FFIType.int, value: FFIType.int) {
glfwSetInputMode(window, mode, value)
}
export function rawMouseMotionSupported(): boolean {
return glfwRawMouseMotionSupported() == GLFW_TRUE
}
export function getKeyName(key: number, scancode: number): string | null {
let keyNamePointer = glfwGetKeyName(key, scancode)
if (keyNamePointer == null) {
return null
}
const keyName = new CString(keyNamePointer)
//!Fixme: This needs to be tested!
return keyName.toString()
}
export function getKeyScancode(key: number): number {
return glfwGetKeyScancode(key)
}
export function getKey(window: FFIType.ptr, key: number): number {
return glfwGetKey(window, key)
}
export function getMouseButton(window: FFIType.ptr, button: number): number {
return glfwGetMouseButton(window, button)
}
export function getCursorPos(window: FFIType.ptr): number[] {
let xpos = new Float64Array(1)
let ypos = new Float64Array(1)
glfwGetCursorPos(window, xpos, ypos)
return [xpos[0], ypos[0]]
}
export function setCursorPos(window: FFIType.ptr, xpos: number, ypos: number) {
glfwSetCursorPos(window, xpos, ypos)
}
export function createCursor(image: FFIType.ptr, xhot: number, yhot: number): FFIType.ptr | null {
return glfwCreateCursor(image, xhot, yhot)
}
export function createStandardCursor(shape: number): FFIType.ptr | null {
return glfwCreateStandardCursor(shape)
}
export function destroyCursor(cursor: FFIType.ptr) {
glfwDestroyCursor(cursor)
}
export function setCursor(window: FFIType.ptr, cursor: FFIType.ptr) {
glfwSetCursor(window, cursor)
}
export function setKeyCallback(window: FFIType.ptr, callback: (window: FFIType.ptr, key: FFIType.int, scancode: FFIType.int, action: FFIType.int, mods: FFIType.int) => void): JSCallback {
const callbackObject = new JSCallback(
callback,
{
args: [FFIType.ptr, FFIType.int, FFIType.int, FFIType.int, FFIType.int],
returns: FFIType.void,
}
)
glfwSetKeyCallback(window, callbackObject.ptr)
return callbackObject
}
export function setCharCallback(window: FFIType.ptr, callback: (window: FFIType.ptr, codepoint: FFIType.uint32_t) => void): JSCallback {
const callbackObject = new JSCallback(
callback,
{
args: [FFIType.ptr, FFIType.uint32_t],
returns: FFIType.void,
}
)
glfwSetCharCallback(window, callbackObject.ptr)
return callbackObject
}
export function setCharModsCallback(window: FFIType.ptr, callback: (window: FFIType.ptr, codepoint: FFIType.uint32_t, mods: FFIType.int) => void): JSCallback {
const callbackObject = new JSCallback(
callback,
{
args: [FFIType.ptr, FFIType.uint32_t, FFIType.int],
returns: FFIType.void,
}
)
glfwSetCharModsCallback(window, callbackObject.ptr)
return callbackObject
}
export function setMouseButtonCallback(window: FFIType.ptr, callback: (window: FFIType.ptr, button: FFIType.int, action: FFIType.int, mods: FFIType.int) => void): JSCallback {
const callbackObject = new JSCallback(
callback,
{
args: [FFIType.ptr, FFIType.int, FFIType.int, FFIType.int],
returns: FFIType.void,
}
)
glfwSetMouseButtonCallback(window, callbackObject.ptr)
return callbackObject
}
export function setCursorPosCallback(window: FFIType.ptr, callback: (window: FFIType.ptr, xpos: FFIType.double, ypos: FFIType.double) => void): JSCallback {
const callbackObject = new JSCallback(
callback,
{
args: [FFIType.ptr, FFIType.double, FFIType.double],
returns: FFIType.void,
}
)
glfwSetCursorPosCallback(window, callbackObject.ptr)
return callbackObject
}
export function setCursorEnterCallback(window: FFIType.ptr, callback: (window: FFIType.ptr, entered: FFIType.int) => void): JSCallback {
const callbackObject = new JSCallback(
callback,
{
args: [FFIType.ptr, FFIType.int],
returns: FFIType.void,
}
)
glfwSetCursorEnterCallback(window, callbackObject.ptr)
return callbackObject
}
export function setScrollCallback(window: FFIType.ptr, callback: (window: FFIType.ptr, xoffset: FFIType.double, yoffset: FFIType.double) => void): JSCallback {
const callbackObject = new JSCallback(
callback,
{
args: [FFIType.ptr, FFIType.double, FFIType.double],
returns: FFIType.void,
}
)
glfwSetScrollCallback(window, callbackObject.ptr)
return callbackObject
}
export function setDropCallback(window: FFIType.ptr, callback: (window: FFIType.ptr, path_count: FFIType.int, paths: FFIType.ptr) => void): JSCallback {
const callbackObject = new JSCallback(
callback,
{
args: [FFIType.ptr, FFIType.int, FFIType.ptr],
returns: FFIType.void,
}
)
glfwSetDropCallback(window, callbackObject.ptr)
return callbackObject
}
export function joystickPresent(jid: number): number {
return glfwJoystickPresent(jid)
}
export function getJoystickAxes(jid: number): number[] | null {
let count = new Int32Array(1)
let axisArrayPointer = glfwGetJoystickAxes(jid, count)
if (count[0] == 0 || axisArrayPointer == null) {
return null
}
let axisArray = new Array(count[0])
for (let i = 0; i < count[0]; i++) {
// I heard you like to just pile on unsafeness, here you go.
//* Assume 64 bit operating system because it's 2023
axisArray[i] = read.ptr(axisArrayPointer, 8 * i)
}
// Returning an array of available axis.
return axisArray
}
export function getJoystickButtons(jid: number): number[] | null {
let count = new Int32Array(1)
let buttonStatePointer = glfwGetJoystickButtons(jid, count)
if (count[0] == 0 || buttonStatePointer == null) {
return null
}
let buttonArray = new Array(count[0])
for (let i = 0; i < count[0]; i++) {
// I heard you like to just pile on unsafeness, here you go.
//* Assume 64 bit operating system because it's 2023
//!FIXME: This might be u8 which is 1 byte
buttonArray[i] = read.ptr(buttonStatePointer, 8 * i)
}
// Returning an array of available axis.
return buttonArray
}
export function getJoystickHats(jid: number): number[] | null {
let count = new Int32Array(1)
let hatStatePointer = glfwGetJoystickHats(jid, count)
if (count[0] == 0 || hatStatePointer == null) {
return null
}
let hatArray = new Array(count[0])
for (let i = 0; i < count[0]; i++) {
// I heard you like to just pile on unsafeness, here you go.
//* Assume 64 bit operating system because it's 2023
//!FIXME: This might be u8 which is 1 byte
hatArray[i] = read.ptr(hatStatePointer, 8 * i)
}
// Returning an array of available axis.
return hatArray
}
export function getJoystickName(jid: number): string | null {
let keyNamePointer = glfwGetJoystickName(jid)
if (keyNamePointer == null) {
return null
}
const keyName = new CString(keyNamePointer)
//!Fixme: This needs to be tested!
return keyName.toString()
}
export function getJoystickGUID(jid: number): string | null {
let keyNamePointer = glfwGetJoystickGUID(jid)
if (keyNamePointer == null) {
return null
}
const keyName = new CString(keyNamePointer)
//!Fixme: This needs to be tested!
return keyName.toString()
}
export function setJoystickUserPointer(jid: number, pointer: FFIType.ptr) {
glfwSetJoystickUserPointer(jid, pointer)
}
export function getJoystickUserPointer(jid: number): FFIType.ptr | null {
return glfwGetJoystickUserPointer(jid)
}
export function joystickIsGamepad(jid: number): boolean {
return glfwJoystickIsGamepad(jid) == GLFW_TRUE
}
export function setJoystickCallback(callback: (jid: FFIType.int, event: FFIType.int) => void): JSCallback {
const callbackObject = new JSCallback(
callback,
{
args: [FFIType.int, FFIType.int],
returns: FFIType.void,
}
)
glfwSetJoystickCallback(callbackObject.ptr)
return callbackObject
}
export function updateGamepadMappings(map: string): boolean {
let mapBuffer = toBuffer(map)
let result = glfwUpdateGamepadMappings(mapBuffer)
return result == GLFW_TRUE
}
export function getGamepadName(jid: number): string | null {
let keyNamePointer = glfwGetGamepadName(jid)
if (keyNamePointer == null) {
return null
}
const keyName = new CString(keyNamePointer)
//!Fixme: This needs to be tested!
return keyName.toString()
}
export function getGamepadState(jid: number): [boolean, FFIType.ptr | null] {
//!FIXME: this is too raw. Don't make me get Gordon Ramsey in here.
let state = new Int32Array(1)
let success = glfwGetGamepadState(jid, state)
return [success == GLFW_TRUE, state[0]]
}
export function setClipboardString(window: FFIType.ptr, text: string) {
let textBuffer = toBuffer(text)
glfwSetClipboardString(window, textBuffer)
}
export function etClipboardString(window: FFIType.ptr): string | null {
let cStringPointer = glfwGetClipboardString(window)
if (cStringPointer == null) {
return null
}
let cString = new CString(cStringPointer)
//!FIXME: I have no idea if this works!
return cString.toString()
}
export function getTime(): number {
return glfwGetTime()
}
export function setTime(time: number) {
glfwSetTime(time)
}
export function getTimerValue(): bigint {
return glfwGetTimerValue()
}
export function getTimerFrequency(): bigint {
return glfwGetTimerFrequency()
}
const [GLFW_VERSION_MAJOR,
GLFW_VERSION_MINOR,
GLFW_VERSION_REVISION] = getVersion()
export {
path as GFLW_PATH,
GLFW_VERSION_MAJOR,
GLFW_VERSION_MINOR,
GLFW_VERSION_REVISION,
}