summaryrefslogtreecommitdiff
path: root/rgfw.c3l/include/RGFW.h
diff options
context:
space:
mode:
authorandromeda <andromeda@bsd.my.domain>2026-10-24 00:48:05 -0400
committerandromeda <andromeda@bsd.my.domain>2026-10-24 00:48:05 -0400
commiteb0f2cc6373393303c5a4cd83792dd79103b85de (patch)
tree3f4b746ec73ce745f0c65a5666da7293bd7bd907 /rgfw.c3l/include/RGFW.h
parent2e0b6ffcd7c3ddc09daca64993bdc62fc428a175 (diff)
revitalise
Diffstat (limited to 'rgfw.c3l/include/RGFW.h')
-rw-r--r--rgfw.c3l/include/RGFW.h5081
1 files changed, 3145 insertions, 1936 deletions
diff --git a/rgfw.c3l/include/RGFW.h b/rgfw.c3l/include/RGFW.h
index 8016f02..844eb95 100644
--- a/rgfw.c3l/include/RGFW.h
+++ b/rgfw.c3l/include/RGFW.h
@@ -41,8 +41,8 @@
#define RGFW_X11 (optional) (unix only) if X11 should be used. This option is turned on by default by unix systems except for MacOS
#define RGFW_WAYLAND (optional) (unix only) use Wayland. (This can be used with X11)
+ #define RGFW_NO_STATIC_CONTEXT - do not initalizize with a static variable, use the heap if RGFW is not manually initalized
#define RGFW_NO_X11 (optional) (unix only) don't fallback to X11 when using Wayland
- #define RGFW_NO_LOAD_WGL (optional) (windows only) if WGL should be loaded dynamically during runtime
#define RGFW_NO_X11_CURSOR (optional) (unix only) don't use XCursor
#define RGFW_NO_X11_CURSOR_PRELOAD (optional) (unix only) use XCursor, but don't link it in code, (you'll have to link it with -lXcursor)
#define RGFW_NO_X11_EXT_PRELOAD (optional) (unix only) use Xext, but don't link it in code, (you'll have to link it with -lXext)
@@ -55,10 +55,11 @@
#define RGFW_COCOA_GRAPHICS_SWITCHING - (optional) (cocoa) use automatic graphics switching (allow the system to choose to use GPU or iGPU)
#define RGFW_COCOA_FRAME_NAME (optional) (cocoa) set frame name
#define RGFW_NO_DPI - do not calculate DPI and don't use libShcore (win32)
- #define RGFW_NO_XRANDR - do use not XRandr (X11)
#define RGFW_ADVANCED_SMOOTH_RESIZE - use advanced methods for smooth resizing (may result in a spike in memory usage or worse performance) (eg. WM_TIMER and XSyncValue)
#define RGFW_NO_INFO - do not define the RGFW_info struct (without RGFW_IMPLEMENTATION)
#define RGFW_NO_GLXWINDOW - do not use GLXWindow
+ #define RGFW_NO_ALLOCATE_MONITORS - do not allocate monitors on the heap at all (when there's no pre-allocated space left)
+ #define RGFW_NO_INCLUDE_VULKAN - do not include the Vulkan.h header, you have to include it yourself
#define RGFW_ALLOC x - choose the default allocation function (defaults to standard malloc)
#define RGFW_FREE x - choose the default deallocation function (defaults to standard free)
@@ -69,12 +70,14 @@
#define RGFW_USE_INT - force the use c-types rather than stdint.h (for systems that might not have stdint.h (msvc))
#define RGFW_bool x - choose what type to use for bool, by default u32 is used
+
+ #define RGFW_PREALLOCATED_MONITORS x - choose the default amount of pre-allocated monitors (can be zero)
*/
/*
Example to get you started :
-linux : gcc main.c -lX11 -lXrandr -lm
+*nix : gcc main.c -lX11 -lXrandr -lm
windows : gcc main.c -lgdi32
macos : gcc main.c -framework Cocoa -framework CoreVideo -framework IOKit
@@ -116,7 +119,7 @@ int main() {
shared :
windows:
gcc -shared RGFW.o -lopengl32 -lgdi32 -o RGFW.dll
- linux:
+ unix:
gcc -shared RGFW.o -lX11 -lGL -lXrandr -o RGFW.so
macos:
gcc -shared RGFW.o -framework CoreVideo -framework Cocoa -framework OpenGL -framework IOKit
@@ -165,7 +168,7 @@ int main() {
#pragma comment(lib, "User32")
#pragma comment(lib, "Advapi32")
#pragma warning( push )
- #pragma warning( disable : 4995 4191 4127)
+ #pragma warning( disable : 4996 4191 4127)
#if _MSC_VER < 600
#define RGFW_C89
#endif
@@ -175,15 +178,14 @@ int main() {
#endif
#endif
-#if defined(RGFW_EGL) && !defined(RGFW_OPENGL)
- #define RGFW_OPENGL
-#endif
-
/* these OS macros look better & are standardized */
/* plus it helps with cross-compiling */
#ifdef __EMSCRIPTEN__
#define RGFW_WASM
+ #ifdef RGFW_EGL
+ #define RGFW_OPENGL
+ #endif
#endif
#if defined(RGFW_X11) && defined(__APPLE__) && !defined(RGFW_CUSTOM_BACKEND)
@@ -212,11 +214,27 @@ int main() {
#define RGFW_MACOS
#endif
+#if defined(RGFW_X11) || defined(RGFW_WASM) || defined(RGFW_WAYLAND)
+ #ifndef _POSIX_C_SOURCE
+ #define _POSIX_C_SOURCE 199309L
+ #endif
+
+ /* __USE_POSIX199309 is part of glibc internals, and isn't intended to be used outside. */
+ /* However, existing RGFW code may depend on it implicitly. */
+ #ifndef __USE_POSIX199309
+ #define __USE_POSIX199309
+ #endif
+#endif
+
#ifndef RGFW_ASSERT
#include <assert.h>
#define RGFW_ASSERT assert
#endif
+#ifndef RGFW_STATIC_ASSERT
+ #define RGFW_STATIC_ASSERT(check_name, x) typedef char RGFW_check_##check_name[(x) ? 1 : -1];
+#endif
+
#if !defined(__STDC_VERSION__)
#define RGFW_C89
#endif
@@ -239,6 +257,10 @@ int main() {
#define RGFW_ROUND(x) (i32)((x) >= 0 ? (x) + 0.5f : (x) - 0.5f)
#endif
+#ifndef RGFW_ABS
+ #define RGFW_ABS(x) (((x) < 0) ? -(x) : (x))
+#endif
+
#ifndef RGFW_ROUNDF
#define RGFW_ROUNDF(x) (float)((i32)((x) + ((x) < 0.0f ? -0.5f : 0.5f)))
#endif
@@ -293,9 +315,10 @@ int main() {
#ifndef RGFW_MAX_EVENTS
#define RGFW_MAX_EVENTS 32
#endif
-
-#ifndef RGFW_MAX_MONITORS
- #define RGFW_MAX_MONITORS 6
+#ifndef RGFW_PREALLOCATED_MONITORS
+ #define RGFW_PREALLOCATED_MONITORS 6 /* the number of preallocated monitors */
+#elif defined(RGFW_NO_ALLOCATE_MONITORS) && (RGFW_PREALLOCATED_MONITORS == 0)
+ #warning RGFW monitors have no place to be allocated
#endif
#ifndef RGFW_COCOA_FRAME_NAME
@@ -345,16 +368,28 @@ int main() {
#define RGFW_HEADER
#include <stddef.h>
+#include <limits.h>
+
#ifndef RGFW_INT_DEFINED
#ifdef RGFW_USE_INT /* optional for any system that might not have stdint.h */
typedef unsigned char u8;
typedef signed char i8;
typedef unsigned short u16;
typedef signed short i16;
- typedef unsigned long int u32;
- typedef signed long int i32;
- typedef unsigned long long u64;
- typedef signed long long i64;
+ #if INT_MAX == 0x7FFFFFFF
+ typedef unsigned int u32;
+ typedef signed int i32;
+ #else
+ typedef unsigned long int u32;
+ typedef signed long int i32;
+ #endif
+ #if LONG_MAX == 0x7FFFFFFFFFFFFFFFL
+ typedef unsigned long u64;
+ typedef signed long i64;
+ #else
+ typedef unsigned long long u64;
+ typedef signed long long i64;
+ #endif
#else /* use stdint standard types instead of c "standard" types */
#include <stdint.h>
@@ -370,7 +405,9 @@ int main() {
#define RGFW_INT_DEFINED
#endif
-typedef ptrdiff_t RGFW_ssize_t;
+RGFW_STATIC_ASSERT(size64, sizeof(i64) == 8)
+RGFW_STATIC_ASSERT(size32, sizeof(i32) == 4)
+RGFW_STATIC_ASSERT(size16, sizeof(i16) == 2)
#ifndef RGFW_BOOL_DEFINED
#define RGFW_BOOL_DEFINED
@@ -381,7 +418,7 @@ typedef ptrdiff_t RGFW_ssize_t;
#define RGFW_TRUE (RGFW_bool)1
#define RGFW_FALSE (RGFW_bool)0
-#define RGFW_ENUM(type, name) type name; enum
+#define RGFW_ENUM(type, name) type name; enum name##_enum
#define RGFW_BIT(x) (1 << (x))
#ifdef RGFW_VULKAN
@@ -408,8 +445,31 @@ typedef ptrdiff_t RGFW_ssize_t;
#define RGFW_VK_SURFACE NULL
#endif
+ #ifndef RGFW_NO_INCLUDE_VULKAN
+ #include <vulkan/vulkan.h>
+ #endif
+
+ #if defined(RGFW_X11)
+ typedef VkResult (VKAPI_PTR *RGFW_vkCreateXlibSurfaceKHRProc)(VkInstance, const VkXlibSurfaceCreateInfoKHR*, const VkAllocationCallbacks*, VkSurfaceKHR*);
+ typedef VkBool32 (VKAPI_PTR *RGFW_vkGetPhysicalDeviceXlibPresentationSupportKHRProc)(VkPhysicalDevice, uint32_t, Display*, VisualID);
+ #endif
+ #ifdef RGFW_WAYLAND
+ typedef VkResult (VKAPI_PTR *RGFW_vkCreateWaylandSurfaceKHRProc)(VkInstance, const VkWaylandSurfaceCreateInfoKHR*, const VkAllocationCallbacks*, VkSurfaceKHR*);
+ typedef VkBool32 (VKAPI_PTR *RGFW_vkGetPhysicalDeviceWaylandPresentationSupportKHRProc)(VkPhysicalDevice, uint32_t, struct wl_display*);
+ #endif
+ #ifdef RGFW_WINDOWS
+ typedef VkResult (VKAPI_PTR *RGFW_vkCreateWin32SurfaceKHRProc)(VkInstance, const VkWin32SurfaceCreateInfoKHR*, const VkAllocationCallbacks*, VkSurfaceKHR*);
+ typedef VkBool32 (VKAPI_PTR *RGFW_vkGetPhysicalDeviceWin32PresentationSupportKHRProc)(VkPhysicalDevice, uint32_t);
+ #endif
#endif
+/*! @brief Flags for RGFW initialization */
+typedef RGFW_ENUM(u8, RGFW_initFlags) {
+ RGFW_initOpenGL = RGFW_BIT(0), /*!< Load Native OpenGL */
+ RGFW_initEGL = RGFW_BIT(1), /*!< Load EGL */
+ RGFW_initVulkan = RGFW_BIT(2), /*!< Load Vulkan */
+ RGFW_initX11 = RGFW_BIT(3) /*!< Force X11 (over Wayland) */
+};
/*! @brief The stucture that contains information about the current RGFW instance */
typedef struct RGFW_info RGFW_info;
@@ -616,9 +676,9 @@ typedef RGFW_ENUM(u8, RGFW_key) {
/*! @brief abstract mouse button codes */
typedef RGFW_ENUM(u8, RGFW_mouseButton) {
- RGFW_mouseLeft = 0, /*!< left mouse button is pressed */
- RGFW_mouseMiddle, /*!< mouse-wheel-button is pressed */
- RGFW_mouseRight, /*!< right mouse button is pressed */
+ RGFW_mouseLeft = 0, /*!< left mouse button */
+ RGFW_mouseMiddle, /*!< mouse-wheel-button */
+ RGFW_mouseRight, /*!< right mouse button */
RGFW_mouseMisc1, RGFW_mouseMisc2, RGFW_mouseMisc3, RGFW_mouseMisc4, RGFW_mouseMisc5,
RGFW_mouseFinal
};
@@ -639,7 +699,7 @@ typedef RGFW_ENUM(u8, RGFW_dndActionType) {
RGFW_dndActionNone = 0,
RGFW_dndActionEnter, /*!< data has been dragged into the window area */
RGFW_dndActionMove, /*!< the data that was dragged into the window area has moved inside the window */
- RGFW_dndActionExit, /*!< the data that was dragged into the window area has left the window */
+ RGFW_dndActionExit /*!< the data that was dragged into the window area has left the window */
};
/*! types of transfered data (clipboard, dnd) */
@@ -652,10 +712,17 @@ typedef RGFW_ENUM(u8, RGFW_dataTransferType) {
RGFW_dataUnknown /*!< unknown raw data */
};
+/*! struct for data transfers, mostly used for the clipboard API */
+typedef struct RGFW_dataTransfer {
+ const char* data; /*!< transfered data */
+ size_t length; /*!< the full length of the data in bytes, including null-terminator, if included. null-terminators are ensured when reading data from RGFW */
+ RGFW_dataTransferType type; /*!< the type of data being transfered */
+} RGFW_dataTransfer;
+
/*! internal node for a individual data drop */
typedef struct RGFW_dataDropNode {
const char* data; /*!< dropped data */
- size_t size; /*!< the size of the data in bytes */
+ size_t length; /*!< the size of the data in bytes */
RGFW_dataTransferType type; /*!< the type of data being dropped */
struct RGFW_dataDropNode* next; /*!< the next drop data node if any [when handling callbacks, this will always be NULL because the linked list is built as events are processed] */
} RGFW_dataDropNode;
@@ -669,7 +736,7 @@ typedef RGFW_ENUM(u8, RGFW_eventType) {
RGFW_mouseButtonPressed, /*!< a mouse button has been pressed (left,middle,right) */
RGFW_mouseButtonReleased, /*!< a mouse button has been released (left,middle,right) */
RGFW_mouseScroll, /*!< a mouse scroll event */
- RGFW_mousePosChanged, /*!< the position of the mouse has been changed */
+ RGFW_mouseMotion, /*!< the position of the mouse has been changed / the mouse has moved */
RGFW_mouseRawMotion, /*!< raw mouse motion */
RGFW_mouseEnter, /*!< mouse entered the window */
RGFW_mouseLeave, /*!< mouse left the window */
@@ -687,7 +754,8 @@ typedef RGFW_ENUM(u8, RGFW_eventType) {
RGFW_scaleUpdated, /*!< content scale factor changed */
RGFW_monitorConnected, /*!< a monitor has been connected */
RGFW_monitorDisconnected, /*!< a monitor has been disconnected */
- RGFW_eventCount /*!< the number of event types there are */
+ RGFW_eventCount, /*!< the number of event types there are */
+ RGFW_mousePosChanged = RGFW_mouseMotion /*!< alias for RGFW_mouseMotion (may be deleted at some point) */
};
/*! @brief flags for toggling whether or not an event should be processed */
@@ -698,7 +766,7 @@ typedef RGFW_ENUM(u32, RGFW_eventFlag) {
RGFW_mouseScrollFlag = RGFW_BIT(RGFW_mouseScroll),
RGFW_mouseButtonPressedFlag = RGFW_BIT(RGFW_mouseButtonPressed),
RGFW_mouseButtonReleasedFlag = RGFW_BIT(RGFW_mouseButtonReleased),
- RGFW_mousePosChangedFlag = RGFW_BIT(RGFW_mousePosChanged),
+ RGFW_mouseMotionFlag = RGFW_BIT(RGFW_mouseMotion),
RGFW_mouseRawMotionFlag = RGFW_BIT(RGFW_mouseRawMotion),
RGFW_mouseEnterFlag = RGFW_BIT(RGFW_mouseEnter),
RGFW_mouseLeaveFlag = RGFW_BIT(RGFW_mouseLeave),
@@ -716,9 +784,10 @@ typedef RGFW_ENUM(u32, RGFW_eventFlag) {
RGFW_dataDragFlag = RGFW_BIT(RGFW_dataDrag),
RGFW_monitorConnectedFlag = RGFW_BIT(RGFW_monitorConnected),
RGFW_monitorDisconnectedFlag = RGFW_BIT(RGFW_monitorDisconnected),
+ RGFW_mousePosChangedFlag = RGFW_mouseMotionFlag, /* alias for RGFW_mouseMotionFlag (may be deleted at some point) */
RGFW_keyEventsFlag = RGFW_keyPressedFlag | RGFW_keyReleasedFlag | RGFW_keyCharFlag,
- RGFW_mouseEventsFlag = RGFW_mouseButtonPressedFlag | RGFW_mouseButtonReleasedFlag | RGFW_mousePosChangedFlag | RGFW_mouseEnterFlag | RGFW_mouseLeaveFlag | RGFW_mouseScrollFlag | RGFW_mouseRawMotionFlag,
+ RGFW_mouseEventsFlag = RGFW_mouseButtonPressedFlag | RGFW_mouseButtonReleasedFlag | RGFW_mouseMotionFlag | RGFW_mouseEnterFlag | RGFW_mouseLeaveFlag | RGFW_mouseScrollFlag | RGFW_mouseRawMotionFlag,
RGFW_windowEventsFlag = RGFW_windowMovedFlag | RGFW_windowResizedFlag | RGFW_windowRefreshFlag | RGFW_windowMaximizedFlag | RGFW_windowMinimizedFlag | RGFW_windowRestoredFlag | RGFW_scaleUpdatedFlag,
RGFW_windowFocusEventsFlag = RGFW_windowFocusInFlag | RGFW_windowFocusOutFlag,
RGFW_dataDragDropEventsFlag = RGFW_dataDropFlag | RGFW_dataDragFlag,
@@ -756,13 +825,13 @@ typedef struct RGFW_mouseDeltaEvent {
float x, y; /*!< the raw mouse scroll or motion delta value */
} RGFW_mouseDeltaEvent;
-/*! @brief event data for a mouse position event (RGFW_mousePosChanged) */
-typedef struct RGFW_mousePosEvent {
+/*! @brief event data for a mouse position event (RGFW_mouseMotion) */
+typedef struct RGFW_mouseMotionEvent {
RGFW_eventType type; /*!< which event has been sent?*/
RGFW_window* win; /*!< the window this event applies to (for event queue events) */
i32 x, y; /*!< mouse x, y of event (or drop point) */
RGFW_bool inWindow; /*!< if the mouse is in the window or not */
-} RGFW_mousePosEvent;
+} RGFW_mouseMotionEvent;
/*! @brief event data for a key press/release event */
typedef struct RGFW_keyEvent {
@@ -830,7 +899,7 @@ typedef union RGFW_event {
RGFW_windowUpdateEvent update; /*!< data for window update/move/resize/refresh events */
RGFW_mouseButtonEvent button; /*!< data for a button press/release */
RGFW_mouseDeltaEvent delta; /*!< data for a mouse scroll or raw motion */
- RGFW_mousePosEvent mouse; /*!< data for mouse motion events */
+ RGFW_mouseMotionEvent mouse; /*!< data for mouse motion events */
RGFW_keyEvent key; /*!< data for key press/release/hold events */
RGFW_keyCharEvent keyChar; /*!< data for key character events */
RGFW_dataDropEvent drop; /*!< data dropping events */
@@ -859,13 +928,24 @@ typedef struct RGFW_callbacks {
RGFW_genericFunc arr[RGFW_eventCount]; /*!< an array of all the callbacks */
} RGFW_callbacks;
+typedef RGFW_ENUM(u8, RGFW_fullscreenMode) {
+ RGFW_fullscreenNone,
+ /*!< borderless/windowed fullscreen | the window changes it's size to match the monitor's current mode
+ the window is not hidden and maintains it's size when it is unfocused */
+ RGFW_fullscreenBorderless, /*!< borderless/windowed fullscreen */
+ /*!< exclusive fullscreen | the monitor's mode tries to change to match the window's size.
+ The original mode is toggled when the window goes in and out of focus and
+ the window is hidden when it is not in focus */
+ RGFW_fullscreenExclusive, /*!< exclusive fullscreen */
+};
+
/*! @brief optional bitwise arguments for making a windows, these can be OR'd together */
typedef RGFW_ENUM(u32, RGFW_windowFlags) {
RGFW_windowNoBorder = RGFW_BIT(0), /*!< the window doesn't have a border / frame / decor */
RGFW_windowNoResize = RGFW_BIT(1), /*!< the window cannot be resized by the user */
RGFW_windowAllowDND = RGFW_BIT(2), /*!< the window supports drag and drop */
RGFW_windowHideMouse = RGFW_BIT(3), /*! the window should hide the mouse (can be toggled later on using `RGFW_window_showMouse`) */
- RGFW_windowFullscreen = RGFW_BIT(4), /*!< the window is fullscreen by default */
+ RGFW_windowFullscreenExclusive = RGFW_BIT(4), /*!< the window is exclusive fullscreen by default */
RGFW_windowTranslucent = RGFW_BIT(5), /*!< the window is translucent (only properly works on X11 and MacOS, although it's meant for for windows) */
RGFW_windowTransparent = RGFW_windowTranslucent, /*!< the window is translucent (only properly works on X11 and MacOS, although it's meant for for windows) */
RGFW_windowCenter = RGFW_BIT(6), /*! center the window on the screen */
@@ -881,8 +961,7 @@ typedef RGFW_ENUM(u32, RGFW_windowFlags) {
RGFW_windowCaptureMouse = RGFW_BIT(16), /*!< capture the mouse mouse mouse on window creation */
RGFW_windowOpenGL = RGFW_BIT(17), /*!< create an OpenGL context (you can also do this manually with RGFW_window_createContext_OpenGL) */
RGFW_windowEGL = RGFW_BIT(18), /*!< create an EGL context (you can also do this manually with RGFW_window_createContext_EGL) */
- RGFW_noDeinitOnClose = RGFW_BIT(19), /*!< do not auto deinit RGFW if the window closes and this is the last window open */
- RGFW_windowedFullscreen = RGFW_windowNoBorder | RGFW_windowMaximize,
+ RGFW_windowFullscreenBorderless = RGFW_BIT(19), /*!< the window is borderless fullscreen by default */
RGFW_windowCaptureRawMouse = RGFW_windowCaptureMouse | RGFW_windowRawMouse
};
@@ -945,8 +1024,10 @@ typedef RGFW_ENUM(u8, RGFW_errorCode) {
RGFW_errFailedFuncLoad,
RGFW_errBuffer,
RGFW_errMetal,
+ RGFW_errObjcRuntime,
RGFW_errPlatform,
RGFW_errEventQueue,
+ RGFW_errNoInit,
RGFW_infoWindow, RGFW_infoBuffer, RGFW_infoGlobal, RGFW_infoOpenGL,
RGFW_warningWayland, RGFW_warningOpenGL
};
@@ -964,7 +1045,7 @@ typedef void (* RGFW_debugFunc)(const RGFW_debugInfo* info);
/*! @brief function pointer equivalent of void* */
typedef void (*RGFW_proc)(void);
-#if defined(RGFW_OPENGL)
+#if defined(RGFW_OPENGL) || defined(RGFW_EGL)
/*! @brief abstract structure for interfacing with the underlying OpenGL API */
typedef struct RGFW_glContext RGFW_glContext;
@@ -983,7 +1064,8 @@ typedef RGFW_ENUM(i32, RGFW_glProfile) {
RGFW_glCore = 0, /*!< the core OpenGL version, e.g. just support for that version */
RGFW_glForwardCompatibility, /*!< only compatibility for newer versions of OpenGL as well as the requested version */
RGFW_glCompatibility, /*!< allow compatibility for older versions of OpenGL as well as the requested version */
- RGFW_glES /*!< use OpenGL ES */
+ RGFW_glES, /*!< use OpenGL ES */
+ RGFW_glWeb /*!< use WebGL version (otherwise the version is changed to match it's GLES equivalent) */
};
/*! values for the renderer hint */
@@ -1014,7 +1096,7 @@ typedef struct RGFW_glHints {
RGFW_glRenderer renderer; /*!< renderer to use e.g. accelerated or software defaults to accelerated */
} RGFW_glHints;
-#endif
+#endif /* RGFW_OPENGL */
/**!
* @brief Allocates memory using the allocator defined by RGFW_ALLOC at compile time.
@@ -1030,6 +1112,51 @@ RGFWDEF void* RGFW_alloc(size_t size);
RGFWDEF void RGFW_free(void* ptr);
/**!
+ * @brief Retrieves the size of the RGFW_info structure.
+ * @return The size (in bytes) of RGFW_info.
+*/
+RGFWDEF size_t RGFW_sizeofInfo(void);
+
+/**!
+ * @brief Initializes the RGFW library internally.
+ * @param className The class name for the application.
+ * @param flags The initialization flags.
+ * @return 0 on success, a negative number error error on failure and a positive number for a warning.
+*/
+RGFWDEF i32 RGFW_init(const char* className, RGFW_initFlags flags);
+
+/**!
+ * @brief Deinitializes the current instance of the RGFW library.
+*/
+RGFWDEF void RGFW_deinit(void);
+
+/**!
+ * @brief Initializes RGFW using a user-provided RGFW_info structure.
+ * @param info A pointer to an RGFW_info structure to be used for initialization.
+ * @return 0 on success, a negative number error error on failure and a positive number for a warning.
+*/
+RGFWDEF i32 RGFW_init_ptr(const char* className, RGFW_initFlags flags, RGFW_info* info);
+
+/**!
+ * @brief Deinitializes a specific RGFW instance stored in the provided RGFW_info pointer.
+ * @param info A pointer to the RGFW_info structure representing the instance to deinitialize.
+*/
+RGFWDEF void RGFW_deinit_ptr(RGFW_info* info);
+
+/**!
+ * @brief Sets the global RGFW_info structure pointer.
+ * @param info A pointer to the RGFW_info structure to set.
+*/
+RGFWDEF void RGFW_setInfo(RGFW_info* info);
+
+/**!
+ * @brief Retrieves the global RGFW_info structure pointer.
+ * @return A pointer to the current RGFW_info structure.
+*/
+RGFWDEF RGFW_info* RGFW_getInfo(void);
+
+
+/**!
* @brief Returns the size (in bytes) of the RGFW_window structure.
* @return The size of the RGFW_window structure.
*/
@@ -1042,15 +1169,6 @@ RGFWDEF size_t RGFW_sizeofWindow(void);
RGFWDEF size_t RGFW_sizeofWindowSrc(void);
/**!
- * @brief (Unix) Toggles the use of Wayland.
- * This is enabled by default when compiled with `RGFW_WAYLAND`.
- * If not using `RGFW_WAYLAND`, Wayland functions are not exposed.
- * This function can be used to force the use of XWayland.
- * @param wayland A boolean value indicating whether to use Wayland (true) or not (false).
-*/
-RGFWDEF void RGFW_useWayland(RGFW_bool wayland);
-
-/**!
* @brief Checks if Wayland is currently being used.
* @return RGFW_TRUE if using Wayland, RGFW_FALSE otherwise.
*/
@@ -1075,21 +1193,6 @@ RGFWDEF void* RGFW_getDisplay_X11(void);
RGFWDEF struct wl_display* RGFW_getDisplay_Wayland(void);
/**!
- * @brief Sets the class name for X11 and WinAPI windows.
- * Windows with the same class name will be grouped by the window manager.
- * By default, the class name matches the root window’s name.
- * @param name The class name to assign.
-*/
-RGFWDEF void RGFW_setClassName(const char* name);
-
-/**!
- * @brief Sets the X11 instance name.
- * By default, the window name will be used as the instance name.
- * @param name The X11 instance name to set.
-*/
-RGFWDEF void RGFW_setXInstName(const char* name);
-
-/**!
* @brief (macOS only) Changes the current working directory to the application’s resource folder.
*/
RGFWDEF void RGFW_moveToMacOSResourceDir(void);
@@ -1336,13 +1439,27 @@ RGFWDEF RGFW_bool RGFW_monitor_getMode(RGFW_monitor* monitor, RGFW_monitorMode*
RGFWDEF void RGFW_pollMonitors(void);
/**!
- * @brief Retrieves an array of all available monitors.
- * @param len [OUTPUT] A pointer to store the number of monitors found (maximum of RGFW_MAX_MONITORS [6 by default]).
- * @return An array of pointers to RGFW_monitor structures.
+ * @brief free all leftlover monitor data (this is called internally RGFW_deinit)
+*/
+RGFWDEF void RGFW_freeMonitors(void);
+
+/**!
+ * @brief Allocates and returns an array of all available monitors.
+ * @param len [OUTPUT] A pointer to store the number of monitors found.
+ * @return An allocated array of pointers to RGFW_monitor structures that must be freed.
*/
RGFWDEF RGFW_monitor** RGFW_getMonitors(size_t* len);
/**!
+ * @brief fills a pre-allocated array with available monitors.
+ * @param maximum number of monitors that the passed [monitors] buffer supports, can be zero to get the length alone
+ * @param pre-allocated buffer of monitors, can be NULL to get the length alone
+ * @param len [OUTPUT] A pointer to store the number of monitors found, if max is not zero and monitors is not NULL, length will be set to max.
+ * @return An array of pointers to RGFW_monitor structures or NULL if the function failed.
+*/
+RGFWDEF RGFW_bool RGFW_getMonitorsPtr(size_t max, RGFW_monitor** monitors, size_t* len);
+
+/**!
* @brief Retrieves the primary monitor.
* @return A pointer to the RGFW_monitor structure representing the primary monitor.
*/
@@ -1538,7 +1655,7 @@ RGFWDEF void RGFW_getMouseVector(float* x, float* y);
*
* NOTE: (windows) if the executable has an icon resource named RGFW_ICON, it will be set as the initial icon for the window
*/
-RGFWDEF RGFW_window* RGFW_createWindow(const char* name, i32 x, i32 y, i32 w, i32 h, RGFW_windowFlags flags);
+RGFWDEF RGFW_window* RGFW_createWindow(const char* name, i32 x, i32 y, i32 w, i32 h, RGFW_windowFlags flags);
/**!
* @brief creates a new window using a pre-allocated window structure
@@ -1864,7 +1981,7 @@ RGFWDEF RGFW_bool RGFW_window_getDataDrag(RGFW_window* win, i32* x, i32* y);
RGFWDEF RGFW_bool RGFW_window_didDataDrop(RGFW_window* win);
/**!
- * @brief retrieves datta from a data drop (drag and drop)
+ * @brief retrieves data from a data drop (drag and drop)
* @param win a pointer to the target window
* @return a valid pointer to the root drag node if a data drop occurred, NULL otherwise
*/
@@ -1966,9 +2083,9 @@ RGFWDEF void RGFW_window_maximize(RGFW_window* win);
/**!
* @brief toggles fullscreen mode for the window
* @param win a pointer to the target window
- * @param fullscreen RGFW_TRUE to enable fullscreen, RGFW_FALSE to disable
+ * @param fullscreen the fullscreen mode to use RGFW_fullscreenNone, RGFW_fullscreenBorderless, RGFW_fullscreenExclusive
*/
-RGFWDEF void RGFW_window_setFullscreen(RGFW_window* win, RGFW_bool fullscreen);
+RGFWDEF void RGFW_window_setFullscreen(RGFW_window* win, RGFW_fullscreenMode mode);
/**!
* @brief centers the window on the screen
@@ -2208,13 +2325,27 @@ RGFWDEF void RGFW_window_moveMouse(RGFW_window* win, i32 x, i32 y);
RGFWDEF RGFW_bool RGFW_window_shouldClose(RGFW_window* win);
/**!
- * @brief Checks if the window is currently fullscreen.
+ * @brief Checks if the window is currently fullscreen (borderless or exclusive).
* @param win The target window.
* @return True if the window is fullscreen.
*/
RGFWDEF RGFW_bool RGFW_window_isFullscreen(RGFW_window* win);
/**!
+ * @brief Checks if the window is currently fullscreen (exclusive).
+ * @param win The target window.
+ * @return True if the window is fullscreen.
+*/
+RGFWDEF RGFW_bool RGFW_window_isFullscreenExclusive(RGFW_window* win);
+
+/**!
+ * @brief Checks if the window is currently fullscreen (borderless).
+ * @param win The target window.
+ * @return True if the window is fullscreen.
+*/
+RGFWDEF RGFW_bool RGFW_window_isFullscreenBorderless(RGFW_window* win);
+
+/**!
* @brief Checks if the window is currently hidden.
* @param win The target window.
* @return True if the window is hidden.
@@ -2269,25 +2400,43 @@ RGFWDEF RGFW_monitor* RGFW_window_getMonitor(RGFW_window* win);
/**!
* @brief Reads clipboard data.
- * @param size [OUTPUT] A pointer that will be filled with the size of the clipboard data.
- * @return A pointer to the clipboard data as a string.
+ * @param requestedType the requested clipboard data type to attempt to read
+ * @return A pointer to the clipboard data object or NULL on failure.
+*/
+RGFWDEF const RGFW_dataTransfer* RGFW_readClipboard(RGFW_dataTransferType requestedType);
+
+/**!
+ * @brief Reads clipboard data into your object pointer using your provided buffer, or returns the required length if the buffer is NULL or bufferCapacity is 0.
+ * @param requestedType the requested clipboard data type to attempt to read
+ * @param buffer the buffer used to fill the output dataTransfer object's data
+ * @param capacity the capacity/length of the buffer in bytes
+ * @param data [OUTPUT] A pointer to the dataTransfer object that will receive the clipboard data. (cannot be NULL)
+ * @return returns RGFW_TRUE on success and RGFW_FALSE on failure
*/
-RGFWDEF const char* RGFW_readClipboard(size_t* size);
+RGFWDEF RGFW_bool RGFW_readClipboardPtr(RGFW_dataTransferType requestedType, u8* buffer, size_t capacity, RGFW_dataTransfer* data);
/**!
- * @brief Reads clipboard data into a provided buffer, or returns the required length if str is NULL.
- * @param str [OUTPUT] A pointer to the buffer that will receive the clipboard data (or NULL to get required size).
- * @param strCapacity The capacity of the provided buffer.
- * @return The number of bytes read or required length of clipboard data.
+ * @brief Reads clipboard string data.
+ * @param requestedType the requested clipboard data type to attempt to read
+ * @return A pointer to the clipboard data object or NULL on failure.
*/
-RGFWDEF RGFW_ssize_t RGFW_readClipboardPtr(char* str, size_t strCapacity);
+RGFWDEF const RGFW_dataTransfer* RGFW_readClipboardString(void);
/**!
- * @brief Writes text to the clipboard.
- * @param text The text to be written to the clipboard.
- * @param textLen The length of the text being written.
+ * @brief Reads clipboard data into your object pointer using your provided buffer, or returns the required length if the buffer is NULL or bufferCapacity is 0.
+ * @param buffer the buffer used to fill the output dataTransfer object's data
+ * @param capacity the capacity/length of the buffer in bytes
+ * @param data [OUTPUT] A pointer to the dataTransfer object that will receive the clipboard data. (cannot be NULL)
+ * @return returns RGFW_TRUE on success and RGFW_FALSE on failure
*/
-RGFWDEF void RGFW_writeClipboard(const char* text, u32 textLen);
+RGFWDEF RGFW_bool RGFW_readClipboardStringPtr(u8* buffer, size_t capacity, RGFW_dataTransfer* data);
+
+/**!
+ * @brief Writes data to the clipboard.
+ * @param data The data to be written to the clipboard, including the length and type.
+ * @param returns RGFW_TRUE on success and RGFW_FALSE on failure
+*/
+RGFWDEF RGFW_bool RGFW_writeClipboard(const RGFW_dataTransfer* data);
/** @} */
@@ -2313,17 +2462,8 @@ RGFWDEF void RGFW_debugCallback(RGFW_debugType type, RGFW_errorCode code, const
/** * @defgroup graphics_API
* @{ */
-/*! native rendering API functions */
-#if defined(RGFW_OPENGL)
-/* these are native opengl specific functions and will NOT work with EGL */
-
-/*!< make the window the current OpenGL drawing context
-
- NOTE:
- if you want to switch the graphics context's thread,
- you have to run RGFW_window_makeCurrentContext_OpenGL(NULL); on the old thread
- then RGFW_window_makeCurrentContext_OpenGL(valid_window) on the new thread
-*/
+#if defined(RGFW_OPENGL) || defined(RGFW_EGL)
+/* these are generic functions that work for both EGL and native OpenGL */
/**!
* @brief Sets the global OpenGL hints to the specified pointer.
@@ -2342,47 +2482,85 @@ RGFWDEF void RGFW_resetGlobalHints_OpenGL(void);
*/
RGFWDEF RGFW_glHints* RGFW_getGlobalHints_OpenGL(void);
+#endif
+
+/*! native rendering API functions */
+#if defined(RGFW_OPENGL)
+/* these are native opengl specific functions and will NOT work with EGL */
+
+/*!< make the window the current OpenGL drawing context
+
+ NOTE:
+ if you want to switch the graphics context's thread,
+ you have to run RGFW_window_makeCurrentContext_OpenGL(NULL); on the old thread
+ then RGFW_window_makeCurrentContext_OpenGL(valid_window) on the new thread
+*/
+
/**!
- * @brief Creates and allocates an OpenGL context for the specified window.
- * @param win A pointer to the target RGFW_window.
+ * @brief Creates and allocates an OpenGL context that can be attached to a window.
* @param hints A pointer to an RGFW_glHints structure defining context creation parameters.
* @return A pointer to the newly created RGFW_glContext.
*/
-RGFWDEF RGFW_glContext* RGFW_window_createContext_OpenGL(RGFW_window* win, RGFW_glHints* hints);
+RGFWDEF RGFW_glContext* RGFW_createContext_OpenGL(RGFW_glHints* hints);
/**!
- * @brief Creates an OpenGL context for the specified window using a preallocated context structure.
- * @param win A pointer to the target RGFW_window.
+ * @brief Creates an OpenGL context that can be attached to a window, using a preallocated context structure.
* @param ctx A pointer to an already allocated RGFW_glContext structure.
* @param hints A pointer to an RGFW_glHints structure defining context creation parameters.
* @return RGFW_TRUE on success, RGFW_FALSE on failure.
*/
-RGFWDEF RGFW_bool RGFW_window_createContextPtr_OpenGL(RGFW_window* win, RGFW_glContext* ctx, RGFW_glHints* hints);
-
-/**!
- * @brief Retrieves the OpenGL context associated with a window.
- * @param win A pointer to the RGFW_window.
- * @return A pointer to the associated RGFW_glContext, or NULL if none exists or if the context is EGL-based.
-*/
-RGFWDEF RGFW_glContext* RGFW_window_getContext_OpenGL(RGFW_window* win);
+RGFWDEF RGFW_bool RGFW_createContextPtr_OpenGL(RGFW_glContext* ctx, RGFW_glHints* hints);
/**!
* @brief Deletes and frees the OpenGL context.
- * @param win A pointer to the RGFW_window.
* @param ctx A pointer to the RGFW_glContext to delete.
*
+ * @note Only use this version if you allocated a context with RGFW_createContext_OpenGL
* @note This is automatically called by RGFW_window_close if the window’s context is not NULL.
+ * @note you should set the window context to NULL with RGFW_window_setContext_OpenGL(win, NULL) after calling this function
*/
-RGFWDEF void RGFW_window_deleteContext_OpenGL(RGFW_window* win, RGFW_glContext* ctx);
+RGFWDEF void RGFW_deleteContext_OpenGL(RGFW_glContext* ctx);
/**!
* @brief Deletes the OpenGL context without freeing its memory.
* @param win A pointer to the RGFW_window.
* @param ctx A pointer to the RGFW_glContext to delete.
*
+ * @note Only use this version if you allocated a context with RGFW_createContext_OpenGL
* @note This is automatically called by RGFW_window_close if the window’s context is not NULL.
+ * @note you should set the window context to NULL with RGFW_window_setContext_OpenGL(win, NULL) after calling this function
+*/
+RGFWDEF void RGFW_deleteContextPtr_OpenGL(RGFW_glContext* ctx);
+
+/**!
+ * @brief allocates a new context, copying the info from an old context
+ * @param ctx A pointer to the RGFW_glContext to copy.
+ * @return The newly allocated context
+*/
+RGFWDEF RGFW_glContext* RGFW_copyContext_OpenGL(RGFW_glContext* ctx);
+
+/**!
+ * @brief copies info from a context to make a new context with the supplied pointer
+ * @param ctx A pointer to the RGFW_glContext to copy.
+ * @param newCtx A pointer to the new context.
+ * @return boolean RGFW_TRUE for success, RGFW_FALSE for failure
+*/
+RGFWDEF RGFW_bool RGFW_copyContextPtr_OpenGL(RGFW_glContext* ctx, RGFW_glContext* newCtx);
+
+/**!
+ * @brief sets the window's context to a context that was already created
+ * @param win A pointer to the RGFW_window.
+ * @param ctx A pointer to the RGFW_glContext to use.
+ * @return boolean RGFW_TRUE for success, RGFW_FALSE for failure
+*/
+RGFWDEF RGFW_bool RGFW_window_setContext_OpenGL(RGFW_window* win, RGFW_glContext* ctx);
+
+/**!
+ * @brief Retrieves the OpenGL context associated with a window.
+ * @param win A pointer to the RGFW_window.
+ * @return A pointer to the associated RGFW_glContext, or NULL if none exists or if the context is EGL-based.
*/
-RGFWDEF void RGFW_window_deleteContextPtr_OpenGL(RGFW_window* win, RGFW_glContext* ctx);
+RGFWDEF RGFW_glContext* RGFW_window_getContext_OpenGL(RGFW_window* win);
/**!
* @brief Retrieves the native source context from an RGFW_glContext.
@@ -2421,6 +2599,12 @@ RGFWDEF void RGFW_window_swapBuffers_OpenGL(RGFW_window* win);
RGFWDEF void* RGFW_getCurrentContext_OpenGL(void);
/**!
+ * @brief Retrieves the current OpenGL surface.
+ * @return A pointer to the currently active OpenGL surface (GLX, WGL, Cocoa, or WebGL backend).
+*/
+RGFWDEF void* RGFW_getCurrentSurface_OpenGL(void);
+
+/**!
* @brief Retrieves the current OpenGL window.
* @return A pointer to the RGFW_window currently bound as the OpenGL context target.
*/
@@ -2455,43 +2639,66 @@ RGFWDEF RGFW_bool RGFW_extensionSupported_OpenGL(const char* extension, size_t l
* @return RGFW_TRUE if supported, RGFW_FALSE otherwise.
*/
RGFWDEF RGFW_bool RGFW_extensionSupportedPlatform_OpenGL(const char* extension, size_t len);
+#endif
-/* these are EGL specific functions, they may fallback to OpenGL */
#ifdef RGFW_EGL
+
+/* these are EGL specific functions, they may fallback to OpenGL */
/**!
- * @brief Creates and allocates an OpenGL/EGL context for the specified window.
- * @param win A pointer to the target RGFW_window.
+ * @brief Creates and allocates an OpenGL/EGL context that can be attached to a window.
* @param hints A pointer to an RGFW_glHints structure defining context creation parameters.
* @return A pointer to the newly created RGFW_eglContext.
*/
-RGFWDEF RGFW_eglContext* RGFW_window_createContext_EGL(RGFW_window* win, RGFW_glHints* hints);
+RGFWDEF RGFW_eglContext* RGFW_createContext_EGL(RGFW_glHints* hints);
/**!
- * @brief Creates an OpenGL/EGL context for the specified window using a preallocated context structure.
- * @param win A pointer to the target RGFW_window.
+ * @brief Creates an OpenGL/EGL context that can be attached to a window, using a preallocated context structure.
* @param ctx A pointer to an already allocated RGFW_eglContext structure.
* @param hints A pointer to an RGFW_glHints structure defining context creation parameters.
* @return RGFW_TRUE on success, RGFW_FALSE on failure.
*/
-RGFWDEF RGFW_bool RGFW_window_createContextPtr_EGL(RGFW_window* win, RGFW_eglContext* ctx, RGFW_glHints* hints);
+RGFWDEF RGFW_bool RGFW_createContextPtr_EGL(RGFW_eglContext* ctx, RGFW_glHints* hints);
/**!
* @brief Frees and deletes an OpenGL/EGL context.
- * @param win A pointer to the RGFW_window.
* @param ctx A pointer to the RGFW_eglContext to delete.
*
* @note Automatically called by RGFW_window_close if RGFW owns the context.
+ * @note you should set the window context to NULL with RGFW_window_setContext_OpenGL(win, NULL) after calling this function
*/
-RGFWDEF void RGFW_window_deleteContext_EGL(RGFW_window* win, RGFW_eglContext* ctx);
+RGFWDEF void RGFW_deleteContext_EGL(RGFW_eglContext* ctx);
/**!
* @brief Deletes an OpenGL/EGL context without freeing its memory.
- * @param win A pointer to the RGFW_window.
* @param ctx A pointer to the RGFW_eglContext to delete.
*
* @note Automatically called by RGFW_window_close if RGFW owns the context.
+ * @note you should set the window context to NULL with RGFW_window_setContext_OpenGL(win, NULL) after calling this function
+*/
+RGFWDEF void RGFW_deleteContextPtr_EGL(RGFW_eglContext* ctx);
+
+/**!
+ * @brief allocates a new context, copying the info from an old context
+ * @param ctx A pointer to the RGFW_eglContext to copy.
+ * @return The newly allocated context
+*/
+RGFWDEF RGFW_eglContext* RGFW_copyContext_EGL(RGFW_eglContext* ctx);
+
+/**!
+ * @brief copies info from a context to make a new context with the supplied pointer
+ * @param ctx A pointer to the RGFW_eglContext to copy.
+ * @param newCtx A pointer to the new context.
+ * @return boolean RGFW_TRUE for success, RGFW_FALSE for failure
*/
-RGFWDEF void RGFW_window_deleteContextPtr_EGL(RGFW_window* win, RGFW_eglContext* ctx);
+RGFWDEF RGFW_bool RGFW_copyContextPtr_EGL(RGFW_eglContext* ctx, RGFW_eglContext* newCtx);
+
+/**!
+ * @brief sets the window's context to a context that was already created
+ * @param win A pointer to the RGFW_window.
+ * @param ctx A pointer to the RGFW_eglContext to use.
+ * @return boolean RGFW_TRUE for success, RGFW_FALSE for failure
+*/
+RGFWDEF RGFW_bool RGFW_window_setContext_EGL(RGFW_window* win, RGFW_eglContext* ctx);
/**!
* @brief Retrieves the OpenGL/EGL context associated with a window.
@@ -2559,6 +2766,12 @@ RGFWDEF void RGFW_window_makeCurrentContext_EGL(RGFW_window* win);
RGFWDEF void* RGFW_getCurrentContext_EGL(void);
/**!
+ * @brief Retrieves the current EGL surface.
+ * @return A pointer to the currently active EGLSurface.
+*/
+RGFWDEF void* RGFW_getCurrentSurface_EGL(void);
+
+/**!
* @brief Retrieves the current EGL window.
* @return A pointer to the RGFW_window currently bound as the EGL context target.
*/
@@ -2593,13 +2806,17 @@ RGFWDEF RGFW_bool RGFW_extensionSupported_EGL(const char* extension, size_t len)
* @return RGFW_TRUE if supported, RGFW_FALSE otherwise.
*/
RGFWDEF RGFW_bool RGFW_extensionSupportedPlatform_EGL(const char* extension, size_t len);
-#endif
-#endif
-#ifdef RGFW_VULKAN
-#include <vulkan/vulkan.h>
+#endif /* RGFW_EGL */
-/* if you don't want to use the above macros */
+#ifdef RGFW_VULKAN
+/**!
+ * @brief Retrieves the address of a Vulkan procedure using a Vulkan instance.
+ * @param the Vulkan Instance to use
+ * @param procname The name of the Vulkan function to look up.
+ * @return A pointer to the function, or NULL if not found.
+*/
+RGFWDEF RGFW_proc RGFW_getInstanceProcAddress_Vulkan(VkInstance instance, const char* procname);
/**!
* @brief Retrieves the Vulkan instance extensions required by RGFW.
@@ -2624,7 +2841,7 @@ RGFWDEF VkResult RGFW_window_createSurface_Vulkan(RGFW_window* win, VkInstance i
* @param queueFamilyIndex The index of the queue family to query for presentation support.
* @return RGFW_TRUE if presentation is supported, RGFW_FALSE otherwise.
*/
-RGFWDEF RGFW_bool RGFW_getPresentationSupport_Vulkan(VkPhysicalDevice physicalDevice, u32 queueFamilyIndex);
+RGFWDEF RGFW_bool RGFW_getPhysicalDevicePresentationSupport_Vulkan(VkInstance instance, VkPhysicalDevice physicalDevice, u32 queueFamilyIndex);
#endif
#ifdef RGFW_DIRECTX
@@ -2645,7 +2862,7 @@ RGFWDEF RGFW_bool RGFW_getPresentationSupport_Vulkan(VkPhysicalDevice physicalDe
* @param swapchain [OUTPUT] A pointer to an IDXGISwapChain pointer that will receive the created swap chain.
* @return An integer result code (0 on success, or a DirectX error code on failure).
*/
-RGFWDEF int RGFW_window_createSwapChain_DirectX(RGFW_window* win, IDXGIFactory* pFactory, IUnknown* pDevice, IDXGISwapChain** swapchain);
+RGFWDEF i32 RGFW_window_createSwapChain_DirectX(RGFW_window* win, IDXGIFactory* pFactory, IUnknown* pDevice, IDXGISwapChain** swapchain);
#endif
#endif
@@ -2728,75 +2945,34 @@ RGFWDEF u32 RGFW_rgfwToApiKey(RGFW_key keycode);
*/
RGFWDEF RGFW_key RGFW_physicalToMappedKey(RGFW_key keycode);
-/**!
- * @brief Retrieves the size of the RGFW_info structure.
- * @return The size (in bytes) of RGFW_info.
-*/
-RGFWDEF size_t RGFW_sizeofInfo(void);
-
-/**!
- * @brief Initializes the RGFW library.
- * @return 0 on success, or a negative error code on failure.
- * @note This is automatically called when the first window is created.
-*/
-RGFWDEF i32 RGFW_init(void);
-
-/**!
- * @brief Deinitializes the RGFW library.
- * @note This is automatically called when the last open window is closed.
-*/
-RGFWDEF void RGFW_deinit(void);
-
-/**!
- * @brief Initializes RGFW using a user-provided RGFW_info structure.
- * @param info A pointer to an RGFW_info structure to be used for initialization.
- * @return 0 on success, or a negative error code on failure.
-*/
-RGFWDEF i32 RGFW_init_ptr(RGFW_info* info);
-
-/**!
- * @brief Deinitializes a specific RGFW instance stored in the provided RGFW_info pointer.
- * @param info A pointer to the RGFW_info structure representing the instance to deinitialize.
-*/
-RGFWDEF void RGFW_deinit_ptr(RGFW_info* info);
-
-/**!
- * @brief Sets the global RGFW_info structure pointer.
- * @param info A pointer to the RGFW_info structure to set.
-*/
-RGFWDEF void RGFW_setInfo(RGFW_info* info);
-
-/**!
- * @brief Retrieves the global RGFW_info structure pointer.
- * @return A pointer to the current RGFW_info structure.
-*/
-RGFWDEF RGFW_info* RGFW_getInfo(void);
-
/** @} */
#endif /* RGFW_HEADER */
#if !defined(RGFW_NATIVE_HEADER) && (defined(RGFW_NATIVE) || defined(RGFW_IMPLEMENTATION))
#define RGFW_NATIVE_HEADER
- #if (defined(RGFW_OPENGL) || defined(RGFW_WEGL)) && defined(_MSC_VER)
- #pragma comment(lib, "opengl32")
- #endif
-
- #ifdef RGFW_OPENGL
+ #ifdef RGFW_EGL
struct RGFW_eglContext {
void* ctx;
void* surface;
+ void* config;
struct wl_egl_window* eglWindow;
};
+ #endif
+ #if defined(RGFW_OPENGL) || defined(RGFW_EGL)
typedef union RGFW_gfxContext {
- RGFW_glContext* native;
- RGFW_eglContext* egl;
+ #ifdef RGFW_OPENGL
+ RGFW_glContext* native;
+ #endif
+
+ #ifdef RGFW_EGL
+ RGFW_eglContext* egl;
+ #endif
} RGFW_gfxContext;
typedef RGFW_ENUM(u32, RGFW_gfxContextType) {
RGFW_gfxNativeOpenGL = RGFW_BIT(0),
- RGFW_gfxEGL = RGFW_BIT(1),
- RGFW_gfxOwnedByRGFW = RGFW_BIT(2)
+ RGFW_gfxEGL = RGFW_BIT(1)
};
#endif
@@ -2820,7 +2996,7 @@ RGFWDEF RGFW_info* RGFW_getInfo(void);
};
#ifdef RGFW_OPENGL
- struct RGFW_glContext { HGLRC ctx; };
+ struct RGFW_glContext { HGLRC ctx; i32 format; };
#endif
struct RGFW_window_src {
@@ -2830,7 +3006,7 @@ RGFWDEF RGFW_info* RGFW_getInfo(void);
i32 maxSizeW, maxSizeH, minSizeW, minSizeH, aspectRatioW, aspectRatioH; /*!< for setting max/min resize (RGFW_WINDOWS) */
RGFW_bool actionFrame; /* frame after a caption button was toggled (e.g. minimize, maximize or close) */
WCHAR highSurrogate;
- #ifdef RGFW_OPENGL
+ #if defined(RGFW_OPENGL) || defined(RGFW_EGL)
RGFW_gfxContext ctx;
RGFW_gfxContextType gfxType;
#endif
@@ -2841,10 +3017,8 @@ RGFWDEF RGFW_info* RGFW_getInfo(void);
#include <X11/Xlib.h>
#include <X11/Xutil.h>
- #ifndef RGFW_NO_XRANDR
- #include <X11/extensions/Xrandr.h>
- #include <X11/Xresource.h>
- #endif
+ #include <X11/extensions/Xrandr.h>
+ #include <X11/Xresource.h>
#ifndef RGFW_XDND_VERSION
#define RGFW_XDND_VERSION 5
@@ -2873,10 +3047,11 @@ RGFWDEF RGFW_info* RGFW_getInfo(void);
RGFW_format format;
};
- #ifdef RGFW_OPENGL
+ #if defined(RGFW_OPENGL) || defined(RGFW_EGL)
struct RGFW_glContext {
#ifdef RGFW_X11
struct __GLXcontextRec* ctx; /*!< source graphics context */
+ void* config;
Window window;
#endif
#ifdef RGFW_WAYLAND
@@ -2887,7 +3062,7 @@ RGFWDEF RGFW_info* RGFW_getInfo(void);
struct RGFW_window_src {
i32 x, y, w, h;
- #ifdef RGFW_OPENGL
+ #if defined(RGFW_OPENGL) || defined(RGFW_EGL)
RGFW_gfxContext ctx;
RGFW_gfxContextType gfxType;
#endif
@@ -2954,7 +3129,7 @@ RGFWDEF RGFW_info* RGFW_getInfo(void);
void* view; /* apple viewpoint thingy */
void* mouse;
void* delegate;
- #ifdef RGFW_OPENGL
+ #if defined(RGFW_OPENGL) || defined(RGFW_EGL)
RGFW_gfxContext ctx;
RGFW_gfxContextType gfxType;
#endif
@@ -2969,14 +3144,14 @@ RGFWDEF RGFW_info* RGFW_getInfo(void);
RGFW_format format;
};
- #ifdef RGFW_OPENGL
+ #if defined(RGFW_OPENGL) || defined(RGFW_EGL)
struct RGFW_glContext {
EMSCRIPTEN_WEBGL_CONTEXT_HANDLE ctx;
};
#endif
struct RGFW_window_src {
- #ifdef RGFW_OPENGL
+ #if defined(RGFW_OPENGL) || defined(RGFW_EGL)
RGFW_gfxContext ctx;
RGFW_gfxContextType gfxType;
#endif
@@ -3007,7 +3182,9 @@ typedef struct RGFW_windowInternal {
RGFW_eventFlag enabledEvents;
u32 flags; /*!< windows flags (for RGFW to check and modify) */
i32 oldX, oldY, oldW, oldH;
- RGFW_monitorMode oldMode;
+ RGFW_bool oldBorderless;
+ RGFW_monitor* monitor;
+ RGFW_monitorMode oldMode, newMode;
RGFW_mouse* mouse;
} RGFW_windowInternal;
@@ -3015,6 +3192,7 @@ struct RGFW_window {
RGFW_window_src src; /*!< src window data */
RGFW_windowInternal internal; /*!< internal window data that is not specific to the OS */
void* userPtr; /* ptr for user data */
+ RGFW_window* next; /* pointer to the next RGFW window in the same context */
i32 x, y, w, h; /*!< position and size of the window */
}; /*!< window structure for the window */
@@ -3022,7 +3200,7 @@ typedef struct RGFW_windowState {
RGFW_bool mouseEnter;
RGFW_bool dataDragging;
RGFW_bool dataDrop;
- size_t dataSize;
+ size_t dataLength;
i32 dropX, dropY;
RGFW_window* win; /*!< it's not possible for one of these events to happen in the frame that the other event happened */
@@ -3046,8 +3224,7 @@ struct RGFW_monitorNode {
RGFW_monitorMode* modes;
size_t modeCount;
#endif
-#if defined(RGFW_X11) && !defined(RGFW_NO_XRANDR)
- i32 screen;
+#if defined(RGFW_X11)
RROutput rrOutput;
RRCrtc crtc;
#endif
@@ -3060,6 +3237,7 @@ struct RGFW_monitorNode {
void* screen;
CGDirectDisplayID display;
u32 uintNum;
+ CFArrayRef allModes;
#endif
};
@@ -3070,18 +3248,17 @@ typedef struct RGFW_monitorList {
typedef struct RGFW_monitors {
RGFW_monitorList list;
- RGFW_monitorList freeList;
size_t count;
RGFW_monitorNode* primary;
- RGFW_monitorNode data[RGFW_MAX_MONITORS];
+ #if (RGFW_PREALLOCATED_MONITORS)
+ RGFW_monitorList freeList;
+ RGFW_monitorNode data[RGFW_PREALLOCATED_MONITORS];
+ #endif
} RGFW_monitors;
-RGFWDEF RGFW_monitorNode* RGFW_monitors_add(const RGFW_monitor* mon);
-RGFWDEF void RGFW_monitors_remove(RGFW_monitorNode* node, RGFW_monitorNode* prev);
-
struct RGFW_info {
- RGFW_window* root;
+ RGFW_window* root, * cur;
i32 windowCount;
RGFW_mouse* hiddenMouse;
@@ -3107,24 +3284,20 @@ struct RGFW_info {
RGFW_key keycodes[256];
#endif
- const char* className;
- RGFW_bool useWaylandBool;
RGFW_bool stopCheckEvents_bool ;
u64 timerOffset;
- char* clipboard_data;
- char* clipboard; /* for writing to the clipboard selection */
- size_t clipboard_len;
+ RGFW_dataTransfer* clipboard;
RGFW_bool dndBuild;
RGFW_dataDropNode* dndRoot;
RGFW_dataDropNode* dndCur;
#ifdef RGFW_X11
+ const char* className;
Display* display;
XContext context;
Window helperWindow;
- const char* instName;
XErrorEvent* x11Error;
i32 xrandrEventBase;
XIM im;
@@ -3132,7 +3305,44 @@ struct RGFW_info {
long x11Version;
i32 x11Format;
RGFW_dataTransferType x11TransferType;
- #endif
+ Atom _NET_WORKAREA,
+ _NET_CURRENT_DESKTOP,
+ _NET_WM_STATE_MAXIMIZED_VERT,
+ _NET_WM_STATE_MAXIMIZED_HORZ,
+ _NET_WM_BYPASS_COMPOSITOR,
+ _NET_WM_STATE,
+ _MOTIF_WM_HINTS,
+ WM_DELETE_WINDOW,
+ _NET_WM_SYNC_REQUEST_COUNTER,
+ _NET_WM_SYNC_REQUEST,
+ ATOM_PAIR,
+ MULTIPLE,
+ TARGETS,
+ SAVE_TARGETS,
+ UTF8_STRING,
+ XdndAware,
+ XdndTypeList,
+ XdndSelection,
+ XdndEnter,
+ XdndPosition,
+ XdndStatus,
+ XdndLeave,
+ XdndDrop,
+ XdndFinished,
+ XdndActionCopy,
+ WM_PROTOCOLS,
+ WM_STATE,
+ _NET_WM_STATE_FULLSCREEN,
+ _NET_WM_STATE_ABOVE,
+ NET_WM_WINDOW_OPACITY,
+ _NET_WM_NAME,
+ _NET_WM_ICON,
+ XSEL_DATA,
+ CLIPBOARD,
+ CLIPBOARD_MANAGER,
+ XtextUriList,
+ XtextPlain;
+ #endif
#ifdef RGFW_WAYLAND
struct wl_display* wl_display;
struct xkb_context *xkb_context;
@@ -3168,13 +3378,20 @@ struct RGFW_info {
u32 last_key; /* wayland key repeat data */
i32 wl_repeat_info_rate, wl_repeat_info_delay;
u32 last_key_time;
- #endif
+ RGFW_bool useWaylandBool;
+ #endif
+ #ifdef RGFW_WINDOWS
+ HINSTANCE instance;
+ WNDCLASSW wndClass;
+ HWND helperWindow;
+ wchar_t wideClassName[256];
+ #endif
RGFW_monitors monitors;
#ifdef RGFW_UNIX
int eventWait_forceStop[3];
- i32 clock;
+ RGFW_dataTransfer* unixClipboard;
#endif
#ifdef RGFW_MACOS
@@ -3183,15 +3400,39 @@ struct RGFW_info {
void* customViewClasses[2]; /* NSView and NSOpenGLView */
void* customNSAppDelegateClass;
void* customWindowDelegateClass;
+ void* customWindowClass;
void* customNSAppDelegate;
void* tisBundle;
#endif
- #ifdef RGFW_OPENGL
+ #if defined(RGFW_OPENGL) || defined(RGFW_EGL)
RGFW_window* current;
#endif
+ #ifdef RGFW_OPENGL
+ void* nativeGL_handle;
+ RGFW_proc (*glGetProcAddress)(const char*);
+ #endif
#ifdef RGFW_EGL
void* EGL_display;
+ void* EGL_handle;
+ RGFW_proc (*eglGetProcAddress)(const char*);
+ #endif
+ #ifdef RGFW_VULKAN
+ void* vulkan_handle;
+ RGFW_proc (*vkGetInstanceProcAddress)(void*, const char*);
+ #if defined(RGFW_X11)
+ RGFW_vkCreateXlibSurfaceKHRProc vkCreateXlibSurfaceKHR;
+ RGFW_vkGetPhysicalDeviceXlibPresentationSupportKHRProc vkGetPhysicalDeviceXlibPresentationSupportKHR;
+ #endif
+ #ifdef RGFW_WAYLAND
+ RGFW_vkCreateWaylandSurfaceKHRProc vkCreateWaylandSurfaceKHR;
+ RGFW_vkGetPhysicalDeviceWaylandPresentationSupportKHRProc vkGetPhysicalDeviceWaylandPresentationSupportKHR;
+ #endif
+
+ #ifdef RGFW_WINDOWS
+ RGFW_vkCreateWin32SurfaceKHRProc vkCreateWin32SurfaceKHR;
+ RGFW_vkGetPhysicalDeviceWin32PresentationSupportKHRProc vkGetPhysicalDeviceWin32PresentationSupportKHR;
+ #endif
#endif
RGFW_bool rawMouse; /* global raw mouse toggle */
@@ -3211,25 +3452,45 @@ struct RGFW_info {
#include <math.h>
#endif
+#if defined(RGFW_MACOS) || defined(RGFW_UNIX)
+ #include <dlfcn.h>
+#endif
+
/* global private API */
/* for C++ / C89 */
RGFWDEF RGFW_window* RGFW_createWindowPlatform(const char* name, RGFW_windowFlags flags, RGFW_window* win);
RGFWDEF void RGFW_window_closePlatform(RGFW_window* win);
RGFWDEF RGFW_bool RGFW_window_setMousePlatform(RGFW_window* win, RGFW_mouse* mouse);
-
+RGFWDEF void RGFW_window_showPlatform(RGFW_window* win);
+RGFWDEF void RGFW_window_restorePlatform(RGFW_window* win);
+RGFWDEF void RGFW_window_minimizePlatform(RGFW_window* win);
+RGFWDEF void RGFW_window_movePlatform(RGFW_window* win, i32 x, i32 y);
+RGFWDEF void RGFW_window_resizePlatform(RGFW_window* win, i32 w, i32 h);
+RGFWDEF void RGFW_window_maximizePlatform(RGFW_window* win);
+RGFWDEF void RGFW_window_setFullscreenPlatform(RGFW_window* win, RGFW_bool fullscreen);
RGFWDEF void RGFW_window_setFlagsInternal(RGFW_window* win, RGFW_windowFlags flags, RGFW_windowFlags cmpFlags);
RGFWDEF void RGFW_initKeycodes(void);
RGFWDEF void RGFW_initKeycodesPlatform(void);
RGFWDEF void RGFW_resetPrevState(void);
RGFWDEF void RGFW_resetKey(void);
-RGFWDEF void RGFW_unloadEGL(void);
RGFWDEF void RGFW_keyUpdateKeyModsEx(RGFW_window* win, RGFW_bool capital, RGFW_bool numlock, RGFW_bool control, RGFW_bool alt, RGFW_bool shift, RGFW_bool super, RGFW_bool scroll);
RGFWDEF void RGFW_keyUpdateKeyMods(RGFW_window* win, RGFW_bool capital, RGFW_bool numlock, RGFW_bool scroll);
RGFWDEF void RGFW_window_showMouseFlags(RGFW_window* win, RGFW_bool show);
RGFWDEF void RGFW_keyUpdateKeyMod(RGFW_window* win, RGFW_keymod mod, RGFW_bool value);
+
+RGFWDEF RGFW_bool RGFW_loadGL(void);
+RGFWDEF void RGFW_unloadGL(void);
+RGFWDEF RGFW_bool RGFW_loadEGL(void);
+RGFWDEF void RGFW_unloadEGL(void);
+RGFWDEF RGFW_bool RGFW_loadVulkan(void);
+RGFWDEF void RGFW_unloadVulkan(void);
+
RGFWDEF void RGFW_monitors_refresh(void);
+RGFWDEF RGFW_monitorNode* RGFW_monitors_add(const RGFW_monitor* mon);
+RGFWDEF void RGFW_monitors_remove(RGFW_monitorNode* node, RGFW_monitorNode* prev);
+RGFWDEF void RGFW_monitorNode_free(RGFW_monitorNode* node);
RGFWDEF void RGFW_windowMaximizedCallback(RGFW_window* win, i32 x, i32 y, i32 w, i32 h);
RGFWDEF void RGFW_windowMinimizedCallback(RGFW_window* win);
@@ -3237,7 +3498,7 @@ RGFWDEF void RGFW_windowRestoredCallback(RGFW_window* win, i32 x, i32 y, i32 w,
RGFWDEF void RGFW_windowMovedCallback(RGFW_window* win, i32 x, i32 y);
RGFWDEF void RGFW_windowResizedCallback(RGFW_window* win, i32 w, i32 h);
RGFWDEF void RGFW_windowCloseCallback(RGFW_window* win);
-RGFWDEF void RGFW_mousePosCallback(RGFW_window* win, i32 x, i32 y);
+RGFWDEF void RGFW_mouseMotionCallback(RGFW_window* win, i32 x, i32 y);
RGFWDEF void RGFW_rawMotionCallback(RGFW_window* win, float x, float y);
RGFWDEF void RGFW_windowRefreshCallback(RGFW_window* win, i32 x, i32 y, i32 w, i32 h);
RGFWDEF void RGFW_windowFocusCallback(RGFW_window* win, RGFW_bool inFocus);
@@ -3260,9 +3521,7 @@ RGFWDEF void RGFW_window_setRawMouseModePlatform(RGFW_window *win, RGFW_bool sta
RGFWDEF void RGFW_copyImageData64(u8* dest_data, i32 w, i32 h, RGFW_format dest_format,
u8* src_data, RGFW_format src_format, RGFW_bool is64bit, RGFW_convertImageDataFunc func);
-RGFWDEF RGFW_bool RGFW_loadEGL(void);
-
-#ifdef RGFW_OPENGL
+#if defined(RGFW_OPENGL) || defined(RGFW_EGL)
typedef struct RGFW_attribStack {
i32* attribs;
size_t count;
@@ -3275,11 +3534,31 @@ RGFWDEF void RGFW_attribStack_pushAttribs(RGFW_attribStack* stack, i32 attrib1,
RGFWDEF RGFW_bool RGFW_extensionSupportedStr(const char* extensions, const char* ext, size_t len);
#endif
+#ifndef RGFW_EGL
+RGFW_bool RGFW_loadEGL(void) { return RGFW_FALSE; }
+void RGFW_unloadEGL(void) { }
+#endif
+
+#ifndef RGFW_OPENGL
+RGFW_bool RGFW_loadGL(void) { return RGFW_FALSE; }
+void RGFW_unloadGL(void) { }
+#endif
+
+#ifndef RGFW_VULKAN
+RGFW_bool RGFW_loadVulkan(void) { return RGFW_FALSE; }
+void RGFW_unloadVulkan(void) { }
+#endif
+
#ifdef RGFW_X11
-RGFWDEF void RGFW_XCreateWindow (XVisualInfo visual, const char* name, RGFW_windowFlags flags, RGFW_window* win);
+RGFWDEF RGFW_bool RGFW_XCreateWindow (XVisualInfo visual, const char* name, RGFW_windowFlags flags, RGFW_window* win);
+RGFWDEF char* RGFW_XGetWindowName(Window window);
#endif
#ifdef RGFW_MACOS
RGFWDEF void RGFW_osx_initView(RGFW_window* win);
+
+ #ifdef RGFW_OPENGL
+ RGFWDEF void RGFW_copyContext_OSX_OpenGL(RGFW_glContext* ctx, RGFW_glContext* newCtx);
+ #endif
#endif
/* end of global private API defs */
@@ -3291,46 +3570,38 @@ RGFW_info* RGFW_getInfo(void) { return _RGFW; }
void* RGFW_alloc(size_t size) { return RGFW_ALLOC(size); }
void RGFW_free(void* ptr) { RGFW_FREE(ptr); }
-void RGFW_useWayland(RGFW_bool wayland) { RGFW_init(); _RGFW->useWaylandBool = RGFW_BOOL(wayland); }
-RGFW_bool RGFW_usingWayland(void) { return _RGFW->useWaylandBool; }
-
void RGFW_setRawMouseMode(RGFW_bool state) {
_RGFW->rawMouse = state;
RGFW_window_setRawMouseModePlatform(_RGFW->root, state);
}
-void RGFW_clipboard_switch(char* newstr);
-void RGFW_clipboard_switch(char* newstr) {
- if (_RGFW->clipboard_data != NULL)
- RGFW_FREE(_RGFW->clipboard_data);
- _RGFW->clipboard_data = newstr;
-}
-
-#define RGFW_CHECK_CLIPBOARD() \
- if (size <= 0 && _RGFW->clipboard_data != NULL) \
- return (const char*)_RGFW->clipboard_data; \
- else if (size <= 0) \
- return "\0";
+const RGFW_dataTransfer* RGFW_readClipboard(RGFW_dataTransferType requestedType) {
+ RGFW_dataTransfer data_check;
+ RGFW_bool ret = RGFW_readClipboardPtr(requestedType, NULL, 0, &data_check);
+ if (ret == RGFW_FALSE || data_check.length == 0) return _RGFW->clipboard;
-const char* RGFW_readClipboard(size_t* len) {
- RGFW_ssize_t size = RGFW_readClipboardPtr(NULL, 0);
- RGFW_CHECK_CLIPBOARD();
- char* str = (char*)RGFW_ALLOC((size_t)size);
- RGFW_ASSERT(str != NULL);
- str[0] = '\0';
+ u8* cont_data = (u8*)RGFW_ALLOC(sizeof(RGFW_dataTransfer) + (size_t)data_check.length);
+ RGFW_ASSERT(cont_data != NULL);
- size = RGFW_readClipboardPtr(str, (size_t)size);
+ RGFW_dataTransfer* data = (RGFW_dataTransfer*)(void*)cont_data;
+ ret = RGFW_readClipboardPtr(requestedType, (u8*)&cont_data[sizeof(RGFW_dataTransfer) - 1], data_check.length, data);
- RGFW_CHECK_CLIPBOARD();
+ if (ret == RGFW_FALSE || data->length == 0) {
+ RGFW_FREE(cont_data);
+ data = NULL;
+ } else if (_RGFW->clipboard) {
+ RGFW_FREE(_RGFW->clipboard);
+ }
- if (len != NULL) *len = (size_t)size;
+ _RGFW->clipboard = data;
- RGFW_clipboard_switch(str);
- return (const char*)str;
+ return _RGFW->clipboard;
}
-/* generic RGFW defines */
+const RGFW_dataTransfer* RGFW_readClipboardString(void) { return RGFW_readClipboard(RGFW_dataText); }
+RGFW_bool RGFW_readClipboardStringPtr(u8* buffer, size_t capacity, RGFW_dataTransfer* data) { return RGFW_readClipboardPtr(RGFW_dataText, buffer, capacity, data); }
+/* generic RGFW defines */
void RGFW_initKeycodes(void) {
RGFW_MEMZERO(_RGFW->keycodes, sizeof(_RGFW->keycodes));
RGFW_initKeycodesPlatform();
@@ -3368,7 +3639,7 @@ void RGFW_resetKey(void) { RGFW_MEMZERO(_RGFW->keyboard, sizeof(_RGFW->keyboard)
RGFW_genericFunc RGFW_setEventCallback(RGFW_eventType type, RGFW_genericFunc func) {
RGFW_ASSERT(type > RGFW_eventNone && type < RGFW_eventCount);
- RGFW_init();
+ RGFW_ASSERT(_RGFW && "An RGFW context must be initialized using RGFW_init and/or set with RGFW_setInfo");
RGFW_genericFunc old = _RGFW->callbacks[type];
_RGFW->callbacks[type] = func;
@@ -3392,7 +3663,8 @@ void RGFW_setAllEventCallbacks(RGFW_genericFunc func, RGFW_callbacks* callbacks)
}
RGFW_debugFunc RGFW_setDebugCallback(RGFW_debugFunc func) {
- RGFW_init();
+ RGFW_ASSERT(_RGFW && "An RGFW context must be initialized using RGFW_init and/or set with RGFW_setInfo");
+
RGFW_debugFunc prev = _RGFW->debugCallbackSrc;
_RGFW->debugCallbackSrc = func;
return prev;
@@ -3467,7 +3739,7 @@ void RGFW_windowMovedCallback(RGFW_window* win, i32 x, i32 y) {
RGFW_event event;
event.type = RGFW_windowMoved;
event.update.x = x;
- event.update.x = y;
+ event.update.y = y;
event.update.w = win->w;
event.update.h = win->h;
event.common.win = win;
@@ -3498,14 +3770,14 @@ void RGFW_windowCloseCallback(RGFW_window* win) {
RGFW_eventQueuePushAndCall(&event);
}
-void RGFW_mousePosCallback(RGFW_window* win, i32 x, i32 y) {
+void RGFW_mouseMotionCallback(RGFW_window* win, i32 x, i32 y) {
win->internal.lastMouseX = x;
win->internal.lastMouseY = y;
- if (!(win->internal.enabledEvents & RGFW_mousePosChangedFlag)) return;
+ if (!(win->internal.enabledEvents & RGFW_mouseMotionFlag)) return;
RGFW_event event;
- event.type = RGFW_mousePosChanged;
+ event.type = RGFW_mouseMotion;
event.mouse.x = x;
event.mouse.y = y;
event.mouse.inWindow = win->internal.mouseInside;
@@ -3549,14 +3821,24 @@ void RGFW_windowFocusCallback(RGFW_window* win, RGFW_bool inFocus) {
event.common.win = win;
event.focus.state = inFocus;
+ #ifdef RGFW_MACOS
+ if (RGFW_window_isFullscreen(win)) {
+ RGFW_window_setFullscreenPlatform(win, inFocus);
+ }
+ #endif
+
if (inFocus == RGFW_TRUE) {
- if ((win->internal.flags & RGFW_windowFullscreen))
+ if ((win->internal.flags & RGFW_windowFullscreenExclusive) && win->internal.monitor) {
RGFW_window_raise(win);
+ RGFW_monitor_setMode(win->internal.monitor, &win->internal.newMode);
+ }
event.type = RGFW_windowFocusIn;
} else if (inFocus == RGFW_FALSE) {
- if ((win->internal.flags & RGFW_windowFullscreen))
+ if ((win->internal.flags & RGFW_windowFullscreenExclusive) && win->internal.monitor) {
RGFW_window_minimize(win);
+ RGFW_monitor_setMode(win->internal.monitor, &win->internal.oldMode);
+ }
size_t key;
for (key = 0; key < RGFW_keyLast; key++) {
@@ -3605,18 +3887,18 @@ void RGFW_mouseNotifyCallback(RGFW_window* win, i32 x, i32 y, RGFW_bool status)
RGFW_eventQueuePushAndCall(&event);
}
-void RGFW_dataDropCallback(RGFW_window* win, const char* data, size_t size, RGFW_dataTransferType dataType) {
+void RGFW_dataDropCallback(RGFW_window* win, const char* data, size_t length, RGFW_dataTransferType dataType) {
if (!(win->internal.enabledEvents & RGFW_dataDropFlag) || !(win->internal.flags & RGFW_windowAllowDND))
return;
_RGFW->windowState.win = win;
_RGFW->windowState.dataDrop = RGFW_TRUE;
- _RGFW->windowState.dataSize = size;
+ _RGFW->windowState.dataLength = length;
RGFW_dataDropNode node;
RGFW_MEMZERO(&node, sizeof(node));
node.data = data;
- node.size = size;
+ node.length = length;
node.type = dataType;
node.next = NULL;
@@ -3636,8 +3918,8 @@ void RGFW_dataDropCallback(RGFW_window* win, const char* data, size_t size, RGFW
_RGFW->dndCur = _RGFW->dndCur->next;
} else { RGFW_ASSERT(0); }
- char* dataCopy = (char*)RGFW_ALLOC(size);
- RGFW_MEMCPY(dataCopy, data, size);
+ char* dataCopy = (char*)RGFW_ALLOC(length);
+ RGFW_MEMCPY(dataCopy, data, length);
node.data = dataCopy;
RGFW_MEMCPY(_RGFW->dndCur, &node, sizeof(node));
@@ -3676,10 +3958,10 @@ void RGFW_keyCharCallback(RGFW_window* win, u32 codepoint) {
RGFW_eventQueuePushAndCall(&event);
}
-void RGFW_keyCallback(RGFW_window* win, RGFW_key key, RGFW_keymod mod, RGFW_bool repeat, RGFW_bool press) {
+void RGFW_keyCallback(RGFW_window* win, RGFW_key key, RGFW_keymod mod, RGFW_bool repeat, RGFW_bool state) {
RGFW_event event;
- if (press) {
+ if (state) {
if (!(win->internal.enabledEvents & RGFW_keyPressedFlag)) return;
event.type = RGFW_keyPressed;
} else {
@@ -3688,12 +3970,12 @@ void RGFW_keyCallback(RGFW_window* win, RGFW_key key, RGFW_keymod mod, RGFW_bool
}
_RGFW->keyboard[key].prev = _RGFW->keyboard[key].current;
- _RGFW->keyboard[key].current = press;
+ _RGFW->keyboard[key].current = state;
event.key.value = key;
event.key.repeat = repeat;
event.key.mod = mod;
- event.key.state = press;
+ event.key.state = state;
event.common.win = win;
RGFW_eventQueuePushAndCall(&event);
}
@@ -3802,18 +4084,18 @@ size_t RGFW_sizeofSurface(void) { return sizeof(RGFW_surface); }
size_t RGFW_sizeofWindow(void) { return sizeof(RGFW_window); }
size_t RGFW_sizeofWindowSrc(void) { return sizeof(RGFW_window_src); }
-RGFW_window_src* RGFW_window_getSrc(RGFW_window* win) { return &win->src; }
-RGFW_bool RGFW_window_getPosition(RGFW_window* win, i32* x, i32* y) { if (x) *x = win->x; if (y) *y = win->y; return RGFW_TRUE; }
-RGFW_bool RGFW_window_getSize(RGFW_window* win, i32* w, i32* h) { if (w) *w = win->w; if (h) *h = win->h; return RGFW_TRUE; }
-u32 RGFW_window_getFlags(RGFW_window* win) { return win->internal.flags; }
-RGFW_key RGFW_window_getExitKey(RGFW_window* win) { return win->internal.exitKey; }
-void RGFW_window_setExitKey(RGFW_window* win, RGFW_key key) { win->internal.exitKey = key; }
-void RGFW_window_setEnabledEvents(RGFW_window* win, RGFW_eventFlag events) { win->internal.enabledEvents = events; }
-RGFW_eventFlag RGFW_window_getEnabledEvents(RGFW_window* win) { return win->internal.enabledEvents; }
-void RGFW_window_setDisabledEvents(RGFW_window* win, RGFW_eventFlag events) { RGFW_window_setEnabledEvents(win, (RGFW_allEventFlags) & ~(u32)events); }
-void RGFW_window_setEventState(RGFW_window* win, RGFW_eventFlag event, RGFW_bool state) { RGFW_setBit(&win->internal.enabledEvents, event, state); }
-void* RGFW_window_getUserPtr(RGFW_window* win) { return win->userPtr; }
-void RGFW_window_setUserPtr(RGFW_window* win, void* ptr) { win->userPtr = ptr; }
+RGFW_window_src* RGFW_window_getSrc(RGFW_window* win) { RGFW_ASSERT(win); return &win->src; }
+RGFW_bool RGFW_window_getPosition(RGFW_window* win, i32* x, i32* y) { RGFW_ASSERT(win); if (x) *x = win->x; if (y) *y = win->y; return RGFW_TRUE; }
+RGFW_bool RGFW_window_getSize(RGFW_window* win, i32* w, i32* h) { RGFW_ASSERT(win); if (w) *w = win->w; if (h) *h = win->h; return RGFW_TRUE; }
+u32 RGFW_window_getFlags(RGFW_window* win) { RGFW_ASSERT(win); return win->internal.flags; }
+RGFW_key RGFW_window_getExitKey(RGFW_window* win) { RGFW_ASSERT(win); return win->internal.exitKey; }
+void RGFW_window_setExitKey(RGFW_window* win, RGFW_key key) { RGFW_ASSERT(win); win->internal.exitKey = key; }
+void RGFW_window_setEnabledEvents(RGFW_window* win, RGFW_eventFlag events) { RGFW_ASSERT(win); win->internal.enabledEvents = events; }
+RGFW_eventFlag RGFW_window_getEnabledEvents(RGFW_window* win) { RGFW_ASSERT(win); return win->internal.enabledEvents; }
+void RGFW_window_setDisabledEvents(RGFW_window* win, RGFW_eventFlag events) { RGFW_ASSERT(win); RGFW_window_setEnabledEvents(win, (RGFW_allEventFlags) & ~(u32)events); }
+void RGFW_window_setEventState(RGFW_window* win, RGFW_eventFlag event, RGFW_bool state) { RGFW_ASSERT(win); RGFW_setBit(&win->internal.enabledEvents, event, state); }
+void* RGFW_window_getUserPtr(RGFW_window* win) { RGFW_ASSERT(win); return win->userPtr; }
+void RGFW_window_setUserPtr(RGFW_window* win, void* ptr) { RGFW_ASSERT(win); win->userPtr = ptr; }
RGFW_bool RGFW_window_getSizeInPixels(RGFW_window* win, i32* w, i32* h) {
RGFW_monitor* mon = RGFW_window_getMonitor(win);
@@ -3831,40 +4113,70 @@ RGFW_bool RGFW_window_getSizeInPixels(RGFW_window* win, i32* w, i32* h) {
#include "XDL.h"
#endif
-#ifndef RGFW_FORCE_INIT
-RGFW_info _rgfwGlobal;
-#endif
+#ifndef RGFW_NO_STATIC_CONTEXT
+
+i32 RGFW_init(const char* className, RGFW_initFlags flags) {
+ static RGFW_info _rgfwGlobal;
+ return RGFW_init_ptr(className, flags, &_rgfwGlobal);
+}
+
+
+void RGFW_deinit(void) { RGFW_deinit_ptr(_RGFW); }
+
+#else
-i32 RGFW_init(void) { return RGFW_init_ptr(&_rgfwGlobal); }
-void RGFW_deinit(void) { RGFW_deinit_ptr(&_rgfwGlobal); }
+RGFW_info* _rgfwGlobal;
+
+i32 RGFW_init(const char* className, RGFW_initFlags flags) {
+ if (_rgfwGlobal != NULL) {
+ RGFW_FREE(_rgfwGlobal);
+ }
+
+ _rgfwGlobal = (RGFW_info*)RGFW_ALLOC(sizeof(RGFW_info));
+ return RGFW_init_ptr(className, flags, &_rgfwGlobal);
+}
+
+void RGFW_deinit(void) {
+ if (_RGFW == _rgfwGlobal) {
+ RGFW_FREE(_rgfwGlobal);
+ _rgfwGlobal = NULL;
+ }
+ RGFW_deinit_ptr(_RGFW);
+}
-i32 RGFW_initPlatform(void);
+#endif
+
+i32 RGFW_initPlatform(const char* className, RGFW_initFlags flags);
void RGFW_deinitPlatform(void);
-i32 RGFW_init_ptr(RGFW_info* info) {
+i32 RGFW_init_ptr(const char* className, RGFW_initFlags flags, RGFW_info* info) {
if (info == _RGFW || info == NULL) return 1;
+ className = className ? className : "RGFW";
+
RGFW_setInfo(info);
RGFW_MEMZERO(_RGFW, sizeof(RGFW_info));
- _RGFW->queueEvents = RGFW_FALSE;
- _RGFW->polledEvents = RGFW_FALSE;
-#ifdef RGFW_WAYLAND
- _RGFW->useWaylandBool = RGFW_TRUE;
-#endif
- _RGFW->monitors.freeList.head = &_RGFW->monitors.data[0];
- _RGFW->monitors.freeList.cur = _RGFW->monitors.freeList.head;
+ #if (RGFW_PREALLOCATED_MONITORS)
+ _RGFW->monitors.freeList.head = &_RGFW->monitors.data[0];
+ _RGFW->monitors.freeList.cur = _RGFW->monitors.freeList.head;
- for (size_t i = 1; i < RGFW_MAX_MONITORS; i++) {
- RGFW_monitorNode* newNode = &_RGFW->monitors.data[i];
- _RGFW->monitors.freeList.cur->next = newNode;
- _RGFW->monitors.freeList.cur = _RGFW->monitors.freeList.cur->next;
- }
+ for (size_t i = 1; i < RGFW_PREALLOCATED_MONITORS; i++) {
+ RGFW_monitorNode* newNode = &_RGFW->monitors.data[i];
+ _RGFW->monitors.freeList.cur->next = newNode;
+ _RGFW->monitors.freeList.cur = _RGFW->monitors.freeList.cur->next;
+ }
+ #endif
- _RGFW->monitors.list.head = NULL;
- _RGFW->monitors.list.head = NULL;
RGFW_initKeycodes();
- i32 out = RGFW_initPlatform();
+ i32 out = RGFW_initPlatform(className, flags);
+ if (out != 0) {
+ RGFW_debugCallback(RGFW_typeError, RGFW_infoGlobal, "failed to initialize global context");
+ RGFW_deinitPlatform();
+ RGFW_MEMZERO(_RGFW, sizeof(RGFW_info));
+ RGFW_setInfo(NULL);
+ return out;
+ }
for (size_t i = 0; i < RGFW_mouseIconCount; i++) {
_RGFW->standardMice[i] = RGFW_createMouseStandard((RGFW_mouseIcon)i);
@@ -3872,29 +4184,57 @@ i32 RGFW_init_ptr(RGFW_info* info) {
RGFW_pollMonitors();
+ if (flags & RGFW_initOpenGL) {
+ #ifdef RGFW_WAYLAND
+ if (!(flags & RGFW_initX11)) {
+ flags |= RGFW_initEGL;
+ } else
+ #endif
+
+ if (RGFW_loadGL() == RGFW_FALSE) {
+ RGFW_debugCallback(RGFW_typeError, RGFW_errFailedFuncLoad, "Failed to load the OpenGL library");
+ return -1;
+ }
+ }
+
+ if (flags & RGFW_initVulkan) {
+ if (RGFW_loadVulkan() == RGFW_FALSE) {
+ RGFW_debugCallback(RGFW_typeError, RGFW_errFailedFuncLoad, "Failed to load the Vulkan library");
+ return -1;
+ }
+ }
+
+ if (flags & RGFW_initEGL) {
+ if (RGFW_loadEGL() == RGFW_FALSE) {
+ RGFW_debugCallback(RGFW_typeError, RGFW_errFailedFuncLoad, "Failed to load the EGL library");
+ return -1;
+ }
+ }
+
RGFW_debugCallback(RGFW_typeInfo, RGFW_infoGlobal, "global context initialized");
return out;
}
-#ifndef RGFW_EGL
-void RGFW_unloadEGL(void) { }
-#endif
-
void RGFW_deinit_ptr(RGFW_info* info) {
if (info == NULL) return;
RGFW_setInfo(info);
- RGFW_unloadEGL();
for (RGFW_mouseIcon i = 0; i < RGFW_mouseIconCount; i++) {
if (_RGFW->standardMice[i]) RGFW_freeMouse(_RGFW->standardMice[i]);
}
+ RGFW_freeMonitors();
+
RGFW_debugCallback(RGFW_typeInfo, RGFW_infoGlobal, "global context deinitialized");
RGFW_deinitPlatform();
+ RGFW_unloadEGL();
+ RGFW_unloadGL();
+
_RGFW->root = NULL;
+ _RGFW->cur = NULL;
_RGFW->windowCount = 0;
RGFW_setInfo(NULL);
}
@@ -3912,17 +4252,32 @@ void RGFW_window_close(RGFW_window* win) {
}
RGFW_window* RGFW_createWindowPtr(const char* name, i32 x, i32 y, i32 w, i32 h, RGFW_windowFlags flags, RGFW_window* win) {
+ RGFW_ASSERT(_RGFW && "An RGFW context must be initialized using RGFW_init and/or set with RGFW_setInfo");
RGFW_ASSERT(win != NULL);
if (name == NULL) name = "\0";
- RGFW_MEMZERO(win, sizeof(RGFW_window));
+#ifndef RGFW_OPENGL
+ if ((flags & RGFW_windowOpenGL)) {
+ RGFW_debugCallback(RGFW_typeWarning, RGFW_warningOpenGL, "cannot create an OpenGL context if RGFW is not compiled with OpenGL support via RGFW_OPENGL");
+ flags &= (RGFW_windowFlags)~RGFW_windowOpenGL;
+ }
+#endif
+#ifndef RGFW_EGL
+ if ((flags & RGFW_windowEGL)) {
+ RGFW_debugCallback(RGFW_typeWarning, RGFW_warningOpenGL, "cannot create an EGL context if RGFW is not compiled with EGL support via RGFW_EGL");
+ flags &= (RGFW_windowFlags)~RGFW_windowEGL;
+ }
+#endif
- if (_RGFW == NULL) RGFW_init();
+ RGFW_MEMZERO(win, sizeof(RGFW_window));
_RGFW->windowCount++;
/* rect based the requested flags */
if (_RGFW->root == NULL) {
RGFW_setRootWindow(win);
+ _RGFW->cur = _RGFW->root;
+ } else {
+ _RGFW->cur->next = win;
}
/* set and init the new window's data */
@@ -3933,11 +4288,15 @@ RGFW_window* RGFW_createWindowPtr(const char* name, i32 x, i32 y, i32 w, i32 h,
win->internal.mouse = _RGFW->standardMice[RGFW_mouseNormal];
win->internal.flags = flags;
win->internal.enabledEvents = RGFW_allEventFlags;
+ win->next = NULL;
RGFW_windowFlags reservedFlags = flags & (RGFW_windowScaleToMonitor);
- flags &= ~reservedFlags;
RGFW_window* ret = RGFW_createWindowPlatform(name, flags, win);
+ if (ret == NULL) {
+ RGFW_debugCallback(RGFW_typeError, RGFW_errPlatform, "failed to create a window");
+ return NULL;
+ }
flags |= reservedFlags;
@@ -3947,13 +4306,18 @@ RGFW_window* RGFW_createWindowPtr(const char* name, i32 x, i32 y, i32 w, i32 h,
#ifdef RGFW_OPENGL
win->src.gfxType = 0;
- if (flags & RGFW_windowOpenGL)
- RGFW_window_createContext_OpenGL(win, RGFW_getGlobalHints_OpenGL());
+ if (flags & RGFW_windowOpenGL) {
+ RGFW_glContext* context = RGFW_createContext_OpenGL(RGFW_getGlobalHints_OpenGL());
+ if (context) RGFW_window_setContext_OpenGL(win, context);
+ }
#endif
#ifdef RGFW_EGL
- if (flags & RGFW_windowEGL)
- RGFW_window_createContext_EGL(win, RGFW_getGlobalHints_OpenGL());
+ if (!(flags & RGFW_windowOpenGL)) win->src.gfxType = 0;
+ if (flags & RGFW_windowEGL) {
+ RGFW_eglContext* context = RGFW_createContext_EGL(RGFW_getGlobalHints_OpenGL());
+ if (context) RGFW_window_setContext_EGL(win, context);
+ }
#endif
/* X11 creates the window after the OpenGL context is created (because of visual garbage),
@@ -3965,11 +4329,6 @@ RGFW_window* RGFW_createWindowPtr(const char* name, i32 x, i32 y, i32 w, i32 h,
RGFW_window_setFlagsInternal(win, flags, 0);
#endif
-#ifdef RGFW_MACOS
- /*NOTE: another OpenGL/setFlags related hack, this because OSX the 'view' class must be setup after the NSOpenGL view is made AND after setFlags happens */
- RGFW_osx_initView(win);
-#endif
-
#ifdef RGFW_WAYLAND
/* recieve all events needed to configure the surface */
/* also gets the wl_outputs */
@@ -3987,6 +4346,10 @@ RGFW_window* RGFW_createWindowPtr(const char* name, i32 x, i32 y, i32 w, i32 h,
}
#endif
+#ifdef RGFW_MACOS
+ RGFW_osx_initView(win);
+#endif
+
if (!(flags & RGFW_windowHideMouse)) {
RGFW_window_setMouseDefault(win);
}
@@ -3995,6 +4358,8 @@ RGFW_window* RGFW_createWindowPtr(const char* name, i32 x, i32 y, i32 w, i32 h,
if (!(flags & RGFW_windowHide)) {
flags |= RGFW_windowHide;
RGFW_window_show(win);
+ } else if ((flags & RGFW_windowMaximize) || (flags & RGFW_windowFullscreenExclusive) || (flags & RGFW_windowFullscreenBorderless)) {
+ RGFW_window_hide(win);
}
RGFW_debugCallback(RGFW_typeInfo, RGFW_infoWindow, "a new window was created");
@@ -4004,6 +4369,9 @@ RGFW_window* RGFW_createWindowPtr(const char* name, i32 x, i32 y, i32 w, i32 h,
void RGFW_window_closePtr(RGFW_window* win) {
RGFW_ASSERT(win != NULL);
+ if ((win->internal.flags & RGFW_windowFullscreenExclusive) && win->internal.monitor) {
+ RGFW_monitor_setMode(win->internal.monitor, &win->internal.oldMode);
+ }
if (win->internal.captureMouse) {
RGFW_window_captureMouse(win, RGFW_FALSE);
@@ -4011,26 +4379,37 @@ void RGFW_window_closePtr(RGFW_window* win) {
#ifdef RGFW_EGL
if ((win->src.gfxType & RGFW_gfxEGL) && win->src.ctx.egl) {
- RGFW_window_deleteContext_EGL(win, win->src.ctx.egl);
- win->src.ctx.egl = NULL;
+ RGFW_eglContext* ctx = win->src.ctx.egl;
+ RGFW_window_setContext_EGL(win, NULL);
+ RGFW_deleteContext_EGL(ctx);
}
#endif
#ifdef RGFW_OPENGL
if ((win->src.gfxType & RGFW_gfxNativeOpenGL) && win->src.ctx.native) {
- RGFW_window_deleteContext_OpenGL(win, win->src.ctx.native);
- win->src.ctx.native = NULL;
+ RGFW_glContext* ctx = win->src.ctx.native;
+ RGFW_window_setContext_OpenGL(win, NULL);
+ RGFW_deleteContext_OpenGL(ctx);
}
#endif
RGFW_window_closePlatform(win);
- RGFW_clipboard_switch(NULL);
+ if (_RGFW->root == win) {
+ _RGFW->root = win->next;
+ if (_RGFW->cur == win) _RGFW->cur = NULL;
+ } else if (_RGFW->cur == win) {
+ RGFW_window* cur;
+ for (cur = _RGFW->root; cur->next && cur->next != win; cur = cur->next);
+ _RGFW->cur = cur;
+ }
+
+ if (_RGFW->clipboard != NULL)
+ RGFW_FREE(_RGFW->clipboard);
+ _RGFW->clipboard = NULL;
_RGFW->windowCount--;
RGFW_debugCallback(RGFW_typeInfo, RGFW_infoWindow, "a window was freed");
-
- if (_RGFW->windowCount == 0 && !(win->internal.flags & RGFW_noDeinitOnClose)) RGFW_deinit();
}
void RGFW_setQueueEvents(RGFW_bool queue) { _RGFW->queueEvents = RGFW_BOOL(queue); }
@@ -4210,6 +4589,7 @@ RGFW_event* RGFW_window_eventQueuePop(RGFW_window* win) {
}
if (ev->common.win != win && ev->common.win != NULL) {
+ RGFW_eventQueuePush(ev);
return NULL;
}
@@ -4219,10 +4599,6 @@ RGFW_event* RGFW_window_eventQueuePop(RGFW_window* win) {
void RGFW_setRootWindow(RGFW_window* win) { _RGFW->root = win; }
RGFW_window* RGFW_getRootWindow(void) { return _RGFW->root; }
-#ifndef RGFW_EGL
-RGFW_bool RGFW_loadEGL(void) { return RGFW_FALSE; }
-#endif
-
void RGFW_window_setFlagsInternal(RGFW_window* win, RGFW_windowFlags flags, RGFW_windowFlags cmpFlags) {
if (flags & RGFW_windowNoBorder) RGFW_window_setBorder(win, 0);
else if (cmpFlags & RGFW_windowNoBorder) RGFW_window_setBorder(win, 1);
@@ -4232,8 +4608,10 @@ void RGFW_window_setFlagsInternal(RGFW_window* win, RGFW_windowFlags flags, RGFW
else if (cmpFlags & RGFW_windowMinimize) RGFW_window_restore(win);
if (flags & RGFW_windowCenter) RGFW_window_center(win);
if (flags & RGFW_windowCenterCursor) RGFW_window_moveMouse(win, win->x + (win->w / 2), win->y + (win->h / 2));
- if (flags & RGFW_windowFullscreen) RGFW_window_setFullscreen(win, RGFW_TRUE);
- else if (cmpFlags & RGFW_windowFullscreen) RGFW_window_setFullscreen(win, 0);
+ if (flags & RGFW_windowFullscreenExclusive) RGFW_window_setFullscreen(win, RGFW_fullscreenExclusive);
+ else if (cmpFlags & RGFW_windowFullscreenExclusive) RGFW_window_setFullscreen(win, 0);
+ if (flags & RGFW_windowFullscreenBorderless) RGFW_window_setFullscreen(win, RGFW_fullscreenBorderless);
+ else if (cmpFlags & RGFW_fullscreenBorderless) RGFW_window_setFullscreen(win, 0);
if (flags & RGFW_windowHideMouse) RGFW_window_showMouse(win, 0);
else if (cmpFlags & RGFW_windowHideMouse) RGFW_window_showMouse(win, 1);
if (flags & RGFW_windowHide) RGFW_window_hide(win);
@@ -4269,13 +4647,8 @@ RGFW_bool RGFW_window_isInFocus(RGFW_window* win) {
#endif
}
-void RGFW_setClassName(const char* name) { RGFW_init(); _RGFW->className = name; }
void RGFW_setBuildDND(RGFW_bool state) { _RGFW->dndBuild = state; }
-#ifndef RGFW_X11
-void RGFW_setXInstName(const char* name) { RGFW_UNUSED(name); }
-#endif
-
RGFW_bool RGFW_window_getMouse(RGFW_window* win, i32* x, i32* y) {
RGFW_ASSERT(win != NULL);
if (x) *x = win->internal.lastMouseX;
@@ -4301,6 +4674,7 @@ u64 RGFW_window_getWindow_X11(RGFW_window* win) { RGFW_UNUSED(win); return 0; }
#ifndef RGFW_WAYLAND
struct wl_display* RGFW_getDisplay_Wayland(void) { return NULL; }
struct wl_surface* RGFW_window_getWindow_Wayland(RGFW_window* win) { RGFW_UNUSED(win); return NULL; }
+RGFW_bool RGFW_usingWayland(void) { return RGFW_FALSE; }
#endif
#ifndef RGFW_WINDOWS
@@ -4329,12 +4703,19 @@ void RGFW_window_center(RGFW_window* win) {
}
RGFW_bool RGFW_monitor_scaleToWindow(RGFW_monitor* mon, RGFW_window* win) {
- RGFW_monitorMode mode;
RGFW_ASSERT(win != NULL);
+ RGFW_ASSERT(mon != NULL);
+ RGFW_monitorMode mode = mon->mode;
mode.w = win->w;
mode.h = win->h;
RGFW_bool ret = RGFW_monitor_requestMode(mon, &mode, RGFW_monitorScale);
+ if (ret == RGFW_FALSE) {
+ RGFW_monitorMode closest;
+ ret = RGFW_monitor_findClosestMode(mon, &mode, &closest);
+ if (ret == RGFW_FALSE) { return ret; }
+ ret = RGFW_monitor_setMode(mon, &closest);
+ }
/* move window to monitor origin so it doesn't move to the next monitor */
RGFW_window_move(win, mon->x, mon->y);
@@ -4374,13 +4755,14 @@ void RGFW_window_setShouldClose(RGFW_window* win, RGFW_bool shouldClose) {
void RGFW_window_scaleToMonitor(RGFW_window* win) {
RGFW_monitor* monitor = RGFW_window_getMonitor(win);
- if (monitor->scaleX == 0 && monitor->scaleY == 0)
+ if (monitor == NULL || (monitor->scaleX == 0 && monitor->scaleY == 0))
return;
RGFW_window_resize(win, (i32)(monitor->scaleX * (float)win->w), (i32)(monitor->scaleY * (float)win->h));
}
void RGFW_window_moveToMonitor(RGFW_window* win, RGFW_monitor* m) {
+ RGFW_ASSERT(m != NULL);
RGFW_window_move(win, m->x + win->x, m->y + win->y);
}
@@ -4478,14 +4860,22 @@ void RGFW_copyImageData64(u8* dest_data, i32 dest_w, i32 dest_h, RGFW_format des
RGFW_monitorNode* RGFW_monitors_add(const RGFW_monitor* mon) {
RGFW_monitorNode* node = NULL;
- if (_RGFW->monitors.freeList.head == NULL) return node;
- node = _RGFW->monitors.freeList.head;
-
- _RGFW->monitors.freeList.head = node->next;
- if (_RGFW->monitors.freeList.head == NULL) {
- _RGFW->monitors.freeList.cur = NULL;
+ #if (RGFW_PREALLOCATED_MONITORS)
+ node = _RGFW->monitors.freeList.head;
+ if (node) {
+ _RGFW->monitors.freeList.head = node->next;
+ if (_RGFW->monitors.freeList.head == NULL) {
+ _RGFW->monitors.freeList.cur = NULL;
+ }
+ } else
+ #elif !defined(RGFW_NO_ALLOCATE_MONITORS)
+ {
+ node = (RGFW_monitorNode*)RGFW_ALLOC(sizeof(RGFW_monitorNode));
}
+ #endif
+
+ if (node == NULL) return NULL;
node->next = NULL;
@@ -4508,23 +4898,34 @@ RGFW_monitorNode* RGFW_monitors_add(const RGFW_monitor* mon) {
void RGFW_monitors_remove(RGFW_monitorNode* node, RGFW_monitorNode* prev) {
_RGFW->monitors.count -= 1;
+ RGFW_monitorNode_free(node);
+
/* remove node from the list */
if (prev != node) {
prev->next = node->next;
} else { /* node is the head */
- _RGFW->monitors.list.head = NULL;
+ _RGFW->monitors.list.head = node->next;
}
node->next = NULL;
- /* move node to the free list */
- if (_RGFW->monitors.freeList.head == NULL) {
- _RGFW->monitors.freeList.head = node;
- } else {
- _RGFW->monitors.freeList.cur->next = node;
- }
+ #if (RGFW_PREALLOCATED_MONITORS)
+ /* check if the monitor was allocated in the heap or not */
+ if (node >= _RGFW->monitors.data && node <= &_RGFW->monitors.data[RGFW_PREALLOCATED_MONITORS - 1]) {
+ /* move node to the free list */
+ if (_RGFW->monitors.freeList.head == NULL) {
+ _RGFW->monitors.freeList.head = node;
+ } else {
+ _RGFW->monitors.freeList.cur->next = node;
+ }
- _RGFW->monitors.freeList.cur = node;
+ _RGFW->monitors.freeList.cur = node;
+ } else
+ {
+ #elif !defined(RGFW_NO_ALLOCATE_MONITORS)
+ RGFW_FREE(node);
+ #endif
+ }
}
void RGFW_monitors_refresh(void) {
@@ -4538,7 +4939,17 @@ void RGFW_monitors_refresh(void) {
}
}
+void RGFW_freeMonitors(void) {
+ RGFW_monitorNode* node = _RGFW->monitors.list.head;
+ while (node != NULL) {
+ RGFW_monitorNode* next = node->next;
+ RGFW_monitors_remove(node, node);
+ node = next;
+ }
+}
+
RGFW_monitorMode* RGFW_monitor_getModes(RGFW_monitor* monitor, size_t* count) {
+ RGFW_ASSERT(monitor != NULL);
size_t num = RGFW_monitor_getModesPtr(monitor, NULL);
RGFW_monitorMode* modes = (RGFW_monitorMode*)RGFW_ALLOC(num * sizeof(RGFW_monitorNode));
num = RGFW_monitor_getModesPtr(monitor, &modes);
@@ -4552,36 +4963,50 @@ void RGFW_freeModes(RGFW_monitorMode* modes) {
}
RGFW_bool RGFW_monitor_findClosestMode(RGFW_monitor* monitor, RGFW_monitorMode* mode, RGFW_monitorMode* closest) {
+ RGFW_ASSERT(monitor != NULL);
size_t count = RGFW_monitor_getModesPtr(monitor, NULL);
RGFW_monitorMode* modes = (RGFW_monitorMode*)RGFW_ALLOC(count * sizeof(RGFW_monitorNode));
count = RGFW_monitor_getModesPtr(monitor, &modes);
RGFW_monitorMode* chosen = NULL;
+ u32 sizeScore = UINT_MAX;
+ u32 rateScore = UINT_MAX;
+ u32 colorScore = UINT_MAX;
- u32 topScore = 1;
for (size_t i = 0; i < count; i++) {
RGFW_monitorMode* mode2 = &modes[i];
- u32 score = 0;
- if (mode->w == mode2->w && mode->h == mode2->h) score += 1000;
- if (mode->red == mode2->red && mode->green == mode2->green && mode->blue == mode2->blue) score += 100;
- if (mode->refreshRate == mode->refreshRate) score += 10;
+ u32 currColorScore = 0;
+ if (mode->red) currColorScore += (u32)RGFW_ABS(mode2->red - mode->red);
+ if (mode->blue) currColorScore += (u32)RGFW_ABS(mode2->green - mode->green);
+ if (mode->green) currColorScore += (u32)RGFW_ABS(mode2->blue - mode->blue);
- if (score > topScore) {
- topScore = score;
- chosen = mode2;
- }
+ u32 currSizeScore = (u32)RGFW_ABS((mode2->w - mode->w) * (mode2->w- mode->w) +
+ (mode2->h - mode->h) * (mode2->h - mode->h));
+
+
+ u32 currRateScore = UINT_MAX - (u32)mode2->refreshRate;
+ currRateScore = (u32)RGFW_ABS(mode2->refreshRate - mode->refreshRate);
+
+ if ((currColorScore < colorScore) ||
+ (currColorScore == colorScore && currSizeScore < sizeScore) ||
+ (currColorScore == colorScore && currSizeScore == sizeScore && currRateScore < rateScore)) {
+ sizeScore = currSizeScore;
+ rateScore = currRateScore;
+ colorScore = currColorScore;
+ chosen = mode2;
+ }
}
if (chosen && closest) *closest = *chosen;
-
RGFW_FREE(modes);
return (chosen == NULL) ? RGFW_FALSE : RGFW_TRUE;
}
RGFW_bool RGFW_monitor_getPosition(RGFW_monitor* monitor, i32* x, i32* y) {
+ RGFW_ASSERT(monitor != NULL);
if (x) *x = monitor->x;
if (y) *y = monitor->y;
return RGFW_TRUE;
@@ -4592,31 +5017,37 @@ const char* RGFW_monitor_getName(RGFW_monitor* monitor) {
}
RGFW_bool RGFW_monitor_getScale(RGFW_monitor* monitor, float* x, float* y) {
+ RGFW_ASSERT(monitor != NULL);
if (x) *x = monitor->scaleX;
if (y) *y = monitor->scaleY;
return RGFW_TRUE;
}
RGFW_bool RGFW_monitor_getPhysicalSize(RGFW_monitor* monitor, float* w, float* h) {
+ RGFW_ASSERT(monitor != NULL);
if (w) *w = monitor->physW;
if (h) *h = monitor->physH;
return RGFW_TRUE;
}
void RGFW_monitor_setUserPtr(RGFW_monitor* monitor, void* userPtr) {
+ RGFW_ASSERT(monitor != NULL);
monitor->userPtr = userPtr;
}
void* RGFW_monitor_getUserPtr(RGFW_monitor* monitor) {
+ RGFW_ASSERT(monitor != NULL);
return monitor->userPtr;
}
RGFW_bool RGFW_monitor_getMode(RGFW_monitor* monitor, RGFW_monitorMode* mode) {
+ RGFW_ASSERT(monitor != NULL);
if (mode) *mode = monitor->mode;
return RGFW_TRUE;
}
RGFW_gammaRamp* RGFW_monitor_getGammaRamp(RGFW_monitor* monitor) {
+ RGFW_ASSERT(monitor != NULL);
RGFW_gammaRamp* ramp = (RGFW_gammaRamp*)RGFW_ALLOC(sizeof(RGFW_gammaRamp));
ramp->count = RGFW_monitor_getGammaRampPtr(monitor, NULL);
ramp->red = (u16*)RGFW_ALLOC(sizeof(u16) * ramp->count);
@@ -4659,6 +5090,7 @@ RGFW_bool RGFW_monitor_setGammaPtr(RGFW_monitor* monitor, float gamma, u16* ptr,
}
RGFW_bool RGFW_monitor_setGamma(RGFW_monitor* monitor, float gamma) {
+ RGFW_ASSERT(monitor != NULL);
size_t count = RGFW_monitor_getGammaRampPtr(monitor, NULL);
u16* ptr = (u16*)RGFW_ALLOC(count * sizeof(u16));
@@ -4669,23 +5101,50 @@ RGFW_bool RGFW_monitor_setGamma(RGFW_monitor* monitor, float gamma) {
}
RGFW_monitor** RGFW_getMonitors(size_t* len) {
- static RGFW_monitor* monitors[RGFW_MAX_MONITORS];
- RGFW_init();
+ if (len != NULL) *len = 0;
+
+ size_t count = 0;
+ if (RGFW_getMonitorsPtr(0, NULL, &count) == RGFW_FALSE || count == 0) return NULL;
+
+ RGFW_monitor** monitors = (RGFW_monitor**)RGFW_ALLOC(sizeof(RGFW_monitor*) * count);
+
+ if (RGFW_getMonitorsPtr(count, monitors, &count) == RGFW_FALSE) {
+ RGFW_FREE(monitors);
+ return NULL;
+ }
+
+ if (len != NULL) *len = count;
+
+ return monitors;
+}
+
+RGFW_bool RGFW_getMonitorsPtr(size_t max, RGFW_monitor** monitors, size_t* len) {
+ RGFW_ASSERT(monitors != NULL);
+ RGFW_ASSERT(_RGFW && "An RGFW context must be initialized using RGFW_init and/or set with RGFW_setInfo");
if (len != NULL) {
*len = _RGFW->monitors.count;
}
- u8 i = 0;
+ if (monitors == NULL || max == 0) return RGFW_TRUE;
+
+
+ if (len != NULL) {
+ *len = max;
+ }
+
+ size_t i = 0;
RGFW_monitorNode* cur_node = _RGFW->monitors.list.head;
- while (cur_node != NULL) {
+ while (cur_node != NULL && i < max) {
monitors[i] = &cur_node->mon;
i++;
cur_node = cur_node->next;
}
- return monitors;
+
+ return RGFW_TRUE;
}
RGFW_monitor* RGFW_getPrimaryMonitor(void) {
+ RGFW_ASSERT(_RGFW && "An RGFW context must be initialized using RGFW_init and/or set with RGFW_setInfo");
if (_RGFW->monitors.primary == NULL) {
_RGFW->monitors.primary = _RGFW->monitors.list.head;
}
@@ -4754,7 +5213,9 @@ RGFW_bool RGFW_window_borderless(RGFW_window* win) {
return (RGFW_bool)RGFW_BOOL(win->internal.flags & RGFW_windowNoBorder);
}
-RGFW_bool RGFW_window_isFullscreen(RGFW_window* win){ return RGFW_BOOL(win->internal.flags & RGFW_windowFullscreen); }
+RGFW_bool RGFW_window_isFullscreenExclusive(RGFW_window* win){ return RGFW_BOOL(win->internal.flags & RGFW_windowFullscreenExclusive); }
+RGFW_bool RGFW_window_isFullscreenBorderless(RGFW_window* win){ return RGFW_BOOL(win->internal.flags & RGFW_windowFullscreenBorderless); }
+RGFW_bool RGFW_window_isFullscreen(RGFW_window* win){ return RGFW_window_isFullscreenExclusive(win) || RGFW_window_isFullscreenBorderless(win); }
RGFW_bool RGFW_window_allowsDND(RGFW_window* win) { return RGFW_BOOL(win->internal.flags & RGFW_windowAllowDND); }
RGFW_bool RGFW_window_setMouseDefault(RGFW_window* win) {
@@ -4782,14 +5243,6 @@ void RGFW_window_setDND(RGFW_window* win, RGFW_bool allow) {
}
#endif
-#if defined(RGFW_X11) || defined(RGFW_MACOS) || defined(RGFW_WASM) || defined(RGFW_WAYLAND)
-#ifndef __USE_POSIX199309
- #define __USE_POSIX199309
-#endif
-#include <time.h>
-struct timespec;
-#endif
-
#if defined(RGFW_WAYLAND) || defined(RGFW_X11) || defined(RGFW_WINDOWS)
void RGFW_window_showMouse(RGFW_window* win, RGFW_bool show) {
RGFW_window_showMouseFlags(win, show);
@@ -4834,6 +5287,118 @@ u32 RGFW_decodeUTF8(const char* string, size_t* starting_index) {
return codepoint - offsets[count - 1];
}
+void RGFW_window_show(RGFW_window* win) {
+ RGFW_ASSERT(win != NULL);
+ if (win->internal.flags & RGFW_windowFocusOnShow) RGFW_window_focus(win);
+ RGFW_window_showPlatform(win);
+ if ((win->internal.flags & RGFW_windowMaximize)) RGFW_window_maximize(win);
+}
+
+void RGFW_window_restore(RGFW_window* win) {
+ RGFW_ASSERT(win != NULL);
+ RGFW_window_restorePlatform(win);
+ win->internal.flags &= ~(u32)RGFW_windowMaximize;
+ RGFW_window_show(win);
+ RGFW_window_move(win, win->internal.oldX, win->internal.oldY);
+ RGFW_window_resize(win, win->internal.oldW, win->internal.oldH);
+}
+
+void RGFW_window_minimize(RGFW_window* win) {
+ RGFW_ASSERT(win != NULL);
+ RGFW_window_minimizePlatform(win);
+ win->internal.flags &= ~(u32)RGFW_windowMaximize;
+}
+
+void RGFW_window_maximize(RGFW_window* win) {
+ RGFW_ASSERT(win != NULL);
+ win->internal.oldX = win->x;
+ win->internal.oldY = win->y;
+ win->internal.oldW = win->w;
+ win->internal.oldH = win->h;
+ win->internal.flags |= RGFW_windowMaximize;
+ RGFW_window_fetchSize(win, NULL, NULL);
+
+ RGFW_window_maximizePlatform(win);
+}
+
+void RGFW_window_move(RGFW_window* win, i32 x, i32 y) {
+ RGFW_ASSERT(win != NULL);
+ win->x = x;
+ win->y = y;
+ RGFW_window_movePlatform(win, x, y);
+ win->internal.flags &= ~(u32)RGFW_windowMaximize;
+}
+
+void RGFW_window_resize(RGFW_window* win, i32 w, i32 h) {
+ RGFW_ASSERT(win != NULL);
+ win->w = w;
+ win->h = h;
+ RGFW_window_resizePlatform(win, w, h);
+ win->internal.flags &= ~(u32)RGFW_windowMaximize;
+}
+
+void RGFW_window_setFullscreen(RGFW_window* win, RGFW_fullscreenMode fullscreen) {
+ RGFW_ASSERT(win != NULL);
+ if ((fullscreen == RGFW_fullscreenExclusive && (win->internal.flags & RGFW_windowFullscreenExclusive)) ||
+ (fullscreen == RGFW_fullscreenBorderless && RGFW_BOOL(win->internal.flags & RGFW_windowFullscreenBorderless)) ||
+ (fullscreen == 0 && RGFW_window_isFullscreen(win) == RGFW_FALSE)) {
+ return;
+ }
+
+ if ((fullscreen == RGFW_fullscreenExclusive && RGFW_BOOL(win->internal.flags & RGFW_windowFullscreenBorderless)) ||
+ (fullscreen == RGFW_fullscreenBorderless && (win->internal.flags & RGFW_windowFullscreenExclusive))) {
+ RGFW_window_setFullscreen(win, RGFW_fullscreenNone);
+ }
+
+ if (fullscreen) {
+ win->internal.oldX = win->x;
+ win->internal.oldY = win->y;
+ win->internal.oldW = win->w;
+ win->internal.oldH = win->h;
+
+ win->internal.oldBorderless = RGFW_window_borderless(win);
+ RGFW_window_setBorder(win, 0);
+
+ RGFW_monitor* mon = RGFW_window_getMonitor(win);
+ RGFW_window_move(win, mon->x, mon->y);
+
+ if (fullscreen == RGFW_fullscreenExclusive) {
+ win->internal.oldMode = mon->mode;
+ RGFW_monitor_scaleToWindow(mon, win);
+ win->internal.monitor = mon;
+ win->internal.newMode = mon->mode;
+ win->internal.flags |= RGFW_windowFullscreenExclusive;
+ } else {
+ win->internal.flags |= RGFW_windowFullscreenBorderless;
+ win->internal.monitor = NULL;
+ }
+
+ RGFW_window_resize(win, mon->mode.w, mon->mode.h);
+ }
+
+ RGFW_window_setFullscreenPlatform(win, (fullscreen > 0) ? RGFW_TRUE : RGFW_FALSE);
+
+ if (fullscreen == 0) {
+ if (win->internal.monitor != NULL) {
+ RGFW_monitor_setMode(win->internal.monitor, &win->internal.oldMode);
+ }
+
+ RGFW_window_setBorder(win, !win->internal.oldBorderless);
+
+ RGFW_window_move(win, win->internal.oldX, win->internal.oldY);
+ RGFW_window_resize(win, win->internal.oldW, win->internal.oldH);
+
+ win->internal.flags &= ~(u32)RGFW_windowFullscreenExclusive;
+ win->internal.flags &= ~(u32)RGFW_windowFullscreenBorderless;
+
+ win->x = win->internal.oldX;
+ win->y = win->internal.oldY;
+ win->w = win->internal.oldW;
+ win->h = win->internal.oldH;
+ return;
+ }
+}
+
/*
graphics API specific code (end of generic code)
starts here
@@ -4844,7 +5409,8 @@ u32 RGFW_decodeUTF8(const char* string, size_t* starting_index) {
OpenGL defines start here (Normal, EGL, OSMesa)
*/
-#if defined(RGFW_OPENGL)
+#if defined(RGFW_OPENGL) || defined(RGFW_EGL)
+
/* EGL, OpenGL */
#define RGFW_DEFAULT_GL_HINTS { \
/* Stencil */ 0, \
@@ -4885,7 +5451,10 @@ void RGFW_resetGlobalHints_OpenGL(void) {
#endif
}
void RGFW_setGlobalHints_OpenGL(RGFW_glHints* hints) { RGFW_globalHints_OpenGL = hints; }
-RGFW_glHints* RGFW_getGlobalHints_OpenGL(void) { RGFW_init(); return RGFW_globalHints_OpenGL; }
+RGFW_glHints* RGFW_getGlobalHints_OpenGL(void) {
+ RGFW_ASSERT(_RGFW && "An RGFW context must be initialized using RGFW_init and/or set with RGFW_setInfo");
+ return RGFW_globalHints_OpenGL;
+}
void* RGFW_glContext_getSourceContext(RGFW_glContext* ctx) {
@@ -4902,30 +5471,15 @@ void* RGFW_glContext_getSourceContext(RGFW_glContext* ctx) {
#endif
}
-RGFW_glContext* RGFW_window_createContext_OpenGL(RGFW_window* win, RGFW_glHints* hints) {
- #ifdef RGFW_WAYLAND
- if (RGFW_usingWayland()) {
- return (RGFW_glContext*)RGFW_window_createContext_EGL(win, hints);
- }
- #endif
- RGFW_glContext* ctx = (RGFW_glContext*)RGFW_ALLOC(sizeof(RGFW_glContext));
- if (RGFW_window_createContextPtr_OpenGL(win, ctx, hints) == RGFW_FALSE) {
- RGFW_FREE(ctx);
- win->src.ctx.native = NULL;
- return NULL;
- }
- win->src.gfxType |= RGFW_gfxOwnedByRGFW;
- return ctx;
-}
-
-RGFW_glContext* RGFW_window_getContext_OpenGL(RGFW_window* win) {
- if (win->src.gfxType & RGFW_windowEGL) return NULL;
- return win->src.ctx.native;
+void RGFW_attribStack_init(RGFW_attribStack* stack, i32* attribs, size_t max) { stack->attribs = attribs; stack->count = 0; stack->max = max; }
+void RGFW_attribStack_pushAttrib(RGFW_attribStack* stack, i32 attrib) {
+ RGFW_ASSERT(stack->count < stack->max);
+ stack->attribs[stack->count] = attrib;
+ stack->count += 1;
}
-
-void RGFW_window_deleteContext_OpenGL(RGFW_window* win, RGFW_glContext* ctx) {
- RGFW_window_deleteContextPtr_OpenGL(win, ctx);
- if (win->src.gfxType & RGFW_gfxOwnedByRGFW) RGFW_FREE(ctx);
+void RGFW_attribStack_pushAttribs(RGFW_attribStack* stack, i32 attrib1, i32 attrib2) {
+ RGFW_attribStack_pushAttrib(stack, attrib1);
+ RGFW_attribStack_pushAttrib(stack, attrib2);
}
RGFW_bool RGFW_extensionSupportedStr(const char* extensions, const char* ext, size_t len) {
@@ -4954,16 +5508,16 @@ RGFW_bool RGFW_extensionSupportedStr(const char* extensions, const char* ext, si
return RGFW_FALSE;
}
-RGFWDEF RGFW_bool RGFW_extensionSupported_base(const char* extension, size_t len);
-RGFW_bool RGFW_extensionSupported_base(const char* extension, size_t len) {
+RGFWDEF RGFW_bool RGFW_extensionSupported_base(const char* extension, size_t len, RGFW_proc (*getProcAddress)(const char* procname));
+RGFW_bool RGFW_extensionSupported_base(const char* extension, size_t len, RGFW_proc (*getProcAddress)(const char* procname)) {
#ifdef GL_NUM_EXTENSIONS
if (RGFW_globalHints_OpenGL->major >= 3) {
i32 i;
GLint count = 0;
- RGFW_proc RGFW_glGetStringi = RGFW_getProcAddress_OpenGL("glGetStringi");
- RGFW_proc RGFW_glGetIntegerv = RGFW_getProcAddress_OpenGL("glGetIntegerv");
+ RGFW_proc RGFW_glGetStringi = getProcAddress("glGetStringi");
+ RGFW_proc RGFW_glGetIntegerv = getProcAddress("glGetIntegerv");
if (RGFW_glGetIntegerv)
((void(*)(GLenum, GLint*))RGFW_glGetIntegerv)(GL_NUM_EXTENSIONS, &count);
@@ -4976,7 +5530,7 @@ RGFW_bool RGFW_extensionSupported_base(const char* extension, size_t len) {
} else
#endif
{
- RGFW_proc RGFW_glGetString = RGFW_getProcAddress_OpenGL("glGetString");
+ RGFW_proc RGFW_glGetString = getProcAddress("glGetString");
#define RGFW_GL_EXTENSIONS 0x1F03
if (RGFW_glGetString) {
const char* extensions = ((const char*(*)(u32))RGFW_glGetString)(RGFW_GL_EXTENSIONS);
@@ -4989,8 +5543,64 @@ RGFW_bool RGFW_extensionSupported_base(const char* extension, size_t len) {
return RGFW_FALSE;
}
+#endif /* OpenGL or EGL */
+
+#ifdef RGFW_OPENGL
+
+void RGFW_unloadGL(void) {
+ if (!_RGFW->nativeGL_handle) return;
+ #ifdef RGFW_WINDOWS
+ FreeLibrary((HMODULE)_RGFW->nativeGL_handle);
+ #elif defined(RGFW_UNIX)
+ dlclose(_RGFW->nativeGL_handle);
+ #endif /* OSX doesn't need it's handle freed */
+
+ _RGFW->nativeGL_handle = NULL;
+ _RGFW->glGetProcAddress = NULL;
+}
+
+RGFW_glContext* RGFW_createContext_OpenGL(RGFW_glHints* hints) {
+ #ifdef RGFW_WAYLAND
+ if (RGFW_usingWayland()) {
+ return (RGFW_glContext*)RGFW_createContext_EGL(hints);
+ }
+ #endif
+ RGFW_glContext* ctx = (RGFW_glContext*)RGFW_ALLOC(sizeof(RGFW_glContext));
+ if (RGFW_createContextPtr_OpenGL(ctx, hints) == RGFW_FALSE) {
+ RGFW_FREE(ctx);
+ return NULL;
+ }
+ return ctx;
+}
+
+RGFW_glContext* RGFW_window_getContext_OpenGL(RGFW_window* win) {
+ if (win->src.gfxType & RGFW_windowEGL) return NULL;
+ return win->src.ctx.native;
+}
+
+void RGFW_deleteContext_OpenGL(RGFW_glContext* ctx) {
+ RGFW_deleteContextPtr_OpenGL(ctx);
+ RGFW_FREE(ctx);
+}
+
+RGFW_glContext* RGFW_copyContext_OpenGL(RGFW_glContext* ctx) {
+ RGFW_glContext* newCtx = (RGFW_glContext*)RGFW_ALLOC(sizeof(RGFW_glContext));
+ RGFW_copyContextPtr_OpenGL(ctx, newCtx);
+ return newCtx;
+}
+
+RGFW_bool RGFW_copyContextPtr_OpenGL(RGFW_glContext* ctx, RGFW_glContext* newCtx) {
+ RGFW_ASSERT(ctx); RGFW_ASSERT(newCtx);
+ RGFW_MEMCPY(newCtx, ctx, sizeof(RGFW_glContext));
+
+#ifdef RGFW_MACOS
+ RGFW_copyContext_OSX_OpenGL(ctx, newCtx);
+#endif
+ return RGFW_TRUE;
+}
+
RGFW_bool RGFW_extensionSupported_OpenGL(const char* extension, size_t len) {
- if (RGFW_extensionSupported_base(extension, len)) return RGFW_TRUE;
+ if (RGFW_extensionSupported_base(extension, len, RGFW_getProcAddress_OpenGL)) return RGFW_TRUE;
return RGFW_extensionSupportedPlatform_OpenGL(extension, len);
}
@@ -5003,16 +5613,7 @@ void RGFW_window_makeCurrentWindow_OpenGL(RGFW_window* win) {
}
RGFW_window* RGFW_getCurrentWindow_OpenGL(void) { return _RGFW->current; }
-void RGFW_attribStack_init(RGFW_attribStack* stack, i32* attribs, size_t max) { stack->attribs = attribs; stack->count = 0; stack->max = max; }
-void RGFW_attribStack_pushAttrib(RGFW_attribStack* stack, i32 attrib) {
- RGFW_ASSERT(stack->count < stack->max);
- stack->attribs[stack->count] = attrib;
- stack->count += 1;
-}
-void RGFW_attribStack_pushAttribs(RGFW_attribStack* stack, i32 attrib1, i32 attrib2) {
- RGFW_attribStack_pushAttrib(stack, attrib1);
- RGFW_attribStack_pushAttrib(stack, attrib2);
-}
+#endif /* OPENGL only */
/* EGL */
#ifdef RGFW_EGL
@@ -5032,33 +5633,25 @@ PFNEGLDESTROYCONTEXTPROC RGFW_eglDestroyContext;
PFNEGLTERMINATEPROC RGFW_eglTerminate;
PFNEGLDESTROYSURFACEPROC RGFW_eglDestroySurface;
PFNEGLGETCURRENTCONTEXTPROC RGFW_eglGetCurrentContext;
-PFNEGLGETPROCADDRESSPROC RGFW_eglGetProcAddress = NULL;
+PFNEGLGETCURRENTSURFACEPROC RGFW_eglGetCurrentSurface;
PFNEGLQUERYSTRINGPROC RGFW_eglQueryString;
PFNEGLGETCONFIGATTRIBPROC RGFW_eglGetConfigAttrib;
#define EGL_SURFACE_MAJOR_VERSION_KHR 0x3098
#define EGL_SURFACE_MINOR_VERSION_KHR 0x30fb
-#ifdef RGFW_WINDOWS
- #include <windows.h>
-#elif defined(RGFW_MACOS) || defined(RGFW_UNIX)
- #include <dlfcn.h>
-#endif
-
#ifdef RGFW_WAYLAND
#include <wayland-egl.h>
#endif
-void* RGFW_eglLibHandle = NULL;
-
void* RGFW_getDisplay_EGL(void) { return _RGFW->EGL_display; }
void* RGFW_eglContext_getSourceContext(RGFW_eglContext* ctx) { return ctx->ctx; }
void* RGFW_eglContext_getSurface(RGFW_eglContext* ctx) { return ctx->surface; }
struct wl_egl_window* RGFW_eglContext_wlEGLWindow(RGFW_eglContext* ctx) { return ctx->eglWindow; }
RGFW_bool RGFW_loadEGL(void) {
- RGFW_init();
- if (RGFW_eglGetProcAddress != NULL) {
+ RGFW_ASSERT(_RGFW && "An RGFW context must be initialized using RGFW_init) and/or set with RGFW_setInfo");
+ if (_RGFW->eglGetProcAddress != NULL) {
return RGFW_TRUE;
}
@@ -5066,7 +5659,7 @@ RGFW_bool RGFW_loadEGL(void) {
#ifdef RGFW_WINDOWS
const char* libNames[] = { "libEGL.dll", "EGL.dll" };
#elif defined(RGFW_MACOS) || defined(RGFW_UNIX)
- /* Linux and macOS */
+ /* unix (including macOS) */
const char* libNames[] = {
"libEGL.so.1", /* most common */
"libEGL.so", /* fallback */
@@ -5076,44 +5669,45 @@ RGFW_bool RGFW_loadEGL(void) {
for (size_t i = 0; i < sizeof(libNames) / sizeof(libNames[0]); i++) {
#ifdef RGFW_WINDOWS
- RGFW_eglLibHandle = (void*)LoadLibraryA(libNames[i]);
- if (RGFW_eglLibHandle) {
- RGFW_eglGetProcAddress = (PFNEGLGETPROCADDRESSPROC)(RGFW_proc)GetProcAddress((HMODULE)RGFW_eglLibHandle, "eglGetProcAddress");
+ _RGFW->EGL_handle = (void*)LoadLibraryA(libNames[i]);
+ if (_RGFW->EGL_handle) {
+ _RGFW->eglGetProcAddress = (PFNEGLGETPROCADDRESSPROC)(RGFW_proc)GetProcAddress((HMODULE)_RGFW->EGL_handle, "eglGetProcAddress");
break;
}
#elif defined(RGFW_MACOS) || defined(RGFW_UNIX)
- RGFW_eglLibHandle = dlopen(libNames[i], RTLD_LAZY | RTLD_GLOBAL);
- if (RGFW_eglLibHandle) {
- void* lib = dlsym(RGFW_eglLibHandle, "eglGetProcAddress");
- if (lib != NULL) RGFW_MEMCPY(&RGFW_eglGetProcAddress, &lib, sizeof(PFNEGLGETPROCADDRESSPROC));
+ _RGFW->EGL_handle = dlopen(libNames[i], RTLD_LAZY | RTLD_GLOBAL);
+ if (_RGFW->EGL_handle) {
+ void* lib = dlsym(_RGFW->EGL_handle, "eglGetProcAddress");
+ if (lib != NULL) RGFW_MEMCPY(&_RGFW->eglGetProcAddress, &lib, sizeof(PFNEGLGETPROCADDRESSPROC));
break;
}
#endif
}
- if (!RGFW_eglLibHandle || !RGFW_eglGetProcAddress) {
+ if (!_RGFW->EGL_handle || !_RGFW->eglGetProcAddress) {
return RGFW_FALSE;
}
- RGFW_eglInitialize = (PFNEGLINITIALIZEPROC) RGFW_eglGetProcAddress("eglInitialize");
- RGFW_eglGetConfigs = (PFNEGLGETCONFIGSPROC) RGFW_eglGetProcAddress("eglGetConfigs");
- RGFW_eglChooseConfig = (PFNEGLCHOOSECONFIGPROC) RGFW_eglGetProcAddress("eglChooseConfig");
- RGFW_eglCreateWindowSurface = (PFNEGLCREATEWINDOWSURFACEPROC) RGFW_eglGetProcAddress("eglCreateWindowSurface");
- RGFW_eglCreateContext = (PFNEGLCREATECONTEXTPROC) RGFW_eglGetProcAddress("eglCreateContext");
- RGFW_eglMakeCurrent = (PFNEGLMAKECURRENTPROC) RGFW_eglGetProcAddress("eglMakeCurrent");
- RGFW_eglGetDisplay = (PFNEGLGETDISPLAYPROC) RGFW_eglGetProcAddress("eglGetDisplay");
- RGFW_eglSwapBuffers = (PFNEGLSWAPBUFFERSPROC) RGFW_eglGetProcAddress("eglSwapBuffers");
- RGFW_eglSwapInterval = (PFNEGLSWAPINTERVALPROC) RGFW_eglGetProcAddress("eglSwapInterval");
- RGFW_eglBindAPI = (PFNEGLBINDAPIPROC) RGFW_eglGetProcAddress("eglBindAPI");
- RGFW_eglDestroyContext = (PFNEGLDESTROYCONTEXTPROC) RGFW_eglGetProcAddress("eglDestroyContext");
- RGFW_eglTerminate = (PFNEGLTERMINATEPROC) RGFW_eglGetProcAddress("eglTerminate");
- RGFW_eglDestroySurface = (PFNEGLDESTROYSURFACEPROC) RGFW_eglGetProcAddress("eglDestroySurface");
- RGFW_eglQueryString = (PFNEGLQUERYSTRINGPROC) RGFW_eglGetProcAddress("eglQueryString");
- RGFW_eglGetCurrentContext = (PFNEGLGETCURRENTCONTEXTPROC) RGFW_eglGetProcAddress("eglGetCurrentContext");
- RGFW_eglGetConfigAttrib = (PFNEGLGETCONFIGATTRIBPROC) RGFW_eglGetProcAddress("eglGetConfigAttrib");
+ RGFW_eglInitialize = (PFNEGLINITIALIZEPROC) _RGFW->eglGetProcAddress("eglInitialize");
+ RGFW_eglGetConfigs = (PFNEGLGETCONFIGSPROC) _RGFW->eglGetProcAddress("eglGetConfigs");
+ RGFW_eglChooseConfig = (PFNEGLCHOOSECONFIGPROC) _RGFW->eglGetProcAddress("eglChooseConfig");
+ RGFW_eglCreateWindowSurface = (PFNEGLCREATEWINDOWSURFACEPROC) _RGFW->eglGetProcAddress("eglCreateWindowSurface");
+ RGFW_eglCreateContext = (PFNEGLCREATECONTEXTPROC) _RGFW->eglGetProcAddress("eglCreateContext");
+ RGFW_eglMakeCurrent = (PFNEGLMAKECURRENTPROC) _RGFW->eglGetProcAddress("eglMakeCurrent");
+ RGFW_eglGetDisplay = (PFNEGLGETDISPLAYPROC) _RGFW->eglGetProcAddress("eglGetDisplay");
+ RGFW_eglSwapBuffers = (PFNEGLSWAPBUFFERSPROC) _RGFW->eglGetProcAddress("eglSwapBuffers");
+ RGFW_eglSwapInterval = (PFNEGLSWAPINTERVALPROC) _RGFW->eglGetProcAddress("eglSwapInterval");
+ RGFW_eglBindAPI = (PFNEGLBINDAPIPROC) _RGFW->eglGetProcAddress("eglBindAPI");
+ RGFW_eglDestroyContext = (PFNEGLDESTROYCONTEXTPROC) _RGFW->eglGetProcAddress("eglDestroyContext");
+ RGFW_eglTerminate = (PFNEGLTERMINATEPROC) _RGFW->eglGetProcAddress("eglTerminate");
+ RGFW_eglDestroySurface = (PFNEGLDESTROYSURFACEPROC) _RGFW->eglGetProcAddress("eglDestroySurface");
+ RGFW_eglQueryString = (PFNEGLQUERYSTRINGPROC) _RGFW->eglGetProcAddress("eglQueryString");
+ RGFW_eglGetCurrentContext = (PFNEGLGETCURRENTCONTEXTPROC) _RGFW->eglGetProcAddress("eglGetCurrentContext");
+ RGFW_eglGetCurrentSurface = (PFNEGLGETCURRENTSURFACEPROC) _RGFW->eglGetProcAddress("eglGetCurrentSurface");
+ RGFW_eglGetConfigAttrib = (PFNEGLGETCONFIGATTRIBPROC) _RGFW->eglGetProcAddress("eglGetConfigAttrib");
#else
- RGFW_eglGetProcAddress = eglGetProcAddress;
+ _RGFW->eglGetProcAddress = eglGetProcAddress;
RGFW_eglInitialize = (PFNEGLINITIALIZEPROC) eglInitialize;
RGFW_eglGetConfigs = (PFNEGLGETCONFIGSPROC) eglGetConfigs;
RGFW_eglChooseConfig = (PFNEGLCHOOSECONFIGPROC) eglChooseConfig;
@@ -5129,6 +5723,7 @@ RGFW_bool RGFW_loadEGL(void) {
RGFW_eglDestroySurface = (PFNEGLDESTROYSURFACEPROC) eglDestroySurface;
RGFW_eglQueryString = (PFNEGLQUERYSTRINGPROC) eglQueryString;
RGFW_eglGetCurrentContext = (PFNEGLGETCURRENTCONTEXTPROC) eglGetCurrentContext;
+ RGFW_eglGetCurrentSurface = (PFNEGLGETCURRENTSURFACEPROC) eglGetCurrentSurface;
RGFW_eglGetConfigAttrib = (PFNEGLGETCONFIGATTRIBPROC)eglGetConfigAttrib;
#endif
@@ -5147,6 +5742,7 @@ RGFW_bool RGFW_loadEGL(void) {
RGFW_eglDestroySurface!= NULL &&
RGFW_eglQueryString != NULL &&
RGFW_eglGetCurrentContext != NULL &&
+ RGFW_eglGetCurrentSurface != NULL &&
RGFW_eglGetConfigAttrib != NULL);
if (out) {
@@ -5155,7 +5751,7 @@ RGFW_bool RGFW_loadEGL(void) {
_RGFW->EGL_display = RGFW_eglGetDisplay((EGLNativeDisplayType) dc);
ReleaseDC(NULL, dc);
#elif defined(RGFW_WAYLAND)
- if (_RGFW->useWaylandBool)
+ if (RGFW_usingWayland() == RGFW_TRUE)
_RGFW->EGL_display = RGFW_eglGetDisplay((EGLNativeDisplayType) _RGFW->wl_display);
else
#endif
@@ -5175,28 +5771,19 @@ RGFW_bool RGFW_loadEGL(void) {
void RGFW_unloadEGL(void) {
- if (!RGFW_eglLibHandle) return;
+ if (!_RGFW->EGL_handle) return;
RGFW_eglTerminate(_RGFW->EGL_display);
#ifdef RGFW_WINDOWS
- FreeLibrary((HMODULE)RGFW_eglLibHandle);
+ FreeLibrary((HMODULE)_RGFW->EGL_handle);
#elif defined(RGFW_MACOS) || defined(RGFW_UNIX)
- dlclose(RGFW_eglLibHandle);
+ dlclose(_RGFW->EGL_handle);
#endif
- RGFW_eglLibHandle = NULL;
- RGFW_eglGetProcAddress = NULL;
+ _RGFW->EGL_handle = NULL;
+ _RGFW->eglGetProcAddress = NULL;
}
-RGFW_bool RGFW_window_createContextPtr_EGL(RGFW_window* win, RGFW_eglContext* ctx, RGFW_glHints* hints) {
- if (RGFW_loadEGL() == RGFW_FALSE) return RGFW_FALSE;
- win->src.ctx.egl = ctx;
- win->src.gfxType = RGFW_gfxEGL;
-
-#ifdef RGFW_WAYLAND
- if (_RGFW->useWaylandBool)
- win->src.ctx.egl->eglWindow = wl_egl_window_create(win->src.surface, win->w, win->h);
-#endif
-
+RGFW_bool RGFW_createContextPtr_EGL(RGFW_eglContext* ctx, RGFW_glHints* hints) {
#ifndef EGL_OPENGL_ES1_BIT
#define EGL_OPENGL_ES1_BIT 0x1
#endif
@@ -5243,8 +5830,13 @@ RGFW_bool RGFW_window_createContextPtr_EGL(RGFW_window* win, RGFW_eglContext* ct
RGFW_eglChooseConfig(_RGFW->EGL_display, egl_config, configs, numConfigs, &numConfigs);
+ if (hints->profile == RGFW_glES)
+ RGFW_eglBindAPI(EGL_OPENGL_ES_API);
+ else
+ RGFW_eglBindAPI(EGL_OPENGL_API);
+
#ifdef RGFW_X11
- RGFW_bool transparent = (win->internal.flags & RGFW_windowTransparent);
+ RGFW_bool transparent = (hints->depth == 32);
EGLint best_depth = 0;
#endif
@@ -5258,7 +5850,7 @@ RGFW_bool RGFW_window_createContextPtr_EGL(RGFW_window* win, RGFW_eglContext* ct
if (best_config == -1) best_config = i;
#ifdef RGFW_X11
- if (_RGFW->useWaylandBool == RGFW_FALSE) {
+ if (RGFW_usingWayland() == RGFW_FALSE) {
XVisualInfo vinfo_template;
vinfo_template.visualid = (VisualID)visual_id;
@@ -5287,15 +5879,101 @@ RGFW_bool RGFW_window_createContextPtr_EGL(RGFW_window* win, RGFW_eglContext* ct
}
EGLConfig config = configs[best_config];
+ ctx->config = config;
+
RGFW_FREE(configs);
+
+ EGLint attribs[20];
+ {
+ RGFW_attribStack stack;
+ RGFW_attribStack_init(&stack, attribs, 20);
+
+ if (hints->major || hints->minor) {
+ RGFW_attribStack_pushAttribs(&stack, EGL_CONTEXT_MAJOR_VERSION, hints->major);
+ RGFW_attribStack_pushAttribs(&stack, EGL_CONTEXT_MINOR_VERSION, hints->minor);
+ }
+
+ if (hints->profile == RGFW_glCore) {
+ RGFW_attribStack_pushAttribs(&stack, EGL_CONTEXT_OPENGL_PROFILE_MASK, EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT);
+ } else if (hints->profile == RGFW_glCompatibility) {
+ RGFW_attribStack_pushAttribs(&stack, EGL_CONTEXT_OPENGL_PROFILE_MASK, EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT);
+ } else if (hints->profile == RGFW_glForwardCompatibility) {
+ RGFW_attribStack_pushAttribs(&stack, EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE, EGL_TRUE);
+ }
+
+
+ RGFW_attribStack_pushAttribs(&stack, EGL_CONTEXT_OPENGL_ROBUST_ACCESS, hints->robustness);
+ RGFW_attribStack_pushAttribs(&stack, EGL_CONTEXT_OPENGL_DEBUG, hints->debug);
+
+ #ifndef EGL_CONTEXT_RELEASE_BEHAVIOR_KHR
+ #define EGL_CONTEXT_RELEASE_BEHAVIOR_KHR 0x2097
+ #endif
+
+ #ifndef EGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_KHR
+ #define EGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_KHR 0x2098
+ #endif
+
+ if (hints->releaseBehavior == RGFW_glReleaseFlush) {
+ RGFW_attribStack_pushAttribs(&stack, EGL_CONTEXT_RELEASE_BEHAVIOR_KHR, EGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_KHR);
+ } else {
+ RGFW_attribStack_pushAttribs(&stack, EGL_CONTEXT_RELEASE_BEHAVIOR_KHR, 0x0000);
+ }
+
+ RGFW_attribStack_pushAttribs(&stack, EGL_NONE, EGL_NONE);
+ }
+
+ ctx->ctx = RGFW_eglCreateContext(_RGFW->EGL_display, config, hints->shareEGL, attribs);
+ if (ctx->ctx == NULL) {
+ RGFW_attribStack stack;
+ RGFW_attribStack_init(&stack, attribs, 20);
+ RGFW_attribStack_pushAttribs(&stack, EGL_CONTEXT_CLIENT_VERSION, hints->major);
+ RGFW_attribStack_pushAttribs(&stack, EGL_NONE, EGL_NONE);
+ ctx->ctx = RGFW_eglCreateContext(_RGFW->EGL_display, config, hints->shareEGL, attribs);
+ }
+
+ if (ctx->ctx == NULL) {
+ RGFW_debugCallback(RGFW_typeError, RGFW_errEGLContext, "Failed to create an EGL context.");
+ return RGFW_FALSE;
+ }
+
+ RGFW_debugCallback(RGFW_typeInfo, RGFW_infoOpenGL, "EGL context initalized.");
+ return RGFW_TRUE;
+}
+
+RGFW_bool RGFW_window_setContext_EGL(RGFW_window* win, RGFW_eglContext* ctx) {
+ RGFW_ASSERT(win);
+ if (ctx == NULL && win->src.ctx.egl != NULL) {
+ #ifdef RGFW_WAYLAND
+ if (RGFW_usingWayland() == RGFW_TRUE) {
+ wl_egl_window_destroy(win->src.ctx.egl->eglWindow);
+ }
+ #endif
+
+ win->src.ctx.egl = NULL;
+ RGFW_debugCallback(RGFW_typeInfo, RGFW_infoOpenGL, "EGL window surface freed");
+ return RGFW_TRUE;
+ }
+
+ win->src.ctx.egl = ctx;
+ win->src.gfxType = RGFW_gfxEGL;
+
+#ifdef RGFW_WAYLAND
+ if (RGFW_usingWayland() == RGFW_TRUE)
+ win->src.ctx.egl->eglWindow = wl_egl_window_create(win->src.surface, win->w, win->h);
+#endif
+
+ #ifndef EGL_OPENGL_ES1_BIT
+ #define EGL_OPENGL_ES1_BIT 0x1
+ #endif
+
#ifdef RGFW_X11
- if (_RGFW->useWaylandBool == RGFW_FALSE) {
+ if (RGFW_usingWayland() == RGFW_FALSE) {
/* This is required so that way the user can create their own OpenGL context after RGFW_createWindow is used */
XVisualInfo* result;
XVisualInfo desired;
EGLint visualID = 0, count = 0;
- RGFW_eglGetConfigAttrib(_RGFW->EGL_display, config, EGL_NATIVE_VISUAL_ID, &visualID);
+ RGFW_eglGetConfigAttrib(_RGFW->EGL_display, ctx->config, EGL_NATIVE_VISUAL_ID, &visualID);
if (visualID) {
desired.visualid = (VisualID)visualID;
result = XGetVisualInfo(_RGFW->display, VisualIDMask, &desired, &count);
@@ -5310,12 +5988,18 @@ RGFW_bool RGFW_window_createContextPtr_EGL(RGFW_window* win, RGFW_eglContext* ct
RGFW_debugCallback(RGFW_typeError, RGFW_errEGLContext, "Failed to find a valid visual for the EGL config");
} else {
RGFW_bool showWindow = RGFW_FALSE;
+ char* name = NULL;
if (win->src.window) {
showWindow = (RGFW_window_isMinimized(win) == RGFW_FALSE);
+ name = RGFW_XGetWindowName(win->src.window);
RGFW_window_closePlatform(win);
}
- RGFW_XCreateWindow(*result, "", win->internal.flags, win);
+ if (RGFW_XCreateWindow(*result, name ? name : "", win->internal.flags, win) == RGFW_FALSE) {
+ return RGFW_FALSE;
+ }
+
+ if (name != NULL) XFree(name);
if (showWindow) {
RGFW_window_show(win);
@@ -5325,6 +6009,8 @@ RGFW_bool RGFW_window_createContextPtr_EGL(RGFW_window* win, RGFW_eglContext* ct
}
#endif
+ RGFW_glHints* hints = RGFW_getGlobalHints_OpenGL();
+
EGLint surf_attribs[9];
{
@@ -5366,81 +6052,38 @@ RGFW_bool RGFW_window_createContextPtr_EGL(RGFW_window* win, RGFW_eglContext* ct
RGFW_window_setLayer_OSX(win, layer);
- win->src.ctx.egl->surface = RGFW_eglCreateWindowSurface(_RGFW->EGL_display, config, (EGLNativeWindowType) layer, surf_attribs);
+ win->src.ctx.egl->surface = RGFW_eglCreateWindowSurface(_RGFW->EGL_display, (EGLConfig)ctx->config, (EGLNativeWindowType) layer, surf_attribs);
#elif defined(RGFW_WINDOWS)
- win->src.ctx.egl->surface = RGFW_eglCreateWindowSurface(_RGFW->EGL_display, config, (EGLNativeWindowType) win->src.window, surf_attribs);
+ win->src.ctx.egl->surface = RGFW_eglCreateWindowSurface(_RGFW->EGL_display, (EGLConfig)ctx->config, (EGLNativeWindowType) win->src.window, surf_attribs);
#elif defined(RGFW_WAYLAND)
- if (_RGFW->useWaylandBool)
- win->src.ctx.egl->surface = RGFW_eglCreateWindowSurface(_RGFW->EGL_display, config, (EGLNativeWindowType) win->src.ctx.egl->eglWindow, surf_attribs);
+ if (RGFW_usingWayland() == RGFW_TRUE)
+ win->src.ctx.egl->surface = RGFW_eglCreateWindowSurface(_RGFW->EGL_display, (EGLConfig)ctx->config, (EGLNativeWindowType) win->src.ctx.egl->eglWindow, surf_attribs);
else
#endif
#ifdef RGFW_X11
- win->src.ctx.egl->surface = RGFW_eglCreateWindowSurface(_RGFW->EGL_display, config, (EGLNativeWindowType) win->src.window, surf_attribs);
+ win->src.ctx.egl->surface = RGFW_eglCreateWindowSurface(_RGFW->EGL_display, (EGLConfig)ctx->config, (EGLNativeWindowType) win->src.window, surf_attribs);
#else
{}
#endif
#ifdef RGFW_WASM
- win->src.ctx.egl->surface = eglCreateWindowSurface(_RGFW->EGL_display, config, 0, 0);
+ win->src.ctx.egl->surface = eglCreateWindowSurface(_RGFW->EGL_display, (EGLConfig)ctx->config, 0, 0);
#endif
- if (win->src.ctx.egl->surface == NULL) {
+ if (win->src.ctx.egl->surface == EGL_NO_SURFACE) {
RGFW_debugCallback(RGFW_typeError, RGFW_errEGLContext, "Failed to create an EGL surface.");
return RGFW_FALSE;
}
- EGLint attribs[20];
- {
- RGFW_attribStack stack;
- RGFW_attribStack_init(&stack, attribs, 20);
-
- if (hints->major || hints->minor) {
- RGFW_attribStack_pushAttribs(&stack, EGL_CONTEXT_MAJOR_VERSION, hints->major);
- RGFW_attribStack_pushAttribs(&stack, EGL_CONTEXT_MINOR_VERSION, hints->minor);
- }
-
- if (hints->profile == RGFW_glCore) {
- RGFW_attribStack_pushAttribs(&stack, EGL_CONTEXT_OPENGL_PROFILE_MASK, EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT);
- } else if (hints->profile == RGFW_glCompatibility) {
- RGFW_attribStack_pushAttribs(&stack, EGL_CONTEXT_OPENGL_PROFILE_MASK, EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT);
- } else if (hints->profile == RGFW_glForwardCompatibility) {
- RGFW_attribStack_pushAttribs(&stack, EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE, EGL_TRUE);
- }
-
-
- RGFW_attribStack_pushAttribs(&stack, EGL_CONTEXT_OPENGL_ROBUST_ACCESS, hints->robustness);
- RGFW_attribStack_pushAttribs(&stack, EGL_CONTEXT_OPENGL_DEBUG, hints->debug);
-
- #ifndef EGL_CONTEXT_RELEASE_BEHAVIOR_KHR
- #define EGL_CONTEXT_RELEASE_BEHAVIOR_KHR 0x2097
- #endif
-
- #ifndef EGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_KHR
- #define EGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_KHR 0x2098
- #endif
-
- if (hints->releaseBehavior == RGFW_glReleaseFlush) {
- RGFW_attribStack_pushAttribs(&stack, EGL_CONTEXT_RELEASE_BEHAVIOR_KHR, EGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_KHR);
- } else {
- RGFW_attribStack_pushAttribs(&stack, EGL_CONTEXT_RELEASE_BEHAVIOR_KHR, 0x0000);
- }
-
- RGFW_attribStack_pushAttribs(&stack, EGL_NONE, EGL_NONE);
- }
-
- if (hints->profile == RGFW_glES)
- RGFW_eglBindAPI(EGL_OPENGL_ES_API);
- else
- RGFW_eglBindAPI(EGL_OPENGL_API);
+ RGFW_eglMakeCurrent(_RGFW->EGL_display, win->src.ctx.egl->surface, win->src.ctx.egl->surface, win->src.ctx.egl->ctx);
+ RGFW_eglSwapBuffers(_RGFW->EGL_display, win->src.ctx.egl->surface);
- win->src.ctx.egl->ctx = RGFW_eglCreateContext(_RGFW->EGL_display, config, hints->shareEGL, attribs);
+ RGFW_window_swapInterval_EGL(win, 0);
- if (win->src.ctx.egl->ctx == NULL) {
- RGFW_debugCallback(RGFW_typeError, RGFW_errEGLContext, "Failed to create an EGL context.");
- return RGFW_FALSE;
- }
+#ifdef RGFW_MACOS
+ /*NOTE: another OpenGL/setFlags related hack, this because OSX the 'view' class must be setup after the NSOpenGL view is made AND after setFlags happens */
+ RGFW_osx_initView(win);
+#endif
- RGFW_eglMakeCurrent(_RGFW->EGL_display, win->src.ctx.egl->surface, win->src.ctx.egl->surface, win->src.ctx.egl->ctx);
- RGFW_eglSwapBuffers(_RGFW->EGL_display, win->src.ctx.egl->surface);
RGFW_debugCallback(RGFW_typeInfo, RGFW_infoOpenGL, "EGL context initalized.");
return RGFW_TRUE;
}
@@ -5450,18 +6093,12 @@ RGFW_eglContext* RGFW_window_getContext_EGL(RGFW_window* win) {
return win->src.ctx.egl;
}
-void RGFW_window_deleteContextPtr_EGL(RGFW_window* win, RGFW_eglContext* ctx) {
+void RGFW_deleteContextPtr_EGL(RGFW_eglContext* ctx) {
if (_RGFW->EGL_display == NULL) return;
RGFW_eglDestroySurface(_RGFW->EGL_display, ctx->surface);
RGFW_eglDestroyContext(_RGFW->EGL_display, ctx->ctx);
RGFW_debugCallback(RGFW_typeInfo, RGFW_infoOpenGL, "EGL context freed");
- #ifdef RGFW_WAYLAND
- if (_RGFW->useWaylandBool == RGFW_FALSE) return;
- wl_egl_window_destroy(win->src.ctx.egl->eglWindow);
- RGFW_debugCallback(RGFW_typeInfo, RGFW_infoOpenGL, "EGL window context freed");
- #endif
- win->src.ctx.egl = NULL;
}
void RGFW_window_makeCurrentContext_EGL(RGFW_window* win) { if (win) RGFW_ASSERT(win->src.ctx.egl);
@@ -5475,37 +6112,52 @@ void RGFW_window_makeCurrentContext_EGL(RGFW_window* win) { if (win) RGFW_ASSERT
void RGFW_window_swapBuffers_EGL(RGFW_window* win) {
if (RGFW_eglSwapBuffers)
RGFW_eglSwapBuffers(_RGFW->EGL_display, win->src.ctx.egl->surface);
+ #ifdef RGFW_OPENGL
else RGFW_window_swapBuffers_OpenGL(win);
+ #endif
}
void* RGFW_getCurrentContext_EGL(void) {
return RGFW_eglGetCurrentContext();
}
+void* RGFW_getCurrentSurface_EGL(void) {
+ return RGFW_eglGetCurrentSurface(EGL_DRAW);
+}
+
RGFW_proc RGFW_getProcAddress_EGL(const char* procname) {
#if defined(RGFW_WINDOWS)
- RGFW_proc proc = (RGFW_proc) GetProcAddress(RGFW_wgl_dll, procname);
+ RGFW_proc proc = (RGFW_proc) GetProcAddress(_RGFW->nativeGL_handle, procname);
if (proc)
return proc;
#endif
- return (RGFW_proc) RGFW_eglGetProcAddress(procname);
+ return (RGFW_proc) _RGFW->eglGetProcAddress(procname);
}
RGFW_bool RGFW_extensionSupportedPlatform_EGL(const char* extension, size_t len) {
- if (RGFW_loadEGL() == RGFW_FALSE) return RGFW_FALSE;
const char* extensions = RGFW_eglQueryString(_RGFW->EGL_display, EGL_EXTENSIONS);
return extensions != NULL && RGFW_extensionSupportedStr(extensions, extension, len);
}
void RGFW_window_swapInterval_EGL(RGFW_window* win, i32 swapInterval) {
RGFW_ASSERT(win != NULL);
+
+ void* ctx = RGFW_eglGetCurrentContext();
+ void* surface = RGFW_eglGetCurrentSurface(EGL_DRAW);
+ if (ctx == win->src.ctx.egl->ctx && surface == win->src.ctx.egl->surface) {
+ RGFW_eglSwapInterval(_RGFW->EGL_display, swapInterval);
+ return;
+ }
+
+ RGFW_eglMakeCurrent(_RGFW->EGL_display, win->src.ctx.egl->surface, win->src.ctx.egl->surface, win->src.ctx.egl->ctx);
RGFW_eglSwapInterval(_RGFW->EGL_display, swapInterval);
+ RGFW_eglMakeCurrent(_RGFW->EGL_display, surface, surface, ctx);
}
RGFW_bool RGFW_extensionSupported_EGL(const char* extension, size_t len) {
- if (RGFW_extensionSupported_base(extension, len)) return RGFW_TRUE;
+ if (RGFW_extensionSupported_base(extension, len, RGFW_getProcAddress_EGL)) return RGFW_TRUE;
return RGFW_extensionSupportedPlatform_EGL(extension, len);
}
@@ -5516,20 +6168,30 @@ void RGFW_window_makeCurrentWindow_EGL(RGFW_window* win) {
RGFW_window* RGFW_getCurrentWindow_EGL(void) { return _RGFW->current; }
-RGFW_eglContext* RGFW_window_createContext_EGL(RGFW_window* win, RGFW_glHints* hints) {
+RGFW_eglContext* RGFW_createContext_EGL(RGFW_glHints* hints) {
RGFW_eglContext* ctx = (RGFW_eglContext*)RGFW_ALLOC(sizeof(RGFW_eglContext));
- if (RGFW_window_createContextPtr_EGL(win, ctx, hints) == RGFW_FALSE) {
+ if (RGFW_createContextPtr_EGL(ctx, hints) == RGFW_FALSE) {
RGFW_FREE(ctx);
- win->src.ctx.egl = NULL;
return NULL;
}
- win->src.gfxType |= RGFW_gfxOwnedByRGFW;
return ctx;
}
-void RGFW_window_deleteContext_EGL(RGFW_window* win, RGFW_eglContext* ctx) {
- RGFW_window_deleteContextPtr_EGL(win, ctx);
- if (win->src.gfxType & RGFW_gfxOwnedByRGFW) RGFW_FREE(ctx);
+void RGFW_deleteContext_EGL(RGFW_eglContext* ctx) {
+ RGFW_deleteContextPtr_EGL(ctx);
+ RGFW_FREE(ctx);
+}
+
+RGFW_eglContext* RGFW_copyContext_EGL(RGFW_eglContext* ctx) {
+ RGFW_eglContext* newCtx = (RGFW_eglContext*)RGFW_ALLOC(sizeof(RGFW_eglContext));
+ RGFW_copyContextPtr_EGL(ctx, newCtx);
+ return newCtx;
+}
+
+RGFW_bool RGFW_copyContextPtr_EGL(RGFW_eglContext* ctx, RGFW_eglContext* newCtx) {
+ RGFW_ASSERT(ctx); RGFW_ASSERT(newCtx);
+ RGFW_MEMCPY(newCtx, ctx, sizeof(RGFW_eglContext));
+ return RGFW_TRUE;
}
#endif /* RGFW_EGL */
@@ -5537,7 +6199,8 @@ void RGFW_window_deleteContext_EGL(RGFW_window* win, RGFW_eglContext* ctx) {
/*
end of RGFW_EGL defines
*/
-#endif /* end of RGFW_GL (OpenGL, EGL, OSMesa )*/
+
+/* end of RGFW_GL (OpenGL, EGL, OSMesa )*/
/*
RGFW_VULKAN defines
@@ -5547,6 +6210,67 @@ void RGFW_window_deleteContext_EGL(RGFW_window* win, RGFW_eglContext* ctx) {
#include <objc/message.h>
#endif
+RGFW_bool RGFW_loadVulkan(void) {
+ if (_RGFW->vulkan_handle) return RGFW_TRUE;
+ const char* names[] = {
+ #ifdef RGFW_WINDOWS
+ "vulkan-1.dll",
+ #endif
+ #ifdef RGFW_MACOS
+ "libvulkan.1.dylib",
+ #endif
+ #ifdef RGFW_UNIX
+ "libvulkan.so.1",
+ "libvulkan.so"
+ #endif
+ };
+
+ for (size_t i = 0; i < sizeof(names) / sizeof(names[0]); i++) {
+ if (_RGFW->vulkan_handle) break;
+ #ifdef RGFW_WINDOWS
+ _RGFW->vulkan_handle = LoadLibraryA(names[i]);
+ #else
+ _RGFW->vulkan_handle = dlopen(names[i], RTLD_LAZY | RTLD_LOCAL);
+ #endif
+ }
+
+ if (!_RGFW->vulkan_handle) {
+ return RGFW_FALSE;
+ }
+
+ #ifdef RGFW_WINDOWS
+ _RGFW->vkGetInstanceProcAddress = (RGFW_proc(*)(void*, const char*))(RGFW_proc)GetProcAddress((HMODULE)_RGFW->vulkan_handle, "vkGetInstanceProcAddr");
+ #else
+ void* lib = dlsym(_RGFW->vulkan_handle, "vkGetInstanceProcAddr");
+ if (lib != NULL) RGFW_MEMCPY(&_RGFW->vkGetInstanceProcAddress, &lib, sizeof(_RGFW->vkGetInstanceProcAddress));
+ #endif
+
+ if (_RGFW->vkGetInstanceProcAddress == NULL) {
+ return RGFW_FALSE;
+ }
+
+
+ return RGFW_TRUE;
+}
+
+#define RGFW_LOAD_VK(func) if (_RGFW->func == NULL) _RGFW->func = (RGFW_##func##Proc)RGFW_getInstanceProcAddress_Vulkan(instance, #func); RGFW_ASSERT(_RGFW->func);
+
+void RGFW_unloadVulkan(void) {
+ if (!_RGFW->vulkan_handle) return;
+ #ifdef RGFW_WINDOWS
+ FreeLibrary((HMODULE)_RGFW->vulkan_handle);
+ #elif defined(RGFW_UNIX)
+ dlclose(_RGFW->vulkan_handle);
+ #endif /* OSX doesn't need it's handle freed */
+
+ _RGFW->vulkan_handle = NULL;
+}
+
+RGFW_proc RGFW_getInstanceProcAddress_Vulkan(VkInstance instance, const char* procname) {
+ RGFW_ASSERT(_RGFW->vkGetInstanceProcAddress);
+ return _RGFW->vkGetInstanceProcAddress(instance, procname);
+}
+
const char** RGFW_getRequiredInstanceExtensions_Vulkan(size_t* count) {
static const char* arr[2] = {VK_KHR_SURFACE_EXTENSION_NAME};
arr[1] = RGFW_VK_SURFACE;
@@ -5559,40 +6283,41 @@ const char** RGFW_getRequiredInstanceExtensions_Vulkan(size_t* count) {
VkResult RGFW_window_createSurface_Vulkan(RGFW_window* win, VkInstance instance, VkSurfaceKHR* surface) {
RGFW_ASSERT(win != NULL); RGFW_ASSERT(instance);
RGFW_ASSERT(surface != NULL);
-
*surface = VK_NULL_HANDLE;
#ifdef RGFW_X11
-
+ RGFW_LOAD_VK(vkCreateXlibSurfaceKHR);
VkXlibSurfaceCreateInfoKHR x11 = { VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR, 0, 0, (Display*) _RGFW->display, (Window) win->src.window };
- return vkCreateXlibSurfaceKHR(instance, &x11, NULL, surface);
+ return _RGFW->vkCreateXlibSurfaceKHR(instance, &x11, NULL, surface);
#endif
#if defined(RGFW_WAYLAND)
-
+ RGFW_LOAD_VK(vkCreateWaylandSurfaceKHR);
VkWaylandSurfaceCreateInfoKHR wayland = { VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR, 0, 0, (struct wl_display*) _RGFW->wl_display, (struct wl_surface*) win->src.surface };
- return vkCreateWaylandSurfaceKHR(instance, &wayland, NULL, surface);
+ return _RGFW->vkCreateWaylandSurfaceKHR(instance, &wayland, NULL, surface);
#elif defined(RGFW_WINDOWS)
- VkWin32SurfaceCreateInfoKHR win32 = { VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR, 0, 0, GetModuleHandle(NULL), (HWND)win->src.window };
-
- return vkCreateWin32SurfaceKHR(instance, &win32, NULL, surface);
+ RGFW_LOAD_VK(vkCreateWin32SurfaceKHR);
+ VkWin32SurfaceCreateInfoKHR win32 = { VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR, 0, 0, _RGFW->instance, (HWND)win->src.window };
+ return _RGFW->vkCreateWin32SurfaceKHR(instance, &win32, NULL, surface);
#endif
}
#endif
-RGFW_bool RGFW_getPresentationSupport_Vulkan(VkPhysicalDevice physicalDevice, u32 queueFamilyIndex) {
- if (_RGFW == NULL) RGFW_init();
-#ifdef RGFW_X11
+RGFW_bool RGFW_getPhysicalDevicePresentationSupport_Vulkan(VkInstance instance, VkPhysicalDevice physicalDevice, u32 queueFamilyIndex) {
+ RGFW_ASSERT(_RGFW && "An RGFW context must be initialized using RGFW_init and/or set with RGFW_setInfo");
+#ifdef RGFW_X11
+ RGFW_LOAD_VK(vkGetPhysicalDeviceXlibPresentationSupportKHR);
Visual* visual = DefaultVisual(_RGFW->display, DefaultScreen(_RGFW->display));
- RGFW_bool out = vkGetPhysicalDeviceXlibPresentationSupportKHR(physicalDevice, queueFamilyIndex, _RGFW->display, XVisualIDFromVisual(visual));
+ RGFW_bool out = _RGFW->vkGetPhysicalDeviceXlibPresentationSupportKHR(physicalDevice, queueFamilyIndex, _RGFW->display, XVisualIDFromVisual(visual));
return out;
#endif
#if defined(RGFW_WAYLAND)
-
- RGFW_bool wlout = vkGetPhysicalDeviceWaylandPresentationSupportKHR(physicalDevice, queueFamilyIndex, _RGFW->wl_display);
+ RGFW_LOAD_VK(vkGetPhysicalDeviceWaylandPresentationSupportKHR);
+ RGFW_bool wlout = _RGFW->vkGetPhysicalDeviceWaylandPresentationSupportKHR(physicalDevice, queueFamilyIndex, _RGFW->wl_display);
return wlout;
#elif defined(RGFW_WINDOWS)
- RGFW_bool out = vkGetPhysicalDeviceWin32PresentationSupportKHR(physicalDevice, queueFamilyIndex);
+ RGFW_LOAD_VK(vkGetPhysicalDeviceWin32PresentationSupportKHR);
+ RGFW_bool out = _RGFW->vkGetPhysicalDeviceWin32PresentationSupportKHR(physicalDevice, queueFamilyIndex);
return out;
#elif defined(RGFW_MACOS) && !defined(RGFW_MACOS_X11)
RGFW_UNUSED(physicalDevice);
@@ -5600,6 +6325,9 @@ RGFW_bool RGFW_getPresentationSupport_Vulkan(VkPhysicalDevice physicalDevice, u3
return RGFW_FALSE; /* TODO */
#endif
}
+
+
+#undef RGFW_LOAD_VK
#endif /* end of RGFW_vulkan */
/*
@@ -5609,9 +6337,11 @@ This is where OS specific stuff starts
/* start of unix (wayland or X11 (unix) ) defines */
#ifdef RGFW_UNIX
+
#include <fcntl.h>
#include <poll.h>
#include <unistd.h>
+#include <time.h>
void RGFW_stopCheckEvents(void) {
@@ -5624,11 +6354,21 @@ void RGFW_stopCheckEvents(void) {
}
}
-RGFWDEF u64 RGFW_linux_getTimeNS(void);
-u64 RGFW_linux_getTimeNS(void) {
- struct timespec ts;
+RGFWDEF u64 RGFW_unix_getTimeNS(void);
+u64 RGFW_unix_getTimeNS(void) {
+ struct timespec ts;
+ static i32 clock = -1;
+ if (clock == -1) {
+ #if defined(_POSIX_MONOTONIC_CLOCK)
+ if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0)
+ clock = CLOCK_MONOTONIC;
+ else
+ #endif
+ clock = CLOCK_REALTIME;
+ }
+
const u64 scale_factor = 1000000000;
- clock_gettime(_RGFW->clock, &ts);
+ clock_gettime(clock, &ts);
return (u64)ts.tv_sec * scale_factor + (u64)ts.tv_nsec;
}
@@ -5685,7 +6425,7 @@ void RGFW_waitForEvent(i32 waitMS) {
}
- u64 start = RGFW_linux_getTimeNS();
+ u64 start = RGFW_unix_getTimeNS();
if (RGFW_usingWayland()) {
#ifdef RGFW_WAYLAND
while (wl_display_dispatch_pending(_RGFW->wl_display) == 0) {
@@ -5698,7 +6438,7 @@ void RGFW_waitForEvent(i32 waitMS) {
}
if (waitMS != RGFW_eventWaitNext) {
- waitMS -= (i32)(RGFW_linux_getTimeNS() - start) / (i32)1e+6;
+ waitMS -= (i32)(RGFW_unix_getTimeNS() - start) / (i32)1e+6;
}
}
@@ -5714,7 +6454,7 @@ void RGFW_waitForEvent(i32 waitMS) {
break;
if (waitMS != RGFW_eventWaitNext) {
- waitMS -= (i32)(RGFW_linux_getTimeNS() - start) / (i32)1e+6;
+ waitMS -= (i32)(RGFW_unix_getTimeNS() - start) / (i32)1e+6;
}
}
#endif
@@ -5781,11 +6521,11 @@ char* RGFW_strtok(char* str, const char* delimStr) {
}
#ifdef RGFW_X11
-RGFWDEF i32 RGFW_initPlatform_X11(void);
+RGFWDEF i32 RGFW_initPlatform_X11(const char* className, RGFW_initFlags flags);
RGFWDEF void RGFW_deinitPlatform_X11(void);
#endif
#ifdef RGFW_WAYLAND
-RGFWDEF i32 RGFW_initPlatform_Wayland(void);
+RGFWDEF i32 RGFW_initPlatform_Wayland(const char* className, RGFW_initFlags flags);
RGFWDEF void RGFW_deinitPlatform_Wayland(void);
#endif
@@ -5922,34 +6662,30 @@ void RGFW_initKeycodesPlatform(void) {
_RGFW->keycodes[162] = RGFW_keyWorld2; /* non-US key #2 */
}
-i32 RGFW_initPlatform(void) {
- #if defined(_POSIX_MONOTONIC_CLOCK)
- struct timespec ts;
- RGFW_MEMZERO(&ts, sizeof(struct timespec));
-
- if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0)
- _RGFW->clock = CLOCK_MONOTONIC;
- #else
- _RGFW->clock = CLOCK_REALTIME;
- #endif
-
+i32 RGFW_initPlatform(const char* className, RGFW_initFlags flags) {
#ifdef RGFW_WAYLAND
- RGFW_load_Wayland();
- i32 ret = RGFW_initPlatform_Wayland();
- if (ret == 0) {
- return 0;
+ if (!(flags & RGFW_initX11)) {
+ _RGFW->useWaylandBool = RGFW_TRUE;
+ RGFW_load_Wayland();
+ i32 ret = RGFW_initPlatform_Wayland(className, flags);
+
+ if (ret == 0) {
+ return 0;
+ } else {
+ #ifdef RGFW_X11
+ RGFW_debugCallback(RGFW_typeWarning, RGFW_warningWayland, "Falling back to X11");
+ _RGFW->useWaylandBool = RGFW_FALSE;
+ #else
+ return ret;
+ #endif
+ }
} else {
- #ifdef RGFW_X11
- RGFW_debugCallback(RGFW_typeWarning, RGFW_warningWayland, "Falling back to X11");
- RGFW_useWayland(0);
- #else
- return ret;
- #endif
+ _RGFW->useWaylandBool = RGFW_FALSE;
}
#endif
#ifdef RGFW_X11
RGFW_load_X11();
- return RGFW_initPlatform_X11();
+ return RGFW_initPlatform_X11(className, flags);
#else
return 0;
#endif
@@ -5962,7 +6698,7 @@ void RGFW_deinitPlatform(void) {
close(_RGFW->eventWait_forceStop[1]);
}
#ifdef RGFW_WAYLAND
- if (_RGFW->useWaylandBool) {
+ if (RGFW_usingWayland()) {
RGFW_deinitPlatform_Wayland();
return;
}
@@ -6034,6 +6770,9 @@ void RGFW_unix_parseURI(RGFW_window* win, char* data) {
}
}
+#if !defined(RGFW_X11) && defined(RGFW_OPENGL)
+RGFW_bool RGFW_loadGL(void) { return RGFW_FALSE; }
+#endif
#endif /* end of wayland or X11 defines */
@@ -6041,7 +6780,7 @@ void RGFW_unix_parseURI(RGFW_window* win, char* data) {
/*
-Start of Linux / Unix defines
+Start of *nix defines
*/
@@ -6053,13 +6792,16 @@ Start of Linux / Unix defines
#define RGFW_FUNC(func) func
#endif
+#ifdef RGFW_X11_DEBUG
+ #define RGFW_X11_CRASH_ON_ERROR
+#endif
+
#include <dlfcn.h>
#include <unistd.h>
#include <limits.h> /* for data limits (mainly used in drag and drop functions) */
#include <poll.h>
-void RGFW_setXInstName(const char* name) { _RGFW->instName = name; }
#if !defined(RGFW_NO_X11_CURSOR) && defined(RGFW_X11)
#include <X11/Xcursor/Xcursor.h>
#endif
@@ -6110,7 +6852,106 @@ void RGFW_setXInstName(const char* name) { _RGFW->instName = name; }
#undef GLsizeiptr
#undef GLboolean
#endif
- typedef GLXContext(*glXCreateContextAttribsARBProc)(Display*, GLXFBConfig, GLXContext, Bool, const int*);
+ typedef GLXContext(*RGFW_glXCreateContextAttribsARBProc)(Display*, GLXFBConfig, GLXContext, Bool, const int*);
+ typedef const char* (*RGFW_glXQueryExtensionsStringProc)(Display* dpy, int screen);
+ typedef XVisualInfo* (*RGFW_glXChooseVisualProc)(Display*, int, int*);
+ typedef GLXContext (*RGFW_glXCreateContextProc)(Display*, XVisualInfo*, GLXContext, Bool);
+ typedef Bool (*RGFW_glXMakeCurrentProc)(Display*, GLXDrawable, GLXContext);
+ typedef GLXContext (*RGFW_glXGetCurrentContextProc)(void);
+ typedef GLXContext (*RGFW_glXGetCurrentDrawableProc)(void);
+ typedef void (*RGFW_glXSwapBuffersProc)(Display*, GLXDrawable);
+ typedef PFNGLXSWAPINTERVALEXTPROC RGFW_glXSwapIntervalEXTProc;
+ typedef __GLXextFuncPtr (*RGFW_glXGetProcAddressProc)(const u8*procname);
+ typedef PFNGLXGETVISUALFROMFBCONFIGPROC RGFW_glXGetVisualFromFBConfigProc;
+ typedef PFNGLXGETFBCONFIGATTRIBPROC RGFW_glXGetFBConfigAttribProc;
+ typedef __GLXextFuncPtr (*RGFW_glXGetProcAddressARBProc)(const u8*);
+ typedef PFNGLXCHOOSEFBCONFIGPROC RGFW_glXChooseFBConfigProc;
+ typedef void (*RGFW_glXDestroyContextProc)(Display *dpy, GLXContext ctx);
+ typedef GLXWindow (*RGFW_glXCreateWindowProc)(Display*,GLXFBConfig,Window,const int*);
+ typedef void (*RGFW_glXDestroyWindowProc)(Display*,GLXWindow);
+ typedef int (*RGFW_GLX_MESA_swap_controlProc) (int);
+ typedef int (*RGFW_GLX_SGI_swap_controlProc) (int);
+
+ RGFW_glXCreateContextAttribsARBProc RGFW_glXCreateContextAttribsARB;
+ RGFW_glXQueryExtensionsStringProc RGFW_glXQueryExtensionsString;
+ RGFW_glXChooseVisualProc RGFW_glXChooseVisual;
+ RGFW_glXCreateContextProc RGFW_glXCreateContext;
+ RGFW_glXMakeCurrentProc RGFW_glXMakeCurrent;
+ RGFW_glXGetCurrentContextProc RGFW_glXGetCurrentContext;
+ RGFW_glXGetCurrentDrawableProc RGFW_glXGetCurrentDrawable;
+ RGFW_glXSwapBuffersProc RGFW_glXSwapBuffers;
+ RGFW_glXSwapIntervalEXTProc RGFW_glXSwapIntervalEXT;
+ RGFW_glXGetVisualFromFBConfigProc RGFW_glXGetVisualFromFBConfig;
+ RGFW_glXGetFBConfigAttribProc RGFW_glXGetFBConfigAttrib;
+ RGFW_glXGetProcAddressARBProc RGFW_glXGetProcAddressARB;
+ RGFW_glXChooseFBConfigProc RGFW_glXChooseFBConfig;
+ RGFW_glXDestroyContextProc RGFW_glXDestroyContext;
+ RGFW_glXCreateWindowProc RGFW_glXCreateWindow;
+ RGFW_glXDestroyWindowProc RGFW_glXDestroyWindow;
+ RGFW_GLX_MESA_swap_controlProc RGFW_GLX_MESA_swap_control;
+ RGFW_GLX_SGI_swap_controlProc RGFW_GLX_SGI_swap_control;
+
+ RGFW_bool RGFW_loadGL(void) {
+ RGFW_ASSERT(_RGFW && "An RGFW context must be initialized using RGFW_init and/or set with RGFW_setInfo");
+ if (RGFW_usingWayland()) return RGFW_FALSE;
+ if (_RGFW->nativeGL_handle && _RGFW->glGetProcAddress != NULL) {
+ return RGFW_TRUE;
+ }
+
+ const char* glxSonames[] = {
+ #if defined(__CYGWIN__)
+ "libGL-1.so",
+ #elif defined(__OpenBSD__) || defined(__NetBSD__)
+ "libGL.so",
+ #else
+ "libGLX.so.0",
+ "libGL.so.1",
+ "libGL.so",
+ #endif
+ };
+
+ for (int i = 0; sizeof(glxSonames) / sizeof(char*); i++) {
+ _RGFW->nativeGL_handle = dlopen(glxSonames[i], RTLD_LAZY | RTLD_LOCAL);
+ if (_RGFW->nativeGL_handle)
+ break;
+ }
+
+ void* ptr = dlsym(_RGFW->nativeGL_handle, "glXGetProcAddress");
+ RGFW_ASSERT(ptr != NULL);
+ RGFW_MEMCPY(&_RGFW->glGetProcAddress, &ptr, sizeof(void*));
+ #define RGFW_PROC_DEF(name) if (RGFW_##name == NULL) RGFW_##name = (RGFW_##name##Proc)_RGFW->glGetProcAddress(#name);
+
+ RGFW_PROC_DEF(glXChooseVisual);
+ RGFW_PROC_DEF(glXCreateContext);
+ RGFW_PROC_DEF(glXMakeCurrent);
+ RGFW_PROC_DEF(glXGetCurrentContext);
+ RGFW_PROC_DEF(glXGetCurrentDrawable);
+ RGFW_PROC_DEF(glXSwapBuffers);
+ RGFW_PROC_DEF(glXGetVisualFromFBConfig);
+ RGFW_PROC_DEF(glXGetFBConfigAttrib);
+ RGFW_PROC_DEF(glXGetProcAddressARB);
+ RGFW_PROC_DEF(glXChooseFBConfig);
+ RGFW_PROC_DEF(glXDestroyContext);
+ RGFW_PROC_DEF(glXCreateWindow);
+ RGFW_PROC_DEF(glXDestroyWindow);
+ RGFW_PROC_DEF(glXQueryExtensionsString);
+ RGFW_PROC_DEF(glXCreateContextAttribsARB);
+ RGFW_PROC_DEF(glXGetProcAddressARB);
+ RGFW_PROC_DEF(GLX_SGI_swap_control);
+ RGFW_PROC_DEF(GLX_MESA_swap_control);
+ RGFW_PROC_DEF(glXSwapIntervalEXT);
+
+ if (RGFW_glXSwapIntervalEXT == NULL) {
+ if (RGFW_GLX_MESA_swap_control == NULL && RGFW_GLX_SGI_swap_control == NULL) {
+ RGFW_debugCallback(RGFW_typeWarning, RGFW_infoOpenGL, "Failed to load swap interval function");
+ } else {
+ RGFW_debugCallback(RGFW_typeWarning, RGFW_infoOpenGL, "Failed to load swap interval function, fallingback to the native swapinterval function");
+ }
+ }
+ #undef RGFW_PROC_DEF
+
+ return RGFW_TRUE;
+ }
#endif
/* atoms needed for drag and drop */
@@ -6304,31 +7145,32 @@ void RGFW_FUNC(RGFW_surface_freePtr) (RGFW_surface* surface) {
return;
}
-#define RGFW_LOAD_ATOM(name) \
- static Atom name = 0; \
- if (name == 0) name = XInternAtom(_RGFW->display, #name, False);
-
void RGFW_FUNC(RGFW_window_setBorder) (RGFW_window* win, RGFW_bool border) {
RGFW_setBit(&win->internal.flags, RGFW_windowNoBorder, !border);
- RGFW_LOAD_ATOM(_MOTIF_WM_HINTS);
struct __x11WindowHints {
- unsigned long flags, functions, decorations, status;
+ unsigned long flags, functions, decorations;
long input_mode;
+ unsigned long status;
} hints;
+ RGFW_MEMZERO(&hints, sizeof(hints));
hints.flags = 2;
- hints.decorations = border;
-
- XChangeProperty(_RGFW->display, win->src.window, _MOTIF_WM_HINTS, _MOTIF_WM_HINTS, 32, PropModeReplace, (u8*)&hints, 5);
-
- if (RGFW_window_isHidden(win) == 0) {
- RGFW_window_hide(win);
- RGFW_window_show(win);
- }
+ hints.decorations = border ? 1 : 0;
+ XChangeProperty(_RGFW->display, win->src.window, _RGFW->_MOTIF_WM_HINTS, _RGFW->_MOTIF_WM_HINTS, 32, PropModeReplace, (u8*)&hints, (sizeof(hints) / sizeof(long)));
}
void RGFW_FUNC(RGFW_window_setRawMouseModePlatform) (RGFW_window* win, RGFW_bool state) {
- RGFW_UNUSED(win); RGFW_UNUSED(state);
+ RGFW_UNUSED(win);
+ unsigned char mask[XIMaskLen(XI_RawMotion)];
+ RGFW_MEMZERO(mask, sizeof(mask));
+ if (state) XISetMask(mask, XI_RawMotion);
+
+ XIEventMask em;
+ em.deviceid = XIAllMasterDevices;
+ em.mask_len = sizeof(mask);
+ em.mask = mask;
+
+ XISelectEvents(_RGFW->display, XDefaultRootWindow(_RGFW->display), &em, 1);
}
void RGFW_FUNC(RGFW_window_captureMousePlatform) (RGFW_window* win, RGFW_bool state) {
@@ -6369,10 +7211,29 @@ int RGFW_XErrorHandler(Display* display, XErrorEvent* ev) {
RGFW_debugCallback(RGFW_typeError, RGFW_errX11, buf);
_RGFW->x11Error = ev;
+
+ #ifdef RGFW_X11_CRASH_ON_ERROR
+ RGFW_ASSERT(0);
+ #endif
+
return 0;
}
-void RGFW_XCreateWindow (XVisualInfo visual, const char* name, RGFW_windowFlags flags, RGFW_window* win) {
+char* RGFW_XGetWindowName(Window window) {
+ Atom actualType;
+ int actualFormat;
+ unsigned long nitems, bytesAfter;
+ char* name = NULL;
+
+ if (XGetWindowProperty(_RGFW->display, window, _RGFW->_NET_WM_NAME, 0, (~0L), False, _RGFW->UTF8_STRING, &actualType, &actualFormat, &nitems, &bytesAfter, (u8**)&name) == Success && name) {
+ return name;
+ }
+
+ if (XFetchName(_RGFW->display, window, &name) != Success) return NULL;
+ return name;
+}
+
+RGFW_bool RGFW_XCreateWindow (XVisualInfo visual, const char* name, RGFW_windowFlags flags, RGFW_window* win) {
i64 event_mask = KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | PointerMotionMask | StructureNotifyMask | FocusChangeMask |
LeaveWindowMask | EnterWindowMask | ExposureMask | VisibilityChangeMask | PropertyChangeMask;
@@ -6394,6 +7255,8 @@ void RGFW_XCreateWindow (XVisualInfo visual, const char* name, RGFW_windowFlags
0, visual.depth, InputOutput, visual.visual,
CWBorderPixel | CWColormap | CWEventMask, &swa);
+ if (win->src.window == 0) return RGFW_FALSE;
+
win->src.flashEnd = 0;
XFreeColors(_RGFW->display, cmap, NULL, 0, 0);
@@ -6410,22 +7273,17 @@ void RGFW_XCreateWindow (XVisualInfo visual, const char* name, RGFW_windowFlags
win->src.ic = XCreateIC(_RGFW->im, XNInputStyle, XIMPreeditNothing | XIMStatusNothing, XNClientWindow, win->src.window, XNFocusWindow, win->src.window, XNDestroyCallback, &callback, NULL);
}
-
/* In your .desktop app, if you set the property
StartupWMClass=RGFW that will assoicate the launcher icon
with your application - robrohan */
- if (_RGFW->className == NULL)
- _RGFW->className = (char*)name;
XClassHint hint;
+ hint.res_name = (char*)(name ? name : "RGFW");
hint.res_class = (char*)_RGFW->className;
-
- if (_RGFW->instName == NULL) hint.res_name = (char*)name;
- else hint.res_name = (char*)_RGFW->instName;
-
XSetClassHint(_RGFW->display, win->src.window, &hint);
XWMHints hints;
+ RGFW_MEMZERO(&hints, sizeof(hints));
hints.flags = StateHint;
hints.initial_state = NormalState;
@@ -6434,8 +7292,7 @@ void RGFW_XCreateWindow (XVisualInfo visual, const char* name, RGFW_windowFlags
XSelectInput(_RGFW->display, (Drawable) win->src.window, event_mask); /*!< tell X11 what events we want */
/* make it so the user can't close the window until the program does */
- RGFW_LOAD_ATOM(WM_DELETE_WINDOW);
- XSetWMProtocols(_RGFW->display, (Drawable) win->src.window, &WM_DELETE_WINDOW, 1);
+ XSetWMProtocols(_RGFW->display, (Drawable) win->src.window, &_RGFW->WM_DELETE_WINDOW, 1);
/* set the background */
RGFW_window_setName(win, name);
@@ -6445,26 +7302,22 @@ void RGFW_XCreateWindow (XVisualInfo visual, const char* name, RGFW_windowFlags
win->internal.flags |= RGFW_windowAllowDND;
/* actions */
- Atom XdndAware = XInternAtom(_RGFW->display, "XdndAware", False);
const u8 version = 5;
XChangeProperty(_RGFW->display, win->src.window,
- XdndAware, 4, 32,
+ _RGFW->XdndAware, 4, 32,
PropModeReplace, &version, 1); /*!< turns on drag and drop */
}
#ifdef RGFW_ADVANCED_SMOOTH_RESIZE
- RGFW_LOAD_ATOM(_NET_WM_SYNC_REQUEST_COUNTER)
- RGFW_LOAD_ATOM(_NET_WM_SYNC_REQUEST)
-
- Atom protcols[2] = {_NET_WM_SYNC_REQUEST, WM_DELETE_WINDOW};
+ Atom protcols[2] = {_RGFW->_NET_WM_SYNC_REQUEST, _RGFW->WM_DELETE_WINDOW};
XSetWMProtocols(_RGFW->display, win->src.window, protcols, 2);
XSyncValue initial_value;
XSyncIntToValue(&initial_value, 0);
win->src.counter = XSyncCreateCounter(_RGFW->display, initial_value);
- XChangeProperty(_RGFW->display, win->src.window, _NET_WM_SYNC_REQUEST_COUNTER, XA_CARDINAL, 32, PropModeReplace, (u8*)&win->src.counter, 1);
+ XChangeProperty(_RGFW->display, win->src.window, _RGFW->_NET_WM_SYNC_REQUEST_COUNTER, XA_CARDINAL, 32, PropModeReplace, (u8*)&win->src.counter, 1);
#endif
win->src.x = win->x;
@@ -6477,6 +7330,8 @@ void RGFW_XCreateWindow (XVisualInfo visual, const char* name, RGFW_windowFlags
/* stupid hack to make resizing the window less bad */
XSetWindowBackgroundPixmap(_RGFW->display, win->src.window, None);
+
+ return RGFW_TRUE;
}
RGFW_window* RGFW_FUNC(RGFW_createWindowPlatform) (const char* name, RGFW_windowFlags flags, RGFW_window* win) {
@@ -6487,12 +7342,12 @@ RGFW_window* RGFW_FUNC(RGFW_createWindowPlatform) (const char* name, RGFW_window
XVisualInfo visual;
RGFW_window_getVisual(&visual, RGFW_BOOL(win->internal.flags & RGFW_windowTransparent));
- RGFW_XCreateWindow(visual, name, flags, win);
+ if (RGFW_XCreateWindow(visual, name, flags, win) == RGFW_FALSE) return NULL;
return win; /*return newly created window */
}
RGFW_bool RGFW_FUNC(RGFW_getGlobalMouse) (i32* fX, i32* fY) {
- RGFW_init();
+ RGFW_ASSERT(_RGFW && "An RGFW context must be initialized using RGFW_init and/or set with RGFW_setInfo");
i32 x, y;
u32 z;
Window window1, window2;
@@ -6502,28 +7357,22 @@ RGFW_bool RGFW_FUNC(RGFW_getGlobalMouse) (i32* fX, i32* fY) {
RGFWDEF void RGFW_XHandleClipboardSelection(XEvent* event);
void RGFW_XHandleClipboardSelection(XEvent* event) { RGFW_UNUSED(event);
- RGFW_LOAD_ATOM(ATOM_PAIR);
- RGFW_LOAD_ATOM(MULTIPLE);
- RGFW_LOAD_ATOM(TARGETS);
- RGFW_LOAD_ATOM(SAVE_TARGETS);
- RGFW_LOAD_ATOM(UTF8_STRING);
-
const XSelectionRequestEvent* request = &event->xselectionrequest;
Atom formats[2] = {0};
- formats[0] = UTF8_STRING;
+ formats[0] = _RGFW->UTF8_STRING;
formats[1] = XA_STRING;
const int formatCount = sizeof(formats) / sizeof(formats[0]);
- if (request->target == TARGETS) {
+ if (request->target == _RGFW->TARGETS) {
Atom targets[4] = {0};
- targets[0] = TARGETS;
- targets[1] = MULTIPLE;
- targets[2] = UTF8_STRING;
+ targets[0] = _RGFW->TARGETS;
+ targets[1] = _RGFW->MULTIPLE;
+ targets[2] = _RGFW->UTF8_STRING;
targets[3] = XA_STRING;
XChangeProperty(_RGFW->display, request->requestor, request->property,
XA_ATOM, 32, PropModeReplace, (u8*) targets, sizeof(targets) / sizeof(Atom));
- } else if (request->target == MULTIPLE) {
+ } else if (request->target == _RGFW->MULTIPLE) {
Atom* targets = NULL;
Atom actualType = 0;
@@ -6531,24 +7380,24 @@ void RGFW_XHandleClipboardSelection(XEvent* event) { RGFW_UNUSED(event);
unsigned long count = 0, bytesAfter = 0;
XGetWindowProperty(_RGFW->display, request->requestor, request->property, 0, LONG_MAX,
- False, ATOM_PAIR, &actualType, &actualFormat, &count, &bytesAfter, (u8**) &targets);
+ False, _RGFW->ATOM_PAIR, &actualType, &actualFormat, &count, &bytesAfter, (u8**) &targets);
unsigned long i;
for (i = 0; i < (u32)count; i += 2) {
- if (targets[i] == UTF8_STRING || targets[i] == XA_STRING)
+ if (targets[i] == _RGFW->UTF8_STRING || targets[i] == XA_STRING)
XChangeProperty(_RGFW->display, request->requestor, targets[i + 1], targets[i],
- 8, PropModeReplace, (const unsigned char *)_RGFW->clipboard, (i32)_RGFW->clipboard_len);
+ 8, PropModeReplace, (const unsigned char *)_RGFW->unixClipboard->data, (i32)_RGFW->unixClipboard->length);
else
targets[i + 1] = None;
}
XChangeProperty(_RGFW->display,
- request->requestor, request->property, ATOM_PAIR, 32,
+ request->requestor, request->property, _RGFW->ATOM_PAIR, 32,
PropModeReplace, (u8*) targets, (i32)count);
XFlush(_RGFW->display);
XFree(targets);
- } else if (request->target == SAVE_TARGETS)
+ } else if (request->target == _RGFW->SAVE_TARGETS)
XChangeProperty(_RGFW->display, request->requestor, request->property, 0, 32, PropModeReplace, NULL, 0);
else {
int i;
@@ -6556,7 +7405,7 @@ void RGFW_XHandleClipboardSelection(XEvent* event) { RGFW_UNUSED(event);
if (request->target != formats[i])
continue;
XChangeProperty(_RGFW->display, request->requestor, request->property, request->target,
- 8, PropModeReplace, (u8*) _RGFW->clipboard, (i32)_RGFW->clipboard_len);
+ 8, PropModeReplace, (u8*) _RGFW->unixClipboard->data, (i32)_RGFW->unixClipboard->length);
}
}
@@ -6583,6 +7432,11 @@ RGFW_key RGFW_FUNC(RGFW_physicalToMappedKey) (RGFW_key key) {
}
switch (sym) {
+ case XK_BackSpace: return RGFW_keyBackSpace;
+ case XK_Tab: return RGFW_keyTab;
+ case XK_Return: return RGFW_keyReturn;
+ case XK_Escape: return RGFW_keyEscape;
+ case XK_Delete: return RGFW_keyDelete;
case XK_F1: return RGFW_keyF1;
case XK_F2: return RGFW_keyF2;
case XK_F3: return RGFW_keyF3;
@@ -6656,24 +7510,11 @@ RGFW_key RGFW_FUNC(RGFW_physicalToMappedKey) (RGFW_key key) {
RGFWDEF void RGFW_XHandleEvent(void);
void RGFW_XHandleEvent(void) {
- RGFW_LOAD_ATOM(XdndTypeList);
- RGFW_LOAD_ATOM(XdndSelection);
- RGFW_LOAD_ATOM(XdndEnter);
- RGFW_LOAD_ATOM(XdndPosition);
- RGFW_LOAD_ATOM(XdndStatus);
- RGFW_LOAD_ATOM(XdndLeave);
- RGFW_LOAD_ATOM(XdndDrop);
- RGFW_LOAD_ATOM(XdndFinished);
- RGFW_LOAD_ATOM(XdndActionCopy);
- RGFW_LOAD_ATOM(_NET_WM_SYNC_REQUEST);
- RGFW_LOAD_ATOM(WM_PROTOCOLS);
- RGFW_LOAD_ATOM(WM_STATE);
- RGFW_LOAD_ATOM(_NET_WM_STATE);
-
static float deltaX = 0.0f;
static float deltaY = 0.0f;
XEvent E;
+ RGFW_MEMZERO(&E, sizeof(E));
XNextEvent(_RGFW->display, &E);
@@ -6682,12 +7523,10 @@ void RGFW_XHandleEvent(void) {
deltaY = 0.0f;
}
-#ifndef RGFW_NO_XRANDR
if (E.type == _RGFW->xrandrEventBase + RRNotify) {
RGFW_pollMonitors();
return;
}
-#endif
switch (E.type) {
case SelectionRequest:
@@ -6730,7 +7569,7 @@ void RGFW_XHandleEvent(void) {
}
if (win->src.flashEnd) {
- if ((win->src.flashEnd <= RGFW_linux_getTimeNS()) || RGFW_window_isInFocus(win)) {
+ if ((win->src.flashEnd <= RGFW_unix_getTimeNS()) || RGFW_window_isInFocus(win)) {
RGFW_window_flash(win, RGFW_flashCancel);
}
}
@@ -6862,11 +7701,11 @@ void RGFW_XHandleEvent(void) {
break;
}
case MotionNotify:
- RGFW_mousePosCallback(win, E.xmotion.x, E.xmotion.y);
+ RGFW_mouseMotionCallback(win, E.xmotion.x, E.xmotion.y);
break;
case Expose: {
- RGFW_windowRefreshCallback(win, 0, 0, win->w, win->h);
+ RGFW_windowRefreshCallback(win, E.xexpose.x, E.xexpose.y, E.xexpose.width, E.xexpose.height);
#ifdef RGFW_ADVANCED_SMOOTH_RESIZE
XSyncValue value;
@@ -6879,12 +7718,12 @@ void RGFW_XHandleEvent(void) {
case PropertyNotify:
if (E.xproperty.state != PropertyNewValue) break;
- if (E.xproperty.atom == WM_STATE) {
+ if (E.xproperty.atom == _RGFW->WM_STATE) {
if (RGFW_window_isMinimized(win) && !(win->internal.flags & RGFW_windowMinimized)) {
RGFW_windowMinimizedCallback(win);
break;
}
- } else if (E.xproperty.atom == _NET_WM_STATE) {
+ } else if (E.xproperty.atom == _RGFW->_NET_WM_STATE) {
if (RGFW_window_isMaximized(win) && !(win->internal.flags & RGFW_windowMaximize)) {
RGFW_windowMaximizedCallback(win, win->x, win->y, win->w, win->h);
break;
@@ -6895,14 +7734,13 @@ void RGFW_XHandleEvent(void) {
break;
case MapNotify: case UnmapNotify: RGFW_window_checkMode(win); break;
case ClientMessage: {
- RGFW_LOAD_ATOM(WM_DELETE_WINDOW);
/* if the client closed the window */
- if (E.xclient.data.l[0] == (long)WM_DELETE_WINDOW) {
+ if (E.xclient.data.l[0] == (long)_RGFW->WM_DELETE_WINDOW) {
RGFW_windowCloseCallback(win);
break;
}
#ifdef RGFW_ADVANCED_SMOOTH_RESIZE
- if (E.xclient.message_type == WM_PROTOCOLS && (Atom)E.xclient.data.l[0] == _NET_WM_SYNC_REQUEST) {
+ if (E.xclient.message_type == _RGFW->WM_PROTOCOLS && (Atom)E.xclient.data.l[0] == _RGFW->_NET_WM_SYNC_REQUEST) {
RGFW_windowRefreshCallback(win, 0, 0, win->w, win->h);
win->src.counter_value = 0;
win->src.counter_value |= E.xclient.data.l[2];
@@ -6921,7 +7759,7 @@ void RGFW_XHandleEvent(void) {
i32 dragX = 0;
i32 dragY = 0;
- if (E.xclient.message_type == XdndEnter) {
+ if (E.xclient.message_type == _RGFW->XdndEnter) {
unsigned long count;
Atom* formats;
Atom real_formats[3];
@@ -6936,7 +7774,7 @@ void RGFW_XHandleEvent(void) {
unsigned long bytesAfter;
XGetWindowProperty(
- _RGFW->display, _RGFW->x11Source, XdndTypeList,
+ _RGFW->display, _RGFW->x11Source, _RGFW->XdndTypeList,
0, LONG_MAX, False, 4,
&actualType, &actualFormat, &count, &bytesAfter, (u8**)&formats
);
@@ -6954,13 +7792,10 @@ void RGFW_XHandleEvent(void) {
formats = real_formats;
}
- Atom XtextPlain = XInternAtom(_RGFW->display, "text/plain", False);
- Atom XtextUriList = XInternAtom(_RGFW->display, "text/uri-list", False);
-
size_t i;
for (i = 0; i < count; i++) {
- if (formats[i] == XtextUriList) _RGFW->x11TransferType = RGFW_dataFile;
- else if (formats[i] == XtextPlain) _RGFW->x11TransferType = RGFW_dataText;
+ if (formats[i] == _RGFW->XtextUriList) _RGFW->x11TransferType = RGFW_dataFile;
+ else if (formats[i] == _RGFW->XtextPlain) _RGFW->x11TransferType = RGFW_dataText;
else continue;
_RGFW->x11Format = (int)formats[i];
@@ -6973,7 +7808,7 @@ void RGFW_XHandleEvent(void) {
RGFW_dataDragCallback(win, _RGFW->x11TransferType , RGFW_dndActionEnter, dragX, dragY);
- } else if (E.xclient.message_type == XdndPosition) {
+ } else if (E.xclient.message_type == _RGFW->XdndPosition) {
const i32 xabs = (E.xclient.data.l[2] >> 16) & 0xffff;
const i32 yabs = (E.xclient.data.l[2]) & 0xffff;
Window dummy;
@@ -6987,10 +7822,10 @@ void RGFW_XHandleEvent(void) {
dragX = xpos;
dragY = ypos;
- RGFW_mousePosCallback(win, xpos, ypos);
+ RGFW_mouseMotionCallback(win, xpos, ypos);
XEvent reply = { ClientMessage };
reply.xclient.window = _RGFW->x11Source;
- reply.xclient.message_type = XdndStatus;
+ reply.xclient.message_type = _RGFW->XdndStatus;
reply.xclient.format = 32;
reply.xclient.data.l[0] = (long)win->src.window;
reply.xclient.data.l[2] = 0;
@@ -6999,7 +7834,7 @@ void RGFW_XHandleEvent(void) {
if (_RGFW->x11Format) {
reply.xclient.data.l[1] = 1;
if (_RGFW->x11Version >= 2)
- reply.xclient.data.l[4] = (long)XdndActionCopy;
+ reply.xclient.data.l[4] = (long)_RGFW->XdndActionCopy;
}
XSendEvent(_RGFW->display, _RGFW->x11Source, False, NoEventMask, &reply);
@@ -7007,21 +7842,21 @@ void RGFW_XHandleEvent(void) {
RGFW_dataDragCallback(win, _RGFW->x11TransferType, RGFW_dndActionMove, dragX, dragY);
- } else if (E.xclient.message_type == XdndLeave) {
+ } else if (E.xclient.message_type == _RGFW->XdndLeave) {
RGFW_dataDragCallback(win, _RGFW->x11TransferType, RGFW_dndActionExit, dragX, dragY);
- } else if (E.xclient.message_type == XdndDrop) {
+ } else if (E.xclient.message_type == _RGFW->XdndDrop) {
if (_RGFW->x11Format) {
Time time = (_RGFW->x11Version >= 1)
? (Time)E.xclient.data.l[2]
: CurrentTime;
XConvertSelection(
- _RGFW->display, XdndSelection, (Atom)_RGFW->x11Format,
- XdndSelection, win->src.window, time
+ _RGFW->display, _RGFW->XdndSelection, (Atom)_RGFW->x11Format,
+ _RGFW->XdndSelection, win->src.window, time
);
} else if (_RGFW->x11Version >= 2) {
XEvent reply = { ClientMessage };
reply.xclient.window = _RGFW->x11Source;
- reply.xclient.message_type = XdndFinished;
+ reply.xclient.message_type = _RGFW->XdndFinished;
reply.xclient.format = 32;
reply.xclient.data.l[0] = (long)win->src.window;
reply.xclient.data.l[1] = 0;
@@ -7034,7 +7869,7 @@ void RGFW_XHandleEvent(void) {
} break;
case SelectionNotify: {
/* this is only for checking for xdnd drops */
- if (!(win->internal.enabledEvents & RGFW_dataDropFlag) || E.xselection.property != XdndSelection || !(win->internal.flags & RGFW_windowAllowDND))
+ if (!(win->internal.enabledEvents & RGFW_dataDropFlag) || E.xselection.property != _RGFW->XdndSelection || !(win->internal.flags & RGFW_windowAllowDND))
return;
char* data;
unsigned long result;
@@ -7055,11 +7890,11 @@ void RGFW_XHandleEvent(void) {
if (_RGFW->x11Version >= 2) {
XEvent reply = { ClientMessage };
reply.xclient.window = _RGFW->x11Source;
- reply.xclient.message_type = XdndFinished;
+ reply.xclient.message_type = _RGFW->XdndFinished;
reply.xclient.format = 32;
reply.xclient.data.l[0] = (long)win->src.window;
reply.xclient.data.l[1] = (long int)result;
- reply.xclient.data.l[2] = (long int)XdndActionCopy;
+ reply.xclient.data.l[2] = (long int)_RGFW->XdndActionCopy;
XSendEvent(_RGFW->display, _RGFW->x11Source, False, NoEventMask, &reply);
XFlush(_RGFW->display);
}
@@ -7108,10 +7943,10 @@ void RGFW_XHandleEvent(void) {
}
/* detect move */
- if (E.xconfigure.x != win->src.x || E.xconfigure.y != win->src.y) {
- win->src.x = E.xconfigure.x;
- win->src.y = E.xconfigure.y;
- RGFW_windowMovedCallback(win, E.xconfigure.x, E.xconfigure.y);
+ if (x != win->src.x || y != win->src.y) {
+ win->src.x = x;
+ win->src.y = y;
+ RGFW_windowMovedCallback(win, x, y);
}
return;
}
@@ -7142,21 +7977,12 @@ void RGFW_FUNC(RGFW_pollEvents) (void) {
}
}
-void RGFW_FUNC(RGFW_window_move) (RGFW_window* win, i32 x, i32 y) {
- RGFW_ASSERT(win != NULL);
- win->x = x;
- win->y = y;
-
+void RGFW_FUNC(RGFW_window_movePlatform) (RGFW_window* win, i32 x, i32 y) {
XMoveWindow(_RGFW->display, win->src.window, x, y);
- return;
}
-void RGFW_FUNC(RGFW_window_resize) (RGFW_window* win, i32 w, i32 h) {
- RGFW_ASSERT(win != NULL);
- win->w = (i32)w;
- win->h = (i32)h;
-
+void RGFW_FUNC(RGFW_window_resizePlatform) (RGFW_window* win, i32 w, i32 h) {
XResizeWindow(_RGFW->display, win->src.window, (u32)w, (u32)h);
if ((win->internal.flags & RGFW_windowNoResize)) {
@@ -7229,32 +8055,23 @@ void RGFW_FUNC(RGFW_window_setMaxSize) (RGFW_window* win, i32 w, i32 h) {
void RGFW_toggleXMaximized(RGFW_window* win, RGFW_bool maximized);
void RGFW_toggleXMaximized(RGFW_window* win, RGFW_bool maximized) {
RGFW_ASSERT(win != NULL);
- RGFW_LOAD_ATOM(_NET_WM_STATE);
- RGFW_LOAD_ATOM(_NET_WM_STATE_MAXIMIZED_VERT);
- RGFW_LOAD_ATOM(_NET_WM_STATE_MAXIMIZED_HORZ);
XEvent xev = {0};
xev.type = ClientMessage;
xev.xclient.window = win->src.window;
- xev.xclient.message_type = _NET_WM_STATE;
+ xev.xclient.message_type = _RGFW->_NET_WM_STATE;
xev.xclient.format = 32;
xev.xclient.data.l[0] = maximized;
- xev.xclient.data.l[1] = (long int)_NET_WM_STATE_MAXIMIZED_HORZ;
- xev.xclient.data.l[2] = (long int)_NET_WM_STATE_MAXIMIZED_VERT;
+ xev.xclient.data.l[1] = (long int)_RGFW->_NET_WM_STATE_MAXIMIZED_HORZ;
+ xev.xclient.data.l[2] = (long int)_RGFW->_NET_WM_STATE_MAXIMIZED_VERT;
xev.xclient.data.l[3] = 0;
xev.xclient.data.l[4] = 0;
XSendEvent(_RGFW->display, DefaultRootWindow(_RGFW->display), False, SubstructureRedirectMask | SubstructureNotifyMask, &xev);
}
-void RGFW_FUNC(RGFW_window_maximize) (RGFW_window* win) {
- win->internal.oldX = win->x;
- win->internal.oldY = win->y;
- win->internal.oldW = win->w;
- win->internal.oldH = win->h;
-
+void RGFW_FUNC(RGFW_window_maximizePlatform) (RGFW_window* win) {
RGFW_toggleXMaximized(win, 1);
- RGFW_window_fetchSize(win, NULL, NULL);
return;
}
@@ -7272,19 +8089,18 @@ void RGFW_FUNC(RGFW_window_focus) (RGFW_window* win) {
void RGFW_FUNC(RGFW_window_raise) (RGFW_window* win) {
RGFW_ASSERT(win);
XMapRaised(_RGFW->display, win->src.window);
- RGFW_window_setFullscreen(win, RGFW_window_isFullscreen(win));
+ RGFW_window_setFullscreenPlatform(win, RGFW_window_isFullscreen(win));
}
void RGFW_window_setXAtom(RGFW_window* win, Atom netAtom, RGFW_bool fullscreen);
void RGFW_window_setXAtom(RGFW_window* win, Atom netAtom, RGFW_bool fullscreen) {
RGFW_ASSERT(win != NULL);
- RGFW_LOAD_ATOM(_NET_WM_STATE);
XEvent xev = {0};
xev.xclient.type = ClientMessage;
xev.xclient.serial = 0;
xev.xclient.send_event = True;
- xev.xclient.message_type = _NET_WM_STATE;
+ xev.xclient.message_type = _RGFW->_NET_WM_STATE;
xev.xclient.window = win->src.window;
xev.xclient.format = 32;
xev.xclient.data.l[0] = fullscreen;
@@ -7294,48 +8110,33 @@ void RGFW_window_setXAtom(RGFW_window* win, Atom netAtom, RGFW_bool fullscreen)
XSendEvent(_RGFW->display, DefaultRootWindow(_RGFW->display), False, SubstructureNotifyMask | SubstructureRedirectMask, &xev);
}
-void RGFW_FUNC(RGFW_window_setFullscreen)(RGFW_window* win, RGFW_bool fullscreen) {
- RGFW_ASSERT(win != NULL);
-
- if (fullscreen) {
- win->internal.flags |= RGFW_windowFullscreen;
- win->internal.oldX = win->x;
- win->internal.oldY = win->y;
- win->internal.oldW = win->w;
- win->internal.oldH = win->h;
- }
- else win->internal.flags &= ~(u32)RGFW_windowFullscreen;
-
+void RGFW_FUNC(RGFW_window_setFullscreenPlatform)(RGFW_window* win, RGFW_bool fullscreen) {
XRaiseWindow(_RGFW->display, win->src.window);
- RGFW_LOAD_ATOM(_NET_WM_STATE_FULLSCREEN);
- RGFW_window_setXAtom(win, _NET_WM_STATE_FULLSCREEN, fullscreen);
+ RGFW_window_setXAtom(win, _RGFW->_NET_WM_STATE_FULLSCREEN, fullscreen);
if (!(win->internal.flags & RGFW_windowTransparent)) {
const unsigned char value = fullscreen;
- RGFW_LOAD_ATOM(_NET_WM_BYPASS_COMPOSITOR);
XChangeProperty(
_RGFW->display, win->src.window,
- _NET_WM_BYPASS_COMPOSITOR, XA_CARDINAL, 32,
+ _RGFW->_NET_WM_BYPASS_COMPOSITOR, XA_CARDINAL, 32,
PropModeReplace, &value, 1);
}
}
void RGFW_FUNC(RGFW_window_setFloating)(RGFW_window* win, RGFW_bool floating) {
RGFW_ASSERT(win != NULL);
- RGFW_LOAD_ATOM(_NET_WM_STATE_ABOVE);
- RGFW_window_setXAtom(win, _NET_WM_STATE_ABOVE, floating);
+ RGFW_window_setXAtom(win, _RGFW->_NET_WM_STATE_ABOVE, floating);
}
void RGFW_FUNC(RGFW_window_setOpacity)(RGFW_window* win, u8 opacity) {
RGFW_ASSERT(win != NULL);
const u32 value = (u32) (0xffffffffu * (double) opacity);
- RGFW_LOAD_ATOM(NET_WM_WINDOW_OPACITY);
XChangeProperty(_RGFW->display, win->src.window,
- NET_WM_WINDOW_OPACITY, XA_CARDINAL, 32, PropModeReplace, (unsigned char*) &value, 1);
+ _RGFW->NET_WM_WINDOW_OPACITY, XA_CARDINAL, 32, PropModeReplace, (unsigned char*) &value, 1);
}
-void RGFW_FUNC(RGFW_window_minimize)(RGFW_window* win) {
+void RGFW_FUNC(RGFW_window_minimizePlatform)(RGFW_window* win) {
RGFW_ASSERT(win != NULL);
if (RGFW_window_isMaximized(win)) return;
@@ -7348,26 +8149,19 @@ void RGFW_FUNC(RGFW_window_minimize)(RGFW_window* win) {
XFlush(_RGFW->display);
}
-void RGFW_FUNC(RGFW_window_restore)(RGFW_window* win) {
+void RGFW_FUNC(RGFW_window_restorePlatform)(RGFW_window* win) {
RGFW_ASSERT(win != NULL);
RGFW_toggleXMaximized(win, RGFW_FALSE);
- RGFW_window_move(win, win->internal.oldX, win->internal.oldY);
- RGFW_window_resize(win, win->internal.oldW, win->internal.oldH);
-
- RGFW_window_show(win);
- XFlush(_RGFW->display);
+ XFlush(_RGFW->display);
}
RGFW_bool RGFW_FUNC(RGFW_window_isFloating)(RGFW_window* win) {
- RGFW_LOAD_ATOM(_NET_WM_STATE);
- RGFW_LOAD_ATOM(_NET_WM_STATE_ABOVE);
-
Atom actual_type;
int actual_format;
unsigned long nitems, bytes_after;
Atom* prop_return = NULL;
- int status = XGetWindowProperty(_RGFW->display, win->src.window, _NET_WM_STATE, 0, (~0L), False, XA_ATOM,
+ int status = XGetWindowProperty(_RGFW->display, win->src.window, _RGFW->_NET_WM_STATE, 0, (~0L), False, XA_ATOM,
&actual_type, &actual_format, &nitems, &bytes_after,
(unsigned char **)&prop_return);
@@ -7376,7 +8170,7 @@ RGFW_bool RGFW_FUNC(RGFW_window_isFloating)(RGFW_window* win) {
unsigned long i;
for (i = 0; i < nitems; i++)
- if (prop_return[i] == _NET_WM_STATE_ABOVE) return RGFW_TRUE;
+ if (prop_return[i] == _RGFW->_NET_WM_STATE_ABOVE) return RGFW_TRUE;
if (prop_return)
XFree(prop_return);
@@ -7390,10 +8184,8 @@ void RGFW_FUNC(RGFW_window_setName)(RGFW_window* win, const char* name) {
Xutf8SetWMProperties(_RGFW->display, win->src.window, name, name, NULL, 0, NULL, NULL, NULL);
XStoreName(_RGFW->display, win->src.window, name);
- RGFW_LOAD_ATOM(_NET_WM_NAME); RGFW_LOAD_ATOM(UTF8_STRING);
-
XChangeProperty(
- _RGFW->display, win->src.window, _NET_WM_NAME, UTF8_STRING,
+ _RGFW->display, win->src.window, _RGFW->_NET_WM_NAME, _RGFW->UTF8_STRING,
8, PropModeReplace, (u8*)name, (int)RGFW_unix_stringlen(name)
);
}
@@ -7414,11 +8206,10 @@ void RGFW_FUNC(RGFW_window_setMousePassthrough) (RGFW_window* win, RGFW_bool pas
#endif /* RGFW_NO_PASSTHROUGH */
RGFW_bool RGFW_FUNC(RGFW_window_setIconEx) (RGFW_window* win, u8* data_src, i32 w, i32 h, RGFW_format format, RGFW_icon type) {
- Atom _NET_WM_ICON = XInternAtom(_RGFW->display, "_NET_WM_ICON", False);
RGFW_ASSERT(win != NULL);
if (data_src == NULL) {
RGFW_bool res = (RGFW_bool)XChangeProperty(
- _RGFW->display, win->src.window, _NET_WM_ICON, XA_CARDINAL, 32,
+ _RGFW->display, win->src.window, _RGFW->_NET_WM_ICON, XA_CARDINAL, 32,
PropModeReplace, (u8*)NULL, 0
);
return res;
@@ -7437,7 +8228,7 @@ RGFW_bool RGFW_FUNC(RGFW_window_setIconEx) (RGFW_window* win, u8* data_src, i32
RGFW_bool res = RGFW_TRUE;
if (type & RGFW_iconTaskbar) {
res = (RGFW_bool)XChangeProperty(
- _RGFW->display, win->src.window, _NET_WM_ICON, XA_CARDINAL, 32,
+ _RGFW->display, win->src.window, _RGFW->_NET_WM_ICON, XA_CARDINAL, 32,
PropModeReplace, (u8*)data, count
);
}
@@ -7498,9 +8289,9 @@ RGFW_mouse* RGFW_FUNC(RGFW_createMouseStandard) (RGFW_mouseIcon mouse) {
}
RGFW_mouse* RGFW_FUNC(RGFW_createMouse) (u8* data, i32 w, i32 h, RGFW_format format) {
- RGFW_ASSERT(data);
+ RGFW_ASSERT(_RGFW && "An RGFW context must be initialized using RGFW_init and/or set with RGFW_setInfo");
+ RGFW_ASSERT(data);
#ifndef RGFW_NO_X11_CURSOR
- RGFW_init();
XcursorImage* native = XcursorImageCreate((i32)w, (i32)h);
native->xhot = 0;
native->yhot = 0;
@@ -7553,9 +8344,8 @@ void RGFW_FUNC(RGFW_window_hide)(RGFW_window* win) {
XFlush(_RGFW->display);
}
-void RGFW_FUNC(RGFW_window_show) (RGFW_window* win) {
+void RGFW_FUNC(RGFW_window_showPlatform) (RGFW_window* win) {
win->internal.flags &= ~(u32)RGFW_windowHide;
- if (win->internal.flags & RGFW_windowFocusOnShow) RGFW_window_focus(win);
if (RGFW_window_isHidden(win) == RGFW_FALSE) {
return;
@@ -7565,7 +8355,7 @@ void RGFW_FUNC(RGFW_window_show) (RGFW_window* win) {
RGFW_window_move(win, win->x, win->y);
RGFW_waitForShowEvent_X11(win);
- RGFW_window_setFullscreen(win, RGFW_window_isFullscreen(win));
+ RGFW_window_setFullscreenPlatform(win, RGFW_window_isFullscreen(win));
return;
}
@@ -7580,7 +8370,7 @@ void RGFW_FUNC(RGFW_window_flash) (RGFW_window* win, RGFW_flashRequest request)
if (request) {
wmhints->flags |= XUrgencyHint;
if (request == RGFW_flashBriefly)
- win->src.flashEnd = RGFW_linux_getTimeNS() + (u64)1e+9;
+ win->src.flashEnd = RGFW_unix_getTimeNS() + (u64)1e+9;
if (request == RGFW_flashUntilFocused)
win->src.flashEnd = (u64)-1;
} else {
@@ -7592,56 +8382,68 @@ void RGFW_FUNC(RGFW_window_flash) (RGFW_window* win, RGFW_flashRequest request)
XFree(wmhints);
}
-RGFW_ssize_t RGFW_FUNC(RGFW_readClipboardPtr)(char* str, size_t strCapacity) {
- RGFW_init();
- RGFW_LOAD_ATOM(XSEL_DATA); RGFW_LOAD_ATOM(UTF8_STRING); RGFW_LOAD_ATOM(CLIPBOARD);
- if (XGetSelectionOwner(_RGFW->display, CLIPBOARD) == _RGFW->helperWindow) {
- if (str != NULL)
- RGFW_STRNCPY(str, _RGFW->clipboard, _RGFW->clipboard_len - 1);
- _RGFW->clipboard[_RGFW->clipboard_len - 1] = '\0';
- return (RGFW_ssize_t)_RGFW->clipboard_len - 1;
+RGFW_bool RGFW_FUNC(RGFW_readClipboardPtr) (RGFW_dataTransferType requestedType, u8* buffer, size_t capacity, RGFW_dataTransfer* dataTransfer) {
+ RGFW_ASSERT(_RGFW && "An RGFW context must be initialized using RGFW_init and/or set with RGFW_setInfo");
+ RGFW_ASSERT(dataTransfer != NULL);
+
+ if (requestedType != RGFW_dataText) return RGFW_FALSE;
+ dataTransfer->data = (char*)buffer;
+
+ if (XGetSelectionOwner(_RGFW->display, _RGFW->CLIPBOARD) == _RGFW->helperWindow) {
+ dataTransfer->length = _RGFW->unixClipboard->length;
+ if (buffer != NULL && _RGFW->unixClipboard->data != NULL) {
+ if (_RGFW->unixClipboard->length > capacity) return RGFW_FALSE;
+
+ RGFW_MEMCPY((char*)buffer, _RGFW->unixClipboard->data, _RGFW->unixClipboard->length);
+ }
+
+ dataTransfer->type = RGFW_dataText;
+ return RGFW_TRUE;
}
XEvent event;
int format;
- unsigned long N, sizeN;
+ unsigned long N, size;
char* data;
Atom target;
- XConvertSelection(_RGFW->display, CLIPBOARD, UTF8_STRING, XSEL_DATA, _RGFW->helperWindow, CurrentTime);
+ XConvertSelection(_RGFW->display, _RGFW->CLIPBOARD, _RGFW->UTF8_STRING, _RGFW->XSEL_DATA, _RGFW->helperWindow, CurrentTime);
XSync(_RGFW->display, 0);
while (1) {
XNextEvent(_RGFW->display, &event);
if (event.type != SelectionNotify) continue;
- if (event.xselection.selection != CLIPBOARD || event.xselection.property == 0)
- return -1;
+ if (event.xselection.selection != _RGFW->CLIPBOARD || event.xselection.property == 0)
+ return RGFW_FALSE;
break;
}
XGetWindowProperty(event.xselection.display, event.xselection.requestor,
event.xselection.property, 0L, (~0L), 0, AnyPropertyType, &target,
- &format, &sizeN, &N, (u8**) &data);
+ &format, &size, &N, (u8**) &data);
+
+ RGFW_bool ret = RGFW_TRUE;
- RGFW_ssize_t size;
- if (sizeN > strCapacity && str != NULL)
- size = -1;
+ size_t length = size;
+ if (data[size - 1] != '\0') length += 1;
+
+ if (size > capacity && buffer != NULL)
+ ret = RGFW_FALSE;
+ else if ((target == _RGFW->UTF8_STRING || target == XA_STRING) && buffer != NULL) {
+ RGFW_MEMCPY(buffer, data, size);
+ buffer[length - 1] = '\0';
- if ((target == UTF8_STRING || target == XA_STRING) && str != NULL) {
- RGFW_MEMCPY(str, data, sizeN);
- str[sizeN] = '\0';
XFree(data);
- } else if (str != NULL) size = -1;
+ } else if (buffer != NULL) ret = RGFW_FALSE;
XDeleteProperty(event.xselection.display, event.xselection.requestor, event.xselection.property);
- size = (RGFW_ssize_t)sizeN;
- return size;
+ dataTransfer->length = length;
+ dataTransfer->type = RGFW_dataText;
+ return ret;
}
i32 RGFW_XHandleClipboardSelectionHelper(void) {
- RGFW_LOAD_ATOM(SAVE_TARGETS);
-
XEvent event;
XPending(_RGFW->display);
@@ -7655,7 +8457,7 @@ i32 RGFW_XHandleClipboardSelectionHelper(void) {
RGFW_XHandleClipboardSelection(&event);
return 0;
case SelectionNotify:
- if (event.xselection.target == SAVE_TARGETS)
+ if (event.xselection.target == _RGFW->SAVE_TARGETS)
return 0;
break;
default: break;
@@ -7664,27 +8466,37 @@ i32 RGFW_XHandleClipboardSelectionHelper(void) {
return 0;
}
-void RGFW_FUNC(RGFW_writeClipboard)(const char* text, u32 textLen) {
- RGFW_LOAD_ATOM(SAVE_TARGETS); RGFW_LOAD_ATOM(CLIPBOARD);
- RGFW_init();
+RGFW_bool RGFW_FUNC(RGFW_writeClipboard)(const RGFW_dataTransfer* data) {
+ RGFW_ASSERT(_RGFW && "An RGFW context must be initialized using RGFW_init and/or set with RGFW_setInfo");
/* request ownership of the clipboard section and request to convert it, this means its our job to convert it */
- XSetSelectionOwner(_RGFW->display, CLIPBOARD, _RGFW->helperWindow, CurrentTime);
- if (XGetSelectionOwner(_RGFW->display, CLIPBOARD) != _RGFW->helperWindow) {
+ XSetSelectionOwner(_RGFW->display, _RGFW->CLIPBOARD, _RGFW->helperWindow, CurrentTime);
+ if (XGetSelectionOwner(_RGFW->display, _RGFW->CLIPBOARD) != _RGFW->helperWindow) {
RGFW_debugCallback(RGFW_typeError, RGFW_errClipboard, "X11 failed to become owner of clipboard selection");
- return;
+ return RGFW_FALSE;
}
- if (_RGFW->clipboard)
- RGFW_FREE(_RGFW->clipboard);
+ if (_RGFW->unixClipboard) {
+ RGFW_FREE(_RGFW->unixClipboard);
+ _RGFW->unixClipboard = NULL;
+ }
- _RGFW->clipboard = (char*)RGFW_ALLOC(textLen);
- RGFW_ASSERT(_RGFW->clipboard != NULL);
+ size_t length = data->length;
+ if (data->data[data->length - 1] != '\0') {
+ length += 1;
+ }
- RGFW_STRNCPY(_RGFW->clipboard, text, textLen - 1);
- _RGFW->clipboard[textLen - 1] = '\0';
- _RGFW->clipboard_len = textLen;
- return;
+ _RGFW->unixClipboard = (RGFW_dataTransfer*)RGFW_ALLOC(sizeof(RGFW_dataTransfer) + data->length);
+ RGFW_ASSERT(_RGFW->unixClipboard != NULL);
+
+ char* data_ptr = &((char*)(void*)_RGFW->unixClipboard)[sizeof(RGFW_dataTransfer) - 1];
+ RGFW_MEMCPY(data_ptr, data->data, data->length);
+ data_ptr[length - 1] = '\0';
+
+ _RGFW->unixClipboard->data = (const char*)data_ptr;
+ _RGFW->unixClipboard->type = RGFW_dataText;
+ _RGFW->unixClipboard->length = length;
+ return RGFW_TRUE;
}
RGFW_bool RGFW_FUNC(RGFW_window_isHidden)(RGFW_window* win) {
@@ -7697,14 +8509,13 @@ RGFW_bool RGFW_FUNC(RGFW_window_isHidden)(RGFW_window* win) {
RGFW_bool RGFW_FUNC(RGFW_window_isMinimized)(RGFW_window* win) {
RGFW_ASSERT(win != NULL);
- RGFW_LOAD_ATOM(WM_STATE);
Atom actual_type;
i32 actual_format;
unsigned long nitems, bytes_after;
unsigned char* prop_data;
- i32 status = XGetWindowProperty(_RGFW->display, win->src.window, WM_STATE, 0, 2, False,
+ i32 status = XGetWindowProperty(_RGFW->display, win->src.window, _RGFW->WM_STATE, 0, 2, False,
AnyPropertyType, &actual_type, &actual_format,
&nitems, &bytes_after, &prop_data);
@@ -7723,16 +8534,13 @@ RGFW_bool RGFW_FUNC(RGFW_window_isMinimized)(RGFW_window* win) {
RGFW_bool RGFW_FUNC(RGFW_window_isMaximized)(RGFW_window* win) {
RGFW_ASSERT(win != NULL);
- RGFW_LOAD_ATOM(_NET_WM_STATE);
- RGFW_LOAD_ATOM(_NET_WM_STATE_MAXIMIZED_VERT);
- RGFW_LOAD_ATOM(_NET_WM_STATE_MAXIMIZED_HORZ);
Atom actual_type;
i32 actual_format;
unsigned long nitems, bytes_after;
unsigned char* prop_data;
- i32 status = XGetWindowProperty(_RGFW->display, win->src.window, _NET_WM_STATE, 0, 1024, False,
+ i32 status = XGetWindowProperty(_RGFW->display, win->src.window, _RGFW->_NET_WM_STATE, 0, 1024, False,
XA_ATOM, &actual_type, &actual_format,
&nitems, &bytes_after, &prop_data);
@@ -7745,8 +8553,8 @@ RGFW_bool RGFW_FUNC(RGFW_window_isMaximized)(RGFW_window* win) {
u64 i;
for (i = 0; i < nitems; i++) {
- if (prop_data[i] == _NET_WM_STATE_MAXIMIZED_VERT ||
- prop_data[i] == _NET_WM_STATE_MAXIMIZED_HORZ) {
+ if (prop_data[i] == _RGFW->_NET_WM_STATE_MAXIMIZED_VERT ||
+ prop_data[i] == _RGFW->_NET_WM_STATE_MAXIMIZED_HORZ) {
XFree(prop_data);
return RGFW_TRUE;
}
@@ -7763,20 +8571,18 @@ void RGFW_XGetSystemContentDPI(float* dpi) {
if (dpi == NULL) return;
float dpiOutput = 96.0f;
- #ifndef RGFW_NO_XRANDR
- char* rms = XResourceManagerString(_RGFW->display);
- if (rms == NULL) return;
+ char* rms = XResourceManagerString(_RGFW->display);
+ if (rms == NULL) return;
- XrmDatabase db = XrmGetStringDatabase(rms);
- if (db == NULL) return;
+ XrmDatabase db = XrmGetStringDatabase(rms);
+ if (db == NULL) return;
- XrmValue value;
- char* type = NULL;
+ XrmValue value;
+ char* type = NULL;
- if (XrmGetResource(db, "Xft.dpi", "Xft.Dpi", &type, &value) && type && RGFW_STRNCMP(type, "String", 7) == 0)
- dpiOutput = (float)RGFW_ATOF(value.addr);
- XrmDestroyDatabase(db);
- #endif
+ if (XrmGetResource(db, "Xft.dpi", "Xft.Dpi", &type, &value) && type && RGFW_STRNCMP(type, "String", 7) == 0)
+ dpiOutput = (float)RGFW_ATOF(value.addr);
+ XrmDestroyDatabase(db);
if (dpi) *dpi = dpiOutput;
}
@@ -7836,7 +8642,7 @@ XRRModeInfo* RGFW_XGetMode(XRRCrtcInfo* ci, XRRScreenResources* res, RRMode mode
}
void RGFW_FUNC(RGFW_pollMonitors) (void) {
- RGFW_init();
+ RGFW_ASSERT(_RGFW && "An RGFW context must be initialized using RGFW_init and/or set with RGFW_setInfo");
Window root = XDefaultRootWindow(_RGFW->display);
XRRScreenResources* res = XRRGetScreenResourcesCurrent(_RGFW->display, root);
@@ -7858,14 +8664,6 @@ void RGFW_FUNC(RGFW_pollMonitors) (void) {
}
}
- if (node) {
- node->disconnected = RGFW_FALSE;
- if (node->rrOutput == primary) {
- _RGFW->monitors.primary = node;
- }
- continue;
- }
-
RGFW_monitor monitor;
XRROutputInfo* info = XRRGetOutputInfo(_RGFW->display, res, res->outputs[i]);
@@ -7914,20 +8712,32 @@ void RGFW_FUNC(RGFW_pollMonitors) (void) {
XRRFreeCrtcInfo(ci);
- node = RGFW_monitors_add(&monitor);
- if (node == NULL) break;
-
- node->rrOutput = res->outputs[i];
- node->crtc = info->crtc;
-
- if (node->rrOutput == primary) {
- _RGFW->monitors.primary = node;
- }
+ RROutput rrOutput = res->outputs[i];
+ RRCrtc crtc = info->crtc;
XRRFreeOutputInfo(info);
info = NULL;
- RGFW_monitorCallback(_RGFW->root, &node->mon, RGFW_TRUE);
+ if (node) {
+ node->disconnected = RGFW_FALSE;
+ if (node->rrOutput == primary) {
+ _RGFW->monitors.primary = node;
+ }
+
+ continue;
+ } else {
+ node = RGFW_monitors_add(&monitor);
+ if (node == NULL) break;
+
+ node->rrOutput = rrOutput;
+ node->crtc = crtc;
+
+ if (node->rrOutput == primary) {
+ _RGFW->monitors.primary = node;
+ }
+
+ RGFW_monitorCallback(_RGFW->root, &node->mon, RGFW_TRUE);
+ }
}
XRRFreeScreenResources(res);
@@ -7935,10 +8745,12 @@ void RGFW_FUNC(RGFW_pollMonitors) (void) {
RGFW_monitors_refresh();
}
-RGFW_bool RGFW_FUNC(RGFW_monitor_getWorkarea) (RGFW_monitor* monitor, i32* x, i32* y, i32* width, i32* height) {
- RGFW_LOAD_ATOM(_NET_WORKAREA);
- RGFW_LOAD_ATOM(_NET_CURRENT_DESKTOP);
+void RGFW_FUNC(RGFW_monitorNode_free) (RGFW_monitorNode* node) {
+ RGFW_ASSERT(node);
+}
+RGFW_bool RGFW_FUNC(RGFW_monitor_getWorkarea) (RGFW_monitor* monitor, i32* x, i32* y, i32* width, i32* height) {
+ RGFW_ASSERT(monitor != NULL);
Window root = DefaultRootWindow(_RGFW->display);
i32 areaX = monitor->x;
@@ -7946,17 +8758,17 @@ RGFW_bool RGFW_FUNC(RGFW_monitor_getWorkarea) (RGFW_monitor* monitor, i32* x, i3
i32 areaW = monitor->mode.w;
i32 areaH = monitor->mode.h;
- if (_NET_WORKAREA && _NET_CURRENT_DESKTOP) {
+ if (_RGFW->_NET_WORKAREA && _RGFW->_NET_CURRENT_DESKTOP) {
Atom* extents = NULL;
Atom* desktop = NULL;
Atom actualType = 0;
int actualFormat = 0;
unsigned long extentCount = 0, bytesAfter = 0;
- XGetWindowProperty(_RGFW->display, root, _NET_WORKAREA, 0, LONG_MAX, False, XA_CARDINAL, &actualType, &actualFormat, &extentCount, &bytesAfter, (u8**) &extents);
+ XGetWindowProperty(_RGFW->display, root, _RGFW->_NET_WORKAREA, 0, LONG_MAX, False, XA_CARDINAL, &actualType, &actualFormat, &extentCount, &bytesAfter, (u8**) &extents);
unsigned long count;
- XGetWindowProperty(_RGFW->display, root, _NET_CURRENT_DESKTOP, 0, LONG_MAX, False, XA_CARDINAL, &actualType, &actualFormat, &count, &bytesAfter, (u8**) &desktop);
+ XGetWindowProperty(_RGFW->display, root, _RGFW->_NET_CURRENT_DESKTOP, 0, LONG_MAX, False, XA_CARDINAL, &actualType, &actualFormat, &count, &bytesAfter, (u8**) &desktop);
if (count) {
if (extentCount >= 4 && *desktop < extentCount / 4) {
@@ -7997,6 +8809,7 @@ RGFW_bool RGFW_FUNC(RGFW_monitor_getWorkarea) (RGFW_monitor* monitor, i32* x, i3
}
size_t RGFW_FUNC(RGFW_monitor_getModesPtr) (RGFW_monitor* monitor, RGFW_monitorMode** modes) {
+ RGFW_ASSERT(monitor != NULL);
size_t count = 0;
XRRScreenResources* res = XRRGetScreenResourcesCurrent(_RGFW->display, DefaultRootWindow(_RGFW->display));
@@ -8020,8 +8833,8 @@ size_t RGFW_FUNC(RGFW_monitor_getModesPtr) (RGFW_monitor* monitor, RGFW_monitorM
}
size_t RGFW_FUNC(RGFW_monitor_getGammaRampPtr) (RGFW_monitor* monitor, RGFW_gammaRamp* ramp) {
+ RGFW_ASSERT(monitor != NULL);
RGFW_UNUSED(monitor); RGFW_UNUSED(ramp);
-#ifndef RGFW_NO_XRANDR
size_t size = (size_t)XRRGetCrtcGammaSize(_RGFW->display, monitor->node->crtc);
XRRCrtcGamma* gamma = XRRGetCrtcGamma(_RGFW->display, monitor->node->crtc);
@@ -8033,15 +8846,12 @@ size_t RGFW_FUNC(RGFW_monitor_getGammaRampPtr) (RGFW_monitor* monitor, RGFW_gamm
XRRFreeGamma(gamma);
return size;
-#endif
-
- return 0;
}
RGFW_bool RGFW_FUNC(RGFW_monitor_setGammaRamp) (RGFW_monitor* monitor, RGFW_gammaRamp* ramp) {
+ RGFW_ASSERT(monitor != NULL);
RGFW_UNUSED(monitor); RGFW_UNUSED(ramp);
-#ifndef RGFW_NO_XRANDR
size_t size = (size_t)XRRGetCrtcGammaSize(_RGFW->display, monitor->node->crtc);
if (size != ramp->count) {
RGFW_debugCallback(RGFW_typeError, RGFW_errX11, "X11: Gamma ramp size must match current ramp size");
@@ -8058,18 +8868,18 @@ RGFW_bool RGFW_FUNC(RGFW_monitor_setGammaRamp) (RGFW_monitor* monitor, RGFW_gamm
XRRFreeGamma(gamma);
return RGFW_TRUE;
-#endif
- return RGFW_FALSE;
}
RGFW_bool RGFW_FUNC(RGFW_monitor_setMode)(RGFW_monitor* mon, RGFW_monitorMode* mode) {
+ RGFW_ASSERT(mon != NULL);
RGFW_bool out = RGFW_FALSE;
XRRScreenResources* res = XRRGetScreenResourcesCurrent(_RGFW->display, DefaultRootWindow(_RGFW->display));
XRRCrtcInfo* ci = XRRGetCrtcInfo(_RGFW->display, res, mon->node->crtc);
- if (XRRSetCrtcConfig(_RGFW->display, res, mon->node->crtc, CurrentTime, ci->x, ci->y, (RRMode)mode->src, ci->rotation, ci->outputs, ci->noutput) == True) {
+ if (XRRSetCrtcConfig(_RGFW->display, res, mon->node->crtc, CurrentTime, ci->x, ci->y, (RRMode)mode->src, ci->rotation, ci->outputs, ci->noutput) == 0) {
out = RGFW_TRUE;
+ mon->mode = *mode;
}
XRRFreeCrtcInfo(ci);
@@ -8078,8 +8888,8 @@ RGFW_bool RGFW_FUNC(RGFW_monitor_setMode)(RGFW_monitor* mon, RGFW_monitorMode* m
}
RGFW_bool RGFW_FUNC(RGFW_monitor_requestMode)(RGFW_monitor* mon, RGFW_monitorMode* mode, RGFW_modeRequest request) {
- #ifndef RGFW_NO_XRANDR
- RGFW_init();
+ RGFW_ASSERT(mon != NULL);
+ RGFW_ASSERT(_RGFW && "An RGFW context must be initialized using RGFW_init and/or set with RGFW_setInfo");
RGFW_bool output = RGFW_FALSE;
@@ -8115,8 +8925,6 @@ RGFW_bool RGFW_FUNC(RGFW_monitor_requestMode)(RGFW_monitor* mon, RGFW_monitorMod
XRRFreeCrtcInfo(ci);
XRRFreeScreenResources(res);
return output;
-#endif
- return RGFW_FALSE;
}
RGFW_monitor* RGFW_FUNC(RGFW_window_getMonitor) (RGFW_window* win) {
@@ -8137,7 +8945,9 @@ RGFW_monitor* RGFW_FUNC(RGFW_window_getMonitor) (RGFW_window* win) {
}
#ifdef RGFW_OPENGL
-RGFW_bool RGFW_FUNC(RGFW_window_createContextPtr_OpenGL) (RGFW_window* win, RGFW_glContext* context, RGFW_glHints* hints) {
+RGFW_bool RGFW_FUNC(RGFW_createContextPtr_OpenGL) (RGFW_glContext* context, RGFW_glHints* hints) {
+ RGFW_ASSERT(_RGFW); RGFW_ASSERT(context); RGFW_ASSERT(hints);
+
/* for checking extensions later */
const char sRGBARBstr[] = "GLX_ARB_framebuffer_sRGB";
const char sRGBEXTstr[] = "GLX_EXT_framebuffer_sRGB";
@@ -8145,18 +8955,8 @@ RGFW_bool RGFW_FUNC(RGFW_window_createContextPtr_OpenGL) (RGFW_window* win, RGFW
const char flushStr[] = "GLX_ARB_context_flush_control";
const char robustStr[] = "GLX_ARB_create_context_robustness";
- /* basic RGFW int */
- win->src.ctx.native = context;
- win->src.gfxType = RGFW_gfxNativeOpenGL;
-
/* This is required so that way the user can create their own OpenGL context after RGFW_createWindow is used */
- RGFW_bool showWindow = RGFW_FALSE;
- if (win->src.window) {
- showWindow = (RGFW_window_isMinimized(win) == RGFW_FALSE);
- RGFW_window_closePlatform(win);
- }
-
- RGFW_bool transparent = (win->internal.flags & RGFW_windowTransparent);
+ RGFW_bool transparent = (hints->depth == 32);
/* start by creating a GLX config / X11 Viusal */
XVisualInfo visual;
@@ -8194,7 +8994,8 @@ RGFW_bool RGFW_FUNC(RGFW_window_createContextPtr_OpenGL) (RGFW_window* win, RGFW
/* find the configs */
i32 fbcount;
- GLXFBConfig* fbc = glXChooseFBConfig(_RGFW->display, DefaultScreen(_RGFW->display), visual_attribs, &fbcount);
+ GLXFBConfig* fbc = RGFW_glXChooseFBConfig(_RGFW->display, DefaultScreen(_RGFW->display), visual_attribs, &fbcount);
+ if (fbc == NULL) return RGFW_FALSE;
i32 best_fbc = -1;
i32 best_depth = 0;
@@ -8208,13 +9009,13 @@ RGFW_bool RGFW_FUNC(RGFW_window_createContextPtr_OpenGL) (RGFW_window* win, RGFW
/* search through all found configs to find the best match */
i32 i;
for (i = 0; i < fbcount; i++) {
- XVisualInfo* vi = glXGetVisualFromFBConfig(_RGFW->display, fbc[i]);
+ XVisualInfo* vi = RGFW_glXGetVisualFromFBConfig(_RGFW->display, fbc[i]);
if (vi == NULL)
continue;
i32 samp_buf, samples;
- glXGetFBConfigAttrib(_RGFW->display, fbc[i], GLX_SAMPLE_BUFFERS, &samp_buf);
- glXGetFBConfigAttrib(_RGFW->display, fbc[i], GLX_SAMPLES, &samples);
+ RGFW_glXGetFBConfigAttrib(_RGFW->display, fbc[i], GLX_SAMPLE_BUFFERS, &samp_buf);
+ RGFW_glXGetFBConfigAttrib(_RGFW->display, fbc[i], GLX_SAMPLES, &samples);
if (best_fbc == -1) best_fbc = i;
if ((!(transparent) || vi->depth == 32) && best_depth == 0) {
@@ -8236,32 +9037,22 @@ RGFW_bool RGFW_FUNC(RGFW_window_createContextPtr_OpenGL) (RGFW_window* win, RGFW
/* we found a config */
bestFbc = fbc[best_fbc];
- XVisualInfo* vi = glXGetVisualFromFBConfig(_RGFW->display, bestFbc);
- if (vi->depth != 32 && transparent)
- RGFW_debugCallback(RGFW_typeWarning, RGFW_warningOpenGL, "Failed to to find a matching visual with a 32-bit depth.");
+ context->config = bestFbc;
if (best_samples < hints->samples)
RGFW_debugCallback(RGFW_typeWarning, RGFW_warningOpenGL, "Failed to load a matching sample count.");
XFree(fbc);
- visual = *vi;
- XFree(vi);
-
- /* use the visual to create a new window */
- RGFW_XCreateWindow(visual, "", win->internal.flags, win);
-
- if (showWindow) {
- RGFW_window_show(win);
- }
/* create the actual OpenGL context */
i32 context_attribs[40];
RGFW_attribStack_init(&stack, context_attribs, 40);
i32 mask = 0;
+ i32 flags = 0;
+
switch (hints->profile) {
case RGFW_glES: mask |= GLX_CONTEXT_ES_PROFILE_BIT_EXT; break;
- case RGFW_glForwardCompatibility: mask |= GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB; break;
case RGFW_glCompatibility: mask |= GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB; break;
case RGFW_glCore: mask |= GLX_CONTEXT_CORE_PROFILE_BIT_ARB; break;
default: mask |= GLX_CONTEXT_CORE_PROFILE_BIT_ARB; break;
@@ -8269,12 +9060,18 @@ RGFW_bool RGFW_FUNC(RGFW_window_createContextPtr_OpenGL) (RGFW_window* win, RGFW
RGFW_attribStack_pushAttribs(&stack, GLX_CONTEXT_PROFILE_MASK_ARB, mask);
+ if (hints->profile == RGFW_glForwardCompatibility) flags |= GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB;
+ if (hints->debug) flags |= GLX_CONTEXT_DEBUG_BIT_ARB;
+ if (hints->robustness && RGFW_extensionSupportedPlatform_OpenGL(robustStr, sizeof(robustStr))) flags |= GLX_CONTEXT_ROBUST_ACCESS_BIT_ARB;
+ if (flags) {
+ RGFW_attribStack_pushAttribs(&stack, GLX_CONTEXT_FLAGS_ARB, flags);
+ }
+
if (hints->minor || hints->major) {
RGFW_attribStack_pushAttribs(&stack, GLX_CONTEXT_MAJOR_VERSION_ARB, hints->major);
RGFW_attribStack_pushAttribs(&stack, GLX_CONTEXT_MINOR_VERSION_ARB, hints->minor);
}
-
if (RGFW_extensionSupportedPlatform_OpenGL(flushStr, sizeof(flushStr))) {
if (hints->releaseBehavior == RGFW_glReleaseFlush) {
RGFW_attribStack_pushAttribs(&stack, GLX_CONTEXT_RELEASE_BEHAVIOR_ARB, GLX_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB);
@@ -8283,13 +9080,6 @@ RGFW_bool RGFW_FUNC(RGFW_window_createContextPtr_OpenGL) (RGFW_window* win, RGFW
}
}
- i32 flags = 0;
- if (hints->debug) flags |= GLX_CONTEXT_DEBUG_BIT_ARB;
- if (hints->robustness && RGFW_extensionSupportedPlatform_OpenGL(robustStr, sizeof(robustStr))) flags |= GLX_CONTEXT_ROBUST_ACCESS_BIT_ARB;
- if (flags) {
- RGFW_attribStack_pushAttribs(&stack, GLX_CONTEXT_FLAGS_ARB, flags);
- }
-
if (RGFW_extensionSupportedPlatform_OpenGL(noErorrStr, sizeof(noErorrStr))) {
RGFW_attribStack_pushAttribs(&stack, GLX_CONTEXT_OPENGL_NO_ERROR_ARB, hints->noError);
}
@@ -8297,111 +9087,207 @@ RGFW_bool RGFW_FUNC(RGFW_window_createContextPtr_OpenGL) (RGFW_window* win, RGFW
RGFW_attribStack_pushAttribs(&stack, 0, 0);
/* create the context */
- glXCreateContextAttribsARBProc glXCreateContextAttribsARB = 0;
- char str[] = "glXCreateContextAttribsARB";
- glXCreateContextAttribsARB = (glXCreateContextAttribsARBProc)glXGetProcAddressARB((u8*) str);
-
GLXContext ctx = NULL;
if (hints->share) {
ctx = hints->share->ctx;
}
- if (glXCreateContextAttribsARB == NULL) {
+ if (RGFW_glXCreateContextAttribsARB == NULL) {
RGFW_debugCallback(RGFW_typeError, RGFW_errOpenGLContext, "Failed to load proc address 'glXCreateContextAttribsARB', loading a generic OpenGL context.");
- win->src.ctx.native->ctx = glXCreateContext(_RGFW->display, &visual, ctx, True);
+ context->ctx = RGFW_glXCreateContext(_RGFW->display, &visual, ctx, True);
} else {
_RGFW->x11Error = NULL;
- win->src.ctx.native->ctx = glXCreateContextAttribsARB(_RGFW->display, bestFbc, ctx, True, context_attribs);
- if (_RGFW->x11Error || win->src.ctx.native->ctx == NULL) {
+ context->ctx = RGFW_glXCreateContextAttribsARB(_RGFW->display, bestFbc, ctx, True, context_attribs);
+ if (_RGFW->x11Error || context->ctx == NULL) {
RGFW_debugCallback(RGFW_typeError, RGFW_errOpenGLContext, "Failed to create an OpenGL context with AttribsARB, loading a generic OpenGL context.");
- win->src.ctx.native->ctx = glXCreateContext(_RGFW->display, &visual, ctx, True);
+ context->ctx = RGFW_glXCreateContext(_RGFW->display, &visual, ctx, True);
+ }
+ }
+
+ RGFW_debugCallback(RGFW_typeInfo, RGFW_infoOpenGL, "OpenGL context initalized.");
+ return RGFW_TRUE;
+}
+
+void RGFW_FUNC(RGFW_deleteContextPtr_OpenGL) (RGFW_glContext* ctx) {
+ RGFW_glXDestroyContext(_RGFW->display, ctx->ctx);
+ RGFW_debugCallback(RGFW_typeInfo, RGFW_infoOpenGL, "OpenGL context freed.");
+}
+
+RGFW_bool RGFW_FUNC(RGFW_window_setContext_OpenGL) (RGFW_window* win, RGFW_glContext* context) {
+ RGFW_ASSERT(win);
+
+ if (context == NULL && win->src.ctx.native != NULL) {
+ #ifndef RGFW_NO_GLXWINDOW
+ if (win->src.ctx.native->window != win->src.window) {
+ RGFW_glXDestroyWindow(_RGFW->display, win->src.ctx.native->window);
}
+ #endif
+
+ win->src.ctx.native = NULL;
+ RGFW_debugCallback(RGFW_typeInfo, RGFW_infoOpenGL, "OpenGL surface freed.");
+ return RGFW_TRUE;
+ }
+
+ /* basic RGFW int */
+ win->src.ctx.native = context;
+ win->src.gfxType = RGFW_gfxNativeOpenGL;
+
+ /* This is required so that way the user can create their own OpenGL context after RGFW_createWindow is used */
+ RGFW_bool showWindow = RGFW_FALSE;
+
+ char* name = NULL;
+ if (win->src.window) {
+ showWindow = (RGFW_window_isMinimized(win) == RGFW_FALSE);
+ name = RGFW_XGetWindowName(win->src.window);
+ RGFW_window_closePlatform(win);
+ }
+
+ XVisualInfo* vi = RGFW_glXGetVisualFromFBConfig(_RGFW->display, (GLXFBConfig)context->config);
+
+ /* use the visual to create a new window */
+ if (RGFW_XCreateWindow(*vi, name ? name : "", win->internal.flags, win) == RGFW_FALSE) return RGFW_FALSE;
+ if (name != NULL) XFree(name);
+
+ if (showWindow) {
+ RGFW_window_show(win);
}
#ifndef RGFW_NO_GLXWINDOW
- win->src.ctx.native->window = glXCreateWindow(_RGFW->display, bestFbc, win->src.window, NULL);
+ win->src.ctx.native->window = RGFW_glXCreateWindow(_RGFW->display, (GLXFBConfig)context->config, win->src.window, NULL);
#else
win->src.ctx.native->window = win->src.window;
#endif
- glXMakeCurrent(_RGFW->display, (Drawable)win->src.ctx.native->window, (GLXContext)win->src.ctx.native->ctx);
- RGFW_debugCallback(RGFW_typeInfo, RGFW_infoOpenGL, "OpenGL context initalized.");
+ RGFW_glXMakeCurrent(_RGFW->display, (Drawable)win->src.ctx.native->window, (GLXContext)win->src.ctx.native->ctx);
+ RGFW_debugCallback(RGFW_typeInfo, RGFW_infoOpenGL, "OpenGL surface initalized.");
RGFW_window_swapInterval_OpenGL(win, 0);
return RGFW_TRUE;
}
-void RGFW_FUNC(RGFW_window_deleteContextPtr_OpenGL) (RGFW_window* win, RGFW_glContext* ctx) {
- #ifndef RGFW_NO_GLXWINDOW
- if (win->src.ctx.native->window != win->src.window) {
- glXDestroyWindow(_RGFW->display, win->src.ctx.native->window);
- }
- #endif
-
- glXDestroyContext(_RGFW->display, ctx->ctx);
- win->src.ctx.native = NULL;
- RGFW_debugCallback(RGFW_typeInfo, RGFW_infoOpenGL, "OpenGL context freed.");
-}
-
RGFW_bool RGFW_FUNC(RGFW_extensionSupportedPlatform_OpenGL)(const char * extension, size_t len) {
- RGFW_init();
- const char* extensions = glXQueryExtensionsString(_RGFW->display, XDefaultScreen(_RGFW->display));
+ RGFW_ASSERT(_RGFW && "An RGFW context must be initialized using RGFW_init and/or set with RGFW_setInfo");
+ const char* extensions = RGFW_glXQueryExtensionsString(_RGFW->display, XDefaultScreen(_RGFW->display));
return (extensions != NULL) && RGFW_extensionSupportedStr(extensions, extension, len);
}
-RGFW_proc RGFW_FUNC(RGFW_getProcAddress_OpenGL)(const char* procname) { return glXGetProcAddress((u8*) procname); }
+RGFW_proc RGFW_FUNC(RGFW_getProcAddress_OpenGL)(const char* procname) { return _RGFW->glGetProcAddress((const char*) procname); }
void RGFW_FUNC(RGFW_window_makeCurrentContext_OpenGL) (RGFW_window* win) { if (win) RGFW_ASSERT(win->src.ctx.native);
if (win == NULL)
- glXMakeCurrent(NULL, (Drawable)NULL, (GLXContext) NULL);
+ RGFW_glXMakeCurrent(NULL, (Drawable)NULL, (GLXContext) NULL);
else
- glXMakeCurrent(_RGFW->display, (Drawable)win->src.ctx.native->window, (GLXContext) win->src.ctx.native->ctx);
+ RGFW_glXMakeCurrent(_RGFW->display, (Drawable)win->src.ctx.native->window, (GLXContext) win->src.ctx.native->ctx);
return;
}
-void* RGFW_FUNC(RGFW_getCurrentContext_OpenGL) (void) { return glXGetCurrentContext(); }
-void RGFW_FUNC(RGFW_window_swapBuffers_OpenGL) (RGFW_window* win) { RGFW_ASSERT(win->src.ctx.native); glXSwapBuffers(_RGFW->display, win->src.ctx.native->window); }
+void* RGFW_FUNC(RGFW_getCurrentContext_OpenGL) (void) { return RGFW_glXGetCurrentContext(); }
+void* RGFW_FUNC(RGFW_getCurrentSurface_OpenGL) (void) { return RGFW_glXGetCurrentDrawable(); }
+void RGFW_FUNC(RGFW_window_swapBuffers_OpenGL) (RGFW_window* win) { RGFW_ASSERT(win->src.ctx.native); RGFW_glXSwapBuffers(_RGFW->display, win->src.ctx.native->window); }
void RGFW_FUNC(RGFW_window_swapInterval_OpenGL) (RGFW_window* win, i32 swapInterval) {
RGFW_ASSERT(win != NULL);
- /* cached pfn to avoid calling glXGetProcAddress more than once */
- static PFNGLXSWAPINTERVALEXTPROC pfn = NULL;
- static int (*pfn2)(int) = NULL;
-
- if (pfn == NULL) {
- u8 str[] = "glXSwapIntervalEXT";
- pfn = (PFNGLXSWAPINTERVALEXTPROC)glXGetProcAddress(str);
- if (pfn == NULL) {
- pfn = (PFNGLXSWAPINTERVALEXTPROC)1;
- const char* array[] = {"GLX_MESA_swap_control", "GLX_SGI_swap_control"};
+ if (RGFW_glXSwapIntervalEXT) {
+ RGFW_glXSwapIntervalEXT(_RGFW->display, win->src.ctx.native->window, swapInterval);
+ } else if (RGFW_GLX_MESA_swap_control || RGFW_GLX_SGI_swap_control) {
+ void* ctx = RGFW_getCurrentContext_OpenGL();
+ void* surf = RGFW_getCurrentSurface_OpenGL();
+ if (ctx != win->src.ctx.native->ctx || (Drawable)surf != win->src.ctx.native->window)
+ RGFW_glXMakeCurrent(_RGFW->display, (Drawable)win->src.ctx.native->window, (GLXContext) win->src.ctx.native->ctx);
- size_t i;
- for (i = 0; i < sizeof(array) / sizeof(char*) && pfn2 == NULL; i++) {
- pfn2 = (int(*)(int))glXGetProcAddress((u8*)array[i]);
- }
-
- if (pfn2 != NULL) {
- RGFW_debugCallback(RGFW_typeError, RGFW_errOpenGLContext, "Failed to load swap interval function, fallingback to the native swapinterval function");
+ if (RGFW_GLX_MESA_swap_control)
+ RGFW_GLX_MESA_swap_control(swapInterval);
+ else if (RGFW_GLX_SGI_swap_control) {
+ if (swapInterval > 0) {
+ RGFW_GLX_SGI_swap_control(swapInterval);
} else {
- RGFW_debugCallback(RGFW_typeError, RGFW_errOpenGLContext, "Failed to load swap interval function");
+ RGFW_debugCallback(RGFW_typeWarning, RGFW_errOpenGLContext, "Failed to disable swap interval, not supported with GLX_SGI_swap_control");
}
}
- }
- if (pfn != (PFNGLXSWAPINTERVALEXTPROC)1) {
- pfn(_RGFW->display, win->src.ctx.native->window, swapInterval);
- }
- else if (pfn2 != NULL) {
- pfn2(swapInterval);
+ if (ctx != win->src.ctx.native->ctx || (Drawable)surf != win->src.ctx.native->window)
+ RGFW_glXMakeCurrent(_RGFW->display, (Drawable)surf, (GLXContext)ctx);
+ } else {
+ RGFW_debugCallback(RGFW_typeWarning, RGFW_errOpenGLContext, "Failed to load swap interval function");
}
}
#endif /* RGFW_OPENGL */
-i32 RGFW_initPlatform_X11(void) {
+i32 RGFW_initPlatform_X11(const char* className, RGFW_initFlags flags) {
+ _RGFW->className = className;
+ RGFW_UNUSED(flags);
+
#ifdef RGFW_USE_XDL
XDL_init();
#endif
+ XInitThreads(); /*!< init X11 threading */
+ _RGFW->display = XOpenDisplay(0);
+
+#ifdef RGFW_X11_DEBUG
+ XSynchronize(_RGFW->display, True);
+#endif
+
+ if (_RGFW->display == NULL) return -1;
+
+ #define RGFW_LOAD_ATOM(name) _RGFW->name = XInternAtom(_RGFW->display, #name, False)
+ RGFW_LOAD_ATOM(_NET_CURRENT_DESKTOP);
+ RGFW_LOAD_ATOM(_NET_WM_STATE_MAXIMIZED_VERT);
+ RGFW_LOAD_ATOM(_NET_WM_STATE_MAXIMIZED_HORZ);
+ RGFW_LOAD_ATOM(_NET_WM_BYPASS_COMPOSITOR);
+ RGFW_LOAD_ATOM(_NET_WM_STATE);
+ RGFW_LOAD_ATOM(_NET_WM_STATE_MAXIMIZED_VERT);
+ RGFW_LOAD_ATOM(_NET_WM_STATE_MAXIMIZED_HORZ);
+ RGFW_LOAD_ATOM(_MOTIF_WM_HINTS);
+ RGFW_LOAD_ATOM(WM_DELETE_WINDOW);
+ RGFW_LOAD_ATOM(_NET_WM_SYNC_REQUEST_COUNTER);
+ RGFW_LOAD_ATOM(_NET_WM_SYNC_REQUEST);
+ RGFW_LOAD_ATOM(ATOM_PAIR);
+ RGFW_LOAD_ATOM(MULTIPLE);
+ RGFW_LOAD_ATOM(TARGETS);
+ RGFW_LOAD_ATOM(SAVE_TARGETS);
+ RGFW_LOAD_ATOM(UTF8_STRING);
+ RGFW_LOAD_ATOM(XdndTypeList);
+ RGFW_LOAD_ATOM(XdndSelection);
+ RGFW_LOAD_ATOM(XdndAware);
+ RGFW_LOAD_ATOM(XdndEnter);
+ RGFW_LOAD_ATOM(XdndPosition);
+ RGFW_LOAD_ATOM(XdndStatus);
+ RGFW_LOAD_ATOM(XdndLeave);
+ RGFW_LOAD_ATOM(XdndDrop);
+ RGFW_LOAD_ATOM(XdndFinished);
+ RGFW_LOAD_ATOM(XdndActionCopy);
+ RGFW_LOAD_ATOM(_NET_WM_SYNC_REQUEST);
+ RGFW_LOAD_ATOM(WM_PROTOCOLS);
+ RGFW_LOAD_ATOM(WM_STATE);
+ RGFW_LOAD_ATOM(_NET_WM_STATE);
+ RGFW_LOAD_ATOM(_NET_WM_STATE_FULLSCREEN);
+ RGFW_LOAD_ATOM(_NET_WM_STATE_ABOVE);
+ RGFW_LOAD_ATOM(NET_WM_WINDOW_OPACITY);
+ RGFW_LOAD_ATOM(_NET_WM_STATE);
+ RGFW_LOAD_ATOM(_NET_WM_STATE_ABOVE);
+ RGFW_LOAD_ATOM(_NET_WM_NAME);
+ RGFW_LOAD_ATOM(_NET_WM_ICON);
+ RGFW_LOAD_ATOM(UTF8_STRING);
+ RGFW_LOAD_ATOM(XSEL_DATA);
+ RGFW_LOAD_ATOM(UTF8_STRING);
+ RGFW_LOAD_ATOM(CLIPBOARD);
+ RGFW_LOAD_ATOM(CLIPBOARD_MANAGER);
+ _RGFW->XtextUriList = XInternAtom(_RGFW->display, "text/uri-list", False);
+ _RGFW->XtextPlain = XInternAtom(_RGFW->display, "text/plain", False);
+ #undef RGFW_LOAD_ATOM
+
+ _RGFW->context = XUniqueContext();
+ if (_RGFW->context == 0) return -1;
+
+ XSetWindowAttributes wa;
+ RGFW_MEMZERO(&wa, sizeof(wa));
+ wa.event_mask = PropertyChangeMask;
+ _RGFW->helperWindow = XCreateWindow(_RGFW->display, XDefaultRootWindow(_RGFW->display), 0, 0, 1, 1, 0, 0,
+ InputOnly, DefaultVisual(_RGFW->display, DefaultScreen(_RGFW->display)), CWEventMask, &wa);
+
+ if (_RGFW->helperWindow == 0) return -1;
+
#if !defined(RGFW_NO_X11_CURSOR) && !defined(RGFW_NO_X11_CURSOR_PRELOAD)
#if defined(__CYGWIN__)
RGFW_LOAD_LIBRARY(X11Cursorhandle, "libXcursor-1.so");
@@ -8441,25 +9327,17 @@ i32 RGFW_initPlatform_X11(void) {
RGFW_PROC_DEF(X11XEXThandle, XShapeCombineMask);
#endif
- XInitThreads(); /*!< init X11 threading */
- _RGFW->display = XOpenDisplay(0);
- _RGFW->context = XUniqueContext();
-
- XSetWindowAttributes wa;
- RGFW_MEMZERO(&wa, sizeof(wa));
- wa.event_mask = PropertyChangeMask;
- _RGFW->helperWindow = XCreateWindow(_RGFW->display, XDefaultRootWindow(_RGFW->display), 0, 0, 1, 1, 0, 0,
- InputOnly, DefaultVisual(_RGFW->display, DefaultScreen(_RGFW->display)), CWEventMask, &wa);
-
u8 RGFW_blk[] = { 0, 0, 0, 0 };
_RGFW->hiddenMouse = RGFW_createMouse(RGFW_blk, 1, 1, RGFW_formatRGBA8);
- _RGFW->clipboard = NULL;
+ _RGFW->unixClipboard = NULL;
XkbComponentNamesRec rec;
XkbDescPtr desc = XkbGetMap(_RGFW->display, 0, XkbUseCoreKbd);
XkbDescPtr evdesc;
XSetErrorHandler(RGFW_XErrorHandler);
+ XSync(_RGFW->display, False);
+
u8 old[256];
XkbGetNames(_RGFW->display, XkbKeyNamesMask, desc);
@@ -8490,47 +9368,35 @@ i32 RGFW_initPlatform_X11(void) {
XSetLocaleModifiers("");
XRegisterIMInstantiateCallback(_RGFW->display, NULL, NULL, NULL, RGFW_x11_imInitCallback, NULL);
- unsigned char mask[XIMaskLen(XI_RawMotion)];
- RGFW_MEMZERO(mask, sizeof(mask));
- XISetMask(mask, XI_RawMotion);
-
- XIEventMask em;
- em.deviceid = XIAllMasterDevices;
- em.mask_len = sizeof(mask);
- em.mask = mask;
-
- XISelectEvents(_RGFW->display, XDefaultRootWindow(_RGFW->display), &em, 1);
-
-#ifndef RGFW_NO_XRANDR
i32 errorBase;
if (XRRQueryExtension(_RGFW->display, &_RGFW->xrandrEventBase, &errorBase)) {
XRRSelectInput(_RGFW->display, RootWindow(_RGFW->display, DefaultScreen(_RGFW->display)), RROutputChangeNotifyMask);
}
-#endif
return 0;
}
void RGFW_deinitPlatform_X11(void) {
#define RGFW_FREE_LIBRARY(x) if (x != NULL) dlclose(x); x = NULL;
- /* to save the clipboard on the x server after the window is closed */
- RGFW_LOAD_ATOM(CLIPBOARD_MANAGER); RGFW_LOAD_ATOM(CLIPBOARD);
- RGFW_LOAD_ATOM(SAVE_TARGETS);
- if (XGetSelectionOwner(_RGFW->display, CLIPBOARD) == _RGFW->helperWindow) {
- XConvertSelection(_RGFW->display, CLIPBOARD_MANAGER, SAVE_TARGETS, None, _RGFW->helperWindow, CurrentTime);
- while (RGFW_XHandleClipboardSelectionHelper());
- }
- XUnregisterIMInstantiateCallback(_RGFW->display, NULL, NULL, NULL, RGFW_x11_imInitCallback, NULL);
+ if (_RGFW->display != NULL) {
+ /* to save the clipboard on the x server after the window is closed */
+ if (XGetSelectionOwner(_RGFW->display, _RGFW->CLIPBOARD) == _RGFW->helperWindow) {
+ XConvertSelection(_RGFW->display, _RGFW->CLIPBOARD_MANAGER, _RGFW->SAVE_TARGETS, None, _RGFW->helperWindow, CurrentTime);
+ while (RGFW_XHandleClipboardSelectionHelper());
+ }
+
+ XUnregisterIMInstantiateCallback(_RGFW->display, NULL, NULL, NULL, RGFW_x11_imInitCallback, NULL);
+ }
if (_RGFW->im) {
XCloseIM(_RGFW->im);
_RGFW->im = NULL;
}
- if (_RGFW->clipboard) {
- RGFW_FREE(_RGFW->clipboard);
- _RGFW->clipboard = NULL;
+ if (_RGFW->unixClipboard) {
+ RGFW_FREE(_RGFW->unixClipboard);
+ _RGFW->unixClipboard = NULL;
}
if (_RGFW->hiddenMouse) {
@@ -8538,8 +9404,12 @@ void RGFW_deinitPlatform_X11(void) {
_RGFW->hiddenMouse = NULL;
}
- XDestroyWindow(_RGFW->display, (Drawable) _RGFW->helperWindow); /*!< close the window */
- XCloseDisplay(_RGFW->display); /*!< kill connection to the x server */
+ if (_RGFW->helperWindow)
+ XDestroyWindow(_RGFW->display, (Drawable) _RGFW->helperWindow); /*!< close the window */
+
+ if (_RGFW->display)
+ XCloseDisplay(_RGFW->display); /*!< kill connection to the x server */
+ _RGFW->display = NULL;
#if !defined(RGFW_NO_X11_CURSOR_PRELOAD) && !defined(RGFW_NO_X11_CURSOR)
RGFW_FREE_LIBRARY(X11Cursorhandle);
@@ -8584,12 +9454,12 @@ WGPUSurface RGFW_FUNC(RGFW_window_createSurface_WebGPU) (RGFW_window* window, WG
#endif
/*
- End of X11 linux / wayland / unix defines
+ End of *nix
*/
/*
- Start of Wayland defayland
+ Start of Wayland defines
*/
#ifdef RGFW_WAYLAND
@@ -8600,24 +9470,6 @@ WGPUSurface RGFW_FUNC(RGFW_window_createSurface_WebGPU) (RGFW_window* window, WG
#define RGFW_FUNC(func) func
#endif
-/*
-Wayland TODO: (out of date)
-- fix RGFW_keyPressed lock state
-
- RGFW_windowMoved, the window was moved (by the user)
- RGFW_windowRefresh The window content needs to be refreshed
-
- RGFW_dataDrop a file has been dropped into the window
- RGFW_dataDrag
-
-- window args:
- #define RGFW_windowNoResize the window cannot be resized by the user
- #define RGFW_windowAllowDND the window supports drag and drop
- #define RGFW_scaleToMonitor scale the window to the screen
-
-- other missing functions functions ("TODO wayland") (~30 functions)
-- fix buffer rendering weird behavior
-*/
#include <errno.h>
#include <unistd.h>
#include <sys/mman.h>
@@ -8629,10 +9481,13 @@ Wayland TODO: (out of date)
#include <wayland-cursor.h>
#include <fcntl.h>
+#ifndef RGFW_X11
+RGFW_bool RGFW_usingWayland(void) { return RGFW_TRUE; }
+#endif
+
struct wl_display* RGFW_getDisplay_Wayland(void) { return _RGFW->wl_display; }
struct wl_surface* RGFW_window_getWindow_Wayland(RGFW_window* win) { return win->src.surface; }
-
/* wayland global garbage (wayland bad, X11 is fine (ish) (not really)) */
#include "xdg-shell.h"
#include "xdg-toplevel-icon-v1.h"
@@ -8825,7 +9680,7 @@ static void RGFW_wl_pointer_motion(void* data, struct wl_pointer *pointer, u32 t
i32 convertedX = (i32)wl_fixed_to_double(x);
i32 convertedY = (i32)wl_fixed_to_double(y);
- RGFW_mousePosCallback(win, convertedX, convertedY);
+ RGFW_mouseMotionCallback(win, convertedX, convertedY);
}
static void RGFW_wl_pointer_button(void* data, struct wl_pointer *pointer, u32 serial, u32 time, u32 button, u32 state) {
@@ -8902,7 +9757,6 @@ static void RGFW_wl_keyboard_enter(void* data, struct wl_keyboard *keyboard, u32
RGFW_window* win = (RGFW_window*)wl_surface_get_user_data(surface);
RGFW->kbOwner = win;
-
// this is to prevent race conditions
if (RGFW->data_device != NULL && win->src.data_source != NULL) {
wl_data_device_set_selection(RGFW->data_device, win->src.data_source, serial);
@@ -9136,7 +9990,7 @@ static void RGFW_wl_output_handle_done(void* data, struct wl_output* output) {
return;
}
- ((RGFW_monitorNode*)data)->disconnected = RGFW_TRUE;
+ ((RGFW_monitorNode*)data)->disconnected = RGFW_FALSE;
RGFW_monitorCallback(_RGFW->root, monitor, RGFW_TRUE);
}
@@ -9150,7 +10004,7 @@ static void RGFW_wl_create_outputs(struct wl_registry *const registry, u32 id) {
char RGFW_mon_default_name[10];
- RGFW_SNPRINTF(RGFW_mon_default_name, sizeof(RGFW_mon_default_name), "monitor-%li", _RGFW->monitors.count);
+ RGFW_SNPRINTF(RGFW_mon_default_name, sizeof(RGFW_mon_default_name), "monitor-%zu", _RGFW->monitors.count);
RGFW_STRNCPY(mon.name, RGFW_mon_default_name, sizeof(mon.name) - 1);
mon.name[sizeof(mon.name) - 1] = '\0';
@@ -9212,7 +10066,11 @@ static void RGFW_wl_data_source_send(void *data, struct wl_data_source *wl_data_
// a client can accept our clipboard
if (RGFW_STRNCMP(mime_type, "text/plain;charset=utf-8", 25) == 0) {
// do not write \0
- write(fd, _RGFW->clipboard, _RGFW->clipboard_len - 1);
+ size_t length = _RGFW->unixClipboard->length;
+ if (_RGFW->unixClipboard->data[0] == '\0') {
+ length -= 1;
+ }
+ write(fd, _RGFW->unixClipboard->data, length);
}
close(fd);
@@ -9222,7 +10080,7 @@ static void RGFW_wl_data_source_cancelled(void *data, struct wl_data_source *wl_
RGFW_info* RGFW = (RGFW_info*)data;
- if (RGFW->kbOwner->src.data_source == wl_data_source) {
+ if (RGFW->kbOwner && RGFW->kbOwner->src.data_source == wl_data_source) {
RGFW->kbOwner->src.data_source = NULL;
}
@@ -9251,7 +10109,7 @@ static void RGFW_wl_data_device_selection(void *data, struct wl_data_device *wl_
int pfds[2];
pipe(pfds);
- wl_data_offer_receive(wl_data_offer, "text/plain;charset=utf-8", pfds[1]);
+ wl_data_offer_receive(wl_data_offer, "text/plain", pfds[1]);
close(pfds[1]);
wl_display_roundtrip(_RGFW->wl_display);
@@ -9259,12 +10117,27 @@ static void RGFW_wl_data_device_selection(void *data, struct wl_data_device *wl_
char buf[1024];
ssize_t n = read(pfds[0], buf, sizeof(buf));
+ if (n <= 0) {
+ close(pfds[0]);
+ wl_data_offer_destroy(wl_data_offer);
+ return;
+ }
+
+ size_t length = (size_t)n;
+ if (buf[n - 1] != '\0') length += 1;
+
+ if (_RGFW->unixClipboard != NULL) RGFW_FREE(_RGFW->unixClipboard);
- _RGFW->clipboard = (char*)RGFW_ALLOC((size_t)n);
- RGFW_ASSERT(_RGFW->clipboard != NULL);
- RGFW_STRNCPY(_RGFW->clipboard, buf, (size_t)n);
+ _RGFW->unixClipboard = (RGFW_dataTransfer*)RGFW_ALLOC(sizeof(RGFW_dataTransfer) + (size_t)n);
+ RGFW_ASSERT(_RGFW->unixClipboard != NULL);
- _RGFW->clipboard_len = (size_t)n + 1;
+ char* data_ptr = &((char*)(void*)_RGFW->unixClipboard)[sizeof(RGFW_dataTransfer) - 1];
+ RGFW_MEMCPY(data_ptr, buf, (size_t)n);
+ data_ptr[length - 1] = '\0';
+
+ _RGFW->unixClipboard->data = data_ptr;
+ _RGFW->unixClipboard->type = RGFW_dataText;
+ _RGFW->unixClipboard->length = length;
close(pfds[0]);
@@ -9328,19 +10201,6 @@ static void RGFW_wl_global_registry_remove(void* data, struct wl_registry *regis
node = prev;
}
- if (node->output) {
- wl_output_destroy(node->output);
- }
-
- if (node->xdg_output) {
- zxdg_output_v1_destroy(node->xdg_output);
- }
-
- if (node->modeCount) {
- RGFW_FREE(node->modes);
- node->modeCount = 0;
- }
-
RGFW_monitorCallback(_RGFW->root, &node->mon, RGFW_FALSE);
RGFW_monitors_remove(node, prev);
}
@@ -9390,7 +10250,8 @@ static int RGFW_wl_create_shm_file(off_t size) {
return fd;
}
-i32 RGFW_initPlatform_Wayland(void) {
+i32 RGFW_initPlatform_Wayland(const char* className, RGFW_initFlags flags) {
+ RGFW_UNUSED(className); RGFW_UNUSED(flags);
_RGFW->wl_display = wl_display_connect(NULL);
if (_RGFW->wl_display == NULL) {
RGFW_debugCallback(RGFW_typeError, RGFW_errWayland, "Failed to load Wayland display");
@@ -9410,7 +10271,7 @@ i32 RGFW_initPlatform_Wayland(void) {
if (_RGFW->compositor == NULL) {
RGFW_debugCallback(RGFW_typeError, RGFW_errWayland, "Can't find compositor.");
- return 1;
+ return -1;
}
if (_RGFW->wl_cursor_theme == NULL) {
@@ -9447,9 +10308,9 @@ i32 RGFW_initPlatform_Wayland(void) {
}
void RGFW_deinitPlatform_Wayland(void) {
- if (_RGFW->clipboard) {
- RGFW_FREE(_RGFW->clipboard);
- _RGFW->clipboard = NULL;
+ if (_RGFW->unixClipboard) {
+ RGFW_FREE(_RGFW->unixClipboard);
+ _RGFW->unixClipboard = NULL;
}
if (_RGFW->wl_pointer) {
@@ -9459,7 +10320,10 @@ void RGFW_deinitPlatform_Wayland(void) {
wl_keyboard_destroy(_RGFW->wl_keyboard);
}
- wl_registry_destroy(_RGFW->registry);
+ if (_RGFW->registry) {
+ wl_registry_destroy(_RGFW->registry);
+ }
+
if (_RGFW->decoration_manager != NULL)
zxdg_decoration_manager_v1_destroy(_RGFW->decoration_manager);
if (_RGFW->relative_pointer_manager != NULL) {
@@ -9474,7 +10338,6 @@ void RGFW_deinitPlatform_Wayland(void) {
zwp_pointer_constraints_v1_destroy(_RGFW->constraint_manager);
}
- if (_RGFW->xdg_output_manager != NULL)
if (_RGFW->icon_manager != NULL) {
xdg_toplevel_icon_manager_v1_destroy(_RGFW->icon_manager);
}
@@ -9499,30 +10362,27 @@ void RGFW_deinitPlatform_Wayland(void) {
wp_pointer_warp_v1_destroy(_RGFW->wp_pointer_warp);
}
- RGFW_freeMouse(_RGFW->hiddenMouse);
+ if (_RGFW->hiddenMouse) {
+ RGFW_freeMouse(_RGFW->hiddenMouse);
+ }
- RGFW_monitorNode* node = _RGFW->monitors.list.head;
+ if (_RGFW->cursor_surface)
+ wl_surface_destroy(_RGFW->cursor_surface);
- while (node != NULL) {
- if (node->output) {
- wl_output_destroy(node->output);
- }
+ if (_RGFW->shm)
+ wl_shm_destroy(_RGFW->shm);
- if (node->xdg_output) {
- zxdg_output_v1_destroy(node->xdg_output);
- }
+ if (_RGFW->seat)
+ wl_seat_release(_RGFW->seat);
- _RGFW->monitors.count -= 1;
- node = node->next;
+ if (_RGFW->xdg_wm_base)
+ xdg_wm_base_destroy(_RGFW->xdg_wm_base);
- }
+ if (_RGFW->compositor)
+ wl_compositor_destroy(_RGFW->compositor);
- wl_surface_destroy(_RGFW->cursor_surface);
- wl_shm_destroy(_RGFW->shm);
- wl_seat_release(_RGFW->seat);
- xdg_wm_base_destroy(_RGFW->xdg_wm_base);
- wl_compositor_destroy(_RGFW->compositor);
- wl_display_disconnect(_RGFW->wl_display);
+ if (_RGFW->wl_display)
+ wl_display_disconnect(_RGFW->wl_display);
}
RGFW_format RGFW_FUNC(RGFW_nativeFormat)(void) { return RGFW_formatBGRA8; }
@@ -9661,9 +10521,6 @@ RGFW_window* RGFW_FUNC(RGFW_createWindowPlatform) (const char* name, RGFW_window
win->src.xdg_toplevel = xdg_surface_get_toplevel(win->src.xdg_surface);
- if (_RGFW->className == NULL)
- _RGFW->className = (char*)name;
-
xdg_toplevel_set_app_id(win->src.xdg_toplevel, name);
xdg_surface_set_window_geometry(win->src.xdg_surface, 0, 0, win->w, win->h);
@@ -9746,21 +10603,25 @@ RGFW_window* RGFW_FUNC(RGFW_createWindowPlatform) (const char* name, RGFW_window
}
RGFW_bool RGFW_FUNC(RGFW_getGlobalMouse) (i32* x, i32* y) {
- RGFW_init();
+ RGFW_ASSERT(_RGFW && "An RGFW context must be initialized using RGFW_init and/or set with RGFW_setInfo");
if (x) *x = 0;
if (y) *y = 0;
return RGFW_FALSE;
}
RGFW_key RGFW_FUNC(RGFW_physicalToMappedKey)(RGFW_key key) {
- u32 keycode = RGFW_rgfwToApiKey(key);
- xkb_keycode_t kc = keycode + 8;
- xkb_keysym_t sym = xkb_state_key_get_one_sym(_RGFW->xkb_state, kc);
+ xkb_keycode_t keycode = (xkb_keycode_t)RGFW_rgfwToApiKey(key);
+ xkb_keysym_t sym = xkb_state_key_get_one_sym(_RGFW->xkb_state, keycode);
if (sym < 256) {
return (RGFW_key)sym;
}
switch (sym) {
+ case XKB_KEY_BackSpace: return RGFW_keyBackSpace;
+ case XKB_KEY_Tab: return RGFW_keyTab;
+ case XKB_KEY_Return: return RGFW_keyReturn;
+ case XKB_KEY_Escape: return RGFW_keyEscape;
+ case XKB_KEY_Delete: return RGFW_keyDelete;
case XKB_KEY_F1: return RGFW_keyF1;
case XKB_KEY_F2: return RGFW_keyF2;
case XKB_KEY_F3: return RGFW_keyF3;
@@ -9852,7 +10713,7 @@ void RGFW_FUNC(RGFW_pollEvents) (void) {
}
}
if (_RGFW->wl_repeat_info_rate != 0 && _RGFW->last_key) {
- u32 now = (u32)(RGFW_linux_getTimeNS() / 1000000);
+ u32 now = (u32)(RGFW_unix_getTimeNS() / 1000000);
if (now > _RGFW->last_key_time) {
RGFW_wl_send_key_event(_RGFW->last_key);
_RGFW->last_key_time = now + 1000 / (u32)_RGFW->wl_repeat_info_rate;
@@ -9861,25 +10722,41 @@ void RGFW_FUNC(RGFW_pollEvents) (void) {
/* read the events; if empty this reads from the */
/* wayland file descriptor */
- if (wl_display_dispatch(_RGFW->wl_display) == -1) {
- return;
- }
+ struct pollfd fds;
+ memset(&fds, 0, sizeof(fds));
+ fds.fd = wl_display_get_fd(_RGFW->wl_display);
+ fds.events = POLLIN;
+ fds.revents = 0;
-}
+ while (1) {
+ while (wl_display_prepare_read(_RGFW->wl_display) != 0) {
+ if (wl_display_dispatch_pending(_RGFW->wl_display) > 0)
+ return;
+ }
-void RGFW_FUNC(RGFW_window_move) (RGFW_window* win, i32 x, i32 y) {
- RGFW_ASSERT(win != NULL);
- win->x = x;
- win->y = y;
+ if (poll(&fds, 1, 0) == 0) {
+ wl_display_cancel_read(_RGFW->wl_display);
+ return;
+ }
+
+ if (fds.revents & POLLIN) {
+ wl_display_read_events(_RGFW->wl_display);
+ if (wl_display_dispatch_pending(_RGFW->wl_display) > 0) {
+ return;
+ }
+ } else {
+ wl_display_cancel_read(_RGFW->wl_display);
+ }
+ }
}
+void RGFW_FUNC(RGFW_window_movePlatform) (RGFW_window* win, i32 x, i32 y) {
+ RGFW_UNUSED(win); RGFW_UNUSED(x); RGFW_UNUSED(y);
+}
-void RGFW_FUNC(RGFW_window_resize) (RGFW_window* win, i32 w, i32 h) {
- RGFW_ASSERT(win != NULL);
- win->w = w;
- win->h = h;
+void RGFW_FUNC(RGFW_window_resizePlatform) (RGFW_window* win, i32 w, i32 h) {
if (_RGFW->compositor) {
- xdg_surface_set_window_geometry(win->src.xdg_surface, 0, 0, win->w, win->h);
+ xdg_surface_set_window_geometry(win->src.xdg_surface, 0, 0, w, h);
#ifdef RGFW_OPENGL
if (win->src.ctx.egl)
wl_egl_window_resize(win->src.ctx.egl->eglWindow, (i32)w, (i32)h, 0, 0);
@@ -9914,13 +10791,8 @@ void RGFW_toggleWaylandMaximized(RGFW_window* win, RGFW_bool maximized) {
}
}
-void RGFW_FUNC(RGFW_window_maximize) (RGFW_window* win) {
- win->internal.oldX = win->x;
- win->internal.oldY = win->y;
- win->internal.oldW = win->w;
- win->internal.oldH = win->h;
+void RGFW_FUNC(RGFW_window_maximizePlatform) (RGFW_window* win) {
RGFW_toggleWaylandMaximized(win, 1);
- RGFW_window_fetchSize(win, NULL, NULL);
return;
}
@@ -9932,21 +10804,12 @@ void RGFW_FUNC(RGFW_window_raise)(RGFW_window* win) {
RGFW_ASSERT(win);
}
-void RGFW_FUNC(RGFW_window_setFullscreen)(RGFW_window* win, RGFW_bool fullscreen) {
- RGFW_ASSERT(win != NULL);
+void RGFW_FUNC(RGFW_window_setFullscreenPlatform)(RGFW_window* win, RGFW_bool fullscreen) {
if (fullscreen) {
-
- win->internal.flags |= RGFW_windowFullscreen;
- win->internal.oldX = win->x;
- win->internal.oldY = win->y;
- win->internal.oldW = win->w;
- win->internal.oldH = win->h;
xdg_toplevel_set_fullscreen(win->src.xdg_toplevel, NULL); /* let the compositor decide */
} else {
- win->internal.flags &= ~(u32)RGFW_windowFullscreen;
xdg_toplevel_unset_fullscreen(win->src.xdg_toplevel);
}
-
}
void RGFW_FUNC(RGFW_window_setFloating) (RGFW_window* win, RGFW_bool floating) {
@@ -9959,7 +10822,7 @@ void RGFW_FUNC(RGFW_window_setOpacity) (RGFW_window* win, u8 opacity) {
RGFW_UNUSED(opacity);
}
-void RGFW_FUNC(RGFW_window_minimize)(RGFW_window* win) {
+void RGFW_FUNC(RGFW_window_minimizePlatform)(RGFW_window* win) {
RGFW_ASSERT(win != NULL);
if (RGFW_window_isMaximized(win)) return;
win->internal.oldX = win->x;
@@ -9970,18 +10833,9 @@ void RGFW_FUNC(RGFW_window_minimize)(RGFW_window* win) {
xdg_toplevel_set_minimized(win->src.xdg_toplevel);
}
-void RGFW_FUNC(RGFW_window_restore)(RGFW_window* win) {
+void RGFW_FUNC(RGFW_window_restorePlatform)(RGFW_window* win) {
RGFW_ASSERT(win != NULL);
RGFW_toggleWaylandMaximized(win, RGFW_FALSE);
-
- RGFW_window_move(win, win->internal.oldX, win->internal.oldY);
- RGFW_window_resize(win, win->internal.oldW, win->internal.oldH);
-
- RGFW_window_show(win);
- RGFW_window_move(win, win->internal.oldX, win->internal.oldY);
- RGFW_window_resize(win, win->internal.oldW, win->internal.oldH);
-
- RGFW_window_show(win);
}
RGFW_bool RGFW_FUNC(RGFW_window_isFloating)(RGFW_window* win) {
@@ -10118,9 +10972,8 @@ void RGFW_FUNC(RGFW_window_hide) (RGFW_window* win) {
win->internal.flags |= RGFW_windowHide;
}
-void RGFW_FUNC(RGFW_window_show) (RGFW_window* win) {
+void RGFW_FUNC(RGFW_window_showPlatform) (RGFW_window* win) {
win->internal.flags &= ~(u32)RGFW_windowHide;
- if (win->internal.flags & RGFW_windowFocusOnShow) RGFW_window_focus(win);
/* wl_surface_attach(win->src.surface, win->x, win->y, win->w, win->h, 0, 0); */
wl_surface_commit(win->src.surface);
}
@@ -10131,31 +10984,57 @@ void RGFW_FUNC(RGFW_window_flash) (RGFW_window* win, RGFW_flashRequest request)
}
}
-RGFW_ssize_t RGFW_FUNC(RGFW_readClipboardPtr) (char* str, size_t strCapacity) {
+RGFW_bool RGFW_FUNC(RGFW_readClipboardPtr) (RGFW_dataTransferType requestedType, u8* buffer, size_t capacity, RGFW_dataTransfer* data) {
+ RGFW_ASSERT(data != NULL);
+
+ if (requestedType != RGFW_dataText) return RGFW_FALSE;
+
+ if (_RGFW->unixClipboard == NULL || _RGFW->unixClipboard->length == 0) {
+ data->length = 0;
+ data->type = RGFW_dataNone;
+ return RGFW_FALSE;
+ }
+
+ data->length = _RGFW->unixClipboard->length;
+ data->type = RGFW_dataText;
+
+ if (buffer == NULL) return RGFW_TRUE;
- RGFW_UNUSED(strCapacity);
+ if (_RGFW->unixClipboard->length > capacity) return RGFW_FALSE;
- if (str != NULL)
- RGFW_STRNCPY(str, _RGFW->clipboard, _RGFW->clipboard_len - 1);
- _RGFW->clipboard[_RGFW->clipboard_len - 1] = '\0';
- return (RGFW_ssize_t)_RGFW->clipboard_len - 1;
+ RGFW_MEMCPY(buffer, _RGFW->unixClipboard->data, _RGFW->unixClipboard->length);
+ data->data = (const char*)buffer;
+
+ return RGFW_TRUE;
}
-void RGFW_FUNC(RGFW_writeClipboard) (const char* text, u32 textLen) {
+RGFW_bool RGFW_FUNC(RGFW_writeClipboard) (const RGFW_dataTransfer* data) {
+ RGFW_ASSERT(data != NULL);
- // compositor does not support wl_data_device_manager
- // clients cannot read rgfw's clipboard
- if (_RGFW->data_device_manager == NULL) return;
+ /* compositor does not support wl_data_device_manager
+ clients cannot read rgfw's clipboard
+ */
+ if (_RGFW->data_device_manager == NULL) return RGFW_FALSE;
// clear the clipboard
- if (_RGFW->clipboard)
- RGFW_FREE(_RGFW->clipboard);
+ if (_RGFW->unixClipboard) {
+ RGFW_FREE(_RGFW->unixClipboard);
+ _RGFW->unixClipboard = NULL;
+ }
// set the contents
- _RGFW->clipboard = (char*)RGFW_ALLOC(textLen);
- RGFW_ASSERT(_RGFW->clipboard != NULL);
- RGFW_STRNCPY(_RGFW->clipboard, text, textLen - 1);
- _RGFW->clipboard[textLen - 1] = '\0';
- _RGFW->clipboard_len = textLen;
+ _RGFW->unixClipboard = (RGFW_dataTransfer*)RGFW_ALLOC(sizeof(RGFW_dataTransfer) + data->length);
+ RGFW_ASSERT(_RGFW->unixClipboard!= NULL);
+
+ size_t length = data->length;
+ if (data->data[length - 1] != '\0') length += 1;
+
+ char* data_ptr = &((char*)(void*)_RGFW->unixClipboard)[sizeof(RGFW_dataTransfer) - 1];
+ RGFW_MEMCPY(data_ptr, data->data, data->length);
+ data_ptr[length - 1] = '\0';
+
+ _RGFW->unixClipboard->data = data_ptr;
+ _RGFW->unixClipboard->type = RGFW_dataText;
+ _RGFW->unixClipboard->length = length;
// means we already wrote to the clipboard
// so destroy it to create a new one
@@ -10172,9 +11051,8 @@ void RGFW_FUNC(RGFW_writeClipboard) (const char* text, u32 textLen) {
// basic error checking
if (win->src.data_source == NULL) {
RGFW_debugCallback(RGFW_typeError, RGFW_errClipboard, "Could not create clipboard data source");
- return;
+ return RGFW_FALSE;
}
- wl_data_source_offer(win->src.data_source , "text/plain;charset=utf-8");
// needed RGFW_doNothing because wayland will call the functions
// if not set they are random data that lead to a crash
@@ -10188,7 +11066,9 @@ void RGFW_FUNC(RGFW_writeClipboard) (const char* text, u32 textLen) {
};
wl_data_source_add_listener(win->src.data_source, &data_source_listener, _RGFW);
+ wl_data_source_offer(win->src.data_source , "text/plain;charset=utf-8");
+ return RGFW_TRUE;
}
RGFW_bool RGFW_FUNC(RGFW_window_isHidden) (RGFW_window* win) {
@@ -10210,8 +11090,25 @@ void RGFW_FUNC(RGFW_pollMonitors) (void) {
_RGFW->monitors.primary = _RGFW->monitors.list.head;
}
+void RGFW_FUNC(RGFW_monitorNode_free) (RGFW_monitorNode* node) {
+ RGFW_ASSERT(node);
+
+ if (node->output) {
+ wl_output_destroy(node->output);
+ }
+
+ if (node->xdg_output) {
+ zxdg_output_v1_destroy(node->xdg_output);
+ }
+
+ if (node->modes) {
+ RGFW_FREE(node->modes);
+ node->modeCount = 0;
+ }
+}
RGFW_bool RGFW_FUNC(RGFW_monitor_getWorkarea) (RGFW_monitor* monitor, i32* x, i32* y, i32* width, i32* height) {
+ RGFW_ASSERT(monitor != NULL);
/* NOTE: Wayland has no way to get the actual workarea as far as I'm aware :( */
if (x) *x = monitor->x;
if (y) *y = monitor->y;
@@ -10221,6 +11118,7 @@ RGFW_bool RGFW_FUNC(RGFW_monitor_getWorkarea) (RGFW_monitor* monitor, i32* x, i3
}
size_t RGFW_FUNC(RGFW_monitor_getModesPtr) (RGFW_monitor* monitor, RGFW_monitorMode** modes) {
+ RGFW_ASSERT(monitor != NULL);
if (modes) {
RGFW_MEMCPY((*modes), monitor->node->modes, monitor->node->modeCount * sizeof(RGFW_monitorMode));
}
@@ -10229,16 +11127,19 @@ size_t RGFW_FUNC(RGFW_monitor_getModesPtr) (RGFW_monitor* monitor, RGFW_monitorM
}
size_t RGFW_FUNC(RGFW_monitor_getGammaRampPtr) (RGFW_monitor* monitor, RGFW_gammaRamp* ramp) {
+ RGFW_ASSERT(monitor != NULL);
RGFW_UNUSED(monitor); RGFW_UNUSED(ramp);
return 0;
}
RGFW_bool RGFW_FUNC(RGFW_monitor_setGammaRamp) (RGFW_monitor* monitor, RGFW_gammaRamp* ramp) {
+ RGFW_ASSERT(monitor != NULL);
RGFW_UNUSED(monitor); RGFW_UNUSED(ramp);
return RGFW_FALSE;
}
RGFW_bool RGFW_FUNC(RGFW_monitor_requestMode) (RGFW_monitor* mon, RGFW_monitorMode* mode, RGFW_modeRequest request) {
+ RGFW_ASSERT(mon != NULL);
for (size_t i = 0; i < mon->node->modeCount; i++) {
if (RGFW_monitorModeCompare(mode, &mon->node->modes[i], request) == RGFW_FALSE) {
continue;
@@ -10252,7 +11153,8 @@ RGFW_bool RGFW_FUNC(RGFW_monitor_requestMode) (RGFW_monitor* mon, RGFW_monitorMo
}
RGFW_bool RGFW_FUNC(RGFW_monitor_setMode) (RGFW_monitor* mon, RGFW_monitorMode* mode) {
- RGFW_UNUSED(mon); RGFW_UNUSED(mode);
+ RGFW_ASSERT(mon != NULL);
+ mon->mode = *mode;
return RGFW_FALSE;
}
@@ -10271,17 +11173,31 @@ RGFW_bool RGFW_FUNC(RGFW_extensionSupportedPlatform_OpenGL) (const char * extens
RGFW_proc RGFW_FUNC(RGFW_getProcAddress_OpenGL) (const char* procname) { return RGFW_getProcAddress_EGL(procname); }
-RGFW_bool RGFW_FUNC(RGFW_window_createContextPtr_OpenGL)(RGFW_window* win, RGFW_glContext* ctx, RGFW_glHints* hints) {
- RGFW_bool out = RGFW_window_createContextPtr_EGL(win, &ctx->egl, hints);
+RGFW_bool RGFW_FUNC(RGFW_createContextPtr_OpenGL)(RGFW_glContext* ctx, RGFW_glHints* hints) {
+ RGFW_bool out = RGFW_createContextPtr_EGL(&ctx->egl, hints);
+ return out;
+}
+void RGFW_FUNC(RGFW_deleteContextPtr_OpenGL) (RGFW_glContext* ctx) { RGFW_deleteContextPtr_EGL(&ctx->egl); }
+RGFW_bool RGFW_FUNC(RGFW_window_setContext_OpenGL) (RGFW_window* win, RGFW_glContext* context) {
+ RGFW_ASSERT(win);
+ if (context == NULL && win->src.ctx.native != NULL) {
+ RGFW_window_setContext_EGL(win, 0);
+ win->src.ctx.native = NULL;
+ RGFW_debugCallback(RGFW_typeInfo, RGFW_infoOpenGL, "OpenGL window surface freed");
+ return RGFW_TRUE;
+ }
+
+ win->src.ctx.native = context;
win->src.gfxType = RGFW_gfxNativeOpenGL;
+ if (RGFW_window_setContext_EGL(win, &context->egl) == RGFW_FALSE) return RGFW_FALSE;
RGFW_window_swapInterval_OpenGL(win, 0);
- return out;
+ return RGFW_TRUE;
}
-void RGFW_FUNC(RGFW_window_deleteContextPtr_OpenGL) (RGFW_window* win, RGFW_glContext* ctx) { RGFW_window_deleteContextPtr_EGL(win, &ctx->egl); win->src.ctx.native = NULL; }
void RGFW_FUNC(RGFW_window_makeCurrentContext_OpenGL) (RGFW_window* win) { RGFW_window_makeCurrentContext_EGL(win); }
void* RGFW_FUNC(RGFW_getCurrentContext_OpenGL) (void) { return RGFW_getCurrentContext_EGL(); }
+void* RGFW_FUNC(RGFW_getCurrentSurface_OpenGL) (void) { return RGFW_getCurrentSurface_EGL(); }
void RGFW_FUNC(RGFW_window_swapBuffers_OpenGL) (RGFW_window* win) { RGFW_window_swapBuffers_EGL(win); }
void RGFW_FUNC(RGFW_window_swapInterval_OpenGL) (RGFW_window* win, i32 swapInterval) { RGFW_window_swapInterval_EGL(win, swapInterval); }
#endif /* RGFW_OPENGL */
@@ -10344,16 +11260,6 @@ WGPUSurface RGFW_FUNC(RGFW_window_createSurface_WebGPU) (RGFW_window* window, WG
*/
#ifdef RGFW_WINDOWS
-#ifndef WIN32_LEAN_AND_MEAN
- #define WIN32_LEAN_AND_MEAN
-#endif
-
-#ifndef OEMRESOURCE
- #define OEMRESOURCE
-#endif
-
-#include <windows.h>
-
#ifndef OCR_NORMAL
#define OCR_NORMAL 32512
#define OCR_IBEAM 32513
@@ -10381,12 +11287,17 @@ WGPUSurface RGFW_FUNC(RGFW_window_createSurface_WebGPU) (RGFW_window* window, WG
#define WM_DPICHANGED 0x02E0
#endif
+#define RGFW_LOAD_LIBRARY(x, lib) if (x == NULL) { x = LoadLibraryA(lib); RGFW_ASSERT(x != NULL); }
+#define RGFW_PROC_DEF(proc, name) if (name##SRC == NULL && proc != NULL) { \
+ name##SRC = (PFN_##name)(RGFW_proc)GetProcAddress((proc), (#name)); \
+ RGFW_ASSERT(name##SRC != NULL); \
+ }
RGFWDEF DWORD RGFW_winapi_window_getStyle(RGFW_window* win, RGFW_windowFlags flags);
DWORD RGFW_winapi_window_getStyle(RGFW_window* win, RGFW_windowFlags flags) {
RGFW_UNUSED(win);
DWORD style = WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
- if ((flags & RGFW_windowFullscreen)) {
+ if ((flags & RGFW_windowFullscreenExclusive)) {
style |= WS_POPUP;
} else {
style |= WS_SYSMENU | WS_MINIMIZEBOX;
@@ -10407,68 +11318,155 @@ DWORD RGFW_winapi_window_getStyle(RGFW_window* win, RGFW_windowFlags flags) {
RGFWDEF DWORD RGFW_winapi_window_getExStyle(RGFW_window* win, RGFW_windowFlags flags);
DWORD RGFW_winapi_window_getExStyle(RGFW_window* win, RGFW_windowFlags flags) {
DWORD style = WS_EX_APPWINDOW;
- if (flags & RGFW_windowFullscreen || (flags & RGFW_windowFloating || RGFW_window_isFloating(win))) {
+ if (flags & RGFW_windowFullscreenExclusive || (flags & RGFW_windowFloating || RGFW_window_isFloating(win))) {
style |= WS_EX_TOPMOST;
}
return style;
}
-RGFW_bool RGFW_createUTF8FromWideStringWin32(const WCHAR* source, char* out, size_t max);
+RGFWDEF i32 RGFW_createUTF8FromWideStringWin32(const WCHAR* source, char* out, size_t max);
+i32 RGFW_createUTF8FromWideStringWin32(const WCHAR* source, char* output, size_t max) {
+ RGFW_ASSERT(source != NULL);
-#define GL_FRONT 0x0404
-#define GL_BACK 0x0405
-#define GL_LEFT 0x0406
-#define GL_RIGHT 0x0407
+ i32 size = WideCharToMultiByte(CP_UTF8, 0, source, -1, NULL, 0, NULL, NULL);
+ if (!size) {
+ return RGFW_FALSE;
+ }
-typedef int (*PFN_wglGetSwapIntervalEXT)(void);
-PFN_wglGetSwapIntervalEXT wglGetSwapIntervalEXTSrc = NULL;
-#define wglGetSwapIntervalEXT wglGetSwapIntervalEXTSrc
+ if (output == NULL || max == 0) {
+ return size;
+ }
-/* these two wgl functions need to be preloaded */
-typedef HGLRC (WINAPI *PFNWGLCREATECONTEXTATTRIBSARBPROC)(HDC hdc, HGLRC hglrc, const int *attribList);
-PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB = NULL;
+ if ((size_t)size > max)
+ size = (i32)max;
-HMODULE RGFW_wgl_dll = NULL;
+ if (!WideCharToMultiByte(CP_UTF8, 0, source, -1, output, size, NULL, NULL)) {
+ return RGFW_FALSE;
+ }
-#ifndef RGFW_NO_LOAD_WGL
- typedef HGLRC(WINAPI* PFN_wglCreateContext)(HDC);
- typedef BOOL(WINAPI* PFN_wglDeleteContext)(HGLRC);
- typedef PROC(WINAPI* PFN_wglGetProcAddress)(LPCSTR);
- typedef BOOL(WINAPI* PFN_wglMakeCurrent)(HDC, HGLRC);
- typedef HDC(WINAPI* PFN_wglGetCurrentDC)(void);
- typedef HGLRC(WINAPI* PFN_wglGetCurrentContext)(void);
- typedef BOOL(WINAPI* PFN_wglShareLists)(HGLRC, HGLRC);
+ return size;
+}
- PFN_wglCreateContext wglCreateContextSRC;
- PFN_wglDeleteContext wglDeleteContextSRC;
- PFN_wglGetProcAddress wglGetProcAddressSRC;
- PFN_wglMakeCurrent wglMakeCurrentSRC;
- PFN_wglGetCurrentDC wglGetCurrentDCSRC;
- PFN_wglGetCurrentContext wglGetCurrentContextSRC;
- PFN_wglShareLists wglShareListsSRC;
+#ifdef RGFW_OPENGL
+#define WGL_ACCELERATION_ARB 0x2003
+#define WGL_FULL_ACCELERATION_ARB 0x2027
+#define WGL_DRAW_TO_WINDOW_ARB 0x2001
+#define WGL_PIXEL_TYPE_ARB 0x2013
+#define WGL_TYPE_RGBA_ARB 0x202b
+#define WGL_SUPPORT_OPENGL_ARB 0x2010
+#define WGL_COLOR_BITS_ARB 0x2014
+#define WGL_DOUBLE_BUFFER_ARB 0x2011
+#define WGL_ALPHA_BITS_ARB 0x201b
+#define WGL_DEPTH_BITS_ARB 0x2022
+#define WGL_STENCIL_BITS_ARB 0x2023
+#define WGL_STEREO_ARB 0x2012
+#define WGL_AUX_BUFFERS_ARB 0x2024
+#define WGL_RED_BITS_ARB 0x2015
+#define WGL_GREEN_BITS_ARB 0x2017
+#define WGL_BLUE_BITS_ARB 0x2019
+#define WGL_ACCUM_RED_BITS_ARB 0x201e
+#define WGL_ACCUM_GREEN_BITS_ARB 0x201f
+#define WGL_ACCUM_BLUE_BITS_ARB 0x2020
+#define WGL_ACCUM_ALPHA_BITS_ARB 0x2021
+#define WGL_COLORSPACE_SRGB_EXT 0x3089
+#define WGL_SAMPLE_BUFFERS_ARB 0x2041
+#define WGL_SAMPLES_ARB 0x2042
+#define WGL_CONTEXT_OPENGL_NO_ERROR_ARB 0x31b3
+#define WGL_CONTEXT_RELEASE_BEHAVIOR_ARB 0x2097
+#define WGL_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB 0x0000
+#define WGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB 0x2098
+#define WGL_CONTEXT_FLAGS_ARB 0x2094
+#define WGL_ACCESS_READ_WRITE_NV 0x00000001
+#define WGL_CONTEXT_ES_PROFILE_BIT_EXT 0x00000004
+#define WGL_CONTEXT_PROFILE_MASK_ARB 0x9126
+#define WGL_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001
+#define WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002
+#define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x00000002
+#define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091
+#define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092
+#define WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB 0x20A9
+#define WGL_CONTEXT_RELEASE_BEHAVIOR_ARB 0x2097
+#define WGL_CONTEXT_DEBUG_BIT_ARB 0x00000001
+#define WGL_CONTEXT_ROBUST_ACCESS_BIT_ARB 0x00000004
- #define wglCreateContext wglCreateContextSRC
- #define wglDeleteContext wglDeleteContextSRC
- #define wglGetProcAddress wglGetProcAddressSRC
- #define wglMakeCurrent wglMakeCurrentSRC
- #define wglGetCurrentDC wglGetCurrentDCSRC
- #define wglGetCurrentContext wglGetCurrentContextSRC
- #define wglShareLists wglShareListsSRC
-#endif
+typedef int (*RGFW_wglGetSwapIntervalEXTProc)(void);
+typedef HGLRC (WINAPI *RGFW_wglCreateContextAttribsARBProc)(HDC hdc, HGLRC hglrc, const int *attribList);
+typedef HGLRC(WINAPI* RGFW_wglCreateContextProc)(HDC);
+typedef BOOL(WINAPI* RGFW_wglDeleteContextProc)(HGLRC);
+typedef PROC(WINAPI* RGFW_wglGetProcAddressProc)(LPCSTR);
+typedef BOOL(WINAPI* RGFW_wglMakeCurrentProc)(HDC, HGLRC);
+typedef HGLRC(WINAPI* RGFW_wglGetCurrentContextProc)(void);
+typedef HDC(WINAPI* RGFW_wglGetCurrentDCProc)(void);
+typedef BOOL(WINAPI* RGFW_wglShareListsProc)(HGLRC, HGLRC);
+typedef HRESULT (APIENTRY* RGFW_wglChoosePixelFormatARBProc)(HDC hdc, const int* piAttribIList, const FLOAT* pfAttribFList, UINT nMaxFormats, int* piFormats, UINT* nNumFormats);
+typedef BOOL(APIENTRY* RGFW_wglSwapIntervalEXTProc)(int interval);
-void* RGFW_window_getHWND(RGFW_window* win) { return win->src.window; }
-void* RGFW_window_getHDC(RGFW_window* win) { return win->src.hdc; }
+RGFW_wglCreateContextProc RGFW_wglCreateContext;
+RGFW_wglDeleteContextProc RGFW_wglDeleteContext;
+RGFW_wglMakeCurrentProc RGFW_wglMakeCurrent;
+RGFW_wglGetCurrentDCProc RGFW_wglGetCurrentDC;
+RGFW_wglGetCurrentContextProc RGFW_wglGetCurrentContext;
+RGFW_wglShareListsProc RGFW_wglShareLists;
+RGFW_wglCreateContextAttribsARBProc RGFW_wglCreateContextAttribsARB;
+RGFW_wglGetSwapIntervalEXTProc RGFW_wglGetSwapIntervalEXT;
+RGFW_wglChoosePixelFormatARBProc RGFW_wglChoosePixelFormatARB;
+RGFW_wglSwapIntervalEXTProc RGFW_wglSwapIntervalEXT;
-#ifdef RGFW_OPENGL
-RGFWDEF void RGFW_win32_loadOpenGLFuncs(HWND dummyWin);
+RGFW_bool RGFW_loadGL(void) {
+ RGFW_ASSERT(_RGFW && "An RGFW context must be initialized using RGFW_init and/or set with RGFW_setInfo");
+ if (_RGFW->nativeGL_handle && _RGFW->glGetProcAddress != NULL) {
+ return RGFW_TRUE;
+ }
+
+ RGFW_LOAD_LIBRARY(_RGFW->nativeGL_handle, "opengl32.dll");
+ _RGFW->glGetProcAddress = (RGFW_proc(*)(const char*))(RGFW_proc)GetProcAddress((HMODULE)_RGFW->nativeGL_handle, "wglGetProcAddress");
+ RGFW_ASSERT(_RGFW->glGetProcAddress);
+
+ #define RGFW_WGL_PROC(name) if (RGFW_##name == NULL) RGFW_##name = (RGFW_##name##Proc)RGFW_getProcAddress_OpenGL(#name);
+
+ RGFW_WGL_PROC(wglCreateContext);
+ RGFW_WGL_PROC(wglDeleteContext);
+ RGFW_WGL_PROC(wglMakeCurrent);
+ RGFW_WGL_PROC(wglGetCurrentDC);
+ RGFW_WGL_PROC(wglGetCurrentContext);
+ RGFW_WGL_PROC(wglShareLists);
+
+ HWND dummyWin = CreateWindowW(_RGFW->wndClass.lpszClassName, (wchar_t*)NULL, 0, 0, 0, 0, 0, 0, 0, _RGFW->instance, 0);
+ HDC dummy_dc = GetDC(dummyWin);
+ u32 pfd_flags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
+
+ 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};
+
+ int dummy_pixel_format = ChoosePixelFormat(dummy_dc, &pfd);
+ SetPixelFormat(dummy_dc, dummy_pixel_format, &pfd);
+
+ HGLRC dummy_context = RGFW_wglCreateContext(dummy_dc);
+
+ HGLRC cur = RGFW_wglGetCurrentContext();
+ RGFW_wglMakeCurrent(dummy_dc, dummy_context);
-typedef HRESULT (APIENTRY* PFNWGLCHOOSEPIXELFORMATARBPROC)(HDC hdc, const int* piAttribIList, const FLOAT* pfAttribFList, UINT nMaxFormats, int* piFormats, UINT* nNumFormats);
-PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormatARB = NULL;
+ RGFW_WGL_PROC(wglCreateContextAttribsARB);
+ RGFW_WGL_PROC(wglChoosePixelFormatARB);
+ RGFW_WGL_PROC(wglSwapIntervalEXT);
+
+ #undef RGFW_WGL_PROC
+
+ if (RGFW_wglSwapIntervalEXT == NULL) {
+ RGFW_debugCallback(RGFW_typeError, RGFW_errOpenGLContext, "Failed to load swap interval function");
+ }
+
+ RGFW_wglMakeCurrent(dummy_dc, cur);
+ RGFW_wglDeleteContext(dummy_context);
+ ReleaseDC(dummyWin, dummy_dc);
+ DestroyWindow(dummyWin);
+
+ return RGFW_TRUE;
+}
-typedef BOOL(APIENTRY* PFNWGLSWAPINTERVALEXTPROC)(int interval);
-PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT = NULL;
#endif
+void* RGFW_window_getHWND(RGFW_window* win) { return win->src.window; }
+void* RGFW_window_getHDC(RGFW_window* win) { return win->src.hdc; }
#ifndef RGFW_NO_DWM
HMODULE RGFW_dwm_dll = NULL;
@@ -10525,6 +11523,15 @@ void RGFW_win32_makeWindowDarkMode(RGFW_window* win, RGFW_bool state) {
LRESULT CALLBACK WndProcW(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
LRESULT CALLBACK WndProcW(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
+ switch (message) {
+ case WM_DISPLAYCHANGE:
+ RGFW_pollMonitors();
+ break;
+ default: break;
+ }
+
+ if (hWnd == _RGFW->helperWindow) return DefWindowProcW(hWnd, message, wParam, lParam);
+
RGFW_window* win = (RGFW_window*)GetPropW(hWnd, L"RGFW");
if (win == NULL) return DefWindowProcW(hWnd, message, wParam, lParam);
@@ -10538,11 +11545,7 @@ LRESULT CALLBACK WndProcW(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
AdjustWindowRectEx(&frame, style, FALSE, exStyle);
switch (message) {
- case WM_DISPLAYCHANGE:
- RGFW_pollMonitors();
- break;
case WM_CLOSE:
- case WM_QUIT:
RGFW_windowCloseCallback(win);
return 0;
case WM_ACTIVATE: {
@@ -10627,10 +11630,15 @@ LRESULT CALLBACK WndProcW(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
return DefWindowProcW(hWnd, message, wParam, lParam);
}
case WM_PAINT: {
- PAINTSTRUCT ps;
- BeginPaint(hWnd, &ps);
- RGFW_windowRefreshCallback(win, 0, 0, win->w, win->h);
- EndPaint(hWnd, &ps);
+ RECT rect;
+ if (GetUpdateRect(hWnd, &rect, FALSE)) {
+ RGFW_windowRefreshCallback(win, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top);
+ } else {
+ PAINTSTRUCT ps;
+ BeginPaint(hWnd, &ps);
+ RGFW_windowRefreshCallback(win, 0, 0, win->w, win->h);
+ EndPaint(hWnd, &ps);
+ }
return DefWindowProcW(hWnd, message, wParam, lParam);
}
@@ -10767,7 +11775,7 @@ LRESULT CALLBACK WndProcW(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
RGFW_mouseNotifyCallback(win, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), RGFW_TRUE);
}
- RGFW_mousePosCallback(win, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
+ RGFW_mouseMotionCallback(win, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
break;
}
case WM_INPUT: {
@@ -10819,6 +11827,7 @@ LRESULT CALLBACK WndProcW(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
else value = (message == WM_LBUTTONDOWN) ? (u8)RGFW_mouseLeft :
(message == WM_RBUTTONDOWN) ? (u8)RGFW_mouseRight : (u8)RGFW_mouseMiddle;
+ SetCapture(win->src.window);
RGFW_mouseButtonCallback(win, value, 1);
break;
}
@@ -10830,6 +11839,9 @@ LRESULT CALLBACK WndProcW(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
(message == WM_RBUTTONUP) ? (u8)RGFW_mouseRight : (u8)RGFW_mouseMiddle;
RGFW_mouseButtonCallback(win, value, 0);
+
+ RGFW_mouseButton i = 0;
+ for (i = RGFW_mouseLeft; i < RGFW_mouseFinal && RGFW_isMouseDown(i) == RGFW_FALSE; i += 1);
break;
}
case WM_MOUSEWHEEL: {
@@ -10855,20 +11867,23 @@ LRESULT CALLBACK WndProcW(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
u32 i;
for (i = 0; i < count; i++) {
- UINT length = DragQueryFileW(drop, i, NULL, 0);
- if (length == 0)
+ UINT length = DragQueryFileW(drop, i, NULL, 0) + 1;
+ if (length <= 1)
continue;
- WCHAR* buffer = (WCHAR*)RGFW_ALLOC(sizeof(WCHAR) * (length + 1));
- char* cbuffer = (char*)RGFW_ALLOC(length + 1);
-
- DragQueryFileW(drop, i, buffer, length + 1);
+ WCHAR* buffer = (WCHAR*)RGFW_ALLOC(sizeof(WCHAR) * length);
+ DragQueryFileW(drop, i, buffer, length);
- RGFW_createUTF8FromWideStringWin32(buffer, cbuffer, length);
+ i32 clength = RGFW_createUTF8FromWideStringWin32(buffer, NULL, 0);
+ if (clength > 0) {
+ char* cbuffer = (char*)RGFW_ALLOC((size_t)clength);
+ if (RGFW_createUTF8FromWideStringWin32(buffer, cbuffer, (size_t)clength) != RGFW_FALSE) {
+ RGFW_dataDropCallback(win, cbuffer, (size_t)clength, RGFW_dataFile);
+ }
+ RGFW_FREE(cbuffer);
+ }
- RGFW_dataDropCallback(win, cbuffer, length + 1, RGFW_dataFile);
RGFW_FREE(buffer);
- RGFW_FREE(cbuffer);
}
DragFinish(drop);
@@ -10899,10 +11914,6 @@ LRESULT CALLBACK WndProcW(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
__declspec(dllimport) u32 __stdcall timeBeginPeriod(u32 uPeriod);
__declspec(dllimport) u32 __stdcall timeEndPeriod(u32 uPeriod);
#endif
-#define RGFW_PROC_DEF(proc, name) if (name##SRC == NULL && proc != NULL) { \
- name##SRC = (PFN_##name)(RGFW_proc)GetProcAddress((proc), (#name)); \
- RGFW_ASSERT(name##SRC != NULL); \
- }
RGFW_format RGFW_nativeFormat(void) { return RGFW_formatBGRA8; }
@@ -10973,35 +11984,6 @@ void RGFW_window_captureMousePlatform(RGFW_window* win, RGFW_bool state) {
ClipCursor(&clipRect);
}
-#define RGFW_LOAD_LIBRARY(x, lib) if (x == NULL) { x = LoadLibraryA(lib); RGFW_ASSERT(x != NULL); }
-
-#ifdef RGFW_DIRECTX
-int RGFW_window_createSwapChain_DirectX(RGFW_window* win, IDXGIFactory* pFactory, IUnknown* pDevice, IDXGISwapChain** swapchain) {
- RGFW_ASSERT(win && pFactory && pDevice && swapchain);
-
- static DXGI_SWAP_CHAIN_DESC swapChainDesc;
- RGFW_MEMZERO(&swapChainDesc, sizeof(swapChainDesc));
- swapChainDesc.BufferCount = 2;
- swapChainDesc.BufferDesc.Width = win->w;
- swapChainDesc.BufferDesc.Height = win->h;
- swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
- swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
- swapChainDesc.OutputWindow = (HWND)win->src.window;
- swapChainDesc.SampleDesc.Count = 1;
- swapChainDesc.SampleDesc.Quality = 0;
- swapChainDesc.Windowed = TRUE;
- swapChainDesc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;
-
- HRESULT hr = pFactory->lpVtbl->CreateSwapChain(pFactory, (IUnknown*)pDevice, &swapChainDesc, swapchain);
- if (FAILED(hr)) {
- RGFW_debugCallback(RGFW_typeError, RGFW_errDirectXContext, "Failed to create DirectX swap chain!");
- return -2;
- }
-
- return 0;
-}
-#endif
-
/* we're doing it with magic numbers because some keys are missing */
void RGFW_initKeycodesPlatform(void) {
_RGFW->keycodes[0x00B] = RGFW_key0;
@@ -11125,7 +12107,8 @@ void RGFW_initKeycodesPlatform(void) {
}
-i32 RGFW_initPlatform(void) {
+i32 RGFW_initPlatform(const char* className, RGFW_initFlags flags) {
+ RGFW_UNUSED(flags);
#ifndef RGFW_NO_DPI
#if (_WIN32_WINNT >= 0x0600)
SetProcessDPIAware();
@@ -11147,20 +12130,28 @@ i32 RGFW_initPlatform(void) {
RGFW_PROC_DEF(RGFW_dwm_dll, DwmSetWindowAttribute);
#endif
- RGFW_LOAD_LIBRARY(RGFW_wgl_dll, "opengl32.dll");
- #ifndef RGFW_NO_LOAD_WGL
- RGFW_PROC_DEF(RGFW_wgl_dll, wglCreateContext);
- RGFW_PROC_DEF(RGFW_wgl_dll, wglDeleteContext);
- RGFW_PROC_DEF(RGFW_wgl_dll, wglGetProcAddress);
- RGFW_PROC_DEF(RGFW_wgl_dll, wglMakeCurrent);
- RGFW_PROC_DEF(RGFW_wgl_dll, wglGetCurrentDC);
- RGFW_PROC_DEF(RGFW_wgl_dll, wglGetCurrentContext);
- RGFW_PROC_DEF(RGFW_wgl_dll, wglShareLists);
- #endif
+ _RGFW->instance = GetModuleHandleW(NULL);
+ MultiByteToWideChar(CP_UTF8, 0, className, -1, _RGFW->wideClassName, 255);
+
+ RGFW_MEMZERO(&_RGFW->wndClass, sizeof(_RGFW->wndClass));
+
+ _RGFW->wndClass.lpszClassName = _RGFW->wideClassName;
+ _RGFW->wndClass.hInstance = _RGFW->instance;
+ _RGFW->wndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
+ _RGFW->wndClass.lpfnWndProc = WndProcW;
+ _RGFW->wndClass.cbClsExtra = sizeof(RGFW_window*);
+ _RGFW->wndClass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
+ _RGFW->wndClass.hIcon = (HICON)LoadImageA(_RGFW->instance, "RGFW_ICON", IMAGE_ICON, 0, 0, LR_DEFAULTSIZE | LR_SHARED);
+ if (_RGFW->wndClass.hIcon == NULL)
+ _RGFW->wndClass.hIcon = (HICON)LoadImageA(NULL, (LPCSTR)IDI_APPLICATION, IMAGE_ICON, 0, 0, LR_DEFAULTSIZE | LR_SHARED);
+
+ RegisterClassW(&_RGFW->wndClass);
+
+ _RGFW->helperWindow = CreateWindowW(_RGFW->wndClass.lpszClassName, (wchar_t*)NULL, 0, 0, 0, 0, 0, 0, 0, _RGFW->instance, 0);
u8 RGFW_blk[] = { 0, 0, 0, 0 };
_RGFW->hiddenMouse = RGFW_createMouse(RGFW_blk, 1, 1, RGFW_formatRGBA8);
- return 1;
+ return 0;
}
RGFW_window* RGFW_createWindowPlatform(const char* name, RGFW_windowFlags flags, RGFW_window* win) {
@@ -11173,32 +12164,6 @@ RGFW_window* RGFW_createWindowPlatform(const char* name, RGFW_windowFlags flags,
win->src.aspectRatioW = 0;
win->src.aspectRatioH = 0;
- HINSTANCE inh = GetModuleHandleA(NULL);
-
- #ifndef __cplusplus
- WNDCLASSW Class = {0}; /*!< Setup the Window class. */
- #else
- WNDCLASSW Class = {};
- #endif
-
- if (_RGFW->className == NULL)
- _RGFW->className = (char*)name;
-
- wchar_t wide_class[256];
- MultiByteToWideChar(CP_UTF8, 0, _RGFW->className, -1, wide_class, 255);
-
- Class.lpszClassName = wide_class;
- Class.hInstance = inh;
- Class.hCursor = LoadCursor(NULL, IDC_ARROW);
- Class.lpfnWndProc = WndProcW;
- Class.cbClsExtra = sizeof(RGFW_window*);
-
- Class.hIcon = (HICON)LoadImageA(GetModuleHandleW(NULL), "RGFW_ICON", IMAGE_ICON, 0, 0, LR_DEFAULTSIZE | LR_SHARED);
- if (Class.hIcon == NULL)
- Class.hIcon = (HICON)LoadImageA(NULL, (LPCSTR)IDI_APPLICATION, IMAGE_ICON, 0, 0, LR_DEFAULTSIZE | LR_SHARED);
-
- RegisterClassW(&Class);
-
DWORD window_style = WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
if (!(flags & RGFW_windowNoBorder)) {
@@ -11211,20 +12176,13 @@ RGFW_window* RGFW_createWindowPlatform(const char* name, RGFW_windowFlags flags,
wchar_t wide_name[256];
MultiByteToWideChar(CP_UTF8, 0, name, -1, wide_name, 255);
- HWND dummyWin = CreateWindowW(Class.lpszClassName, (wchar_t*)wide_name, window_style, win->x, win->y, win->w, win->h, 0, 0, inh, 0);
-
-#ifdef RGFW_OPENGL
- RGFW_win32_loadOpenGLFuncs(dummyWin);
-#endif
-
- DestroyWindow(dummyWin);
RECT rect = { 0, 0, win->w, win->h};
DWORD style = RGFW_winapi_window_getStyle(win, flags);
DWORD exStyle = RGFW_winapi_window_getExStyle(win, flags);
AdjustWindowRectEx(&rect, style, FALSE, exStyle);
- win->src.window = CreateWindowW(Class.lpszClassName, (wchar_t*)wide_name, window_style, win->x + rect.left, win->y + rect.top, rect.right - rect.left, rect.bottom - rect.top, 0, 0, inh, 0);
+ win->src.window = CreateWindowW(_RGFW->wndClass.lpszClassName, (wchar_t*)wide_name, window_style, win->x + rect.left, win->y + rect.top, rect.right - rect.left, rect.bottom - rect.top, 0, 0, _RGFW->instance, 0);
SetPropW(win->src.window, L"RGFW", win);
RGFW_window_resize(win, win->w, win->h); /* so WM_GETMINMAXINFO gets called again */
@@ -11309,57 +12267,15 @@ void RGFW_window_raise(RGFW_window* win) {
SetWindowPos(win->src.window, HWND_TOP, win->x, win->y, win->w, win->h, SWP_NOSIZE | SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_FRAMECHANGED);
}
-void RGFW_window_setFullscreen(RGFW_window* win, RGFW_bool fullscreen) {
- RGFW_ASSERT(win != NULL);
-
- RGFW_monitor* mon = RGFW_window_getMonitor(win);
-
- if (fullscreen == RGFW_FALSE) {
- RGFW_monitor_setMode(mon, &win->internal.oldMode);
-
- RGFW_window_setBorder(win, 1);
+void RGFW_window_setFullscreenPlatform(RGFW_window* win, RGFW_bool fullscreen) { RGFW_UNUSED(win); RGFW_UNUSED(fullscreen); }
- RECT rect = { 0, 0, win->internal.oldW, win->internal.oldH};
- DWORD style = RGFW_winapi_window_getStyle(win, win->internal.flags);
- DWORD exStyle = RGFW_winapi_window_getExStyle(win, win->internal.flags);
- AdjustWindowRectEx(&rect, style, FALSE, exStyle);
- SetWindowPos(win->src.window, HWND_TOP, win->internal.oldX, win->internal.oldY, rect.right - rect.left, rect.bottom - rect.top, SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOZORDER);
-
- win->internal.flags &= ~(u32)RGFW_windowFullscreen;
- win->x = win->internal.oldX;
- win->y = win->internal.oldY;
- win->w = win->internal.oldW;
- win->h = win->internal.oldH;
- return;
- }
-
- win->internal.oldX = win->x;
- win->internal.oldY = win->y;
- win->internal.oldW = win->w;
- win->internal.oldH = win->h;
- win->internal.oldMode = mon->mode;
- win->internal.flags |= RGFW_windowFullscreen;
-
- RGFW_window_setBorder(win, 0);
-
- SetWindowPos(win->src.window, HWND_TOPMOST, (i32)mon->x, (i32)mon->y, 0, 0, SWP_NOOWNERZORDER | SWP_FRAMECHANGED | SWP_SHOWWINDOW | SWP_NOSIZE);
- win->x = mon->x;
- win->y = mon->y;
-
- RGFW_monitor_scaleToWindow(mon, win);
- SetWindowPos(win->src.window, HWND_TOPMOST, 0, 0, (i32)mon->mode.w, (i32)mon->mode.h, SWP_NOOWNERZORDER | SWP_FRAMECHANGED | SWP_SHOWWINDOW | SWP_NOMOVE);
- win->w = mon->mode.w;
- win->h = mon->mode.h;
-}
-
-void RGFW_window_maximize(RGFW_window* win) {
+void RGFW_window_maximizePlatform(RGFW_window* win) {
RGFW_ASSERT(win != NULL);
RGFW_window_hide(win);
ShowWindow(win->src.window, SW_MAXIMIZE);
- RGFW_window_fetchSize(win, NULL, NULL);
}
-void RGFW_window_minimize(RGFW_window* win) {
+void RGFW_window_minimizePlatform(RGFW_window* win) {
RGFW_ASSERT(win != NULL);
ShowWindow(win->src.window, SW_MINIMIZE);
}
@@ -11375,14 +12291,14 @@ void RGFW_window_setOpacity(RGFW_window* win, u8 opacity) {
SetLayeredWindowAttributes(win->src.window, 0, opacity, LWA_ALPHA);
}
-void RGFW_window_restore(RGFW_window* win) { RGFW_window_show(win); }
+void RGFW_window_restorePlatform(RGFW_window* win) { RGFW_UNUSED(win); }
RGFW_bool RGFW_window_isFloating(RGFW_window* win) {
return (GetWindowLongPtr(win->src.window, GWL_EXSTYLE) & WS_EX_TOPMOST) != 0;
}
void RGFW_stopCheckEvents(void) {
- PostMessageW(_RGFW->root->src.window, WM_NULL, 0, 0);
+ PostMessageW(_RGFW->helperWindow, WM_NULL, 0, 0);
}
void RGFW_waitForEvent(i32 waitMS) {
@@ -11404,9 +12320,15 @@ RGFW_key RGFW_physicalToMappedKey(RGFW_key key) {
if (result == 1 && charBuffer[0] < 256) {
return (RGFW_key)charBuffer[0];
- }
+ }
switch (vk) {
+ case VK_BACK: return RGFW_keyBackSpace;
+ case VK_TAB: return RGFW_keyTab;
+ /* VK_RETURN can be either RGFW_keyReturn or RGFW_keyPadReturn. RGFW can only give its best guess as to which key it should be. */
+ case VK_RETURN: return (key == RGFW_keyPadReturn) ? RGFW_keyPadReturn : RGFW_keyReturn;
+ case VK_ESCAPE: return RGFW_keyEscape;
+ case VK_DELETE: return RGFW_keyDelete;
case VK_F1: return RGFW_keyF1;
case VK_F2: return RGFW_keyF2;
case VK_F3: return RGFW_keyF3;
@@ -11456,7 +12378,6 @@ RGFW_key RGFW_physicalToMappedKey(RGFW_key key) {
case VK_SUBTRACT: return RGFW_keyPadMinus;
case VK_MULTIPLY: return RGFW_keyPadMultiply;
case VK_DIVIDE: return RGFW_keyPadSlash;
- case VK_RETURN: return RGFW_keyPadReturn;
case VK_DECIMAL: return RGFW_keyPadPeriod;
case VK_NUMPAD0: return RGFW_keyPad0;
case VK_NUMPAD1: return RGFW_keyPad1;
@@ -11470,7 +12391,7 @@ RGFW_key RGFW_physicalToMappedKey(RGFW_key key) {
case VK_NUMPAD9: return RGFW_keyPad9;
case VK_SNAPSHOT: return RGFW_keyPrintScreen;
case VK_PAUSE: return RGFW_keyPause;
- default: return RGFW_keyNULL;
+ default: break;
}
return RGFW_keyNULL;
@@ -11490,6 +12411,15 @@ void RGFW_pollEvents(void) {
RGFW_resetPrevState();
MSG msg;
while (PeekMessageA(&msg, NULL, 0u, 0u, PM_REMOVE)) {
+ if (msg.message == WM_QUIT) {
+ RGFW_window* cur = _RGFW->root;
+ while (cur) {
+ RGFW_window* next = cur->next;
+ RGFW_windowCloseCallback(cur);
+ cur = next;
+ }
+ }
+
TranslateMessage(&msg);
DispatchMessageA(&msg);
}
@@ -11503,11 +12433,8 @@ RGFW_bool RGFW_window_isHidden(RGFW_window* win) {
RGFW_bool RGFW_window_isMinimized(RGFW_window* win) {
RGFW_ASSERT(win != NULL);
- #ifndef __cplusplus
- WINDOWPLACEMENT placement = {0};
- #else
- WINDOWPLACEMENT placement = {};
- #endif
+ WINDOWPLACEMENT placement;
+ RGFW_MEMZERO(&placement, sizeof(placement));
GetWindowPlacement(win->src.window, &placement);
return placement.showCmd == SW_SHOWMINIMIZED;
}
@@ -11515,16 +12442,14 @@ RGFW_bool RGFW_window_isMinimized(RGFW_window* win) {
RGFW_bool RGFW_window_isMaximized(RGFW_window* win) {
RGFW_ASSERT(win != NULL);
- #ifndef __cplusplus
- WINDOWPLACEMENT placement = {0};
- #else
- WINDOWPLACEMENT placement = {};
- #endif
+ WINDOWPLACEMENT placement;
+ RGFW_MEMZERO(&placement, sizeof(placement));
GetWindowPlacement(win->src.window, &placement);
return placement.showCmd == SW_SHOWMAXIMIZED || IsZoomed(win->src.window);
}
RGFW_bool RGFW_monitor_getWorkarea(RGFW_monitor* monitor, i32* x, i32* y, i32* width, i32* height) {
+ RGFW_ASSERT(monitor != NULL);
MONITORINFOEX mi;
mi.cbSize = sizeof(MONITORINFOEX);
GetMonitorInfoA(monitor->node->hMonitor, (LPMONITORINFO)&mi);
@@ -11538,6 +12463,7 @@ RGFW_bool RGFW_monitor_getWorkarea(RGFW_monitor* monitor, i32* x, i32* y, i32* w
}
size_t RGFW_monitor_getGammaRampPtr(RGFW_monitor* monitor, RGFW_gammaRamp* ramp) {
+ RGFW_ASSERT(monitor != NULL);
WORD values[3][256];
HDC dc = CreateDCW(L"DISPLAY", monitor->node->adapterName, NULL, NULL);
@@ -11554,6 +12480,7 @@ size_t RGFW_monitor_getGammaRampPtr(RGFW_monitor* monitor, RGFW_gammaRamp* ramp)
}
RGFW_bool RGFW_monitor_setGammaRamp(RGFW_monitor* monitor, RGFW_gammaRamp* ramp) {
+ RGFW_ASSERT(monitor != NULL);
WORD values[3][256];
if (ramp->count != 256) {
RGFW_debugCallback(RGFW_typeError, RGFW_errX11, "Win32: Gamma ramp size must be 256");
@@ -11609,7 +12536,8 @@ void RGFW_win32_getMode(DEVMODEW* dm, RGFW_monitorMode* mode) {
}
}
-size_t RGFW_monitor_getModesPtr(RGFW_monitor* monitor, RGFW_monitorMode** modes){
+size_t RGFW_monitor_getModesPtr(RGFW_monitor* monitor, RGFW_monitorMode** modes) {
+ RGFW_ASSERT(monitor != NULL);
size_t count = 0;
DWORD modeIndex = 0;
@@ -11654,8 +12582,8 @@ size_t RGFW_monitor_getModesPtr(RGFW_monitor* monitor, RGFW_monitorMode** modes)
return count;
}
-RGFWDEF void RGFW_win32_createMonitor(DISPLAY_DEVICEW* adapter, DISPLAY_DEVICEW* dd);
-void RGFW_win32_createMonitor(DISPLAY_DEVICEW* adapter, DISPLAY_DEVICEW* dd) {
+RGFWDEF void RGFW_win32_initMonitor(DISPLAY_DEVICEW* adapter, RGFW_monitorNode* node);
+void RGFW_win32_initMonitor(DISPLAY_DEVICEW* adapter, RGFW_monitorNode* node) {
DEVMODEW dm;
ZeroMemory(&dm, sizeof(dm));
dm.dmSize = sizeof(dm);
@@ -11664,14 +12592,6 @@ void RGFW_win32_createMonitor(DISPLAY_DEVICEW* adapter, DISPLAY_DEVICEW* dd) {
return;
}
- RGFW_monitorNode* node = RGFW_monitors_add(NULL);
-
- wcscpy(node->adapterName, adapter->DeviceName);
- wcscpy(node->deviceName, dd->DeviceName);
-
- RGFW_createUTF8FromWideStringWin32(dd->DeviceString, node->mon.name, sizeof(node->mon.name));
- node->mon.name[sizeof(node->mon.name) - 1] = '\0';
-
RECT rect;
rect.left = (LONG)dm.dmPosition.x;
rect.top = (LONG)dm.dmPosition.y;
@@ -11689,9 +12609,9 @@ void RGFW_win32_createMonitor(DISPLAY_DEVICEW* adapter, DISPLAY_DEVICEW* dd) {
node->mon.y = monitorInfo.rcMonitor.top;
HDC hdc = CreateDCW(monitorInfo.szDevice, NULL, NULL, NULL);
- /* get pixels per inch */
+
float dpiX = (float)GetDeviceCaps(hdc, LOGPIXELSX);
- float dpiY = (float)GetDeviceCaps(hdc, LOGPIXELSX);
+ float dpiY = (float)GetDeviceCaps(hdc, LOGPIXELSY);
node->mon.scaleX = dpiX / 96.0f;
node->mon.scaleY = dpiY / 96.0f;
@@ -11717,6 +12637,18 @@ void RGFW_win32_createMonitor(DISPLAY_DEVICEW* adapter, DISPLAY_DEVICEW* dd) {
if (monitorInfo.dwFlags & MONITORINFOF_PRIMARY) {
_RGFW->monitors.primary = node;
}
+}
+
+RGFWDEF void RGFW_win32_createMonitor(DISPLAY_DEVICEW* adapter, DISPLAY_DEVICEW* dd);
+void RGFW_win32_createMonitor(DISPLAY_DEVICEW* adapter, DISPLAY_DEVICEW* dd) {
+ RGFW_monitorNode* node = RGFW_monitors_add(NULL);
+ RGFW_win32_initMonitor(adapter, node);
+
+ wcscpy(node->adapterName, adapter->DeviceName);
+ wcscpy(node->deviceName, dd->DeviceName);
+
+ i32 size = RGFW_createUTF8FromWideStringWin32(dd->DeviceString, node->mon.name, sizeof(node->mon.name));
+ node->mon.name[size - 1] = '\0';
RGFW_monitorCallback(_RGFW->root, &node->mon, RGFW_TRUE);
}
@@ -11758,7 +12690,7 @@ void RGFW_pollMonitors(void) {
for (node = _RGFW->monitors.list.head; node; node = node->next) {
if (node->disconnected == RGFW_TRUE && wcscmp(node->deviceName, dd.DeviceName) == 0) {
node->disconnected = RGFW_FALSE;
- EnumDisplayMonitors(NULL, NULL, RGFW_win32_getMonitorHandle, (LPARAM) &node->mon);
+ RGFW_win32_initMonitor(&adapter, node);
break;
}
}
@@ -11776,6 +12708,7 @@ void RGFW_pollMonitors(void) {
for (node = _RGFW->monitors.list.head; node; node = node->next) {
if (node->disconnected == RGFW_TRUE && wcscmp(node->adapterName, adapter.DeviceName) == 0) {
node->disconnected = RGFW_FALSE;
+ RGFW_win32_initMonitor(&adapter, node);
break;
}
}
@@ -11783,14 +12716,16 @@ void RGFW_pollMonitors(void) {
if (node) {
continue;
}
-
- RGFW_win32_createMonitor(&adapter, NULL);
}
}
RGFW_monitors_refresh();
}
+void RGFW_monitorNode_free(RGFW_monitorNode* node) {
+ RGFW_ASSERT(node);
+}
+
RGFW_monitor* RGFW_window_getMonitor(RGFW_window* win) {
HMONITOR src = MonitorFromWindow(win->src.window, MONITOR_DEFAULTTOPRIMARY);
RGFW_monitorNode* node = _RGFW->monitors.list.head;
@@ -11805,6 +12740,7 @@ RGFW_monitor* RGFW_window_getMonitor(RGFW_window* win) {
}
RGFW_bool RGFW_monitor_setMode(RGFW_monitor* mon, RGFW_monitorMode* mode) {
+ RGFW_ASSERT(mon != NULL);
DEVMODEW dm;
ZeroMemory(&dm, sizeof(dm));
dm.dmSize = sizeof(dm);
@@ -11822,6 +12758,7 @@ RGFW_bool RGFW_monitor_setMode(RGFW_monitor* mon, RGFW_monitorMode* mode) {
if (ChangeDisplaySettingsExW(mon->node->adapterName, &dm, NULL, CDS_TEST, NULL) == DISP_CHANGE_SUCCESSFUL) {
if (ChangeDisplaySettingsExW(mon->node->adapterName, &dm, NULL, CDS_UPDATEREGISTRY, NULL) == DISP_CHANGE_SUCCESSFUL) {
RGFW_win32_getMode(&dm, &mon->mode);
+ mon->mode = *mode;
return RGFW_TRUE;
}
return RGFW_FALSE;
@@ -11829,7 +12766,8 @@ RGFW_bool RGFW_monitor_setMode(RGFW_monitor* mon, RGFW_monitorMode* mode) {
}
RGFW_bool RGFW_monitor_requestMode(RGFW_monitor* mon, RGFW_monitorMode* mode, RGFW_modeRequest request) {
-HMONITOR src = mon->node->hMonitor;
+ RGFW_ASSERT(mon != NULL);
+ HMONITOR src = mon->node->hMonitor;
MONITORINFOEX monitorInfo;
monitorInfo.cbSize = sizeof(MONITORINFOEX);
@@ -11968,9 +12906,10 @@ void RGFW_window_hide(RGFW_window* win) {
ShowWindow(win->src.window, SW_HIDE);
}
-void RGFW_window_show(RGFW_window* win) {
- if (win->internal.flags & RGFW_windowFocusOnShow) RGFW_window_focus(win);
- ShowWindow(win->src.window, SW_RESTORE);
+void RGFW_window_showPlatform(RGFW_window* win) {
+ if (!(win->internal.flags & RGFW_windowMaximize)) {
+ ShowWindow(win->src.window, SW_RESTORE);
+ }
}
void RGFW_window_flash(RGFW_window* win, RGFW_flashRequest request) {
@@ -12004,21 +12943,25 @@ void RGFW_window_flash(RGFW_window* win, RGFW_flashRequest request) {
#define RGFW_FREE_LIBRARY(x) if (x != NULL) FreeLibrary(x); x = NULL;
void RGFW_deinitPlatform(void) {
#ifndef RGFW_NO_DPI
- RGFW_FREE_LIBRARY(RGFW_Shcore_dll);
+ RGFW_FREE_LIBRARY(RGFW_Shcore_dll);
#endif
#ifndef RGFW_NO_WINMM
- timeEndPeriod(1);
- #ifndef RGFW_NO_LOAD_WINMM
- RGFW_FREE_LIBRARY(RGFW_winmm_dll);
- #endif
+ timeEndPeriod(1);
+ #ifndef RGFW_NO_LOAD_WINMM
+ RGFW_FREE_LIBRARY(RGFW_winmm_dll);
+ #endif
#endif
- RGFW_FREE_LIBRARY(RGFW_wgl_dll);
+ if (_RGFW->helperWindow)
+ DestroyWindow(_RGFW->helperWindow);
- RGFW_freeMouse(_RGFW->hiddenMouse);
-}
+ if (_RGFW->instance)
+ UnregisterClassW(_RGFW->wndClass.lpszClassName, _RGFW->instance);
+ if (_RGFW->hiddenMouse)
+ RGFW_freeMouse(_RGFW->hiddenMouse);
+}
void RGFW_window_closePlatform(RGFW_window* win) {
RemovePropW(win->src.window, L"RGFW");
@@ -12029,19 +12972,16 @@ void RGFW_window_closePlatform(RGFW_window* win) {
if (win->src.hIconBig) DestroyIcon(win->src.hIconBig);
}
-void RGFW_window_move(RGFW_window* win, i32 x, i32 y) {
- RGFW_ASSERT(win != NULL);
-
- win->x = x;
- win->y = y;
- SetWindowPos(win->src.window, HWND_TOP, win->x, win->y, 0, 0, SWP_NOSIZE);
+void RGFW_window_movePlatform(RGFW_window* win, i32 x, i32 y) {
+ SetWindowPos(win->src.window, HWND_TOP, x, y, 0, 0, SWP_NOSIZE);
}
-void RGFW_window_resize(RGFW_window* win, i32 w, i32 h) {
- RGFW_ASSERT(win != NULL);
+void RGFW_window_resizePlatform(RGFW_window* win, i32 w, i32 h) {
+ if (win->internal.flags & RGFW_windowNoResize) {
+ win->src.minSizeW = win->src.maxSizeW = w;
+ win->src.minSizeH = win->src.maxSizeH = h;
+ }
- win->w = w;
- win->h = h;
RECT rect = { 0, 0, w, h};
DWORD style = RGFW_winapi_window_getStyle(win, win->internal.flags);
DWORD exStyle = RGFW_winapi_window_getExStyle(win, win->internal.flags);
@@ -12115,69 +13055,84 @@ RGFW_bool RGFW_window_setIconEx(RGFW_window* win, u8* data, i32 w, i32 h, RGFW_f
#endif
}
-RGFW_ssize_t RGFW_readClipboardPtr(char* str, size_t strCapacity) {
+RGFW_bool RGFW_readClipboardPtr(RGFW_dataTransferType requestedType, u8* buffer, size_t capacity, RGFW_dataTransfer* data) {
+ RGFW_ASSERT(data != NULL);
+
+ if (requestedType != RGFW_dataText) return RGFW_FALSE;
+
/* Open the clipboard */
- if (OpenClipboard(NULL) == 0)
- return -1;
+ size_t retry = 0;
+ BOOL isOpen = FALSE;
+ while (isOpen == FALSE && retry < 3) {
+ isOpen = OpenClipboard(NULL);
+ retry += 1;
+ }
+
+ if (isOpen == FALSE) return RGFW_FALSE;
/* Get the clipboard data as a Unicode string */
HANDLE hData = GetClipboardData(CF_UNICODETEXT);
if (hData == NULL) {
CloseClipboard();
- return -1;
+ return RGFW_FALSE;
}
wchar_t* wstr = (wchar_t*) GlobalLock(hData);
- RGFW_ssize_t textLen = 0;
+ RGFW_bool ret = RGFW_TRUE;
- {
- setlocale(LC_ALL, "en_US.UTF-8");
-
- textLen = (RGFW_ssize_t)wcstombs(NULL, wstr, 0) + 1;
- if (str != NULL && (RGFW_ssize_t)strCapacity <= textLen - 1)
- textLen = 0;
+ i32 length = WideCharToMultiByte(CP_UTF8, 0, wstr, -1, NULL, 0, NULL, NULL);
+ if (length <= 0) return RGFW_FALSE;
- if (str != NULL && textLen) {
- if (textLen > 1)
- wcstombs(str, wstr, (size_t)(textLen));
+ data->length = (size_t)length;
+ data->type = RGFW_dataText;
- str[textLen - 1] = '\0';
- }
+ if (buffer != NULL && capacity < data->length) {
+ ret = RGFW_FALSE;
+ } else if (buffer != NULL && data->length) {
+ if (WideCharToMultiByte(CP_UTF8, 0, wstr, -1, (char*)buffer, length, NULL, NULL) <= 0) return RGFW_FALSE;
+ data->data = (const char*)buffer;
}
/* Release the clipboard data */
GlobalUnlock(hData);
CloseClipboard();
- return textLen;
+ return ret;
}
-void RGFW_writeClipboard(const char* text, u32 textLen) {
- HANDLE object;
- WCHAR* buffer;
-
- object = GlobalAlloc(GMEM_MOVEABLE, (1 + textLen) * sizeof(WCHAR));
+RGFW_bool RGFW_writeClipboard(const RGFW_dataTransfer* data) {
+ RGFW_ASSERT(data != NULL);
+ HANDLE object = GlobalAlloc(GMEM_MOVEABLE, data->length * sizeof(WCHAR));
if (!object)
- return;
+ return RGFW_FALSE;
- buffer = (WCHAR*) GlobalLock(object);
+ WCHAR* buffer = (WCHAR*) GlobalLock(object);
if (!buffer) {
GlobalFree(object);
- return;
+ return RGFW_FALSE;
}
- MultiByteToWideChar(CP_UTF8, 0, text, -1, buffer, (i32)textLen);
+ MultiByteToWideChar(CP_UTF8, 0, data->data, -1, buffer, (i32)data->length);
GlobalUnlock(object);
- if (!OpenClipboard(_RGFW->root->src.window)) {
+ size_t retry = 0;
+ BOOL isOpen = FALSE;
+ while (isOpen == FALSE && retry < 3) {
+ isOpen = OpenClipboard(NULL);
+ retry += 1;
+ }
+
+ if (isOpen == FALSE) {
GlobalFree(object);
- return;
+ return RGFW_FALSE;
}
EmptyClipboard();
SetClipboardData(CF_UNICODETEXT, object);
CloseClipboard();
+
+ return RGFW_TRUE;
}
void RGFW_window_moveMouse(RGFW_window* win, i32 x, i32 y) {
@@ -12187,6 +13142,36 @@ void RGFW_window_moveMouse(RGFW_window* win, i32 x, i32 y) {
SetCursorPos(x, y);
}
+#ifdef RGFW_DIRECTX
+i32 RGFW_window_createSwapChain_DirectX(RGFW_window* win, IDXGIFactory* pFactory, IUnknown* pDevice, IDXGISwapChain** swapchain) {
+ RGFW_ASSERT(win && pFactory && pDevice && swapchain);
+
+ DXGI_SWAP_CHAIN_DESC swapChainDesc;
+ RGFW_MEMZERO(&swapChainDesc, sizeof(swapChainDesc));
+ swapChainDesc.BufferCount = 2;
+ swapChainDesc.BufferDesc.Width = win->w;
+ swapChainDesc.BufferDesc.Height = win->h;
+ swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
+ swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
+ swapChainDesc.OutputWindow = (HWND)win->src.window;
+ swapChainDesc.SampleDesc.Count = 1;
+ swapChainDesc.SampleDesc.Quality = 0;
+ swapChainDesc.Windowed = TRUE;
+ swapChainDesc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;
+#ifdef __cplusplus
+ HRESULT hr = pFactory->CreateSwapChain(pDevice, &swapChainDesc, swapchain);
+#else
+ HRESULT hr = pFactory->lpVtbl->CreateSwapChain(pFactory, (IUnknown*)pDevice, &swapChainDesc, swapchain);
+#endif
+ if (FAILED(hr)) {
+ RGFW_debugCallback(RGFW_typeError, RGFW_errDirectXContext, "Failed to create DirectX swap chain!");
+ return -2;
+ }
+
+ return 0;
+}
+#endif
+
#ifdef RGFW_OPENGL
RGFW_bool RGFW_extensionSupportedPlatform_OpenGL(const char * extension, size_t len) {
const char* extensions = NULL;
@@ -12195,97 +13180,27 @@ RGFW_bool RGFW_extensionSupportedPlatform_OpenGL(const char * extension, size_t
RGFW_proc proc2 = RGFW_getProcAddress_OpenGL("wglGetExtensionsStringEXT");
if (proc)
- extensions = ((const char* (*)(HDC))proc)(wglGetCurrentDC());
+ extensions = ((const char* (*)(HDC))proc)(RGFW_wglGetCurrentDC());
else if (proc2)
extensions = ((const char*(*)(void))proc2)();
return extensions != NULL && RGFW_extensionSupportedStr(extensions, extension, len);
}
RGFW_proc RGFW_getProcAddress_OpenGL(const char* procname) {
- RGFW_proc proc = (RGFW_proc)wglGetProcAddress(procname);
+ RGFW_proc proc = (RGFW_proc)_RGFW->glGetProcAddress(procname);
if (proc)
return proc;
- return (RGFW_proc) GetProcAddress(RGFW_wgl_dll, procname);
+ return (RGFW_proc) GetProcAddress((HMODULE)_RGFW->nativeGL_handle, procname);
}
-void RGFW_win32_loadOpenGLFuncs(HWND dummyWin) {
- if (wglSwapIntervalEXT != NULL && wglChoosePixelFormatARB != NULL && wglChoosePixelFormatARB != NULL)
- return;
-
- HDC dummy_dc = GetDC(dummyWin);
- u32 pfd_flags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
-
- 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};
-
- int dummy_pixel_format = ChoosePixelFormat(dummy_dc, &pfd);
- SetPixelFormat(dummy_dc, dummy_pixel_format, &pfd);
-
- HGLRC dummy_context = wglCreateContext(dummy_dc);
-
- HGLRC cur = wglGetCurrentContext();
- wglMakeCurrent(dummy_dc, dummy_context);
-
- wglCreateContextAttribsARB = ((PFNWGLCREATECONTEXTATTRIBSARBPROC(WINAPI *)(const char*)) wglGetProcAddress)("wglCreateContextAttribsARB");
- wglChoosePixelFormatARB = ((PFNWGLCHOOSEPIXELFORMATARBPROC(WINAPI *)(const char*)) wglGetProcAddress)("wglChoosePixelFormatARB");
-
- wglSwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC)(RGFW_proc)wglGetProcAddress("wglSwapIntervalEXT");
- if (wglSwapIntervalEXT == NULL) {
- RGFW_debugCallback(RGFW_typeError, RGFW_errOpenGLContext, "Failed to load swap interval function");
- }
-
- wglMakeCurrent(dummy_dc, cur);
- wglDeleteContext(dummy_context);
- ReleaseDC(dummyWin, dummy_dc);
-}
-
-#define WGL_ACCELERATION_ARB 0x2003
-#define WGL_FULL_ACCELERATION_ARB 0x2027
-#define WGL_DRAW_TO_WINDOW_ARB 0x2001
-#define WGL_PIXEL_TYPE_ARB 0x2013
-#define WGL_TYPE_RGBA_ARB 0x202b
-#define WGL_SUPPORT_OPENGL_ARB 0x2010
-#define WGL_COLOR_BITS_ARB 0x2014
-#define WGL_DOUBLE_BUFFER_ARB 0x2011
-#define WGL_ALPHA_BITS_ARB 0x201b
-#define WGL_DEPTH_BITS_ARB 0x2022
-#define WGL_STENCIL_BITS_ARB 0x2023
-#define WGL_STEREO_ARB 0x2012
-#define WGL_AUX_BUFFERS_ARB 0x2024
-#define WGL_RED_BITS_ARB 0x2015
-#define WGL_GREEN_BITS_ARB 0x2017
-#define WGL_BLUE_BITS_ARB 0x2019
-#define WGL_ACCUM_RED_BITS_ARB 0x201e
-#define WGL_ACCUM_GREEN_BITS_ARB 0x201f
-#define WGL_ACCUM_BLUE_BITS_ARB 0x2020
-#define WGL_ACCUM_ALPHA_BITS_ARB 0x2021
-#define WGL_COLORSPACE_SRGB_EXT 0x3089
-#define WGL_CONTEXT_OPENGL_NO_ERROR_ARB 0x31b3
-#define WGL_CONTEXT_RELEASE_BEHAVIOR_ARB 0x2097
-#define WGL_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB 0x0000
-#define WGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB 0x2098
-#define WGL_CONTEXT_FLAGS_ARB 0x2094
-#define WGL_ACCESS_READ_WRITE_NV 0x00000001
-#define WGL_COVERAGE_SAMPLES_NV 0x2042
-#define WGL_CONTEXT_ES_PROFILE_BIT_EXT 0x00000004
-#define WGL_CONTEXT_PROFILE_MASK_ARB 0x9126
-#define WGL_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001
-#define WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002
-#define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x00000002
-#define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091
-#define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092
-#define WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB 0x20A9
-#define WGL_CONTEXT_RELEASE_BEHAVIOR_ARB 0x2097
-#define WGL_CONTEXT_DEBUG_BIT_ARB 0x00000001
-#define WGL_CONTEXT_ROBUST_ACCESS_BIT_ARB 0x00000004
-
-RGFW_bool RGFW_window_createContextPtr_OpenGL(RGFW_window* win, RGFW_glContext* ctx, RGFW_glHints* hints) {
+RGFW_bool RGFW_createContextPtr_OpenGL(RGFW_glContext* ctx, RGFW_glHints* hints) {
const char flushControl[] = "WGL_ARB_context_flush_control";
const char noError[] = "WGL_ARB_create_context_no_error";
const char robustness[] = "WGL_ARB_create_context_robustness";
- win->src.ctx.native = ctx;
- win->src.gfxType = RGFW_gfxNativeOpenGL;
+ HWND dummyWindow = CreateWindowW(_RGFW->wndClass.lpszClassName, (wchar_t*)NULL, 0, 0, 0, 0, 0, 0, 0, _RGFW->instance, 0);
+ HDC hdc = GetDC(dummyWindow);
PIXELFORMATDESCRIPTOR pfd;
pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
@@ -12293,9 +13208,9 @@ RGFW_bool RGFW_window_createContextPtr_OpenGL(RGFW_window* win, RGFW_glContext*
pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
pfd.iPixelType = PFD_TYPE_RGBA;
pfd.iLayerType = PFD_MAIN_PLANE;
- pfd.cColorBits = 32;
- pfd.cAlphaBits = 8;
- pfd.cDepthBits = 24;
+ pfd.cColorBits = (BYTE)(hints->red + hints->green + hints->blue + hints->alpha);
+ pfd.cAlphaBits = (BYTE)hints->alpha;
+ pfd.cDepthBits = (BYTE)hints->depth;
pfd.cStencilBits = (BYTE)hints->stencil;
pfd.cAuxBuffers = (BYTE)hints->auxBuffers;
if (hints->stereo) pfd.dwFlags |= PFD_STEREO;
@@ -12305,8 +13220,8 @@ RGFW_bool RGFW_window_createContextPtr_OpenGL(RGFW_window* win, RGFW_glContext*
pfd.dwFlags |= PFD_GENERIC_FORMAT | PFD_GENERIC_ACCELERATED;
/* get pixel format, default to a basic pixel format */
- int pixel_format = ChoosePixelFormat(win->src.hdc, &pfd);
- if (wglChoosePixelFormatARB != NULL) {
+ ctx->format = ChoosePixelFormat(hdc, &pfd);
+ if (RGFW_wglChoosePixelFormatARB != NULL) {
i32 pixel_format_attribs[50];
RGFW_attribStack stack;
RGFW_attribStack_init(&stack, pixel_format_attribs, 50);
@@ -12315,7 +13230,7 @@ RGFW_bool RGFW_window_createContextPtr_OpenGL(RGFW_window* win, RGFW_glContext*
RGFW_attribStack_pushAttribs(&stack, WGL_DRAW_TO_WINDOW_ARB, 1);
RGFW_attribStack_pushAttribs(&stack, WGL_PIXEL_TYPE_ARB, WGL_TYPE_RGBA_ARB);
RGFW_attribStack_pushAttribs(&stack, WGL_SUPPORT_OPENGL_ARB, 1);
- RGFW_attribStack_pushAttribs(&stack, WGL_COLOR_BITS_ARB, 32);
+ RGFW_attribStack_pushAttribs(&stack, WGL_COLOR_BITS_ARB, hints->red + hints->green + hints->blue + hints->alpha);
RGFW_attribStack_pushAttribs(&stack, WGL_DOUBLE_BUFFER_ARB, 1);
RGFW_attribStack_pushAttribs(&stack, WGL_ALPHA_BITS_ARB, hints->alpha);
RGFW_attribStack_pushAttribs(&stack, WGL_DEPTH_BITS_ARB, hints->depth);
@@ -12337,24 +13252,28 @@ RGFW_bool RGFW_window_createContextPtr_OpenGL(RGFW_window* win, RGFW_glContext*
RGFW_attribStack_pushAttribs(&stack, WGL_COLORSPACE_SRGB_EXT, hints->sRGB);
}
- RGFW_attribStack_pushAttribs(&stack, WGL_COVERAGE_SAMPLES_NV, hints->samples);
+ if (hints->samples) {
+ RGFW_attribStack_pushAttribs(&stack, WGL_SAMPLE_BUFFERS_ARB, 1);
+ RGFW_attribStack_pushAttribs(&stack, WGL_SAMPLES_ARB, hints->samples);
+ }
RGFW_attribStack_pushAttribs(&stack, 0, 0);
int new_pixel_format;
UINT num_formats;
- wglChoosePixelFormatARB(win->src.hdc, pixel_format_attribs, 0, 1, &new_pixel_format, &num_formats);
+ RGFW_wglChoosePixelFormatARB(hdc, pixel_format_attribs, 0, 1, &new_pixel_format, &num_formats);
if (!num_formats)
RGFW_debugCallback(RGFW_typeError, RGFW_errOpenGLContext, "Failed to create a pixel format for WGL");
- else pixel_format = new_pixel_format;
+ else ctx->format = new_pixel_format;
}
+
PIXELFORMATDESCRIPTOR suggested;
- if (!DescribePixelFormat(win->src.hdc, pixel_format, sizeof(suggested), &suggested) ||
- !SetPixelFormat(win->src.hdc, pixel_format, &pfd))
+ if (!DescribePixelFormat(hdc, ctx->format, sizeof(suggested), &suggested) ||
+ !SetPixelFormat(hdc, ctx->format, &suggested))
RGFW_debugCallback(RGFW_typeError, RGFW_errOpenGLContext, "Failed to set the WGL pixel format");
- if (wglCreateContextAttribsARB != NULL) {
+ if (RGFW_wglCreateContextAttribsARB != NULL) {
/* create OpenGL/WGL context for the specified version */
i32 attribs[40];
RGFW_attribStack stack;
@@ -12398,41 +13317,109 @@ RGFW_bool RGFW_window_createContextPtr_OpenGL(RGFW_window* win, RGFW_glContext*
RGFW_attribStack_pushAttribs(&stack, 0, 0);
- win->src.ctx.native->ctx = (HGLRC)wglCreateContextAttribsARB(win->src.hdc, NULL, attribs);
+ ctx->ctx = (HGLRC)RGFW_wglCreateContextAttribsARB(hdc, NULL, attribs);
}
- if (wglCreateContextAttribsARB == NULL || win->src.ctx.native->ctx == NULL) { /* fall back to a default context (probably OpenGL 2 or something) */
+ if (RGFW_wglCreateContextAttribsARB == NULL || ctx->ctx == NULL) { /* fall back to a default context (probably OpenGL 2 or something) */
RGFW_debugCallback(RGFW_typeError, RGFW_errOpenGLContext, "Failed to create an accelerated OpenGL Context.");
- win->src.ctx.native->ctx = wglCreateContext(win->src.hdc);
+ ctx->ctx = RGFW_wglCreateContext(hdc);
}
- ReleaseDC(win->src.window, win->src.hdc);
- win->src.hdc = GetDC(win->src.window);
-
if (hints->share) {
- wglShareLists((HGLRC)RGFW_getCurrentContext_OpenGL(), hints->share->ctx);
+ RGFW_wglShareLists((HGLRC)RGFW_getCurrentContext_OpenGL(), hints->share->ctx);
}
- wglMakeCurrent(win->src.hdc, win->src.ctx.native->ctx);
+ DestroyWindow(dummyWindow);
+
RGFW_debugCallback(RGFW_typeInfo, RGFW_infoOpenGL, "OpenGL context initalized.");
return RGFW_TRUE;
}
-void RGFW_window_deleteContextPtr_OpenGL(RGFW_window* win, RGFW_glContext* ctx) {
- wglDeleteContext((HGLRC) ctx->ctx); /*!< delete OpenGL context */
- win->src.ctx.native->ctx = NULL;
+RGFW_bool RGFW_window_setContext_OpenGL(RGFW_window* win, RGFW_glContext* ctx) {
+ RGFW_ASSERT(win);
+ if (ctx == NULL && win->src.ctx.native != NULL) {
+ RGFW_debugCallback(RGFW_typeInfo, RGFW_infoOpenGL, "OpenGL surface freed.");
+ win->src.ctx.native = NULL;
+
+ RGFW_debugCallback(RGFW_typeInfo, RGFW_infoOpenGL, "OpenGL window surface freed");
+ return RGFW_TRUE;
+ }
+
+ win->src.ctx.native = ctx;
+ win->src.gfxType = RGFW_gfxNativeOpenGL;
+
+ PIXELFORMATDESCRIPTOR suggested;
+ if (!DescribePixelFormat(win->src.hdc, ctx->format, sizeof(suggested), &suggested) ||
+ !SetPixelFormat(win->src.hdc, ctx->format, &suggested))
+ RGFW_debugCallback(RGFW_typeError, RGFW_errOpenGLContext, "Failed to set the WGL pixel format");
+
+ if (RGFW_wglMakeCurrent(win->src.hdc, win->src.ctx.native->ctx) == FALSE) {
+ /*
+ Windows may fail to set the pixel format if the window was already created,
+ this tries to make a new window as a fallback
+ */
+
+ int length = GetWindowTextLengthW(win->src.window);
+ char* name = NULL;
+ if (length > 0) {
+ WCHAR* buffer = (WCHAR*)RGFW_ALLOC(sizeof(WCHAR) * (size_t)(length));
+ if (GetWindowTextW(win->src.window, buffer, length) > 0) {
+ i32 clength = RGFW_createUTF8FromWideStringWin32(buffer, NULL, 0);
+ if (clength > 0) {
+ name = (char*)RGFW_ALLOC((size_t)clength + 1);
+ if (RGFW_createUTF8FromWideStringWin32(buffer, name, (size_t)clength) > 0) {
+ name[clength] = '\0';
+ } else {
+ RGFW_FREE(name);
+ name = NULL;
+ }
+ }
+ RGFW_FREE(buffer);
+ }
+ }
+
+ RGFW_window_closePlatform(win);
+ win = RGFW_createWindowPlatform(name ? name : "", win->internal.flags, win);
+
+ if (name) RGFW_FREE(name);
+
+ win->src.ctx.native = ctx;
+ win->src.gfxType = RGFW_gfxNativeOpenGL;
+
+ if (!DescribePixelFormat(win->src.hdc, ctx->format, sizeof(suggested), &suggested) ||
+ !SetPixelFormat(win->src.hdc, ctx->format, &suggested))
+ RGFW_debugCallback(RGFW_typeError, RGFW_errOpenGLContext, "Failed to set the WGL pixel format");
+
+ if (RGFW_wglMakeCurrent(win->src.hdc, win->src.ctx.native->ctx) == FALSE) {
+ RGFW_debugCallback(RGFW_typeInfo, RGFW_infoOpenGL, "failed to create OpenGL surface.");
+ return RGFW_FALSE;
+ }
+ }
+
+ RGFW_window_swapInterval_OpenGL(win, 0);
+ RGFW_debugCallback(RGFW_typeInfo, RGFW_infoOpenGL, "OpenGL surface initalized.");
+ return RGFW_TRUE;
+}
+
+void RGFW_deleteContextPtr_OpenGL(RGFW_glContext* ctx) {
+ RGFW_wglDeleteContext((HGLRC) ctx->ctx); /*!< delete OpenGL context */
RGFW_debugCallback(RGFW_typeInfo, RGFW_infoOpenGL, "OpenGL context freed.");
}
void RGFW_window_makeCurrentContext_OpenGL(RGFW_window* win) {
if (win == NULL)
- wglMakeCurrent(NULL, NULL);
+ RGFW_wglMakeCurrent(NULL, NULL);
else
- wglMakeCurrent(win->src.hdc, (HGLRC) win->src.ctx.native->ctx);
+ RGFW_wglMakeCurrent(win->src.hdc, (HGLRC) win->src.ctx.native->ctx);
}
void* RGFW_getCurrentContext_OpenGL(void) {
- return wglGetCurrentContext();
+ return RGFW_wglGetCurrentContext();
+}
+
+void* RGFW_getCurrentSurface_OpenGL(void) {
+ return RGFW_wglGetCurrentDC();
}
+
void RGFW_window_swapBuffers_OpenGL(RGFW_window* win) {
RGFW_ASSERT(win->src.ctx.native);
SwapBuffers(win->src.hdc);
@@ -12440,31 +13427,18 @@ void RGFW_window_swapBuffers_OpenGL(RGFW_window* win) {
void RGFW_window_swapInterval_OpenGL(RGFW_window* win, i32 swapInterval) {
RGFW_ASSERT(win != NULL);
- if (wglSwapIntervalEXT == NULL || wglSwapIntervalEXT(swapInterval) == FALSE)
- RGFW_debugCallback(RGFW_typeError, RGFW_errOpenGLContext, "Failed to set swap interval");
-}
-#endif
+ void* ctx = RGFW_getCurrentContext_OpenGL();
+ void* surf = RGFW_getCurrentSurface_OpenGL();
+ if (ctx != win->src.ctx.native->ctx || surf != win->src.hdc)
+ RGFW_wglMakeCurrent(win->src.hdc, (HGLRC) win->src.ctx.native->ctx);
-RGFW_bool RGFW_createUTF8FromWideStringWin32(const WCHAR* source, char* output, size_t max) {
- i32 size = 0;
- if (source == NULL) {
- return RGFW_FALSE;
- }
- size = WideCharToMultiByte(CP_UTF8, 0, source, -1, NULL, 0, NULL, NULL);
- if (!size) {
- return RGFW_FALSE;
- }
-
- if (size > (i32)max)
- size = (i32)max;
-
- if (!WideCharToMultiByte(CP_UTF8, 0, source, -1, output, size, NULL, NULL)) {
- return RGFW_FALSE;
- }
+ if (RGFW_wglSwapIntervalEXT == NULL || RGFW_wglSwapIntervalEXT(swapInterval) == FALSE)
+ RGFW_debugCallback(RGFW_typeError, RGFW_errOpenGLContext, "Failed to set swap interval");
- output[size] = 0;
- return RGFW_TRUE;
+ if (ctx != win->src.ctx.native->ctx || surf != win->src.hdc)
+ RGFW_wglMakeCurrent((HDC)surf, (HGLRC)ctx);
}
+#endif
#ifdef RGFW_WEBGPU
WGPUSurface RGFW_window_createSurface_WebGPU(RGFW_window* window, WGPUInstance instance) {
@@ -12473,7 +13447,7 @@ WGPUSurface RGFW_window_createSurface_WebGPU(RGFW_window* window, WGPUInstance i
fromHwnd.chain.sType = WGPUSType_SurfaceSourceWindowsHWND;
fromHwnd.hwnd = window->src.window;
- fromHwnd.hinstance = GetModuleHandle(NULL);
+ fromHwnd.hinstance = _RGFW->instance;
surfaceDesc.nextInChain = (WGPUChainedStruct*)&fromHwnd.chain;
return wgpuInstanceCreateSurface(instance, &surfaceDesc);
@@ -12523,12 +13497,15 @@ PFN_LMGetKbdType LMGetKbdTypeSrc;
CFStringRef kTISPropertyUnicodeKeyLayoutDataSrc;
+#define RSGL_NSPasteboardTypeURL "public.url"
+#define RSGL_NSPasteboardTypeFileURL "public.file-url"
+#define RSGL_NSPasteboardTypeString "public.utf8-plain-text"
+
#ifndef __OBJC__
typedef CGRect NSRect;
typedef CGPoint NSPoint;
typedef CGSize NSSize;
-typedef const char* NSPasteboardType;
typedef unsigned long NSUInteger;
typedef long NSInteger;
typedef NSInteger NSModalResponse;
@@ -12538,19 +13515,19 @@ typedef enum NSRequestUserAttentionType {
NSInformationalRequest = 10
} NSRequestUserAttentionType;
-typedef enum NSApplicationActivationPolicy {
+typedef RGFW_ENUM(NSInteger, NSApplicationActivationPolicy) {
NSApplicationActivationPolicyRegular,
NSApplicationActivationPolicyAccessory,
NSApplicationActivationPolicyProhibited
-} NSApplicationActivationPolicy;
+};
-typedef RGFW_ENUM(u32, NSBackingStoreType) {
+typedef RGFW_ENUM(NSUInteger, NSBackingStoreType) {
NSBackingStoreRetained = 0,
NSBackingStoreNonretained = 1,
NSBackingStoreBuffered = 2
};
-typedef RGFW_ENUM(u32, NSWindowStyleMask) {
+typedef RGFW_ENUM(NSUInteger, NSWindowStyleMask) {
NSWindowStyleMaskBorderless = 0,
NSWindowStyleMaskTitled = 1 << 0,
NSWindowStyleMaskClosable = 1 << 1,
@@ -12566,9 +13543,7 @@ typedef RGFW_ENUM(u32, NSWindowStyleMask) {
NSWindowStyleMaskHUDWindow = 1 << 13
};
-#define NSPasteboardTypeString "public.utf8-plain-text"
-
-typedef RGFW_ENUM(i32, NSDragOperation) {
+typedef RGFW_ENUM(NSUInteger, NSDragOperation) {
NSDragOperationNone = 0,
NSDragOperationCopy = 1,
NSDragOperationLink = 2,
@@ -12608,8 +13583,6 @@ typedef RGFW_ENUM(NSInteger, NSWindowButton) {
NSWindowFullScreenButton = 7,
};
-#define NSPasteboardTypeURL "public.url"
-#define NSPasteboardTypeFileURL "public.file-url"
#define NSTrackingMouseEnteredAndExited 0x01
#define NSTrackingMouseMoved 0x02
#define NSTrackingCursorUpdate 0x04
@@ -12665,19 +13638,19 @@ enum {
NSOpenGLPFARemotePixelBuffer = 91,
};
-typedef RGFW_ENUM(u32, NSEventType) { /* various types of events */
+typedef RGFW_ENUM(NSUInteger, NSEventType) { /* various types of events */
NSEventTypeApplicationDefined = 15,
};
-typedef unsigned long long NSEventMask;
+typedef NSUInteger NSEventMask;
-typedef enum NSEventModifierFlags {
+typedef RGFW_ENUM(NSUInteger, NSEventModifierFlags) {
NSEventModifierFlagCapsLock = 1 << 16,
NSEventModifierFlagShift = 1 << 17,
NSEventModifierFlagControl = 1 << 18,
NSEventModifierFlagOption = 1 << 19,
NSEventModifierFlagCommand = 1 << 20,
NSEventModifierFlagNumericPad = 1 << 21
-} NSEventModifierFlags;
+};
typedef RGFW_ENUM(NSUInteger, NSBitmapFormat) {
NSBitmapFormatAlphaFirst = 1 << 0, /* 0 means is alpha last (RGBA, CMYKA, etc.) */
@@ -12731,6 +13704,17 @@ id NSString_stringWithUTF8String(const char* str) {
RGFWDEF float RGFW_cocoaYTransform(float y);
float RGFW_cocoaYTransform(float y) { return (float)(CGDisplayBounds(CGMainDisplayID()).size.height - (double)y - (double)1.0f); }
+RGFWDEF void RGFW_cocoaFetchRect(RGFW_window* win);
+void RGFW_cocoaFetchRect(RGFW_window* win) {
+ NSRect frame = ((NSRect(*)(id, SEL))abi_objc_msgSend_stret)((id)win->src.window, sel_registerName("frame"));
+ NSRect content = ((NSRect(*)(id, SEL, NSRect))abi_objc_msgSend_stret)((id)win->src.window, sel_registerName("contentRectForFrameRect:"), frame);
+
+ win->x = (i32)content.origin.x;
+ win->y = (i32)RGFW_cocoaYTransform((float)(content.origin.y + content.size.height - 1));
+ win->w = (i32)content.size.width;
+ win->h = (i32)content.size.height;
+}
+
const char* NSString_to_char(id str);
const char* NSString_to_char(id str) {
return ((const char* (*)(id, SEL)) objc_msgSend) ((id)(id)str, sel_registerName("UTF8String"));
@@ -12772,8 +13756,8 @@ id* cstrToNSStringArray(char** strs, size_t len) {
return nstrs;
}
-const char* NSPasteboard_stringForType(id pasteboard, NSPasteboardType dataType, size_t* len);
-const char* NSPasteboard_stringForType(id pasteboard, NSPasteboardType dataType, size_t* len) {
+const char* NSPasteboard_stringForType(id pasteboard, const char* dataType, size_t* len);
+const char* NSPasteboard_stringForType(id pasteboard, const char* dataType, size_t* len) {
SEL func = sel_registerName("stringForType:");
id nsstr = NSString_stringWithUTF8String((const char*)dataType);
id nsString = ((id(*)(id, SEL, id))objc_msgSend)(pasteboard, func, nsstr);
@@ -12789,8 +13773,8 @@ id c_array_to_NSArray(void* array, size_t len) {
}
-void NSregisterForDraggedTypes(id view, NSPasteboardType* newTypes, size_t len);
-void NSregisterForDraggedTypes(id view, NSPasteboardType* newTypes, size_t len) {
+void NSregisterForDraggedTypes(id view, const char** newTypes, size_t len);
+void NSregisterForDraggedTypes(id view, const char** newTypes, size_t len) {
id* ntypes = cstrToNSStringArray((char**)newTypes, len);
id array = c_array_to_NSArray(ntypes, len);
@@ -12798,8 +13782,8 @@ void NSregisterForDraggedTypes(id view, NSPasteboardType* newTypes, size_t len)
NSRelease(array);
}
-NSInteger NSPasteBoard_declareTypes(id pasteboard, NSPasteboardType* newTypes, size_t len, void* owner);
-NSInteger NSPasteBoard_declareTypes(id pasteboard, NSPasteboardType* newTypes, size_t len, void* owner) {
+NSInteger NSPasteBoard_declareTypes(id pasteboard, const char** newTypes, size_t len, void* owner);
+NSInteger NSPasteBoard_declareTypes(id pasteboard, const char** newTypes, size_t len, void* owner) {
id* ntypes = cstrToNSStringArray((char**)newTypes, len);
SEL func = sel_registerName("declareTypes:owner:");
@@ -12813,8 +13797,6 @@ NSInteger NSPasteBoard_declareTypes(id pasteboard, NSPasteboardType* newTypes, s
return output;
}
-#define NSRetain(obj) objc_msgSend_void((id)obj, sel_registerName("retain"))
-
/*
End of cocoa wrapper
*/
@@ -12847,24 +13829,16 @@ static id RGFW__osxCustomInitWithRGFWWindow(id self, SEL _cmd, RGFW_window* win)
((void (*)(id, SEL))objc_msgSend)(self, sel_registerName("updateTrackingAreas"));
- ((void (*)(id, SEL, id))objc_msgSend)(
- self, sel_registerName("registerForDraggedTypes:"),
- ((id (*)(Class, SEL, id))objc_msgSend)(
- objc_getClass("NSArray"),
- sel_registerName("arrayWithObject:"),
- ((id (*)(Class, SEL, const char*))objc_msgSend)(
- objc_getClass("NSString"),
- sel_registerName("stringWithUTF8String:"),
- "public.url"
- )
- )
- );
- }
+ const char* types[] = {RSGL_NSPasteboardTypeURL, RSGL_NSPasteboardTypeFileURL, RSGL_NSPasteboardTypeString};
+ NSregisterForDraggedTypes((id)self, types, 3);
+
+ }
return self;
}
-static u32 RGFW_OnClose(id self) {
+static BOOL RGFW_osxWindowShouldClose(id self, SEL _cmd, id sender) {
+ RGFW_UNUSED(_cmd); RGFW_UNUSED(sender);
RGFW_window* win = NULL;
object_getInstanceVariable(self, (const char*)"RGFW_window", (void**)&win);
if (win == NULL) return true;
@@ -12873,9 +13847,47 @@ static u32 RGFW_OnClose(id self) {
return false;
}
-/* NOTE(EimaMei): Fixes the constant clicking when the app is running under a terminal. */
-static bool RGFW__osxAcceptsFirstResponder(void) { return true; }
-static bool RGFW__osxPerformKeyEquivalent(id event) { RGFW_UNUSED(event); return true; }
+static BOOL RGFW__osxAcceptsFirstResponder(id self, SEL _cmd) { RGFW_UNUSED(self); RGFW_UNUSED(_cmd); return true; }
+static BOOL RGFW__osxPerformKeyEquivalent(id self, SEL _cmd, id event) {
+ RGFW_UNUSED(_cmd);
+ RGFW_window* win = NULL;
+ object_getInstanceVariable(self, (const char*)"RGFW_window", (void**)&win);
+ if (win == NULL) return true;
+
+ /* claim and emit consumed key combinations so they aren't missed (hack borrowed from GLFW (I'm not giving it back)) */
+ u32 key = (u16)((u32(*)(id, SEL))objc_msgSend)(event, sel_registerName("keyCode"));
+ RGFW_key value = (u8)RGFW_apiKeyToRGFW(key);
+
+ u32 flags = (u32)((u32(*)(id, SEL))objc_msgSend)(event, sel_registerName("modifierFlags"));
+ RGFW_keyUpdateKeyModsEx(win,
+ ((u32)(flags & NSEventModifierFlagCapsLock) % 255),
+ ((flags & NSEventModifierFlagNumericPad) % 255),
+ ((flags & NSEventModifierFlagControl) % 255),
+ ((flags & NSEventModifierFlagOption) % 255),
+ ((flags & NSEventModifierFlagShift) % 255),
+ ((flags & NSEventModifierFlagCommand) % 255), 0);
+
+ RGFW_bool repeat = RGFW_isKeyDown(value);
+
+ if (win->internal.mod & RGFW_modControl) {
+ if (key == RGFW_keyTab || key == RGFW_keyEscape) {
+ RGFW_keyCallback(win, value, win->internal.mod, repeat, 1);
+ return YES;
+ }
+ }
+
+ if (win->internal.mod & RGFW_modSuper) {
+ if (key == RGFW_keyPeriod) {
+ RGFW_keyCallback(win, value, win->internal.mod, repeat, 1);
+ return YES;
+ }
+ }
+
+ struct objc_super s = { self, class_getSuperclass(object_getClass(self)) };
+ return ((bool (*)(struct objc_super*, SEL, id))objc_msgSendSuper)(&s, sel_registerName("performKeyEquivalent:"), event);
+}
+
+static BOOL RGFW__osxAcceptsFirstMouse(id self, SEL _cmd, id event) { RGFW_UNUSED(self); RGFW_UNUSED(_cmd); RGFW_UNUSED(event); return true; }
static NSDragOperation RGFW__osxDraggingEntered(id self, SEL sel, id sender) {
RGFW_UNUSED(sel);
@@ -12902,7 +13914,7 @@ static NSDragOperation RGFW__osxDraggingUpdated(id self, SEL sel, id sender) {
RGFW_dataDragCallback(win, RGFW_dataFile, RGFW_dndActionMove, (i32) p.x, (i32) (win->h - p.y));
return NSDragOperationCopy;
}
-static bool RGFW__osxPrepareForDragOperation(id self) {
+static BOOL RGFW__osxPrepareForDragOperation(id self) {
RGFW_window* win = NULL;
object_getInstanceVariable(self, "RGFW_window", (void**)&win);
if (win == NULL || (!(win->internal.enabledEvents & RGFW_dataDropFlag)))
@@ -12929,7 +13941,7 @@ static void RGFW__osxDraggingEnded(id self, SEL sel, id sender) {
return;
}
-static bool RGFW__osxPerformDragOperation(id self, SEL sel, id sender) {
+static BOOL RGFW__osxPerformDragOperation(id self, SEL sel, id sender) {
RGFW_UNUSED(sender); RGFW_UNUSED(self); RGFW_UNUSED(sel);
RGFW_window* win = NULL;
object_getInstanceVariable(self, "RGFW_window", (void**)&win);
@@ -12952,17 +13964,25 @@ static bool RGFW__osxPerformDragOperation(id self, SEL sel, id sender) {
return 0;
}
- id fileURLs = objc_msgSend_id_id(pasteBoard, sel_registerName("propertyListForType:"), fileURLsType);
- int count = ((int (*)(id, SEL))objc_msgSend)(fileURLs, sel_registerName("count"));
+ id propertyList = objc_msgSend_id_id(pasteBoard, sel_registerName("propertyListForType:"), fileURLsType);
+
+ if (objc_msgSend_id_bool(propertyList, sel_registerName("isKindOfClass:"), objc_getClass("NSString"))) {
+ int string_count = ((int (*)(id, SEL))objc_msgSend)(propertyList , sel_registerName("length"));
+ const char *filePath = ((const char* (*)(id, SEL))objc_msgSend)(propertyList, sel_registerName("UTF8String"));
+ RGFW_dataDropCallback(win, filePath, (size_t)string_count + 1, RGFW_dataFile);
+ /*} if (objc_msgSend_id_bool(propertyList, sel_registerName("isKindOfClass:"), objc_getClass("NSData"))) { */
+ } if (objc_msgSend_id_bool(propertyList, sel_registerName("isKindOfClass:"), objc_getClass("NSArray")) == false) return false;
+
+ int count = ((int (*)(id, SEL))objc_msgSend)(propertyList, sel_registerName("count"));
if (count == 0)
return 0;
u32 i;
for (i = 0; i < (u32)count; i++) {
- id fileURL = objc_msgSend_arr(fileURLs, sel_registerName("objectAtIndex:"), i);
+ id fileURL = objc_msgSend_arr(propertyList, sel_registerName("objectAtIndex:"), i);
const char *filePath = ((const char* (*)(id, SEL))objc_msgSend)(fileURL, sel_registerName("UTF8String"));
- int string_count = ((int (*)(id, SEL))objc_msgSend)(fileURL, sel_registerName("count"));
+ int string_count = ((int (*)(id, SEL))objc_msgSend)(fileURL, sel_registerName("length"));
RGFW_dataDropCallback(win, filePath, (size_t)string_count + 1, RGFW_dataFile);
}
@@ -13050,8 +14070,23 @@ static void RGFW__osxDidChangeScreenParameters(id self, SEL _cmd, id notificatio
RGFW_pollMonitors();
}
-static void RGFW__osxWindowDeminiaturize(id self, SEL sel) {
- RGFW_UNUSED(sel);
+static NSUInteger RGFW__osxApplicationShouldTerminate(id self, SEL _cmd, id sender) {
+ RGFW_UNUSED(self); RGFW_UNUSED(_cmd); RGFW_UNUSED(sender);
+
+ id windows = objc_msgSend_id(_RGFW->NSApp, sel_registerName("windows"));
+ NSUInteger count = (NSUInteger)objc_msgSend_uint(windows, sel_registerName("count"));
+
+ for (unsigned long i = 0; i < count; i++) {
+ id window = ((id (*)(id, SEL, int))objc_msgSend) (windows, sel_registerName("objectAtIndex:"), (int)i);
+ id delegate = ((id (*)(id, SEL))objc_msgSend) (window, sel_registerName("delegate"));
+ ((void(*)(id, SEL, id))objc_msgSend)(delegate, sel_registerName("windowShouldClose:"), window);
+ }
+
+ return 0; /* NSTerminateCancel */
+}
+
+static void RGFW__osxWindowDeminiaturize(id self, SEL sel, id notification) {
+ RGFW_UNUSED(sel); RGFW_UNUSED(notification);
RGFW_window* win = NULL;
object_getInstanceVariable(self, "RGFW_window", (void**)&win);
if (win == NULL) return;
@@ -13059,8 +14094,8 @@ static void RGFW__osxWindowDeminiaturize(id self, SEL sel) {
RGFW_windowRestoredCallback(win, win->x, win->y, win->w, win->h);
}
-static void RGFW__osxWindowMiniaturize(id self, SEL sel) {
- RGFW_UNUSED(sel);
+static void RGFW__osxWindowMiniaturize(id self, SEL sel, id notification) {
+ RGFW_UNUSED(sel); RGFW_UNUSED(notification);
RGFW_window* win = NULL;
object_getInstanceVariable(self, "RGFW_window", (void**)&win);
if (win == NULL) return;
@@ -13069,8 +14104,8 @@ static void RGFW__osxWindowMiniaturize(id self, SEL sel) {
}
-static void RGFW__osxWindowBecameKey(id self, SEL sel) {
- RGFW_UNUSED(sel);
+static void RGFW__osxWindowBecameKey(id self, SEL sel, id notification) {
+ RGFW_UNUSED(sel); RGFW_UNUSED(notification);
RGFW_window* win = NULL;
object_getInstanceVariable(self, "RGFW_window", (void**)&win);
if (win == NULL) return;
@@ -13078,8 +14113,8 @@ static void RGFW__osxWindowBecameKey(id self, SEL sel) {
RGFW_windowFocusCallback(win, RGFW_TRUE);
}
-static void RGFW__osxWindowResignKey(id self, SEL sel) {
- RGFW_UNUSED(sel);
+static void RGFW__osxWindowResignKey(id self, SEL sel, id notification) {
+ RGFW_UNUSED(sel); RGFW_UNUSED(notification);
RGFW_window* win = NULL;
object_getInstanceVariable(self, "RGFW_window", (void**)&win);
if (win == NULL) return;
@@ -13113,8 +14148,8 @@ static void RGFW__osxDidWindowResize(id self, SEL _cmd, id notification) {
RGFW_windowResizedCallback(win, win->w, win->h);
}
-static void RGFW__osxWindowMove(id self, SEL sel) {
- RGFW_UNUSED(sel);
+static void RGFW__osxWindowMove(id self, SEL sel, id notification) {
+ RGFW_UNUSED(sel); RGFW_UNUSED(notification);
RGFW_window* win = NULL;
object_getInstanceVariable(self, "RGFW_window", (void**)&win);
if (win == NULL) return;
@@ -13155,7 +14190,9 @@ static void RGFW__osxDrawRect(id self, SEL _cmd, CGRect rect) {
object_getInstanceVariable(self, "RGFW_window", (void**)&win);
if (win == NULL) return;
- RGFW_windowRefreshCallback(win, 0, 0, win->w, win->h);
+ float y = RGFW_cocoaYTransform((float)(rect.size.height - 1));
+
+ RGFW_windowRefreshCallback(win, (i32)rect.origin.x, (i32)y, (i32)rect.size.width, (i32)rect.size.height);
}
static void RGFW__osxMouseEntered(id self, SEL _cmd, id event) {
@@ -13267,7 +14304,7 @@ static void RGFW__osxMouseMoved(id self, SEL _cmd, id event) {
CGFloat vecX = ((CGFloat(*)(id, SEL))abi_objc_msgSend_fpret)(event, sel_registerName("deltaX"));
CGFloat vecY = ((CGFloat(*)(id, SEL))abi_objc_msgSend_fpret)(event, sel_registerName("deltaY"));
- RGFW_mousePosCallback(win, (i32)p.x, (i32)(win->h - p.y));
+ RGFW_mouseMotionCallback(win, (i32)p.x, (i32)(win->h - p.y));
RGFW_rawMotionCallback(win, (float)vecX, (float)vecY);
}
@@ -13315,10 +14352,27 @@ static void RGFW__osxScrollWheel(id self, SEL _cmd, id event) {
object_getInstanceVariable(self, "RGFW_window", (void**)&win);
if (win == NULL) return;
- float deltaX = (float)((CGFloat(*)(id, SEL))abi_objc_msgSend_fpret)(event, sel_registerName("deltaX"));
- float deltaY = (float)((CGFloat(*)(id, SEL))abi_objc_msgSend_fpret)(event, sel_registerName("deltaY"));
+ CGFloat deltaX = ((CGFloat(*)(id, SEL))abi_objc_msgSend_fpret)(event, sel_registerName("scrollingDeltaX"));
+ CGFloat deltaY = ((CGFloat(*)(id, SEL))abi_objc_msgSend_fpret)(event, sel_registerName("scrollingDeltaY"));
+
+ if (objc_msgSend_bool(event, sel_registerName("hasPreciseScrollingDeltas"))) {
+ deltaX *= (CGFloat)0.1;
+ deltaY *= (CGFloat)0.1;
+ }
+
+ RGFW_mouseScrollCallback(win, (float)deltaX, (float)deltaY);
+}
- RGFW_mouseScrollCallback(win, deltaX, deltaY);
+BOOL RGFW__osxCanBecomeKeyWindow(id self, SEL _cmd);
+BOOL RGFW__osxCanBecomeKeyWindow(id self, SEL _cmd) {
+ RGFW_UNUSED(self); RGFW_UNUSED(_cmd);
+ return YES;
+}
+
+BOOL RGFW__osxCanBecomeMainWindow(id self, SEL _cmd);
+BOOL RGFW__osxCanBecomeMainWindow(id self, SEL _cmd) {
+ RGFW_UNUSED(self); RGFW_UNUSED(_cmd);
+ return YES;
}
RGFW_format RGFW_nativeFormat(void) { return RGFW_formatRGBA8; }
@@ -13494,7 +14548,8 @@ void RGFW_initKeycodesPlatform(void) {
_RGFW->keycodes[0x4E] = RGFW_keyPadMinus;
}
-i32 RGFW_initPlatform(void) {
+i32 RGFW_initPlatform(const char* className, RGFW_initFlags flags) {
+ RGFW_UNUSED(className); RGFW_UNUSED(flags);
_RGFW->tisBundle = (void*)CFBundleGetBundleWithIdentifier(CFSTR("com.apple.HIToolbox"));
TISGetInputSourcePropertySrc = (PFN_TISGetInputSourceProperty)CFBundleGetFunctionPointerForName((CFBundleRef)_RGFW->tisBundle, CFSTR("TISGetInputSourceProperty"));
@@ -13503,31 +14558,42 @@ i32 RGFW_initPlatform(void) {
CFStringRef* cfStr = (CFStringRef*)CFBundleGetDataPointerForName((CFBundleRef)_RGFW->tisBundle, CFSTR("kTISPropertyUnicodeKeyLayoutData"));;
if (cfStr) kTISPropertyUnicodeKeyLayoutDataSrc = *cfStr;
-
- class_addMethod(objc_getClass("NSObject"), sel_registerName("windowShouldClose:"), (IMP)(void*)RGFW_OnClose, 0);
-
- /* NOTE(EimaMei): Fixes the 'Boop' sfx from constantly playing each time you click a key. Only a problem when running in the terminal. */
- class_addMethod(objc_getClass("NSWindowClass"), sel_registerName("acceptsFirstResponder:"), (IMP)(void*)RGFW__osxAcceptsFirstResponder, 0);
- class_addMethod(objc_getClass("NSWindowClass"), sel_registerName("performKeyEquivalent:"), (IMP)(void*)RGFW__osxPerformKeyEquivalent, 0);
-
_RGFW->NSApp = objc_msgSend_id(objc_getClass("NSApplication"), sel_registerName("sharedApplication"));
-
- NSRetain(_RGFW->NSApp);
+ ((void (*)(id, SEL, NSUInteger))objc_msgSend) ((id)_RGFW->NSApp, sel_registerName("setActivationPolicy:"), NSApplicationActivationPolicyRegular);
+ /* Note about addMethod strings
+ * @ -> id, : -> SEL, B -> bool
+ * a basic char is a c-type, capital letter = unsigned, ^ = pointer
+ * e.g. i = int, I = unsigned int c = char, C = unsigned char and ^C = unsigned char*
+ * most functions start with v@: because it's `void function(id self, SEL _cmd)
+ */
_RGFW->customNSAppDelegateClass = objc_allocateClassPair(objc_getClass("NSObject"), "RGFWNSAppDelegate", 0);
+ if (_RGFW->customNSAppDelegateClass == NULL) {
+ RGFW_debugCallback(RGFW_typeError, RGFW_errObjcRuntime, "failed to create RGFWNSAppDelegate class");
+ return -1;
+ }
+
class_addMethod((Class)_RGFW->customNSAppDelegateClass, sel_registerName("applicationDidChangeScreenParameters:"), (IMP)RGFW__osxDidChangeScreenParameters, "v@:@");
+ class_addMethod((Class)_RGFW->customNSAppDelegateClass, sel_registerName("applicationShouldTerminate:"), (IMP)RGFW__osxApplicationShouldTerminate, "@:@");
objc_registerClassPair((Class)_RGFW->customNSAppDelegateClass);
_RGFW->customNSAppDelegate = objc_msgSend_id(NSAlloc(_RGFW->customNSAppDelegateClass), sel_registerName("init"));
objc_msgSend_void_id(_RGFW->NSApp, sel_registerName("setDelegate:"), _RGFW->customNSAppDelegate);
- ((void (*)(id, SEL, NSUInteger))objc_msgSend) ((id)_RGFW->NSApp, sel_registerName("setActivationPolicy:"), NSApplicationActivationPolicyRegular);
+ objc_msgSend_void(_RGFW->NSApp, sel_registerName("finishLaunching"));
_RGFW->customViewClasses[0] = objc_allocateClassPair(objc_getClass("NSView"), "RGFWCustomView", 0);
_RGFW->customViewClasses[1] = objc_allocateClassPair(objc_getClass("NSOpenGLView"), "RGFWOpenGLCustomView", 0);
for (size_t i = 0; i < 2; i++) {
- class_addIvar((Class)_RGFW->customViewClasses[i], "RGFW_window", sizeof(RGFW_window*), sizeof(RGFW_window*), "L");
- class_addMethod((Class)_RGFW->customViewClasses[i], sel_registerName("drawRect:"), (IMP)RGFW__osxDrawRect, "v@:{CGRect=ffff}");
+ if (_RGFW->customViewClasses[i] == NULL) {
+ RGFW_debugCallback(RGFW_typeError, RGFW_errObjcRuntime, (i == 0) ? "failed to create RGFWCustomView class" : "failed to create RGFWOpenGLCustomView class");
+ return -1;
+ }
+
+ RGFW_ASSERT((sizeof(RGFW_window*) <= 8)); /* some future where pointers are greater than 8 bytes (64-bit) (I'm pretty sure much more will be broken if this is the case) */
+ class_addIvar((Class)_RGFW->customViewClasses[i], "RGFW_window", sizeof(RGFW_window*), (sizeof(RGFW_window*) == 8) ? 3 : 2, "^v");
+ class_addMethod((Class)_RGFW->customViewClasses[i], sel_registerName("acceptsFirstMouse:"), (IMP)RGFW__osxAcceptsFirstMouse, "B@:@");
+ class_addMethod((Class)_RGFW->customViewClasses[i], sel_registerName("drawRect:"), (IMP)RGFW__osxDrawRect, "v@:{CGRect={CGPoint=dd}{CGSize=dd}}");
class_addMethod((Class)_RGFW->customViewClasses[i], sel_registerName("viewDidChangeBackingProperties"), (IMP)RGFW__osxViewDidChangeBackingProperties, "v@:");
class_addMethod((Class)_RGFW->customViewClasses[i], sel_registerName("mouseDown:"), (IMP)RGFW__osxMouseDown, "v@:@");
class_addMethod((Class)_RGFW->customViewClasses[i], sel_registerName("rightMouseDown:"), (IMP)RGFW__osxMouseDown, "v@:@");
@@ -13546,27 +14612,45 @@ i32 RGFW_initPlatform(void) {
class_addMethod((Class)_RGFW->customViewClasses[i], sel_registerName("mouseExited:"), (IMP)RGFW__osxMouseExited, "v@:@");
class_addMethod((Class)_RGFW->customViewClasses[i], sel_registerName("flagsChanged:"), (IMP)RGFW__osxFlagsChanged, "v@:@");
class_addMethod((Class)_RGFW->customViewClasses[i], sel_getUid("acceptsFirstResponder"), (IMP)RGFW__osxAcceptsFirstResponder, "B@:");
- class_addMethod((Class)_RGFW->customViewClasses[i], sel_registerName("initWithRGFWWindow:"), (IMP)RGFW__osxCustomInitWithRGFWWindow, "@@:{CGRect={CGPoint=dd}{CGSize=dd}}");
+ class_addMethod((Class)_RGFW->customViewClasses[i], sel_registerName("initWithRGFWWindow:"), (IMP)RGFW__osxCustomInitWithRGFWWindow, "@@:^v");
class_addMethod((Class)_RGFW->customViewClasses[i], sel_registerName("wantsUpdateLayer"), (IMP)RGFW__osxWantsUpdateLayer, "B@:");
class_addMethod((Class)_RGFW->customViewClasses[i], sel_registerName("updateLayer"), (IMP)RGFW__osxUpdateLayer, "v@:");
+ class_addMethod((Class)_RGFW->customViewClasses[i], sel_registerName("draggingEntered:"), (IMP)RGFW__osxDraggingEntered, "L@:@");
+ class_addMethod((Class)_RGFW->customViewClasses[i], sel_registerName("draggingUpdated:"), (IMP)RGFW__osxDraggingUpdated, "L@:@");
+ class_addMethod((Class)_RGFW->customViewClasses[i], sel_registerName("draggingExited:"), (IMP)RGFW__osxDraggingEnded, "v@:@");
+ class_addMethod((Class)_RGFW->customViewClasses[i], sel_registerName("draggingEnded:"), (IMP)RGFW__osxDraggingEnded, "v@:@");
+ class_addMethod((Class)_RGFW->customViewClasses[i], sel_registerName("prepareForDragOperation:"), (IMP)RGFW__osxPrepareForDragOperation, "B@:@");
+ class_addMethod((Class)_RGFW->customViewClasses[i], sel_registerName("performDragOperation:"), (IMP)RGFW__osxPerformDragOperation, "B@:@");
+ class_addMethod((Class)_RGFW->customViewClasses[i], sel_registerName("performKeyEquivalent:"), (IMP)(void*)RGFW__osxPerformKeyEquivalent, "B@:@");
objc_registerClassPair((Class)_RGFW->customViewClasses[i]);
}
_RGFW->customWindowDelegateClass = objc_allocateClassPair(objc_getClass("NSObject"), "RGFWWindowDelegate", 0);
- class_addIvar((Class)_RGFW->customWindowDelegateClass, "RGFW_window", sizeof(RGFW_window*), sizeof(RGFW_window*), "L");
+ if (_RGFW->customWindowDelegateClass == NULL) {
+ RGFW_debugCallback(RGFW_typeError, RGFW_errObjcRuntime, "failed to create RGFWWindowDelegate class");
+ return -1;
+ }
+
+ class_addIvar((Class)_RGFW->customWindowDelegateClass, "RGFW_window", sizeof(RGFW_window*), (sizeof(RGFW_window*) == 8) ? 3 : 2, "^v");
class_addMethod((Class)_RGFW->customWindowDelegateClass, sel_registerName("windowDidResize:"), (IMP)RGFW__osxDidWindowResize, "v@:@");
- class_addMethod((Class)_RGFW->customWindowDelegateClass, sel_registerName("windowDidMove:"), (IMP) RGFW__osxWindowMove, "");
- class_addMethod((Class)_RGFW->customWindowDelegateClass, sel_registerName("windowDidMiniaturize:"), (IMP) RGFW__osxWindowMiniaturize, "");
- class_addMethod((Class)_RGFW->customWindowDelegateClass, sel_registerName("windowDidDeminiaturize:"), (IMP) RGFW__osxWindowDeminiaturize, "");
- class_addMethod((Class)_RGFW->customWindowDelegateClass, sel_registerName("windowDidBecomeKey:"), (IMP) RGFW__osxWindowBecameKey, "");
- class_addMethod((Class)_RGFW->customWindowDelegateClass, sel_registerName("windowDidResignKey:"), (IMP) RGFW__osxWindowResignKey, "");
- class_addMethod((Class)_RGFW->customWindowDelegateClass, sel_registerName("draggingEntered:"), (IMP)RGFW__osxDraggingEntered, "l@:@");
- class_addMethod((Class)_RGFW->customWindowDelegateClass, sel_registerName("draggingUpdated:"), (IMP)RGFW__osxDraggingUpdated, "l@:@");
- class_addMethod((Class)_RGFW->customWindowDelegateClass, sel_registerName("draggingExited:"), (IMP)RGFW__osxDraggingEnded, "v@:@");
- class_addMethod((Class)_RGFW->customWindowDelegateClass, sel_registerName("draggingEnded:"), (IMP)RGFW__osxDraggingEnded, "v@:@");
- class_addMethod((Class)_RGFW->customWindowDelegateClass, sel_registerName("prepareForDragOperation:"), (IMP)RGFW__osxPrepareForDragOperation, "B@:@");
- class_addMethod((Class)_RGFW->customWindowDelegateClass, sel_registerName("performDragOperation:"), (IMP)RGFW__osxPerformDragOperation, "B@:@");
+ class_addMethod((Class)_RGFW->customWindowDelegateClass, sel_registerName("windowDidMove:"), (IMP) RGFW__osxWindowMove, "v@:@");
+ class_addMethod((Class)_RGFW->customWindowDelegateClass, sel_registerName("windowDidMiniaturize:"), (IMP) RGFW__osxWindowMiniaturize, "v@:@");
+ class_addMethod((Class)_RGFW->customWindowDelegateClass, sel_registerName("windowDidDeminiaturize:"), (IMP) RGFW__osxWindowDeminiaturize, "v@:@");
+ class_addMethod((Class)_RGFW->customWindowDelegateClass, sel_registerName("windowDidBecomeKey:"), (IMP) RGFW__osxWindowBecameKey, "v@:@");
+ class_addMethod((Class)_RGFW->customWindowDelegateClass, sel_registerName("windowDidResignKey:"), (IMP) RGFW__osxWindowResignKey, "v@:@");
+ class_addMethod((Class)_RGFW->customWindowDelegateClass, sel_registerName("windowShouldClose:"), (IMP)(void*)RGFW_osxWindowShouldClose, "B@:@");
objc_registerClassPair((Class)_RGFW->customWindowDelegateClass);
+
+ _RGFW->customWindowClass = objc_allocateClassPair(objc_getClass("NSWindow"), "RGFWWindowClass", 0);
+ if (_RGFW->customWindowClass== NULL) {
+ RGFW_debugCallback(RGFW_typeError, RGFW_errObjcRuntime, "failed to create RGFWWindowClass class");
+ return -1;
+ }
+
+ class_addMethod((Class)_RGFW->customWindowClass, sel_registerName("canBecomeKeyWindow"), (IMP)RGFW__osxCanBecomeKeyWindow, "B@:");
+ class_addMethod((Class)_RGFW->customWindowClass, sel_registerName("canBecomeMainWindow"),(IMP)RGFW__osxCanBecomeMainWindow, "B@:");
+ objc_registerClassPair((Class)_RGFW->customWindowClass);
+
return 0;
}
@@ -13613,17 +14697,19 @@ RGFW_window* RGFW_createWindowPlatform(const char* name, RGFW_windowFlags flags,
windowRect.origin.y = (double)RGFW_cocoaYTransform((float)(win->y + win->h - 1));
windowRect.size.width = (double)win->w;
windowRect.size.height = (double)win->h;
- NSBackingStoreType macArgs = (NSBackingStoreType)(NSWindowStyleMaskClosable | NSWindowStyleMaskMiniaturizable | NSBackingStoreBuffered | NSWindowStyleMaskTitled);
+ NSWindowStyleMask macArgs = (NSWindowStyleMask)(NSWindowStyleMaskClosable | NSWindowStyleMaskMiniaturizable | NSBackingStoreBuffered);
if (!(flags & RGFW_windowNoResize))
- macArgs = (NSBackingStoreType)(macArgs | (NSBackingStoreType)NSWindowStyleMaskResizable);
+ macArgs |= (NSWindowStyleMask)NSWindowStyleMaskResizable;
if (!(flags & RGFW_windowNoBorder))
- macArgs = (NSBackingStoreType)(macArgs | (NSBackingStoreType)NSWindowStyleMaskTitled);
+ macArgs |= (NSWindowStyleMask)NSWindowStyleMaskTitled;
+ else
+ macArgs |= (NSWindowStyleMask)NSWindowStyleMaskBorderless;
{
- void* nsclass = objc_getClass("NSWindow");
+ void* nsclass = objc_getClass("RGFWWindowClass");
SEL func = sel_registerName("initWithContentRect:styleMask:backing:defer:");
- win->src.window = ((id(*)(id, SEL, NSRect, NSWindowStyleMask, NSBackingStoreType, bool))objc_msgSend)
+ win->src.window = ((id(*)(id, SEL, NSRect, NSWindowStyleMask, NSWindowStyleMask, bool))objc_msgSend)
(NSAlloc(nsclass), func, windowRect, (NSWindowStyleMask)macArgs, macArgs, false);
}
@@ -13635,13 +14721,6 @@ RGFW_window* RGFW_createWindowPlatform(const char* name, RGFW_windowFlags flags,
objc_msgSend_void_id((id)win->src.window, sel_registerName("setDelegate:"), (id)win->src.delegate);
- if (flags & RGFW_windowAllowDND) {
- win->internal.flags |= RGFW_windowAllowDND;
-
- NSPasteboardType types[] = {NSPasteboardTypeURL, NSPasteboardTypeFileURL, NSPasteboardTypeString};
- NSregisterForDraggedTypes((id)win->src.window, types, 3);
- }
-
objc_msgSend_void_bool((id)win->src.window, sel_registerName("setAcceptsMouseMovedEvents:"), true);
if (flags & RGFW_windowTransparent) {
@@ -13651,46 +14730,38 @@ RGFW_window* RGFW_createWindowPlatform(const char* name, RGFW_windowFlags flags,
NSColor_colorWithSRGB(0, 0, 0, 0));
}
- /* Show the window */
- objc_msgSend_void_bool((id)_RGFW->NSApp, sel_registerName("activateIgnoringOtherApps:"), true);
+ if (flags & RGFW_windowAllowDND) {
+ win->internal.flags |= RGFW_windowAllowDND;
+ }
if (_RGFW->root == NULL) {
objc_msgSend_void(win->src.window, sel_registerName("makeMainWindow"));
}
- objc_msgSend_void(win->src.window, sel_registerName("makeKeyWindow"));
-
- NSRetain(win->src.window);
-
win->src.view = ((id(*)(id, SEL, RGFW_window*))objc_msgSend) (NSAlloc((Class)_RGFW->customViewClasses[0]), sel_registerName("initWithRGFWWindow:"), win);
+
+ RGFW_cocoaFetchRect(win);
return win;
}
void RGFW_window_setBorder(RGFW_window* win, RGFW_bool border) {
- NSRect frame = ((NSRect(*)(id, SEL))abi_objc_msgSend_stret)((id)win->src.window, sel_registerName("frame"));
- NSRect content = ((NSRect(*)(id, SEL))abi_objc_msgSend_stret)((id)win->src.view, sel_registerName("frame"));
- double offset = 0;
-
RGFW_setBit(&win->internal.flags, RGFW_windowNoBorder, !border);
- NSBackingStoreType storeType = (NSBackingStoreType)(NSWindowStyleMaskBorderless | NSWindowStyleMaskFullSizeContentView);
- if (border)
- storeType = (NSBackingStoreType)(NSWindowStyleMaskTitled | NSWindowStyleMaskClosable | NSWindowStyleMaskMiniaturizable);
- if (!(win->internal.flags & RGFW_windowNoResize)) {
- storeType = (NSBackingStoreType)(storeType | (NSBackingStoreType)NSWindowStyleMaskResizable);
- }
- ((void (*)(id, SEL, NSBackingStoreType))objc_msgSend)((id)win->src.window, sel_registerName("setStyleMask:"), storeType);
+ NSWindowStyleMask styleMask = ((NSWindowStyleMask (*)(id, SEL))objc_msgSend)((id)win->src.window, sel_registerName("styleMask"));
+ if (border) {
+ styleMask |= (NSWindowStyleMaskTitled | NSWindowStyleMaskClosable);
+ styleMask &= (u32)~NSWindowStyleMaskBorderless;
+ } else {
+ styleMask |= NSWindowStyleMaskBorderless;
+ styleMask &= (u32)~(NSWindowStyleMaskTitled | NSWindowStyleMaskClosable);
+ }
- if (!border) {
- id miniaturizeButton = objc_msgSend_int((id)win->src.window, sel_registerName("standardWindowButton:"), NSWindowMiniaturizeButton);
- id titleBarView = objc_msgSend_id(miniaturizeButton, sel_registerName("superview"));
- objc_msgSend_void_bool(titleBarView, sel_registerName("setHidden:"), true);
+ ((void (*)(id, SEL, NSWindowStyleMask))objc_msgSend)((id)win->src.window, sel_registerName("setStyleMask:"), styleMask);
- offset = (double)(frame.size.height - content.size.height);
- }
+ /* changing the style can clear the first responder */
+ ((void (*)(id, SEL, id))objc_msgSend)((id)win->src.window, sel_registerName("makeFirstResponder:"), (id)win->src.view);
- RGFW_window_resize(win, win->w, win->h + (i32)offset);
- win->h -= (i32)offset;
+ RGFW_window_move(win, win->x, win->y);
}
RGFW_bool RGFW_getGlobalMouse(i32* x, i32* y) {
@@ -13723,8 +14794,12 @@ void RGFW_waitForEvent(i32 waitMS) {
id eventPool = objc_msgSend_class(objc_getClass("NSAutoreleasePool"), sel_registerName("alloc"));
eventPool = objc_msgSend_id(eventPool, sel_registerName("init"));
- void* date = (void*) ((id(*)(Class, SEL, double))objc_msgSend)
- (objc_getClass("NSDate"), sel_registerName("dateWithTimeIntervalSinceNow:"), waitMS);
+ void* date = objc_msgSend_class(objc_getClass("NSDate"), sel_registerName("distantFuture"));
+ if (waitMS >= 0) {
+ double seconds = (((double)waitMS) / ((double)1000));
+ date = (void*) ((id(*)(Class, SEL, double))objc_msgSend)
+ (objc_getClass("NSDate"), sel_registerName("dateWithTimeIntervalSinceNow:"), seconds);
+ }
SEL eventFunc = sel_registerName("nextEventMatchingMask:untilDate:inMode:dequeue:");
id e = (id) ((id(*)(id, SEL, NSEventMask, void*, id, bool))objc_msgSend)
@@ -13734,6 +14809,15 @@ void RGFW_waitForEvent(i32 waitMS) {
if (e) {
((void (*)(id, SEL, id, bool))objc_msgSend)
((id)_RGFW->NSApp, sel_registerName("postEvent:atStart:"), e, 1);
+
+ u32 flags = (u32)((u32(*)(id, SEL))objc_msgSend)((id)e, sel_registerName("modifierFlags"));
+ if (flags & NSEventModifierFlagCommand) {
+ id window = objc_msgSend_id(_RGFW->NSApp, sel_registerName("keyWindow"));
+
+ if (window) {
+ objc_msgSend_void_id((id)window, sel_registerName("sendEvent:"), e);
+ }
+ }
}
objc_msgSend_bool_void(eventPool, sel_registerName("drain"));
@@ -13801,31 +14885,23 @@ void RGFW_pollEvents(void) {
}
-void RGFW_window_move(RGFW_window* win, i32 x, i32 y) {
- RGFW_ASSERT(win != NULL);
-
+void RGFW_window_movePlatform(RGFW_window* win, i32 x, i32 y) {
NSRect content = ((NSRect(*)(id, SEL))abi_objc_msgSend_stret)((id)win->src.view, sel_registerName("frame"));
-
- win->x = x;
- win->y = (i32)RGFW_cocoaYTransform((float)y + (float)content.size.height - 1.0f);
-
- ((void(*)(id,SEL,NSPoint))objc_msgSend)((id)win->src.window, sel_registerName("setFrameOrigin:"), (NSPoint){(double)x, (double)y});
+ float yFlip = RGFW_cocoaYTransform((float)y + (float)content.size.height - 1.0f);
+ ((void(*)(id,SEL,NSPoint))objc_msgSend)((id)win->src.window, sel_registerName("setFrameOrigin:"), (NSPoint){(double)x, (double)yFlip});
+ RGFW_cocoaFetchRect(win);
}
-void RGFW_window_resize(RGFW_window* win, i32 w, i32 h) {
- RGFW_ASSERT(win != NULL);
-
+void RGFW_window_resizePlatform(RGFW_window* win, i32 w, i32 h) {
NSRect frame = ((NSRect(*)(id, SEL))abi_objc_msgSend_stret)((id)win->src.window, sel_registerName("frame"));
- NSRect content = ((NSRect(*)(id, SEL))abi_objc_msgSend_stret)((id)win->src.view, sel_registerName("frame"));
- float offset = (float)(frame.size.height - content.size.height);
-
- win->w = w;
- win->h = h;
+ NSRect content = ((NSRect(*)(id, SEL, NSRect))abi_objc_msgSend_stret)((id)win->src.window, sel_registerName("contentRectForFrameRect:"), frame);
+ content.origin.y += content.size.height - (CGFloat)h;
+ content.size = (CGSize){(CGFloat)w, (CGFloat)h};
+ frame = ((NSRect(*)(id, SEL, NSRect))abi_objc_msgSend_stret)((id)win->src.window, sel_registerName("frameRectForContentRect:"), content);
- ((void(*)(id, SEL, CGRect))objc_msgSend)((id)win->src.view, sel_registerName("setFrame:"), (NSRect){{0, 0}, {(double)win->w, (double)win->h}});
- ((void(*)(id, SEL, NSRect, bool, bool))objc_msgSend)
- ((id)win->src.window, sel_registerName("setFrame:display:animate:"), (NSRect){{(double)win->x, (double)win->y}, {(double)win->w, (double)win->h + (double)offset}}, true, true);
+ ((void(*)(id, SEL, CGRect))objc_msgSend)((id)win->src.view, sel_registerName("setFrame:"),frame);
+ RGFW_cocoaFetchRect(win);
}
void RGFW_window_focus(RGFW_window* win) {
@@ -13837,76 +14913,43 @@ void RGFW_window_focus(RGFW_window* win) {
void RGFW_window_raise(RGFW_window* win) {
RGFW_ASSERT(win != NULL);
((id(*)(id, SEL, SEL))objc_msgSend)((id)win->src.window, sel_registerName("orderFront:"), (SEL)NULL);
- objc_msgSend_void_id(win->src.window, sel_registerName("setLevel:"), kCGNormalWindowLevelKey);
}
-void RGFW_window_setFullscreen(RGFW_window* win, RGFW_bool fullscreen) {
- RGFW_ASSERT(win != NULL);
- if (fullscreen && (win->internal.flags & RGFW_windowFullscreen)) return;
- if (!fullscreen && !(win->internal.flags & RGFW_windowFullscreen)) return;
-
+void RGFW_window_setFullscreenPlatform(RGFW_window* win, RGFW_bool fullscreen) {
if (fullscreen) {
- win->internal.oldX = win->x;
- win->internal.oldY = win->y;
- win->internal.oldW = win->w;
- win->internal.oldH = win->h;
-
- win->internal.flags |= RGFW_windowFullscreen;
-
- RGFW_monitor* mon = RGFW_window_getMonitor(win);
- RGFW_monitor_scaleToWindow(mon, win);
-
- RGFW_window_setBorder(win, RGFW_FALSE);
-
- if (mon != NULL) {
- win->x = mon->x;
- win->y = mon->y;
- win->w = mon->mode.w;
- win->h = mon->mode.h;
- RGFW_window_resize(win, mon->mode.w, mon->mode.h);
- RGFW_window_move(win, mon->x, mon->y);
- }
-
((id(*)(id, SEL, SEL))objc_msgSend)((id)win->src.window, sel_registerName("orderFront:"), (SEL)NULL);
objc_msgSend_void_id(win->src.window, sel_registerName("setLevel:"), 25);
+ } else {
+ objc_msgSend_void_id(win->src.window, sel_registerName("setLevel:"), kCGNormalWindowLevel);
}
- objc_msgSend_void_SEL(win->src.window, sel_registerName("toggleFullScreen:"), NULL);
+ NSWindowStyleMask styleMask = ((NSWindowStyleMask (*)(id, SEL))objc_msgSend)((id)win->src.window, sel_registerName("styleMask"));
- if (!fullscreen) {
- win->x = win->internal.oldX;
- win->y = win->internal.oldY;
- win->w = win->internal.oldW;
- win->h = win->internal.oldH;
- win->internal.flags &= ~(u32)RGFW_windowFullscreen;
-
- RGFW_window_resize(win, win->w, win->h);
- RGFW_window_move(win, win->x, win->y);
+ if (RGFW_BOOL(styleMask & NSWindowStyleMaskFullScreen) != fullscreen) {
+ objc_msgSend_void_SEL(win->src.window, sel_registerName("toggleFullScreen:"), NULL);
}
}
-void RGFW_window_maximize(RGFW_window* win) {
- RGFW_ASSERT(win != NULL);
+void RGFW_window_maximizePlatform(RGFW_window* win) {
if (RGFW_window_isMaximized(win)) return;
- win->internal.flags |= RGFW_windowMaximize;
objc_msgSend_void_SEL(win->src.window, sel_registerName("zoom:"), NULL);
- RGFW_window_fetchSize(win, NULL, NULL);
}
-void RGFW_window_minimize(RGFW_window* win) {
+void RGFW_window_minimizePlatform(RGFW_window* win) {
RGFW_ASSERT(win != NULL);
- objc_msgSend_void_SEL(win->src.window, sel_registerName("performMiniaturize:"), NULL);
+ objc_msgSend_void_SEL(win->src.window, sel_registerName("miniaturize:"), NULL);
}
void RGFW_window_setFloating(RGFW_window* win, RGFW_bool floating) {
RGFW_ASSERT(win != NULL);
- if (floating) objc_msgSend_void_id(win->src.window, sel_registerName("setLevel:"), kCGFloatingWindowLevelKey);
- else objc_msgSend_void_id(win->src.window, sel_registerName("setLevel:"), kCGNormalWindowLevelKey);
+ if (floating) objc_msgSend_void_id(win->src.window, sel_registerName("setLevel:"), kCGFloatingWindowLevel);
+ else objc_msgSend_void_id(win->src.window, sel_registerName("setLevel:"), kCGNormalWindowLevel);
}
void RGFW_window_setOpacity(RGFW_window* win, u8 opacity) {
- objc_msgSend_int(win->src.window, sel_registerName("setAlphaValue:"), opacity);
+ ((void(*)(id, SEL, CGFloat))objc_msgSend) ((id)win->src.window, sel_registerName("setAlphaValue:"), ((CGFloat)opacity) / (CGFloat)255.0);
+
objc_msgSend_void_bool(win->src.window, sel_registerName("setOpaque:"), (opacity < (u8)255));
if (opacity)
@@ -13914,7 +14957,7 @@ void RGFW_window_setOpacity(RGFW_window* win, u8 opacity) {
}
-void RGFW_window_restore(RGFW_window* win) {
+void RGFW_window_restorePlatform(RGFW_window* win) {
RGFW_ASSERT(win != NULL);
if (RGFW_window_isMaximized(win))
@@ -13927,7 +14970,7 @@ void RGFW_window_restore(RGFW_window* win) {
RGFW_bool RGFW_window_isFloating(RGFW_window* win) {
RGFW_ASSERT(win != NULL);
int level = ((int (*)(id, SEL))objc_msgSend) ((id)(win->src.window), (SEL)sel_registerName("level"));
- return level > kCGNormalWindowLevelKey;
+ return level > kCGNormalWindowLevel;
}
void RGFW_window_setName(RGFW_window* win, const char* name) {
@@ -14003,7 +15046,7 @@ id NSCursor_arrowStr(const char* str) {
void* nclass = objc_getClass("NSCursor");
SEL func = sel_registerName(str);
id mouse = (id) objc_msgSend_id(nclass, func);
- NSRetain(mouse);
+ objc_msgSend_void((id)mouse, sel_registerName("retain"));
return mouse;
}
@@ -14078,7 +15121,9 @@ void RGFW_freeMouse(RGFW_mouse* mouse) {
}
void RGFW_window_showMouse(RGFW_window* win, RGFW_bool show) {
+ if (RGFW_window_isMouseHidden(win) != show) return;
RGFW_window_showMouseFlags(win, show);
+
if (show) CGDisplayShowCursor(kCGDirectMainDisplay);
else CGDisplayHideCursor(kCGDirectMainDisplay);
}
@@ -14105,12 +15150,13 @@ void RGFW_window_hide(RGFW_window* win) {
objc_msgSend_void_bool(win->src.window, sel_registerName("setIsVisible:"), false);
}
-void RGFW_window_show(RGFW_window* win) {
+void RGFW_window_showPlatform(RGFW_window* win) {
if (win->internal.flags & RGFW_windowFocusOnShow)
((id(*)(id, SEL, SEL))objc_msgSend)((id)win->src.window, sel_registerName("makeKeyAndOrderFront:"), NULL);
((id(*)(id, SEL, SEL))objc_msgSend)((id)win->src.window, sel_registerName("orderFront:"), NULL);
objc_msgSend_void_bool(win->src.window, sel_registerName("setIsVisible:"), true);
+ RGFW_cocoaFetchRect(win);
}
void RGFW_window_flash(RGFW_window* win, RGFW_flashRequest request) {
@@ -14196,14 +15242,17 @@ float RGFW_osx_getRefreshRate(CGDirectDisplayID display, CGDisplayModeRef mode)
}
void RGFW_pollMonitors(void) {
- static CGDirectDisplayID displays[RGFW_MAX_MONITORS];
u32 count;
- if (CGGetActiveDisplayList(RGFW_MAX_MONITORS, displays, &count) != kCGErrorSuccess) {
+ if (CGGetActiveDisplayList(0, NULL, &count) != kCGErrorSuccess) {
+ return;
+ }
+
+ CGDirectDisplayID* displays = (CGDirectDisplayID*)RGFW_ALLOC(sizeof(CGDirectDisplayID) * count);
+ if (CGGetActiveDisplayList(count, displays, &count) != kCGErrorSuccess) {
return;
}
- if (count > RGFW_MAX_MONITORS) count = RGFW_MAX_MONITORS;
for (RGFW_monitorNode* node = _RGFW->monitors.list.head; node; node = node->next) {
node->disconnected = RGFW_TRUE;
@@ -14223,27 +15272,29 @@ void RGFW_pollMonitors(void) {
if (node->uintNum == uintNum) break;
}
- if (node) {
- node->screen = (void*)screen;
- node->display = displays[i];
- node->disconnected = RGFW_FALSE;
- if (displays[i] == primary) {
- _RGFW->monitors.primary = node;
- }
- continue;
- }
-
const char name[] = "MacOS\0";
RGFW_MEMCPY(monitor.name, name, 6);
CGRect bounds = CGDisplayBounds(displays[i]);
monitor.x = (i32)bounds.origin.x;
- monitor.y = (i32)RGFW_cocoaYTransform((float)(bounds.origin.y + bounds.size.height - 1));
+ monitor.y = (i32)bounds.origin.y;
CGDisplayModeRef mode = CGDisplayCopyDisplayMode(displays[i]);
+
+ CFArrayRef allModes = CGDisplayCopyAllDisplayModes(displays[i], NULL);
+ CFIndex modeCount = (CFIndex)CFArrayGetCount(allModes);
+
+ CFIndex modeIndex;
+ for (modeIndex = 0; modeIndex < modeCount && allModes; modeIndex++) {
+ CGDisplayModeRef cmode = (CGDisplayModeRef)CFArrayGetValueAtIndex(allModes, modeIndex);
+ if (cmode == mode) {
+ monitor.mode.src = (void*)modeIndex;
+ break;
+ }
+ }
+
monitor.mode.w = (i32)CGDisplayModeGetWidth(mode);
monitor.mode.h = (i32)CGDisplayModeGetHeight(mode);
- monitor.mode.src = (void*)mode;
monitor.mode.red = 8; monitor.mode.green = 8; monitor.mode.blue = 8;
monitor.mode.refreshRate = RGFW_osx_getRefreshRate(displays[i], mode);
@@ -14262,23 +15313,42 @@ void RGFW_pollMonitors(void) {
monitor.scaleX = ((((float) (ppi_width) / dpi) * 10.0f)) / 10.0f;
monitor.scaleY = ((((float) (ppi_height) / dpi) * 10.0f)) / 10.0f;
- node = RGFW_monitors_add(&monitor);
+ if (node) {
+ node->screen = (void*)screen;
+ node->display = displays[i];
+ node->disconnected = RGFW_FALSE;
+ if (displays[i] == primary) {
+ _RGFW->monitors.primary = node;
+ }
+ continue;
+ } else {
+ node = RGFW_monitors_add(&monitor);
- node->screen = (void*)screen;
- node->uintNum = uintNum;
- node->display = displays[i];
+ node->allModes = allModes;
+ node->screen = (void*)screen;
+ node->uintNum = uintNum;
+ node->display = displays[i];
- if (displays[i] == primary) {
- _RGFW->monitors.primary = node;
- }
+ if (displays[i] == primary) {
+ _RGFW->monitors.primary = node;
+ }
- RGFW_monitorCallback(_RGFW->root, &node->mon, RGFW_TRUE);
+ RGFW_monitorCallback(_RGFW->root, &node->mon, RGFW_TRUE);
+ }
}
+ RGFW_FREE(displays);
+
RGFW_monitors_refresh();
}
+void RGFW_monitorNode_free(RGFW_monitorNode* node) {
+ RGFW_ASSERT(node);
+ CFRelease(node->allModes);
+}
+
RGFW_bool RGFW_monitor_getWorkarea(RGFW_monitor* monitor, i32* x, i32* y, i32* width, i32* height) {
+ RGFW_ASSERT(monitor != NULL);
NSRect frameRect = ((NSRect(*)(id, SEL))abi_objc_msgSend_stret)((id)monitor->node->screen, sel_registerName("visibleFrame"));
if (x) *x = (i32)frameRect.origin.x;
@@ -14290,6 +15360,7 @@ RGFW_bool RGFW_monitor_getWorkarea(RGFW_monitor* monitor, i32* x, i32* y, i32* w
}
size_t RGFW_monitor_getGammaRampPtr(RGFW_monitor* monitor, RGFW_gammaRamp* ramp) {
+ RGFW_ASSERT(monitor != NULL);
id pool = objc_msgSend_class(objc_getClass("NSAutoreleasePool"), sel_registerName("alloc"));
pool = objc_msgSend_id(pool, sel_registerName("init"));
@@ -14311,6 +15382,7 @@ size_t RGFW_monitor_getGammaRampPtr(RGFW_monitor* monitor, RGFW_gammaRamp* ramp)
}
RGFW_bool RGFW_monitor_setGammaRamp(RGFW_monitor* monitor, RGFW_gammaRamp* ramp) {
+ RGFW_ASSERT(monitor != NULL);
id pool = objc_msgSend_class(objc_getClass("NSAutoreleasePool"), sel_registerName("alloc"));
pool = objc_msgSend_id(pool, sel_registerName("init"));
@@ -14332,8 +15404,9 @@ RGFW_bool RGFW_monitor_setGammaRamp(RGFW_monitor* monitor, RGFW_gammaRamp* ramp)
}
size_t RGFW_monitor_getModesPtr(RGFW_monitor* mon, RGFW_monitorMode** modes) {
+ RGFW_ASSERT(mon != NULL);
CGDirectDisplayID display = mon->node->display;
- CFArrayRef allModes = CGDisplayCopyAllDisplayModes(display, NULL);
+ CFArrayRef allModes = mon->node->allModes;
if (allModes == NULL) {
return RGFW_FALSE;
@@ -14350,16 +15423,19 @@ size_t RGFW_monitor_getModesPtr(RGFW_monitor* mon, RGFW_monitorMode** modes) {
foundMode.h = (i32)CGDisplayModeGetHeight(cmode);
foundMode.refreshRate = RGFW_osx_getRefreshRate(display, cmode);
foundMode.red = 8; foundMode.green = 8; foundMode.blue = 8;
- foundMode.src = (void*)cmode;
+ foundMode.src = (void*)i;
(*modes)[i] = foundMode;
}
- CFRelease(allModes);
return count;
}
RGFW_bool RGFW_monitor_setMode(RGFW_monitor* mon, RGFW_monitorMode* mode) {
- if (CGDisplaySetDisplayMode(mon->node->display, (CGDisplayModeRef)mode->src, NULL) == kCGErrorSuccess) {
+ RGFW_ASSERT(mon != NULL);
+
+ CGDisplayModeRef cmode = (CGDisplayModeRef)CFArrayGetValueAtIndex(mon->node->allModes, (CFIndex)mode->src);
+ if (CGDisplaySetDisplayMode(mon->node->display, cmode, NULL) == kCGErrorSuccess) {
+ mon->mode = *mode;
return RGFW_TRUE;
}
@@ -14367,8 +15443,9 @@ RGFW_bool RGFW_monitor_setMode(RGFW_monitor* mon, RGFW_monitorMode* mode) {
}
RGFW_bool RGFW_monitor_requestMode(RGFW_monitor* mon, RGFW_monitorMode* mode, RGFW_modeRequest request) {
+ RGFW_ASSERT(mon != NULL);
CGDirectDisplayID display = mon->node->display;
- CFArrayRef allModes = CGDisplayCopyAllDisplayModes(display, NULL);
+ CFArrayRef allModes = mon->node->allModes;
if (allModes == NULL) {
return RGFW_FALSE;
@@ -14385,7 +15462,7 @@ RGFW_bool RGFW_monitor_requestMode(RGFW_monitor* mon, RGFW_monitorMode* mode, RG
foundMode.h = (i32)CGDisplayModeGetHeight(cmode);
foundMode.refreshRate = RGFW_osx_getRefreshRate(display, cmode);
foundMode.red = 8; foundMode.green = 8; foundMode.blue = 8;
- foundMode.src = (void*)cmode;
+ foundMode.src = (void*)i;
if (RGFW_monitorModeCompare(mode, &foundMode, request)) {
native = cmode;
@@ -14394,8 +15471,6 @@ RGFW_bool RGFW_monitor_requestMode(RGFW_monitor* mon, RGFW_monitorMode* mode, RG
}
}
- CFRelease(allModes);
-
if (native) {
if (CGDisplaySetDisplayMode(display, native, NULL) == kCGErrorSuccess) {
return RGFW_TRUE;
@@ -14428,35 +15503,60 @@ RGFW_monitor* RGFW_window_getMonitor(RGFW_window* win) {
return &node->mon;
}
-RGFW_ssize_t RGFW_readClipboardPtr(char* str, size_t strCapacity) {
- size_t clip_len;
- char* clip = (char*)NSPasteboard_stringForType(NSPasteboard_generalPasteboard(), NSPasteboardTypeString, &clip_len);
- if (clip == NULL) return -1;
+RGFW_bool RGFW_readClipboardPtr(RGFW_dataTransferType requestedType, u8* buffer, size_t capacity, RGFW_dataTransfer* data) {
+ RGFW_ASSERT(data != NULL);
- if (str != NULL) {
- if (strCapacity < clip_len)
- return 0;
+ if (requestedType != RGFW_dataText) return RGFW_FALSE;
- RGFW_MEMCPY(str, clip, clip_len);
+ size_t length = 0;
+ char* clip = (char*)NSPasteboard_stringForType(NSPasteboard_generalPasteboard(), RSGL_NSPasteboardTypeString, &length);
+ if (clip == NULL) return RGFW_FALSE;
- str[clip_len] = '\0';
- }
+ data->type = RGFW_dataText;
+ data->length = length;
- return (RGFW_ssize_t)clip_len;
+ if (clip[data->length - 1] != '\0') data->length += 1;
+
+ if (buffer == NULL) return RGFW_TRUE;
+ if (capacity < data->length) return RGFW_FALSE;
+
+ RGFW_MEMCPY(buffer, clip, length);
+ buffer[data->length - 1] = '\0';
+ data->data = (const char*)buffer;
+
+ return RGFW_TRUE;
}
-void RGFW_writeClipboard(const char* text, u32 textLen) {
- RGFW_UNUSED(textLen);
+RGFW_bool RGFW_writeClipboard(const RGFW_dataTransfer* data) {
+ RGFW_ASSERT(data != NULL);
- NSPasteboardType array[] = { NSPasteboardTypeString, NULL };
+ const char* array[] = { RSGL_NSPasteboardTypeString, NULL };
NSPasteBoard_declareTypes(NSPasteboard_generalPasteboard(), array, 1, NULL);
SEL func = sel_registerName("setString:forType:");
- ((bool (*)(id, SEL, id, id))objc_msgSend)
- (NSPasteboard_generalPasteboard(), func, NSString_stringWithUTF8String(text), NSString_stringWithUTF8String((const char*)NSPasteboardTypeString));
+ bool ret = ((bool (*)(id, SEL, id, id))objc_msgSend)
+ (NSPasteboard_generalPasteboard(), func, NSString_stringWithUTF8String(data->data), NSString_stringWithUTF8String((const char*)RSGL_NSPasteboardTypeString));
+
+ return (ret == true) ? RGFW_TRUE : RGFW_FALSE;
}
#ifdef RGFW_OPENGL
+RGFW_bool RGFW_loadGL(void) {
+ _RGFW->nativeGL_handle = (void*)CFBundleGetBundleWithIdentifier(CFSTR("com.apple.opengl"));
+ _RGFW->glGetProcAddress = RGFW_getProcAddress_OpenGL;
+ return RGFW_TRUE;
+}
+
+void RGFW_copyContext_OSX_OpenGL(RGFW_glContext* ctx, RGFW_glContext* newCtx) {
+ id pixelFormat = (id)objc_msgSend_id((id)ctx->ctx, sel_registerName("pixelFormat"));
+ id newContext = ((id (*)(id, SEL, id, id))objc_msgSend)(NSAlloc((id)objc_getClass("NSOpenGLContext")),
+ sel_registerName("initWithFormat:shareContext:"),
+ pixelFormat, (id)ctx->ctx
+ );
+
+ newCtx->ctx = newContext;
+}
+
void NSOpenGLContext_setValues(id context, const int* vals, NSOpenGLContextParameter param);
void NSOpenGLContext_setValues(id context, const int* vals, NSOpenGLContextParameter param) {
((void (*)(id, SEL, const int*, NSOpenGLContextParameter))objc_msgSend)
@@ -14468,23 +15568,16 @@ void NSOpenGLContext_setValues(id context, const int* vals, NSOpenGLContextParam
RGFW_bool RGFW_extensionSupportedPlatform_OpenGL(const char * extension, size_t len) { RGFW_UNUSED(extension); RGFW_UNUSED(len); return RGFW_FALSE; }
RGFW_proc RGFW_getProcAddress_OpenGL(const char* procname) {
- static CFBundleRef RGFWnsglFramework = NULL;
- if (RGFWnsglFramework == NULL)
- RGFWnsglFramework = CFBundleGetBundleWithIdentifier(CFSTR("com.apple.opengl"));
-
CFStringRef symbolName = CFStringCreateWithCString(kCFAllocatorDefault, procname, kCFStringEncodingASCII);
- RGFW_proc symbol = (RGFW_proc)CFBundleGetFunctionPointerForName(RGFWnsglFramework, symbolName);
+ RGFW_proc symbol = (RGFW_proc)CFBundleGetFunctionPointerForName((CFBundleRef)_RGFW->nativeGL_handle, symbolName);
CFRelease(symbolName);
return symbol;
}
-RGFW_bool RGFW_window_createContextPtr_OpenGL(RGFW_window* win, RGFW_glContext* ctx, RGFW_glHints* hints) {
- win->src.ctx.native = ctx;
- win->src.gfxType = RGFW_gfxNativeOpenGL;
-
+RGFW_bool RGFW_createContextPtr_OpenGL(RGFW_glContext* ctx, RGFW_glHints* hints) {
i32 attribs[40];
size_t render_type_index = 0;
{
@@ -14553,48 +15646,65 @@ RGFW_bool RGFW_window_createContextPtr_OpenGL(RGFW_window* win, RGFW_glContext*
/* the pixel format can be passed directly to OpenGL context creation to create a context
this is because the format also includes information about the OpenGL version (which may be a bad thing) */
- if (win->src.view)
- NSRelease(win->src.view);
- win->src.view = (id) ((id(*)(id, SEL, NSRect, u32*))objc_msgSend) (NSAlloc(_RGFW->customViewClasses[1]),
- sel_registerName("initWithFrame:pixelFormat:"), (NSRect){{0, 0}, {(double)win->w, (double)win->h}}, (u32*)format);
-
id share = NULL;
if (hints->share) {
share = (id)hints->share->ctx;
}
- win->src.ctx.native->ctx = ((id (*)(id, SEL, id, id))objc_msgSend)(NSAlloc(objc_getClass("NSOpenGLContext")),
+ ctx->ctx = ((id (*)(id, SEL, id, id))objc_msgSend)(NSAlloc(objc_getClass("NSOpenGLContext")),
sel_registerName("initWithFormat:shareContext:"),
(id)format, share);
- win->src.ctx.native->format = format;
+ ctx->format = format;
- objc_msgSend_void_id(win->src.view, sel_registerName("setOpenGLContext:"), win->src.ctx.native->ctx);
- if (win->internal.flags & RGFW_windowTransparent) {
+ if (hints->depth == 32) {
i32 opacity = 0;
#define NSOpenGLCPSurfaceOpacity 236
- NSOpenGLContext_setValues((id)win->src.ctx.native->ctx, &opacity, (NSOpenGLContextParameter)NSOpenGLCPSurfaceOpacity);
+ NSOpenGLContext_setValues((id)ctx->ctx, &opacity, (NSOpenGLContextParameter)NSOpenGLCPSurfaceOpacity);
+ }
+
+ RGFW_debugCallback(RGFW_typeInfo, RGFW_infoOpenGL, "OpenGL context initalized.");
+ return RGFW_TRUE;
+}
+
+RGFW_bool RGFW_window_setContext_OpenGL(RGFW_window* win, RGFW_glContext* ctx) {
+ RGFW_ASSERT(win);
+ if (ctx == NULL && win->src.ctx.native != NULL) {
+ win->src.ctx.native = NULL;
+ RGFW_debugCallback(RGFW_typeInfo, RGFW_infoOpenGL, "OpenGL surface freed.");
+ return RGFW_TRUE;
}
- objc_msgSend_void(win->src.ctx.native->ctx, sel_registerName("makeCurrentContext"));
+ win->src.ctx.native = ctx;
+ win->src.gfxType = RGFW_gfxNativeOpenGL;
+
+ if (win->src.view)
+ NSRelease(win->src.view);
+ win->src.view = (id) ((id(*)(id, SEL, NSRect, u32*))objc_msgSend) (NSAlloc(_RGFW->customViewClasses[1]),
+ sel_registerName("initWithFrame:pixelFormat:"), (NSRect){{0, 0}, {(double)win->w, (double)win->h}}, (u32*)ctx->format);
+
+
+ objc_msgSend_void_id(win->src.view, sel_registerName("setOpenGLContext:"), ctx->ctx);
+
+ objc_msgSend_void(ctx->ctx, sel_registerName("makeCurrentContext"));
objc_msgSend_void_id((id)win->src.window, sel_registerName("setContentView:"), win->src.view);
objc_msgSend_void_bool(win->src.view, sel_registerName("setWantsLayer:"), true);
objc_msgSend_int((id)win->src.view, sel_registerName("setLayerContentsPlacement:"), 4);
- RGFW_window_swapInterval_OpenGL(win, 0);
+ /*NOTE: another OpenGL/setFlags related hack, this because OSX the 'view' class must be setup after the NSOpenGL view is made AND after setFlags happens */
+ RGFW_osx_initView(win);
+ ((void (*)(id, SEL, id))objc_msgSend)((id)win->src.window, sel_registerName("makeFirstResponder:"), (id)win->src.view);
- RGFW_debugCallback(RGFW_typeInfo, RGFW_infoOpenGL, "OpenGL context initalized.");
+ RGFW_window_swapInterval_OpenGL(win, 0);
+ RGFW_debugCallback(RGFW_typeInfo, RGFW_infoOpenGL, "OpenGL surface initalized.");
return RGFW_TRUE;
}
-void RGFW_window_deleteContextPtr_OpenGL(RGFW_window* win, RGFW_glContext* ctx) {
+void RGFW_deleteContextPtr_OpenGL(RGFW_glContext* ctx) {
objc_msgSend_void(ctx->format, sel_registerName("release"));
- win->src.ctx.native->format = NULL;
-
objc_msgSend_void(ctx->ctx, sel_registerName("release"));
- win->src.ctx.native->ctx = NULL;
RGFW_debugCallback(RGFW_typeInfo, RGFW_infoOpenGL, "OpenGL context freed.");
}
@@ -14609,6 +15719,12 @@ void* RGFW_getCurrentContext_OpenGL(void) {
return objc_msgSend_id(objc_getClass("NSOpenGLContext"), sel_registerName("currentContext"));
}
+void* RGFW_getCurrentSurface_OpenGL(void) {
+ id ctx = (id)RGFW_getCurrentContext_OpenGL();
+ if (ctx == NULL) return NULL;
+ return objc_msgSend_id(ctx, sel_registerName("view"));
+}
+
void RGFW_window_swapBuffers_OpenGL(RGFW_window* win) {
RGFW_ASSERT(win && win->src.ctx.native);
objc_msgSend_void(win->src.ctx.native->ctx, sel_registerName("flushBuffer"));
@@ -14620,29 +15736,54 @@ void RGFW_window_swapInterval_OpenGL(RGFW_window* win, i32 swapInterval) {
#endif
void RGFW_deinitPlatform(void) {
- objc_msgSend_void_id(_RGFW->NSApp, sel_registerName("setDelegate:"), NULL);
+ if (_RGFW->NSApp) {
+ objc_msgSend_void_id(_RGFW->NSApp, sel_registerName("setDelegate:"), NULL);
+ NSRelease(_RGFW->customNSAppDelegate);
+ _RGFW->customNSAppDelegate = NULL;
- objc_msgSend_void_id(_RGFW->NSApp, sel_registerName("stop:"), NULL);
- NSRelease(_RGFW->NSApp);
- _RGFW->NSApp = NULL;
+ objc_msgSend_void_id(_RGFW->NSApp, sel_registerName("stop:"), NULL);
+ _RGFW->NSApp = NULL;
+ }
- NSRelease(_RGFW->customNSAppDelegate);
+ if (_RGFW->customNSAppDelegate != NULL)
+ NSRelease(_RGFW->customNSAppDelegate);
_RGFW->customNSAppDelegate = NULL;
- objc_disposeClassPair((Class)_RGFW->customViewClasses[0]);
- objc_disposeClassPair((Class)_RGFW->customViewClasses[1]);
- objc_disposeClassPair((Class)_RGFW->customWindowDelegateClass);
- objc_disposeClassPair((Class)_RGFW->customNSAppDelegateClass);
+ if (_RGFW->customViewClasses[0] != NULL)
+ objc_disposeClassPair((Class)_RGFW->customViewClasses[0]);
+ if (_RGFW->customViewClasses[0] != NULL)
+ objc_disposeClassPair((Class)_RGFW->customViewClasses[1]);
+
+ if (_RGFW->customWindowDelegateClass)
+ objc_disposeClassPair((Class)_RGFW->customWindowDelegateClass);
+
+ if (_RGFW->customWindowClass) {
+ Class kvoClass = objc_getClass("NSKVONotifying_RGFWWindowClass");
+ if (kvoClass) {
+ objc_disposeClassPair(kvoClass);
+
+ }
+ objc_disposeClassPair((Class)_RGFW->customWindowClass);
+ }
+
+ if (_RGFW->customNSAppDelegateClass)
+ objc_disposeClassPair((Class)_RGFW->customNSAppDelegateClass);
}
void RGFW_window_closePlatform(RGFW_window* win) {
+ id pool = objc_msgSend_class(objc_getClass("NSAutoreleasePool"), sel_registerName("alloc"));
+ pool = objc_msgSend_id(pool, sel_registerName("init"));
+
objc_msgSend_void_id((id)win->src.window, sel_registerName("setDelegate:"), NULL);
NSRelease((id)win->src.delegate);
NSRelease(win->src.view);
objc_msgSend_id(win->src.window, sel_registerName("close"));
NSRelease(win->src.window);
+
+ objc_msgSend_bool_void(pool, sel_registerName("drain"));
+ RGFW_pollEvents();
}
#ifdef RGFW_VULKAN
@@ -14667,7 +15808,7 @@ VkResult RGFW_window_createSurface_Vulkan(RGFW_window* win, VkInstance instance,
if (metalLayer == NULL) {
return -1;
}
- ((void (*)(id, SEL, id))objc_msgSend)((id)nsView, sel_registerName("setLayer:"), metalLayer);
+ ((void (*)(id, SEL, id))objc_msgSend)((id)nsView, sel_registerName("setLayer:"), (id)metalLayer);
((void (*)(id, SEL, BOOL))objc_msgSend)(nsView, sel_registerName("setWantsLayer:"), YES);
VkResult result;
@@ -14695,7 +15836,7 @@ VkResult RGFW_window_createSurface_Vulkan(RGFW_window* win, VkInstance instance,
#ifdef RGFW_WEBGPU
WGPUSurface RGFW_window_createSurface_WebGPU(RGFW_window* window, WGPUInstance instance) {
WGPUSurfaceDescriptor surfaceDesc = {0};
- id* nsView = (id*)window->src.view;
+ id nsView = (id)window->src.view;
if (!nsView) {
RGFW_debugCallback(RGFW_typeError, RGFW_errMetal, "NSView is NULL for macOS window");
return NULL;
@@ -14708,8 +15849,8 @@ WGPUSurface RGFW_window_createSurface_WebGPU(RGFW_window* window, WGPUInstance i
if (metalLayer == NULL) {
return NULL;
}
- ((void (*)(id, SEL, id))objc_msgSend)((id)nsView, sel_registerName("setLayer:"), metalLayer);
- layer = metalLayer;
+ ((void (*)(id, SEL, id))objc_msgSend)((id)nsView, sel_registerName("setLayer:"), (id)metalLayer);
+ layer = (id)metalLayer;
WGPUSurfaceSourceMetalLayer fromMetal = {0};
fromMetal.chain.sType = WGPUSType_SurfaceSourceMetalLayer;
@@ -14764,7 +15905,7 @@ EM_BOOL Emscripten_on_fullscreenchange(int eventType, const EmscriptenFullscreen
_RGFW->root->w = originalW;
_RGFW->root->h = originalH;
} else {
- #if __EMSCRIPTEN_major__ >= 1 && __EMSCRIPTEN_minor__ >= 29 && __EMSCRIPTEN_tiny__ >= 0
+ #if __EMSCRIPTEN_MAJOR__ >= 1 && __EMSCRIPTEN_MINOR__ >= 29 && __EMSCRIPTEN_TINY__ >= 0
EmscriptenFullscreenStrategy FSStrat = {0};
FSStrat.scaleMode = EMSCRIPTEN_FULLSCREEN_SCALE_STRETCH;
FSStrat.canvasResolutionScaleMode = EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE_HIDEF;
@@ -14796,7 +15937,7 @@ EM_BOOL Emscripten_on_focusout(int eventType, const EmscriptenFocusEvent* E, voi
EM_BOOL Emscripten_on_mousemove(int eventType, const EmscriptenMouseEvent* E, void* userData) {
RGFW_UNUSED(eventType); RGFW_UNUSED(userData);
- RGFW_mousePosCallback(_RGFW->root, E->targetX, E->targetY);
+ RGFW_mouseMotionCallback(_RGFW->root, E->targetX, E->targetY);
RGFW_rawMotionCallback(_RGFW->root, E->movementX, E->movementY);
return EM_TRUE;
}
@@ -14838,7 +15979,7 @@ EM_BOOL Emscripten_on_touchstart(int eventType, const EmscriptenTouchEvent* E, v
size_t i;
for (i = 0; i < (size_t)E->numTouches; i++) {
- RGFW_mousePosCallback(_RGFW->root, E->touches[i].targetX, E->touches[i].targetY);
+ RGFW_mouseMotionCallback(_RGFW->root, E->touches[i].targetX, E->touches[i].targetY);
RGFW_rawMotionCallback(_RGFW->root, 0, 0);
RGFW_mouseButtonCallback(_RGFW->root, RGFW_mouseLeft, 1);
}
@@ -14849,11 +15990,11 @@ EM_BOOL Emscripten_on_touchstart(int eventType, const EmscriptenTouchEvent* E, v
EM_BOOL Emscripten_on_touchmove(int eventType, const EmscriptenTouchEvent* E, void* userData) {
RGFW_UNUSED(eventType); RGFW_UNUSED(userData);
- if (!(_RGFW->root->internal.enabledEvents & RGFW_mousePosChangedFlag)) return EM_TRUE;
+ if (!(_RGFW->root->internal.enabledEvents & RGFW_mouseMotionFlag)) return EM_TRUE;
size_t i;
for (i = 0; i < (size_t)E->numTouches; i++) {
- RGFW_mousePosCallback(_RGFW->root, E->touches[i].targetX, E->touches[i].targetY);
+ RGFW_mouseMotionCallback(_RGFW->root, E->touches[i].targetX, E->touches[i].targetY);
RGFW_rawMotionCallback(_RGFW->root, 0, 0);
}
return EM_TRUE;
@@ -14866,7 +16007,7 @@ EM_BOOL Emscripten_on_touchend(int eventType, const EmscriptenTouchEvent* E, voi
size_t i;
for (i = 0; i < (size_t)E->numTouches; i++) {
- RGFW_mousePosCallback(_RGFW->root, E->touches[i].targetX, E->touches[i].targetY);
+ RGFW_mouseMotionCallback(_RGFW->root, E->touches[i].targetX, E->touches[i].targetY);
RGFW_rawMotionCallback(_RGFW->root, 0, 0);
RGFW_mouseButtonCallback(_RGFW->root, RGFW_mouseLeft, 0);
}
@@ -14899,6 +16040,8 @@ void EMSCRIPTEN_KEEPALIVE Emscripten_onDrop(char* file, size_t size) {
RGFW_dataDropCallback(_RGFW->root, file, size, RGFW_dataFile);
}
+void EMSCRIPTEN_KEEPALIVE RGFW_webFree(void* ptr) { free(ptr); }
+
void RGFW_stopCheckEvents(void) {
_RGFW->stopCheckEvents_bool = RGFW_TRUE;
}
@@ -15052,7 +16195,8 @@ void RGFW_initKeycodesPlatform(void) {
_RGFW->keycodes[DOM_VK_F24] = RGFW_keyF24;
}
-i32 RGFW_initPlatform(void) {
+i32 RGFW_initPlatform(const char* className, RGFW_initFlags flags) {
+ RGFW_UNUSED(className); RGFW_UNUSED(flags);
RGFW_monitorNode* node = NULL;
RGFW_monitor monitor;
@@ -15119,7 +16263,7 @@ RGFW_window* RGFW_createWindowPlatform(const char* name, RGFW_windowFlags flags,
}
Module._RGFW_handleKeyEvent(code, codepoint, 1);
- _free(code);
+ Module._RGFW_webFree(code);
},
true);
window.addEventListener("keyup",
@@ -15127,7 +16271,7 @@ RGFW_window* RGFW_createWindowPlatform(const char* name, RGFW_windowFlags flags,
var code = stringToNewUTF8(event.code);
Module._RGFW_handleKeyMods(event.getModifierState("CapsLock"), event.getModifierState("NumLock"), event.getModifierState("Control"), event.getModifierState("Alt"), event.getModifierState("Shift"), event.getModifierState("Meta"), event.getModifierState("ScrollLock"));
Module._RGFW_handleKeyEvent(code, 0, 0);
- _free(code);
+ Module._RGFW_webFree(code);
},
true);
});
@@ -15186,11 +16330,16 @@ RGFW_bool RGFW_window_fetchSize(RGFW_window* win, i32* w, i32* h) {
}
void RGFW_pollEvents(void) {
+ static int using_asyncify = -1;
+ if (using_asyncify == -1) using_asyncify = EM_ASM_INT({ return (typeof Asyncify !== 'undefined') || ('Asyncify' in Module); });
+
RGFW_resetPrevState();
- emscripten_sleep(0);
+ if (using_asyncify) {
+ emscripten_sleep(0);
+ }
}
-void RGFW_window_resize(RGFW_window* win, i32 w, i32 h) {
+void RGFW_window_resizePlatform(RGFW_window* win, i32 w, i32 h) {
RGFW_UNUSED(win);
emscripten_set_canvas_element_size("#canvas", w, h);
}
@@ -15271,27 +16420,32 @@ void RGFW_window_setMousePassthrough(RGFW_window* win, RGFW_bool passthrough) {
}, passthrough);
}
-void RGFW_writeClipboard(const char* text, u32 textLen) {
- RGFW_UNUSED(textLen);
- EM_ASM({ navigator.clipboard.writeText(UTF8ToString($0)); }, text);
+RGFW_bool RGFW_writeClipboard(const RGFW_dataTransfer* data) {
+ RGFW_ASSERT(data != NULL);
+ EM_ASM({ navigator.clipboard.writeText(UTF8ToString($0)); }, data->data);
+ return RGFW_TRUE;
}
-RGFW_ssize_t RGFW_readClipboardPtr(char* str, size_t strCapacity) {
- RGFW_UNUSED(str); RGFW_UNUSED(strCapacity);
+RGFW_bool RGFW_readClipboardPtr(RGFW_dataTransferType requestedType, u8* buffer, size_t capacity, RGFW_dataTransfer* data) {
+ RGFW_ASSERT(data != NULL);
+ RGFW_UNUSED(buffer); RGFW_UNUSED(capacity);
+
+ if (requestedType != RGFW_dataText) return RGFW_FALSE;
+
/*
placeholder code for later
I'm not sure if this is possible do the the async stuff
*/
- return 0;
+ return RGFW_FALSE;
}
#ifdef RGFW_OPENGL
-RGFW_bool RGFW_window_createContextPtr_OpenGL(RGFW_window* win, RGFW_glContext* ctx, RGFW_glHints* hints) {
- win->src.ctx.native = ctx;
- win->src.gfxType = RGFW_gfxNativeOpenGL;
+RGFW_bool RGFW_loadGL(void) { return RGFW_TRUE; }
+RGFW_bool RGFW_createContextPtr_OpenGL(RGFW_glContext* ctx, RGFW_glHints* hints) {
EmscriptenWebGLContextAttributes attrs;
+ emscripten_webgl_init_context_attributes(&attrs);
attrs.alpha = hints->alpha;
attrs.depth = hints->depth;
attrs.stencil = hints->stencil;
@@ -15305,29 +16459,65 @@ RGFW_bool RGFW_window_createContextPtr_OpenGL(RGFW_window* win, RGFW_glContext*
attrs.renderViaOffscreenBackBuffer = hints->auxBuffers;
attrs.failIfMajorPerformanceCaveat = EM_FALSE;
- attrs.majorVersion = (hints->major == 0) ? 1 : hints->major;
- attrs.minorVersion = hints->minor;
attrs.enableExtensionsByDefault = EM_TRUE;
+
+ if (hints->profile == RGFW_glWeb) {
+ attrs.majorVersion = (hints->major == 0) ? 1 : hints->major;
+ attrs.minorVersion = hints->minor;
+ } else {
+ attrs.majorVersion = (hints->major == 0) ? 1 : ( (hints->major > 1) ? hints->major - 1 : hints->major );
+ attrs.minorVersion = hints->minor;
+ }
+
attrs.explicitSwapControl = EM_TRUE;
+ ctx->ctx = emscripten_webgl_create_context("#canvas", &attrs);
- emscripten_webgl_init_context_attributes(&attrs);
- win->src.ctx.native->ctx = emscripten_webgl_create_context("#canvas", &attrs);
- emscripten_webgl_make_context_current(win->src.ctx.native->ctx);
+ if (ctx->ctx == 0) {
+ RGFW_debugCallback(RGFW_typeError, RGFW_warningOpenGL, "WebGL: Failed to create an OpenGL Context with explicit swap control.");
+ attrs.explicitSwapControl = EM_FALSE;
+ ctx->ctx = emscripten_webgl_create_context("#canvas", &attrs);
+ }
+
+ if (ctx->ctx == 0) {
+ RGFW_debugCallback(RGFW_typeError, RGFW_errOpenGLContext, "Failed to create an OpenGL Context with the requested attributes, falling back to defaults.");
+ ctx->ctx = emscripten_webgl_create_context("#canvas", &attrs);
+ }
+
+ if (ctx->ctx == 0) {
+ RGFW_debugCallback(RGFW_typeError, RGFW_errOpenGLContext, "Failed to create an OpenGL Context.");
+ return RGFW_FALSE;
+ }
+
+ emscripten_webgl_make_context_current(ctx->ctx);
#ifdef LEGACY_GL_EMULATION
EM_ASM("Module.useWebGL = true; GLImmediate.init();");
RGFW_debugCallback(RGFW_typeInfo, RGFW_infoOpenGL, "OpenGL context initalized.");
#endif
- RGFW_window_swapInterval_OpenGL(win, 0);
+ return RGFW_TRUE;
+}
+RGFW_bool RGFW_window_setContext_OpenGL(RGFW_window* win, RGFW_glContext* ctx) {
+ RGFW_ASSERT(win);
+ if (ctx == NULL && win->src.ctx.native != NULL) {
+ win->src.ctx.native = NULL;
+
+ RGFW_debugCallback(RGFW_typeInfo, RGFW_infoOpenGL, "OpenGL surface freed.");
+ return RGFW_TRUE;
+ }
+
+ win->src.ctx.native = ctx;
+ win->src.gfxType = RGFW_gfxNativeOpenGL;
+
+ RGFW_window_swapInterval_OpenGL(win, 0);
+ RGFW_debugCallback(RGFW_typeInfo, RGFW_infoOpenGL, "OpenGL surface initalized.");
return RGFW_TRUE;
}
-void RGFW_window_deleteContextPtr_OpenGL(RGFW_window* win, RGFW_glContext* ctx) {
+void RGFW_deleteContextPtr_OpenGL(RGFW_glContext* ctx) {
emscripten_webgl_destroy_context(ctx->ctx);
- win->src.ctx.native->ctx = 0;
RGFW_debugCallback(RGFW_typeInfo, RGFW_infoOpenGL, "OpenGL context freed.");
}
@@ -15344,6 +16534,7 @@ void RGFW_window_swapBuffers_OpenGL(RGFW_window* win) {
emscripten_webgl_commit_frame();
}
void* RGFW_getCurrentContext_OpenGL(void) { return (void*)emscripten_webgl_get_current_context(); }
+void* RGFW_getCurrentSurface_OpenGL(void) { return (void*)emscripten_webgl_get_current_context(); }
RGFW_bool RGFW_extensionSupportedPlatform_OpenGL(const char* extension, size_t len) {
return EM_ASM_INT({
@@ -15394,26 +16585,20 @@ void RGFW_window_setName(RGFW_window* win, const char* name) {
emscripten_set_window_title(name);
}
-void RGFW_window_maximize(RGFW_window* win) {
- RGFW_ASSERT(win != NULL);
-
+void RGFW_window_maximizePlatform(RGFW_window* win) {
RGFW_monitor* mon = RGFW_window_getMonitor(win);
if (mon != NULL) {
RGFW_window_resize(win, mon->mode.w, mon->mode.h);
}
RGFW_window_move(win, 0, 0);
- RGFW_window_fetchSize(win, NULL, NULL);
}
-void RGFW_window_setFullscreen(RGFW_window* win, RGFW_bool fullscreen) {
- RGFW_ASSERT(win != NULL);
+void RGFW_window_setFullscreenPlatform(RGFW_window* win, RGFW_bool fullscreen) {
if (fullscreen) {
- win->internal.flags |= RGFW_windowFullscreen;
EM_ASM( Module.requestFullscreen(false, true); );
return;
}
- win->internal.flags &= ~(u32)RGFW_windowFullscreen;
EM_ASM( Module.exitFullscreen(false, true); );
}
@@ -15462,6 +16647,7 @@ RGFW_key RGFW_WASMPhysicalToRGFW(u32 hash) {
case 0x2C595B54U /* KeyT */: return RGFW_keyT; /* 0x0014 */
case 0x2C595B59U /* KeyY */: return RGFW_keyY; /* 0x0015 */
case 0x2C595B55U /* KeyU */: return RGFW_keyU; /* 0x0016 */
+ case 0x2C595B49U /* KeyI */: return RGFW_keyI; /* 0x0017 */
case 0x2C595B4FU /* KeyO */: return RGFW_keyO; /* 0x0018 */
case 0x2C595B50U /* KeyP */: return RGFW_keyP; /* 0x0019 */
case 0x45D8158CU /* BracketLeft */: return RGFW_keyCloseBracket; /* 0x001A */
@@ -15507,7 +16693,7 @@ RGFW_key RGFW_WASMPhysicalToRGFW(u32 hash) {
case 0x7174B780U /* F8 */: return RGFW_keyF8; /* 0x0042 */
case 0x7174B781U /* F9 */: return RGFW_keyF9; /* 0x0043 */
case 0x7B8E57B0U /* F10 */: return RGFW_keyF10; /* 0x0044 */
- case 0xC925FCDFU /* Numpad7 */: return RGFW_keyPadMultiply; /* 0x0047 */
+ case 0xC925FCDFU /* Numpad7 */: return RGFW_key7; /* 0x0047 */
case 0xC925FCD0U /* Numpad8 */: return RGFW_keyPad8; /* 0x0048 */
case 0xC925FCD1U /* Numpad9 */: return RGFW_keyPad9; /* 0x0049 */
case 0x5EA3E8A4U /* NumpadSubtract */: return RGFW_keyMinus; /* 0x004A */
@@ -15521,17 +16707,17 @@ RGFW_key RGFW_WASMPhysicalToRGFW(u32 hash) {
case 0x95852DACU /* NumpadDecimal */: return RGFW_keyPeriod; /* 0x0053 */
case 0x7B8E57B1U /* F11 */: return RGFW_keyF11; /* 0x0057 */
case 0x7B8E57B2U /* F12 */: return RGFW_keyF12; /* 0x0058 */
- case 0x7B8E57B3U /* F13 */: return DOM_PK_F13; /* 0x0064 */
- case 0x7B8E57B4U /* F14 */: return DOM_PK_F14; /* 0x0065 */
- case 0x7B8E57B5U /* F15 */: return DOM_PK_F15; /* 0x0066 */
- case 0x7B8E57B6U /* F16 */: return DOM_PK_F16; /* 0x0067 */
- case 0x7B8E57B7U /* F17 */: return DOM_PK_F17; /* 0x0068 */
- case 0x7B8E57B8U /* F18 */: return DOM_PK_F18; /* 0x0069 */
- case 0x7B8E57B9U /* F19 */: return DOM_PK_F19; /* 0x006A */
- case 0x7B8E57A8U /* F20 */: return DOM_PK_F20; /* 0x006B */
- case 0x7B8E57A9U /* F21 */: return DOM_PK_F21; /* 0x006C */
- case 0x7B8E57AAU /* F22 */: return DOM_PK_F22; /* 0x006D */
- case 0x7B8E57ABU /* F23 */: return DOM_PK_F23; /* 0x006E */
+ case 0x7B8E57B3U /* F13 */: return RGFW_keyF13; /* 0x0064 */
+ case 0x7B8E57B4U /* F14 */: return RGFW_keyF14; /* 0x0065 */
+ case 0x7B8E57B5U /* F15 */: return RGFW_keyF15; /* 0x0066 */
+ case 0x7B8E57B6U /* F16 */: return RGFW_keyF16; /* 0x0067 */
+ case 0x7B8E57B7U /* F17 */: return RGFW_keyF17; /* 0x0068 */
+ case 0x7B8E57B8U /* F18 */: return RGFW_keyF18; /* 0x0069 */
+ case 0x7B8E57B9U /* F19 */: return RGFW_keyF19; /* 0x006A */
+ case 0x7B8E57A8U /* F20 */: return RGFW_keyF20; /* 0x006B */
+ case 0x7B8E57A9U /* F21 */: return RGFW_keyF21; /* 0x006C */
+ case 0x7B8E57AAU /* F22 */: return RGFW_keyF22; /* 0x006D */
+ case 0x7B8E57ABU /* F23 */: return RGFW_keyF23; /* 0x006E */
case 0x7393FBACU /* NumpadEqual */: return RGFW_keyPadReturn;
case 0xB88EBF7CU /* AltRight */: return RGFW_keyAltR; /* 0xE038 */
case 0xC925873BU /* NumLock */: return RGFW_keyNumLock; /* 0xE045 */
@@ -15547,7 +16733,13 @@ RGFW_key RGFW_WASMPhysicalToRGFW(u32 hash) {
case 0x6725C50DU /* Delete */: return RGFW_keyDelete; /* 0xE053 */
case 0x6723658CU /* OSLeft */: return RGFW_keySuperL; /* 0xE05B */
case 0x39643F7CU /* MetaRight */: return RGFW_keySuperR; /* 0xE05C */
- case 0x380B9C8CU /* NumpadAdd */: return DOM_PK_NUMPAD_ADD; /* 0x004E */
+ case 0x380B9C8CU /* NumpadAdd */: return RGFW_keyPadPlus; /* 0x004E */
+ case 0x92E08B35U /* Pause */: return RGFW_keyPause; /* 0x0045 */
+ case 0xCC1E198EU /* PrintScreen */: return RGFW_keyPrintScreen; /* 0x0054 */
+ case 0xCDED173BU /* ScrollLock */: return RGFW_keyScrollLock; /* 0x0046 */
+ case 0x7393C5D2U /* NumpadEnter */: return RGFW_keyPadReturn; /* 0xE01C */
+ case 0xE00E97CDU /* ContextMenu */: return RGFW_keyMenu; /* 0xE05D */
+ case 0x6CB5328DU /* NumpadDivide */: return RGFW_keyPadSlash; /* 0xE035 */
default: return DOM_PK_UNKNOWN;
}
@@ -15561,6 +16753,7 @@ RGFW_monitor* RGFW_window_getMonitor(RGFW_window* win) {
/* unsupported functions */
void RGFW_pollMonitors(void) { }
+void RGFW_monitorNode_free(RGFW_monitorNode* node) { RGFW_UNUSED(node); }
void RGFW_window_focus(RGFW_window* win) { RGFW_UNUSED(win); }
void RGFW_window_raise(RGFW_window* win) { RGFW_UNUSED(win); }
RGFW_bool RGFW_monitor_requestMode(RGFW_monitor* mon, RGFW_monitorMode* mode, RGFW_modeRequest request) { RGFW_UNUSED(mon); RGFW_UNUSED(mode); RGFW_UNUSED(request); return RGFW_FALSE; }
@@ -15569,17 +16762,17 @@ size_t RGFW_monitor_getGammaRampPtr(RGFW_monitor* monitor, RGFW_gammaRamp* ramp)
RGFW_bool RGFW_monitor_setGammaRamp(RGFW_monitor* monitor, RGFW_gammaRamp* ramp) { RGFW_UNUSED(monitor); RGFW_UNUSED(ramp); return RGFW_FALSE; }
size_t RGFW_monitor_getModesPtr(RGFW_monitor* mon, RGFW_monitorMode** modes) { RGFW_UNUSED(mon); RGFW_UNUSED(modes); return 0; }
RGFW_bool RGFW_monitor_setMode(RGFW_monitor* mon, RGFW_monitorMode* mode) { RGFW_UNUSED(mon); RGFW_UNUSED(mode); return RGFW_FALSE; }
-void RGFW_window_move(RGFW_window* win, i32 x, i32 y) { RGFW_UNUSED(win); RGFW_UNUSED(x); RGFW_UNUSED(y); }
+void RGFW_window_movePlatform(RGFW_window* win, i32 x, i32 y) { RGFW_UNUSED(win); RGFW_UNUSED(x); RGFW_UNUSED(y); }
void RGFW_window_setAspectRatio(RGFW_window* win, i32 w, i32 h) { RGFW_UNUSED(win); RGFW_UNUSED(w); RGFW_UNUSED(h); }
void RGFW_window_setMinSize(RGFW_window* win, i32 w, i32 h) { RGFW_UNUSED(win); RGFW_UNUSED(w); RGFW_UNUSED(h); }
void RGFW_window_setMaxSize(RGFW_window* win, i32 w, i32 h) { RGFW_UNUSED(win); RGFW_UNUSED(w); RGFW_UNUSED(h); }
-void RGFW_window_minimize(RGFW_window* win) { RGFW_UNUSED(win); }
-void RGFW_window_restore(RGFW_window* win) { RGFW_UNUSED(win); }
+void RGFW_window_minimizePlatform(RGFW_window* win) { RGFW_UNUSED(win); }
+void RGFW_window_restorePlatform(RGFW_window* win) { RGFW_UNUSED(win); }
void RGFW_window_setFloating(RGFW_window* win, RGFW_bool floating) { RGFW_UNUSED(win); RGFW_UNUSED(floating); }
void RGFW_window_setBorder(RGFW_window* win, RGFW_bool border) { RGFW_UNUSED(win); RGFW_UNUSED(border); }
RGFW_bool RGFW_window_setIconEx(RGFW_window* win, u8* data, i32 w, i32 h, RGFW_format format, RGFW_icon type) { RGFW_UNUSED(win); RGFW_UNUSED(data); RGFW_UNUSED(w); RGFW_UNUSED(h); RGFW_UNUSED(format); RGFW_UNUSED(type); return RGFW_FALSE; }
void RGFW_window_hide(RGFW_window* win) { RGFW_UNUSED(win); }
-void RGFW_window_show(RGFW_window* win) {RGFW_UNUSED(win); }
+void RGFW_window_showPlatform(RGFW_window* win) {RGFW_UNUSED(win); }
void RGFW_window_flash(RGFW_window* win, RGFW_flashRequest request) { RGFW_UNUSED(win); RGFW_UNUSED(request); }
RGFW_bool RGFW_window_isHidden(RGFW_window* win) { RGFW_UNUSED(win); return RGFW_FALSE; }
RGFW_bool RGFW_window_isMinimized(RGFW_window* win) { RGFW_UNUSED(win); return RGFW_FALSE; }
@@ -15600,6 +16793,7 @@ typedef RGFW_key (*RGFW_physicalToMappedKey_ptr)(RGFW_key key);
typedef void (*RGFW_pollEvents_ptr)(void);
typedef RGFW_bool (*RGFW_window_fetchSize_ptr)(RGFW_window* win, i32* w, i32* h);
typedef void (*RGFW_pollMonitors_ptr)(void);
+typedef void (*RGFW_monitorNode_free_ptr)(RGFW_monitorNode* node);
typedef void (*RGFW_window_move_ptr)(RGFW_window* win, i32 x, i32 y);
typedef void (*RGFW_window_resize_ptr)(RGFW_window* win, i32 w, i32 h);
typedef void (*RGFW_window_setAspectRatio_ptr)(RGFW_window* win, i32 w, i32 h);
@@ -15608,7 +16802,7 @@ typedef void (*RGFW_window_setMaxSize_ptr)(RGFW_window* win, i32 w, i32 h);
typedef void (*RGFW_window_maximize_ptr)(RGFW_window* win);
typedef void (*RGFW_window_focus_ptr)(RGFW_window* win);
typedef void (*RGFW_window_raise_ptr)(RGFW_window* win);
-typedef void (*RGFW_window_setFullscreen_ptr)(RGFW_window* win, RGFW_bool fullscreen);
+typedef void (*RGFW_window_setFullscreenPlatform_ptr)(RGFW_window* win, RGFW_bool fullscreen);
typedef void (*RGFW_window_setFloating_ptr)(RGFW_window* win, RGFW_bool floating);
typedef void (*RGFW_window_setOpacity_ptr)(RGFW_window* win, u8 opacity);
typedef void (*RGFW_window_minimize_ptr)(RGFW_window* win);
@@ -15624,8 +16818,8 @@ typedef void (*RGFW_window_moveMouse_ptr)(RGFW_window* win, i32 x, i32 y);
typedef void (*RGFW_window_hide_ptr)(RGFW_window* win);
typedef void (*RGFW_window_show_ptr)(RGFW_window* win);
typedef void (*RGFW_window_flash_ptr)(RGFW_window* win, RGFW_flashRequest request);
-typedef RGFW_ssize_t (*RGFW_readClipboardPtr_ptr)(char* str, size_t strCapacity);
-typedef void (*RGFW_writeClipboard_ptr)(const char* text, u32 textLen);
+typedef RGFW_bool (*RGFW_readClipboardPtr_ptr)(RGFW_dataTransferType requestedType, u8* buffer, size_t capacity, RGFW_dataTransfer* data);
+typedef RGFW_bool (*RGFW_writeClipboard_ptr)(const RGFW_dataTransfer* data);
typedef RGFW_bool (*RGFW_window_isHidden_ptr)(RGFW_window* win);
typedef RGFW_bool (*RGFW_window_isMinimized_ptr)(RGFW_window* win);
typedef RGFW_bool (*RGFW_window_isMaximized_ptr)(RGFW_window* win);
@@ -15648,12 +16842,14 @@ typedef void (*RGFW_window_setRawMouseModePlatform_ptr)(RGFW_window* win, RGFW_b
#ifdef RGFW_OPENGL
typedef void (*RGFW_window_makeCurrentContext_OpenGL_ptr)(RGFW_window* win);
typedef void* (*RGFW_getCurrentContext_OpenGL_ptr)(void);
+typedef void* (*RGFW_getCurrentSurface_OpenGL_ptr)(void);
typedef void (*RGFW_window_swapBuffers_OpenGL_ptr)(RGFW_window* win);
typedef void (*RGFW_window_swapInterval_OpenGL_ptr)(RGFW_window* win, i32 swapInterval);
typedef RGFW_bool (*RGFW_extensionSupportedPlatform_OpenGL_ptr)(const char* extension, size_t len);
typedef RGFW_proc (*RGFW_getProcAddress_OpenGL_ptr)(const char* procname);
-typedef RGFW_bool (*RGFW_window_createContextPtr_OpenGL_ptr)(RGFW_window* win, RGFW_glContext* ctx, RGFW_glHints* hints);
-typedef void (*RGFW_window_deleteContextPtr_OpenGL_ptr)(RGFW_window* win, RGFW_glContext* ctx);
+typedef RGFW_bool (*RGFW_createContextPtr_OpenGL_ptr)(RGFW_glContext* ctx, RGFW_glHints* hints);
+typedef RGFW_bool (*RGFW_window_setContext_OpenGL_ptr)(RGFW_window* win, RGFW_glContext* ctx);
+typedef void (*RGFW_deleteContextPtr_OpenGL_ptr)(RGFW_glContext* ctx);
#endif
#ifdef RGFW_WEBGPU
typedef WGPUSurface (*RGFW_window_createSurface_WebGPU_ptr)(RGFW_window* window, WGPUInstance instance);
@@ -15675,25 +16871,26 @@ typedef struct RGFW_FunctionPointers {
RGFW_window_fetchSize_ptr window_fetchSize;
RGFW_pollEvents_ptr pollEvents;
RGFW_pollMonitors_ptr pollMonitors;
- RGFW_window_move_ptr window_move;
- RGFW_window_resize_ptr window_resize;
+ RGFW_monitorNode_free_ptr monitorNode_free;
+ RGFW_window_move_ptr window_movePlatform;
+ RGFW_window_resize_ptr window_resizePlatform;
RGFW_window_setAspectRatio_ptr window_setAspectRatio;
RGFW_window_setMinSize_ptr window_setMinSize;
RGFW_window_setMaxSize_ptr window_setMaxSize;
- RGFW_window_maximize_ptr window_maximize;
+ RGFW_window_maximize_ptr window_maximizePlatform;
RGFW_window_focus_ptr window_focus;
RGFW_window_raise_ptr window_raise;
- RGFW_window_setFullscreen_ptr window_setFullscreen;
+ RGFW_window_setFullscreenPlatform_ptr window_setFullscreenPlatform;
RGFW_window_setFloating_ptr window_setFloating;
RGFW_window_setOpacity_ptr window_setOpacity;
- RGFW_window_minimize_ptr window_minimize;
- RGFW_window_restore_ptr window_restore;
+ RGFW_window_minimize_ptr window_minimizePlatform;
+ RGFW_window_restore_ptr window_restorePlatform;
RGFW_window_isFloating_ptr window_isFloating;
RGFW_window_setName_ptr window_setName;
RGFW_window_setMousePassthrough_ptr window_setMousePassthrough;
RGFW_window_setIconEx_ptr window_setIconEx;
- RGFW_createMouse_ptr loadMouse;
- RGFW_createMouseStandard_ptr loadMouseStandard;
+ RGFW_createMouse_ptr createMouse;
+ RGFW_createMouseStandard_ptr createMouseStandard;
RGFW_window_setMousePlatform_ptr window_setMousePlatform;
RGFW_window_moveMouse_ptr window_moveMouse;
RGFW_window_hide_ptr window_hide;
@@ -15715,10 +16912,12 @@ typedef struct RGFW_FunctionPointers {
#ifdef RGFW_OPENGL
RGFW_extensionSupportedPlatform_OpenGL_ptr extensionSupportedPlatform_OpenGL;
RGFW_getProcAddress_OpenGL_ptr getProcAddress_OpenGL;
- RGFW_window_createContextPtr_OpenGL_ptr window_createContextPtr_OpenGL;
- RGFW_window_deleteContextPtr_OpenGL_ptr window_deleteContextPtr_OpenGL;
+ RGFW_createContextPtr_OpenGL_ptr createContextPtr_OpenGL;
+ RGFW_window_setContext_OpenGL_ptr window_setContext_OpenGL;
+ RGFW_deleteContextPtr_OpenGL_ptr deleteContextPtr_OpenGL;
RGFW_window_makeCurrentContext_OpenGL_ptr window_makeCurrentContext_OpenGL;
RGFW_getCurrentContext_OpenGL_ptr getCurrentContext_OpenGL;
+ RGFW_getCurrentSurface_OpenGL_ptr getCurrentSurface_OpenGL;
RGFW_window_swapBuffers_OpenGL_ptr window_swapBuffers_OpenGL;
RGFW_window_swapInterval_OpenGL_ptr window_swapInterval_OpenGL;
#endif
@@ -15737,25 +16936,26 @@ void RGFW_window_blitSurface(RGFW_window* win, RGFW_surface* surface) { RGFW_api
void RGFW_window_setBorder(RGFW_window* win, RGFW_bool border) { RGFW_api.window_setBorder(win, border); }
void RGFW_window_captureMousePlatform(RGFW_window* win, RGFW_bool state) { RGFW_api.window_captureMousePlatform(win, state); }
void RGFW_window_setRawMouseModePlatform(RGFW_window* win, RGFW_bool state) { RGFW_api.window_setRawMouseModePlatform(win, state); }
-RGFW_window* RGFW_createWindowPlatform(const char* name, RGFW_windowFlags flags, RGFW_window* win) { RGFW_init(); return RGFW_api.createWindowPlatform(name, flags, win); }
+RGFW_window* RGFW_createWindowPlatform(const char* name, RGFW_windowFlags flags, RGFW_window* win) { return RGFW_api.createWindowPlatform(name, flags, win); }
RGFW_bool RGFW_getGlobalMouse(i32* x, i32* y) { return RGFW_api.getGlobalMouse(x, y); }
RGFW_key RGFW_physicalToMappedKey(RGFW_key key) { return RGFW_api.physicalToMappedKey(key); }
void RGFW_pollEvents(void) { RGFW_api.pollEvents(); }
RGFW_bool RGFW_window_fetchSize(RGFW_window* win, i32* w, i32* h) { return RGFW_api.window_fetchSize(win, w, h); }
void RGFW_pollMonitors(void) { RGFW_api.pollMonitors(); }
-void RGFW_window_move(RGFW_window* win, i32 x, i32 y) { RGFW_api.window_move(win, x, y); }
-void RGFW_window_resize(RGFW_window* win, i32 w, i32 h) { RGFW_api.window_resize(win, w, h); }
+void RGFW_monitorNode_free(RGFW_monitorNode* node) { RGFW_api.monitorNode_free(node); }
+void RGFW_window_movePlatform(RGFW_window* win, i32 x, i32 y) { RGFW_api.window_movePlatform(win, x, y); }
+void RGFW_window_resizePlatform(RGFW_window* win, i32 w, i32 h) { RGFW_api.window_resizePlatform(win, w, h); }
void RGFW_window_setAspectRatio(RGFW_window* win, i32 w, i32 h) { RGFW_api.window_setAspectRatio(win, w, h); }
void RGFW_window_setMinSize(RGFW_window* win, i32 w, i32 h) { RGFW_api.window_setMinSize(win, w, h); }
void RGFW_window_setMaxSize(RGFW_window* win, i32 w, i32 h) { RGFW_api.window_setMaxSize(win, w, h); }
-void RGFW_window_maximize(RGFW_window* win) { RGFW_api.window_maximize(win); }
+void RGFW_window_maximizePlatform(RGFW_window* win) { RGFW_api.window_maximizePlatform(win); }
void RGFW_window_focus(RGFW_window* win) { RGFW_api.window_focus(win); }
void RGFW_window_raise(RGFW_window* win) { RGFW_api.window_raise(win); }
-void RGFW_window_setFullscreen(RGFW_window* win, RGFW_bool fullscreen) { RGFW_api.window_setFullscreen(win, fullscreen); }
+void RGFW_window_setFullscreenPlatform(RGFW_window* win, RGFW_bool fullscreen) { RGFW_api.window_setFullscreenPlatform(win, fullscreen); }
void RGFW_window_setFloating(RGFW_window* win, RGFW_bool floating) { RGFW_api.window_setFloating(win, floating); }
void RGFW_window_setOpacity(RGFW_window* win, u8 opacity) { RGFW_api.window_setOpacity(win, opacity); }
-void RGFW_window_minimize(RGFW_window* win) { RGFW_api.window_minimize(win); }
-void RGFW_window_restore(RGFW_window* win) { RGFW_api.window_restore(win); }
+void RGFW_window_minimizePlatform(RGFW_window* win) { RGFW_api.window_minimizePlatform(win); }
+void RGFW_window_restorePlatform(RGFW_window* win) { RGFW_api.window_restorePlatform(win); }
RGFW_bool RGFW_window_isFloating(RGFW_window* win) { return RGFW_api.window_isFloating(win); }
void RGFW_window_setName(RGFW_window* win, const char* name) { RGFW_api.window_setName(win, name); }
@@ -15764,15 +16964,15 @@ void RGFW_window_setMousePassthrough(RGFW_window* win, RGFW_bool passthrough) {
#endif
RGFW_bool RGFW_window_setIconEx(RGFW_window* win, u8* data, i32 w, i32 h, RGFW_format format, u8 type) { return RGFW_api.window_setIconEx(win, data, w, h, format, type); }
-RGFW_mouse* RGFW_createMouse(u8* data, i32 w, i32 h, RGFW_format format) { return RGFW_api.loadMouse(data, w, h, format); }
-RGFW_mouse* RGFW_createMouseStandard(RGFW_mouseIcon icon) { return RGFW_api.loadMouseStandard(icon); }
+RGFW_mouse* RGFW_createMouse(u8* data, i32 w, i32 h, RGFW_format format) { return RGFW_api.createMouse(data, w, h, format); }
+RGFW_mouse* RGFW_createMouseStandard(RGFW_mouseIcon icon) { return RGFW_api.createMouseStandard(icon); }
RGFW_bool RGFW_window_setMousePlatform(RGFW_window* win, RGFW_mouse* mouse) { return RGFW_api.window_setMousePlatform(win, mouse); }
void RGFW_window_moveMouse(RGFW_window* win, i32 x, i32 y) { RGFW_api.window_moveMouse(win, x, y); }
void RGFW_window_hide(RGFW_window* win) { RGFW_api.window_hide(win); }
-void RGFW_window_show(RGFW_window* win) { RGFW_api.window_show(win); }
+void RGFW_window_showPlatform(RGFW_window* win) { RGFW_api.window_show(win); }
void RGFW_window_flash(RGFW_window* win, RGFW_flashRequest request) { RGFW_api.window_flash(win, request); }
-RGFW_ssize_t RGFW_readClipboardPtr(char* str, size_t strCapacity) { return RGFW_api.readClipboardPtr(str, strCapacity); }
-void RGFW_writeClipboard(const char* text, u32 textLen) { RGFW_api.writeClipboard(text, textLen); }
+RGFW_bool RGFW_readClipboardPtr(RGFW_dataTransferType requestedType, u8* buffer, size_t capacity, RGFW_dataTransfer* data) { return RGFW_api.readClipboardPtr(requestedType, buffer, capacity, data); }
+RGFW_bool RGFW_writeClipboard(const RGFW_dataTransfer* data) { return RGFW_api.writeClipboard(data); }
RGFW_bool RGFW_window_isHidden(RGFW_window* win) { return RGFW_api.window_isHidden(win); }
RGFW_bool RGFW_window_isMinimized(RGFW_window* win) { return RGFW_api.window_isMinimized(win); }
RGFW_bool RGFW_window_isMaximized(RGFW_window* win) { return RGFW_api.window_isMaximized(win); }
@@ -15788,10 +16988,12 @@ void RGFW_window_closePlatform(RGFW_window* win) { RGFW_api.window_closePlatform
#ifdef RGFW_OPENGL
RGFW_bool RGFW_extensionSupportedPlatform_OpenGL(const char* extension, size_t len) { return RGFW_api.extensionSupportedPlatform_OpenGL(extension, len); }
RGFW_proc RGFW_getProcAddress_OpenGL(const char* procname) { return RGFW_api.getProcAddress_OpenGL(procname); }
-RGFW_bool RGFW_window_createContextPtr_OpenGL(RGFW_window* win, RGFW_glContext* ctx, RGFW_glHints* hints) { return RGFW_api.window_createContextPtr_OpenGL(win, ctx, hints); }
-void RGFW_window_deleteContextPtr_OpenGL(RGFW_window* win, RGFW_glContext* ctx) { RGFW_api.window_deleteContextPtr_OpenGL(win, ctx); }
+RGFW_bool RGFW_createContextPtr_OpenGL(RGFW_glContext* ctx, RGFW_glHints* hints) { return RGFW_api.createContextPtr_OpenGL(ctx, hints); }
+RGFW_bool RGFW_window_setContext_OpenGL(RGFW_window* win, RGFW_glContext* ctx) { return RGFW_api.window_setContext_OpenGL(win, ctx); }
+void RGFW_deleteContextPtr_OpenGL(RGFW_glContext* ctx) { RGFW_api.deleteContextPtr_OpenGL(ctx); }
void RGFW_window_makeCurrentContext_OpenGL(RGFW_window* win) { RGFW_api.window_makeCurrentContext_OpenGL(win); }
void* RGFW_getCurrentContext_OpenGL(void) { return RGFW_api.getCurrentContext_OpenGL(); }
+void* RGFW_getCurrentSurface_OpenGL(void) { return RGFW_api.getCurrentSurface_OpenGL(); }
void RGFW_window_swapBuffers_OpenGL(RGFW_window* win) { RGFW_api.window_swapBuffers_OpenGL(win); }
void RGFW_window_swapInterval_OpenGL(RGFW_window* win, i32 swapInterval) { RGFW_api.window_swapInterval_OpenGL(win, swapInterval); }
#endif
@@ -15807,6 +17009,8 @@ WGPUSurface RGFW_window_createSurface_WebGPU(RGFW_window* window, WGPUInstance i
* falling back to x11 if wayland fails to initalize
*/
#if defined(RGFW_WAYLAND) && defined(RGFW_X11)
+RGFW_bool RGFW_usingWayland(void) { return _RGFW->useWaylandBool; }
+
void RGFW_load_X11(void) {
RGFW_api.nativeFormat = RGFW_nativeFormat_X11;
RGFW_api.createSurfacePtr = RGFW_createSurfacePtr_X11;
@@ -15822,30 +17026,31 @@ void RGFW_load_X11(void) {
RGFW_api.pollEvents = RGFW_pollEvents_X11;
RGFW_api.window_fetchSize = RGFW_window_fetchSize_X11;
RGFW_api.pollMonitors = RGFW_pollMonitors_X11;
- RGFW_api.window_move = RGFW_window_move_X11;
- RGFW_api.window_resize = RGFW_window_resize_X11;
+ RGFW_api.window_movePlatform = RGFW_window_movePlatform_X11;
+ RGFW_api.window_resizePlatform = RGFW_window_resizePlatform_X11;
RGFW_api.window_setAspectRatio = RGFW_window_setAspectRatio_X11;
RGFW_api.window_setMinSize = RGFW_window_setMinSize_X11;
RGFW_api.window_setMaxSize = RGFW_window_setMaxSize_X11;
- RGFW_api.window_maximize = RGFW_window_maximize_X11;
+ RGFW_api.window_maximizePlatform = RGFW_window_maximizePlatform_X11;
RGFW_api.window_focus = RGFW_window_focus_X11;
RGFW_api.window_raise = RGFW_window_raise_X11;
- RGFW_api.window_setFullscreen = RGFW_window_setFullscreen_X11;
+ RGFW_api.window_setFullscreenPlatform = RGFW_window_setFullscreenPlatform_X11;
RGFW_api.window_setFloating = RGFW_window_setFloating_X11;
RGFW_api.window_setOpacity = RGFW_window_setOpacity_X11;
- RGFW_api.window_minimize = RGFW_window_minimize_X11;
- RGFW_api.window_restore = RGFW_window_restore_X11;
+ RGFW_api.window_minimizePlatform = RGFW_window_minimizePlatform_X11;
+ RGFW_api.window_restorePlatform = RGFW_window_restorePlatform_X11;
RGFW_api.window_isFloating = RGFW_window_isFloating_X11;
RGFW_api.window_setName = RGFW_window_setName_X11;
#ifndef RGFW_NO_PASSTHROUGH
RGFW_api.window_setMousePassthrough = RGFW_window_setMousePassthrough_X11;
#endif
RGFW_api.window_setIconEx = RGFW_window_setIconEx_X11;
- RGFW_api.loadMouse = RGFW_createMouse_X11;
+ RGFW_api.createMouse = RGFW_createMouse_X11;
+ RGFW_api.createMouseStandard = RGFW_createMouseStandard_X11;
RGFW_api.window_setMousePlatform = RGFW_window_setMousePlatform_X11;
RGFW_api.window_moveMouse = RGFW_window_moveMouse_X11;
RGFW_api.window_hide = RGFW_window_hide_X11;
- RGFW_api.window_show = RGFW_window_show_X11;
+ RGFW_api.window_show = RGFW_window_showPlatform_X11;
RGFW_api.window_flash = RGFW_window_flash_X11;
RGFW_api.readClipboardPtr = RGFW_readClipboardPtr_X11;
RGFW_api.writeClipboard = RGFW_writeClipboard_X11;
@@ -15856,17 +17061,40 @@ void RGFW_load_X11(void) {
RGFW_api.monitor_getModesPtr = RGFW_monitor_getModesPtr_X11;
RGFW_api.monitor_setGammaRamp = RGFW_monitor_setGammaRamp_X11;
RGFW_api.monitor_getGammaRampPtr = RGFW_monitor_getGammaRampPtr_X11;
- RGFW_api.monitor_setMode = RGFW_monitor_setMode_X11;
+ RGFW_api.window_setRawMouseModePlatform = RGFW_window_setRawMouseModePlatform_Wayland;
+ RGFW_api.createWindowPlatform = RGFW_createWindowPlatform_Wayland;
+ RGFW_api.getGlobalMouse = RGFW_getGlobalMouse_Wayland;
+ RGFW_api.physicalToMappedKey = RGFW_physicalToMappedKey_Wayland;
+ RGFW_api.pollEvents = RGFW_pollEvents_Wayland;
+ RGFW_api.window_fetchSize = RGFW_window_fetchSize_Wayland;
+ RGFW_api.pollMonitors = RGFW_pollMonitors_Wayland;
+ RGFW_api.window_movePlatform = RGFW_window_movePlatform_Wayland;
+ RGFW_api.window_resizePlatform = RGFW_window_resizePlatform_Wayland;
+ RGFW_api.window_setAspectRatio = RGFW_window_setAspectRatio_Wayland;
+ RGFW_api.window_setMinSize = RGFW_window_setMinSize_Wayland;
+ RGFW_api.window_setMaxSize = RGFW_window_setMaxSize_Wayland;
+ RGFW_api.window_maximizePlatform = RGFW_window_maximizePlatform_Wayland;
+ RGFW_api.window_focus = RGFW_window_focus_Wayland;
+ RGFW_api.window_raise = RGFW_window_raise_Wayland;
+ RGFW_api.window_setFullscreenPlatform = RGFW_window_setFullscreenPlatform_Wayland;
+ RGFW_api.window_setFloating = RGFW_window_setFloating_Wayland;
+ RGFW_api.window_setOpacity = RGFW_window_setOpacity_Wayland;
+ RGFW_api.window_minimizePlatform = RGFW_window_minimizePlatform_Wayland;
+ RGFW_api.window_restorePlatform = RGFW_window_restorePlatform_Wayland;
+ RGFW_api.window_isFloating = RGFW_window_isFloating_Wayland;
+ RGFW_api.window_setName = RGFW_window_setName_Wayland;RGFW_api.monitor_setMode = RGFW_monitor_setMode_X11;
RGFW_api.window_getMonitor = RGFW_window_getMonitor_X11;
RGFW_api.window_closePlatform = RGFW_window_closePlatform_X11;
#ifdef RGFW_OPENGL
RGFW_api.extensionSupportedPlatform_OpenGL = RGFW_extensionSupportedPlatform_OpenGL_X11;
RGFW_api.getProcAddress_OpenGL = RGFW_getProcAddress_OpenGL_X11;
- RGFW_api.window_createContextPtr_OpenGL = RGFW_window_createContextPtr_OpenGL_X11;
- RGFW_api.window_deleteContextPtr_OpenGL = RGFW_window_deleteContextPtr_OpenGL_X11;
+ RGFW_api.createContextPtr_OpenGL = RGFW_createContextPtr_OpenGL_X11;
+ RGFW_api.deleteContextPtr_OpenGL = RGFW_deleteContextPtr_OpenGL_X11;
RGFW_api.window_makeCurrentContext_OpenGL = RGFW_window_makeCurrentContext_OpenGL_X11;
RGFW_api.getCurrentContext_OpenGL = RGFW_getCurrentContext_OpenGL_X11;
+ RGFW_api.getCurrentSurface_OpenGL = RGFW_getCurrentSurface_OpenGL_X11;
RGFW_api.window_swapBuffers_OpenGL = RGFW_window_swapBuffers_OpenGL_X11;
+ RGFW_api.window_setContext_OpenGL = RGFW_window_setContext_OpenGL_X11;
RGFW_api.window_swapInterval_OpenGL = RGFW_window_swapInterval_OpenGL_X11;
#endif
#ifdef RGFW_WEBGPU
@@ -15882,37 +17110,16 @@ void RGFW_load_Wayland(void) {
RGFW_api.freeMouse = RGFW_freeMouse_Wayland;
RGFW_api.window_setBorder = RGFW_window_setBorder_Wayland;
RGFW_api.window_captureMousePlatform = RGFW_window_captureMousePlatform_Wayland;
- RGFW_api.window_setRawMouseModePlatform = RGFW_window_setRawMouseModePlatform_Wayland;
- RGFW_api.createWindowPlatform = RGFW_createWindowPlatform_Wayland;
- RGFW_api.getGlobalMouse = RGFW_getGlobalMouse_Wayland;
- RGFW_api.physicalToMappedKey = RGFW_physicalToMappedKey_Wayland;
- RGFW_api.pollEvents = RGFW_pollEvents_Wayland;
- RGFW_api.window_fetchSize = RGFW_window_fetchSize_Wayland;
- RGFW_api.pollMonitors = RGFW_pollMonitors_Wayland;
- RGFW_api.window_move = RGFW_window_move_Wayland;
- RGFW_api.window_resize = RGFW_window_resize_Wayland;
- RGFW_api.window_setAspectRatio = RGFW_window_setAspectRatio_Wayland;
- RGFW_api.window_setMinSize = RGFW_window_setMinSize_Wayland;
- RGFW_api.window_setMaxSize = RGFW_window_setMaxSize_Wayland;
- RGFW_api.window_maximize = RGFW_window_maximize_Wayland;
- RGFW_api.window_focus = RGFW_window_focus_Wayland;
- RGFW_api.window_raise = RGFW_window_raise_Wayland;
- RGFW_api.window_setFullscreen = RGFW_window_setFullscreen_Wayland;
- RGFW_api.window_setFloating = RGFW_window_setFloating_Wayland;
- RGFW_api.window_setOpacity = RGFW_window_setOpacity_Wayland;
- RGFW_api.window_minimize = RGFW_window_minimize_Wayland;
- RGFW_api.window_restore = RGFW_window_restore_Wayland;
- RGFW_api.window_isFloating = RGFW_window_isFloating_Wayland;
- RGFW_api.window_setName = RGFW_window_setName_Wayland;
#ifndef RGFW_NO_PASSTHROUGH
RGFW_api.window_setMousePassthrough = RGFW_window_setMousePassthrough_Wayland;
#endif
RGFW_api.window_setIconEx = RGFW_window_setIconEx_Wayland;
- RGFW_api.loadMouse = RGFW_createMouse_Wayland;
+ RGFW_api.createMouse = RGFW_createMouse_Wayland;
+ RGFW_api.createMouseStandard = RGFW_createMouseStandard_Wayland;
RGFW_api.window_setMousePlatform = RGFW_window_setMousePlatform_Wayland;
RGFW_api.window_moveMouse = RGFW_window_moveMouse_Wayland;
RGFW_api.window_hide = RGFW_window_hide_Wayland;
- RGFW_api.window_show = RGFW_window_show_Wayland;
+ RGFW_api.window_show = RGFW_window_showPlatform_Wayland;
RGFW_api.window_flash = RGFW_window_flash_X11;
RGFW_api.readClipboardPtr = RGFW_readClipboardPtr_Wayland;
RGFW_api.writeClipboard = RGFW_writeClipboard_Wayland;
@@ -15929,10 +17136,12 @@ void RGFW_load_Wayland(void) {
#ifdef RGFW_OPENGL
RGFW_api.extensionSupportedPlatform_OpenGL = RGFW_extensionSupportedPlatform_OpenGL_Wayland;
RGFW_api.getProcAddress_OpenGL = RGFW_getProcAddress_OpenGL_Wayland;
- RGFW_api.window_createContextPtr_OpenGL = RGFW_window_createContextPtr_OpenGL_Wayland;
- RGFW_api.window_deleteContextPtr_OpenGL = RGFW_window_deleteContextPtr_OpenGL_Wayland;
+ RGFW_api.createContextPtr_OpenGL = RGFW_createContextPtr_OpenGL_Wayland;
+ RGFW_api.deleteContextPtr_OpenGL = RGFW_deleteContextPtr_OpenGL_Wayland;
RGFW_api.window_makeCurrentContext_OpenGL = RGFW_window_makeCurrentContext_OpenGL_Wayland;
RGFW_api.getCurrentContext_OpenGL = RGFW_getCurrentContext_OpenGL_Wayland;
+ RGFW_api.getCurrentSurface_OpenGL = RGFW_getCurrentSurface_OpenGL_Wayland;
+ RGFW_api.window_setContext_OpenGL = RGFW_window_setContext_OpenGL_Wayland;
RGFW_api.window_swapBuffers_OpenGL = RGFW_window_swapBuffers_OpenGL_Wayland;
RGFW_api.window_swapInterval_OpenGL = RGFW_window_swapInterval_OpenGL_Wayland;
#endif