From 94897c4eca842673bad16ab03ad776a0a2255b14 Mon Sep 17 00:00:00 2001 From: Thomas Anderson <5776225+CrackedPixel@users.noreply.github.com> Date: Wed, 10 Jun 2026 01:56:07 -0500 Subject: [PATCH] [platform/RGFW] update rgfw (#5919) * update rgfw + platform v1 * added drop events * updates --- src/external/RGFW/RGFW.h | 4340 +++++++++++++++------------- src/platforms/rcore_desktop_rgfw.c | 856 +++--- 2 files changed, 2729 insertions(+), 2467 deletions(-) diff --git a/src/external/RGFW/RGFW.h b/src/external/RGFW/RGFW.h index 427db0168..e114334e0 100644 --- a/src/external/RGFW/RGFW.h +++ b/src/external/RGFW/RGFW.h @@ -41,6 +41,7 @@ #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 @@ -55,10 +56,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 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,32 +71,25 @@ #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 -lGL -windows : gcc main.c -lopengl32 -lgdi32 -macos : gcc main.c -framework Cocoa -framework CoreVideo -framework OpenGL -framework IOKit +linux : gcc main.c -lX11 -lXrandr -lm +windows : gcc main.c -lgdi32 +macos : gcc main.c -framework Cocoa -framework CoreVideo -framework IOKit #define RGFW_IMPLEMENTATION #include "RGFW.h" -u8 icon[4 * 3 * 3] = {0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF}; - int main() { - RGFW_window* win = RGFW_createWindow("name", 100, 100, 500, 500, (u64)0); - RGFW_event event; - - RGFW_window_setExitKey(win, RGFW_escape); - RGFW_window_setIcon(win, icon, 3, 3, RGFW_formatRGBA8); + RGFW_window* win = RGFW_createWindow("name", 100, 100, 500, 500, 0); while (RGFW_window_shouldClose(win) == RGFW_FALSE) { - while (RGFW_window_checkEvent(win, &event)) { - if (event.type == RGFW_quit) - break; - } + RGFW_pollEvents(); } RGFW_window_close(win); @@ -137,10 +132,6 @@ int main() { Credits : EimaMei/Sacode : Code review, helped with X11, MacOS and Windows support, Silicon, siliapp.h -> referencing - stb : This project is heavily inspired by the stb single header files - - SDL, GLFW and other online resources : reference implementations - contributors : (feel free to put yourself here if you contribute) krisvers (@krisvers) -> code review EimaMei (@SaCode) -> code review @@ -225,6 +216,18 @@ 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 #define RGFW_ASSERT assert @@ -235,25 +238,9 @@ int main() { #endif #if !defined(RGFW_SNPRINTF) && (defined(RGFW_X11) || defined(RGFW_WAYLAND)) - /* required for X11 errors */ #include - - #ifdef RGFW_C89 - #include - static int RGFW_c89_snprintf(char *dst, size_t size, const char *format, ...) { - va_list args; - size_t count = 0; - va_start(args, format); - count = (size_t)vsprintf(dst, format, args); - RGFW_ASSERT(count + 1 < size && "Buffer overflow"); - va_end(args); - return (int)count; - } - #define RGFW_SNPRINTF RGFW_c89_snprintf - #else - #define RGFW_SNPRINTF snprintf - #endif /*RGFW_C89*/ + #define RGFW_SNPRINTF snprintf #endif #ifndef RGFW_USERPTR @@ -282,12 +269,12 @@ int main() { #define RGFW_FREE free #endif -#if !defined(RGFW_MEMCPY) || !defined(RGFW_STRNCMP) || !defined(RGFW_STRNCPY) || !defined(RGFW_MEMSET) +#if !defined(RGFW_MEMCPY) || !defined(RGFW_STRNCMP) || !defined(RGFW_STRNCPY) || !defined(RGFW_MEMZERO) #include #endif -#ifndef RGFW_MEMSET - #define RGFW_MEMSET(ptr, value, num) memset(ptr, value, num) +#ifndef RGFW_MEMZERO + #define RGFW_MEMZERO(ptr, num) memset(ptr, 0, num) #endif #ifndef RGFW_MEMCPY @@ -319,19 +306,13 @@ int main() { #define RGFW_PRINTF printf #endif -#ifndef RGFW_MAX_PATH - #define RGFW_MAX_PATH 260 /* max length of a path (for drag andn drop) */ -#endif -#ifndef RGFW_MAX_DROPS - #define RGFW_MAX_DROPS 260 /* max items you can drop at once */ -#endif - #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 @@ -524,129 +505,129 @@ typedef void RGFW_mouse; /*! @brief RGFW's abstract keycodes */ typedef RGFW_ENUM(u8, RGFW_key) { RGFW_keyNULL = 0, - RGFW_escape = '\033', - RGFW_backtick = '`', - RGFW_0 = '0', - RGFW_1 = '1', - RGFW_2 = '2', - RGFW_3 = '3', - RGFW_4 = '4', - RGFW_5 = '5', - RGFW_6 = '6', - RGFW_7 = '7', - RGFW_8 = '8', - RGFW_9 = '9', - RGFW_minus = '-', - RGFW_equal = '=', - RGFW_equals = RGFW_equal, - RGFW_backSpace = '\b', - RGFW_tab = '\t', - RGFW_space = ' ', - RGFW_a = 'a', - RGFW_b = 'b', - RGFW_c = 'c', - RGFW_d = 'd', - RGFW_e = 'e', - RGFW_f = 'f', - RGFW_g = 'g', - RGFW_h = 'h', - RGFW_i = 'i', - RGFW_j = 'j', - RGFW_k = 'k', - RGFW_l = 'l', - RGFW_m = 'm', - RGFW_n = 'n', - RGFW_o = 'o', - RGFW_p = 'p', - RGFW_q = 'q', - RGFW_r = 'r', - RGFW_s = 's', - RGFW_t = 't', - RGFW_u = 'u', - RGFW_v = 'v', - RGFW_w = 'w', - RGFW_x = 'x', - RGFW_y = 'y', - RGFW_z = 'z', - RGFW_period = '.', - RGFW_comma = ',', - RGFW_slash = '/', - RGFW_bracket = '[', - RGFW_closeBracket = ']', - RGFW_semicolon = ';', - RGFW_apostrophe = '\'', - RGFW_backSlash = '\\', - RGFW_return = '\n', - RGFW_enter = RGFW_return, - RGFW_delete = '\177', /* 127 */ - RGFW_F1, - RGFW_F2, - RGFW_F3, - RGFW_F4, - RGFW_F5, - RGFW_F6, - RGFW_F7, - RGFW_F8, - RGFW_F9, - RGFW_F10, - RGFW_F11, - RGFW_F12, - RGFW_F13, - RGFW_F14, - RGFW_F15, - RGFW_F16, - RGFW_F17, - RGFW_F18, - RGFW_F19, - RGFW_F20, - RGFW_F21, - RGFW_F22, - RGFW_F23, - RGFW_F24, - RGFW_F25, - RGFW_capsLock, - RGFW_shiftL, - RGFW_controlL, - RGFW_altL, - RGFW_superL, - RGFW_shiftR, - RGFW_controlR, - RGFW_altR, - RGFW_superR, - RGFW_up, - RGFW_down, - RGFW_left, - RGFW_right, - RGFW_insert, - RGFW_menu, - RGFW_end, - RGFW_home, - RGFW_pageUp, - RGFW_pageDown, - RGFW_numLock, - RGFW_kpSlash, - RGFW_kpMultiply, - RGFW_kpPlus, - RGFW_kpMinus, - RGFW_kpEqual, - RGFW_kpEquals = RGFW_kpEqual, - RGFW_kp1, - RGFW_kp2, - RGFW_kp3, - RGFW_kp4, - RGFW_kp5, - RGFW_kp6, - RGFW_kp7, - RGFW_kp8, - RGFW_kp9, - RGFW_kp0, - RGFW_kpPeriod, - RGFW_kpReturn, - RGFW_scrollLock, - RGFW_printScreen, - RGFW_pause, - RGFW_world1, - RGFW_world2, + RGFW_keyEscape = '\033', + RGFW_keyBacktick = '`', + RGFW_key0 = '0', + RGFW_key1 = '1', + RGFW_key2 = '2', + RGFW_key3 = '3', + RGFW_key4 = '4', + RGFW_key5 = '5', + RGFW_key6 = '6', + RGFW_key7 = '7', + RGFW_key8 = '8', + RGFW_key9 = '9', + RGFW_keyMinus = '-', + RGFW_keyEqual = '=', + RGFW_keyEquals = RGFW_keyEqual, + RGFW_keyBackSpace = '\b', + RGFW_keyTab = '\t', + RGFW_keySpace = ' ', + RGFW_keyA = 'a', + RGFW_keyB = 'b', + RGFW_keyC = 'c', + RGFW_keyD = 'd', + RGFW_keyE = 'e', + RGFW_keyF = 'f', + RGFW_keyG = 'g', + RGFW_keyH = 'h', + RGFW_keyI = 'i', + RGFW_keyJ = 'j', + RGFW_keyK = 'k', + RGFW_keyL = 'l', + RGFW_keyM = 'm', + RGFW_keyN = 'n', + RGFW_keyO = 'o', + RGFW_keyP = 'p', + RGFW_keyQ = 'q', + RGFW_keyR = 'r', + RGFW_keyS = 's', + RGFW_keyT = 't', + RGFW_keyU = 'u', + RGFW_keyV = 'v', + RGFW_keyW = 'w', + RGFW_keyX = 'x', + RGFW_keyY = 'y', + RGFW_keyZ = 'z', + RGFW_keyPeriod = '.', + RGFW_keyComma = ',', + RGFW_keySlash = '/', + RGFW_keyBracket = '[', + RGFW_keyCloseBracket = ']', + RGFW_keySemicolon = ';', + RGFW_keyApostrophe = '\'', + RGFW_keyBackSlash = '\\', + RGFW_keyReturn = '\n', + RGFW_keyEnter = RGFW_keyReturn, + RGFW_keyDelete = '\177', /* 127 */ + RGFW_keyF1, + RGFW_keyF2, + RGFW_keyF3, + RGFW_keyF4, + RGFW_keyF5, + RGFW_keyF6, + RGFW_keyF7, + RGFW_keyF8, + RGFW_keyF9, + RGFW_keyF10, + RGFW_keyF11, + RGFW_keyF12, + RGFW_keyF13, + RGFW_keyF14, + RGFW_keyF15, + RGFW_keyF16, + RGFW_keyF17, + RGFW_keyF18, + RGFW_keyF19, + RGFW_keyF20, + RGFW_keyF21, + RGFW_keyF22, + RGFW_keyF23, + RGFW_keyF24, + RGFW_keyF25, + RGFW_keyCapsLock, + RGFW_keyShiftL, + RGFW_keyControlL, + RGFW_keyAltL, + RGFW_keySuperL, + RGFW_keyShiftR, + RGFW_keyControlR, + RGFW_keyAltR, + RGFW_keySuperR, + RGFW_keyUp, + RGFW_keyDown, + RGFW_keyLeft, + RGFW_keyRight, + RGFW_keyInsert, + RGFW_keyMenu, + RGFW_keyEnd, + RGFW_keyHome, + RGFW_keyPageUp, + RGFW_keyPageDown, + RGFW_keyNumLock, + RGFW_keyPadSlash, + RGFW_keyPadMultiply, + RGFW_keyPadPlus, + RGFW_keyPadMinus, + RGFW_keyPadEqual, + RGFW_keyPadEquals = RGFW_keyPadEqual, + RGFW_keyPad1, + RGFW_keyPad2, + RGFW_keyPad3, + RGFW_keyPad4, + RGFW_keyPad5, + RGFW_keyPad6, + RGFW_keyPad7, + RGFW_keyPad8, + RGFW_keyPad9, + RGFW_keyPad0, + RGFW_keyPadPeriod, + RGFW_keyPadReturn, + RGFW_keyScrollLock, + RGFW_keyPrintScreen, + RGFW_keyPause, + RGFW_keyWorld1, + RGFW_keyWorld2, RGFW_keyLast = 256 /* padding for alignment ~(175 by default) */ }; @@ -670,6 +651,32 @@ typedef RGFW_ENUM(u8, RGFW_keymod) { RGFW_modScrollLock = RGFW_BIT(6) }; +/*! types of dnd drag actions */ +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 */ +}; + +/*! types of transfered data (clipboard, dnd) */ +typedef RGFW_ENUM(u8, RGFW_dataTransferType) { + RGFW_dataNone = 0, + RGFW_dataText, /*!< plain text string */ + RGFW_dataFile, /*!< file string */ + RGFW_dataURL, /*!< URL string */ + RGFW_dataImage, /*!< raw image data */ + RGFW_dataUnknown /*!< unknown raw data */ +}; + +/*! 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 */ + 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; + /*! @brief codes for the event types that can be sent */ typedef RGFW_ENUM(u8, RGFW_eventType) { RGFW_eventNone = 0, /*!< no event has been sent */ @@ -679,44 +686,29 @@ 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 */ - /*! mouse event note - the x and y of the mouse can be found in the vector, RGFW_x, y - - RGFW_event.button.value holds which mouse button was pressed - */ + 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 */ RGFW_windowMoved, /*!< the window was moved (by the user) */ RGFW_windowResized, /*!< the window was resized (by the user), [on WASM this means the browser was resized] */ - RGFW_focusIn, /*!< window is in focus now */ - RGFW_focusOut, /*!< window is out of focus now */ - RGFW_mouseEnter, /* mouse entered the window */ - RGFW_mouseLeave, /* mouse left the window */ - RGFW_windowRefresh, /* The window content needs to be refreshed */ - - /* attribs change event note - The event data is sent straight to the window structure - with win->x, win->y, win->w and win->h - */ - RGFW_quit, /*!< the user clicked the quit button */ - RGFW_dataDrop, /*!< a file has been dropped into the window */ - RGFW_dataDrag, /*!< the start of a drag and drop event, when the file is being dragged */ - /* drop data note - The x and y coords of the drop are stored in the vector RGFW_x, y - - RGFW_event.drop.count holds how many files were dropped - - This is also the size of the array which stores all the dropped file string, - RGFW_event.drop.files - */ + RGFW_windowFocusIn, /*!< window is in focus now */ + RGFW_windowFocusOut, /*!< window is out of focus now */ + RGFW_windowRefresh, /*!< The window content needs to be refreshed */ + RGFW_windowClose, /*!< the user attempts to close the window */ RGFW_windowMaximized, /*!< the window was maximized */ RGFW_windowMinimized, /*!< the window was minimized */ RGFW_windowRestored, /*!< the window was restored */ + RGFW_dataDrop, /*!< data has been dropped into the window */ + RGFW_dataDrag, /*!< the start of a drag and drop event, when data is being dragged */ RGFW_scaleUpdated, /*!< content scale factor changed */ RGFW_monitorConnected, /*!< a monitor has been connected */ - RGFW_monitorDisconnected /*!< a monitor has been disconnected */ + RGFW_monitorDisconnected, /*!< a monitor has been disconnected */ + 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 wether or not an event should be processed */ +/*! @brief flags for toggling whether or not an event should be processed */ typedef RGFW_ENUM(u32, RGFW_eventFlag) { RGFW_keyPressedFlag = RGFW_BIT(RGFW_keyPressed), RGFW_keyReleasedFlag = RGFW_BIT(RGFW_keyReleased), @@ -724,31 +716,33 @@ 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), RGFW_windowMovedFlag = RGFW_BIT(RGFW_windowMoved), RGFW_windowResizedFlag = RGFW_BIT(RGFW_windowResized), - RGFW_focusInFlag = RGFW_BIT(RGFW_focusIn), - RGFW_focusOutFlag = RGFW_BIT(RGFW_focusOut), + RGFW_windowFocusInFlag = RGFW_BIT(RGFW_windowFocusIn), + RGFW_windowFocusOutFlag = RGFW_BIT(RGFW_windowFocusOut), RGFW_windowRefreshFlag = RGFW_BIT(RGFW_windowRefresh), RGFW_windowMaximizedFlag = RGFW_BIT(RGFW_windowMaximized), RGFW_windowMinimizedFlag = RGFW_BIT(RGFW_windowMinimized), RGFW_windowRestoredFlag = RGFW_BIT(RGFW_windowRestored), RGFW_scaleUpdatedFlag = RGFW_BIT(RGFW_scaleUpdated), - RGFW_quitFlag = RGFW_BIT(RGFW_quit), + RGFW_windowCloseFlag = RGFW_BIT(RGFW_windowClose), RGFW_dataDropFlag = RGFW_BIT(RGFW_dataDrop), 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_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_focusEventsFlag = RGFW_focusInFlag | RGFW_focusOutFlag, - RGFW_dataDropEventsFlag = RGFW_dataDropFlag | RGFW_dataDragFlag, + RGFW_windowFocusEventsFlag = RGFW_windowFocusInFlag | RGFW_windowFocusOutFlag, + RGFW_dataDragDropEventsFlag = RGFW_dataDropFlag | RGFW_dataDragFlag, RGFW_monitorEventsFlag = RGFW_monitorConnectedFlag | RGFW_monitorDisconnectedFlag, - RGFW_allEventFlags = RGFW_keyEventsFlag | RGFW_mouseEventsFlag | RGFW_windowEventsFlag | RGFW_focusEventsFlag | RGFW_dataDropEventsFlag | RGFW_quitFlag | RGFW_monitorEventsFlag + RGFW_allEventFlags = RGFW_keyEventsFlag | RGFW_mouseEventsFlag | RGFW_windowEventsFlag | RGFW_windowFocusEventsFlag | RGFW_dataDragDropEventsFlag | RGFW_windowCloseFlag | RGFW_monitorEventsFlag }; /*! Event structure(s) and union for checking/getting events */ @@ -759,27 +753,35 @@ typedef struct RGFW_commonEvent { RGFW_window* win; /*!< the window this event applies to (for event queue events) */ } RGFW_commonEvent; +/*! @brief event data for all focus events */ +typedef struct RGFW_windowFocusEvent { + RGFW_eventType type; /*!< which event has been sent?*/ + RGFW_window* win; /*!< the window this event applies to (for event queue events) */ + RGFW_bool state; /*!< wether or not the window is in focus or not */ +} RGFW_windowFocusEvent; + /*! @brief event data for any mouse button event (press/release) */ typedef struct RGFW_mouseButtonEvent { RGFW_eventType type; /*!< which event has been sent?*/ RGFW_window* win; /*!< the window this event applies to (for event queue events) */ RGFW_mouseButton value; /* !< which mouse button was pressed */ + RGFW_bool state; /*!< if the button was pressed or released */ } RGFW_mouseButtonEvent; -/*! @brief event data for any mouse scroll event */ -typedef struct RGFW_mouseScrollEvent { +/*! @brief event data for any mouse scroll or raw motion event */ +typedef struct RGFW_mouseDeltaEvent { RGFW_eventType type; /*!< which event has been sent?*/ RGFW_window* win; /*!< the window this event applies to (for event queue events) */ - float x, y; /*!< the raw mouse scroll value */ -} RGFW_mouseScrollEvent; + float x, y; /*!< the raw mouse scroll or motion delta value */ +} RGFW_mouseDeltaEvent; -/*! @brief event data for any 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) */ - float vecX, vecY; /*!< raw mouse movement */ -} RGFW_mousePosEvent; + RGFW_bool inWindow; /*!< if the mouse is in the window or not */ +} RGFW_mouseMotionEvent; /*! @brief event data for a key press/release event */ typedef struct RGFW_keyEvent { @@ -787,7 +789,8 @@ typedef struct RGFW_keyEvent { RGFW_window* win; /*!< the window this event applies to (for event queue events) */ RGFW_key value; /*!< the physical key of the event, refers to where key is physically */ RGFW_bool repeat; /*!< key press event repeated (the key is being held) */ - RGFW_keymod mod; + RGFW_keymod mod; /*!< state of the key modifier state */ + RGFW_bool state; /*!< if the key was pressed or released */ } RGFW_keyEvent; /*! @brief event data for a key character event */ @@ -801,9 +804,7 @@ typedef struct RGFW_keyCharEvent { typedef struct RGFW_dataDropEvent { RGFW_eventType type; /*!< which event has been sent?*/ RGFW_window* win; /*!< the window this event applies to (for event queue events) */ - /* 260 max paths with a max length of 260 */ - char** files; /*!< dropped files */ - size_t count; /*!< how many files were dropped */ + const RGFW_dataDropNode* value; } RGFW_dataDropEvent; /*! @brief event data for any data drag event */ @@ -811,6 +812,8 @@ typedef struct RGFW_dataDragEvent { 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_dndActionType action; /*!< the type of drag action, e.g. enter, leave, move */ + RGFW_dataTransferType dataType; /*!< the type of data being dragged*/ } RGFW_dataDragEvent; /*! @brief event data for when the window scale (DPI) is updated */ @@ -825,19 +828,32 @@ typedef struct RGFW_monitorEvent { RGFW_eventType type; /*!< which event has been sent?*/ RGFW_window* win; /*!< the window this event applies to (for event queue events) */ const RGFW_monitor* monitor; /*!< the monitor that this event applies to */ + RGFW_bool state; /*!< if the monitor is connected or disconnected */ } RGFW_monitorEvent; +/*! @breif event data for when the window is updated, moved, resized or refreshed */ +typedef struct RGFW_windowUpdateEvent { + RGFW_eventType type; /*!< the specific event type */ + RGFW_window* win; /*!< the window that was updated */ + i32 x; /*!< the new window x OR the x of the rectanglular refresh area */ + i32 y; /*!< the new window y OR the y of the rectanglular refresh area */ + i32 w; /*!< the new window width OR the width of the rectanglular refresh area */ + i32 h; /*!< the new window height OR the height of the rectanglular refresh area */ +} RGFW_windowUpdateEvent; + /*! @brief union for all of the event stucture types */ typedef union RGFW_event { RGFW_eventType type; /*!< which event has been sent?*/ RGFW_commonEvent common; /*!< common event data (e.g.) type and win */ + RGFW_windowFocusEvent focus; /*!< event data for focus in/out events */ + RGFW_windowUpdateEvent update; /*!< data for window update/move/resize/refresh events */ RGFW_mouseButtonEvent button; /*!< data for a button press/release */ - RGFW_mouseScrollEvent scroll; /*!< data for a mouse scroll */ - RGFW_mousePosEvent mouse; /*!< data for mouse motion events */ + RGFW_mouseDeltaEvent delta; /*!< data for a mouse scroll or raw motion */ + 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; /*!< dropping a file events */ - RGFW_dataDragEvent drag; /*!< data for dragging a file events */ + RGFW_dataDropEvent drop; /*!< data dropping events */ + RGFW_dataDragEvent drag; /*!< data for data dragging events */ RGFW_scaleUpdatedEvent scale; /*!< data for dpi scaling update events */ RGFW_monitorEvent monitor; /*!< data for monitor events */ } RGFW_event; @@ -854,14 +870,23 @@ typedef RGFW_ENUM(i32, RGFW_eventWait) { RGFW_eventWaitNext = -1 }; +/*! @brief generic event callback function type */ +typedef void (*RGFW_genericFunc)(const RGFW_event* e); + +/*! brief structure that holds an array to callback data*/ +typedef struct RGFW_callbacks { + RGFW_genericFunc arr[RGFW_eventCount]; /*!< an array of all the callbacks */ +} RGFW_callbacks; + /*! @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 */ + 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_windowTransparent = RGFW_BIT(5), /*!< the window is transparent (only properly works on X11 and MacOS, although it's meant for for windows) */ + 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 */ RGFW_windowRawMouse = RGFW_BIT(7), /*!< use raw mouse mouse on window creation */ RGFW_windowScaleToMonitor = RGFW_BIT(8), /*! scale the window to the screen */ @@ -888,7 +913,7 @@ typedef RGFW_ENUM(u8, RGFW_icon) { }; /*! @brief standard mouse icons */ -typedef RGFW_ENUM(u8, RGFW_mouseIcons) { +typedef RGFW_ENUM(u8, RGFW_mouseIcon) { RGFW_mouseNormal = 0, RGFW_mouseArrow, RGFW_mouseIbeam, @@ -945,47 +970,15 @@ typedef RGFW_ENUM(u8, RGFW_errorCode) { RGFW_warningWayland, RGFW_warningOpenGL }; +/*! @brief data for debug messages */ +typedef struct RGFW_debugInfo { + RGFW_debugType type; /*!< the type of message */ + RGFW_errorCode code; /*!< the code for the specific type of debug message */ + const char* msg; /*!< string message */ +} RGFW_debugInfo; + /*! @brief callback function type for debug messags */ -typedef void (* RGFW_debugfunc)(RGFW_debugType type, RGFW_errorCode err, const char* msg); - -/*! @brief RGFW_windowMoved, the window and its new rect value */ -typedef void (* RGFW_windowMovedfunc)(RGFW_window* win, i32 x, i32 y); -/*! @brief RGFW_windowResized, the window and its new rect value */ -typedef void (* RGFW_windowResizedfunc)(RGFW_window* win, i32 w, i32 h); -/*! @brief RGFW_windowRestored, the window and its new rect value */ -typedef void (* RGFW_windowRestoredfunc)(RGFW_window* win, i32 x, i32 y, i32 w, i32 h); -/*! @brief RGFW_windowMaximized, the window and its new rect value */ -typedef void (* RGFW_windowMaximizedfunc)(RGFW_window* win, i32 x, i32 y, i32 w, i32 h); -/*! @brief RGFW_windowMinimized, the window and its new rect value */ -typedef void (* RGFW_windowMinimizedfunc)(RGFW_window* win); -/*! @brief RGFW_quit, the window that was closed */ -typedef void (* RGFW_windowQuitfunc)(RGFW_window* win); -/*! @brief RGFW_focusIn / RGFW_focusOut, the window who's focus has changed and if its in focus */ -typedef void (* RGFW_focusfunc)(RGFW_window* win, RGFW_bool inFocus); -/*! @brief RGFW_mouseEnter / RGFW_mouseLeave, the window that changed, the point of the mouse (enter only) and if the mouse has entered */ -typedef void (* RGFW_mouseNotifyfunc)(RGFW_window* win, i32 x, i32 y, RGFW_bool status); -/*! @brief RGFW_mousePosChanged, the window that the move happened on, and the new point of the mouse */ -typedef void (* RGFW_mousePosfunc)(RGFW_window* win, i32 x, i32 y, float vecX, float vecY); -/*! @brief RGFW_dataDrag, the window, the point of the drop on the windows */ -typedef void (* RGFW_dataDragfunc)(RGFW_window* win, i32 x, i32 y); -/*! @brief RGFW_windowRefresh, the window that needs to be refreshed */ -typedef void (* RGFW_windowRefreshfunc)(RGFW_window* win); -/*! @brief RGFW_keyChar, the window that got the event, the unicode key value */ -typedef void (* RGFW_keyCharfunc)(RGFW_window* win, u32 codepoint); -/*! @brief RGFW_mouseButtonPressed / RGFW_mouseButtonReleased, the window that got the event, the button that was pressed, the scroll value, if it was a press (else it's a release) */ - -/*! @brief RGFW_keyPressed / RGFW_keyReleased, the window that got the event, the mapped key, the physical key, the string version, the state of the mod keys, if it was a press (else it's a release) */ -typedef void (* RGFW_keyfunc)(RGFW_window* win, u8 key, RGFW_keymod mod, RGFW_bool repeat, RGFW_bool pressed); -/*! @brief RGFW_mouseButtonPressed / RGFW_mouseButtonReleased, the window that got the event, the button that was pressed, the scroll value, if it was a press (else it's a release) */ -typedef void (* RGFW_mouseButtonfunc)(RGFW_window* win, RGFW_mouseButton button, RGFW_bool pressed); -/*! @brief RGFW_mouseScroll, the window that got the event, the x scroll value, the y scroll value */ -typedef void (* RGFW_mouseScrollfunc)(RGFW_window* win, float x, float y); -/*! @brief RGFW_dataDrop the window that had the drop, the drop data and the number of files dropped */ -typedef void (* RGFW_dataDropfunc)(RGFW_window* win, char** files, size_t count); -/*! @brief RGFW_scaleUpdated, the window the event was sent to, content scaleX, content scaleY */ -typedef void (* RGFW_scaleUpdatedfunc)(RGFW_window* win, float scaleX, float scaleY); -/*! @brief RGFW_monitorConnected / RGFW_monitorDisconnected, there was a monitor connected/disconnected */ -typedef void (* RGFW_monitorfunc)(RGFW_window* win, const RGFW_monitor* monitor, RGFW_bool connected); +typedef void (* RGFW_debugFunc)(const RGFW_debugInfo* info); /*! @brief function pointer equivalent of void* */ typedef void (*RGFW_proc)(void); @@ -1009,7 +1002,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 */ @@ -1188,7 +1182,7 @@ RGFWDEF void RGFW_surface_freePtr(RGFW_surface* surface); /**! - * @brief Loads a mouse icon from bitmap data (similar to RGFW_window_setIcon). + * @brief create a mouse icon from bitmap data (similar to RGFW_window_setIcon). * @param data A pointer to the bitmap pixel data. * @param w The width of the mouse icon in pixels. * @param h The height of the mouse icon in pixels. @@ -1197,7 +1191,14 @@ RGFWDEF void RGFW_surface_freePtr(RGFW_surface* surface); * * @note The icon is not resized by default. */ -RGFWDEF RGFW_mouse* RGFW_loadMouse(u8* data, i32 w, i32 h, RGFW_format format); +RGFWDEF RGFW_mouse* RGFW_createMouse(u8* data, i32 w, i32 h, RGFW_format format); + +/**! + * @brief create a standard mouse icon + * @param mouse The standard cursor type (see RGFW_MOUSE enum). + * @return A pointer to the newly loaded RGFW_mouse structure. +*/ +RGFWDEF RGFW_mouse* RGFW_createMouseStandard(RGFW_mouseIcon mouse); /**! * @brief Frees the data associated with an RGFW_mouse structure. @@ -1355,12 +1356,21 @@ 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 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. @@ -1409,6 +1419,13 @@ RGFWDEF RGFW_bool RGFW_monitor_scaleToWindow(RGFW_monitor* mon, struct RGFW_wind */ RGFWDEF void RGFW_setRawMouseMode(RGFW_bool state); +/**! + * @brief toggles building the drag-and-drop (DND) linked list + * @param allow RGFW_TRUE to allow DND building, RGFW_FALSE to disable + * @note this is for state checking, the list is created by default if you are using the event queue +*/ +RGFWDEF void RGFW_setBuildDND(RGFW_bool allow); + /**! * @brief sleep until RGFW gets an event or the timer ends (defined by OS) * @param waitMS how long to wait for the next event (in miliseconds) @@ -1421,6 +1438,29 @@ RGFWDEF void RGFW_waitForEvent(i32 waitMS); */ RGFWDEF void RGFW_setQueueEvents(RGFW_bool queue); +/**! + * @brief Sets the callback function for the event. + * @param the event type for the callback + * @param func The function to be called when the event is triggered. + * @return The previously set callback function, if any. +*/ +RGFWDEF RGFW_genericFunc RGFW_setEventCallback(RGFW_eventType type, RGFW_genericFunc func); + +/**! + * @brief Sets the callback function for two continuous events. + * @param func The function to be called when the event is triggered. + * @param [OUTPUT] The previously set callback function for the first event, if any. + * @param [OUTPUT] The previously set callback function for the second event, if any. +*/ +RGFWDEF void RGFW_setDualEventCallback(RGFW_eventType type, RGFW_genericFunc func, RGFW_genericFunc* first, RGFW_genericFunc* second); + +/**! + * @brief Sets the callback function for all events. + * @param func The function to be called when the event is triggered. + * @param [OUTPUT] a structure that holds an array of all the event callbacks +*/ +RGFWDEF void RGFW_setAllEventCallbacks(RGFW_genericFunc func, RGFW_callbacks* callbacks); + /**! * @brief check all the events until there are none left and updates window structure attributes */ @@ -1853,13 +1893,11 @@ RGFWDEF RGFW_bool RGFW_window_getDataDrag(RGFW_window* win, i32* x, i32* y); RGFWDEF RGFW_bool RGFW_window_didDataDrop(RGFW_window* win); /**! - * @brief retrieves files 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 - * @param files [OUTPUT] a pointer to the array of file paths - * @param count [OUTPUT] the number of dropped files - * @return RGFW_TRUE if a data drop occurred, RGFW_FALSE otherwise + * @return a valid pointer to the root drag node if a data drop occurred, NULL otherwise */ -RGFWDEF RGFW_bool RGFW_window_getDataDrop(RGFW_window* win, const char*** files, size_t* count); +RGFWDEF RGFW_dataDropNode* RGFW_window_getDataDrop(RGFW_window* win); /**! * @brief closes the window and frees its associated structure @@ -1873,6 +1911,15 @@ RGFWDEF void RGFW_window_close(RGFW_window* win); */ RGFWDEF void RGFW_window_closePtr(RGFW_window* win); +/**! + * @brief fetches the size of the window through the OS (and updates the internal values) + * @param win a pointer to the window + * @param w [OUTPUT] the width of the window + * @param h [OUTPUT] the height of the window + * @return a bool if the function was successful +*/ +RGFWDEF RGFW_bool RGFW_window_fetchSize(RGFW_window* win, i32* w, i32* h); + /**! * @brief moves the window to a new position on the screen * @param win a pointer to the target window @@ -1985,14 +2032,14 @@ RGFWDEF void RGFW_window_setFloating(RGFW_window* win, RGFW_bool floating); RGFWDEF void RGFW_window_setOpacity(RGFW_window* win, u8 opacity); /**! - * @brief toggles window borders + * @brief toggles window borders / frame / decor * @param win a pointer to the target window * @param border RGFW_TRUE for bordered, RGFW_FALSE for borderless */ RGFWDEF void RGFW_window_setBorder(RGFW_window* win, RGFW_bool border); /**! - * @brief checks if the window is borderless + * @brief checks if the window is borderless (has a border, frame or decor) * @param win a pointer to the target window * @return RGFW_TRUE if borderless, RGFW_FALSE otherwise */ @@ -2055,19 +2102,19 @@ RGFWDEF RGFW_bool RGFW_window_setIcon(RGFW_window* win, u8* data, i32 w, i32 h, RGFWDEF RGFW_bool RGFW_window_setIconEx(RGFW_window* win, u8* data, i32 w, i32 h, RGFW_format format, RGFW_icon type); /**! - * @brief sets the mouse icon for the window using a loaded bitmap + * @brief sets the mouse icon for the window using a loaded mouse icon * @param win a pointer to the target window * @param mouse a pointer to the RGFW_mouse struct containing the icon */ -RGFWDEF void RGFW_window_setMouse(RGFW_window* win, RGFW_mouse* mouse); +RGFWDEF RGFW_bool RGFW_window_setMouse(RGFW_window* win, RGFW_mouse* mouse); /**! - * @brief Sets the mouse to a standard system cursor. + * @brief Sets the mouse to a preloaded [by RGFW] standard system cursor. * @param win The target window. - * @param mouse The standard cursor type (see RGFW_MOUSE enum). + * @param mouse The standardmouse icon (see RGFW_mouseIcon enum). * @return True if the standard cursor was successfully applied. */ -RGFWDEF RGFW_bool RGFW_window_setMouseStandard(RGFW_window* win, RGFW_mouseIcons mouse); +RGFWDEF RGFW_bool RGFW_window_setMouseStandard(RGFW_window* win, RGFW_mouseIcon icon); /**! * @brief Sets the mouse to the default cursor icon. @@ -2281,7 +2328,7 @@ RGFWDEF void RGFW_writeClipboard(const char* text, u32 textLen); * @param func The function pointer to be used as the debug callback. * @return The previously set debug callback function. */ -RGFWDEF RGFW_debugfunc RGFW_setDebugCallback(RGFW_debugfunc func); +RGFWDEF RGFW_debugFunc RGFW_setDebugCallback(RGFW_debugFunc func); /**! * @brief Sends a debug message manually through the currently set debug callback. @@ -2289,146 +2336,7 @@ RGFWDEF RGFW_debugfunc RGFW_setDebugCallback(RGFW_debugfunc func); * @param err The associated error code. * @param msg The debug message text. */ -RGFWDEF void RGFW_sendDebugInfo(RGFW_debugType type, RGFW_errorCode err, const char* msg); -/** @} */ - -/** - - - event callbacks. - These are completely optional, so you can use the normal - RGFW_checkEvent() method if you prefer that - -* @defgroup Callbacks -* @{ -*/ - -/**! - * @brief Sets the callback function for window move events. - * @param func The function to be called when the window is moved. - * @return The previously set callback function, if any. -*/ -RGFWDEF RGFW_windowMovedfunc RGFW_setWindowMovedCallback(RGFW_windowMovedfunc func); - -/**! - * @brief Sets the callback function for window resize events. - * @param func The function to be called when the window is resized. - * @return The previously set callback function, if any. -*/ -RGFWDEF RGFW_windowResizedfunc RGFW_setWindowResizedCallback(RGFW_windowResizedfunc func); - -/**! - * @brief Sets the callback function for window quit events. - * @param func The function to be called when the window receives a quit signal. - * @return The previously set callback function, if any. -*/ -RGFWDEF RGFW_windowQuitfunc RGFW_setWindowQuitCallback(RGFW_windowQuitfunc func); - -/**! - * @brief Sets the callback function for mouse move events. - * @param func The function to be called when the mouse moves within the window. - * @return The previously set callback function, if any. -*/ -RGFWDEF RGFW_mousePosfunc RGFW_setMousePosCallback(RGFW_mousePosfunc func); - -/**! - * @brief Sets the callback function for window refresh events. - * @param func The function to be called when the window needs to be refreshed. - * @return The previously set callback function, if any. -*/ -RGFWDEF RGFW_windowRefreshfunc RGFW_setWindowRefreshCallback(RGFW_windowRefreshfunc func); - -/**! - * @brief Sets the callback function for focus change events. - * @param func The function to be called when the window gains or loses focus. - * @return The previously set callback function, if any. -*/ -RGFWDEF RGFW_focusfunc RGFW_setFocusCallback(RGFW_focusfunc func); - -/**! - * @brief Sets the callback function for mouse notification events. - * @param func The function to be called when a mouse notification event occurs. - * @return The previously set callback function, if any. -*/ -RGFWDEF RGFW_mouseNotifyfunc RGFW_setMouseNotifyCallback(RGFW_mouseNotifyfunc func); - -/**! - * @brief Sets the callback function for data drop events. - * @param func The function to be called when data is dropped into the window. - * @return The previously set callback function, if any. -*/ -RGFWDEF RGFW_dataDropfunc RGFW_setDataDropCallback(RGFW_dataDropfunc func); - -/**! - * @brief Sets the callback function for the start of a data drag event. - * @param func The function to be called when data dragging begins. - * @return The previously set callback function, if any. -*/ -RGFWDEF RGFW_dataDragfunc RGFW_setDataDragCallback(RGFW_dataDragfunc func); - -/**! - * @brief Sets the callback function for key press and release events. - * @param func The function to be called when a key is pressed or released. - * @return The previously set callback function, if any. -*/ -RGFWDEF RGFW_keyfunc RGFW_setKeyCallback(RGFW_keyfunc func); - -/**! - * @brief Sets the callback function for key character events. - * @param func The function to be called when a key is pressed or released. - * @return The previously set callback function, if any. -*/ -RGFWDEF RGFW_keyCharfunc RGFW_setKeyCharCallback(RGFW_keyCharfunc func); - -/**! - * @brief Sets the callback function for mouse button press and release events. - * @param func The function to be called when a mouse button is pressed or released. - * @return The previously set callback function, if any. -*/ -RGFWDEF RGFW_mouseButtonfunc RGFW_setMouseButtonCallback(RGFW_mouseButtonfunc func); - -/**! - * @brief Sets the callback function for mouse scroll events. - * @param func The function to be called when the mouse wheel is scrolled. - * @return The previously set callback function, if any. -*/ -RGFWDEF RGFW_mouseScrollfunc RGFW_setMouseScrollCallback(RGFW_mouseScrollfunc func); - -/**! - * @brief Sets the callback function for window maximize events. - * @param func The function to be called when the window is maximized. - * @return The previously set callback function, if any. -*/ -RGFWDEF RGFW_windowMaximizedfunc RGFW_setWindowMaximizedCallback(RGFW_windowMaximizedfunc func); - -/**! - * @brief Sets the callback function for window minimize events. - * @param func The function to be called when the window is minimized. - * @return The previously set callback function, if any. -*/ -RGFWDEF RGFW_windowMinimizedfunc RGFW_setWindowMinimizedCallback(RGFW_windowMinimizedfunc func); - -/**! - * @brief Sets the callback function for window restore events. - * @param func The function to be called when the window is restored from a minimized or maximized state. - * @return The previously set callback function, if any. -*/ -RGFWDEF RGFW_windowRestoredfunc RGFW_setWindowRestoredCallback(RGFW_windowRestoredfunc func); - -/**! - * @brief Sets the callback function for DPI (scale) update events. - * @param func The function to be called when the window’s DPI or scale changes. - * @return The previously set callback function, if any. -*/ -RGFWDEF RGFW_scaleUpdatedfunc RGFW_setScaleUpdatedCallback(RGFW_scaleUpdatedfunc func); - -/**! - * @brief Sets the callback function for monitor connected and disconnect events. - * @param func The function to be called when a monitor is connected or disconnected. - * @return The previously set callback function, if any. -*/ -RGFWDEF RGFW_monitorfunc RGFW_setMonitorCallback(RGFW_monitorfunc func); - +RGFWDEF void RGFW_debugCallback(RGFW_debugType type, RGFW_errorCode code, const char* msg); /** @} */ /** * @defgroup graphics_API @@ -2718,7 +2626,9 @@ RGFWDEF RGFW_bool RGFW_extensionSupportedPlatform_EGL(const char* extension, siz #endif #ifdef RGFW_VULKAN -#include +#ifndef RGFW_NO_INCLUDE_VULKAN + #include +#endif /* if you don't want to use the above macros */ @@ -2804,6 +2714,12 @@ RGFWDEF RGFW_window* RGFW_getRootWindow(void); */ RGFWDEF void RGFW_eventQueuePush(const RGFW_event* event); +/**! + * @brief Pushes an event into the standard RGFW event queue and call the callback. + * @param event A pointer to the RGFW_event to be added to the queue. +*/ +RGFWDEF void RGFW_eventQueuePushAndCall(const RGFW_event* event); + /**! * @brief Clears all events from the RGFW event queue without processing them. */ @@ -2850,14 +2766,14 @@ RGFWDEF RGFW_key RGFW_physicalToMappedKey(RGFW_key keycode); RGFWDEF size_t RGFW_sizeofInfo(void); /**! - * @brief Initializes the RGFW library. - * @return 0 on success, or a negative error code on failure. + * @brief Initializes the RGFW library internally. + * @return 0 on success, a negative number error error on failure. * @note This is automatically called when the first window is created. */ RGFWDEF i32 RGFW_init(void); /**! - * @brief Deinitializes the RGFW library. + * @brief Deinitializes the current instance of the RGFW library. * @note This is automatically called when the last open window is closed. */ RGFWDEF void RGFW_deinit(void); @@ -2865,7 +2781,7 @@ 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. + * @return 0 on success, a negative number error error on failure and a positive number for a warning. */ RGFWDEF i32 RGFW_init_ptr(RGFW_info* info); @@ -2956,9 +2872,11 @@ RGFWDEF RGFW_info* RGFW_getInfo(void); #include #include - #ifndef RGFW_NO_XRANDR - #include - #include + #include + #include + + #ifndef RGFW_XDND_VERSION + #define RGFW_XDND_VERSION 5 #endif #endif @@ -3118,6 +3036,8 @@ 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_mouse* mouse; } RGFW_windowInternal; struct RGFW_window { @@ -3131,7 +3051,7 @@ typedef struct RGFW_windowState { RGFW_bool mouseEnter; RGFW_bool dataDragging; RGFW_bool dataDrop; - size_t filesCount; + size_t dataSize; 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 */ @@ -3155,7 +3075,7 @@ struct RGFW_monitorNode { RGFW_monitorMode* modes; size_t modeCount; #endif -#if defined(RGFW_X11) && !defined(RGFW_NO_XRANDR) +#if defined(RGFW_X11) i32 screen; RROutput rrOutput; RRCrtc crtc; @@ -3179,22 +3099,24 @@ 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; i32 windowCount; RGFW_mouse* hiddenMouse; + RGFW_mouse* standardMice[RGFW_mouseIconCount]; + RGFW_debugFunc debugCallbackSrc; + RGFW_genericFunc callbacks[RGFW_eventCount]; RGFW_event events[RGFW_MAX_EVENTS]; /* A circular buffer (FIFO), using eventBottom/Len */ i32 eventBottom; @@ -3221,8 +3143,11 @@ struct RGFW_info { char* clipboard_data; char* clipboard; /* for writing to the clipboard selection */ size_t clipboard_len; - char filesSrc[RGFW_MAX_PATH * RGFW_MAX_DROPS]; - char** files; + + RGFW_bool dndBuild; + RGFW_dataDropNode* dndRoot; + RGFW_dataDropNode* dndCur; + #ifdef RGFW_X11 Display* display; XContext context; @@ -3231,6 +3156,10 @@ struct RGFW_info { XErrorEvent* x11Error; i32 xrandrEventBase; XIM im; + Window x11Source; + long x11Version; + i32 x11Format; + RGFW_dataTransferType x11TransferType; #endif #ifdef RGFW_WAYLAND struct wl_display* wl_display; @@ -3264,6 +3193,9 @@ struct RGFW_info { RGFW_window* kbOwner; RGFW_window* mouseOwner; /* what window has access to the mouse */ + u32 last_key; /* wayland key repeat data */ + i32 wl_repeat_info_rate, wl_repeat_info_delay; + u32 last_key_time; #endif RGFW_monitors monitors; @@ -3312,6 +3244,7 @@ struct RGFW_info { /* 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_setFlagsInternal(RGFW_window* win, RGFW_windowFlags flags, RGFW_windowFlags cmpFlags); @@ -3320,24 +3253,28 @@ RGFWDEF void RGFW_initKeycodesPlatform(void); RGFWDEF void RGFW_resetPrevState(void); RGFWDEF void RGFW_resetKey(void); RGFWDEF void RGFW_unloadEGL(void); -RGFWDEF void RGFW_updateKeyModsEx(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_updateKeyMods(RGFW_window* win, RGFW_bool capital, RGFW_bool numlock, RGFW_bool scroll); +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_updateKeyMod(RGFW_window* win, RGFW_keymod mod, RGFW_bool value); +RGFWDEF void RGFW_keyUpdateKeyMod(RGFW_window* win, RGFW_keymod mod, RGFW_bool value); + 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_windowMaximizedCallback(RGFW_window* win, i32 x, i32 y, i32 w, i32 h); RGFWDEF void RGFW_windowMinimizedCallback(RGFW_window* win); RGFWDEF void RGFW_windowRestoredCallback(RGFW_window* win, i32 x, i32 y, i32 w, i32 h); 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_windowQuitCallback(RGFW_window* win); -RGFWDEF void RGFW_mousePosCallback(RGFW_window* win, i32 x, i32 y, float vecX, float vecY); -RGFWDEF void RGFW_windowRefreshCallback(RGFW_window* win); -RGFWDEF void RGFW_focusCallback(RGFW_window* win, RGFW_bool inFocus); +RGFWDEF void RGFW_windowCloseCallback(RGFW_window* win); +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); RGFWDEF void RGFW_mouseNotifyCallback(RGFW_window* win, i32 x, i32 y, RGFW_bool status); -RGFWDEF void RGFW_dataDropCallback(RGFW_window* win, char** files, size_t count); -RGFWDEF void RGFW_dataDragCallback(RGFW_window* win, i32 x, i32 y); +RGFWDEF void RGFW_dataDropCallback(RGFW_window* win, const char* data, size_t count, RGFW_dataTransferType dataType); +RGFWDEF void RGFW_dataDragCallback(RGFW_window* win, RGFW_dataTransferType dataType, RGFW_dndActionType action, i32 x, i32 y); RGFWDEF void RGFW_keyCharCallback(RGFW_window* win, u32 codepoint); RGFWDEF void RGFW_keyCallback(RGFW_window* win, RGFW_key key, RGFW_keymod mod, RGFW_bool repeat, RGFW_bool press); RGFWDEF void RGFW_mouseButtonCallback(RGFW_window* win, RGFW_mouseButton button, RGFW_bool press); @@ -3423,16 +3360,10 @@ const char* RGFW_readClipboard(size_t* len) { return (const char*)str; } -/* -RGFW_IMPLEMENTATION starts with generic RGFW defines - -This is the start of keycode data -*/ - - +/* generic RGFW defines */ void RGFW_initKeycodes(void) { - RGFW_MEMSET(_RGFW->keycodes, 0, sizeof(_RGFW->keycodes)); + RGFW_MEMZERO(_RGFW->keycodes, sizeof(_RGFW->keycodes)); RGFW_initKeycodesPlatform(); size_t i, y; for (i = 0; i < RGFW_keyLast; i++) { @@ -3461,64 +3392,66 @@ u32 RGFW_rgfwToApiKey(RGFW_key keycode) { return _RGFW->apiKeycodes[keycode]; } -void RGFW_resetKey(void) { RGFW_MEMSET(_RGFW->keyboard, 0, sizeof(_RGFW->keyboard)); } +void RGFW_resetKey(void) { RGFW_MEMZERO(_RGFW->keyboard, sizeof(_RGFW->keyboard)); } /* this is the end of keycode data */ -/* - event callback defines start here -*/ +RGFW_genericFunc RGFW_setEventCallback(RGFW_eventType type, RGFW_genericFunc func) { + RGFW_ASSERT(type > RGFW_eventNone && type < RGFW_eventCount); + RGFW_init(); + RGFW_genericFunc old = _RGFW->callbacks[type]; + _RGFW->callbacks[type] = func; -/* - These exist to avoid the - if (func == NULL) check - for (allegedly) better performance - - RGFW_EMPTY_DEF exists to prevent the missing-prototypes warning -*/ -#define RGFW_CALLBACK_DEFINE(x, x2) \ -RGFW_##x##func RGFW_##x##CallbackSrc = NULL; \ -RGFW_##x##func RGFW_set##x2##Callback(RGFW_##x##func func) { \ - RGFW_##x##func prev = RGFW_##x##CallbackSrc; \ - RGFW_##x##CallbackSrc = func; \ - return prev; \ + return old; } -RGFW_CALLBACK_DEFINE(windowMaximized, WindowMaximized) -RGFW_CALLBACK_DEFINE(windowMinimized, WindowMinimized) -RGFW_CALLBACK_DEFINE(windowRestored, WindowRestored) -RGFW_CALLBACK_DEFINE(windowMoved, WindowMoved) -RGFW_CALLBACK_DEFINE(windowResized, WindowResized) -RGFW_CALLBACK_DEFINE(windowQuit, WindowQuit) -RGFW_CALLBACK_DEFINE(mousePos, MousePos) -RGFW_CALLBACK_DEFINE(windowRefresh, WindowRefresh) -RGFW_CALLBACK_DEFINE(focus, Focus) -RGFW_CALLBACK_DEFINE(mouseNotify, MouseNotify) -RGFW_CALLBACK_DEFINE(dataDrop, DataDrop) -RGFW_CALLBACK_DEFINE(dataDrag, DataDrag) -RGFW_CALLBACK_DEFINE(key, Key) -RGFW_CALLBACK_DEFINE(keyChar, KeyChar) -RGFW_CALLBACK_DEFINE(mouseButton, MouseButton) -RGFW_CALLBACK_DEFINE(mouseScroll, MouseScroll) -RGFW_CALLBACK_DEFINE(scaleUpdated, ScaleUpdated) -RGFW_CALLBACK_DEFINE(monitor, Monitor) -RGFW_CALLBACK_DEFINE(debug, Debug) -#define RGFW_debugCallback(type, err, msg) if (RGFW_debugCallbackSrc) RGFW_debugCallbackSrc(type, err, msg); -#undef RGFW_CALLBACK_DEFINE +void RGFW_setDualEventCallback(RGFW_eventType type, RGFW_genericFunc func, RGFW_genericFunc* first, RGFW_genericFunc* second) { + RGFW_genericFunc func1 = RGFW_setEventCallback(type, func); + RGFW_genericFunc func2 = RGFW_setEventCallback(type + 1, func); + + if (first) *first = func1; + if (second) *second = func2; +} + +void RGFW_setAllEventCallbacks(RGFW_genericFunc func, RGFW_callbacks* callbacks) { + for (RGFW_eventType i = RGFW_eventNone + 1; i < RGFW_eventCount; i++) { + if (callbacks) callbacks->arr[i] = _RGFW->callbacks[i]; + RGFW_setEventCallback(i, func); + } +} + +RGFW_debugFunc RGFW_setDebugCallback(RGFW_debugFunc func) { + RGFW_init(); + RGFW_debugFunc prev = _RGFW->debugCallbackSrc; + _RGFW->debugCallbackSrc = func; + return prev; +} + +void RGFW_eventQueuePushAndCall(const RGFW_event* event) { + RGFW_ASSERT(event->type > RGFW_eventNone && event->type < RGFW_eventCount); + if (_RGFW->callbacks[event->type]) (_RGFW->callbacks[event->type])(event); + RGFW_eventQueuePush(event); +} void RGFW_windowMaximizedCallback(RGFW_window* win, i32 x, i32 y, i32 w, i32 h) { win->internal.flags |= RGFW_windowMaximize; + win->x = x; + win->y = y; + win->w = w; + win->h = h; if (!(win->internal.enabledEvents & RGFW_windowMaximizedFlag)) return; RGFW_event event; event.type = RGFW_windowMaximized; + event.update.x = x; + event.update.y = y; + event.update.w = w; + event.update.h = h; event.common.win = win; - RGFW_eventQueuePush(&event); - - if (RGFW_windowMaximizedCallbackSrc) RGFW_windowMaximizedCallbackSrc(win, x, y, w, h); + RGFW_eventQueuePushAndCall(&event); } void RGFW_windowMinimizedCallback(RGFW_window* win) { @@ -3528,24 +3461,33 @@ void RGFW_windowMinimizedCallback(RGFW_window* win) { RGFW_event event; event.type = RGFW_windowMinimized; + event.update.x = win->x; + event.update.y = win->y; + event.update.w = win->w; + event.update.h = win->h; event.common.win = win; - RGFW_eventQueuePush(&event); - - if (RGFW_windowMinimizedCallbackSrc) RGFW_windowMinimizedCallbackSrc(win); + RGFW_eventQueuePushAndCall(&event); } void RGFW_windowRestoredCallback(RGFW_window* win, i32 x, i32 y, i32 w, i32 h) { win->internal.flags &= ~(u32)RGFW_windowMinimize; + win->x = x; + win->y = y; + win->w = w; + win->h = h; + if (RGFW_window_isMaximized(win) == RGFW_FALSE) win->internal.flags &= ~(u32)RGFW_windowMaximize; if (!(win->internal.enabledEvents & RGFW_windowRestoredFlag)) return; RGFW_event event; event.type = RGFW_windowRestored; + event.update.x = x; + event.update.y = y; + event.update.w = w; + event.update.h = h; event.common.win = win; - RGFW_eventQueuePush(&event); - - if (RGFW_windowRestoredCallbackSrc) RGFW_windowRestoredCallbackSrc(win, x, y, w, h); + RGFW_eventQueuePushAndCall(&event); } void RGFW_windowMovedCallback(RGFW_window* win, i32 x, i32 y) { @@ -3555,10 +3497,12 @@ void RGFW_windowMovedCallback(RGFW_window* win, i32 x, i32 y) { RGFW_event event; event.type = RGFW_windowMoved; + event.update.x = x; + event.update.y = y; + event.update.w = win->w; + event.update.h = win->h; event.common.win = win; - RGFW_eventQueuePush(&event); - - if (RGFW_windowMovedCallbackSrc) RGFW_windowMovedCallbackSrc(win, x, y); + RGFW_eventQueuePushAndCall(&event); } void RGFW_windowResizedCallback(RGFW_window* win, i32 w, i32 h) { @@ -3568,55 +3512,64 @@ void RGFW_windowResizedCallback(RGFW_window* win, i32 w, i32 h) { if (!(win->internal.enabledEvents & RGFW_windowResizedFlag)) return; RGFW_event event; event.type = RGFW_windowResized; + event.update.x = win->x; + event.update.y = win->y; + event.update.w = w; + event.update.h = h; event.common.win = win; - RGFW_eventQueuePush(&event); - - if (RGFW_windowResizedCallbackSrc) RGFW_windowResizedCallbackSrc(win, w, h); + RGFW_eventQueuePushAndCall(&event); } -void RGFW_windowQuitCallback(RGFW_window* win) { +void RGFW_windowCloseCallback(RGFW_window* win) { win->internal.shouldClose = RGFW_TRUE; RGFW_event event; - event.type = RGFW_quit; + event.type = RGFW_windowClose; event.common.win = win; - RGFW_eventQueuePush(&event); - - if (RGFW_windowQuitCallbackSrc) RGFW_windowQuitCallbackSrc(win); + RGFW_eventQueuePushAndCall(&event); } -void RGFW_mousePosCallback(RGFW_window* win, i32 x, i32 y, float vecX, float vecY) { +void RGFW_mouseMotionCallback(RGFW_window* win, i32 x, i32 y) { win->internal.lastMouseX = x; win->internal.lastMouseY = y; - _RGFW->vectorX = vecX; - _RGFW->vectorY = vecY; - 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.vecX = vecX; - event.mouse.vecY = vecY; + event.mouse.inWindow = win->internal.mouseInside; event.common.win = win; - - RGFW_eventQueuePush(&event); - - if (RGFW_mousePosCallbackSrc) RGFW_mousePosCallbackSrc(win, x, y, vecX, vecY); + RGFW_eventQueuePushAndCall(&event); } -void RGFW_windowRefreshCallback(RGFW_window* win) { +void RGFW_rawMotionCallback(RGFW_window* win, float x, float y) { + _RGFW->vectorX = x; + _RGFW->vectorY = y; + if (!(win->internal.enabledEvents & RGFW_mouseRawMotionFlag)) return; + + RGFW_event event; + event.type = RGFW_mouseRawMotion; + event.delta.x = x; + event.delta.y = y; + event.common.win = win; + RGFW_eventQueuePushAndCall(&event); +} + +void RGFW_windowRefreshCallback(RGFW_window* win, i32 x, i32 y, i32 w, i32 h) { if (!(win->internal.enabledEvents & RGFW_windowRefreshFlag)) return; RGFW_event event; event.type = RGFW_windowRefresh; + event.update.x = x; + event.update.y = y; + event.update.w = w; + event.update.h = h; event.common.win = win; - RGFW_eventQueuePush(&event); - - if (RGFW_windowRefreshCallbackSrc) RGFW_windowRefreshCallbackSrc(win); + RGFW_eventQueuePushAndCall(&event); } -void RGFW_focusCallback(RGFW_window* win, RGFW_bool inFocus) { +void RGFW_windowFocusCallback(RGFW_window* win, RGFW_bool inFocus) { win->internal.inFocus = inFocus; if (win->internal.captureMouse) { @@ -3625,12 +3578,13 @@ void RGFW_focusCallback(RGFW_window* win, RGFW_bool inFocus) { RGFW_event event; event.common.win = win; + event.focus.state = inFocus; if (inFocus == RGFW_TRUE) { if ((win->internal.flags & RGFW_windowFullscreen)) RGFW_window_raise(win); - event.type = RGFW_focusIn; + event.type = RGFW_windowFocusIn; } else if (inFocus == RGFW_FALSE) { if ((win->internal.flags & RGFW_windowFullscreen)) RGFW_window_minimize(win); @@ -3646,14 +3600,12 @@ void RGFW_focusCallback(RGFW_window* win, RGFW_bool inFocus) { } RGFW_resetKey(); - event.type = RGFW_focusOut; + event.type = RGFW_windowFocusOut; } event.common.win = win; - RGFW_eventQueuePush(&event); - - if (RGFW_focusCallbackSrc) RGFW_focusCallbackSrc(win, inFocus); + RGFW_eventQueuePushAndCall(&event); } void RGFW_mouseNotifyCallback(RGFW_window* win, i32 x, i32 y, RGFW_bool status) { @@ -3667,6 +3619,7 @@ void RGFW_mouseNotifyCallback(RGFW_window* win, i32 x, i32 y, RGFW_bool status) event.common.win = win; event.mouse.x = x; event.mouse.y = y; + event.mouse.inWindow = win->internal.mouseInside; if (status) { if (!(win->internal.enabledEvents & RGFW_mouseEnterFlag)) return; @@ -3680,45 +3633,68 @@ void RGFW_mouseNotifyCallback(RGFW_window* win, i32 x, i32 y, RGFW_bool status) event.type = RGFW_mouseLeave; } - RGFW_eventQueuePush(&event); - - if (RGFW_mouseNotifyCallbackSrc) RGFW_mouseNotifyCallbackSrc(win, x, y, status); + RGFW_eventQueuePushAndCall(&event); } -void RGFW_dataDropCallback(RGFW_window* win, char** files, size_t count) { +void RGFW_dataDropCallback(RGFW_window* win, const char* data, size_t size, 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.filesCount = count; + _RGFW->windowState.dataSize = size; + + RGFW_dataDropNode node; + RGFW_MEMZERO(&node, sizeof(node)); + node.data = data; + node.size = size; + node.type = dataType; + node.next = NULL; RGFW_event event; event.type = RGFW_dataDrop; - event.drop.files = files; - event.drop.count = count; - event.common.win = win; - RGFW_eventQueuePush(&event); + event.drop.value = &node; + event.drop.win = win; - if (RGFW_dataDropCallbackSrc) RGFW_dataDropCallbackSrc(win, files, count); + if (_RGFW->callbacks[event.type]) (_RGFW->callbacks[event.type])(&event); + + if (_RGFW->queueEvents == RGFW_TRUE || _RGFW->dndBuild) { + if (_RGFW->dndRoot == NULL) { + _RGFW->dndRoot = (RGFW_dataDropNode*)RGFW_ALLOC(sizeof(RGFW_dataDropNode)); + _RGFW->dndCur = _RGFW->dndRoot; + } else if (_RGFW->dndCur) { + _RGFW->dndCur->next = (RGFW_dataDropNode*)RGFW_ALLOC(sizeof(RGFW_dataDropNode)); + _RGFW->dndCur = _RGFW->dndCur->next; + } else { RGFW_ASSERT(0); } + + char* dataCopy = (char*)RGFW_ALLOC(size); + RGFW_MEMCPY(dataCopy, data, size); + node.data = dataCopy; + + RGFW_MEMCPY(_RGFW->dndCur, &node, sizeof(node)); + + event.drop.value = _RGFW->dndCur; + RGFW_eventQueuePush(&event); + } } -void RGFW_dataDragCallback(RGFW_window* win, i32 x, i32 y) { +void RGFW_dataDragCallback(RGFW_window* win, RGFW_dataTransferType dataType, RGFW_dndActionType action, i32 x, i32 y) { + if (!(win->internal.enabledEvents & RGFW_dataDragFlag) || !(win->internal.flags & RGFW_windowAllowDND)) return; + _RGFW->windowState.win = win; _RGFW->windowState.dataDragging = RGFW_TRUE; _RGFW->windowState.dropX = x; _RGFW->windowState.dropY = y; - if (win->internal.enabledEvents & RGFW_dataDragFlag) return; - RGFW_event event; event.type = RGFW_dataDrag; event.drag.x = x; event.drag.y = y; + event.drag.action = action; + event.drag.dataType = dataType; event.common.win = win; - RGFW_eventQueuePush(&event); - if (RGFW_dataDragCallbackSrc) RGFW_dataDragCallbackSrc(win, x, y); + RGFW_eventQueuePushAndCall(&event); } void RGFW_keyCharCallback(RGFW_window* win, u32 codepoint) { @@ -3728,9 +3704,7 @@ void RGFW_keyCharCallback(RGFW_window* win, u32 codepoint) { event.type = RGFW_keyChar; event.keyChar.value = codepoint; event.common.win = win; - RGFW_eventQueuePush(&event); - - if (RGFW_keyCharCallbackSrc) RGFW_keyCharCallbackSrc(win, codepoint); + RGFW_eventQueuePushAndCall(&event); } void RGFW_keyCallback(RGFW_window* win, RGFW_key key, RGFW_keymod mod, RGFW_bool repeat, RGFW_bool press) { @@ -3748,16 +3722,16 @@ void RGFW_keyCallback(RGFW_window* win, RGFW_key key, RGFW_keymod mod, RGFW_bool _RGFW->keyboard[key].current = press; event.key.value = key; - event.key.mod = repeat; + event.key.repeat = repeat; event.key.mod = mod; + event.key.state = press; event.common.win = win; - RGFW_eventQueuePush(&event); - - if (RGFW_keyCallbackSrc) RGFW_keyCallbackSrc(win, key, mod, repeat, press); + RGFW_eventQueuePushAndCall(&event); } void RGFW_mouseButtonCallback(RGFW_window* win, RGFW_mouseButton button, RGFW_bool press) { RGFW_event event; + if (press) { if (!(win->internal.enabledEvents & RGFW_mouseButtonPressedFlag)) return; event.type = RGFW_mouseButtonPressed; @@ -3770,10 +3744,9 @@ void RGFW_mouseButtonCallback(RGFW_window* win, RGFW_mouseButton button, RGFW_bo _RGFW->mouseButtons[button].current = press; event.button.value = button; + event.button.state = press; event.common.win = win; - RGFW_eventQueuePush(&event); - - if (RGFW_mouseButtonCallbackSrc) RGFW_mouseButtonCallbackSrc(win, button, press); + RGFW_eventQueuePushAndCall(&event); } void RGFW_mouseScrollCallback(RGFW_window* win, float x, float y) { @@ -3783,16 +3756,13 @@ void RGFW_mouseScrollCallback(RGFW_window* win, float x, float y) { RGFW_event event; event.type = RGFW_mouseScroll; - event.scroll.x = x; - event.scroll.y = y; + event.delta.x = x; + event.delta.y = y; event.common.win = win; - RGFW_eventQueuePush(&event); - - if (RGFW_mouseScrollCallbackSrc) RGFW_mouseScrollCallbackSrc(win, x, y); + RGFW_eventQueuePushAndCall(&event); } void RGFW_scaleUpdatedCallback(RGFW_window* win, float scaleX, float scaleY) { - if (win->internal.flags & RGFW_windowScaleToMonitor) RGFW_window_scaleToMonitor(win); if (!(win->internal.enabledEvents & RGFW_scaleUpdatedFlag)) return; RGFW_event event; @@ -3800,9 +3770,7 @@ void RGFW_scaleUpdatedCallback(RGFW_window* win, float scaleX, float scaleY) { event.scale.x = scaleX; event.scale.y = scaleY; event.common.win = win; - RGFW_eventQueuePush(&event); - - if (RGFW_scaleUpdatedCallbackSrc) RGFW_scaleUpdatedCallbackSrc(win, scaleX, scaleY); + RGFW_eventQueuePushAndCall(&event); } void RGFW_monitorCallback(RGFW_window* win, const RGFW_monitor* monitor, RGFW_bool connected) { @@ -3812,26 +3780,30 @@ void RGFW_monitorCallback(RGFW_window* win, const RGFW_monitor* monitor, RGFW_bo } RGFW_event event; - event.type = (connected) ? (RGFW_monitorConnected) : (RGFW_monitorDisconnected); + event.type = (connected) ? (RGFW_eventType)(RGFW_monitorConnected) : (RGFW_eventType)(RGFW_monitorDisconnected); event.monitor.monitor = monitor; + event.monitor.state = connected; event.common.win = win; - RGFW_eventQueuePush(&event); - - if (RGFW_monitorCallbackSrc) RGFW_monitorCallbackSrc(win, monitor, connected); + RGFW_eventQueuePushAndCall(&event); } #ifdef RGFW_DEBUG #include #endif -void RGFW_sendDebugInfo(RGFW_debugType type, RGFW_errorCode err, const char* msg) { - RGFW_debugCallback(type, err, msg); +void RGFW_debugCallback(RGFW_debugType type, RGFW_errorCode code, const char* msg) { + RGFW_debugInfo info; + info.type = type; + info.code = code; + info.msg = msg; + + if (_RGFW && _RGFW->debugCallbackSrc) _RGFW->debugCallbackSrc(&info); #ifdef RGFW_DEBUG switch (type) { - case RGFW_typeInfo: RGFW_PRINTF("RGFW INFO (%i %i): %s", type, err, msg); break; - case RGFW_typeError: RGFW_PRINTF("RGFW DEBUG (%i %i): %s", type, err, msg); break; - case RGFW_typeWarning: RGFW_PRINTF("RGFW WARNING (%i %i): %s", type, err, msg); break; + case RGFW_typeInfo: RGFW_PRINTF("RGFW INFO (%i %i): %s", type, code, msg); break; + case RGFW_typeError: RGFW_PRINTF("RGFW DEBUG (%i %i): %s", type, code, msg); break; + case RGFW_typeWarning: RGFW_PRINTF("RGFW WARNING (%i %i): %s", type, code, msg); break; default: break; } @@ -3890,12 +3862,39 @@ 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(void) { return RGFW_init_ptr(&_rgfwGlobal); } -void RGFW_deinit(void) { RGFW_deinit_ptr(&_rgfwGlobal); } +i32 RGFW_init(void) { + static RGFW_info _rgfwGlobal; + return RGFW_init_ptr(&_rgfwGlobal); +} + + +void RGFW_deinit(void) { RGFW_deinit_ptr(_RGFW); } + +#else + +RGFW_info* _rgfwGlobal; + +i32 RGFW_init(void) { + if (_rgfwGlobal != NULL) { + RGFW_FREE(_rgfwGlobal); + } + + _rgfwGlobal = (RGFW_info*)RGFW_ALLOC(sizeof(RGFW_info)); + + return RGFW_init_ptr(&_rgfwGlobal); +} + +void RGFW_deinit(void) { + if (_RGFW == _rgfwGlobal) { + RGFW_FREE(_rgfwGlobal); + _rgfwGlobal = NULL; + } + RGFW_deinit_ptr(_RGFW); +} + +#endif i32 RGFW_initPlatform(void); void RGFW_deinitPlatform(void); @@ -3904,35 +3903,36 @@ i32 RGFW_init_ptr(RGFW_info* info) { if (info == _RGFW || info == NULL) return 1; RGFW_setInfo(info); - RGFW_MEMSET(_RGFW, 0, sizeof(RGFW_info)); + RGFW_MEMZERO(_RGFW, sizeof(RGFW_info)); _RGFW->queueEvents = RGFW_FALSE; _RGFW->polledEvents = RGFW_FALSE; #ifdef RGFW_WAYLAND _RGFW->useWaylandBool = RGFW_TRUE; #endif - _RGFW->files = (char**)(void*)_RGFW->filesSrc; - u32 i; - for (i = 0; i < RGFW_MAX_DROPS; i++) - _RGFW->files[i] = (char*)(_RGFW->filesSrc + RGFW_MAX_DROPS + (i * RGFW_MAX_PATH)); + #if (RGFW_PREALLOCATED_MONITORS) + _RGFW->monitors.freeList.head = &_RGFW->monitors.data[0]; + _RGFW->monitors.freeList.cur = _RGFW->monitors.freeList.head; - _RGFW->monitors.freeList.head = &_RGFW->monitors.data[0]; - _RGFW->monitors.freeList.cur = _RGFW->monitors.freeList.head; - - for (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(); + for (size_t i = 0; i < RGFW_mouseIconCount; i++) { + _RGFW->standardMice[i] = RGFW_createMouseStandard((RGFW_mouseIcon)i); + } + RGFW_pollMonitors(); - RGFW_sendDebugInfo(RGFW_typeInfo, RGFW_infoGlobal, "global context initialized"); + RGFW_debugCallback(RGFW_typeInfo, RGFW_infoGlobal, "global context initialized"); return out; } @@ -3946,12 +3946,17 @@ void RGFW_deinit_ptr(RGFW_info* info) { RGFW_setInfo(info); RGFW_unloadEGL(); + + for (RGFW_mouseIcon i = 0; i < RGFW_mouseIconCount; i++) { + if (_RGFW->standardMice[i]) RGFW_freeMouse(_RGFW->standardMice[i]); + } + + RGFW_debugCallback(RGFW_typeInfo, RGFW_infoGlobal, "global context deinitialized"); RGFW_deinitPlatform(); _RGFW->root = NULL; _RGFW->windowCount = 0; RGFW_setInfo(NULL); - RGFW_sendDebugInfo(RGFW_typeInfo, RGFW_infoGlobal, "global context deinitialized"); } RGFW_window* RGFW_createWindow(const char* name, i32 x, i32 y, i32 w, i32 h, RGFW_windowFlags flags) { @@ -3970,7 +3975,7 @@ RGFW_window* RGFW_createWindowPtr(const char* name, i32 x, i32 y, i32 w, i32 h, RGFW_ASSERT(win != NULL); if (name == NULL) name = "\0"; - RGFW_MEMSET(win, 0, sizeof(RGFW_window)); + RGFW_MEMZERO(win, sizeof(RGFW_window)); if (_RGFW == NULL) RGFW_init(); _RGFW->windowCount++; @@ -3985,11 +3990,17 @@ RGFW_window* RGFW_createWindowPtr(const char* name, i32 x, i32 y, i32 w, i32 h, win->y = y; win->w = w; win->h = h; + win->internal.mouse = _RGFW->standardMice[RGFW_mouseNormal]; win->internal.flags = flags; win->internal.enabledEvents = RGFW_allEventFlags; + RGFW_windowFlags reservedFlags = flags & (RGFW_windowScaleToMonitor); + flags &= ~reservedFlags; + RGFW_window* ret = RGFW_createWindowPlatform(name, flags, win); + flags |= reservedFlags; + #ifndef RGFW_X11 RGFW_window_setFlagsInternal(win, flags, 0); #endif @@ -4027,7 +4038,7 @@ RGFW_window* RGFW_createWindowPtr(const char* name, i32 x, i32 y, i32 w, i32 h, /* NOTE: this is a hack so that way wayland spawns a window, even if nothing is drawn */ if (!(flags & RGFW_windowOpenGL) && !(flags & RGFW_windowEGL)) { u8* data = (u8*)RGFW_ALLOC((u32)(win->w * win->h * 3)); - RGFW_MEMSET(data, 0, (u32)(win->w * win->h * 3) * sizeof(u8)); + RGFW_MEMZERO(data, (u32)(win->w * win->h * 3) * sizeof(u8)); RGFW_surface* surface = RGFW_createSurface(data, win->w, win->h, RGFW_formatBGR8); RGFW_window_blitSurface(win, surface); RGFW_FREE(data); @@ -4046,7 +4057,7 @@ RGFW_window* RGFW_createWindowPtr(const char* name, i32 x, i32 y, i32 w, i32 h, RGFW_window_show(win); } - RGFW_sendDebugInfo(RGFW_typeInfo, RGFW_infoWindow, "a new window was created"); + RGFW_debugCallback(RGFW_typeInfo, RGFW_infoWindow, "a new window was created"); return ret; } @@ -4077,7 +4088,7 @@ void RGFW_window_closePtr(RGFW_window* win) { RGFW_clipboard_switch(NULL); _RGFW->windowCount--; - RGFW_sendDebugInfo(RGFW_typeInfo, RGFW_infoWindow, "a window was freed"); + RGFW_debugCallback(RGFW_typeInfo, RGFW_infoWindow, "a window was freed"); if (_RGFW->windowCount == 0 && !(win->internal.flags & RGFW_noDeinitOnClose)) RGFW_deinit(); } @@ -4091,7 +4102,7 @@ void RGFW_eventQueuePush(const RGFW_event* event) { RGFW_ASSERT(_RGFW->eventLen >= 0); if (_RGFW->eventLen >= RGFW_MAX_EVENTS) { - RGFW_sendDebugInfo(RGFW_typeError, RGFW_errEventQueue, "Event queue limit 'RGFW_MAX_EVENTS' has been reached automatically flushing queue."); + RGFW_debugCallback(RGFW_typeError, RGFW_errEventQueue, "Event queue limit 'RGFW_MAX_EVENTS' has been reached automatically flushing queue."); RGFW_eventQueueFlush(); return; } @@ -4152,7 +4163,16 @@ void RGFW_resetPrevState(void) { _RGFW->scrollY = 0.0f; _RGFW->vectorX = (float)0.0f; _RGFW->vectorY = (float)0.0f; - RGFW_MEMSET(&_RGFW->windowState, 0, sizeof(_RGFW->windowState)); + RGFW_MEMZERO(&_RGFW->windowState, sizeof(_RGFW->windowState)); + + for (RGFW_dataDropNode* node = _RGFW->dndRoot; node; ) { + RGFW_dataDropNode* next = node->next; + RGFW_FREE(node); + node = next; + } + + _RGFW->dndRoot = NULL; + _RGFW->dndCur = NULL; } RGFW_bool RGFW_isKeyPressed(RGFW_key key) { @@ -4199,7 +4219,7 @@ RGFW_bool RGFW_window_didMouseEnter(RGFW_window* win) { return _RGFW->windowStat RGFW_bool RGFW_window_isMouseInside(RGFW_window* win) { return win->internal.mouseInside; } RGFW_bool RGFW_window_isDataDragging(RGFW_window* win) { return RGFW_window_getDataDrag(win, (i32*)NULL, (i32*)NULL); } -RGFW_bool RGFW_window_didDataDrop(RGFW_window* win) { return RGFW_window_getDataDrop(win, (const char***)NULL, (size_t*)NULL);} +RGFW_bool RGFW_window_didDataDrop(RGFW_window* win) { return RGFW_window_getDataDrop(win) != NULL;} RGFW_bool RGFW_window_getDataDrag(RGFW_window* win, i32* x, i32* y) { @@ -4208,11 +4228,9 @@ RGFW_bool RGFW_window_getDataDrag(RGFW_window* win, i32* x, i32* y) { if (y) *y = _RGFW->windowState.dropY; return RGFW_TRUE; } -RGFW_bool RGFW_window_getDataDrop(RGFW_window* win, const char*** files, size_t* count) { - if (_RGFW->windowState.win != win || _RGFW->windowState.dataDrop == RGFW_FALSE) return RGFW_FALSE; - if (files) *files = (const char**)_RGFW->files; - if (count) *count = _RGFW->windowState.filesCount; - return RGFW_TRUE; +RGFW_dataDropNode* RGFW_window_getDataDrop(RGFW_window* win) { + if (_RGFW->windowState.win != win || _RGFW->windowState.dataDrop == RGFW_FALSE) return NULL; + return _RGFW->dndRoot; } RGFW_bool RGFW_window_checkEvent(RGFW_window* win, RGFW_event* event) { @@ -4268,7 +4286,6 @@ RGFW_bool RGFW_loadEGL(void) { return RGFW_FALSE; } 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); - if (flags & RGFW_windowScaleToMonitor) RGFW_window_scaleToMonitor(win); if (flags & RGFW_windowMaximize) RGFW_window_maximize(win); else if (cmpFlags & RGFW_windowMaximize) RGFW_window_restore(win); if (flags & RGFW_windowMinimize) RGFW_window_minimize(win); @@ -4288,6 +4305,7 @@ void RGFW_window_setFlagsInternal(RGFW_window* win, RGFW_windowFlags flags, RGFW if (flags & RGFW_windowCaptureMouse) RGFW_window_captureRawMouse(win, RGFW_TRUE); else if (cmpFlags & RGFW_windowCaptureMouse) RGFW_window_captureMouse(win, RGFW_FALSE); if (flags & RGFW_windowFocus) RGFW_window_focus(win); + if (flags & RGFW_windowScaleToMonitor) RGFW_window_scaleToMonitor(win); if (flags & RGFW_windowNoResize) { RGFW_window_setMaxSize(win, win->w, win->h); @@ -4312,6 +4330,7 @@ RGFW_bool RGFW_window_isInFocus(RGFW_window* win) { } 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); } @@ -4366,7 +4385,7 @@ void RGFW_window_center(RGFW_window* win) { RGFW_monitor* mon = RGFW_window_getMonitor(win); if (mon == NULL) return; - RGFW_window_move(win, (i32)(mon->mode.w - win->w) / 2, (mon->mode.h - win->h) / 2); + RGFW_window_move(win, mon->x + ((i32)(mon->mode.w - win->w) / 2), mon->y + ((mon->mode.h - win->h) / 2)); } RGFW_bool RGFW_monitor_scaleToWindow(RGFW_monitor* mon, RGFW_window* win) { @@ -4377,7 +4396,6 @@ RGFW_bool RGFW_monitor_scaleToWindow(RGFW_monitor* mon, RGFW_window* win) { mode.h = win->h; RGFW_bool ret = RGFW_monitor_requestMode(mon, &mode, RGFW_monitorScale); - /* move window to monitor origin so it doesn't move to the next monitor */ RGFW_window_move(win, mon->x, mon->y); @@ -4403,12 +4421,12 @@ RGFW_bool RGFW_monitorModeCompare(RGFW_monitorMode* mon, RGFW_monitorMode* mon2, } RGFW_bool RGFW_window_shouldClose(RGFW_window* win) { - return (win == NULL || win->internal.shouldClose || (win->internal.exitKey && RGFW_window_isKeyDown(win, win->internal.exitKey))); + return (win == NULL || win->internal.shouldClose || (win->internal.exitKey && RGFW_isKeyDown(win->internal.exitKey))); } void RGFW_window_setShouldClose(RGFW_window* win, RGFW_bool shouldClose) { if (shouldClose) { - RGFW_windowQuitCallback(win); + RGFW_windowCloseCallback(win); } else { win->internal.shouldClose = RGFW_FALSE; } @@ -4428,7 +4446,7 @@ void RGFW_window_moveToMonitor(RGFW_window* win, RGFW_monitor* m) { RGFW_surface* RGFW_createSurface(u8* data, i32 w, i32 h, RGFW_format format) { RGFW_surface* surface = (RGFW_surface*)RGFW_ALLOC(sizeof(RGFW_surface)); - RGFW_MEMSET(surface, 0, sizeof(RGFW_surface)); + RGFW_MEMZERO(surface, sizeof(RGFW_surface)); RGFW_createSurfacePtr(data, w, h, format, surface); return surface; } @@ -4448,7 +4466,7 @@ RGFW_nativeImage* RGFW_surface_getNativeImage(RGFW_surface* surface) { RGFW_surface* RGFW_window_createSurface(RGFW_window* win, u8* data, i32 w, i32 h, RGFW_format format) { RGFW_surface* surface = (RGFW_surface*)RGFW_ALLOC(sizeof(RGFW_surface)); - RGFW_MEMSET(surface, 0, sizeof(RGFW_surface)); + RGFW_MEMZERO(surface, sizeof(RGFW_surface)); RGFW_window_createSurfacePtr(win, data, w, h, format, surface); return surface; } @@ -4520,14 +4538,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; @@ -4559,14 +4585,23 @@ void RGFW_monitors_remove(RGFW_monitorNode* node, RGFW_monitorNode* prev) { 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) { @@ -4711,23 +4746,49 @@ RGFW_bool RGFW_monitor_setGamma(RGFW_monitor* monitor, float gamma) { } RGFW_monitor** RGFW_getMonitors(size_t* len) { - static RGFW_monitor* monitors[RGFW_MAX_MONITORS]; + 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_init(); 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_init(); if (_RGFW->monitors.primary == NULL) { _RGFW->monitors.primary = _RGFW->monitors.list.head; } @@ -4757,27 +4818,27 @@ void RGFW_window_captureRawMouse(RGFW_window* win, RGFW_bool state) { RGFW_bool RGFW_window_isRawMouseMode(RGFW_window* win) { return RGFW_BOOL(win->internal.rawMouse); } RGFW_bool RGFW_window_isCaptured(RGFW_window* win) { return RGFW_BOOL(win->internal.captureMouse); } -void RGFW_updateKeyMod(RGFW_window* win, RGFW_keymod mod, RGFW_bool value) { +void RGFW_keyUpdateKeyMod(RGFW_window* win, RGFW_keymod mod, RGFW_bool value) { if (value) win->internal.mod |= mod; else win->internal.mod &= ~mod; } -void RGFW_updateKeyModsEx(RGFW_window* win, RGFW_bool capital, RGFW_bool numlock, RGFW_bool control, RGFW_bool alt, RGFW_bool shift, RGFW_bool super, RGFW_bool scroll) { - RGFW_updateKeyMod(win, RGFW_modCapsLock, capital); - RGFW_updateKeyMod(win, RGFW_modNumLock, numlock); - RGFW_updateKeyMod(win, RGFW_modControl, control); - RGFW_updateKeyMod(win, RGFW_modAlt, alt); - RGFW_updateKeyMod(win, RGFW_modShift, shift); - RGFW_updateKeyMod(win, RGFW_modSuper, super); - RGFW_updateKeyMod(win, RGFW_modScrollLock, scroll); +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) { + RGFW_keyUpdateKeyMod(win, RGFW_modCapsLock, capital); + RGFW_keyUpdateKeyMod(win, RGFW_modNumLock, numlock); + RGFW_keyUpdateKeyMod(win, RGFW_modControl, control); + RGFW_keyUpdateKeyMod(win, RGFW_modAlt, alt); + RGFW_keyUpdateKeyMod(win, RGFW_modShift, shift); + RGFW_keyUpdateKeyMod(win, RGFW_modSuper, super); + RGFW_keyUpdateKeyMod(win, RGFW_modScrollLock, scroll); } -void RGFW_updateKeyMods(RGFW_window* win, RGFW_bool capital, RGFW_bool numlock, RGFW_bool scroll) { - RGFW_updateKeyModsEx(win, capital, numlock, - RGFW_window_isKeyDown(win, RGFW_controlL) || RGFW_window_isKeyDown(win, RGFW_controlR), - RGFW_window_isKeyDown(win, RGFW_altL) || RGFW_window_isKeyDown(win, RGFW_altR), - RGFW_window_isKeyDown(win, RGFW_shiftL) || RGFW_window_isKeyDown(win, RGFW_shiftR), - RGFW_window_isKeyDown(win, RGFW_superL) || RGFW_window_isKeyDown(win, RGFW_superR), +void RGFW_keyUpdateKeyMods(RGFW_window* win, RGFW_bool capital, RGFW_bool numlock, RGFW_bool scroll) { + RGFW_keyUpdateKeyModsEx(win, capital, numlock, + RGFW_isKeyDown(RGFW_keyControlL) || RGFW_isKeyDown(RGFW_keyControlR), + RGFW_isKeyDown(RGFW_keyAltL) || RGFW_isKeyDown(RGFW_keyAltR), + RGFW_isKeyDown(RGFW_keyShiftL) || RGFW_isKeyDown(RGFW_keyShiftR), + RGFW_isKeyDown(RGFW_keySuperL) || RGFW_isKeyDown(RGFW_keySuperR), scroll); } @@ -4799,27 +4860,39 @@ RGFW_bool RGFW_window_borderless(RGFW_window* win) { RGFW_bool RGFW_window_isFullscreen(RGFW_window* win){ return RGFW_BOOL(win->internal.flags & RGFW_windowFullscreen); } RGFW_bool RGFW_window_allowsDND(RGFW_window* win) { return RGFW_BOOL(win->internal.flags & RGFW_windowAllowDND); } +RGFW_bool RGFW_window_setMouseDefault(RGFW_window* win) { + return RGFW_window_setMouseStandard(win, RGFW_mouseNormal); +} + +RGFW_bool RGFW_window_setMouseStandard(RGFW_window* win, RGFW_mouseIcon icon) { + RGFW_ASSERT(win); + RGFW_ASSERT(icon < RGFW_mouseIconCount); + return RGFW_window_setMouse(win, _RGFW->standardMice[icon]); +} + +RGFW_bool RGFW_window_setMouse(RGFW_window* win, RGFW_mouse* mouse) { + RGFW_ASSERT(win && mouse); + if (mouse != _RGFW->hiddenMouse) { + win->internal.mouse = mouse; + } + + return RGFW_window_setMousePlatform(win, mouse); +} + #ifndef RGFW_WINDOWS void RGFW_window_setDND(RGFW_window* win, RGFW_bool allow) { RGFW_setBit(&win->internal.flags, RGFW_windowAllowDND, allow); } #endif -#if defined(RGFW_X11) || defined(RGFW_MACOS) || defined(RGFW_WASM) || defined(RGFW_WAYLAND) -#ifndef __USE_POSIX199309 - #define __USE_POSIX199309 -#endif -#include -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); - if (show == RGFW_FALSE) + if (show == RGFW_FALSE) { RGFW_window_setMouse(win, _RGFW->hiddenMouse); - else - RGFW_window_setMouseDefault(win); + } else { + RGFW_window_setMouse(win, win->internal.mouse); + } } #endif @@ -5038,7 +5111,6 @@ void RGFW_attribStack_pushAttribs(RGFW_attribStack* stack, i32 attrib1, i32 attr /* EGL */ #ifdef RGFW_EGL -#include #include PFNEGLINITIALIZEPROC RGFW_eglInitialize; @@ -5322,7 +5394,7 @@ RGFW_bool RGFW_window_createContextPtr_EGL(RGFW_window* win, RGFW_eglContext* ct if (visualID) { desired.visualid = (VisualID)visualID; result = XGetVisualInfo(_RGFW->display, VisualIDMask, &desired, &count); - } else RGFW_sendDebugInfo(RGFW_typeError, RGFW_errEGLContext, "Failed to fetch a valid EGL VisualID"); + } else RGFW_debugCallback(RGFW_typeError, RGFW_errEGLContext, "Failed to fetch a valid EGL VisualID"); if (result == NULL || count == 0) { if (win->src.window == 0) { @@ -5330,7 +5402,7 @@ RGFW_bool RGFW_window_createContextPtr_EGL(RGFW_window* win, RGFW_eglContext* ct win->internal.flags &= ~(u32)RGFW_windowEGL; RGFW_createWindowPlatform("", win->internal.flags, win); } - RGFW_sendDebugInfo(RGFW_typeError, RGFW_errEGLContext, "Failed to find a valid visual for the EGL config"); + RGFW_debugCallback(RGFW_typeError, RGFW_errEGLContext, "Failed to find a valid visual for the EGL config"); } else { RGFW_bool showWindow = RGFW_FALSE; if (win->src.window) { @@ -5407,7 +5479,7 @@ RGFW_bool RGFW_window_createContextPtr_EGL(RGFW_window* win, RGFW_eglContext* ct #endif if (win->src.ctx.egl->surface == NULL) { - RGFW_sendDebugInfo(RGFW_typeError, RGFW_errEGLContext, "Failed to create an EGL surface."); + RGFW_debugCallback(RGFW_typeError, RGFW_errEGLContext, "Failed to create an EGL surface."); return RGFW_FALSE; } @@ -5458,13 +5530,13 @@ RGFW_bool RGFW_window_createContextPtr_EGL(RGFW_window* win, RGFW_eglContext* ct win->src.ctx.egl->ctx = RGFW_eglCreateContext(_RGFW->EGL_display, config, hints->shareEGL, attribs); if (win->src.ctx.egl->ctx == NULL) { - RGFW_sendDebugInfo(RGFW_typeError, RGFW_errEGLContext, "Failed to create an EGL context."); + RGFW_debugCallback(RGFW_typeError, RGFW_errEGLContext, "Failed to create an EGL context."); return RGFW_FALSE; } 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_sendDebugInfo(RGFW_typeInfo, RGFW_infoOpenGL, "EGL context initalized."); + RGFW_debugCallback(RGFW_typeInfo, RGFW_infoOpenGL, "EGL context initalized."); return RGFW_TRUE; } @@ -5478,11 +5550,11 @@ void RGFW_window_deleteContextPtr_EGL(RGFW_window* win, RGFW_eglContext* ctx) { RGFW_eglDestroySurface(_RGFW->EGL_display, ctx->surface); RGFW_eglDestroyContext(_RGFW->EGL_display, ctx->ctx); - RGFW_sendDebugInfo(RGFW_typeInfo, RGFW_infoOpenGL, "EGL context freed"); + 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_sendDebugInfo(RGFW_typeInfo, RGFW_infoOpenGL, "EGL window context freed"); + RGFW_debugCallback(RGFW_typeInfo, RGFW_infoOpenGL, "EGL window context freed"); #endif win->src.ctx.egl = NULL; } @@ -5632,9 +5704,11 @@ This is where OS specific stuff starts /* start of unix (wayland or X11 (unix) ) defines */ #ifdef RGFW_UNIX + #include #include #include +#include void RGFW_stopCheckEvents(void) { @@ -5746,7 +5820,7 @@ void RGFW_waitForEvent(i32 waitMS) { /* drain any data in the stop request */ if (_RGFW->eventWait_forceStop[2]) { char data[64]; - RGFW_MEMSET(data, 0, sizeof(data)); + RGFW_MEMZERO(data, sizeof(data)); (void)!read(_RGFW->eventWait_forceStop[0], data, sizeof(data)); _RGFW->eventWait_forceStop[2] = 0; @@ -5826,129 +5900,129 @@ void RGFW_load_Wayland(void) { } * We can't use linux enums, because the headers don't exist on BSD */ void RGFW_initKeycodesPlatform(void) { - _RGFW->keycodes[49] = RGFW_backtick; - _RGFW->keycodes[19] = RGFW_0; - _RGFW->keycodes[10] = RGFW_1; - _RGFW->keycodes[11] = RGFW_2; - _RGFW->keycodes[12] = RGFW_3; - _RGFW->keycodes[13] = RGFW_4; - _RGFW->keycodes[14] = RGFW_5; - _RGFW->keycodes[15] = RGFW_6; - _RGFW->keycodes[16] = RGFW_7; - _RGFW->keycodes[17] = RGFW_8; - _RGFW->keycodes[18] = RGFW_9; - _RGFW->keycodes[65] = RGFW_space; - _RGFW->keycodes[38] = RGFW_a; - _RGFW->keycodes[56] = RGFW_b; - _RGFW->keycodes[54] = RGFW_c; - _RGFW->keycodes[40] = RGFW_d; - _RGFW->keycodes[26] = RGFW_e; - _RGFW->keycodes[41] = RGFW_f; - _RGFW->keycodes[42] = RGFW_g; - _RGFW->keycodes[43] = RGFW_h; - _RGFW->keycodes[31] = RGFW_i; - _RGFW->keycodes[44] = RGFW_j; - _RGFW->keycodes[45] = RGFW_k; - _RGFW->keycodes[46] = RGFW_l; - _RGFW->keycodes[58] = RGFW_m; - _RGFW->keycodes[57] = RGFW_n; - _RGFW->keycodes[32] = RGFW_o; - _RGFW->keycodes[33] = RGFW_p; - _RGFW->keycodes[24] = RGFW_q; - _RGFW->keycodes[27] = RGFW_r; - _RGFW->keycodes[39] = RGFW_s; - _RGFW->keycodes[28] = RGFW_t; - _RGFW->keycodes[30] = RGFW_u; - _RGFW->keycodes[55] = RGFW_v; - _RGFW->keycodes[25] = RGFW_w; - _RGFW->keycodes[53] = RGFW_x; - _RGFW->keycodes[29] = RGFW_y; - _RGFW->keycodes[52] = RGFW_z; - _RGFW->keycodes[60] = RGFW_period; - _RGFW->keycodes[59] = RGFW_comma; - _RGFW->keycodes[61] = RGFW_slash; - _RGFW->keycodes[34] = RGFW_bracket; - _RGFW->keycodes[35] = RGFW_closeBracket; - _RGFW->keycodes[47] = RGFW_semicolon; - _RGFW->keycodes[48] = RGFW_apostrophe; - _RGFW->keycodes[51] = RGFW_backSlash; - _RGFW->keycodes[36] = RGFW_return; - _RGFW->keycodes[119] = RGFW_delete; - _RGFW->keycodes[77] = RGFW_numLock; - _RGFW->keycodes[106] = RGFW_kpSlash; - _RGFW->keycodes[63] = RGFW_kpMultiply; - _RGFW->keycodes[86] = RGFW_kpPlus; - _RGFW->keycodes[82] = RGFW_kpMinus; - _RGFW->keycodes[87] = RGFW_kp1; - _RGFW->keycodes[88] = RGFW_kp2; - _RGFW->keycodes[89] = RGFW_kp3; - _RGFW->keycodes[83] = RGFW_kp4; - _RGFW->keycodes[84] = RGFW_kp5; - _RGFW->keycodes[85] = RGFW_kp6; - _RGFW->keycodes[81] = RGFW_kp9; - _RGFW->keycodes[90] = RGFW_kp0; - _RGFW->keycodes[91] = RGFW_kpPeriod; - _RGFW->keycodes[104] = RGFW_kpReturn; - _RGFW->keycodes[20] = RGFW_minus; - _RGFW->keycodes[21] = RGFW_equals; - _RGFW->keycodes[22] = RGFW_backSpace; - _RGFW->keycodes[23] = RGFW_tab; - _RGFW->keycodes[66] = RGFW_capsLock; - _RGFW->keycodes[50] = RGFW_shiftL; - _RGFW->keycodes[37] = RGFW_controlL; - _RGFW->keycodes[64] = RGFW_altL; - _RGFW->keycodes[133] = RGFW_superL; - _RGFW->keycodes[105] = RGFW_controlR; - _RGFW->keycodes[134] = RGFW_superR; - _RGFW->keycodes[62] = RGFW_shiftR; - _RGFW->keycodes[108] = RGFW_altR; - _RGFW->keycodes[67] = RGFW_F1; - _RGFW->keycodes[68] = RGFW_F2; - _RGFW->keycodes[69] = RGFW_F3; - _RGFW->keycodes[70] = RGFW_F4; - _RGFW->keycodes[71] = RGFW_F5; - _RGFW->keycodes[72] = RGFW_F6; - _RGFW->keycodes[73] = RGFW_F7; - _RGFW->keycodes[74] = RGFW_F8; - _RGFW->keycodes[75] = RGFW_F9; - _RGFW->keycodes[76] = RGFW_F10; - _RGFW->keycodes[95] = RGFW_F11; - _RGFW->keycodes[96] = RGFW_F12; - _RGFW->keycodes[111] = RGFW_up; - _RGFW->keycodes[116] = RGFW_down; - _RGFW->keycodes[113] = RGFW_left; - _RGFW->keycodes[114] = RGFW_right; - _RGFW->keycodes[118] = RGFW_insert; - _RGFW->keycodes[115] = RGFW_end; - _RGFW->keycodes[112] = RGFW_pageUp; - _RGFW->keycodes[117] = RGFW_pageDown; - _RGFW->keycodes[9] = RGFW_escape; - _RGFW->keycodes[110] = RGFW_home; - _RGFW->keycodes[78] = RGFW_scrollLock; - _RGFW->keycodes[107] = RGFW_printScreen; - _RGFW->keycodes[128] = RGFW_pause; - _RGFW->keycodes[191] = RGFW_F13; - _RGFW->keycodes[192] = RGFW_F14; - _RGFW->keycodes[193] = RGFW_F15; - _RGFW->keycodes[194] = RGFW_F16; - _RGFW->keycodes[195] = RGFW_F17; - _RGFW->keycodes[196] = RGFW_F18; - _RGFW->keycodes[197] = RGFW_F19; - _RGFW->keycodes[198] = RGFW_F20; - _RGFW->keycodes[199] = RGFW_F21; - _RGFW->keycodes[200] = RGFW_F22; - _RGFW->keycodes[201] = RGFW_F23; - _RGFW->keycodes[202] = RGFW_F24; - _RGFW->keycodes[203] = RGFW_F25; - _RGFW->keycodes[142] = RGFW_kpEqual; - _RGFW->keycodes[161] = RGFW_world1; /* non-US key #1 */ - _RGFW->keycodes[162] = RGFW_world2; /* non-US key #2 */ + _RGFW->keycodes[49] = RGFW_keyBacktick; + _RGFW->keycodes[19] = RGFW_key0; + _RGFW->keycodes[10] = RGFW_key1; + _RGFW->keycodes[11] = RGFW_key2; + _RGFW->keycodes[12] = RGFW_key3; + _RGFW->keycodes[13] = RGFW_key4; + _RGFW->keycodes[14] = RGFW_key5; + _RGFW->keycodes[15] = RGFW_key6; + _RGFW->keycodes[16] = RGFW_key7; + _RGFW->keycodes[17] = RGFW_key8; + _RGFW->keycodes[18] = RGFW_key9; + _RGFW->keycodes[65] = RGFW_keySpace; + _RGFW->keycodes[38] = RGFW_keyA; + _RGFW->keycodes[56] = RGFW_keyB; + _RGFW->keycodes[54] = RGFW_keyC; + _RGFW->keycodes[40] = RGFW_keyD; + _RGFW->keycodes[26] = RGFW_keyE; + _RGFW->keycodes[41] = RGFW_keyF; + _RGFW->keycodes[42] = RGFW_keyG; + _RGFW->keycodes[43] = RGFW_keyH; + _RGFW->keycodes[31] = RGFW_keyI; + _RGFW->keycodes[44] = RGFW_keyJ; + _RGFW->keycodes[45] = RGFW_keyK; + _RGFW->keycodes[46] = RGFW_keyL; + _RGFW->keycodes[58] = RGFW_keyM; + _RGFW->keycodes[57] = RGFW_keyN; + _RGFW->keycodes[32] = RGFW_keyO; + _RGFW->keycodes[33] = RGFW_keyP; + _RGFW->keycodes[24] = RGFW_keyQ; + _RGFW->keycodes[27] = RGFW_keyR; + _RGFW->keycodes[39] = RGFW_keyS; + _RGFW->keycodes[28] = RGFW_keyT; + _RGFW->keycodes[30] = RGFW_keyU; + _RGFW->keycodes[55] = RGFW_keyV; + _RGFW->keycodes[25] = RGFW_keyW; + _RGFW->keycodes[53] = RGFW_keyX; + _RGFW->keycodes[29] = RGFW_keyY; + _RGFW->keycodes[52] = RGFW_keyZ; + _RGFW->keycodes[60] = RGFW_keyPeriod; + _RGFW->keycodes[59] = RGFW_keyComma; + _RGFW->keycodes[61] = RGFW_keySlash; + _RGFW->keycodes[34] = RGFW_keyBracket; + _RGFW->keycodes[35] = RGFW_keyCloseBracket; + _RGFW->keycodes[47] = RGFW_keySemicolon; + _RGFW->keycodes[48] = RGFW_keyApostrophe; + _RGFW->keycodes[51] = RGFW_keyBackSlash; + _RGFW->keycodes[36] = RGFW_keyReturn; + _RGFW->keycodes[119] = RGFW_keyDelete; + _RGFW->keycodes[77] = RGFW_keyNumLock; + _RGFW->keycodes[106] = RGFW_keyPadSlash; + _RGFW->keycodes[63] = RGFW_keyPadMultiply; + _RGFW->keycodes[86] = RGFW_keyPadPlus; + _RGFW->keycodes[82] = RGFW_keyPadMinus; + _RGFW->keycodes[87] = RGFW_keyPad1; + _RGFW->keycodes[88] = RGFW_keyPad2; + _RGFW->keycodes[89] = RGFW_keyPad3; + _RGFW->keycodes[83] = RGFW_keyPad4; + _RGFW->keycodes[84] = RGFW_keyPad5; + _RGFW->keycodes[85] = RGFW_keyPad6; + _RGFW->keycodes[81] = RGFW_keyPad9; + _RGFW->keycodes[90] = RGFW_keyPad0; + _RGFW->keycodes[91] = RGFW_keyPadPeriod; + _RGFW->keycodes[104] = RGFW_keyPadReturn; + _RGFW->keycodes[20] = RGFW_keyMinus; + _RGFW->keycodes[21] = RGFW_keyEquals; + _RGFW->keycodes[22] = RGFW_keyBackSpace; + _RGFW->keycodes[23] = RGFW_keyTab; + _RGFW->keycodes[66] = RGFW_keyCapsLock; + _RGFW->keycodes[50] = RGFW_keyShiftL; + _RGFW->keycodes[37] = RGFW_keyControlL; + _RGFW->keycodes[64] = RGFW_keyAltL; + _RGFW->keycodes[133] = RGFW_keySuperL; + _RGFW->keycodes[105] = RGFW_keyControlR; + _RGFW->keycodes[134] = RGFW_keySuperR; + _RGFW->keycodes[62] = RGFW_keyShiftR; + _RGFW->keycodes[108] = RGFW_keyAltR; + _RGFW->keycodes[67] = RGFW_keyF1; + _RGFW->keycodes[68] = RGFW_keyF2; + _RGFW->keycodes[69] = RGFW_keyF3; + _RGFW->keycodes[70] = RGFW_keyF4; + _RGFW->keycodes[71] = RGFW_keyF5; + _RGFW->keycodes[72] = RGFW_keyF6; + _RGFW->keycodes[73] = RGFW_keyF7; + _RGFW->keycodes[74] = RGFW_keyF8; + _RGFW->keycodes[75] = RGFW_keyF9; + _RGFW->keycodes[76] = RGFW_keyF10; + _RGFW->keycodes[95] = RGFW_keyF11; + _RGFW->keycodes[96] = RGFW_keyF12; + _RGFW->keycodes[111] = RGFW_keyUp; + _RGFW->keycodes[116] = RGFW_keyDown; + _RGFW->keycodes[113] = RGFW_keyLeft; + _RGFW->keycodes[114] = RGFW_keyRight; + _RGFW->keycodes[118] = RGFW_keyInsert; + _RGFW->keycodes[115] = RGFW_keyEnd; + _RGFW->keycodes[112] = RGFW_keyPageUp; + _RGFW->keycodes[117] = RGFW_keyPageDown; + _RGFW->keycodes[9] = RGFW_keyEscape; + _RGFW->keycodes[110] = RGFW_keyHome; + _RGFW->keycodes[78] = RGFW_keyScrollLock; + _RGFW->keycodes[107] = RGFW_keyPrintScreen; + _RGFW->keycodes[128] = RGFW_keyPause; + _RGFW->keycodes[191] = RGFW_keyF13; + _RGFW->keycodes[192] = RGFW_keyF14; + _RGFW->keycodes[193] = RGFW_keyF15; + _RGFW->keycodes[194] = RGFW_keyF16; + _RGFW->keycodes[195] = RGFW_keyF17; + _RGFW->keycodes[196] = RGFW_keyF18; + _RGFW->keycodes[197] = RGFW_keyF19; + _RGFW->keycodes[198] = RGFW_keyF20; + _RGFW->keycodes[199] = RGFW_keyF21; + _RGFW->keycodes[200] = RGFW_keyF22; + _RGFW->keycodes[201] = RGFW_keyF23; + _RGFW->keycodes[202] = RGFW_keyF24; + _RGFW->keycodes[203] = RGFW_keyF25; + _RGFW->keycodes[142] = RGFW_keyPadEqual; + _RGFW->keycodes[161] = RGFW_keyWorld1; /* non-US key #1 */ + _RGFW->keycodes[162] = RGFW_keyWorld2; /* non-US key #2 */ } i32 RGFW_initPlatform(void) { #if defined(_POSIX_MONOTONIC_CLOCK) struct timespec ts; - RGFW_MEMSET(&ts, 0, sizeof(struct timespec)); + RGFW_MEMZERO(&ts, sizeof(struct timespec)); if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0) _RGFW->clock = CLOCK_MONOTONIC; @@ -5963,7 +6037,7 @@ i32 RGFW_initPlatform(void) { return 0; } else { #ifdef RGFW_X11 - RGFW_sendDebugInfo(RGFW_typeWarning, RGFW_warningWayland, "Falling back to X11"); + RGFW_debugCallback(RGFW_typeWarning, RGFW_warningWayland, "Falling back to X11"); RGFW_useWayland(0); #else return ret; @@ -6002,6 +6076,62 @@ size_t RGFW_unix_stringlen(const char* name) { return i; } +RGFWDEF void RGFW_unix_parseURI(RGFW_window* win, char* data); +void RGFW_unix_parseURI(RGFW_window* win, char* data) { + const char* prefix = (const char*)"file://"; + char* line; + while ((line = (char*)RGFW_strtok(data, "\r\n"))) { + data = NULL; + + if (line[0] == '#') + continue; + + char* l; + for (l = line; 1; l++) { + if ((l - line) > 7) + break; + else if (*l != prefix[(l - line)]) + break; + else if (*l == '\0' && prefix[(l - line)] == '\0') { + line += 7; + while (*line != '/') + line++; + break; + } else if (*l == '\0') + break; + } + + size_t len = RGFW_unix_stringlen(line); + char* path = (char*)RGFW_ALLOC(len + 1); + + size_t index = 0; + while (*line) { + if (line[0] == '%' && line[1] && line[2]) { + char digits[3] = {0}; + digits[0] = line[1]; + digits[1] = line[2]; + digits[2] = '\0'; + path[index] = (char) RGFW_STRTOL(digits, NULL, 16); + line += 2; + } else { + if (index >= len) { + break; + } + + path[index] = *line; + } + + index++; + line++; + } + + path[len] = '\0'; + RGFW_dataDropCallback(win, (const char*)path, len + 1, RGFW_dataFile); + RGFW_FREE(path); + } +} + + #endif /* end of wayland or X11 defines */ @@ -6229,7 +6359,7 @@ RGFW_bool RGFW_window_createSurfacePtr(RGFW_window* win, u8* data, i32 w, i32 h, XWindowAttributes attrs; if (XGetWindowAttributes(_RGFW->display, win->src.window, &attrs) == 0) { - RGFW_sendDebugInfo(RGFW_typeError, RGFW_errBuffer, "Failed to get window attributes."); + RGFW_debugCallback(RGFW_typeError, RGFW_errBuffer, "Failed to get window attributes."); return RGFW_FALSE; } @@ -6240,7 +6370,7 @@ RGFW_bool RGFW_window_createSurfacePtr(RGFW_window* win, u8* data, i32 w, i32 h, surface->native.format = RGFW_XImage_getFormat(surface->native.bitmap); if (surface->native.bitmap == NULL) { - RGFW_sendDebugInfo(RGFW_typeError, RGFW_errBuffer, "Failed to create XImage."); + RGFW_debugCallback(RGFW_typeError, RGFW_errBuffer, "Failed to create XImage."); return RGFW_FALSE; } @@ -6295,7 +6425,17 @@ void RGFW_FUNC(RGFW_window_setBorder) (RGFW_window* win, RGFW_bool border) { } 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) { @@ -6320,7 +6460,7 @@ void RGFW_window_getVisual(XVisualInfo* visual, RGFW_bool transparent) { if (transparent) { XMatchVisualInfo(_RGFW->display, DefaultScreen(_RGFW->display), 32, TrueColor, visual); /*!< for RGBA backgrounds */ if (visual->depth != 32) - RGFW_sendDebugInfo(RGFW_typeWarning, RGFW_warningOpenGL, "Failed to load a 32-bit depth."); + RGFW_debugCallback(RGFW_typeWarning, RGFW_warningOpenGL, "Failed to load a 32-bit depth."); } } @@ -6334,7 +6474,7 @@ int RGFW_XErrorHandler(Display* display, XErrorEvent* ev) { errorText, ev->error_code, ev->request_code, ev->minor_code, ev->serial); - RGFW_sendDebugInfo(RGFW_typeError, RGFW_errX11, buf); + RGFW_debugCallback(RGFW_typeError, RGFW_errX11, buf); _RGFW->x11Error = ev; return 0; } @@ -6345,7 +6485,7 @@ void RGFW_XCreateWindow (XVisualInfo visual, const char* name, RGFW_windowFlags /* make X window attrubutes */ XSetWindowAttributes swa; - RGFW_MEMSET(&swa, 0, sizeof(swa)); + RGFW_MEMZERO(&swa, sizeof(swa)); win->src.parent = DefaultRootWindow(_RGFW->display); @@ -6398,9 +6538,6 @@ void RGFW_XCreateWindow (XVisualInfo visual, const char* name, RGFW_windowFlags XSetWMHints(_RGFW->display, win->src.window, &hints); - if (flags & RGFW_windowScaleToMonitor) - RGFW_window_scaleToMonitor(win); - 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 */ @@ -6553,71 +6690,71 @@ RGFW_key RGFW_FUNC(RGFW_physicalToMappedKey) (RGFW_key key) { } switch (sym) { - case XK_F1: return RGFW_F1; - case XK_F2: return RGFW_F2; - case XK_F3: return RGFW_F3; - case XK_F4: return RGFW_F4; - case XK_F5: return RGFW_F5; - case XK_F6: return RGFW_F6; - case XK_F7: return RGFW_F7; - case XK_F8: return RGFW_F8; - case XK_F9: return RGFW_F9; - case XK_F10: return RGFW_F10; - case XK_F11: return RGFW_F11; - case XK_F12: return RGFW_F12; - case XK_F13: return RGFW_F13; - case XK_F14: return RGFW_F14; - case XK_F15: return RGFW_F15; - case XK_F16: return RGFW_F16; - case XK_F17: return RGFW_F17; - case XK_F18: return RGFW_F18; - case XK_F19: return RGFW_F19; - case XK_F20: return RGFW_F20; - case XK_F21: return RGFW_F21; - case XK_F22: return RGFW_F22; - case XK_F23: return RGFW_F23; - case XK_F24: return RGFW_F24; - case XK_F25: return RGFW_F25; - case XK_Shift_L: return RGFW_shiftL; - case XK_Shift_R: return RGFW_shiftR; - case XK_Control_L: return RGFW_controlL; - case XK_Control_R: return RGFW_controlR; - case XK_Alt_L: return RGFW_altL; - case XK_Alt_R: return RGFW_altR; - case XK_Super_L: return RGFW_superL; - case XK_Super_R: return RGFW_superR; - case XK_Caps_Lock: return RGFW_capsLock; - case XK_Num_Lock: return RGFW_numLock; - case XK_Scroll_Lock:return RGFW_scrollLock; - case XK_Up: return RGFW_up; - case XK_Down: return RGFW_down; - case XK_Left: return RGFW_left; - case XK_Right: return RGFW_right; - case XK_Home: return RGFW_home; - case XK_End: return RGFW_end; - case XK_Page_Up: return RGFW_pageUp; - case XK_Page_Down: return RGFW_pageDown; - case XK_Insert: return RGFW_insert; - case XK_Menu: return RGFW_menu; - case XK_KP_Add: return RGFW_kpPlus; - case XK_KP_Subtract: return RGFW_kpMinus; - case XK_KP_Multiply: return RGFW_kpMultiply; - case XK_KP_Divide: return RGFW_kpSlash; - case XK_KP_Equal: return RGFW_kpEqual; - case XK_KP_Enter: return RGFW_kpReturn; - case XK_KP_Decimal: return RGFW_kpPeriod; - case XK_KP_0: return RGFW_kp0; - case XK_KP_1: return RGFW_kp1; - case XK_KP_2: return RGFW_kp2; - case XK_KP_3: return RGFW_kp3; - case XK_KP_4: return RGFW_kp4; - case XK_KP_5: return RGFW_kp5; - case XK_KP_6: return RGFW_kp6; - case XK_KP_7: return RGFW_kp7; - case XK_KP_8: return RGFW_kp8; - case XK_KP_9: return RGFW_kp9; - case XK_Print: return RGFW_printScreen; - case XK_Pause: return RGFW_pause; + case XK_F1: return RGFW_keyF1; + case XK_F2: return RGFW_keyF2; + case XK_F3: return RGFW_keyF3; + case XK_F4: return RGFW_keyF4; + case XK_F5: return RGFW_keyF5; + case XK_F6: return RGFW_keyF6; + case XK_F7: return RGFW_keyF7; + case XK_F8: return RGFW_keyF8; + case XK_F9: return RGFW_keyF9; + case XK_F10: return RGFW_keyF10; + case XK_F11: return RGFW_keyF11; + case XK_F12: return RGFW_keyF12; + case XK_F13: return RGFW_keyF13; + case XK_F14: return RGFW_keyF14; + case XK_F15: return RGFW_keyF15; + case XK_F16: return RGFW_keyF16; + case XK_F17: return RGFW_keyF17; + case XK_F18: return RGFW_keyF18; + case XK_F19: return RGFW_keyF19; + case XK_F20: return RGFW_keyF20; + case XK_F21: return RGFW_keyF21; + case XK_F22: return RGFW_keyF22; + case XK_F23: return RGFW_keyF23; + case XK_F24: return RGFW_keyF24; + case XK_F25: return RGFW_keyF25; + case XK_Shift_L: return RGFW_keyShiftL; + case XK_Shift_R: return RGFW_keyShiftR; + case XK_Control_L: return RGFW_keyControlL; + case XK_Control_R: return RGFW_keyControlR; + case XK_Alt_L: return RGFW_keyAltL; + case XK_Alt_R: return RGFW_keyAltR; + case XK_Super_L: return RGFW_keySuperL; + case XK_Super_R: return RGFW_keySuperR; + case XK_Caps_Lock: return RGFW_keyCapsLock; + case XK_Num_Lock: return RGFW_keyNumLock; + case XK_Scroll_Lock:return RGFW_keyScrollLock; + case XK_Up: return RGFW_keyUp; + case XK_Down: return RGFW_keyDown; + case XK_Left: return RGFW_keyLeft; + case XK_Right: return RGFW_keyRight; + case XK_Home: return RGFW_keyHome; + case XK_End: return RGFW_keyEnd; + case XK_Page_Up: return RGFW_keyPageUp; + case XK_Page_Down: return RGFW_keyPageDown; + case XK_Insert: return RGFW_keyInsert; + case XK_Menu: return RGFW_keyMenu; + case XK_KP_Add: return RGFW_keyPadPlus; + case XK_KP_Subtract: return RGFW_keyPadMinus; + case XK_KP_Multiply: return RGFW_keyPadMultiply; + case XK_KP_Divide: return RGFW_keyPadSlash; + case XK_KP_Equal: return RGFW_keyPadEqual; + case XK_KP_Enter: return RGFW_keyPadReturn; + case XK_KP_Decimal: return RGFW_keyPadPeriod; + case XK_KP_0: return RGFW_keyPad0; + case XK_KP_1: return RGFW_keyPad1; + case XK_KP_2: return RGFW_keyPad2; + case XK_KP_3: return RGFW_keyPad3; + case XK_KP_4: return RGFW_keyPad4; + case XK_KP_5: return RGFW_keyPad5; + case XK_KP_6: return RGFW_keyPad6; + case XK_KP_7: return RGFW_keyPad7; + case XK_KP_8: return RGFW_keyPad8; + case XK_KP_9: return RGFW_keyPad9; + case XK_Print: return RGFW_keyPrintScreen; + case XK_Pause: return RGFW_keyPause; default: break; } @@ -6640,15 +6777,9 @@ void RGFW_XHandleEvent(void) { RGFW_LOAD_ATOM(WM_STATE); RGFW_LOAD_ATOM(_NET_WM_STATE); - /* xdnd data */ - static Window source = 0; - static long version = 0; - static i32 format = 0; - static float deltaX = 0.0f; static float deltaY = 0.0f; - XEvent reply = { ClientMessage }; XEvent E; XNextEvent(_RGFW->display, &E); @@ -6658,12 +6789,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: @@ -6690,6 +6819,7 @@ void RGFW_XHandleEvent(void) { _RGFW->vectorX = (float)deltaX; _RGFW->vectorY = (float)deltaY; + RGFW_rawMotionCallback(_RGFW->root, _RGFW->vectorX, _RGFW->vectorY); } default: break; } @@ -6735,7 +6865,7 @@ void RGFW_XHandleEvent(void) { XkbStateRec state; XkbGetState(_RGFW->display, XkbUseCoreKbd, &state); - RGFW_updateKeyMods(win, (state.locked_mods & LockMask), (state.locked_mods & Mod2Mask), (state.locked_mods & Mod3Mask)); + RGFW_keyUpdateKeyMods(win, (state.locked_mods & LockMask), (state.locked_mods & Mod2Mask), (state.locked_mods & Mod3Mask)); if (win->src.ic && XFilterEvent(&E, None) == False) { char buffer[100]; @@ -6784,9 +6914,9 @@ void RGFW_XHandleEvent(void) { XkbStateRec state; XkbGetState(_RGFW->display, XkbUseCoreKbd, &state); - RGFW_updateKeyMods(win, (state.locked_mods & LockMask), (state.locked_mods & Mod2Mask), (state.locked_mods & Mod3Mask)); + RGFW_keyUpdateKeyMods(win, (state.locked_mods & LockMask), (state.locked_mods & Mod2Mask), (state.locked_mods & Mod3Mask)); - RGFW_keyCallback(win, value, win->internal.mod, keyRepeat, RGFW_FALSE); + RGFW_keyCallback(win, value, win->internal.mod, RGFW_FALSE, RGFW_FALSE); break; } case ButtonPress: { @@ -6837,11 +6967,11 @@ void RGFW_XHandleEvent(void) { break; } case MotionNotify: - RGFW_mousePosCallback(win, E.xmotion.x, E.xmotion.y, _RGFW->vectorX, _RGFW->vectorY); + RGFW_mouseMotionCallback(win, E.xmotion.x, E.xmotion.y); break; case Expose: { - RGFW_windowRefreshCallback(win); + RGFW_windowRefreshCallback(win, E.xexpose.x, E.xexpose.y, E.xexpose.width, E.xexpose.height); #ifdef RGFW_ADVANCED_SMOOTH_RESIZE XSyncValue value; @@ -6873,12 +7003,12 @@ void RGFW_XHandleEvent(void) { RGFW_LOAD_ATOM(WM_DELETE_WINDOW); /* if the client closed the window */ if (E.xclient.data.l[0] == (long)WM_DELETE_WINDOW) { - RGFW_windowQuitCallback(win); + 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) { - RGFW_windowRefreshCallback(win); + RGFW_windowRefreshCallback(win, 0, 0, win->w, win->h); win->src.counter_value = 0; win->src.counter_value |= E.xclient.data.l[2]; win->src.counter_value |= (E.xclient.data.l[3] << 32); @@ -6889,37 +7019,29 @@ void RGFW_XHandleEvent(void) { break; } #endif - if ((win->internal.flags & RGFW_windowAllowDND) == 0) + if ((win->internal.flags & RGFW_windowAllowDND) == 0 || _RGFW->x11Version > RGFW_XDND_VERSION) { return; + } i32 dragX = 0; i32 dragY = 0; - reply.xclient.window = source; - reply.xclient.format = 32; - reply.xclient.data.l[0] = (long)win->src.window; - reply.xclient.data.l[1] = 0; - reply.xclient.data.l[2] = None; - if (E.xclient.message_type == XdndEnter) { - if (version > 5) - break; - unsigned long count; Atom* formats; - Atom real_formats[6]; + Atom real_formats[3]; Bool list = E.xclient.data.l[1] & 1; - source = (unsigned long int)E.xclient.data.l[0]; - version = E.xclient.data.l[1] >> 24; - format = None; + _RGFW->x11Source = (Window)E.xclient.data.l[0]; + _RGFW->x11Version = E.xclient.data.l[1] >> 24; + _RGFW->x11Format = None; if (list) { Atom actualType; i32 actualFormat; unsigned long bytesAfter; XGetWindowProperty( - _RGFW->display, source, XdndTypeList, + _RGFW->display, _RGFW->x11Source, XdndTypeList, 0, LONG_MAX, False, 4, &actualType, &actualFormat, &count, &bytesAfter, (u8**)&formats ); @@ -6927,7 +7049,7 @@ void RGFW_XHandleEvent(void) { count = 0; size_t i; - for (i = 2; i < 5; i++) { + for (i = 2; i < (2 + 3); i++) { if (E.xclient.data.l[i] != None) { real_formats[count] = (unsigned long int)E.xclient.data.l[i]; count += 1; @@ -6942,28 +7064,26 @@ void RGFW_XHandleEvent(void) { size_t i; for (i = 0; i < count; i++) { - if (formats[i] == XtextUriList || formats[i] == XtextPlain) { - format = (int)formats[i]; - break; - } + if (formats[i] == XtextUriList) _RGFW->x11TransferType = RGFW_dataFile; + else if (formats[i] == XtextPlain) _RGFW->x11TransferType = RGFW_dataText; + else continue; + + _RGFW->x11Format = (int)formats[i]; + break; } - if (list) { + if (list && formats) { XFree(formats); } - break; - } - if (E.xclient.message_type == XdndPosition) { + RGFW_dataDragCallback(win, _RGFW->x11TransferType , RGFW_dndActionEnter, dragX, dragY); + } else if (E.xclient.message_type == XdndPosition) { const i32 xabs = (E.xclient.data.l[2] >> 16) & 0xffff; const i32 yabs = (E.xclient.data.l[2]) & 0xffff; Window dummy; i32 xpos, ypos; - if (version > 5) - break; - XTranslateCoordinates( _RGFW->display, XDefaultRootWindow(_RGFW->display), win->src.window, xabs, yabs, &xpos, &ypos, &dummy @@ -6972,42 +7092,50 @@ void RGFW_XHandleEvent(void) { dragX = xpos; dragY = ypos; - reply.xclient.window = source; - reply.xclient.message_type = XdndStatus; + RGFW_mouseMotionCallback(win, xpos, ypos); + XEvent reply = { ClientMessage }; + reply.xclient.window = _RGFW->x11Source; + reply.xclient.message_type = XdndStatus; + reply.xclient.format = 32; + reply.xclient.data.l[0] = (long)win->src.window; + reply.xclient.data.l[2] = 0; + reply.xclient.data.l[3] = 0; - if (format) { + if (_RGFW->x11Format) { reply.xclient.data.l[1] = 1; - if (version >= 2) + if (_RGFW->x11Version >= 2) reply.xclient.data.l[4] = (long)XdndActionCopy; } - XSendEvent(_RGFW->display, source, False, NoEventMask, &reply); + XSendEvent(_RGFW->display, _RGFW->x11Source, False, NoEventMask, &reply); XFlush(_RGFW->display); - break; + + + RGFW_dataDragCallback(win, _RGFW->x11TransferType, RGFW_dndActionMove, dragX, dragY); + } else if (E.xclient.message_type == XdndLeave) { + RGFW_dataDragCallback(win, _RGFW->x11TransferType, RGFW_dndActionExit, dragX, dragY); + } else if (E.xclient.message_type == 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 + ); + } else if (_RGFW->x11Version >= 2) { + XEvent reply = { ClientMessage }; + reply.xclient.window = _RGFW->x11Source; + reply.xclient.message_type = XdndFinished; + reply.xclient.format = 32; + reply.xclient.data.l[0] = (long)win->src.window; + reply.xclient.data.l[1] = 0; + reply.xclient.data.l[2] = None; + + XSendEvent(_RGFW->display, _RGFW->x11Source, False, NoEventMask, &reply); + XFlush(_RGFW->display); + } } - if (E.xclient.message_type != XdndDrop) - break; - - if (version > 5) - break; - - if (format) { - Time time = (version >= 1) - ? (Time)E.xclient.data.l[2] - : CurrentTime; - - XConvertSelection( - _RGFW->display, XdndSelection, (Atom)format, - XdndSelection, win->src.window, time - ); - } else if (version >= 2) { - XEvent new_reply = { ClientMessage }; - - XSendEvent(_RGFW->display, source, False, NoEventMask, &new_reply); - XFlush(_RGFW->display); - } - - RGFW_dataDragCallback(win, dragX, dragY); } break; case SelectionNotify: { /* this is only for checking for xdnd drops */ @@ -7022,96 +7150,33 @@ void RGFW_XHandleEvent(void) { XGetWindowProperty(_RGFW->display, E.xselection.requestor, E.xselection.property, 0, LONG_MAX, False, E.xselection.target, &actualType, &actualFormat, &result, &bytesAfter, (u8**) &data); - if (result == 0) - break; + if (result != 0) { + RGFW_unix_parseURI(win, data); - const char* prefix = (const char*)"file://"; - - char* line; - - size_t count = 0; - char** files = _RGFW->files; - - while ((line = (char*)RGFW_strtok(data, "\r\n"))) { - data = NULL; - - if (line[0] == '#') - continue; - - char* l; - for (l = line; 1; l++) { - if ((l - line) > 7) - break; - else if (*l != prefix[(l - line)]) - break; - else if (*l == '\0' && prefix[(l - line)] == '\0') { - line += 7; - while (*line != '/') - line++; - break; - } else if (*l == '\0') - break; - } - - count++; - - size_t len = RGFW_unix_stringlen(line); - char* path = (char*)RGFW_ALLOC(len + 1); - - size_t index = 0; - while (*line) { - if (line[0] == '%' && line[1] && line[2]) { - char digits[3] = {0}; - digits[0] = line[1]; - digits[1] = line[2]; - digits[2] = '\0'; - path[index] = (char) RGFW_STRTOL(digits, NULL, 16); - line += 2; - } else { - if (index >= len) { - break; - } - - path[index] = *line; - } - - index++; - line++; - } - - path[len] = '\0'; - size_t cnt = RGFW_MIN(len + 1, RGFW_MAX_PATH); - if (cnt == RGFW_MAX_PATH) { - path[cnt] = '\0'; - } - - RGFW_MEMCPY(files[count - 1], path, cnt); - RGFW_FREE(path); + if (data) + XFree(data); } - RGFW_dataDropCallback(win, files, count); - if (data) - XFree(data); - - if (version >= 2) { - XEvent new_reply = { ClientMessage }; - new_reply.xclient.window = source; - new_reply.xclient.message_type = XdndFinished; - new_reply.xclient.format = 32; - new_reply.xclient.data.l[1] = (long int)result; - new_reply.xclient.data.l[2] = (long int)XdndActionCopy; - XSendEvent(_RGFW->display, source, False, NoEventMask, &new_reply); + if (_RGFW->x11Version >= 2) { + XEvent reply = { ClientMessage }; + reply.xclient.window = _RGFW->x11Source; + reply.xclient.message_type = 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; + XSendEvent(_RGFW->display, _RGFW->x11Source, False, NoEventMask, &reply); XFlush(_RGFW->display); } break; } case FocusIn: if (win->src.ic) XSetICFocus(win->src.ic); - RGFW_focusCallback(win, 1); + RGFW_windowFocusCallback(win, 1); break; case FocusOut: if (win->src.ic) XUnsetICFocus(win->src.ic); - RGFW_focusCallback(win, 0); + RGFW_windowFocusCallback(win, 0); break; case EnterNotify: { RGFW_mouseNotifyCallback(win, E.xcrossing.x, E.xcrossing.y, RGFW_TRUE); @@ -7162,6 +7227,16 @@ void RGFW_XHandleEvent(void) { XFlush(_RGFW->display); } +RGFW_bool RGFW_FUNC(RGFW_window_fetchSize) (RGFW_window* win, i32* w, i32* h) { + XWindowAttributes attribs; + XGetWindowAttributes(_RGFW->display, win->src.window, &attribs); + + win->w = attribs.width; + win->h = attribs.height; + + return RGFW_window_getSize(win, w, h); +} + void RGFW_FUNC(RGFW_pollEvents) (void) { RGFW_resetPrevState(); @@ -7225,7 +7300,7 @@ void RGFW_FUNC(RGFW_window_setMinSize) (RGFW_window* win, i32 w, i32 h) { long flags; XSizeHints hints; - RGFW_MEMSET(&hints, 0, sizeof(XSizeHints)); + RGFW_MEMZERO(&hints, sizeof(XSizeHints)); XGetWMNormalHints(_RGFW->display, win->src.window, &hints, &flags); @@ -7243,7 +7318,7 @@ void RGFW_FUNC(RGFW_window_setMaxSize) (RGFW_window* win, i32 w, i32 h) { long flags; XSizeHints hints; - RGFW_MEMSET(&hints, 0, sizeof(XSizeHints)); + RGFW_MEMZERO(&hints, sizeof(XSizeHints)); XGetWMNormalHints(_RGFW->display, win->src.window, &hints, &flags); @@ -7284,6 +7359,7 @@ void RGFW_FUNC(RGFW_window_maximize) (RGFW_window* win) { win->internal.oldH = win->h; RGFW_toggleXMaximized(win, 1); + RGFW_window_fetchSize(win, NULL, NULL); return; } @@ -7458,7 +7534,7 @@ RGFW_bool RGFW_FUNC(RGFW_window_setIconEx) (RGFW_window* win, u8* data_src, i32 unsigned long* data = (unsigned long*) RGFW_ALLOC((u32)count * sizeof(unsigned long)); RGFW_ASSERT(data != NULL); - RGFW_MEMSET(data, 0, (u32)count * sizeof(unsigned long)); + RGFW_MEMZERO(data, (u32)count * sizeof(unsigned long)); data[0] = (unsigned long)w; data[1] = (unsigned long)h; @@ -7494,61 +7570,7 @@ RGFW_bool RGFW_FUNC(RGFW_window_setIconEx) (RGFW_window* win, u8* data_src, i32 return RGFW_BOOL(res); } -RGFW_mouse* RGFW_FUNC(RGFW_loadMouse) (u8* data, i32 w, i32 h, RGFW_format format) { - RGFW_ASSERT(data); -#ifndef RGFW_NO_X11_CURSOR - RGFW_init(); - XcursorImage* native = XcursorImageCreate((i32)w, (i32)h); - native->xhot = 0; - native->yhot = 0; - RGFW_MEMSET(native->pixels, 0, (u32)(w * h * 4)); - RGFW_copyImageData((u8*)native->pixels, w, h, RGFW_formatBGRA8, data, format, NULL); - - Cursor cursor = XcursorImageLoadCursor(_RGFW->display, native); - XcursorImageDestroy(native); - - return (void*)cursor; -#else - RGFW_UNUSED(data); RGFW_UNUSED(w); RGFW_UNUSED(h); RGFW_UNUSED(format); - return NULL; -#endif -} - -void RGFW_FUNC(RGFW_window_setMouse)(RGFW_window* win, RGFW_mouse* mouse) { - RGFW_ASSERT(win && mouse); - XDefineCursor(_RGFW->display, win->src.window, (Cursor)mouse); -} - -void RGFW_FUNC(RGFW_freeMouse)(RGFW_mouse* mouse) { - RGFW_ASSERT(mouse); - XFreeCursor(_RGFW->display, (Cursor)mouse); -} - -void RGFW_FUNC(RGFW_window_moveMouse)(RGFW_window* win, i32 x, i32 y) { - RGFW_ASSERT(win != NULL); - - XEvent event; - XQueryPointer(_RGFW->display, DefaultRootWindow(_RGFW->display), - &event.xbutton.root, &event.xbutton.window, - &event.xbutton.x_root, &event.xbutton.y_root, - &event.xbutton.x, &event.xbutton.y, - &event.xbutton.state); - - win->internal.lastMouseX = x - win->x; - win->internal.lastMouseY = y - win->y; - if (event.xbutton.x == x && event.xbutton.y == y) - return; - - XWarpPointer(_RGFW->display, None, win->src.window, 0, 0, 0, 0, (int) x - win->x, (int) y - win->y); -} - -RGFW_bool RGFW_FUNC(RGFW_window_setMouseDefault) (RGFW_window* win) { - return RGFW_window_setMouseStandard(win, RGFW_mouseArrow); -} - -RGFW_bool RGFW_FUNC(RGFW_window_setMouseStandard) (RGFW_window* win, u8 mouse) { - RGFW_ASSERT(win != NULL); - +RGFW_mouse* RGFW_FUNC(RGFW_createMouseStandard) (RGFW_mouseIcon mouse) { u32 mouseIcon = 0; switch (mouse) { @@ -7573,15 +7595,62 @@ RGFW_bool RGFW_FUNC(RGFW_window_setMouseStandard) (RGFW_window* win, u8 mouse) { case RGFW_mouseResizeAll: mouseIcon = XC_fleur; break; case RGFW_mouseNotAllowed: mouseIcon = XC_pirate; break; case RGFW_mousePointingHand: mouseIcon = XC_hand2; break; - default: return RGFW_FALSE; + default: return NULL; } Cursor cursor = XCreateFontCursor(_RGFW->display, mouseIcon); - XDefineCursor(_RGFW->display, win->src.window, (Cursor) cursor); - XFreeCursor(_RGFW->display, (Cursor) cursor); + return (RGFW_mouse*)cursor; +} + +RGFW_mouse* RGFW_FUNC(RGFW_createMouse) (u8* data, i32 w, i32 h, RGFW_format format) { + RGFW_ASSERT(data); +#ifndef RGFW_NO_X11_CURSOR + RGFW_init(); + XcursorImage* native = XcursorImageCreate((i32)w, (i32)h); + native->xhot = 0; + native->yhot = 0; + RGFW_MEMZERO(native->pixels, (u32)(w * h * 4)); + RGFW_copyImageData((u8*)native->pixels, w, h, RGFW_formatBGRA8, data, format, NULL); + + Cursor cursor = XcursorImageLoadCursor(_RGFW->display, native); + XcursorImageDestroy(native); + + return (void*)cursor; +#else + RGFW_UNUSED(data); RGFW_UNUSED(w); RGFW_UNUSED(h); RGFW_UNUSED(format); + return NULL; +#endif +} + +RGFW_bool RGFW_FUNC(RGFW_window_setMousePlatform)(RGFW_window* win, RGFW_mouse* mouse) { + RGFW_ASSERT(win && mouse); + XDefineCursor(_RGFW->display, win->src.window, (Cursor)mouse); return RGFW_TRUE; } +void RGFW_FUNC(RGFW_freeMouse)(RGFW_mouse* mouse) { + RGFW_ASSERT(mouse); + XFreeCursor(_RGFW->display, (Cursor)mouse); +} + +void RGFW_FUNC(RGFW_window_moveMouse)(RGFW_window* win, i32 x, i32 y) { + RGFW_ASSERT(win != NULL); + + XEvent event; + XQueryPointer(_RGFW->display, DefaultRootWindow(_RGFW->display), + &event.xbutton.root, &event.xbutton.window, + &event.xbutton.x_root, &event.xbutton.y_root, + &event.xbutton.x, &event.xbutton.y, + &event.xbutton.state); + + win->internal.lastMouseX = x - win->x; + win->internal.lastMouseY = y - win->y; + if (event.xbutton.x == x && event.xbutton.y == y) + return; + + XWarpPointer(_RGFW->display, None, win->src.window, 0, 0, 0, 0, (int) x - win->x, (int) y - win->y); +} + void RGFW_FUNC(RGFW_window_hide)(RGFW_window* win) { win->internal.flags |= (u32)RGFW_windowHide; XUnmapWindow(_RGFW->display, win->src.window); @@ -7707,7 +7776,7 @@ void RGFW_FUNC(RGFW_writeClipboard)(const char* text, u32 textLen) { /* 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) { - RGFW_sendDebugInfo(RGFW_typeError, RGFW_errClipboard, "X11 failed to become owner of clipboard selection"); + RGFW_debugCallback(RGFW_typeError, RGFW_errClipboard, "X11 failed to become owner of clipboard selection"); return; } @@ -7799,20 +7868,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; } @@ -7905,7 +7972,9 @@ void RGFW_FUNC(RGFW_pollMonitors) (void) { RGFW_monitor monitor; XRROutputInfo* info = XRRGetOutputInfo(_RGFW->display, res, res->outputs[i]); - if (info == NULL || info->connection != RR_Connected || info->crtc == None) { + if (info == NULL) continue; + if (info->connection != RR_Connected || info->crtc == None) { + XRRFreeOutputInfo(info); continue; } @@ -8055,7 +8124,6 @@ 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_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); @@ -8067,18 +8135,14 @@ 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_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_sendDebugInfo(RGFW_typeError, RGFW_errX11, "X11: Gamma ramp size must match current ramp size"); + RGFW_debugCallback(RGFW_typeError, RGFW_errX11, "X11: Gamma ramp size must match current ramp size"); return RGFW_FALSE; } @@ -8092,8 +8156,6 @@ 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) { @@ -8112,7 +8174,6 @@ 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_bool output = RGFW_FALSE; @@ -8149,8 +8210,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) { @@ -8235,7 +8294,7 @@ RGFW_bool RGFW_FUNC(RGFW_window_createContextPtr_OpenGL) (RGFW_window* win, RGFW i32 best_samples = 0; if (fbcount == 0) { - RGFW_sendDebugInfo(RGFW_typeError, RGFW_errOpenGLContext, "Failed to find any valid GLX visual configs."); + RGFW_debugCallback(RGFW_typeError, RGFW_errOpenGLContext, "Failed to find any valid GLX visual configs."); return 0; } @@ -8264,7 +8323,7 @@ RGFW_bool RGFW_FUNC(RGFW_window_createContextPtr_OpenGL) (RGFW_window* win, RGFW } if (best_fbc == -1) { - RGFW_sendDebugInfo(RGFW_typeError, RGFW_errOpenGLContext, "Failed to get a valid GLX visual."); + RGFW_debugCallback(RGFW_typeError, RGFW_errOpenGLContext, "Failed to get a valid GLX visual."); return 0; } @@ -8272,10 +8331,10 @@ RGFW_bool RGFW_FUNC(RGFW_window_createContextPtr_OpenGL) (RGFW_window* win, RGFW bestFbc = fbc[best_fbc]; XVisualInfo* vi = glXGetVisualFromFBConfig(_RGFW->display, bestFbc); if (vi->depth != 32 && transparent) - RGFW_sendDebugInfo(RGFW_typeWarning, RGFW_warningOpenGL, "Failed to to find a matching visual with a 32-bit depth."); + RGFW_debugCallback(RGFW_typeWarning, RGFW_warningOpenGL, "Failed to to find a matching visual with a 32-bit depth."); if (best_samples < hints->samples) - RGFW_sendDebugInfo(RGFW_typeWarning, RGFW_warningOpenGL, "Failed to load a matching sample count."); + RGFW_debugCallback(RGFW_typeWarning, RGFW_warningOpenGL, "Failed to load a matching sample count."); XFree(fbc); visual = *vi; @@ -8341,13 +8400,13 @@ RGFW_bool RGFW_FUNC(RGFW_window_createContextPtr_OpenGL) (RGFW_window* win, RGFW } if (glXCreateContextAttribsARB == NULL) { - RGFW_sendDebugInfo(RGFW_typeError, RGFW_errOpenGLContext, "Failed to load proc address 'glXCreateContextAttribsARB', loading a generic OpenGL context."); + 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); } 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) { - RGFW_sendDebugInfo(RGFW_typeError, RGFW_errOpenGLContext, "Failed to create an OpenGL context with AttribsARB, loading a generic OpenGL context."); + 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); } } @@ -8359,7 +8418,7 @@ RGFW_bool RGFW_FUNC(RGFW_window_createContextPtr_OpenGL) (RGFW_window* win, RGFW #endif glXMakeCurrent(_RGFW->display, (Drawable)win->src.ctx.native->window, (GLXContext)win->src.ctx.native->ctx); - RGFW_sendDebugInfo(RGFW_typeInfo, RGFW_infoOpenGL, "OpenGL context initalized."); + RGFW_debugCallback(RGFW_typeInfo, RGFW_infoOpenGL, "OpenGL context initalized."); RGFW_window_swapInterval_OpenGL(win, 0); @@ -8375,7 +8434,7 @@ void RGFW_FUNC(RGFW_window_deleteContextPtr_OpenGL) (RGFW_window* win, RGFW_glCo glXDestroyContext(_RGFW->display, ctx->ctx); win->src.ctx.native = NULL; - RGFW_sendDebugInfo(RGFW_typeInfo, RGFW_infoOpenGL, "OpenGL context freed."); + RGFW_debugCallback(RGFW_typeInfo, RGFW_infoOpenGL, "OpenGL context freed."); } RGFW_bool RGFW_FUNC(RGFW_extensionSupportedPlatform_OpenGL)(const char * extension, size_t len) { @@ -8415,9 +8474,9 @@ void RGFW_FUNC(RGFW_window_swapInterval_OpenGL) (RGFW_window* win, i32 swapInter } if (pfn2 != NULL) { - RGFW_sendDebugInfo(RGFW_typeError, RGFW_errOpenGLContext, "Failed to load swap interval function, fallingback to the native swapinterval function"); + RGFW_debugCallback(RGFW_typeError, RGFW_errOpenGLContext, "Failed to load swap interval function, fallingback to the native swapinterval function"); } else { - RGFW_sendDebugInfo(RGFW_typeError, RGFW_errOpenGLContext, "Failed to load swap interval function"); + RGFW_debugCallback(RGFW_typeError, RGFW_errOpenGLContext, "Failed to load swap interval function"); } } } @@ -8480,13 +8539,14 @@ i32 RGFW_initPlatform_X11(void) { _RGFW->context = XUniqueContext(); XSetWindowAttributes wa; - RGFW_MEMSET(&wa, 0, sizeof(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_loadMouse(RGFW_blk, 1, 1, RGFW_formatRGBA8); + _RGFW->hiddenMouse = RGFW_createMouse(RGFW_blk, 1, 1, RGFW_formatRGBA8); + _RGFW->clipboard = NULL; XkbComponentNamesRec rec; @@ -8497,7 +8557,7 @@ i32 RGFW_initPlatform_X11(void) { XkbGetNames(_RGFW->display, XkbKeyNamesMask, desc); - RGFW_MEMSET(&rec, 0, sizeof(rec)); + RGFW_MEMZERO(&rec, sizeof(rec)); char evdev[] = "evdev"; rec.keycodes = evdev; evdesc = XkbGetKeyboardByName(_RGFW->display, XkbUseCoreKbd, &rec, XkbGBN_KeyNamesMask, XkbGBN_KeyNamesMask, False); @@ -8523,23 +8583,10 @@ i32 RGFW_initPlatform_X11(void) { XSetLocaleModifiers(""); XRegisterIMInstantiateCallback(_RGFW->display, NULL, NULL, NULL, RGFW_x11_imInitCallback, NULL); - unsigned char mask[XIMaskLen(XI_RawMotion)]; - RGFW_MEMSET(mask, 0, 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; } @@ -8667,13 +8714,13 @@ struct wl_surface* RGFW_window_getWindow_Wayland(RGFW_window* win) { return win- /* wayland global garbage (wayland bad, X11 is fine (ish) (not really)) */ -#include "xdg-shell-client-protocol.h" -#include "xdg-toplevel-icon-v1-client-protocol.h" -#include "xdg-decoration-unstable-v1-client-protocol.h" -#include "relative-pointer-unstable-v1-client-protocol.h" -#include "pointer-constraints-unstable-v1-client-protocol.h" -#include "xdg-output-unstable-v1-client-protocol.h" -#include "pointer-warp-v1-client-protocol.h" +#include "xdg-shell.h" +#include "xdg-toplevel-icon-v1.h" +#include "xdg-decoration-unstable-v1.h" +#include "relative-pointer-unstable-v1.h" +#include "pointer-constraints-unstable-v1.h" +#include "xdg-output-unstable-v1.h" +#include "pointer-warp-v1.h" void RGFW_toggleWaylandMaximized(RGFW_window* win, RGFW_bool maximized); @@ -8770,7 +8817,7 @@ static void RGFW_wl_xdg_toplevel_close_handler(void* data, struct xdg_toplevel * RGFW_window* win = (RGFW_window*)data; if (!win->internal.shouldClose) { - RGFW_windowQuitCallback(win); + RGFW_windowCloseCallback(win); } } @@ -8804,7 +8851,7 @@ static void RGFW_wl_relative_pointer_motion(void *data, struct zwp_relative_poin float vecX = (float)wl_fixed_to_double(dx); float vecY = (float)wl_fixed_to_double(dy); - RGFW_mousePosCallback(win, win->internal.lastMouseX, win->internal.lastMouseY, vecX, vecY); + RGFW_rawMotionCallback(win, vecX, vecY); } static void RGFW_wl_pointer_locked(void *data, struct zwp_locked_pointer_v1 *zwp_locked_pointer_v1) { @@ -8850,7 +8897,6 @@ static void RGFW_wl_pointer_leave(void* data, struct wl_pointer *pointer, u32 se static void RGFW_wl_pointer_motion(void* data, struct wl_pointer *pointer, u32 time, wl_fixed_t x, wl_fixed_t y) { RGFW_UNUSED(pointer); RGFW_UNUSED(time); - RGFW_info* RGFW = (RGFW_info*)data; RGFW_ASSERT(RGFW->mouseOwner != NULL); @@ -8858,10 +8904,8 @@ 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); - float newVecX = (float)(convertedX - win->internal.lastMouseX); - float newVecY = (float)(convertedY - win->internal.lastMouseY); - RGFW_mousePosCallback(win, convertedX, convertedY, newVecX, newVecY); + 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) { @@ -8947,7 +8991,7 @@ static void RGFW_wl_keyboard_enter(void* data, struct wl_keyboard *keyboard, u32 /* pressed this flag is not set since there is no event to listen for */ if (win->src.minimized == RGFW_TRUE) win->src.minimized = RGFW_FALSE; - RGFW_focusCallback(win, RGFW_TRUE); + RGFW_windowFocusCallback(win, RGFW_TRUE); } static void RGFW_wl_keyboard_leave(void* data, struct wl_keyboard *keyboard, u32 serial, struct wl_surface *surface) { @@ -8958,7 +9002,7 @@ static void RGFW_wl_keyboard_leave(void* data, struct wl_keyboard *keyboard, u32 if (RGFW->kbOwner == win) RGFW->kbOwner = NULL; - RGFW_focusCallback(win, RGFW_FALSE); + RGFW_windowFocusCallback(win, RGFW_FALSE); } static xkb_keysym_t RGFW_wl_composeSymbol(RGFW_info* RGFW, xkb_keysym_t sym) { @@ -8978,8 +9022,19 @@ static xkb_keysym_t RGFW_wl_composeSymbol(RGFW_info* RGFW, xkb_keysym_t sym) { } } +static void RGFW_wl_send_key_event(u32 key) { + const xkb_keysym_t* keysyms; + if (xkb_state_key_get_syms(_RGFW->xkb_state, key + 8, &keysyms) == 1) { + xkb_keysym_t keysym = RGFW_wl_composeSymbol(_RGFW, keysyms[0]); + u32 codepoint = xkb_keysym_to_utf32(keysym); + if (codepoint != 0) { + RGFW_keyCharCallback(_RGFW->kbOwner, codepoint); + } + } +} + static void RGFW_wl_keyboard_key(void* data, struct wl_keyboard *keyboard, u32 serial, u32 time, u32 key, u32 state) { - RGFW_UNUSED(keyboard); RGFW_UNUSED(serial); RGFW_UNUSED(time); + RGFW_UNUSED(keyboard); RGFW_UNUSED(serial); RGFW_info* RGFW = (RGFW_info*)data; if (RGFW->kbOwner == NULL) return; @@ -8987,17 +9042,22 @@ static void RGFW_wl_keyboard_key(void* data, struct wl_keyboard *keyboard, u32 s RGFW_window *RGFW_key_win = RGFW->kbOwner; RGFW_key RGFWkey = RGFW_apiKeyToRGFW(key + 8); - RGFW_updateKeyMods(RGFW_key_win, RGFW_BOOL(xkb_keymap_mod_get_index(RGFW->keymap, "Lock")), RGFW_BOOL(xkb_keymap_mod_get_index(RGFW->keymap, "Mod2")), RGFW_BOOL(xkb_keymap_mod_get_index(RGFW->keymap, "ScrollLock"))); - RGFW_keyCallback(RGFW_key_win, (u8)RGFWkey, RGFW_key_win->internal.mod, RGFW_window_isKeyDown(RGFW_key_win, (u8)RGFWkey), RGFW_BOOL(state)); + RGFW_keyUpdateKeyMods(RGFW_key_win, RGFW_BOOL(xkb_keymap_mod_get_index(RGFW->keymap, "Lock")), RGFW_BOOL(xkb_keymap_mod_get_index(RGFW->keymap, "Mod2")), RGFW_BOOL(xkb_keymap_mod_get_index(RGFW->keymap, "ScrollLock"))); + RGFW_keyCallback(RGFW_key_win, (u8)RGFWkey, RGFW_key_win->internal.mod, RGFW_isKeyDown((u8)RGFWkey) && RGFW_BOOL(state), RGFW_BOOL(state)); - const xkb_keysym_t* keysyms; - if (xkb_state_key_get_syms(RGFW->xkb_state, key + 8, &keysyms) == 1) { - xkb_keysym_t keysym = RGFW_wl_composeSymbol(RGFW, keysyms[0]); - u32 codepoint = xkb_keysym_to_utf32(keysym); - if (codepoint != 0) { - RGFW_keyCharCallback(RGFW_key_win, codepoint); - } - } + /* [comment by Kala Telo (@kala-telo) and edited by Riley Mabb (@ColleagueRiley)] + we send the event at the moment we receive it, and + repeated key presses will be handled by RGFW_pollEvents + if the compositor doesn't support proxy (seat?) version + of at least 4, it won't initialize wl_repeat_info_rate, + and by spec, rate of 0 means disabled, thus repeating + keys are disabled by being zero-initialized + */ + RGFW->last_key = state ? key : 0; + RGFW->last_key_time = time + (u32)_RGFW->wl_repeat_info_delay; + if (state) { + RGFW_wl_send_key_event(_RGFW->last_key); + } } static void RGFW_wl_keyboard_modifiers(void* data, struct wl_keyboard *keyboard, u32 serial, u32 mods_depressed, u32 mods_latched, u32 mods_locked, u32 group) { @@ -9006,10 +9066,17 @@ static void RGFW_wl_keyboard_modifiers(void* data, struct wl_keyboard *keyboard, xkb_state_update_mask(RGFW->xkb_state, mods_depressed, mods_latched, mods_locked, 0, 0, group); } +static void RGFW_wl_keyboard_repeat_info(void* data, struct wl_keyboard *keyboard, i32 rate, i32 delay) { + RGFW_UNUSED(data); + RGFW_UNUSED(keyboard); + _RGFW->wl_repeat_info_rate = rate; + _RGFW->wl_repeat_info_delay = delay; +} + static void RGFW_wl_seat_capabilities(void* data, struct wl_seat *seat, u32 capabilities) { RGFW_info* RGFW = (RGFW_info*)data; static struct wl_pointer_listener pointer_listener; - RGFW_MEMSET(&pointer_listener, 0, sizeof(pointer_listener)); + RGFW_MEMZERO(&pointer_listener, sizeof(pointer_listener)); pointer_listener.enter = &RGFW_wl_pointer_enter; pointer_listener.leave = &RGFW_wl_pointer_leave; pointer_listener.motion = &RGFW_wl_pointer_motion; @@ -9017,12 +9084,13 @@ static void RGFW_wl_seat_capabilities(void* data, struct wl_seat *seat, u32 capa pointer_listener.axis = &RGFW_wl_pointer_axis; static struct wl_keyboard_listener keyboard_listener; - RGFW_MEMSET(&keyboard_listener, 0, sizeof(keyboard_listener)); + RGFW_MEMZERO(&keyboard_listener, sizeof(keyboard_listener)); keyboard_listener.keymap = &RGFW_wl_keyboard_keymap; keyboard_listener.enter = &RGFW_wl_keyboard_enter; keyboard_listener.leave = &RGFW_wl_keyboard_leave; keyboard_listener.key = &RGFW_wl_keyboard_key; keyboard_listener.modifiers = &RGFW_wl_keyboard_modifiers; + keyboard_listener.repeat_info = &RGFW_wl_keyboard_repeat_info; if ((capabilities & WL_SEAT_CAPABILITY_POINTER) && !RGFW->wl_pointer) { RGFW->wl_pointer = wl_seat_get_pointer(seat); @@ -9154,7 +9222,7 @@ static void RGFW_wl_output_handle_done(void* data, struct wl_output* output) { } static void RGFW_wl_create_outputs(struct wl_registry *const registry, u32 id) { - struct wl_output *output = wl_registry_bind(registry, id, &wl_output_interface, wl_display_get_version(_RGFW->wl_display) < 4 ? 3 : 4); + struct wl_output *output = wl_registry_bind(registry, id, &wl_output_interface, wl_proxy_get_version((struct wl_proxy*)_RGFW->seat)); RGFW_monitorNode* node; RGFW_monitor mon; @@ -9162,7 +9230,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'; @@ -9216,9 +9284,6 @@ static void RGFW_wl_surface_enter(void *data, struct wl_surface *wl_surface, str if (node == NULL) return; win->src.active_monitor = node; - - if (win->internal.flags & RGFW_windowScaleToMonitor) - RGFW_window_scaleToMonitor(win); } static void RGFW_wl_data_source_send(void *data, struct wl_data_source *wl_data_source, const char *mime_type, i32 fd) { @@ -9275,6 +9340,9 @@ static void RGFW_wl_data_device_selection(void *data, struct wl_data_device *wl_ ssize_t n = read(pfds[0], buf, sizeof(buf)); + if (_RGFW->clipboard) { + RGFW_FREE(_RGFW->clipboard); + } _RGFW->clipboard = (char*)RGFW_ALLOC((size_t)n); RGFW_ASSERT(_RGFW->clipboard != NULL); RGFW_STRNCPY(_RGFW->clipboard, buf, (size_t)n); @@ -9311,7 +9379,7 @@ static void RGFW_wl_global_registry_handler(void* data, struct wl_registry *regi RGFW->shm = wl_registry_bind(registry, id, &wl_shm_interface, 1); wl_shm_add_listener(RGFW->shm, &shm_listener, RGFW); } else if (RGFW_STRNCMP(interface,"wl_seat", 8) == 0) { - RGFW->seat = wl_registry_bind(registry, id, &wl_seat_interface, 1); + RGFW->seat = wl_registry_bind(registry, id, &wl_seat_interface, version < 4 ? 3 : 4); wl_seat_add_listener(RGFW->seat, &seat_listener, RGFW); } else if (RGFW_STRNCMP(interface, zxdg_output_manager_v1_interface.name, 255) == 0) { RGFW->xdg_output_manager = wl_registry_bind(registry, id, &zxdg_output_manager_v1_interface, 1); @@ -9408,7 +9476,7 @@ static int RGFW_wl_create_shm_file(off_t size) { i32 RGFW_initPlatform_Wayland(void) { _RGFW->wl_display = wl_display_connect(NULL); if (_RGFW->wl_display == NULL) { - RGFW_sendDebugInfo(RGFW_typeError, RGFW_errWayland, "Failed to load Wayland display"); + RGFW_debugCallback(RGFW_typeError, RGFW_errWayland, "Failed to load Wayland display"); return -1; } @@ -9424,8 +9492,8 @@ i32 RGFW_initPlatform_Wayland(void) { wl_display_roundtrip(_RGFW->wl_display); /* bind to globals */ if (_RGFW->compositor == NULL) { - RGFW_sendDebugInfo(RGFW_typeError, RGFW_errWayland, "Can't find compositor."); - return 1; + RGFW_debugCallback(RGFW_typeError, RGFW_errWayland, "Can't find compositor."); + return -1; } if (_RGFW->wl_cursor_theme == NULL) { @@ -9434,7 +9502,7 @@ i32 RGFW_initPlatform_Wayland(void) { } u8 RGFW_blk[] = { 0, 0, 0, 0 }; - _RGFW->hiddenMouse = RGFW_loadMouse(RGFW_blk, 1, 1, RGFW_formatRGBA8); + _RGFW->hiddenMouse = RGFW_createMouse(RGFW_blk, 1, 1, RGFW_formatRGBA8); static const struct xdg_wm_base_listener xdg_wm_base_listener = { .ping = RGFW_wl_xdg_wm_base_ping_handler, @@ -9548,12 +9616,12 @@ RGFW_bool RGFW_FUNC(RGFW_createSurfacePtr) (u8* data, i32 w, i32 h, RGFW_format surface->w = w; surface->h = h; surface->format = format; - RGFW_sendDebugInfo(RGFW_typeInfo, RGFW_infoBuffer, "Creating a 4 channel buffer"); + RGFW_debugCallback(RGFW_typeInfo, RGFW_infoBuffer, "Creating a 4 channel buffer"); u32 size = (u32)(surface->w * surface->h * 4); int fd = RGFW_wl_create_shm_file(size); if (fd < 0) { - RGFW_sendDebugInfo(RGFW_typeError, RGFW_errBuffer, "Failed to create a buffer."); + RGFW_debugCallback(RGFW_typeError, RGFW_errBuffer, "Failed to create a buffer."); return RGFW_FALSE; } @@ -9561,7 +9629,7 @@ RGFW_bool RGFW_FUNC(RGFW_createSurfacePtr) (u8* data, i32 w, i32 h, RGFW_format surface->native.buffer = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if (surface->native.buffer == MAP_FAILED) { - RGFW_sendDebugInfo(RGFW_typeError, RGFW_errBuffer, "mmap failed."); + RGFW_debugCallback(RGFW_typeError, RGFW_errBuffer, "mmap failed."); return RGFW_FALSE; } @@ -9581,15 +9649,16 @@ void RGFW_FUNC(RGFW_window_blitSurface) (RGFW_window* win, RGFW_surface* surface wl_surface_commit(win->src.surface); wl_buffer_destroy(surface->native.wl_buffer); + + surface->native.wl_buffer = NULL; } void RGFW_FUNC(RGFW_surface_freePtr) (RGFW_surface* surface) { RGFW_ASSERT(surface != NULL); - wl_shm_pool_destroy(surface->native.pool); - close(surface->native.fd); - - munmap(surface->native.buffer, (size_t)(surface->w * surface->h * 4)); + if (surface->native.pool) wl_shm_pool_destroy(surface->native.pool); + if (surface->native.fd) close(surface->native.fd); + if (surface->native.buffer) munmap(surface->native.buffer, (size_t)(surface->w * surface->h * 4)); } void RGFW_FUNC(RGFW_window_setBorder) (RGFW_window* win, RGFW_bool border) { @@ -9649,7 +9718,7 @@ void RGFW_FUNC(RGFW_window_captureMousePlatform) (RGFW_window* win, RGFW_bool st } RGFW_window* RGFW_FUNC(RGFW_createWindowPlatform) (const char* name, RGFW_windowFlags flags, RGFW_window* win) { - RGFW_sendDebugInfo(RGFW_typeWarning, RGFW_warningWayland, "RGFW Wayland support is experimental"); + RGFW_debugCallback(RGFW_typeWarning, RGFW_warningWayland, "RGFW Wayland support is experimental"); static const struct xdg_surface_listener xdg_surface_listener = { .configure = RGFW_wl_xdg_surface_configure_handler, @@ -9775,77 +9844,81 @@ RGFW_key RGFW_FUNC(RGFW_physicalToMappedKey)(RGFW_key key) { } switch (sym) { - case XKB_KEY_F1: return RGFW_F1; - case XKB_KEY_F2: return RGFW_F2; - case XKB_KEY_F3: return RGFW_F3; - case XKB_KEY_F4: return RGFW_F4; - case XKB_KEY_F5: return RGFW_F5; - case XKB_KEY_F6: return RGFW_F6; - case XKB_KEY_F7: return RGFW_F7; - case XKB_KEY_F8: return RGFW_F8; - case XKB_KEY_F9: return RGFW_F9; - case XKB_KEY_F10: return RGFW_F10; - case XKB_KEY_F11: return RGFW_F11; - case XKB_KEY_F12: return RGFW_F12; - case XKB_KEY_F13: return RGFW_F13; - case XKB_KEY_F14: return RGFW_F14; - case XKB_KEY_F15: return RGFW_F15; - case XKB_KEY_F16: return RGFW_F16; - case XKB_KEY_F17: return RGFW_F17; - case XKB_KEY_F18: return RGFW_F18; - case XKB_KEY_F19: return RGFW_F19; - case XKB_KEY_F20: return RGFW_F20; - case XKB_KEY_F21: return RGFW_F21; - case XKB_KEY_F22: return RGFW_F22; - case XKB_KEY_F23: return RGFW_F23; - case XKB_KEY_F24: return RGFW_F24; - case XKB_KEY_F25: return RGFW_F25; - case XKB_KEY_Shift_L: return RGFW_shiftL; - case XKB_KEY_Shift_R: return RGFW_shiftR; - case XKB_KEY_Control_L: return RGFW_controlL; - case XKB_KEY_Control_R: return RGFW_controlR; - case XKB_KEY_Alt_L: return RGFW_altL; - case XKB_KEY_Alt_R: return RGFW_altR; - case XKB_KEY_Super_L: return RGFW_superL; - case XKB_KEY_Super_R: return RGFW_superR; - case XKB_KEY_Caps_Lock: return RGFW_capsLock; - case XKB_KEY_Num_Lock: return RGFW_numLock; - case XKB_KEY_Scroll_Lock:return RGFW_scrollLock; - case XKB_KEY_Up: return RGFW_up; - case XKB_KEY_Down: return RGFW_down; - case XKB_KEY_Left: return RGFW_left; - case XKB_KEY_Right: return RGFW_right; - case XKB_KEY_Home: return RGFW_home; - case XKB_KEY_End: return RGFW_end; - case XKB_KEY_Page_Up: return RGFW_pageUp; - case XKB_KEY_Page_Down: return RGFW_pageDown; - case XKB_KEY_Insert: return RGFW_insert; - case XKB_KEY_Menu: return RGFW_menu; - case XKB_KEY_KP_Add: return RGFW_kpPlus; - case XKB_KEY_KP_Subtract: return RGFW_kpMinus; - case XKB_KEY_KP_Multiply: return RGFW_kpMultiply; - case XKB_KEY_KP_Divide: return RGFW_kpSlash; - case XKB_KEY_KP_Equal: return RGFW_kpEqual; - case XKB_KEY_KP_Enter: return RGFW_kpReturn; - case XKB_KEY_KP_Decimal: return RGFW_kpPeriod; - case XKB_KEY_KP_0: return RGFW_kp0; - case XKB_KEY_KP_1: return RGFW_kp1; - case XKB_KEY_KP_2: return RGFW_kp2; - case XKB_KEY_KP_3: return RGFW_kp3; - case XKB_KEY_KP_4: return RGFW_kp4; - case XKB_KEY_KP_5: return RGFW_kp5; - case XKB_KEY_KP_6: return RGFW_kp6; - case XKB_KEY_KP_7: return RGFW_kp7; - case XKB_KEY_KP_8: return RGFW_kp8; - case XKB_KEY_KP_9: return RGFW_kp9; - case XKB_KEY_Print: return RGFW_printScreen; - case XKB_KEY_Pause: return RGFW_pause; + case XKB_KEY_F1: return RGFW_keyF1; + case XKB_KEY_F2: return RGFW_keyF2; + case XKB_KEY_F3: return RGFW_keyF3; + case XKB_KEY_F4: return RGFW_keyF4; + case XKB_KEY_F5: return RGFW_keyF5; + case XKB_KEY_F6: return RGFW_keyF6; + case XKB_KEY_F7: return RGFW_keyF7; + case XKB_KEY_F8: return RGFW_keyF8; + case XKB_KEY_F9: return RGFW_keyF9; + case XKB_KEY_F10: return RGFW_keyF10; + case XKB_KEY_F11: return RGFW_keyF11; + case XKB_KEY_F12: return RGFW_keyF12; + case XKB_KEY_F13: return RGFW_keyF13; + case XKB_KEY_F14: return RGFW_keyF14; + case XKB_KEY_F15: return RGFW_keyF15; + case XKB_KEY_F16: return RGFW_keyF16; + case XKB_KEY_F17: return RGFW_keyF17; + case XKB_KEY_F18: return RGFW_keyF18; + case XKB_KEY_F19: return RGFW_keyF19; + case XKB_KEY_F20: return RGFW_keyF20; + case XKB_KEY_F21: return RGFW_keyF21; + case XKB_KEY_F22: return RGFW_keyF22; + case XKB_KEY_F23: return RGFW_keyF23; + case XKB_KEY_F24: return RGFW_keyF24; + case XKB_KEY_F25: return RGFW_keyF25; + case XKB_KEY_Shift_L: return RGFW_keyShiftL; + case XKB_KEY_Shift_R: return RGFW_keyShiftR; + case XKB_KEY_Control_L: return RGFW_keyControlL; + case XKB_KEY_Control_R: return RGFW_keyControlR; + case XKB_KEY_Alt_L: return RGFW_keyAltL; + case XKB_KEY_Alt_R: return RGFW_keyAltR; + case XKB_KEY_Super_L: return RGFW_keySuperL; + case XKB_KEY_Super_R: return RGFW_keySuperR; + case XKB_KEY_Caps_Lock: return RGFW_keyCapsLock; + case XKB_KEY_Num_Lock: return RGFW_keyNumLock; + case XKB_KEY_Scroll_Lock:return RGFW_keyScrollLock; + case XKB_KEY_Up: return RGFW_keyUp; + case XKB_KEY_Down: return RGFW_keyDown; + case XKB_KEY_Left: return RGFW_keyLeft; + case XKB_KEY_Right: return RGFW_keyRight; + case XKB_KEY_Home: return RGFW_keyHome; + case XKB_KEY_End: return RGFW_keyEnd; + case XKB_KEY_Page_Up: return RGFW_keyPageUp; + case XKB_KEY_Page_Down: return RGFW_keyPageDown; + case XKB_KEY_Insert: return RGFW_keyInsert; + case XKB_KEY_Menu: return RGFW_keyMenu; + case XKB_KEY_KP_Add: return RGFW_keyPadPlus; + case XKB_KEY_KP_Subtract: return RGFW_keyPadMinus; + case XKB_KEY_KP_Multiply: return RGFW_keyPadMultiply; + case XKB_KEY_KP_Divide: return RGFW_keyPadSlash; + case XKB_KEY_KP_Equal: return RGFW_keyPadEqual; + case XKB_KEY_KP_Enter: return RGFW_keyPadReturn; + case XKB_KEY_KP_Decimal: return RGFW_keyPadPeriod; + case XKB_KEY_KP_0: return RGFW_keyPad0; + case XKB_KEY_KP_1: return RGFW_keyPad1; + case XKB_KEY_KP_2: return RGFW_keyPad2; + case XKB_KEY_KP_3: return RGFW_keyPad3; + case XKB_KEY_KP_4: return RGFW_keyPad4; + case XKB_KEY_KP_5: return RGFW_keyPad5; + case XKB_KEY_KP_6: return RGFW_keyPad6; + case XKB_KEY_KP_7: return RGFW_keyPad7; + case XKB_KEY_KP_8: return RGFW_keyPad8; + case XKB_KEY_KP_9: return RGFW_keyPad9; + case XKB_KEY_Print: return RGFW_keyPrintScreen; + case XKB_KEY_Pause: return RGFW_keyPause; default: break; } return RGFW_keyNULL; } +RGFW_bool RGFW_FUNC(RGFW_window_fetchSize) (RGFW_window* win, i32* w, i32* h) { + return RGFW_window_getSize(win, w, h); +} + void RGFW_FUNC(RGFW_pollEvents) (void) { RGFW_resetPrevState(); @@ -9861,13 +9934,42 @@ void RGFW_FUNC(RGFW_pollEvents) (void) { return; } } + if (_RGFW->wl_repeat_info_rate != 0 && _RGFW->last_key) { + u32 now = (u32)(RGFW_linux_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; + } + } /* 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; + } + + 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_move) (RGFW_window* win, i32 x, i32 y) { @@ -9923,6 +10025,7 @@ void RGFW_FUNC(RGFW_window_maximize) (RGFW_window* win) { win->internal.oldW = win->w; win->internal.oldH = win->h; RGFW_toggleWaylandMaximized(win, 1); + RGFW_window_fetchSize(win, NULL, NULL); return; } @@ -10030,50 +10133,7 @@ RGFW_bool RGFW_FUNC(RGFW_window_setIconEx) (RGFW_window* win, u8* data, i32 w, i return RGFW_TRUE; } -RGFW_mouse* RGFW_FUNC(RGFW_loadMouse)(u8* data, i32 w, i32 h, RGFW_format format) { - - RGFW_surface *mouse_surface = RGFW_createSurface(data, w, h, format); - - if (mouse_surface == NULL) return NULL; - - RGFW_copyImageData(mouse_surface->native.buffer, RGFW_MIN(w, mouse_surface->w), RGFW_MIN(h, mouse_surface->h), mouse_surface->native.format, mouse_surface->data, mouse_surface->format, NULL); - - return (void*) mouse_surface; -} - -void RGFW_FUNC(RGFW_window_setMouse)(RGFW_window* win, RGFW_mouse* mouse) { - RGFW_ASSERT(win); RGFW_ASSERT(mouse); - RGFW_surface *mouse_surface = (RGFW_surface*)mouse; - - win->src.using_custom_cursor = RGFW_TRUE; - - struct wl_buffer *mouse_buffer = mouse_surface->native.wl_buffer; - - wl_surface_attach(win->src.custom_cursor_surface, mouse_buffer, 0, 0); - wl_surface_damage(win->src.custom_cursor_surface, 0, 0, mouse_surface->w, mouse_surface->h); - wl_surface_commit(win->src.custom_cursor_surface); - -} - -void RGFW_FUNC(RGFW_freeMouse)(RGFW_mouse* mouse) { - if (mouse != NULL) { - RGFW_surface_free((RGFW_surface*)mouse); - } -} - -void RGFW_FUNC(RGFW_window_moveMouse)(RGFW_window* win, i32 x, i32 y) { - if (_RGFW->wp_pointer_warp != NULL) { - wp_pointer_warp_v1_warp_pointer(_RGFW->wp_pointer_warp, win->src.surface, _RGFW->wl_pointer, wl_fixed_from_int(x), wl_fixed_from_int(y), _RGFW->mouse_enter_serial); - } -} - -RGFW_bool RGFW_FUNC(RGFW_window_setMouseDefault)(RGFW_window* win) { - return RGFW_window_setMouseStandard(win, RGFW_mouseArrow); -} - -RGFW_bool RGFW_FUNC(RGFW_window_setMouseStandard)(RGFW_window* win, u8 mouse) { - RGFW_ASSERT(win != NULL); - +RGFW_mouse* RGFW_FUNC(RGFW_createMouseStandard) (RGFW_mouseIcon mouse) { char* cursorName = NULL; switch (mouse) { case RGFW_mouseNormal: cursorName = (char*)"left_ptr"; break; @@ -10097,23 +10157,66 @@ RGFW_bool RGFW_FUNC(RGFW_window_setMouseStandard)(RGFW_window* win, u8 mouse) { case RGFW_mouseNotAllowed: cursorName = (char*)"not-allowed"; break; case RGFW_mouseWait: cursorName = (char*)"watch"; break; case RGFW_mouseProgress: cursorName = (char*)"watch"; break; - default: return RGFW_FALSE; + default: return NULL; } - win->src.using_custom_cursor = RGFW_FALSE; - struct wl_cursor* wlcursor = wl_cursor_theme_get_cursor(_RGFW->wl_cursor_theme, cursorName); if (wlcursor == NULL) - return RGFW_FALSE; + return NULL; struct wl_cursor_image* cursor_image = wlcursor->images[0]; struct wl_buffer* cursor_buffer = wl_cursor_image_get_buffer(cursor_image); - wl_pointer_set_cursor(_RGFW->wl_pointer, _RGFW->mouse_enter_serial, _RGFW->cursor_surface, (i32)cursor_image->hotspot_x, (i32)cursor_image->hotspot_y); - wl_surface_attach(_RGFW->cursor_surface, cursor_buffer, 0, 0); - wl_surface_damage(_RGFW->cursor_surface, 0, 0, (i32)cursor_image->width, (i32)cursor_image->height); - wl_surface_commit(_RGFW->cursor_surface); + + RGFW_surface* surface = RGFW_ALLOC(sizeof(RGFW_surface)); + RGFW_MEMZERO(surface, sizeof(RGFW_surface)); + surface->w = (i32)cursor_image->width; + surface->h = (i32)cursor_image->height; + surface->native.wl_buffer = cursor_buffer; + + return (RGFW_mouse*)surface; +} + +RGFW_mouse* RGFW_FUNC(RGFW_createMouse)(u8* data, i32 w, i32 h, RGFW_format format) { + RGFW_surface* surface = RGFW_createSurface(data, w, h, format); + if (surface == NULL) return NULL; + + surface->native.wl_buffer = wl_shm_pool_create_buffer(surface->native.pool, 0, surface->w, surface->h, (i32)surface->w * 4, WL_SHM_FORMAT_ARGB8888); + + RGFW_copyImageData(surface->native.buffer, RGFW_MIN(w, surface->w), RGFW_MIN(h, surface->h), surface->native.format, surface->data, surface->format, NULL); + + return (RGFW_mouse*)surface; +} + +RGFW_bool RGFW_FUNC(RGFW_window_setMousePlatform)(RGFW_window* win, RGFW_mouse* mouse) { + RGFW_ASSERT(win); RGFW_ASSERT(mouse); + RGFW_surface* surface = (RGFW_surface*)mouse; + + win->src.using_custom_cursor = RGFW_TRUE; + + wl_surface_attach(win->src.custom_cursor_surface, surface->native.wl_buffer, 0, 0); + wl_surface_damage(win->src.custom_cursor_surface, 0, 0, surface->w, surface->h); + wl_surface_commit(win->src.custom_cursor_surface); + return RGFW_TRUE; } +void RGFW_FUNC(RGFW_freeMouse)(RGFW_mouse* mouse) { + if (mouse != NULL) { + RGFW_surface* surface = (RGFW_surface*)mouse; + + if (surface->native.buffer && surface->native.wl_buffer) { + wl_buffer_destroy(surface->native.wl_buffer); + } + + RGFW_surface_free(surface); + } +} + +void RGFW_FUNC(RGFW_window_moveMouse)(RGFW_window* win, i32 x, i32 y) { + if (_RGFW->wp_pointer_warp != NULL) { + wp_pointer_warp_v1_warp_pointer(_RGFW->wp_pointer_warp, win->src.surface, _RGFW->wl_pointer, wl_fixed_from_int(x), wl_fixed_from_int(y), _RGFW->mouse_enter_serial); + } +} + void RGFW_FUNC(RGFW_window_hide) (RGFW_window* win) { wl_surface_attach(win->src.surface, NULL, 0, 0); wl_surface_commit(win->src.surface); @@ -10134,6 +10237,7 @@ 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_UNUSED(strCapacity); if (str != NULL) @@ -10172,7 +10276,7 @@ void RGFW_FUNC(RGFW_writeClipboard) (const char* text, u32 textLen) { // basic error checking if (win->src.data_source == NULL) { - RGFW_sendDebugInfo(RGFW_typeError, RGFW_errClipboard, "Could not create clipboard data source"); + RGFW_debugCallback(RGFW_typeError, RGFW_errClipboard, "Could not create clipboard data source"); return; } wl_data_source_offer(win->src.data_source , "text/plain;charset=utf-8"); @@ -10289,7 +10393,7 @@ void RGFW_FUNC(RGFW_window_swapInterval_OpenGL) (RGFW_window* win, i32 swapInter void RGFW_FUNC(RGFW_window_closePlatform)(RGFW_window* win) { RGFW_ASSERT(win != NULL); - RGFW_sendDebugInfo(RGFW_typeInfo, RGFW_infoWindow, "a window was freed"); + RGFW_debugCallback(RGFW_typeInfo, RGFW_infoWindow, "a window was freed"); #ifdef RGFW_LIBDECOR if (win->src.decorContext) libdecor_unref(win->src.decorContext); @@ -10505,6 +10609,7 @@ void RGFW_win32_makeWindowTransparent(RGFW_window* win) { RGFWDEF RGFW_bool RGFW_win32_getDarkModeState(void); RGFW_bool RGFW_win32_getDarkModeState(void) { u32 lightMode = 1; +#if (_WIN32_WINNT >= 0x0600) DWORD len = sizeof(lightMode); RegGetValueW( @@ -10512,6 +10617,7 @@ RGFW_bool RGFW_win32_getDarkModeState(void) { L"Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize", L"AppsUseLightTheme", RRF_RT_REG_DWORD, NULL, &lightMode, &len ); +#endif return (lightMode == 0); } @@ -10542,11 +10648,11 @@ LRESULT CALLBACK WndProcW(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) break; case WM_CLOSE: case WM_QUIT: - RGFW_windowQuitCallback(win); + RGFW_windowCloseCallback(win); return 0; case WM_ACTIVATE: { RGFW_bool inFocus = RGFW_BOOL(LOWORD(wParam) != WA_INACTIVE); - RGFW_focusCallback(win, inFocus); + RGFW_windowFocusCallback(win, inFocus); return DefWindowProcW(hWnd, message, wParam, lParam); } @@ -10626,10 +10732,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); - 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); } @@ -10659,7 +10770,7 @@ LRESULT CALLBACK WndProcW(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) break; } case WM_TIMER: - RGFW_windowRefreshCallback(win); + RGFW_windowRefreshCallback(win, 0, 0, win->w, win->h); break; case WM_NCLBUTTONDOWN: { @@ -10727,14 +10838,12 @@ LRESULT CALLBACK WndProcW(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) if (wParam == VK_CONTROL) { if (HIWORD(lParam) & KF_EXTENDED) - value = RGFW_controlR; - else value = RGFW_controlL; + value = RGFW_keyControlR; + else value = RGFW_keyControlL; } - RGFW_bool repeat = ((lParam & 0x40000000) != 0) || RGFW_window_isKeyDown(win, value); - - RGFW_updateKeyMods(win, (GetKeyState(VK_CAPITAL) & 0x0001), (GetKeyState(VK_NUMLOCK) & 0x0001), (GetKeyState(VK_SCROLL) & 0x0001)); - RGFW_keyCallback(win, value, win->internal.mod, repeat, RGFW_FALSE); + RGFW_keyUpdateKeyMods(win, (GetKeyState(VK_CAPITAL) & 0x0001), (GetKeyState(VK_NUMLOCK) & 0x0001), (GetKeyState(VK_SCROLL) & 0x0001)); + RGFW_keyCallback(win, value, win->internal.mod, RGFW_FALSE, RGFW_FALSE); break; } case WM_SYSKEYDOWN: case WM_KEYDOWN: { @@ -10753,13 +10862,13 @@ LRESULT CALLBACK WndProcW(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) RGFW_key value = (u8)RGFW_apiKeyToRGFW((u32) scancode); if (wParam == VK_CONTROL) { if (HIWORD(lParam) & KF_EXTENDED) - value = RGFW_controlR; - else value = RGFW_controlL; + value = RGFW_keyControlR; + else value = RGFW_keyControlL; } - RGFW_bool repeat = ((lParam & 0x40000000) != 0) || RGFW_window_isKeyDown(win, value); + RGFW_bool repeat = RGFW_isKeyDown(value); - RGFW_updateKeyMods(win, (GetKeyState(VK_CAPITAL) & 0x0001), (GetKeyState(VK_NUMLOCK) & 0x0001), (GetKeyState(VK_SCROLL) & 0x0001)); + RGFW_keyUpdateKeyMods(win, (GetKeyState(VK_CAPITAL) & 0x0001), (GetKeyState(VK_NUMLOCK) & 0x0001), (GetKeyState(VK_SCROLL) & 0x0001)); RGFW_keyCallback(win, value, win->internal.mod, repeat, 1); break; } @@ -10768,11 +10877,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); } - if ((win->internal.rawMouse) || _RGFW->rawMouse) { - return DefWindowProcW(hWnd, message, wParam, lParam); - } - - RGFW_mousePosCallback(win, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), _RGFW->vectorX, _RGFW->vectorY); + RGFW_mouseMotionCallback(win, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)); break; } case WM_INPUT: { @@ -10814,7 +10919,7 @@ LRESULT CALLBACK WndProcW(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) vecY = (float)(raw.data.mouse.lLastY); } - RGFW_mousePosCallback(win, win->internal.lastMouseX, win->internal.lastMouseY, vecX, vecY); + RGFW_rawMotionCallback(win, vecX, vecY); break; } case WM_LBUTTONDOWN: case WM_RBUTTONDOWN: case WM_MBUTTONDOWN: case WM_XBUTTONDOWN: { @@ -10853,10 +10958,9 @@ LRESULT CALLBACK WndProcW(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) /* Move the mouse to the position of the drop */ DragQueryPoint(drop, &pt); - RGFW_dataDragCallback(win, pt.x, pt.y); + RGFW_dataDragCallback(win, RGFW_dataFile, RGFW_dndActionMove, pt.x, pt.y); if (!(win->internal.enabledEvents & RGFW_dataDrop)) return DefWindowProcW(hWnd, message, wParam, lParam); - char** files = _RGFW->files; size_t count = DragQueryFileW(drop, 0xffffffff, NULL, 0); u32 i; @@ -10865,20 +10969,20 @@ LRESULT CALLBACK WndProcW(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) if (length == 0) continue; - WCHAR buffer[RGFW_MAX_PATH * 2]; - if (length > (RGFW_MAX_PATH * 2) - 1) - length = RGFW_MAX_PATH * 2; + WCHAR* buffer = (WCHAR*)RGFW_ALLOC(sizeof(WCHAR) * (length + 1)); + char* cbuffer = (char*)RGFW_ALLOC(length + 1); DragQueryFileW(drop, i, buffer, length + 1); - RGFW_createUTF8FromWideStringWin32(buffer, files[i], RGFW_MAX_PATH); + RGFW_createUTF8FromWideStringWin32(buffer, cbuffer, length); - files[i][RGFW_MAX_PATH - 1] = '\0'; + RGFW_dataDropCallback(win, cbuffer, length + 1, RGFW_dataFile); + RGFW_FREE(buffer); + RGFW_FREE(cbuffer); } DragFinish(drop); - RGFW_dataDropCallback(win, files, count); break; } default: break; @@ -10933,10 +11037,10 @@ RGFW_bool RGFW_createSurfacePtr(u8* data, i32 w, i32 h, RGFW_format format, RGFW (void**) &surface->native.bitmapBits, NULL, (DWORD) 0); - surface->native.format = (format >= RGFW_formatRGBA8) ? RGFW_formatBGRA8 : RGFW_formatBGR8; + surface->native.format = (format >= RGFW_formatRGBA8) ? (RGFW_format) RGFW_formatBGRA8 : (RGFW_format) RGFW_formatBGR8; if (surface->native.bitmap == NULL) { - RGFW_sendDebugInfo(RGFW_typeError, RGFW_errBuffer, "Failed to create DIB section."); + RGFW_debugCallback(RGFW_typeError, RGFW_errBuffer, "Failed to create DIB section."); return RGFW_FALSE; } @@ -10986,7 +11090,7 @@ int RGFW_window_createSwapChain_DirectX(RGFW_window* win, IDXGIFactory* pFactory RGFW_ASSERT(win && pFactory && pDevice && swapchain); static DXGI_SWAP_CHAIN_DESC swapChainDesc; - RGFW_MEMSET(&swapChainDesc, 0, sizeof(swapChainDesc)); + RGFW_MEMZERO(&swapChainDesc, sizeof(swapChainDesc)); swapChainDesc.BufferCount = 2; swapChainDesc.BufferDesc.Width = win->w; swapChainDesc.BufferDesc.Height = win->h; @@ -11000,7 +11104,7 @@ int RGFW_window_createSwapChain_DirectX(RGFW_window* win, IDXGIFactory* pFactory HRESULT hr = pFactory->lpVtbl->CreateSwapChain(pFactory, (IUnknown*)pDevice, &swapChainDesc, swapchain); if (FAILED(hr)) { - RGFW_sendDebugInfo(RGFW_typeError, RGFW_errDirectXContext, "Failed to create DirectX swap chain!"); + RGFW_debugCallback(RGFW_typeError, RGFW_errDirectXContext, "Failed to create DirectX swap chain!"); return -2; } @@ -11010,124 +11114,124 @@ int RGFW_window_createSwapChain_DirectX(RGFW_window* win, IDXGIFactory* pFactory /* we're doing it with magic numbers because some keys are missing */ void RGFW_initKeycodesPlatform(void) { - _RGFW->keycodes[0x00B] = RGFW_0; - _RGFW->keycodes[0x002] = RGFW_1; - _RGFW->keycodes[0x003] = RGFW_2; - _RGFW->keycodes[0x004] = RGFW_3; - _RGFW->keycodes[0x005] = RGFW_4; - _RGFW->keycodes[0x006] = RGFW_5; - _RGFW->keycodes[0x007] = RGFW_6; - _RGFW->keycodes[0x008] = RGFW_7; - _RGFW->keycodes[0x009] = RGFW_8; - _RGFW->keycodes[0x00A] = RGFW_9; - _RGFW->keycodes[0x01E] = RGFW_a; - _RGFW->keycodes[0x030] = RGFW_b; - _RGFW->keycodes[0x02E] = RGFW_c; - _RGFW->keycodes[0x020] = RGFW_d; - _RGFW->keycodes[0x012] = RGFW_e; - _RGFW->keycodes[0x021] = RGFW_f; - _RGFW->keycodes[0x022] = RGFW_g; - _RGFW->keycodes[0x023] = RGFW_h; - _RGFW->keycodes[0x017] = RGFW_i; - _RGFW->keycodes[0x024] = RGFW_j; - _RGFW->keycodes[0x025] = RGFW_k; - _RGFW->keycodes[0x026] = RGFW_l; - _RGFW->keycodes[0x032] = RGFW_m; - _RGFW->keycodes[0x031] = RGFW_n; - _RGFW->keycodes[0x018] = RGFW_o; - _RGFW->keycodes[0x019] = RGFW_p; - _RGFW->keycodes[0x010] = RGFW_q; - _RGFW->keycodes[0x013] = RGFW_r; - _RGFW->keycodes[0x01F] = RGFW_s; - _RGFW->keycodes[0x014] = RGFW_t; - _RGFW->keycodes[0x016] = RGFW_u; - _RGFW->keycodes[0x02F] = RGFW_v; - _RGFW->keycodes[0x011] = RGFW_w; - _RGFW->keycodes[0x02D] = RGFW_x; - _RGFW->keycodes[0x015] = RGFW_y; - _RGFW->keycodes[0x02C] = RGFW_z; - _RGFW->keycodes[0x028] = RGFW_apostrophe; - _RGFW->keycodes[0x02B] = RGFW_backSlash; - _RGFW->keycodes[0x033] = RGFW_comma; - _RGFW->keycodes[0x00D] = RGFW_equals; - _RGFW->keycodes[0x029] = RGFW_backtick; - _RGFW->keycodes[0x01A] = RGFW_bracket; - _RGFW->keycodes[0x00C] = RGFW_minus; - _RGFW->keycodes[0x034] = RGFW_period; - _RGFW->keycodes[0x01B] = RGFW_closeBracket; - _RGFW->keycodes[0x027] = RGFW_semicolon; - _RGFW->keycodes[0x035] = RGFW_slash; - _RGFW->keycodes[0x056] = RGFW_world2; - _RGFW->keycodes[0x00E] = RGFW_backSpace; - _RGFW->keycodes[0x153] = RGFW_delete; - _RGFW->keycodes[0x14F] = RGFW_end; - _RGFW->keycodes[0x01C] = RGFW_enter; - _RGFW->keycodes[0x001] = RGFW_escape; - _RGFW->keycodes[0x147] = RGFW_home; - _RGFW->keycodes[0x152] = RGFW_insert; - _RGFW->keycodes[0x15D] = RGFW_menu; - _RGFW->keycodes[0x151] = RGFW_pageDown; - _RGFW->keycodes[0x149] = RGFW_pageUp; - _RGFW->keycodes[0x045] = RGFW_pause; - _RGFW->keycodes[0x039] = RGFW_space; - _RGFW->keycodes[0x00F] = RGFW_tab; - _RGFW->keycodes[0x03A] = RGFW_capsLock; - _RGFW->keycodes[0x145] = RGFW_numLock; - _RGFW->keycodes[0x046] = RGFW_scrollLock; - _RGFW->keycodes[0x03B] = RGFW_F1; - _RGFW->keycodes[0x03C] = RGFW_F2; - _RGFW->keycodes[0x03D] = RGFW_F3; - _RGFW->keycodes[0x03E] = RGFW_F4; - _RGFW->keycodes[0x03F] = RGFW_F5; - _RGFW->keycodes[0x040] = RGFW_F6; - _RGFW->keycodes[0x041] = RGFW_F7; - _RGFW->keycodes[0x042] = RGFW_F8; - _RGFW->keycodes[0x043] = RGFW_F9; - _RGFW->keycodes[0x044] = RGFW_F10; - _RGFW->keycodes[0x057] = RGFW_F11; - _RGFW->keycodes[0x058] = RGFW_F12; - _RGFW->keycodes[0x064] = RGFW_F13; - _RGFW->keycodes[0x065] = RGFW_F14; - _RGFW->keycodes[0x066] = RGFW_F15; - _RGFW->keycodes[0x067] = RGFW_F16; - _RGFW->keycodes[0x068] = RGFW_F17; - _RGFW->keycodes[0x069] = RGFW_F18; - _RGFW->keycodes[0x06A] = RGFW_F19; - _RGFW->keycodes[0x06B] = RGFW_F20; - _RGFW->keycodes[0x06C] = RGFW_F21; - _RGFW->keycodes[0x06D] = RGFW_F22; - _RGFW->keycodes[0x06E] = RGFW_F23; - _RGFW->keycodes[0x076] = RGFW_F24; - _RGFW->keycodes[0x038] = RGFW_altL; - _RGFW->keycodes[0x01D] = RGFW_controlL; - _RGFW->keycodes[0x02A] = RGFW_shiftL; - _RGFW->keycodes[0x15B] = RGFW_superL; - _RGFW->keycodes[0x137] = RGFW_printScreen; - _RGFW->keycodes[0x138] = RGFW_altR; - _RGFW->keycodes[0x11D] = RGFW_controlR; - _RGFW->keycodes[0x036] = RGFW_shiftR; - _RGFW->keycodes[0x15C] = RGFW_superR; - _RGFW->keycodes[0x150] = RGFW_down; - _RGFW->keycodes[0x14B] = RGFW_left; - _RGFW->keycodes[0x14D] = RGFW_right; - _RGFW->keycodes[0x148] = RGFW_up; - _RGFW->keycodes[0x052] = RGFW_kp0; - _RGFW->keycodes[0x04F] = RGFW_kp1; - _RGFW->keycodes[0x050] = RGFW_kp2; - _RGFW->keycodes[0x051] = RGFW_kp3; - _RGFW->keycodes[0x04B] = RGFW_kp4; - _RGFW->keycodes[0x04C] = RGFW_kp5; - _RGFW->keycodes[0x04D] = RGFW_kp6; - _RGFW->keycodes[0x047] = RGFW_kp7; - _RGFW->keycodes[0x048] = RGFW_kp8; - _RGFW->keycodes[0x049] = RGFW_kp9; - _RGFW->keycodes[0x04E] = RGFW_kpPlus; - _RGFW->keycodes[0x053] = RGFW_kpPeriod; - _RGFW->keycodes[0x135] = RGFW_kpSlash; - _RGFW->keycodes[0x11C] = RGFW_kpReturn; - _RGFW->keycodes[0x059] = RGFW_kpEqual; - _RGFW->keycodes[0x037] = RGFW_kpMultiply; - _RGFW->keycodes[0x04A] = RGFW_kpMinus; + _RGFW->keycodes[0x00B] = RGFW_key0; + _RGFW->keycodes[0x002] = RGFW_key1; + _RGFW->keycodes[0x003] = RGFW_key2; + _RGFW->keycodes[0x004] = RGFW_key3; + _RGFW->keycodes[0x005] = RGFW_key4; + _RGFW->keycodes[0x006] = RGFW_key5; + _RGFW->keycodes[0x007] = RGFW_key6; + _RGFW->keycodes[0x008] = RGFW_key7; + _RGFW->keycodes[0x009] = RGFW_key8; + _RGFW->keycodes[0x00A] = RGFW_key9; + _RGFW->keycodes[0x01E] = RGFW_keyA; + _RGFW->keycodes[0x030] = RGFW_keyB; + _RGFW->keycodes[0x02E] = RGFW_keyC; + _RGFW->keycodes[0x020] = RGFW_keyD; + _RGFW->keycodes[0x012] = RGFW_keyE; + _RGFW->keycodes[0x021] = RGFW_keyF; + _RGFW->keycodes[0x022] = RGFW_keyG; + _RGFW->keycodes[0x023] = RGFW_keyH; + _RGFW->keycodes[0x017] = RGFW_keyI; + _RGFW->keycodes[0x024] = RGFW_keyJ; + _RGFW->keycodes[0x025] = RGFW_keyK; + _RGFW->keycodes[0x026] = RGFW_keyL; + _RGFW->keycodes[0x032] = RGFW_keyM; + _RGFW->keycodes[0x031] = RGFW_keyN; + _RGFW->keycodes[0x018] = RGFW_keyO; + _RGFW->keycodes[0x019] = RGFW_keyP; + _RGFW->keycodes[0x010] = RGFW_keyQ; + _RGFW->keycodes[0x013] = RGFW_keyR; + _RGFW->keycodes[0x01F] = RGFW_keyS; + _RGFW->keycodes[0x014] = RGFW_keyT; + _RGFW->keycodes[0x016] = RGFW_keyU; + _RGFW->keycodes[0x02F] = RGFW_keyV; + _RGFW->keycodes[0x011] = RGFW_keyW; + _RGFW->keycodes[0x02D] = RGFW_keyX; + _RGFW->keycodes[0x015] = RGFW_keyY; + _RGFW->keycodes[0x02C] = RGFW_keyZ; + _RGFW->keycodes[0x028] = RGFW_keyApostrophe; + _RGFW->keycodes[0x02B] = RGFW_keyBackSlash; + _RGFW->keycodes[0x033] = RGFW_keyComma; + _RGFW->keycodes[0x00D] = RGFW_keyEquals; + _RGFW->keycodes[0x029] = RGFW_keyBacktick; + _RGFW->keycodes[0x01A] = RGFW_keyBracket; + _RGFW->keycodes[0x00C] = RGFW_keyMinus; + _RGFW->keycodes[0x034] = RGFW_keyPeriod; + _RGFW->keycodes[0x01B] = RGFW_keyCloseBracket; + _RGFW->keycodes[0x027] = RGFW_keySemicolon; + _RGFW->keycodes[0x035] = RGFW_keySlash; + _RGFW->keycodes[0x056] = RGFW_keyWorld2; + _RGFW->keycodes[0x00E] = RGFW_keyBackSpace; + _RGFW->keycodes[0x153] = RGFW_keyDelete; + _RGFW->keycodes[0x14F] = RGFW_keyEnd; + _RGFW->keycodes[0x01C] = RGFW_keyEnter; + _RGFW->keycodes[0x001] = RGFW_keyEscape; + _RGFW->keycodes[0x147] = RGFW_keyHome; + _RGFW->keycodes[0x152] = RGFW_keyInsert; + _RGFW->keycodes[0x15D] = RGFW_keyMenu; + _RGFW->keycodes[0x151] = RGFW_keyPageDown; + _RGFW->keycodes[0x149] = RGFW_keyPageUp; + _RGFW->keycodes[0x045] = RGFW_keyPause; + _RGFW->keycodes[0x039] = RGFW_keySpace; + _RGFW->keycodes[0x00F] = RGFW_keyTab; + _RGFW->keycodes[0x03A] = RGFW_keyCapsLock; + _RGFW->keycodes[0x145] = RGFW_keyNumLock; + _RGFW->keycodes[0x046] = RGFW_keyScrollLock; + _RGFW->keycodes[0x03B] = RGFW_keyF1; + _RGFW->keycodes[0x03C] = RGFW_keyF2; + _RGFW->keycodes[0x03D] = RGFW_keyF3; + _RGFW->keycodes[0x03E] = RGFW_keyF4; + _RGFW->keycodes[0x03F] = RGFW_keyF5; + _RGFW->keycodes[0x040] = RGFW_keyF6; + _RGFW->keycodes[0x041] = RGFW_keyF7; + _RGFW->keycodes[0x042] = RGFW_keyF8; + _RGFW->keycodes[0x043] = RGFW_keyF9; + _RGFW->keycodes[0x044] = RGFW_keyF10; + _RGFW->keycodes[0x057] = RGFW_keyF11; + _RGFW->keycodes[0x058] = RGFW_keyF12; + _RGFW->keycodes[0x064] = RGFW_keyF13; + _RGFW->keycodes[0x065] = RGFW_keyF14; + _RGFW->keycodes[0x066] = RGFW_keyF15; + _RGFW->keycodes[0x067] = RGFW_keyF16; + _RGFW->keycodes[0x068] = RGFW_keyF17; + _RGFW->keycodes[0x069] = RGFW_keyF18; + _RGFW->keycodes[0x06A] = RGFW_keyF19; + _RGFW->keycodes[0x06B] = RGFW_keyF20; + _RGFW->keycodes[0x06C] = RGFW_keyF21; + _RGFW->keycodes[0x06D] = RGFW_keyF22; + _RGFW->keycodes[0x06E] = RGFW_keyF23; + _RGFW->keycodes[0x076] = RGFW_keyF24; + _RGFW->keycodes[0x038] = RGFW_keyAltL; + _RGFW->keycodes[0x01D] = RGFW_keyControlL; + _RGFW->keycodes[0x02A] = RGFW_keyShiftL; + _RGFW->keycodes[0x15B] = RGFW_keySuperL; + _RGFW->keycodes[0x137] = RGFW_keyPrintScreen; + _RGFW->keycodes[0x138] = RGFW_keyAltR; + _RGFW->keycodes[0x11D] = RGFW_keyControlR; + _RGFW->keycodes[0x036] = RGFW_keyShiftR; + _RGFW->keycodes[0x15C] = RGFW_keySuperR; + _RGFW->keycodes[0x150] = RGFW_keyDown; + _RGFW->keycodes[0x14B] = RGFW_keyLeft; + _RGFW->keycodes[0x14D] = RGFW_keyRight; + _RGFW->keycodes[0x148] = RGFW_keyUp; + _RGFW->keycodes[0x052] = RGFW_keyPad0; + _RGFW->keycodes[0x04F] = RGFW_keyPad1; + _RGFW->keycodes[0x050] = RGFW_keyPad2; + _RGFW->keycodes[0x051] = RGFW_keyPad3; + _RGFW->keycodes[0x04B] = RGFW_keyPad4; + _RGFW->keycodes[0x04C] = RGFW_keyPad5; + _RGFW->keycodes[0x04D] = RGFW_keyPad6; + _RGFW->keycodes[0x047] = RGFW_keyPad7; + _RGFW->keycodes[0x048] = RGFW_keyPad8; + _RGFW->keycodes[0x049] = RGFW_keyPad9; + _RGFW->keycodes[0x04E] = RGFW_keyPadPlus; + _RGFW->keycodes[0x053] = RGFW_keyPadPeriod; + _RGFW->keycodes[0x135] = RGFW_keyPadSlash; + _RGFW->keycodes[0x11C] = RGFW_keyPadReturn; + _RGFW->keycodes[0x059] = RGFW_keyPadEqual; + _RGFW->keycodes[0x037] = RGFW_keyPadMultiply; + _RGFW->keycodes[0x04A] = RGFW_keyPadMinus; } @@ -11165,8 +11269,8 @@ i32 RGFW_initPlatform(void) { #endif u8 RGFW_blk[] = { 0, 0, 0, 0 }; - _RGFW->hiddenMouse = RGFW_loadMouse(RGFW_blk, 1, 1, RGFW_formatRGBA8); - return 1; + _RGFW->hiddenMouse = RGFW_createMouse(RGFW_blk, 1, 1, RGFW_formatRGBA8); + return 0; } RGFW_window* RGFW_createWindowPlatform(const char* name, RGFW_windowFlags flags, RGFW_window* win) { @@ -11207,8 +11311,6 @@ RGFW_window* RGFW_createWindowPlatform(const char* name, RGFW_windowFlags flags, DWORD window_style = WS_CLIPSIBLINGS | WS_CLIPCHILDREN; - RECT windowRect, clientRect; - if (!(flags & RGFW_windowNoBorder)) { window_style |= WS_CAPTION | WS_SYSMENU | WS_BORDER | WS_MINIMIZEBOX; @@ -11221,9 +11323,6 @@ RGFW_window* RGFW_createWindowPlatform(const char* name, RGFW_windowFlags flags, 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); - GetWindowRect(dummyWin, &windowRect); - GetClientRect(dummyWin, &clientRect); - #ifdef RGFW_OPENGL RGFW_win32_loadOpenGLFuncs(dummyWin); #endif @@ -11252,23 +11351,29 @@ RGFW_window* RGFW_createWindowPlatform(const char* name, RGFW_windowFlags flags, void RGFW_window_setBorder(RGFW_window* win, RGFW_bool border) { RGFW_setBit(&win->internal.flags, RGFW_windowNoBorder, !border); + + RECT rect; + GetClientRect(win->src.window, &rect); + LONG style = GetWindowLong(win->src.window, GWL_STYLE); + style |= (LONG)RGFW_winapi_window_getStyle(win, win->internal.flags); if (border == 0) { - SetWindowLong(win->src.window, GWL_STYLE, style & ~WS_OVERLAPPEDWINDOW); - SetWindowPos( - win->src.window, HWND_TOP, 0, 0, 0, 0, - SWP_NOZORDER | SWP_FRAMECHANGED | SWP_SHOWWINDOW | SWP_NOMOVE | SWP_NOSIZE - ); - } - else { + style &= ~WS_OVERLAPPEDWINDOW; + } else { if (win->internal.flags & RGFW_windowNoResize) style &= ~WS_MAXIMIZEBOX; - SetWindowLong(win->src.window, GWL_STYLE, style | WS_OVERLAPPEDWINDOW); - SetWindowPos( - win->src.window, HWND_TOP, 0, 0, 0, 0, - SWP_NOZORDER | SWP_FRAMECHANGED | SWP_SHOWWINDOW | SWP_NOMOVE | SWP_NOSIZE - ); + style |= WS_OVERLAPPEDWINDOW; } + + DWORD exStyle = RGFW_winapi_window_getExStyle(win, win->internal.flags); + ClientToScreen(win->src.window, (POINT*) &rect.left); + ClientToScreen(win->src.window, (POINT*) &rect.right); + + AdjustWindowRectEx(&rect, (DWORD)style, FALSE, exStyle); + SetWindowLong(win->src.window, GWL_STYLE, style); + + SetWindowLongW(win->src.window, GWL_STYLE, style); + SetWindowPos(win->src.window, HWND_TOP, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOZORDER); } void RGFW_window_setDND(RGFW_window* win, RGFW_bool allow) { @@ -11317,15 +11422,18 @@ void RGFW_window_raise(RGFW_window* win) { 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); 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, 0, 0, rect.right - rect.left, rect.bottom - rect.top, SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOMOVE | SWP_NOZORDER); - + 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; @@ -11339,17 +11447,17 @@ void RGFW_window_setFullscreen(RGFW_window* win, RGFW_bool fullscreen) { 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_monitor* mon = RGFW_window_getMonitor(win); - RGFW_window_setBorder(win, 0); - RGFW_monitor_scaleToWindow(mon, win); - - SetWindowPos(win->src.window, HWND_TOPMOST, (i32)mon->x, (i32)mon->y, (i32)mon->mode.w, (i32)mon->mode.h, SWP_NOOWNERZORDER | SWP_FRAMECHANGED | SWP_SHOWWINDOW); + 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; } @@ -11358,6 +11466,7 @@ void RGFW_window_maximize(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) { @@ -11408,75 +11517,85 @@ RGFW_key RGFW_physicalToMappedKey(RGFW_key key) { } switch (vk) { - case VK_F1: return RGFW_F1; - case VK_F2: return RGFW_F2; - case VK_F3: return RGFW_F3; - case VK_F4: return RGFW_F4; - case VK_F5: return RGFW_F5; - case VK_F6: return RGFW_F6; - case VK_F7: return RGFW_F7; - case VK_F8: return RGFW_F8; - case VK_F9: return RGFW_F9; - case VK_F10: return RGFW_F10; - case VK_F11: return RGFW_F11; - case VK_F12: return RGFW_F12; - case VK_F13: return RGFW_F13; - case VK_F14: return RGFW_F14; - case VK_F15: return RGFW_F15; - case VK_F16: return RGFW_F16; - case VK_F17: return RGFW_F17; - case VK_F18: return RGFW_F18; - case VK_F19: return RGFW_F19; - case VK_F20: return RGFW_F20; - case VK_F21: return RGFW_F21; - case VK_F22: return RGFW_F22; - case VK_F23: return RGFW_F23; - case VK_F24: return RGFW_F24; - case VK_LSHIFT: return RGFW_shiftL; - case VK_RSHIFT: return RGFW_shiftR; - case VK_LCONTROL: return RGFW_controlL; - case VK_RCONTROL: return RGFW_controlR; - case VK_LMENU: return RGFW_altL; - case VK_RMENU: return RGFW_altR; - case VK_LWIN: return RGFW_superL; - case VK_RWIN: return RGFW_superR; - case VK_CAPITAL: return RGFW_capsLock; - case VK_NUMLOCK: return RGFW_numLock; - case VK_SCROLL: return RGFW_scrollLock; - case VK_UP: return RGFW_up; - case VK_DOWN: return RGFW_down; - case VK_LEFT: return RGFW_left; - case VK_RIGHT: return RGFW_right; - case VK_HOME: return RGFW_home; - case VK_END: return RGFW_end; - case VK_PRIOR: return RGFW_pageUp; - case VK_NEXT: return RGFW_pageDown; - case VK_INSERT: return RGFW_insert; - case VK_APPS: return RGFW_menu; - case VK_ADD: return RGFW_kpPlus; - case VK_SUBTRACT: return RGFW_kpMinus; - case VK_MULTIPLY: return RGFW_kpMultiply; - case VK_DIVIDE: return RGFW_kpSlash; - case VK_RETURN: return RGFW_kpReturn; - case VK_DECIMAL: return RGFW_kpPeriod; - case VK_NUMPAD0: return RGFW_kp0; - case VK_NUMPAD1: return RGFW_kp1; - case VK_NUMPAD2: return RGFW_kp2; - case VK_NUMPAD3: return RGFW_kp3; - case VK_NUMPAD4: return RGFW_kp4; - case VK_NUMPAD5: return RGFW_kp5; - case VK_NUMPAD6: return RGFW_kp6; - case VK_NUMPAD7: return RGFW_kp7; - case VK_NUMPAD8: return RGFW_kp8; - case VK_NUMPAD9: return RGFW_kp9; - case VK_SNAPSHOT: return RGFW_printScreen; - case VK_PAUSE: return RGFW_pause; + case VK_F1: return RGFW_keyF1; + case VK_F2: return RGFW_keyF2; + case VK_F3: return RGFW_keyF3; + case VK_F4: return RGFW_keyF4; + case VK_F5: return RGFW_keyF5; + case VK_F6: return RGFW_keyF6; + case VK_F7: return RGFW_keyF7; + case VK_F8: return RGFW_keyF8; + case VK_F9: return RGFW_keyF9; + case VK_F10: return RGFW_keyF10; + case VK_F11: return RGFW_keyF11; + case VK_F12: return RGFW_keyF12; + case VK_F13: return RGFW_keyF13; + case VK_F14: return RGFW_keyF14; + case VK_F15: return RGFW_keyF15; + case VK_F16: return RGFW_keyF16; + case VK_F17: return RGFW_keyF17; + case VK_F18: return RGFW_keyF18; + case VK_F19: return RGFW_keyF19; + case VK_F20: return RGFW_keyF20; + case VK_F21: return RGFW_keyF21; + case VK_F22: return RGFW_keyF22; + case VK_F23: return RGFW_keyF23; + case VK_F24: return RGFW_keyF24; + case VK_LSHIFT: return RGFW_keyShiftL; + case VK_RSHIFT: return RGFW_keyShiftR; + case VK_LCONTROL: return RGFW_keyControlL; + case VK_RCONTROL: return RGFW_keyControlR; + case VK_LMENU: return RGFW_keyAltL; + case VK_RMENU: return RGFW_keyAltR; + case VK_LWIN: return RGFW_keySuperL; + case VK_RWIN: return RGFW_keySuperR; + case VK_CAPITAL: return RGFW_keyCapsLock; + case VK_NUMLOCK: return RGFW_keyNumLock; + case VK_SCROLL: return RGFW_keyScrollLock; + case VK_UP: return RGFW_keyUp; + case VK_DOWN: return RGFW_keyDown; + case VK_LEFT: return RGFW_keyLeft; + case VK_RIGHT: return RGFW_keyRight; + case VK_HOME: return RGFW_keyHome; + case VK_END: return RGFW_keyEnd; + case VK_PRIOR: return RGFW_keyPageUp; + case VK_NEXT: return RGFW_keyPageDown; + case VK_INSERT: return RGFW_keyInsert; + case VK_APPS: return RGFW_keyMenu; + case VK_ADD: return RGFW_keyPadPlus; + 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; + case VK_NUMPAD2: return RGFW_keyPad2; + case VK_NUMPAD3: return RGFW_keyPad3; + case VK_NUMPAD4: return RGFW_keyPad4; + case VK_NUMPAD5: return RGFW_keyPad5; + case VK_NUMPAD6: return RGFW_keyPad6; + case VK_NUMPAD7: return RGFW_keyPad7; + case VK_NUMPAD8: return RGFW_keyPad8; + case VK_NUMPAD9: return RGFW_keyPad9; + case VK_SNAPSHOT: return RGFW_keyPrintScreen; + case VK_PAUSE: return RGFW_keyPause; default: return RGFW_keyNULL; } return RGFW_keyNULL; } +RGFW_bool RGFW_window_fetchSize(RGFW_window* win, i32* w, i32* h) { + RECT area; + GetClientRect(win->src.window, &area); + + win->w = area.right; + win->h = area.bottom; + + return RGFW_window_getSize(win, w, h); +} + void RGFW_pollEvents(void) { RGFW_resetPrevState(); MSG msg; @@ -11547,7 +11666,7 @@ size_t RGFW_monitor_getGammaRampPtr(RGFW_monitor* monitor, RGFW_gammaRamp* ramp) RGFW_bool RGFW_monitor_setGammaRamp(RGFW_monitor* monitor, RGFW_gammaRamp* ramp) { WORD values[3][256]; if (ramp->count != 256) { - RGFW_sendDebugInfo(RGFW_typeError, RGFW_errX11, "Win32: Gamma ramp size must be 256"); + RGFW_debugCallback(RGFW_typeError, RGFW_errX11, "Win32: Gamma ramp size must be 256"); return RGFW_FALSE; } @@ -11612,6 +11731,10 @@ size_t RGFW_monitor_getModesPtr(RGFW_monitor* monitor, RGFW_monitorMode** modes) if (!EnumDisplaySettingsW(monitor->node->adapterName, modeIndex, &dm)) break; + if (ChangeDisplaySettingsExW(monitor->node->adapterName, &dm, NULL, CDS_TEST, NULL) != DISP_CHANGE_SUCCESSFUL) { + continue; + } + modeIndex++; if (dm.dmBitsPerPel < 15) @@ -11676,9 +11799,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; @@ -11807,14 +11930,16 @@ RGFW_bool RGFW_monitor_setMode(RGFW_monitor* mon, RGFW_monitorMode* mode) { dm.dmBitsPerPel = (DWORD)(mode->red + mode->green + mode->blue); 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) + if (ChangeDisplaySettingsExW(mon->node->adapterName, &dm, NULL, CDS_UPDATEREGISTRY, NULL) == DISP_CHANGE_SUCCESSFUL) { + RGFW_win32_getMode(&dm, &mon->mode); return RGFW_TRUE; + } return RGFW_FALSE; } else return RGFW_FALSE; } RGFW_bool RGFW_monitor_requestMode(RGFW_monitor* mon, RGFW_monitorMode* mode, RGFW_modeRequest request) { - HMONITOR src = mon->node->hMonitor; +HMONITOR src = mon->node->hMonitor; MONITORINFOEX monitorInfo; monitorInfo.cbSize = sizeof(MONITORINFOEX); @@ -11824,7 +11949,15 @@ RGFW_bool RGFW_monitor_requestMode(RGFW_monitor* mon, RGFW_monitorMode* mode, RG ZeroMemory(&dm, sizeof(dm)); dm.dmSize = sizeof(dm); - if (EnumDisplaySettingsW(mon->node->adapterName, ENUM_CURRENT_SETTINGS, &dm)) { + DWORD index = 0; + + for (;;) { + if (EnumDisplaySettingsW(mon->node->adapterName, index, &dm) == 0) { + break; + } + + index += 1; + if (request & RGFW_monitorScale) { dm.dmFields |= DM_PELSWIDTH | DM_PELSHEIGHT; dm.dmPelsWidth = (u32)mode->w; @@ -11847,7 +11980,7 @@ RGFW_bool RGFW_monitor_requestMode(RGFW_monitor* mon, RGFW_monitorMode* mode, RG return RGFW_TRUE; } return RGFW_FALSE; - } else return RGFW_FALSE; + } } return RGFW_FALSE; @@ -11890,29 +12023,8 @@ HICON RGFW_loadHandleImage(u8* data, i32 w, i32 h, RGFW_format format, BOOL icon return handle; } -RGFW_mouse* RGFW_loadMouse(u8* data, i32 w, i32 h, RGFW_format format) { - HCURSOR cursor = (HCURSOR) RGFW_loadHandleImage(data, w, h, format, FALSE); - return cursor; -} - -void RGFW_window_setMouse(RGFW_window* win, RGFW_mouse* mouse) { - RGFW_ASSERT(win && mouse); - SetClassLongPtrA(win->src.window, GCLP_HCURSOR, (LPARAM) mouse); - SetCursor((HCURSOR)mouse); -} - -void RGFW_freeMouse(RGFW_mouse* mouse) { - RGFW_ASSERT(mouse); - DestroyCursor((HCURSOR)mouse); -} - -RGFW_bool RGFW_window_setMouseDefault(RGFW_window* win) { - return RGFW_window_setMouseStandard(win, RGFW_mouseArrow); -} - -RGFW_bool RGFW_window_setMouseStandard(RGFW_window* win, u8 mouse) { - RGFW_ASSERT(win != NULL); +RGFW_mouse* RGFW_createMouseStandard(RGFW_mouseIcon mouse) { u32 mouseIcon = 0; switch (mouse) { @@ -11937,14 +12049,29 @@ RGFW_bool RGFW_window_setMouseStandard(RGFW_window* win, u8 mouse) { case RGFW_mouseResizeS: mouseIcon = OCR_SIZENS; break; case RGFW_mouseResizeSW: mouseIcon = OCR_SIZENESW; break; case RGFW_mouseResizeW: mouseIcon = OCR_SIZEWE; break; - default: return RGFW_FALSE; + default: return NULL; } char* icon = MAKEINTRESOURCEA(mouseIcon); + return LoadCursorA(NULL, icon); +} - SetClassLongPtrA(win->src.window, GCLP_HCURSOR, (LPARAM) LoadCursorA(NULL, icon)); - SetCursor(LoadCursorA(NULL, icon)); - return RGFW_TRUE; +RGFW_mouse* RGFW_createMouse(u8* data, i32 w, i32 h, RGFW_format format) { + HCURSOR cursor = (HCURSOR) RGFW_loadHandleImage(data, w, h, format, FALSE); + return cursor; +} + +RGFW_bool RGFW_window_setMousePlatform(RGFW_window* win, RGFW_mouse* mouse) { + RGFW_ASSERT(win && mouse); + SetClassLongPtrA(win->src.window, GCLP_HCURSOR, (LPARAM) mouse); + SetCursor((HCURSOR)mouse); + + return RGFW_FALSE; +} + +void RGFW_freeMouse(RGFW_mouse* mouse) { + RGFW_ASSERT(mouse); + DestroyCursor((HCURSOR)mouse); } void RGFW_window_hide(RGFW_window* win) { @@ -11962,7 +12089,7 @@ void RGFW_window_flash(RGFW_window* win, RGFW_flashRequest request) { } FLASHWINFO desc; - RGFW_MEMSET(&desc, 0, sizeof(desc)); + RGFW_MEMZERO(&desc, sizeof(desc)); desc.cbSize = sizeof(desc); desc.hwnd = win->src.window; @@ -12025,12 +12152,10 @@ void RGFW_window_resize(RGFW_window* win, i32 w, i32 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); AdjustWindowRectEx(&rect, style, FALSE, exStyle); - SetWindowPos(win->src.window, HWND_TOP, 0, 0, rect.right - rect.left, rect.bottom - rect.top, SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOMOVE | SWP_NOZORDER); } @@ -12216,7 +12341,7 @@ void RGFW_win32_loadOpenGLFuncs(HWND dummyWin) { wglSwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC)(RGFW_proc)wglGetProcAddress("wglSwapIntervalEXT"); if (wglSwapIntervalEXT == NULL) { - RGFW_sendDebugInfo(RGFW_typeError, RGFW_errOpenGLContext, "Failed to load swap interval function"); + RGFW_debugCallback(RGFW_typeError, RGFW_errOpenGLContext, "Failed to load swap interval function"); } wglMakeCurrent(dummy_dc, cur); @@ -12330,14 +12455,14 @@ RGFW_bool RGFW_window_createContextPtr_OpenGL(RGFW_window* win, RGFW_glContext* UINT num_formats; wglChoosePixelFormatARB(win->src.hdc, pixel_format_attribs, 0, 1, &new_pixel_format, &num_formats); if (!num_formats) - RGFW_sendDebugInfo(RGFW_typeError, RGFW_errOpenGLContext, "Failed to create a pixel format for WGL"); + RGFW_debugCallback(RGFW_typeError, RGFW_errOpenGLContext, "Failed to create a pixel format for WGL"); else pixel_format = new_pixel_format; } PIXELFORMATDESCRIPTOR suggested; if (!DescribePixelFormat(win->src.hdc, pixel_format, sizeof(suggested), &suggested) || !SetPixelFormat(win->src.hdc, pixel_format, &pfd)) - RGFW_sendDebugInfo(RGFW_typeError, RGFW_errOpenGLContext, "Failed to set the WGL pixel format"); + RGFW_debugCallback(RGFW_typeError, RGFW_errOpenGLContext, "Failed to set the WGL pixel format"); if (wglCreateContextAttribsARB != NULL) { /* create OpenGL/WGL context for the specified version */ @@ -12387,7 +12512,7 @@ RGFW_bool RGFW_window_createContextPtr_OpenGL(RGFW_window* win, RGFW_glContext* } if (wglCreateContextAttribsARB == NULL || win->src.ctx.native->ctx == NULL) { /* fall back to a default context (probably OpenGL 2 or something) */ - RGFW_sendDebugInfo(RGFW_typeError, RGFW_errOpenGLContext, "Failed to create an accelerated OpenGL Context."); + RGFW_debugCallback(RGFW_typeError, RGFW_errOpenGLContext, "Failed to create an accelerated OpenGL Context."); win->src.ctx.native->ctx = wglCreateContext(win->src.hdc); } @@ -12399,14 +12524,14 @@ RGFW_bool RGFW_window_createContextPtr_OpenGL(RGFW_window* win, RGFW_glContext* } wglMakeCurrent(win->src.hdc, win->src.ctx.native->ctx); - RGFW_sendDebugInfo(RGFW_typeInfo, RGFW_infoOpenGL, "OpenGL context initalized."); + 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_sendDebugInfo(RGFW_typeInfo, RGFW_infoOpenGL, "OpenGL context freed."); + RGFW_debugCallback(RGFW_typeInfo, RGFW_infoOpenGL, "OpenGL context freed."); } void RGFW_window_makeCurrentContext_OpenGL(RGFW_window* win) { @@ -12426,7 +12551,7 @@ 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_sendDebugInfo(RGFW_typeError, RGFW_errOpenGLContext, "Failed to set swap interval"); + RGFW_debugCallback(RGFW_typeError, RGFW_errOpenGLContext, "Failed to set swap interval"); } #endif @@ -12807,7 +12932,16 @@ NSInteger NSPasteBoard_declareTypes(id pasteboard, NSPasteboardType* newTypes, s static id RGFW__osxCustomInitWithRGFWWindow(id self, SEL _cmd, RGFW_window* win) { RGFW_UNUSED(_cmd); struct objc_super s = { self, class_getSuperclass(object_getClass(self)) }; - self = ((id (*)(struct objc_super*, SEL))objc_msgSendSuper)(&s, sel_registerName("init")); + + CGRect rect; + rect.origin.x = 0; + rect.origin.y = 0; + rect.size.width = (double)win->w; + rect.size.height = (double)win->h; + + self = ((id (*)(struct objc_super*, SEL, CGRect))objc_msgSendSuper)( + &s, sel_registerName("initWithFrame:"), rect + ); if (self != nil) { object_setInstanceVariable(self, "RGFW_window", win); @@ -12845,7 +12979,7 @@ static u32 RGFW_OnClose(id self) { object_getInstanceVariable(self, (const char*)"RGFW_window", (void**)&win); if (win == NULL) return true; - RGFW_windowQuitCallback(win); + RGFW_windowCloseCallback(win); return false; } @@ -12854,22 +12988,28 @@ static bool RGFW__osxAcceptsFirstResponder(void) { return true; } static bool RGFW__osxPerformKeyEquivalent(id event) { RGFW_UNUSED(event); return true; } static NSDragOperation RGFW__osxDraggingEntered(id self, SEL sel, id sender) { - RGFW_UNUSED(sender); RGFW_UNUSED(self); RGFW_UNUSED(sel); + RGFW_UNUSED(sel); + RGFW_window* win = NULL; + object_getInstanceVariable(self, "RGFW_window", (void**)&win); + if (win == NULL) + return 0; + + NSPoint p = ((NSPoint(*)(id, SEL)) objc_msgSend)(sender, sel_registerName("draggingLocation")); + RGFW_dataDragCallback(win, RGFW_dataFile, RGFW_dndActionEnter, (i32) p.x, (i32) (win->h - p.y)); return NSDragOperationCopy; } static NSDragOperation RGFW__osxDraggingUpdated(id self, SEL sel, id sender) { RGFW_UNUSED(sel); RGFW_window* win = NULL; - object_getInstanceVariable(self, "RGFW_window", (void**)&win); if (win == NULL) return 0; if (!(win->internal.enabledEvents & RGFW_dataDragFlag)) return NSDragOperationCopy; NSPoint p = ((NSPoint(*)(id, SEL)) objc_msgSend)(sender, sel_registerName("draggingLocation")); - RGFW_dataDragCallback(win, (i32) p.x, (i32) (win->h - p.y)); + RGFW_dataDragCallback(win, RGFW_dataFile, RGFW_dndActionMove, (i32) p.x, (i32) (win->h - p.y)); return NSDragOperationCopy; } static bool RGFW__osxPrepareForDragOperation(id self) { @@ -12885,12 +13025,22 @@ static bool RGFW__osxPrepareForDragOperation(id self) { return true; } -void RGFW__osxDraggingEnded(id self, SEL sel, id sender); -void RGFW__osxDraggingEnded(id self, SEL sel, id sender) { RGFW_UNUSED(sender); RGFW_UNUSED(self); RGFW_UNUSED(sel); return; } +static void RGFW__osxDraggingEnded(id self, SEL sel, id sender) { + RGFW_UNUSED(sel); + + RGFW_window* win = NULL; + object_getInstanceVariable(self, "RGFW_window", (void**)&win); + if (win == NULL) + return; + if (!(win->internal.enabledEvents & RGFW_dataDragFlag)) return; + + NSPoint p = ((NSPoint(*)(id, SEL)) objc_msgSend)(sender, sel_registerName("draggingLocation")); + RGFW_dataDragCallback(win, RGFW_dataFile, RGFW_dndActionExit, (i32) p.x, (i32) (win->h - p.y)); + return; +} 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); if (win == NULL || (!(win->internal.enabledEvents & RGFW_dataDropFlag))) @@ -12908,7 +13058,7 @@ static bool RGFW__osxPerformDragOperation(id self, SEL sel, id sender) { /* Check if the pasteboard contains file URLs */ if (objc_msgSend_id_bool(types, sel_registerName("containsObject:"), fileURLsType) == 0) { - RGFW_sendDebugInfo(RGFW_typeError, RGFW_errClipboard, "No files found on the pasteboard."); + RGFW_debugCallback(RGFW_typeError, RGFW_errClipboard, "No files found on the pasteboard."); return 0; } @@ -12918,17 +13068,14 @@ static bool RGFW__osxPerformDragOperation(id self, SEL sel, id sender) { if (count == 0) return 0; - char** files = (char**)(void*)_RGFW->files; - u32 i; for (i = 0; i < (u32)count; i++) { id fileURL = objc_msgSend_arr(fileURLs, sel_registerName("objectAtIndex:"), i); const char *filePath = ((const char* (*)(id, SEL))objc_msgSend)(fileURL, sel_registerName("UTF8String")); - RGFW_STRNCPY(files[i], filePath, RGFW_MAX_PATH - 1); - files[i][RGFW_MAX_PATH - 1] = '\0'; - } + int string_count = ((int (*)(id, SEL))objc_msgSend)(fileURL, sel_registerName("count")); - RGFW_dataDropCallback(win, files, (size_t)count); + RGFW_dataDropCallback(win, filePath, (size_t)string_count + 1, RGFW_dataFile); + } return false; } @@ -13038,7 +13185,7 @@ static void RGFW__osxWindowBecameKey(id self, SEL sel) { object_getInstanceVariable(self, "RGFW_window", (void**)&win); if (win == NULL) return; - RGFW_focusCallback(win, RGFW_TRUE); + RGFW_windowFocusCallback(win, RGFW_TRUE); } static void RGFW__osxWindowResignKey(id self, SEL sel) { @@ -13047,7 +13194,7 @@ static void RGFW__osxWindowResignKey(id self, SEL sel) { object_getInstanceVariable(self, "RGFW_window", (void**)&win); if (win == NULL) return; - RGFW_focusCallback(win, RGFW_FALSE); + RGFW_windowFocusCallback(win, RGFW_FALSE); } static void RGFW__osxDidWindowResize(id self, SEL _cmd, id notification) { @@ -13109,7 +13256,7 @@ static void RGFW__osxUpdateLayer(id self, SEL _cmd) { RGFW_window* win = NULL; object_getInstanceVariable(self, "RGFW_window", (void**)&win); if (win == NULL) return; - RGFW_windowRefreshCallback(win); + RGFW_windowRefreshCallback(win, 0, 0, win->w, win->h); } static void RGFW__osxDrawRect(id self, SEL _cmd, CGRect rect) { @@ -13118,7 +13265,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); + 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) { @@ -13149,7 +13298,7 @@ static void RGFW__osxKeyDown(id self, SEL _cmd, id event) { u32 key = (u16)((u32(*)(id, SEL))objc_msgSend)(event, sel_registerName("keyCode")); RGFW_key value = (u8)RGFW_apiKeyToRGFW(key); - RGFW_bool repeat = RGFW_window_isKeyPressed(win, value); + RGFW_bool repeat = RGFW_isKeyDown(value); RGFW_keyCallback(win, value, win->internal.mod, repeat, 1); @@ -13171,9 +13320,8 @@ static void RGFW__osxKeyUp(id self, SEL _cmd, id event) { u32 key = (u16)((u32(*)(id, SEL))objc_msgSend)(event, sel_registerName("keyCode")); RGFW_key value = (u8)RGFW_apiKeyToRGFW(key); - RGFW_bool repeat = RGFW_window_isKeyDown(win, (u8)value); - RGFW_keyCallback(win, value, win->internal.mod, repeat, 0); + RGFW_keyCallback(win, value, win->internal.mod, RGFW_FALSE, 0); } static void RGFW__osxFlagsChanged(id self, SEL _cmd, id event) { @@ -13186,7 +13334,7 @@ static void RGFW__osxFlagsChanged(id self, SEL _cmd, id event) { RGFW_bool pressed = RGFW_FALSE; u32 flags = (u32)((u32(*)(id, SEL))objc_msgSend)(event, sel_registerName("modifierFlags")); - RGFW_updateKeyModsEx(win, + RGFW_keyUpdateKeyModsEx(win, ((u32)(flags & NSEventModifierFlagCapsLock) % 255), ((flags & NSEventModifierFlagNumericPad) % 255), ((flags & NSEventModifierFlagControl) % 255), @@ -13195,28 +13343,27 @@ static void RGFW__osxFlagsChanged(id self, SEL _cmd, id event) { ((flags & NSEventModifierFlagCommand) % 255), 0); u8 i; for (i = 0; i < 9; i++) - _RGFW->keyboard[i + RGFW_capsLock].prev = _RGFW->keyboard[i + RGFW_capsLock].current; + _RGFW->keyboard[i + RGFW_keyCapsLock].prev = _RGFW->keyboard[i + RGFW_keyCapsLock].current; for (i = 0; i < 5; i++) { u32 shift = (1 << (i + 16)); - RGFW_key key = i + RGFW_capsLock; - if ((flags & shift) && !RGFW_window_isKeyDown(win, (u8)key)) { + RGFW_key key = i + RGFW_keyCapsLock; + if ((flags & shift) && !RGFW_isKeyDown((u8)key)) { pressed = RGFW_TRUE; value = (u8)key; break; } - if (!(flags & shift) && RGFW_window_isKeyDown(win, (u8)key)) { + if (!(flags & shift) && RGFW_isKeyDown((u8)key)) { pressed = RGFW_FALSE; value = (u8)key; break; } } - RGFW_bool repeat = RGFW_window_isKeyDown(win, (u8)value); - RGFW_keyCallback(win, value, win->internal.mod, repeat, pressed); + RGFW_keyCallback(win, value, win->internal.mod, RGFW_isKeyDown(value) && pressed, pressed); - if (value != RGFW_capsLock) { - RGFW_keyCallback(win, value + 4, win->internal.mod, repeat, pressed); + if (value != RGFW_keyCapsLock) { + RGFW_keyCallback(win, value + 4, win->internal.mod, RGFW_isKeyDown(value + 4) && pressed, pressed); } } @@ -13232,7 +13379,8 @@ 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), (float)vecX, (float)vecY); + RGFW_mouseMotionCallback(win, (i32)p.x, (i32)(win->h - p.y)); + RGFW_rawMotionCallback(win, (float)vecX, (float)vecY); } static void RGFW__osxMouseDown(id self, SEL _cmd, id event) { @@ -13345,117 +13493,117 @@ void* RGFW_getLayer_OSX(void) { void* RGFW_window_getWindow_OSX(RGFW_window* win) { return win->src.window; } void RGFW_initKeycodesPlatform(void) { - _RGFW->keycodes[0x1D] = RGFW_0; - _RGFW->keycodes[0x12] = RGFW_1; - _RGFW->keycodes[0x13] = RGFW_2; - _RGFW->keycodes[0x14] = RGFW_3; - _RGFW->keycodes[0x15] = RGFW_4; - _RGFW->keycodes[0x17] = RGFW_5; - _RGFW->keycodes[0x16] = RGFW_6; - _RGFW->keycodes[0x1A] = RGFW_7; - _RGFW->keycodes[0x1C] = RGFW_8; - _RGFW->keycodes[0x19] = RGFW_9; - _RGFW->keycodes[0x00] = RGFW_a; - _RGFW->keycodes[0x0B] = RGFW_b; - _RGFW->keycodes[0x08] = RGFW_c; - _RGFW->keycodes[0x02] = RGFW_d; - _RGFW->keycodes[0x0E] = RGFW_e; - _RGFW->keycodes[0x03] = RGFW_f; - _RGFW->keycodes[0x05] = RGFW_g; - _RGFW->keycodes[0x04] = RGFW_h; - _RGFW->keycodes[0x22] = RGFW_i; - _RGFW->keycodes[0x26] = RGFW_j; - _RGFW->keycodes[0x28] = RGFW_k; - _RGFW->keycodes[0x25] = RGFW_l; - _RGFW->keycodes[0x2E] = RGFW_m; - _RGFW->keycodes[0x2D] = RGFW_n; - _RGFW->keycodes[0x1F] = RGFW_o; - _RGFW->keycodes[0x23] = RGFW_p; - _RGFW->keycodes[0x0C] = RGFW_q; - _RGFW->keycodes[0x0F] = RGFW_r; - _RGFW->keycodes[0x01] = RGFW_s; - _RGFW->keycodes[0x11] = RGFW_t; - _RGFW->keycodes[0x20] = RGFW_u; - _RGFW->keycodes[0x09] = RGFW_v; - _RGFW->keycodes[0x0D] = RGFW_w; - _RGFW->keycodes[0x07] = RGFW_x; - _RGFW->keycodes[0x10] = RGFW_y; - _RGFW->keycodes[0x06] = RGFW_z; - _RGFW->keycodes[0x27] = RGFW_apostrophe; - _RGFW->keycodes[0x2A] = RGFW_backSlash; - _RGFW->keycodes[0x2B] = RGFW_comma; - _RGFW->keycodes[0x18] = RGFW_equals; - _RGFW->keycodes[0x32] = RGFW_backtick; - _RGFW->keycodes[0x21] = RGFW_bracket; - _RGFW->keycodes[0x1B] = RGFW_minus; - _RGFW->keycodes[0x2F] = RGFW_period; - _RGFW->keycodes[0x1E] = RGFW_closeBracket; - _RGFW->keycodes[0x29] = RGFW_semicolon; - _RGFW->keycodes[0x2C] = RGFW_slash; - _RGFW->keycodes[0x0A] = RGFW_world1; - _RGFW->keycodes[0x33] = RGFW_backSpace; - _RGFW->keycodes[0x39] = RGFW_capsLock; - _RGFW->keycodes[0x75] = RGFW_delete; - _RGFW->keycodes[0x7D] = RGFW_down; - _RGFW->keycodes[0x77] = RGFW_end; - _RGFW->keycodes[0x24] = RGFW_enter; - _RGFW->keycodes[0x35] = RGFW_escape; - _RGFW->keycodes[0x7A] = RGFW_F1; - _RGFW->keycodes[0x78] = RGFW_F2; - _RGFW->keycodes[0x63] = RGFW_F3; - _RGFW->keycodes[0x76] = RGFW_F4; - _RGFW->keycodes[0x60] = RGFW_F5; - _RGFW->keycodes[0x61] = RGFW_F6; - _RGFW->keycodes[0x62] = RGFW_F7; - _RGFW->keycodes[0x64] = RGFW_F8; - _RGFW->keycodes[0x65] = RGFW_F9; - _RGFW->keycodes[0x6D] = RGFW_F10; - _RGFW->keycodes[0x67] = RGFW_F11; - _RGFW->keycodes[0x6F] = RGFW_F12; - _RGFW->keycodes[0x69] = RGFW_printScreen; - _RGFW->keycodes[0x6B] = RGFW_F14; - _RGFW->keycodes[0x71] = RGFW_F15; - _RGFW->keycodes[0x6A] = RGFW_F16; - _RGFW->keycodes[0x40] = RGFW_F17; - _RGFW->keycodes[0x4F] = RGFW_F18; - _RGFW->keycodes[0x50] = RGFW_F19; - _RGFW->keycodes[0x5A] = RGFW_F20; - _RGFW->keycodes[0x73] = RGFW_home; - _RGFW->keycodes[0x72] = RGFW_insert; - _RGFW->keycodes[0x7B] = RGFW_left; - _RGFW->keycodes[0x3A] = RGFW_altL; - _RGFW->keycodes[0x3B] = RGFW_controlL; - _RGFW->keycodes[0x38] = RGFW_shiftL; - _RGFW->keycodes[0x37] = RGFW_superL; - _RGFW->keycodes[0x6E] = RGFW_menu; - _RGFW->keycodes[0x47] = RGFW_numLock; - _RGFW->keycodes[0x79] = RGFW_pageDown; - _RGFW->keycodes[0x74] = RGFW_pageUp; - _RGFW->keycodes[0x7C] = RGFW_right; - _RGFW->keycodes[0x3D] = RGFW_altR; - _RGFW->keycodes[0x3E] = RGFW_controlR; - _RGFW->keycodes[0x3C] = RGFW_shiftR; - _RGFW->keycodes[0x36] = RGFW_superR; - _RGFW->keycodes[0x31] = RGFW_space; - _RGFW->keycodes[0x30] = RGFW_tab; - _RGFW->keycodes[0x7E] = RGFW_up; - _RGFW->keycodes[0x52] = RGFW_kp0; - _RGFW->keycodes[0x53] = RGFW_kp1; - _RGFW->keycodes[0x54] = RGFW_kp2; - _RGFW->keycodes[0x55] = RGFW_kp3; - _RGFW->keycodes[0x56] = RGFW_kp4; - _RGFW->keycodes[0x57] = RGFW_kp5; - _RGFW->keycodes[0x58] = RGFW_kp6; - _RGFW->keycodes[0x59] = RGFW_kp7; - _RGFW->keycodes[0x5B] = RGFW_kp8; - _RGFW->keycodes[0x5C] = RGFW_kp9; - _RGFW->keycodes[0x45] = RGFW_kpSlash; - _RGFW->keycodes[0x41] = RGFW_kpPeriod; - _RGFW->keycodes[0x4B] = RGFW_kpSlash; - _RGFW->keycodes[0x4C] = RGFW_kpReturn; - _RGFW->keycodes[0x51] = RGFW_kpEqual; - _RGFW->keycodes[0x43] = RGFW_kpMultiply; - _RGFW->keycodes[0x4E] = RGFW_kpMinus; + _RGFW->keycodes[0x1D] = RGFW_key0; + _RGFW->keycodes[0x12] = RGFW_key1; + _RGFW->keycodes[0x13] = RGFW_key2; + _RGFW->keycodes[0x14] = RGFW_key3; + _RGFW->keycodes[0x15] = RGFW_key4; + _RGFW->keycodes[0x17] = RGFW_key5; + _RGFW->keycodes[0x16] = RGFW_key6; + _RGFW->keycodes[0x1A] = RGFW_key7; + _RGFW->keycodes[0x1C] = RGFW_key8; + _RGFW->keycodes[0x19] = RGFW_key9; + _RGFW->keycodes[0x00] = RGFW_keyA; + _RGFW->keycodes[0x0B] = RGFW_keyB; + _RGFW->keycodes[0x08] = RGFW_keyC; + _RGFW->keycodes[0x02] = RGFW_keyD; + _RGFW->keycodes[0x0E] = RGFW_keyE; + _RGFW->keycodes[0x03] = RGFW_keyF; + _RGFW->keycodes[0x05] = RGFW_keyG; + _RGFW->keycodes[0x04] = RGFW_keyH; + _RGFW->keycodes[0x22] = RGFW_keyI; + _RGFW->keycodes[0x26] = RGFW_keyJ; + _RGFW->keycodes[0x28] = RGFW_keyK; + _RGFW->keycodes[0x25] = RGFW_keyL; + _RGFW->keycodes[0x2E] = RGFW_keyM; + _RGFW->keycodes[0x2D] = RGFW_keyN; + _RGFW->keycodes[0x1F] = RGFW_keyO; + _RGFW->keycodes[0x23] = RGFW_keyP; + _RGFW->keycodes[0x0C] = RGFW_keyQ; + _RGFW->keycodes[0x0F] = RGFW_keyR; + _RGFW->keycodes[0x01] = RGFW_keyS; + _RGFW->keycodes[0x11] = RGFW_keyT; + _RGFW->keycodes[0x20] = RGFW_keyU; + _RGFW->keycodes[0x09] = RGFW_keyV; + _RGFW->keycodes[0x0D] = RGFW_keyW; + _RGFW->keycodes[0x07] = RGFW_keyX; + _RGFW->keycodes[0x10] = RGFW_keyY; + _RGFW->keycodes[0x06] = RGFW_keyZ; + _RGFW->keycodes[0x27] = RGFW_keyApostrophe; + _RGFW->keycodes[0x2A] = RGFW_keyBackSlash; + _RGFW->keycodes[0x2B] = RGFW_keyComma; + _RGFW->keycodes[0x18] = RGFW_keyEquals; + _RGFW->keycodes[0x32] = RGFW_keyBacktick; + _RGFW->keycodes[0x21] = RGFW_keyBracket; + _RGFW->keycodes[0x1B] = RGFW_keyMinus; + _RGFW->keycodes[0x2F] = RGFW_keyPeriod; + _RGFW->keycodes[0x1E] = RGFW_keyCloseBracket; + _RGFW->keycodes[0x29] = RGFW_keySemicolon; + _RGFW->keycodes[0x2C] = RGFW_keySlash; + _RGFW->keycodes[0x0A] = RGFW_keyWorld1; + _RGFW->keycodes[0x33] = RGFW_keyBackSpace; + _RGFW->keycodes[0x39] = RGFW_keyCapsLock; + _RGFW->keycodes[0x75] = RGFW_keyDelete; + _RGFW->keycodes[0x7D] = RGFW_keyDown; + _RGFW->keycodes[0x77] = RGFW_keyEnd; + _RGFW->keycodes[0x24] = RGFW_keyEnter; + _RGFW->keycodes[0x35] = RGFW_keyEscape; + _RGFW->keycodes[0x7A] = RGFW_keyF1; + _RGFW->keycodes[0x78] = RGFW_keyF2; + _RGFW->keycodes[0x63] = RGFW_keyF3; + _RGFW->keycodes[0x76] = RGFW_keyF4; + _RGFW->keycodes[0x60] = RGFW_keyF5; + _RGFW->keycodes[0x61] = RGFW_keyF6; + _RGFW->keycodes[0x62] = RGFW_keyF7; + _RGFW->keycodes[0x64] = RGFW_keyF8; + _RGFW->keycodes[0x65] = RGFW_keyF9; + _RGFW->keycodes[0x6D] = RGFW_keyF10; + _RGFW->keycodes[0x67] = RGFW_keyF11; + _RGFW->keycodes[0x6F] = RGFW_keyF12; + _RGFW->keycodes[0x69] = RGFW_keyPrintScreen; + _RGFW->keycodes[0x6B] = RGFW_keyF14; + _RGFW->keycodes[0x71] = RGFW_keyF15; + _RGFW->keycodes[0x6A] = RGFW_keyF16; + _RGFW->keycodes[0x40] = RGFW_keyF17; + _RGFW->keycodes[0x4F] = RGFW_keyF18; + _RGFW->keycodes[0x50] = RGFW_keyF19; + _RGFW->keycodes[0x5A] = RGFW_keyF20; + _RGFW->keycodes[0x73] = RGFW_keyHome; + _RGFW->keycodes[0x72] = RGFW_keyInsert; + _RGFW->keycodes[0x7B] = RGFW_keyLeft; + _RGFW->keycodes[0x3A] = RGFW_keyAltL; + _RGFW->keycodes[0x3B] = RGFW_keyControlL; + _RGFW->keycodes[0x38] = RGFW_keyShiftL; + _RGFW->keycodes[0x37] = RGFW_keySuperL; + _RGFW->keycodes[0x6E] = RGFW_keyMenu; + _RGFW->keycodes[0x47] = RGFW_keyNumLock; + _RGFW->keycodes[0x79] = RGFW_keyPageDown; + _RGFW->keycodes[0x74] = RGFW_keyPageUp; + _RGFW->keycodes[0x7C] = RGFW_keyRight; + _RGFW->keycodes[0x3D] = RGFW_keyAltR; + _RGFW->keycodes[0x3E] = RGFW_keyControlR; + _RGFW->keycodes[0x3C] = RGFW_keyShiftR; + _RGFW->keycodes[0x36] = RGFW_keySuperR; + _RGFW->keycodes[0x31] = RGFW_keySpace; + _RGFW->keycodes[0x30] = RGFW_keyTab; + _RGFW->keycodes[0x7E] = RGFW_keyUp; + _RGFW->keycodes[0x52] = RGFW_keyPad0; + _RGFW->keycodes[0x53] = RGFW_keyPad1; + _RGFW->keycodes[0x54] = RGFW_keyPad2; + _RGFW->keycodes[0x55] = RGFW_keyPad3; + _RGFW->keycodes[0x56] = RGFW_keyPad4; + _RGFW->keycodes[0x57] = RGFW_keyPad5; + _RGFW->keycodes[0x58] = RGFW_keyPad6; + _RGFW->keycodes[0x59] = RGFW_keyPad7; + _RGFW->keycodes[0x5B] = RGFW_keyPad8; + _RGFW->keycodes[0x5C] = RGFW_keyPad9; + _RGFW->keycodes[0x45] = RGFW_keyPadSlash; + _RGFW->keycodes[0x41] = RGFW_keyPadPeriod; + _RGFW->keycodes[0x4B] = RGFW_keyPadSlash; + _RGFW->keycodes[0x4C] = RGFW_keyPadReturn; + _RGFW->keycodes[0x51] = RGFW_keyPadEqual; + _RGFW->keycodes[0x43] = RGFW_keyPadMultiply; + _RGFW->keycodes[0x4E] = RGFW_keyPadMinus; } i32 RGFW_initPlatform(void) { @@ -13733,6 +13881,15 @@ RGFW_key RGFW_physicalToMappedKey(RGFW_key key) { return key; } +RGFW_bool RGFW_window_fetchSize(RGFW_window* win, i32* w, i32* h) { + NSRect content = ((NSRect(*)(id, SEL))abi_objc_msgSend_stret)((id)win->src.view, sel_registerName("frame")); + + win->w = (i32)content.size.width; + win->h = (i32)content.size.height; + + return RGFW_window_getSize(win, w, h); +} + void RGFW_pollEvents(void) { RGFW_resetPrevState(); @@ -13846,6 +14003,7 @@ void RGFW_window_maximize(RGFW_window* win) { 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) { @@ -13956,10 +14114,40 @@ id NSCursor_arrowStr(const char* str); id NSCursor_arrowStr(const char* str) { void* nclass = objc_getClass("NSCursor"); SEL func = sel_registerName(str); - return (id) objc_msgSend_id(nclass, func); + id mouse = (id) objc_msgSend_id(nclass, func); + NSRetain(mouse); + return mouse; } -RGFW_mouse* RGFW_loadMouse(u8* data, i32 w, i32 h, RGFW_format format) { +RGFW_mouse* RGFW_createMouseStandard(RGFW_mouseIcon mouse) { + switch (mouse) { + case RGFW_mouseNormal: return NSCursor_arrowStr("arrowCursor"); + case RGFW_mouseArrow: return NSCursor_arrowStr("arrowCursor"); + case RGFW_mouseIbeam: return NSCursor_arrowStr("IBeamCursor"); + case RGFW_mouseCrosshair: return NSCursor_arrowStr("crosshairCursor"); + case RGFW_mousePointingHand: return NSCursor_arrowStr("pointingHandCursor"); + case RGFW_mouseResizeEW: return NSCursor_arrowStr("resizeLeftRightCursor"); + case RGFW_mouseResizeE: return NSCursor_arrowStr("resizeLeftRightCursor"); + case RGFW_mouseResizeW: return NSCursor_arrowStr("resizeLeftRightCursor"); + case RGFW_mouseResizeNS: return NSCursor_arrowStr("resizeUpDownCursor"); + case RGFW_mouseResizeN: return NSCursor_arrowStr("resizeUpDownCursor"); + case RGFW_mouseResizeS: return NSCursor_arrowStr("resizeUpDownCursor"); + case RGFW_mouseResizeNWSE: return NSCursor_arrowStr("_windowResizeNorthWestSouthEastCursor"); + case RGFW_mouseResizeNW: return NSCursor_arrowStr("_windowResizeNorthWestSouthEastCursor"); + case RGFW_mouseResizeSE: return NSCursor_arrowStr("_windowResizeNorthWestSouthEastCursor"); + case RGFW_mouseResizeNESW: return NSCursor_arrowStr("_windowResizeNorthEastSouthWestCursor"); + case RGFW_mouseResizeNE: return NSCursor_arrowStr("_windowResizeNorthEastSouthWestCursor"); + case RGFW_mouseResizeSW: return NSCursor_arrowStr("_windowResizeNorthEastSouthWestCursor"); + case RGFW_mouseResizeAll: return NSCursor_arrowStr("openHandCursor"); + case RGFW_mouseNotAllowed: return NSCursor_arrowStr("operationNotAllowedCursor"); + case RGFW_mouseWait: return NSCursor_arrowStr("arrowCursor"); + case RGFW_mouseProgress: return NSCursor_arrowStr("arrowCursor"); + default: return NULL; + } + return NULL; +} + +RGFW_mouse* RGFW_createMouse(u8* data, i32 w, i32 h, RGFW_format format) { id pool = objc_msgSend_class(objc_getClass("NSAutoreleasePool"), sel_registerName("alloc")); pool = objc_msgSend_id(pool, sel_registerName("init")); @@ -13988,11 +14176,12 @@ RGFW_mouse* RGFW_loadMouse(u8* data, i32 w, i32 h, RGFW_format format) { return (void*)cursor; } -void RGFW_window_setMouse(RGFW_window* win, RGFW_mouse* mouse) { +RGFW_bool RGFW_window_setMousePlatform(RGFW_window* win, RGFW_mouse* mouse) { RGFW_ASSERT(win != NULL); RGFW_ASSERT(mouse); CGDisplayShowCursor(kCGDirectMainDisplay); objc_msgSend_void((id)mouse, sel_registerName("set")); win->src.mouse = mouse; + return RGFW_TRUE; } void RGFW_freeMouse(RGFW_mouse* mouse) { @@ -14000,57 +14189,12 @@ void RGFW_freeMouse(RGFW_mouse* mouse) { NSRelease((id)mouse); } -RGFW_bool RGFW_window_setMouseDefault(RGFW_window* win) { - return RGFW_window_setMouseStandard(win, RGFW_mouseArrow); -} - void RGFW_window_showMouse(RGFW_window* win, RGFW_bool show) { RGFW_window_showMouseFlags(win, show); if (show) CGDisplayShowCursor(kCGDirectMainDisplay); else CGDisplayHideCursor(kCGDirectMainDisplay); } -RGFW_bool RGFW_window_setMouseStandard(RGFW_window* win, u8 stdMouse) { - const char* cursorSelectorStr; - switch (stdMouse) { - case RGFW_mouseNormal: cursorSelectorStr = "arrowCursor"; break; - case RGFW_mouseArrow: cursorSelectorStr = "arrowCursor"; break; - case RGFW_mouseIbeam: cursorSelectorStr = "IBeamCursor"; break; - case RGFW_mouseCrosshair: cursorSelectorStr = "crosshairCursor"; break; - case RGFW_mousePointingHand: cursorSelectorStr = "pointingHandCursor"; break; - case RGFW_mouseResizeEW: cursorSelectorStr = "resizeLeftRightCursor"; break; - case RGFW_mouseResizeE: cursorSelectorStr = "resizeLeftRightCursor"; break; - case RGFW_mouseResizeW: cursorSelectorStr = "resizeLeftRightCursor"; break; - case RGFW_mouseResizeNS: cursorSelectorStr = "resizeUpDownCursor"; break; - case RGFW_mouseResizeN: cursorSelectorStr = "resizeUpDownCursor"; break; - case RGFW_mouseResizeS: cursorSelectorStr = "resizeUpDownCursor"; break; - case RGFW_mouseResizeNWSE: cursorSelectorStr = "_windowResizeNorthWestSouthEastCursor"; break; - case RGFW_mouseResizeNW: cursorSelectorStr = "_windowResizeNorthWestSouthEastCursor"; break; - case RGFW_mouseResizeSE: cursorSelectorStr = "_windowResizeNorthWestSouthEastCursor"; break; - case RGFW_mouseResizeNESW: cursorSelectorStr = "_windowResizeNorthEastSouthWestCursor"; break; - case RGFW_mouseResizeNE: cursorSelectorStr = "_windowResizeNorthEastSouthWestCursor"; break; - case RGFW_mouseResizeSW: cursorSelectorStr = "_windowResizeNorthEastSouthWestCursor"; break; - case RGFW_mouseResizeAll: cursorSelectorStr = "openHandCursor"; break; - case RGFW_mouseNotAllowed: cursorSelectorStr = "operationNotAllowedCursor"; break; - case RGFW_mouseWait: cursorSelectorStr = "arrowCursor"; break; - case RGFW_mouseProgress: cursorSelectorStr = "arrowCursor"; break; - default: - return RGFW_FALSE; - } - - id mouse = NSCursor_arrowStr(cursorSelectorStr); - - if (mouse == NULL) - return RGFW_FALSE; - - RGFW_UNUSED(win); - CGDisplayShowCursor(kCGDirectMainDisplay); - objc_msgSend_void(mouse, sel_registerName("set")); - win->src.mouse = mouse; - - return RGFW_TRUE; -} - void RGFW_window_setRawMouseModePlatform(RGFW_window* win, RGFW_bool state) { RGFW_UNUSED(win); RGFW_UNUSED(state); } @@ -14164,14 +14308,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; @@ -14243,6 +14390,8 @@ void RGFW_pollMonitors(void) { RGFW_monitorCallback(_RGFW->root, &node->mon, RGFW_TRUE); } + RGFW_FREE(displays); + RGFW_monitors_refresh(); } @@ -14388,6 +14537,11 @@ RGFW_monitor* RGFW_window_getMonitor(RGFW_window* win) { } } + if (node == NULL) { + node = _RGFW->monitors.primary ? _RGFW->monitors.primary : _RGFW->monitors.list.head; + } + + if (node == NULL) return NULL; return &node->mon; } @@ -14499,7 +14653,7 @@ RGFW_bool RGFW_window_createContextPtr_OpenGL(RGFW_window* win, RGFW_glContext* void* format = (void*) ((id(*)(id, SEL, const u32*))objc_msgSend) (NSAlloc((id)objc_getClass("NSOpenGLPixelFormat")), sel_registerName("initWithAttributes:"), (u32*)attribs); if (format == NULL) { - RGFW_sendDebugInfo(RGFW_typeError, RGFW_errOpenGLContext, "Failed to load pixel format for OpenGL"); + RGFW_debugCallback(RGFW_typeError, RGFW_errOpenGLContext, "Failed to load pixel format for OpenGL"); assert(render_type_index + 3 < (sizeof(attribs) / sizeof(attribs[0]))); attribs[render_type_index] = NSOpenGLPFARendererID; @@ -14508,9 +14662,9 @@ RGFW_bool RGFW_window_createContextPtr_OpenGL(RGFW_window* win, RGFW_glContext* format = (void*) ((id(*)(id, SEL, const u32*))objc_msgSend) (NSAlloc((id)objc_getClass("NSOpenGLPixelFormat")), sel_registerName("initWithAttributes:"), (u32*)attribs); if (format == NULL) - RGFW_sendDebugInfo(RGFW_typeError, RGFW_errOpenGLContext, "and loading software rendering OpenGL failed"); + RGFW_debugCallback(RGFW_typeError, RGFW_errOpenGLContext, "and loading software rendering OpenGL failed"); else - RGFW_sendDebugInfo(RGFW_typeWarning, RGFW_warningOpenGL, "Switching to software rendering"); + RGFW_debugCallback(RGFW_typeWarning, RGFW_warningOpenGL, "Switching to software rendering"); } /* the pixel format can be passed directly to OpenGL context creation to create a context @@ -14548,7 +14702,7 @@ RGFW_bool RGFW_window_createContextPtr_OpenGL(RGFW_window* win, RGFW_glContext* RGFW_window_swapInterval_OpenGL(win, 0); - RGFW_sendDebugInfo(RGFW_typeInfo, RGFW_infoOpenGL, "OpenGL context initalized."); + RGFW_debugCallback(RGFW_typeInfo, RGFW_infoOpenGL, "OpenGL context initalized."); return RGFW_TRUE; } @@ -14558,7 +14712,7 @@ void RGFW_window_deleteContextPtr_OpenGL(RGFW_window* win, RGFW_glContext* ctx) objc_msgSend_void(ctx->ctx, sel_registerName("release")); win->src.ctx.native->ctx = NULL; - RGFW_sendDebugInfo(RGFW_typeInfo, RGFW_infoOpenGL, "OpenGL context freed."); + RGFW_debugCallback(RGFW_typeInfo, RGFW_infoOpenGL, "OpenGL context freed."); } void RGFW_window_makeCurrentContext_OpenGL(RGFW_window* win) { @@ -14619,7 +14773,7 @@ VkResult RGFW_window_createSurface_Vulkan(RGFW_window* win, VkInstance instance, id nsView = (id)win->src.view; if (!nsView) { - RGFW_sendDebugInfo(RGFW_typeError, RGFW_errMetal, "NSView is NULL for macOS window"); + RGFW_debugCallback(RGFW_typeError, RGFW_errMetal, "NSView is NULL for macOS window"); return -1; } @@ -14638,12 +14792,12 @@ VkResult RGFW_window_createSurface_Vulkan(RGFW_window* win, VkInstance instance, VkMetalSurfaceCreateInfoEXT macos; macos.sType = VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK; macos.slayer = metalLayer; - RGFW_MEMSET(&macos, 0, sizeof(macos)); + RGFW_MEMZERO(&macos, sizeof(macos)); result = vkCreateMacOSSurfaceMVK(instance, &macos, NULL, surface); */ VkMacOSSurfaceCreateInfoMVK macos; - RGFW_MEMSET(&macos, 0, sizeof(macos)); + RGFW_MEMZERO(&macos, sizeof(macos)); macos.sType = VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK; macos.pView = nsView; @@ -14660,7 +14814,7 @@ WGPUSurface RGFW_window_createSurface_WebGPU(RGFW_window* window, WGPUInstance i WGPUSurfaceDescriptor surfaceDesc = {0}; id* nsView = (id*)window->src.view; if (!nsView) { - RGFW_sendDebugInfo(RGFW_typeError, RGFW_errMetal, "NSView is NULL for macOS window"); + RGFW_debugCallback(RGFW_typeError, RGFW_errMetal, "NSView is NULL for macOS window"); return NULL; } @@ -14746,20 +14900,21 @@ EM_BOOL Emscripten_on_fullscreenchange(int eventType, const EmscriptenFullscreen EM_BOOL Emscripten_on_focusin(int eventType, const EmscriptenFocusEvent* E, void* userData) { RGFW_UNUSED(eventType); RGFW_UNUSED(userData); RGFW_UNUSED(E); - RGFW_focusCallback(_RGFW->root, 1); + RGFW_windowFocusCallback(_RGFW->root, 1); return EM_TRUE; } EM_BOOL Emscripten_on_focusout(int eventType, const EmscriptenFocusEvent* E, void* userData) { RGFW_UNUSED(eventType); RGFW_UNUSED(userData); RGFW_UNUSED(E); - RGFW_focusCallback(_RGFW->root, 0); + RGFW_windowFocusCallback(_RGFW->root, 0); return EM_TRUE; } 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, E->movementX, E->movementY); + RGFW_mouseMotionCallback(_RGFW->root, E->targetX, E->targetY); + RGFW_rawMotionCallback(_RGFW->root, E->movementX, E->movementY); return EM_TRUE; } @@ -14800,7 +14955,8 @@ 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, 0, 0); + 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); } @@ -14810,11 +14966,12 @@ 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, 0, 0); + RGFW_mouseMotionCallback(_RGFW->root, E->touches[i].targetX, E->touches[i].targetY); + RGFW_rawMotionCallback(_RGFW->root, 0, 0); } return EM_TRUE; } @@ -14826,7 +14983,8 @@ 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, 0, 0); + 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); } return EM_TRUE; @@ -14844,20 +15002,22 @@ void EMSCRIPTEN_KEEPALIVE RGFW_handleKeyEvent(char* code, u32 codepoint, RGFW_bo u32 physicalKey = RGFW_WASMPhysicalToRGFW(hash); - RGFW_keyCallback(_RGFW->root, physicalKey, _RGFW->root->internal.mod, RGFW_window_isKeyDown(_RGFW->root, (u8)physicalKey), press); + RGFW_keyCallback(_RGFW->root, physicalKey, _RGFW->root->internal.mod, RGFW_isKeyDown((u8)physicalKey) && press, press); if (press) { ; RGFW_keyCharCallback(_RGFW->root, codepoint); } } void EMSCRIPTEN_KEEPALIVE RGFW_handleKeyMods(RGFW_bool capital, RGFW_bool numlock, RGFW_bool control, RGFW_bool alt, RGFW_bool shift, RGFW_bool super, RGFW_bool scroll) { - RGFW_updateKeyModsEx(_RGFW->root, capital, numlock, control, alt, shift, super, scroll); + RGFW_keyUpdateKeyModsEx(_RGFW->root, capital, numlock, control, alt, shift, super, scroll); } -void EMSCRIPTEN_KEEPALIVE Emscripten_onDrop(size_t count) { - RGFW_dataDropCallback(_RGFW->root, _RGFW->files, count); +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; } @@ -14884,14 +15044,6 @@ void RGFW_window_blitSurface(RGFW_window* win, RGFW_surface* surface) { void RGFW_surface_freePtr(RGFW_surface* surface) { } -void EMSCRIPTEN_KEEPALIVE RGFW_makeSetValue(size_t index, char* file) { - /* This seems like a terrible idea, don't replicate this unless you hate yourself or the OS */ - /* TODO: find a better way to do this - */ - RGFW_STRNCPY((char*)_RGFW->files[index], file, RGFW_MAX_PATH - 1); - _RGFW->files[index][RGFW_MAX_PATH - 1] = '\0'; -} - #include #include #include @@ -14909,117 +15061,148 @@ void EMSCRIPTEN_KEEPALIVE RGFW_writeFile(const char *path, const char *data, siz } void RGFW_initKeycodesPlatform(void) { - _RGFW->keycodes[DOM_VK_BACK_QUOTE] = RGFW_backtick; - _RGFW->keycodes[DOM_VK_0] = RGFW_0; - _RGFW->keycodes[DOM_VK_1] = RGFW_1; - _RGFW->keycodes[DOM_VK_2] = RGFW_2; - _RGFW->keycodes[DOM_VK_3] = RGFW_3; - _RGFW->keycodes[DOM_VK_4] = RGFW_4; - _RGFW->keycodes[DOM_VK_5] = RGFW_5; - _RGFW->keycodes[DOM_VK_6] = RGFW_6; - _RGFW->keycodes[DOM_VK_7] = RGFW_7; - _RGFW->keycodes[DOM_VK_8] = RGFW_8; - _RGFW->keycodes[DOM_VK_9] = RGFW_9; - _RGFW->keycodes[DOM_VK_SPACE] = RGFW_space; - _RGFW->keycodes[DOM_VK_A] = RGFW_a; - _RGFW->keycodes[DOM_VK_B] = RGFW_b; - _RGFW->keycodes[DOM_VK_C] = RGFW_c; - _RGFW->keycodes[DOM_VK_D] = RGFW_d; - _RGFW->keycodes[DOM_VK_E] = RGFW_e; - _RGFW->keycodes[DOM_VK_F] = RGFW_f; - _RGFW->keycodes[DOM_VK_G] = RGFW_g; - _RGFW->keycodes[DOM_VK_H] = RGFW_h; - _RGFW->keycodes[DOM_VK_I] = RGFW_i; - _RGFW->keycodes[DOM_VK_J] = RGFW_j; - _RGFW->keycodes[DOM_VK_K] = RGFW_k; - _RGFW->keycodes[DOM_VK_L] = RGFW_l; - _RGFW->keycodes[DOM_VK_M] = RGFW_m; - _RGFW->keycodes[DOM_VK_N] = RGFW_n; - _RGFW->keycodes[DOM_VK_O] = RGFW_o; - _RGFW->keycodes[DOM_VK_P] = RGFW_p; - _RGFW->keycodes[DOM_VK_Q] = RGFW_q; - _RGFW->keycodes[DOM_VK_R] = RGFW_r; - _RGFW->keycodes[DOM_VK_S] = RGFW_s; - _RGFW->keycodes[DOM_VK_T] = RGFW_t; - _RGFW->keycodes[DOM_VK_U] = RGFW_u; - _RGFW->keycodes[DOM_VK_V] = RGFW_v; - _RGFW->keycodes[DOM_VK_W] = RGFW_w; - _RGFW->keycodes[DOM_VK_X] = RGFW_x; - _RGFW->keycodes[DOM_VK_Y] = RGFW_y; - _RGFW->keycodes[DOM_VK_Z] = RGFW_z; - _RGFW->keycodes[DOM_VK_PERIOD] = RGFW_period; - _RGFW->keycodes[DOM_VK_COMMA] = RGFW_comma; - _RGFW->keycodes[DOM_VK_SLASH] = RGFW_slash; - _RGFW->keycodes[DOM_VK_OPEN_BRACKET] = RGFW_bracket; - _RGFW->keycodes[DOM_VK_CLOSE_BRACKET] = RGFW_closeBracket; - _RGFW->keycodes[DOM_VK_SEMICOLON] = RGFW_semicolon; - _RGFW->keycodes[DOM_VK_QUOTE] = RGFW_apostrophe; - _RGFW->keycodes[DOM_VK_BACK_SLASH] = RGFW_backSlash; - _RGFW->keycodes[DOM_VK_RETURN] = RGFW_return; - _RGFW->keycodes[DOM_VK_DELETE] = RGFW_delete; - _RGFW->keycodes[DOM_VK_NUM_LOCK] = RGFW_numLock; - _RGFW->keycodes[DOM_VK_DIVIDE] = RGFW_kpSlash; - _RGFW->keycodes[DOM_VK_MULTIPLY] = RGFW_kpMultiply; - _RGFW->keycodes[DOM_VK_SUBTRACT] = RGFW_kpMinus; - _RGFW->keycodes[DOM_VK_NUMPAD1] = RGFW_kp1; - _RGFW->keycodes[DOM_VK_NUMPAD2] = RGFW_kp2; - _RGFW->keycodes[DOM_VK_NUMPAD3] = RGFW_kp3; - _RGFW->keycodes[DOM_VK_NUMPAD4] = RGFW_kp4; - _RGFW->keycodes[DOM_VK_NUMPAD5] = RGFW_kp5; - _RGFW->keycodes[DOM_VK_NUMPAD6] = RGFW_kp6; - _RGFW->keycodes[DOM_VK_NUMPAD9] = RGFW_kp9; - _RGFW->keycodes[DOM_VK_NUMPAD0] = RGFW_kp0; - _RGFW->keycodes[DOM_VK_DECIMAL] = RGFW_kpPeriod; - _RGFW->keycodes[DOM_VK_RETURN] = RGFW_kpReturn; - _RGFW->keycodes[DOM_VK_HYPHEN_MINUS] = RGFW_minus; - _RGFW->keycodes[DOM_VK_EQUALS] = RGFW_equals; - _RGFW->keycodes[DOM_VK_BACK_SPACE] = RGFW_backSpace; - _RGFW->keycodes[DOM_VK_TAB] = RGFW_tab; - _RGFW->keycodes[DOM_VK_CAPS_LOCK] = RGFW_capsLock; - _RGFW->keycodes[DOM_VK_SHIFT] = RGFW_shiftL; - _RGFW->keycodes[DOM_VK_CONTROL] = RGFW_controlL; - _RGFW->keycodes[DOM_VK_ALT] = RGFW_altL; - _RGFW->keycodes[DOM_VK_META] = RGFW_superL; - _RGFW->keycodes[DOM_VK_F1] = RGFW_F1; - _RGFW->keycodes[DOM_VK_F2] = RGFW_F2; - _RGFW->keycodes[DOM_VK_F3] = RGFW_F3; - _RGFW->keycodes[DOM_VK_F4] = RGFW_F4; - _RGFW->keycodes[DOM_VK_F5] = RGFW_F5; - _RGFW->keycodes[DOM_VK_F6] = RGFW_F6; - _RGFW->keycodes[DOM_VK_F7] = RGFW_F7; - _RGFW->keycodes[DOM_VK_F8] = RGFW_F8; - _RGFW->keycodes[DOM_VK_F9] = RGFW_F9; - _RGFW->keycodes[DOM_VK_F10] = RGFW_F10; - _RGFW->keycodes[DOM_VK_F11] = RGFW_F11; - _RGFW->keycodes[DOM_VK_F12] = RGFW_F12; - _RGFW->keycodes[DOM_VK_UP] = RGFW_up; - _RGFW->keycodes[DOM_VK_DOWN] = RGFW_down; - _RGFW->keycodes[DOM_VK_LEFT] = RGFW_left; - _RGFW->keycodes[DOM_VK_RIGHT] = RGFW_right; - _RGFW->keycodes[DOM_VK_INSERT] = RGFW_insert; - _RGFW->keycodes[DOM_VK_END] = RGFW_end; - _RGFW->keycodes[DOM_VK_PAGE_UP] = RGFW_pageUp; - _RGFW->keycodes[DOM_VK_PAGE_DOWN] = RGFW_pageDown; - _RGFW->keycodes[DOM_VK_ESCAPE] = RGFW_escape; - _RGFW->keycodes[DOM_VK_HOME] = RGFW_home; - _RGFW->keycodes[DOM_VK_SCROLL_LOCK] = RGFW_scrollLock; - _RGFW->keycodes[DOM_VK_PRINTSCREEN] = RGFW_printScreen; - _RGFW->keycodes[DOM_VK_PAUSE] = RGFW_pause; - _RGFW->keycodes[DOM_VK_F13] = RGFW_F13; - _RGFW->keycodes[DOM_VK_F14] = RGFW_F14; - _RGFW->keycodes[DOM_VK_F15] = RGFW_F15; - _RGFW->keycodes[DOM_VK_F16] = RGFW_F16; - _RGFW->keycodes[DOM_VK_F17] = RGFW_F17; - _RGFW->keycodes[DOM_VK_F18] = RGFW_F18; - _RGFW->keycodes[DOM_VK_F19] = RGFW_F19; - _RGFW->keycodes[DOM_VK_F20] = RGFW_F20; - _RGFW->keycodes[DOM_VK_F21] = RGFW_F21; - _RGFW->keycodes[DOM_VK_F22] = RGFW_F22; - _RGFW->keycodes[DOM_VK_F23] = RGFW_F23; - _RGFW->keycodes[DOM_VK_F24] = RGFW_F24; + _RGFW->keycodes[DOM_VK_BACK_QUOTE] = RGFW_keyBacktick; + _RGFW->keycodes[DOM_VK_0] = RGFW_key0; + _RGFW->keycodes[DOM_VK_1] = RGFW_key1; + _RGFW->keycodes[DOM_VK_2] = RGFW_key2; + _RGFW->keycodes[DOM_VK_3] = RGFW_key3; + _RGFW->keycodes[DOM_VK_4] = RGFW_key4; + _RGFW->keycodes[DOM_VK_5] = RGFW_key5; + _RGFW->keycodes[DOM_VK_6] = RGFW_key6; + _RGFW->keycodes[DOM_VK_7] = RGFW_key7; + _RGFW->keycodes[DOM_VK_8] = RGFW_key8; + _RGFW->keycodes[DOM_VK_9] = RGFW_key9; + _RGFW->keycodes[DOM_VK_SPACE] = RGFW_keySpace; + _RGFW->keycodes[DOM_VK_A] = RGFW_keyA; + _RGFW->keycodes[DOM_VK_B] = RGFW_keyB; + _RGFW->keycodes[DOM_VK_C] = RGFW_keyC; + _RGFW->keycodes[DOM_VK_D] = RGFW_keyD; + _RGFW->keycodes[DOM_VK_E] = RGFW_keyE; + _RGFW->keycodes[DOM_VK_F] = RGFW_keyF; + _RGFW->keycodes[DOM_VK_G] = RGFW_keyG; + _RGFW->keycodes[DOM_VK_H] = RGFW_keyH; + _RGFW->keycodes[DOM_VK_I] = RGFW_keyI; + _RGFW->keycodes[DOM_VK_J] = RGFW_keyJ; + _RGFW->keycodes[DOM_VK_K] = RGFW_keyK; + _RGFW->keycodes[DOM_VK_L] = RGFW_keyL; + _RGFW->keycodes[DOM_VK_M] = RGFW_keyM; + _RGFW->keycodes[DOM_VK_N] = RGFW_keyN; + _RGFW->keycodes[DOM_VK_O] = RGFW_keyO; + _RGFW->keycodes[DOM_VK_P] = RGFW_keyP; + _RGFW->keycodes[DOM_VK_Q] = RGFW_keyQ; + _RGFW->keycodes[DOM_VK_R] = RGFW_keyR; + _RGFW->keycodes[DOM_VK_S] = RGFW_keyS; + _RGFW->keycodes[DOM_VK_T] = RGFW_keyT; + _RGFW->keycodes[DOM_VK_U] = RGFW_keyU; + _RGFW->keycodes[DOM_VK_V] = RGFW_keyV; + _RGFW->keycodes[DOM_VK_W] = RGFW_keyW; + _RGFW->keycodes[DOM_VK_X] = RGFW_keyX; + _RGFW->keycodes[DOM_VK_Y] = RGFW_keyY; + _RGFW->keycodes[DOM_VK_Z] = RGFW_keyZ; + _RGFW->keycodes[DOM_VK_PERIOD] = RGFW_keyPeriod; + _RGFW->keycodes[DOM_VK_COMMA] = RGFW_keyComma; + _RGFW->keycodes[DOM_VK_SLASH] = RGFW_keySlash; + _RGFW->keycodes[DOM_VK_OPEN_BRACKET] = RGFW_keyBracket; + _RGFW->keycodes[DOM_VK_CLOSE_BRACKET] = RGFW_keyCloseBracket; + _RGFW->keycodes[DOM_VK_SEMICOLON] = RGFW_keySemicolon; + _RGFW->keycodes[DOM_VK_QUOTE] = RGFW_keyApostrophe; + _RGFW->keycodes[DOM_VK_BACK_SLASH] = RGFW_keyBackSlash; + _RGFW->keycodes[DOM_VK_RETURN] = RGFW_keyReturn; + _RGFW->keycodes[DOM_VK_DELETE] = RGFW_keyDelete; + _RGFW->keycodes[DOM_VK_NUM_LOCK] = RGFW_keyNumLock; + _RGFW->keycodes[DOM_VK_DIVIDE] = RGFW_keyPadSlash; + _RGFW->keycodes[DOM_VK_MULTIPLY] = RGFW_keyPadMultiply; + _RGFW->keycodes[DOM_VK_SUBTRACT] = RGFW_keyPadMinus; + _RGFW->keycodes[DOM_VK_NUMPAD1] = RGFW_keyPad1; + _RGFW->keycodes[DOM_VK_NUMPAD2] = RGFW_keyPad2; + _RGFW->keycodes[DOM_VK_NUMPAD3] = RGFW_keyPad3; + _RGFW->keycodes[DOM_VK_NUMPAD4] = RGFW_keyPad4; + _RGFW->keycodes[DOM_VK_NUMPAD5] = RGFW_keyPad5; + _RGFW->keycodes[DOM_VK_NUMPAD6] = RGFW_keyPad6; + _RGFW->keycodes[DOM_VK_NUMPAD9] = RGFW_keyPad9; + _RGFW->keycodes[DOM_VK_NUMPAD0] = RGFW_keyPad0; + _RGFW->keycodes[DOM_VK_DECIMAL] = RGFW_keyPadPeriod; + _RGFW->keycodes[DOM_VK_RETURN] = RGFW_keyPadReturn; + _RGFW->keycodes[DOM_VK_HYPHEN_MINUS] = RGFW_keyMinus; + _RGFW->keycodes[DOM_VK_EQUALS] = RGFW_keyEquals; + _RGFW->keycodes[DOM_VK_BACK_SPACE] = RGFW_keyBackSpace; + _RGFW->keycodes[DOM_VK_TAB] = RGFW_keyTab; + _RGFW->keycodes[DOM_VK_CAPS_LOCK] = RGFW_keyCapsLock; + _RGFW->keycodes[DOM_VK_SHIFT] = RGFW_keyShiftL; + _RGFW->keycodes[DOM_VK_CONTROL] = RGFW_keyControlL; + _RGFW->keycodes[DOM_VK_ALT] = RGFW_keyAltL; + _RGFW->keycodes[DOM_VK_META] = RGFW_keySuperL; + _RGFW->keycodes[DOM_VK_F1] = RGFW_keyF1; + _RGFW->keycodes[DOM_VK_F2] = RGFW_keyF2; + _RGFW->keycodes[DOM_VK_F3] = RGFW_keyF3; + _RGFW->keycodes[DOM_VK_F4] = RGFW_keyF4; + _RGFW->keycodes[DOM_VK_F5] = RGFW_keyF5; + _RGFW->keycodes[DOM_VK_F6] = RGFW_keyF6; + _RGFW->keycodes[DOM_VK_F7] = RGFW_keyF7; + _RGFW->keycodes[DOM_VK_F8] = RGFW_keyF8; + _RGFW->keycodes[DOM_VK_F9] = RGFW_keyF9; + _RGFW->keycodes[DOM_VK_F10] = RGFW_keyF10; + _RGFW->keycodes[DOM_VK_F11] = RGFW_keyF11; + _RGFW->keycodes[DOM_VK_F12] = RGFW_keyF12; + _RGFW->keycodes[DOM_VK_UP] = RGFW_keyUp; + _RGFW->keycodes[DOM_VK_DOWN] = RGFW_keyDown; + _RGFW->keycodes[DOM_VK_LEFT] = RGFW_keyLeft; + _RGFW->keycodes[DOM_VK_RIGHT] = RGFW_keyRight; + _RGFW->keycodes[DOM_VK_INSERT] = RGFW_keyInsert; + _RGFW->keycodes[DOM_VK_END] = RGFW_keyEnd; + _RGFW->keycodes[DOM_VK_PAGE_UP] = RGFW_keyPageUp; + _RGFW->keycodes[DOM_VK_PAGE_DOWN] = RGFW_keyPageDown; + _RGFW->keycodes[DOM_VK_ESCAPE] = RGFW_keyEscape; + _RGFW->keycodes[DOM_VK_HOME] = RGFW_keyHome; + _RGFW->keycodes[DOM_VK_SCROLL_LOCK] = RGFW_keyScrollLock; + _RGFW->keycodes[DOM_VK_PRINTSCREEN] = RGFW_keyPrintScreen; + _RGFW->keycodes[DOM_VK_PAUSE] = RGFW_keyPause; + _RGFW->keycodes[DOM_VK_F13] = RGFW_keyF13; + _RGFW->keycodes[DOM_VK_F14] = RGFW_keyF14; + _RGFW->keycodes[DOM_VK_F15] = RGFW_keyF15; + _RGFW->keycodes[DOM_VK_F16] = RGFW_keyF16; + _RGFW->keycodes[DOM_VK_F17] = RGFW_keyF17; + _RGFW->keycodes[DOM_VK_F18] = RGFW_keyF18; + _RGFW->keycodes[DOM_VK_F19] = RGFW_keyF19; + _RGFW->keycodes[DOM_VK_F20] = RGFW_keyF20; + _RGFW->keycodes[DOM_VK_F21] = RGFW_keyF21; + _RGFW->keycodes[DOM_VK_F22] = RGFW_keyF22; + _RGFW->keycodes[DOM_VK_F23] = RGFW_keyF23; + _RGFW->keycodes[DOM_VK_F24] = RGFW_keyF24; } -i32 RGFW_initPlatform(void) { return 0; } +i32 RGFW_initPlatform(void) { + RGFW_monitorNode* node = NULL; + RGFW_monitor monitor; + + monitor.name[0] = '\0'; + + monitor.x = 0; + monitor.y = 0; + + monitor.pixelRatio = EM_ASM_DOUBLE({return window.devicePixelRatio || 1;}); + monitor.mode.w = EM_ASM_INT({return window.innerWidth || 0;}); + monitor.mode.h = EM_ASM_INT({return window.innerHeight || 0;}); + + monitor.physW = (float)RGFW_ROUND((float)monitor.mode.w * monitor.pixelRatio); + monitor.physH = (float)RGFW_ROUND((float)monitor.mode.h * monitor.pixelRatio); + + float dpi = 96.0f * monitor.pixelRatio; + monitor.scaleX = dpi / 96.0f; + monitor.scaleY = dpi / 96.0f; + + RGFW_splitBPP(32, &monitor.mode); + + monitor.mode.refreshRate = 0; + + node = RGFW_monitors_add(&monitor); + if (node != NULL) { + _RGFW->monitors.primary = node; + RGFW_monitorCallback(_RGFW->root, &node->mon, RGFW_TRUE); + } + + return 0; +} RGFW_window* RGFW_createWindowPlatform(const char* name, RGFW_windowFlags flags, RGFW_window* win) { emscripten_set_canvas_element_size("#canvas", win->w, win->h); @@ -15055,7 +15238,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", @@ -15063,7 +15246,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); }); @@ -15075,7 +15258,6 @@ RGFW_window* RGFW_createWindowPlatform(const char* name, RGFW_windowFlags flags, if (e.dataTransfer.file < 0) return; - var filenamesArray = []; var count = e.dataTransfer.files.length; /* Read and save the files to emscripten's files */ @@ -15100,19 +15282,12 @@ RGFW_window* RGFW_createWindowPlatform(const char* name, RGFW_windowFlags flags, }; reader.readAsArrayBuffer(file); - /* This works weird on modern OpenGL */ var filename = stringToNewUTF8(path); - filenamesArray.push(filename); - - Module._RGFW_makeSetValue(i, filename); + Module._Emscripten_onDrop(filename, path.length + 1); + free(filename); } - Module._Emscripten_onDrop(count); - - for (var i = 0; i < count; i++) { - _free(filenamesArray[i]); - } }, true); canvas.addEventListener('dragover', function(e) { e.preventDefault(); return false; }, true); @@ -15125,9 +15300,18 @@ RGFW_key RGFW_physicalToMappedKey(RGFW_key key) { return key; } +RGFW_bool RGFW_window_fetchSize(RGFW_window* win, i32* w, i32* h) { + return RGFW_window_getSize(win, w, h); +} + void RGFW_pollEvents(void) { + static int using_asyncify = -1; + if (using_asyncify == -1) using_asyncify = EM_ASM_INT({ return '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) { @@ -15135,16 +15319,7 @@ void RGFW_window_resize(RGFW_window* win, i32 w, i32 h) { emscripten_set_canvas_element_size("#canvas", w, h); } -/* NOTE: I don't know if this is possible */ -void RGFW_window_moveMouse(RGFW_window* win, i32 x, i32 y) { RGFW_UNUSED(win); RGFW_UNUSED(x); RGFW_UNUSED(y); } -/* this one might be possible but it looks iffy */ -RGFW_mouse* RGFW_loadMouse(u8* data, i32 w, i32 h, RGFW_format format) { RGFW_UNUSED(data); RGFW_UNUSED(w); RGFW_UNUSED(h); RGFW_UNUSED(format); return NULL; } - -void RGFW_window_setMouse(RGFW_window* win, RGFW_mouse* mouse) { RGFW_UNUSED(win); RGFW_UNUSED(mouse); } -void RGFW_freeMouse(RGFW_mouse* mouse) { RGFW_UNUSED(mouse); } - -RGFW_bool RGFW_window_setMouseStandard(RGFW_window* win, u8 mouse) { - RGFW_UNUSED(win); +RGFW_mouse* RGFW_createMouseStandard(RGFW_mouseIcon mouse) { char* cursorName = NULL; switch (mouse) { @@ -15169,16 +15344,25 @@ RGFW_bool RGFW_window_setMouseStandard(RGFW_window* win, u8 mouse) { case RGFW_mouseNotAllowed: cursorName = (char*)"not-allowed"; break; case RGFW_mouseWait: cursorName = (char*)"wait"; break; case RGFW_mouseProgress: cursorName = (char*)"progress"; break; - default: return RGFW_FALSE; + default: return NULL; } - EM_ASM( { document.getElementById("canvas").style.cursor = UTF8ToString($0); }, cursorName); - return RGFW_TRUE; + return (RGFW_mouse*)cursorName; } -RGFW_bool RGFW_window_setMouseDefault(RGFW_window* win) { - return RGFW_window_setMouseStandard(win, RGFW_mouseNormal); +/* NOTE: I don't know if this is possible */ +void RGFW_window_moveMouse(RGFW_window* win, i32 x, i32 y) { RGFW_UNUSED(win); RGFW_UNUSED(x); RGFW_UNUSED(y); } +/* this one might be possible but it looks iffy */ +RGFW_mouse* RGFW_createMouse(u8* data, i32 w, i32 h, RGFW_format format) { RGFW_UNUSED(data); RGFW_UNUSED(w); RGFW_UNUSED(h); RGFW_UNUSED(format); return NULL; } + +RGFW_bool RGFW_window_setMousePlatform(RGFW_window* win, RGFW_mouse* mouse) { + RGFW_ASSERT(win != NULL); + RGFW_ASSERT(mouse != NULL); + + EM_ASM( { document.getElementById("canvas").style.cursor = UTF8ToString($0); }, (char*)mouse); + return RGFW_TRUE; } +void RGFW_freeMouse(RGFW_mouse* mouse) { RGFW_UNUSED(mouse); } void RGFW_window_showMouse(RGFW_window* win, RGFW_bool show) { RGFW_window_showMouseFlags(win, show); @@ -15232,6 +15416,7 @@ RGFW_bool RGFW_window_createContextPtr_OpenGL(RGFW_window* win, RGFW_glContext* win->src.gfxType = RGFW_gfxNativeOpenGL; EmscriptenWebGLContextAttributes attrs; + emscripten_webgl_init_context_attributes(&attrs); attrs.alpha = hints->alpha; attrs.depth = hints->depth; attrs.stencil = hints->stencil; @@ -15245,19 +15430,41 @@ 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; - attrs.explicitSwapControl = EM_TRUE; - emscripten_webgl_init_context_attributes(&attrs); + 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; win->src.ctx.native->ctx = emscripten_webgl_create_context("#canvas", &attrs); + + if (win->src.ctx.native->ctx == 0) { + RGFW_debugCallback(RGFW_typeError, RGFW_warningOpenGL, "WebGL: Failed to create an OpenGL Context with explicit swap control."); + attrs.explicitSwapControl = EM_FALSE; + win->src.ctx.native->ctx = emscripten_webgl_create_context("#canvas", &attrs); + } + + if (win->src.ctx.native->ctx == 0) { + RGFW_debugCallback(RGFW_typeError, RGFW_errOpenGLContext, "Failed to create an OpenGL Context with the requested attributes, falling back to defaults."); + win->src.ctx.native->ctx = emscripten_webgl_create_context("#canvas", &attrs); + } + + if (win->src.ctx.native->ctx == 0) { + RGFW_debugCallback(RGFW_typeError, RGFW_errOpenGLContext, "Failed to create an OpenGL Context."); + return RGFW_FALSE; + } + emscripten_webgl_make_context_current(win->src.ctx.native->ctx); #ifdef LEGACY_GL_EMULATION EM_ASM("Module.useWebGL = true; GLImmediate.init();"); - RGFW_sendDebugInfo(RGFW_typeInfo, RGFW_infoOpenGL, "OpenGL context initalized."); + RGFW_debugCallback(RGFW_typeInfo, RGFW_infoOpenGL, "OpenGL context initalized."); #endif RGFW_window_swapInterval_OpenGL(win, 0); @@ -15268,7 +15475,7 @@ RGFW_bool RGFW_window_createContextPtr_OpenGL(RGFW_window* win, RGFW_glContext* void RGFW_window_deleteContextPtr_OpenGL(RGFW_window* win, RGFW_glContext* ctx) { emscripten_webgl_destroy_context(ctx->ctx); win->src.ctx.native->ctx = 0; - RGFW_sendDebugInfo(RGFW_typeInfo, RGFW_infoOpenGL, "OpenGL context freed."); + RGFW_debugCallback(RGFW_typeInfo, RGFW_infoOpenGL, "OpenGL context freed."); } void RGFW_window_makeCurrentContext_OpenGL(RGFW_window* win) { @@ -15343,6 +15550,7 @@ void RGFW_window_maximize(RGFW_window* win) { } RGFW_window_move(win, 0, 0); + RGFW_window_fetchSize(win, NULL, NULL); } void RGFW_window_setFullscreen(RGFW_window* win, RGFW_bool fullscreen) { @@ -15379,87 +15587,87 @@ WGPUSurface RGFW_window_createSurface_WebGPU(RGFW_window* window, WGPUInstance i RGFW_key RGFW_WASMPhysicalToRGFW(u32 hash) { switch(hash) { /* 0x0000 */ - case 0x67243A2DU /* Escape */: return RGFW_escape; /* 0x0001 */ - case 0x67251058U /* Digit0 */: return RGFW_0; /* 0x0002 */ - case 0x67251059U /* Digit1 */: return RGFW_1; /* 0x0003 */ - case 0x6725105AU /* Digit2 */: return RGFW_2; /* 0x0004 */ - case 0x6725105BU /* Digit3 */: return RGFW_3; /* 0x0005 */ - case 0x6725105CU /* Digit4 */: return RGFW_4; /* 0x0006 */ - case 0x6725105DU /* Digit5 */: return RGFW_5; /* 0x0007 */ - case 0x6725105EU /* Digit6 */: return RGFW_6; /* 0x0008 */ - case 0x6725105FU /* Digit7 */: return RGFW_7; /* 0x0009 */ - case 0x67251050U /* Digit8 */: return RGFW_8; /* 0x000A */ - case 0x67251051U /* Digit9 */: return RGFW_9; /* 0x000B */ - case 0x92E14DD3U /* Minus */: return RGFW_minus; /* 0x000C */ - case 0x92E1FBACU /* Equal */: return RGFW_equals; /* 0x000D */ - case 0x36BF1CB5U /* Backspace */: return RGFW_backSpace; /* 0x000E */ - case 0x7B8E51E2U /* Tab */: return RGFW_tab; /* 0x000F */ - case 0x2C595B51U /* KeyQ */: return RGFW_q; /* 0x0010 */ - case 0x2C595B57U /* KeyW */: return RGFW_w; /* 0x0011 */ - case 0x2C595B45U /* KeyE */: return RGFW_e; /* 0x0012 */ - case 0x2C595B52U /* KeyR */: return RGFW_r; /* 0x0013 */ - case 0x2C595B54U /* KeyT */: return RGFW_t; /* 0x0014 */ - case 0x2C595B59U /* KeyY */: return RGFW_y; /* 0x0015 */ - case 0x2C595B55U /* KeyU */: return RGFW_u; /* 0x0016 */ - case 0x2C595B4FU /* KeyO */: return RGFW_o; /* 0x0018 */ - case 0x2C595B50U /* KeyP */: return RGFW_p; /* 0x0019 */ - case 0x45D8158CU /* BracketLeft */: return RGFW_closeBracket; /* 0x001A */ - case 0xDEEABF7CU /* BracketRight */: return RGFW_bracket; /* 0x001B */ - case 0x92E1C5D2U /* Enter */: return RGFW_return; /* 0x001C */ - case 0xE058958CU /* ControlLeft */: return RGFW_controlL; /* 0x001D */ - case 0x2C595B41U /* KeyA */: return RGFW_a; /* 0x001E */ - case 0x2C595B53U /* KeyS */: return RGFW_s; /* 0x001F */ - case 0x2C595B44U /* KeyD */: return RGFW_d; /* 0x0020 */ - case 0x2C595B46U /* KeyF */: return RGFW_f; /* 0x0021 */ - case 0x2C595B47U /* KeyG */: return RGFW_g; /* 0x0022 */ - case 0x2C595B48U /* KeyH */: return RGFW_h; /* 0x0023 */ - case 0x2C595B4AU /* KeyJ */: return RGFW_j; /* 0x0024 */ - case 0x2C595B4BU /* KeyK */: return RGFW_k; /* 0x0025 */ - case 0x2C595B4CU /* KeyL */: return RGFW_l; /* 0x0026 */ - case 0x2707219EU /* Semicolon */: return RGFW_semicolon; /* 0x0027 */ - case 0x92E0B58DU /* Quote */: return RGFW_apostrophe; /* 0x0028 */ - case 0x36BF358DU /* Backquote */: return RGFW_backtick; /* 0x0029 */ - case 0x26B1958CU /* ShiftLeft */: return RGFW_shiftL; /* 0x002A */ - case 0x36BF2438U /* Backslash */: return RGFW_backSlash; /* 0x002B */ - case 0x2C595B5AU /* KeyZ */: return RGFW_z; /* 0x002C */ - case 0x2C595B58U /* KeyX */: return RGFW_x; /* 0x002D */ - case 0x2C595B43U /* KeyC */: return RGFW_c; /* 0x002E */ - case 0x2C595B56U /* KeyV */: return RGFW_v; /* 0x002F */ - case 0x2C595B42U /* KeyB */: return RGFW_b; /* 0x0030 */ - case 0x2C595B4EU /* KeyN */: return RGFW_n; /* 0x0031 */ - case 0x2C595B4DU /* KeyM */: return RGFW_m; /* 0x0032 */ - case 0x92E1A1C1U /* Comma */: return RGFW_comma; /* 0x0033 */ - case 0x672FFAD4U /* Period */: return RGFW_period; /* 0x0034 */ - case 0x92E0A438U /* Slash */: return RGFW_slash; /* 0x0035 */ - case 0xC5A6BF7CU /* ShiftRight */: return RGFW_shiftR; - case 0x5D64DA91U /* NumpadMultiply */: return RGFW_kpMultiply; - case 0xC914958CU /* AltLeft */: return RGFW_altL; /* 0x0038 */ - case 0x92E09CB5U /* Space */: return RGFW_space; /* 0x0039 */ - case 0xB8FAE73BU /* CapsLock */: return RGFW_capsLock; /* 0x003A */ - case 0x7174B789U /* F1 */: return RGFW_F1; /* 0x003B */ - case 0x7174B78AU /* F2 */: return RGFW_F2; /* 0x003C */ - case 0x7174B78BU /* F3 */: return RGFW_F3; /* 0x003D */ - case 0x7174B78CU /* F4 */: return RGFW_F4; /* 0x003E */ - case 0x7174B78DU /* F5 */: return RGFW_F5; /* 0x003F */ - case 0x7174B78EU /* F6 */: return RGFW_F6; /* 0x0040 */ - case 0x7174B78FU /* F7 */: return RGFW_F7; /* 0x0041 */ - case 0x7174B780U /* F8 */: return RGFW_F8; /* 0x0042 */ - case 0x7174B781U /* F9 */: return RGFW_F9; /* 0x0043 */ - case 0x7B8E57B0U /* F10 */: return RGFW_F10; /* 0x0044 */ - case 0xC925FCDFU /* Numpad7 */: return RGFW_kpMultiply; /* 0x0047 */ - case 0xC925FCD0U /* Numpad8 */: return RGFW_kp8; /* 0x0048 */ - case 0xC925FCD1U /* Numpad9 */: return RGFW_kp9; /* 0x0049 */ - case 0x5EA3E8A4U /* NumpadSubtract */: return RGFW_minus; /* 0x004A */ - case 0xC925FCDCU /* Numpad4 */: return RGFW_kp4; /* 0x004B */ - case 0xC925FCDDU /* Numpad5 */: return RGFW_kp5; /* 0x004C */ - case 0xC925FCDEU /* Numpad6 */: return RGFW_kp6; /* 0x004D */ - case 0xC925FCD9U /* Numpad1 */: return RGFW_kp1; /* 0x004F */ - case 0xC925FCDAU /* Numpad2 */: return RGFW_kp2; /* 0x0050 */ - case 0xC925FCDBU /* Numpad3 */: return RGFW_kp3; /* 0x0051 */ - case 0xC925FCD8U /* Numpad0 */: return RGFW_kp0; /* 0x0052 */ - case 0x95852DACU /* NumpadDecimal */: return RGFW_period; /* 0x0053 */ - case 0x7B8E57B1U /* F11 */: return RGFW_F11; /* 0x0057 */ - case 0x7B8E57B2U /* F12 */: return RGFW_F12; /* 0x0058 */ + case 0x67243A2DU /* Escape */: return RGFW_keyEscape; /* 0x0001 */ + case 0x67251058U /* Digit0 */: return RGFW_key0; /* 0x0002 */ + case 0x67251059U /* Digit1 */: return RGFW_key1; /* 0x0003 */ + case 0x6725105AU /* Digit2 */: return RGFW_key2; /* 0x0004 */ + case 0x6725105BU /* Digit3 */: return RGFW_key3; /* 0x0005 */ + case 0x6725105CU /* Digit4 */: return RGFW_key4; /* 0x0006 */ + case 0x6725105DU /* Digit5 */: return RGFW_key5; /* 0x0007 */ + case 0x6725105EU /* Digit6 */: return RGFW_key6; /* 0x0008 */ + case 0x6725105FU /* Digit7 */: return RGFW_key7; /* 0x0009 */ + case 0x67251050U /* Digit8 */: return RGFW_key8; /* 0x000A */ + case 0x67251051U /* Digit9 */: return RGFW_key9; /* 0x000B */ + case 0x92E14DD3U /* Minus */: return RGFW_keyMinus; /* 0x000C */ + case 0x92E1FBACU /* Equal */: return RGFW_keyEquals; /* 0x000D */ + case 0x36BF1CB5U /* Backspace */: return RGFW_keyBackSpace; /* 0x000E */ + case 0x7B8E51E2U /* Tab */: return RGFW_keyTab; /* 0x000F */ + case 0x2C595B51U /* KeyQ */: return RGFW_keyQ; /* 0x0010 */ + case 0x2C595B57U /* KeyW */: return RGFW_keyW; /* 0x0011 */ + case 0x2C595B45U /* KeyE */: return RGFW_keyE; /* 0x0012 */ + case 0x2C595B52U /* KeyR */: return RGFW_keyR; /* 0x0013 */ + case 0x2C595B54U /* KeyT */: return RGFW_keyT; /* 0x0014 */ + case 0x2C595B59U /* KeyY */: return RGFW_keyY; /* 0x0015 */ + case 0x2C595B55U /* KeyU */: return RGFW_keyU; /* 0x0016 */ + case 0x2C595B4FU /* KeyO */: return RGFW_keyO; /* 0x0018 */ + case 0x2C595B50U /* KeyP */: return RGFW_keyP; /* 0x0019 */ + case 0x45D8158CU /* BracketLeft */: return RGFW_keyCloseBracket; /* 0x001A */ + case 0xDEEABF7CU /* BracketRight */: return RGFW_keyBracket; /* 0x001B */ + case 0x92E1C5D2U /* Enter */: return RGFW_keyReturn; /* 0x001C */ + case 0xE058958CU /* ControlLeft */: return RGFW_keyControlL; /* 0x001D */ + case 0x2C595B41U /* KeyA */: return RGFW_keyA; /* 0x001E */ + case 0x2C595B53U /* KeyS */: return RGFW_keyS; /* 0x001F */ + case 0x2C595B44U /* KeyD */: return RGFW_keyD; /* 0x0020 */ + case 0x2C595B46U /* KeyF */: return RGFW_keyF; /* 0x0021 */ + case 0x2C595B47U /* KeyG */: return RGFW_keyG; /* 0x0022 */ + case 0x2C595B48U /* KeyH */: return RGFW_keyH; /* 0x0023 */ + case 0x2C595B4AU /* KeyJ */: return RGFW_keyJ; /* 0x0024 */ + case 0x2C595B4BU /* KeyK */: return RGFW_keyK; /* 0x0025 */ + case 0x2C595B4CU /* KeyL */: return RGFW_keyL; /* 0x0026 */ + case 0x2707219EU /* Semicolon */: return RGFW_keySemicolon; /* 0x0027 */ + case 0x92E0B58DU /* Quote */: return RGFW_keyApostrophe; /* 0x0028 */ + case 0x36BF358DU /* Backquote */: return RGFW_keyBacktick; /* 0x0029 */ + case 0x26B1958CU /* ShiftLeft */: return RGFW_keyShiftL; /* 0x002A */ + case 0x36BF2438U /* Backslash */: return RGFW_keyBackSlash; /* 0x002B */ + case 0x2C595B5AU /* KeyZ */: return RGFW_keyZ; /* 0x002C */ + case 0x2C595B58U /* KeyX */: return RGFW_keyX; /* 0x002D */ + case 0x2C595B43U /* KeyC */: return RGFW_keyC; /* 0x002E */ + case 0x2C595B56U /* KeyV */: return RGFW_keyV; /* 0x002F */ + case 0x2C595B42U /* KeyB */: return RGFW_keyB; /* 0x0030 */ + case 0x2C595B4EU /* KeyN */: return RGFW_keyN; /* 0x0031 */ + case 0x2C595B4DU /* KeyM */: return RGFW_keyM; /* 0x0032 */ + case 0x92E1A1C1U /* Comma */: return RGFW_keyComma; /* 0x0033 */ + case 0x672FFAD4U /* Period */: return RGFW_keyPeriod; /* 0x0034 */ + case 0x92E0A438U /* Slash */: return RGFW_keySlash; /* 0x0035 */ + case 0xC5A6BF7CU /* ShiftRight */: return RGFW_keyShiftR; + case 0x5D64DA91U /* NumpadMultiply */: return RGFW_keyPadMultiply; + case 0xC914958CU /* AltLeft */: return RGFW_keyAltL; /* 0x0038 */ + case 0x92E09CB5U /* Space */: return RGFW_keySpace; /* 0x0039 */ + case 0xB8FAE73BU /* CapsLock */: return RGFW_keyCapsLock; /* 0x003A */ + case 0x7174B789U /* F1 */: return RGFW_keyF1; /* 0x003B */ + case 0x7174B78AU /* F2 */: return RGFW_keyF2; /* 0x003C */ + case 0x7174B78BU /* F3 */: return RGFW_keyF3; /* 0x003D */ + case 0x7174B78CU /* F4 */: return RGFW_keyF4; /* 0x003E */ + case 0x7174B78DU /* F5 */: return RGFW_keyF5; /* 0x003F */ + case 0x7174B78EU /* F6 */: return RGFW_keyF6; /* 0x0040 */ + case 0x7174B78FU /* F7 */: return RGFW_keyF7; /* 0x0041 */ + 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 0xC925FCD0U /* Numpad8 */: return RGFW_keyPad8; /* 0x0048 */ + case 0xC925FCD1U /* Numpad9 */: return RGFW_keyPad9; /* 0x0049 */ + case 0x5EA3E8A4U /* NumpadSubtract */: return RGFW_keyMinus; /* 0x004A */ + case 0xC925FCDCU /* Numpad4 */: return RGFW_keyPad4; /* 0x004B */ + case 0xC925FCDDU /* Numpad5 */: return RGFW_keyPad5; /* 0x004C */ + case 0xC925FCDEU /* Numpad6 */: return RGFW_keyPad6; /* 0x004D */ + case 0xC925FCD9U /* Numpad1 */: return RGFW_keyPad1; /* 0x004F */ + case 0xC925FCDAU /* Numpad2 */: return RGFW_keyPad2; /* 0x0050 */ + case 0xC925FCDBU /* Numpad3 */: return RGFW_keyPad3; /* 0x0051 */ + case 0xC925FCD8U /* Numpad0 */: return RGFW_keyPad0; /* 0x0052 */ + 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 */ @@ -15471,21 +15679,21 @@ RGFW_key RGFW_WASMPhysicalToRGFW(u32 hash) { 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 0x7393FBACU /* NumpadEqual */: return RGFW_kpReturn; - case 0xB88EBF7CU /* AltRight */: return RGFW_altR; /* 0xE038 */ - case 0xC925873BU /* NumLock */: return RGFW_numLock; /* 0xE045 */ - case 0x2C595F45U /* Home */: return RGFW_home; /* 0xE047 */ - case 0xC91BB690U /* ArrowUp */: return RGFW_up; /* 0xE048 */ - case 0x672F9210U /* PageUp */: return RGFW_pageUp; /* 0xE049 */ - case 0x3799258CU /* ArrowLeft */: return RGFW_left; /* 0xE04B */ - case 0x4CE33F7CU /* ArrowRight */: return RGFW_right; /* 0xE04D */ - case 0x7B8E55DCU /* End */: return RGFW_end; /* 0xE04F */ - case 0x3799379EU /* ArrowDown */: return RGFW_down; /* 0xE050 */ - case 0xBA90179EU /* PageDown */: return RGFW_pageDown; /* 0xE051 */ - case 0x6723CB2CU /* Insert */: return RGFW_insert; /* 0xE052 */ - case 0x6725C50DU /* Delete */: return RGFW_delete; /* 0xE053 */ - case 0x6723658CU /* OSLeft */: return RGFW_superL; /* 0xE05B */ - case 0x39643F7CU /* MetaRight */: return RGFW_superR; /* 0xE05C */ + case 0x7393FBACU /* NumpadEqual */: return RGFW_keyPadReturn; + case 0xB88EBF7CU /* AltRight */: return RGFW_keyAltR; /* 0xE038 */ + case 0xC925873BU /* NumLock */: return RGFW_keyNumLock; /* 0xE045 */ + case 0x2C595F45U /* Home */: return RGFW_keyHome; /* 0xE047 */ + case 0xC91BB690U /* ArrowUp */: return RGFW_keyUp; /* 0xE048 */ + case 0x672F9210U /* PageUp */: return RGFW_keyPageUp; /* 0xE049 */ + case 0x3799258CU /* ArrowLeft */: return RGFW_keyLeft; /* 0xE04B */ + case 0x4CE33F7CU /* ArrowRight */: return RGFW_keyRight; /* 0xE04D */ + case 0x7B8E55DCU /* End */: return RGFW_keyEnd; /* 0xE04F */ + case 0x3799379EU /* ArrowDown */: return RGFW_keyDown; /* 0xE050 */ + case 0xBA90179EU /* PageDown */: return RGFW_keyPageDown; /* 0xE051 */ + case 0x6723CB2CU /* Insert */: return RGFW_keyInsert; /* 0xE052 */ + 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 */ default: return DOM_PK_UNKNOWN; } @@ -15493,7 +15701,13 @@ RGFW_key RGFW_WASMPhysicalToRGFW(u32 hash) { return 0; } +RGFW_monitor* RGFW_window_getMonitor(RGFW_window* win) { + RGFW_UNUSED(win); + return RGFW_getPrimaryMonitor(); +} + /* unsupported functions */ +void RGFW_pollMonitors(void) { } 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; } @@ -15502,7 +15716,6 @@ 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_pollMonitors(void) { } void RGFW_window_move(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); } @@ -15519,7 +15732,6 @@ RGFW_bool RGFW_window_isHidden(RGFW_window* win) { RGFW_UNUSED(win); return RGFW RGFW_bool RGFW_window_isMinimized(RGFW_window* win) { RGFW_UNUSED(win); return RGFW_FALSE; } RGFW_bool RGFW_window_isMaximized(RGFW_window* win) { RGFW_UNUSED(win); return RGFW_FALSE; } RGFW_bool RGFW_window_isFloating(RGFW_window* win) { RGFW_UNUSED(win); return RGFW_FALSE; } -RGFW_monitor* RGFW_window_getMonitor(RGFW_window* win) { RGFW_UNUSED(win); return NULL; } void RGFW_waitForEvent(i32 waitMS) { RGFW_UNUSED(waitMS); } #endif @@ -15533,6 +15745,7 @@ typedef RGFW_window* (*RGFW_createWindowPlatform_ptr)(const char* name, RGFW_win typedef RGFW_bool (*RGFW_getMouse_ptr)(i32* x, i32* y); 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_window_move_ptr)(RGFW_window* win, i32 x, i32 y); typedef void (*RGFW_window_resize_ptr)(RGFW_window* win, i32 w, i32 h); @@ -15551,11 +15764,10 @@ typedef RGFW_bool (*RGFW_window_isFloating_ptr)(RGFW_window* win); typedef void (*RGFW_window_setName_ptr)(RGFW_window* win, const char* name); typedef void (*RGFW_window_setMousePassthrough_ptr)(RGFW_window* win, RGFW_bool passthrough); typedef RGFW_bool (*RGFW_window_setIconEx_ptr)(RGFW_window* win, u8* data, i32 w, i32 h, RGFW_format format, u8 type); -typedef RGFW_mouse* (*RGFW_loadMouse_ptr)(u8* data, i32 w, i32 h, RGFW_format format); -typedef void (*RGFW_window_setMouse_ptr)(RGFW_window* win, RGFW_mouse* mouse); +typedef RGFW_mouse* (*RGFW_createMouse_ptr)(u8* data, i32 w, i32 h, RGFW_format format); +typedef RGFW_mouse* (*RGFW_createMouseStandard_ptr)(RGFW_mouseIcon icons); +typedef RGFW_bool (*RGFW_window_setMousePlatform_ptr)(RGFW_window* win, RGFW_mouse* mouse); typedef void (*RGFW_window_moveMouse_ptr)(RGFW_window* win, i32 x, i32 y); -typedef RGFW_bool (*RGFW_window_setMouseDefault_ptr)(RGFW_window* win); -typedef RGFW_bool (*RGFW_window_setMouseStandard_ptr)(RGFW_window* win, u8 mouse); 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); @@ -15607,7 +15819,8 @@ typedef struct RGFW_FunctionPointers { RGFW_createWindowPlatform_ptr createWindowPlatform; RGFW_getMouse_ptr getGlobalMouse; RGFW_physicalToMappedKey_ptr physicalToMappedKey; - RGFW_pollEvents_ptr pollEvents; + 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; @@ -15626,11 +15839,10 @@ typedef struct RGFW_FunctionPointers { RGFW_window_setName_ptr window_setName; RGFW_window_setMousePassthrough_ptr window_setMousePassthrough; RGFW_window_setIconEx_ptr window_setIconEx; - RGFW_loadMouse_ptr loadMouse; - RGFW_window_setMouse_ptr window_setMouse; + RGFW_createMouse_ptr createMouse; + RGFW_createMouseStandard_ptr createMouseStandard; + RGFW_window_setMousePlatform_ptr window_setMousePlatform; RGFW_window_moveMouse_ptr window_moveMouse; - RGFW_window_setMouseDefault_ptr window_setMouseDefault; - RGFW_window_setMouseStandard_ptr window_setMouseStandard; RGFW_window_hide_ptr window_hide; RGFW_window_show_ptr window_show; RGFW_window_flash_ptr window_flash; @@ -15676,6 +15888,7 @@ RGFW_window* RGFW_createWindowPlatform(const char* name, RGFW_windowFlags flags, 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); } @@ -15698,11 +15911,10 @@ 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_loadMouse(u8* data, i32 w, i32 h, RGFW_format format) { return RGFW_api.loadMouse(data, w, h, format); } -void RGFW_window_setMouse(RGFW_window* win, RGFW_mouse* mouse) { RGFW_api.window_setMouse(win, mouse); } +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); } -RGFW_bool RGFW_window_setMouseDefault(RGFW_window* win) { return RGFW_api.window_setMouseDefault(win); } -RGFW_bool RGFW_window_setMouseStandard(RGFW_window* win, u8 mouse) { return RGFW_api.window_setMouseStandard(win, mouse); } 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_flash(RGFW_window* win, RGFW_flashRequest request) { RGFW_api.window_flash(win, request); } @@ -15755,6 +15967,7 @@ void RGFW_load_X11(void) { RGFW_api.getGlobalMouse = RGFW_getGlobalMouse_X11; RGFW_api.physicalToMappedKey = RGFW_physicalToMappedKey_X11; 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; @@ -15775,11 +15988,10 @@ void RGFW_load_X11(void) { RGFW_api.window_setMousePassthrough = RGFW_window_setMousePassthrough_X11; #endif RGFW_api.window_setIconEx = RGFW_window_setIconEx_X11; - RGFW_api.loadMouse = RGFW_loadMouse_X11; - RGFW_api.window_setMouse = RGFW_window_setMouse_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_setMouseDefault = RGFW_window_setMouseDefault_X11; - RGFW_api.window_setMouseStandard = RGFW_window_setMouseStandard_X11; RGFW_api.window_hide = RGFW_window_hide_X11; RGFW_api.window_show = RGFW_window_show_X11; RGFW_api.window_flash = RGFW_window_flash_X11; @@ -15823,6 +16035,7 @@ void RGFW_load_Wayland(void) { 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; @@ -15843,11 +16056,10 @@ void RGFW_load_Wayland(void) { RGFW_api.window_setMousePassthrough = RGFW_window_setMousePassthrough_Wayland; #endif RGFW_api.window_setIconEx = RGFW_window_setIconEx_Wayland; - RGFW_api.loadMouse = RGFW_loadMouse_Wayland; - RGFW_api.window_setMouse = RGFW_window_setMouse_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_setMouseDefault = RGFW_window_setMouseDefault_Wayland; - RGFW_api.window_setMouseStandard = RGFW_window_setMouseStandard_Wayland; RGFW_api.window_hide = RGFW_window_hide_Wayland; RGFW_api.window_show = RGFW_window_show_Wayland; RGFW_api.window_flash = RGFW_window_flash_X11; diff --git a/src/platforms/rcore_desktop_rgfw.c b/src/platforms/rcore_desktop_rgfw.c index 4f54e1708..a2c005662 100644 --- a/src/platforms/rcore_desktop_rgfw.c +++ b/src/platforms/rcore_desktop_rgfw.c @@ -76,7 +76,7 @@ void ShowCursor(void); void CloseWindow(void); -double get_time_seconds(void); +double GetTimeSeconds(void); #if defined(__unix__) || defined(__linux__) #define _XTYPEDEF_FONT @@ -310,113 +310,113 @@ static PlatformData platform = { 0 }; // Platform specific static const unsigned short RGFW_keyConvertTable[] = { [RGFW_keyNULL] = KEY_NULL, - [RGFW_apostrophe] = KEY_APOSTROPHE, - [RGFW_comma] = KEY_COMMA, - [RGFW_minus] = KEY_MINUS, - [RGFW_period] = KEY_PERIOD, - [RGFW_slash] = KEY_SLASH, - [RGFW_0] = KEY_ZERO, - [RGFW_1] = KEY_ONE, - [RGFW_2] = KEY_TWO, - [RGFW_3] = KEY_THREE, - [RGFW_4] = KEY_FOUR, - [RGFW_5] = KEY_FIVE, - [RGFW_6] = KEY_SIX, - [RGFW_7] = KEY_SEVEN, - [RGFW_8] = KEY_EIGHT, - [RGFW_9] = KEY_NINE, - [RGFW_semicolon] = KEY_SEMICOLON, - [RGFW_equals] = KEY_EQUAL, - [RGFW_a] = KEY_A, - [RGFW_b] = KEY_B, - [RGFW_c] = KEY_C, - [RGFW_d] = KEY_D, - [RGFW_e] = KEY_E, - [RGFW_f] = KEY_F, - [RGFW_g] = KEY_G, - [RGFW_h] = KEY_H, - [RGFW_i] = KEY_I, - [RGFW_j] = KEY_J, - [RGFW_k] = KEY_K, - [RGFW_l] = KEY_L, - [RGFW_m] = KEY_M, - [RGFW_n] = KEY_N, - [RGFW_o] = KEY_O, - [RGFW_p] = KEY_P, - [RGFW_q] = KEY_Q, - [RGFW_r] = KEY_R, - [RGFW_s] = KEY_S, - [RGFW_t] = KEY_T, - [RGFW_u] = KEY_U, - [RGFW_v] = KEY_V, - [RGFW_w] = KEY_W, - [RGFW_x] = KEY_X, - [RGFW_y] = KEY_Y, - [RGFW_z] = KEY_Z, - [RGFW_bracket] = KEY_LEFT_BRACKET, - [RGFW_backSlash] = KEY_BACKSLASH, - [RGFW_closeBracket] = KEY_RIGHT_BRACKET, - [RGFW_backtick] = KEY_GRAVE, - [RGFW_space] = KEY_SPACE, - [RGFW_escape] = KEY_ESCAPE, - [RGFW_return] = KEY_ENTER, - [RGFW_tab] = KEY_TAB, - [RGFW_backSpace] = KEY_BACKSPACE, - [RGFW_insert] = KEY_INSERT, - [RGFW_delete] = KEY_DELETE, - [RGFW_right] = KEY_RIGHT, - [RGFW_left] = KEY_LEFT, - [RGFW_down] = KEY_DOWN, - [RGFW_up] = KEY_UP, - [RGFW_pageUp] = KEY_PAGE_UP, - [RGFW_pageDown] = KEY_PAGE_DOWN, - [RGFW_home] = KEY_HOME, - [RGFW_end] = KEY_END, - [RGFW_capsLock] = KEY_CAPS_LOCK, - [RGFW_scrollLock] = KEY_SCROLL_LOCK, - [RGFW_numLock] = KEY_NUM_LOCK, - [RGFW_printScreen] = KEY_PRINT_SCREEN, - [RGFW_pause] = KEY_PAUSE, - [RGFW_F1] = KEY_F1, - [RGFW_F2] = KEY_F2, - [RGFW_F3] = KEY_F3, - [RGFW_F4] = KEY_F4, - [RGFW_F5] = KEY_F5, - [RGFW_F6] = KEY_F6, - [RGFW_F7] = KEY_F7, - [RGFW_F8] = KEY_F8, - [RGFW_F9] = KEY_F9, - [RGFW_F10] = KEY_F10, - [RGFW_F11] = KEY_F11, - [RGFW_F12] = KEY_F12, - [RGFW_shiftL] = KEY_LEFT_SHIFT, - [RGFW_controlL] = KEY_LEFT_CONTROL, - [RGFW_altL] = KEY_LEFT_ALT, - [RGFW_superL] = KEY_LEFT_SUPER, + [RGFW_keyApostrophe] = KEY_APOSTROPHE, + [RGFW_keyComma] = KEY_COMMA, + [RGFW_keyMinus] = KEY_MINUS, + [RGFW_keyPeriod] = KEY_PERIOD, + [RGFW_keySlash] = KEY_SLASH, + [RGFW_key0] = KEY_ZERO, + [RGFW_key1] = KEY_ONE, + [RGFW_key2] = KEY_TWO, + [RGFW_key3] = KEY_THREE, + [RGFW_key4] = KEY_FOUR, + [RGFW_key5] = KEY_FIVE, + [RGFW_key6] = KEY_SIX, + [RGFW_key7] = KEY_SEVEN, + [RGFW_key8] = KEY_EIGHT, + [RGFW_key9] = KEY_NINE, + [RGFW_keySemicolon] = KEY_SEMICOLON, + [RGFW_keyEquals] = KEY_EQUAL, + [RGFW_keyA] = KEY_A, + [RGFW_keyB] = KEY_B, + [RGFW_keyC] = KEY_C, + [RGFW_keyD] = KEY_D, + [RGFW_keyE] = KEY_E, + [RGFW_keyF] = KEY_F, + [RGFW_keyG] = KEY_G, + [RGFW_keyH] = KEY_H, + [RGFW_keyI] = KEY_I, + [RGFW_keyJ] = KEY_J, + [RGFW_keyK] = KEY_K, + [RGFW_keyL] = KEY_L, + [RGFW_keyM] = KEY_M, + [RGFW_keyN] = KEY_N, + [RGFW_keyO] = KEY_O, + [RGFW_keyP] = KEY_P, + [RGFW_keyQ] = KEY_Q, + [RGFW_keyR] = KEY_R, + [RGFW_keyS] = KEY_S, + [RGFW_keyT] = KEY_T, + [RGFW_keyU] = KEY_U, + [RGFW_keyV] = KEY_V, + [RGFW_keyW] = KEY_W, + [RGFW_keyX] = KEY_X, + [RGFW_keyY] = KEY_Y, + [RGFW_keyZ] = KEY_Z, + [RGFW_keyBracket] = KEY_LEFT_BRACKET, + [RGFW_keyBackSlash] = KEY_BACKSLASH, + [RGFW_keyCloseBracket] = KEY_RIGHT_BRACKET, + [RGFW_keyBacktick] = KEY_GRAVE, + [RGFW_keySpace] = KEY_SPACE, + [RGFW_keyEscape] = KEY_ESCAPE, + [RGFW_keyReturn] = KEY_ENTER, + [RGFW_keyTab] = KEY_TAB, + [RGFW_keyBackSpace] = KEY_BACKSPACE, + [RGFW_keyInsert] = KEY_INSERT, + [RGFW_keyDelete] = KEY_DELETE, + [RGFW_keyRight] = KEY_RIGHT, + [RGFW_keyLeft] = KEY_LEFT, + [RGFW_keyDown] = KEY_DOWN, + [RGFW_keyUp] = KEY_UP, + [RGFW_keyPageUp] = KEY_PAGE_UP, + [RGFW_keyPageDown] = KEY_PAGE_DOWN, + [RGFW_keyHome] = KEY_HOME, + [RGFW_keyEnd] = KEY_END, + [RGFW_keyCapsLock] = KEY_CAPS_LOCK, + [RGFW_keyScrollLock] = KEY_SCROLL_LOCK, + [RGFW_keyNumLock] = KEY_NUM_LOCK, + [RGFW_keyPrintScreen] = KEY_PRINT_SCREEN, + [RGFW_keyPause] = KEY_PAUSE, + [RGFW_keyF1] = KEY_F1, + [RGFW_keyF2] = KEY_F2, + [RGFW_keyF3] = KEY_F3, + [RGFW_keyF4] = KEY_F4, + [RGFW_keyF5] = KEY_F5, + [RGFW_keyF6] = KEY_F6, + [RGFW_keyF7] = KEY_F7, + [RGFW_keyF8] = KEY_F8, + [RGFW_keyF9] = KEY_F9, + [RGFW_keyF10] = KEY_F10, + [RGFW_keyF11] = KEY_F11, + [RGFW_keyF12] = KEY_F12, + [RGFW_keyShiftL] = KEY_LEFT_SHIFT, + [RGFW_keyControlL] = KEY_LEFT_CONTROL, + [RGFW_keyAltL] = KEY_LEFT_ALT, + [RGFW_keySuperL] = KEY_LEFT_SUPER, // #ifndef RGFW_MACOS - [RGFW_shiftR] = KEY_RIGHT_SHIFT, - [RGFW_controlR] = KEY_RIGHT_CONTROL, - [RGFW_altR] = KEY_RIGHT_ALT, - [RGFW_superR] = KEY_RIGHT_SUPER, + [RGFW_keyShiftR] = KEY_RIGHT_SHIFT, + [RGFW_keyControlR] = KEY_RIGHT_CONTROL, + [RGFW_keyAltR] = KEY_RIGHT_ALT, + [RGFW_keySuperR] = KEY_RIGHT_SUPER, // #endif - [RGFW_menu] = KEY_KB_MENU, - [RGFW_kp0] = KEY_KP_0, - [RGFW_kp1] = KEY_KP_1, - [RGFW_kp2] = KEY_KP_2, - [RGFW_kp3] = KEY_KP_3, - [RGFW_kp4] = KEY_KP_4, - [RGFW_kp5] = KEY_KP_5, - [RGFW_kp6] = KEY_KP_6, - [RGFW_kp7] = KEY_KP_7, - [RGFW_kp8] = KEY_KP_8, - [RGFW_kp9] = KEY_KP_9, - [RGFW_kpPeriod] = KEY_KP_DECIMAL, - [RGFW_kpSlash] = KEY_KP_DIVIDE, - [RGFW_kpMultiply] = KEY_KP_MULTIPLY, - [RGFW_kpMinus] = KEY_KP_SUBTRACT, - [RGFW_kpPlus] = KEY_KP_ADD, - [RGFW_kpReturn] = KEY_KP_ENTER, - [RGFW_kpEqual] = KEY_KP_EQUAL, + [RGFW_keyMenu] = KEY_KB_MENU, + [RGFW_keyPad0] = KEY_KP_0, + [RGFW_keyPad1] = KEY_KP_1, + [RGFW_keyPad2] = KEY_KP_2, + [RGFW_keyPad3] = KEY_KP_3, + [RGFW_keyPad4] = KEY_KP_4, + [RGFW_keyPad5] = KEY_KP_5, + [RGFW_keyPad6] = KEY_KP_6, + [RGFW_keyPad7] = KEY_KP_7, + [RGFW_keyPad8] = KEY_KP_8, + [RGFW_keyPad9] = KEY_KP_9, + [RGFW_keyPadPeriod] = KEY_KP_DECIMAL, + [RGFW_keyPadSlash] = KEY_KP_DIVIDE, + [RGFW_keyPadMultiply] = KEY_KP_MULTIPLY, + [RGFW_keyPadMinus] = KEY_KP_SUBTRACT, + [RGFW_keyPadPlus] = KEY_KP_ADD, + [RGFW_keyPadReturn] = KEY_KP_ENTER, + [RGFW_keyPadEqual] = KEY_KP_EQUAL, }; static int mg_buttonConvertTable[] = { @@ -456,14 +456,297 @@ static int mg_axisConvertTable[] = { [MG_AXIS_HAT_DPAD_DOWN] = -1, }; +static KeyboardKey ConvertScancodeToKey(u32 keycode); +void RemapMouseToTouch(int touchAction); + +// --------------------------------------------------------------------------------- +// RGFW Callbacks (instead of the older polling) +// --------------------------------------------------------------------------------- +static void RGFW_cb_mousenotifyfunc(const RGFW_event* e) +{ + if (e->common.win != platform.window) return; + + CORE.Input.Mouse.cursorOnScreen = e->mouse.inWindow; +} +// static void RGFW_cb_windowclosefunc(const RGFW_event* e) +// { +// if (e->common.win != platform.window) return; + +// // we don't want to close here. raylib handles it +// // RGFW_window_setShouldClose(platform.window, true); +// } +static void RGFW_cb_dropfunc(const RGFW_event* e) +{ + if (e->common.win != platform.window) return; + + if (CORE.Window.dropFileCount == 0) + { + CORE.Window.dropFilepaths = (char **)RL_CALLOC(1024, sizeof(char *)); + + CORE.Window.dropFilepaths[CORE.Window.dropFileCount] = (char *)RL_CALLOC(MAX_FILEPATH_LENGTH, sizeof(char)); + strcpy(CORE.Window.dropFilepaths[CORE.Window.dropFileCount], e->drop.value->data); + + CORE.Window.dropFileCount++; + } + else if (CORE.Window.dropFileCount < 1024) + { + CORE.Window.dropFilepaths[CORE.Window.dropFileCount] = (char *)RL_CALLOC(MAX_FILEPATH_LENGTH, sizeof(char)); + strcpy(CORE.Window.dropFilepaths[CORE.Window.dropFileCount], e->drop.value->data); + + CORE.Window.dropFileCount++; + } + else TRACELOG(LOG_WARNING, "FILE: Maximum drag and drop files at once is limited to 1024 files!"); +} +static void RGFW_cb_windowresizefunc(const RGFW_event* e) +{ + if (e->common.win != platform.window) return; + + CORE.Window.resizedLastFrame = true; + + #if defined(__APPLE__) + if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_HIGHDPI)) + { + RGFW_monitor* currentMonitor = RGFW_window_getMonitor(platform.window); + SetupViewport(platform.window->w*currentMonitor->pixelRatio, platform.window->h*currentMonitor->pixelRatio); + CORE.Window.screenScale = MatrixScale(currentMonitor->pixelRatio, currentMonitor->pixelRatio, 1.0f); + + CORE.Window.screen.width = platform.window->w; + CORE.Window.screen.height = platform.window->h; + CORE.Window.render.width = CORE.Window.screen.width*currentMonitor->pixelRatio; + CORE.Window.render.height = CORE.Window.screen.height*currentMonitor->pixelRatio; + } + else + { + SetupViewport(platform.window->w, platform.window->h); + CORE.Window.screen.width = platform.window->w; + CORE.Window.screen.height = platform.window->h; + CORE.Window.render.width = CORE.Window.screen.width; + CORE.Window.render.height = CORE.Window.screen.height; + } + + CORE.Window.currentFbo.width = CORE.Window.render.width; + CORE.Window.currentFbo.height = CORE.Window.render.height; + #elif defined(PLATFORM_WEB_RGFW) + // do nothing but prevent other behavior + #else + SetupViewport(platform.window->w, platform.window->h); + + // Consider content scaling if required + if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_HIGHDPI)) + { + Vector2 scaleDpi = GetWindowScaleDPI(); + CORE.Window.screen.width = (int)(platform.window->w/scaleDpi.x); + CORE.Window.screen.height = (int)(platform.window->h/scaleDpi.y); + CORE.Window.screenScale = MatrixScale(scaleDpi.x, scaleDpi.y, 1.0f); + } + else + { + CORE.Window.screen.width = platform.window->w; + CORE.Window.screen.height = platform.window->h; + } + + CORE.Window.currentFbo.width = CORE.Window.screen.width; + CORE.Window.currentFbo.height = CORE.Window.screen.height; + #endif + + #if defined(GRAPHICS_API_OPENGL_SOFTWARE) + #if defined(__APPLE__) + RGFW_monitor* currentMonitor = RGFW_window_getMonitor(platform.window); + CORE.Window.screenScale = MatrixScale(currentMonitor->pixelRatio, currentMonitor->pixelRatio, 1.0f); + SetupViewport(platform.window->w*currentMonitor->pixelRatio, platform.window->h*currentMonitor->pixelRatio); + + CORE.Window.render.width = CORE.Window.screen.width*currentMonitor->pixelRatio; + CORE.Window.render.height = CORE.Window.screen.height*currentMonitor->pixelRatio; + CORE.Window.currentFbo.width = CORE.Window.render.width; + CORE.Window.currentFbo.height = CORE.Window.render.height; + #endif + platform.surfaceWidth = CORE.Window.currentFbo.width; + platform.surfaceHeight = CORE.Window.currentFbo.height; + + // in software mode we dont have the viewport so we need to reverse the highdpi changes + if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_HIGHDPI)) + { + Vector2 scaleDpi = GetWindowScaleDPI(); + platform.surfaceWidth *= scaleDpi.x; + platform.surfaceHeight *= scaleDpi.y; + } + + if (platform.surfacePixels != NULL) + { + RL_FREE(platform.surfacePixels); + platform.surfacePixels = RL_MALLOC(platform.surfaceWidth*platform.surfaceHeight*4); + } + + if (platform.surface != NULL) + { + RGFW_surface_free(platform.surface); + platform.surface = RGFW_window_createSurface(platform.window, platform.surfacePixels, platform.surfaceWidth, platform.surfaceHeight, RGFW_formatBGRA8); + swResize(platform.surfaceWidth, platform.surfaceHeight); + } + #endif +} +static void RGFW_cb_windowmaximizefunc(const RGFW_event* e) +{ + if (e->common.win != platform.window) return; + + FLAG_SET(CORE.Window.flags, FLAG_WINDOW_MAXIMIZED); // The window was maximized +} +static void RGFW_cb_windowminimizefunc(const RGFW_event* e) +{ + if (e->common.win != platform.window) return; + + FLAG_SET(CORE.Window.flags, FLAG_WINDOW_MINIMIZED); // The window was iconified +} +static void RGFW_cb_windowrestorefunc(const RGFW_event* e) +{ + if (e->common.win != platform.window) return; + + if (RGFW_window_isMaximized(platform.window)) + FLAG_CLEAR(CORE.Window.flags, FLAG_WINDOW_MAXIMIZED); // The window was restored + if (RGFW_window_isMinimized(platform.window)) + FLAG_CLEAR(CORE.Window.flags, FLAG_WINDOW_MINIMIZED); // The window was restored +} +static void RGFW_cb_windowmovefunc(const RGFW_event* e) +{ + if (e->common.win != platform.window) return; + + CORE.Window.position.x = platform.window->x; + CORE.Window.position.y = platform.window->x; +} +static void RGFW_cb_keycharfunc(const RGFW_event* e) +{ + if (e->common.win != platform.window) return; + + // NOTE: event.text.text data comes an UTF-8 text sequence but registering codepoints (int) + // Check if there is space available in the queue + if (CORE.Input.Keyboard.charPressedQueueCount < MAX_CHAR_PRESSED_QUEUE) + { + // Add character (codepoint) to the queue + CORE.Input.Keyboard.charPressedQueue[CORE.Input.Keyboard.charPressedQueueCount] = e->keyChar.value; + CORE.Input.Keyboard.charPressedQueueCount++; + } +} +static void RGFW_cb_scrollfunc(const RGFW_event* e) +{ + if (e->common.win != platform.window) return; + + CORE.Input.Mouse.currentWheelMove.x += e->delta.x; + CORE.Input.Mouse.currentWheelMove.y += e->delta.y; +} +static void RGFW_cb_mousebuttonfunc(const RGFW_event* e) +{ + if (e->common.win != platform.window) return; + + int btn = e->button.value; + if (btn == RGFW_mouseLeft) btn = 1; + else if (btn == RGFW_mouseRight) btn = 2; + else if (btn == RGFW_mouseMiddle) btn = 3; + + // pressed or released + if (e->button.state){ + CORE.Input.Mouse.currentButtonState[btn - 1] = 1; + CORE.Input.Touch.currentTouchState[btn - 1] = 1; + + // simulate touch with the mouse + RemapMouseToTouch(1); + } else + { + CORE.Input.Mouse.currentButtonState[btn - 1] = 0; + CORE.Input.Touch.currentTouchState[btn - 1] = 0; + + // simulate touch with the mouse + RemapMouseToTouch(0); + } +} +static void RGFW_cb_mouserawmotionfunc(const RGFW_event* e) +{ + if (!RGFW_window_isRawMouseMode(platform.window)) + { + // if not raw, use non-raw motion. this prevents the doubled events + return; + } + + float mouseX = 0.0f; + float mouseY = 0.0f; + mouseX = e->delta.x; + mouseY = e->delta.y; + + #if defined(__EMSCRIPTEN__) + double canvasWidth = 0.0; + double canvasHeight = 0.0; + emscripten_get_element_css_size("#canvas", &canvasWidth, &canvasHeight); + mouseX *= ((float)GetScreenWidth()/(float)canvasWidth); + mouseY *= ((float)GetScreenHeight()/(float)canvasHeight); + #endif + + CORE.Input.Mouse.currentPosition.x += mouseX; + CORE.Input.Mouse.currentPosition.y += mouseY; + + // simulate touch with the mouse + CORE.Input.Touch.position[0] = CORE.Input.Mouse.currentPosition; + RemapMouseToTouch(2); +} +static void RGFW_cb_mousemotionfunc(const RGFW_event* e) +{ + if (RGFW_window_isRawMouseMode(platform.window)) + { + // if raw, use raw motion. this prevents the doubled events + return; + } + + float mouseX = 0.0f; + float mouseY = 0.0f; + mouseX = e->mouse.x; + mouseY = e->mouse.y; + + #if defined(__EMSCRIPTEN__) + double canvasWidth = 0.0; + double canvasHeight = 0.0; + emscripten_get_element_css_size("#canvas", &canvasWidth, &canvasHeight); + mouseX *= ((float)GetScreenWidth()/(float)canvasWidth); + mouseY *= ((float)GetScreenHeight()/(float)canvasHeight); + #endif + + CORE.Input.Mouse.currentPosition.x = mouseX; + CORE.Input.Mouse.currentPosition.y = mouseY; + + // simulate touch with the mouse + CORE.Input.Touch.position[0] = CORE.Input.Mouse.currentPosition; + RemapMouseToTouch(2); +} +static void RGFW_cb_keyfunc(const RGFW_keyEvent* e) +{ + if (e->win != platform.window) return; + + KeyboardKey key = ConvertScancodeToKey(e->value); + if (key == KEY_NULL) return; + + // pressed or released + if (e->state) + { + // If key was up, add it to the key pressed queue + if ((CORE.Input.Keyboard.currentKeyState[key] == 0) && (CORE.Input.Keyboard.keyPressedQueueCount < MAX_KEY_PRESSED_QUEUE)) + { + CORE.Input.Keyboard.keyPressedQueue[CORE.Input.Keyboard.keyPressedQueueCount] = key; + CORE.Input.Keyboard.keyPressedQueueCount++; + } + + CORE.Input.Keyboard.currentKeyState[key] = 1; + + if (CORE.Input.Keyboard.currentKeyState[CORE.Input.Keyboard.exitKey]) RGFW_window_setShouldClose(platform.window, true); + } + else + { + CORE.Input.Keyboard.currentKeyState[key] = 0; + } +} + //---------------------------------------------------------------------------------- // Module Internal Functions Declaration //---------------------------------------------------------------------------------- int InitPlatform(void); // Initialize platform (graphics, inputs and more) bool InitGraphicsDevice(void); // Initialize graphics device -static KeyboardKey ConvertScancodeToKey(u32 keycode); - //---------------------------------------------------------------------------------- // Module Functions Declaration //---------------------------------------------------------------------------------- @@ -476,10 +759,9 @@ static KeyboardKey ConvertScancodeToKey(u32 keycode); // Check if application should close bool WindowShouldClose(void) { - if (CORE.Window.shouldClose == false) - CORE.Window.shouldClose = RGFW_window_shouldClose(platform.window); + if (CORE.Window.shouldClose == false) CORE.Window.shouldClose = RGFW_window_shouldClose(platform.window); if (CORE.Window.ready) return CORE.Window.shouldClose; - else return true; + return true; } // Toggle fullscreen mode @@ -1181,7 +1463,7 @@ double GetTime(void) { // CORE.Time.base is nanoseconds as integer double baseTime = (double)CORE.Time.base*1e-9; - double time = get_time_seconds() - baseTime; + double time = GetTimeSeconds() - baseTime; return time; } @@ -1288,9 +1570,6 @@ void PollInputEvents(void) // Map touch position to mouse position for convenience CORE.Input.Touch.position[0] = CORE.Input.Mouse.currentPosition; - int touchAction = -1; // 0-TOUCH_ACTION_UP, 1-TOUCH_ACTION_DOWN, 2-TOUCH_ACTION_MOVE - bool realTouch = false; // Flag to differentiate real touch gestures from mouse ones - // Register previous keys states // NOTE: Android supports up to 260 keys for (int i = 0; i < MAX_KEYBOARD_KEYS; i++) @@ -1322,291 +1601,9 @@ void PollInputEvents(void) CORE.Time.previous = GetTime(); } - RGFW_event rgfw_event; - while (RGFW_window_checkEvent(platform.window, &rgfw_event)) - { - // All input events can be processed after polling - switch (rgfw_event.type) - { - case RGFW_mouseEnter: CORE.Input.Mouse.cursorOnScreen = true; break; - case RGFW_mouseLeave: CORE.Input.Mouse.cursorOnScreen = false; break; - case RGFW_quit: - RGFW_window_setShouldClose(platform.window, true); - return; - case RGFW_dataDrop: // Dropped file - { - for (int i = 0; i < rgfw_event.drop.count; i++) - { - if (CORE.Window.dropFileCount == 0) - { - // When a new file is dropped, reserve a fixed number of slots for all possible dropped files - // at the moment limiting the number of drops at once to 1024 files but this behaviour should probably be reviewed - // TODO: Pointers should probably be reallocated for any new file added... - CORE.Window.dropFilepaths = (char **)RL_CALLOC(1024, sizeof(char *)); - - CORE.Window.dropFilepaths[CORE.Window.dropFileCount] = (char *)RL_CALLOC(MAX_FILEPATH_LENGTH, sizeof(char)); - strcpy(CORE.Window.dropFilepaths[CORE.Window.dropFileCount], rgfw_event.drop.files[i]); - - CORE.Window.dropFileCount++; - } - else if (CORE.Window.dropFileCount < 1024) - { - CORE.Window.dropFilepaths[CORE.Window.dropFileCount] = (char *)RL_CALLOC(MAX_FILEPATH_LENGTH, sizeof(char)); - strcpy(CORE.Window.dropFilepaths[CORE.Window.dropFileCount], rgfw_event.drop.files[i]); - - CORE.Window.dropFileCount++; - } - else TRACELOG(LOG_WARNING, "FILE: Maximum drag and drop files at once is limited to 1024 files!"); - } - } break; - - // Window events are also polled (Minimized, maximized, close...) - case RGFW_windowResized: - { - // set flag that the window was resized - CORE.Window.resizedLastFrame = true; - - #if defined(__APPLE__) - if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_HIGHDPI)) - { - RGFW_monitor* currentMonitor = RGFW_window_getMonitor(platform.window); - SetupViewport(platform.window->w*currentMonitor->pixelRatio, platform.window->h*currentMonitor->pixelRatio); - CORE.Window.screenScale = MatrixScale(currentMonitor->pixelRatio, currentMonitor->pixelRatio, 1.0f); - - CORE.Window.screen.width = platform.window->w; - CORE.Window.screen.height = platform.window->h; - CORE.Window.render.width = CORE.Window.screen.width*currentMonitor->pixelRatio; - CORE.Window.render.height = CORE.Window.screen.height*currentMonitor->pixelRatio; - } - else - { - SetupViewport(platform.window->w, platform.window->h); - CORE.Window.screen.width = platform.window->w; - CORE.Window.screen.height = platform.window->h; - CORE.Window.render.width = CORE.Window.screen.width; - CORE.Window.render.height = CORE.Window.screen.height; - } - - CORE.Window.currentFbo.width = CORE.Window.render.width; - CORE.Window.currentFbo.height = CORE.Window.render.height; - #elif defined(PLATFORM_WEB_RGFW) - // do nothing but prevent other behavior - #else - SetupViewport(platform.window->w, platform.window->h); - - // Consider content scaling if required - if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_HIGHDPI)) - { - Vector2 scaleDpi = GetWindowScaleDPI(); - CORE.Window.screen.width = (int)(platform.window->w/scaleDpi.x); - CORE.Window.screen.height = (int)(platform.window->h/scaleDpi.y); - CORE.Window.screenScale = MatrixScale(scaleDpi.x, scaleDpi.y, 1.0f); - - // Mouse scale does not seem to be needed - //SetMouseScale(1.0f/scaleDpi.x, 1.0f/scaleDpi.y); - } - else - { - CORE.Window.screen.width = platform.window->w; - CORE.Window.screen.height = platform.window->h; - } - - CORE.Window.currentFbo.width = CORE.Window.screen.width; - CORE.Window.currentFbo.height = CORE.Window.screen.height; - #endif - - #if defined(GRAPHICS_API_OPENGL_SOFTWARE) - #if defined(__APPLE__) - RGFW_monitor* currentMonitor = RGFW_window_getMonitor(platform.window); - CORE.Window.screenScale = MatrixScale(currentMonitor->pixelRatio, currentMonitor->pixelRatio, 1.0f); - SetupViewport(platform.window->w*currentMonitor->pixelRatio, platform.window->h*currentMonitor->pixelRatio); - - CORE.Window.render.width = CORE.Window.screen.width*currentMonitor->pixelRatio; - CORE.Window.render.height = CORE.Window.screen.height*currentMonitor->pixelRatio; - CORE.Window.currentFbo.width = CORE.Window.render.width; - CORE.Window.currentFbo.height = CORE.Window.render.height; - #endif - platform.surfaceWidth = CORE.Window.currentFbo.width; - platform.surfaceHeight = CORE.Window.currentFbo.height; - - // in software mode we dont have the viewport so we need to reverse the highdpi changes - if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_HIGHDPI)) - { - Vector2 scaleDpi = GetWindowScaleDPI(); - platform.surfaceWidth *= scaleDpi.x; - platform.surfaceHeight *= scaleDpi.y; - } - - if (platform.surfacePixels != NULL) - { - RL_FREE(platform.surfacePixels); - platform.surfacePixels = RL_MALLOC(platform.surfaceWidth*platform.surfaceHeight*4); - } - - if (platform.surface != NULL) - { - RGFW_surface_free(platform.surface); - platform.surface = RGFW_window_createSurface(platform.window, platform.surfacePixels, platform.surfaceWidth, platform.surfaceHeight, RGFW_formatBGRA8); - swResize(platform.surfaceWidth, platform.surfaceHeight); - } - #endif - } break; - case RGFW_windowMaximized: - { - FLAG_SET(CORE.Window.flags, FLAG_WINDOW_MAXIMIZED); // The window was maximized - } break; - case RGFW_windowMinimized: - { - FLAG_SET(CORE.Window.flags, FLAG_WINDOW_MINIMIZED); // The window was iconified - } break; - case RGFW_windowRestored: - { - if (RGFW_window_isMaximized(platform.window)) - FLAG_CLEAR(CORE.Window.flags, FLAG_WINDOW_MAXIMIZED); // The window was restored - if (RGFW_window_isMinimized(platform.window)) - FLAG_CLEAR(CORE.Window.flags, FLAG_WINDOW_MINIMIZED); // The window was restored - } break; - case RGFW_windowMoved: - { - CORE.Window.position.x = platform.window->x; - CORE.Window.position.y = platform.window->x; - } break; - - // Keyboard events - case RGFW_keyPressed: - { - KeyboardKey key = ConvertScancodeToKey(rgfw_event.key.value); - if (key != KEY_NULL) - { - // If key was up, add it to the key pressed queue - if ((CORE.Input.Keyboard.currentKeyState[key] == 0) && (CORE.Input.Keyboard.keyPressedQueueCount < MAX_KEY_PRESSED_QUEUE)) - { - CORE.Input.Keyboard.keyPressedQueue[CORE.Input.Keyboard.keyPressedQueueCount] = key; - CORE.Input.Keyboard.keyPressedQueueCount++; - } - - CORE.Input.Keyboard.currentKeyState[key] = 1; - - if (CORE.Input.Keyboard.currentKeyState[CORE.Input.Keyboard.exitKey]) RGFW_window_setShouldClose(platform.window, true); - } - } break; - case RGFW_keyReleased: - { - KeyboardKey key = ConvertScancodeToKey(rgfw_event.key.value); - if (key != KEY_NULL) CORE.Input.Keyboard.currentKeyState[key] = 0; - } break; - - case RGFW_keyChar: - { - // NOTE: event.text.text data comes an UTF-8 text sequence but registering codepoints (int) - // Check if there is space available in the queue - if (CORE.Input.Keyboard.charPressedQueueCount < MAX_CHAR_PRESSED_QUEUE) - { - // Add character (codepoint) to the queue - CORE.Input.Keyboard.charPressedQueue[CORE.Input.Keyboard.charPressedQueueCount] = rgfw_event.keyChar.value; - CORE.Input.Keyboard.charPressedQueueCount++; - } - } break; - - // Check mouse events - case RGFW_mouseScroll: - { - CORE.Input.Mouse.currentWheelMove.x += rgfw_event.scroll.x; - CORE.Input.Mouse.currentWheelMove.y += rgfw_event.scroll.y; - } break; - case RGFW_mouseButtonPressed: - { - int btn = rgfw_event.button.value; - if (btn == RGFW_mouseLeft) btn = 1; - else if (btn == RGFW_mouseRight) btn = 2; - else if (btn == RGFW_mouseMiddle) btn = 3; - - CORE.Input.Mouse.currentButtonState[btn - 1] = 1; - CORE.Input.Touch.currentTouchState[btn - 1] = 1; - - touchAction = 1; - } break; - case RGFW_mouseButtonReleased: - { - int btn = rgfw_event.button.value; - if (btn == RGFW_mouseLeft) btn = 1; - else if (btn == RGFW_mouseRight) btn = 2; - else if (btn == RGFW_mouseMiddle) btn = 3; - - CORE.Input.Mouse.currentButtonState[btn - 1] = 0; - CORE.Input.Touch.currentTouchState[btn - 1] = 0; - - touchAction = 0; - } break; - case RGFW_mousePosChanged: - { - float mouseX = 0.0f; - float mouseY = 0.0f; - if (RGFW_window_isCaptured(platform.window)) - { - mouseX = (float)rgfw_event.mouse.vecX; - mouseY = (float)rgfw_event.mouse.vecY; - } - else - { - mouseX = (float)rgfw_event.mouse.x; - mouseY = (float)rgfw_event.mouse.y; - } - -#if defined(__EMSCRIPTEN__) - double canvasWidth = 0.0; - double canvasHeight = 0.0; - emscripten_get_element_css_size("#canvas", &canvasWidth, &canvasHeight); - mouseX *= ((float)GetScreenWidth()/(float)canvasWidth); - mouseY *= ((float)GetScreenHeight()/(float)canvasHeight); -#endif - if (RGFW_window_isCaptured(platform.window)) - { - CORE.Input.Mouse.currentPosition.x += mouseX; - CORE.Input.Mouse.currentPosition.y += mouseY; - } - else - { - CORE.Input.Mouse.currentPosition.x = mouseX; - CORE.Input.Mouse.currentPosition.y = mouseY; - } - - CORE.Input.Touch.position[0] = CORE.Input.Mouse.currentPosition; - touchAction = 2; - } break; - default: break; - } - -#if SUPPORT_GESTURES_SYSTEM - if (touchAction > -1) - { - // Process mouse events as touches to be able to use mouse-gestures - GestureEvent gestureEvent = { 0 }; - - // Register touch actions - gestureEvent.touchAction = touchAction; - - // Assign a pointer ID - gestureEvent.pointId[0] = 0; - - // Register touch points count - gestureEvent.pointCount = 1; - - // Register touch points position, only one point registered - if (touchAction == 2 || realTouch) gestureEvent.position[0] = CORE.Input.Touch.position[0]; - else gestureEvent.position[0] = GetMousePosition(); - - // Normalize gestureEvent.position[0] for CORE.Window.screen.width and CORE.Window.screen.height - gestureEvent.position[0].x /= (float)GetScreenWidth(); - gestureEvent.position[0].y /= (float)GetScreenHeight(); - - // Gesture data is sent to gestures-system for processing - ProcessGestureEvent(gestureEvent); - - touchAction = -1; - } -#endif - } + //----------------------------------------------------------------------------- + // using RGFW callbacks instead of polling + RGFW_pollEvents(); //----------------------------------------------------------------------------- mg_event gamepad_event; @@ -1663,9 +1660,12 @@ void PollInputEvents(void) int axisCount = 0; for (int i = 0; i < MG_AXIS_COUNT; i += 1) { - if (platform.minigamepad.gamepads[gamepadIndex].axes[i].supported) { + if (platform.minigamepad.gamepads[gamepadIndex].axes[i].supported) + { axisCount += 1; - } else { + } + else + { break; } } @@ -1886,6 +1886,25 @@ int InitPlatform(void) } #endif + // Set callbacks + RGFW_setEventCallback(RGFW_mouseEnter, RGFW_cb_mousenotifyfunc); + RGFW_setEventCallback(RGFW_mouseLeave, RGFW_cb_mousenotifyfunc); + // RGFW_setEventCallback(RGFW_windowClose, RGFW_cb_windowclosefunc); // do not close here. let raylib handle it + RGFW_setEventCallback(RGFW_dataDrop, RGFW_cb_dropfunc); + RGFW_setEventCallback(RGFW_windowResized, RGFW_cb_windowresizefunc); + RGFW_setEventCallback(RGFW_windowMaximized, RGFW_cb_windowmaximizefunc); + RGFW_setEventCallback(RGFW_windowMinimized, RGFW_cb_windowminimizefunc); + RGFW_setEventCallback(RGFW_windowRestored, RGFW_cb_windowrestorefunc); + RGFW_setEventCallback(RGFW_windowMoved, RGFW_cb_windowmovefunc); + RGFW_setEventCallback(RGFW_keyChar, RGFW_cb_keycharfunc); + RGFW_setEventCallback(RGFW_mouseScroll, RGFW_cb_scrollfunc); + RGFW_setEventCallback(RGFW_mouseButtonPressed, RGFW_cb_mousebuttonfunc); + RGFW_setEventCallback(RGFW_mouseButtonReleased, RGFW_cb_mousebuttonfunc); + RGFW_setEventCallback(RGFW_mouseRawMotion, RGFW_cb_mouserawmotionfunc); + RGFW_setEventCallback(RGFW_mouseMotion, RGFW_cb_mousemotionfunc); + RGFW_setEventCallback(RGFW_keyPressed, (RGFW_genericFunc)RGFW_cb_keyfunc); + RGFW_setEventCallback(RGFW_keyReleased, (RGFW_genericFunc)RGFW_cb_keyfunc); + TRACELOG(LOG_INFO, "DISPLAY: Device initialized successfully %s", FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_HIGHDPI)? "(HighDPI)" : ""); TRACELOG(LOG_INFO, " > Display size: %i x %i", CORE.Window.display.width, CORE.Window.display.height); @@ -2007,8 +2026,39 @@ static KeyboardKey ConvertScancodeToKey(u32 keycode) return (KeyboardKey)RGFW_keyConvertTable[keycode]; } +// assign mouse to touches +// 0-TOUCH_ACTION_UP, 1-TOUCH_ACTION_DOWN, 2-TOUCH_ACTION_MOVE +void RemapMouseToTouch(int touchAction) +{ + #if SUPPORT_GESTURES_SYSTEM + if (touchAction < 0) return; + + GestureEvent gestureEvent = { 0 }; + + // Register touch actions + gestureEvent.touchAction = touchAction; + + // Assign a pointer ID + gestureEvent.pointId[0] = 0; + + // Register touch points count + gestureEvent.pointCount = 1; + + // Register touch points position, only one point registered + if (touchAction == 2 /* || realTouch */) gestureEvent.position[0] = CORE.Input.Touch.position[0]; + else gestureEvent.position[0] = GetMousePosition(); + + // Normalize gestureEvent.position[0] for CORE.Window.screen.width and CORE.Window.screen.height + gestureEvent.position[0].x /= (float)GetScreenWidth(); + gestureEvent.position[0].y /= (float)GetScreenHeight(); + + // Gesture data is sent to gestures-system for processing + ProcessGestureEvent(gestureEvent); + #endif +} + // Helper functions for Time -double get_time_seconds(void) +double GetTimeSeconds(void) { double currentTime = 0.0;