168 #pragma comment(lib, "gdi32")
169 #pragma comment(lib, "shell32")
170 #pragma comment(lib, "User32")
171 #pragma warning( push )
172 #pragma warning( disable : 4996 4191 4127)
177 #if defined(__STDC__) && !defined(__STDC_VERSION__)
183 #define RGFW_USERPTR NULL
187 #define RGFW_UNUSED(x) (void)(x)
191 #define RGFW_ROUND(x) (i32)((x) >= 0 ? (x) + 0.5f : (x) - 0.5f)
196 #define RGFW_ALLOC malloc
197 #define RGFW_FREE free
202 #define RGFW_ASSERT assert
205#if !defined(RGFW_MEMCPY) || !defined(RGFW_STRNCMP) || !defined(RGFW_STRNCPY) || !defined(RGFW_MEMSET)
210 #define RGFW_MEMSET(ptr, value, num) memset(ptr, value, num)
214 #define RGFW_MEMCPY(dist, src, len) memcpy(dist, src, len)
218 #define RGFW_STRNCMP(s1, s2, max) strncmp(s1, s2, max)
222 #define RGFW_STRNCPY(dist, src, len) strncpy(dist, src, len)
226 #define RGFW_STRSTR(str, substr) strstr(str, substr)
232 #define RGFW_STRTOL(str, endptr, base) strtol(str, endptr, base)
233 #define RGFW_ATOF(num) atof(num)
236#if !defined(RGFW_PRINTF) && ( defined(RGFW_DEBUG) || defined(RGFW_WAYLAND) )
239 #define RGFW_PRINTF printf
243 #define RGFW_NO_MONITOR
244 #define RGFW_NO_PASSTHROUGH
247#if defined(RGFW_EXPORT) || defined(RGFW_IMPORT)
249 #if defined(__TINYC__) && (defined(RGFW_EXPORT) || defined(RGFW_IMPORT))
250 #define __declspec(x) __attribute__((x))
253 #if defined(RGFW_EXPORT)
254 #define RGFWDEF __declspec(dllexport)
256 #define RGFWDEF __declspec(dllimport)
259 #if defined(RGFW_EXPORT)
260 #define RGFWDEF __attribute__((visibility("default")))
270 #define RGFWDEF __inline
272 #define RGFWDEF inline
277 #define RGFW_ENUM(type, name) type name; enum
281#if defined(__cplusplus) && !defined(__EMSCRIPTEN__)
291#ifndef RGFW_INT_DEFINED
293 typedef unsigned char u8;
294 typedef signed char i8;
295 typedef unsigned short u16;
296 typedef signed short i16;
297 typedef unsigned long int u32;
298 typedef signed long int i32;
299 typedef unsigned long long u64;
300 typedef signed long long i64;
313 #define RGFW_INT_DEFINED
316#ifndef RGFW_BOOL_DEFINED
317 #define RGFW_BOOL_DEFINED
321#define RGFW_BOOL(x) (RGFW_bool)((x) ? RGFW_TRUE : RGFW_FALSE)
322#define RGFW_TRUE (RGFW_bool)1
323#define RGFW_FALSE (RGFW_bool)0
331 #if !defined(RGFW_NO_API) && !defined(RGFW_WEBGPU)
339 #include <emscripten/html5.h>
340 #include <emscripten/key_codes.h>
343 #include <emscripten/html5_webgpu.h>
347#if defined(RGFW_X11) && defined(__APPLE__) && !defined(RGFW_CUSTOM_BACKEND)
348 #define RGFW_MACOS_X11
353#if defined(_WIN32) && !defined(RGFW_X11) && !defined(RGFW_UNIX) && !defined(RGFW_WASM) && !defined(RGFW_CUSTOM_BACKEND)
366 #ifndef RGFW_NO_XINPUT
374#if defined(RGFW_WAYLAND)
376 #if !defined(RGFW_NO_API) && (!defined(RGFW_BUFFER) || defined(RGFW_OPENGL))
379 #include <wayland-egl.h>
383 #include <wayland-client.h>
385#if !defined(RGFW_NO_X11) && (defined(__unix__) || defined(RGFW_MACOS_X11) || defined(RGFW_X11)) && !defined(RGFW_WASM) && !defined(RGFW_CUSTOM_BACKEND)
386 #define RGFW_MACOS_X11
389 #include <X11/Xlib.h>
390 #include <X11/Xutil.h>
391#elif defined(__APPLE__) && !defined(RGFW_MACOS_X11) && !defined(RGFW_X11) && !defined(RGFW_WASM) && !defined(RGFW_CUSTOM_BACKEND)
393 #if !defined(RGFW_BUFFER_BGR)
394 #define RGFW_BUFFER_BGR
396 #undef RGFW_BUFFER_BGR
400#if (defined(RGFW_OPENGL_ES1) || defined(RGFW_OPENGL_ES2) || defined(RGFW_OPENGL_ES3)) && !defined(RGFW_EGL)
404#if !defined(RGFW_EGL) && !defined(RGFW_OPENGL) && !defined(RGFW_DIRECTX) && !defined(RGFW_BUFFER) && !defined(RGFW_NO_API)
412#if (defined(RGFW_OPENGL) || defined(RGFW_WEGL)) && defined(_MSC_VER)
413 #pragma comment(lib, "opengl32")
416#if defined(RGFW_OPENGL) && defined(RGFW_X11)
417 #ifndef GLX_MESA_swap_control
418 #define GLX_MESA_swap_control
423#if !defined(RGFW_SNPRINTF) && defined(RGFW_X11)
426 #define RGFW_SNPRINTF snprintf
430#define RGFW_COCOA_FRAME_NAME NULL
459 RGFW_mouseButtonPressed,
460 RGFW_mouseButtonReleased,
461 RGFW_mousePosChanged,
467 RGFW_gamepadConnected,
468 RGFW_gamepadDisconnected,
469 RGFW_gamepadButtonPressed,
470 RGFW_gamepadButtonReleased,
471 RGFW_gamepadAxisMove,
502 RGFW_windowMaximized,
503 RGFW_windowMinimized,
514 RGFW_mouseScrollDown,
515 RGFW_mouseMisc1, RGFW_mouseMisc2, RGFW_mouseMisc3, RGFW_mouseMisc4, RGFW_mouseMisc5,
520#define RGFW_MAX_PATH 260
522#ifndef RGFW_MAX_DROPS
523#define RGFW_MAX_DROPS 260
526#define RGFW_BIT(x) (1 << x)
541 RGFW_gamepadNone = 0,
577#if defined(__cplusplus) && !defined(__APPLE__)
578#define RGFW_POINT(x, y) {(i32)x, (i32)y}
579#define RGFW_RECT(x, y, w, h) {(i32)x, (i32)y, (i32)w, (i32)h}
580#define RGFW_AREA(w, h) {(u32)w, (u32)h}
582#define RGFW_POINT(x, y) (RGFW_point){(i32)(x), (i32)(y)}
583#define RGFW_RECT(x, y, w, h) (RGFW_rect){(i32)(x), (i32)(y), (i32)(w), (i32)(h)}
584#define RGFW_AREA(w, h) (RGFW_area){(u32)(w), (u32)(h)}
587#ifndef RGFW_NO_MONITOR
615 RGFW_monitorAll = RGFW_monitorScale | RGFW_monitorRefresh | RGFW_monitorRGB
665typedef struct RGFW_window_src {
669 HICON hIconSmall, hIconBig;
670 #if (defined(RGFW_OPENGL)) && !defined(RGFW_EGL)
672 #elif defined(RGFW_EGL)
673 EGLSurface EGL_surface;
674 EGLDisplay EGL_display;
675 EGLContext EGL_context;
678 #if defined(RGFW_BUFFER)
685#elif defined(RGFW_UNIX)
686typedef struct RGFW_window_src {
690 #if (defined(RGFW_OPENGL)) && !defined(RGFW_EGL)
693 #elif defined(RGFW_EGL)
694 EGLSurface EGL_surface;
695 EGLDisplay EGL_display;
696 EGLContext EGL_context;
699 #if defined(RGFW_BUFFER)
704 #ifdef RGFW_ADVANCED_SMOOTH_RESIZE
710#if defined(RGFW_WAYLAND)
711 struct wl_display* wl_display;
712 struct wl_surface* surface;
713 struct wl_buffer* wl_buffer;
714 struct wl_keyboard* keyboard;
716 struct wl_compositor* compositor;
717 struct xdg_surface* xdg_surface;
718 struct xdg_toplevel* xdg_toplevel;
719 struct zxdg_toplevel_decoration_v1* decoration;
720 struct xdg_wm_base* xdg_wm_base;
722 struct wl_seat *seat;
724 #if defined(RGFW_EGL)
725 struct wl_egl_window* eglWindow;
727 #if defined(RGFW_EGL) && !defined(RGFW_X11)
728 EGLSurface EGL_surface;
729 EGLDisplay EGL_display;
730 EGLContext EGL_context;
735#if defined(RGFW_MACOS)
736typedef struct RGFW_window_src {
738#if (defined(RGFW_OPENGL)) && !defined(RGFW_EGL)
740#elif defined(RGFW_EGL)
741 EGLSurface EGL_surface;
742 EGLDisplay EGL_display;
743 EGLContext EGL_context;
748#if defined(RGFW_BUFFER)
751#elif defined(RGFW_WASM)
752typedef struct RGFW_window_src {
753 #if defined(RGFW_WEBGPU)
758 EMSCRIPTEN_WEBGL_CONTEXT_HANDLE ctx;
770 RGFW_windowFullscreen =
RGFW_BIT(5),
771 RGFW_windowTransparent =
RGFW_BIT(6),
773 RGFW_windowOpenglSoftware =
RGFW_BIT(8),
774 RGFW_windowCocoaCHDirToRes =
RGFW_BIT(9),
775 RGFW_windowScaleToMonitor =
RGFW_BIT(10),
778 RGFW_windowCenterCursor =
RGFW_BIT(13),
780 RGFW_windowFreeOnClose =
RGFW_BIT(15),
781 RGFW_windowFocusOnShow =
RGFW_BIT(16),
784 RGFW_windowedFullscreen = RGFW_windowNoBorder | RGFW_windowMaximize
790#if defined(RGFW_BUFFER)
831 RGFW_windowFlags flags
837 RGFW_windowFlags flags,
874 RGFW_eventNoWait = 0,
875 RGFW_eventWaitNext = -1
900#ifndef RGFW_NO_MONITOR
940#ifndef RGFW_NO_PASSTHROUGH
959 RGFW_iconBoth = RGFW_iconTaskbar | RGFW_iconWindow
1023#ifndef RGFW_NO_MONITOR
1074 RGFW_typeError = 0, RGFW_typeWarning, RGFW_typeInfo
1079 RGFW_errOpenglContext, RGFW_errEGLContext,
1080 RGFW_errWayland, RGFW_errX11,
1081 RGFW_errDirectXContext,
1084 RGFW_errFailedFuncLoad,
1086 RGFW_infoMonitor, RGFW_infoWindow, RGFW_infoBuffer, RGFW_infoGlobal, RGFW_infoOpenGL,
1087 RGFW_warningWayland, RGFW_warningOpenGL
1092#if defined(__cplusplus) && !defined(__APPLE__)
1093#define RGFW_DEBUG_CTX(win, err) {win, NULL, err}
1094#define RGFW_DEBUG_CTX_MON(monitor) {_RGFW->root, &monitor, 0}
1096#define RGFW_DEBUG_CTX(win, err) (RGFW_debugContext){win, NULL, err}
1097#define RGFW_DEBUG_CTX_MON(monitor) (RGFW_debugContext){_RGFW->root, &monitor, 0}
1195 RGFW_gamepadMicrosoft = 0, RGFW_gamepadSony, RGFW_gamepadNintendo, RGFW_gamepadLogitech, RGFW_gamepadUnknown
1234#if defined(RGFW_OPENGL) || defined(RGFW_EGL)
1246 RGFW_glDoubleBuffer,
1247 RGFW_glRed, RGFW_glGreen, RGFW_glBlue, RGFW_glAlpha,
1249 RGFW_glAccumRed, RGFW_glAccumGreen, RGFW_glAccumBlue,RGFW_glAccumAlpha,
1254 RGFW_glReleaseBehavior,
1256 RGFW_glMajor, RGFW_glMinor,
1257 RGFW_glFinalHint = 32,
1258 RGFW_releaseFlush = 0, RGFW_glReleaseNone,
1259 RGFW_glCore = 0, RGFW_glCompatibility
1271 #if defined(RGFW_WAYLAND) && defined(RGFW_X11)
1272 #define VK_USE_PLATFORM_WAYLAND_KHR
1273 #define VK_USE_PLATFORM_XLIB_KHR
1274 #define RGFW_VK_SURFACE ((RGFW_usingWayland()) ? ("VK_KHR_wayland_surface") : ("VK_KHR_xlib_surface"))
1275 #elif defined(RGFW_WAYLAND)
1276 #define VK_USE_PLATFORM_WAYLAND_KHR
1277 #define VK_USE_PLATFORM_XLIB_KHR
1278 #define RGFW_VK_SURFACE "VK_KHR_wayland_surface"
1279 #elif defined(RGFW_X11)
1280 #define VK_USE_PLATFORM_XLIB_KHR
1281 #define RGFW_VK_SURFACE "VK_KHR_xlib_surface"
1282 #elif defined(RGFW_WINDOWS)
1283 #define VK_USE_PLATFORM_WIN32_KHR
1285 #define RGFW_VK_SURFACE "VK_KHR_win32_surface"
1286 #elif defined(RGFW_MACOS) && !defined(RGFW_MACOS_X11)
1287 #define VK_USE_PLATFORM_MACOS_MVK
1288 #define RGFW_VK_SURFACE "VK_MVK_macos_surface"
1290 #define RGFW_VK_SURFACE NULL
1294RGFWDEF const char** RGFW_getVKRequiredInstanceExtensions(
size_t* count);
1296#include <vulkan/vulkan.h>
1298RGFWDEF VkResult RGFW_window_createVKSurface(
RGFW_window* win, VkInstance instance, VkSurfaceKHR* surface);
1299RGFWDEF RGFW_bool RGFW_getVKPresentationSupport(VkInstance instance, VkPhysicalDevice physicalDevice,
u32 queueFamilyIndex);
1309 #define __uuidof(T) IID_##T
1311RGFWDEF int RGFW_window_createDXSwapChain(
RGFW_window* win, IDXGIFactory* pFactory, IUnknown* pDevice, IDXGISwapChain** swapchain);
1327#define RGFW_MAX_EVENTS 32
1342#define RGFW_eventQueuePushEx(eventInit) { RGFW_event e; eventInit; RGFW_eventQueuePush(e); }
1350 RGFW_escape =
'\033',
1351 RGFW_backtick =
'`',
1365 RGFW_backSpace =
'\b',
1400 RGFW_closeBracket =
']',
1401 RGFW_semicolon =
';',
1402 RGFW_apostrophe =
'\'',
1403 RGFW_backSlash =
'\\',
1405 RGFW_enter = RGFW_return,
1407 RGFW_delete =
'\177',
1472 RGFW_mouseNormal = 0,
1475 RGFW_mouseCrosshair,
1476 RGFW_mousePointingHand,
1479 RGFW_mouseResizeNWSE,
1480 RGFW_mouseResizeNESW,
1481 RGFW_mouseResizeAll,
1482 RGFW_mouseNotAllowed,
1483 RGFW_mouseIconFinal = 16
1488#if defined(RGFW_X11) || defined(RGFW_WAYLAND)
1489 #define RGFW_OS_BASED_VALUE(l, w, m, h) l
1490#elif defined(RGFW_WINDOWS)
1491 #define RGFW_OS_BASED_VALUE(l, w, m, h) w
1492#elif defined(RGFW_MACOS)
1493 #define RGFW_OS_BASED_VALUE(l, w, m, h) m
1494#elif defined(RGFW_WASM)
1495 #define RGFW_OS_BASED_VALUE(l, w, m, h) h
1505struct __IOHIDDevice;
1507#if !defined(RGFW_NO_INFO) || defined(RGFW_IMPLEMENTATION)
1538 Window helperWindow;
1540 size_t clipboard_len;
1541 const char* instName;
1542 XErrorEvent* x11Error;
1545 struct wl_display* wl_display;
1546 struct xkb_context *xkb_context;
1547 struct xkb_keymap *keymap;
1548 struct xkb_state *xkb_state;
1549 struct zxdg_decoration_manager_v1 *decoration_manager;
1551 struct wl_cursor_theme* wl_cursor_theme;
1552 struct wl_surface* cursor_surface;
1553 struct wl_cursor_image* cursor_image;
1559 int eventWait_forceStop[3];
1564 struct __IOHIDDevice* osxControllers[4];
1575#ifdef RGFW_IMPLEMENTATION
1583#if !defined(RGFW_NO_X11) && defined(RGFW_WAYLAND)
1584#define RGFW_GOTO_WAYLAND(fallback) if (_RGFW->useWaylandBool && fallback == 0) goto wayland
1585#define RGFW_WAYLAND_LABEL wayland:;
1587#define RGFW_GOTO_WAYLAND(fallback)
1588#define RGFW_WAYLAND_LABEL
1591void RGFW_clipboard_switch(
char* newstr);
1592void RGFW_clipboard_switch(
char* newstr) {
1598#define RGFW_CHECK_CLIPBOARD() \
1599 if (size <= 0 && _RGFW->clipboard_data != NULL) \
1600 return (const char*)_RGFW->clipboard_data; \
1601 else if (size <= 0) \
1606 RGFW_CHECK_CLIPBOARD();
1613 RGFW_CHECK_CLIPBOARD();
1615 if (len != NULL) *len = (size_t)size;
1617 RGFW_clipboard_switch(str);
1618 return (
const char*)str;
1624 RGFW_debugCallback = func;
1625 return RGFW_debugCallbackPrev;
1633 if (RGFW_debugCallback) RGFW_debugCallback(type, err, ctx, msg);
1637 case RGFW_typeInfo: RGFW_PRINTF(
"RGFW INFO (%i %i): %s", type, err, msg);
break;
1638 case RGFW_typeError: RGFW_PRINTF(
"RGFW DEBUG (%i %i): %s", type, err, msg);
break;
1639 case RGFW_typeWarning: RGFW_PRINTF(
"RGFW WARNING (%i %i): %s", type, err, msg);
break;
1645 case RGFW_errBuffer:
case RGFW_infoBuffer: RGFW_PRINTF(
" buffer size: %i %i\n", ctx.
win->bufferSize.w, ctx.
win->bufferSize.h);
break;
1647 case RGFW_infoMonitor: RGFW_PRINTF(
": scale (%s):\n rect: {%i, %i, %i, %i}\n physical size:%f %f\n scale: %f %f\n pixelRatio: %f\n refreshRate: %i\n depth: %i\n", ctx.
monitor->
name, ctx.
monitor->
x, ctx.
monitor->
y, ctx.
monitor->
mode.
area.
w, ctx.
monitor->
mode.
area.
h, ctx.
monitor->
physW, ctx.
monitor->
physH, ctx.
monitor->
scaleX, ctx.
monitor->
scaleY, ctx.
monitor->
pixelRatio, ctx.
monitor->
mode.
refreshRate, ctx.
monitor->
mode.
red + ctx.
monitor->
mode.
green + ctx.
monitor->
mode.
blue);
break;
1648 case RGFW_infoWindow: RGFW_PRINTF(
" with rect of {%i, %i, %i, %i} \n", ctx.
win->
r.
x, ctx.
win->
r.
y,ctx. win->r.w, ctx.
win->
r.
h);
break;
1649 case RGFW_errDirectXContext: RGFW_PRINTF(
" srcError %i\n", ctx.
srcError);
break;
1650 default: RGFW_PRINTF(
"\n");
1685RGFW_keyState RGFW_gamepadPressed[3][32];
1686RGFW_keyState RGFW_mouseButtons[RGFW_mouseFinal];
1687RGFW_keyState RGFW_keyboard[RGFW_keyLast];
1689RGFWDEF void RGFW_resetKeyPrev(
void);
1690RGFWDEF void RGFW_resetKey(
void);
1692#ifndef RGFW_CUSTOM_BACKEND
1693RGFWDEF void RGFW_init_keys(
void);
1695void RGFW_init_keys(
void) {
1696 _RGFW->
keycodes[RGFW_OS_BASED_VALUE(49, 0x029, 50, DOM_VK_BACK_QUOTE)] = RGFW_backtick;
1697 _RGFW->
keycodes[RGFW_OS_BASED_VALUE(19, 0x00B, 29, DOM_VK_0)] = RGFW_0;
1698 _RGFW->
keycodes[RGFW_OS_BASED_VALUE(10, 0x002, 18, DOM_VK_1)] = RGFW_1;
1699 _RGFW->
keycodes[RGFW_OS_BASED_VALUE(11, 0x003, 19, DOM_VK_2)] = RGFW_2;
1700 _RGFW->
keycodes[RGFW_OS_BASED_VALUE(12, 0x004, 20, DOM_VK_3)] = RGFW_3;
1701 _RGFW->
keycodes[RGFW_OS_BASED_VALUE(13, 0x005, 21, DOM_VK_4)] = RGFW_4;
1702 _RGFW->
keycodes[RGFW_OS_BASED_VALUE(14, 0x006, 23, DOM_VK_5)] = RGFW_5;
1703 _RGFW->
keycodes[RGFW_OS_BASED_VALUE(15, 0x007, 22, DOM_VK_6)] = RGFW_6;
1704 _RGFW->
keycodes[RGFW_OS_BASED_VALUE(16, 0x008, 26, DOM_VK_7)] = RGFW_7;
1705 _RGFW->
keycodes[RGFW_OS_BASED_VALUE(17, 0x009, 28, DOM_VK_8)] = RGFW_8;
1706 _RGFW->
keycodes[RGFW_OS_BASED_VALUE(18, 0x00A, 25, DOM_VK_9)] = RGFW_9;
1707 _RGFW->
keycodes[RGFW_OS_BASED_VALUE(65, 0x039, 49, DOM_VK_SPACE)] = RGFW_space;
1708 _RGFW->
keycodes[RGFW_OS_BASED_VALUE(38, 0x01E, 0, DOM_VK_A)] = RGFW_a;
1709 _RGFW->
keycodes[RGFW_OS_BASED_VALUE(56, 0x030, 11, DOM_VK_B)] = RGFW_b;
1710 _RGFW->
keycodes[RGFW_OS_BASED_VALUE(54, 0x02E, 8, DOM_VK_C)] = RGFW_c;
1711 _RGFW->
keycodes[RGFW_OS_BASED_VALUE(40, 0x020, 2, DOM_VK_D)] = RGFW_d;
1712 _RGFW->
keycodes[RGFW_OS_BASED_VALUE(26, 0x012, 14, DOM_VK_E)] = RGFW_e;
1713 _RGFW->
keycodes[RGFW_OS_BASED_VALUE(41, 0x021, 3, DOM_VK_F)] = RGFW_f;
1714 _RGFW->
keycodes[RGFW_OS_BASED_VALUE(42, 0x022, 5, DOM_VK_G)] = RGFW_g;
1715 _RGFW->
keycodes[RGFW_OS_BASED_VALUE(43, 0x023, 4, DOM_VK_H)] = RGFW_h;
1716 _RGFW->
keycodes[RGFW_OS_BASED_VALUE(31, 0x017, 34, DOM_VK_I)] = RGFW_i;
1717 _RGFW->
keycodes[RGFW_OS_BASED_VALUE(44, 0x024, 38, DOM_VK_J)] = RGFW_j;
1718 _RGFW->
keycodes[RGFW_OS_BASED_VALUE(45, 0x025, 40, DOM_VK_K)] = RGFW_k;
1719 _RGFW->
keycodes[RGFW_OS_BASED_VALUE(46, 0x026, 37, DOM_VK_L)] = RGFW_l;
1720 _RGFW->
keycodes[RGFW_OS_BASED_VALUE(58, 0x032, 46, DOM_VK_M)] = RGFW_m;
1721 _RGFW->
keycodes[RGFW_OS_BASED_VALUE(57, 0x031, 45, DOM_VK_N)] = RGFW_n;
1722 _RGFW->
keycodes[RGFW_OS_BASED_VALUE(32, 0x018, 31, DOM_VK_O)] = RGFW_o;
1723 _RGFW->
keycodes[RGFW_OS_BASED_VALUE(33, 0x019, 35, DOM_VK_P)] = RGFW_p;
1724 _RGFW->
keycodes[RGFW_OS_BASED_VALUE(24, 0x010, 12, DOM_VK_Q)] = RGFW_q;
1725 _RGFW->
keycodes[RGFW_OS_BASED_VALUE(27, 0x013, 15, DOM_VK_R)] = RGFW_r;
1726 _RGFW->
keycodes[RGFW_OS_BASED_VALUE(39, 0x01F, 1, DOM_VK_S)] = RGFW_s;
1727 _RGFW->
keycodes[RGFW_OS_BASED_VALUE(28, 0x014, 17, DOM_VK_T)] = RGFW_t;
1728 _RGFW->
keycodes[RGFW_OS_BASED_VALUE(30, 0x016, 32, DOM_VK_U)] = RGFW_u;
1729 _RGFW->
keycodes[RGFW_OS_BASED_VALUE(55, 0x02F, 9, DOM_VK_V)] = RGFW_v;
1730 _RGFW->
keycodes[RGFW_OS_BASED_VALUE(25, 0x011, 13, DOM_VK_W)] = RGFW_w;
1731 _RGFW->
keycodes[RGFW_OS_BASED_VALUE(53, 0x02D, 7, DOM_VK_X)] = RGFW_x;
1732 _RGFW->
keycodes[RGFW_OS_BASED_VALUE(29, 0x015, 16, DOM_VK_Y)] = RGFW_y;
1733 _RGFW->
keycodes[RGFW_OS_BASED_VALUE(52, 0x02C, 6, DOM_VK_Z)] = RGFW_z;
1734 _RGFW->
keycodes[RGFW_OS_BASED_VALUE(60, 0x034, 47, DOM_VK_PERIOD)] = RGFW_period;
1735 _RGFW->
keycodes[RGFW_OS_BASED_VALUE(59, 0x033, 43, DOM_VK_COMMA)] = RGFW_comma;
1736 _RGFW->
keycodes[RGFW_OS_BASED_VALUE(61, 0x035, 44, DOM_VK_SLASH)] = RGFW_slash;
1737 _RGFW->
keycodes[RGFW_OS_BASED_VALUE(34, 0x01A, 33, DOM_VK_OPEN_BRACKET)] = RGFW_bracket;
1738 _RGFW->
keycodes[RGFW_OS_BASED_VALUE(35, 0x01B, 30, DOM_VK_CLOSE_BRACKET)] = RGFW_closeBracket;
1739 _RGFW->
keycodes[RGFW_OS_BASED_VALUE(47, 0x027, 41, DOM_VK_SEMICOLON)] = RGFW_semicolon;
1740 _RGFW->
keycodes[RGFW_OS_BASED_VALUE(48, 0x028, 39, DOM_VK_QUOTE)] = RGFW_apostrophe;
1741 _RGFW->
keycodes[RGFW_OS_BASED_VALUE(51, 0x02B, 42, DOM_VK_BACK_SLASH)] = RGFW_backSlash;
1742 _RGFW->
keycodes[RGFW_OS_BASED_VALUE(36, 0x01C, 36, DOM_VK_RETURN)] = RGFW_return;
1743 _RGFW->
keycodes[RGFW_OS_BASED_VALUE(119, 0x153, 118, DOM_VK_DELETE)] = RGFW_delete;
1744 _RGFW->
keycodes[RGFW_OS_BASED_VALUE(77, 0x145, 72, DOM_VK_NUM_LOCK)] = RGFW_numLock;
1745 _RGFW->
keycodes[RGFW_OS_BASED_VALUE(106, 0x135, 82, DOM_VK_DIVIDE)] = RGFW_KP_Slash;
1746 _RGFW->
keycodes[RGFW_OS_BASED_VALUE(63, 0x037, 76, DOM_VK_MULTIPLY)] = RGFW_multiply;
1747 _RGFW->
keycodes[RGFW_OS_BASED_VALUE(82, 0x04A, 67, DOM_VK_SUBTRACT)] = RGFW_KP_Minus;
1748 _RGFW->
keycodes[RGFW_OS_BASED_VALUE(87, 0x04F, 84, DOM_VK_NUMPAD1)] = RGFW_KP_1;
1749 _RGFW->
keycodes[RGFW_OS_BASED_VALUE(88, 0x050, 85, DOM_VK_NUMPAD2)] = RGFW_KP_2;
1750 _RGFW->
keycodes[RGFW_OS_BASED_VALUE(89, 0x051, 86, DOM_VK_NUMPAD3)] = RGFW_KP_3;
1751 _RGFW->
keycodes[RGFW_OS_BASED_VALUE(83, 0x04B, 87, DOM_VK_NUMPAD4)] = RGFW_KP_4;
1752 _RGFW->
keycodes[RGFW_OS_BASED_VALUE(84, 0x04C, 88, DOM_VK_NUMPAD5)] = RGFW_KP_5;
1753 _RGFW->
keycodes[RGFW_OS_BASED_VALUE(85, 0x04D, 89, DOM_VK_NUMPAD6)] = RGFW_KP_6;
1754 _RGFW->
keycodes[RGFW_OS_BASED_VALUE(79, 0x047, 90, DOM_VK_NUMPAD7)] = RGFW_KP_7;
1755 _RGFW->
keycodes[RGFW_OS_BASED_VALUE(80, 0x048, 92, DOM_VK_NUMPAD8)] = RGFW_KP_8;
1756 _RGFW->
keycodes[RGFW_OS_BASED_VALUE(81, 0x049, 93, DOM_VK_NUMPAD9)] = RGFW_KP_9;
1757 _RGFW->
keycodes[RGFW_OS_BASED_VALUE(90, 0x052, 83, DOM_VK_NUMPAD0)] = RGFW_KP_0;
1758 _RGFW->
keycodes[RGFW_OS_BASED_VALUE(91, 0x053, 65, DOM_VK_DECIMAL)] = RGFW_KP_Period;
1759 _RGFW->
keycodes[RGFW_OS_BASED_VALUE(104, 0x11C, 77, 0)] = RGFW_KP_Return;
1760 _RGFW->
keycodes[RGFW_OS_BASED_VALUE(20, 0x00C, 27, DOM_VK_HYPHEN_MINUS)] = RGFW_minus;
1761 _RGFW->
keycodes[RGFW_OS_BASED_VALUE(21, 0x00D, 24, DOM_VK_EQUALS)] = RGFW_equals;
1762 _RGFW->
keycodes[RGFW_OS_BASED_VALUE(22, 0x00E, 51, DOM_VK_BACK_SPACE)] = RGFW_backSpace;
1763 _RGFW->
keycodes[RGFW_OS_BASED_VALUE(23, 0x00F, 48, DOM_VK_TAB)] = RGFW_tab;
1764 _RGFW->
keycodes[RGFW_OS_BASED_VALUE(66, 0x03A, 57, DOM_VK_CAPS_LOCK)] = RGFW_capsLock;
1765 _RGFW->
keycodes[RGFW_OS_BASED_VALUE(50, 0x02A, 56, DOM_VK_SHIFT)] = RGFW_shiftL;
1766 _RGFW->
keycodes[RGFW_OS_BASED_VALUE(37, 0x01D, 59, DOM_VK_CONTROL)] = RGFW_controlL;
1767 _RGFW->
keycodes[RGFW_OS_BASED_VALUE(64, 0x038, 58, DOM_VK_ALT)] = RGFW_altL;
1768 _RGFW->
keycodes[RGFW_OS_BASED_VALUE(133, 0x15B, 55, DOM_VK_WIN)] = RGFW_superL;
1769 #if !defined(RGFW_MACOS) && !defined(RGFW_WASM)
1770 _RGFW->
keycodes[RGFW_OS_BASED_VALUE(105, 0x11D, 59, 0)] = RGFW_controlR;
1771 _RGFW->
keycodes[RGFW_OS_BASED_VALUE(134, 0x15C, 55, 0)] = RGFW_superR;
1772 _RGFW->
keycodes[RGFW_OS_BASED_VALUE(62, 0x036, 56, 0)] = RGFW_shiftR;
1773 _RGFW->
keycodes[RGFW_OS_BASED_VALUE(108, 0x138, 58, 0)] = RGFW_altR;
1775 _RGFW->
keycodes[RGFW_OS_BASED_VALUE(67, 0x03B, 127, DOM_VK_F1)] = RGFW_F1;
1776 _RGFW->
keycodes[RGFW_OS_BASED_VALUE(68, 0x03C, 121, DOM_VK_F2)] = RGFW_F2;
1777 _RGFW->
keycodes[RGFW_OS_BASED_VALUE(69, 0x03D, 100, DOM_VK_F3)] = RGFW_F3;
1778 _RGFW->
keycodes[RGFW_OS_BASED_VALUE(70, 0x03E, 119, DOM_VK_F4)] = RGFW_F4;
1779 _RGFW->
keycodes[RGFW_OS_BASED_VALUE(71, 0x03F, 97, DOM_VK_F5)] = RGFW_F5;
1780 _RGFW->
keycodes[RGFW_OS_BASED_VALUE(72, 0x040, 98, DOM_VK_F6)] = RGFW_F6;
1781 _RGFW->
keycodes[RGFW_OS_BASED_VALUE(73, 0x041, 99, DOM_VK_F7)] = RGFW_F7;
1782 _RGFW->
keycodes[RGFW_OS_BASED_VALUE(74, 0x042, 101, DOM_VK_F8)] = RGFW_F8;
1783 _RGFW->
keycodes[RGFW_OS_BASED_VALUE(75, 0x043, 102, DOM_VK_F9)] = RGFW_F9;
1784 _RGFW->
keycodes[RGFW_OS_BASED_VALUE(76, 0x044, 110, DOM_VK_F10)] = RGFW_F10;
1785 _RGFW->
keycodes[RGFW_OS_BASED_VALUE(95, 0x057, 104, DOM_VK_F11)] = RGFW_F11;
1786 _RGFW->
keycodes[RGFW_OS_BASED_VALUE(96, 0x058, 111, DOM_VK_F12)] = RGFW_F12;
1787 _RGFW->
keycodes[RGFW_OS_BASED_VALUE(111, 0x148, 126, DOM_VK_UP)] = RGFW_up;
1788 _RGFW->
keycodes[RGFW_OS_BASED_VALUE(116, 0x150, 125, DOM_VK_DOWN)] = RGFW_down;
1789 _RGFW->
keycodes[RGFW_OS_BASED_VALUE(113, 0x14B, 123, DOM_VK_LEFT)] = RGFW_left;
1790 _RGFW->
keycodes[RGFW_OS_BASED_VALUE(114, 0x14D, 124, DOM_VK_RIGHT)] = RGFW_right;
1791 _RGFW->
keycodes[RGFW_OS_BASED_VALUE(118, 0x152, 115, DOM_VK_INSERT)] = RGFW_insert;
1792 _RGFW->
keycodes[RGFW_OS_BASED_VALUE(115, 0x14F, 120, DOM_VK_END)] = RGFW_end;
1793 _RGFW->
keycodes[RGFW_OS_BASED_VALUE(112, 0x149, 117, DOM_VK_PAGE_UP)] = RGFW_pageUp;
1794 _RGFW->
keycodes[RGFW_OS_BASED_VALUE(117, 0x151, 122, DOM_VK_PAGE_DOWN)] = RGFW_pageDown;
1795 _RGFW->
keycodes[RGFW_OS_BASED_VALUE(9, 0x001, 53, DOM_VK_ESCAPE)] = RGFW_escape;
1796 _RGFW->
keycodes[RGFW_OS_BASED_VALUE(110, 0x147, 116, DOM_VK_HOME)] = RGFW_home;
1797 _RGFW->
keycodes[RGFW_OS_BASED_VALUE(78, 0x046, 107, DOM_VK_SCROLL_LOCK)] = RGFW_scrollLock;
1798 _RGFW->
keycodes[RGFW_OS_BASED_VALUE(107, 0x137, 105, DOM_VK_PRINTSCREEN)] = RGFW_printScreen;
1799 _RGFW->
keycodes[RGFW_OS_BASED_VALUE(128, 0x045, 113, DOM_VK_PAUSE)] = RGFW_pause;
1802 for (i = 0; i < RGFW_keyLast; i++) {
1803 for (y = 0; y <
sizeof(_RGFW->
keycodes); y++) {
1817 if (keycode >
sizeof(_RGFW->
keycodes) /
sizeof(
u8))
1832void RGFW_resetKeyPrev(
void) {
1834 for (i = 0; i < RGFW_keyLast; i++) RGFW_keyboard[i].prev = 0;
1836void RGFW_resetKey(
void) {
RGFW_MEMSET(RGFW_keyboard, 0,
sizeof(RGFW_keyboard)); }
1872#define RGFW_CALLBACK_DEFINE(x, x2) \
1873RGFW_##x##func RGFW_##x##Callback = RGFW_##x##funcEMPTY; \
1874RGFW_##x##func RGFW_set##x2##Callback(RGFW_##x##func func) { \
1875 RGFW_##x##func prev = RGFW_##x##Callback; \
1876 RGFW_##x##Callback = func; \
1879RGFW_CALLBACK_DEFINE(windowMaximized, WindowMaximized)
1880RGFW_CALLBACK_DEFINE(windowMinimized, WindowMinimized)
1881RGFW_CALLBACK_DEFINE(windowRestored, WindowRestored)
1882RGFW_CALLBACK_DEFINE(windowMoved, WindowMoved)
1883RGFW_CALLBACK_DEFINE(windowResized, WindowResized)
1884RGFW_CALLBACK_DEFINE(windowQuit, WindowQuit)
1885RGFW_CALLBACK_DEFINE(mousePos, MousePos)
1886RGFW_CALLBACK_DEFINE(windowRefresh, WindowRefresh)
1887RGFW_CALLBACK_DEFINE(focus, Focus)
1888RGFW_CALLBACK_DEFINE(mouseNotify, MouseNotify)
1889RGFW_CALLBACK_DEFINE(dnd, Dnd)
1890RGFW_CALLBACK_DEFINE(dndInit, DndInit)
1891RGFW_CALLBACK_DEFINE(key, Key)
1892RGFW_CALLBACK_DEFINE(mouseButton, MouseButton)
1893RGFW_CALLBACK_DEFINE(gamepadButton, GamepadButton)
1894RGFW_CALLBACK_DEFINE(gamepadAxis, GamepadAxis)
1895RGFW_CALLBACK_DEFINE(gamepad, Gamepad)
1896RGFW_CALLBACK_DEFINE(scaleUpdated, ScaleUpdated)
1897#undef RGFW_CALLBACK_DEFINE
1903 if (win->
event.
type == RGFW_quit)
return;
1914 win->
_flags |= RGFW_windowMinimize;
1915 RGFW_windowMinimizedCallback(win, win->
r);
1917 win->
_flags |= RGFW_windowMaximize;
1919 RGFW_windowMaximizedCallback(win, win->
r);
1922 win->
_flags &= ~(
u32)RGFW_windowMinimize;
1925 RGFW_windowRestoredCallback(win, win->
r);
1933#define SET_ATTRIB(a, v) { \
1934 RGFW_ASSERT(((size_t) index + 1) < sizeof(attribs) / sizeof(attribs[0])); \
1935 attribs[index++] = a; \
1936 attribs[index++] = v; \
1940#define RGFW_EVENT_QUIT RGFW_BIT(25)
1941#define RGFW_HOLD_MOUSE RGFW_BIT(26)
1942#define RGFW_MOUSE_LEFT RGFW_BIT(27)
1943#define RGFW_WINDOW_ALLOC RGFW_BIT(28)
1944#define RGFW_BUFFER_ALLOC RGFW_BIT(29)
1945#define RGFW_WINDOW_INIT RGFW_BIT(30)
1946#define RGFW_INTERNAL_FLAGS (RGFW_EVENT_QUIT | RGFW_HOLD_MOUSE | RGFW_MOUSE_LEFT | RGFW_WINDOW_ALLOC | RGFW_BUFFER_ALLOC | RGFW_windowFocus)
1951 win->
_flags = RGFW_WINDOW_ALLOC;
1955#if defined(RGFW_USE_XDL) && defined(RGFW_X11)
1956 #define XDL_IMPLEMENTATION
1960#ifndef RGFW_FORCE_INIT
1979i32 RGFW_initPlatform(
void);
1980void RGFW_deinitPlatform(
void);
1983 if (info == _RGFW || info == NULL)
return 1;
1998 i32 out = RGFW_initPlatform();
2004 if (info == NULL)
return;
2007 RGFW_deinitPlatform();
2024 if (_RGFW->
eventLen == 0)
return NULL;
2035 if (ev->
_win != win && ev->
_win != NULL) {
2050 RGFW_resetKeyPrev();
2052 if (win->
event.
type == RGFW_quit && win->
_flags & RGFW_windowFreeOnClose) {
2084 if (_RGFW->
root == NULL) {
2089 if (!(win->
_flags & RGFW_WINDOW_ALLOC)) win->
_flags = 0;
2112 RGFW_windowFlags cmpFlags = win->
_flags;
2113 if (win->
_flags & RGFW_WINDOW_INIT) cmpFlags = 0;
2115 #ifndef RGFW_NO_MONITOR
2120 if (flags & RGFW_windowCenterCursor)
2139 if (flags & RGFW_windowNoResize) {
2142 }
else if (cmpFlags & RGFW_windowNoResize) {
2147 win->
_flags = flags | (win->
_flags & RGFW_INTERNAL_FLAGS);
2164 if ((win->
_flags & RGFW_windowNoResize))
2171#if defined(RGFW_BUFFER)
2172 win->
_flags |= RGFW_BUFFER_ALLOC;
2173 #ifndef RGFW_WINDOWS
2188RGFWDEF void* RGFW_cocoaGetLayer(
void);
2237#if defined(RGFW_OPENGL) || defined(RGFW_EGL)
2249#if defined(RGFW_OPENGL) || defined(RGFW_EGL)
2258 else if (!value && (*(data) & bit))
2279 if (bpp == 32) bpp = 24;
2282 u32 delta = bpp - (mode->
red * 3);
2283 if (delta >= 1) mode->
green = mode->
green + 1;
2284 if (delta == 2) mode->
red = mode->
red + 1;
2288 return (((mon.
area.
w == mon2.
area.
w && mon.
area.
h == mon2.
area.
h) || !(request & RGFW_monitorScale)) &&
2299 win->
_flags |= RGFW_EVENT_QUIT;
2300 RGFW_windowQuitCallback(win);
2306#ifndef RGFW_NO_MONITOR
2331 if (!area.
w && !area.
h)
2334 win->
_flags |= RGFW_HOLD_MOUSE;
2335 RGFW_captureCursor(win, win->
r);
2341 RGFW_releaseCursor(win);
2346 if (deltaTime == 0)
return 0;
2348 double fps = (frameCount / deltaTime);
2349 if (fpsCap && fps > fpsCap) {
2350 double frameTime = (double)frameCount / (
double)fpsCap;
2351 double sleepTime = frameTime - deltaTime;
2359#if defined(RGFW_BUFFER)
2361 #if !defined(RGFW_BUFFER_BGR)
2363 for (y = 0; y < (
u32)win->
r.
h; y++) {
2364 for (x = 0; x < (
u32)win->
r.
w; x++) {
2365 u32 index = (y * 4 * win->bufferSize.w) + x * 4;
2367 u8 red = data[index];
2368 data[index] = win->buffer[index + 2];
2369 data[index + 2] = red;
2380 return RGFW_gamepadPressed[c][button].current;
2384 return RGFW_gamepadPressed[c][button].prev;
2422 RGFW_updateKeyMod(win, RGFW_modCapsLock, capital);
2423 RGFW_updateKeyMod(win, RGFW_modNumLock, numlock);
2424 RGFW_updateKeyMod(win, RGFW_modControl, control);
2425 RGFW_updateKeyMod(win, RGFW_modAlt, alt);
2426 RGFW_updateKeyMod(win, RGFW_modShift, shift);
2427 RGFW_updateKeyMod(win, RGFW_modSuper, super);
2428 RGFW_updateKeyMod(win, RGFW_modScrollLock, scroll);
2433 RGFW_updateKeyModsPro(win, capital, numlock,
2443 if (show && (win->
_flags & RGFW_windowHideMouse))
2444 win->
_flags ^= RGFW_windowHideMouse;
2445 else if (!show && !(win->
_flags & RGFW_windowHideMouse))
2446 win->
_flags |= RGFW_windowHideMouse;
2463 if ((win->
_flags & RGFW_windowFullscreen))
2467 for (key = 0; key < RGFW_keyLast; key++) {
2474 e.keyChar = keyChar;
2485 RGFW_setBit(&win->
_flags, RGFW_windowAllowDND, allow);
2489#if defined(RGFW_X11) || defined(RGFW_MACOS) || defined(RGFW_WASM) || defined(RGFW_WAYLAND)
2490#ifndef __USE_POSIX199309
2491 #define __USE_POSIX199309
2497#if defined(RGFW_WAYLAND) || defined(RGFW_X11) || defined(RGFW_WINDOWS)
2499 RGFW_window_showMouseFlags(win, show);
2521#if defined(RGFW_OPENGL) || defined(RGFW_EGL)
2524 #define WIN32_LEAN_AND_MEAN
2526 #include <windows.h>
2529#if !defined(__APPLE__) && !defined(RGFW_NO_GL_HEADER)
2531#elif defined(__APPLE__)
2532 #ifndef GL_SILENCE_DEPRECATION
2533 #define GL_SILENCE_DEPRECATION
2535 #include <OpenGL/gl.h>
2536 #include <OpenGL/OpenGL.h>
2541i32 RGFW_GL_HINTS[RGFW_glFinalHint] = {8,
2543i32 RGFW_GL_HINTS[RGFW_glFinalHint] = {0,
2545 0, 0, 0, 1, 8, 8, 8, 8, 24, 0, 0, 0, 0, 0, 0, 0, 0, RGFW_glReleaseNone, RGFW_glCore, 0, 0};
2548 if (hint < RGFW_glFinalHint && hint) RGFW_GL_HINTS[hint] = value;
2551RGFW_bool RGFW_extensionSupportedStr(
const char* extensions,
const char* ext,
size_t len) {
2552 const char *start = extensions;
2554 const char* terminator;
2556 if (extensions == NULL || ext == NULL)
2561 terminator = where + len;
2562 if ((where == start || *(where - 1) ==
' ') &&
2563 (*terminator ==
' ' || *terminator ==
'\0')) {
2573 #ifdef GL_NUM_EXTENSIONS
2574 if (RGFW_GL_HINTS[RGFW_glMajor] >= 3) {
2580 if (RGFW_glGetIntegerv)
2581 ((void(*)(GLenum, GLint*))RGFW_glGetIntegerv)(GL_NUM_EXTENSIONS, &count);
2583 for (i = 0; RGFW_glGetStringi && i < count; i++) {
2584 const char* en = ((
const char* (*)(
u32,
u32))RGFW_glGetStringi)(GL_EXTENSIONS, (
u32)i);
2593 if (RGFW_glGetString) {
2594 const char* extensions = ((
const char*(*)(
u32))RGFW_glGetString)(GL_EXTENSIONS);
2595 if ((extensions != NULL) && RGFW_extensionSupportedStr(extensions, extension, len))
2604#if defined(RGFW_OPENGL) && !defined(RGFW_EGL) && !defined(RGFW_CUSTOM_BACKEND) && !defined(RGFW_WASM)
2606#define RGFW_GL_RENDER_TYPE RGFW_OS_BASED_VALUE(GLX_X_VISUAL_TYPE, 0x2003, 73, 0)
2607 #define RGFW_GL_ALPHA_SIZE RGFW_OS_BASED_VALUE(GLX_ALPHA_SIZE, 0x201b, 11, 0)
2608 #define RGFW_GL_DEPTH_SIZE RGFW_OS_BASED_VALUE(GLX_DEPTH_SIZE, 0x2022, 12, 0)
2609 #define RGFW_GL_DOUBLEBUFFER RGFW_OS_BASED_VALUE(GLX_DOUBLEBUFFER, 0x2011, 5, 0)
2610 #define RGFW_GL_STENCIL_SIZE RGFW_OS_BASED_VALUE(GLX_STENCIL_SIZE, 0x2023, 13, 0)
2611 #define RGFW_GL_SAMPLES RGFW_OS_BASED_VALUE(GLX_SAMPLES, 0x2042, 55, 0)
2612 #define RGFW_GL_STEREO RGFW_OS_BASED_VALUE(GLX_STEREO, 0x2012, 6, 0)
2613 #define RGFW_GL_AUX_BUFFERS RGFW_OS_BASED_VALUE(GLX_AUX_BUFFERS, 0x2024, 7, 0)
2615#if defined(RGFW_X11) || defined(RGFW_WINDOWS)
2616 #define RGFW_GL_DRAW RGFW_OS_BASED_VALUE(GLX_X_RENDERABLE, 0x2001, 0, 0)
2617 #define RGFW_GL_DRAW_TYPE RGFW_OS_BASED_VALUE(GLX_RENDER_TYPE, 0x2013, 0, 0)
2618 #define RGFW_GL_FULL_FORMAT RGFW_OS_BASED_VALUE(GLX_TRUE_COLOR, 0x2027, 0, 0)
2619 #define RGFW_GL_RED_SIZE RGFW_OS_BASED_VALUE(GLX_RED_SIZE, 0x2015, 0, 0)
2620 #define RGFW_GL_GREEN_SIZE RGFW_OS_BASED_VALUE(GLX_GREEN_SIZE, 0x2017, 0, 0)
2621 #define RGFW_GL_BLUE_SIZE RGFW_OS_BASED_VALUE(GLX_BLUE_SIZE, 0x2019, 0, 0)
2622 #define RGFW_GL_USE_RGBA RGFW_OS_BASED_VALUE(GLX_RGBA_BIT, 0x202B, 0, 0)
2623 #define RGFW_GL_ACCUM_RED_SIZE RGFW_OS_BASED_VALUE(14, 0x201E, 0, 0)
2624 #define RGFW_GL_ACCUM_GREEN_SIZE RGFW_OS_BASED_VALUE(15, 0x201F, 0, 0)
2625 #define RGFW_GL_ACCUM_BLUE_SIZE RGFW_OS_BASED_VALUE(16, 0x2020, 0, 0)
2626 #define RGFW_GL_ACCUM_ALPHA_SIZE RGFW_OS_BASED_VALUE(17, 0x2021, 0, 0)
2627 #define RGFW_GL_SRGB RGFW_OS_BASED_VALUE(0x20b2, 0x3089, 0, 0)
2628 #define RGFW_GL_NOERROR RGFW_OS_BASED_VALUE(0x31b3, 0x31b3, 0, 0)
2629 #define RGFW_GL_FLAGS RGFW_OS_BASED_VALUE(GLX_CONTEXT_FLAGS_ARB, 0x2094, 0, 0)
2630 #define RGFW_GL_RELEASE_BEHAVIOR RGFW_OS_BASED_VALUE(GLX_CONTEXT_RELEASE_BEHAVIOR_ARB, 0x2097 , 0, 0)
2631 #define RGFW_GL_CONTEXT_RELEASE RGFW_OS_BASED_VALUE(GLX_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB, 0x2098, 0, 0)
2632 #define RGFW_GL_CONTEXT_NONE RGFW_OS_BASED_VALUE(GLX_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB, 0x0000, 0, 0)
2633 #define RGFW_GL_FLAGS RGFW_OS_BASED_VALUE(GLX_CONTEXT_FLAGS_ARB, 0x2094, 0, 0)
2634 #define RGFW_GL_DEBUG_BIT RGFW_OS_BASED_VALUE(GLX_CONTEXT_FLAGS_ARB, 0x2094, 0, 0)
2635 #define RGFW_GL_ROBUST_BIT RGFW_OS_BASED_VALUE(GLX_CONTEXT_ROBUST_ACCESS_BIT_ARB, 0x00000004, 0, 0)
2639 #define WGL_SUPPORT_OPENGL_ARB 0x2010
2640 #define WGL_COLOR_BITS_ARB 0x2014
2641 #define WGL_NUMBER_PIXEL_FORMATS_ARB 0x2000
2642 #define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091
2643 #define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092
2644 #define WGL_CONTEXT_PROFILE_MASK_ARB 0x9126
2645 #define WGL_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001
2646 #define WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002
2647 #define WGL_SAMPLE_BUFFERS_ARB 0x2041
2648 #define WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB 0x20a9
2649 #define WGL_PIXEL_TYPE_ARB 0x2013
2650 #define WGL_TYPE_RGBA_ARB 0x202B
2652 #define WGL_TRANSPARENT_ARB 0x200A
2659i32* RGFW_initFormatAttribs(
void);
2660i32* RGFW_initFormatAttribs(
void) {
2661 static i32 attribs[] = {
2662 #if defined(RGFW_X11) || defined(RGFW_WINDOWS)
2663 RGFW_GL_RENDER_TYPE,
2664 RGFW_GL_FULL_FORMAT,
2666 RGFW_GL_DRAW_TYPE , RGFW_GL_USE_RGBA,
2670 GLX_DRAWABLE_TYPE , GLX_WINDOW_BIT,
2679 WGL_SUPPORT_OPENGL_ARB, 1,
2680 WGL_PIXEL_TYPE_ARB, WGL_TYPE_RGBA_ARB,
2681 WGL_COLOR_BITS_ARB, 32,
2683 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
2686 size_t index = (
sizeof(attribs) /
sizeof(attribs[0])) - 27;
2688 #define RGFW_GL_ADD_ATTRIB(attrib, attVal) \
2690 attribs[index] = attrib;\
2691 attribs[index + 1] = attVal;\
2695 #if defined(RGFW_MACOS) && defined(RGFW_COCOA_GRAPHICS_SWITCHING)
2696 RGFW_GL_ADD_ATTRIB(96, kCGLPFASupportsAutomaticGraphicsSwitching);
2699 RGFW_GL_ADD_ATTRIB(RGFW_GL_DOUBLEBUFFER, 1);
2701 RGFW_GL_ADD_ATTRIB(RGFW_GL_ALPHA_SIZE, RGFW_GL_HINTS[RGFW_glAlpha]);
2702 RGFW_GL_ADD_ATTRIB(RGFW_GL_DEPTH_SIZE, RGFW_GL_HINTS[RGFW_glDepth]);
2703 RGFW_GL_ADD_ATTRIB(RGFW_GL_STENCIL_SIZE, RGFW_GL_HINTS[RGFW_glStencil]);
2704 RGFW_GL_ADD_ATTRIB(RGFW_GL_STEREO, RGFW_GL_HINTS[RGFW_glStereo]);
2705 RGFW_GL_ADD_ATTRIB(RGFW_GL_AUX_BUFFERS, RGFW_GL_HINTS[RGFW_glAuxBuffers]);
2707 #if defined(RGFW_X11) || defined(RGFW_WINDOWS)
2708 RGFW_GL_ADD_ATTRIB(RGFW_GL_RED_SIZE, RGFW_GL_HINTS[RGFW_glRed]);
2709 RGFW_GL_ADD_ATTRIB(RGFW_GL_GREEN_SIZE, RGFW_GL_HINTS[RGFW_glBlue]);
2710 RGFW_GL_ADD_ATTRIB(RGFW_GL_BLUE_SIZE, RGFW_GL_HINTS[RGFW_glGreen]);
2713 #if defined(RGFW_X11) || defined(RGFW_WINDOWS)
2714 RGFW_GL_ADD_ATTRIB(RGFW_GL_ACCUM_RED_SIZE, RGFW_GL_HINTS[RGFW_glAccumRed]);
2715 RGFW_GL_ADD_ATTRIB(RGFW_GL_ACCUM_GREEN_SIZE, RGFW_GL_HINTS[RGFW_glAccumBlue]);
2716 RGFW_GL_ADD_ATTRIB(RGFW_GL_ACCUM_BLUE_SIZE, RGFW_GL_HINTS[RGFW_glAccumGreen]);
2717 RGFW_GL_ADD_ATTRIB(RGFW_GL_ACCUM_ALPHA_SIZE, RGFW_GL_HINTS[RGFW_glAccumAlpha]);
2718 RGFW_GL_ADD_ATTRIB(RGFW_GL_SRGB, RGFW_GL_HINTS[RGFW_glSRGB]);
2719 RGFW_GL_ADD_ATTRIB(RGFW_GL_NOERROR, RGFW_GL_HINTS[RGFW_glNoError]);
2721 if (RGFW_GL_HINTS[RGFW_glReleaseBehavior] == RGFW_releaseFlush) {
2722 RGFW_GL_ADD_ATTRIB(RGFW_GL_RELEASE_BEHAVIOR, RGFW_GL_CONTEXT_RELEASE);
2723 }
else if (RGFW_GL_HINTS[RGFW_glReleaseBehavior] == RGFW_glReleaseNone) {
2724 RGFW_GL_ADD_ATTRIB(RGFW_GL_RELEASE_BEHAVIOR, RGFW_GL_CONTEXT_NONE);
2728 if (RGFW_GL_HINTS[RGFW_glDebug]) flags |= RGFW_GL_DEBUG_BIT;
2729 if (RGFW_GL_HINTS[RGFW_glRobustness]) flags |= RGFW_GL_ROBUST_BIT;
2730 RGFW_GL_ADD_ATTRIB(RGFW_GL_FLAGS, flags);
2732 i32 accumSize = (
i32)(RGFW_GL_HINTS[RGFW_glAccumRed] + RGFW_GL_HINTS[RGFW_glAccumGreen] + RGFW_GL_HINTS[RGFW_glAccumBlue] + RGFW_GL_HINTS[RGFW_glAccumAlpha]) / 4;
2733 RGFW_GL_ADD_ATTRIB(14, accumSize);
2737 RGFW_GL_ADD_ATTRIB(RGFW_GL_SAMPLES, RGFW_GL_HINTS[RGFW_glSamples]);
2741 if (_RGFW->
root->
_flags & RGFW_windowOpenglSoftware) {
2742 RGFW_GL_ADD_ATTRIB(70, kCGLRendererGenericFloatID);
2744 attribs[index] = RGFW_GL_RENDER_TYPE;
2753 attribs[index] = 99;
2754 attribs[index + 1] = 0x1000;
2757 if (RGFW_GL_HINTS[RGFW_glMajor] >= 4 || RGFW_GL_HINTS[RGFW_glMajor] >= 3) {
2758 attribs[index + 1] = (
i32) ((RGFW_GL_HINTS[RGFW_glMajor] >= 4) ? 0x4100 : 0x3200);
2762 RGFW_GL_ADD_ATTRIB(0, 0);
2768#elif defined(RGFW_EGL)
2772#if defined(RGFW_LINK_EGL)
2773 typedef EGLBoolean(EGLAPIENTRY* PFN_eglInitialize)(EGLDisplay, EGLint*, EGLint*);
2775 PFNEGLINITIALIZEPROC eglInitializeSource;
2776 PFNEGLGETCONFIGSPROC eglGetConfigsSource;
2777 PFNEGLCHOOSECONFIgamepadROC eglChooseConfigSource;
2778 PFNEGLCREATEWINDOWSURFACEPROC eglCreateWindowSurfaceSource;
2779 PFNEGLCREATECONTEXTPROC eglCreateContextSource;
2780 PFNEGLMAKECURRENTPROC eglMakeCurrentSource;
2781 PFNEGLGETDISPLAYPROC eglGetDisplaySource;
2782 PFNEGLSWAPBUFFERSPROC eglSwapBuffersSource;
2783 PFNEGLSWAPINTERVALPROC eglSwapIntervalSource;
2784 PFNEGLBINDAPIPROC eglBindAPISource;
2785 PFNEGLDESTROYCONTEXTPROC eglDestroyContextSource;
2786 PFNEGLTERMINATEPROC eglTerminateSource;
2787 PFNEGLDESTROYSURFACEPROC eglDestroySurfaceSource;
2789 #define eglInitialize eglInitializeSource
2790 #define eglGetConfigs eglGetConfigsSource
2791 #define eglChooseConfig eglChooseConfigSource
2792 #define eglCreateWindowSurface eglCreateWindowSurfaceSource
2793 #define eglCreateContext eglCreateContextSource
2794 #define eglMakeCurrent eglMakeCurrentSource
2795 #define eglGetDisplay eglGetDisplaySource
2796 #define eglSwapBuffers eglSwapBuffersSource
2797 #define eglSwapInterval eglSwapIntervalSource
2798 #define eglBindAPI eglBindAPISource
2799 #define eglDestroyContext eglDestroyContextSource
2800 #define eglTerminate eglTerminateSource
2801 #define eglDestroySurface eglDestroySurfaceSource;
2805#define EGL_SURFACE_MAJOR_VERSION_KHR 0x3098
2806#define EGL_SURFACE_MINOR_VERSION_KHR 0x30fb
2808#ifndef RGFW_GL_ADD_ATTRIB
2809#define RGFW_GL_ADD_ATTRIB(attrib, attVal) \
2811 attribs[index] = attrib;\
2812 attribs[index + 1] = attVal;\
2819#if defined(RGFW_LINK_EGL)
2820 eglInitializeSource = (PFNEGLINITIALIZEPROC) eglGetProcAddress(
"eglInitialize");
2821 eglGetConfigsSource = (PFNEGLGETCONFIGSPROC) eglGetProcAddress(
"eglGetConfigs");
2822 eglChooseConfigSource = (PFNEGLCHOOSECONFIgamepadROC) eglGetProcAddress(
"eglChooseConfig");
2823 eglCreateWindowSurfaceSource = (PFNEGLCREATEWINDOWSURFACEPROC) eglGetProcAddress(
"eglCreateWindowSurface");
2824 eglCreateContextSource = (PFNEGLCREATECONTEXTPROC) eglGetProcAddress(
"eglCreateContext");
2825 eglMakeCurrentSource = (PFNEGLMAKECURRENTPROC) eglGetProcAddress(
"eglMakeCurrent");
2826 eglGetDisplaySource = (PFNEGLGETDISPLAYPROC) eglGetProcAddress(
"eglGetDisplay");
2827 eglSwapBuffersSource = (PFNEGLSWAPBUFFERSPROC) eglGetProcAddress(
"eglSwapBuffers");
2828 eglSwapIntervalSource = (PFNEGLSWAPINTERVALPROC) eglGetProcAddress(
"eglSwapInterval");
2829 eglBindAPISource = (PFNEGLBINDAPIPROC) eglGetProcAddress(
"eglBindAPI");
2830 eglDestroyContextSource = (PFNEGLDESTROYCONTEXTPROC) eglGetProcAddress(
"eglDestroyContext");
2831 eglTerminateSource = (PFNEGLTERMINATEPROC) eglGetProcAddress(
"eglTerminate");
2832 eglDestroySurfaceSource = (PFNEGLDESTROYSURFACEPROC) eglGetProcAddress(
"eglDestroySurface");
2835 eglGetConfigsSource != NULL &&
2836 eglChooseConfigSource != NULL &&
2837 eglCreateWindowSurfaceSource != NULL &&
2838 eglCreateContextSource != NULL &&
2839 eglMakeCurrentSource != NULL &&
2840 eglGetDisplaySource != NULL &&
2841 eglSwapBuffersSource != NULL &&
2842 eglSwapIntervalsSource != NULL &&
2843 eglBindAPISource != NULL &&
2844 eglDestroyContextSource != NULL &&
2845 eglTerminateSource != NULL &&
2846 eglDestroySurfaceSource != NULL);
2851 win->
src.eglWindow = wl_egl_window_create(win->
src.surface, win->
r.
w, win->
r.
h);
2855 win->
src.EGL_display = eglGetDisplay((EGLNativeDisplayType) win->
src.hdc);
2856 #elif defined(RGFW_MACOS)
2857 win->
src.EGL_display = eglGetDisplay((EGLNativeDisplayType)0);
2858 #elif defined(RGFW_WAYLAND)
2860 win->
src.EGL_display = eglGetDisplay((EGLNativeDisplayType) win->
src.wl_display);
2864 win->
src.EGL_display = eglGetDisplay((EGLNativeDisplayType) win->
src.display);
2868 #if !defined(RGFW_WAYLAND) && !defined(RGFW_WINDOWS) && !defined(RGFW_X11)
2869 win->
src.EGL_display = eglGetDisplay((EGLNativeDisplayType) win->
src.display);
2872 EGLint major, minor;
2874 eglInitialize(win->
src.EGL_display, &major, &minor);
2876 #ifndef EGL_OPENGL_ES1_BIT
2877 #define EGL_OPENGL_ES1_BIT 0x1
2880 EGLint egl_config[24] = {
2881 EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
2882 EGL_RENDERABLE_TYPE,
2883 #ifdef RGFW_OPENGL_ES1
2885 #elif defined(RGFW_OPENGL_ES3)
2887 #elif defined(RGFW_OPENGL_ES2)
2897 EGLint* attribs = egl_config;
2899 RGFW_GL_ADD_ATTRIB(EGL_RED_SIZE, RGFW_GL_HINTS[RGFW_glRed]);
2900 RGFW_GL_ADD_ATTRIB(EGL_GREEN_SIZE, RGFW_GL_HINTS[RGFW_glBlue]);
2901 RGFW_GL_ADD_ATTRIB(EGL_BLUE_SIZE, RGFW_GL_HINTS[RGFW_glGreen]);
2902 RGFW_GL_ADD_ATTRIB(EGL_ALPHA_SIZE, RGFW_GL_HINTS[RGFW_glAlpha]);
2903 RGFW_GL_ADD_ATTRIB(EGL_DEPTH_SIZE, RGFW_GL_HINTS[RGFW_glDepth]);
2905 if (RGFW_GL_HINTS[RGFW_glSRGB])
2906 RGFW_GL_ADD_ATTRIB(0x3089, RGFW_GL_HINTS[RGFW_glSRGB]);
2908 RGFW_GL_ADD_ATTRIB(EGL_NONE, EGL_NONE);
2913 eglChooseConfig(win->
src.EGL_display, egl_config, &config, 1, &numConfigs);
2915 #if defined(RGFW_MACOS)
2916 void* layer = RGFW_cocoaGetLayer();
2918 RGFW_window_cocoaSetLayer(win, layer);
2920 win->
src.EGL_surface = eglCreateWindowSurface(win->
src.EGL_display, config, (EGLNativeWindowType) layer, NULL);
2921 #elif defined(RGFW_WINDOWS)
2922 win->
src.EGL_surface = eglCreateWindowSurface(win->
src.EGL_display, config, (EGLNativeWindowType) win->
src.window, NULL);
2923 #elif defined(RGFW_WAYLAND)
2925 win->
src.EGL_surface = eglCreateWindowSurface(win->
src.EGL_display, config, (EGLNativeWindowType) win->
src.eglWindow, NULL);
2929 win->
src.EGL_surface = eglCreateWindowSurface(win->
src.EGL_display, config, (EGLNativeWindowType) win->
src.window, NULL);
2933 #if !defined(RGFW_X11) && !defined(RGFW_WAYLAND) && !defined(RGFW_MACOS)
2934 win->
src.EGL_surface = eglCreateWindowSurface(win->
src.EGL_display, config, (EGLNativeWindowType) win->
src.window, NULL);
2940#ifdef RGFW_OPENGL_ES1
2941 RGFW_GL_ADD_ATTRIB(EGL_CONTEXT_CLIENT_VERSION, 1);
2942#elif defined(RGFW_OPENGL_ES2)
2943 RGFW_GL_ADD_ATTRIB(EGL_CONTEXT_CLIENT_VERSION, 2);
2944#elif defined(RGFW_OPENGL_ES3)
2945 RGFW_GL_ADD_ATTRIB(EGL_CONTEXT_CLIENT_VERSION, 3);
2948 RGFW_GL_ADD_ATTRIB(EGL_STENCIL_SIZE, RGFW_GL_HINTS[RGFW_glStencil]);
2949 RGFW_GL_ADD_ATTRIB(EGL_SAMPLES, RGFW_GL_HINTS[RGFW_glSamples]);
2951 if (RGFW_GL_HINTS[RGFW_glDoubleBuffer] == 0)
2952 RGFW_GL_ADD_ATTRIB(EGL_RENDER_BUFFER, EGL_SINGLE_BUFFER);
2954 if (RGFW_GL_HINTS[RGFW_glMajor]) {
2955 RGFW_GL_ADD_ATTRIB(EGL_CONTEXT_MAJOR_VERSION, RGFW_GL_HINTS[RGFW_glMajor]);
2956 RGFW_GL_ADD_ATTRIB(EGL_CONTEXT_MINOR_VERSION, RGFW_GL_HINTS[RGFW_glMinor]);
2958 if (RGFW_GL_HINTS[RGFW_glProfile] == RGFW_glCore) {
2959 RGFW_GL_ADD_ATTRIB(EGL_CONTEXT_OPENGL_PROFILE_MASK, EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT);
2962 RGFW_GL_ADD_ATTRIB(EGL_CONTEXT_OPENGL_PROFILE_MASK, EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT);
2966 RGFW_GL_ADD_ATTRIB(EGL_CONTEXT_OPENGL_ROBUST_ACCESS, RGFW_GL_HINTS[RGFW_glRobustness]);
2967 RGFW_GL_ADD_ATTRIB(EGL_CONTEXT_OPENGL_DEBUG, RGFW_GL_HINTS[RGFW_glDebug]);
2968 if (RGFW_GL_HINTS[RGFW_glReleaseBehavior] == RGFW_releaseFlush) {
2969 RGFW_GL_ADD_ATTRIB(0x2097, 0x2098);
2971 RGFW_GL_ADD_ATTRIB(0x2096, 0x0000);
2974 RGFW_GL_ADD_ATTRIB(EGL_NONE, EGL_NONE);
2976 #if defined(RGFW_OPENGL_ES1) || defined(RGFW_OPENGL_ES2) || defined(RGFW_OPENGL_ES3)
2977 eglBindAPI(EGL_OPENGL_ES_API);
2979 eglBindAPI(EGL_OPENGL_API);
2982 win->
src.EGL_context = eglCreateContext(win->
src.EGL_display, config, EGL_NO_CONTEXT, attribs);
2984 if (win->
src.EGL_context == NULL) {
2989 eglMakeCurrent(win->
src.EGL_display, win->
src.EGL_surface, win->
src.EGL_surface, win->
src.EGL_context);
2990 eglSwapBuffers(win->
src.EGL_display, win->
src.EGL_surface);
2995 if (win->
src.EGL_display == NULL)
return;
2997 eglDestroySurface(win->
src.EGL_display, win->
src.EGL_surface);
2998 eglDestroyContext(win->
src.EGL_display, win->
src.EGL_context);
2999 eglTerminate(win->
src.EGL_display);
3000 win->
src.EGL_display = NULL;
3006 eglMakeCurrent(_RGFW->
root->
src.EGL_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
3008 eglMakeCurrent(win->
src.EGL_display, win->
src.EGL_surface, win->
src.EGL_surface, win->
src.EGL_context);
3016#if defined(RGFW_WINDOWS)
3017HMODULE RGFW_wgl_dll = NULL;
3021 #if defined(RGFW_WINDOWS)
3028 return (
RGFW_proc) eglGetProcAddress(procname);
3032 const char* extensions = eglQueryString(_RGFW->
root->
src.EGL_display, EGL_EXTENSIONS);
3033 return extensions != NULL && RGFW_extensionSupportedStr(extensions, extension, len);
3039 eglSwapInterval(win->
src.EGL_display, swapInterval);
3055#include <objc/message.h>
3058const char** RGFW_getVKRequiredInstanceExtensions(
size_t* count) {
3059 static const char* arr[2] = {VK_KHR_SURFACE_EXTENSION_NAME};
3060 arr[1] = RGFW_VK_SURFACE;
3061 if (count != NULL) *count = 2;
3063 return (
const char**)arr;
3066VkResult RGFW_window_createVKSurface(
RGFW_window* win, VkInstance instance, VkSurfaceKHR* surface) {
3070 *surface = VK_NULL_HANDLE;
3073 RGFW_GOTO_WAYLAND(0);
3074 VkXlibSurfaceCreateInfoKHR x11 = { VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR, 0, 0, (Display*) win->
src.display, (Window) win->
src.window };
3075 return vkCreateXlibSurfaceKHR(instance, &x11, NULL, surface);
3077#if defined(RGFW_WAYLAND)
3079 VkWaylandSurfaceCreateInfoKHR wayland = { VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR, 0, 0, (
struct wl_display*) win->
src.wl_display, (
struct wl_surface*) win->
src.surface };
3080 return vkCreateWaylandSurfaceKHR(instance, &wayland, NULL, surface);
3081#elif defined(RGFW_WINDOWS)
3082 VkWin32SurfaceCreateInfoKHR win32 = { VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR, 0, 0, GetModuleHandle(NULL), (HWND)win->
src.window };
3084 return vkCreateWin32SurfaceKHR(instance, &win32, NULL, surface);
3085#elif defined(RGFW_MACOS) && !defined(RGFW_MACOS_X11)
3086 void* contentView = ((
void* (*)(
id,
SEL))objc_msgSend)((id)win->
src.window, sel_getUid(
"contentView"));
3087 VkMacOSSurfaceCreateFlagsMVK macos = { VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK, 0, 0, win->
src.display, (
void*)contentView };
3089 return vkCreateMacOSSurfaceMVK(instance, &macos, NULL, surface);
3094RGFW_bool RGFW_getVKPresentationSupport(VkInstance instance, VkPhysicalDevice physicalDevice,
u32 queueFamilyIndex) {
3098 RGFW_GOTO_WAYLAND(0);
3099 Visual* visual = DefaultVisual(_RGFW->display, DefaultScreen(_RGFW->display));
3101 visual = _RGFW->
root->
src.visual.visual;
3103 RGFW_bool out = vkGetPhysicalDeviceXlibPresentationSupportKHR(physicalDevice, queueFamilyIndex, _RGFW->display,
XVisualIDFromVisual(visual));
3106#if defined(RGFW_WAYLAND)
3108 RGFW_bool wlout = vkGetPhysicalDeviceWaylandPresentationSupportKHR(physicalDevice, queueFamilyIndex, _RGFW->wl_display);
3110#elif defined(RGFW_WINDOWS)
3111#elif defined(RGFW_MACOS) && !defined(RGFW_MACOS_X11)
3122#if (defined(RGFW_WAYLAND) || defined(RGFW_X11)) && !defined(RGFW_NO_LINUX)
3123 #if defined(__linux__)
3124 #include <linux/joystick.h>
3132 static const char* str[] = {
"/dev/input/js0",
"/dev/input/js1",
"/dev/input/js2",
"/dev/input/js3",
"/dev/input/js4",
"/dev/input/js5"};
3133 static u8 RGFW_rawGamepads[6];
3136 for (i = 0; i < 6; i++) {
3138 if (RGFW_rawGamepads[i]) {
3139 struct input_id device_info;
3140 if (ioctl(RGFW_rawGamepads[i], EVIOCGID, &device_info) == -2) {
3141 if (errno == ENODEV) {
3142 RGFW_rawGamepads[i] = 0;
3148 i32 js = open(str[i], O_RDONLY);
3158 RGFW_rawGamepads[i] = 1;
3161 if (ioctl(js, JSIOCGAXES, &axes) < 0 || ioctl(js, JSIOCGBUTTONS, &buttons) < 0) {
3166 if (buttons <= 5 || buttons >= 30) {
3179 for (j = 0; j < 16; j++) {
3180 RGFW_gamepadPressed[index][j].prev = 0;
3181 RGFW_gamepadPressed[index][j].current = 0;
3184 win->
event.
type = RGFW_gamepadConnected;
3197 RGFW_gamepadCallback(win, index, 1);
3210 i32 flags = fcntl(_RGFW->
gamepads[i], F_GETFL, 0);
3211 fcntl(_RGFW->
gamepads[i], F_SETFL, flags | O_NONBLOCK);
3214 while ((bytes = read(_RGFW->
gamepads[i], &e,
sizeof(e))) > 0) {
3216 case JS_EVENT_BUTTON: {
3217 size_t typeIndex = 0;
3218 if (_RGFW->
gamepads_type[i] == RGFW_gamepadMicrosoft) typeIndex = 1;
3219 else if (_RGFW->
gamepads_type[i] == RGFW_gamepadLogitech) typeIndex = 2;
3221 win->
event.
type = e.value ? RGFW_gamepadButtonPressed : RGFW_gamepadButtonReleased;
3222 u8 RGFW_linux2RGFW[3][RGFW_gamepadR3 + 8] = {{
3223 RGFW_gamepadA, RGFW_gamepadB, RGFW_gamepadY, RGFW_gamepadX, RGFW_gamepadL1, RGFW_gamepadR1, RGFW_gamepadL2, RGFW_gamepadR2,
3224 RGFW_gamepadSelect, RGFW_gamepadStart, RGFW_gamepadHome, RGFW_gamepadL3, RGFW_gamepadR3, RGFW_gamepadUp, RGFW_gamepadDown, RGFW_gamepadLeft, RGFW_gamepadRight,
3226 RGFW_gamepadA, RGFW_gamepadB, RGFW_gamepadX, RGFW_gamepadY, RGFW_gamepadL1, RGFW_gamepadR1, RGFW_gamepadSelect, RGFW_gamepadStart,
3227 RGFW_gamepadHome, RGFW_gamepadL3, RGFW_gamepadR3, 255, 255, RGFW_gamepadUp, RGFW_gamepadDown, RGFW_gamepadLeft, RGFW_gamepadRight
3229 RGFW_gamepadA, RGFW_gamepadB, RGFW_gamepadX, RGFW_gamepadY, RGFW_gamepadL1, RGFW_gamepadR1, RGFW_gamepadL2, RGFW_gamepadR2,
3230 RGFW_gamepadSelect, RGFW_gamepadStart, RGFW_gamepadHome, RGFW_gamepadL3, RGFW_gamepadR3, RGFW_gamepadUp, RGFW_gamepadDown, RGFW_gamepadLeft, RGFW_gamepadRight
3234 win->
event.
button = RGFW_linux2RGFW[typeIndex][e.number];
3244 case JS_EVENT_AXIS: {
3245 size_t axis = e.number / 2;
3246 if (axis == 2) axis = 1;
3252 if (e.number == 0 || e.number == 3)
3254 else if (e.number == 1 || e.number == 4) {
3269 if (bytes == -1 && errno == ENODEV) {
3274 win->
event.
type = RGFW_gamepadDisconnected;
3276 RGFW_gamepadCallback(win, i, 0);
3315#include <sys/mman.h>
3316#include <xkbcommon/xkbcommon.h>
3317#include <xkbcommon/xkbcommon-keysyms.h>
3319#include <linux/kd.h>
3320#include <wayland-cursor.h>
3325#include "xdg-shell.h"
3326#include "xdg-decoration-unstable-v1.h"
3328void RGFW_wl_xdg_wm_base_ping_handler(
void *data,
3329 struct xdg_wm_base *wm_base, uint32_t serial)
3332 xdg_wm_base_pong(wm_base, serial);
3335void RGFW_wl_xdg_surface_configure_handler(
void *data,
3336 struct xdg_surface *xdg_surface, uint32_t serial)
3339 xdg_surface_ack_configure(xdg_surface, serial);
3340 _RGFW->wl_configured = 1;
3343void RGFW_wl_xdg_toplevel_configure_handler(
void *data,
3344 struct xdg_toplevel *toplevel, int32_t width, int32_t height,
3345 struct wl_array *states)
3347 if (!_RGFW->wl_configured)
return;
3356 if (width <= 0 || height <= 0) {
3357 width = win->
src.r.w;
3358 height = win->
src.r.h;
3361 RGFW_window_checkMode(win);
3362 if (width != win->
src.r.w || height != win->
src.r.h) {
3366 RGFW_windowResizedCallback(win, win->
r);
3374void RGFW_wl_xdg_toplevel_close_handler(
void *data,
3375 struct xdg_toplevel *toplevel)
3383 RGFW_windowQuitCallback(win);
3386void RGFW_wl_shm_format_handler(
void *data,
3387 struct wl_shm *shm, uint32_t format)
3394void RGFW_wl_pointer_enter(
void *data,
struct wl_pointer *pointer, uint32_t serial,
struct wl_surface *surface, wl_fixed_t surface_x, wl_fixed_t surface_y) {
3397 RGFW_mouse_win = win;
3400 e.point =
RGFW_POINT(wl_fixed_to_double(surface_x), wl_fixed_to_double(surface_y));
3405void RGFW_wl_pointer_leave(
void *data,
struct wl_pointer *pointer, uint32_t serial,
struct wl_surface *surface) {
3408 if (RGFW_mouse_win == win)
3409 RGFW_mouse_win = NULL;
3417void RGFW_wl_pointer_motion(
void *data,
struct wl_pointer *pointer, uint32_t time, wl_fixed_t x, wl_fixed_t y) {
3422 e.point =
RGFW_POINT(wl_fixed_to_double(x), wl_fixed_to_double(y));
3423 e._win = RGFW_mouse_win);
3425 RGFW_mousePosCallback(RGFW_mouse_win,
RGFW_POINT(wl_fixed_to_double(x), wl_fixed_to_double(y)), RGFW_mouse_win->
event.
vector);
3427void RGFW_wl_pointer_button(
void *data,
struct wl_pointer *pointer, uint32_t serial, uint32_t time, uint32_t button, uint32_t state) {
3431 u32 b = (button - 0x110);
3435 else if (b == 2) b = 1;
3437 RGFW_mouseButtons[b].prev = RGFW_mouseButtons[b].current;
3438 RGFW_mouseButtons[b].current =
RGFW_BOOL(state);
3443 e._win = RGFW_mouse_win);
3444 RGFW_mouseButtonCallback(RGFW_mouse_win, (
u8)b, 0,
RGFW_BOOL(state));
3446void RGFW_wl_pointer_axis(
void *data,
struct wl_pointer *pointer, uint32_t time, uint32_t axis, wl_fixed_t value) {
3450 double scroll = - wl_fixed_to_double(value);
3454 e.button = RGFW_mouseScrollUp + (scroll < 0);
3456 e._win = RGFW_mouse_win);
3458 RGFW_mouseButtonCallback(RGFW_mouse_win, RGFW_mouseScrollUp + (scroll < 0), scroll, 1);
3461void RGFW_doNothing(
void) { }
3463void RGFW_wl_keyboard_keymap (
void *data,
struct wl_keyboard *keyboard, uint32_t format, int32_t fd, uint32_t size) {
3466 char *keymap_string = mmap (NULL, size, PROT_READ, MAP_SHARED, fd, 0);
3467 xkb_keymap_unref (_RGFW->keymap);
3468 _RGFW->keymap = xkb_keymap_new_from_string (_RGFW->xkb_context, keymap_string, XKB_KEYMAP_FORMAT_TEXT_V1, XKB_KEYMAP_COMPILE_NO_FLAGS);
3470 munmap (keymap_string, size);
3472 xkb_state_unref (_RGFW->xkb_state);
3473 _RGFW->xkb_state = xkb_state_new (_RGFW->keymap);
3475void RGFW_wl_keyboard_enter (
void *data,
struct wl_keyboard *keyboard, uint32_t serial,
struct wl_surface *surface,
struct wl_array *keys) {
3478 RGFW_key_win = (
RGFW_window*)wl_surface_get_user_data(surface);
3480 RGFW_key_win->
_flags |= RGFW_windowFocus;
3482 RGFW_focusCallback(RGFW_key_win,
RGFW_TRUE);
3486void RGFW_wl_keyboard_leave (
void *data,
struct wl_keyboard *keyboard, uint32_t serial,
struct wl_surface *surface) {
3490 if (RGFW_key_win == win)
3491 RGFW_key_win = NULL;
3495 RGFW_window_focusLost(win);
3497void RGFW_wl_keyboard_key (
void *data,
struct wl_keyboard *keyboard, uint32_t serial, uint32_t time, uint32_t key, uint32_t state) {
3500 if (RGFW_key_win == NULL)
return;
3502 xkb_keysym_t keysym = xkb_state_key_get_one_sym(_RGFW->xkb_state, key + 8);
3505 RGFW_keyboard[RGFWkey].prev = RGFW_keyboard[RGFWkey].current;
3506 RGFW_keyboard[RGFWkey].current =
RGFW_BOOL(state);
3509 e.key = (
u8)RGFWkey;
3510 e.keyChar = (
u8)keysym;
3512 e._win = RGFW_key_win);
3514 RGFW_updateKeyMods(RGFW_key_win,
RGFW_BOOL(xkb_keymap_mod_get_index(_RGFW->keymap,
"Lock")),
RGFW_BOOL(xkb_keymap_mod_get_index(_RGFW->keymap,
"Mod2")),
RGFW_BOOL(xkb_keymap_mod_get_index(_RGFW->keymap,
"ScrollLock")));
3517void RGFW_wl_keyboard_modifiers (
void *data,
struct wl_keyboard *keyboard, uint32_t serial, uint32_t mods_depressed, uint32_t mods_latched, uint32_t mods_locked, uint32_t group) {
3519 xkb_state_update_mask (_RGFW->xkb_state, mods_depressed, mods_latched, mods_locked, 0, 0, group);
3521void RGFW_wl_seat_capabilities (
void *data,
struct wl_seat *seat, uint32_t capabilities) {
3523 static struct wl_pointer_listener pointer_listener = {&RGFW_wl_pointer_enter, &RGFW_wl_pointer_leave, &RGFW_wl_pointer_motion, &RGFW_wl_pointer_button, &RGFW_wl_pointer_axis, (void (*)(
void *,
struct wl_pointer *))&RGFW_doNothing, (void (*)(
void *,
struct wl_pointer *, uint32_t))&RGFW_doNothing, (void (*)(
void *,
struct wl_pointer *, uint32_t, uint32_t))&RGFW_doNothing, (void (*)(
void *,
struct wl_pointer *, uint32_t, int32_t))&RGFW_doNothing, (void (*)(
void *,
struct wl_pointer *, uint32_t, int32_t))&RGFW_doNothing, (void (*)(
void*,
struct wl_pointer*, uint32_t, uint32_t))&RGFW_doNothing};
3525 static struct wl_keyboard_listener keyboard_listener = {&RGFW_wl_keyboard_keymap, &RGFW_wl_keyboard_enter, &RGFW_wl_keyboard_leave, &RGFW_wl_keyboard_key, &RGFW_wl_keyboard_modifiers, (void (*)(
void *,
struct wl_keyboard *,
3526 int, int))&RGFW_doNothing};
3528 if (capabilities & WL_SEAT_CAPABILITY_POINTER) {
3529 struct wl_pointer *pointer = wl_seat_get_pointer (seat);
3530 wl_pointer_add_listener (pointer, &pointer_listener, NULL);
3532 if (capabilities & WL_SEAT_CAPABILITY_KEYBOARD) {
3533 struct wl_keyboard *keyboard = wl_seat_get_keyboard (seat);
3534 wl_keyboard_add_listener (keyboard, &keyboard_listener, NULL);
3538void RGFW_wl_global_registry_handler(
void *data,
3539 struct wl_registry *registry, uint32_t
id,
const char *interface,
3542 static struct wl_seat_listener seat_listener = {&RGFW_wl_seat_capabilities, (void (*)(
void *,
struct wl_seat *,
const char *))&RGFW_doNothing};
3543 static const struct wl_shm_listener shm_listener = { .format = RGFW_wl_shm_format_handler };
3548 if (
RGFW_STRNCMP(interface,
"wl_compositor", 16) == 0) {
3549 win->
src.compositor = wl_registry_bind(registry,
3550 id, &wl_compositor_interface, 4);
3551 }
else if (
RGFW_STRNCMP(interface,
"xdg_wm_base", 12) == 0) {
3552 win->
src.xdg_wm_base = wl_registry_bind(registry,
3553 id, &xdg_wm_base_interface, 1);
3554 }
else if (
RGFW_STRNCMP(interface, zxdg_decoration_manager_v1_interface.name, 255) == 0) {
3555 _RGFW->decoration_manager = wl_registry_bind(registry,
id, &zxdg_decoration_manager_v1_interface, 1);
3556 }
else if (
RGFW_STRNCMP(interface,
"wl_shm", 7) == 0) {
3557 win->
src.shm = wl_registry_bind(registry,
3558 id, &wl_shm_interface, 1);
3559 wl_shm_add_listener(win->
src.shm, &shm_listener, NULL);
3560 }
else if (
RGFW_STRNCMP(interface,
"wl_seat", 8) == 0) {
3561 win->
src.seat = wl_registry_bind(registry,
id, &wl_seat_interface, 1);
3562 wl_seat_add_listener(win->
src.seat, &seat_listener, NULL);
3568void RGFW_wl_randname(
char *buf) {
3570 clock_gettime(CLOCK_REALTIME, &ts);
3571 long r = ts.tv_nsec;
3574 for (i = 0; i < 6; ++i) {
3575 buf[i] = (char)(
'A'+(r&15)+(r&16)*2);
3580size_t RGFW_wl_stringlen(
char* name) {
3582 while (name[i]) { i++; }
3586int RGFW_wl_anonymous_shm_open(
void) {
3587 char name[] =
"/RGFW-wayland-XXXXXX";
3591 RGFW_wl_randname(name + RGFW_wl_stringlen(name) - 6);
3595 int fd = shm_open(name, O_RDWR | O_CREAT | O_EXCL, 0600);
3600 }
while (retries > 0 && errno == EEXIST);
3605int RGFW_wl_create_shm_file(off_t size) {
3606 int fd = RGFW_wl_anonymous_shm_open();
3611 if (ftruncate(fd, size) < 0) {
3619void RGFW_wl_surface_frame_done(
void *data,
struct wl_callback *cb, uint32_t time) {
3624 wl_surface_attach(win->
src.surface, win->
src.wl_buffer, 0, 0);
3625 wl_surface_damage_buffer(win->
src.surface, 0, 0, win->
r.
w, win->
r.
h);
3626 wl_surface_commit(win->
src.surface);
3644#if !defined(RGFW_NO_X11_CURSOR) && defined(RGFW_X11)
3645#include <X11/Xcursor/Xcursor.h>
3650#include <X11/extensions/Xrandr.h>
3651#include <X11/Xresource.h>
3654#include <X11/Xatom.h>
3655#include <X11/keysymdef.h>
3656#include <X11/extensions/sync.h>
3659#include <X11/XKBlib.h>
3660#include <X11/cursorfont.h>
3661#include <X11/extensions/shapeconst.h>
3662#include <X11/extensions/shape.h>
3663#include <X11/extensions/XInput2.h>
3669#if defined(RGFW_X11) && !defined(RGFW_NO_X11_CURSOR) && !defined(RGFW_NO_X11_CURSOR_PRELOAD)
3670 typedef XcursorImage* (*PFN_XcursorImageCreate)(int, int);
3671 typedef void (*PFN_XcursorImageDestroy)(XcursorImage*);
3672 typedef Cursor(*PFN_XcursorImageLoadCursor)(Display*,
const XcursorImage*);
3674#if defined(RGFW_OPENGL) && defined(RGFW_X11)
3675 typedef GLXContext(*glXCreateContextAttribsARBProc)(Display*, GLXFBConfig, GLXContext, Bool,
const int*);
3678#if !defined(RGFW_NO_X11_XI_PRELOAD) && defined(RGFW_X11)
3679 typedef int (* PFN_XISelectEvents)(Display*,Window,XIEventMask*,int);
3680 PFN_XISelectEvents XISelectEventsSRC = NULL;
3681 #define XISelectEvents XISelectEventsSRC
3683 void* X11Xihandle = NULL;
3686#if !defined(RGFW_NO_X11_EXT_PRELOAD) && defined(RGFW_X11)
3687 typedef void (* PFN_XSyncIntToValue)(XSyncValue*, int);
3688 PFN_XSyncIntToValue XSyncIntToValueSRC = NULL;
3689 #define XSyncIntToValue XSyncIntToValueSRC
3691 typedef Status (* PFN_XSyncSetCounter)(Display*, XSyncCounter, XSyncValue);
3692 PFN_XSyncSetCounter XSyncSetCounterSRC = NULL;
3693 #define XSyncSetCounter XSyncSetCounterSRC
3695 typedef XSyncCounter (* PFN_XSyncCreateCounter)(Display*, XSyncValue);
3696 PFN_XSyncCreateCounter XSyncCreateCounterSRC = NULL;
3697 #define XSyncCreateCounter XSyncCreateCounterSRC
3699 typedef void (* PFN_XShapeCombineMask)(Display*,Window,int,int,int,Pixmap,int);
3700 PFN_XShapeCombineMask XShapeCombineMaskSRC;
3701 #define XShapeCombineMask XShapeCombineMaskSRC
3703 typedef void (* PFN_XShapeCombineRegion)(Display*,Window,int,int,int,Region,int);
3704 PFN_XShapeCombineRegion XShapeCombineRegionSRC;
3705 #define XShapeCombineRegion XShapeCombineRegionSRC
3706 void* X11XEXThandle = NULL;
3709#if !defined(RGFW_NO_X11_CURSOR) && !defined(RGFW_NO_X11_CURSOR_PRELOAD) && defined(RGFW_X11)
3710 PFN_XcursorImageLoadCursor XcursorImageLoadCursorSRC = NULL;
3711 PFN_XcursorImageCreate XcursorImageCreateSRC = NULL;
3712 PFN_XcursorImageDestroy XcursorImageDestroySRC = NULL;
3714 #define XcursorImageLoadCursor XcursorImageLoadCursorSRC
3715 #define XcursorImageCreate XcursorImageCreateSRC
3716 #define XcursorImageDestroy XcursorImageDestroySRC
3718 void* X11Cursorhandle = NULL;
3725#if defined(RGFW_OPENGL) && !defined(RGFW_EGL)
3728 return (extensions != NULL) && RGFW_extensionSupportedStr(extensions, extension, len);
3735#if defined(RGFW_BUFFER)
3736 win->buffer = (
u8*)buffer;
3737 win->bufferSize = area;
3741 RGFW_GOTO_WAYLAND(0);
3744 win->
src.display, win->
src.visual.visual, (
u32)win->
src.visual.depth,
3745 ZPixmap, 0, NULL, area.
w, area.
h, 32, 0
3749 RGFW_WAYLAND_LABEL {}
3750 u32 size = (
u32)(area.
w * area.
h * 4);
3751 int fd = RGFW_wl_create_shm_file(size);
3757 win->
src.buffer = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
3758 if (win->
src.buffer == MAP_FAILED) {
3764 win->
_flags |= RGFW_BUFFER_ALLOC;
3766 struct wl_shm_pool* pool = wl_shm_create_pool(win->
src.shm, fd, (
i32)size);
3767 win->
src.wl_buffer = wl_shm_pool_create_buffer(pool, 0, win->
r.
w, win->
r.
h, win->
r.
w * 4,
3768 WL_SHM_FORMAT_ARGB8888);
3769 wl_shm_pool_destroy(pool);
3773 wl_surface_attach(win->
src.surface, win->
src.wl_buffer, 0, 0);
3774 wl_surface_commit(win->
src.surface);
3776 u8 color[] = {0x00, 0x00, 0x00, 0xFF};
3779 for (i = 0; i < area.
w * area.
h * 4; i += 4) {
3789#define RGFW_LOAD_ATOM(name) \
3790 static Atom name = 0; \
3791 if (name == 0) name = XInternAtom(_RGFW->display, #name, False);
3794 RGFW_setBit(&win->
_flags, RGFW_windowNoBorder, !border);
3796 RGFW_GOTO_WAYLAND(0);
3798 RGFW_LOAD_ATOM(_MOTIF_WM_HINTS);
3800 struct __x11WindowHints {
3801 unsigned long flags, functions, decorations, status;
3805 hints.decorations = border;
3808 PropModeReplace, (
u8*)&hints, 5
3824RGFW_GOTO_WAYLAND(0);
3829 unsigned char mask[] = { 0 };
3831 em.deviceid = XIAllMasterDevices;
3832 em.mask_len =
sizeof(mask);
3844RGFW_GOTO_WAYLAND(0);
3847 unsigned char mask[XIMaskLen(XI_RawMotion)] = { 0 };
3848 XISetMask(mask, XI_RawMotion);
3851 em.deviceid = XIAllMasterDevices;
3852 em.mask_len =
sizeof(mask);
3857 XGrabPointer(win->
src.display, win->
src.window, True, PointerMotionMask, GrabModeAsync, GrabModeAsync, None, None, CurrentTime);
3866#define RGFW_LOAD_LIBRARY(x, lib) if (x == NULL) x = dlopen(lib, RTLD_LAZY | RTLD_LOCAL)
3867#define RGFW_PROC_DEF(proc, name) if (name##SRC == NULL && proc != NULL) { \
3868 void* ptr = dlsym(proc, #name); \
3869 if (ptr != NULL) RGFW_MEMCPY(&name##SRC, &ptr, sizeof(PFN_##name)); \
3874#if defined(RGFW_OPENGL) && !defined(RGFW_EGL)
3875 i32* visual_attribs = RGFW_initFormatAttribs();
3877 GLXFBConfig* fbc =
glXChooseFBConfig(win->
src.display, DefaultScreen(win->
src.display), visual_attribs, &fbcount);
3881 i32 best_samples = 0;
3889 for (i = 0; i < fbcount; i++) {
3894 i32 samp_buf, samples;
3898 if (best_fbc == -1) best_fbc = i;
3899 if ((!(win->
_flags & RGFW_windowTransparent) || vi->depth == 32) && best_depth == 0) {
3901 best_depth = vi->depth;
3903 if ((!(win->
_flags & RGFW_windowTransparent) || vi->depth == 32) && samples <= RGFW_GL_HINTS[RGFW_glSamples] && samples > best_samples) {
3905 best_depth = vi->depth;
3906 best_samples = samples;
3911 if (best_fbc == -1) {
3916 win->
src.bestFbc = fbc[best_fbc];
3918 if (vi->depth != 32 && (win->
_flags & RGFW_windowTransparent))
3921 if (best_samples < RGFW_GL_HINTS[RGFW_glSamples])
3926 configCaveat == GLX_SLOW_CONFIG) {
3927 win->
_flags |= RGFW_windowOpenglSoftware;
3931 win->
src.visual = *vi;
3934 win->
src.visual.visual = DefaultVisual(win->
src.display, DefaultScreen(win->
src.display));
3935 win->
src.visual.depth = DefaultDepth(win->
src.display, DefaultScreen(win->
src.display));
3936 if (win->
_flags & RGFW_windowTransparent) {
3938 if (win->
src.visual.depth != 32)
3947 i32 context_attribs[7] = { 0, 0, 0, 0, 0, 0, 0 };
3948 context_attribs[0] = GLX_CONTEXT_PROFILE_MASK_ARB;
3949 if (RGFW_GL_HINTS[RGFW_glProfile] == RGFW_glCore)
3950 context_attribs[1] = GLX_CONTEXT_CORE_PROFILE_BIT_ARB;
3952 context_attribs[1] = GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB;
3954 if (RGFW_GL_HINTS[RGFW_glMinor] || RGFW_GL_HINTS[RGFW_glMajor]) {
3955 context_attribs[2] = GLX_CONTEXT_MAJOR_VERSION_ARB;
3956 context_attribs[3] = RGFW_GL_HINTS[RGFW_glMajor];
3957 context_attribs[4] = GLX_CONTEXT_MINOR_VERSION_ARB;
3958 context_attribs[5] = RGFW_GL_HINTS[RGFW_glMinor];
3961 glXCreateContextAttribsARBProc glXCreateContextAttribsARB = 0;
3962 glXCreateContextAttribsARB = (glXCreateContextAttribsARBProc)
3965 GLXContext ctx = NULL;
3966 if (_RGFW->
root != NULL && _RGFW->
root != win) {
3971 if (glXCreateContextAttribsARB == NULL) {
3972 RGFW_sendDebugInfo(RGFW_typeError, RGFW_errOpenglContext,
RGFW_DEBUG_CTX(win, 0),
"failed to load proc address 'glXCreateContextAttribsARB', loading a generic opengl context");
3976 _RGFW->x11Error = NULL;
3977 win->
src.ctx = glXCreateContextAttribsARB(win->
src.display, win->
src.bestFbc, ctx, True, context_attribs);
3978 if (_RGFW->x11Error || win->
src.ctx == NULL) {
3979 RGFW_sendDebugInfo(RGFW_typeError, RGFW_errOpenglContext,
RGFW_DEBUG_CTX(win, 0),
"failed to create an opengl context with AttribsARB, loading a generic opengl context");
3993 if (win->
src.ctx == NULL)
return;
3995 win->
src.ctx = NULL;
4003static int RGFW_XErrorHandler(Display* display, XErrorEvent* ev) {
4004 char errorText[512];
4005 XGetErrorText(display, ev->error_code, errorText,
sizeof(errorText));
4008 RGFW_SNPRINTF(buf,
sizeof(buf),
"[X Error] %s\n Error code: %d\n Request code: %d\n Minor code: %d\n Serial: %lu\n",
4010 ev->error_code, ev->request_code, ev->minor_code, ev->serial);
4013 _RGFW->x11Error = ev;
4018i32 RGFW_initPlatform(
void) {
4019 RGFW_GOTO_WAYLAND(1);
4026 #if !defined(RGFW_NO_X11_CURSOR) && !defined(RGFW_NO_X11_CURSOR_PRELOAD)
4027 #if defined(__CYGWIN__)
4028 RGFW_LOAD_LIBRARY(X11Cursorhandle,
"libXcursor-1.so");
4029 #elif defined(__OpenBSD__) || defined(__NetBSD__)
4030 RGFW_LOAD_LIBRARY(X11Cursorhandle,
"libXcursor.so");
4032 RGFW_LOAD_LIBRARY(X11Cursorhandle,
"libXcursor.so.1");
4034 RGFW_PROC_DEF(X11Cursorhandle, XcursorImageCreate);
4035 RGFW_PROC_DEF(X11Cursorhandle, XcursorImageDestroy);
4036 RGFW_PROC_DEF(X11Cursorhandle, XcursorImageLoadCursor);
4039 #if !defined(RGFW_NO_X11_XI_PRELOAD)
4040 #if defined(__CYGWIN__)
4041 RGFW_LOAD_LIBRARY(X11Xihandle,
"libXi-6.so");
4042 #elif defined(__OpenBSD__) || defined(__NetBSD__)
4043 RGFW_LOAD_LIBRARY(X11Xihandle,
"libXi.so");
4045 RGFW_LOAD_LIBRARY(X11Xihandle,
"libXi.so.6");
4047 RGFW_PROC_DEF(X11Xihandle, XISelectEvents);
4050 #if !defined(RGFW_NO_X11_EXT_PRELOAD)
4051 #if defined(__CYGWIN__)
4052 RGFW_LOAD_LIBRARY(X11XEXThandle,
"libXext-6.so");
4053 #elif defined(__OpenBSD__) || defined(__NetBSD__)
4054 RGFW_LOAD_LIBRARY(X11XEXThandle,
"libXext.so");
4056 RGFW_LOAD_LIBRARY(X11XEXThandle,
"libXext.so.6");
4058 RGFW_PROC_DEF(X11XEXThandle, XSyncCreateCounter);
4059 RGFW_PROC_DEF(X11XEXThandle, XSyncIntToValue);
4060 RGFW_PROC_DEF(X11XEXThandle, XSyncSetCounter);
4061 RGFW_PROC_DEF(X11XEXThandle, XShapeCombineRegion);
4062 RGFW_PROC_DEF(X11XEXThandle, XShapeCombineMask);
4067 XSetWindowAttributes wa;
4069 wa.event_mask = PropertyChangeMask;
4071 InputOnly, DefaultVisual(_RGFW->display, DefaultScreen(_RGFW->display)), CWEventMask, &wa);
4073 u8 RGFW_blk[] = { 0, 0, 0, 0 };
4075 _RGFW->clipboard = NULL;
4077 XkbComponentNamesRec rec;
4078 XkbDescPtr desc =
XkbGetMap(_RGFW->display, 0, XkbUseCoreKbd);
4082 XkbGetNames(_RGFW->display, XkbKeyNamesMask, desc);
4085 rec.keycodes = (
char*)
"evdev";
4086 evdesc =
XkbGetKeyboardByName(_RGFW->display, XkbUseCoreKbd, &rec, XkbGBN_KeyNamesMask, XkbGBN_KeyNamesMask, False);
4088 if(evdesc != NULL && desc != NULL){
4090 for(i = 0; i < (int)
sizeof(old); i++){
4094 for(i = evdesc->min_key_code; i <= evdesc->max_key_code; i++){
4095 for(j = desc->min_key_code; j <= desc->max_key_code; j++){
4096 if(
RGFW_STRNCMP(evdesc->names->keys[i].name, desc->names->keys[j].name, XkbKeyNameLength) == 0){
4111 _RGFW->wl_display = wl_display_connect(NULL);
4117 RGFW_window_basic_init(win, rect, flags);
4120 win->
src.compositor = NULL;
4122 RGFW_GOTO_WAYLAND(0);
4124 i64 event_mask = KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | PointerMotionMask | StructureNotifyMask | FocusChangeMask | LeaveWindowMask | EnterWindowMask | ExposureMask;
4127 RGFW_window_getVisual(win);
4130 XSetWindowAttributes swa;
4135 DefaultRootWindow(win->
src.display),
4136 win->
src.visual.visual, AllocNone);
4137 swa.event_mask = event_mask;
4141 0, win->
src.visual.depth, InputOutput, win->
src.visual.visual,
4142 CWColormap | CWBorderPixel | CWEventMask, &swa);
4155 hint.res_class = (
char*)_RGFW->
className;
4156 if (_RGFW->instName == NULL) hint.res_name = (
char*)name;
4157 else hint.res_name = (
char*)_RGFW->instName;
4160 #ifndef RGFW_NO_MONITOR
4161 if (flags & RGFW_windowScaleToMonitor)
4167 RGFW_LOAD_ATOM(WM_DELETE_WINDOW);
4174 if (flags & RGFW_windowAllowDND) {
4175 win->
_flags |= RGFW_windowAllowDND;
4178 Atom XdndAware =
XInternAtom(win->
src.display,
"XdndAware", False);
4179 const u8 version = 5;
4183 PropModeReplace, &version, 1);
4186#ifdef RGFW_ADVANCED_SMOOTH_RESIZE
4187 RGFW_LOAD_ATOM(_NET_WM_SYNC_REQUEST_COUNTER)
4188 RGFW_LOAD_ATOM(_NET_WM_SYNC_REQUEST)
4190 Atom protcols[2] = {_NET_WM_SYNC_REQUEST, WM_DELETE_WINDOW};
4193 XSyncValue initial_value;
4194 XSyncIntToValue(&initial_value, 0);
4195 win->
src.counter = XSyncCreateCounter(win->
src.display, initial_value);
4197 XChangeProperty(win->
src.display, win->
src.window, _NET_WM_SYNC_REQUEST_COUNTER, XA_CARDINAL, 32, PropModeReplace, (uint8_t*)&win->
src.counter, 1);
4200 if ((flags & RGFW_windowNoInitAPI) == 0) {
4209 win->
src.r = win->
r;
4218 win->
src.wl_display = _RGFW->wl_display;
4219 if (win->
src.wl_display == NULL) {
4231 win->
src.display = _RGFW->display;
4232 win->
src.window = _RGFW->helperWindow;
4237 static const struct wl_registry_listener registry_listener = {
4238 .global = RGFW_wl_global_registry_handler,
4239 .global_remove = RGFW_wl_global_registry_remove,
4243 struct wl_registry *registry = wl_display_get_registry(win->
src.wl_display);
4244 wl_registry_add_listener(registry, ®istry_listener, win);
4246 wl_display_roundtrip(win->
src.wl_display);
4247 wl_display_dispatch(win->
src.wl_display);
4249 if (win->
src.compositor == NULL) {
4254 if (_RGFW->wl_cursor_theme == NULL) {
4255 _RGFW->wl_cursor_theme = wl_cursor_theme_load(NULL, 24, win->
src.shm);
4256 _RGFW->cursor_surface = wl_compositor_create_surface(win->
src.compositor);
4258 struct wl_cursor* cursor = wl_cursor_theme_get_cursor(_RGFW->wl_cursor_theme,
"left_ptr");
4259 _RGFW->cursor_image = cursor->images[0];
4260 struct wl_buffer* cursor_buffer = wl_cursor_image_get_buffer(_RGFW->cursor_image);
4262 wl_surface_attach(_RGFW->cursor_surface, cursor_buffer, 0, 0);
4263 wl_surface_commit(_RGFW->cursor_surface);
4266 static const struct xdg_wm_base_listener xdg_wm_base_listener = {
4267 .ping = RGFW_wl_xdg_wm_base_ping_handler,
4270 static const struct xdg_surface_listener xdg_surface_listener = {
4271 .configure = RGFW_wl_xdg_surface_configure_handler,
4274 static const struct wl_callback_listener wl_surface_frame_listener = {
4275 .done = RGFW_wl_surface_frame_done,
4279 xdg_wm_base_add_listener(win->
src.xdg_wm_base, &xdg_wm_base_listener, NULL);
4281 _RGFW->xkb_context = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
4283 win->
src.surface = wl_compositor_create_surface(win->
src.compositor);
4284 wl_surface_set_user_data(win->
src.surface, win);
4286 win->
src.xdg_surface = xdg_wm_base_get_xdg_surface(win->
src.xdg_wm_base, win->
src.surface);
4287 xdg_surface_add_listener(win->
src.xdg_surface, &xdg_surface_listener, NULL);
4289 xdg_wm_base_set_user_data(win->
src.xdg_wm_base, win);
4291 win->
src.xdg_toplevel = xdg_surface_get_toplevel(win->
src.xdg_surface);
4292 xdg_toplevel_set_user_data(win->
src.xdg_toplevel, win);
4294 static const struct xdg_toplevel_listener xdg_toplevel_listener = {
4295 .configure = RGFW_wl_xdg_toplevel_configure_handler,
4296 .close = RGFW_wl_xdg_toplevel_close_handler,
4299 xdg_toplevel_add_listener(win->
src.xdg_toplevel, &xdg_toplevel_listener, NULL);
4301 xdg_surface_set_window_geometry(win->
src.xdg_surface, 0, 0, win->
r.
w, win->
r.
h);
4303 if (!(flags & RGFW_windowNoBorder)) {
4304 win->
src.decoration = zxdg_decoration_manager_v1_get_toplevel_decoration(
4305 _RGFW->decoration_manager, win->
src.xdg_toplevel);
4308 wl_display_roundtrip(win->
src.wl_display);
4310 wl_surface_commit(win->
src.surface);
4314 while (wl_display_dispatch(win->
src.wl_display) != -1 && !_RGFW->wl_configured) { }
4316 if ((flags & RGFW_windowNoInitAPI) == 0) {
4320 struct wl_callback* callback = wl_surface_frame(win->
src.surface);
4321 wl_callback_add_listener(callback, &wl_surface_frame_listener, win);
4322 wl_surface_commit(win->
src.surface);
4325 #ifndef RGFW_NO_MONITOR
4326 if (flags & RGFW_windowScaleToMonitor)
4338 RGFW_GOTO_WAYLAND(1);
4342 Screen* scrn = DefaultScreenOfDisplay(_RGFW->display);
4343 return RGFW_AREA(scrn->width, scrn->height);
4353 RGFW_GOTO_WAYLAND(1);
4357 Window window1, window2;
4367RGFWDEF void RGFW_XHandleClipboardSelection(XEvent* event);
4368void RGFW_XHandleClipboardSelection(XEvent* event) {
RGFW_UNUSED(event);
4370 RGFW_LOAD_ATOM(ATOM_PAIR);
4371 RGFW_LOAD_ATOM(MULTIPLE);
4372 RGFW_LOAD_ATOM(TARGETS);
4373 RGFW_LOAD_ATOM(SAVE_TARGETS);
4374 RGFW_LOAD_ATOM(UTF8_STRING);
4376 const XSelectionRequestEvent* request = &
event->xselectionrequest;
4377 const Atom formats[] = { UTF8_STRING, XA_STRING };
4378 const int formatCount =
sizeof(formats) /
sizeof(formats[0]);
4380 if (request->target == TARGETS) {
4381 const Atom targets[] = { TARGETS, MULTIPLE, UTF8_STRING, XA_STRING };
4383 XChangeProperty(_RGFW->display, request->requestor, request->property,
4384 XA_ATOM, 32, PropModeReplace, (
u8*) targets,
sizeof(targets) /
sizeof(Atom));
4385 }
else if (request->target == MULTIPLE) {
4386 Atom* targets = NULL;
4388 Atom actualType = 0;
4389 int actualFormat = 0;
4390 unsigned long count = 0, bytesAfter = 0;
4392 XGetWindowProperty(_RGFW->display, request->requestor, request->property, 0, LONG_MAX,
4393 False, ATOM_PAIR, &actualType, &actualFormat, &count, &bytesAfter, (
u8**) &targets);
4396 for (i = 0; i < (
u32)count; i += 2) {
4397 if (targets[i] == UTF8_STRING || targets[i] == XA_STRING)
4398 XChangeProperty(_RGFW->display, request->requestor, targets[i + 1], targets[i],
4399 8, PropModeReplace, (
const unsigned char *)_RGFW->clipboard, (
i32)_RGFW->clipboard_len);
4401 targets[i + 1] = None;
4405 request->requestor, request->property, ATOM_PAIR, 32,
4406 PropModeReplace, (
u8*) targets, (
i32)count);
4410 }
else if (request->target == SAVE_TARGETS)
4411 XChangeProperty(_RGFW->display, request->requestor, request->property, 0, 32, PropModeReplace, NULL, 0);
4414 for (i = 0; i < formatCount; i++) {
4415 if (request->target != formats[i])
4417 XChangeProperty(_RGFW->display, request->requestor, request->property, request->target,
4418 8, PropModeReplace, (
u8*) _RGFW->clipboard, (
i32)_RGFW->clipboard_len);
4422 XEvent reply = { SelectionNotify };
4423 reply.xselection.property = request->property;
4424 reply.xselection.display = request->display;
4425 reply.xselection.requestor = request->requestor;
4426 reply.xselection.selection = request->selection;
4427 reply.xselection.target = request->target;
4428 reply.xselection.time = request->time;
4430 XSendEvent(_RGFW->display, request->requestor, False, 0, &reply);
4434char* RGFW_strtok(
char* str,
const char* delimStr);
4435char* RGFW_strtok(
char* str,
const char* delimStr) {
4436 static char* static_str = NULL;
4441 if (static_str == NULL) {
4445 while (*static_str !=
'\0') {
4448 for (d = delimStr; *d !=
'\0'; d++) {
4449 if (*static_str == *d) {
4459 if (*static_str ==
'\0')
4462 char* token_start = static_str;
4463 while (*static_str !=
'\0') {
4466 for (d = delimStr; *d !=
'\0'; d++) {
4467 if (*static_str == *d) {
4484i32 RGFW_XHandleClipboardSelectionHelper(
void);
4489 RGFW_GOTO_WAYLAND(0);
4491 Window root = DefaultRootWindow(_RGFW->display);
4492 Window ret_root, ret_child;
4493 int root_x, root_y, win_x, win_y;
4495 XQueryPointer(_RGFW->display, root, &ret_root, &ret_child, &root_x, &root_y, &win_x, &win_y, &mask);
4496 KeySym sym = (KeySym)
XkbKeycodeToKeysym(_RGFW->display, (KeyCode)keycode, 0, (KeyCode)mask & ShiftMask ? 1 : 0);
4498 if ((mask & LockMask) && sym >= XK_a && sym <= XK_z)
4499 sym = (mask & ShiftMask) ? sym + 32 : sym - 32;
4500 if ((
u8)sym != (
u32)sym)
4512 RGFW_XHandleClipboardSelectionHelper();
4514 if (win == NULL || ((win->
_flags & RGFW_windowFreeOnClose) && (win->
_flags & RGFW_EVENT_QUIT)))
return NULL;
4515 RGFW_event* ev = RGFW_window_checkEventCore(win);
4518 #if defined(__linux__) && !defined(RGFW_NO_LINUX)
4519 if (RGFW_linux_updateGamepad(win))
return &win->
event;
4521 RGFW_GOTO_WAYLAND(0);
4523 RGFW_LOAD_ATOM(XdndTypeList);
4524 RGFW_LOAD_ATOM(XdndSelection);
4525 RGFW_LOAD_ATOM(XdndEnter);
4526 RGFW_LOAD_ATOM(XdndPosition);
4527 RGFW_LOAD_ATOM(XdndStatus);
4528 RGFW_LOAD_ATOM(XdndLeave);
4529 RGFW_LOAD_ATOM(XdndDrop);
4530 RGFW_LOAD_ATOM(XdndFinished);
4531 RGFW_LOAD_ATOM(XdndActionCopy);
4532 RGFW_LOAD_ATOM(_NET_WM_SYNC_REQUEST);
4533 RGFW_LOAD_ATOM(WM_PROTOCOLS);
4550 static Window source = 0;
4551 static long version = 0;
4552 static i32 format = 0;
4554 XEvent reply = { ClientMessage };
4561 if (E.type == KeyRelease &&
XEventsQueued(win->
src.display, QueuedAfterReading)) {
4565 if (E.xkey.time == NE.xkey.time && E.xkey.keycode == NE.xkey.keycode)
4573 RGFW_keyboard[win->
event.
key].prev = RGFW_keyboard[win->
event.
key].current;
4576 win->
event.
type = (E.type == KeyPress) ? RGFW_keyPressed : RGFW_keyReleased;
4578 XKeyboardState keystate;
4581 RGFW_keyboard[win->
event.
key].current = (E.type == KeyPress);
4585 RGFW_updateKeyMods(win, (state.locked_mods & LockMask), (state.locked_mods & Mod2Mask), (state.locked_mods & Mod3Mask));
4592 if (E.xbutton.button > RGFW_mouseFinal) {
4597 win->
event.
type = RGFW_mouseButtonPressed + (E.type == ButtonRelease);
4600 case RGFW_mouseScrollUp:
4603 case RGFW_mouseScrollDown:
4614 RGFW_mouseButtons[win->
event.
button].current = (E.type == ButtonPress);
4630 case GenericEvent: {
4632 if (!(win->
_flags & RGFW_HOLD_MOUSE)) {
4638 if (E.xcookie.evtype == XI_RawMotion) {
4639 XIRawEvent *raw = (XIRawEvent *)E.xcookie.data;
4640 if (raw->valuators.mask_len == 0) {
4645 double deltaX = 0.0f;
4646 double deltaY = 0.0f;
4649 if (XIMaskIsSet(raw->valuators.mask, 0) != 0)
4650 deltaX += raw->raw_values[0];
4651 if (XIMaskIsSet(raw->valuators.mask, 1) != 0)
4652 deltaY += raw->raw_values[1];
4671 RGFW_windowRefreshCallback(win);
4673#ifdef RGFW_ADVANCED_SMOOTH_RESIZE
4675 XSyncIntToValue(&value, (
i32)win->
src.counter_value);
4676 XSyncSetCounter(win->
src.display, win->
src.counter, value);
4680 case MapNotify:
case UnmapNotify: RGFW_window_checkMode(win);
break;
4681 case ClientMessage: {
4682 RGFW_LOAD_ATOM(WM_DELETE_WINDOW);
4684 if (E.xclient.data.l[0] == (
long)WM_DELETE_WINDOW) {
4687 RGFW_windowQuitCallback(win);
4690#ifdef RGFW_ADVANCED_SMOOTH_RESIZE
4691 if (E.xclient.message_type == WM_PROTOCOLS && (Atom)E.xclient.data.l[0] == _NET_WM_SYNC_REQUEST) {
4692 RGFW_windowRefreshCallback(win);
4693 win->
src.counter_value = 0;
4694 win->
src.counter_value |= E.xclient.data.l[2];
4695 win->
src.counter_value |= (E.xclient.data.l[3] << 32);
4698 XSyncIntToValue(&value, (
i32)win->
src.counter_value);
4699 XSyncSetCounter(win->
src.display, win->
src.counter, value);
4703 if ((win->
_flags & RGFW_windowAllowDND) == 0)
4706 reply.xclient.window = source;
4707 reply.xclient.format = 32;
4708 reply.xclient.data.l[0] = (long)win->
src.window;
4709 reply.xclient.data.l[1] = 0;
4710 reply.xclient.data.l[2] = None;
4712 if (E.xclient.message_type == XdndEnter) {
4716 unsigned long count;
4718 Atom real_formats[6];
4719 Bool list = E.xclient.data.l[1] & 1;
4721 source = (
unsigned long int)E.xclient.data.l[0];
4722 version = E.xclient.data.l[1] >> 24;
4727 unsigned long bytesAfter;
4730 win->
src.display, source, XdndTypeList,
4731 0, LONG_MAX, False, 4,
4732 &actualType, &actualFormat, &count, &bytesAfter, (
u8**)&formats
4738 for (i = 2; i < 5; i++) {
4739 if (E.xclient.data.l[i] != None) {
4740 real_formats[count] = (
unsigned long int)E.xclient.data.l[i];
4745 formats = real_formats;
4748 Atom XtextPlain =
XInternAtom(win->
src.display,
"text/plain", False);
4749 Atom XtextUriList =
XInternAtom(win->
src.display,
"text/uri-list", False);
4752 for (i = 0; i < count; i++) {
4753 if (formats[i] == XtextUriList || formats[i] == XtextPlain) {
4754 format = (int)formats[i];
4766 if (E.xclient.message_type == XdndPosition) {
4767 const i32 xabs = (E.xclient.data.l[2] >> 16) & 0xffff;
4768 const i32 yabs = (E.xclient.data.l[2]) & 0xffff;
4777 xabs, yabs, &xpos, &ypos, &dummy
4783 reply.xclient.window = source;
4784 reply.xclient.message_type = XdndStatus;
4787 reply.xclient.data.l[1] = 1;
4789 reply.xclient.data.l[4] = (long)XdndActionCopy;
4792 XSendEvent(win->
src.display, source, False, NoEventMask, &reply);
4796 if (E.xclient.message_type != XdndDrop)
4812 Time time = (version >= 1)
4813 ? (Time)E.xclient.data.l[2]
4817 win->
src.display, XdndSelection, (Atom)format,
4818 XdndSelection, win->
src.window, time
4820 }
else if (version >= 2) {
4821 XEvent new_reply = { ClientMessage };
4823 XSendEvent(win->
src.display, source, False, NoEventMask, &new_reply);
4829 case SelectionRequest:
4830 RGFW_XHandleClipboardSelection(&E);
4833 case SelectionNotify: {
4835 if (E.xselection.property != XdndSelection || !(win->
_flags & RGFW_windowAllowDND))
4838 unsigned long result;
4842 unsigned long bytesAfter;
4844 XGetWindowProperty(win->
src.display, E.xselection.requestor, E.xselection.property, 0, LONG_MAX, False, E.xselection.target, &actualType, &actualFormat, &result, &bytesAfter, (
u8**) &data);
4849 const char* prefix = (
const char*)
"file://";
4856 while ((line = (
char*)RGFW_strtok(data,
"\r\n"))) {
4865 for (l = line; 1; l++) {
4868 else if (*l != prefix[(l - line)])
4870 else if (*l ==
'\0' && prefix[(l - line)] ==
'\0') {
4872 while (*line !=
'/')
4875 }
else if (*l ==
'\0')
4883 if (line[0] ==
'%' && line[1] && line[2]) {
4884 const char digits[3] = { line[1], line[2],
'\0' };
4885 path[index] = (char)
RGFW_STRTOL(digits, NULL, 16);
4888 path[index] = *line;
4902 XEvent new_reply = { ClientMessage };
4903 new_reply.xclient.window = source;
4904 new_reply.xclient.message_type = XdndFinished;
4905 new_reply.xclient.format = 32;
4906 new_reply.xclient.data.l[1] = (
long int)result;
4907 new_reply.xclient.data.l[2] = (
long int)XdndActionCopy;
4908 XSendEvent(win->
src.display, source, False, NoEventMask, &new_reply);
4914 if ((win->
_flags & RGFW_windowFullscreen))
4917 win->
_flags |= RGFW_windowFocus;
4919 RGFW_focusCallback(win, 1);
4925 RGFW_focusCallback(win, 0);
4926 RGFW_window_focusLost(win);
4928 case PropertyNotify: RGFW_window_checkMode(win);
break;
4933 RGFW_mouseNotifyCallback(win, win->
event.
point, 1);
4939 RGFW_mouseNotifyCallback(win, win->
event.
point, 0);
4943 case ConfigureNotify: {
4945 RGFW_window_checkMode(win);
4946 if (E.xconfigure.width != win->
src.r.w || E.xconfigure.height != win->
src.r.h) {
4948 win->
src.r = win->
r =
RGFW_RECT(win->
src.r.x, win->
src.r.y, E.xconfigure.width, E.xconfigure.height);
4949 RGFW_windowResizedCallback(win, win->
r);
4954 if (E.xconfigure.x != win->
src.r.x || E.xconfigure.y != win->
src.r.y) {
4956 win->
src.r = win->
r =
RGFW_RECT(E.xconfigure.x, E.xconfigure.y, win->
src.r.w, win->
src.r.h);
4957 RGFW_windowMovedCallback(win, win->
r);
4973 if ((win->
_flags & RGFW_windowHide) == 0)
4974 wl_display_roundtrip(win->
src.wl_display);
4983 RGFW_GOTO_WAYLAND(0);
4991 if (win->
src.compositor) {
4992 struct wl_pointer *pointer = wl_seat_get_pointer(win->
src.seat);
4997 wl_display_flush(win->
src.wl_display);
5007 RGFW_GOTO_WAYLAND(0);
5011 if ((win->
_flags & RGFW_windowNoResize)) {
5013 sh.flags = (1L << 4) | (1L << 5);
5014 sh.min_width = sh.max_width = (
i32)a.
w;
5015 sh.min_height = sh.max_height = (
i32)a.
h;
5022 if (win->
src.compositor) {
5023 xdg_surface_set_window_geometry(win->
src.xdg_surface, 0, 0, win->
r.
w, win->
r.
h);
5025 wl_egl_window_resize(win->
src.eglWindow, (
i32)a.
w, (
i32)a.
h, 0, 0);
5033 RGFW_GOTO_WAYLAND(0);
5035 if (a.
w == 0 && a.
h == 0)
5043 hints.flags |= PAspect;
5045 hints.min_aspect.x = hints.max_aspect.x = (
i32)a.
w;
5046 hints.min_aspect.y = hints.max_aspect.y = (
i32)a.
h;
5058 RGFW_GOTO_WAYLAND(0);
5066 hints.flags |= PMinSize;
5068 hints.min_width = (
i32)a.
w;
5069 hints.min_height = (
i32)a.
h;
5076 xdg_toplevel_set_min_size(win->
src.xdg_toplevel, (
i32)a.
w, (
i32)a.
h);
5082 RGFW_GOTO_WAYLAND(0);
5090 hints.flags |= PMaxSize;
5092 hints.max_width = (
i32)a.
w;
5093 hints.max_height = (
i32)a.
h;
5099 xdg_toplevel_set_max_size(win->
src.xdg_toplevel, (
i32)a.
w, (
i32)a.
h);
5107 RGFW_LOAD_ATOM(_NET_WM_STATE);
5108 RGFW_LOAD_ATOM(_NET_WM_STATE_MAXIMIZED_VERT);
5109 RGFW_LOAD_ATOM(_NET_WM_STATE_MAXIMIZED_HORZ);
5112 xev.type = ClientMessage;
5113 xev.xclient.window = win->
src.window;
5114 xev.xclient.message_type = _NET_WM_STATE;
5115 xev.xclient.format = 32;
5116 xev.xclient.data.l[0] = maximized;
5117 xev.xclient.data.l[1] = (
long int)_NET_WM_STATE_MAXIMIZED_HORZ;
5118 xev.xclient.data.l[2] = (
long int)_NET_WM_STATE_MAXIMIZED_VERT;
5119 xev.xclient.data.l[3] = 0;
5120 xev.xclient.data.l[4] = 0;
5122 XSendEvent(win->
src.display, DefaultRootWindow(win->
src.display), False, SubstructureRedirectMask | SubstructureNotifyMask, &xev);
5130 xdg_toplevel_set_maximized(win->
src.xdg_toplevel);
5135 RGFW_GOTO_WAYLAND(0);
5137 RGFW_toggleXMaximized(win, 1);
5142 RGFW_toggleWaylandMaximized(win, 1);
5149 RGFW_GOTO_WAYLAND(0);
5151 XWindowAttributes attr;
5153 if (attr.map_state != IsViewable)
return;
5165 RGFW_GOTO_WAYLAND(0);
5179 RGFW_LOAD_ATOM(_NET_WM_STATE);
5182 xev.xclient.type = ClientMessage;
5183 xev.xclient.serial = 0;
5184 xev.xclient.send_event = True;
5185 xev.xclient.message_type = _NET_WM_STATE;
5186 xev.xclient.window = win->
src.window;
5187 xev.xclient.format = 32;
5188 xev.xclient.data.l[0] = fullscreen;
5189 xev.xclient.data.l[1] = (
long int)netAtom;
5190 xev.xclient.data.l[2] = 0;
5192 XSendEvent(win->
src.display, DefaultRootWindow(win->
src.display), False, SubstructureNotifyMask | SubstructureRedirectMask, &xev);
5198 RGFW_GOTO_WAYLAND(0);
5200 win->
_flags |= RGFW_windowFullscreen;
5203 else win->
_flags &= ~(
u32)RGFW_windowFullscreen;
5205 RGFW_LOAD_ATOM(_NET_WM_STATE_FULLSCREEN);
5207 RGFW_window_setXAtom(win, _NET_WM_STATE_FULLSCREEN, fullscreen);
5219 RGFW_GOTO_WAYLAND(0);
5221 RGFW_LOAD_ATOM(_NET_WM_STATE_ABOVE);
5222 RGFW_window_setXAtom(win, _NET_WM_STATE_ABOVE, floating);
5231 RGFW_GOTO_WAYLAND(0);
5233 const u32 value = (
u32) (0xffffffffu * (
double) opacity);
5234 RGFW_LOAD_ATOM(NET_WM_WINDOW_OPACITY);
5236 NET_WM_WINDOW_OPACITY, XA_CARDINAL, 32, PropModeReplace, (
unsigned char*) &value, 1);
5245 RGFW_GOTO_WAYLAND(0);
5260 RGFW_GOTO_WAYLAND(0);
5262 RGFW_toggleXMaximized(win, 0);
5278 RGFW_GOTO_WAYLAND(0);
5280 RGFW_LOAD_ATOM(_NET_WM_STATE);
5281 RGFW_LOAD_ATOM(_NET_WM_STATE_ABOVE);
5285 unsigned long nitems, bytes_after;
5286 Atom* prop_return = NULL;
5289 &actual_type, &actual_format, &nitems, &bytes_after,
5290 (
unsigned char **)&prop_return);
5292 if (status != Success || actual_type != XA_ATOM)
5296 for (i = 0; i < nitems; i++)
5297 if (prop_return[i] == _NET_WM_STATE_ABOVE)
return RGFW_TRUE;
5310 RGFW_GOTO_WAYLAND(0);
5314 RGFW_LOAD_ATOM(_NET_WM_NAME); RGFW_LOAD_ATOM(UTF8_STRING);
5321 win->
src.display, win->
src.window, _NET_WM_NAME, UTF8_STRING,
5322 8, PropModeReplace, (
u8*)buf,
sizeof(buf)
5327 if (win->
src.compositor)
5328 xdg_toplevel_set_title(win->
src.xdg_toplevel, name);
5332#ifndef RGFW_NO_PASSTHROUGH
5335 RGFW_GOTO_WAYLAND(0);
5339 XShapeCombineRegion(win->
src.display, win->
src.window, ShapeInput, 0, 0, region, ShapeSet);
5345 XShapeCombineMask(win->
src.display, win->
src.window, ShapeInput, 0, 0, None, ShapeSet);
5355 RGFW_GOTO_WAYLAND(0);
5357 RGFW_LOAD_ATOM(_NET_WM_ICON);
5358 if (icon == NULL || (channels != 3 && channels != 4)) {
5360 win->
src.display, win->
src.window, _NET_WM_ICON, XA_CARDINAL, 32,
5361 PropModeReplace, (
u8*)NULL, 0
5366 i32 count = (
i32)(2 + (a.
w * a.
h));
5368 unsigned long* data = (
unsigned long*)
RGFW_ALLOC((
u32)count *
sizeof(
unsigned long));
5371 data[0] = (
unsigned long)a.
w;
5372 data[1] = (
unsigned long)a.
h;
5374 unsigned long* target = &data[2];
5377 for (x = 0; x < a.
w; x++) {
5378 for (y = 0; y < a.
h; y++) {
5379 size_t i = y * a.
w + x;
5380 u32 alpha = (channels == 4) ? icon[i * 4 + 3] : 0xFF;
5382 target[i] = (
unsigned long)((icon[i * 4 + 0]) << 16) |
5383 (
unsigned long)((icon[i * 4 + 1]) << 8) |
5384 (
unsigned long)((icon[i * 4 + 2]) << 0) |
5385 (
unsigned long)(alpha << 24);
5390 if (type & RGFW_iconTaskbar) {
5392 win->
src.display, win->
src.window, _NET_WM_ICON, XA_CARDINAL, 32,
5393 PropModeReplace, (
u8*)data, count
5397 if (type & RGFW_iconWindow) {
5399 wm_hints.flags = IconPixmapHint;
5401 i32 depth = DefaultDepth(win->
src.display, DefaultScreen(win->
src.display));
5402 XImage *image =
XCreateImage(win->
src.display, DefaultVisual(win->
src.display, DefaultScreen(win->
src.display)),
5403 (
u32)depth, ZPixmap, 0, (
char *)target, a.
w, a.
h, 32, 0);
5406 XPutImage(win->
src.display, wm_hints.icon_pixmap, DefaultGC(win->
src.display, DefaultScreen(win->
src.display)), image, 0, 0, 0, 0, a.
w, a.
h);
5408 XDestroyImage(image);
5426 RGFW_GOTO_WAYLAND(0);
5429#ifndef RGFW_NO_X11_CURSOR
5431 XcursorImage* native = XcursorImageCreate((
i32)a.
w, (
i32)a.
h);
5435 XcursorPixel* target = native->pixels;
5437 for (x = 0; x < a.
w; x++) {
5438 for (y = 0; y < a.
h; y++) {
5439 size_t i = y * a.
w + x;
5440 u32 alpha = (channels == 4) ? icon[i * 4 + 3] : 0xFF;
5442 target[i] = (
u32)((icon[i * 4 + 0]) << 16)
5443 | (
u32)((icon[i * 4 + 1]) << 8)
5444 | (
u32)((icon[i * 4 + 2]) << 0)
5445 | (
u32)(alpha << 24);
5449 Cursor cursor = XcursorImageLoadCursor(_RGFW->display, native);
5450 XcursorImageDestroy(native);
5452 return (
void*)cursor;
5466RGFW_GOTO_WAYLAND(0);
5478RGFW_GOTO_WAYLAND(0);
5490RGFW_GOTO_WAYLAND(1);
5496 &event.xbutton.root, &event.xbutton.window,
5497 &event.xbutton.x_root, &event.xbutton.y_root,
5498 &event.xbutton.x, &event.xbutton.y,
5499 &event.xbutton.state);
5502 if (event.xbutton.x == p.
x && event.xbutton.y == p.
y)
5519 RGFW_GOTO_WAYLAND(0);
5521 static const u8 mouseIconSrc[16] = { XC_arrow, XC_left_ptr, XC_xterm, XC_crosshair, XC_hand2, XC_sb_h_double_arrow, XC_sb_v_double_arrow, XC_bottom_left_corner, XC_bottom_right_corner, XC_fleur, XC_X_cursor};
5523 if (mouse > (
sizeof(mouseIconSrc) /
sizeof(
u8)))
5526 mouse = mouseIconSrc[mouse];
5535 RGFW_WAYLAND_LABEL { }
5536 static const char* iconStrings[16] = {
"left_ptr",
"left_ptr",
"text",
"cross",
"pointer",
"e-resize",
"n-resize",
"nw-resize",
"ne-resize",
"all-resize",
"not-allowed" };
5538 struct wl_cursor* wlcursor = wl_cursor_theme_get_cursor(_RGFW->wl_cursor_theme, iconStrings[mouse]);
5539 _RGFW->cursor_image = wlcursor->images[0];
5540 struct wl_buffer* cursor_buffer = wl_cursor_image_get_buffer(_RGFW->cursor_image);
5542 wl_surface_attach(_RGFW->cursor_surface, cursor_buffer, 0, 0);
5543 wl_surface_commit(_RGFW->cursor_surface);
5550 RGFW_GOTO_WAYLAND(0);
5556 wl_surface_attach(win->
src.surface, NULL, 0, 0);
5557 wl_surface_commit(win->
src.surface);
5558 win->
_flags |= RGFW_windowHide;
5565 RGFW_GOTO_WAYLAND(0);
5572 wl_surface_commit(win->
src.surface);
5577 RGFW_GOTO_WAYLAND(1);
5580 RGFW_LOAD_ATOM(XSEL_DATA); RGFW_LOAD_ATOM(UTF8_STRING); RGFW_LOAD_ATOM(CLIPBOARD);
5583 RGFW_STRNCPY(str, _RGFW->clipboard, _RGFW->clipboard_len - 1);
5584 _RGFW->clipboard[_RGFW->clipboard_len - 1] =
'\0';
5590 unsigned long N, sizeN;
5594 XConvertSelection(_RGFW->display, CLIPBOARD, UTF8_STRING, XSEL_DATA, _RGFW->helperWindow, CurrentTime);
5595 XSync(_RGFW->display, 0);
5598 if (event.type != SelectionNotify)
continue;
5600 if (event.xselection.selection != CLIPBOARD || event.xselection.property == 0)
5606 event.xselection.property, 0L, (~0L), 0, AnyPropertyType, &target,
5607 &format, &sizeN, &N, (
u8**) &data);
5610 if (sizeN > strCapacity && str != NULL)
5613 if ((target == UTF8_STRING || target == XA_STRING) && str != NULL) {
5617 }
else if (str != NULL) size = -1;
5619 XDeleteProperty(event.xselection.display, event.xselection.requestor, event.xselection.property);
5624 #if defined(RGFW_WAYLAND)
5630i32 RGFW_XHandleClipboardSelectionHelper(
void) {
5632 RGFW_LOAD_ATOM(SAVE_TARGETS);
5637 if (QLength(_RGFW->display) ||
XEventsQueued(_RGFW->display, QueuedAlready) +
XEventsQueued(_RGFW->display, QueuedAfterReading))
5642 switch (event.type) {
5643 case SelectionRequest:
5644 RGFW_XHandleClipboardSelection(&event);
5646 case SelectionNotify:
5647 if (event.xselection.target == SAVE_TARGETS)
5660 RGFW_GOTO_WAYLAND(1);
5662 RGFW_LOAD_ATOM(SAVE_TARGETS); RGFW_LOAD_ATOM(CLIPBOARD);
5672 if (_RGFW->clipboard)
5675 _RGFW->clipboard = (
char*)
RGFW_ALLOC(textLen);
5679 _RGFW->clipboard[textLen - 1] =
'\0';
5680 _RGFW->clipboard_len = textLen;
5690 RGFW_GOTO_WAYLAND(0);
5693 XWindowAttributes windowAttributes;
5706 RGFW_GOTO_WAYLAND(0);
5708 RGFW_LOAD_ATOM(WM_STATE);
5712 unsigned long nitems, bytes_after;
5713 unsigned char* prop_data;
5716 AnyPropertyType, &actual_type, &actual_format,
5717 &nitems, &bytes_after, &prop_data);
5719 if (status == Success && nitems >= 1 && prop_data == (
unsigned char*)IconicState) {
5724 if (prop_data != NULL)
5727 XWindowAttributes windowAttributes;
5729 return windowAttributes.map_state != IsViewable;
5739 RGFW_GOTO_WAYLAND(0);
5741 RGFW_LOAD_ATOM(_NET_WM_STATE);
5742 RGFW_LOAD_ATOM(_NET_WM_STATE_MAXIMIZED_VERT);
5743 RGFW_LOAD_ATOM(_NET_WM_STATE_MAXIMIZED_HORZ);
5747 unsigned long nitems, bytes_after;
5748 unsigned char* prop_data;
5751 XA_ATOM, &actual_type, &actual_format,
5752 &nitems, &bytes_after, &prop_data);
5754 if (status != Success) {
5755 if (prop_data != NULL)
5762 for (i = 0; i < nitems; ++i) {
5763 if (prop_data[i] == _NET_WM_STATE_MAXIMIZED_VERT ||
5764 prop_data[i] == _NET_WM_STATE_MAXIMIZED_HORZ) {
5770 if (prop_data != NULL)
5780u32 RGFW_XCalculateRefreshRate(XRRModeInfo mi);
5781u32 RGFW_XCalculateRefreshRate(XRRModeInfo mi) {
5782 if (mi.hTotal == 0 || mi.vTotal == 0)
return 0;
5783 return (
u32)
RGFW_ROUND((
double) mi.dotClock / ((
double) mi.hTotal * (
double) mi.vTotal));
5789static float XGetSystemContentDPI(Display* display,
i32 screen) {
5795 XrmDatabase db = NULL;
5807 dpi =
RGFW_ROUND(DisplayWidth(display, screen) / (DisplayWidthMM(display, screen) / 25.4));
5819 RGFW_GOTO_WAYLAND(1);
5821 Display* display = _RGFW->display;
5823 if (screen == -1) screen = DefaultScreen(display);
5825 Screen* scrn = DefaultScreenOfDisplay(display);
5831 monitor.
physW = (float)DisplayWidthMM(display, screen) / 25.4f;
5832 monitor.
physH = (float)DisplayHeightMM(display, screen) / 25.4f;
5834 RGFW_splitBPP((
u32)DefaultDepth(display, DefaultScreen(display)), &monitor.
mode);
5838 monitor.
name[
sizeof(monitor.
name) - 1] =
'\0';
5840 float dpi = XGetSystemContentDPI(display, screen);
5842 monitor.
scaleX = (float) (dpi) / 96.0f;
5843 monitor.
scaleY = (float) (dpi) / 96.0f;
5847 monitor.
mode.
refreshRate = RGFW_XCalculateRefreshRate(sr->modes[screen]);
5849 XRRCrtcInfo* ci = NULL;
5852 if (sr->ncrtc > crtc) {
5860 if (info == NULL || ci == NULL) {
5867 float physW = (float)info->mm_width / 25.4f;
5868 float physH = (
float)info->mm_height / 25.4f;
5871 monitor.
name[
sizeof(monitor.
name) - 1] =
'\0';
5873 if ((
u8)physW && (
u8)physH) {
5874 monitor.
physW = physW;
5875 monitor.
physH = physH;
5881 if (ci->width && ci->height) {
5905 RGFW_GOTO_WAYLAND(1);
5909 Display* display = _RGFW->display;
5910 i32 max = ScreenCount(display);
5913 for (i = 0; i < max && i < 6; i++)
5914 monitors[i] = RGFW_XCreateMonitor(i);
5916 if (len != NULL) *len = (size_t)((max <= 6) ? (max) : (6));
5927 RGFW_GOTO_WAYLAND(1);
5929 return RGFW_XCreateMonitor(-1);
5937 RGFW_GOTO_WAYLAND(1);
5941 XRRScreenResources* screenRes =
XRRGetScreenResources(_RGFW->display, DefaultRootWindow(_RGFW->display));
5945 for (i = 0; i < screenRes->ncrtc; i++) {
5946 XRRCrtcInfo* crtcInfo =
XRRGetCrtcInfo(_RGFW->display, screenRes, screenRes->crtcs[i]);
5947 if (!crtcInfo)
continue;
5949 if (mon.
x == crtcInfo->x && mon.
y == crtcInfo->y && (
u32)mon.
mode.
area.
w == crtcInfo->width && (
u32)mon.
mode.
area.
h == crtcInfo->height) {
5950 RRMode rmode = None;
5952 for (index = 0; index < screenRes->nmode; index++) {
5954 foundMode.
area =
RGFW_AREA(screenRes->modes[index].width, screenRes->modes[index].height);
5955 foundMode.
refreshRate = RGFW_XCalculateRefreshRate(screenRes->modes[index]);
5956 RGFW_splitBPP((
u32)DefaultDepth(_RGFW->display, DefaultScreen(_RGFW->display)), &foundMode);
5959 rmode = screenRes->modes[index].id;
5961 RROutput output = screenRes->outputs[i];
5965 CurrentTime, 0, 0, rmode, RR_Rotate_0, &output, 1);
5997 RGFW_GOTO_WAYLAND(1);
5999 XWindowAttributes attrs;
6005 for (i = 0; i < ScreenCount(win->
src.display) && i < 6; i++) {
6006 Screen* screen = ScreenOfDisplay(win->
src.display, i);
6009 return RGFW_XCreateMonitor(i);
6019#if defined(RGFW_OPENGL) && !defined(RGFW_EGL)
6032 RGFW_GOTO_WAYLAND(0);
6033#if defined(RGFW_BUFFER)
6035 win->
src.bitmap->data = (
char*) win->buffer;
6036 RGFW_RGB_to_BGR(win, (
u8*)win->
src.bitmap->data);
6037 XPutImage(win->
src.display, win->
src.window, win->
src.gc, win->
src.bitmap, 0, 0, 0, 0, win->bufferSize.w, win->bufferSize.h);
6038 win->
src.bitmap->data = NULL;
6044 for (y = 0; y < (
u32)win->
r.
h; y++) {
6045 for (x = 0; x < (
u32)win->
r.
w; x++) {
6046 u32 index = (y * 4 * (
u32)win->
r.
w) + x * 4;
6047 u32 index2 = (y * 4 * win->bufferSize.w) + x * 4;
6049 u8 r = win->buffer[index2];
6050 win->buffer[index2] = win->buffer[index2 + 2];
6051 win->buffer[index2 + 1] = win->buffer[index2 + 1];
6052 win->buffer[index2 + 2] = r;
6053 win->buffer[index2 + 3] = win->buffer[index + 3];
6059 RGFW_wl_surface_frame_done(win, NULL, 0);
6060 wl_surface_commit(win->
src.surface);
6070#if !defined(RGFW_EGL)
6075 #if defined(RGFW_OPENGL)
6077 static PFNGLXSWAPINTERVALEXTPROC pfn = (PFNGLXSWAPINTERVALEXTPROC)123;
6078 static int (*pfn2)(int) = NULL;
6080 if (pfn == (PFNGLXSWAPINTERVALEXTPROC)123) {
6081 pfn = ((PFNGLXSWAPINTERVALEXTPROC)
glXGetProcAddress((GLubyte*)
"glXSwapIntervalEXT"));
6083 const char* array[] = {
"GLX_MESA_swap_control",
"GLX_SGI_swap_control"};
6085 for (i = 0; i <
sizeof(array) /
sizeof(
char*) && pfn2 == NULL; i++)
6089 RGFW_sendDebugInfo(RGFW_typeError, RGFW_errOpenglContext,
RGFW_DEBUG_CTX(_RGFW->
root, 0),
"Failed to load swap interval function, fallingback to the native swapinterval function");
6096 pfn(win->
src.display, win->
src.window, swapInterval);
6097 else if (pfn2 != NULL) {
6106void RGFW_deinitPlatform(
void) {
6107 #define RGFW_FREE_LIBRARY(x) if (x != NULL) dlclose(x); x = NULL;
6110 RGFW_LOAD_ATOM(CLIPBOARD_MANAGER); RGFW_LOAD_ATOM(CLIPBOARD);
6111 RGFW_LOAD_ATOM(SAVE_TARGETS);
6113 XConvertSelection(_RGFW->display, CLIPBOARD_MANAGER, SAVE_TARGETS, None, _RGFW->helperWindow, CurrentTime);
6114 while (RGFW_XHandleClipboardSelectionHelper());
6116 if (_RGFW->clipboard) {
6118 _RGFW->clipboard = NULL;
6126 #if !defined(RGFW_NO_X11_CURSOR_PRELOAD) && !defined(RGFW_NO_X11_CURSOR)
6127 RGFW_FREE_LIBRARY(X11Cursorhandle);
6129 #if !defined(RGFW_NO_X11_XI_PRELOAD)
6130 RGFW_FREE_LIBRARY(X11Xihandle);
6137 #if !defined(RGFW_NO_X11_EXT_PRELOAD)
6138 RGFW_FREE_LIBRARY(X11XEXThandle);
6142 wl_display_disconnect(_RGFW->wl_display);
6144 #ifndef RGFW_NO_LINUX
6145 if (_RGFW->eventWait_forceStop[0] || _RGFW->eventWait_forceStop[1]){
6146 close(_RGFW->eventWait_forceStop[0]);
6147 close(_RGFW->eventWait_forceStop[1]);
6162 RGFW_GOTO_WAYLAND(0);
6165 if (win->
_flags & RGFW_HOLD_MOUSE)
6168 #if defined(RGFW_BUFFER)
6169 if (win->buffer != NULL) {
6170 if ((win->
_flags & RGFW_BUFFER_ALLOC))
6172 XDestroyImage((XImage*) win->
src.bitmap);
6178 win->
src.window = 0;
6182 RGFW_clipboard_switch(NULL);
6185 if ((win->
_flags & RGFW_WINDOW_ALLOC)) {
6197 #if defined(RGFW_BUFFER)
6198 wl_buffer_destroy(win->
src.wl_buffer);
6199 if ((win->
_flags & RGFW_BUFFER_ALLOC))
6202 munmap(win->
src.buffer, (
size_t)(win->
r.
w * win->
r.
h * 4));
6205 xdg_toplevel_destroy(win->
src.xdg_toplevel);
6206 xdg_surface_destroy(win->
src.xdg_surface);
6207 wl_surface_destroy(win->
src.surface);
6209 RGFW_clipboard_switch(NULL);
6213 if ((win->
_flags & RGFW_WINDOW_ALLOC)) {
6231 _RGFW->eventWait_forceStop[2] = 1;
6233 const char byte = 0;
6234 const ssize_t result = write(_RGFW->eventWait_forceStop[1], &
byte, 1);
6235 if (result == 1 || result == -1)
6241 if (waitMS == 0)
return;
6244 if (_RGFW->eventWait_forceStop[0] == 0 || _RGFW->eventWait_forceStop[1] == 0) {
6245 if (pipe(_RGFW->eventWait_forceStop) != -1) {
6246 fcntl(_RGFW->eventWait_forceStop[0], F_GETFL, 0);
6247 fcntl(_RGFW->eventWait_forceStop[0], F_GETFD, 0);
6248 fcntl(_RGFW->eventWait_forceStop[1], F_GETFL, 0);
6249 fcntl(_RGFW->eventWait_forceStop[1], F_GETFD, 0);
6253 struct pollfd fds[] = {
6255 { wl_display_get_fd(win->
src.wl_display), POLLIN, 0 },
6257 { ConnectionNumber(win->
src.display), POLLIN, 0 },
6260 { ConnectionNumber(_RGFW->display), POLLIN, 0 },
6262 { _RGFW->eventWait_forceStop[0], POLLIN, 0 },
6263 #if defined(__linux__)
6264 { -1, POLLIN, 0 }, {-1, POLLIN, 0 }, {-1, POLLIN, 0 }, {-1, POLLIN, 0}
6273 #if defined(__linux__) || defined(__NetBSD__)
6278 fds[index].fd = _RGFW->
gamepads[i];
6288 while (wl_display_dispatch(win->
src.wl_display) <= 0
6296 if (poll(fds, index, waitMS) <= 0)
6299 if (waitMS != RGFW_eventWaitNext)
6300 waitMS -= (i32)(RGFW_getTimeNS() - start) / (i32)1e+6;
6304 if (_RGFW->eventWait_forceStop[2]) {
6306 RGFW_MEMSET(data, 0, sizeof(data));
6307 (void)!read(_RGFW->eventWait_forceStop[0], data, sizeof(data));
6309 _RGFW->eventWait_forceStop[2] = 0;
6313i32 RGFW_getClock(
void);
6314i32 RGFW_getClock(
void) {
6315 static i32 clock = -1;
6316 if (clock != -1)
return clock;
6318 #if defined(_POSIX_MONOTONIC_CLOCK)
6320 if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0)
6321 clock = CLOCK_MONOTONIC;
6323 clock = CLOCK_REALTIME;
6332 clock_gettime(CLOCK_REALTIME, &ts);
6347#define WIN32_LEAN_AND_MEAN
6351#include <windowsx.h>
6352#include <shellapi.h>
6353#include <shellscalingapi.h>
6358#ifndef WM_DPICHANGED
6359#define WM_DPICHANGED 0x02E0
6362#ifndef RGFW_NO_XINPUT
6363 typedef DWORD (WINAPI * PFN_XInputGetState)(DWORD,XINPUT_STATE*);
6364 PFN_XInputGetState XInputGetStateSRC = NULL;
6365 #define XInputGetState XInputGetStateSRC
6367 typedef DWORD (WINAPI * PFN_XInputGetKeystroke)(DWORD, DWORD, PXINPUT_KEYSTROKE);
6368 PFN_XInputGetKeystroke XInputGetKeystrokeSRC = NULL;
6369 #define XInputGetKeystroke XInputGetKeystrokeSRC
6371 HMODULE RGFW_XInput_dll = NULL;
6374char* RGFW_createUTF8FromWideStringWin32(
const WCHAR* source);
6376#define GL_FRONT 0x0404
6377#define GL_BACK 0x0405
6378#define GL_LEFT 0x0406
6379#define GL_RIGHT 0x0407
6381typedef int (*PFN_wglGetSwapIntervalEXT)(void);
6382PFN_wglGetSwapIntervalEXT wglGetSwapIntervalEXTSrc = NULL;
6383#define wglGetSwapIntervalEXT wglGetSwapIntervalEXTSrc
6386typedef HGLRC (WINAPI *PFNWGLCREATECONTEXTATTRIBSARBPROC)(HDC hdc, HGLRC hglrc,
const int *attribList);
6387PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB = NULL;
6390 HMODULE RGFW_wgl_dll = NULL;
6393#ifndef RGFW_NO_LOAD_WGL
6394 typedef HGLRC(WINAPI* PFN_wglCreateContext)(HDC);
6395 typedef BOOL(WINAPI* PFN_wglDeleteContext)(HGLRC);
6396 typedef PROC(WINAPI* PFN_wglGetProcAddress)(LPCSTR);
6397 typedef BOOL(WINAPI* PFN_wglMakeCurrent)(HDC, HGLRC);
6398 typedef HDC(WINAPI* PFN_wglGetCurrentDC)(void);
6399 typedef HGLRC(WINAPI* PFN_wglGetCurrentContext)(void);
6400 typedef BOOL(WINAPI* PFN_wglShareLists)(HGLRC, HGLRC);
6402 PFN_wglCreateContext wglCreateContextSRC;
6403 PFN_wglDeleteContext wglDeleteContextSRC;
6404 PFN_wglGetProcAddress wglGetProcAddressSRC;
6405 PFN_wglMakeCurrent wglMakeCurrentSRC;
6406 PFN_wglGetCurrentDC wglGetCurrentDCSRC;
6407 PFN_wglGetCurrentContext wglGetCurrentContextSRC;
6408 PFN_wglShareLists wglShareListsSRC;
6410 #define wglCreateContext wglCreateContextSRC
6411 #define wglDeleteContext wglDeleteContextSRC
6412 #define wglGetProcAddress wglGetProcAddressSRC
6413 #define wglMakeCurrent wglMakeCurrentSRC
6414 #define wglGetCurrentDC wglGetCurrentDCSRC
6415 #define wglGetCurrentContext wglGetCurrentContextSRC
6416 #define wglShareLists wglShareListsSRC
6419#if defined(RGFW_OPENGL) && !defined(RGFW_EGL)
6421 const char* extensions = NULL;
6427 extensions = ((
const char* (*)(HDC))proc)(wglGetCurrentDC());
6429 extensions = ((
const char*(*)(
void))proc2)();
6431 return extensions != NULL && RGFW_extensionSupportedStr(extensions, extension, len);
6439 return (
RGFW_proc) GetProcAddress(RGFW_wgl_dll, procname);
6442typedef HRESULT (APIENTRY* PFNWGLCHOOSEPIXELFORMATARBPROC)(HDC hdc,
const int* piAttribIList,
const FLOAT* pfAttribFList, UINT nMaxFormats,
int* piFormats, UINT* nNumFormats);
6443PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormatARB = NULL;
6445typedef BOOL(APIENTRY* PFNWGLSWAPINTERVALEXTPROC)(
int interval);
6446PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT = NULL;
6450HMODULE RGFW_dwm_dll = NULL;
6451typedef struct { DWORD dwFlags;
int fEnable; HRGN hRgnBlur;
int fTransitionOnMaximized;} DWM_BLURBEHIND;
6452typedef HRESULT (WINAPI * PFN_DwmEnableBlurBehindWindow)(HWND,
const DWM_BLURBEHIND*);
6453PFN_DwmEnableBlurBehindWindow DwmEnableBlurBehindWindowSRC = NULL;
6455void RGFW_win32_makeWindowTransparent(
RGFW_window* win);
6456void RGFW_win32_makeWindowTransparent(
RGFW_window* win) {
6457 if (!(win->
_flags & RGFW_windowTransparent))
return;
6460 if (DwmEnableBlurBehindWindowSRC != NULL) {
6461 DWM_BLURBEHIND bb = {0, 0, 0, 0};
6465 DwmEnableBlurBehindWindowSRC(win->
src.window, &bb);
6470 SetWindowLong(win->
src.window, GWL_EXSTYLE, WS_EX_LAYERED);
6471 SetLayeredWindowAttributes(win->
src.window, 0, 128, LWA_ALPHA);
6475LRESULT CALLBACK WndProcW(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
6476LRESULT CALLBACK WndProcW(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
6478 if (win == NULL)
return DefWindowProcW(hWnd, message, wParam, lParam);
6481 GetWindowRect(hWnd, &windowRect);
6487 RGFW_windowQuitCallback(win);
6491 if (inFocus) win->
_flags |= RGFW_windowFocus;
6492 else win->
_flags &= ~ (
u32)RGFW_windowFocus;
6495 RGFW_focusCallback(win, inFocus);
6496 if (inFocus ==
RGFW_FALSE) RGFW_window_focusLost(win);
6499 return DefWindowProcW(hWnd, message, wParam, lParam);
6502 win->
r.
x = windowRect.left;
6503 win->
r.
y = windowRect.top;
6505 RGFW_windowMovedCallback(win, win->
r);
6506 return DefWindowProcW(hWnd, message, wParam, lParam);
6508 if (win->
src.aspectRatio.w != 0 && win->
src.aspectRatio.h != 0) {
6509 double aspectRatio = (double)win->
src.aspectRatio.w / win->
src.aspectRatio.h;
6511 int width = windowRect.right - windowRect.left;
6512 int height = windowRect.bottom - windowRect.top;
6513 int newHeight = (
int)(width / aspectRatio);
6514 int newWidth = (int)(height * aspectRatio);
6516 if (win->
r.
w > windowRect.right - windowRect.left ||
6517 win->
r.
h > (
i32)((
u32)(windowRect.bottom - windowRect.top) - win->
src.hOffset))
6519 if (newHeight > height) windowRect.right = windowRect.left + newWidth;
6520 else windowRect.bottom = windowRect.top + newHeight;
6522 if (newHeight < height) windowRect.right = windowRect.left + newWidth;
6523 else windowRect.bottom = windowRect.top + newHeight;
6527 (
u32)(windowRect.bottom - windowRect.top) - (
u32)win->
src.hOffset));
6530 win->
r.
w = windowRect.right - windowRect.left;
6531 win->
r.
h = (windowRect.bottom - windowRect.top) - (
i32)win->
src.hOffset;
6533 RGFW_windowResizedCallback(win, win->
r);
6534 RGFW_window_checkMode(win);
6535 return DefWindowProcW(hWnd, message, wParam, lParam);
6537 #ifndef RGFW_NO_MONITOR
6538 case WM_DPICHANGED: {
6541 const float scaleX = HIWORD(wParam) / (float) 96;
6542 const float scaleY = LOWORD(wParam) / (float) 96;
6543 RGFW_scaleUpdatedCallback(win, scaleX, scaleY);
6544 RGFW_eventQueuePushEx(e.type = RGFW_scaleUpdated; e.scaleX = scaleX; e.scaleY = scaleY; e._win = win);
6545 return DefWindowProcW(hWnd, message, wParam, lParam);
6548 case WM_GETMINMAXINFO: {
6549 MINMAXINFO* mmi = (MINMAXINFO*) lParam;
6550 mmi->ptMinTrackSize.x = (LONG)win->
src.minSize.w;
6551 mmi->ptMinTrackSize.y = (LONG)(win->
src.minSize.h + win->
src.hOffset);
6552 if (win->
src.maxSize.w == 0 && win->
src.maxSize.h == 0)
6553 return DefWindowProcW(hWnd, message, wParam, lParam);
6555 mmi->ptMaxTrackSize.x = (LONG)win->
src.maxSize.w;
6556 mmi->ptMaxTrackSize.y = (LONG)(win->
src.maxSize.h + win->
src.hOffset);
6557 return DefWindowProcW(hWnd, message, wParam, lParam);
6561 BeginPaint(hWnd, &ps);
6563 RGFW_windowRefreshCallback(win);
6564 EndPaint(hWnd, &ps);
6566 return DefWindowProcW(hWnd, message, wParam, lParam);
6568 #if(_WIN32_WINNT >= 0x0600)
6569 case WM_DWMCOMPOSITIONCHANGED:
6570 case WM_DWMCOLORIZATIONCOLORCHANGED:
6571 RGFW_win32_makeWindowTransparent(win);
6575#ifdef RGFW_ADVANCED_SMOOTH_RESIZE
6576 case WM_ENTERSIZEMOVE: SetTimer(win->
src.window, 1, USER_TIMER_MINIMUM, NULL);
break;
6577 case WM_EXITSIZEMOVE: KillTimer(win->
src.window, 1);
break;
6578 case WM_TIMER: RGFW_windowRefreshCallback(win);
break;
6580 case WM_NCLBUTTONDOWN: {
6584 POINT point = { 0, 0 };
6585 if (SendMessage(win->
src.window, WM_NCHITTEST, wParam, lParam) != HTCAPTION || GetCursorPos(&point) == FALSE)
6588 ScreenToClient(win->
src.window, &point);
6589 PostMessage(win->
src.window, WM_MOUSEMOVE, 0, ((uint32_t)point.x)|(((uint32_t)point.y) << 16));
6594 return DefWindowProcW(hWnd, message, wParam, lParam);
6598 HMODULE RGFW_Shcore_dll = NULL;
6599 typedef HRESULT (WINAPI *PFN_GetDpiForMonitor)(HMONITOR,MONITOR_DPI_TYPE,UINT*,UINT*);
6600 PFN_GetDpiForMonitor GetDpiForMonitorSRC = NULL;
6601 #define GetDpiForMonitor GetDpiForMonitorSRC
6604#if !defined(RGFW_NO_LOAD_WINMM) && !defined(RGFW_NO_WINMM)
6605 HMODULE RGFW_winmm_dll = NULL;
6606 typedef u32 (WINAPI * PFN_timeBeginPeriod)(
u32);
6607 typedef PFN_timeBeginPeriod PFN_timeEndPeriod;
6608 PFN_timeBeginPeriod timeBeginPeriodSRC, timeEndPeriodSRC;
6609 #define timeBeginPeriod timeBeginPeriodSRC
6610 #define timeEndPeriod timeEndPeriodSRC
6611#elif !defined(RGFW_NO_WINMM)
6612 __declspec(dllimport)
u32 __stdcall timeBeginPeriod(
u32 uPeriod);
6613 __declspec(dllimport)
u32 __stdcall timeEndPeriod(
u32 uPeriod);
6615#define RGFW_PROC_DEF(proc, name) if (name##SRC == NULL && proc != NULL) { \
6616 name##SRC = (PFN_##name)(RGFW_proc)GetProcAddress((proc), (#name)); \
6617 RGFW_ASSERT(name##SRC != NULL); \
6620#ifndef RGFW_NO_XINPUT
6621void RGFW_loadXInput(
void);
6622void RGFW_loadXInput(
void) {
6624 static const char* names[] = {
"xinput1_4.dll",
"xinput9_1_0.dll",
"xinput1_2.dll",
"xinput1_1.dll"};
6626 for (i = 0; i <
sizeof(names) /
sizeof(
const char*) && (XInputGetStateSRC == NULL || XInputGetKeystrokeSRC != NULL); i++) {
6627 RGFW_XInput_dll = LoadLibraryA(names[i]);
6628 RGFW_PROC_DEF(RGFW_XInput_dll, XInputGetState);
6629 RGFW_PROC_DEF(RGFW_XInput_dll, XInputGetKeystroke);
6632 if (XInputGetStateSRC == NULL)
6634 if (XInputGetKeystrokeSRC == NULL)
6640#if defined(RGFW_BUFFER)
6641 win->buffer = buffer;
6642 win->bufferSize = area;
6645 ZeroMemory(&bi,
sizeof(bi));
6646 bi.bV5Size =
sizeof(bi);
6647 bi.bV5Width = (
i32)area.
w;
6648 bi.bV5Height = -((LONG) area.
h);
6650 bi.bV5BitCount = 32;
6651 bi.bV5Compression = BI_RGB;
6653 win->
src.bitmap = CreateDIBSection(win->
src.hdc,
6654 (BITMAPINFO*) &bi, DIB_RGB_COLORS,
6655 (
void**) &win->
src.bitmapBits,
6658 if (win->buffer == NULL)
6659 win->buffer = win->
src.bitmapBits;
6661 win->
src.hdcMem = CreateCompatibleDC(win->
src.hdc);
6662 SelectObject(win->
src.hdcMem, win->
src.bitmap);
6671 const RAWINPUTDEVICE
id = { 0x01, 0x02, RIDEV_REMOVE, NULL };
6672 RegisterRawInputDevices(&
id, 1,
sizeof(
id));
6679 GetClientRect(win->
src.window, &clipRect);
6680 ClientToScreen(win->
src.window, (POINT*) &clipRect.left);
6681 ClientToScreen(win->
src.window, (POINT*) &clipRect.right);
6682 ClipCursor(&clipRect);
6684 const RAWINPUTDEVICE
id = { 0x01, 0x02, 0, win->
src.window };
6685 RegisterRawInputDevices(&
id, 1,
sizeof(
id));
6688#define RGFW_LOAD_LIBRARY(x, lib) if (x == NULL) { x = LoadLibraryA(lib); RGFW_ASSERT(x != NULL); }
6691int RGFW_window_createDXSwapChain(
RGFW_window* win, IDXGIFactory* pFactory, IUnknown* pDevice, IDXGISwapChain** swapchain) {
6692 RGFW_ASSERT(win && pFactory && pDevice && swapchain);
6694 static DXGI_SWAP_CHAIN_DESC swapChainDesc = { 0 };
6695 swapChainDesc.BufferCount = 2;
6696 swapChainDesc.BufferDesc.Width = win->
r.
w;
6697 swapChainDesc.BufferDesc.Height = win->
r.
h;
6698 swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
6699 swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
6700 swapChainDesc.OutputWindow = (HWND)win->
src.window;
6701 swapChainDesc.SampleDesc.Count = 1;
6702 swapChainDesc.SampleDesc.Quality = 0;
6703 swapChainDesc.Windowed = TRUE;
6704 swapChainDesc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;
6706 HRESULT hr = pFactory->lpVtbl->CreateSwapChain(pFactory, (IUnknown*)pDevice, &swapChainDesc, swapchain);
6716void RGFW_win32_loadOpenGLFuncs(HWND dummyWin);
6717void RGFW_win32_loadOpenGLFuncs(HWND dummyWin) {
6719 if (wglSwapIntervalEXT != NULL && wglChoosePixelFormatARB != NULL && wglChoosePixelFormatARB != NULL)
6722 HDC dummy_dc = GetDC(dummyWin);
6723 u32 pfd_flags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
6725 PIXELFORMATDESCRIPTOR pfd = {
sizeof(pfd), 1, pfd_flags, PFD_TYPE_RGBA, 32, 8, PFD_MAIN_PLANE, 32, 8, 8, 8, 8, 8, 0, 0, 0, 0, 0, 32, 8, 0, PFD_MAIN_PLANE, 0, 0, 0, 0};
6727 int dummy_pixel_format = ChoosePixelFormat(dummy_dc, &pfd);
6728 SetPixelFormat(dummy_dc, dummy_pixel_format, &pfd);
6730 HGLRC dummy_context = wglCreateContext(dummy_dc);
6731 wglMakeCurrent(dummy_dc, dummy_context);
6733 wglCreateContextAttribsARB = ((PFNWGLCREATECONTEXTATTRIBSARBPROC(WINAPI *)(
const char*)) wglGetProcAddress)(
"wglCreateContextAttribsARB");
6734 wglChoosePixelFormatARB = ((PFNWGLCHOOSEPIXELFORMATARBPROC(WINAPI *)(
const char*)) wglGetProcAddress)(
"wglChoosePixelFormatARB");
6736 wglSwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC)(
RGFW_proc)wglGetProcAddress(
"wglSwapIntervalEXT");
6737 if (wglSwapIntervalEXT == NULL) {
6741 wglMakeCurrent(dummy_dc, 0);
6742 wglDeleteContext(dummy_context);
6743 ReleaseDC(dummyWin, dummy_dc);
6752 PIXELFORMATDESCRIPTOR pfd;
6753 pfd.nSize =
sizeof(PIXELFORMATDESCRIPTOR);
6755 pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
6756 pfd.iPixelType = PFD_TYPE_RGBA;
6757 pfd.iLayerType = PFD_MAIN_PLANE;
6758 pfd.cColorBits = 32;
6760 pfd.cDepthBits = 24;
6761 pfd.cStencilBits = (BYTE)RGFW_GL_HINTS[RGFW_glStencil];
6762 pfd.cAuxBuffers = (BYTE)RGFW_GL_HINTS[RGFW_glAuxBuffers];
6763 if (RGFW_GL_HINTS[RGFW_glStereo]) pfd.dwFlags |= PFD_STEREO;
6766 if (win->
_flags & RGFW_windowOpenglSoftware)
6767 pfd.dwFlags |= PFD_GENERIC_FORMAT | PFD_GENERIC_ACCELERATED;
6770 int pixel_format = ChoosePixelFormat(win->
src.hdc, &pfd);
6771 if (wglChoosePixelFormatARB != NULL) {
6772 i32* pixel_format_attribs = (
i32*)RGFW_initFormatAttribs();
6774 int new_pixel_format;
6776 wglChoosePixelFormatARB(win->
src.hdc, pixel_format_attribs, 0, 1, &new_pixel_format, &num_formats);
6779 else pixel_format = new_pixel_format;
6782 PIXELFORMATDESCRIPTOR suggested;
6783 if (!DescribePixelFormat(win->
src.hdc, pixel_format,
sizeof(suggested), &suggested) ||
6784 !SetPixelFormat(win->
src.hdc, pixel_format, &pfd))
6787 if (!(pfd.dwFlags & PFD_GENERIC_ACCELERATED)) {
6788 win->
_flags |= RGFW_windowOpenglSoftware;
6791 if (wglCreateContextAttribsARB != NULL) {
6796 if (RGFW_GL_HINTS[RGFW_glProfile]== RGFW_glCore) {
6797 SET_ATTRIB(WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_CORE_PROFILE_BIT_ARB);
6800 SET_ATTRIB(WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB);
6803 if (RGFW_GL_HINTS[RGFW_glMinor] || RGFW_GL_HINTS[RGFW_glMajor]) {
6804 SET_ATTRIB(WGL_CONTEXT_MAJOR_VERSION_ARB, RGFW_GL_HINTS[RGFW_glMajor]);
6805 SET_ATTRIB(WGL_CONTEXT_MINOR_VERSION_ARB, RGFW_GL_HINTS[RGFW_glMinor]);
6810 win->
src.ctx = (HGLRC)wglCreateContextAttribsARB(win->
src.hdc, NULL, attribs);
6813 win->
src.ctx = wglCreateContext(win->
src.hdc);
6816 ReleaseDC(win->
src.window, win->
src.hdc);
6817 win->
src.hdc = GetDC(win->
src.window);
6818 wglMakeCurrent(win->
src.hdc, win->
src.ctx);
6820 if (_RGFW->
root != win)
6821 wglShareLists(_RGFW->
root->
src.ctx, win->
src.ctx);
6830 if (win->
src.ctx == NULL)
return;
6831 wglDeleteContext((HGLRC) win->
src.ctx);
6832 win->
src.ctx = NULL;
6841i32 RGFW_initPlatform(
void) {
6842 #ifndef RGFW_NO_XINPUT
6843 if (RGFW_XInput_dll == NULL)
6848 #if (_WIN32_WINNT >= 0x0600)
6849 SetProcessDPIAware();
6853 #ifndef RGFW_NO_WINMM
6854 #ifndef RGFW_NO_LOAD_WINMM
6855 RGFW_LOAD_LIBRARY(RGFW_winmm_dll,
"winmm.dll");
6856 RGFW_PROC_DEF(RGFW_winmm_dll, timeBeginPeriod);
6857 RGFW_PROC_DEF(RGFW_winmm_dll, timeEndPeriod);
6863 RGFW_LOAD_LIBRARY(RGFW_dwm_dll,
"dwmapi.dll");
6864 RGFW_PROC_DEF(RGFW_dwm_dll, DwmEnableBlurBehindWindow);
6867 RGFW_LOAD_LIBRARY(RGFW_wgl_dll,
"opengl32.dll");
6868 #ifndef RGFW_NO_LOAD_WGL
6869 RGFW_PROC_DEF(RGFW_wgl_dll, wglCreateContext);
6870 RGFW_PROC_DEF(RGFW_wgl_dll, wglDeleteContext);
6871 RGFW_PROC_DEF(RGFW_wgl_dll, wglGetProcAddress);
6872 RGFW_PROC_DEF(RGFW_wgl_dll, wglMakeCurrent);
6873 RGFW_PROC_DEF(RGFW_wgl_dll, wglGetCurrentDC);
6874 RGFW_PROC_DEF(RGFW_wgl_dll, wglGetCurrentContext);
6875 RGFW_PROC_DEF(RGFW_wgl_dll, wglShareLists);
6878 u8 RGFW_blk[] = { 0, 0, 0, 0 };
6884 if (name[0] == 0) name = (
char*)
" ";
6886 RGFW_window_basic_init(win, rect, flags);
6888 win->
src.hIconSmall = win->
src.hIconBig = NULL;
6893 HINSTANCE inh = GetModuleHandleA(NULL);
6896 WNDCLASSW Class = { 0 };
6898 WNDCLASSW Class = { };
6904 wchar_t wide_class[256];
6905 MultiByteToWideChar(CP_UTF8, 0, _RGFW->
className, -1, wide_class, 255);
6907 Class.lpszClassName = wide_class;
6908 Class.hInstance = inh;
6909 Class.hCursor = LoadCursor(NULL, IDC_ARROW);
6910 Class.lpfnWndProc = WndProcW;
6913 Class.hIcon = (HICON)LoadImageA(GetModuleHandleW(NULL),
"RGFW_ICON", IMAGE_ICON, 0, 0, LR_DEFAULTSIZE | LR_SHARED);
6914 if (Class.hIcon == NULL)
6915 Class.hIcon = (HICON)LoadImageA(NULL, (LPCSTR)IDI_APPLICATION, IMAGE_ICON, 0, 0, LR_DEFAULTSIZE | LR_SHARED);
6917 RegisterClassW(&Class);
6919 DWORD window_style = WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
6921 RECT windowRect, clientRect;
6923 if (!(flags & RGFW_windowNoBorder)) {
6924 window_style |= WS_CAPTION | WS_SYSMENU | WS_BORDER | WS_MINIMIZEBOX | WS_THICKFRAME;
6926 if (!(flags & RGFW_windowNoResize))
6927 window_style |= WS_SIZEBOX | WS_MAXIMIZEBOX;
6929 window_style |= WS_POPUP | WS_VISIBLE | WS_SYSMENU;
6931 wchar_t wide_name[256];
6932 MultiByteToWideChar(CP_UTF8, 0, name, -1, wide_name, 255);
6933 HWND dummyWin = CreateWindowW(Class.lpszClassName, (
wchar_t*)wide_name, window_style, win->
r.
x, win->
r.
y, win->
r.
w, win->
r.
h, 0, 0, inh, 0);
6935 GetWindowRect(dummyWin, &windowRect);
6936 GetClientRect(dummyWin, &clientRect);
6938 RGFW_win32_loadOpenGLFuncs(dummyWin);
6939 DestroyWindow(dummyWin);
6941 win->
src.hOffset = (
u32)(windowRect.bottom - windowRect.top) - (
u32)(clientRect.bottom - clientRect.top);
6942 win->
src.window = CreateWindowW(Class.lpszClassName, (
wchar_t*)wide_name, window_style, win->
r.
x, win->
r.
y, win->
r.
w, win->
r.
h + (
i32)win->
src.hOffset, 0, 0, inh, 0);
6943 SetPropW(win->
src.window, L
"RGFW", win);
6946 if (flags & RGFW_windowAllowDND) {
6947 win->
_flags |= RGFW_windowAllowDND;
6950 win->
src.hdc = GetDC(win->
src.window);
6952 if ((flags & RGFW_windowNoInitAPI) == 0) {
6958 RGFW_win32_makeWindowTransparent(win);
6966 RGFW_setBit(&win->
_flags, RGFW_windowNoBorder, !border);
6967 LONG style = GetWindowLong(win->
src.window, GWL_STYLE);
6971 SetWindowLong(win->
src.window, GWL_STYLE, style & ~WS_OVERLAPPEDWINDOW);
6973 win->
src.window, HWND_TOP, 0, 0, 0, 0,
6974 SWP_NOZORDER | SWP_FRAMECHANGED | SWP_SHOWWINDOW | SWP_NOMOVE | SWP_NOSIZE
6978 style |= WS_OVERLAPPEDWINDOW;
6979 if (win->
_flags & RGFW_windowNoResize) style &= ~WS_MAXIMIZEBOX;
6981 win->
src.window, HWND_TOP, 0, 0, 0, 0,
6982 SWP_NOZORDER | SWP_FRAMECHANGED | SWP_SHOWWINDOW | SWP_NOMOVE | SWP_NOSIZE
6988 RGFW_setBit(&win->
_flags, RGFW_windowAllowDND, allow);
6989 DragAcceptFiles(win->
src.window, allow);
6993 HDC dc = GetDC(NULL);
6995 ReleaseDC(NULL, dc);
7008 win->
src.aspectRatio = a;
7013 win->
src.minSize = a;
7018 win->
src.maxSize = a;
7023 SetForegroundWindow(win->
src.window);
7024 SetFocus(win->
src.window);
7029 BringWindowToTop(win->
src.window);
7030 SetWindowPos(win->
src.window, HWND_TOP, win->
r.
x, win->
r.
y, win->
r.
w, win->
r.
h, SWP_NOSIZE | SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_FRAMECHANGED);
7039 SWP_NOOWNERZORDER | SWP_FRAMECHANGED);
7041 win->
_flags &= ~(
u32)RGFW_windowFullscreen;
7047 win->
_flags |= RGFW_windowFullscreen;
7052 SetWindowPos(win->
src.window, HWND_TOPMOST, 0, 0, (
i32)mon.
mode.
area.
w, (
i32)mon.
mode.
area.
h, SWP_NOOWNERZORDER | SWP_FRAMECHANGED | SWP_SHOWWINDOW);
7061 ShowWindow(win->
src.window, SW_MAXIMIZE);
7066 ShowWindow(win->
src.window, SW_MINIMIZE);
7071 if (floating) SetWindowPos(win->
src.window, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW);
7072 else SetWindowPos(win->
src.window, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW);
7076 SetWindowLong(win->
src.window, GWL_EXSTYLE, WS_EX_LAYERED);
7077 SetLayeredWindowAttributes(win->
src.window, 0, opacity, LWA_ALPHA);
7083 return (GetWindowLongPtr(win->
src.window, GWL_EXSTYLE) & WS_EX_TOPMOST) != 0;
7089 static const u8 xinput2RGFW[] = {
7098 0, 0, 0, 0, 0, 0, 0, 0,
7108 #ifndef RGFW_NO_XINPUT
7112 for (i = 0; i < 4; i++) {
7113 XINPUT_KEYSTROKE keystroke;
7115 if (XInputGetKeystroke == NULL)
7118 DWORD result = XInputGetKeystroke((DWORD)i, 0, &keystroke);
7120 if ((keystroke.Flags & XINPUT_KEYSTROKE_REPEAT) == 0 && result != ERROR_EMPTY) {
7121 if (result != ERROR_SUCCESS)
7124 if (keystroke.VirtualKey > VK_PAD_RTHUMB_PRESS)
7128 e->
type = RGFW_gamepadButtonPressed + !(keystroke.Flags & XINPUT_KEYSTROKE_KEYDOWN);
7129 e->
button = xinput2RGFW[keystroke.VirtualKey - 0x5800];
7130 RGFW_gamepadPressed[i][e->
button].prev = RGFW_gamepadPressed[i][e->
button].current;
7131 RGFW_gamepadPressed[i][e->
button].current =
RGFW_BOOL(keystroke.Flags & XINPUT_KEYSTROKE_KEYDOWN);
7133 RGFW_gamepadButtonCallback(win, i, e->
button, e->
type == RGFW_gamepadButtonPressed);
7138 if (XInputGetState == NULL ||
7139 XInputGetState((DWORD) i, &state) == ERROR_DEVICE_NOT_CONNECTED
7147 win->
event.
type = RGFW_gamepadDisconnected;
7149 RGFW_gamepadCallback(win, i, 0);
7157 char str[] =
"Microsoft X-Box (XInput device)";
7160 win->
event.
type = RGFW_gamepadConnected;
7164 RGFW_gamepadCallback(win, i, 1);
7168#define INPUT_DEADZONE ( 0.24f * (float)(0x7FFF) )
7170 if ((state.Gamepad.sThumbLX < INPUT_DEADZONE &&
7171 state.Gamepad.sThumbLX > -INPUT_DEADZONE) &&
7172 (state.Gamepad.sThumbLY < INPUT_DEADZONE &&
7173 state.Gamepad.sThumbLY > -INPUT_DEADZONE))
7175 state.Gamepad.sThumbLX = 0;
7176 state.Gamepad.sThumbLY = 0;
7179 if ((state.Gamepad.sThumbRX < INPUT_DEADZONE &&
7180 state.Gamepad.sThumbRX > -INPUT_DEADZONE) &&
7181 (state.Gamepad.sThumbRY < INPUT_DEADZONE &&
7182 state.Gamepad.sThumbRY > -INPUT_DEADZONE))
7184 state.Gamepad.sThumbRX = 0;
7185 state.Gamepad.sThumbRY = 0;
7189 RGFW_point axis1 =
RGFW_POINT(((
float)state.Gamepad.sThumbLX / 32768.0f) * 100, ((
float)state.Gamepad.sThumbLY / -32768.0f) * 100);
7190 RGFW_point axis2 =
RGFW_POINT(((
float)state.Gamepad.sThumbRX / 32768.0f) * 100, ((
float)state.Gamepad.sThumbRY / -32768.0f) * 100);
7192 if (axis1.
x != e->
axis[0].
x || axis1.
y != e->
axis[0].
y){
7195 e->
type = RGFW_gamepadAxisMove;
7203 if (axis2.
x != e->
axis[1].
x || axis2.
y != e->
axis[1].
y) {
7205 e->
type = RGFW_gamepadAxisMove;
7220 PostMessageW(_RGFW->
root->
src.window, WM_NULL, 0, 0);
7225 MsgWaitForMultipleObjects(0, NULL, FALSE, (DWORD)waitMS, QS_ALLINPUT);
7230 BYTE keyboardState[256] = {0};
7232 if (!GetKeyboardState(keyboardState))
7233 return (
u8)rgfw_keycode;
7235 UINT vk = MapVirtualKeyW(vsc, MAPVK_VSC_TO_VK);
7236 HKL layout = GetKeyboardLayout(0);
7238 wchar_t charBuffer[2] = {0};
7239 int result = ToUnicodeEx(vk, vsc, keyboardState, charBuffer, 1, 0, layout);
7242 return (
u8)rgfw_keycode;
7244 return (
u8)charBuffer[0];
7248 if (win == NULL || ((win->
_flags & RGFW_windowFreeOnClose) && (win->
_flags & RGFW_EVENT_QUIT)))
return NULL;
7249 RGFW_event* ev = RGFW_window_checkEventCore(win);
7267 UINT length = DragQueryFileW(drop, i, NULL, 0);
7275 DragQueryFileW(drop, i, buffer, length + 1);
7277 char* str = RGFW_createUTF8FromWideStringWin32(buffer);
7291 if (RGFW_checkXInput(win, &win->
event))
7294 static BYTE keyboardState[256];
7295 GetKeyboardState(keyboardState);
7298 if (PeekMessageA(&msg, NULL, 0u, 0u, PM_REMOVE)) {
7299 if (msg.hwnd != win->
src.window && msg.hwnd != NULL) {
7300 TranslateMessage(&msg);
7301 DispatchMessageA(&msg);
7308 switch (msg.message) {
7311 win->
_flags |= RGFW_MOUSE_LEFT;
7312 RGFW_mouseNotifyCallback(win, win->
event.
point, 0);
7314 case WM_SYSKEYUP:
case WM_KEYUP: {
7315 i32 scancode = (HIWORD(msg.lParam) & (KF_EXTENDED | 0xff));
7317 scancode = (
i32)MapVirtualKeyW((UINT)msg.wParam, MAPVK_VK_TO_VSC);
7320 case 0x54: scancode = 0x137;
break;
7321 case 0x146: scancode = 0x45;
break;
7322 case 0x136: scancode = 0x36;
break;
7328 if (msg.wParam == VK_CONTROL) {
7329 if (HIWORD(msg.lParam) & KF_EXTENDED)
7331 else win->
event.
key = RGFW_controlL;
7335 ToUnicodeEx((UINT)msg.wParam, (UINT)scancode, keyboardState, (
wchar_t*)&charBuffer, 1, 0, NULL);
7339 RGFW_keyboard[win->
event.
key].prev = RGFW_keyboard[win->
event.
key].current;
7341 RGFW_keyboard[win->
event.
key].current = 0;
7343 RGFW_updateKeyMods(win, (GetKeyState(VK_CAPITAL) & 0x0001), (GetKeyState(VK_NUMLOCK) & 0x0001), (GetKeyState(VK_SCROLL) & 0x0001));
7348 case WM_SYSKEYDOWN:
case WM_KEYDOWN: {
7349 i32 scancode = (HIWORD(msg.lParam) & (KF_EXTENDED | 0xff));
7351 scancode = (
i32)MapVirtualKeyW((
u32)msg.wParam, MAPVK_VK_TO_VSC);
7354 case 0x54: scancode = 0x137;
break;
7355 case 0x146: scancode = 0x45;
break;
7356 case 0x136: scancode = 0x36;
break;
7361 if (msg.wParam == VK_CONTROL) {
7362 if (HIWORD(msg.lParam) & KF_EXTENDED)
7364 else win->
event.
key = RGFW_controlL;
7368 ToUnicodeEx((UINT)msg.wParam, (UINT)scancode, keyboardState, &charBuffer, 1, 0, NULL);
7371 RGFW_keyboard[win->
event.
key].prev = RGFW_keyboard[win->
event.
key].current;
7374 RGFW_keyboard[win->
event.
key].current = 1;
7375 RGFW_updateKeyMods(win, (GetKeyState(VK_CAPITAL) & 0x0001), (GetKeyState(VK_NUMLOCK) & 0x0001), (GetKeyState(VK_SCROLL) & 0x0001));
7380 case WM_MOUSEMOVE: {
7381 if ((win->
_flags & RGFW_HOLD_MOUSE))
7386 i32 x = GET_X_LPARAM(msg.lParam);
7387 i32 y = GET_Y_LPARAM(msg.lParam);
7391 if (win->
_flags & RGFW_MOUSE_LEFT) {
7394 RGFW_mouseNotifyCallback(win, win->
event.
point, 1);
7404 if (!(win->
_flags & RGFW_HOLD_MOUSE))
7407 unsigned size =
sizeof(RAWINPUT);
7408 static RAWINPUT raw;
7410 GetRawInputData((HRAWINPUT)msg.lParam, RID_INPUT, &raw, &size,
sizeof(RAWINPUTHEADER));
7412 if (raw.header.dwType != RIM_TYPEMOUSE || (raw.data.mouse.lLastX == 0 && raw.data.mouse.lLastY == 0) )
7415 if (raw.data.mouse.usFlags & MOUSE_MOVE_ABSOLUTE) {
7419 if (raw.data.mouse.usFlags & MOUSE_VIRTUAL_DESKTOP) {
7420 pos.x += GetSystemMetrics(SM_XVIRTUALSCREEN);
7421 pos.y += GetSystemMetrics(SM_YVIRTUALSCREEN);
7422 width = GetSystemMetrics(SM_CXVIRTUALSCREEN);
7423 height = GetSystemMetrics(SM_CYVIRTUALSCREEN);
7426 width = GetSystemMetrics(SM_CXSCREEN);
7427 height = GetSystemMetrics(SM_CYSCREEN);
7430 pos.x += (int) (((
float)raw.data.mouse.lLastX / 65535.f) * (float)width);
7431 pos.y += (int) (((
float)raw.data.mouse.lLastY / 65535.f) * (
float)height);
7432 ScreenToClient(win->
src.window, &pos);
7448 case WM_LBUTTONDOWN:
case WM_RBUTTONDOWN:
case WM_MBUTTONDOWN:
case WM_XBUTTONDOWN:
7449 if (msg.message == WM_XBUTTONDOWN)
7450 win->
event.
button = RGFW_mouseMisc1 + (GET_XBUTTON_WPARAM(msg.wParam) == XBUTTON2);
7451 else win->
event.
button = (msg.message == WM_LBUTTONDOWN) ? (
u8)RGFW_mouseLeft :
7452 (msg.message == WM_RBUTTONDOWN) ? (
u8)RGFW_mouseRight : (
u8)RGFW_mouseMiddle;
7454 win->
event.
type = RGFW_mouseButtonPressed;
7459 case WM_LBUTTONUP:
case WM_RBUTTONUP:
case WM_MBUTTONUP:
case WM_XBUTTONUP:
7460 if (msg.message == WM_XBUTTONUP)
7461 win->
event.
button = RGFW_mouseMisc1 + (GET_XBUTTON_WPARAM(msg.wParam) == XBUTTON2);
7462 else win->
event.
button = (msg.message == WM_LBUTTONUP) ? (
u8)RGFW_mouseLeft :
7463 (msg.message == WM_RBUTTONUP) ? (
u8)RGFW_mouseRight : (
u8)RGFW_mouseMiddle;
7464 win->
event.
type = RGFW_mouseButtonReleased;
7478 win->
event.
scroll = (SHORT) HIWORD(msg.wParam) / (double) WHEEL_DELTA;
7480 win->
event.
type = RGFW_mouseButtonPressed;
7483 case WM_DROPFILES: {
7486 drop = (HDROP) msg.wParam;
7490 DragQueryPoint(drop, &pt);
7499 TranslateMessage(&msg);
7500 DispatchMessageA(&msg);
7504 TranslateMessage(&msg);
7505 DispatchMessageA(&msg);
7520 WINDOWPLACEMENT placement = { 0 };
7522 WINDOWPLACEMENT placement = { };
7524 GetWindowPlacement(win->
src.window, &placement);
7525 return placement.showCmd == SW_SHOWMINIMIZED;
7532 WINDOWPLACEMENT placement = { 0 };
7534 WINDOWPLACEMENT placement = { };
7536 GetWindowPlacement(win->
src.window, &placement);
7537 return placement.showCmd == SW_SHOWMAXIMIZED || IsZoomed(win->
src.window);
7540typedef struct {
int iIndex; HMONITOR hMonitor;
RGFW_monitor* monitors; } RGFW_mInfo;
7541#ifndef RGFW_NO_MONITOR
7545 MONITORINFOEX monitorInfo;
7547 monitorInfo.cbSize =
sizeof(MONITORINFOEX);
7548 GetMonitorInfoA(src, (LPMONITORINFO)&monitorInfo);
7555 for (deviceNum = 0; EnumDisplayDevicesA(NULL, deviceNum, &dd, 0); deviceNum++) {
7556 if (!(dd.StateFlags & DISPLAY_DEVICE_ACTIVE))
7560 ZeroMemory(&dm,
sizeof(dm));
7561 dm.dmSize =
sizeof(dm);
7563 if (EnumDisplaySettingsA(dd.DeviceName, ENUM_CURRENT_SETTINGS, &dm)) {
7565 RGFW_splitBPP(dm.dmBitsPerPel, &monitor.
mode);
7568 DISPLAY_DEVICEA mdd;
7569 mdd.cb =
sizeof(mdd);
7571 if (EnumDisplayDevicesA(dd.DeviceName, (DWORD)deviceNum, &mdd, 0)) {
7573 monitor.
name[
sizeof(monitor.
name) - 1] =
'\0';
7581 monitor.
x = monitorInfo.rcWork.left;
7582 monitor.
y = monitorInfo.rcWork.top;
7583 monitor.
mode.
area.
w = (
u32)(monitorInfo.rcMonitor.right - monitorInfo.rcMonitor.left);
7584 monitor.
mode.
area.
h = (
u32)(monitorInfo.rcMonitor.bottom - monitorInfo.rcMonitor.top);
7586 HDC hdc = CreateDC(monitorInfo.szDevice, NULL, NULL, NULL);
7588 float dpiX = (float)GetDeviceCaps(hdc, LOGPIXELSX);
7589 float dpiY = (float)GetDeviceCaps(hdc, LOGPIXELSX);
7591 monitor.
scaleX = dpiX / 96.0f;
7592 monitor.
scaleY = dpiY / 96.0f;
7593 monitor.
pixelRatio = dpiX >= 192.0f ? 2.0f : 1.0f;
7595 monitor.
physW = (float)GetDeviceCaps(hdc, HORZSIZE) / 25.4f;
7596 monitor.
physH = (float)GetDeviceCaps(hdc, VERTSIZE) / 25.4f;
7600 RGFW_LOAD_LIBRARY(RGFW_Shcore_dll,
"shcore.dll");
7601 RGFW_PROC_DEF(RGFW_Shcore_dll, GetDpiForMonitor);
7603 if (GetDpiForMonitor != NULL) {
7605 GetDpiForMonitor(src, MDT_EFFECTIVE_DPI, &x, &y);
7606 monitor.
scaleX = (float) (x) / (float) 96.0f;
7607 monitor.
scaleY = (float) (y) / (float) 96.0f;
7608 monitor.
pixelRatio = dpiX >= 192.0f ? 2.0f : 1.0f;
7617#ifndef RGFW_NO_MONITOR
7618BOOL CALLBACK GetMonitorHandle(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData);
7619BOOL CALLBACK GetMonitorHandle(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData) {
7623 RGFW_mInfo* info = (RGFW_mInfo*) dwData;
7626 if (info->iIndex >= 6)
7629 info->monitors[info->iIndex] = win32CreateMonitor(hMonitor);
7637 return win32CreateMonitor(MonitorFromPoint({ 0, 0 }, MONITOR_DEFAULTTOPRIMARY));
7639 return win32CreateMonitor(MonitorFromPoint((POINT) { 0, 0 }, MONITOR_DEFAULTTOPRIMARY));
7647 info.monitors = monitors;
7649 EnumDisplayMonitors(NULL, NULL, GetMonitorHandle, (LPARAM) &info);
7651 if (len != NULL) *len = (size_t)info.iIndex;
7656 HMONITOR src = MonitorFromWindow(win->
src.window, MONITOR_DEFAULTTOPRIMARY);
7657 return win32CreateMonitor(src);
7661 POINT p = { mon.
x, mon.
y };
7662 HMONITOR src = MonitorFromPoint(p, MONITOR_DEFAULTTOPRIMARY);
7664 MONITORINFOEX monitorInfo;
7665 monitorInfo.cbSize =
sizeof(MONITORINFOEX);
7666 GetMonitorInfoA(src, (LPMONITORINFO)&monitorInfo);
7673 for (deviceNum = 0; EnumDisplayDevicesA(NULL, deviceNum, &dd, 0); deviceNum++) {
7674 if (!(dd.StateFlags & DISPLAY_DEVICE_ACTIVE))
7677 if (strcmp(dd.DeviceName, (
const char*)monitorInfo.szDevice) != 0)
7681 ZeroMemory(&dm,
sizeof(dm));
7682 dm.dmSize =
sizeof(dm);
7684 if (EnumDisplaySettingsA(dd.DeviceName, ENUM_CURRENT_SETTINGS, &dm)) {
7685 if (request & RGFW_monitorScale) {
7686 dm.dmFields |= DM_PELSWIDTH | DM_PELSHEIGHT;
7687 dm.dmPelsWidth = mode.
area.
w;
7688 dm.dmPelsHeight = mode.
area.
h;
7691 if (request & RGFW_monitorRefresh) {
7692 dm.dmFields |= DM_DISPLAYFREQUENCY;
7696 if (request & RGFW_monitorRGB) {
7697 dm.dmFields |= DM_BITSPERPEL;
7698 dm.dmBitsPerPel = (DWORD)(mode.
red + mode.
green + mode.
blue);
7701 if (ChangeDisplaySettingsEx(dd.DeviceName, &dm, NULL, CDS_TEST, NULL) == DISP_CHANGE_SUCCESSFUL) {
7702 if (ChangeDisplaySettingsEx(dd.DeviceName, &dm, NULL, CDS_UPDATEREGISTRY, NULL) == DISP_CHANGE_SUCCESSFUL)
7713HICON RGFW_loadHandleImage(
u8* src,
i32 c,
RGFW_area a, BOOL icon);
7714HICON RGFW_loadHandleImage(
u8* src,
i32 c,
RGFW_area a, BOOL icon) {
7715 size_t channels = (size_t)c;
7718 ZeroMemory(&bi,
sizeof(bi));
7719 bi.bV5Size =
sizeof(bi);
7720 bi.bV5Width = (
i32)a.
w;
7721 bi.bV5Height = -((LONG) a.
h);
7723 bi.bV5BitCount = (WORD)(channels * 8);
7724 bi.bV5Compression = BI_RGB;
7725 HDC dc = GetDC(NULL);
7728 HBITMAP color = CreateDIBSection(dc,
7729 (BITMAPINFO*) &bi, DIB_RGB_COLORS, (
void**) &target,
7733 for (y = 0; y < a.
h; y++) {
7734 for (x = 0; x < a.
w; x++) {
7735 size_t index = (y * 4 * (size_t)a.
w) + x * channels;
7736 target[index] = src[index + 2];
7737 target[index + 1] = src[index + 1];
7738 target[index + 2] = src[index];
7739 target[index + 3] = src[index + 3];
7743 ReleaseDC(NULL, dc);
7745 HBITMAP mask = CreateBitmap((
i32)a.
w, (
i32)a.
h, 1, 1, NULL);
7748 ZeroMemory(&ii,
sizeof(ii));
7750 ii.xHotspot = a.
w / 2;
7751 ii.yHotspot = a.
h / 2;
7753 ii.hbmColor = color;
7755 HICON handle = CreateIconIndirect(&ii);
7757 DeleteObject(color);
7764 HCURSOR cursor = (HCURSOR) RGFW_loadHandleImage(icon, channels, a, FALSE);
7770 SetClassLongPtrA(win->
src.window, GCLP_HCURSOR, (LPARAM) mouse);
7771 SetCursor((HCURSOR)mouse);
7776 DestroyCursor((HCURSOR)mouse);
7786 static const u32 mouseIconSrc[16] = {OCR_NORMAL, OCR_NORMAL, OCR_IBEAM, OCR_CROSS, OCR_HAND, OCR_SIZEWE, OCR_SIZENS, OCR_SIZENWSE, OCR_SIZENESW, OCR_SIZEALL, OCR_NO};
7787 if (mouse > (
sizeof(mouseIconSrc) /
sizeof(
u32)))
7790 char* icon = MAKEINTRESOURCEA(mouseIconSrc[mouse]);
7792 SetClassLongPtrA(win->
src.window, GCLP_HCURSOR, (LPARAM) LoadCursorA(NULL, icon));
7793 SetCursor(LoadCursorA(NULL, icon));
7798 ShowWindow(win->
src.window, SW_HIDE);
7803 ShowWindow(win->
src.window, SW_RESTORE);
7806#define RGFW_FREE_LIBRARY(x) if (x != NULL) FreeLibrary(x); x = NULL;
7807void RGFW_deinitPlatform(
void) {
7808 #ifndef RGFW_NO_XINPUT
7809 RGFW_FREE_LIBRARY(RGFW_XInput_dll);
7813 RGFW_FREE_LIBRARY(RGFW_Shcore_dll);
7816 #ifndef RGFW_NO_WINMM
7818 #ifndef RGFW_NO_LOAD_WINMM
7819 RGFW_FREE_LIBRARY(RGFW_winmm_dll);
7823 RGFW_FREE_LIBRARY(RGFW_wgl_dll);
7833 DeleteDC(win->
src.hdcMem);
7834 DeleteObject(win->
src.bitmap);
7838 RemovePropW(win->
src.window, L
"RGFW");
7839 ReleaseDC(win->
src.window, win->
src.hdc);
7840 DestroyWindow(win->
src.window);
7842 if (win->
src.hIconSmall) DestroyIcon(win->
src.hIconSmall);
7843 if (win->
src.hIconBig) DestroyIcon(win->
src.hIconBig);
7846 RGFW_clipboard_switch(NULL);
7850 if ((win->
_flags & RGFW_WINDOW_ALLOC)) {
7861 SetWindowPos(win->
src.window, HWND_TOP, win->
r.
x, win->
r.
y, 0, 0, SWP_NOSIZE);
7869 SetWindowPos(win->
src.window, HWND_TOP, 0, 0, win->
r.
w, win->
r.
h + (
i32)win->
src.hOffset, SWP_NOMOVE);
7876 wchar_t wide_name[256];
7877 MultiByteToWideChar(CP_UTF8, 0, name, -1, wide_name, 256);
7878 SetWindowTextW(win->
src.window, wide_name);
7881#ifndef RGFW_NO_PASSTHROUGH
7887 i32 exStyle = GetWindowLongW(win->
src.window, GWL_EXSTYLE);
7889 if (exStyle & WS_EX_LAYERED)
7890 GetLayeredWindowAttributes(win->
src.window, &key, &alpha, &flags);
7893 exStyle |= (WS_EX_TRANSPARENT | WS_EX_LAYERED);
7895 exStyle &= ~WS_EX_TRANSPARENT;
7896 if (exStyle & WS_EX_LAYERED && !(flags & LWA_ALPHA))
7897 exStyle &= ~WS_EX_LAYERED;
7900 SetWindowLongW(win->
src.window, GWL_EXSTYLE, exStyle);
7903 SetLayeredWindowAttributes(win->
src.window, key, alpha, flags);
7912 if (win->
src.hIconSmall && (type & RGFW_iconWindow)) DestroyIcon(win->
src.hIconSmall);
7913 if (win->
src.hIconBig && (type & RGFW_iconTaskbar)) DestroyIcon(win->
src.hIconBig);
7916 HICON defaultIcon = LoadIcon(NULL, IDI_APPLICATION);
7917 if (type & RGFW_iconWindow)
7918 SendMessage(win->
src.window, WM_SETICON, (WPARAM)ICON_SMALL, (LPARAM)defaultIcon);
7919 if (type & RGFW_iconTaskbar)
7920 SendMessage(win->
src.window, WM_SETICON, (WPARAM)ICON_BIG, (LPARAM)defaultIcon);
7924 if (type & RGFW_iconWindow) {
7925 win->
src.hIconSmall = RGFW_loadHandleImage(src, channels, a, TRUE);
7926 SendMessage(win->
src.window, WM_SETICON, (WPARAM)ICON_SMALL, (LPARAM)win->
src.hIconSmall);
7928 if (type & RGFW_iconTaskbar) {
7929 win->
src.hIconBig = RGFW_loadHandleImage(src, channels, a, TRUE);
7930 SendMessage(win->
src.window, WM_SETICON, (WPARAM)ICON_BIG, (LPARAM)win->
src.hIconBig);
7943 if (OpenClipboard(NULL) == 0)
7947 HANDLE hData = GetClipboardData(CF_UNICODETEXT);
7948 if (hData == NULL) {
7953 wchar_t* wstr = (
wchar_t*) GlobalLock(hData);
7958 setlocale(LC_ALL,
"en_US.UTF-8");
7961 if (str != NULL && (
RGFW_ssize_t)strCapacity <= textLen - 1)
7964 if (str != NULL && textLen) {
7966 wcstombs(str, wstr, (
size_t)(textLen));
7968 str[textLen] =
'\0';
7973 GlobalUnlock(hData);
7983 object = GlobalAlloc(GMEM_MOVEABLE, (1 + textLen) *
sizeof(WCHAR));
7987 buffer = (WCHAR*) GlobalLock(
object);
7993 MultiByteToWideChar(CP_UTF8, 0, text, -1, buffer, (
i32)textLen);
7994 GlobalUnlock(
object);
7996 if (!OpenClipboard(_RGFW->
root->
src.window)) {
8002 SetClipboardData(CF_UNICODETEXT,
object);
8009 SetCursorPos(p.
x, p.
y);
8015 wglMakeCurrent(NULL, NULL);
8017 wglMakeCurrent(win->
src.hdc, (HGLRC) win->
src.ctx);
8026#if defined(RGFW_OPENGL)
8027 if (wglSwapIntervalEXT == NULL || wglSwapIntervalEXT(swapInterval) == FALSE)
8036#if defined(RGFW_BUFFER)
8037 if (win->buffer != win->
src.bitmapBits)
8038 memcpy(win->
src.bitmapBits, win->buffer, win->bufferSize.w * win->bufferSize.h * 4);
8040 RGFW_RGB_to_BGR(win, win->
src.bitmapBits);
8041 BitBlt(win->
src.hdc, 0, 0, win->
r.
w, win->
r.
h, win->
src.hdcMem, 0, 0, SRCCOPY);
8047char* RGFW_createUTF8FromWideStringWin32(
const WCHAR* source) {
8050 if (source == NULL) {
8053 size = WideCharToMultiByte(CP_UTF8, 0, source, -1, NULL, 0, NULL, NULL);
8063 if (!WideCharToMultiByte(CP_UTF8, 0, source, -1, target, size, NULL, NULL)) {
8071 static u64 frequency = 0;
8072 if (frequency == 0) QueryPerformanceFrequency((LARGE_INTEGER*)&frequency);
8079 QueryPerformanceCounter((LARGE_INTEGER*)&value);
8101#if defined(RGFW_MACOS)
8107#include <CoreGraphics/CoreGraphics.h>
8108#include <ApplicationServices/ApplicationServices.h>
8109#include <objc/runtime.h>
8110#include <objc/message.h>
8111#include <mach/mach_time.h>
8112#include <CoreVideo/CoreVideo.h>
8114typedef CGRect NSRect;
8115typedef CGPoint NSPoint;
8116typedef CGSize NSSize;
8118typedef const char* NSPasteboardType;
8119typedef unsigned long NSUInteger;
8120typedef long NSInteger;
8121typedef NSInteger NSModalResponse;
8125#define abi_objc_msgSend_stret objc_msgSend
8126#define abi_objc_msgSend_fpret objc_msgSend
8129#define abi_objc_msgSend_stret objc_msgSend_stret
8130#define abi_objc_msgSend_fpret objc_msgSend_fpret
8133#define NSAlloc(nsclass) objc_msgSend_id((id)nsclass, sel_registerName("alloc"))
8134#define objc_msgSend_bool(x, y) ((BOOL (*)(id, SEL))objc_msgSend) ((id)(x), (SEL)y)
8135#define objc_msgSend_void(x, y) ((void (*)(id, SEL))objc_msgSend) ((id)(x), (SEL)y)
8136#define objc_msgSend_void_id(x, y, z) ((void (*)(id, SEL, id))objc_msgSend) ((id)x, (SEL)y, (id)z)
8137#define objc_msgSend_uint(x, y) ((NSUInteger (*)(id, SEL))objc_msgSend) ((id)(x), (SEL)y)
8138#define objc_msgSend_void_bool(x, y, z) ((void (*)(id, SEL, BOOL))objc_msgSend) ((id)(x), (SEL)y, (BOOL)z)
8139#define objc_msgSend_bool_void(x, y) ((BOOL (*)(id, SEL))objc_msgSend) ((id)(x), (SEL)y)
8140#define objc_msgSend_void_SEL(x, y, z) ((void (*)(id, SEL, SEL))objc_msgSend) ((id)(x), (SEL)y, (SEL)z)
8141#define objc_msgSend_id(x, y) ((id (*)(id, SEL))objc_msgSend) ((id)(x), (SEL)y)
8142#define objc_msgSend_id_id(x, y, z) ((id (*)(id, SEL, id))objc_msgSend) ((id)(x), (SEL)y, (id)z)
8143#define objc_msgSend_id_bool(x, y, z) ((BOOL (*)(id, SEL, id))objc_msgSend) ((id)(x), (SEL)y, (id)z)
8144#define objc_msgSend_int(x, y, z) ((id (*)(id, SEL, int))objc_msgSend) ((id)(x), (SEL)y, (int)z)
8145#define objc_msgSend_arr(x, y, z) ((id (*)(id, SEL, int))objc_msgSend) ((id)(x), (SEL)y, (int)z)
8146#define objc_msgSend_ptr(x, y, z) ((id (*)(id, SEL, void*))objc_msgSend) ((id)(x), (SEL)y, (void*)z)
8147#define objc_msgSend_class(x, y) ((id (*)(Class, SEL))objc_msgSend) ((Class)(x), (SEL)y)
8148#define objc_msgSend_class_char(x, y, z) ((id (*)(Class, SEL, char*))objc_msgSend) ((Class)(x), (SEL)y, (char*)z)
8150#define NSRelease(obj) objc_msgSend_void((id)obj, sel_registerName("release"))
8151id NSString_stringWithUTF8String(
const char* str);
8152id NSString_stringWithUTF8String(
const char* str) {
8153 return ((
id(*)(
id,
SEL,
const char*))objc_msgSend)
8154 ((id)objc_getClass(
"NSString"), sel_registerName(
"stringWithUTF8String:"), str);
8157const char* NSString_to_char(
id str);
8158const char* NSString_to_char(
id str) {
8159 return ((
const char* (*)(
id,
SEL)) objc_msgSend) ((id)(
id)str, sel_registerName(
"UTF8String"));
8162void si_impl_func_to_SEL_with_name(
const char* class_name,
const char* register_name,
void* function);
8163void si_impl_func_to_SEL_with_name(
const char* class_name,
const char* register_name,
void* function) {
8164 Class selected_class;
8167 selected_class = objc_getClass(
"ViewClass");
8168 }
else if (
RGFW_STRNCMP(class_name,
"NSWindow", 8) == 0) {
8169 selected_class = objc_getClass(
"WindowClass");
8171 selected_class = objc_getClass(class_name);
8174 class_addMethod(selected_class, sel_registerName(register_name), (IMP) function, 0);
8178typedef struct siArrayHeader {
8184#define SI_ARRAY_HEADER(s) ((siArrayHeader*)s - 1)
8185#define si_array_len(array) (SI_ARRAY_HEADER(array)->count)
8186#define si_func_to_SEL(class_name, function) si_impl_func_to_SEL_with_name(class_name, #function":", (void*)function)
8188#define si_func_to_SEL_with_name(class_name, register_name, function) si_impl_func_to_SEL_with_name(class_name, register_name":", (void*)function)
8190unsigned char* NSBitmapImageRep_bitmapData(
id imageRep);
8191unsigned char* NSBitmapImageRep_bitmapData(
id imageRep) {
8192 return ((
unsigned char* (*)(
id,
SEL))objc_msgSend) ((id)imageRep, sel_registerName(
"bitmapData"));
8195typedef RGFW_ENUM(NSUInteger, NSBitmapFormat) {
8196 NSBitmapFormatAlphaFirst = 1 << 0,
8197 NSBitmapFormatAlphaNonpremultiplied = 1 << 1,
8198 NSBitmapFormatFloatingpointSamples = 1 << 2,
8200 NSBitmapFormatSixteenBitLittleEndian = (1 << 8),
8201 NSBitmapFormatThirtyTwoBitLittleEndian = (1 << 9),
8202 NSBitmapFormatSixteenBitBigEndian = (1 << 10),
8203 NSBitmapFormatThirtyTwoBitBigEndian = (1 << 11)
8206id NSBitmapImageRep_initWithBitmapData(
unsigned char** planes, NSInteger width, NSInteger height, NSInteger bps, NSInteger spp,
bool alpha,
bool isPlanar,
const char* colorSpaceName, NSBitmapFormat bitmapFormat, NSInteger rowBytes, NSInteger pixelBits);
8207id NSBitmapImageRep_initWithBitmapData(
unsigned char** planes, NSInteger width, NSInteger height, NSInteger bps, NSInteger spp,
bool alpha,
bool isPlanar,
const char* colorSpaceName, NSBitmapFormat bitmapFormat, NSInteger rowBytes, NSInteger pixelBits) {
8208 SEL func = sel_registerName(
"initWithBitmapDataPlanes:pixelsWide:pixelsHigh:bitsPerSample:samplesPerPixel:hasAlpha:isPlanar:colorSpaceName:bitmapFormat:bytesPerRow:bitsPerPixel:");
8210 return (
id) ((id(*)(id, SEL,
unsigned char**, NSInteger, NSInteger, NSInteger, NSInteger, bool, bool, id, NSBitmapFormat, NSInteger, NSInteger))objc_msgSend)
8211 (NSAlloc((
id)objc_getClass(
"NSBitmapImageRep")), func, planes, width, height, bps, spp, alpha, isPlanar, NSString_stringWithUTF8String(colorSpaceName), bitmapFormat, rowBytes, pixelBits);
8214id NSColor_colorWithSRGB(CGFloat red, CGFloat green, CGFloat blue, CGFloat alpha);
8215id NSColor_colorWithSRGB(CGFloat red, CGFloat green, CGFloat blue, CGFloat alpha) {
8216 void* nsclass = objc_getClass(
"NSColor");
8217 SEL func = sel_registerName(
"colorWithSRGBRed:green:blue:alpha:");
8218 return ((
id(*)(
id,
SEL, CGFloat, CGFloat, CGFloat, CGFloat))objc_msgSend)
8219 ((id)nsclass, func, red, green, blue, alpha);
8222typedef RGFW_ENUM(NSInteger, NSOpenGLContextParameter) {
8223 NSOpenGLContextParameterSwapInterval = 222,
8224 NSOpenGLContextParametectxaceOrder = 235,
8225 NSOpenGLContextParametectxaceOpacity = 236,
8226 NSOpenGLContextParametectxaceBackingSize = 304,
8227 NSOpenGLContextParameterReclaimResources = 308,
8228 NSOpenGLContextParameterCurrentRendererID = 309,
8229 NSOpenGLContextParameterGPUVertexProcessing = 310,
8230 NSOpenGLContextParameterGPUFragmentProcessing = 311,
8231 NSOpenGLContextParameterHasDrawable = 314,
8232 NSOpenGLContextParameterMPSwapsInFlight = 315,
8234 NSOpenGLContextParameterSwapRectangle API_DEPRECATED(
"", macos(10.0, 10.14)) = 200,
8235 NSOpenGLContextParameterSwapRectangleEnable API_DEPRECATED(
"", macos(10.0, 10.14)) = 201,
8236 NSOpenGLContextParameterRasterizationEnable API_DEPRECATED(
"", macos(10.0, 10.14)) = 221,
8237 NSOpenGLContextParameterStateValidation API_DEPRECATED(
"", macos(10.0, 10.14)) = 301,
8238 NSOpenGLContextParametectxaceSurfaceVolatile API_DEPRECATED(
"", macos(10.0, 10.14)) = 306,
8241typedef RGFW_ENUM(NSInteger, NSWindowButton) {
8242 NSWindowCloseButton = 0,
8243 NSWindowMiniaturizeButton = 1,
8244 NSWindowZoomButton = 2,
8245 NSWindowToolbarButton = 3,
8246 NSWindowDocumentIconButton = 4,
8247 NSWindowDocumentVersionsButton = 6,
8248 NSWindowFullScreenButton = 7,
8250void NSOpenGLContext_setValues(
id context,
const int* vals, NSOpenGLContextParameter param);
8251void NSOpenGLContext_setValues(
id context,
const int* vals, NSOpenGLContextParameter param) {
8252 ((void (*)(id, SEL,
const int*, NSOpenGLContextParameter))objc_msgSend)
8253 (context, sel_registerName(
"setValues:forParameter:"), vals, param);
8255void* NSOpenGLPixelFormat_initWithAttributes(
const uint32_t* attribs);
8256void* NSOpenGLPixelFormat_initWithAttributes(
const uint32_t* attribs) {
8257 return (
void*) ((id(*)(id, SEL,
const uint32_t*))objc_msgSend)
8258 (NSAlloc((
id)objc_getClass(
"NSOpenGLPixelFormat")), sel_registerName(
"initWithAttributes:"), attribs);
8261id NSPasteboard_generalPasteboard(
void);
8262id NSPasteboard_generalPasteboard(
void) {
8263 return (
id) objc_msgSend_id((
id)objc_getClass(
"NSPasteboard"), sel_registerName(
"generalPasteboard"));
8266id* cstrToNSStringArray(
char** strs,
size_t len);
8267id* cstrToNSStringArray(
char** strs,
size_t len) {
8270 for (i = 0; i < len; i++)
8271 nstrs[i] = NSString_stringWithUTF8String(strs[i]);
8276const char* NSPasteboard_stringForType(
id pasteboard, NSPasteboardType dataType,
size_t* len);
8277const char* NSPasteboard_stringForType(
id pasteboard, NSPasteboardType dataType,
size_t* len) {
8278 SEL func = sel_registerName(
"stringForType:");
8279 id nsstr = NSString_stringWithUTF8String(dataType);
8280 id nsString = ((id(*)(id, SEL, id))objc_msgSend)(pasteboard, func, nsstr);
8281 const char* str = NSString_to_char(nsString);
8283 *len = (size_t)((NSUInteger(*)(
id,
SEL,
int))objc_msgSend)(nsString, sel_registerName(
"maximumLengthOfBytesUsingEncoding:"), 4);
8287id c_array_to_NSArray(
void* array,
size_t len);
8288id c_array_to_NSArray(
void* array,
size_t len) {
8289 SEL func = sel_registerName(
"initWithObjects:count:");
8290 void* nsclass = objc_getClass(
"NSArray");
8291 return ((
id (*)(
id,
SEL,
void*, NSUInteger))objc_msgSend)
8292 (NSAlloc(nsclass), func, array, len);
8296void NSregisterForDraggedTypes(
id view, NSPasteboardType* newTypes,
size_t len);
8297void NSregisterForDraggedTypes(
id view, NSPasteboardType* newTypes,
size_t len) {
8298 id* ntypes = cstrToNSStringArray((
char**)newTypes, len);
8300 id array = c_array_to_NSArray(ntypes, len);
8301 objc_msgSend_void_id(view, sel_registerName(
"registerForDraggedTypes:"), array);
8305NSInteger NSPasteBoard_declareTypes(
id pasteboard, NSPasteboardType* newTypes,
size_t len,
void* owner);
8306NSInteger NSPasteBoard_declareTypes(
id pasteboard, NSPasteboardType* newTypes,
size_t len,
void* owner) {
8307 id* ntypes = cstrToNSStringArray((
char**)newTypes, len);
8309 SEL func = sel_registerName(
"declareTypes:owner:");
8311 id array = c_array_to_NSArray(ntypes, len);
8313 NSInteger output = ((NSInteger(*)(id, SEL, id,
void*))objc_msgSend)
8314 (pasteboard, func, array, owner);
8320#define NSRetain(obj) objc_msgSend_void((id)obj, sel_registerName("retain"))
8322typedef enum NSApplicationActivationPolicy {
8323 NSApplicationActivationPolicyRegular,
8324 NSApplicationActivationPolicyAccessory,
8325 NSApplicationActivationPolicyProhibited
8326} NSApplicationActivationPolicy;
8329 NSBackingStoreRetained = 0,
8330 NSBackingStoreNonretained = 1,
8331 NSBackingStoreBuffered = 2
8335 NSWindowStyleMaskBorderless = 0,
8336 NSWindowStyleMaskTitled = 1 << 0,
8337 NSWindowStyleMaskClosable = 1 << 1,
8338 NSWindowStyleMaskMiniaturizable = 1 << 2,
8339 NSWindowStyleMaskResizable = 1 << 3,
8340 NSWindowStyleMaskTexturedBackground = 1 << 8,
8341 NSWindowStyleMaskUnifiedTitleAndToolbar = 1 << 12,
8342 NSWindowStyleMaskFullScreen = 1 << 14,
8343 NSWindowStyleMaskFullSizeContentView = 1 << 15,
8344 NSWindowStyleMaskUtilityWindow = 1 << 4,
8345 NSWindowStyleMaskDocModalWindow = 1 << 6,
8346 NSWindowStyleMaskNonactivatingpanel = 1 << 7,
8347 NSWindowStyleMaskHUDWindow = 1 << 13
8350#define NSPasteboardTypeString "public.utf8-plain-text"
8353 NSDragOperationNone = 0,
8354 NSDragOperationCopy = 1,
8355 NSDragOperationLink = 2,
8356 NSDragOperationGeneric = 4,
8357 NSDragOperationPrivate = 8,
8358 NSDragOperationMove = 16,
8359 NSDragOperationDelete = 32,
8360 NSDragOperationEvery = (int)ULONG_MAX
8363void* NSArray_objectAtIndex(
id array, NSUInteger index) {
8364 SEL func = sel_registerName(
"objectAtIndex:");
8365 return ((
id(*)(
id,
SEL, NSUInteger))objc_msgSend)(array, func, index);
8368id NSWindow_contentView(
id window) {
8369 SEL func = sel_registerName(
"contentView");
8370 return objc_msgSend_id(window, func);
8382 static CFBundleRef RGFWnsglFramework = NULL;
8383 if (RGFWnsglFramework == NULL)
8384 RGFWnsglFramework = CFBundleGetBundleWithIdentifier(CFSTR(
"com.apple.opengl"));
8386 CFStringRef symbolName = CFStringCreateWithCString(kCFAllocatorDefault, procname, kCFStringEncodingASCII);
8388 RGFW_proc symbol = (
RGFW_proc)CFBundleGetFunctionPointerForName(RGFWnsglFramework, symbolName);
8390 CFRelease(symbolName);
8397 return (
id) objc_msgSend_id((
id)win->
src.window, sel_registerName(
"delegate"));
8400u32 RGFW_OnClose(
id self) {
8402 object_getInstanceVariable(self, (
const char*)
"RGFW_window", (
void**)&win);
8407 RGFW_windowQuitCallback(win);
8413bool acceptsFirstResponder(
void) {
return true; }
8414bool performKeyEquivalent(
id event) {
RGFW_UNUSED(event);
return true; }
8416NSDragOperation draggingEntered(
id self,
SEL sel,
id sender) {
8419 return NSDragOperationCopy;
8421NSDragOperation draggingUpdated(
id self,
SEL sel,
id sender) {
8425 object_getInstanceVariable(self,
"RGFW_window", (
void**)&win);
8426 if (win == NULL || (!(win->
_flags & RGFW_windowAllowDND)))
8429 NSPoint p = ((NSPoint(*)(id, SEL)) objc_msgSend)(sender, sel_registerName(
"draggingLocation"));
8435 return NSDragOperationCopy;
8437bool prepareForDragOperation(
id self) {
8439 object_getInstanceVariable(self,
"RGFW_window", (
void**)&win);
8443 if (!(win->
_flags & RGFW_windowAllowDND)) {
8450void RGFW__osxDraggingEnded(
id self,
SEL sel,
id sender);
8454bool performDragOperation(
id self,
SEL sel,
id sender) {
8458 object_getInstanceVariable(self,
"RGFW_window", (
void**)&win);
8465 id pasteBoard = objc_msgSend_id(sender, sel_registerName(
"draggingPasteboard"));
8468 id types = objc_msgSend_id(pasteBoard, sel_registerName(
"types"));
8471 id fileURLsType = objc_msgSend_class_char(objc_getClass(
"NSString"), sel_registerName(
"stringWithUTF8String:"),
"NSFilenamesPboardType");
8474 if (objc_msgSend_id_bool(types, sel_registerName(
"containsObject:"), fileURLsType) == 0) {
8479 id fileURLs = objc_msgSend_id_id(pasteBoard, sel_registerName(
"propertyListForType:"), fileURLsType);
8480 int count = ((int (*)(id, SEL))objc_msgSend)(fileURLs, sel_registerName(
"count"));
8486 for (i = 0; i < count; i++) {
8487 id fileURL = objc_msgSend_arr(fileURLs, sel_registerName(
"objectAtIndex:"), i);
8488 const char *filePath = ((
const char* (*)(
id,
SEL))objc_msgSend)(fileURL, sel_registerName(
"UTF8String"));
8492 NSPoint p = ((NSPoint(*)(id, SEL)) objc_msgSend)(sender, sel_registerName(
"draggingLocation"));
8505#ifndef RGFW_NO_IOKIT
8506#include <IOKit/IOKitLib.h>
8507#include <IOKit/hid/IOHIDManager.h>
8509u32 RGFW_osx_getFallbackRefreshRate(CGDirectDisplayID displayID) {
8510 u32 refreshRate = 0;
8512 io_service_t service;
8513 CFNumberRef indexRef, clockRef, countRef;
8514 uint32_t clock, count;
8516#ifdef kIOMainPortDefault
8517 if (IOServiceGetMatchingServices(kIOMainPortDefault, IOServiceMatching(
"IOFramebuffer"), &it) != 0)
8518#elif defined(kIOMasterPortDefault)
8519 if (IOServiceGetMatchingServices(kIOMainPortDefault, IOServiceMatching(
"IOFramebuffer"), &it) != 0)
8523 while ((service = IOIteratorNext(it)) != 0) {
8525 indexRef = (CFNumberRef)IORegistryEntryCreateCFProperty(service, CFSTR(
"IOFramebufferOpenGLIndex"), kCFAllocatorDefault, kNilOptions);
8526 if (indexRef == 0)
continue;
8528 if (CFNumberGetValue(indexRef, kCFNumberIntType, &index) && CGOpenGLDisplayMaskToDisplayID(1 << index) == displayID) {
8529 CFRelease(indexRef);
8533 CFRelease(indexRef);
8537 clockRef = (CFNumberRef)IORegistryEntryCreateCFProperty(service, CFSTR(
"IOFBCurrentPixelClock"), kCFAllocatorDefault, kNilOptions);
8539 if (CFNumberGetValue(clockRef, kCFNumberIntType, &clock) && clock) {
8540 countRef = (CFNumberRef)IORegistryEntryCreateCFProperty(service, CFSTR(
"IOFBCurrentPixelCount"), kCFAllocatorDefault, kNilOptions);
8541 if (countRef && CFNumberGetValue(countRef, kCFNumberIntType, &count) && count) {
8543 CFRelease(countRef);
8546 CFRelease(clockRef);
8550 IOObjectRelease(it);
8554size_t findControllerIndex(IOHIDDeviceRef device) {
8556 for (i = 0; i < 4; i++)
8557 if (_RGFW->osxControllers[i] == device)
8562void RGFW__osxInputValueChangedCallback(
void *context, IOReturn result,
void *sender, IOHIDValueRef value) {
8564 IOHIDElementRef element = IOHIDValueGetElement(value);
8566 IOHIDDeviceRef device = IOHIDElementGetDevice(element);
8567 size_t index = findControllerIndex(device);
8568 if (index == (
size_t)-1)
return;
8570 uint32_t usagePage = IOHIDElementGetUsagePage(element);
8571 uint32_t usage = IOHIDElementGetUsage(element);
8573 CFIndex intValue = IOHIDValueGetIntegerValue(value);
8575 u8 RGFW_osx2RGFWSrc[2][RGFW_gamepadFinal] = {{
8576 0, RGFW_gamepadSelect, RGFW_gamepadL3, RGFW_gamepadR3, RGFW_gamepadStart,
8577 RGFW_gamepadUp, RGFW_gamepadRight, RGFW_gamepadDown, RGFW_gamepadLeft,
8578 RGFW_gamepadL2, RGFW_gamepadR2, RGFW_gamepadL1, RGFW_gamepadR1,
8579 RGFW_gamepadY, RGFW_gamepadB, RGFW_gamepadA, RGFW_gamepadX, RGFW_gamepadHome},
8580 {0, RGFW_gamepadA, RGFW_gamepadB, RGFW_gamepadR3, RGFW_gamepadX,
8581 RGFW_gamepadY, RGFW_gamepadRight, RGFW_gamepadL1, RGFW_gamepadR1,
8582 RGFW_gamepadL2, RGFW_gamepadR2, RGFW_gamepadDown, RGFW_gamepadStart,
8583 RGFW_gamepadUp, RGFW_gamepadL3, RGFW_gamepadSelect, RGFW_gamepadStart, RGFW_gamepadHome}
8586 u8* RGFW_osx2RGFW = RGFW_osx2RGFWSrc[0];
8588 RGFW_osx2RGFW = RGFW_osx2RGFWSrc[1];
8590 switch (usagePage) {
8591 case kHIDPage_Button: {
8593 if (usage <
sizeof(RGFW_osx2RGFW))
8594 button = RGFW_osx2RGFW[usage];
8596 RGFW_gamepadButtonCallback(_RGFW->
root, (
u16)index, button, (
u8)intValue);
8597 RGFW_gamepadPressed[index][button].prev = RGFW_gamepadPressed[index][button].current;
8598 RGFW_gamepadPressed[index][button].current =
RGFW_BOOL(intValue);
8605 case kHIDPage_GenericDesktop: {
8606 CFIndex logicalMin = IOHIDElementGetLogicalMin(element);
8607 CFIndex logicalMax = IOHIDElementGetLogicalMax(element);
8609 if (logicalMax <= logicalMin)
return;
8610 if (intValue < logicalMin) intValue = logicalMin;
8611 if (intValue > logicalMax) intValue = logicalMax;
8613 i8 axisValue = (
i8)(-100.0 + ((intValue - logicalMin) * 200.0) / (logicalMax - logicalMin));
8617 case kHIDUsage_GD_X: _RGFW->
gamepadAxes[index][0].
x = axisValue; whichAxis = 0;
break;
8618 case kHIDUsage_GD_Y: _RGFW->
gamepadAxes[index][0].
y = axisValue; whichAxis = 0;
break;
8619 case kHIDUsage_GD_Z: _RGFW->
gamepadAxes[index][1].
x = axisValue; whichAxis = 1;
break;
8620 case kHIDUsage_GD_Rz: _RGFW->
gamepadAxes[index][1].
y = axisValue; whichAxis = 1;
break;
8625 e.
type = RGFW_gamepadAxisMove;
8629 for (
size_t i = 0; i < 4; i++)
8634 RGFW_gamepadAxisCallback(_RGFW->
root, (
u16)index, _RGFW->
gamepadAxes[index], 2, whichAxis);
8639void RGFW__osxDeviceAddedCallback(
void* context, IOReturn result,
void *sender, IOHIDDeviceRef device) {
8641 CFTypeRef usageRef = (CFTypeRef)IOHIDDeviceGetProperty(device, CFSTR(kIOHIDPrimaryUsageKey));
8644 CFNumberGetValue((CFNumberRef)usageRef, kCFNumberIntType, (
void*)&usage);
8646 if (usage != kHIDUsage_GD_Joystick && usage != kHIDUsage_GD_GamePad && usage != kHIDUsage_GD_MultiAxisController) {
8651 for (i = 0; i < 4; i++) {
8652 if (_RGFW->osxControllers[i] != NULL)
8655 _RGFW->osxControllers[i] = device;
8657 IOHIDDeviceRegisterInputValueCallback(device, RGFW__osxInputValueChangedCallback, NULL);
8659 CFStringRef deviceName = (CFStringRef)IOHIDDeviceGetProperty(device, CFSTR(kIOHIDProductKey));
8680 RGFW_gamepadCallback(_RGFW->
root, (
u16)i, 1);
8685void RGFW__osxDeviceRemovedCallback(
void *context, IOReturn result,
void *sender, IOHIDDeviceRef device) {
8687 CFNumberRef usageRef = (CFNumberRef)IOHIDDeviceGetProperty(device, CFSTR(kIOHIDPrimaryUsageKey));
8690 CFNumberGetValue(usageRef, kCFNumberIntType, &usage);
8692 if (usage != kHIDUsage_GD_Joystick && usage != kHIDUsage_GD_GamePad && usage != kHIDUsage_GD_MultiAxisController) {
8696 size_t index = findControllerIndex(device);
8697 if (index != (
size_t)-1)
8698 _RGFW->osxControllers[index] = NULL;
8703 RGFW_gamepadCallback(_RGFW->
root, (
u16)index, 0);
8708RGFWDEF void RGFW_osxInitIOKit(
void);
8709void RGFW_osxInitIOKit(
void) {
8710 IOHIDManagerRef hidManager = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone);
8716 CFMutableDictionaryRef matchingDictionary = CFDictionaryCreateMutable(
8717 kCFAllocatorDefault,
8719 &kCFTypeDictionaryKeyCallBacks,
8720 &kCFTypeDictionaryValueCallBacks
8722 if (!matchingDictionary) {
8724 CFRelease(hidManager);
8728 CFDictionarySetValue(
8730 CFSTR(kIOHIDDeviceUsagePageKey),
8731 CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, (
int[]){kHIDPage_GenericDesktop})
8734 IOHIDManagerSetDeviceMatching(hidManager, matchingDictionary);
8736 IOHIDManagerRegisterDeviceMatchingCallback(hidManager, RGFW__osxDeviceAddedCallback, NULL);
8737 IOHIDManagerRegisterDeviceRemovalCallback(hidManager, RGFW__osxDeviceRemovedCallback, NULL);
8739 IOHIDManagerScheduleWithRunLoop(hidManager, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
8741 IOHIDManagerOpen(hidManager, kIOHIDOptionsTypeNone);
8744 CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0,
false);
8749 char resourcesPath[256];
8751 CFBundleRef bundle = CFBundleGetMainBundle();
8755 CFURLRef resourcesURL = CFBundleCopyResourcesDirectoryURL(bundle);
8756 CFStringRef last = CFURLCopyLastPathComponent(resourcesURL);
8759 CFStringCompare(CFSTR(
"Resources"), last, 0) != kCFCompareEqualTo ||
8760 CFURLGetFileSystemRepresentation(resourcesURL,
true, (
u8*) resourcesPath, 255) == 0
8763 CFRelease(resourcesURL);
8768 CFRelease(resourcesURL);
8770 chdir(resourcesPath);
8774void RGFW__osxWindowDeminiaturize(
id self,
SEL sel) {
8777 object_getInstanceVariable(self,
"RGFW_window", (
void**)&win);
8778 if (win == NULL)
return;
8780 win->
_flags |= RGFW_windowMinimize;
8782 RGFW_windowRestoredCallback(win, win->
r);
8785void RGFW__osxWindowMiniaturize(
id self,
SEL sel) {
8788 object_getInstanceVariable(self,
"RGFW_window", (
void**)&win);
8789 if (win == NULL)
return;
8791 win->
_flags &= ~(
u32)RGFW_windowMinimize;
8793 RGFW_windowMinimizedCallback(win, win->
r);
8797void RGFW__osxWindowBecameKey(
id self,
SEL sel) {
8800 object_getInstanceVariable(self,
"RGFW_window", (
void**)&win);
8801 if (win == NULL)
return;
8803 win->
_flags |= RGFW_windowFocus;
8811void RGFW__osxWindowResignKey(
id self,
SEL sel) {
8814 object_getInstanceVariable(self,
"RGFW_window", (
void**)&win);
8815 if (win == NULL)
return;
8817 RGFW_window_focusLost(win);
8822NSSize RGFW__osxWindowResize(
id self,
SEL sel, NSSize frameSize) {
8826 object_getInstanceVariable(self,
"RGFW_window", (
void**)&win);
8827 if (win == NULL)
return frameSize;
8829 win->
r.
w = (
i32)frameSize.width;
8830 win->
r.
h = (
i32)frameSize.height;
8834 win->
_flags |= RGFW_windowMaximize;
8836 RGFW_windowMaximizedCallback(win, win->
r);
8837 }
else if (win->
_flags & RGFW_windowMaximize) {
8838 win->
_flags &= ~(
u32)RGFW_windowMaximize;
8840 RGFW_windowRestoredCallback(win, win->
r);
8846 RGFW_windowResizedCallback(win, win->
r);
8850void RGFW__osxWindowMove(
id self,
SEL sel) {
8854 object_getInstanceVariable(self,
"RGFW_window", (
void**)&win);
8855 if (win == NULL)
return;
8857 NSRect frame = ((NSRect(*)(id, SEL))abi_objc_msgSend_stret)((
id)win->
src.window, sel_registerName(
"frame"));
8858 win->
r.
x = (
i32) frame.origin.x;
8859 win->
r.
y = (
i32) frame.origin.y;
8862 RGFW_windowMovedCallback(win, win->
r);
8865void RGFW__osxViewDidChangeBackingProperties(
id self,
SEL _cmd) {
8868 object_getInstanceVariable(self,
"RGFW_window", (
void**)&win);
8869 if (win == NULL)
return;
8872 RGFW_scaleUpdatedCallback(win, mon.
scaleX, mon.
scaleY);
8876void RGFW__osxDrawRect(
id self,
SEL _cmd, CGRect rect) {
8879 object_getInstanceVariable(self,
"RGFW_window", (
void**)&win);
8880 if (win == NULL)
return;
8883 RGFW_windowRefreshCallback(win);
8887 #if defined(RGFW_BUFFER)
8888 win->buffer = buffer;
8889 win->bufferSize = area;
8890 win->
_flags |= RGFW_BUFFER_ALLOC;
8896void RGFW_window_cocoaSetLayer(
RGFW_window* win,
void* layer) {
8897 objc_msgSend_void_id((
id)win->
src.view, sel_registerName(
"setLayer"), (
id)layer);
8900void* RGFW_cocoaGetLayer(
void) {
8901 return objc_msgSend_class((
id)objc_getClass(
"CAMetalLayer"), (
SEL)sel_registerName(
"layer"));
8904#define NSPasteboardTypeURL "public.url"
8905#define NSPasteboardTypeFileURL "public.file-url"
8907id RGFW__osx_generateViewClass(
const char* subclass,
RGFW_window* win) {
8908 Class customViewClass;
8909 customViewClass = objc_allocateClassPair(objc_getClass(subclass),
"RGFWCustomView", 0);
8912 class_addMethod(customViewClass, sel_registerName(
"drawRect:"), (IMP)RGFW__osxDrawRect,
"v@:{CGRect=ffff}");
8913 class_addMethod(customViewClass, sel_registerName(
"viewDidChangeBackingProperties"), (IMP)RGFW__osxViewDidChangeBackingProperties,
"");
8915 id customView = objc_msgSend_id(NSAlloc(customViewClass), sel_registerName(
"init"));
8916 object_setInstanceVariable(customView,
"RGFW_window", win);
8924 void* attrs = RGFW_initFormatAttribs();
8925 void* format = NSOpenGLPixelFormat_initWithAttributes((uint32_t*)attrs);
8927 if (format == NULL) {
8929 win->
_flags |= RGFW_windowOpenglSoftware;
8930 void* subAttrs = RGFW_initFormatAttribs();
8931 format = NSOpenGLPixelFormat_initWithAttributes((uint32_t*)subAttrs);
8942 win->
src.view = (id) ((
id(*)(
id,
SEL, NSRect, uint32_t*))objc_msgSend) (RGFW__osx_generateViewClass(
"NSOpenGLView", win),
8943 sel_registerName(
"initWithFrame:pixelFormat:"), (NSRect){{0, 0}, {win->
r.
w, win->
r.
h}}, (uint32_t*)format);
8945 objc_msgSend_void(win->
src.view, sel_registerName(
"prepareOpenGL"));
8946 win->
src.ctx = objc_msgSend_id(win->
src.view, sel_registerName(
"openGLContext"));
8948 if (win->
_flags & RGFW_windowTransparent) {
8950 #define NSOpenGLCPSurfaceOpacity 236
8951 NSOpenGLContext_setValues((
id)win->
src.ctx, &opacity, NSOpenGLCPSurfaceOpacity);
8954 objc_msgSend_void(win->
src.ctx, sel_registerName(
"makeCurrentContext"));
8963 if (win->
src.ctx == NULL)
return;
8964 objc_msgSend_void(win->
src.ctx, sel_registerName(
"release"));
8965 win->
src.ctx = NULL;
8974i32 RGFW_initPlatform(
void) {
8978 si_func_to_SEL_with_name(
"NSObject",
"windowShouldClose", (
void*)RGFW_OnClose);
8981 si_func_to_SEL(
"NSWindow", acceptsFirstResponder);
8982 si_func_to_SEL(
"NSWindow", performKeyEquivalent);
8984 if ((
id)_RGFW->NSApp == NULL) {
8985 _RGFW->NSApp = objc_msgSend_id((
id)objc_getClass(
"NSApplication"), sel_registerName(
"sharedApplication"));
8987 ((void (*)(id, SEL, NSUInteger))objc_msgSend)
8988 ((
id)_RGFW->NSApp, sel_registerName(
"setActivationPolicy:"), NSApplicationActivationPolicyRegular);
8990 #ifndef RGFW_NO_IOKIT
8991 RGFW_osxInitIOKit();
8998 static u8 RGFW_loaded = 0;
8999 RGFW_window_basic_init(win, rect, flags);
9002 id pool = objc_msgSend_class(objc_getClass(
"NSAutoreleasePool"), sel_registerName(
"alloc"));
9003 pool = objc_msgSend_id(pool, sel_registerName(
"init"));
9008 windowRect.origin.x = win->
r.
x;
9009 windowRect.origin.y = win->
r.
y;
9010 windowRect.size.width = win->
r.
w;
9011 windowRect.size.height = win->
r.
h;
9013 NSBackingStoreType macArgs = NSWindowStyleMaskClosable | NSWindowStyleMaskMiniaturizable | NSBackingStoreBuffered | NSWindowStyleMaskTitled;
9015 if (!(flags & RGFW_windowNoResize))
9016 macArgs |= NSWindowStyleMaskResizable;
9017 if (!(flags & RGFW_windowNoBorder))
9018 macArgs |= NSWindowStyleMaskTitled;
9020 void* nsclass = objc_getClass(
"NSWindow");
9021 SEL func = sel_registerName(
"initWithContentRect:styleMask:backing:defer:");
9023 win->
src.window = ((id(*)(id, SEL, NSRect, NSWindowStyleMask, NSBackingStoreType, bool))objc_msgSend)
9024 (NSAlloc(nsclass), func, windowRect, macArgs, macArgs,
false);
9027 id str = NSString_stringWithUTF8String(name);
9028 objc_msgSend_void_id((
id)win->
src.window, sel_registerName(
"setTitle:"), str);
9030 if ((flags & RGFW_windowNoInitAPI) == 0) {
9039 NSRect contentRect = (NSRect){{0, 0}, {win->
r.
w, win->
r.
h}};
9040 win->
src.view = ((id(*)(id, SEL, NSRect))objc_msgSend) (NSAlloc(objc_getClass(
"NSView")), sel_registerName(
"initWithFrame:"), contentRect);
9043 void* contentView = NSWindow_contentView((
id)win->
src.window);
9044 objc_msgSend_void_bool(contentView, sel_registerName(
"setWantsLayer:"),
true);
9045 objc_msgSend_int((
id)win->
src.view, sel_registerName(
"setLayerContentsPlacement:"), 4);
9046 objc_msgSend_void_id((
id)win->
src.window, sel_registerName(
"setContentView:"), win->
src.view);
9048 if (flags & RGFW_windowTransparent) {
9049 objc_msgSend_void_bool(win->
src.window, sel_registerName(
"setOpaque:"),
false);
9051 objc_msgSend_void_id((
id)win->
src.window, sel_registerName(
"setBackgroundColor:"),
9052 NSColor_colorWithSRGB(0, 0, 0, 0));
9055 Class delegateClass = objc_allocateClassPair(objc_getClass(
"NSObject"),
"WindowDelegate", 0);
9058 delegateClass,
"RGFW_window",
9063 class_addMethod(delegateClass, sel_registerName(
"windowWillResize:toSize:"), (IMP) RGFW__osxWindowResize,
"{NSSize=ff}@:{NSSize=ff}");
9064 class_addMethod(delegateClass, sel_registerName(
"windowWillMove:"), (IMP) RGFW__osxWindowMove,
"");
9065 class_addMethod(delegateClass, sel_registerName(
"windowDidMove:"), (IMP) RGFW__osxWindowMove,
"");
9066 class_addMethod(delegateClass, sel_registerName(
"windowDidMiniaturize:"), (IMP) RGFW__osxWindowMiniaturize,
"");
9067 class_addMethod(delegateClass, sel_registerName(
"windowDidDeminiaturize:"), (IMP) RGFW__osxWindowDeminiaturize,
"");
9068 class_addMethod(delegateClass, sel_registerName(
"windowDidBecomeKey:"), (IMP) RGFW__osxWindowBecameKey,
"");
9069 class_addMethod(delegateClass, sel_registerName(
"windowDidResignKey:"), (IMP) RGFW__osxWindowResignKey,
"");
9070 class_addMethod(delegateClass, sel_registerName(
"draggingEntered:"), (IMP)draggingEntered,
"l@:@");
9071 class_addMethod(delegateClass, sel_registerName(
"draggingUpdated:"), (IMP)draggingUpdated,
"l@:@");
9072 class_addMethod(delegateClass, sel_registerName(
"draggingExited:"), (IMP)RGFW__osxDraggingEnded,
"v@:@");
9073 class_addMethod(delegateClass, sel_registerName(
"draggingEnded:"), (IMP)RGFW__osxDraggingEnded,
"v@:@");
9074 class_addMethod(delegateClass, sel_registerName(
"prepareForDragOperation:"), (IMP)prepareForDragOperation,
"B@:@");
9075 class_addMethod(delegateClass, sel_registerName(
"performDragOperation:"), (IMP)performDragOperation,
"B@:@");
9077 id delegate = objc_msgSend_id(NSAlloc(delegateClass), sel_registerName(
"init"));
9082 object_setInstanceVariable(delegate,
"RGFW_window", win);
9084 objc_msgSend_void_id((
id)win->
src.window, sel_registerName(
"setDelegate:"), delegate);
9086 if (flags & RGFW_windowAllowDND) {
9087 win->
_flags |= RGFW_windowAllowDND;
9089 NSPasteboardType types[] = {NSPasteboardTypeURL, NSPasteboardTypeFileURL, NSPasteboardTypeString};
9090 NSregisterForDraggedTypes((
id)win->
src.window, types, 3);
9096 objc_msgSend_void_bool((
id)_RGFW->NSApp, sel_registerName(
"activateIgnoringOtherApps:"),
true);
9097 ((id(*)(id, SEL, SEL))objc_msgSend)((
id)win->
src.window, sel_registerName(
"makeKeyAndOrderFront:"), NULL);
9101 objc_msgSend_void(win->
src.window, sel_registerName(
"makeMainWindow"));
9106 objc_msgSend_void(win->
src.window, sel_registerName(
"makeKeyWindow"));
9108 objc_msgSend_void((
id)_RGFW->NSApp, sel_registerName(
"finishLaunching"));
9109 NSRetain(win->
src.window);
9110 NSRetain(_RGFW->NSApp);
9117 NSRect frame = ((NSRect(*)(id, SEL))abi_objc_msgSend_stret)((
id)win->
src.window, sel_registerName(
"frame"));
9118 NSRect content = ((NSRect(*)(id, SEL))abi_objc_msgSend_stret)((
id)win->
src.view, sel_registerName(
"frame"));
9121 RGFW_setBit(&win->
_flags, RGFW_windowNoBorder, !border);
9122 NSBackingStoreType storeType = NSWindowStyleMaskBorderless | NSWindowStyleMaskFullSizeContentView;
9124 storeType = NSWindowStyleMaskTitled | NSWindowStyleMaskClosable | NSWindowStyleMaskMiniaturizable;
9125 if (!(win->
_flags & RGFW_windowNoResize)) {
9126 storeType |= NSWindowStyleMaskResizable;
9129 ((void (*)(id, SEL, NSBackingStoreType))objc_msgSend)((
id)win->
src.window, sel_registerName(
"setStyleMask:"), storeType);
9132 id miniaturizeButton = objc_msgSend_int((
id)win->
src.window, sel_registerName(
"standardWindowButton:"), NSWindowMiniaturizeButton);
9133 id titleBarView = objc_msgSend_id(miniaturizeButton, sel_registerName(
"superview"));
9134 objc_msgSend_void_bool(titleBarView, sel_registerName(
"setHidden:"),
true);
9136 offset = (float)(frame.size.height - content.size.height);
9140 win->
r.
h -= (
i32)offset;
9144 static CGDirectDisplayID display = 0;
9147 display = CGMainDisplayID();
9149 return RGFW_AREA(CGDisplayPixelsWide(display), CGDisplayPixelsHigh(display));
9155 CGEventRef e = CGEventCreate(NULL);
9156 CGPoint point = CGEventGetLocation(e);
9163 NSEventTypeLeftMouseDown = 1,
9164 NSEventTypeLeftMouseUp = 2,
9165 NSEventTypeRightMouseDown = 3,
9166 NSEventTypeRightMouseUp = 4,
9167 NSEventTypeMouseMoved = 5,
9168 NSEventTypeLeftMouseDragged = 6,
9169 NSEventTypeRightMouseDragged = 7,
9170 NSEventTypeMouseEntered = 8,
9171 NSEventTypeMouseExited = 9,
9172 NSEventTypeKeyDown = 10,
9173 NSEventTypeKeyUp = 11,
9174 NSEventTypeFlagsChanged = 12,
9175 NSEventTypeAppKitDefined = 13,
9176 NSEventTypeSystemDefined = 14,
9177 NSEventTypeApplicationDefined = 15,
9178 NSEventTypePeriodic = 16,
9179 NSEventTypeCursorUpdate = 17,
9180 NSEventTypeScrollWheel = 22,
9181 NSEventTypeTabletPoint = 23,
9182 NSEventTypeTabletProximity = 24,
9183 NSEventTypeOtherMouseDown = 25,
9184 NSEventTypeOtherMouseUp = 26,
9185 NSEventTypeOtherMouseDragged = 27,
9187 NSEventTypeGesture = 29,
9188 NSEventTypeMagnify = 30,
9189 NSEventTypeSwipe = 31,
9190 NSEventTypeRotate = 18,
9191 NSEventTypeBeginGesture = 19,
9192 NSEventTypeEndGesture = 20,
9194 NSEventTypeSmartMagnify = 32,
9195 NSEventTypeQuickLook = 33,
9197 NSEventTypePressure = 34,
9198 NSEventTypeDirectTouch = 37,
9200 NSEventTypeChangeMode = 38,
9203typedef unsigned long long NSEventMask;
9205typedef enum NSEventModifierFlags {
9206 NSEventModifierFlagCapsLock = 1 << 16,
9207 NSEventModifierFlagShift = 1 << 17,
9208 NSEventModifierFlagControl = 1 << 18,
9209 NSEventModifierFlagOption = 1 << 19,
9210 NSEventModifierFlagCommand = 1 << 20,
9211 NSEventModifierFlagNumericPad = 1 << 21
9212} NSEventModifierFlags;
9215 id eventPool = objc_msgSend_class(objc_getClass(
"NSAutoreleasePool"), sel_registerName(
"alloc"));
9216 eventPool = objc_msgSend_id(eventPool, sel_registerName(
"init"));
9218 id e = (id) ((
id(*)(Class,
SEL, NSEventType, NSPoint, NSEventModifierFlags,
void*, NSInteger,
void**,
short, NSInteger, NSInteger))objc_msgSend)
9219 (objc_getClass(
"NSEvent"), sel_registerName(
"otherEventWithType:location:modifierFlags:timestamp:windowNumber:context:subtype:data1:data2:"),
9220 NSEventTypeApplicationDefined, (NSPoint){0, 0}, (NSEventModifierFlags)0, NULL, (NSInteger)0, NULL, 0, 0, 0);
9222 ((void (*)(id, SEL, id, bool))objc_msgSend)
9223 ((
id)_RGFW->NSApp, sel_registerName(
"postEvent:atStart:"), e, 1);
9225 objc_msgSend_bool_void(eventPool, sel_registerName(
"drain"));
9231 id eventPool = objc_msgSend_class(objc_getClass(
"NSAutoreleasePool"), sel_registerName(
"alloc"));
9232 eventPool = objc_msgSend_id(eventPool, sel_registerName(
"init"));
9234 void* date = (
void*) ((
id(*)(Class,
SEL,
double))objc_msgSend)
9235 (objc_getClass(
"NSDate"), sel_registerName(
"dateWithTimeIntervalSinceNow:"), waitMS);
9237 SEL eventFunc = sel_registerName(
"nextEventMatchingMask:untilDate:inMode:dequeue:");
9238 id e = (id) ((
id(*)(
id,
SEL, NSEventMask,
void*,
id,
bool))objc_msgSend)
9239 ((
id)_RGFW->NSApp, eventFunc,
9240 ULONG_MAX, date, NSString_stringWithUTF8String(
"kCFRunLoopDefaultMode"),
true);
9243 ((void (*)(id, SEL, id, bool))objc_msgSend)
9244 ((
id)_RGFW->NSApp, sel_registerName(
"postEvent:atStart:"), e, 1);
9247 objc_msgSend_bool_void(eventPool, sel_registerName(
"drain"));
9251 return (
u8)rgfw_keycode;
9255 if (win == NULL || ((win->
_flags & RGFW_windowFreeOnClose) && (win->
_flags & RGFW_EVENT_QUIT)))
return NULL;
9257 objc_msgSend_void((
id)win->
src.mouse, sel_registerName(
"set"));
9258 RGFW_event* ev = RGFW_window_checkEventCore(win);
9260 ((void(*)(id, SEL))objc_msgSend)((
id)_RGFW->NSApp, sel_registerName(
"updateWindows"));
9264 id eventPool = objc_msgSend_class(objc_getClass(
"NSAutoreleasePool"), sel_registerName(
"alloc"));
9265 eventPool = objc_msgSend_id(eventPool, sel_registerName(
"init"));
9267 SEL eventFunc = sel_registerName(
"nextEventMatchingMask:untilDate:inMode:dequeue:");
9271 id e = (id) ((
id(*)(
id,
SEL, NSEventMask,
void*,
id,
bool))objc_msgSend)
9272 ((
id)_RGFW->NSApp, eventFunc, ULONG_MAX, date, NSString_stringWithUTF8String(
"kCFRunLoopDefaultMode"),
true);
9275 objc_msgSend_bool_void(eventPool, sel_registerName(
"drain"));
9276 objc_msgSend_void_id((
id)_RGFW->NSApp, sel_registerName(
"sendEvent:"), e);
9277 ((void(*)(id, SEL))objc_msgSend)((
id)_RGFW->NSApp, sel_registerName(
"updateWindows"));
9281 if (objc_msgSend_id(e, sel_registerName(
"window")) != win->
src.window) {
9282 ((void (*)(id, SEL, id, bool))objc_msgSend)
9283 ((
id)_RGFW->NSApp, sel_registerName(
"postEvent:atStart:"), e, 0);
9285 objc_msgSend_void_id((
id)_RGFW->NSApp, sel_registerName(
"sendEvent:"), e);
9286 objc_msgSend_bool_void(eventPool, sel_registerName(
"drain"));
9287 ((void(*)(id, SEL))objc_msgSend)((
id)_RGFW->NSApp, sel_registerName(
"updateWindows"));
9300 u32 type = (
u32)objc_msgSend_uint(e, sel_registerName(
"type"));
9302 case NSEventTypeMouseEntered: {
9304 NSPoint p = ((NSPoint(*)(id, SEL)) objc_msgSend)(e, sel_registerName(
"locationInWindow"));
9307 RGFW_mouseNotifyCallback(win, win->
event.
point, 1);
9311 case NSEventTypeMouseExited:
9313 RGFW_mouseNotifyCallback(win, win->
event.
point, 0);
9316 case NSEventTypeKeyDown: {
9317 u32 key = (
u16) objc_msgSend_uint(e, sel_registerName(
"keyCode"));
9319 u32 mappedKey = (
u32)*(((
char*)(
const char*) NSString_to_char(objc_msgSend_id(e, sel_registerName(
"charactersIgnoringModifiers")))));
9320 if (((
u8)mappedKey) == 239)
9326 RGFW_keyboard[win->
event.
key].prev = RGFW_keyboard[win->
event.
key].current;
9330 RGFW_keyboard[win->
event.
key].current = 1;
9336 case NSEventTypeKeyUp: {
9337 u32 key = (
u16) objc_msgSend_uint(e, sel_registerName(
"keyCode"));
9338 u32 mappedKey = (
u32)*(((
char*)(
const char*) NSString_to_char(objc_msgSend_id(e, sel_registerName(
"charactersIgnoringModifiers")))));
9339 if (((
u8)mappedKey) == 239)
9346 RGFW_keyboard[win->
event.
key].prev = RGFW_keyboard[win->
event.
key].current;
9350 RGFW_keyboard[win->
event.
key].current = 0;
9355 case NSEventTypeFlagsChanged: {
9356 u32 flags = (
u32)objc_msgSend_uint(e, sel_registerName(
"modifierFlags"));
9357 RGFW_updateKeyModsPro(win, ((
u32)(flags & NSEventModifierFlagCapsLock) % 255), ((flags & NSEventModifierFlagNumericPad) % 255),
9358 ((flags & NSEventModifierFlagControl) % 255), ((flags & NSEventModifierFlagOption) % 255),
9359 ((flags & NSEventModifierFlagShift) % 255), ((flags & NSEventModifierFlagCommand) % 255), 0);
9361 for (i = 0; i < 9; i++)
9362 RGFW_keyboard[i + RGFW_capsLock].prev = 0;
9364 for (i = 0; i < 5; i++) {
9365 u32 shift = (1 << (i + 16));
9366 u32 key = i + RGFW_capsLock;
9369 RGFW_keyboard[key].current = 1;
9371 if (key != RGFW_capsLock)
9372 RGFW_keyboard[key+ 4].current = 1;
9380 RGFW_keyboard[key].current = 0;
9382 if (key != RGFW_capsLock)
9383 RGFW_keyboard[key + 4].current = 0;
9395 case NSEventTypeLeftMouseDragged:
9396 case NSEventTypeOtherMouseDragged:
9397 case NSEventTypeRightMouseDragged:
9398 case NSEventTypeMouseMoved: {
9400 NSPoint p = ((NSPoint(*)(id, SEL)) objc_msgSend)(e, sel_registerName(
"locationInWindow"));
9403 p.x = ((CGFloat(*)(id, SEL))abi_objc_msgSend_fpret)(e, sel_registerName(
"deltaX"));
9404 p.y = ((CGFloat(*)(id, SEL))abi_objc_msgSend_fpret)(e, sel_registerName(
"deltaY"));
9411 case NSEventTypeLeftMouseDown:
case NSEventTypeRightMouseDown:
case NSEventTypeOtherMouseDown: {
9412 u32 buttonNumber = (
u32)objc_msgSend_uint(e, sel_registerName(
"buttonNumber"));
9413 switch (buttonNumber) {
9414 case 0: win->
event.
button = RGFW_mouseLeft;
break;
9415 case 1: win->
event.
button = RGFW_mouseRight;
break;
9416 case 2: win->
event.
button = RGFW_mouseMiddle;
break;
9420 win->
event.
type = RGFW_mouseButtonPressed;
9426 case NSEventTypeLeftMouseUp:
case NSEventTypeRightMouseUp:
case NSEventTypeOtherMouseUp: {
9427 u32 buttonNumber = (
u32)objc_msgSend_uint(e, sel_registerName(
"buttonNumber"));
9428 switch (buttonNumber) {
9429 case 0: win->
event.
button = RGFW_mouseLeft;
break;
9430 case 1: win->
event.
button = RGFW_mouseRight;
break;
9431 case 2: win->
event.
button = RGFW_mouseMiddle;
break;
9436 win->
event.
type = RGFW_mouseButtonReleased;
9440 case NSEventTypeScrollWheel: {
9441 double deltaY = ((CGFloat(*)(id, SEL))abi_objc_msgSend_fpret)(e, sel_registerName(
"deltaY"));
9446 else if (deltaY < 0) {
9455 win->
event.
type = RGFW_mouseButtonPressed;
9461 objc_msgSend_void_id((
id)_RGFW->NSApp, sel_registerName(
"sendEvent:"), e);
9462 ((void(*)(id, SEL))objc_msgSend)((
id)_RGFW->NSApp, sel_registerName(
"updateWindows"));
9466 objc_msgSend_void_id((
id)_RGFW->NSApp, sel_registerName(
"sendEvent:"), e);
9467 ((void(*)(id, SEL))objc_msgSend)((
id)_RGFW->NSApp, sel_registerName(
"updateWindows"));
9468 objc_msgSend_bool_void(eventPool, sel_registerName(
"drain"));
9478 ((void(*)(id, SEL, NSRect, bool, bool))objc_msgSend)
9479 ((
id)win->
src.window, sel_registerName(
"setFrame:display:animate:"), (NSRect){{win->
r.
x, win->
r.
y}, {win->
r.
w, win->
r.
h}},
true,
true);
9485 NSRect frame = ((NSRect(*)(id, SEL))abi_objc_msgSend_stret)((
id)win->
src.window, sel_registerName(
"frame"));
9486 NSRect content = ((NSRect(*)(id, SEL))abi_objc_msgSend_stret)((
id)win->
src.view, sel_registerName(
"frame"));
9487 float offset = (float)(frame.size.height - content.size.height);
9492 ((void(*)(id, SEL, NSRect, bool, bool))objc_msgSend)
9493 ((
id)win->
src.window, sel_registerName(
"setFrame:display:animate:"), (NSRect){{win->
r.
x, win->
r.
y}, {win->
r.
w, win->
r.
h + offset}},
true,
true);
9498 objc_msgSend_void_bool((
id)_RGFW->NSApp, sel_registerName(
"activateIgnoringOtherApps:"),
true);
9499 ((void (*)(id, SEL))objc_msgSend)((
id)win->
src.window, sel_registerName(
"makeKeyWindow"));
9504 ((id(*)(id, SEL, SEL))objc_msgSend)((
id)win->
src.window, sel_registerName(
"orderFront:"), (SEL)NULL);
9505 objc_msgSend_void_id(win->
src.window, sel_registerName(
"setLevel:"), kCGNormalWindowLevelKey);
9510 if (fullscreen && (win->
_flags & RGFW_windowFullscreen))
return;
9511 if (!fullscreen && !(win->
_flags & RGFW_windowFullscreen))
return;
9517 win->
_flags |= RGFW_windowFullscreen;
9521 objc_msgSend_void_SEL(win->
src.window, sel_registerName(
"toggleFullScreen:"), NULL);
9525 win->
_flags &= ~(
u32)RGFW_windowFullscreen;
9536 win->
_flags |= RGFW_windowMaximize;
9537 objc_msgSend_void_SEL(win->
src.window, sel_registerName(
"zoom:"), NULL);
9542 objc_msgSend_void_SEL(win->
src.window, sel_registerName(
"performMiniaturize:"), NULL);
9547 if (floating) objc_msgSend_void_id(win->
src.window, sel_registerName(
"setLevel:"), kCGFloatingWindowLevelKey);
9548 else objc_msgSend_void_id(win->
src.window, sel_registerName(
"setLevel:"), kCGNormalWindowLevelKey);
9552 objc_msgSend_int(win->
src.window, sel_registerName(
"setAlphaValue:"), opacity);
9553 objc_msgSend_void_bool(win->
src.window, sel_registerName(
"setOpaque:"), (opacity < (
u8)255));
9556 objc_msgSend_void_id((
id)win->
src.window, sel_registerName(
"setBackgroundColor:"), NSColor_colorWithSRGB(0, 0, 0, opacity));
9564 objc_msgSend_void_SEL(win->
src.window, sel_registerName(
"zoom:"), NULL);
9566 objc_msgSend_void_SEL(win->
src.window, sel_registerName(
"deminiaturize:"), NULL);
9572 int level = ((int (*)(id, SEL))objc_msgSend) ((
id)(win->
src.window), (
SEL)sel_registerName(
"level"));
9573 return level > kCGNormalWindowLevelKey;
9579 id str = NSString_stringWithUTF8String(name);
9580 objc_msgSend_void_id((
id)win->
src.window, sel_registerName(
"setTitle:"), str);
9583#ifndef RGFW_NO_PASSTHROUGH
9585 objc_msgSend_void_bool(win->
src.window, sel_registerName(
"setIgnoresMouseEvents:"), passthrough);
9592 ((void (*)(id, SEL, NSSize))objc_msgSend)
9593 ((
id)win->
src.window, sel_registerName(
"setContentAspectRatio:"), (NSSize){a.
w, a.
h});
9597 ((void (*)(id, SEL, NSSize))objc_msgSend)
9598 ((
id)win->
src.window, sel_registerName(
"setMinSize:"), (NSSize){a.
w, a.
h});
9602 if (a.
w == 0 && a.
h == 0) {
9606 ((void (*)(id, SEL, NSSize))objc_msgSend)
9607 ((
id)win->
src.window, sel_registerName(
"setMaxSize:"), (NSSize){a.
w, a.
h});
9615 objc_msgSend_void_id((
id)_RGFW->NSApp, sel_registerName(
"setApplicationIconImage:"), NULL);
9620 id representation = NSBitmapImageRep_initWithBitmapData(NULL, area.
w, area.
h, 8, channels, (channels == 4),
false,
"NSCalibratedRGBColorSpace", 1 << 1, area.
w * (
u32)channels, 8 * (
u32)channels);
9621 RGFW_MEMCPY(NSBitmapImageRep_bitmapData(representation), data, area.
w * area.
h * (
u32)channels);
9624 id dock_image = ((id(*)(id, SEL, NSSize))objc_msgSend) (NSAlloc((
id)objc_getClass(
"NSImage")), sel_registerName(
"initWithSize:"), ((NSSize){area.
w, area.
h}));
9626 objc_msgSend_void_id(dock_image, sel_registerName(
"addRepresentation:"), representation);
9629 objc_msgSend_void_id((
id)_RGFW->NSApp, sel_registerName(
"setApplicationIconImage:"), dock_image);
9631 NSRelease(dock_image);
9632 NSRelease(representation);
9637id NSCursor_arrowStr(
const char* str) {
9638 void* nclass = objc_getClass(
"NSCursor");
9639 SEL func = sel_registerName(str);
9640 return (
id) objc_msgSend_id(nclass, func);
9645 objc_msgSend_void(NSCursor_arrowStr(
"arrowCursor"), sel_registerName(
"set"));
9651 id representation = (id)NSBitmapImageRep_initWithBitmapData(NULL, a.
w, a.
h, 8, channels, (channels == 4),
false,
"NSCalibratedRGBColorSpace", 1 << 1, a.
w * (
u32)channels, 8 * (
u32)channels);
9652 RGFW_MEMCPY(NSBitmapImageRep_bitmapData(representation), icon, a.
w * a.
h * (
u32)channels);
9655 id cursor_image = ((id(*)(id, SEL, NSSize))objc_msgSend) (NSAlloc((
id)objc_getClass(
"NSImage")), sel_registerName(
"initWithSize:"), ((NSSize){a.
w, a.
h}));
9657 objc_msgSend_void_id(cursor_image, sel_registerName(
"addRepresentation:"), representation);
9660 id cursor = (id) ((
id(*)(
id,
SEL,
id, NSPoint))objc_msgSend)
9661 (NSAlloc(objc_getClass(
"NSCursor")), sel_registerName(
"initWithImage:hotSpot:"), cursor_image, (NSPoint){0.0, 0.0});
9664 NSRelease(cursor_image);
9665 NSRelease(representation);
9667 return (
void*)cursor;
9672 CGDisplayShowCursor(kCGDirectMainDisplay);
9673 objc_msgSend_void((
id)mouse, sel_registerName(
"set"));
9674 win->
src.mouse = mouse;
9679 NSRelease((
id)mouse);
9687 RGFW_window_showMouseFlags(win, show);
9688 if (show) CGDisplayShowCursor(kCGDirectMainDisplay);
9689 else CGDisplayHideCursor(kCGDirectMainDisplay);
9693 static const char* mouseIconSrc[16] = {
"arrowCursor",
"arrowCursor",
"IBeamCursor",
"crosshairCursor",
"pointingHandCursor",
"resizeLeftRightCursor",
"resizeUpDownCursor",
"_windowResizeNorthWestSouthEastCursor",
"_windowResizeNorthEastSouthWestCursor",
"closedHandCursor",
"operationNotAllowedCursor"};
9694 if (stdMouses > ((
sizeof(mouseIconSrc)) / (
sizeof(
char*))))
9697 const char* mouseStr = mouseIconSrc[stdMouses];
9698 id mouse = NSCursor_arrowStr(mouseStr);
9704 CGDisplayShowCursor(kCGDirectMainDisplay);
9705 objc_msgSend_void(mouse, sel_registerName(
"set"));
9706 win->
src.mouse = mouse;
9713 CGAssociateMouseAndMouseCursorPosition(1);
9719 CGWarpMouseCursorPosition((CGPoint){r.
x + (r.
w / 2), r.
y + (r.
h / 2)});
9720 CGAssociateMouseAndMouseCursorPosition(0);
9727 CGWarpMouseCursorPosition((CGPoint){v.
x, v.
y});
9732 objc_msgSend_void_bool(win->
src.window, sel_registerName(
"setIsVisible:"),
false);
9736 if (win->
_flags & RGFW_windowFocusOnShow)
9737 ((id(*)(id, SEL, SEL))objc_msgSend)((
id)win->
src.window, sel_registerName(
"makeKeyAndOrderFront:"), NULL);
9739 ((id(*)(id, SEL, SEL))objc_msgSend)((
id)win->
src.window, sel_registerName(
"orderFront:"), NULL);
9740 objc_msgSend_void_bool(win->
src.window, sel_registerName(
"setIsVisible:"),
true);
9746 bool visible = objc_msgSend_bool(win->
src.window, sel_registerName(
"isVisible"));
9753 return objc_msgSend_bool(win->
src.window, sel_registerName(
"isMiniaturized")) == YES;
9762id RGFW_getNSScreenForDisplayID(CGDirectDisplayID display) {
9763 Class NSScreenClass = objc_getClass(
"NSScreen");
9765 id screens = objc_msgSend_id(NSScreenClass, sel_registerName(
"screens"));
9767 NSUInteger count = (NSUInteger)objc_msgSend_uint(screens, sel_registerName(
"count"));
9769 for (i = 0; i < count; i++) {
9770 id screen = ((id (*)(id, SEL, int))objc_msgSend) (screens, sel_registerName(
"objectAtIndex:"), (int)i);
9771 id description = objc_msgSend_id(screen, sel_registerName(
"deviceDescription"));
9772 id screenNumberKey = NSString_stringWithUTF8String(
"NSScreenNumber");
9773 id screenNumber = objc_msgSend_id_id(description, sel_registerName(
"objectForKey:"), screenNumberKey);
9775 if ((CGDirectDisplayID)objc_msgSend_uint(screenNumber, sel_registerName(
"unsignedIntValue")) == display) {
9783u32 RGFW_osx_getFallbackRefreshRate(CGDirectDisplayID displayID);
9785u32 RGFW_osx_getRefreshRate(CGDirectDisplayID display, CGDisplayModeRef mode) {
9787 u32 refreshRate = (
u32)CGDisplayModeGetRefreshRate(mode);
9788 if (refreshRate != 0)
return refreshRate;
9791#ifndef RGFW_NO_IOKIT
9792 u32 res = RGFW_osx_getFallbackRefreshRate(display);
9793 if (res != 0)
return res;
9800RGFW_monitor RGFW_NSCreateMonitor(CGDirectDisplayID display,
id screen) {
9803 const char name[] =
"MacOS\0";
9806 CGRect bounds = CGDisplayBounds(display);
9807 monitor.
x = (
i32)bounds.origin.x;
9808 monitor.
y = (
i32)bounds.origin.y;
9809 monitor.
mode.
area =
RGFW_AREA((
int) bounds.size.width, (
int) bounds.size.height);
9813 CGDisplayModeRef mode = CGDisplayCopyDisplayMode(display);
9817 CGSize screenSizeMM = CGDisplayScreenSize(display);
9818 monitor.
physW = (float)screenSizeMM.width / 25.4f;
9819 monitor.
physH = (
float)screenSizeMM.height / 25.4f;
9824 monitor.
pixelRatio = (float)((CGFloat (*)(id, SEL))abi_objc_msgSend_fpret) (screen, sel_registerName(
"backingScaleFactor"));
9827 monitor.
scaleX = ((
i32)(((
float) (ppi_width) / dpi) * 10.0f)) / 10.0f;
9828 monitor.
scaleY = ((
i32)(((
float) (ppi_height) / dpi) * 10.0f)) / 10.0f;
9836 static CGDirectDisplayID displays[7];
9839 if (CGGetActiveDisplayList(6, displays, &count) != kCGErrorSuccess)
9842 if (count > 6) count = 6;
9847 for (i = 0; i < count; i++)
9848 monitors[i] = RGFW_NSCreateMonitor(displays[i], RGFW_getNSScreenForDisplayID(displays[i]));
9850 if (len != NULL) *len = count;
9855 CGPoint point = { mon.
x, mon.
y };
9857 CGDirectDisplayID display;
9858 uint32_t displayCount = 0;
9859 CGError err = CGGetDisplaysWithPoint(point, 1, &display, &displayCount);
9860 if (err != kCGErrorSuccess || displayCount != 1)
9863 CFArrayRef allModes = CGDisplayCopyAllDisplayModes(display, NULL);
9865 if (allModes == NULL)
9869 for (i = 0; i < CFArrayGetCount(allModes); i++) {
9870 CGDisplayModeRef cmode = (CGDisplayModeRef)CFArrayGetValueAtIndex(allModes, i);
9873 foundMode.
area =
RGFW_AREA(CGDisplayModeGetWidth(cmode), CGDisplayModeGetHeight(cmode));
9874 foundMode.
refreshRate = RGFW_osx_getRefreshRate(display, cmode);
9875 foundMode.
red = 8; foundMode.
green = 8; foundMode.
blue = 8;
9878 if (CGDisplaySetDisplayMode(display, cmode, NULL) == kCGErrorSuccess) {
9879 CFRelease(allModes);
9886 CFRelease(allModes);
9892 CGDirectDisplayID primary = CGMainDisplayID();
9893 return RGFW_NSCreateMonitor(primary, RGFW_getNSScreenForDisplayID(primary));
9897 id screen = objc_msgSend_id(win->
src.window, sel_registerName(
"screen"));
9898 id description = objc_msgSend_id(screen, sel_registerName(
"deviceDescription"));
9899 id screenNumberKey = NSString_stringWithUTF8String(
"NSScreenNumber");
9900 id screenNumber = objc_msgSend_id_id(description, sel_registerName(
"objectForKey:"), screenNumberKey);
9902 CGDirectDisplayID display = (CGDirectDisplayID)objc_msgSend_uint(screenNumber, sel_registerName(
"unsignedIntValue"));
9904 return RGFW_NSCreateMonitor(display, screen);
9909 char* clip = (
char*)NSPasteboard_stringForType(NSPasteboard_generalPasteboard(), NSPasteboardTypeString, &clip_len);
9910 if (clip == NULL)
return -1;
9913 if (strCapacity < clip_len)
9918 str[clip_len] =
'\0';
9927 NSPasteboardType array[] = { NSPasteboardTypeString, NULL };
9928 NSPasteBoard_declareTypes(NSPasteboard_generalPasteboard(), array, 1, NULL);
9930 SEL func = sel_registerName(
"setString:forType:");
9931 ((bool (*)(id, SEL, id, id))objc_msgSend)
9932 (NSPasteboard_generalPasteboard(), func, NSString_stringWithUTF8String(text), NSString_stringWithUTF8String(NSPasteboardTypeString));
9938 objc_msgSend_void(win->
src.ctx, sel_registerName(
"makeCurrentContext"));
9940 objc_msgSend_id(objc_getClass(
"NSOpenGLContext"), sel_registerName(
"clearCurrentContext"));
9943 return objc_msgSend_id(objc_getClass(
"NSOpenGLContext"), sel_registerName(
"currentContext"));
9947 objc_msgSend_void(win->
src.ctx, sel_registerName(
"flushBuffer"));
9951 #if !defined(RGFW_EGL)
9955 #if defined(RGFW_OPENGL)
9957 NSOpenGLContext_setValues((
id)win->
src.ctx, &swapInterval, 222);
9966#if defined(RGFW_BUFFER)
9967 RGFW_RGB_to_BGR(win, win->buffer);
9969 id image = ((id (*)(Class, SEL))objc_msgSend)(objc_getClass(
"NSImage"), sel_getUid(
"alloc"));
9970 NSSize size = (NSSize){win->bufferSize.w, win->bufferSize.h};
9971 image = ((id (*)(id, SEL, NSSize))objc_msgSend)((
id)image, sel_getUid(
"initWithSize:"), size);
9973 id rep = NSBitmapImageRep_initWithBitmapData(&win->buffer, win->
r.
w, win->
r.
h , 8, channels, (channels == 4),
false,
9974 "NSDeviceRGBColorSpace", 1 << 1, (
u32)win->bufferSize.w * (
u32)channels, 8 * (
u32)channels);
9975 ((void (*)(id, SEL, id))objc_msgSend)((
id)image, sel_getUid(
"addRepresentation:"), rep);
9977 id contentView = ((id (*)(id, SEL))objc_msgSend)((
id)win->
src.window, sel_getUid(
"contentView"));
9978 ((void (*)(id, SEL, BOOL))objc_msgSend)(contentView, sel_getUid(
"setWantsLayer:"), YES);
9979 id layer = ((id (*)(id, SEL))objc_msgSend)(contentView, sel_getUid(
"layer"));
9981 ((void (*)(id, SEL, id))objc_msgSend)(layer, sel_getUid(
"setContents:"), (id)image);
9982 ((void (*)(id, SEL, BOOL))objc_msgSend)(contentView, sel_getUid(
"setNeedsDisplay:"), YES);
9991void RGFW_deinitPlatform(
void) { }
9995 NSRelease(win->
src.view);
9998 #if defined(RGFW_BUFFER)
9999 if ((win->
_flags & RGFW_BUFFER_ALLOC))
10004 RGFW_clipboard_switch(NULL);
10007 if ((win->
_flags & RGFW_WINDOW_ALLOC)) {
10014 static u64 freq = 0;
10016 mach_timebase_info_data_t info;
10017 mach_timebase_info(&info);
10018 freq = (
u64)((info.denom * 1e9) / info.numer);
10037EM_BOOL Emscripten_on_resize(
int eventType,
const EmscriptenUiEvent* E,
void* userData) {
10041 RGFW_windowResizedCallback(_RGFW->
root,
RGFW_RECT(0, 0, E->windowInnerWidth, E->windowInnerHeight));
10045EM_BOOL Emscripten_on_fullscreenchange(
int eventType,
const EmscriptenFullscreenChangeEvent* E,
void* userData) {
10051 ogRect = _RGFW->
root->
r;
10054 fullscreen = !fullscreen;
10056 _RGFW->
root->
r =
RGFW_RECT(0, 0, E->screenWidth, E->screenHeight);
10058 EM_ASM(
"Module.canvas.focus();");
10064 #if __EMSCRIPTEN_major__ >= 1 && __EMSCRIPTEN_minor__ >= 29 && __EMSCRIPTEN_tiny__ >= 0
10065 EmscriptenFullscreenStrategy FSStrat = {0};
10066 FSStrat.scaleMode = EMSCRIPTEN_FULLSCREEN_SCALE_STRETCH;
10067 FSStrat.canvasResolutionScaleMode = EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE_HIDEF;
10068 FSStrat.filteringMode = EMSCRIPTEN_FULLSCREEN_FILTERING_DEFAULT;
10069 emscripten_request_fullscreen_strategy(
"#canvas", 1, &FSStrat);
10071 emscripten_request_fullscreen(
"#canvas", 1);
10075 emscripten_set_canvas_element_size(
"#canvas", _RGFW->
root->
r.
w, _RGFW->
root->
r.
h);
10077 RGFW_windowResizedCallback(_RGFW->
root, _RGFW->
root->
r);
10083EM_BOOL Emscripten_on_focusin(
int eventType,
const EmscriptenFocusEvent* E,
void* userData) {
10088 RGFW_focusCallback(_RGFW->
root, 1);
10094EM_BOOL Emscripten_on_focusout(
int eventType,
const EmscriptenFocusEvent* E,
void* userData) {
10098 RGFW_window_focusLost(_RGFW->
root);
10099 RGFW_focusCallback(_RGFW->
root, 0);
10103EM_BOOL Emscripten_on_mousemove(
int eventType,
const EmscriptenMouseEvent* E,
void* userData) {
10106 e.point =
RGFW_POINT(E->targetX, E->targetY);
10107 e.vector =
RGFW_POINT(E->movementX, E->movementY);
10108 e._win = _RGFW->
root);
10115EM_BOOL Emscripten_on_mousedown(
int eventType,
const EmscriptenMouseEvent* E,
void* userData) {
10118 int button = E->button;
10123 e.point =
RGFW_POINT(E->targetX, E->targetY);
10124 e.vector =
RGFW_POINT(E->movementX, E->movementY);
10125 e.button = (
u8)button;
10127 e._win = _RGFW->
root);
10128 RGFW_mouseButtons[button].prev = RGFW_mouseButtons[button].current;
10129 RGFW_mouseButtons[button].current = 1;
10131 RGFW_mouseButtonCallback(_RGFW->
root, button, 0, 1);
10135EM_BOOL Emscripten_on_mouseup(
int eventType,
const EmscriptenMouseEvent* E,
void* userData) {
10138 int button = E->button;
10143 e.point =
RGFW_POINT(E->targetX, E->targetY);
10144 e.vector =
RGFW_POINT(E->movementX, E->movementY);
10145 e.button = (
u8)button;
10147 e._win = _RGFW->
root);
10148 RGFW_mouseButtons[button].prev = RGFW_mouseButtons[button].current;
10149 RGFW_mouseButtons[button].current = 0;
10151 RGFW_mouseButtonCallback(_RGFW->
root, button, 0, 0);
10155EM_BOOL Emscripten_on_wheel(
int eventType,
const EmscriptenWheelEvent* E,
void* userData) {
10158 int button = RGFW_mouseScrollUp + (E->deltaY < 0);
10160 e.button = (
u8)button;
10161 e.scroll = (
double)(E->deltaY < 0 ? 1 : -1);
10162 e._win = _RGFW->
root);
10163 RGFW_mouseButtons[button].prev = RGFW_mouseButtons[button].current;
10164 RGFW_mouseButtons[button].current = 1;
10165 RGFW_mouseButtonCallback(_RGFW->
root, button, E->deltaY < 0 ? 1 : -1, 1);
10170EM_BOOL Emscripten_on_touchstart(
int eventType,
const EmscriptenTouchEvent* E,
void* userData) {
10174 for (i = 0; i < (size_t)E->numTouches; i++) {
10176 e.point =
RGFW_POINT(E->touches[i].targetX, E->touches[i].targetY);
10177 e.button = RGFW_mouseLeft;
10178 e._win = _RGFW->
root);
10180 RGFW_mouseButtons[RGFW_mouseLeft].prev = RGFW_mouseButtons[RGFW_mouseLeft].current;
10181 RGFW_mouseButtons[RGFW_mouseLeft].current = 1;
10185 RGFW_mouseButtonCallback(_RGFW->
root, RGFW_mouseLeft, 0, 1);
10190EM_BOOL Emscripten_on_touchmove(
int eventType,
const EmscriptenTouchEvent* E,
void* userData) {
10194 for (i = 0; i < (size_t)E->numTouches; i++) {
10196 e.point =
RGFW_POINT(E->touches[i].targetX, E->touches[i].targetY);
10197 e.button = RGFW_mouseLeft;
10198 e._win = _RGFW->
root);
10206EM_BOOL Emscripten_on_touchend(
int eventType,
const EmscriptenTouchEvent* E,
void* userData) {
10210 for (i = 0; i < (size_t)E->numTouches; i++) {
10212 e.point =
RGFW_POINT(E->touches[i].targetX, E->touches[i].targetY);
10213 e.button = RGFW_mouseLeft;
10214 e._win = _RGFW->
root);
10216 RGFW_mouseButtons[RGFW_mouseLeft].prev = RGFW_mouseButtons[RGFW_mouseLeft].current;
10217 RGFW_mouseButtons[RGFW_mouseLeft].current = 0;
10221 RGFW_mouseButtonCallback(_RGFW->
root, RGFW_mouseLeft, 0, 0);
10226EM_BOOL Emscripten_on_touchcancel(
int eventType,
const EmscriptenTouchEvent* E,
void* userData) {
RGFW_UNUSED(eventType);
RGFW_UNUSED(userData);
return EM_TRUE; }
10228EM_BOOL Emscripten_on_gamepad(
int eventType,
const EmscriptenGamepadEvent *gamepadEvent,
void *userData) {
10231 if (gamepadEvent->index >= 4)
10234 size_t i = gamepadEvent->index;
10235 if (gamepadEvent->connected) {
10252 RGFW_eventQueuePushEx(e.type = (RGFW_eventType)(gamepadEvent->connected ? RGFW_gamepadConnected : RGFW_gamepadConnected);
10253 e.gamepad = (
u16)gamepadEvent->index;
10254 e._win = _RGFW->
root);
10256 RGFW_gamepadCallback(_RGFW->
root, gamepadEvent->index, gamepadEvent->connected);
10257 _RGFW->
gamepads[gamepadEvent->index] = gamepadEvent->connected;
10262u32 RGFW_wASMPhysicalToRGFW(
u32 hash) {
10264 case 0x67243A2DU :
return RGFW_escape;
10265 case 0x67251058U :
return RGFW_0;
10266 case 0x67251059U :
return RGFW_1;
10267 case 0x6725105AU :
return RGFW_2;
10268 case 0x6725105BU :
return RGFW_3;
10269 case 0x6725105CU :
return RGFW_4;
10270 case 0x6725105DU :
return RGFW_5;
10271 case 0x6725105EU :
return RGFW_6;
10272 case 0x6725105FU :
return RGFW_7;
10273 case 0x67251050U :
return RGFW_8;
10274 case 0x67251051U :
return RGFW_9;
10275 case 0x92E14DD3U :
return RGFW_minus;
10276 case 0x92E1FBACU :
return RGFW_equals;
10277 case 0x36BF1CB5U :
return RGFW_backSpace;
10278 case 0x7B8E51E2U :
return RGFW_tab;
10279 case 0x2C595B51U :
return RGFW_q;
10280 case 0x2C595B57U :
return RGFW_w;
10281 case 0x2C595B45U :
return RGFW_e;
10282 case 0x2C595B52U :
return RGFW_r;
10283 case 0x2C595B54U :
return RGFW_t;
10284 case 0x2C595B59U :
return RGFW_y;
10285 case 0x2C595B55U :
return RGFW_u;
10286 case 0x2C595B4FU :
return RGFW_o;
10287 case 0x2C595B50U :
return RGFW_p;
10288 case 0x45D8158CU :
return RGFW_closeBracket;
10289 case 0xDEEABF7CU :
return RGFW_bracket;
10290 case 0x92E1C5D2U :
return RGFW_return;
10291 case 0xE058958CU :
return RGFW_controlL;
10292 case 0x2C595B41U :
return RGFW_a;
10293 case 0x2C595B53U :
return RGFW_s;
10294 case 0x2C595B44U :
return RGFW_d;
10295 case 0x2C595B46U :
return RGFW_f;
10296 case 0x2C595B47U :
return RGFW_g;
10297 case 0x2C595B48U :
return RGFW_h;
10298 case 0x2C595B4AU :
return RGFW_j;
10299 case 0x2C595B4BU :
return RGFW_k;
10300 case 0x2C595B4CU :
return RGFW_l;
10301 case 0x2707219EU :
return RGFW_semicolon;
10302 case 0x92E0B58DU :
return RGFW_apostrophe;
10303 case 0x36BF358DU :
return RGFW_backtick;
10304 case 0x26B1958CU :
return RGFW_shiftL;
10305 case 0x36BF2438U :
return RGFW_backSlash;
10306 case 0x2C595B5AU :
return RGFW_z;
10307 case 0x2C595B58U :
return RGFW_x;
10308 case 0x2C595B43U :
return RGFW_c;
10309 case 0x2C595B56U :
return RGFW_v;
10310 case 0x2C595B42U :
return RGFW_b;
10311 case 0x2C595B4EU :
return RGFW_n;
10312 case 0x2C595B4DU :
return RGFW_m;
10313 case 0x92E1A1C1U :
return RGFW_comma;
10314 case 0x672FFAD4U :
return RGFW_period;
10315 case 0x92E0A438U :
return RGFW_slash;
10316 case 0xC5A6BF7CU :
return RGFW_shiftR;
10317 case 0x5D64DA91U :
return RGFW_multiply;
10318 case 0xC914958CU :
return RGFW_altL;
10319 case 0x92E09CB5U :
return RGFW_space;
10320 case 0xB8FAE73BU :
return RGFW_capsLock;
10321 case 0x7174B789U :
return RGFW_F1;
10322 case 0x7174B78AU :
return RGFW_F2;
10323 case 0x7174B78BU :
return RGFW_F3;
10324 case 0x7174B78CU :
return RGFW_F4;
10325 case 0x7174B78DU :
return RGFW_F5;
10326 case 0x7174B78EU :
return RGFW_F6;
10327 case 0x7174B78FU :
return RGFW_F7;
10328 case 0x7174B780U :
return RGFW_F8;
10329 case 0x7174B781U :
return RGFW_F9;
10330 case 0x7B8E57B0U :
return RGFW_F10;
10331 case 0xC925FCDFU :
return RGFW_multiply;
10332 case 0xC925FCD0U :
return RGFW_KP_8;
10333 case 0xC925FCD1U :
return RGFW_KP_9;
10334 case 0x5EA3E8A4U :
return RGFW_minus;
10335 case 0xC925FCDCU :
return RGFW_KP_4;
10336 case 0xC925FCDDU :
return RGFW_KP_5;
10337 case 0xC925FCDEU :
return RGFW_KP_6;
10338 case 0xC925FCD9U :
return RGFW_KP_1;
10339 case 0xC925FCDAU :
return RGFW_KP_2;
10340 case 0xC925FCDBU :
return RGFW_KP_3;
10341 case 0xC925FCD8U :
return RGFW_KP_0;
10342 case 0x95852DACU :
return RGFW_period;
10343 case 0x7B8E57B1U :
return RGFW_F11;
10344 case 0x7B8E57B2U :
return RGFW_F12;
10345 case 0x7393FBACU :
return RGFW_KP_Return;
10346 case 0xB88EBF7CU :
return RGFW_altR;
10347 case 0xC925873BU :
return RGFW_numLock;
10348 case 0x2C595F45U :
return RGFW_home;
10349 case 0xC91BB690U :
return RGFW_up;
10350 case 0x672F9210U :
return RGFW_pageUp;
10351 case 0x3799258CU :
return RGFW_left;
10352 case 0x4CE33F7CU :
return RGFW_right;
10353 case 0x7B8E55DCU :
return RGFW_end;
10354 case 0x3799379EU :
return RGFW_down;
10355 case 0xBA90179EU :
return RGFW_pageDown;
10356 case 0x6723CB2CU :
return RGFW_insert;
10357 case 0x6725C50DU :
return RGFW_delete;
10358 case 0x6723658CU :
return RGFW_superL;
10359 case 0x39643F7CU :
return RGFW_superR;
10365void EMSCRIPTEN_KEEPALIVE RGFW_handleKeyEvent(
char* key,
char* code,
RGFW_bool press) {
10366 const char* iCode = code;
10369 while(*iCode) hash = ((hash ^ 0x7E057D79U) << 3) ^ (
unsigned int)*iCode++;
10371 u32 physicalKey = RGFW_wASMPhysicalToRGFW(hash);
10373 u8 mappedKey = (
u8)(*((
u32*)key));
10375 if (*((
u16*)key) != mappedKey) {
10377 if (*((
u32*)key) == *((
u32*)
"Tab")) mappedKey = RGFW_tab;
10381 e.key = (
u8)physicalKey;
10382 e.keyChar = (
u8)mappedKey;
10384 e._win = _RGFW->
root);
10386 RGFW_keyboard[physicalKey].prev = RGFW_keyboard[physicalKey].current;
10387 RGFW_keyboard[physicalKey].current = press;
10393 RGFW_updateKeyModsPro(_RGFW->
root, capital, numlock, control, alt, shift, super, scroll);
10396void EMSCRIPTEN_KEEPALIVE Emscripten_onDrop(
size_t count) {
10397 if (!(_RGFW->
root->
_flags & RGFW_windowAllowDND))
10402 e.droppedFilesCount = count;
10403 e._win = _RGFW->
root);
10413 if (waitMS == 0)
return;
10418 emscripten_sleep(0);
10424 #if defined(RGFW_BUFFER)
10425 win->buffer = buffer;
10426 win->bufferSize = area;
10432void EMSCRIPTEN_KEEPALIVE RGFW_makeSetValue(
size_t index,
char* file) {
10440#include <sys/stat.h>
10441#include <sys/types.h>
10445void EMSCRIPTEN_KEEPALIVE RGFW_mkdir(
char* name) { mkdir(name, 0755); }
10447void EMSCRIPTEN_KEEPALIVE RGFW_writeFile(
const char *path,
const char *data,
size_t len) {
10448 FILE* file = fopen(path,
"w+");
10452 fwrite(data,
sizeof(
char), len, file);
10457#if defined(RGFW_OPENGL) && !defined(RGFW_WEBGPU) && !defined(RGFW_BUFFER)
10458 EmscriptenWebGLContextAttributes attrs;
10459 attrs.alpha = RGFW_GL_HINTS[RGFW_glDepth];
10460 attrs.depth = RGFW_GL_HINTS[RGFW_glAlpha];
10461 attrs.stencil = RGFW_GL_HINTS[RGFW_glStencil];
10462 attrs.antialias = RGFW_GL_HINTS[RGFW_glSamples];
10463 attrs.premultipliedAlpha = EM_TRUE;
10464 attrs.preserveDrawingBuffer = EM_FALSE;
10466 if (RGFW_GL_HINTS[RGFW_glDoubleBuffer] == 0)
10467 attrs.renderViaOffscreenBackBuffer = 0;
10469 attrs.renderViaOffscreenBackBuffer = RGFW_GL_HINTS[RGFW_glAuxBuffers];
10471 attrs.failIfMajorPerformanceCaveat = EM_FALSE;
10472 attrs.majorVersion = (RGFW_GL_HINTS[RGFW_glMajor] == 0) ? 1 : RGFW_GL_HINTS[RGFW_glMajor];
10473 attrs.minorVersion = RGFW_GL_HINTS[RGFW_glMinor];
10475 attrs.enableExtensionsByDefault = EM_TRUE;
10476 attrs.explicitSwapControl = EM_TRUE;
10478 emscripten_webgl_init_context_attributes(&attrs);
10479 win->
src.ctx = emscripten_webgl_create_context(
"#canvas", &attrs);
10480 emscripten_webgl_make_context_current(win->
src.ctx);
10482 #ifdef LEGACY_GL_EMULATION
10483 EM_ASM(
"Module.useWebGL = true; GLImmediate.init();");
10486 glViewport(0, 0, win->
r.
w, win->
r.
h);
10491#if defined(RGFW_OPENGL) && !defined(RGFW_WEBGPU) && !defined(RGFW_BUFFER)
10492 if (win->
src.ctx == 0)
return;
10493 emscripten_webgl_destroy_context(win->
src.ctx);
10501i32 RGFW_initPlatform(
void) {
return 0; }
10504 RGFW_window_basic_init(win, rect, flags);
10507 #if defined(RGFW_WEBGPU)
10508 win->
src.ctx = wgpuCreateInstance(NULL);
10509 win->
src.device = emscripten_webgpu_get_device();
10510 win->
src.queue = wgpuDeviceGetQueue(win->
src.device);
10513 emscripten_set_canvas_element_size(
"#canvas", rect.
w, rect.
h);
10514 emscripten_set_window_title(name);
10517 emscripten_set_resize_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, NULL, EM_FALSE, Emscripten_on_resize);
10518 emscripten_set_fullscreenchange_callback(EMSCRIPTEN_EVENT_TARGET_DOCUMENT, NULL, EM_FALSE, Emscripten_on_fullscreenchange);
10519 emscripten_set_mousemove_callback(
"#canvas", NULL, EM_FALSE, Emscripten_on_mousemove);
10520 emscripten_set_touchstart_callback(
"#canvas", NULL, EM_FALSE, Emscripten_on_touchstart);
10521 emscripten_set_touchend_callback(
"#canvas", NULL, EM_FALSE, Emscripten_on_touchend);
10522 emscripten_set_touchmove_callback(
"#canvas", NULL, EM_FALSE, Emscripten_on_touchmove);
10523 emscripten_set_touchcancel_callback(
"#canvas", NULL, EM_FALSE, Emscripten_on_touchcancel);
10524 emscripten_set_mousedown_callback(
"#canvas", NULL, EM_FALSE, Emscripten_on_mousedown);
10525 emscripten_set_mouseup_callback(
"#canvas", NULL, EM_FALSE, Emscripten_on_mouseup);
10526 emscripten_set_wheel_callback(
"#canvas", NULL, EM_FALSE, Emscripten_on_wheel);
10527 emscripten_set_focusin_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, NULL, EM_FALSE, Emscripten_on_focusin);
10528 emscripten_set_focusout_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, NULL, EM_FALSE, Emscripten_on_focusout);
10529 emscripten_set_gamepadconnected_callback(NULL, 1, Emscripten_on_gamepad);
10530 emscripten_set_gamepaddisconnected_callback(NULL, 1, Emscripten_on_gamepad);
10532 if (flags & RGFW_windowAllowDND) {
10533 win->
_flags |= RGFW_windowAllowDND;
10537 window.addEventListener(
"keydown",
10539 var key = stringToNewUTF8(event.key); var code = stringToNewUTF8(event.code);
10540 Module._RGFW_handleKeyMods(event.getModifierState(
"CapsLock"), event.getModifierState(
"NumLock"), event.getModifierState(
"Control"), event.getModifierState(
"Alt"), event.getModifierState(
"Shift"), event.getModifierState(
"Meta"), event.getModifierState(
"ScrollLock"));
10541 Module._RGFW_handleKeyEvent(key, code, 1);
10542 _free(key); _free(code);
10545 window.addEventListener(
"keyup",
10547 var key = stringToNewUTF8(event.key); var code = stringToNewUTF8(event.code);
10548 Module._RGFW_handleKeyMods(event.getModifierState(
"CapsLock"), event.getModifierState(
"NumLock"), event.getModifierState(
"Control"), event.getModifierState(
"Alt"), event.getModifierState(
"Shift"), event.getModifierState(
"Meta"), event.getModifierState(
"ScrollLock"));
10549 Module._RGFW_handleKeyEvent(key, code, 0);
10550 _free(key); _free(code);
10556 var canvas = document.getElementById(
'canvas');
10557 canvas.addEventListener(
'drop', function(e) {
10558 e.preventDefault();
10559 if (e.dataTransfer.file < 0)
10562 var filenamesArray = [];
10563 var count = e.dataTransfer.files.length;
10566 var drop_dir =
'.rgfw_dropped_files';
10567 Module._RGFW_mkdir(drop_dir);
10569 for (var i = 0; i < count; i++) {
10570 var file = e.dataTransfer.files[i];
10572 var path =
'/' + drop_dir +
'/' + file.name.replace(
"//",
'_');
10573 var reader =
new FileReader();
10575 reader.onloadend = (e) => {
10576 if (reader.readyState != 2) {
10577 out(
'failed to read dropped file: '+file.name+
': '+reader.error);
10580 var data = e.target.result;
10582 Module._RGFW_writeFile(path,
new Uint8Array(data), file.size);
10586 reader.readAsArrayBuffer(file);
10588 var filename = stringToNewUTF8(path);
10590 filenamesArray.push(filename);
10592 Module._RGFW_makeSetValue(i, filename);
10595 Module._Emscripten_onDrop(count);
10597 for (var i = 0; i < count; ++i) {
10598 _free(filenamesArray[i]);
10602 canvas.addEventListener(
'dragover', function(e) { e.preventDefault();
return false; },
true);
10607 if ((flags & RGFW_windowNoInitAPI) == 0) {
10616 return (
u8)rgfw_keycode;
10620 if (win == NULL || ((win->
_flags & RGFW_windowFreeOnClose) && (win->
_flags & RGFW_EVENT_QUIT)))
return NULL;
10621 RGFW_event* ev = RGFW_window_checkEventCore(win);
10624 emscripten_sample_gamepad_data();
10627 for (i = 0; (i < emscripten_get_num_gamepads()) && (i < 4); i++) {
10630 EmscriptenGamepadEvent gamepadState;
10632 if (emscripten_get_gamepad_status(i, &gamepadState) != EMSCRIPTEN_RESULT_SUCCESS)
10637 for (j = 0; (j < gamepadState.numButtons) && (j < 16); j++) {
10639 RGFW_gamepadA, RGFW_gamepadB, RGFW_gamepadX, RGFW_gamepadY,
10640 RGFW_gamepadL1, RGFW_gamepadR1, RGFW_gamepadL2, RGFW_gamepadR2,
10641 RGFW_gamepadSelect, RGFW_gamepadStart,
10642 RGFW_gamepadL3, RGFW_gamepadR3,
10643 RGFW_gamepadUp, RGFW_gamepadDown, RGFW_gamepadLeft, RGFW_gamepadRight, RGFW_gamepadHome
10647 u32 button = map[j];
10651 if (RGFW_gamepadPressed[i][button].current != gamepadState.digitalButton[j]) {
10652 if (gamepadState.digitalButton[j])
10653 win->
event.
type = RGFW_gamepadButtonPressed;
10655 win->
event.
type = RGFW_gamepadButtonReleased;
10660 RGFW_gamepadPressed[i][button].prev = RGFW_gamepadPressed[i][button].current;
10661 RGFW_gamepadPressed[i][button].current = gamepadState.digitalButton[j];
10664 return &win->
event;
10668 for (j = 0; (j < gamepadState.numAxes) && (j < 4); j += 2) {
10670 if (_RGFW->
gamepadAxes[i][(
size_t)(j / 2)].x != (
i8)(gamepadState.axis[j] * 100.0f) ||
10671 _RGFW->
gamepadAxes[i][(
size_t)(j / 2)].y != (
i8)(gamepadState.axis[j + 1] * 100.0f)
10674 _RGFW->
gamepadAxes[i][(size_t)(j / 2)].
x = (
i8)(gamepadState.axis[j] * 100.0f);
10675 _RGFW->
gamepadAxes[i][(size_t)(j / 2)].
y = (
i8)(gamepadState.axis[j + 1] * 100.0f);
10678 win->
event.
type = RGFW_gamepadAxisMove;
10683 return &win->
event;
10693 emscripten_set_canvas_element_size(
"#canvas", a.
w, a.
h);
10705 static const char cursors[16][16] = {
10706 "default",
"default",
"text",
"crosshair",
10707 "pointer",
"ew-resize",
"ns-resize",
"nwse-resize",
"nesw-resize",
10708 "move",
"not-allowed"
10712 EM_ASM( { document.getElementById(
"canvas").style.cursor = UTF8ToString($0); }, cursors[mouse]);
10721 RGFW_window_showMouseFlags(win, show);
10725 EM_ASM(document.getElementById(
'canvas').style.cursor =
'none';);
10730 point.
x = EM_ASM_INT({
10731 return window.mouseX || 0;
10733 point.
y = EM_ASM_INT({
10734 return window.mouseY || 0;
10743 var canvas = document.getElementById(
'canvas');
10745 canvas.style.pointerEvents =
'none';
10747 canvas.style.pointerEvents =
'auto';
10754 EM_ASM({ navigator.clipboard.writeText(UTF8ToString($0)); }, text);
10768#if defined(RGFW_BUFFER)
10770 var data = Module.HEAPU8.slice($0, $0 + $1 * $2 * 4);
10771 let context = document.getElementById(
"canvas").getContext(
"2d");
10772 let image = context.getImageData(0, 0, $1, $2);
10773 image.data.set(data);
10774 context.putImageData(image, 0, $4 - $2);
10775 }, win->buffer, win->bufferSize.w, win->bufferSize.h, win->
r.
w, win->
r.
h);
10776#elif defined(RGFW_BUFFER)
10778 var data = Module.HEAPU8.slice($0, $0 + $1 * $2 * 4);
10779 let context = document.getElementById(
"canvas").getContext(
"2d");
10780 let image = context.getImageData(0, 0, $1, $2);
10781 image.data.set(data);
10782 context.putImageData(image, 0, 0);
10783 }, win->buffer, win->bufferSize.w, win->bufferSize.h, win->
r.
w, win->
r.
h);
10784 emscripten_sleep(0);
10791#if !defined(RGFW_WEBGPU) && !defined(RGFW_BUFFER)
10793 emscripten_webgl_make_context_current(0);
10795 emscripten_webgl_make_context_current(win->
src.ctx);
10802 emscripten_webgl_commit_frame();
10805 emscripten_sleep(0);
10816void RGFW_deinitPlatform(
void) { }
10821 #if defined(RGFW_BUFFER)
10822 if ((win->
_flags & RGFW_BUFFER_ALLOC))
10827 RGFW_clipboard_switch(NULL);
10831 if ((win->
_flags & RGFW_WINDOW_ALLOC)) {
10837int RGFW_innerWidth(
void) {
return EM_ASM_INT({
return window.innerWidth; }); }
10838int RGFW_innerHeight(
void) {
return EM_ASM_INT({
return window.innerHeight; }); }
10841 return RGFW_AREA(RGFW_innerWidth(), RGFW_innerHeight());
10846 return EM_ASM_INT({
10847 var ext = UTF8ToString($0, $1);
10848 var canvas = document.querySelector(
'canvas');
10849 var gl = canvas.getContext(
'webgl') || canvas.getContext(
'experimental-webgl');
10852 var supported = gl.getSupportedExtensions();
10853 return supported && supported.includes(ext) ? 1 : 0;
10854 }, extension, len);
10862 return (
RGFW_proc)emscripten_webgl_get_proc_address(procname);
10869 emscripten_sleep(milisecond);
10877 emscripten_exit_pointerlock();
10883 emscripten_request_pointerlock(
"#canvas", 1);
10889 emscripten_set_window_title(name);
10903 win->
_flags |= RGFW_windowFullscreen;
10904 EM_ASM( Module.requestFullscreen(
false,
true); );
10907 win->
_flags &= ~(
u32)RGFW_windowFullscreen;
10908 EM_ASM( Module.exitFullscreen(
false,
true); );
10914 var element = document.getElementById(
"canvas");
10916 element.style.opacity = $1;
10917 },
"elementId", opacity);
10947#if defined(RGFW_X11) || defined(RGFW_MACOS) || defined(RGFW_WASM) || defined(RGFW_WAYLAND)
10950 struct timespec time;
10952 time.tv_nsec = (
long int)((
double)ms * 1e+6);
10954 #ifndef RGFW_NO_UNIX_CLOCK
10955 nanosleep(&time, NULL);
10963#if defined(__cplusplus) && !defined(__EMSCRIPTEN__)
10968 #pragma warning( pop )
RGFWDEF void RGFW_deinit(void)
#define RGFW_STRNCMP(s1, s2, max)
Definition: RGFW.h:218
#define RGFW_ROUND(x)
Definition: RGFW.h:191
RGFWDEF RGFW_mouse * RGFW_loadMouse(u8 *icon, RGFW_area a, i32 channels)
RGFWDEF void RGFW_deinit_heap(void)
#define RGFW_key
Definition: RGFW.h:441
RGFWDEF RGFW_bool RGFW_usingWayland(void)
#define RGFW_STRSTR(str, substr)
Definition: RGFW.h:226
#define RGFW_FREE
Definition: RGFW.h:197
#define RGFW_RECT(x, y, w, h)
Definition: RGFW.h:583
RGFWDEF void RGFW_useWayland(RGFW_bool wayland)
uint64_t u64
Definition: RGFW.h:310
RGFWDEF RGFW_info * RGFW_getInfo(void)
RGFWDEF RGFW_bool RGFW_monitorModeCompare(RGFW_monitorMode mon, RGFW_monitorMode mon2, RGFW_modeRequest request)
int32_t i32
Definition: RGFW.h:309
#define RGFW_TRUE
Definition: RGFW.h:322
#define RGFW_POINT(x, y)
Definition: RGFW.h:582
#define RGFW_FALSE
Definition: RGFW.h:323
#define RGFW_MEMSET(ptr, value, num)
Definition: RGFW.h:210
u8 RGFW_bool
Definition: RGFW.h:318
#define RGFW_COCOA_FRAME_NAME
Definition: RGFW.h:430
#define RGFW_AREA(w, h)
Definition: RGFW.h:584
#define RGFW_ALLOC
Definition: RGFW.h:196
#define RGFW_ENUM(type, name)
Definition: RGFW.h:277
void RGFW_mouse
Definition: RGFW.h:625
int64_t i64
Definition: RGFW.h:311
uint8_t u8
Definition: RGFW.h:304
RGFWDEF RGFW_bool RGFW_monitor_requestMode(RGFW_monitor mon, RGFW_monitorMode mode, RGFW_modeRequest request)
#define RGFW_MAX_DROPS
Definition: RGFW.h:523
RGFWDEF RGFW_monitor RGFW_getPrimaryMonitor(void)
RGFWDEF void * RGFW_init_heap(void)
RGFWDEF i32 RGFW_init_ptr(RGFW_info *info)
RGFWDEF RGFW_monitor * RGFW_getMonitors(size_t *len)
RGFWDEF RGFW_bool RGFW_monitor_scaleToWindow(RGFW_monitor mon, RGFW_window *win)
#define RGFW_UNUSED(x)
Definition: RGFW.h:187
#define RGFW_STRNCPY(dist, src, len)
Definition: RGFW.h:222
#define RGFW_ASSERT
Definition: RGFW.h:202
RGFWDEF void RGFW_freeMouse(RGFW_mouse *mouse)
#define RGFWDEF
Definition: RGFW.h:272
#define RGFW_STRTOL(str, endptr, base)
Definition: RGFW.h:232
#define RGFW_ATOF(num)
Definition: RGFW.h:233
uint16_t u16
Definition: RGFW.h:306
int16_t i16
Definition: RGFW.h:307
RGFWDEF void RGFW_setInfo(RGFW_info *info)
#define RGFW_BOOL(x)
Definition: RGFW.h:321
int8_t i8
Definition: RGFW.h:305
#define RGFW_BIT(x)
Definition: RGFW.h:526
#define RGFW_MEMCPY(dist, src, len)
Definition: RGFW.h:214
RGFWDEF void RGFW_deinit_ptr(RGFW_info *info)
RGFWDEF i32 RGFW_init(void)
#define RGFW_MAX_PATH
Definition: RGFW.h:520
uint32_t u32
Definition: RGFW.h:308
#define XGetWindowProperty
Definition: XDL.h:416
#define XCreateFontCursor
Definition: XDL.h:380
#define XSetWMProtocols
Definition: XDL.h:447
#define XRRGetCrtcInfo
Definition: XDL.h:489
#define XDisplayName
Definition: XDL.h:482
#define XGetErrorText
Definition: XDL.h:405
#define XCloseDisplay
Definition: XDL.h:376
#define XRRGetOutputInfo
Definition: XDL.h:490
#define glXCreateContext
Definition: XDL.h:501
#define XRRFreeScreenResources
Definition: XDL.h:493
#define XDefineCursor
Definition: XDL.h:384
#define XResourceManagerString
Definition: XDL.h:433
#define XFreeGC
Definition: XDL.h:395
#define XMatchVisualInfo
Definition: XDL.h:472
#define glXGetProcAddress
Definition: XDL.h:505
#define XFreeCursor
Definition: XDL.h:403
#define XkbGetNames
Definition: XDL.h:466
#define XPutImage
Definition: XDL.h:485
#define XInternAtom
Definition: XDL.h:419
#define XRaiseWindow
Definition: XDL.h:430
#define XCreateRegion
Definition: XDL.h:382
#define glXGetCurrentContext
Definition: XDL.h:503
#define glXGetProcAddressARB
Definition: XDL.h:508
#define XSetWMSizeHints
Definition: XDL.h:458
#define XPeekEvent
Definition: XDL.h:426
#define XrmGetStringDatabase
Definition: XDL.h:479
#define XPending
Definition: XDL.h:427
#define XFreeColors
Definition: XDL.h:476
#define XDefaultRootWindow
Definition: XDL.h:470
#define XkbFreeKeyboard
Definition: XDL.h:468
#define XIconifyWindow
Definition: XDL.h:418
#define XDefaultScreen
Definition: XDL.h:471
#define glXChooseFBConfig
Definition: XDL.h:509
#define XRRGetScreenResources
Definition: XDL.h:492
#define XMoveWindow
Definition: XDL.h:424
#define XStoreName
Definition: XDL.h:457
#define XFreeEventData
Definition: XDL.h:404
#define XGetKeyboardControl
Definition: XDL.h:473
#define XGrabPointer
Definition: XDL.h:417
#define XTranslateCoordinates
Definition: XDL.h:450
#define XFlush
Definition: XDL.h:400
#define XRRGetScreenResourcesCurrent
Definition: XDL.h:488
XDLDEF void XDL_close(void)
#define glXGetVisualFromFBConfig
Definition: XDL.h:506
#define XRRSetCrtcConfig
Definition: XDL.h:496
#define XSetErrorHandler
Definition: XDL.h:438
#define XDestroyRegion
Definition: XDL.h:388
#define XDestroyWindow
Definition: XDL.h:389
#define XResizeWindow
Definition: XDL.h:432
#define XGetWindowAttributes
Definition: XDL.h:415
#define XSendEvent
Definition: XDL.h:436
#define XSetWMNormalHints
Definition: XDL.h:446
#define XWidthOfScreen
Definition: XDL.h:392
#define XCreateGC
Definition: XDL.h:394
#define XVisualIDFromVisual
Definition: XDL.h:455
#define XSetSelectionOwner
Definition: XDL.h:444
XDLDEF void XDL_init(void)
#define XGetSelectionOwner
Definition: XDL.h:412
#define XNextEvent
Definition: XDL.h:425
#define XrmDestroyDatabase
Definition: XDL.h:481
#define XkbGetState
Definition: XDL.h:391
#define XOpenDisplay
Definition: XDL.h:459
#define XkbGetKeyboardByName
Definition: XDL.h:467
#define XQueryPointer
Definition: XDL.h:429
#define XFree
Definition: XDL.h:401
#define XUnmapWindow
Definition: XDL.h:453
#define XkbGetMap
Definition: XDL.h:465
#define XSetInputFocus
Definition: XDL.h:441
#define XSetClassHint
Definition: XDL.h:437
#define XCreateColormap
Definition: XDL.h:379
#define XEventsQueued
Definition: XDL.h:397
#define glXMakeCurrent
Definition: XDL.h:502
#define glXQueryExtensionsString
Definition: XDL.h:512
#define XSync
Definition: XDL.h:449
#define XHeightOfScreen
Definition: XDL.h:393
#define XSelectInput
Definition: XDL.h:435
#define XGetWMNormalHints
Definition: XDL.h:414
#define XInitThreads
Definition: XDL.h:463
#define XrmGetResource
Definition: XDL.h:480
#define XMapRaised
Definition: XDL.h:421
#define XCreateImage
Definition: XDL.h:483
#define XDeleteProperty
Definition: XDL.h:386
#define XUngrabPointer
Definition: XDL.h:452
#define XChangeProperty
Definition: XDL.h:372
#define XCreatePixmap
Definition: XDL.h:484
#define XMapWindow
Definition: XDL.h:422
#define XConvertSelection
Definition: XDL.h:378
#define XWarpPointer
Definition: XDL.h:456
#define XRRFreeCrtcInfo
Definition: XDL.h:491
#define XGetEventData
Definition: XDL.h:406
#define glXGetFBConfigAttrib
Definition: XDL.h:507
#define XCreateWindow
Definition: XDL.h:383
#define glXSwapBuffers
Definition: XDL.h:504
#define XkbKeycodeToKeysym
Definition: XDL.h:464
#define XSetWMHints
Definition: XDL.h:445
#define XRRFreeOutputInfo
Definition: XDL.h:494
#define glXDestroyContext
Definition: XDL.h:510
void(* RGFW_windowMovedfunc)(RGFW_window *win, RGFW_rect r)
Definition: RGFW.h:1117
void(* RGFW_windowRefreshfunc)(RGFW_window *win)
Definition: RGFW.h:1137
void(* RGFW_mouseButtonfunc)(RGFW_window *win, RGFW_mouseButton button, double scroll, RGFW_bool pressed)
Definition: RGFW.h:1141
void(* RGFW_dndInitfunc)(RGFW_window *win, RGFW_point point)
Definition: RGFW.h:1135
RGFWDEF RGFW_gamepadButtonfunc RGFW_setGamepadButtonCallback(RGFW_gamepadButtonfunc func)
RGFWDEF RGFW_mouseButtonfunc RGFW_setMouseButtonCallback(RGFW_mouseButtonfunc func)
RGFWDEF RGFW_dndfunc RGFW_setDndCallback(RGFW_dndfunc func)
RGFWDEF RGFW_scaleUpdatedfunc RGFW_setScaleUpdatedCallback(RGFW_scaleUpdatedfunc func)
RGFWDEF RGFW_mouseNotifyfunc RGFW_setMouseNotifyCallback(RGFW_mouseNotifyfunc func)
RGFWDEF RGFW_windowMovedfunc RGFW_setWindowMovedCallback(RGFW_windowMovedfunc func)
void(* RGFW_windowQuitfunc)(RGFW_window *win)
Definition: RGFW.h:1127
RGFWDEF RGFW_windowResizedfunc RGFW_setWindowRestoredCallback(RGFW_windowResizedfunc func)
void(* RGFW_gamepadButtonfunc)(RGFW_window *win, u16 gamepad, u8 button, RGFW_bool pressed)
Definition: RGFW.h:1143
RGFWDEF RGFW_gamepadAxisfunc RGFW_setGamepadAxisCallback(RGFW_gamepadAxisfunc func)
RGFWDEF RGFW_windowQuitfunc RGFW_setWindowQuitCallback(RGFW_windowQuitfunc func)
void(* RGFW_keyfunc)(RGFW_window *win, u8 key, u8 keyChar, RGFW_keymod keyMod, RGFW_bool pressed)
Definition: RGFW.h:1139
void(* RGFW_windowMaximizedfunc)(RGFW_window *win, RGFW_rect r)
Definition: RGFW.h:1123
RGFWDEF RGFW_dndInitfunc RGFW_setDndInitCallback(RGFW_dndInitfunc func)
RGFWDEF RGFW_focusfunc RGFW_setFocusCallback(RGFW_focusfunc func)
RGFWDEF RGFW_gamepadfunc RGFW_setGamepadCallback(RGFW_gamepadfunc func)
RGFWDEF RGFW_mousePosfunc RGFW_setMousePosCallback(RGFW_mousePosfunc func)
void(* RGFW_mouseNotifyfunc)(RGFW_window *win, RGFW_point point, RGFW_bool status)
Definition: RGFW.h:1131
void(* RGFW_windowRestoredfunc)(RGFW_window *win, RGFW_rect r)
Definition: RGFW.h:1121
RGFWDEF RGFW_keyfunc RGFW_setKeyCallback(RGFW_keyfunc func)
void(* RGFW_dndfunc)(RGFW_window *win, char **droppedFiles, size_t droppedFilesCount)
Definition: RGFW.h:1149
void(* RGFW_mousePosfunc)(RGFW_window *win, RGFW_point point, RGFW_point vector)
Definition: RGFW.h:1133
void(* RGFW_focusfunc)(RGFW_window *win, RGFW_bool inFocus)
Definition: RGFW.h:1129
RGFWDEF RGFW_windowResizedfunc RGFW_setWindowMaximizedCallback(RGFW_windowResizedfunc func)
void(* RGFW_windowResizedfunc)(RGFW_window *win, RGFW_rect r)
Definition: RGFW.h:1119
void(* RGFW_gamepadAxisfunc)(RGFW_window *win, u16 gamepad, RGFW_point axis[2], u8 axisesCount, u8 whichAxis)
Definition: RGFW.h:1145
void(* RGFW_windowMinimizedfunc)(RGFW_window *win, RGFW_rect r)
Definition: RGFW.h:1125
RGFWDEF RGFW_windowRefreshfunc RGFW_setWindowRefreshCallback(RGFW_windowRefreshfunc func)
RGFWDEF RGFW_windowResizedfunc RGFW_setWindowResizedCallback(RGFW_windowResizedfunc func)
void(* RGFW_gamepadfunc)(RGFW_window *win, u16 gamepad, RGFW_bool connected)
Definition: RGFW.h:1147
RGFWDEF RGFW_windowResizedfunc RGFW_setWindowMinimizedCallback(RGFW_windowResizedfunc func)
void(* RGFW_scaleUpdatedfunc)(RGFW_window *win, float scaleX, float scaleY)
Definition: RGFW.h:1151
RGFWDEF void RGFW_writeClipboard(const char *text, u32 textLen)
ptrdiff_t RGFW_ssize_t
Definition: RGFW.h:1061
RGFWDEF const char * RGFW_readClipboard(size_t *size)
RGFWDEF RGFW_ssize_t RGFW_readClipboardPtr(char *str, size_t strCapacity)
RGFWDEF void RGFW_window_scaleToMonitor(RGFW_window *win)
RGFWDEF RGFW_monitor RGFW_window_getMonitor(RGFW_window *win)
#define RGFW_eventQueuePushEx(eventInit)
Definition: RGFW.h:1342
RGFWDEF double RGFW_getTime(void)
RGFWDEF u64 RGFW_getTimeNS(void)
RGFWDEF u64 RGFW_getTimerValue(void)
#define RGFW_MAX_EVENTS
Definition: RGFW.h:1327
void RGFW_eventQueuePush(RGFW_event event)
RGFW_event * RGFW_eventQueuePop(RGFW_window *win)
RGFWDEF u32 RGFW_rgfwToApiKey(u32 keycode)
RGFWDEF u64 RGFW_getTimerFreq(void)
RGFWDEF u32 RGFW_checkFPS(double startTime, u32 frameCount, u32 fpsCap)
RGFWDEF u8 RGFW_rgfwToKeyChar(u32 keycode)
RGFWDEF void RGFW_sleep(u64 milisecond)
RGFWDEF RGFW_window * RGFW_getRootWindow(void)
RGFWDEF void RGFW_setTime(double time)
RGFWDEF u32 RGFW_apiKeyToRGFW(u32 keycode)
RGFWDEF void RGFW_setRootWindow(RGFW_window *win)
RGFWDEF void RGFW_setXInstName(const char *name)
RGFWDEF RGFW_bool RGFW_window_mouseHeld(RGFW_window *win)
RGFWDEF void RGFW_window_checkEvents(RGFW_window *win, i32 waitMS)
RGFWDEF RGFW_bool RGFW_window_isMaximized(RGFW_window *win)
RGFWDEF void RGFW_window_setFlags(RGFW_window *win, RGFW_windowFlags)
RGFWDEF void RGFW_window_move(RGFW_window *win, RGFW_point v)
RGFWDEF RGFW_point RGFW_window_getMousePoint(RGFW_window *win)
RGFWDEF void RGFW_window_moveMouse(RGFW_window *win, RGFW_point v)
RGFWDEF void RGFW_window_setBorder(RGFW_window *win, RGFW_bool border)
RGFWDEF RGFW_bool RGFW_window_isMinimized(RGFW_window *win)
RGFWDEF void RGFW_window_setMousePassthrough(RGFW_window *win, RGFW_bool passthrough)
RGFWDEF RGFW_area RGFW_getScreenSize(void)
RGFWDEF void RGFW_window_focus(RGFW_window *win)
RGFWDEF void RGFW_window_moveToMonitor(RGFW_window *win, RGFW_monitor m)
RGFWDEF RGFW_bool RGFW_window_setMouseDefault(RGFW_window *win)
RGFWDEF void RGFW_window_resize(RGFW_window *win, RGFW_area a)
RGFWDEF RGFW_point RGFW_getGlobalMousePoint(void)
RGFWDEF void RGFW_window_eventWait(RGFW_window *win, i32 waitMS)
RGFWDEF RGFW_bool RGFW_window_opengl_isSoftware(RGFW_window *win)
RGFWDEF void RGFW_window_setOpacity(RGFW_window *win, u8 opacity)
RGFWDEF void RGFW_window_setFullscreen(RGFW_window *win, RGFW_bool fullscreen)
RGFWDEF RGFW_bool RGFW_window_allowsDND(RGFW_window *win)
RGFWDEF void RGFW_window_mouseHold(RGFW_window *win, RGFW_area area)
RGFWDEF void RGFW_window_setMinSize(RGFW_window *win, RGFW_area a)
RGFWDEF void RGFW_window_restore(RGFW_window *win)
RGFWDEF RGFW_bool RGFW_window_isHidden(RGFW_window *win)
RGFWDEF void RGFW_stopCheckEvents(void)
RGFWDEF void RGFW_window_setFloating(RGFW_window *win, RGFW_bool floating)
RGFWDEF void RGFW_window_initBufferSize(RGFW_window *win, RGFW_area area)
RGFWDEF RGFW_bool RGFW_window_isFloating(RGFW_window *win)
RGFWDEF void RGFW_window_maximize(RGFW_window *win)
RGFWDEF void RGFW_window_center(RGFW_window *win)
RGFWDEF void RGFW_window_setShouldClose(RGFW_window *win, RGFW_bool shouldClose)
RGFWDEF void RGFW_window_raise(RGFW_window *win)
RGFWDEF void RGFW_window_setName(RGFW_window *win, const char *name)
RGFWDEF RGFW_bool RGFW_window_isInFocus(RGFW_window *win)
RGFWDEF void RGFW_window_close(RGFW_window *win)
RGFWDEF void RGFW_window_mouseUnhold(RGFW_window *win)
RGFWDEF void RGFW_window_initBuffer(RGFW_window *win)
RGFWDEF void RGFW_moveToMacOSResourceDir(void)
RGFWDEF void RGFW_window_setMouse(RGFW_window *win, RGFW_mouse *mouse)
RGFWDEF RGFW_bool RGFW_window_setIcon(RGFW_window *win, u8 *icon, RGFW_area a, i32 channels)
RGFWDEF void RGFW_window_setAspectRatio(RGFW_window *win, RGFW_area a)
RGFWDEF RGFW_bool RGFW_window_borderless(RGFW_window *win)
RGFWDEF void RGFW_window_showMouse(RGFW_window *win, RGFW_bool show)
RGFWDEF RGFW_window * RGFW_createWindowPtr(const char *name, RGFW_rect rect, RGFW_windowFlags flags, RGFW_window *win)
RGFWDEF void RGFW_window_setMaxSize(RGFW_window *win, RGFW_area a)
RGFWDEF void RGFW_window_hide(RGFW_window *win)
RGFWDEF void RGFW_setClassName(const char *name)
RGFWDEF void RGFW_window_minimize(RGFW_window *win)
RGFWDEF RGFW_bool RGFW_window_shouldClose(RGFW_window *win)
RGFWDEF RGFW_bool RGFW_window_setIconEx(RGFW_window *win, u8 *icon, RGFW_area a, i32 channels, u8 type)
RGFWDEF RGFW_bool RGFW_window_mouseHidden(RGFW_window *win)
RGFWDEF RGFW_bool RGFW_window_isFullscreen(RGFW_window *win)
RGFWDEF RGFW_bool RGFW_window_setMouseStandard(RGFW_window *win, u8 mouse)
RGFWDEF RGFW_event * RGFW_window_checkEvent(RGFW_window *win)
RGFWDEF RGFW_window * RGFW_createWindow(const char *name, RGFW_rect rect, RGFW_windowFlags flags)
RGFWDEF void RGFW_window_show(RGFW_window *win)
RGFWDEF void RGFW_window_setDND(RGFW_window *win, RGFW_bool allow)
RGFWDEF void RGFW_window_initBufferPtr(RGFW_window *win, u8 *buffer, RGFW_area area)
RGFWDEF void RGFW_sendDebugInfo(RGFW_debugType type, RGFW_errorCode err, RGFW_debugContext ctx, const char *msg)
void(* RGFW_debugfunc)(RGFW_debugType type, RGFW_errorCode err, RGFW_debugContext ctx, const char *msg)
Definition: RGFW.h:1100
#define RGFW_DEBUG_CTX(win, err)
Definition: RGFW.h:1096
RGFWDEF RGFW_debugfunc RGFW_setDebugCallback(RGFW_debugfunc func)
#define RGFW_DEBUG_CTX_MON(monitor)
Definition: RGFW.h:1097
RGFWDEF const char * RGFW_getGamepadName(RGFW_window *win, u16 controller)
RGFWDEF RGFW_point RGFW_getGamepadAxis(RGFW_window *win, u16 controller, u16 whichAxis)
RGFWDEF u32 RGFW_isHeldGamepad(RGFW_window *win, u8 controller, RGFW_gamepadCodes button)
RGFWDEF u32 RGFW_isPressedGamepad(RGFW_window *win, u8 controller, RGFW_gamepadCodes button)
RGFWDEF u32 RGFW_wasPressedGamepad(RGFW_window *win, u8 controller, RGFW_gamepadCodes button)
RGFWDEF size_t RGFW_getGamepadCount(RGFW_window *win)
RGFWDEF RGFW_gamepadType RGFW_getGamepadType(RGFW_window *win, u16 controller)
RGFWDEF u32 RGFW_isReleasedGamepad(RGFW_window *win, u8 controller, RGFW_gamepadCodes button)
RGFWDEF void RGFW_setGLHint(RGFW_glHints hint, i32 value)
void(* RGFW_proc)(void)
Definition: RGFW.h:1231
RGFWDEF void RGFW_window_initOpenGL(RGFW_window *win)
RGFWDEF void RGFW_window_swapBuffers_software(RGFW_window *win)
void * RGFW_getCurrent_OpenGL(void)
RGFWDEF void RGFW_window_swapInterval(RGFW_window *win, i32 swapInterval)
RGFWDEF RGFW_bool RGFW_extensionSupported(const char *extension, size_t len)
RGFWDEF void RGFW_window_swapBuffers_OpenGL(RGFW_window *win)
RGFWDEF void RGFW_window_freeOpenGL(RGFW_window *win)
RGFWDEF RGFW_bool RGFW_extensionSupportedPlatform(const char *extension, size_t len)
RGFWDEF void RGFW_window_swapBuffers(RGFW_window *win)
RGFWDEF RGFW_proc RGFW_getProcAddress(const char *procname)
RGFWDEF RGFW_window * RGFW_getCurrent(void)
RGFWDEF void RGFW_window_makeCurrent_OpenGL(RGFW_window *win)
RGFWDEF void RGFW_window_makeCurrent(RGFW_window *win)
u32 h
Definition: RGFW.h:574
u32 w
Definition: RGFW.h:574
RGFW_monitor * monitor
Definition: RGFW.h:1090
u32 srcError
Definition: RGFW.h:1090
RGFW_window * win
Definition: RGFW.h:1090
RGFW_point vector
Definition: RGFW.h:637
float scaleX
Definition: RGFW.h:638
RGFW_point axis[4]
Definition: RGFW.h:653
RGFW_key key
Definition: RGFW.h:640
u8 axisesCount
Definition: RGFW.h:650
double scroll
Definition: RGFW.h:647
size_t droppedFilesCount
Definition: RGFW.h:658
u8 keyChar
Definition: RGFW.h:641
RGFW_bool repeat
Definition: RGFW.h:643
u8 button
Definition: RGFW.h:646
void * _win
Definition: RGFW.h:660
RGFW_eventType type
Definition: RGFW.h:635
RGFW_keymod keyMod
Definition: RGFW.h:644
RGFW_point point
Definition: RGFW.h:636
u16 gamepad
Definition: RGFW.h:649
u8 whichAxis
Definition: RGFW.h:652
char ** droppedFiles
Definition: RGFW.h:657
float scaleY
Definition: RGFW.h:638
i32 eventIndex
Definition: RGFW.h:1513
char * clipboard_data
Definition: RGFW.h:1534
RGFW_bool stopCheckEvents_bool
Definition: RGFW.h:1531
u32 apiKeycodes[RGFW_keyLast]
Definition: RGFW.h:1518
u8 keycodes[RGFW_OS_BASED_VALUE(256, 512, 128, 256)]
Definition: RGFW.h:1519
u64 timerOffset
Definition: RGFW.h:1532
RGFW_window * current
Definition: RGFW.h:1510
RGFW_point gamepadAxes[4][4]
Definition: RGFW.h:1522
u16 gamepadCount
Definition: RGFW.h:1527
const char * className
Definition: RGFW.h:1529
i32 eventLen
Definition: RGFW.h:1512
RGFW_event events[RGFW_MAX_EVENTS]
Definition: RGFW.h:1516
i32 gamepads[4]
Definition: RGFW.h:1525
RGFW_window * root
Definition: RGFW.h:1509
char gamepads_name[4][128]
Definition: RGFW.h:1526
RGFW_bool useWaylandBool
Definition: RGFW.h:1530
i32 windowCount
Definition: RGFW.h:1511
RGFW_mouse * hiddenMouse
Definition: RGFW.h:1515
RGFW_gamepadType gamepads_type[4]
Definition: RGFW.h:1524
char droppedFiles[RGFW_MAX_PATH *RGFW_MAX_DROPS]
Definition: RGFW.h:1535
u8 blue
Definition: RGFW.h:592
u8 red
Definition: RGFW.h:592
u8 green
Definition: RGFW.h:592
u32 refreshRate
Definition: RGFW.h:591
RGFW_area area
Definition: RGFW.h:590
i32 x
Definition: RGFW.h:597
RGFW_monitorMode mode
Definition: RGFW.h:603
float pixelRatio
Definition: RGFW.h:600
float scaleY
Definition: RGFW.h:599
float physH
Definition: RGFW.h:601
char name[128]
Definition: RGFW.h:598
float scaleX
Definition: RGFW.h:599
i32 y
Definition: RGFW.h:597
float physW
Definition: RGFW.h:601
i32 x
Definition: RGFW.h:564
i32 y
Definition: RGFW.h:564
i32 h
Definition: RGFW.h:569
i32 y
Definition: RGFW.h:569
i32 x
Definition: RGFW.h:569
i32 w
Definition: RGFW.h:569
RGFW_key exitKey
Definition: RGFW.h:802
RGFW_point _lastMousePoint
Definition: RGFW.h:803
u32 _flags
Definition: RGFW.h:805
RGFW_rect _oldRect
Definition: RGFW.h:806
RGFW_rect r
Definition: RGFW.h:799
RGFW_window_src src
Definition: RGFW.h:788
void * userPtr
Definition: RGFW.h:795
RGFW_event event
Definition: RGFW.h:797