From 98662b6a4a77994000348891820b6785d4a3b09e Mon Sep 17 00:00:00 2001
From: Colleague Riley <colleagueRiley@gmail.com>
Date: Tue, 9 Jul 2024 03:12:03 -0400
Subject: [PATCH] update RGFW to RGFW 1.0 (#4144)

* update RGFW

* fix bug with GetCurrentMonitor
---
 src/external/RGFW.h                | 7646 ++++++++++++++--------------
 src/platforms/rcore_desktop_rgfw.c |   92 +-
 2 files changed, 3857 insertions(+), 3881 deletions(-)

diff --git a/src/external/RGFW.h b/src/external/RGFW.h
index 86e68a17f..646ecc9a0 100644
--- a/src/external/RGFW.h
+++ b/src/external/RGFW.h
@@ -37,7 +37,6 @@
 									This version doesn't work for desktops (I'm pretty sure)
 	#define RGFW_OPENGL_ES2 - (optional) use OpenGL ES (version 2)
 	#define RGFW_OPENGL_ES3 - (optional) use OpenGL ES (version 3)
-	#define RGFW_VULKAN - (optional) use vulkan for the rendering backend (rather than opengl)
 	#define RGFW_DIRECTX - (optional) use directX for the rendering backend (rather than opengl) (windows only, defaults to opengl for unix)
 	#define RGFW_NO_API - (optional) don't use any rendering API (no opengl, no vulkan, no directX)
 
@@ -59,7 +58,7 @@
 
 /*
 	Credits :
-		EimaMei/Sacode : Much of the code for creating windows using winapi, Wrote the Silicon library, helped with MacOS Support
+		EimaMei/Sacode : Much of the code for creating windows using winapi, Wrote the Silicon library, helped with MacOS Support, siliapp.h -> referencing 
 
 		stb - This project is heavily inspired by the stb single header files
 
@@ -72,6 +71,13 @@
 
 			Copyright (c) 2002-2006 Marcus Geelnard
 			Copyright (c) 2006-2019 Camilla Löwy
+
+		contributors : (feel free to put yourself here if you contribute)
+		krisvers -> code review
+		EimaMei (SaCode) -> code review
+		Code-Nycticebus -> bug fixes
+		Rob Rohan -> X11 bugs and missing features
+		AICDG (@THISISAGOODNAME) -> vulkan support (example)
 */
 
 #ifndef RGFW_MALLOC
@@ -90,6 +96,12 @@
 #endif
 #endif
 
+/* for windows 95 testing (not that it works well) */
+#ifdef RGFW_WIN95
+#define RGFW_NO_MONITOR
+#define RGFW_NO_PASSTHROUGH
+#endif
+
 #ifndef RGFWDEF
 #ifdef __APPLE__
 #define RGFWDEF static inline
@@ -98,8 +110,12 @@
 #endif
 #endif
 
+#ifndef RGFW_ENUM
+#define RGFW_ENUM(type, name) type name; enum
+#endif
+
 #ifndef RGFW_UNUSED
-#define RGFW_UNUSED(x) if (x){}
+#define RGFW_UNUSED(x) (void)(x);
 #endif
 
 #ifdef __cplusplus
@@ -135,6 +151,10 @@ extern "C" {
 	#endif
 #endif
 
+#if !defined(b8)
+	typedef u8 b8;
+#endif
+
 #if defined(RGFW_X11) && defined(__APPLE__)
 #define RGFW_MACOS_X11
 #undef __APPLE__
@@ -161,16 +181,18 @@ extern "C" {
 #undef _X86_
 #else
 #undef _AMD64_
+#ifndef _X86_
 #define _X86_
 #endif
+#endif
 
-#include <windef.h>
-
+#ifndef RGFW_NO_XINPUT
 #ifdef __MINGW32__
 #include <xinput.h>
 #else
 #include <XInput.h>
 #endif
+#endif
 
 #else 
 #if defined(__unix__) || defined(RGFW_MACOS_X11) || defined(RGFW_X11)
@@ -192,28 +214,10 @@ extern "C" {
 #undef RGFW_EGL
 #endif
 
-#if !defined(RGFW_OSMESA) && !defined(RGFW_EGL) && !defined(RGFW_OPENGL) && !defined (RGFW_VULKAN) && !defined(RGFW_DIRECTX) && !defined(RGFW_BUFFER) && !defined(RGFW_NO_API)
+#if !defined(RGFW_OSMESA) && !defined(RGFW_EGL) && !defined(RGFW_OPENGL) && !defined(RGFW_DIRECTX) && !defined(RGFW_BUFFER) && !defined(RGFW_NO_API)
 #define RGFW_OPENGL
 #endif
 
-#ifdef RGFW_VULKAN
-#ifndef RGFW_MAX_FRAMES_IN_FLIGHT
-#define RGFW_MAX_FRAMES_IN_FLIGHT 2
-#endif
-
-#ifdef RGFW_X11
-#define VK_USE_PLATFORM_XLIB_KHR
-#endif
-#ifdef RGFW_WINDOWS
-#define VK_USE_PLATFORM_WIN32_KHR
-#endif
-#ifdef RGFW_MACOS
-#define VK_USE_PLATFORM_MACOS_MVK
-#endif
-
-#include <vulkan/vulkan.h>
-#endif
-
 #if defined(RGFW_X11) && (defined(RGFW_OPENGL))
 #ifndef GLX_MESA_swap_control
 #define  GLX_MESA_swap_control
@@ -244,8 +248,12 @@ extern "C" {
 #endif
 #endif
 
-		/*! Optional arguments for making a windows */
-#define RGFW_TRANSPARENT_WINDOW		(1L<<9) /*!< the window is transparent */
+#ifndef RGFW_ALPHA
+#define RGFW_ALPHA 128 /* alpha value for RGFW_TRANSPARENT_WINDOW (WINAPI ONLY, macOS + linux don't need this) */
+#endif
+
+/*! Optional arguments for making a windows */
+#define RGFW_TRANSPARENT_WINDOW		(1L<<9) /*!< the window is transparent (only properly works on X11 and MacOS, although it's although for windows) */
 #define RGFW_NO_BORDER		(1L<<3) /*!< the window doesn't have border */
 #define RGFW_NO_RESIZE		(1L<<4) /*!< the window cannot be resized  by the user */
 #define RGFW_ALLOW_DND     (1L<<5) /*!< the window supports drag and drop*/
@@ -255,6 +263,7 @@ extern "C" {
 #define RGFW_OPENGL_SOFTWARE (1L<<11) /*! use OpenGL software rendering */
 #define RGFW_COCOA_MOVE_TO_RESOURCE_DIR (1L << 12) /* (cocoa only), move to resource folder */
 #define RGFW_SCALE_TO_MONITOR (1L << 13) /* scale the window to the screen */
+#define RGFW_NO_INIT_API (1L << 2) /* DO not init an API (mostly for bindings, you should use `#define RGFW_NO_API` in C */
 
 #define RGFW_NO_GPU_RENDER (1L<<14) /* don't render (using the GPU based API)*/
 #define RGFW_NO_CPU_RENDER (1L<<15) /* don't render (using the CPU based buffer rendering)*/
@@ -298,6 +307,11 @@ extern "C" {
 #define RGFW_focusIn 12 /*!< window is in focus now */
 #define RGFW_focusOut 13 /*!< window is out of focus now */
 
+#define RGFW_mouseEnter 14 /* mouse entered the window */
+#define RGFW_mouseLeave 15 /* mouse left the window */
+
+#define RGFW_windowRefresh 16 /* The window content needs to be refreshed */
+
 /* attribs change event note
 	The event data is sent straight to the window structure
 	with win->r.x, win->r.y, win->r.w and win->r.h
@@ -334,23 +348,25 @@ extern "C" {
 #define RGFW_NUMLOCK (1L << 2)
 
 /*! joystick button codes (based on xbox/playstation), you may need to change these values per controller */
-#ifndef RGFW_JS_A
-
-#define RGFW_JS_A 0 /* or PS X button */
-#define RGFW_JS_B 1 /* or PS circle button */
-#define RGFW_JS_Y 2 /* or PS triangle button */
-#define RGFW_JS_X 3 /* or PS square button */
-#define RGFW_JS_START 9 /* start button */
-#define RGFW_JS_SELECT 8 /* select button */
-#define RGFW_JS_HOME 10 /* home button */
-#define RGFW_JS_UP 13 /* dpad up */
-#define RGFW_JS_DOWN 14 /* dpad down*/
-#define RGFW_JS_LEFT 15 /* dpad left */
-#define RGFW_JS_RIGHT 16 /* dpad right */
-#define RGFW_JS_L1 4 /* left bump */
-#define RGFW_JS_L2 5 /* left trigger*/
-#define RGFW_JS_R1 6 /* right bumper */
-#define RGFW_JS_R2 7 /* right trigger */
+#ifndef RGFW_joystick_codes
+
+typedef RGFW_ENUM(u8, RGFW_joystick_codes) {
+	RGFW_JS_A = 0, /* or PS X button */
+	RGFW_JS_B = 1, /* or PS circle button */
+	RGFW_JS_Y = 2, /* or PS triangle button */
+	RGFW_JS_X = 3, /* or PS square button */
+	RGFW_JS_START = 9, /* start button */
+	RGFW_JS_SELECT = 8, /* select button */
+	RGFW_JS_HOME = 10, /* home button */
+	RGFW_JS_UP = 13, /* dpad up */
+	RGFW_JS_DOWN = 14, /* dpad down*/
+	RGFW_JS_LEFT = 15, /* dpad left */
+	RGFW_JS_RIGHT = 16, /* dpad right */
+	RGFW_JS_L1 = 4, /* left bump */
+	RGFW_JS_L2 = 5, /* left trigger*/
+ 	RGFW_JS_R1 = 6, /* right bumper */
+	RGFW_JS_R2 = 7, /* right trigger */
+};
 
 #endif
 
@@ -373,6 +389,7 @@ typedef struct { i32 x, y; } RGFW_vector;
 #define RGFW_RECT(x, y, w, h) (RGFW_rect){x, y, w, h}
 #define RGFW_AREA(w, h) (RGFW_area){w, h}
 
+	#ifndef RGFW_NO_MONITOR
 	typedef struct RGFW_monitor {
 		char name[128];  /* monitor name */
 		RGFW_rect rect; /* monitor Workarea */
@@ -388,14 +405,11 @@ typedef struct { i32 x, y; } RGFW_vector;
 	RGFWDEF RGFW_monitor* RGFW_getMonitors(void);
 	/* get the primary monitor */
 	RGFWDEF RGFW_monitor RGFW_getPrimaryMonitor(void);
+	#endif
 
 	/* NOTE: some parts of the data can represent different things based on the event (read comments in RGFW_Event struct) */
 	typedef struct RGFW_Event {
-#ifdef RGFW_WINDOWS
 		char keyName[16]; /* key name of event*/
-#else
-		char* keyName; /*!< key name of event */
-#endif
 
 		/*! drag and drop data */
 		/* 260 max paths with a max length of 260 */
@@ -408,12 +422,13 @@ typedef struct { i32 x, y; } RGFW_vector;
 
 		u32 type; /*!< which event has been sent?*/
 		RGFW_vector point; /*!< mouse x, y of event (or drop point) */
-		u32 keyCode; /*!< keycode of event 	!!Keycodes defined at the bottom of the RGFW_HEADER part of this file!! */
-
+		
 		u32 fps; /*the current fps of the window [the fps is checked when events are checked]*/
 		u64 frameTime, frameTime2; /* this is used for counting the fps */
+		
+		u8 keyCode; /*!< keycode of event 	!!Keycodes defined at the bottom of the RGFW_HEADER part of this file!! */
 
-		u8 inFocus;  /*if the window is in focus or not*/
+		b8 inFocus;  /*if the window is in focus or not (this is always true for MacOS windows due to the api being weird) */
 
 		u8 lockState;
 
@@ -441,7 +456,7 @@ typedef struct { i32 x, y; } RGFW_vector;
 		u32 display;
 		void* displayLink;
 		void* window;
-		u8 dndPassed;
+		b8 dndPassed;
 #endif
 
 #if (defined(RGFW_OPENGL)) && !defined(RGFW_OSMESA)
@@ -455,15 +470,6 @@ typedef struct { i32 x, y; } RGFW_vector;
 		GLXContext rSurf; /*!< source graphics context */
 #endif
 #else
-#ifdef RGFW_VULKAN
-		VkSurfaceKHR rSurf; /*!< source graphics context */
-
-		/* vulkan data */
-		VkSwapchainKHR swapchain;
-		u32 image_count;
-		VkImage* swapchain_images;
-		VkImageView* swapchain_image_views;
-#endif
 
 #ifdef RGFW_OSMESA
 		OSMesaContext rSurf;
@@ -495,6 +501,7 @@ typedef struct { i32 x, y; } RGFW_vector;
 #endif
 #ifdef RGFW_X11
 		XImage* bitmap;
+		GC gc;
 #endif
 #ifdef RGFW_MACOS
 		void* bitmap; /* API's bitmap for storing or managing */
@@ -513,7 +520,7 @@ typedef struct { i32 x, y; } RGFW_vector;
 		RGFW_area scale; /* window scaling */
 
 #ifdef RGFW_MACOS
-		u8 cursorChanged; /* for steve jobs */
+		b8 cursorChanged; /* for steve jobs */
 #endif
 
 		u32 winArgs; /* windows args (for RGFW to check) */
@@ -545,6 +552,9 @@ typedef struct { i32 x, y; } RGFW_vector;
 	typedef void* RGFW_thread; /* thread type for window */
 #endif
 
+	/* this has to be set before createWindow is called, else the fulscreen size is used */
+	RGFWDEF void RGFW_setBufferSize(RGFW_area size); /* the buffer cannot be resized (by RGFW) */
+
 	RGFW_window* RGFW_createWindow(
 		const char* name, /* name of the window */
 		RGFW_rect rect, /* rect of window */
@@ -561,9 +571,19 @@ typedef struct { i32 x, y; } RGFW_vector;
 		ex.
 
 		while (RGFW_window_checkEvent(win) != NULL) [this keeps checking events until it reaches the last one]
+
+		this function is optional if you choose to use event callbacks, 
+		although you still need some way to tell RGFW to process events eg. `RGFW_window_checkEvents`
 	*/
 
-	RGFW_Event* RGFW_window_checkEvent(RGFW_window* win); /*!< check events (returns a pointer to win->event or NULL if there is no event)*/
+	RGFW_Event* RGFW_window_checkEvent(RGFW_window* win); /*!< check current event (returns a pointer to win->event or NULL if there is no event)*/
+
+	/* 
+		check all the events until there are none left,  
+		this should only be used if you're using callbacks only
+	*/
+	RGFWDEF void RGFW_window_checkEvents(RGFW_window* win);
+
 
 	/*! window managment functions*/
 	RGFWDEF void RGFW_window_close(RGFW_window* win); /*!< close the window and free leftover data */
@@ -572,9 +592,10 @@ typedef struct { i32 x, y; } RGFW_vector;
 		RGFW_vector v/* new pos*/
 	);
 
+	#ifndef RGFW_NO_MONITOR
 	/* move to a specific monitor */
 	RGFWDEF void RGFW_window_moveToMonitor(RGFW_window* win, RGFW_monitor m);
-
+	#endif
 	RGFWDEF void RGFW_window_resize(RGFW_window* win,
 		RGFW_area a/* new size*/
 	);
@@ -588,6 +609,14 @@ typedef struct { i32 x, y; } RGFW_vector;
 	RGFWDEF void RGFW_window_minimize(RGFW_window* win); /* minimize the window (in taskbar (per OS))*/
 	RGFWDEF void RGFW_window_restore(RGFW_window* win); /* restore the window from minimized (per OS)*/
 
+	RGFWDEF void RGFW_window_setBorder(RGFW_window* win, b8 border); /* if the window should have a border or not (borderless) based on bool value of `border` */
+	
+	RGFWDEF void RGFW_window_setDND(RGFW_window* win, b8 allow); /* turn on / off dnd (RGFW_ALLOW_DND stil must be passed to the window)*/
+
+	#ifndef RGFW_NO_PASSTHROUGH
+	RGFWDEF void RGFW_window_setMousePassthrough(RGFW_window* win, b8 passthrough); /* turn on / off mouse passthrough */
+	#endif 
+
 	RGFWDEF void RGFW_window_setName(RGFW_window* win,
 		char* name
 	);
@@ -638,16 +667,18 @@ typedef struct { i32 x, y; } RGFW_vector;
 	RGFWDEF void RGFW_window_moveMouse(RGFW_window* win, RGFW_vector v);
 
 	/* if the window should close (RGFW_close was sent or escape was pressed) */
-	RGFWDEF u8 RGFW_window_shouldClose(RGFW_window* win);
+	RGFWDEF b8 RGFW_window_shouldClose(RGFW_window* win);
 	/* if window is fullscreen'd */
-	RGFWDEF u8 RGFW_window_isFullscreen(RGFW_window* win);
+	RGFWDEF b8 RGFW_window_isFullscreen(RGFW_window* win);
 	/* if window is hidden */
-	RGFWDEF u8 RGFW_window_isHidden(RGFW_window* win);
+	RGFWDEF b8 RGFW_window_isHidden(RGFW_window* win);
 	/* if window is minimized */
-	RGFWDEF u8 RGFW_window_isMinimized(RGFW_window* win);
+	RGFWDEF b8 RGFW_window_isMinimized(RGFW_window* win);
 	/* if window is maximized */
-	RGFWDEF u8 RGFW_window_isMaximized(RGFW_window* win);
+	RGFWDEF b8 RGFW_window_isMaximized(RGFW_window* win);
 
+
+	#ifndef RGFW_NO_MONITOR
 	/*
 	scale the window to the monitor,
 	this is run by default if the user uses the arg `RGFW_SCALE_TO_MONITOR` during window creation
@@ -655,53 +686,91 @@ typedef struct { i32 x, y; } RGFW_vector;
 	RGFWDEF void RGFW_window_scaleToMonitor(RGFW_window* win);
 	/* get the struct of the window's monitor  */
 	RGFWDEF RGFW_monitor RGFW_window_getMonitor(RGFW_window* win);
+	#endif
 
 	/*!< make the window the current opengl drawing context */
 	RGFWDEF void RGFW_window_makeCurrent(RGFW_window* win);
 
 	/*error handling*/
-	RGFWDEF u8 RGFW_Error(void); /* returns true if an error has occurred (doesn't print errors itself) */
+	RGFWDEF b8 RGFW_Error(void); /* returns true if an error has occurred (doesn't print errors itself) */
 
 	/*!< if window == NULL, it checks if the key is pressed globally. Otherwise, it checks only if the key is pressed while the window in focus.*/
-	RGFWDEF u8 RGFW_isPressedI(RGFW_window* win, u32 key); /*!< if key is pressed (key code)*/
+	RGFWDEF b8 RGFW_isPressed(RGFW_window* win, u8 key); /*!< if key is pressed (key code)*/
 
-	RGFWDEF u8 RGFW_wasPressedI(RGFW_window* win, u32 key); /*!< if key was pressed (checks prev keymap only) (key code)*/
+	RGFWDEF b8 RGFW_wasPressed(RGFW_window* win, u8 key); /*!< if key was pressed (checks prev keymap only) (key code)*/
 
-	RGFWDEF u8 RGFW_isHeldI(RGFW_window* win, u32 key); /*!< if key is held (key code)*/
-	RGFWDEF u8 RGFW_isReleasedI(RGFW_window* win, u32 key); /*!< if key is released (key code)*/
+	RGFWDEF b8 RGFW_isHeld(RGFW_window* win, u8 key); /*!< if key is held (key code)*/
+	RGFWDEF b8 RGFW_isReleased(RGFW_window* win, u8 key); /*!< if key is released (key code)*/
 
-	RGFWDEF u8 RGFW_isMousePressed(RGFW_window* win, u8 button);
-	RGFWDEF u8 RGFW_isMouseHeld(RGFW_window* win, u8 button);
-	RGFWDEF u8 RGFW_isMouseReleased(RGFW_window* win, u8 button);
-	RGFWDEF u8 RGFW_wasMousePressed(RGFW_window* win, u8 button);
+	RGFWDEF b8 RGFW_isClicked(RGFW_window* win, u8 key);
 
-	/*
-		!!Keycodes defined at the bottom of RGFW_HEADER part of this file!!
-	*/
-	/*!< converts a key code to it's key string */
-	RGFWDEF char* RGFW_keyCodeTokeyStr(u64 key);
-	/*!< converts a string of a key to it's key code */
-	RGFWDEF u32 RGFW_keyStrToKeyCode(char* key);
-	/*!< if key is pressed (key string) */
-#define RGFW_isPressedS(win, key) RGFW_isPressedI(win, RGFW_keyStrToKeyCode(key))
+	RGFWDEF b8 RGFW_isMousePressed(RGFW_window* win, u8 button);
+	RGFWDEF b8 RGFW_isMouseHeld(RGFW_window* win, u8 button);
+	RGFWDEF b8 RGFW_isMouseReleased(RGFW_window* win, u8 button);
+	RGFWDEF b8 RGFW_wasMousePressed(RGFW_window* win, u8 button);
 
 /*! clipboard functions*/
 	RGFWDEF char* RGFW_readClipboard(size_t* size); /*!< read clipboard data */
-#define RGFW_clipboardFree free /* the string returned from RGFW_readClipboard must be freed */
+	RGFWDEF void RGFW_clipboardFree(char* str); /* the string returned from RGFW_readClipboard must be freed */
 
 	RGFWDEF void RGFW_writeClipboard(const char* text, u32 textLen); /*!< write text to the clipboard */
 
-	/*
-		convert a keyString to a char version
-	*/
-	RGFWDEF char RGFW_keystrToChar(const char*);
-	/*
-		ex.
-		"parenleft" -> '('
-		"A" -> 'A',
-		"Return" -> "\n"
+	/* 
+		
+		
+		Event callbacks, 
+		these are completely optional, you can use the normal 
+		RGFW_checkEvent() method if you prefer that
+
 	*/
 
+	/* RGFW_windowMoved, the window and its new rect value  */
+	typedef void (* RGFW_windowmovefunc)(RGFW_window* win, RGFW_rect r);
+	/* RGFW_windowResized, the window and its new rect value  */
+	typedef void (* RGFW_windowresizefunc)(RGFW_window* win, RGFW_rect r);
+	/* RGFW_quit, the window that was closed */
+	typedef void (* RGFW_windowquitfunc)(RGFW_window* win);
+	/* RGFW_focusIn / RGFW_focusOut, the window who's focus has changed and if its inFocus */
+	typedef void (* RGFW_focusfunc)(RGFW_window* win, b8 inFocus);
+	/* 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, RGFW_vector point, b8 status);
+	/* RGFW_mousePosChanged, the window that the move happened on and the new point of the mouse  */
+	typedef void (* RGFW_mouseposfunc)(RGFW_window* win, RGFW_vector point);
+	/* RGFW_dnd_init, the window, the point of the drop on the windows */
+	typedef void (* RGFW_dndInitfunc)(RGFW_window* win, RGFW_vector point);
+	/* RGFW_windowRefresh, the window that needs to be refreshed */
+	typedef void (* RGFW_windowrefreshfunc)(RGFW_window* win);
+	/* RGFW_keyPressed / RGFW_keyReleased, the window that got the event, the keycode, the string version, the state of mod keys, if it was a press (else it's a release) */
+	typedef void (* RGFW_keyfunc)(RGFW_window* win, u32 keycode, char keyName[16], u8 lockState, b8 pressed);
+	/* 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, u8 button, double scroll, b8 pressed);
+	/* RGFW_jsButtonPressed / RGFW_jsButtonReleased, 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_jsButtonfunc)(RGFW_window* win, u16 joystick, u8 button, b8 pressed);
+	/* RGFW_jsAxisMove, the window that got the event, the joystick in question, the axis values and the amount of axises */
+	typedef void (* RGFW_jsAxisfunc)(RGFW_window* win, u16 joystick, RGFW_vector axis[2], u8 axisesCount);
+	
+	/*  RGFW_dnd, the window that had the drop, the drop data and the amount files dropped */
+	#ifdef RGFW_ALLOC_DROPFILES
+	typedef void (* RGFW_dndfunc)(RGFW_window* win, char** droppedFiles, u32 droppedFilesCount);
+	#else
+	typedef void (* RGFW_dndfunc)(RGFW_window* win, char droppedFiles[RGFW_MAX_DROPS][RGFW_MAX_PATH], u32 droppedFilesCount);
+	#endif
+
+	RGFWDEF void RGFW_setWindowMoveCallback(RGFW_windowmovefunc func);
+	RGFWDEF void RGFW_setWindowResizeCallback(RGFW_windowresizefunc func);
+	RGFWDEF void RGFW_setWindowQuitCallback(RGFW_windowquitfunc func);
+	RGFWDEF void RGFW_setMousePosCallback(RGFW_mouseposfunc func);
+	RGFWDEF void RGFW_setWindowRefreshCallback(RGFW_windowrefreshfunc func);
+	RGFWDEF void RGFW_setFocusCallback(RGFW_focusfunc func);
+	RGFWDEF void RGFW_setMouseNotifyCallBack(RGFW_mouseNotifyfunc func);
+	RGFWDEF void RGFW_setDndCallback(RGFW_dndfunc func);
+	RGFWDEF void RGFW_setDndInitCallback(RGFW_dndInitfunc func);
+	RGFWDEF void RGFW_setKeyCallback(RGFW_keyfunc func);
+	RGFWDEF void RGFW_setMouseButtonCallback(RGFW_mousebuttonfunc func);
+	RGFWDEF void RGFW_setjsButtonCallback(RGFW_jsButtonfunc func);
+	RGFWDEF void RGFW_setjsAxisCallback(RGFW_jsAxisfunc func);
+
+
 #ifndef RGFW_NO_THREADS
 	/*! threading functions*/
 
@@ -715,7 +784,7 @@ typedef struct { i32 x, y; } RGFW_vector;
 	#if defined(__unix__) || defined(__APPLE__) 
 	typedef void* (* RGFW_threadFunc_ptr)(void*);
 	#else
-	typedef DWORD (* RGFW_threadFunc_ptr)(void*);
+	typedef DWORD (__stdcall *RGFW_threadFunc_ptr) (LPVOID lpThreadParameter);  
 	#endif
 
 	RGFWDEF RGFW_thread RGFW_createThread(RGFW_threadFunc_ptr ptr, void* args); /*!< create a thread*/
@@ -746,63 +815,14 @@ typedef struct { i32 x, y; } RGFW_vector;
 	/*! Set OpenGL version hint */
 	RGFWDEF void RGFW_setGLVersion(i32 major, i32 minor);
 	RGFWDEF void* RGFW_getProcAddress(const char* procname); /* get native opengl proc address */
+	RGFWDEF void RGFW_window_makeCurrent_OpenGL(RGFW_window* win); /* to be called by RGFW_window_makeCurrent */
 #endif
 	/* supports openGL, directX, OSMesa, EGL and software rendering */
 	RGFWDEF void RGFW_window_swapBuffers(RGFW_window* win); /* swap the rendering buffer */
 	RGFWDEF void RGFW_window_swapInterval(RGFW_window* win, i32 swapInterval);
 
 	RGFWDEF void RGFW_window_setGPURender(RGFW_window* win, i8 set);
-
-#ifdef RGFW_VULKAN
-	typedef struct {
-		VkInstance instance;
-		VkPhysicalDevice physical_device;
-		VkDevice device;
-
-		VkDebugUtilsMessengerEXT debugMessenger;
-
-		VkQueue graphics_queue;
-		VkQueue present_queue;
-
-		VkFramebuffer* framebuffers;
-
-		VkRenderPass render_pass;
-		VkPipelineLayout pipeline_layout;
-		VkPipeline graphics_pipeline;
-
-		VkCommandPool command_pool;
-		VkCommandBuffer* command_buffers;
-
-		VkSemaphore* available_semaphores;
-		VkSemaphore* finished_semaphore;
-		VkFence* in_flight_fences;
-		VkFence* image_in_flight;
-		size_t current_frame;
-	} RGFW_vulkanInfo;
-
-	/*! initializes a vulkan rendering context for the RGFW window,
-		this outputs the vulkan surface into wwin->src.rSurf
-		other vulkan data is stored in the global instance of the RGFW_vulkanInfo structure which is returned
-		by the initVulkan() function
-		RGFW_VULKAN must be defined for this function to be defined
-
-	*/
-	RGFWDEF RGFW_vulkanInfo* RGFW_initVulkan(RGFW_window* win);
-	RGFWDEF void RGFW_freeVulkan(void);
-
-	RGFWDEF RGFW_vulkanInfo* RGFW_getVulkanInfo(void);
-
-	RGFWDEF int RGFW_initData(RGFW_window* win);
-	RGFWDEF void RGFW_createSurface(VkInstance instance, RGFW_window* win);
-	int RGFW_deviceInitialization(RGFW_window* win);
-	int RGFW_createSwapchain(RGFW_window* win);
-	RGFWDEF int RGFW_createRenderPass(void);
-	int RGFW_createCommandPool(void);
-	int RGFW_createCommandBuffers(RGFW_window* win);
-	int RGFW_createSyncObjects(RGFW_window* win);
-	RGFWDEF int RGFW_createFramebuffers(RGFW_window* win);
-#endif
-
+	RGFWDEF void RGFW_window_setCPURender(RGFW_window* win, i8 set);
 #ifdef RGFW_DIRECTX
 	typedef struct {
 		IDXGIFactory* pFactory;
@@ -824,7 +844,7 @@ typedef struct { i32 x, y; } RGFW_vector;
 	RGFWDEF u64 RGFW_getTimeNS(void); /* get time in nanoseconds */
 	RGFWDEF void RGFW_sleep(u64 microsecond); /* sleep for a set time */
 
-	typedef enum {
+	typedef RGFW_ENUM(u8, RGFW_Key) {
 		RGFW_KEY_NULL = 0,
 		RGFW_Escape,
 		RGFW_F1,
@@ -932,10 +952,12 @@ typedef struct { i32 x, y; } RGFW_vector;
 		RGFW_KP_9,
 		RGFW_KP_0,
 		RGFW_KP_Period,
-		RGFW_KP_Return
-	} RGFW_Key;
+		RGFW_KP_Return,
 
-	typedef enum RGFW_mouseIcons {
+		final_key,
+	};
+
+	typedef RGFW_ENUM(u8, RGFW_mouseIcons) {
 		RGFW_MOUSE_NORMAL = 0,
 		RGFW_MOUSE_ARROW,
 		RGFW_MOUSE_IBEAM,
@@ -947,7 +969,7 @@ typedef struct { i32 x, y; } RGFW_vector;
 		RGFW_MOUSE_RESIZE_NESW,
 		RGFW_MOUSE_RESIZE_ALL,
 		RGFW_MOUSE_NOT_ALLOWED,
-	} RGFW_mouseIcons;
+	};
 
 #endif /* RGFW_HEADER */
 
@@ -970,7 +992,7 @@ typedef struct { i32 x, y; } RGFW_vector;
 
 		for (;;) {
 			RGFW_window_checkEvent(win); // NOTE: checking events outside of a while loop may cause input lag
-			if (win->event.type == RGFW_quit || RGFW_isPressedI(win, RGFW_Escape))
+			if (win->event.type == RGFW_quit || RGFW_isPressed(win, RGFW_Escape))
 				break;
 
 			RGFW_window_swapBuffers(win);
@@ -1024,11 +1046,14 @@ typedef struct { i32 x, y; } RGFW_vector;
 #include <assert.h>
 
 /*
-
+RGFW_IMPLEMENTATION starts with generic RGFW defines
 
 This is the start of keycode data
 
-
+Why not use macros instead of the numbers itself?
+Windows -> Not all virtual keys are macros (VK_0 - VK_1, VK_a - VK_z)
+Linux -> Only symcodes are values, (XK_0 - XK_1, XK_a - XK_z) are larger than 0xFF00, I can't find any way to work with them without making the array an unreasonable size
+MacOS -> windows and linux already don't have keycodes as macros, so there's no point
 */
 
 	u8 RGFW_keycodes[] = {
@@ -1146,17 +1171,13 @@ This is the start of keycode data
 		[RGFW_OS_BASED_VALUE(110, 0x24, 116)] = RGFW_Home,
 	};
 
-	#ifdef RGFW_X11
-	u8 RGFW_mouseIconSrc[] = {68, 68, 152, 34, 60, 108, 116, 12, 14, 52, 0};  
-	#elif defined(RGFW_WINDOWS)
-	u32 RGFW_mouseIconSrc[] = {32512, 32512, 32513, 32515, 32649, 32644, 32645, 32642, 32643, 32646, 32648};
-	#elif defined(RGFW_MACOS)
-	char* RGFW_mouseIconSrc[] = {"arrowCursor", "arrowCursor", "IBeamCursor", "crosshairCursor", "pointingHandCursor", "resizeLeftRightCursor", "resizeUpDownCursor", "_windowResizeNorthWestSouthEastCursor", "_windowResizeNorthEastSouthWestCursor", "closedHandCursor", "operationNotAllowedCursor"};
-	#endif
-
-	u8 RGFW_keyboard[128] = { 0 };
-	u8 RGFW_keyboard_prev[128];
+	typedef struct {
+		b8 current  : 1;
+		b8 prev  : 1;
+	} RGFW_keyState;
 
+	RGFW_keyState RGFW_keyboard[final_key] = { {0, 0} };
+	
 	RGFWDEF u32 RGFW_apiKeyCodeToRGFW(u32 keycode);
 
 	u32 RGFW_apiKeyCodeToRGFW(u32 keycode) {
@@ -1166,956 +1187,737 @@ This is the start of keycode data
 		return RGFW_keycodes[keycode];
 	}
 
-/*
-
-this is the end of keycode data
+	RGFWDEF void RGFW_resetKey(void);
+	void RGFW_resetKey(void) {
+		size_t len = final_key;
+		
+		size_t i; 
+		for (i = 0; i < len; i++) 
+			RGFW_keyboard[i].prev = 0;
+	}
 
+/*
+	this is the end of keycode data
 */
 
-#ifdef RGFW_WINDOWS
 
-#include <windows.h>
+/* 
+	event callback defines start here
+*/
 
-#endif
 
-#ifdef RGFW_MACOS
 	/*
-		based on silicon.h
+		These exist to avoid the 
+		if (func == NULL) check 
+		for (allegedly) better performance
 	*/
+	void RGFW_windowmovefuncEMPTY(RGFW_window* win, RGFW_rect r) { RGFW_UNUSED(win); RGFW_UNUSED(r); }
+	void RGFW_windowresizefuncEMPTY(RGFW_window* win, RGFW_rect r) { RGFW_UNUSED(win); RGFW_UNUSED(r); }
+	void RGFW_windowquitfuncEMPTY(RGFW_window* win) { RGFW_UNUSED(win); }
+	void RGFW_focusfuncEMPTY(RGFW_window* win, b8 inFocus) {RGFW_UNUSED(win); RGFW_UNUSED(inFocus);}
+	void RGFW_mouseNotifyfuncEMPTY(RGFW_window* win, RGFW_vector point, b8 status) {RGFW_UNUSED(win); RGFW_UNUSED(point); RGFW_UNUSED(status);}
+	void RGFW_mouseposfuncEMPTY(RGFW_window* win, RGFW_vector point) {RGFW_UNUSED(win); RGFW_UNUSED(point);}
+	void RGFW_dndInitfuncEMPTY(RGFW_window* win, RGFW_vector point) {RGFW_UNUSED(win); RGFW_UNUSED(point);}
+	void RGFW_windowrefreshfuncEMPTY(RGFW_window* win) {RGFW_UNUSED(win); }
+	void RGFW_keyfuncEMPTY(RGFW_window* win, u32 keycode, char keyName[16], u8 lockState, b8 pressed) {RGFW_UNUSED(win); RGFW_UNUSED(keycode); RGFW_UNUSED(keyName); RGFW_UNUSED(lockState); RGFW_UNUSED(pressed);}
+	void RGFW_mousebuttonfuncEMPTY(RGFW_window* win, u8 button, double scroll, b8 pressed) {RGFW_UNUSED(win); RGFW_UNUSED(button); RGFW_UNUSED(scroll); RGFW_UNUSED(pressed);}
+	void RGFW_jsButtonfuncEMPTY(RGFW_window* win, u16 joystick, u8 button, b8 pressed){RGFW_UNUSED(win); RGFW_UNUSED(joystick); RGFW_UNUSED(button); RGFW_UNUSED(pressed); }
+	void RGFW_jsAxisfuncEMPTY(RGFW_window* win, u16 joystick, RGFW_vector axis[2], u8 axisesCount){RGFW_UNUSED(win); RGFW_UNUSED(joystick); RGFW_UNUSED(axis); RGFW_UNUSED(axisesCount); }
+
+	#ifdef RGFW_ALLOC_DROPFILES
+	void RGFW_dndfuncEMPTY(RGFW_window* win, char** droppedFiles, u32 droppedFilesCount) {RGFW_UNUSED(win); RGFW_UNUSED(droppedFiles); RGFW_UNUSED(droppedFilesCount);}
+	#else
+	void RGFW_dndfuncEMPTY(RGFW_window* win, char droppedFiles[RGFW_MAX_DROPS][RGFW_MAX_PATH], u32 droppedFilesCount) {RGFW_UNUSED(win); RGFW_UNUSED(droppedFiles); RGFW_UNUSED(droppedFilesCount);}
+	#endif
 
-#ifndef GL_SILENCE_DEPRECATION
-#define GL_SILENCE_DEPRECATION
-#endif
-
-#include <CoreVideo/CVDisplayLink.h>
-#include <ApplicationServices/ApplicationServices.h>
-#include <objc/runtime.h>
-#include <objc/message.h>
-
-	typedef CGRect NSRect;
-	typedef CGPoint NSPoint;
-	typedef CGSize NSSize;
-
-	typedef void NSBitmapImageRep;
-	typedef void NSCursor;
-	typedef void NSDraggingInfo;
-	typedef void NSWindow;
-	typedef void NSApplication;
-	typedef void NSScreen;
-	typedef void NSEvent;
-	typedef void NSString;
-	typedef void NSOpenGLContext;
-	typedef void NSPasteboard;
-	typedef void NSColor;
-	typedef void NSArray;
-	typedef void NSImageRep;
-	typedef void NSImage;
-	typedef void NSOpenGLView;
-
-
-	typedef const char* NSPasteboardType;
-	typedef unsigned long NSUInteger;
-	typedef long NSInteger;
-	typedef NSInteger NSModalResponse;
+	RGFW_windowmovefunc RGFW_windowMoveCallback = RGFW_windowmovefuncEMPTY;
+	RGFW_windowresizefunc RGFW_windowResizeCallback = RGFW_windowresizefuncEMPTY;
+	RGFW_windowquitfunc RGFW_windowQuitCallback = RGFW_windowquitfuncEMPTY;
+	RGFW_mouseposfunc RGFW_mousePosCallback = RGFW_mouseposfuncEMPTY;
+	RGFW_windowrefreshfunc RGFW_windowRefreshCallback = RGFW_windowrefreshfuncEMPTY;
+	RGFW_focusfunc RGFW_focusCallback = RGFW_focusfuncEMPTY;
+	RGFW_mouseNotifyfunc RGFW_mouseNotifyCallBack = RGFW_mouseNotifyfuncEMPTY;
+	RGFW_dndfunc RGFW_dndCallback = RGFW_dndfuncEMPTY;
+	RGFW_dndInitfunc RGFW_dndInitCallback = RGFW_dndInitfuncEMPTY;
+	RGFW_keyfunc RGFW_keyCallback = RGFW_keyfuncEMPTY;
+	RGFW_mousebuttonfunc RGFW_mouseButtonCallback = RGFW_mousebuttonfuncEMPTY;
+	RGFW_jsButtonfunc RGFW_jsButtonCallback = RGFW_jsButtonfuncEMPTY;
+	RGFW_jsAxisfunc RGFW_jsAxisCallback = RGFW_jsAxisfuncEMPTY;
+
+	void RGFW_window_checkEvents(RGFW_window* win) { while (RGFW_window_checkEvent(win) != NULL && RGFW_window_shouldClose(win) == 0) { if (win->event.type == RGFW_quit) return; }}
+	
+	void RGFW_setWindowMoveCallback(RGFW_windowmovefunc func) { RGFW_windowMoveCallback = func; }
+	void RGFW_setWindowResizeCallback(RGFW_windowresizefunc func) { RGFW_windowResizeCallback = func; }
+	void RGFW_setWindowQuitCallback(RGFW_windowquitfunc func) { RGFW_windowQuitCallback = func; }
+	void RGFW_setMousePosCallback(RGFW_mouseposfunc func) { RGFW_mousePosCallback = func; }
+	void RGFW_setWindowRefreshCallback(RGFW_windowrefreshfunc func) { RGFW_windowRefreshCallback = func; }
+	void RGFW_setFocusCallback(RGFW_focusfunc func) { RGFW_focusCallback = func; }
+	void RGFW_setMouseNotifyCallBack(RGFW_mouseNotifyfunc func) { RGFW_mouseNotifyCallBack = func; }
+	void RGFW_setDndCallback(RGFW_dndfunc func) { RGFW_dndCallback = func; }
+	void RGFW_setDndInitCallback(RGFW_dndInitfunc func) { RGFW_dndInitCallback = func; }
+	void RGFW_setKeyCallback(RGFW_keyfunc func) { RGFW_keyCallback = func; }
+	void RGFW_setMouseButtonCallback(RGFW_mousebuttonfunc func) { RGFW_mouseButtonCallback = func; }
+	void RGFW_setjsButtonCallback(RGFW_jsButtonfunc func) { RGFW_jsButtonCallback = func; }
+	void RGFW_setjsAxisCallback(RGFW_jsAxisfunc func) { RGFW_jsAxisCallback = func; }
+/* 
+	no more event call back defines
+*/
 
-#ifdef __arm64__
-	/* ARM just uses objc_msgSend */
-#define abi_objc_msgSend_stret objc_msgSend
-#define abi_objc_msgSend_fpret objc_msgSend
-#else /* __i386__ */ 
-	/* x86 just uses abi_objc_msgSend_fpret and (NSColor *)objc_msgSend_id respectively */
-#define abi_objc_msgSend_stret objc_msgSend_stret
-#define abi_objc_msgSend_fpret objc_msgSend_fpret
-#endif
+#define RGFW_ASSERT(check, str) {\
+	if (!(check)) { \
+		printf(str); \
+		assert(check); \
+	} \
+}
 
-#define NSAlloc(nsclass) objc_msgSend_id((id)nsclass, sel_registerName("alloc"))
-#define objc_msgSend_bool			((BOOL (*)(id, SEL))objc_msgSend)
-#define objc_msgSend_void			((void (*)(id, SEL))objc_msgSend)
-#define objc_msgSend_void_id		((void (*)(id, SEL, id))objc_msgSend)
-#define objc_msgSend_uint			((NSUInteger (*)(id, SEL))objc_msgSend)
-#define objc_msgSend_void_bool		((void (*)(id, SEL, BOOL))objc_msgSend)
-#define objc_msgSend_void_SEL		((void (*)(id, SEL, SEL))objc_msgSend)
-#define objc_msgSend_id				((id (*)(id, SEL))objc_msgSend)
+	b8 RGFW_error = 0;
+	b8 RGFW_Error() { return RGFW_error; }
 
-#define si_declare_single(class, name, func)	\
-	void class##_##name(class* obj) { \
-		return objc_msgSend_void(obj, sel_registerName(func)); \
+#define SET_ATTRIB(a, v) { \
+    assert(((size_t) index + 1) < sizeof(attribs) / sizeof(attribs[0])); \
+    attribs[index++] = a; \
+    attribs[index++] = v; \
+}
+	
+	RGFW_area RGFW_bufferSize = {0, 0};
+	void RGFW_setBufferSize(RGFW_area size) {
+		RGFW_bufferSize = size;
 	}
 
 
-#define loadFunc(funcName) \
-	static void* func = NULL;\
-	if (func == NULL) \
-		func = sel_registerName(funcName);
+	RGFWDEF RGFW_window* RGFW_window_basic_init(RGFW_rect rect, u16 args);
 
-	void NSRelease(id obj) {
-		loadFunc("release");
-		objc_msgSend_void(obj, func);
-	}
+	RGFW_window* RGFW_window_basic_init(RGFW_rect rect, u16 args) {
+		RGFW_window* win = (RGFW_window*) RGFW_MALLOC(sizeof(RGFW_window)); /* make a new RGFW struct */
 
-#define release NSRelease
+#ifdef RGFW_ALLOC_DROPFILES
+		win->event.droppedFiles = (char**) RGFW_MALLOC(sizeof(char*) * RGFW_MAX_DROPS);
+		u32 i;
+		for (i = 0; i < RGFW_MAX_DROPS; i++)
+			win->event.droppedFiles[i] = (char*) RGFW_CALLOC(RGFW_MAX_PATH, sizeof(char));
+#endif
 
-	si_declare_single(NSApplication, finishLaunching, "finishLaunching")
-		si_declare_single(NSOpenGLContext, flushBuffer, "flushBuffer")
+		#ifndef RGFW_X11 
+		RGFW_area screenR = RGFW_getScreenSize();
+		#else
+		win->src.display = XOpenDisplay(NULL);
+		assert(win->src.display != NULL);
 
-		NSString* NSString_stringWithUTF8String(const char* str) {
-		loadFunc("stringWithUTF8String:");
+		Screen* scrn = DefaultScreenOfDisplay((Display*)win->src.display);
+		RGFW_area screenR = RGFW_AREA(scrn->width, scrn->height);
+		#endif
+		
+		if (args & RGFW_FULLSCREEN)
+			rect = RGFW_RECT(0, 0, screenR.w, screenR.h);
 
-		return ((id(*)(id, SEL, const char*))objc_msgSend)
-			((id)objc_getClass("NSString"), func, str);
-	}
+		if (args & RGFW_CENTER)
+			rect = RGFW_RECT((screenR.w - rect.w) / 2, (screenR.h - rect.h) / 2, rect.w, rect.h);
 
-	const char* NSString_to_char(NSString* str) {
-		return ((const char* (*)(id, SEL)) objc_msgSend) (str, sel_registerName("UTF8String"));
-	}
+		/* set and init the new window's data */
+		win->r = rect;
+		win->fpsCap = 0;
+		win->event.inFocus = 1;
+		win->event.droppedFilesCount = 0;
+		win->src.joystickCount = 0;
+		win->src.winArgs = 0;
+		win->event.lockState = 0;
 
-	void si_impl_func_to_SEL_with_name(const char* class_name, const char* register_name, void* function) {
-		Class selected_class;
+		return win;
+	}
 
-		if (strcmp(class_name, "NSView") == 0) {
-			selected_class = objc_getClass("ViewClass");
-		} else if (strcmp(class_name, "NSWindow") == 0) {
-			selected_class = objc_getClass("WindowClass");
-		} else {
-			selected_class = objc_getClass(class_name);
-		}
+	#ifndef RGFW_NO_MONITOR
+	void RGFW_window_scaleToMonitor(RGFW_window* win) {
+		RGFW_monitor monitor = RGFW_window_getMonitor(win);
 
-		class_addMethod(selected_class, sel_registerName(register_name), (IMP) function, 0);
+		RGFW_window_resize(win, RGFW_AREA(((u32) monitor.scaleX) * win->r.w, ((u32) monitor.scaleX) * win->r.h));
 	}
+	#endif
 
-	/* Header for the array. */
-	typedef struct siArrayHeader {
-		size_t count;
-		/* TODO(EimaMei): Add a `type_width` later on. */
-	} siArrayHeader;
+RGFW_window* RGFW_root = NULL;
 
-	/* Gets the header of the siArray. */
-#define SI_ARRAY_HEADER(s) ((siArrayHeader*)s - 1)
 
-	void* si_array_init_reserve(size_t sizeof_element, size_t count) {
-		siArrayHeader* ptr = malloc(sizeof(siArrayHeader) + (sizeof_element * count));
-		void* array = ptr + sizeof(siArrayHeader);
+#define RGFW_HOLD_MOUSE			(1L<<2) /*!< hold the moues still */
+#define RGFW_MOUSE_LEFT 		(1L<<3) /* if mouse left the window */
 
-		siArrayHeader* header = SI_ARRAY_HEADER(array);
-		header->count = count;
+	void RGFW_clipboardFree(char* str) { RGFW_FREE(str); }
+	
+	b8 RGFW_mouseButtons[5] = { 0 };
+	b8 RGFW_mouseButtons_prev[5];
 
-		return array;
+	b8 RGFW_isMousePressed(RGFW_window* win, u8 button) {
+		assert(win != NULL);
+		return RGFW_mouseButtons[button] && (win != NULL) && win->event.inFocus; 
+	}
+	b8 RGFW_wasMousePressed(RGFW_window* win, u8 button) {
+		assert(win != NULL); 
+		return RGFW_mouseButtons_prev[button] && (win != NULL) && win->event.inFocus; 
+	}
+	b8 RGFW_isMouseHeld(RGFW_window* win, u8 button) {
+		return (RGFW_isMousePressed(win, button) && RGFW_wasMousePressed(win, button));
+	}
+	b8 RGFW_isMouseReleased(RGFW_window* win, u8 button) {
+		return (!RGFW_isMousePressed(win, button) && RGFW_wasMousePressed(win, button));	
 	}
 
-#define si_array_len(array) (SI_ARRAY_HEADER(array)->count)
-#define si_func_to_SEL(class_name, function) si_impl_func_to_SEL_with_name(class_name, #function":", function)
-	/* Creates an Objective-C method (SEL) from a regular C function with the option to set the register name.*/
-#define si_func_to_SEL_with_name(class_name, register_name, function) si_impl_func_to_SEL_with_name(class_name, register_name":", function)
-
-	NSRect NSMakeRect(double x, double y, double width, double height) {
-		NSRect r;
-		r.origin.x = x;
-		r.origin.y = y;
-		r.size.width = width;
-		r.size.height = height;
-
-		return r;
+	b8 RGFW_isPressed(RGFW_window* win, u8 key) {
+		assert(win != NULL);
+		return RGFW_keyboard[key].current && win->event.inFocus;
 	}
 
-	NSPoint NSMakePoint(double x, double y) {
-		NSPoint point;
-		point.x = x;
-		point.y = y;
-		return point;
+	b8 RGFW_wasPressed(RGFW_window* win, u8 key) {
+		assert(win != NULL);
+		return RGFW_keyboard[key].prev && win->event.inFocus;
 	}
 
-	NSSize NSMakeSize(double w, double h) {
-		NSSize size;
-		size.width = w;
-		size.height = h;
-		return size;
+	b8 RGFW_isHeld(RGFW_window* win, u8 key) {
+		return (RGFW_isPressed(win, key) && RGFW_wasPressed(win, key));
 	}
 
-	void* si_array_init(void* allocator, size_t sizeof_element, size_t count) {
-		void* array = si_array_init_reserve(sizeof_element, count);
-		memcpy(array, allocator, sizeof_element * count);
+	b8 RGFW_isClicked(RGFW_window* win, u8 key) {
+		return (RGFW_wasPressed(win, key) && !RGFW_isPressed(win, key));
+	}
 
-		return array;
+	b8 RGFW_isReleased(RGFW_window* win, u8 key) {
+		return (!RGFW_isPressed(win, key) && RGFW_wasPressed(win, key));	
 	}
 	
-	unsigned char* NSBitmapImageRep_bitmapData(NSBitmapImageRep* imageRep) {
-		return ((unsigned char* (*)(id, SEL))objc_msgSend)
-			(imageRep, sel_registerName("bitmapData"));
-	}
-
-#define NS_ENUM(type, name) type name; enum
+	void RGFW_window_makeCurrent(RGFW_window* win) {
+		assert(win != NULL);
 
-	typedef NS_ENUM(NSUInteger, NSBitmapFormat) {
-		NSBitmapFormatAlphaFirst = 1 << 0,       // 0 means is alpha last (RGBA, CMYKA, etc.)
-			NSBitmapFormatAlphaNonpremultiplied = 1 << 1,       // 0 means is premultiplied
-			NSBitmapFormatFloatingPointSamples = 1 << 2,  // 0 is integer
-
-			NSBitmapFormatSixteenBitLittleEndian API_AVAILABLE(macos(10.10)) = (1 << 8),
-			NSBitmapFormatThirtyTwoBitLittleEndian API_AVAILABLE(macos(10.10)) = (1 << 9),
-			NSBitmapFormatSixteenBitBigEndian API_AVAILABLE(macos(10.10)) = (1 << 10),
-			NSBitmapFormatThirtyTwoBitBigEndian API_AVAILABLE(macos(10.10)) = (1 << 11)
-	};
-
-	NSBitmapImageRep* NSBitmapImageRep_initWithBitmapData(unsigned char** planes, NSInteger width, NSInteger height, NSInteger bps, NSInteger spp, bool alpha, bool isPlanar, const char* colorSpaceName, NSBitmapFormat bitmapFormat, NSInteger rowBytes, NSInteger pixelBits) {
-		void* func = sel_registerName("initWithBitmapDataPlanes:pixelsWide:pixelsHigh:bitsPerSample:samplesPerPixel:hasAlpha:isPlanar:colorSpaceName:bitmapFormat:bytesPerRow:bitsPerPixel:");
-
-		return (NSBitmapImageRep*) ((id(*)(id, SEL, unsigned char**, NSInteger, NSInteger, NSInteger, NSInteger, bool, bool, const char*, NSBitmapFormat, NSInteger, NSInteger))objc_msgSend)
-			(NSAlloc((id)objc_getClass("NSBitmapImageRep")), func, planes, width, height, bps, spp, alpha, isPlanar, NSString_stringWithUTF8String(colorSpaceName), bitmapFormat, rowBytes, pixelBits);
-	}
+#if defined(RGFW_WINDOWS) && defined(RGFW_DIRECTX)
+		RGFW_dxInfo.pDeviceContext->lpVtbl->OMSetRenderTargets(RGFW_dxInfo.pDeviceContext, 1, &win->src.renderTargetView, NULL);
+#endif
 
-	NSColor* NSColor_colorWithSRGB(CGFloat red, CGFloat green, CGFloat blue, CGFloat alpha) {
-		void* nsclass = objc_getClass("NSColor");
-		void* func = sel_registerName("colorWithSRGBRed:green:blue:alpha:");
-		return ((id(*)(id, SEL, CGFloat, CGFloat, CGFloat, CGFloat))objc_msgSend)
-			(nsclass, func, red, green, blue, alpha);
+#ifdef RGFW_OPENGL
+		RGFW_window_makeCurrent_OpenGL(win);
+#endif
 	}
 
-	NSCursor* NSCursor_initWithImage(NSImage* newImage, NSPoint aPoint) {
-		void* func = sel_registerName("initWithImage:hotSpot:");
-		void* nsclass = objc_getClass("NSCursor");
+	void RGFW_window_setGPURender(RGFW_window* win, i8 set) {
+		if (!set && !(win->src.winArgs & RGFW_NO_GPU_RENDER))
+			win->src.winArgs |= RGFW_NO_GPU_RENDER;
 
-		return (NSCursor*) ((id(*)(id, SEL, id, NSPoint))objc_msgSend)
-			(NSAlloc(nsclass), func, newImage, aPoint);
+		else if (set && win->src.winArgs & RGFW_NO_GPU_RENDER)
+			win->src.winArgs ^= RGFW_NO_GPU_RENDER;
 	}
 
-	void NSImage_addRepresentation(NSImage* image, NSImageRep* imageRep) {
-		void* func = sel_registerName("addRepresentation:");
-		objc_msgSend_void_id(image, func, imageRep);
-	}
+	void RGFW_window_setCPURender(RGFW_window* win, i8 set) {
+		if (!set && !(win->src.winArgs & RGFW_NO_CPU_RENDER))
+			win->src.winArgs |= RGFW_NO_CPU_RENDER;
 
-	NSImage* NSImage_initWithSize(NSSize size) {
-		void* func = sel_registerName("initWithSize:");
-		return ((id(*)(id, SEL, NSSize))objc_msgSend)
-			(NSAlloc((id)objc_getClass("NSImage")), func, size);
+		else if (set && win->src.winArgs & RGFW_NO_CPU_RENDER)
+			win->src.winArgs ^= RGFW_NO_CPU_RENDER;
 	}
-#define NS_OPENGL_ENUM_DEPRECATED(minVers, maxVers) API_AVAILABLE(macos(minVers))
-	typedef NS_ENUM(NSInteger, NSOpenGLContextParameter) {
-		NSOpenGLContextParameterSwapInterval           NS_OPENGL_ENUM_DEPRECATED(10.0, 10.14) = 222, /* 1 param.  0 -> Don't sync, 1 -> Sync to vertical retrace     */
-			NSOpenGLContextParameterSurfaceOrder           NS_OPENGL_ENUM_DEPRECATED(10.0, 10.14) = 235, /* 1 param.  1 -> Above Window (default), -1 -> Below Window    */
-			NSOpenGLContextParameterSurfaceOpacity         NS_OPENGL_ENUM_DEPRECATED(10.0, 10.14) = 236, /* 1 param.  1-> Surface is opaque (default), 0 -> non-opaque   */
-			NSOpenGLContextParameterSurfaceBackingSize     NS_OPENGL_ENUM_DEPRECATED(10.0, 10.14) = 304, /* 2 params.  Width/height of surface backing size              */
-			NSOpenGLContextParameterReclaimResources       NS_OPENGL_ENUM_DEPRECATED(10.0, 10.14) = 308, /* 0 params.                                                    */
-			NSOpenGLContextParameterCurrentRendererID      NS_OPENGL_ENUM_DEPRECATED(10.0, 10.14) = 309, /* 1 param.   Retrieves the current renderer ID                 */
-			NSOpenGLContextParameterGPUVertexProcessing    NS_OPENGL_ENUM_DEPRECATED(10.0, 10.14) = 310, /* 1 param.   Currently processing vertices with GPU (get)      */
-			NSOpenGLContextParameterGPUFragmentProcessing  NS_OPENGL_ENUM_DEPRECATED(10.0, 10.14) = 311, /* 1 param.   Currently processing fragments with GPU (get)     */
-			NSOpenGLContextParameterHasDrawable            NS_OPENGL_ENUM_DEPRECATED(10.0, 10.14) = 314, /* 1 param.   Boolean returned if drawable is attached          */
-			NSOpenGLContextParameterMPSwapsInFlight        NS_OPENGL_ENUM_DEPRECATED(10.0, 10.14) = 315, /* 1 param.   Max number of swaps queued by the MP GL engine    */
-
-			NSOpenGLContextParameterSwapRectangle API_DEPRECATED("", macos(10.0, 10.14)) = 200, /* 4 params.  Set or get the swap rectangle {x, y, w, h} */
-			NSOpenGLContextParameterSwapRectangleEnable API_DEPRECATED("", macos(10.0, 10.14)) = 201, /* Enable or disable the swap rectangle */
-			NSOpenGLContextParameterRasterizationEnable API_DEPRECATED("", macos(10.0, 10.14)) = 221, /* Enable or disable all rasterization */
-			NSOpenGLContextParameterStateValidation API_DEPRECATED("", macos(10.0, 10.14)) = 301, /* Validate state for multi-screen functionality */
-			NSOpenGLContextParameterSurfaceSurfaceVolatile API_DEPRECATED("", macos(10.0, 10.14)) = 306, /* 1 param.   Surface volatile state */
-	};
 
+	void RGFW_window_maximize(RGFW_window* win) {
+		assert(win != NULL);
 
-	void NSOpenGLContext_setValues(NSOpenGLContext* context, const int* vals, NSOpenGLContextParameter param) {
-		void* func = sel_registerName("setValues:forParameter:");
-		((void (*)(id, SEL, const int*, NSOpenGLContextParameter))objc_msgSend)
-			(context, func, vals, param);
-	}
+		RGFW_area screen = RGFW_getScreenSize();
 
-	void* NSOpenGLPixelFormat_initWithAttributes(const uint32_t* attribs) {
-		void* func = sel_registerName("initWithAttributes:");
-		return (void*) ((id(*)(id, SEL, const uint32_t*))objc_msgSend)
-			(NSAlloc((id)objc_getClass("NSOpenGLPixelFormat")), func, attribs);
+		RGFW_window_move(win, RGFW_VECTOR(0, 0));
+		RGFW_window_resize(win, screen);
 	}
 
-	NSOpenGLView* NSOpenGLView_initWithFrame(NSRect frameRect, uint32_t* format) {
-		void* func = sel_registerName("initWithFrame:pixelFormat:");
-		return (NSOpenGLView*) ((id(*)(id, SEL, NSRect, uint32_t*))objc_msgSend)
-			(NSAlloc((id)objc_getClass("NSOpenGLView")), func, frameRect, format);
+	b8 RGFW_window_shouldClose(RGFW_window* win) {
+		assert(win != NULL);
+		return (win->event.type == RGFW_quit || RGFW_isPressed(win, RGFW_Escape));
 	}
 
-	void NSCursor_performSelector(NSCursor* cursor, void* selector) {
-		void* func = sel_registerName("performSelector:");
-		objc_msgSend_void_SEL(cursor, func, selector);
-	}
+	void RGFW_window_setShouldClose(RGFW_window* win) { win->event.type = RGFW_quit; RGFW_windowQuitCallback(win); }
 
-	NSPasteboard* NSPasteboard_generalPasteboard(void) {
-		return (NSPasteboard*) objc_msgSend_id((id)objc_getClass("NSPasteboard"), sel_registerName("generalPasteboard"));
+	#ifndef RGFW_NO_MONITOR
+	void RGFW_window_moveToMonitor(RGFW_window* win, RGFW_monitor m) {
+		RGFW_window_move(win, RGFW_VECTOR(m.rect.x + win->r.x, m.rect.y + win->r.y));
 	}
+	#endif
 
-	NSString** cstrToNSStringArray(char** strs, size_t len) {
-		static NSString* nstrs[6];
-		size_t i;
-		for (i = 0; i < len; i++)
-			nstrs[i] = NSString_stringWithUTF8String(strs[i]);
-
-		return nstrs;
-	}
+	RGFWDEF void RGFW_clipCursor(RGFW_rect);
+			
+	#if !defined(RGFW_WINDOWS) && !defined(RGFW_MACOS)	
+	void RGFW_clipCursor(RGFW_rect r) { RGFW_UNUSED(r) }
+	#endif
 
-	const char* NSPasteboard_stringForType(NSPasteboard* pasteboard, NSPasteboardType dataType) {
-		void* func = sel_registerName("stringForType:");
-		return (const char*) NSString_to_char(((id(*)(id, SEL, const char*))objc_msgSend)(pasteboard, func, NSString_stringWithUTF8String(dataType)));
+	void RGFW_window_mouseHold(RGFW_window* win, RGFW_area area) {
+		if (!(win->src.winArgs & RGFW_HOLD_MOUSE)) {
+			RGFW_clipCursor(win->r);
+			win->src.winArgs |= RGFW_HOLD_MOUSE;
+		}
+		
+		if (!area.w && !area.h)
+			area = RGFW_AREA(win->r.w / 2, win->r.h / 2);
+		
+		#ifndef RGFW_MACOS
+		RGFW_window_moveMouse(win, RGFW_VECTOR(win->r.x + (area.w), win->r.y + (area.h)));
+		#endif
 	}
 
-	NSArray* c_array_to_NSArray(void* array, size_t len) {
-		SEL func = sel_registerName("initWithObjects:count:");
-		void* nsclass = objc_getClass("NSArray");
-		return ((id (*)(id, SEL, void*, NSUInteger))objc_msgSend)
-					(NSAlloc(nsclass), func, array, len);
-	}
- 
-	void NSregisterForDraggedTypes(void* view, NSPasteboardType* newTypes, size_t len) {
-		NSString** ntypes = cstrToNSStringArray((char**)newTypes, len);
+	void RGFW_window_mouseUnhold(RGFW_window* win) {
+		if ((win->src.winArgs & RGFW_HOLD_MOUSE)) {
+			win->src.winArgs ^= RGFW_HOLD_MOUSE;
 
-		NSArray* array = c_array_to_NSArray(ntypes, len);
-		objc_msgSend_void_id(view, sel_registerName("registerForDraggedTypes:"), array);
-		NSRelease(array);
+			RGFW_clipCursor(RGFW_RECT(0, 0, 0, 0));
+		}
 	}
 
-	NSInteger NSPasteBoard_declareTypes(NSPasteboard* pasteboard, NSPasteboardType* newTypes, size_t len, void* owner) {
-		NSString** ntypes = cstrToNSStringArray((char**)newTypes, len);
+	void RGFW_window_checkFPS(RGFW_window* win) {
+		u64 deltaTime = RGFW_getTimeNS() - win->event.frameTime;
 
-		void* func = sel_registerName("declareTypes:owner:");
+		u64 fps = round(1e+9 / deltaTime);
+		win->event.fps = fps;
 
-		NSArray* array = c_array_to_NSArray(ntypes, len);
+		if (win->fpsCap && fps > win->fpsCap) {
+			u64 frameTimeNS = 1e+9 / win->fpsCap;
+			u64 sleepTimeMS = (frameTimeNS - deltaTime) / 1e6;
 
-		NSInteger output = ((NSInteger(*)(id, SEL, id, void*))objc_msgSend)
-			(pasteboard, func, array, owner);
-		NSRelease(array);
+			if (sleepTimeMS > 0) {
+				RGFW_sleep(sleepTimeMS);
+				win->event.frameTime = 0;
+			}
+		}
 
-		return output;
+		win->event.frameTime = RGFW_getTimeNS();
+		
+		if (win->fpsCap == 0)
+			return;
+		
+		deltaTime = RGFW_getTimeNS() - win->event.frameTime2;
+		win->event.fps = round(1e+9 / deltaTime);
+		win->event.frameTime2 = RGFW_getTimeNS();
 	}
+	
+	u32 RGFW_isPressedJS(RGFW_window* win, u16 c, u8 button) { return win->src.jsPressed[c][button]; }
+	
+	#if defined(RGFW_X11) || defined(RGFW_WINDOWS)
+		void RGFW_window_showMouse(RGFW_window* win, i8 show) {
+			static u8 RGFW_blk[] = { 0, 0, 0, 0 };
+			if (show == 0)
+				RGFW_window_setMouse(win, RGFW_blk, RGFW_AREA(1, 1), 4);
+			else
+				RGFW_window_setMouseDefault(win);
+		}
+	#endif
 
-	bool NSPasteBoard_setString(NSPasteboard* pasteboard, const char* stringToWrite, NSPasteboardType dataType) {
-		void* func = sel_registerName("setString:forType:");
-		return ((bool (*)(id, SEL, id, NSPasteboardType))objc_msgSend)
-			(pasteboard, func, NSString_stringWithUTF8String(stringToWrite), NSString_stringWithUTF8String(dataType));
+	RGFWDEF void RGFW_updateLockState(RGFW_window* win, b8 capital, b8 numlock);	
+	void RGFW_updateLockState(RGFW_window* win, b8 capital, b8 numlock) {
+		if (capital && !(win->event.lockState & RGFW_CAPSLOCK))
+			win->event.lockState |= RGFW_CAPSLOCK;
+		else if (!capital && (win->event.lockState & RGFW_CAPSLOCK))			
+			win->event.lockState ^= RGFW_CAPSLOCK;
+		
+		if (numlock && !(win->event.lockState & RGFW_NUMLOCK))
+			win->event.lockState |= RGFW_NUMLOCK;
+		else if (!numlock && (win->event.lockState & RGFW_NUMLOCK))
+			win->event.lockState ^= RGFW_NUMLOCK;
 	}
 
-	void NSRetain(id obj) { objc_msgSend_void(obj, sel_registerName("retain")); }
+	#if defined(RGFW_X11) || defined(RGFW_MACOS)
+		struct timespec;
 
-	typedef enum NSApplicationActivationPolicy {
-		NSApplicationActivationPolicyRegular,
-		NSApplicationActivationPolicyAccessory,
-		NSApplicationActivationPolicyProhibited
-	} NSApplicationActivationPolicy;
+		int nanosleep(const struct timespec* duration, struct timespec* rem);
+		int clock_gettime(clockid_t clk_id, struct timespec* tp);
+		int setenv(const char *name, const char *value, int overwrite);
 
-	typedef NS_ENUM(u32, NSBackingStoreType) {
-		NSBackingStoreRetained = 0,
-			NSBackingStoreNonretained = 1,
-			NSBackingStoreBuffered = 2
-	};
+		void RGFW_window_setDND(RGFW_window* win, b8 allow) {
+			if (allow && !(win->src.winArgs & RGFW_ALLOW_DND))
+				win->src.winArgs |= RGFW_ALLOW_DND;
 
-	typedef NS_ENUM(u32, NSWindowStyleMask) {
-		NSWindowStyleMaskBorderless = 0,
-			NSWindowStyleMaskTitled = 1 << 0,
-			NSWindowStyleMaskClosable = 1 << 1,
-			NSWindowStyleMaskMiniaturizable = 1 << 2,
-			NSWindowStyleMaskResizable = 1 << 3,
-			NSWindowStyleMaskTexturedBackground = 1 << 8, /* deprecated */
-			NSWindowStyleMaskUnifiedTitleAndToolbar = 1 << 12,
-			NSWindowStyleMaskFullScreen = 1 << 14,
-			NSWindowStyleMaskFullSizeContentView = 1 << 15,
-			NSWindowStyleMaskUtilityWindow = 1 << 4,
-			NSWindowStyleMaskDocModalWindow = 1 << 6,
-			NSWindowStyleMaskNonactivatingPanel = 1 << 7,
-			NSWindowStyleMaskHUDWindow = 1 << 13
-	};
+			else if (!allow && (win->src.winArgs & RGFW_ALLOW_DND))
+				win->src.winArgs ^= RGFW_ALLOW_DND;
+		}
+	#endif
 
-	typedef const char* NSPasteboardType;
-	NSPasteboardType const NSPasteboardTypeString = "public.utf8-plain-text"; // Replaces NSStringPboardType
+/*
+	graphics API spcific code (end of generic code)
+	starts here 
+*/
 
 
+/* 
+	OpenGL defines start here   (Normal, EGL, OSMesa)
+*/
 
-	typedef NS_ENUM(i32, NSDragOperation) {
-		NSDragOperationNone = 0,
-			NSDragOperationCopy = 1,
-			NSDragOperationLink = 2,
-			NSDragOperationGeneric = 4,
-			NSDragOperationPrivate = 8,
-			NSDragOperationMove = 16,
-			NSDragOperationDelete = 32,
-			NSDragOperationEvery = ULONG_MAX,
+#if defined(RGFW_OPENGL) || defined(RGFW_EGL) || defined(RGFW_OSMESA)
+#ifndef __APPLE__
+#include <GL/gl.h>
+#else
+#ifndef GL_SILENCE_DEPRECATION
+#define GL_SILENCE_DEPRECATION
+#endif
+#include <OpenGL/gl.h>
+#include <OpenGL/OpenGL.h>
+#endif
 
-			//NSDragOperationAll_Obsolete	API_DEPRECATED("", macos(10.0,10.10)) = 15, // Use NSDragOperationEvery
-			//NSDragOperationAll API_DEPRECATED("", macos(10.0,10.10)) = NSDragOperationAll_Obsolete, // Use NSDragOperationEvery
-	};
+/* EGL, normal OpenGL only */
+#if !defined(RGFW_OSMESA) 
+	i32 RGFW_majorVersion = 0, RGFW_minorVersion = 0;
+	
+	#ifndef RGFW_EGL
+	i32 RGFW_STENCIL = 8, RGFW_SAMPLES = 4, RGFW_STEREO = GL_FALSE, RGFW_AUX_BUFFERS = 0;
+	#else
+	i32 RGFW_STENCIL = 0, RGFW_SAMPLES = 0, RGFW_STEREO = GL_FALSE, RGFW_AUX_BUFFERS = 0;
+	#endif
 
 
-	NSUInteger NSArray_count(NSArray* array) {
-		void* func = sel_registerName("count");
-		return ((NSUInteger(*)(id, SEL))objc_msgSend)(array, func);
-	}
+	void RGFW_setGLStencil(i32 stencil) { RGFW_STENCIL = stencil; }
+	void RGFW_setGLSamples(i32 samples) { RGFW_SAMPLES = samples; }
+	void RGFW_setGLStereo(i32 stereo) { RGFW_STEREO = stereo; }
+	void RGFW_setGLAuxBuffers(i32 auxBuffers) { RGFW_AUX_BUFFERS = auxBuffers; }
 
-	void* NSArray_objectAtIndex(NSArray* array, NSUInteger index) {
-		void* func = sel_registerName("objectAtIndex:");
-		return ((id(*)(id, SEL, NSUInteger))objc_msgSend)(array, func, index);
+	void RGFW_setGLVersion(i32 major, i32 minor) {
+		RGFW_majorVersion = major;
+		RGFW_minorVersion = minor;
 	}
 
-	const char** NSPasteboard_readObjectsForClasses(NSPasteboard* pasteboard, Class* classArray, size_t len, void* options) {
-		void* func = sel_registerName("readObjectsForClasses:options:");
+	u8* RGFW_getMaxGLVersion(void) {
+		RGFW_window* dummy = RGFW_createWindow("dummy", RGFW_RECT(0, 0, 1, 1), 0);
 
-		NSArray* array = c_array_to_NSArray(classArray, len);
+		const char* versionStr = (const char*) glGetString(GL_VERSION);
 
-		NSArray* output = (NSArray*) ((id(*)(id, SEL, id, void*))objc_msgSend)
-			(pasteboard, func, array, options);
+		static u8 version[2];
+		version[0] = versionStr[0] - '0',
+			version[1] = versionStr[2] - '0';
 
-		NSRelease(array);
-		NSUInteger count = NSArray_count(output);
+		RGFW_window_close(dummy);
 
-		const char** res = si_array_init_reserve(sizeof(const char*), count);
+		return version;
+	}
 
-		void* path_func = sel_registerName("path");
+/* OPENGL normal only (no EGL / OSMesa) */
+#ifndef RGFW_EGL
 
-		for (NSUInteger i = 0; i < count; i++) {
-			void* url = NSArray_objectAtIndex(output, i);
-			NSString* url_str = ((id(*)(id, SEL))objc_msgSend)(url, path_func);
-			res[i] = NSString_to_char(url_str);
-		}
+#define RGFW_GL_RENDER_TYPE 		RGFW_OS_BASED_VALUE(GLX_X_VISUAL_TYPE,    	0x2003,		73)
+#define RGFW_GL_ALPHA_SIZE 		RGFW_OS_BASED_VALUE(GLX_ALPHA_SIZE,       	0x201b,		11)
+#define RGFW_GL_DEPTH_SIZE 		RGFW_OS_BASED_VALUE(GLX_DEPTH_SIZE,       	0x2022,		12)
+#define RGFW_GL_DOUBLEBUFFER 		RGFW_OS_BASED_VALUE(GLX_DOUBLEBUFFER,     	0x2011, 	5)   
+#define RGFW_GL_STENCIL_SIZE 		RGFW_OS_BASED_VALUE(GLX_STENCIL_SIZE,	 	0x2023,	13)
+#define RGFW_GL_SAMPLES			RGFW_OS_BASED_VALUE(GLX_SAMPLES, 		 	0x2042,	    55)
+#define RGFW_GL_STEREO 			RGFW_OS_BASED_VALUE(GLX_STEREO,	 		 	0x2012,			6)
+#define RGFW_GL_AUX_BUFFERS		RGFW_OS_BASED_VALUE(GLX_AUX_BUFFERS,	    0x2024,	7)
 
-		return res;
-	}
+#if defined(RGFW_X11) || defined(RGFW_WINDOWS)
+#define RGFW_GL_DRAW 			RGFW_OS_BASED_VALUE(GLX_X_RENDERABLE,	 	0x2001,					0)
+#define RGFW_GL_DRAW_TYPE 		RGFW_OS_BASED_VALUE(GLX_RENDER_TYPE,     	0x2013,						0)
+#define RGFW_GL_USE_OPENGL		RGFW_OS_BASED_VALUE(GLX_USE_GL,				0x2010,						0)
+#define RGFW_GL_FULL_FORMAT		RGFW_OS_BASED_VALUE(GLX_TRUE_COLOR,   	 	0x2027,						0)
+#define RGFW_GL_RED_SIZE		RGFW_OS_BASED_VALUE(GLX_RED_SIZE,         	0x2015,						0)
+#define RGFW_GL_GREEN_SIZE		RGFW_OS_BASED_VALUE(GLX_GREEN_SIZE,       	0x2017,						0)
+#define RGFW_GL_BLUE_SIZE		RGFW_OS_BASED_VALUE(GLX_BLUE_SIZE, 	 		0x2019,						0)
+#define RGFW_GL_USE_RGBA		RGFW_OS_BASED_VALUE(GLX_RGBA_BIT,   	 	0x202B,						0)
+#endif
 
-	void* NSWindow_contentView(NSWindow* window) {
-		void* func = sel_registerName("contentView");
-		return objc_msgSend_id(window, func);
-	}
+#ifdef RGFW_WINDOWS
+#define WGL_COLOR_BITS_ARB                        0x2014
+#define WGL_NUMBER_PIXEL_FORMATS_ARB 			0x2000
+#define WGL_CONTEXT_MAJOR_VERSION_ARB             0x2091
+#define WGL_CONTEXT_MINOR_VERSION_ARB             0x2092
+#define WGL_CONTEXT_PROFILE_MASK_ARB              0x9126
+#define WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002
+#define WGL_SAMPLE_BUFFERS_ARB               0x2041
+#define WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB 0x20a9
+#define WGL_PIXEL_TYPE_ARB                        0x2013
+#define WGL_TYPE_RGBA_ARB                         0x202B
+
+#define WGL_TRANSPARENT_ARB   					  0x200A
 #endif
 
+	static u32* RGFW_initAttribs(u32 useSoftware) {
+		RGFW_UNUSED(useSoftware);
+		static u32 attribs[] = {
+								#ifndef RGFW_MACOS
+								RGFW_GL_RENDER_TYPE,
+								RGFW_GL_FULL_FORMAT,
+								#endif
+								RGFW_GL_ALPHA_SIZE      , 8,
+								RGFW_GL_DEPTH_SIZE      , 24,
+								RGFW_GL_DOUBLEBUFFER    ,
+								#ifndef RGFW_MACOS
+								1,
+								#endif
 
-#define RGFW_ASSERT(check, str) {\
-	if (!(check)) { \
-		printf(str); \
-		assert(check); \
-	} \
-}
+								#if defined(RGFW_X11) || defined(RGFW_WINDOWS)
+								RGFW_GL_USE_OPENGL,		1,
+								RGFW_GL_DRAW, 1,
+								RGFW_GL_RED_SIZE        , 8,
+								RGFW_GL_GREEN_SIZE      , 8,
+								RGFW_GL_BLUE_SIZE       , 8,
+								RGFW_GL_DRAW_TYPE     , RGFW_GL_USE_RGBA,
+								#endif 
 
-	u8 RGFW_error = 0;
-	u8 RGFW_Error() { return RGFW_error; }
+								#ifdef RGFW_X11
+								GLX_DRAWABLE_TYPE   , GLX_WINDOW_BIT,
+								#endif
 
-#define SET_ATTRIB(a, v) { \
-    assert(((size_t) index + 1) < sizeof(attribs) / sizeof(attribs[0])); \
-    attribs[index++] = a; \
-    attribs[index++] = v; \
-}
+								#ifdef RGFW_MACOS
+								72,
+								8, 24,
+								#endif
 
-#define ADD_ATTRIB(a) { \
-    assert(((size_t) index + 1) < sizeof(attribs) / sizeof(attribs[0])); \
-    attribs[index++] = a; \
-}
+								#ifdef RGFW_WINDOWS
+								WGL_PIXEL_TYPE_ARB, WGL_TYPE_RGBA_ARB,
+								WGL_TRANSPARENT_ARB, TRUE,
+								WGL_COLOR_BITS_ARB,	 32,
+								#endif
 
-#if defined(RGFW_X11) || defined(RGFW_WINDOWS)
-	void RGFW_window_showMouse(RGFW_window* win, i8 show) {
-		static u8 RGFW_blk[] = { 0, 0, 0, 0 };
-		if (show == 0)
-			RGFW_window_setMouse(win, RGFW_blk, RGFW_AREA(1, 1), 4);
-		else
-			RGFW_window_setMouseDefault(win);
-	}
-#endif
+								0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+		};
 
-	#ifdef RGFW_WINDOWS
-	__declspec(dllimport) u32 __stdcall timeBeginPeriod(u32 uPeriod);
-	#endif
+		size_t index = (sizeof(attribs) / sizeof(attribs[0])) - 13;
 
-	RGFWDEF RGFW_window* RGFW_window_basic_init(RGFW_rect rect, u16 args);
-	RGFWDEF void RGFW_init_buffer(RGFW_window* win);
+#define RGFW_GL_ADD_ATTRIB(attrib, attVal) \
+		if (attVal) { \
+			attribs[index] = attrib;\
+			attribs[index + 1] = attVal;\
+			index += 2;\
+		}
 
-	RGFW_window* RGFW_window_basic_init(RGFW_rect rect, u16 args) {
-		RGFW_window* win = (RGFW_window*) RGFW_MALLOC(sizeof(RGFW_window)); /* make a new RGFW struct */
+		RGFW_GL_ADD_ATTRIB(RGFW_GL_STENCIL_SIZE, RGFW_STENCIL);
+		RGFW_GL_ADD_ATTRIB(RGFW_GL_STEREO, RGFW_STEREO);
+		RGFW_GL_ADD_ATTRIB(RGFW_GL_AUX_BUFFERS, RGFW_AUX_BUFFERS);
 
-		#ifdef RGFW_WINDOWS
-		timeBeginPeriod(1);
-		#endif
- 
-#ifdef RGFW_ALLOC_DROPFILES
-		win->event.droppedFiles = (char**) RGFW_MALLOC(sizeof(char*) * RGFW_MAX_DROPS);
-		u32 i;
-		for (i = 0; i < RGFW_MAX_DROPS; i++)
-			win->event.droppedFiles[i] = (char*) RGFW_CALLOC(RGFW_MAX_PATH, sizeof(char));
-#endif
+#ifndef RGFW_X11
+		RGFW_GL_ADD_ATTRIB(RGFW_GL_SAMPLES, RGFW_SAMPLES);
+#endif 
 
-#ifdef RGFW_X11 
-		/* open X11 display */
-		/* this is done here so the screen size can be accessed */
-		win->src.display = XOpenDisplay(NULL);
-		assert(win->src.display != NULL);
+#ifdef RGFW_MACOS
+		if (useSoftware) {
+			RGFW_GL_ADD_ATTRIB(70, kCGLRendererGenericFloatID);
+		} else {
+			attribs[index] = RGFW_GL_RENDER_TYPE;
+			index += 1;
+		}
 #endif
 
-		#ifndef RGFW_X11 
-		RGFW_area screenR = RGFW_getScreenSize();
-		#else
-		win->src.display = XOpenDisplay(NULL);
-		assert(win->src.display != NULL);
-
-		Screen* scrn = DefaultScreenOfDisplay((Display*)win->src.display);
-		RGFW_area screenR = RGFW_AREA(scrn->width, scrn->height);
-		#endif
-		
-		if (args & RGFW_FULLSCREEN)
-			rect = RGFW_RECT(0, 0, screenR.w, screenR.h);
+#ifdef RGFW_MACOS
+		attribs[index] = 99;
+		attribs[index + 1] = 0x1000;
 
-		if (args & RGFW_CENTER)
-			rect = RGFW_RECT((screenR.w - rect.w) / 2, (screenR.h - rect.h) / 2, rect.w, rect.h);
+		if (RGFW_majorVersion >= 4 || RGFW_majorVersion >= 3) {
+			attribs[index + 1] = (u32) ((RGFW_majorVersion >= 4) ? 0x4100 : 0x3200);
+		}
 
-		/* set and init the new window's data */
-		win->r = rect;
-		win->fpsCap = 0;
-		win->event.inFocus = 1;
-		win->event.droppedFilesCount = 0;
-		win->src.joystickCount = 0;
-#ifdef RGFW_MACOS
-		RGFW_window_setMouseDefault(win);
-#endif
-#ifdef RGFW_WINDOWS
-		win->src.maxSize = RGFW_AREA(0, 0);
-		win->src.minSize = RGFW_AREA(0, 0);
 #endif
-		win->src.winArgs = 0;
-
-		return win;
-	}
 
-	void RGFW_window_scaleToMonitor(RGFW_window* win) {
-		RGFW_monitor monitor = RGFW_window_getMonitor(win);
+		RGFW_GL_ADD_ATTRIB(0, 0);
 
-		RGFW_window_resize(win, RGFW_AREA(((u32) monitor.scaleX) * win->r.w, ((u32) monitor.scaleX) * win->r.h));
+		return attribs;
 	}
 
-	void RGFW_init_buffer(RGFW_window* win) {
-#if defined(RGFW_OSMESA) || defined(RGFW_BUFFER)
-		RGFW_area area = RGFW_getScreenSize();
-#if !(defined(RGFW_WINDOWS)) || defined(RGFW_OSMESA)
-		win->buffer = RGFW_MALLOC(area.w * area.h * 4);
-#endif
+/* EGL only (no OSMesa nor normal OPENGL) */
+#elif defined(RGFW_EGL)
 
-#ifdef RGFW_OSMESA
-		win->src.rSurf = OSMesaCreateContext(OSMESA_RGBA, NULL);
-		OSMesaMakeCurrent(win->src.rSurf, win->buffer, GL_UNSIGNED_BYTE, win->r.w, win->r.h);
-#endif
-#ifdef RGFW_X11
-		win->src.bitmap = XCreateImage(
-			win->src.display, DefaultVisual(win->src.display, XDefaultScreen(win->src.display)),
-			DefaultDepth(win->src.display, XDefaultScreen(win->src.display)),
-			ZPixmap, 0, NULL, area.w, area.h,
-			32, 0
-		);
-#endif
-#ifdef RGFW_WINDOWS
-		BITMAPV5HEADER bi = { 0 };
-		ZeroMemory(&bi, sizeof(bi));
-		bi.bV5Size = sizeof(bi);
-		bi.bV5Width = area.w;
-		bi.bV5Height = -((LONG) area.h);
-		bi.bV5Planes = 1;
-		bi.bV5BitCount = 32;
-		bi.bV5Compression = BI_BITFIELDS;
-		bi.bV5BlueMask = 0x00ff0000;
-		bi.bV5GreenMask = 0x0000ff00;
-		bi.bV5RedMask = 0x000000ff;
-		bi.bV5AlphaMask = 0xff000000;
+#include <EGL/egl.h>
 
-		win->src.bitmap = CreateDIBSection(win->src.hdc,
-			(BITMAPINFO*) &bi,
-			DIB_RGB_COLORS,
-			(void**) &win->buffer,
-			NULL,
-			(DWORD) 0);
+#if defined(RGFW_LINK_EGL)
+	typedef EGLBoolean(EGLAPIENTRY* PFN_eglInitialize)(EGLDisplay, EGLint*, EGLint*);
 
-		win->src.hdcMem = CreateCompatibleDC(win->src.hdc);
-#endif
-#else
-RGFW_UNUSED(win); /* if buffer rendering is not being used */
-#endif
-	}
+	PFNEGLINITIALIZEPROC eglInitializeSource;
+	PFNEGLGETCONFIGSPROC eglGetConfigsSource;
+	PFNEGLCHOOSECONFIGPROC eglChooseConfigSource;
+	PFNEGLCREATEWINDOWSURFACEPROC eglCreateWindowSurfaceSource;
+	PFNEGLCREATECONTEXTPROC eglCreateContextSource;
+	PFNEGLMAKECURRENTPROC eglMakeCurrentSource;
+	PFNEGLGETDISPLAYPROC eglGetDisplaySource;
+	PFNEGLSWAPBUFFERSPROC eglSwapBuffersSource;
+	PFNEGLSWAPINTERVALPROC eglSwapIntervalSource;
+	PFNEGLBINDAPIPROC eglBindAPISource;
+	PFNEGLDESTROYCONTEXTPROC eglDestroyContextSource;
+	PFNEGLTERMINATEPROC eglTerminateSource;
+	PFNEGLDESTROYSURFACEPROC eglDestroySurfaceSource;
 
-#if defined(RGFW_OPENGL) || defined(RGFW_EGL) || defined(RGFW_OSMESA)
-#ifndef __APPLE__
-#include <GL/gl.h>
-#else
-#include <OpenGL/gl.h>
-#endif
+#define eglInitialize eglInitializeSource
+#define eglGetConfigs eglGetConfigsSource
+#define eglChooseConfig eglChooseConfigSource
+#define eglCreateWindowSurface eglCreateWindowSurfaceSource
+#define eglCreateContext eglCreateContextSource
+#define eglMakeCurrent eglMakeCurrentSource
+#define eglGetDisplay eglGetDisplaySource
+#define eglSwapBuffers eglSwapBuffersSource
+#define eglSwapInterval eglSwapIntervalSource
+#define eglBindAPI eglBindAPISource
+#define eglDestroyContext eglDestroyContextSource
+#define eglTerminate eglTerminateSource
+#define eglDestroySurface eglDestroySurfaceSource;
 #endif
 
-#ifdef RGFW_VULKAN
-	RGFW_vulkanInfo RGFW_vulkan_info;
 
-	RGFW_vulkanInfo* RGFW_initVulkan(RGFW_window* win) {
-		assert(win != NULL);
-
-		if (
-			RGFW_initData(win) ||
-			RGFW_deviceInitialization(win) ||
-			RGFW_createSwapchain(win)
-			)
-			return NULL;
+#define EGL_SURFACE_MAJOR_VERSION_KHR 0x3098
+#define EGL_SURFACE_MINOR_VERSION_KHR 0x30fb
 
-		u32 graphics_family_index = 0;
-		u32 present_family_index = 0;
+#ifndef RGFW_GL_ADD_ATTRIB
+#define RGFW_GL_ADD_ATTRIB(attrib, attVal) \
+	if (attVal) { \
+		attribs[index] = attrib;\
+		attribs[index + 1] = attVal;\
+		index += 2;\
+	}
+#endif
 
-		vkGetDeviceQueue(RGFW_vulkan_info.device, graphics_family_index, 0, &RGFW_vulkan_info.graphics_queue);
-		vkGetDeviceQueue(RGFW_vulkan_info.device, present_family_index, 0, &RGFW_vulkan_info.present_queue);
 
-		if (
-			RGFW_createRenderPass() ||
-			RGFW_createFramebuffers(win) ||
-			RGFW_createCommandPool() ||
-			RGFW_createCommandBuffers(win) ||
-			RGFW_createSyncObjects(win)
-			)
-			return NULL;
-
-		return &RGFW_vulkan_info;
-	}
-
-	int RGFW_initData(RGFW_window* win) {
-		assert(win != NULL);
-
-		win->src.swapchain = VK_NULL_HANDLE;
-		win->src.image_count = 0;
-		RGFW_vulkan_info.current_frame = 0;
-
-		return 0;
-	}
-
-	void RGFW_createSurface(VkInstance instance, RGFW_window* win) {
-		assert(win != NULL);
-		assert(instance);
-
-		win->src.rSurf = VK_NULL_HANDLE;
-
-#ifdef RGFW_X11
-		VkXlibSurfaceCreateInfoKHR x11 = { VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR, 0, 0, (Display*) win->src.display, (Window) win->src.window };
-
-		vkCreateXlibSurfaceKHR(RGFW_vulkan_info.instance, &x11, NULL, &win->src.rSurf);
-#endif
-#ifdef RGFW_WINDOWS
-		VkWin32SurfaceCreateInfoKHR win32 = { VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR, 0, 0, GetModuleHandle(NULL), win->src.window };
-
-		vkCreateWin32SurfaceKHR(RGFW_vulkan_info.instance, &win32, NULL, &win->src.rSurf);
-#endif
-#if defined(RGFW_MACOS) && !defined(RGFW_MACOS_X11)
-		VkMacOSSurfaceCreateFlagsMVK macos = { VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK, 0, 0, win->src.display, win->src.window };
-
-		vkCreateMacOSSurfaceMVK(RGFW_vulkan_info.instance, &macos, NULL, &win->src.rSurf);
-#endif
-	}
+	void RGFW_createOpenGLContext(RGFW_window* win) {
+#if defined(RGFW_LINK_EGL)
+		eglInitializeSource = (PFNEGLINITIALIZEPROC) eglGetProcAddress("eglInitialize");
+		eglGetConfigsSource = (PFNEGLGETCONFIGSPROC) eglGetProcAddress("eglGetConfigs");
+		eglChooseConfigSource = (PFNEGLCHOOSECONFIGPROC) eglGetProcAddress("eglChooseConfig");
+		eglCreateWindowSurfaceSource = (PFNEGLCREATEWINDOWSURFACEPROC) eglGetProcAddress("eglCreateWindowSurface");
+		eglCreateContextSource = (PFNEGLCREATECONTEXTPROC) eglGetProcAddress("eglCreateContext");
+		eglMakeCurrentSource = (PFNEGLMAKECURRENTPROC) eglGetProcAddress("eglMakeCurrent");
+		eglGetDisplaySource = (PFNEGLGETDISPLAYPROC) eglGetProcAddress("eglGetDisplay");
+		eglSwapBuffersSource = (PFNEGLSWAPBUFFERSPROC) eglGetProcAddress("eglSwapBuffers");
+		eglSwapIntervalSource = (PFNEGLSWAPINTERVALPROC) eglGetProcAddress("eglSwapInterval");
+		eglBindAPISource = (PFNEGLBINDAPIPROC) eglGetProcAddress("eglBindAPI");
+		eglDestroyContextSource = (PFNEGLDESTROYCONTEXTPROC) eglGetProcAddress("eglDestroyContext");
+		eglTerminateSource = (PFNEGLTERMINATEPROC) eglGetProcAddress("eglTerminate");
+		eglDestroySurfaceSource = (PFNEGLDESTROYSURFACEPROC) eglGetProcAddress("eglDestroySurface");
+#endif /* RGFW_LINK_EGL */
 
-	RGFW_vulkanInfo* RGFW_getVulkanInfo(void) {
-		return &RGFW_vulkan_info;
-	}
+		#ifdef RGFW_WINDOWS
+		win->src.EGL_display = eglGetDisplay((EGLNativeDisplayType) win->src.hdc);
+		#else
+		win->src.EGL_display = eglGetDisplay((EGLNativeDisplayType) win->src.display);
+		#endif
 
-	int RGFW_deviceInitialization(RGFW_window* win) {
-		assert(win != NULL);
+		EGLint major, minor;
 
-		VkApplicationInfo appInfo = { 0 };
-		appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
-		appInfo.pApplicationName = "RGFW app";
-		appInfo.apiVersion = VK_MAKE_VERSION(1, 0, 0);
+		eglInitialize(win->src.EGL_display, &major, &minor);
 
-		char* extension =
-#ifdef RGFW_WINDOWS
-			"VK_KHR_win32_surface";
-#elif defined(RGFW_X11)
-			VK_KHR_XLIB_SURFACE_EXTENSION_NAME;
-#elif defined(RGFW_MACOS)
-			"VK_MVK_macos_surface";
-#else
-			NULL;
-#endif
+		#ifndef EGL_OPENGL_ES1_BIT
+		#define EGL_OPENGL_ES1_BIT 0x1
+		#endif
 
-		VkInstanceCreateInfo instance_create_info = { 0 };
-		instance_create_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
-		instance_create_info.pApplicationInfo = &appInfo;
-		instance_create_info.enabledExtensionCount = extension ? 2 : 0,
-			instance_create_info.ppEnabledExtensionNames = (const char* [2]){
-					VK_KHR_SURFACE_EXTENSION_NAME,
-					extension
+		EGLint egl_config[] = {
+			EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
+			EGL_RENDERABLE_TYPE,
+			#ifdef RGFW_OPENGL_ES1
+			EGL_OPENGL_ES1_BIT,
+			#elif defined(RGFW_OPENGL_ES3)
+			EGL_OPENGL_ES3_BIT,
+			#elif defined(RGFW_OPENGL_ES2)
+			EGL_OPENGL_ES2_BIT,
+			#else
+			EGL_OPENGL_BIT,
+			#endif
+			EGL_NONE, EGL_NONE
 		};
 
-		if (vkCreateInstance(&instance_create_info, NULL, &RGFW_vulkan_info.instance) != VK_SUCCESS) {
-			fprintf(stderr, "failed to create instance!\n");
-			return -1;
-		}
-
-
-		RGFW_createSurface(RGFW_vulkan_info.instance, win);
-
-		u32 deviceCount = 0;
-		vkEnumeratePhysicalDevices(RGFW_vulkan_info.instance, &deviceCount, NULL);
-		VkPhysicalDevice* devices = (VkPhysicalDevice*) RGFW_MALLOC(sizeof(VkPhysicalDevice) * deviceCount);
-		vkEnumeratePhysicalDevices(RGFW_vulkan_info.instance, &deviceCount, devices);
-
-		RGFW_vulkan_info.physical_device = devices[0];
-
-		u32 queue_family_count = 0;
-		vkGetPhysicalDeviceQueueFamilyProperties(RGFW_vulkan_info.physical_device, &queue_family_count, NULL);
-		VkQueueFamilyProperties* queueFamilies = (VkQueueFamilyProperties*) RGFW_MALLOC(sizeof(VkQueueFamilyProperties) * queue_family_count);
-		vkGetPhysicalDeviceQueueFamilyProperties(RGFW_vulkan_info.physical_device, &queue_family_count, queueFamilies);
+		EGLConfig config;
+		EGLint numConfigs;
+		eglChooseConfig(win->src.EGL_display, egl_config, &config, 1, &numConfigs);
 
-		float queuePriority = 1.0f;
 
-		VkPhysicalDeviceFeatures device_features = { 0 };
+		win->src.EGL_surface = eglCreateWindowSurface(win->src.EGL_display, config, (EGLNativeWindowType) win->src.window, NULL);
 
-		VkDeviceCreateInfo device_create_info = { 0 };
-		device_create_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
-		VkDeviceQueueCreateInfo queue_create_infos[2] = {
-			{0},
-			{0},
-		};
-		queue_create_infos[0].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
-		queue_create_infos[0].queueCount = 1;
-		queue_create_infos[0].pQueuePriorities = &queuePriority;
-		queue_create_infos[1].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
-		queue_create_infos[1].queueCount = 1;
-		queue_create_infos[1].pQueuePriorities = &queuePriority;
-		device_create_info.queueCreateInfoCount = 2;
-		device_create_info.pQueueCreateInfos = queue_create_infos;
-
-		device_create_info.enabledExtensionCount = 1;
-
-		const char* device_extensions[] = {
-			VK_KHR_SWAPCHAIN_EXTENSION_NAME
+		EGLint attribs[] = {
+			EGL_CONTEXT_CLIENT_VERSION,
+			#ifdef RGFW_OPENGL_ES1
+			1,
+			#else
+			2,
+			#endif
+			EGL_NONE, EGL_NONE, EGL_NONE, EGL_NONE, EGL_NONE, EGL_NONE
 		};
 
-		device_create_info.ppEnabledExtensionNames = device_extensions;
-		device_create_info.pEnabledFeatures = &device_features;
+		size_t index = 4;
+		RGFW_GL_ADD_ATTRIB(EGL_STENCIL_SIZE, RGFW_STENCIL);
+		RGFW_GL_ADD_ATTRIB(EGL_SAMPLES, RGFW_SAMPLES);
 
-		if (vkCreateDevice(RGFW_vulkan_info.physical_device, &device_create_info, NULL, &RGFW_vulkan_info.device) != VK_SUCCESS) {
-			fprintf(stderr, "failed to create logical device!\n");
-			return -1;
+		if (RGFW_majorVersion) {
+			attribs[1] = RGFW_majorVersion;
+			RGFW_GL_ADD_ATTRIB(EGL_CONTEXT_OPENGL_PROFILE_MASK, EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT);
+			RGFW_GL_ADD_ATTRIB(EGL_CONTEXT_MAJOR_VERSION, RGFW_majorVersion);
+			RGFW_GL_ADD_ATTRIB(EGL_CONTEXT_MINOR_VERSION, RGFW_minorVersion);
 		}
 
-		return 0;
-	}
-
-	int RGFW_createSwapchain(RGFW_window* win) {
-		assert(win != NULL);
-
-		VkSurfaceFormatKHR surfaceFormat = { VK_FORMAT_B8G8R8A8_SRGB, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR };
-		VkPresentModeKHR presentMode = VK_PRESENT_MODE_FIFO_KHR;
+		#if defined(RGFW_OPENGL_ES1) || defined(RGFW_OPENGL_ES2) || defined(RGFW_OPENGL_ES3)
+		eglBindAPI(EGL_OPENGL_ES_API);
+		#else
+		eglBindAPI(EGL_OPENGL_API);		
+		#endif
 
-		VkSurfaceCapabilitiesKHR capabilities = { 0 };
-		vkGetPhysicalDeviceSurfaceCapabilitiesKHR(RGFW_vulkan_info.physical_device, win->src.rSurf, &capabilities);
+      	win->src.EGL_context = eglCreateContext(win->src.EGL_display, config, EGL_NO_CONTEXT, attribs);
 
-		win->src.image_count = capabilities.minImageCount + 1;
-		if (capabilities.maxImageCount > 0 && win->src.image_count > capabilities.maxImageCount) {
-			win->src.image_count = capabilities.maxImageCount;
-		}
+		eglMakeCurrent(win->src.EGL_display, win->src.EGL_surface, win->src.EGL_surface, win->src.EGL_context);
+		eglSwapBuffers(win->src.EGL_display, win->src.EGL_surface);
+	}
 
-		VkSwapchainCreateInfoKHR swapchain_create_info = { 0 };
-		swapchain_create_info.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
-		swapchain_create_info.surface = win->src.rSurf;
-		swapchain_create_info.minImageCount = win->src.image_count;
-		swapchain_create_info.imageFormat = surfaceFormat.format;
-		swapchain_create_info.imageColorSpace = surfaceFormat.colorSpace;
-		swapchain_create_info.imageExtent = (VkExtent2D){ win->r.w, win->r.h };
-		swapchain_create_info.imageArrayLayers = 1;
-		swapchain_create_info.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
-		swapchain_create_info.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
-		swapchain_create_info.queueFamilyIndexCount = 2;
-		swapchain_create_info.preTransform = capabilities.currentTransform;
-		swapchain_create_info.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
-		swapchain_create_info.presentMode = presentMode;
-		swapchain_create_info.clipped = VK_TRUE;
-		swapchain_create_info.oldSwapchain = VK_NULL_HANDLE;
-
-		if (vkCreateSwapchainKHR(RGFW_vulkan_info.device, &swapchain_create_info, NULL, &win->src.swapchain) != VK_SUCCESS) {
-			fprintf(stderr, "failed to create swap chain!\n");
-			return -1;
-		}
+	#ifdef RGFW_APPLE
+	void* RGFWnsglFramework = NULL;
+	#elif defined(RGFW_WINDOWS)
+	static HMODULE wglinstance = NULL;
+	#endif
 
-		u32 imageCount;
-		vkGetSwapchainImagesKHR(RGFW_vulkan_info.device, win->src.swapchain, &imageCount, NULL);
-		win->src.swapchain_images = (VkImage*) RGFW_MALLOC(sizeof(VkImage) * imageCount);
-		vkGetSwapchainImagesKHR(RGFW_vulkan_info.device, win->src.swapchain, &imageCount, win->src.swapchain_images);
-
-		win->src.swapchain_image_views = (VkImageView*) RGFW_MALLOC(sizeof(VkImageView) * imageCount);
-		for (u32 i = 0; i < imageCount; i++) {
-			VkImageViewCreateInfo image_view_cre_infos = { 0 };
-			image_view_cre_infos.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
-			image_view_cre_infos.image = win->src.swapchain_images[i];
-			image_view_cre_infos.viewType = VK_IMAGE_VIEW_TYPE_2D;
-			image_view_cre_infos.format = VK_FORMAT_B8G8R8A8_SRGB;
-			image_view_cre_infos.components.r = VK_COMPONENT_SWIZZLE_IDENTITY;
-			image_view_cre_infos.components.g = VK_COMPONENT_SWIZZLE_IDENTITY;
-			image_view_cre_infos.components.b = VK_COMPONENT_SWIZZLE_IDENTITY;
-			image_view_cre_infos.components.a = VK_COMPONENT_SWIZZLE_IDENTITY;
-			image_view_cre_infos.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
-			image_view_cre_infos.subresourceRange.baseMipLevel = 0;
-			image_view_cre_infos.subresourceRange.levelCount = 1;
-			image_view_cre_infos.subresourceRange.baseArrayLayer = 0;
-			image_view_cre_infos.subresourceRange.layerCount = 1;
-			if (vkCreateImageView(RGFW_vulkan_info.device, &image_view_cre_infos, NULL, &win->src.swapchain_image_views[i]) != VK_SUCCESS) {
-				fprintf(stderr, "failed to create image views!");
-				return -1;
-			}
-		}
+	void* RGFW_getProcAddress(const char* procname) { 
+		#if defined(RGFW_WINDOWS)
+			void* proc = (void*) GetProcAddress(wglinstance, procname); 
 
-		return 0;
-	}
+			if (proc)
+				return proc;
+		#endif
 
-	int RGFW_createRenderPass(void) {
-		VkAttachmentDescription color_attachment = { 0 };
-		color_attachment.format = VK_FORMAT_B8G8R8A8_SRGB;
-		color_attachment.samples = VK_SAMPLE_COUNT_1_BIT;
-		color_attachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
-		color_attachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
-		color_attachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
-		color_attachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
-		color_attachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
-		color_attachment.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
-
-		VkAttachmentReference color_attachment_ref = { 0 };
-		color_attachment_ref.attachment = 0;
-		color_attachment_ref.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
-
-		VkSubpassDescription subpass = { 0 };
-		subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
-		subpass.colorAttachmentCount = 1;
-		subpass.pColorAttachments = &color_attachment_ref;
-
-		VkSubpassDependency dependency = { 0 };
-		dependency.srcSubpass = VK_SUBPASS_EXTERNAL;
-		dependency.dstSubpass = 0;
-		dependency.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
-		dependency.srcAccessMask = 0;
-		dependency.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
-		dependency.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
-
-		VkRenderPassCreateInfo render_pass_info = { 0 };
-		render_pass_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
-		render_pass_info.attachmentCount = 1;
-		render_pass_info.pAttachments = &color_attachment;
-		render_pass_info.subpassCount = 1;
-		render_pass_info.pSubpasses = &subpass;
-		render_pass_info.dependencyCount = 1;
-		render_pass_info.pDependencies = &dependency;
-
-		if (vkCreateRenderPass(RGFW_vulkan_info.device, &render_pass_info, NULL, &RGFW_vulkan_info.render_pass) != VK_SUCCESS) {
-			fprintf(stderr, "failed to create render pass\n");
-			return -1; // failed to create render pass!
-		}
-		return 0;
+		return (void*) eglGetProcAddress(procname); 
 	}
 
-	int RGFW_createCommandPool(void) {
-		VkCommandPoolCreateInfo pool_info = { 0 };
-		pool_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
-		pool_info.queueFamilyIndex = 0;
+	void RGFW_closeEGL(RGFW_window* win) {
+		eglDestroySurface(win->src.EGL_display, win->src.EGL_surface);
+		eglDestroyContext(win->src.EGL_display, win->src.EGL_context);
 
-		if (vkCreateCommandPool(RGFW_vulkan_info.device, &pool_info, NULL, &RGFW_vulkan_info.command_pool) != VK_SUCCESS) {
-			fprintf(stderr, "failed to create command pool\n");
-			return -1; // failed to create command pool
-		}
-		return 0;
+		eglTerminate(win->src.EGL_display);
 	}
 
-	int RGFW_createCommandBuffers(RGFW_window* win) {
+	void RGFW_window_swapInterval(RGFW_window* win, i32 swapInterval) {
 		assert(win != NULL);
+		
+		eglSwapInterval(win->src.EGL_display, swapInterval);
 
-		RGFW_vulkan_info.command_buffers = (VkCommandBuffer*) RGFW_MALLOC(sizeof(VkCommandBuffer) * win->src.image_count);
-
-		VkCommandBufferAllocateInfo allocInfo = { 0 };
-		allocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
-		allocInfo.commandPool = RGFW_vulkan_info.command_pool;
-		allocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
-		allocInfo.commandBufferCount = (u32) win->src.image_count;
-
-		if (vkAllocateCommandBuffers(RGFW_vulkan_info.device, &allocInfo, RGFW_vulkan_info.command_buffers) != VK_SUCCESS) {
-			return -1; // failed to allocate command buffers;
-		}
+		win->fpsCap = (swapInterval == 1) ? 0 : swapInterval;
 
-		return 0;
 	}
+#endif /* RGFW_EGL */
 
-	int RGFW_createSyncObjects(RGFW_window* win) {
-		assert(win != NULL);
-
-		RGFW_vulkan_info.available_semaphores = (VkSemaphore*) RGFW_MALLOC(sizeof(VkSemaphore) * RGFW_MAX_FRAMES_IN_FLIGHT);
-		RGFW_vulkan_info.finished_semaphore = (VkSemaphore*) RGFW_MALLOC(sizeof(VkSemaphore) * RGFW_MAX_FRAMES_IN_FLIGHT);
-		RGFW_vulkan_info.in_flight_fences = (VkFence*) RGFW_MALLOC(sizeof(VkFence) * RGFW_MAX_FRAMES_IN_FLIGHT);
-		RGFW_vulkan_info.image_in_flight = (VkFence*) RGFW_MALLOC(sizeof(VkFence) * win->src.image_count);
-
-		VkSemaphoreCreateInfo semaphore_info = { 0 };
-		semaphore_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
-
-		VkFenceCreateInfo fence_info = { 0 };
-		fence_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
-		fence_info.flags = VK_FENCE_CREATE_SIGNALED_BIT;
-
-		for (size_t i = 0; i < RGFW_MAX_FRAMES_IN_FLIGHT; i++) {
-			if (vkCreateSemaphore(RGFW_vulkan_info.device, &semaphore_info, NULL, &RGFW_vulkan_info.available_semaphores[i]) != VK_SUCCESS ||
-				vkCreateSemaphore(RGFW_vulkan_info.device, &semaphore_info, NULL, &RGFW_vulkan_info.finished_semaphore[i]) != VK_SUCCESS ||
-				vkCreateFence(RGFW_vulkan_info.device, &fence_info, NULL, &RGFW_vulkan_info.in_flight_fences[i]) != VK_SUCCESS) {
-				fprintf(stderr, "failed to create sync objects\n");
-				return -1; // failed to create synchronization objects for a frame
-			}
-		}
-
-		for (size_t i = 0; i < win->src.image_count; i++) {
-			RGFW_vulkan_info.image_in_flight[i] = VK_NULL_HANDLE;
-		}
-
-		return 0;
-	}
+/* 
+	end of RGFW_EGL defines
+*/
 
-	int RGFW_createFramebuffers(RGFW_window* win) {
-		assert(win != NULL);
+/* OPENGL Normal / EGL defines only (no OS MESA)  Ends here */
 
-		RGFW_vulkan_info.framebuffers = (VkFramebuffer*) RGFW_MALLOC(sizeof(VkFramebuffer) * win->src.image_count);
+#elif defined(RGFW_OSMESA) /* OSmesa only */
+RGFWDEF void RGFW_OSMesa_reorganize(void);
 
-		for (size_t i = 0; i < win->src.image_count; i++) {
-			VkImageView attachments[] = { win->src.swapchain_image_views[i] };
+/* reorganize buffer for osmesa */
+void RGFW_OSMesa_reorganize(void) {
+	u8* row = (u8*) RGFW_MALLOC(win->r.w * 3);
 
-			VkFramebufferCreateInfo framebuffer_info = { 0 };
-			framebuffer_info.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
-			framebuffer_info.renderPass = RGFW_vulkan_info.render_pass;
-			framebuffer_info.attachmentCount = 1;
-			framebuffer_info.pAttachments = attachments;
-			framebuffer_info.width = win->r.w;
-			framebuffer_info.height = win->r.h;
-			framebuffer_info.layers = 1;
+	i32 half_height = win->r.h / 2;
+	i32 stride = win->r.w * 3;
 
-			if (vkCreateFramebuffer(RGFW_vulkan_info.device, &framebuffer_info, NULL, &RGFW_vulkan_info.framebuffers[i]) != VK_SUCCESS) {
-				return -1; // failed to create framebuffer
-			}
-		}
-		return 0;
+	i32 y;
+	for (y = 0; y < half_height; ++y) {
+		i32 top_offset = y * stride;
+		i32 bottom_offset = (win->r.h - y - 1) * stride;
+		memcpy(row, win->buffer + top_offset, stride);
+		memcpy(win->buffer + top_offset, win->buffer + bottom_offset, stride);
+		memcpy(win->buffer + bottom_offset, row, stride);
 	}
 
-	void RGFW_freeVulkan(void) {
-		vkDeviceWaitIdle(RGFW_vulkan_info.device);
+	RGFW_FREE(row);
+}
+#endif /* RGFW_OSMesa */
 
-		for (size_t i = 0; i < RGFW_MAX_FRAMES_IN_FLIGHT; i++) {
-			vkDestroySemaphore(RGFW_vulkan_info.device, RGFW_vulkan_info.finished_semaphore[i], NULL);
-			vkDestroySemaphore(RGFW_vulkan_info.device, RGFW_vulkan_info.available_semaphores[i], NULL);
-			vkDestroyFence(RGFW_vulkan_info.device, RGFW_vulkan_info.in_flight_fences[i], NULL);
-		}
+#endif /* RGFW_GL (OpenGL, EGL, OSMesa )*/
 
-		vkDestroyCommandPool(RGFW_vulkan_info.device, RGFW_vulkan_info.command_pool, NULL);
+/*
+This is where OS specific stuff starts
+*/
 
-		vkDestroyPipeline(RGFW_vulkan_info.device, RGFW_vulkan_info.graphics_pipeline, NULL);
-		vkDestroyPipelineLayout(RGFW_vulkan_info.device, RGFW_vulkan_info.pipeline_layout, NULL);
-		vkDestroyRenderPass(RGFW_vulkan_info.device, RGFW_vulkan_info.render_pass, NULL);
 
-#ifdef RGFW_DEBUG
-		PFN_vkDestroyDebugUtilsMessengerEXT func = (PFN_vkDestroyDebugUtilsMessengerEXT) vkGetInstanceProcAddr(RGFW_vulkan_info.instance, "vkDestroyDebugUtilsMessengerEXT");
-		if (func != NULL) {
-			func(RGFW_vulkan_info.instance, RGFW_vulkan_info.debugMessenger, NULL);
-		}
-#endif
+/*
 
-		vkDestroyDevice(RGFW_vulkan_info.device, NULL);
-		vkDestroyInstance(RGFW_vulkan_info.instance, NULL);
 
-		RGFW_FREE(RGFW_vulkan_info.framebuffers);
-		RGFW_FREE(RGFW_vulkan_info.command_buffers);
-		RGFW_FREE(RGFW_vulkan_info.available_semaphores);
-		RGFW_FREE(RGFW_vulkan_info.finished_semaphore);
-		RGFW_FREE(RGFW_vulkan_info.in_flight_fences);
-		RGFW_FREE(RGFW_vulkan_info.image_in_flight);
-	}
+Start of Linux / Unix defines
 
-#endif /* RGFW_VULKAN */
 
-	RGFW_window* RGFW_root = NULL;
+*/
 
 #ifdef RGFW_X11
-#include <X11/Xlib.h>
 #ifndef RGFW_NO_X11_CURSOR
 #include <X11/Xcursor/Xcursor.h>
 #endif
@@ -2125,1908 +1927,1652 @@ RGFW_UNUSED(win); /* if buffer rendering is not being used */
 #include <X11/extensions/Xrandr.h>
 #include <X11/Xresource.h>
 #endif
-#endif
 
-#define RGFW_HOLD_MOUSE			(1L<<2) /*!< hold the moues still */
+#include <X11/Xutil.h>
+#include <X11/Xatom.h>
+#include <X11/keysymdef.h>
+#include <unistd.h>
 
-#ifdef RGFW_WINDOWS
-#include <processthreadsapi.h>
-#include <wchar.h>
-#include <locale.h>
-#include <windowsx.h>
-#include <shellapi.h>
-#include <shellscalingapi.h>
-#endif
-	
-	u8 RGFW_mouseButtons[5] = { 0 };
-	u8 RGFW_mouseButtons_prev[5];
+#include <X11/XKBlib.h> /* for converting keycode to string */
+#include <X11/cursorfont.h> /* for hiding */
+#include <X11/extensions/shapeconst.h>
+#include <X11/extensions/shape.h>
 
-	u8 RGFW_isMousePressed(RGFW_window* win, u8 button) {
-		if (win != NULL && !win->event.inFocus)
-			return 0;
+#include <limits.h> /* for data limits (mainly used in drag and drop functions) */
+#include <fcntl.h>
 
-		return RGFW_mouseButtons[button]; 
-	}
-	u8 RGFW_wasMousePressed(RGFW_window* win, u8 button) { 
-		if (win != NULL && !win->event.inFocus)
-			return 0;
+#ifdef __linux__
+#include <linux/joystick.h>
+#endif
 
-		return RGFW_mouseButtons_prev[button]; 
-	}
-	u8 RGFW_isMouseHeld(RGFW_window* win, u8 button) {
-		return (RGFW_isMousePressed(win, button) && RGFW_wasMousePressed(win, button));
-	}
-	u8 RGFW_isMouseReleased(RGFW_window* win, u8 button) {
-		return (!RGFW_isMousePressed(win, button) && RGFW_wasMousePressed(win, button));	
-	}
+	u8 RGFW_mouseIconSrc[] = { XC_arrow, XC_left_ptr, XC_xterm, XC_crosshair, XC_hand2, XC_sb_h_double_arrow, XC_sb_v_double_arrow, XC_bottom_left_corner, XC_bottom_right_corner, XC_fleur, XC_X_cursor};  
+	/*atoms needed for drag and drop*/
+	Atom XdndAware, XdndTypeList, XdndSelection, XdndEnter, XdndPosition, XdndStatus, XdndLeave, XdndDrop, XdndFinished, XdndActionCopy, XdndActionMove, XdndActionLink, XdndActionAsk, XdndActionPrivate;
 
-	u8 RGFW_isPressedI(RGFW_window* win, u32 key) {
-		RGFW_UNUSED(win);
-		
-		return RGFW_keyboard[key];
-	}
+	Atom wm_delete_window = 0;
 
-	u8 RGFW_wasPressedI(RGFW_window* win, u32 key) {
-		RGFW_UNUSED(win);
+#if !defined(RGFW_NO_X11_CURSOR) && !defined(RGFW_NO_X11_CURSOR_PRELOAD)
+	typedef XcursorImage* (*PFN_XcursorImageCreate)(int, int);
+	typedef void (*PFN_XcursorImageDestroy)(XcursorImage*);
+	typedef Cursor(*PFN_XcursorImageLoadCursor)(Display*, const XcursorImage*);
+#endif
+#ifdef RGFW_OPENGL
+	typedef GLXContext(*glXCreateContextAttribsARBProc)(Display*, GLXFBConfig, GLXContext, Bool, const int*);
+#endif
 
-		return RGFW_keyboard_prev[key];
-	}
+#if !defined(RGFW_NO_X11_CURSOR) && !defined(RGFW_NO_X11_CURSOR_PRELOAD)
+	PFN_XcursorImageLoadCursor XcursorImageLoadCursorSrc = NULL;
+	PFN_XcursorImageCreate XcursorImageCreateSrc = NULL;
+	PFN_XcursorImageDestroy XcursorImageDestroySrc = NULL;
 
-	u8 RGFW_isHeldI(RGFW_window* win, u32 key) {
-		return (RGFW_isPressedI(win, key) && RGFW_wasPressedI(win, key));
-	}
+#define XcursorImageLoadCursor XcursorImageLoadCursorSrc
+#define XcursorImageCreate XcursorImageCreateSrc
+#define XcursorImageDestroy XcursorImageDestroySrc
 
-	u8 RGFW_isReleasedI(RGFW_window* win, u32 key) {
-		return (!RGFW_isPressedI(win, key) && RGFW_wasPressedI(win, key));	
-	}
+	void* X11Cursorhandle = NULL;
+#endif
 
-	char* RGFW_keyCodeTokeyStr(u64 key) {
-		static char* keyStrs[128] = {"Escape", "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10", "F11", "F12", 	"Backtick", 	"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", 	"-", "=", "BackSpace", "Tab", "CapsLock", "ShiftL", "ControlL", "AltL", "SuperL", "ShiftR", "ControlR", "AltR", "SuperR", " ", 	"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", 	".", ",", "-", "[", "]", ";", "Return", "'", "\\", 	"Up", "Down", "Left", "Right", 	"Delete", "Insert", "End", "Home", "PageUp", "PageDown", 	"Numlock", "KP_Slash", "Multiply", "KP_Minus", "KP_1", "KP_2", "KP_3", "KP_4", "KP_5", "KP_6", "KP_7", "KP_8", "KP_9", "KP_0", "KP_Period", "KP_Return" };
+	u32 RGFW_windowsOpen = 0;
 
-		return keyStrs[key];
-	}
+#ifdef RGFW_OPENGL
+	void* RGFW_getProcAddress(const char* procname) { return (void*) glXGetProcAddress((GLubyte*) procname); }
+#endif
 
-	u32 RGFW_keyStrToKeyCode(char* key) {
-		static char* keyStrs[128] = {"Escape", "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10", "F11", "F12", 	"Backtick", 	"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", 	"-", "=", "BackSpace", "Tab", "CapsLock", "ShiftL", "ControlL", "AltL", "SuperL", "ShiftR", "ControlR", "AltR", "SuperR", " ", 	"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", 	".", ",", "-", "[", "]", ";", "Return", "'", "\\", 	"Up", "Down", "Left", "Right", 	"Delete", "Insert", "End", "Home", "PageUp", "PageDown", 	"Numlock", "KP_Slash", "Multiply", "KP_Minus", "KP_1", "KP_2", "KP_3", "KP_4", "KP_5", "KP_6", "KP_7", "KP_8", "KP_9", "KP_0", "KP_Period", "KP_Return" };
+	RGFWDEF void RGFW_init_buffer(RGFW_window* win, XVisualInfo* vi);
+	void RGFW_init_buffer(RGFW_window* win, XVisualInfo* vi) {
+#if defined(RGFW_OSMESA) || defined(RGFW_BUFFER)
+		if (RGFW_bufferSize.w == 0 && RGFW_bufferSize.h == 0)
+			RGFW_bufferSize = RGFW_getScreenSize();
 		
-		key--;
-		while (key++) {
-			u32 i;
-			for (i = 0; i < 128; i++) {
-				if (*keyStrs[i] == '\1')
-					continue;
+		win->buffer = RGFW_MALLOC(RGFW_bufferSize.w * RGFW_bufferSize.h * 4);
 
-				if (*keyStrs[i] != *key) {
-					keyStrs[i] = "\1";
-					continue;
-				}
+		#ifdef RGFW_OSMESA
+				win->src.rSurf = OSMesaCreateContext(OSMESA_RGBA, NULL);
+				OSMesaMakeCurrent(win->src.rSurf, win->buffer, GL_UNSIGNED_BYTE, win->r.w, win->r.h);
+		#endif
 
-				if (*keyStrs[i] == '\0' && *key == '\0')
-					return RGFW_apiKeyCodeToRGFW(i);
+		win->src.bitmap = XCreateImage(
+			win->src.display, vi->visual,
+			vi->depth,
+			ZPixmap, 0, NULL, RGFW_bufferSize.w, RGFW_bufferSize.h,
+			32, 0
+		);
 
-				else
-					keyStrs[i]++;
-			}
+		win->src.gc = XCreateGC(win->src.display, win->src.window, 0, NULL);
 
-			if (*key == '\0')
-				break;
-		}
-		
-		return 0;
+		#else
+		RGFW_UNUSED(win); /* if buffer rendering is not being used */
+		RGFW_UNUSED(vi)
+		#endif
 	}
 
 
-	char RGFW_keystrToChar(const char* str) {
-		if (str[1] == 0)
-			return str[0];
-
-		static const char* map[] = {
-			"asciitilde", "`",
-			"grave", "~",
-			"exclam", "!",
-			"at", "@",
-			"numbersign", "#",
-			"dollar", "$",
-			"percent", "%%",
-			"asciicircum", "^",
-			"ampersand", "&",
-			"asterisk", "*",
-			"parenleft", "(",
-			"parenright", ")",
-			"underscore", "_",
-			"minus", "-",
-			"plus", "+",
-			"equal", "=",
-			"braceleft", "{",
-			"bracketleft", "[",
-			"bracketright", "]",
-			"braceright", "}",
-			"colon", ":",
-			"semicolon", ";",
-			"quotedbl", "\"",
-			"apostrophe", "'",
-			"bar", "|",
-			"backslash", "\'",
-			"less", "<",
-			"comma", ",",
-			"greater", ">",
-			"period", ".",
-			"question", "?",
-			"slash", "/",
-			"space", " ",
-			"Return", "\n",
-			"Enter", "\n",
-			"enter", "\n",
-		};
-
-		u8 i = 0;
-		for (i = 0; i < (sizeof(map) / sizeof(char*)); i += 2)
-			if (strcmp(map[i], str) == 0)
-				return *map[i + 1];
 
-		return '\0';
+	void RGFW_window_setBorder(RGFW_window* win, u8 border) {
+		static Atom _MOTIF_WM_HINTS = 0;
+		if (_MOTIF_WM_HINTS == 0 )
+			_MOTIF_WM_HINTS = XInternAtom(win->src.display, "_MOTIF_WM_HINTS", False);
+		
+		struct __x11WindowHints {
+			unsigned long flags, functions, decorations, status;
+			long input_mode;
+		} hints;
+		hints.flags = (1L << 1);
+		hints.decorations = !border;
+
+		XChangeProperty(
+			win->src.display, win->src.window,
+			_MOTIF_WM_HINTS, _MOTIF_WM_HINTS,
+			32, PropModeReplace, (u8*)&hints, 5
+		);
 	}
 
-#ifndef M_PI
-#define M_PI		3.14159265358979323846	/* pi */
-#endif
-
-#ifndef RGFW_WINDOWS
-	struct timespec;
-
-	int nanosleep(const struct timespec* duration, struct timespec* rem);
-	int clock_gettime(clockid_t clk_id, struct timespec* tp);
-	int setenv(const char *name, const char *value, int overwrite);
-
-	u32 RGFW_isPressedJS(RGFW_window* win, u16 c, u8 button) { return win->src.jsPressed[c][button]; }
-#else
-
-	typedef u64 (WINAPI * PFN_XInputGetState)(DWORD,XINPUT_STATE*);
-	PFN_XInputGetState XInputGetStateSRC = NULL;
-	#define XInputGetState XInputGetStateSRC
-	static HMODULE RGFW_XInput_dll = NULL;
-	
-	u32 RGFW_isPressedJS(RGFW_window* win, u16 c, u8 button) {
-		RGFW_UNUSED(win)
-		
-		XINPUT_STATE state;
-		if (XInputGetState == NULL || XInputGetState(c, &state) == ERROR_DEVICE_NOT_CONNECTED)
-			return 0;
-
-		if (button == RGFW_JS_A) return state.Gamepad.wButtons & XINPUT_GAMEPAD_A;
-		else if (button == RGFW_JS_B) return state.Gamepad.wButtons & XINPUT_GAMEPAD_B;
-		else if (button == RGFW_JS_Y) return state.Gamepad.wButtons & XINPUT_GAMEPAD_Y;
-		else if (button == RGFW_JS_X) return state.Gamepad.wButtons & XINPUT_GAMEPAD_X;
-		else if (button == RGFW_JS_START) return state.Gamepad.wButtons & XINPUT_GAMEPAD_START;
-		else if (button == RGFW_JS_SELECT) return state.Gamepad.wButtons & XINPUT_GAMEPAD_BACK;
-		else if (button == RGFW_JS_UP) return state.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_UP;
-		else if (button == RGFW_JS_DOWN) return state.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_DOWN;
-		else if (button == RGFW_JS_LEFT) return state.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_LEFT;
-		else if (button == RGFW_JS_RIGHT) return state.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_RIGHT;
-		else if (button == RGFW_JS_L1) return state.Gamepad.wButtons & XINPUT_GAMEPAD_LEFT_SHOULDER;
-		else if (button == RGFW_JS_R1) return state.Gamepad.wButtons & XINPUT_GAMEPAD_RIGHT_SHOULDER;
-		else if (button == RGFW_JS_L2 && state.Gamepad.bLeftTrigger) return 1;
-		else if (button == RGFW_JS_R2 && state.Gamepad.bRightTrigger) return 1;
+	RGFW_window* RGFW_createWindow(const char* name, RGFW_rect rect, u16 args) {
+#if !defined(RGFW_NO_X11_CURSOR) && !defined(RGFW_NO_X11_CURSOR_PRELOAD)
+		if (X11Cursorhandle == NULL) {
+#if defined(__CYGWIN__)
+			X11Cursorhandle = dlopen("libXcursor-1.so", RTLD_LAZY | RTLD_LOCAL);
+#elif defined(__OpenBSD__) || defined(__NetBSD__)
+			X11Cursorhandle = dlopen("libXcursor.so", RTLD_LAZY | RTLD_LOCAL);
+#else
+			X11Cursorhandle = dlopen("libXcursor.so.1", RTLD_LAZY | RTLD_LOCAL);
+#endif
 
-		return 0;
-	}
+			XcursorImageCreateSrc = (PFN_XcursorImageCreate) dlsym(X11Cursorhandle, "XcursorImageCreate");
+			XcursorImageDestroySrc = (PFN_XcursorImageDestroy) dlsym(X11Cursorhandle, "XcursorImageDestroy");
+			XcursorImageLoadCursorSrc = (PFN_XcursorImageLoadCursor) dlsym(X11Cursorhandle, "XcursorImageLoadCursor");
+		}
 #endif
 
-#if defined(RGFW_OPENGL) || defined(RGFW_EGL)
-	i32 RGFW_majorVersion = 0, RGFW_minorVersion = 0;
-	
-	#ifndef RGFW_EGL
-	i32 RGFW_STENCIL = 8, RGFW_SAMPLES = 4, RGFW_STEREO = GL_FALSE, RGFW_AUX_BUFFERS = 0;
-	#else
-	i32 RGFW_STENCIL = 0, RGFW_SAMPLES = 0, RGFW_STEREO = GL_FALSE, RGFW_AUX_BUFFERS = 0;
-	#endif
+		XInitThreads(); /* init X11 threading*/
 
+		if (args & RGFW_OPENGL_SOFTWARE)
+			setenv("LIBGL_ALWAYS_SOFTWARE", "1", 1);
 
-	void RGFW_setGLStencil(i32 stencil) { RGFW_STENCIL = stencil; }
-	void RGFW_setGLSamples(i32 samples) { RGFW_SAMPLES = samples; }
-	void RGFW_setGLStereo(i32 stereo) { RGFW_STEREO = stereo; }
-	void RGFW_setGLAuxBuffers(i32 auxBuffers) { RGFW_AUX_BUFFERS = auxBuffers; }
+		RGFW_window* win = RGFW_window_basic_init(rect, args);
 
-	void RGFW_setGLVersion(i32 major, i32 minor) {
-		RGFW_majorVersion = major;
-		RGFW_minorVersion = minor;
-	}
+		u64 event_mask = KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | PointerMotionMask | StructureNotifyMask | FocusChangeMask | LeaveWindowMask | EnterWindowMask | ExposureMask; /* X11 events accepted*/
 
-	u8* RGFW_getMaxGLVersion(void) {
-		RGFW_window* dummy = RGFW_createWindow("dummy", RGFW_RECT(0, 0, 1, 1), 0);
+#ifdef RGFW_OPENGL
+		u32* visual_attribs = RGFW_initAttribs(args & RGFW_OPENGL_SOFTWARE);
+		i32 fbcount;
+		GLXFBConfig* fbc = glXChooseFBConfig((Display*) win->src.display, DefaultScreen(win->src.display), (i32*) visual_attribs, &fbcount);
 
-		const char* versionStr = (const char*) glGetString(GL_VERSION);
+		i32 best_fbc = -1;
 
-		static u8 version[2];
-		version[0] = versionStr[0] - '0',
-			version[1] = versionStr[2] - '0';
+		if (fbcount == 0) {
+			printf("Failed to find any valid GLX configs\n");
+			return NULL;
+		}
 
-		RGFW_window_close(dummy);
+		u32 i;
+		for (i = 0; i < (u32)fbcount; i++) {
+			XVisualInfo* vi = glXGetVisualFromFBConfig((Display*) win->src.display, fbc[i]);
+			if (vi == NULL)
+				continue;
 
-		return version;
-	}
+			XFree(vi);
 
-#ifndef RGFW_EGL
+			i32 samp_buf, samples;
+			glXGetFBConfigAttrib((Display*) win->src.display, fbc[i], GLX_SAMPLE_BUFFERS, &samp_buf);
+			glXGetFBConfigAttrib((Display*) win->src.display, fbc[i], GLX_SAMPLES, &samples);
+			if ((best_fbc < 0 || samp_buf) && (samples == RGFW_SAMPLES || best_fbc == -1)) {
+				best_fbc = i;
+			}
+		}
 
-#define RGFW_GL_RENDER_TYPE 		RGFW_OS_BASED_VALUE(GLX_X_VISUAL_TYPE,    	0x2003,		73)
-#define RGFW_GL_ALPHA_SIZE 		RGFW_OS_BASED_VALUE(GLX_ALPHA_SIZE,       	0x201b,		11)
-#define RGFW_GL_DEPTH_SIZE 		RGFW_OS_BASED_VALUE(GLX_DEPTH_SIZE,       	0x2022,		12)
-#define RGFW_GL_DOUBLEBUFFER 		RGFW_OS_BASED_VALUE(GLX_DOUBLEBUFFER,     	0x2011, 	5)   
-#define RGFW_GL_STENCIL_SIZE 		RGFW_OS_BASED_VALUE(GLX_STENCIL_SIZE,	 	0x2023,	13)
-#define RGFW_GL_SAMPLES			RGFW_OS_BASED_VALUE(GLX_SAMPLES, 		 	0x2042,	    55)
-#define RGFW_GL_STEREO 			RGFW_OS_BASED_VALUE(GLX_STEREO,	 		 	0x2012,			6)
-#define RGFW_GL_AUX_BUFFERS		RGFW_OS_BASED_VALUE(GLX_AUX_BUFFERS,	    0x2024,	7)
+		if (best_fbc == -1) {
+			printf("Failed to get a valid GLX visual\n");
+			return NULL;
+		}
 
-#if defined(RGFW_X11) || defined(RGFW_WINDOWS)
-#define RGFW_GL_DRAW 			RGFW_OS_BASED_VALUE(GLX_X_RENDERABLE,	 	0x2001,					0)
-#define RGFW_GL_DRAW_TYPE 		RGFW_OS_BASED_VALUE(GLX_RENDER_TYPE,     	0x2013,						0)
-#define RGFW_GL_USE_OPENGL		RGFW_OS_BASED_VALUE(GLX_USE_GL,				0x2010,						0)
-#define RGFW_GL_FULL_FORMAT		RGFW_OS_BASED_VALUE(GLX_TRUE_COLOR,   	 	0x2027,						0)
-#define RGFW_GL_RED_SIZE		RGFW_OS_BASED_VALUE(GLX_RED_SIZE,         	0x2015,						0)
-#define RGFW_GL_GREEN_SIZE		RGFW_OS_BASED_VALUE(GLX_GREEN_SIZE,       	0x2017,						0)
-#define RGFW_GL_BLUE_SIZE		RGFW_OS_BASED_VALUE(GLX_BLUE_SIZE, 	 		0x2019,						0)
-#define RGFW_GL_USE_RGBA		RGFW_OS_BASED_VALUE(GLX_RGBA_BIT,   	 	0x202B,						0)
-#endif
+		GLXFBConfig bestFbc = fbc[best_fbc];
 
-#ifdef RGFW_WINDOWS
-#define WGL_COLOR_BITS_ARB                        0x2014
-#define WGL_NUMBER_PIXEL_FORMATS_ARB 			0x2000
-#define WGL_CONTEXT_MAJOR_VERSION_ARB             0x2091
-#define WGL_CONTEXT_MINOR_VERSION_ARB             0x2092
-#define WGL_CONTEXT_PROFILE_MASK_ARB              0x9126
-#define WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002
-#define WGL_SAMPLE_BUFFERS_ARB               0x2041
-#define WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB 0x20a9
-#endif
+		/* Get a visual */
+		XVisualInfo* vi = glXGetVisualFromFBConfig((Display*) win->src.display, bestFbc);
 
-	static u32* RGFW_initAttribs(u32 useSoftware) {
-		RGFW_UNUSED(useSoftware);
-		static u32 attribs[] = {
-								#ifndef RGFW_MACOS
-								RGFW_GL_RENDER_TYPE,
-								RGFW_GL_FULL_FORMAT,
-								#endif
-								RGFW_GL_ALPHA_SIZE      , 8,
-								RGFW_GL_DEPTH_SIZE      , 24,
-								RGFW_GL_DOUBLEBUFFER    ,
-								#ifndef RGFW_MACOS
-								1,
-								#endif
+		XFree(fbc);
 
-								#if defined(RGFW_X11) || defined(RGFW_WINDOWS)
-								RGFW_GL_USE_OPENGL,		1,
-								RGFW_GL_DRAW, 1,
-								RGFW_GL_RED_SIZE        , 8,
-								RGFW_GL_GREEN_SIZE      , 8,
-								RGFW_GL_BLUE_SIZE       , 8,
-								RGFW_GL_DRAW_TYPE     , RGFW_GL_USE_RGBA,
-								#endif 
+		if (args & RGFW_TRANSPARENT_WINDOW) {
+			XMatchVisualInfo((Display*) win->src.display, DefaultScreen((Display*) win->src.display), 32, TrueColor, vi); /* for RGBA backgrounds*/
+		}
+#else
+		XVisualInfo viNorm;
 
-								#ifdef RGFW_X11
-								GLX_DRAWABLE_TYPE   , GLX_WINDOW_BIT,
-								#endif
+		viNorm.visual = DefaultVisual((Display*) win->src.display, DefaultScreen((Display*) win->src.display));
+		
+		viNorm.depth = 0;
+		XVisualInfo* vi = &viNorm;
+		
+		XMatchVisualInfo((Display*) win->src.display, DefaultScreen((Display*) win->src.display), 32, TrueColor, vi); /* for RGBA backgrounds*/
+#endif
+		/* make X window attrubutes*/
+		XSetWindowAttributes swa;
+		Colormap cmap;
 
-								#ifdef RGFW_MACOS
-								72,
-								8, 24,
-								#endif
+		swa.colormap = cmap = XCreateColormap((Display*) win->src.display,
+			DefaultRootWindow(win->src.display),
+			vi->visual, AllocNone);
 
-								#ifdef RGFW_WINDOWS
-								WGL_COLOR_BITS_ARB,	 32,
-								#endif
+		swa.background_pixmap = None;
+		swa.border_pixel = 0;
+		swa.event_mask = event_mask;
+		
+		swa.background_pixel = 0;
 
-								0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-		};
+		/* create the window*/
+		win->src.window = XCreateWindow((Display*) win->src.display, DefaultRootWindow((Display*) win->src.display), win->r.x, win->r.y, win->r.w, win->r.h,
+			0, vi->depth, InputOutput, vi->visual,
+			CWColormap | CWBorderPixel | CWBackPixel | CWEventMask, &swa);
 
-		size_t index = (sizeof(attribs) / sizeof(attribs[0])) - 13;
+		XFreeColors((Display*) win->src.display, cmap, NULL, 0, 0);
 
-#define RGFW_GL_ADD_ATTRIB(attrib, attVal) \
-		if (attVal) { \
-			attribs[index] = attrib;\
-			attribs[index + 1] = attVal;\
-			index += 2;\
+		#ifdef RGFW_OPENGL
+		XFree(vi);
+		#endif
+
+		// In your .desktop app, if you set the property
+		// StartupWMClass=RGFW that will assoicate the launcher icon
+		// with your application - robrohan 
+		XClassHint *hint = XAllocClassHint();
+		assert(hint != NULL);
+		hint->res_class = "RGFW";
+		hint->res_name = (char*)name; // just use the window name as the app name
+		XSetClassHint((Display*) win->src.display, win->src.window, hint);
+		XFree(hint);
+
+		if ((args & RGFW_NO_INIT_API) == 0) {
+#ifdef RGFW_OPENGL
+		i32 context_attribs[7] = { 0, 0, 0, 0, 0, 0, 0 };
+		context_attribs[0] = GLX_CONTEXT_PROFILE_MASK_ARB;
+		context_attribs[1] = GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB;
+		
+		if (RGFW_majorVersion || RGFW_minorVersion) {
+			context_attribs[2] = GLX_CONTEXT_MAJOR_VERSION_ARB;
+			context_attribs[3] = RGFW_majorVersion;
+			context_attribs[4] = GLX_CONTEXT_MINOR_VERSION_ARB;
+			context_attribs[5] = RGFW_minorVersion;
 		}
 
-		RGFW_GL_ADD_ATTRIB(RGFW_GL_STENCIL_SIZE, RGFW_STENCIL);
-		RGFW_GL_ADD_ATTRIB(RGFW_GL_STEREO, RGFW_STEREO);
-		RGFW_GL_ADD_ATTRIB(RGFW_GL_AUX_BUFFERS, RGFW_AUX_BUFFERS);
+		glXCreateContextAttribsARBProc glXCreateContextAttribsARB = 0;
+		glXCreateContextAttribsARB = (glXCreateContextAttribsARBProc)
+			glXGetProcAddressARB((GLubyte*) "glXCreateContextAttribsARB");
 
-#ifndef RGFW_X11
-		RGFW_GL_ADD_ATTRIB(RGFW_GL_SAMPLES, RGFW_SAMPLES);
-#endif 
+		GLXContext ctx = NULL;
 
-#ifdef RGFW_MACOS
-		if (useSoftware) {
-			RGFW_GL_ADD_ATTRIB(70, kCGLRendererGenericFloatID);
-		} else {
-			attribs[index] = RGFW_GL_RENDER_TYPE;
-			index += 1;
-		}
+		if (RGFW_root != NULL)
+			ctx = RGFW_root->src.rSurf;
+
+		win->src.rSurf = glXCreateContextAttribsARB((Display*) win->src.display, bestFbc, ctx, True, context_attribs);
 #endif
+		if (RGFW_root == NULL)
+			RGFW_root = win;
 
-#ifdef RGFW_MACOS
-		attribs[index] = 99;
-		attribs[index + 1] = 0x1000;
+		RGFW_init_buffer(win, vi);
+		}
+		
 
-		if (RGFW_majorVersion >= 4 || RGFW_majorVersion >= 3) {
-			attribs[index + 1] = (u32) ((RGFW_majorVersion >= 4) ? 0x4100 : 0x3200);
+		#ifndef RGFW_NO_MONITOR
+		if (args & RGFW_SCALE_TO_MONITOR)
+			RGFW_window_scaleToMonitor(win);
+		#endif
+
+		if (args & RGFW_NO_RESIZE) { /* make it so the user can't resize the window*/
+			XSizeHints* sh = XAllocSizeHints();
+			sh->flags = (1L << 4) | (1L << 5);
+			sh->min_width = sh->max_width = win->r.w;
+			sh->min_height = sh->max_height = win->r.h;
+
+			XSetWMSizeHints((Display*) win->src.display, (Drawable) win->src.window, sh, XA_WM_NORMAL_HINTS);
+			XFree(sh);
 		}
 
-#endif
+		if (args & RGFW_NO_BORDER) {
+			RGFW_window_setBorder(win, 0);
+		}
 
-		RGFW_GL_ADD_ATTRIB(0, 0);
+		XSelectInput((Display*) win->src.display, (Drawable) win->src.window, event_mask); /* tell X11 what events we want*/
 
-		return attribs;
-	}
+		/* make it so the user can't close the window until the program does*/
+		if (wm_delete_window == 0)
+			wm_delete_window = XInternAtom((Display*) win->src.display, "WM_DELETE_WINDOW", False);
 
-#else
+		XSetWMProtocols((Display*) win->src.display, (Drawable) win->src.window, &wm_delete_window, 1);
 
-#include <EGL/egl.h>
+		/* connect the context to the window*/
+#ifdef RGFW_OPENGL
+		if ((args & RGFW_NO_INIT_API) == 0)
+			glXMakeCurrent((Display*) win->src.display, (Drawable) win->src.window, (GLXContext) win->src.rSurf);
+#endif
 
-#if defined(RGFW_LINK_EGL)
-	typedef EGLBoolean(EGLAPIENTRY* PFN_eglInitialize)(EGLDisplay, EGLint*, EGLint*);
+		/* set the background*/
+		XStoreName((Display*) win->src.display, (Drawable) win->src.window, name); /* set the name*/
 
-	PFNEGLINITIALIZEPROC eglInitializeSource;
-	PFNEGLGETCONFIGSPROC eglGetConfigsSource;
-	PFNEGLCHOOSECONFIGPROC eglChooseConfigSource;
-	PFNEGLCREATEWINDOWSURFACEPROC eglCreateWindowSurfaceSource;
-	PFNEGLCREATECONTEXTPROC eglCreateContextSource;
-	PFNEGLMAKECURRENTPROC eglMakeCurrentSource;
-	PFNEGLGETDISPLAYPROC eglGetDisplaySource;
-	PFNEGLSWAPBUFFERSPROC eglSwapBuffersSource;
-	PFNEGLSWAPINTERVALPROC eglSwapIntervalSource;
-	PFNEGLBINDAPIPROC eglBindAPISource;
-	PFNEGLDESTROYCONTEXTPROC eglDestroyContextSource;
-	PFNEGLTERMINATEPROC eglTerminateSource;
-	PFNEGLDESTROYSURFACEPROC eglDestroySurfaceSource;
-
-#define eglInitialize eglInitializeSource
-#define eglGetConfigs eglGetConfigsSource
-#define eglChooseConfig eglChooseConfigSource
-#define eglCreateWindowSurface eglCreateWindowSurfaceSource
-#define eglCreateContext eglCreateContextSource
-#define eglMakeCurrent eglMakeCurrentSource
-#define eglGetDisplay eglGetDisplaySource
-#define eglSwapBuffers eglSwapBuffersSource
-#define eglSwapInterval eglSwapIntervalSource
-#define eglBindAPI eglBindAPISource
-#define eglDestroyContext eglDestroyContextSource
-#define eglTerminate eglTerminateSource
-#define eglDestroySurface eglDestroySurfaceSource;
-#endif
+		XMapWindow((Display*) win->src.display, (Drawable) win->src.window);						  /* draw the window*/
+		XMoveWindow((Display*) win->src.display, (Drawable) win->src.window, win->r.x, win->r.y); /* move the window to it's proper cords*/
 
+		if (args & RGFW_ALLOW_DND) { /* init drag and drop atoms and turn on drag and drop for this window */
+			win->src.winArgs |= RGFW_ALLOW_DND;
 
-#define EGL_SURFACE_MAJOR_VERSION_KHR 0x3098
-#define EGL_SURFACE_MINOR_VERSION_KHR 0x30fb
+			XdndAware = XInternAtom((Display*) win->src.display, "XdndAware", False);
+			XdndTypeList = XInternAtom((Display*) win->src.display, "XdndTypeList", False);
+			XdndSelection = XInternAtom((Display*) win->src.display, "XdndSelection", False);
 
-#ifndef RGFW_GL_ADD_ATTRIB
-#define RGFW_GL_ADD_ATTRIB(attrib, attVal) \
-	if (attVal) { \
-		attribs[index] = attrib;\
-		attribs[index + 1] = attVal;\
-		index += 2;\
-	}
-#endif
+			/* client messages */
+			XdndEnter = XInternAtom((Display*) win->src.display, "XdndEnter", False);
+			XdndPosition = XInternAtom((Display*) win->src.display, "XdndPosition", False);
+			XdndStatus = XInternAtom((Display*) win->src.display, "XdndStatus", False);
+			XdndLeave = XInternAtom((Display*) win->src.display, "XdndLeave", False);
+			XdndDrop = XInternAtom((Display*) win->src.display, "XdndDrop", False);
+			XdndFinished = XInternAtom((Display*) win->src.display, "XdndFinished", False);
 
+			/* actions */
+			XdndActionCopy = XInternAtom((Display*) win->src.display, "XdndActionCopy", False);
+			XdndActionMove = XInternAtom((Display*) win->src.display, "XdndActionMove", False);
+			XdndActionLink = XInternAtom((Display*) win->src.display, "XdndActionLink", False);
+			XdndActionAsk = XInternAtom((Display*) win->src.display, "XdndActionAsk", False);
+			XdndActionPrivate = XInternAtom((Display*) win->src.display, "XdndActionPrivate", False);
+			const Atom version = 5;
 
-	void RGFW_createOpenGLContext(RGFW_window* win) {
-#if defined(RGFW_LINK_EGL)
-		eglInitializeSource = (PFNEGLINITIALIZEPROC) eglGetProcAddress("eglInitialize");
-		eglGetConfigsSource = (PFNEGLGETCONFIGSPROC) eglGetProcAddress("eglGetConfigs");
-		eglChooseConfigSource = (PFNEGLCHOOSECONFIGPROC) eglGetProcAddress("eglChooseConfig");
-		eglCreateWindowSurfaceSource = (PFNEGLCREATEWINDOWSURFACEPROC) eglGetProcAddress("eglCreateWindowSurface");
-		eglCreateContextSource = (PFNEGLCREATECONTEXTPROC) eglGetProcAddress("eglCreateContext");
-		eglMakeCurrentSource = (PFNEGLMAKECURRENTPROC) eglGetProcAddress("eglMakeCurrent");
-		eglGetDisplaySource = (PFNEGLGETDISPLAYPROC) eglGetProcAddress("eglGetDisplay");
-		eglSwapBuffersSource = (PFNEGLSWAPBUFFERSPROC) eglGetProcAddress("eglSwapBuffers");
-		eglSwapIntervalSource = (PFNEGLSWAPINTERVALPROC) eglGetProcAddress("eglSwapInterval");
-		eglBindAPISource = (PFNEGLBINDAPIPROC) eglGetProcAddress("eglBindAPI");
-		eglDestroyContextSource = (PFNEGLDESTROYCONTEXTPROC) eglGetProcAddress("eglDestroyContext");
-		eglTerminateSource = (PFNEGLTERMINATEPROC) eglGetProcAddress("eglTerminate");
-		eglDestroySurfaceSource = (PFNEGLDESTROYSURFACEPROC) eglGetProcAddress("eglDestroySurface");
-#endif /* RGFW_LINK_EGL */
+			XChangeProperty((Display*) win->src.display, (Window) win->src.window,
+				XdndAware, 4, 32,
+				PropModeReplace, (u8*) &version, 1); /* turns on drag and drop */
+		}
 
-		#ifdef RGFW_WINDOWS
-		win->src.EGL_display = eglGetDisplay((EGLNativeDisplayType) win->src.hdc);
-		#else
-		win->src.EGL_display = eglGetDisplay((EGLNativeDisplayType) win->src.display);
+		#ifdef RGFW_EGL
+			if ((args & RGFW_NO_INIT_API) == 0)
+				RGFW_createOpenGLContext(win);
 		#endif
 
-		EGLint major, minor;
-
-		eglInitialize(win->src.EGL_display, &major, &minor);
+		RGFW_window_setMouseDefault(win);
 
-		#ifndef EGL_OPENGL_ES1_BIT
-		#define EGL_OPENGL_ES1_BIT 0x1
-		#endif
+		RGFW_windowsOpen++;
 
-		EGLint egl_config[] = {
-			EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
-			EGL_RENDERABLE_TYPE,
-			#ifdef RGFW_OPENGL_ES1
-			EGL_OPENGL_ES1_BIT,
-			#elif defined(RGFW_OPENGL_ES3)
-			EGL_OPENGL_ES3_BIT,
-			#elif defined(RGFW_OPENGL_ES2)
-			EGL_OPENGL_ES2_BIT,
-			#else
-			EGL_OPENGL_BIT,
-			#endif
-			EGL_NONE, EGL_NONE
-		};
+		return win; /*return newly created window*/
+	}
 
-		EGLConfig config;
-		EGLint numConfigs;
-		eglChooseConfig(win->src.EGL_display, egl_config, &config, 1, &numConfigs);
+	RGFW_area RGFW_getScreenSize(void) {
+		assert(RGFW_root != NULL);
 
+		Screen* scrn = DefaultScreenOfDisplay((Display*) RGFW_root->src.display);
+		return RGFW_AREA(scrn->width, scrn->height);
+	}
 
-		win->src.EGL_surface = eglCreateWindowSurface(win->src.EGL_display, config, (EGLNativeWindowType) win->src.window, NULL);
+	RGFW_vector RGFW_getGlobalMousePoint(void) {
+		assert(RGFW_root != NULL);
 
-		EGLint attribs[] = {
-			EGL_CONTEXT_CLIENT_VERSION,
-			#ifdef RGFW_OPENGL_ES1
-			1,
-			#else
-			2,
-			#endif
-			EGL_NONE, EGL_NONE, EGL_NONE, EGL_NONE, EGL_NONE, EGL_NONE
-		};
+		RGFW_vector RGFWMouse;
 
-		size_t index = 4;
-		RGFW_GL_ADD_ATTRIB(EGL_STENCIL_SIZE, RGFW_STENCIL);
-		RGFW_GL_ADD_ATTRIB(EGL_SAMPLES, RGFW_SAMPLES);
+		i32 x, y;
+		u32 z;
+		Window window1, window2;
+		XQueryPointer((Display*) RGFW_root->src.display, XDefaultRootWindow((Display*) RGFW_root->src.display), &window1, &window2, &RGFWMouse.x, &RGFWMouse.y, &x, &y, &z);
+ 
+		return RGFWMouse;
+	}
 
-		if (RGFW_majorVersion) {
-			attribs[1] = RGFW_majorVersion;
-			RGFW_GL_ADD_ATTRIB(EGL_CONTEXT_OPENGL_PROFILE_MASK, EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT);
-			RGFW_GL_ADD_ATTRIB(EGL_CONTEXT_MAJOR_VERSION, RGFW_majorVersion);
-			RGFW_GL_ADD_ATTRIB(EGL_CONTEXT_MINOR_VERSION, RGFW_minorVersion);
-		}
+	RGFW_vector RGFW_window_getMousePoint(RGFW_window* win) {
+		assert(win != NULL);
 
-		#if defined(RGFW_OPENGL_ES1) || defined(RGFW_OPENGL_ES2) || defined(RGFW_OPENGL_ES3)
-		eglBindAPI(EGL_OPENGL_ES_API);
-		#else
-		eglBindAPI(EGL_OPENGL_API);		
-		#endif
+		RGFW_vector RGFWMouse;
 
-      	win->src.EGL_context = eglCreateContext(win->src.EGL_display, config, EGL_NO_CONTEXT, attribs);
+		i32 x, y;
+		u32 z;
+		Window window1, window2;
+		XQueryPointer((Display*) win->src.display, win->src.window, &window1, &window2, &x, &y, &RGFWMouse.x, &RGFWMouse.y, &z);
 
-		eglMakeCurrent(win->src.EGL_display, win->src.EGL_surface, win->src.EGL_surface, win->src.EGL_context);
-		eglSwapBuffers(win->src.EGL_display, win->src.EGL_surface);
+		return RGFWMouse;
 	}
 
-	#ifdef RGFW_APPLE
-	void* RGFWnsglFramework = NULL;
-	#elif defined(RGFW_WINDOWS)
-	static HMODULE wglinstance = NULL;
-	#endif
-
-	void* RGFW_getProcAddress(const char* procname) { 
-		#if defined(RGFW_WINDOWS)
-			void* proc = (void*) GetProcAddress(wglinstance, procname); 
+	typedef struct XDND {
+		long source, version;
+		i32 format;
+	} XDND; /* data structure for xdnd events */
+	XDND xdnd;
 
-			if (proc)
-				return proc;
-		#endif
+	int xAxis = 0, yAxis = 0;
 
-		return (void*) eglGetProcAddress(procname); 
-	}
+	RGFW_Event* RGFW_window_checkEvent(RGFW_window* win) {
+		assert(win != NULL);
 
-	void RGFW_closeEGL(RGFW_window* win) {
-		eglDestroySurface(win->src.EGL_display, win->src.EGL_surface);
-		eglDestroyContext(win->src.EGL_display, win->src.EGL_context);
+		if (win->event.type == 0) 
+			RGFW_resetKey();
 
-		eglTerminate(win->src.EGL_display);
-	}
+		if (win->event.type == RGFW_quit) {
+			return NULL;
+		}
 
-#endif /* RGFW_EGL */
-#endif /* RGFW_GL stuff? */
+		win->event.type = 0;
 
-	/*
-	This is where OS specific stuff starts
-	*/
+#ifdef __linux__
+		{
+			u8 i;
+			for (i = 0; i < win->src.joystickCount; i++) {
+				struct js_event e;
 
-#ifdef RGFW_X11
-#include <X11/Xutil.h>
-#include <X11/Xatom.h>
-#include <X11/keysymdef.h>
-#include <unistd.h>
 
-#include <X11/XKBlib.h> /* for converting keycode to string */
-#include <X11/cursorfont.h> /* for hiding */
+				if (win->src.joysticks[i] == 0)
+					continue;
 
-#include <limits.h> /* for data limits (mainly used in drag and drop functions) */
-#include <fcntl.h>
+				i32 flags = fcntl(win->src.joysticks[i], F_GETFL, 0);
+				fcntl(win->src.joysticks[i], F_SETFL, flags | O_NONBLOCK);
 
-#ifdef __linux__
-#include <linux/joystick.h>
-#endif
+				ssize_t bytes;
+				while ((bytes = read(win->src.joysticks[i], &e, sizeof(e))) > 0) {
+					switch (e.type) {
+					case JS_EVENT_BUTTON:
+						win->event.type = e.value ? RGFW_jsButtonPressed : RGFW_jsButtonReleased;
+						win->event.button = e.number;
+						win->src.jsPressed[i][e.number] = e.value;
+						RGFW_jsButtonCallback(win, i, e.number, e.value);
+						return &win->event;
+					case JS_EVENT_AXIS:
+						ioctl(win->src.joysticks[i], JSIOCGAXES, &win->event.axisesCount);
 
-	/*atoms needed for drag and drop*/
-	Atom XdndAware, XdndTypeList, XdndSelection, XdndEnter, XdndPosition, XdndStatus, XdndLeave, XdndDrop, XdndFinished, XdndActionCopy, XdndActionMove, XdndActionLink, XdndActionAsk, XdndActionPrivate;
+						if ((e.number == 0 || e.number % 2) && e.number != 1)
+							xAxis = e.value;
+						else
+							yAxis = e.value;
 
-	Atom wm_delete_window = 0;
+						win->event.axis[e.number / 2].x = xAxis;
+						win->event.axis[e.number / 2].y = yAxis;
+						win->event.type = RGFW_jsAxisMove;
+						win->event.joystick = i;
+						RGFW_jsAxisCallback(win, i, win->event.axis, win->event.axisesCount);
+						return &win->event;
 
-#if !defined(RGFW_NO_X11_CURSOR) && !defined(RGFW_NO_X11_CURSOR_PRELOAD)
-	typedef XcursorImage* (*PFN_XcursorImageCreate)(int, int);
-	typedef void (*PFN_XcursorImageDestroy)(XcursorImage*);
-	typedef Cursor(*PFN_XcursorImageLoadCursor)(Display*, const XcursorImage*);
-#endif
-#ifdef RGFW_OPENGL
-	typedef GLXContext(*glXCreateContextAttribsARBProc)(Display*, GLXFBConfig, GLXContext, Bool, const int*);
+					default: break;
+					}
+				}
+			}
+		}
 #endif
 
-#if !defined(RGFW_NO_X11_CURSOR) && !defined(RGFW_NO_X11_CURSOR_PRELOAD)
-	PFN_XcursorImageLoadCursor XcursorImageLoadCursorSrc = NULL;
-	PFN_XcursorImageCreate XcursorImageCreateSrc = NULL;
-	PFN_XcursorImageDestroy XcursorImageDestroySrc = NULL;
-
-#define XcursorImageLoadCursor XcursorImageLoadCursorSrc
-#define XcursorImageCreate XcursorImageCreateSrc
-#define XcursorImageDestroy XcursorImageDestroySrc
+		XEvent E; /* raw X11 event */
 
-	void* X11Cursorhandle = NULL;
-#endif
+		/* if there is no unread qued events, get a new one */
+		if (XEventsQueued((Display*) win->src.display, QueuedAlready) + XEventsQueued((Display*) win->src.display, QueuedAfterReading) && win->event.type != RGFW_quit)
+			XNextEvent((Display*) win->src.display, &E);
+		else {
+			return NULL;
+		}
 
-	u32 RGFW_windowsOpen = 0;
+		u32 i;
+		win->event.type = 0;
 
-#ifdef RGFW_OPENGL
-	void* RGFW_getProcAddress(const char* procname) { return (void*) glXGetProcAddress((GLubyte*) procname); }
-#endif
 
-	RGFW_window* RGFW_createWindow(const char* name, RGFW_rect rect, u16 args) {
-#if !defined(RGFW_NO_X11_CURSOR) && !defined(RGFW_NO_X11_CURSOR_PRELOAD)
-		if (X11Cursorhandle == NULL) {
-#if defined(__CYGWIN__)
-			X11Cursorhandle = dlopen("libXcursor-1.so", RTLD_LAZY | RTLD_LOCAL);
-#elif defined(__OpenBSD__) || defined(__NetBSD__)
-			X11Cursorhandle = dlopen("libXcursor.so", RTLD_LAZY | RTLD_LOCAL);
-#else
-			X11Cursorhandle = dlopen("libXcursor.so.1", RTLD_LAZY | RTLD_LOCAL);
-#endif
-
-			XcursorImageCreateSrc = (PFN_XcursorImageCreate) dlsym(X11Cursorhandle, "XcursorImageCreate");
-			XcursorImageDestroySrc = (PFN_XcursorImageDestroy) dlsym(X11Cursorhandle, "XcursorImageDestroy");
-			XcursorImageLoadCursorSrc = (PFN_XcursorImageLoadCursor) dlsym(X11Cursorhandle, "XcursorImageLoadCursor");
-		}
-#endif
-
-		XInitThreads(); /* init X11 threading*/
-
-		if (args & RGFW_OPENGL_SOFTWARE)
-			setenv("LIBGL_ALWAYS_SOFTWARE", "1", 1);
+		switch (E.type) {
+		case KeyPress:
+		case KeyRelease:
+			/* check if it's a real key release */
+			if (E.type == KeyRelease && XEventsQueued((Display*) win->src.display, QueuedAfterReading)) { /* get next event if there is one*/
+				XEvent NE;
+				XPeekEvent((Display*) win->src.display, &NE);
 
-		RGFW_window* win = RGFW_window_basic_init(rect, args);
+				if (E.xkey.time == NE.xkey.time && E.xkey.keycode == NE.xkey.keycode) /* check if the current and next are both the same*/
+					break;
+			}
 
-		u64 event_mask = KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | PointerMotionMask | StructureNotifyMask | FocusChangeMask; /* X11 events accepted*/
+			/* set event key data */
+			KeySym sym = XkbKeycodeToKeysym((Display*) win->src.display, E.xkey.keycode, 0, E.xkey.state & ShiftMask ? 1 : 0);
+			win->event.keyCode = RGFW_apiKeyCodeToRGFW(E.xkey.keycode);
+			
+			char* str = XKeysymToString(sym);
+			if (str != NULL)
+				strncpy(win->event.keyName, str, 16);
 
-#ifdef RGFW_OPENGL
-		u32* visual_attribs = RGFW_initAttribs(args & RGFW_OPENGL_SOFTWARE);
-		i32 fbcount;
-		GLXFBConfig* fbc = glXChooseFBConfig((Display*) win->src.display, DefaultScreen(win->src.display), (i32*) visual_attribs, &fbcount);
+			win->event.keyName[15] = '\0';		
 
-		i32 best_fbc = -1;
+			RGFW_keyboard[win->event.keyCode].prev = RGFW_isPressed(win, win->event.keyCode);
+			
+			/* get keystate data */
+			win->event.type = (E.type == KeyPress) ? RGFW_keyPressed : RGFW_keyReleased;
 
-		if (fbcount == 0) {
-			printf("Failed to find any valid GLX configs\n");
-			return NULL;
-		}
+			XKeyboardState keystate;
+			XGetKeyboardControl((Display*) win->src.display, &keystate);
 
-		u32 i;
-		for (i = 0; i < (u32)fbcount; i++) {
-			XVisualInfo* vi = glXGetVisualFromFBConfig((Display*) win->src.display, fbc[i]);
-			if (vi == NULL)
-				continue;
+			RGFW_updateLockState(win, (keystate.led_mask & 1), (keystate.led_mask & 2));
 
-			XFree(vi);
+			RGFW_keyboard[win->event.keyCode].current = (E.type == KeyPress);
+			RGFW_keyCallback(win, win->event.keyCode, win->event.keyName, win->event.lockState, (E.type == KeyPress));
+			break;
 
-			i32 samp_buf, samples;
-			glXGetFBConfigAttrib((Display*) win->src.display, fbc[i], GLX_SAMPLE_BUFFERS, &samp_buf);
-			glXGetFBConfigAttrib((Display*) win->src.display, fbc[i], GLX_SAMPLES, &samples);
-			if ((best_fbc < 0 || samp_buf) && (samples == RGFW_SAMPLES || best_fbc == -1)) {
-				best_fbc = i;
+		case ButtonPress:
+		case ButtonRelease:
+			win->event.type = E.type; // the events match 
+			
+			switch(win->event.button) {
+				case RGFW_mouseScrollUp:
+					win->event.scroll = 1;
+					break;
+				case RGFW_mouseScrollDown:
+					win->event.scroll = -1;
+					break;
+				default: break;
 			}
-		}
 
-		if (best_fbc == -1) {
-			printf("Failed to get a valid GLX visual\n");
-			return NULL;
-		}
+			win->event.button = E.xbutton.button;
+			RGFW_mouseButtons_prev[win->event.button] = RGFW_mouseButtons[win->event.button];
+			RGFW_mouseButtons[win->event.button] = (E.type == ButtonPress);
+			RGFW_mouseButtonCallback(win, win->event.button, win->event.scroll, (E.type == ButtonPress));
+			break;
 
-		GLXFBConfig bestFbc = fbc[best_fbc];
+		case MotionNotify:
+			win->event.point.x = E.xmotion.x;
+			win->event.point.y = E.xmotion.y;
+			win->event.type = RGFW_mousePosChanged;
+			RGFW_mousePosCallback(win, win->event.point);
+			break;
+		
+		case Expose:
+			win->event.type = RGFW_windowRefresh;
+			RGFW_windowRefreshCallback(win);
+			break;
 
-		/* Get a visual */
-		XVisualInfo* vi = glXGetVisualFromFBConfig((Display*) win->src.display, bestFbc);
+		case ClientMessage:
+			/* if the client closed the window*/
+			if (E.xclient.data.l[0] == (i64) wm_delete_window) {
+				win->event.type = RGFW_quit;
+				RGFW_windowQuitCallback(win);
+				break;
+			}
+			
+			/* reset DND values */
+			if (win->event.droppedFilesCount) {
+				for (i = 0; i < win->event.droppedFilesCount; i++)
+					win->event.droppedFiles[i][0] = '\0';
+			}
 
-		XFree(fbc);
+			win->event.droppedFilesCount = 0;
 
-		u32 valuemask = CWBorderPixel | CWColormap;
-#else
-		XVisualInfo* vi = (XVisualInfo*) RGFW_MALLOC(sizeof(XVisualInfo));
-		vi->screen = DefaultScreen((Display*) win->src.display);
-		vi->visual = DefaultVisual((Display*) win->src.display, vi->screen);
+			/*
+				much of this event (drag and drop code) is source from glfw
+			*/
 
-		vi->depth = 0;
-		u32 valuemask = 0;
-#endif
+			if ((win->src.winArgs & RGFW_ALLOW_DND) == 0)
+				break;
 
-		/* make X window attrubutes*/
-		XSetWindowAttributes swa;
-		Colormap cmap;
+			if (E.xclient.message_type == XdndEnter) {
+				u64 count;
+				Atom* formats;
+				Atom real_formats[6];
 
-		swa.colormap = cmap = XCreateColormap((Display*) win->src.display,
-			RootWindow(win->src.display, vi->screen),
-			vi->visual, AllocNone);
+				Bool list = E.xclient.data.l[1] & 1;
 
-		swa.background_pixmap = None;
-		swa.border_pixel = 0;
-		swa.event_mask = event_mask;
+				xdnd.source = E.xclient.data.l[0];
+				xdnd.version = E.xclient.data.l[1] >> 24;
+				xdnd.format = None;
 
-		/* create the window*/
-		win->src.window = XCreateWindow((Display*) win->src.display, RootWindow((Display*) win->src.display, vi->screen), win->r.x, win->r.y, win->r.w, win->r.h,
-			0, vi->depth, InputOutput, vi->visual,
-			valuemask | CWEventMask, &swa);
+				if (xdnd.version > 5)
+					break;
 
+				if (list) {
+					Atom actualType;
+					i32 actualFormat;
+					u64 bytesAfter;
 
-		XFreeColors((Display*) win->src.display, cmap, NULL, 0, 0);
-		if (args & RGFW_TRANSPARENT_WINDOW)
-			XMatchVisualInfo((Display*) win->src.display, DefaultScreen((Display*) win->src.display), 32, TrueColor, vi); /* for RGBA backgrounds*/
+					XGetWindowProperty((Display*) win->src.display,
+						xdnd.source,
+						XdndTypeList,
+						0,
+						LONG_MAX,
+						False,
+						4,
+						&actualType,
+						&actualFormat,
+						(unsigned long*) &count,
+						(unsigned long*) &bytesAfter,
+						(u8**) &formats);
+				} else {
+					count = 0;
 
-		XFree(vi);
+					if (E.xclient.data.l[2] != None)
+						real_formats[count++] = E.xclient.data.l[2];
+					if (E.xclient.data.l[3] != None)
+						real_formats[count++] = E.xclient.data.l[3];
+					if (E.xclient.data.l[4] != None)
+						real_formats[count++] = E.xclient.data.l[4];
+					
+					formats = real_formats;
+				}
 
-#ifdef RGFW_OPENGL
-		i32 context_attribs[7] = { 0, 0, 0, 0, 0, 0, 0 };
-		context_attribs[0] = GLX_CONTEXT_PROFILE_MASK_ARB;
-		context_attribs[1] = GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB;
+				u32 i;
+				for (i = 0; i < count; i++) {
+					char* name = XGetAtomName((Display*) win->src.display, formats[i]);
 
-		if (RGFW_majorVersion || RGFW_minorVersion) {
-			context_attribs[2] = GLX_CONTEXT_MAJOR_VERSION_ARB;
-			context_attribs[3] = RGFW_majorVersion;
-			context_attribs[4] = GLX_CONTEXT_MINOR_VERSION_ARB;
-			context_attribs[5] = RGFW_minorVersion;
-		}
+					char* links[2] = { (char*) (const char*) "text/uri-list", (char*) (const char*) "text/plain" };
+					for (; 1; name++) {
+						u32 j;
+						for (j = 0; j < 2; j++) {
+							if (*links[j] != *name) {
+								links[j] = (char*) (const char*) "\1";
+								continue;
+							}
 
-		glXCreateContextAttribsARBProc glXCreateContextAttribsARB = 0;
-		glXCreateContextAttribsARB = (glXCreateContextAttribsARBProc)
-			glXGetProcAddressARB((GLubyte*) "glXCreateContextAttribsARB");
+							if (*links[j] == '\0' && *name == '\0')
+								xdnd.format = formats[i];
 
-		GLXContext ctx = NULL;
+							if (*links[j] != '\0' && *links[j] != '\1')
+								links[j]++;
+						}
 
-		if (RGFW_root != NULL)
-			ctx = RGFW_root->src.rSurf;
+						if (*name == '\0')
+							break;
+					}
+				}
 
-		win->src.rSurf = glXCreateContextAttribsARB((Display*) win->src.display, bestFbc, ctx, True, context_attribs);
-#endif
-		if (RGFW_root == NULL)
-			RGFW_root = win;
+				if (list) {
+					XFree(formats);
+				}
 
-		RGFW_init_buffer(win);
+				break;
+			}
+			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;
 
-#ifdef RGFW_VULKAN
-		RGFW_initVulkan(win);
-#endif
+				if (xdnd.version > 5)
+					break;
 
-		if (args & RGFW_SCALE_TO_MONITOR)
-			RGFW_window_scaleToMonitor(win);
+				XTranslateCoordinates((Display*) win->src.display,
+					XDefaultRootWindow((Display*) win->src.display),
+					(Window) win->src.window,
+					xabs, yabs,
+					&xpos, &ypos,
+					&dummy);
 
-		if (args & RGFW_NO_RESIZE) { /* make it so the user can't resize the window*/
-			XSizeHints* sh = XAllocSizeHints();
-			sh->flags = (1L << 4) | (1L << 5);
-			sh->min_width = sh->max_width = win->r.w;
-			sh->min_height = sh->max_height = win->r.h;
+				win->event.point.x = xpos;
+				win->event.point.y = ypos;
 
-			XSetWMSizeHints((Display*) win->src.display, (Drawable) win->src.window, sh, XA_WM_NORMAL_HINTS);
-			XFree(sh);
-		}
+				XEvent reply = { ClientMessage };
+				reply.xclient.window = xdnd.source;
+				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 (args & RGFW_NO_BORDER) {
-			/* Atom vars for no-border*/
-			static Atom window_type = 0;
-			static Atom value = 0;
+				if (xdnd.format) {
+					reply.xclient.data.l[1] = 1;
+					if (xdnd.version >= 2)
+						reply.xclient.data.l[4] = XdndActionCopy;
+				}
 
-			if (window_type == 0) {
-				window_type = XInternAtom((Display*) win->src.display, "_NET_WM_WINDOW_TYPE", False);
-				value = XInternAtom((Display*) win->src.display, "_NET_WM_WINDOW_TYPE_DOCK", False);
+				XSendEvent((Display*) win->src.display, xdnd.source, False, NoEventMask, &reply);
+				XFlush((Display*) win->src.display);
+				break;
 			}
 
-			XChangeProperty((Display*) win->src.display, (Drawable) win->src.window, window_type, XA_ATOM, 32, PropModeReplace, (u8*) &value, 1); /* toggle border*/
-		}
+			if (E.xclient.message_type != XdndDrop)
+				break;
 
-		XSelectInput((Display*) win->src.display, (Drawable) win->src.window, event_mask); /* tell X11 what events we want*/
+			if (xdnd.version > 5)
+				break;
 
-		/* make it so the user can't close the window until the program does*/
-		if (wm_delete_window == 0)
-			wm_delete_window = XInternAtom((Display*) win->src.display, "WM_DELETE_WINDOW", 1);
+			win->event.type = RGFW_dnd_init;
 
-		XSetWMProtocols((Display*) win->src.display, (Drawable) win->src.window, &wm_delete_window, 1);
+			if (xdnd.format) {
+				Time time = CurrentTime;
 
-		/* connect the context to the window*/
-#ifdef RGFW_OPENGL
-		glXMakeCurrent((Display*) win->src.display, (Drawable) win->src.window, (GLXContext) win->src.rSurf);
-#endif
+				if (xdnd.version >= 1)
+					time = E.xclient.data.l[2];
 
-		/* set the background*/
-		XStoreName((Display*) win->src.display, (Drawable) win->src.window, name); /* set the name*/
-
-		XMapWindow((Display*) win->src.display, (Drawable) win->src.window);						  /* draw the window*/
-		XMoveWindow((Display*) win->src.display, (Drawable) win->src.window, win->r.x, win->r.y); /* move the window to it's proper cords*/
-
-		if (args & RGFW_ALLOW_DND) { /* init drag and drop atoms and turn on drag and drop for this window */
-			win->src.winArgs |= RGFW_ALLOW_DND;
-
-			XdndAware = XInternAtom((Display*) win->src.display, "XdndAware", False);
-			XdndTypeList = XInternAtom((Display*) win->src.display, "XdndTypeList", False);
-			XdndSelection = XInternAtom((Display*) win->src.display, "XdndSelection", False);
+				XConvertSelection((Display*) win->src.display,
+					XdndSelection,
+					xdnd.format,
+					XdndSelection,
+					(Window) win->src.window,
+					time);
+			} else if (xdnd.version >= 2) {
+				XEvent reply = { ClientMessage };
+				reply.xclient.window = xdnd.source;
+				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;
 
-			/* client messages */
-			XdndEnter = XInternAtom((Display*) win->src.display, "XdndEnter", False);
-			XdndPosition = XInternAtom((Display*) win->src.display, "XdndPosition", False);
-			XdndStatus = XInternAtom((Display*) win->src.display, "XdndStatus", False);
-			XdndLeave = XInternAtom((Display*) win->src.display, "XdndLeave", False);
-			XdndDrop = XInternAtom((Display*) win->src.display, "XdndDrop", False);
-			XdndFinished = XInternAtom((Display*) win->src.display, "XdndFinished", False);
+				XSendEvent((Display*) win->src.display, xdnd.source,
+					False, NoEventMask, &reply);
+				XFlush((Display*) win->src.display);
+			}
 
-			/* actions */
-			XdndActionCopy = XInternAtom((Display*) win->src.display, "XdndActionCopy", False);
-			XdndActionMove = XInternAtom((Display*) win->src.display, "XdndActionMove", False);
-			XdndActionLink = XInternAtom((Display*) win->src.display, "XdndActionLink", False);
-			XdndActionAsk = XInternAtom((Display*) win->src.display, "XdndActionAsk", False);
-			XdndActionPrivate = XInternAtom((Display*) win->src.display, "XdndActionPrivate", False);
-			const Atom version = 5;
+			RGFW_dndInitCallback(win, win->event.point);
+			break;
+		case SelectionNotify:
+			/* this is only for checking for xdnd drops */
+			if (E.xselection.property != XdndSelection || !(win->src.winArgs | RGFW_ALLOW_DND))
+				break;
 
-			XChangeProperty((Display*) win->src.display, (Window) win->src.window,
-				XdndAware, 4, 32,
-				PropModeReplace, (u8*) &version, 1); /* turns on drag and drop */
-		}
+			char* data;
+			u64 result;
 
-		#ifdef RGFW_EGL
-			RGFW_createOpenGLContext(win);
-		#endif
+			Atom actualType;
+			i32 actualFormat;
+			u64 bytesAfter;
 
-		RGFW_window_setMouseDefault(win);
+			XGetWindowProperty((Display*) win->src.display, E.xselection.requestor, E.xselection.property, 0, LONG_MAX, False, E.xselection.target, &actualType, &actualFormat, &result, &bytesAfter, (u8**) &data);
 
-		RGFW_windowsOpen++;
+			if (result == 0)
+				break;
 
-		return win; /*return newly created window*/
-	}
+			/*
+			SOURCED FROM GLFW _glfwParseUriList
+			Copyright (c) 2002-2006 Marcus Geelnard
+			Copyright (c) 2006-2019 Camilla Löwy
+			*/
 
-	RGFW_area RGFW_getScreenSize(void) {
-		assert(RGFW_root != NULL);
+			const char* prefix = "file://";
 
-		Screen* scrn = DefaultScreenOfDisplay((Display*) RGFW_root->src.display);
-		return RGFW_AREA(scrn->width, scrn->height);
-	}
+			char* line;
 
-	RGFW_vector RGFW_getGlobalMousePoint(void) {
-		assert(RGFW_root != NULL);
+			win->event.droppedFilesCount = 0;
 
-		RGFW_vector RGFWMouse;
+			win->event.type = RGFW_dnd;
 
-		i32 x, y;
-		u32 z;
-		Window window1, window2;
-		XQueryPointer((Display*) RGFW_root->src.display, XDefaultRootWindow((Display*) RGFW_root->src.display), &window1, &window2, &RGFWMouse.x, &RGFWMouse.y, &x, &y, &z);
- 
-		return RGFWMouse;
-	}
+			while ((line = strtok(data, "\r\n"))) {
+				char path[RGFW_MAX_PATH];
 
-	RGFW_vector RGFW_window_getMousePoint(RGFW_window* win) {
-		assert(win != NULL);
+				data = NULL;
 
-		RGFW_vector RGFWMouse;
+				if (line[0] == '#')
+					continue;
 
-		i32 x, y;
-		u32 z;
-		Window window1, window2;
-		XQueryPointer((Display*) win->src.display, win->src.window, &window1, &window2, &x, &y, &RGFWMouse.x, &RGFWMouse.y, &z);
+				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;
+				}
 
-		return RGFWMouse;
-	}
+				win->event.droppedFilesCount++;
 
-	typedef struct XDND {
-		long source, version;
-		i32 format;
-	} XDND; /* data structure for xdnd events */
-	XDND xdnd;
+				size_t index = 0;
+				while (*line) {
+					if (line[0] == '%' && line[1] && line[2]) {
+						const char digits[3] = { line[1], line[2], '\0' };
+						path[index] = (char) strtol(digits, NULL, 16);
+						line += 2;
+					} else
+						path[index] = *line;
 
-	int xAxis = 0, yAxis = 0;
+					index++;
+					line++;
+				}
+				path[index] = '\0';
+				strncpy(win->event.droppedFiles[win->event.droppedFilesCount - 1], path, index + 1);
+			}
 
-	RGFW_Event* RGFW_window_checkEvent(RGFW_window* win) {
-		assert(win != NULL);
-		win->event.type = 0;
+			if (data)
+				XFree(data);
 
-#ifdef __linux__
-		{
-			u8 i;
-			for (i = 0; i < win->src.joystickCount; i++) {
-				struct js_event e;
+			if (xdnd.version >= 2) {
+				XEvent reply = { ClientMessage };
+				reply.xclient.window = xdnd.source;
+				reply.xclient.message_type = XdndFinished;
+				reply.xclient.format = 32;
+				reply.xclient.data.l[0] = (long) win->src.window;
+				reply.xclient.data.l[1] = result;
+				reply.xclient.data.l[2] = XdndActionCopy;
 
+				XSendEvent((Display*) win->src.display, xdnd.source, False, NoEventMask, &reply);
+				XFlush((Display*) win->src.display);
+			}
 
-				if (!win->src.joysticks[i])
-					continue;
+			RGFW_dndCallback(win, win->event.droppedFiles, win->event.droppedFilesCount);
+			break;
 
-				i32 flags = fcntl(win->src.joysticks[i], F_GETFL, 0);
-				fcntl(win->src.joysticks[i], F_SETFL, flags | O_NONBLOCK);
+		case FocusIn:
+			win->event.inFocus = 1;
+			win->event.type = RGFW_focusIn;
+			RGFW_focusCallback(win, 1);
+			break;
 
-				ssize_t bytes;
-				while ((bytes = read(win->src.joysticks[i], &e, sizeof(e))) > 0) {
-					switch (e.type) {
-					case JS_EVENT_BUTTON:
-						win->event.type = e.value ? RGFW_jsButtonPressed : RGFW_jsButtonReleased;
-						win->event.button = e.number;
-						win->src.jsPressed[i][e.number] = e.value;
-						return &win->event;
-					case JS_EVENT_AXIS:
-						ioctl(win->src.joysticks[i], JSIOCGAXES, &win->event.axisesCount);
+			break;
+		case FocusOut:
+			win->event.inFocus = 0;
+			win->event.type = RGFW_focusOut;
+			RGFW_focusCallback(win, 0);
+			break;
+		
+		case EnterNotify: {
+			win->event.type = RGFW_mouseEnter;
+			win->event.point.x = E.xcrossing.x;
+			win->event.point.y = E.xcrossing.y;
+			RGFW_mouseNotifyCallBack(win, win->event.point, 1);
+			break;
+		}
 
-						if ((e.number == 0 || e.number % 2) && e.number != 1)
-							xAxis = e.value;
-						else
-							yAxis = e.value;
+		case LeaveNotify: {
+			win->event.type = RGFW_mouseLeave;
+			RGFW_mouseNotifyCallBack(win, win->event.point, 0);
+			break;
+		}
 
-						win->event.axis[e.number / 2].x = xAxis;
-						win->event.axis[e.number / 2].y = yAxis;
-						win->event.type = RGFW_jsAxisMove;
-						win->event.joystick = e.number / 2;
-						return &win->event;
+		case ConfigureNotify: {
+				/* detect resize */
+      			if (E.xconfigure.width != win->r.w || E.xconfigure.height != win->r.h) {
+					win->event.type = RGFW_windowResized;
+					win->r = RGFW_RECT(win->r.x, win->r.y, E.xconfigure.width, E.xconfigure.height);
+					RGFW_windowResizeCallback(win, win->r);
+					break;
+      			}  
+      
+      			/* detect move */
+      			if (E.xconfigure.x != win->r.x || E.xconfigure.y != win->r.y) {
+					win->event.type = RGFW_windowMoved;
+					win->r = RGFW_RECT(E.xconfigure.x, E.xconfigure.y, win->r.w, win->r.h);
+					RGFW_windowMoveCallback(win, win->r);
+					break;
+				} 
 
-					default: break;
-					}
-				}
-			}
+				break;
+		}
+		default: {
+			break;
+		}
 		}
-#endif
 
-		XEvent E; /* raw X11 event */
+		XFlush((Display*) win->src.display);
 
-		/* if there is no unread qued events, get a new one */
-		if (XEventsQueued((Display*) win->src.display, QueuedAlready) + XEventsQueued((Display*) win->src.display, QueuedAfterReading) && win->event.type != RGFW_quit)
-			XNextEvent((Display*) win->src.display, &E);
-		else {
+		if (win->event.type)
+			return &win->event;
+		else
 			return NULL;
-		}
-
-		u32 i;
-		win->event.type = 0;
+	}
 
+	void RGFW_window_move(RGFW_window* win, RGFW_vector v) {
+		assert(win != NULL);
+		win->r.x = v.x;
+		win->r.y = v.y;
 
-		switch (E.type) {
-		case KeyPress:
-		case KeyRelease:
-			/* check if it's a real key release */
-			if (E.type == KeyRelease && XEventsQueued((Display*) win->src.display, QueuedAfterReading)) { /* get next event if there is one*/
-				XEvent NE;
-				XPeekEvent((Display*) win->src.display, &NE);
+		XMoveWindow((Display*) win->src.display, (Window) win->src.window, v.x, v.y);
+	}
 
-				if (E.xkey.time == NE.xkey.time && E.xkey.keycode == NE.xkey.keycode) /* check if the current and next are both the same*/
-					break;
-			}
 
-			/* set event key data */
-			KeySym sym = XkbKeycodeToKeysym((Display*) win->src.display, E.xkey.keycode, 0, E.xkey.state & ShiftMask ? 1 : 0);
-			win->event.keyCode = RGFW_apiKeyCodeToRGFW(E.xkey.keycode);
-			win->event.keyName = XKeysymToString(sym); /* convert to string */
+	void RGFW_window_resize(RGFW_window* win, RGFW_area a) {
+		assert(win != NULL);
+		win->r.w = a.w;
+		win->r.h = a.h;
 
-			RGFW_keyboard_prev[win->event.keyCode] = RGFW_isPressedI(win, win->event.keyCode);
-			
-			/* get keystate data */
-			win->event.type = (E.type == KeyPress) ? RGFW_keyPressed : RGFW_keyReleased;
+		XResizeWindow((Display*) win->src.display, (Window) win->src.window, a.w, a.h);
+	}
 
-			if (win->event.type == RGFW_keyReleased) {
-				if (sym == XK_Caps_Lock && win->event.lockState & RGFW_CAPSLOCK)
-					win->event.lockState ^= RGFW_CAPSLOCK;
-				else if (sym == XK_Caps_Lock)
-					win->event.lockState |= RGFW_CAPSLOCK;
+	void RGFW_window_setMinSize(RGFW_window* win, RGFW_area a) {
+		assert(win != NULL);
 
-				else if (sym == XK_Num_Lock && win->event.lockState & RGFW_NUMLOCK)
-					win->event.lockState ^= RGFW_NUMLOCK;
-				else if (sym == XK_Num_Lock)
-					win->event.lockState |= RGFW_NUMLOCK;
-			}
-			
-			RGFW_keyboard[win->event.keyCode] = (E.type == KeyPress);
-			break;
+		if (a.w == 0 && a.h == 0)
+			return;
 
-		case ButtonPress:
-		case ButtonRelease:
-			win->event.type = (E.type == ButtonPress) ? RGFW_mouseButtonPressed : RGFW_mouseButtonReleased;
-		
-			if (win->event.button == RGFW_mouseScrollUp) {
-				win->event.scroll = 1;
-			}
-			else if (win->event.button == RGFW_mouseScrollDown) {
-				win->event.scroll = -1;
-			}
+		XSizeHints hints;
+		long flags;
 
-			win->event.button = E.xbutton.button;
-			RGFW_mouseButtons_prev[win->event.button] = RGFW_mouseButtons[win->event.button];
-			RGFW_mouseButtons[win->event.button] = (E.type == ButtonPress);
-			break;
+		XGetWMNormalHints(win->src.display, (Window) win->src.window, &hints, &flags);
 
-		case MotionNotify:
-			win->event.point.x = E.xmotion.x;
-			win->event.point.y = E.xmotion.y;
-			win->event.type = RGFW_mousePosChanged;
-			break;
+		hints.flags |= PMinSize;
+		
+		hints.min_width = a.w;
+		hints.min_height = a.h;
 
-		case ClientMessage:
-			/* if the client closed the window*/
-			if (E.xclient.data.l[0] == (i64) wm_delete_window) {
-				win->event.type = RGFW_quit;
-				break;
-			}
-			
-			/* reset DND values */
-			if (win->event.droppedFilesCount) {
-				for (i = 0; i < win->event.droppedFilesCount; i++)
-					win->event.droppedFiles[i][0] = '\0';
-			}
+		XSetWMNormalHints(win->src.display, (Window) win->src.window, &hints);
+	}
 
-			win->event.droppedFilesCount = 0;
+	void RGFW_window_setMaxSize(RGFW_window* win, RGFW_area a) {
+		assert(win != NULL);
 
-			/*
-				much of this event (drag and drop code) is source from glfw
-			*/
+		if (a.w == 0 && a.h == 0)
+			return;
 
-			if ((win->src.winArgs & RGFW_ALLOW_DND) == 0)
-				break;
+		XSizeHints hints;
+		long flags;
 
-			u8 formFree = 0;
-			if (E.xclient.message_type == XdndEnter) {
-				u64 count;
-				Atom* formats = (Atom*) 0;
-				Bool list = E.xclient.data.l[1] & 1;
+		XGetWMNormalHints(win->src.display, (Window) win->src.window, &hints, &flags);
 
-				xdnd.source = E.xclient.data.l[0];
-				xdnd.version = E.xclient.data.l[1] >> 24;
-				xdnd.format = None;
+		hints.flags |= PMaxSize;
 
-				if (xdnd.version > 5)
-					break;
+		hints.max_width = a.w;
+		hints.max_height = a.h;
 
-				if (list) {
-					Atom actualType;
-					i32 actualFormat;
-					u64 bytesAfter;
+		XSetWMNormalHints(win->src.display, (Window) win->src.window, &hints);
+	}
 
-					XGetWindowProperty((Display*) win->src.display,
-						xdnd.source,
-						XdndTypeList,
-						0,
-						LONG_MAX,
-						False,
-						4,
-						&actualType,
-						&actualFormat,
-						(unsigned long*) &count,
-						(unsigned long*) &bytesAfter,
-						(u8**) &formats);
-				} else {
-					formats = (Atom*) RGFW_MALLOC(E.xclient.data.l[2] + E.xclient.data.l[3] + E.xclient.data.l[4]);
-					formFree = 1;
 
-					count = 0;
+	void RGFW_window_minimize(RGFW_window* win) {
+		assert(win != NULL);
 
-					if (E.xclient.data.l[2] != None)
-						formats[count++] = E.xclient.data.l[2];
-					if (E.xclient.data.l[3] != None)
-						formats[count++] = E.xclient.data.l[3];
-					if (E.xclient.data.l[4] != None)
-						formats[count++] = E.xclient.data.l[4];
-				}
+		XIconifyWindow(win->src.display, (Window) win->src.window, DefaultScreen(win->src.display));
+		XFlush(win->src.display);
+	}
 
-				u32 i;
-				for (i = 0; i < count; i++) {
-					char* name = XGetAtomName((Display*) win->src.display, formats[i]);
+	void RGFW_window_restore(RGFW_window* win) {
+		assert(win != NULL);
 
-					char* links[2] = { (char*) (const char*) "text/uri-list", (char*) (const char*) "text/plain" };
-					for (; 1; name++) {
-						u32 j;
-						for (j = 0; j < 2; j++) {
-							if (*links[j] != *name) {
-								links[j] = (char*) (const char*) "\1";
-								continue;
-							}
+		XMapWindow(win->src.display, (Window) win->src.window);
+		XFlush(win->src.display);
+	}	
 
-							if (*links[j] == '\0' && *name == '\0')
-								xdnd.format = formats[i];
+	void RGFW_window_setName(RGFW_window* win, char* name) {
+		assert(win != NULL);
 
-							if (*links[j] != '\0' && *links[j] != '\1')
-								links[j]++;
-						}
+		XStoreName((Display*) win->src.display, (Window) win->src.window, name);
+	}
+	
+	void* RGFW_libxshape = NULL;
 
-						if (*name == '\0')
-							break;
-					}
-				}
+	#ifndef RGFW_NO_PASSTHROUGH
+	void RGFW_window_setMousePassthrough(RGFW_window* win, b8 passthrough) {
+		assert(win != NULL);
+		
+		#if defined(__CYGWIN__)
+			RGFW_libxshape = dlopen("libXext-6.so", RTLD_LAZY | RTLD_LOCAL);
+		#elif defined(__OpenBSD__) || defined(__NetBSD__)
+			RGFW_libxshape = dlopen("libXext.so", RTLD_LAZY | RTLD_LOCAL);
+		#else
+    		RGFW_libxshape = dlopen("libXext.so.6", RTLD_LAZY | RTLD_LOCAL);
+		#endif
+		
+		typedef void (* PFN_XShapeCombineMask)(Display*,Window,int,int,int,Pixmap,int);
+		static PFN_XShapeCombineMask XShapeCombineMask;
+		
+		typedef void (* PFN_XShapeCombineRegion)(Display*,Window,int,int,int,Region,int);
+		static PFN_XShapeCombineRegion XShapeCombineRegion;
+		
+		if (XShapeCombineMask != NULL)
+			XShapeCombineMask = (PFN_XShapeCombineMask) dlsym(RGFW_libxshape, "XShapeCombineMask");
 
-				if (list && formats) {
-					XFree(formats);
-					formats = (Atom*) 0;
-				} else if (formFree && formats != (Atom*) 0) {
-					RGFW_FREE(formats);
+		if (XShapeCombineRegion != NULL)
+			XShapeCombineRegion = (PFN_XShapeCombineRegion) dlsym(RGFW_libxshape, "XShapeCombineMask");
 
-					formats = (Atom*) 0;
-					formFree = 1;
-				}
+		if (passthrough) {
+			Region region = XCreateRegion();
+			XShapeCombineRegion(win->src.display, win->src.window, ShapeInput, 0, 0, region, ShapeSet);
+			XDestroyRegion(region);
 
-				break;
-			}
-			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;
+			return;
+		}
 
-				if (xdnd.version > 5)
-					break;
+		XShapeCombineMask(win->src.display, win->src.window, ShapeInput, 0, 0, None, ShapeSet);
+	}
+	#endif
 
-				XTranslateCoordinates((Display*) win->src.display,
-					XDefaultRootWindow((Display*) win->src.display),
-					(Window) win->src.window,
-					xabs, yabs,
-					&xpos, &ypos,
-					&dummy);
+	/*
+		the majority function is sourced from GLFW
+	*/
 
-				win->event.point.x = xpos;
-				win->event.point.y = ypos;
+	void RGFW_window_setIcon(RGFW_window* win, u8* icon, RGFW_area a, i32 channels) {
+		assert(win != NULL);
 
-				XEvent reply = { ClientMessage };
-				reply.xclient.window = xdnd.source;
-				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;
+		i32 longCount = 2 + a.w * a.h;
 
-				if (xdnd.format) {
-					reply.xclient.data.l[1] = 1;
-					if (xdnd.version >= 2)
-						reply.xclient.data.l[4] = XdndActionCopy;
-				}
+		u64* X11Icon = (u64*) RGFW_MALLOC(longCount * sizeof(u64));
+		u64* target = X11Icon;
 
-				XSendEvent((Display*) win->src.display, xdnd.source, False, NoEventMask, &reply);
-				XFlush((Display*) win->src.display);
-				break;
-			}
+		*target++ = a.w;
+		*target++ = a.h;
 
-			if (E.xclient.message_type != XdndDrop)
-				break;
+		u32 i;
 
-			if (xdnd.version > 5)
-				break;
+		for (i = 0; i < a.w * a.h; i++) {
+			if (channels == 3)
+				*target++ = ((icon[i * 3 + 0]) << 16) |
+				((icon[i * 3 + 1]) << 8) |
+				((icon[i * 3 + 2]) << 0) |
+				(0xFF << 24);
 
-			win->event.type = RGFW_dnd_init;
+			else if (channels == 4)
+				*target++ = ((icon[i * 4 + 0]) << 16) |
+				((icon[i * 4 + 1]) << 8) |
+				((icon[i * 4 + 2]) << 0) |
+				((icon[i * 4 + 3]) << 24);
+		}
 
-			if (xdnd.format) {
-				Time time = CurrentTime;
+		static Atom NET_WM_ICON = 0;
+		if (NET_WM_ICON == 0)
+			NET_WM_ICON = XInternAtom((Display*) win->src.display, "_NET_WM_ICON", False);
 
-				if (xdnd.version >= 1)
-					time = E.xclient.data.l[2];
+		XChangeProperty((Display*) win->src.display, (Window) win->src.window,
+			NET_WM_ICON,
+			6, 32,
+			PropModeReplace,
+			(u8*) X11Icon,
+			longCount);
 
-				XConvertSelection((Display*) win->src.display,
-					XdndSelection,
-					xdnd.format,
-					XdndSelection,
-					(Window) win->src.window,
-					time);
-			} else if (xdnd.version >= 2) {
-				XEvent reply = { ClientMessage };
-				reply.xclient.window = xdnd.source;
-				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;
+		RGFW_FREE(X11Icon);
 
-				XSendEvent((Display*) win->src.display, xdnd.source,
-					False, NoEventMask, &reply);
-				XFlush((Display*) win->src.display);
-			}
-			break;
-		case SelectionNotify:
-			/* this is only for checking for xdnd drops */
-			if (E.xselection.property != XdndSelection || !(win->src.winArgs | RGFW_ALLOW_DND))
-				break;
+		XFlush((Display*) win->src.display);
+	}
 
-			char* data;
-			u64 result;
+	void RGFW_window_setMouse(RGFW_window* win, u8* image, RGFW_area a, i32 channels) {
+		assert(win != NULL);
 
-			Atom actualType;
-			i32 actualFormat;
-			u64 bytesAfter;
+#ifndef RGFW_NO_X11_CURSOR
+		XcursorImage* native = XcursorImageCreate(a.w, a.h);
+		native->xhot = 0;
+		native->yhot = 0;
 
-			XGetWindowProperty((Display*) win->src.display, E.xselection.requestor, E.xselection.property, 0, LONG_MAX, False, E.xselection.target, &actualType, &actualFormat, &result, &bytesAfter, (u8**) &data);
+		u8* source = (u8*) image;
+		XcursorPixel* target = native->pixels;
 
-			if (result == 0)
-				break;
+		u32 i;
+		for (i = 0; i < a.w * a.h; i++, target++, source += 4) {
+			u8 alpha = 0xFF;
+			if (channels == 4)
+				alpha = source[3];
 
-			/*
-			SOURCED FROM GLFW _glfwParseUriList
-			Copyright (c) 2002-2006 Marcus Geelnard
-			Copyright (c) 2006-2019 Camilla Löwy
-			*/
-
-			const char* prefix = "file://";
-
-			char* line;
+			*target = (alpha << 24) | (((source[0] * alpha) / 255) << 16) | (((source[1] * alpha) / 255) << 8) | (((source[2] * alpha) / 255) << 0);
+		}
 
-			win->event.droppedFilesCount = 0;
+		Cursor cursor = XcursorImageLoadCursor((Display*) win->src.display, native);
+		XDefineCursor((Display*) win->src.display, (Window) win->src.window, (Cursor) cursor);
 
-			win->event.type = RGFW_dnd;
+		XFreeCursor((Display*) win->src.display, (Cursor) cursor);
+		XcursorImageDestroy(native);
+#else
+	RGFW_UNUSED(image) RGFW_UNUSED(a.w) RGFW_UNUSED(channels)
+#endif
+	}
 
-			while ((line = strtok(data, "\r\n"))) {
-				char path[RGFW_MAX_PATH];
+	void RGFW_window_moveMouse(RGFW_window* win, RGFW_vector v) {
+		assert(win != NULL);
 
-				data = NULL;
+		XEvent event;
+		XQueryPointer(win->src.display, DefaultRootWindow(win->src.display),
+			&event.xbutton.root, &event.xbutton.window,
+			&event.xbutton.x_root, &event.xbutton.y_root,
+			&event.xbutton.x, &event.xbutton.y,
+			&event.xbutton.state);
 
-				if (line[0] == '#')
-					continue;
+		if (event.xbutton.x == v.x && event.xbutton.y == v.y)
+			return;
 
-				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;
-				}
+		XWarpPointer(win->src.display, None, win->src.window, 0, 0, 0, 0, (int) v.x - win->r.x, (int) v.y - win->r.y);
+	}
 
-				win->event.droppedFilesCount++;
+	RGFWDEF void RGFW_window_disableMouse(RGFW_window* win) {
+		RGFW_UNUSED(win);
+	}
 
-				size_t index = 0;
-				while (*line) {
-					if (line[0] == '%' && line[1] && line[2]) {
-						const char digits[3] = { line[1], line[2], '\0' };
-						path[index] = (char) strtol(digits, NULL, 16);
-						line += 2;
-					} else
-						path[index] = *line;
+	void RGFW_window_setMouseDefault(RGFW_window* win) {
+		RGFW_window_setMouseStandard(win, RGFW_MOUSE_ARROW);
+	}
 
-					index++;
-					line++;
-				}
-				path[index] = '\0';
-				strcpy(win->event.droppedFiles[win->event.droppedFilesCount - 1], path);
-			}
+	void RGFW_window_setMouseStandard(RGFW_window* win, u8 mouse) {
+		assert(win != NULL);
 
-			if (data)
-				XFree(data);
+		if (mouse > (sizeof(RGFW_mouseIconSrc) / sizeof(u8)))
+			return;
+		
+		mouse = RGFW_mouseIconSrc[mouse];
 
-			if (xdnd.version >= 2) {
-				XEvent reply = { ClientMessage };
-				reply.xclient.window = xdnd.source;
-				reply.xclient.message_type = XdndFinished;
-				reply.xclient.format = 32;
-				reply.xclient.data.l[0] = (long) win->src.window;
-				reply.xclient.data.l[1] = result;
-				reply.xclient.data.l[2] = XdndActionCopy;
+		Cursor cursor = XCreateFontCursor((Display*) win->src.display, mouse);
+		XDefineCursor((Display*) win->src.display, (Window) win->src.window, (Cursor) cursor);
 
-				XSendEvent((Display*) win->src.display, xdnd.source, False, NoEventMask, &reply);
-				XFlush((Display*) win->src.display);
-			}
+		XFreeCursor((Display*) win->src.display, (Cursor) cursor);
+	}
 
-			break;
+	void RGFW_window_hide(RGFW_window* win) {
+		XMapWindow(win->src.display, win->src.window);
+	}
 
-		case FocusIn:
-			win->event.inFocus = 1;
+	void RGFW_window_show(RGFW_window* win) {
+		XUnmapWindow(win->src.display, win->src.window);
+	}
 
-			XKeyboardState keystate;
-			XGetKeyboardControl((Display*) win->src.display, &keystate);
-			win->event.lockState = keystate.led_mask;
+	/*
+		the majority function is sourced from GLFW
+	*/
+	char* RGFW_readClipboard(size_t* size) {
+		static Atom UTF8 = 0;
+		if (UTF8 == 0)
+			UTF8 = XInternAtom(RGFW_root->src.display, "UTF8_STRING", True);
 
-			win->event.type = RGFW_focusIn;
-			break;
+		XEvent event;
+		int format;
+		unsigned long N, sizeN;
+		char* data, * s = NULL;
+		Atom target;
+		Atom CLIPBOARD = 0, XSEL_DATA = 0;
 
-			break;
-		case FocusOut:
-			win->event.inFocus = 0;
-			win->event.type = RGFW_focusOut;
-			break;
-		case ConfigureNotify: {
-			// detect resize
-      			if (E.xconfigure.width != win->r.w || E.xconfigure.height != win->r.h) {
-				win->event.type = RGFW_windowResized;
-				win->r = RGFW_RECT(win->r.x, win->r.y, E.xconfigure.width, E.xconfigure.height);
-				break;
-      			}  
-      
-      			// detect move
-      			if (E.xconfigure.x != win->r.x || E.xconfigure.y != win->r.y) {
-				win->event.type = RGFW_windowMoved;
-				win->r = RGFW_RECT(E.xconfigure.x, E.xconfigure.y, win->r.w, win->r.h);
-				break;
-			} 
-		}
-		default: {
-			break;
-		}
+		if (CLIPBOARD == 0) {
+			CLIPBOARD = XInternAtom(RGFW_root->src.display, "CLIPBOARD", 0);
+			XSEL_DATA = XInternAtom(RGFW_root->src.display, "XSEL_DATA", 0);
 		}
 
-		XFlush((Display*) win->src.display);
+		XConvertSelection(RGFW_root->src.display, CLIPBOARD, UTF8, XSEL_DATA, RGFW_root->src.window, CurrentTime);
+		XSync(RGFW_root->src.display, 0);
+		XNextEvent(RGFW_root->src.display, &event);
 
-		if (win->event.type)
-			return &win->event;
-		else
+		if (event.type != SelectionNotify || event.xselection.selection != CLIPBOARD || event.xselection.property == 0)
 			return NULL;
-	}
 
-	void RGFW_window_close(RGFW_window* win) {
-		assert(win != NULL);
+		XGetWindowProperty(event.xselection.display, event.xselection.requestor,
+			event.xselection.property, 0L, (~0L), 0, AnyPropertyType, &target,
+			&format, &sizeN, &N, (unsigned char**) &data);
 
-#ifdef RGFW_VULKAN
-		for (u32 i = 0; i < win->src.image_count; i++) {
-			vkDestroyImageView(RGFW_vulkan_info.device, win->src.swapchain_image_views[i], NULL);
+		if (target == UTF8 || target == XA_STRING) {
+			s = (char*)RGFW_MALLOC(sizeof(char) * sizeN);
+			strncpy(s, data, sizeN);
+			s[sizeN] = '\0';
+			XFree(data);
 		}
 
-		vkDestroySwapchainKHR(RGFW_vulkan_info.device, win->src.swapchain, NULL);
-		vkDestroySurfaceKHR(RGFW_vulkan_info.instance, win->src.rSurf, NULL);
-		RGFW_FREE(win->src.swapchain_image_views);
-		RGFW_FREE(win->src.swapchain_images);
-#endif
-
-#ifdef RGFW_EGL
-		RGFW_closeEGL(win);
-#endif
-
-#if defined(RGFW_OSMESA) || defined(RGFW_BUFFER)
-		if (win->buffer != NULL) {
-			XDestroyImage((XImage*) win->src.bitmap);
-		}
-#endif
+		XDeleteProperty(event.xselection.display, event.xselection.requestor, event.xselection.property);
 
-		if ((Display*) win->src.display) {
-#ifdef RGFW_OPENGL
-			glXDestroyContext((Display*) win->src.display, win->src.rSurf);
-#endif
+		if (s != NULL && size != NULL)
+			*size = sizeN;
 
-			if (win == RGFW_root)
-				RGFW_root = NULL;
+		return s;
+	}
 
-			if ((Drawable) win->src.window)
-				XDestroyWindow((Display*) win->src.display, (Drawable) win->src.window); /* close the window*/
+	/*
+		almost all of this function is sourced from GLFW
+	*/
+	void RGFW_writeClipboard(const char* text, u32 textLen) {
+		static Atom CLIPBOARD = 0,
+			UTF8_STRING = 0,
+			SAVE_TARGETS = 0,
+			TARGETS = 0,
+			MULTIPLE = 0,
+			ATOM_PAIR = 0,
+			CLIPBOARD_MANAGER = 0;
 
-			if (win->src.display)
-				XCloseDisplay((Display*) win->src.display); /* kill the display*/
+		if (CLIPBOARD == 0) {
+			CLIPBOARD = XInternAtom((Display*) RGFW_root->src.display, "CLIPBOARD", False);
+			UTF8_STRING = XInternAtom((Display*) RGFW_root->src.display, "UTF8_STRING", False);
+			SAVE_TARGETS = XInternAtom((Display*) RGFW_root->src.display, "SAVE_TARGETS", False);
+			TARGETS = XInternAtom((Display*) RGFW_root->src.display, "TARGETS", False);
+			MULTIPLE = XInternAtom((Display*) RGFW_root->src.display, "MULTIPLE", False);
+			ATOM_PAIR = XInternAtom((Display*) RGFW_root->src.display, "ATOM_PAIR", False);
+			CLIPBOARD_MANAGER = XInternAtom((Display*) RGFW_root->src.display, "CLIPBOARD_MANAGER", False);
 		}
 
-#ifdef RGFW_ALLOC_DROPFILES
-		{
-			u32 i;
-			for (i = 0; i < RGFW_MAX_DROPS; i++)
-				RGFW_FREE(win->event.droppedFiles[i]);
+		XSetSelectionOwner((Display*) RGFW_root->src.display, CLIPBOARD, (Window) RGFW_root->src.window, CurrentTime);
 
+		XConvertSelection((Display*) RGFW_root->src.display, CLIPBOARD_MANAGER, SAVE_TARGETS, None, (Window) RGFW_root->src.window, CurrentTime);
 
-			RGFW_FREE(win->event.droppedFiles);
-		}
-#endif
+		for (;;) {
+			XEvent event;
 
-		RGFW_windowsOpen--;
-#if !defined(RGFW_NO_X11_CURSOR_PRELOAD) && !defined(RGFW_NO_X11_CURSOR)
-		if (X11Cursorhandle != NULL && RGFW_windowsOpen <= 0) {
-			dlclose(X11Cursorhandle);
+			XNextEvent((Display*) RGFW_root->src.display, &event);
+			if (event.type != SelectionRequest)
+				return;
 
-			X11Cursorhandle = NULL;
-		}
-#endif
+			const XSelectionRequestEvent* request = &event.xselectionrequest;
 
-		/* set cleared display / window to NULL for error checking */
-		win->src.display = (Display*) 0;
-		win->src.window = (Window) 0;
+			XEvent reply = { SelectionNotify };
 
-		u8 i;
-		for (i = 0; i < win->src.joystickCount; i++)
-			close(win->src.joysticks[i]);
+			char* selectionString = NULL;
+			const Atom formats[] = { UTF8_STRING, XA_STRING };
+			const i32 formatCount = sizeof(formats) / sizeof(formats[0]);
 
-		RGFW_FREE(win); /* free collected window data */
-	}
+			selectionString = (char*) text;
 
-	void RGFW_window_move(RGFW_window* win, RGFW_vector v) {
-		assert(win != NULL);
-		win->r.x = v.x;
-		win->r.y = v.y;
+			if (request->target == TARGETS) {
+				const Atom targets[] = { TARGETS,
+										MULTIPLE,
+										UTF8_STRING,
+										XA_STRING };
 
-		XMoveWindow((Display*) win->src.display, (Window) win->src.window, v.x, v.y);
-	}
+				XChangeProperty((Display*) RGFW_root->src.display,
+					request->requestor,
+					request->property,
+					4,
+					32,
+					PropModeReplace,
+					(u8*) targets,
+					sizeof(targets) / sizeof(targets[0]));
 
+				reply.xselection.property = request->property;
+			}
 
-	void RGFW_window_resize(RGFW_window* win, RGFW_area a) {
-		assert(win != NULL);
-		win->r.w = a.w;
-		win->r.h = a.h;
-
-		XResizeWindow((Display*) win->src.display, (Window) win->src.window, a.w, a.h);
-	}
-
-	void RGFW_window_setMinSize(RGFW_window* win, RGFW_area a) {
-		assert(win != NULL);
+			if (request->target == MULTIPLE) {
 
-		XSizeHints hints;
-		long flags;
+				Atom* targets;
 
-		XGetWMNormalHints(win->src.display, (Window) win->src.window, &hints, &flags);
+				Atom actualType;
+				i32 actualFormat;
+				u64 count, bytesAfter;
 
-		hints.flags |= PMinSize;
+				XGetWindowProperty((Display*) RGFW_root->src.display, request->requestor, request->property, 0, LONG_MAX, False, ATOM_PAIR, &actualType, &actualFormat, &count, &bytesAfter, (u8**) &targets);
 
-		hints.min_width = a.w;
-		hints.min_height = a.h;
+				u64 i;
+				for (i = 0; i < count; i += 2) {
+					i32 j;
 
-		XSetWMNormalHints(win->src.display, (Window) win->src.window, &hints);
-	}
+					for (j = 0; j < formatCount; j++) {
+						if (targets[i] == formats[j])
+							break;
+					}
 
-	void RGFW_window_setMaxSize(RGFW_window* win, RGFW_area a) {
-		assert(win != NULL);
+					if (j < formatCount)
+					{
+						XChangeProperty((Display*) RGFW_root->src.display,
+							request->requestor,
+							targets[i + 1],
+							targets[i],
+							8,
+							PropModeReplace,
+							(u8*) selectionString,
+							textLen);
+					} else
+						targets[i + 1] = None;
+				}
 
-		XSizeHints hints;
-		long flags;
+				XChangeProperty((Display*) RGFW_root->src.display,
+					request->requestor,
+					request->property,
+					ATOM_PAIR,
+					32,
+					PropModeReplace,
+					(u8*) targets,
+					count);
 
-		XGetWMNormalHints(win->src.display, (Window) win->src.window, &hints, &flags);
+				XFree(targets);
 
-		hints.flags |= PMaxSize;
+				reply.xselection.property = request->property;
+			}
 
-		hints.max_width = a.w;
-		hints.max_height = a.h;
+			reply.xselection.display = request->display;
+			reply.xselection.requestor = request->requestor;
+			reply.xselection.selection = request->selection;
+			reply.xselection.target = request->target;
+			reply.xselection.time = request->time;
 
-		XSetWMNormalHints(win->src.display, (Window) win->src.window, &hints);
+			XSendEvent((Display*) RGFW_root->src.display, request->requestor, False, 0, &reply);
+		}
 	}
 
-
-	void RGFW_window_minimize(RGFW_window* win) {
+	u16 RGFW_registerJoystick(RGFW_window* win, i32 jsNumber) {
 		assert(win != NULL);
 
-		XIconifyWindow(win->src.display, (Window) win->src.window, DefaultScreen(win->src.display));
-		XFlush(win->src.display);
+#ifdef __linux__
+		char file[15];
+		sprintf(file, "/dev/input/js%i", jsNumber);
+
+		return RGFW_registerJoystickF(win, file);
+#endif
 	}
 
-	void RGFW_window_restore(RGFW_window* win) {
+	u16 RGFW_registerJoystickF(RGFW_window* win, char* file) {
 		assert(win != NULL);
 
-		XMapWindow(win->src.display, (Window) win->src.window);
-		XFlush(win->src.display);
-	}
+#ifdef __linux__
 
-	void RGFW_window_setName(RGFW_window* win, char* name) {
-		assert(win != NULL);
+		i32 js = open(file, O_RDONLY);
 
-		XStoreName((Display*) win->src.display, (Window) win->src.window, name);
-	}
+		if (js && win->src.joystickCount < 4) {
+			win->src.joystickCount++;
 
-	/*
-		the majority function is sourced from GLFW
-	*/
+			win->src.joysticks[win->src.joystickCount - 1] = open(file, O_RDONLY);
 
-	void RGFW_window_setIcon(RGFW_window* win, u8* icon, RGFW_area a, i32 channels) {
-		assert(win != NULL);
+			u8 i;
+			for (i = 0; i < 16; i++)
+				win->src.jsPressed[win->src.joystickCount - 1][i] = 0;
 
-		i32 longCount = 2 + a.w * a.h;
+		}
 
-		u64* X11Icon = (u64*) RGFW_MALLOC(longCount * sizeof(u64));
-		u64* target = X11Icon;
+		else {
+#ifdef RGFW_PRINT_ERRORS
+			RGFW_error = 1;
+			fprintf(stderr, "Error RGFW_registerJoystickF : Cannot open file %s\n", file);
+#endif
+		}
 
-		*target++ = a.w;
-		*target++ = a.h;
+		return win->src.joystickCount - 1;
+#endif
+	}
 
-		u32 i;
+	u8 RGFW_window_isFullscreen(RGFW_window* win) {
+		assert(win != NULL);
 
-		for (i = 0; i < a.w * a.h; i++) {
-			if (channels == 3)
-				*target++ = ((icon[i * 3 + 0]) << 16) |
-				((icon[i * 3 + 1]) << 8) |
-				((icon[i * 3 + 2]) << 0) |
-				(0xFF << 24);
+		XWindowAttributes windowAttributes;
+		XGetWindowAttributes(win->src.display, (Window) win->src.window, &windowAttributes);
 
-			else if (channels == 4)
-				*target++ = ((icon[i * 4 + 0]) << 16) |
-				((icon[i * 4 + 1]) << 8) |
-				((icon[i * 4 + 2]) << 0) |
-				((icon[i * 4 + 3]) << 24);
-		}
+		/* check if the window is visable */
+		if (windowAttributes.map_state != IsViewable)
+			return 0;
 
-		static Atom NET_WM_ICON = 0;
-		if (NET_WM_ICON == 0)
-			NET_WM_ICON = XInternAtom((Display*) win->src.display, "_NET_WM_ICON", False);
+		/* check if the window covers the full screen */
+		return (windowAttributes.x == 0 && windowAttributes.y == 0 &&
+			windowAttributes.width == XDisplayWidth(win->src.display, DefaultScreen(win->src.display)) &&
+			windowAttributes.height == XDisplayHeight(win->src.display, DefaultScreen(win->src.display)));
+	}
 
-		XChangeProperty((Display*) win->src.display, (Window) win->src.window,
-			NET_WM_ICON,
-			6, 32,
-			PropModeReplace,
-			(u8*) X11Icon,
-			longCount);
+	u8 RGFW_window_isHidden(RGFW_window* win) {
+		assert(win != NULL);
 
-		RGFW_FREE(X11Icon);
+		XWindowAttributes windowAttributes;
+		XGetWindowAttributes(win->src.display, (Window) win->src.window, &windowAttributes);
 
-		XFlush((Display*) win->src.display);
+		return (windowAttributes.map_state == IsUnmapped && !RGFW_window_isMinimized(win));
 	}
 
-	void RGFW_window_setMouse(RGFW_window* win, u8* image, RGFW_area a, i32 channels) {
+	u8 RGFW_window_isMinimized(RGFW_window* win) {
 		assert(win != NULL);
 
-#ifndef RGFW_NO_X11_CURSOR
-		XcursorImage* native = XcursorImageCreate(a.w, a.h);
-		native->xhot = 0;
-		native->yhot = 0;
+		static Atom prop = 0;
+		if (prop == 0)
+			prop = XInternAtom(win->src.display, "WM_STATE", False);
 
-		u8* source = (u8*) image;
-		XcursorPixel* target = native->pixels;
+		Atom actual_type;
+		i32 actual_format;
+		u64 nitems, bytes_after;
+		unsigned char* prop_data;
 
-		u32 i;
-		for (i = 0; i < a.w * a.h; i++, target++, source += 4) {
-			u8 alpha = 0xFF;
-			if (channels == 4)
-				alpha = source[3];
+		i16 status = XGetWindowProperty(win->src.display, (Window) win->src.window, prop, 0, 2, False,
+			AnyPropertyType, &actual_type, &actual_format,
+			&nitems, &bytes_after, &prop_data);
 
-			*target = (alpha << 24) | (((source[0] * alpha) / 255) << 16) | (((source[1] * alpha) / 255) << 8) | (((source[2] * alpha) / 255) << 0);
+		if (status == Success && nitems >= 1 && *((int*) prop_data) == IconicState) {
+			XFree(prop_data);
+			return 1;
 		}
 
-		Cursor cursor = XcursorImageLoadCursor((Display*) win->src.display, native);
-		XDefineCursor((Display*) win->src.display, (Window) win->src.window, (Cursor) cursor);
+		if (prop_data != NULL)
+			XFree(prop_data);
 
-		XFreeCursor((Display*) win->src.display, (Cursor) cursor);
-		XcursorImageDestroy(native);
-#else
-	RGFW_UNUSED(image) RGFW_UNUSED(a.w) RGFW_UNUSED(channels)
-#endif
+		return 0;
 	}
 
-	void RGFW_window_moveMouse(RGFW_window* win, RGFW_vector v) {
+	u8 RGFW_window_isMaximized(RGFW_window* win) {
 		assert(win != NULL);
 
-		XEvent event;
-		XQueryPointer(win->src.display, DefaultRootWindow(win->src.display),
-			&event.xbutton.root, &event.xbutton.window,
-			&event.xbutton.x_root, &event.xbutton.y_root,
-			&event.xbutton.x, &event.xbutton.y,
-			&event.xbutton.state);
-
-		if (event.xbutton.x == v.x && event.xbutton.y == v.y)
-			return;
+		static Atom net_wm_state = 0;
+		static Atom net_wm_state_maximized_horz = 0;
+		static Atom net_wm_state_maximized_vert = 0;
 
-		XWarpPointer(win->src.display, None, None, 0, 0, 0, 0, -event.xbutton.x, -event.xbutton.y);
-		XWarpPointer(win->src.display, None, None, 0, 0, 0, 0, v.x, v.y);
-	}
+		if (net_wm_state == 0) {
+			net_wm_state = XInternAtom(win->src.display, "_NET_WM_STATE", False);
+			net_wm_state_maximized_vert = XInternAtom(win->src.display, "_NET_WM_STATE_MAXIMIZED_VERT", False);
+			net_wm_state_maximized_horz = XInternAtom(win->src.display, "_NET_WM_STATE_MAXIMIZED_HORZ", False);
+		}
 
-	RGFWDEF void RGFW_window_disableMouse(RGFW_window* win) {
-		RGFW_UNUSED(win);
-	}
+		Atom actual_type;
+		i32 actual_format;
+		u64 nitems, bytes_after;
+		unsigned char* prop_data;
 
-	void RGFW_window_setMouseDefault(RGFW_window* win) {
-		RGFW_window_setMouseStandard(win, RGFW_MOUSE_ARROW);
-	}
+		i16 status = XGetWindowProperty(win->src.display, (Window) win->src.window, net_wm_state, 0, 1024, False,
+			XA_ATOM, &actual_type, &actual_format,
+			&nitems, &bytes_after, &prop_data);
 
-	void RGFW_window_setMouseStandard(RGFW_window* win, u8 mouse) {
-		assert(win != NULL);
+		if (status != Success) {
+			if (prop_data != NULL)
+				XFree(prop_data);
 
-		if (mouse > (sizeof(RGFW_mouseIconSrc) / sizeof(u8)))
-			return;
-		
-		mouse = RGFW_mouseIconSrc[mouse];
+			return 0;
+		}
 
-		Cursor cursor = XCreateFontCursor((Display*) win->src.display, mouse);
-		XDefineCursor((Display*) win->src.display, (Window) win->src.window, (Cursor) cursor);
+		Atom* atoms = (Atom*) prop_data;
+		u64 i;
+		for (i = 0; i < nitems; ++i) {
+			if (atoms[i] == net_wm_state_maximized_horz ||
+				atoms[i] == net_wm_state_maximized_vert) {
+				XFree(prop_data);
+				return 1;
+			}
+		}
 
-		XFreeCursor((Display*) win->src.display, (Cursor) cursor);
+		return 0;
 	}
 
-	void RGFW_window_hide(RGFW_window* win) {
-		XMapWindow(win->src.display, win->src.window);
-	}
-
-	void RGFW_window_show(RGFW_window* win) {
-		XUnmapWindow(win->src.display, win->src.window);
-	}
+	static void XGetSystemContentScale(Display* display, float* xscale, float* yscale) {
+		float xdpi = 96.f, ydpi = 96.f;
 
-	/*
-		the majority function is sourced from GLFW
-	*/
-	char* RGFW_readClipboard(size_t* size) {
-		static Atom UTF8 = 0;
-		if (UTF8 == 0)
-			UTF8 = XInternAtom(RGFW_root->src.display, "UTF8_STRING", True);
+#ifndef RGFW_NO_DPI
+		char* rms = XResourceManagerString(display);
+		XrmDatabase db = NULL;
 
-		XEvent event;
-		int format;
-		unsigned long N, sizeN;
-		char* data, * s = NULL;
-		Atom target;
-		Atom CLIPBOARD = 0, XSEL_DATA = 0;
+		if (rms && db)
+			db = XrmGetStringDatabase(rms);
 
-		if (CLIPBOARD == 0) {
-			CLIPBOARD = XInternAtom(RGFW_root->src.display, "CLIPBOARD", 0);
-			XSEL_DATA = XInternAtom(RGFW_root->src.display, "XSEL_DATA", 0);
+		if (db == 0) {
+			*xscale = xdpi / 96.f;
+			*yscale = ydpi / 96.f;
+			return;
 		}
 
-		XConvertSelection(RGFW_root->src.display, CLIPBOARD, UTF8, XSEL_DATA, RGFW_root->src.window, CurrentTime);
-		XSync(RGFW_root->src.display, 0);
-		XNextEvent(RGFW_root->src.display, &event);
+		XrmValue value;
+		char* type = NULL;
 
-		if (event.type != SelectionNotify || event.xselection.selection != CLIPBOARD || event.xselection.property == 0)
-			return NULL;
+		if (XrmGetResource(db, "Xft.dpi", "Xft.Dpi", &type, &value) && type && strncmp(type, "String", 7) == 0)
+			xdpi = ydpi = atof(value.addr);
+		XrmDestroyDatabase(db);
+#endif
 
-		XGetWindowProperty(event.xselection.display, event.xselection.requestor,
-			event.xselection.property, 0L, (~0L), 0, AnyPropertyType, &target,
-			&format, &sizeN, &N, (unsigned char**) &data);
+		* xscale = xdpi / 96.f;
+		*yscale = ydpi / 96.f;
+	}
 
-		if (target == UTF8 || target == XA_STRING) {
-			s = (char*)RGFW_MALLOC(sizeof(char) * sizeN);
-			strcpy(s, data);
-			XFree(data);
-		}
+	RGFW_monitor RGFW_XCreateMonitor(i32 screen) {
+		RGFW_monitor monitor;
 
-		XDeleteProperty(event.xselection.display, event.xselection.requestor, event.xselection.property);
+		Display* display = XOpenDisplay(NULL);
 
-		if (s != NULL && size != NULL)
-			*size = sizeN;
+		monitor.rect = RGFW_RECT(0, 0, DisplayWidth(display, screen), DisplayHeight(display, screen));
+		monitor.physW = (monitor.rect.w * 25.4f / 96.f);
+		monitor.physH = (monitor.rect.h * 25.4f / 96.f);
 
-		return s;
-	}
+		strncpy(monitor.name, DisplayString(display), 128);
 
-	/*
-		almost all of this function is sourced from GLFW
-	*/
-	void RGFW_writeClipboard(const char* text, u32 textLen) {
-		static Atom CLIPBOARD = 0,
-			UTF8_STRING = 0,
-			SAVE_TARGETS = 0,
-			TARGETS = 0,
-			MULTIPLE = 0,
-			ATOM_PAIR = 0,
-			CLIPBOARD_MANAGER = 0;
+		XGetSystemContentScale(display, &monitor.scaleX, &monitor.scaleY);
 
-		if (CLIPBOARD == 0) {
-			CLIPBOARD = XInternAtom((Display*) RGFW_root->src.display, "CLIPBOARD", False);
-			UTF8_STRING = XInternAtom((Display*) RGFW_root->src.display, "UTF8_STRING", False);
-			SAVE_TARGETS = XInternAtom((Display*) RGFW_root->src.display, "SAVE_TARGETS", False);
-			TARGETS = XInternAtom((Display*) RGFW_root->src.display, "TARGETS", False);
-			MULTIPLE = XInternAtom((Display*) RGFW_root->src.display, "MULTIPLE", False);
-			ATOM_PAIR = XInternAtom((Display*) RGFW_root->src.display, "ATOM_PAIR", False);
-			CLIPBOARD_MANAGER = XInternAtom((Display*) RGFW_root->src.display, "CLIPBOARD_MANAGER", False);
-		}
+		XRRScreenResources* sr = XRRGetScreenResourcesCurrent(display, RootWindow(display, screen));
 
-		XSetSelectionOwner((Display*) RGFW_root->src.display, CLIPBOARD, (Window) RGFW_root->src.window, CurrentTime);
+		XRRCrtcInfo* ci = NULL;
+		int crtc = 0;
 
-		XConvertSelection((Display*) RGFW_root->src.display, CLIPBOARD_MANAGER, SAVE_TARGETS, None, (Window) RGFW_root->src.window, CurrentTime);
+		if (sr->ncrtc > crtc) {
+			ci = XRRGetCrtcInfo(display, sr, sr->crtcs[crtc]);
+		}
 
-		for (;;) {
-			XEvent event;
+		if (ci == NULL) {
+			XRRFreeScreenResources(sr);
+			XCloseDisplay(display);
+			return monitor;
+		}
 
-			XNextEvent((Display*) RGFW_root->src.display, &event);
-			if (event.type != SelectionRequest)
-				return;
+		monitor.rect.x = ci->x;
+		monitor.rect.y = ci->y;
 
-			const XSelectionRequestEvent* request = &event.xselectionrequest;
+		XRRFreeCrtcInfo(ci);
+		XRRFreeScreenResources(sr);
 
-			XEvent reply = { SelectionNotify };
+		XCloseDisplay(display);
 
-			char* selectionString = NULL;
-			const Atom formats[] = { UTF8_STRING, XA_STRING };
-			const i32 formatCount = sizeof(formats) / sizeof(formats[0]);
+		return monitor;
+	}
 
-			selectionString = (char*) text;
+	RGFW_monitor RGFW_monitors[6];
+	RGFW_monitor* RGFW_getMonitors(void) {
+		size_t i;
+		for (i = 0; i < (size_t)ScreenCount(RGFW_root->src.display) && i < 6; i++)
+			RGFW_monitors[i] = RGFW_XCreateMonitor(i);
 
-			if (request->target == TARGETS) {
-				const Atom targets[] = { TARGETS,
-										MULTIPLE,
-										UTF8_STRING,
-										XA_STRING };
+		return RGFW_monitors;
+	}
 
-				XChangeProperty((Display*) RGFW_root->src.display,
-					request->requestor,
-					request->property,
-					4,
-					32,
-					PropModeReplace,
-					(u8*) targets,
-					sizeof(targets) / sizeof(targets[0]));
+	RGFW_monitor RGFW_getPrimaryMonitor(void) {
+		assert(RGFW_root != NULL);
 
-				reply.xselection.property = request->property;
+		i32 primary = -1;
+		Window root = DefaultRootWindow(RGFW_root->src.display);
+		XRRScreenResources* res = XRRGetScreenResources(RGFW_root->src.display, root);
+
+		for (int i = 0; i < res->noutput; i++) {
+			XRROutputInfo* output_info = XRRGetOutputInfo(RGFW_root->src.display, res, res->outputs[i]);
+			if (output_info->connection == RR_Connected && output_info->crtc) {
+				XRRCrtcInfo* crtc_info = XRRGetCrtcInfo(RGFW_root->src.display, res, output_info->crtc);
+				if (crtc_info->mode != None && crtc_info->x == 0 && crtc_info->y == 0) {
+					primary = i;
+					XRRFreeCrtcInfo(crtc_info);
+					XRRFreeOutputInfo(output_info);
+					break;
+				}
+				XRRFreeCrtcInfo(crtc_info);
 			}
+			XRRFreeOutputInfo(output_info);
+		}
 
-			if (request->target == MULTIPLE) {
+		XRRFreeScreenResources(res);
 
-				Atom* targets;
+		return RGFW_XCreateMonitor(primary);
+	}
 
-				Atom actualType;
-				i32 actualFormat;
-				u64 count, bytesAfter;
+	RGFW_monitor RGFW_window_getMonitor(RGFW_window* win) {
+		return RGFW_XCreateMonitor(DefaultScreen(win->src.display));
+	}
 
-				XGetWindowProperty((Display*) RGFW_root->src.display, request->requestor, request->property, 0, LONG_MAX, False, ATOM_PAIR, &actualType, &actualFormat, &count, &bytesAfter, (u8**) &targets);
+	#ifdef RGFW_OPENGL
+	void RGFW_window_makeCurrent_OpenGL(RGFW_window* win) {
+		assert(win != NULL);
 
-				u64 i;
-				for (i = 0; i < count; i += 2) {
-					i32 j;
+		glXMakeCurrent((Display*) win->src.display, (Drawable) win->src.window, (GLXContext) win->src.rSurf);
+	}
+	#endif
 
-					for (j = 0; j < formatCount; j++) {
-						if (targets[i] == formats[j])
-							break;
-					}
 
-					if (j < formatCount)
-					{
-						XChangeProperty((Display*) RGFW_root->src.display,
-							request->requestor,
-							targets[i + 1],
-							targets[i],
-							8,
-							PropModeReplace,
-							(u8*) selectionString,
-							textLen);
-					} else
-						targets[i + 1] = None;
-				}
+	void RGFW_window_swapBuffers(RGFW_window* win) {
+		assert(win != NULL);
 
-				XChangeProperty((Display*) RGFW_root->src.display,
-					request->requestor,
-					request->property,
-					ATOM_PAIR,
-					32,
-					PropModeReplace,
-					(u8*) targets,
-					count);
+		RGFW_window_makeCurrent(win);
 
-				XFree(targets);
+		/* clear the window*/
+		if (!(win->src.winArgs & RGFW_NO_CPU_RENDER)) {
+#if defined(RGFW_OSMESA) || defined(RGFW_BUFFER)
+			#ifdef RGFW_OSMESA
+			RGFW_OSMesa_reorganize();
+			#endif
+			RGFW_area area = RGFW_bufferSize;
 
-				reply.xselection.property = request->property;
-			}
+#ifndef RGFW_X11_DONT_CONVERT_BGR
+			win->src.bitmap->data = (char*) win->buffer;
+			u32 x, y;
+			for (y = 0; y < (u32)win->r.h; y++) {
+				for (x = 0; x < (u32)win->r.w; x++) {
+					u32 index = (y * 4 * area.w) + x * 4;
 
-			reply.xselection.display = request->display;
-			reply.xselection.requestor = request->requestor;
-			reply.xselection.selection = request->selection;
-			reply.xselection.target = request->target;
-			reply.xselection.time = request->time;
+					u8 red = win->src.bitmap->data[index];
+					win->src.bitmap->data[index] = win->buffer[index + 2];
+					win->src.bitmap->data[index + 2] = red;
 
-			XSendEvent((Display*) RGFW_root->src.display, request->requestor, False, 0, &reply);
+				}
+			}
+#endif	
+			XPutImage(win->src.display, (Window) win->src.window, win->src.gc, win->src.bitmap, 0, 0, 0, 0, RGFW_bufferSize.w, RGFW_bufferSize.h);
+#endif
+		}
+
+		if (!(win->src.winArgs & RGFW_NO_GPU_RENDER)) {
+			#ifdef RGFW_EGL
+					eglSwapBuffers(win->src.EGL_display, win->src.EGL_surface);
+			#elif defined(RGFW_OPENGL)
+					glXSwapBuffers((Display*) win->src.display, (Window) win->src.window);
+			#endif
 		}
+
+		RGFW_window_checkFPS(win);
 	}
 
-	u16 RGFW_registerJoystick(RGFW_window* win, i32 jsNumber) {
+	#if !defined(RGFW_EGL)	
+	void RGFW_window_swapInterval(RGFW_window* win, i32 swapInterval) {
 		assert(win != NULL);
 
-#ifdef __linux__
-		char file[15];
-		sprintf(file, "/dev/input/js%i", jsNumber);
+		#if defined(RGFW_OPENGL)	
+		((PFNGLXSWAPINTERVALEXTPROC) glXGetProcAddress((GLubyte*) "glXSwapIntervalEXT"))((Display*) win->src.display, (Window) win->src.window, swapInterval);
+		#endif
 
-		return RGFW_registerJoystickF(win, file);
-#endif
+		win->fpsCap = (swapInterval == 1) ? 0 : swapInterval;
 	}
+	#endif
 
-	u16 RGFW_registerJoystickF(RGFW_window* win, char* file) {
-		assert(win != NULL);
-
-#ifdef __linux__
 
-		i32 js = open(file, O_RDONLY);
-
-		if (js && win->src.joystickCount < 4) {
-			win->src.joystickCount++;
-
-			win->src.joysticks[win->src.joystickCount - 1] = open(file, O_RDONLY);
-
-			u8 i;
-			for (i = 0; i < 16; i++)
-				win->src.jsPressed[win->src.joystickCount - 1][i] = 0;
+	void RGFW_window_close(RGFW_window* win) {
+		assert(win != NULL);
+#ifdef RGFW_EGL
+		RGFW_closeEGL(win);
+#endif
 
+#if defined(RGFW_OSMESA) || defined(RGFW_BUFFER)
+		if (win->buffer != NULL) {
+			XDestroyImage((XImage*) win->src.bitmap);
+			XFreeGC(win->src.display, win->src.gc);
 		}
-
-		else {
-#ifdef RGFW_PRINT_ERRORS
-			RGFW_error = 1;
-			fprintf(stderr, "Error RGFW_registerJoystickF : Cannot open file %s\n", file);
 #endif
-		}
 
-		return win->src.joystickCount - 1;
+		if ((Display*) win->src.display) {
+#ifdef RGFW_OPENGL
+			glXDestroyContext((Display*) win->src.display, win->src.rSurf);
 #endif
-	}
-
-	u8 RGFW_window_isFullscreen(RGFW_window* win) {
-		assert(win != NULL);
-
-		XWindowAttributes windowAttributes;
-		XGetWindowAttributes(win->src.display, (Window) win->src.window, &windowAttributes);
-
-		/* check if the window is visable */
-		if (windowAttributes.map_state != IsViewable)
-			return 0;
-
-		/* check if the window covers the full screen */
-		return (windowAttributes.x == 0 && windowAttributes.y == 0 &&
-			windowAttributes.width == XDisplayWidth(win->src.display, DefaultScreen(win->src.display)) &&
-			windowAttributes.height == XDisplayHeight(win->src.display, DefaultScreen(win->src.display)));
-	}
-
-	u8 RGFW_window_isHidden(RGFW_window* win) {
-		assert(win != NULL);
-
-		XWindowAttributes windowAttributes;
-		XGetWindowAttributes(win->src.display, (Window) win->src.window, &windowAttributes);
-
-		return (windowAttributes.map_state == IsUnmapped && !RGFW_window_isMinimized(win));
-	}
-
-	u8 RGFW_window_isMinimized(RGFW_window* win) {
-		assert(win != NULL);
-
-		static Atom prop = 0;
-		if (prop == 0)
-			prop = XInternAtom(win->src.display, "WM_STATE", False);
-
-		Atom actual_type;
-		i32 actual_format;
-		u64 nitems, bytes_after;
-		unsigned char* prop_data;
 
-		i16 status = XGetWindowProperty(win->src.display, (Window) win->src.window, prop, 0, 2, False,
-			AnyPropertyType, &actual_type, &actual_format,
-			&nitems, &bytes_after, &prop_data);
+			if (win == RGFW_root)
+				RGFW_root = NULL;
 
-		if (status == Success && nitems >= 1 && *((int*) prop_data) == IconicState) {
-			XFree(prop_data);
-			return 1;
+			if ((Drawable) win->src.window)
+				XDestroyWindow((Display*) win->src.display, (Drawable) win->src.window); /* close the window*/
+			
+			XCloseDisplay((Display*) win->src.display); /* kill the display*/
 		}
 
-		if (prop_data != NULL)
-			XFree(prop_data);
-
-		return 0;
-	}
-
-	u8 RGFW_window_isMaximized(RGFW_window* win) {
-		assert(win != NULL);
+#ifdef RGFW_ALLOC_DROPFILES
+		{
+			u32 i;
+			for (i = 0; i < RGFW_MAX_DROPS; i++)
+				RGFW_FREE(win->event.droppedFiles[i]);
 
-		static Atom net_wm_state = 0;
-		static Atom net_wm_state_maximized_horz = 0;
-		static Atom net_wm_state_maximized_vert = 0;
 
-		if (net_wm_state == 0) {
-			net_wm_state = XInternAtom(win->src.display, "_NET_WM_STATE", False);
-			net_wm_state_maximized_vert = XInternAtom(win->src.display, "_NET_WM_STATE_MAXIMIZED_VERT", False);
-			net_wm_state_maximized_horz = XInternAtom(win->src.display, "_NET_WM_STATE_MAXIMIZED_HORZ", False);
+			RGFW_FREE(win->event.droppedFiles);
 		}
+#endif
 
-		Atom actual_type;
-		i32 actual_format;
-		u64 nitems, bytes_after;
-		unsigned char* prop_data;
-
-		i16 status = XGetWindowProperty(win->src.display, (Window) win->src.window, net_wm_state, 0, 1024, False,
-			XA_ATOM, &actual_type, &actual_format,
-			&nitems, &bytes_after, &prop_data);
-
-		if (status != Success) {
-			if (prop_data != NULL)
-				XFree(prop_data);
-
-			return 0;
-		}
+		RGFW_windowsOpen--;
+#if !defined(RGFW_NO_X11_CURSOR_PRELOAD) && !defined(RGFW_NO_X11_CURSOR)
+		if (X11Cursorhandle != NULL && RGFW_windowsOpen <= 0) {
+			dlclose(X11Cursorhandle);
 
-		Atom* atoms = (Atom*) prop_data;
-		u64 i;
-		for (i = 0; i < nitems; ++i) {
-			if (atoms[i] == net_wm_state_maximized_horz ||
-				atoms[i] == net_wm_state_maximized_vert) {
-				XFree(prop_data);
-				return 1;
-			}
+			X11Cursorhandle = NULL;
 		}
+#endif
 
-		return 0;
-	}
-
-	static void XGetSystemContentScale(Display* display, float* xscale, float* yscale) {
-		float xdpi = 96.f, ydpi = 96.f;
-
-#ifndef RGFW_NO_DPI
-		char* rms = XResourceManagerString(display);
-		XrmDatabase db = NULL;
-
-		if (rms && db)
-			db = XrmGetStringDatabase(rms);
-
-		if (db == 0) {
-			*xscale = xdpi / 96.f;
-			*yscale = ydpi / 96.f;
-			return;
+		if (RGFW_libxshape != NULL && RGFW_windowsOpen <= 0) {
+			dlclose(RGFW_libxshape);
+			RGFW_libxshape = NULL;
 		}
 
-		XrmValue value;
-		char* type = NULL;
+		/* set cleared display / window to NULL for error checking */
+		win->src.display = (Display*) 0;
+		win->src.window = (Window) 0;
 
-		if (XrmGetResource(db, "Xft.dpi", "Xft.Dpi", &type, &value) && type && strcmp(type, "String") == 0)
-			xdpi = ydpi = atof(value.addr);
-		XrmDestroyDatabase(db);
-#endif
+		u8 i;
+		for (i = 0; i < win->src.joystickCount; i++)
+			close(win->src.joysticks[i]);
 
-		* xscale = xdpi / 96.f;
-		*yscale = ydpi / 96.f;
+		RGFW_FREE(win); /* free collected window data */
 	}
 
-	RGFW_monitor RGFW_XCreateMonitor(i32 screen) {
-		RGFW_monitor monitor;
-
-		Display* display = XOpenDisplay(NULL);
-
-		monitor.rect = RGFW_RECT(0, 0, DisplayWidth(display, screen), DisplayHeight(display, screen));
-		monitor.physW = (monitor.rect.w * 25.4f / 96.f);
-		monitor.physH = (monitor.rect.h * 25.4f / 96.f);
-
-		strcpy(monitor.name, DisplayString(display));
-
-		XGetSystemContentScale(display, &monitor.scaleX, &monitor.scaleY);
-
-		XRRScreenResources* sr = XRRGetScreenResourcesCurrent(display, RootWindow(display, screen));
-
-		XRRCrtcInfo* ci = NULL;
-		int crtc = 0;
-
-		if (sr->ncrtc > crtc) {
-			ci = XRRGetCrtcInfo(display, sr, sr->crtcs[crtc]);
-		}
+	u64 	RGFW_getTimeNS(void) { 
+		struct timespec ts = { 0 };
+		clock_gettime(1, &ts);
+		unsigned long long int nanoSeconds = (unsigned long long int)ts.tv_sec*1000000000LLU + (unsigned long long int)ts.tv_nsec;
 
-		if (ci == NULL) {
-			XRRFreeScreenResources(sr);
-			XCloseDisplay(display);
-			return monitor;
-		}
+		return nanoSeconds;
+	}
 
-		monitor.rect.x = ci->x;
-		monitor.rect.y = ci->y;
+	u64 RGFW_getTime(void) {
+		struct timespec ts = { 0 };
+		clock_gettime(1, &ts);
+		unsigned long long int nanoSeconds = (unsigned long long int)ts.tv_sec*1000000000LLU + (unsigned long long int)ts.tv_nsec;
 
-		XRRFreeCrtcInfo(ci);
-		XRRFreeScreenResources(sr);
+		return (double)(nanoSeconds) * 1e-9;
+	}
+/* 
+	End of linux / unix defines
+*/
 
-		XCloseDisplay(display);
+#endif /* RGFW_X11 */
 
-		return monitor;
-	}
 
-	RGFW_monitor RGFW_monitors[6];
-	RGFW_monitor* RGFW_getMonitors(void) {
-		size_t i;
-		for (i = 0; i < (size_t)ScreenCount(RGFW_root->src.display) && i < 6; i++)
-			RGFW_monitors[i] = RGFW_XCreateMonitor(i);
+/*
 
-		return RGFW_monitors;
-	}
+	Start of Windows defines
 
-	RGFW_monitor RGFW_getPrimaryMonitor(void) {
-		assert(RGFW_root != NULL);
 
-		i32 primary = -1;
-		Window root = DefaultRootWindow(RGFW_root->src.display);
-		XRRScreenResources* res = XRRGetScreenResources(RGFW_root->src.display, root);
+*/
 
-		for (int i = 0; i < res->noutput; i++) {
-			XRROutputInfo* output_info = XRRGetOutputInfo(RGFW_root->src.display, res, res->outputs[i]);
-			if (output_info->connection == RR_Connected && output_info->crtc) {
-				XRRCrtcInfo* crtc_info = XRRGetCrtcInfo(RGFW_root->src.display, res, output_info->crtc);
-				if (crtc_info->mode != None && crtc_info->x == 0 && crtc_info->y == 0) {
-					primary = i;
-					XRRFreeCrtcInfo(crtc_info);
-					XRRFreeOutputInfo(output_info);
-					break;
-				}
-				XRRFreeCrtcInfo(crtc_info);
-			}
-			XRRFreeOutputInfo(output_info);
-		}
+#ifdef RGFW_WINDOWS
+	#include <processthreadsapi.h>
+	#include <wchar.h>
+	#include <locale.h>
+	#include <windowsx.h>
+	#include <shellapi.h>
+	#include <shellscalingapi.h>
+	#include <windows.h>
+	#include <winuser.rh>
+
+	#ifndef RGFW_NO_XINPUT
+	typedef DWORD (WINAPI * PFN_XInputGetState)(DWORD,XINPUT_STATE*);
+	PFN_XInputGetState XInputGetStateSRC = NULL;
+	#define XInputGetState XInputGetStateSRC
 
-		XRRFreeScreenResources(res);
+	typedef DWORD (WINAPI * PFN_XInputGetKeystroke)(DWORD, DWORD, PXINPUT_KEYSTROKE);
+	PFN_XInputGetKeystroke XInputGetKeystrokeSRC = NULL;
+	#define XInputGetKeystroke XInputGetKeystrokeSRC
 
-		return RGFW_XCreateMonitor(primary);
-	}
+	static HMODULE RGFW_XInput_dll = NULL;
+	#endif
 
-	RGFW_monitor RGFW_window_getMonitor(RGFW_window* win) {
-		return RGFW_XCreateMonitor(DefaultScreen(win->src.display));
-	}
-#endif
+	u32 RGFW_mouseIconSrc[] = {OCR_NORMAL, OCR_NORMAL, OCR_IBEAM, OCR_CROSS, OCR_HAND, OCR_SIZEWE, OCR_SIZENS, OCR_SIZENWSE, OCR_SIZENESW, OCR_SIZEALL, OCR_NO};
 
-#ifdef RGFW_WINDOWS
 	char* createUTF8FromWideStringWin32(const WCHAR* source);
 
 #define GL_FRONT				0x0404
@@ -4064,21 +3610,18 @@ RGFW_UNUSED(win); /* if buffer rendering is not being used */
 	void* RGFWjoystickApi = NULL;
 
 	/* these two wgl functions need to be preloaded */
-	typedef long long int (WINAPI* wglCreateContextAttribsARB_type)(HDC hdc, HGLRC hShareContext,
-		const int* attribList);
-	wglCreateContextAttribsARB_type wglCreateContextAttribsARB = NULL;
+	typedef HGLRC (WINAPI *PFNWGLCREATECONTEXTATTRIBSARBPROC)(HDC hdc, HGLRC hglrc, const int *attribList);
+	PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB = NULL;
 
 	/* defines for creating ARB attributes */
 #define WGL_NUMBER_PIXEL_FORMATS_ARB 0x2000
 #define WGL_CONTEXT_MAJOR_VERSION_ARB             0x2091
 #define WGL_CONTEXT_MINOR_VERSION_ARB             0x2092
-#define WGL_TRANSPARENT_ARB   					  0x200A
 #define WGL_DRAW_TO_WINDOW_ARB                    0x2001
 #define WGL_ACCELERATION_ARB                      0x2003
 #define WGL_NO_ACCELERATION_ARB 0x2025
 #define WGL_SUPPORT_OPENGL_ARB                    0x2010
 #define WGL_DOUBLE_BUFFER_ARB                     0x2011
-#define WGL_PIXEL_TYPE_ARB                        0x2013
 #define WGL_COLOR_BITS_ARB                        0x2014
 #define WGL_RED_BITS_ARB 0x2015
 #define WGL_RED_SHIFT_ARB 0x2016
@@ -4099,7 +3642,6 @@ RGFW_UNUSED(win); /* if buffer rendering is not being used */
 #define WGL_DEPTH_BITS_ARB                        0x2022
 #define WGL_STENCIL_BITS_ARB 					  0x2023
 #define WGL_FULL_ACCELERATION_ARB                 0x2027
-#define WGL_TYPE_RGBA_ARB                         0x202B
 #define WGL_CONTEXT_FLAGS_ARB                     0x2094
 #define WGL_CONTEXT_PROFILE_MASK_ARB              0x9126
 #define WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002
@@ -4144,7 +3686,7 @@ static HMODULE wglinstance = NULL;
 		return (void*) GetProcAddress(wglinstance, procname); 
 	}
 
-	typedef u64 (APIENTRY* PFNWGLCHOOSEPIXELFORMATARBPROC)(HDC hdc, const int* piAttribIList, const FLOAT* pfAttribFList, UINT nMaxFormats, int* piFormats, UINT* nNumFormats);
+	typedef HRESULT (APIENTRY* PFNWGLCHOOSEPIXELFORMATARBPROC)(HDC hdc, const int* piAttribIList, const FLOAT* pfAttribFList, UINT nMaxFormats, int* piFormats, UINT* nNumFormats);
 	static PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormatARB = NULL;
 #endif
 
@@ -4169,11 +3711,14 @@ static HMODULE wglinstance = NULL;
 	
 	#ifndef RGFW_NO_DPI
 	static HMODULE RGFW_Shcore_dll = NULL;
-	typedef u64 (WINAPI * PFN_GetDpiForMonitor)(HMONITOR,MONITOR_DPI_TYPE,UINT*,UINT*);
+	typedef HRESULT (WINAPI * PFN_GetDpiForMonitor)(HMONITOR,MONITOR_DPI_TYPE,UINT*,UINT*);
 	PFN_GetDpiForMonitor GetDpiForMonitorSRC = NULL;
 	#define GetDpiForMonitor GetDpiForMonitorSRC
 	#endif
 
+	__declspec(dllimport) u32 __stdcall timeBeginPeriod(u32 uPeriod);
+
+	#ifndef RGFW_NO_XINPUT
 	void RGFW_loadXInput(void) {
 		u32 i;
 		static const char* names[] = { 
@@ -4188,22 +3733,76 @@ static HMODULE wglinstance = NULL;
 			RGFW_XInput_dll = LoadLibraryA(names[i]);
 
 			if (RGFW_XInput_dll) {
-				XInputGetStateSRC = (PFN_XInputGetState)GetProcAddress(RGFW_XInput_dll, "XInputGetState");
+				XInputGetStateSRC = (PFN_XInputGetState)(void*)GetProcAddress(RGFW_XInput_dll, "XInputGetState");
 			
 				if (XInputGetStateSRC == NULL)
 					printf("Failed to load XInputGetState");
 			}
 		}
 	}
+	#endif
 
-	RGFW_window* RGFW_createWindow(const char* name, RGFW_rect rect, u16 args) {
-		if (RGFW_XInput_dll == NULL)
-			RGFW_loadXInput();
-		
-		#ifndef RGFW_NO_DPI
-		if (RGFW_Shcore_dll == NULL) {
+	RGFWDEF void RGFW_init_buffer(RGFW_window* win);
+	void RGFW_init_buffer(RGFW_window* win) {
+#if defined(RGFW_OSMESA) || defined(RGFW_BUFFER)
+	if (RGFW_bufferSize.w == 0 && RGFW_bufferSize.h == 0)
+		RGFW_bufferSize = RGFW_getScreenSize();
+	
+	BITMAPV5HEADER bi = { 0 };
+	ZeroMemory(&bi, sizeof(bi));
+	bi.bV5Size = sizeof(bi);
+	bi.bV5Width = RGFW_bufferSize.w;
+	bi.bV5Height = -((LONG) RGFW_bufferSize.h);
+	bi.bV5Planes = 1;
+	bi.bV5BitCount = 32;
+	bi.bV5Compression = BI_BITFIELDS;
+	bi.bV5BlueMask = 0x00ff0000;
+	bi.bV5GreenMask = 0x0000ff00;
+	bi.bV5RedMask = 0x000000ff;
+	bi.bV5AlphaMask = 0xff000000;
+
+	win->src.bitmap = CreateDIBSection(win->src.hdc,
+		(BITMAPINFO*) &bi,
+		DIB_RGB_COLORS,
+		(void**) &win->buffer,
+		NULL,
+		(DWORD) 0);
+	
+	win->src.hdcMem = CreateCompatibleDC(win->src.hdc);
+
+	#if defined(RGFW_OSMESA)
+	win->src.rSurf = OSMesaCreateContext(OSMESA_RGBA, NULL);
+	OSMesaMakeCurrent(win->src.rSurf, win->buffer, GL_UNSIGNED_BYTE, win->r.w, win->r.h);
+	#endif
+#else
+RGFW_UNUSED(win); /* if buffer rendering is not being used */
+#endif
+	}
+
+	void RGFW_window_setDND(RGFW_window* win, b8 allow) {
+		DragAcceptFiles(win->src.window, allow);
+	}
+
+	void RGFW_clipCursor(RGFW_rect rect) {
+		if (!rect.x && !rect.y && rect.w && !rect.h) {
+			ClipCursor(NULL);
+			return;
+		}
+
+		RECT r = {rect.x, rect.y, rect.x + rect.w, rect.y + rect.h};
+		ClipCursor(&r);
+	}
+
+	RGFW_window* RGFW_createWindow(const char* name, RGFW_rect rect, u16 args) {
+		#ifndef RGFW_NO_XINPUT
+		if (RGFW_XInput_dll == NULL)
+			RGFW_loadXInput();
+		#endif
+
+		#ifndef RGFW_NO_DPI
+		if (RGFW_Shcore_dll == NULL) {
 			RGFW_Shcore_dll = LoadLibraryA("shcore.dll");
-			GetDpiForMonitorSRC = (PFN_GetDpiForMonitor)GetProcAddress(RGFW_Shcore_dll, "GetDpiForMonitor");
+			GetDpiForMonitorSRC = (PFN_GetDpiForMonitor)(void*)GetProcAddress(RGFW_Shcore_dll, "GetDpiForMonitor");
 		}
 		#endif
 
@@ -4219,1126 +3818,1640 @@ static HMODULE wglinstance = NULL;
 #endif
 		}
 
-		if (name[0] == 0) name = (char*) " ";
+		timeBeginPeriod(1);
+
+		if (name[0] == 0) name = (char*) " ";
+
+		RGFW_eventWindow.r = RGFW_RECT(-1, -1, -1, -1);
+		RGFW_eventWindow.src.window = NULL;
+
+		RGFW_window* win = RGFW_window_basic_init(rect, args);
+
+		win->src.maxSize = RGFW_AREA(0, 0);
+		win->src.minSize = RGFW_AREA(0, 0);
+
+
+		HINSTANCE inh = GetModuleHandleA(NULL);
+
+		WNDCLASSA Class = { 0 }; /* Setup the Window class. */
+		Class.lpszClassName = name;
+		Class.hInstance = inh;
+		Class.hCursor = LoadCursor(NULL, IDC_ARROW);
+		Class.lpfnWndProc = WndProc;
+
+		RegisterClassA(&Class);
+
+		DWORD window_style = WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
+
+		RECT windowRect, clientRect;
+
+		if (!(args & RGFW_NO_BORDER)) {
+			window_style |= WS_CAPTION | WS_SYSMENU | WS_BORDER | WS_VISIBLE | WS_MINIMIZEBOX;
+
+			if (!(args & RGFW_NO_RESIZE))
+				window_style |= WS_SIZEBOX | WS_MAXIMIZEBOX | WS_THICKFRAME;
+		} else
+			window_style |= WS_POPUP | WS_VISIBLE | WS_SYSMENU | WS_MINIMIZEBOX;
+
+		HWND dummyWin = CreateWindowA(Class.lpszClassName, name, window_style, win->r.x, win->r.y, win->r.w, win->r.h, 0, 0, inh, 0);
+
+		GetWindowRect(dummyWin, &windowRect);
+		GetClientRect(dummyWin, &clientRect);
+
+		win->src.hOffset = (windowRect.bottom - windowRect.top) - (clientRect.bottom - clientRect.top);
+		win->src.window = CreateWindowA(Class.lpszClassName, name, window_style, win->r.x, win->r.y, win->r.w, win->r.h + win->src.hOffset, 0, 0, inh, 0);
+
+		if (args & RGFW_ALLOW_DND) {
+			win->src.winArgs |= RGFW_ALLOW_DND;
+			RGFW_window_setDND(win, 1);
+		}
+		win->src.hdc = GetDC(win->src.window);
+
+		if ((args & RGFW_NO_INIT_API) == 0) {
+#ifdef RGFW_DIRECTX
+		assert(FAILED(CreateDXGIFactory(&__uuidof(IDXGIFactory), (void**) &RGFW_dxInfo.pFactory)) == 0);
+
+		if (FAILED(RGFW_dxInfo.pFactory->lpVtbl->EnumAdapters(RGFW_dxInfo.pFactory, 0, &RGFW_dxInfo.pAdapter))) {
+			fprintf(stderr, "Failed to enumerate DXGI adapters\n");
+			RGFW_dxInfo.pFactory->lpVtbl->Release(RGFW_dxInfo.pFactory);
+			return NULL;
+		}
+
+		D3D_FEATURE_LEVEL featureLevels[] = { D3D_FEATURE_LEVEL_11_0 };
+
+		if (FAILED(D3D11CreateDevice(RGFW_dxInfo.pAdapter, D3D_DRIVER_TYPE_UNKNOWN, NULL, 0, featureLevels, 1, D3D11_SDK_VERSION, &RGFW_dxInfo.pDevice, NULL, &RGFW_dxInfo.pDeviceContext))) {
+			fprintf(stderr, "Failed to create Direct3D device\n");
+			RGFW_dxInfo.pAdapter->lpVtbl->Release(RGFW_dxInfo.pAdapter);
+			RGFW_dxInfo.pFactory->lpVtbl->Release(RGFW_dxInfo.pFactory);
+			return NULL;
+		}
+
+		DXGI_SWAP_CHAIN_DESC swapChainDesc = { 0 };
+		swapChainDesc.BufferCount = 1;
+		swapChainDesc.BufferDesc.Width = win->r.w;
+		swapChainDesc.BufferDesc.Height = win->r.h;
+		swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
+		swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
+		swapChainDesc.OutputWindow = win->src.window;
+		swapChainDesc.SampleDesc.Count = 1;
+		swapChainDesc.SampleDesc.Quality = 0;
+		swapChainDesc.Windowed = TRUE;
+		RGFW_dxInfo.pFactory->lpVtbl->CreateSwapChain(RGFW_dxInfo.pFactory, (IUnknown*) RGFW_dxInfo.pDevice, &swapChainDesc, &win->src.swapchain);
+
+		ID3D11Texture2D* pBackBuffer;
+		win->src.swapchain->lpVtbl->GetBuffer(win->src.swapchain, 0, &__uuidof(ID3D11Texture2D), (LPVOID*) &pBackBuffer);
+		RGFW_dxInfo.pDevice->lpVtbl->CreateRenderTargetView(RGFW_dxInfo.pDevice, (ID3D11Resource*) pBackBuffer, NULL, &win->src.renderTargetView);
+		pBackBuffer->lpVtbl->Release(pBackBuffer);
+
+		D3D11_TEXTURE2D_DESC depthStencilDesc = { 0 };
+		depthStencilDesc.Width = win->r.w;
+		depthStencilDesc.Height = win->r.h;
+		depthStencilDesc.MipLevels = 1;
+		depthStencilDesc.ArraySize = 1;
+		depthStencilDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
+		depthStencilDesc.SampleDesc.Count = 1;
+		depthStencilDesc.SampleDesc.Quality = 0;
+		depthStencilDesc.Usage = D3D11_USAGE_DEFAULT;
+		depthStencilDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
+
+		ID3D11Texture2D* pDepthStencilTexture = NULL;
+		RGFW_dxInfo.pDevice->lpVtbl->CreateTexture2D(RGFW_dxInfo.pDevice, &depthStencilDesc, NULL, &pDepthStencilTexture);
+
+		D3D11_DEPTH_STENCIL_VIEW_DESC depthStencilViewDesc = { 0 };
+		depthStencilViewDesc.Format = depthStencilDesc.Format;
+		depthStencilViewDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
+		depthStencilViewDesc.Texture2D.MipSlice = 0;
+
+		RGFW_dxInfo.pDevice->lpVtbl->CreateDepthStencilView(RGFW_dxInfo.pDevice, (ID3D11Resource*) pDepthStencilTexture, &depthStencilViewDesc, &win->src.pDepthStencilView);
+
+		pDepthStencilTexture->lpVtbl->Release(pDepthStencilTexture);
+
+		RGFW_dxInfo.pDeviceContext->lpVtbl->OMSetRenderTargets(RGFW_dxInfo.pDeviceContext, 1, &win->src.renderTargetView, win->src.pDepthStencilView);
+#endif
+
+#ifdef RGFW_OPENGL 
+		HDC dummy_dc = GetDC(dummyWin);
+
+		PIXELFORMATDESCRIPTOR pfd = {
+			.nSize = sizeof(pfd),
+			.nVersion = 1,
+			.iPixelType = PFD_TYPE_RGBA,
+			.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
+			.cColorBits = 24,
+			.cAlphaBits = 8,
+			.iLayerType = PFD_MAIN_PLANE,
+			.cDepthBits = 32,
+			.cStencilBits = 8,
+		};
+
+		int pixel_format = ChoosePixelFormat(dummy_dc, &pfd);
+		SetPixelFormat(dummy_dc, pixel_format, &pfd);
+
+		HGLRC dummy_context = wglCreateContext(dummy_dc);
+		wglMakeCurrent(dummy_dc, dummy_context);
+
+		if (wglChoosePixelFormatARB == NULL) {
+			wglCreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC) (void*) wglGetProcAddress("wglCreateContextAttribsARB");
+			wglChoosePixelFormatARB = (PFNWGLCHOOSEPIXELFORMATARBPROC) (void*)wglGetProcAddress("wglChoosePixelFormatARB");
+		}
+
+		wglMakeCurrent(dummy_dc, 0);
+		wglDeleteContext(dummy_context);
+		ReleaseDC(dummyWin, dummy_dc);
+
+		if (wglCreateContextAttribsARB != NULL) {
+			PIXELFORMATDESCRIPTOR pfd = (PIXELFORMATDESCRIPTOR){ sizeof(pfd), 1, PFD_TYPE_RGBA, PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, 32, 8, PFD_MAIN_PLANE, 24, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+
+			if (args & RGFW_OPENGL_SOFTWARE)
+				pfd.dwFlags |= PFD_GENERIC_FORMAT | PFD_GENERIC_ACCELERATED;
+
+			if (wglChoosePixelFormatARB != NULL) {
+				i32* pixel_format_attribs = (i32*)RGFW_initAttribs(args & RGFW_OPENGL_SOFTWARE);
+
+				int pixel_format;
+				UINT num_formats;
+				wglChoosePixelFormatARB(win->src.hdc, pixel_format_attribs, 0, 1, &pixel_format, &num_formats);
+				if (!num_formats) {
+					printf("Failed to set the OpenGL 3.3 pixel format.\n");
+				}
+
+				DescribePixelFormat(win->src.hdc, pixel_format, sizeof(pfd), &pfd);
+				if (!SetPixelFormat(win->src.hdc, pixel_format, &pfd)) {
+					printf("Failed to set the OpenGL 3.3 pixel format.\n");
+				}
+			}
+
+			u32 index = 0;
+			i32 attribs[40];
+
+			SET_ATTRIB(WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB);
+
+			if (RGFW_majorVersion || RGFW_minorVersion) {
+				SET_ATTRIB(WGL_CONTEXT_MAJOR_VERSION_ARB, RGFW_majorVersion);
+				SET_ATTRIB(WGL_CONTEXT_MINOR_VERSION_ARB, RGFW_minorVersion);
+			}
+
+			SET_ATTRIB(WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB);
+
+			if (RGFW_majorVersion || RGFW_minorVersion) {
+				SET_ATTRIB(WGL_CONTEXT_MAJOR_VERSION_ARB, RGFW_majorVersion);
+				SET_ATTRIB(WGL_CONTEXT_MINOR_VERSION_ARB, RGFW_minorVersion);
+			}
+
+			SET_ATTRIB(0, 0);
+
+			win->src.rSurf = (HGLRC)wglCreateContextAttribsARB(win->src.hdc, NULL, attribs);
+		} else {
+			fprintf(stderr, "Failed to create an accelerated OpenGL Context\n");
+
+			int pixel_format = ChoosePixelFormat(win->src.hdc, &pfd);
+			SetPixelFormat(win->src.hdc, pixel_format, &pfd);
+
+			win->src.rSurf = wglCreateContext(win->src.hdc);
+		}
+		
+		wglMakeCurrent(win->src.hdc, win->src.rSurf);
+#endif
+	}
+
+#ifdef RGFW_OSMESA
+#ifdef RGFW_LINK_OSM ESA
+		OSMesaMakeCurrentSource = (PFN_OSMesaMakeCurrent) GetProcAddress(win->src.hdc, "OSMesaMakeCurrent");
+		OSMesaCreateContextSource = (PFN_OSMesaCreateContext) GetProcAddress(win->src.hdc, "OSMesaCreateContext");
+		OSMesaDestroyContextSource = (PFN_OSMesaDestroyContext) GetProcAddress(win->src.hdc, "OSMesaDestroyContext");
+#endif
+#endif
+
+#ifdef RGFW_OPENGL
+		if ((args & RGFW_NO_INIT_API) == 0) {
+			ReleaseDC(win->src.window, win->src.hdc);
+			win->src.hdc = GetDC(win->src.window);
+			wglMakeCurrent(win->src.hdc, win->src.rSurf);
+		}
+#endif
+
+		DestroyWindow(dummyWin);
+		RGFW_init_buffer(win);
+
+
+		#ifndef RGFW_NO_MONITOR
+		if (args & RGFW_SCALE_TO_MONITOR)
+			RGFW_window_scaleToMonitor(win);
+		#endif
+
+#ifdef RGFW_EGL
+		if ((args & RGFW_NO_INIT_API) == 0)
+			RGFW_createOpenGLContext(win);
+#endif
+
+		if (args & RGFW_HIDE_MOUSE)
+			RGFW_window_showMouse(win, 0);
+
+		if (args & RGFW_TRANSPARENT_WINDOW) {
+			SetWindowLong(win->src.window, GWL_EXSTYLE, GetWindowLong(win->src.window, GWL_EXSTYLE) | WS_EX_LAYERED);
+			SetLayeredWindowAttributes(win->src.window, RGB(255, 255, 255), RGFW_ALPHA, LWA_ALPHA);
+		}
+
+		ShowWindow(win->src.window, SW_SHOWNORMAL);
+		
+		if (RGFW_root == NULL)
+			RGFW_root = win;
+		
+		#ifdef RGFW_OPENGL
+		else 
+			wglShareLists(RGFW_root->src.rSurf, win->src.rSurf);
+		#endif
+
+		return win;
+	}
+
+	void RGFW_window_setBorder(RGFW_window* win, u8 border) {
+		DWORD style = GetWindowLong(win->src.window, GWL_STYLE);
+
+		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 {
+			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
+			);
+		}
+	}
+
+
+	RGFW_area RGFW_getScreenSize(void) {
+		return RGFW_AREA(GetDeviceCaps(GetDC(NULL), HORZRES), GetDeviceCaps(GetDC(NULL), VERTRES));
+	}
+
+	RGFW_vector RGFW_getGlobalMousePoint(void) {
+		POINT p;
+		GetCursorPos(&p);
+
+		return RGFW_VECTOR(p.x, p.y);
+	}
+
+	RGFW_vector RGFW_window_getMousePoint(RGFW_window* win) {
+		POINT p;
+		GetCursorPos(&p);
+		ScreenToClient(win->src.window, &p);
+
+		return RGFW_VECTOR(p.x, p.y);
+	}
+
+	void RGFW_window_setMinSize(RGFW_window* win, RGFW_area a) {
+		assert(win != NULL);
+		win->src.minSize = a;
+	}
+
+	void RGFW_window_setMaxSize(RGFW_window* win, RGFW_area a) {
+		assert(win != NULL);
+		win->src.maxSize = a;
+	}
+
+
+	void RGFW_window_minimize(RGFW_window* win) {
+		assert(win != NULL);
+
+		ShowWindow(win->src.window, SW_MINIMIZE);
+	}
+
+	void RGFW_window_restore(RGFW_window* win) {
+		assert(win != NULL);
+
+		ShowWindow(win->src.window, SW_RESTORE);
+	}
+
+
+	u8 RGFW_xinput2RGFW[] = {
+		RGFW_JS_A, /* or PS X button */
+		RGFW_JS_B, /* or PS circle button */
+		RGFW_JS_X, /* or PS square button */
+		RGFW_JS_Y, /* or PS triangle button */
+		RGFW_JS_R1, /* right bumper */
+		RGFW_JS_L1, /* left bump */
+		RGFW_JS_L2, /* left trigger*/
+		RGFW_JS_R2, /* right trigger */
+		0, 0, 0, 0, 0, 0, 0, 0,
+		RGFW_JS_UP, /* dpad up */
+		RGFW_JS_DOWN, /* dpad down*/
+		RGFW_JS_LEFT, /* dpad left */
+		RGFW_JS_RIGHT, /* dpad right */
+		RGFW_JS_START, /* start button */
+		RGFW_JS_SELECT/* select button */
+	};
+
+	static i32 RGFW_checkXInput(RGFW_window* win, RGFW_Event* e) {
+		size_t i;
+		for (i = 0; i < 4; i++) {
+			XINPUT_KEYSTROKE keystroke;
+
+			if (XInputGetKeystroke == NULL)
+				return 0;
+
+			DWORD result = XInputGetKeystroke((DWORD)i, 0, &keystroke);
+
+			if ((keystroke.Flags & XINPUT_KEYSTROKE_REPEAT) == 0 && result != ERROR_EMPTY) {
+				if (result != ERROR_SUCCESS)
+					return 0;
+
+				if (keystroke.VirtualKey > VK_PAD_BACK)
+					continue;
+
+				// RGFW_jsButtonPressed + 1 = RGFW_jsButtonReleased
+				e->type = RGFW_jsButtonPressed + !(keystroke.Flags & XINPUT_KEYSTROKE_KEYDOWN);
+				e->button = RGFW_xinput2RGFW[keystroke.VirtualKey - 0x5800];
+				win->src.jsPressed[i][e->button] = !(keystroke.Flags & XINPUT_KEYSTROKE_KEYDOWN);
+
+				return 1;
+			}
+
+			XINPUT_STATE state;
+			if (XInputGetState == NULL ||
+				XInputGetState((DWORD) i, &state) == ERROR_DEVICE_NOT_CONNECTED
+			)
+				return 0;
+#define INPUT_DEADZONE  ( 0.24f * (float)(0x7FFF) )  // Default to 24% of the +/- 32767 range.   This is a reasonable default value but can be altered if needed.
+
+			if ((state.Gamepad.sThumbLX < INPUT_DEADZONE &&
+				state.Gamepad.sThumbLX > -INPUT_DEADZONE) &&
+				(state.Gamepad.sThumbLY < INPUT_DEADZONE &&
+					state.Gamepad.sThumbLY > -INPUT_DEADZONE))
+			{
+				state.Gamepad.sThumbLX = 0;
+				state.Gamepad.sThumbLY = 0;
+			}
+
+			if ((state.Gamepad.sThumbRX < INPUT_DEADZONE &&
+				state.Gamepad.sThumbRX > -INPUT_DEADZONE) &&
+				(state.Gamepad.sThumbRY < INPUT_DEADZONE &&
+					state.Gamepad.sThumbRY > -INPUT_DEADZONE))
+			{
+				state.Gamepad.sThumbRX = 0;
+				state.Gamepad.sThumbRY = 0;
+			}
+
+			e->axisesCount = 2;
+			RGFW_vector axis1 = RGFW_VECTOR(state.Gamepad.sThumbLX, state.Gamepad.sThumbLY);
+			RGFW_vector axis2 = RGFW_VECTOR(state.Gamepad.sThumbRX, state.Gamepad.sThumbRY);
+
+			if (axis1.x != e->axis[0].x || axis1.y != e->axis[0].y || axis2.x != e->axis[1].x || axis2.y != e->axis[1].y) {
+				e->type = RGFW_jsAxisMove;
+
+				e->axis[0] = axis1;
+				e->axis[1] = axis2;
+
+				return 1;
+			}
+
+			e->axis[0] = axis1;
+			e->axis[1] = axis2;
+		}
+
+		return 0;
+	}
+
+	RGFW_Event* RGFW_window_checkEvent(RGFW_window* win) {
+		assert(win != NULL);
+
+		if (win->event.type == RGFW_quit) {
+			return NULL;
+		}
+
+		MSG msg;
+
+		if (RGFW_eventWindow.src.window == win->src.window) {
+			if (RGFW_eventWindow.r.x != -1) {
+				win->r.x = RGFW_eventWindow.r.x;
+				win->r.y = RGFW_eventWindow.r.y;
+				win->event.type = RGFW_windowMoved;
+				RGFW_windowMoveCallback(win, win->r);
+			}
+
+			if (RGFW_eventWindow.r.w != -1) {
+				win->r.w = RGFW_eventWindow.r.w;
+				win->r.h = RGFW_eventWindow.r.h;
+				win->event.type = RGFW_windowResized;
+				RGFW_windowResizeCallback(win, win->r);
+			}
+
+			RGFW_eventWindow.src.window = NULL;
+			RGFW_eventWindow.r = RGFW_RECT(-1, -1, -1, -1);
+
+			return &win->event;
+		}
+
+
+		static HDROP drop;
+		
+		if (win->event.type == RGFW_dnd_init) {
+			if (win->event.droppedFilesCount) {
+				u32 i;
+				for (i = 0; i < win->event.droppedFilesCount; i++)
+					win->event.droppedFiles[i][0] = '\0';
+			}
+
+			win->event.droppedFilesCount = 0;
+			win->event.droppedFilesCount = DragQueryFileW(drop, 0xffffffff, NULL, 0);
+			//win->event.droppedFiles = (char**)RGFW_CALLOC(win->event.droppedFilesCount, sizeof(char*));
+
+			u32 i;
+			for (i = 0; i < win->event.droppedFilesCount; i++) {
+				const UINT length = DragQueryFileW(drop, i, NULL, 0);
+				WCHAR* buffer = (WCHAR*) RGFW_CALLOC((size_t) length + 1, sizeof(WCHAR));
+
+				DragQueryFileW(drop, i, buffer, length + 1);
+				strncpy(win->event.droppedFiles[i], createUTF8FromWideStringWin32(buffer), RGFW_MAX_PATH);
+				win->event.droppedFiles[i][RGFW_MAX_PATH - 1] = '\0';
+				RGFW_FREE(buffer);
+			}
+
+			DragFinish(drop);
+			RGFW_dndCallback(win, win->event.droppedFiles, win->event.droppedFilesCount);
+			
+			win->event.type = RGFW_dnd;
+			return &win->event;
+		}
+
+		win->event.inFocus = (GetForegroundWindow() == win->src.window);
+
+		if (RGFW_checkXInput(win, &win->event))
+			return &win->event;
+
+		static BYTE keyboardState[256];
+
+		if (PeekMessageA(&msg, win->src.window, 0u, 0u, PM_REMOVE)) {
+			switch (msg.message) {
+			case WM_CLOSE:
+			case WM_QUIT:
+				RGFW_windowQuitCallback(win);
+				win->event.type = RGFW_quit;
+				break;
+
+			case WM_ACTIVATE:
+				win->event.inFocus = (LOWORD(msg.wParam) == WA_INACTIVE);
+
+				if (win->event.inFocus) {
+					win->event.type = RGFW_focusIn;
+					RGFW_focusCallback(win, 1);
+				}
+				else {
+					win->event.type = RGFW_focusOut;
+					RGFW_focusCallback(win, 0);
+				}
+
+				break;
+			
+			case WM_PAINT:
+				win->event.type = RGFW_windowRefresh;
+				RGFW_windowRefreshCallback(win);
+				break;
+			
+			case WM_MOUSELEAVE:
+				win->event.type = RGFW_mouseLeave;
+				win->src.winArgs |= RGFW_MOUSE_LEFT;
+				RGFW_mouseNotifyCallBack(win, win->event.point, 0);
+				break;
+			
+			case WM_KEYUP: {
+				win->event.keyCode = RGFW_apiKeyCodeToRGFW((u32) msg.wParam);
+								
+				RGFW_keyboard[win->event.keyCode].prev = RGFW_isPressed(win, win->event.keyCode);
+
+				static char keyName[16];
+				
+				{
+					GetKeyNameTextA((LONG) msg.lParam, keyName, 16);
+
+					if ((!(GetKeyState(VK_CAPITAL) & 0x0001) && !(GetKeyState(VK_SHIFT) & 0x8000)) ||
+						((GetKeyState(VK_CAPITAL) & 0x0001) && (GetKeyState(VK_SHIFT) & 0x8000))) {
+						CharLowerBuffA(keyName, 16);
+					}
+				}
+
+				RGFW_updateLockState(win, (GetKeyState(VK_CAPITAL) & 0x0001), (GetKeyState(VK_NUMLOCK) & 0x0001));
 
-		RGFW_eventWindow.r = RGFW_RECT(-1, -1, -1, -1);
-		RGFW_eventWindow.src.window = NULL;
+				strncpy(win->event.keyName, keyName, 16);
 
-		RGFW_window* win = RGFW_window_basic_init(rect, args);
+				if (RGFW_isPressed(win, RGFW_ShiftL)) {
+					ToAscii((UINT) msg.wParam, MapVirtualKey((UINT) msg.wParam, MAPVK_VK_TO_CHAR),
+						keyboardState, (LPWORD) win->event.keyName, 0);
+				}
 
-		if (RGFW_root == NULL) {
-			RGFW_root = win;
-		}
-		
-		HINSTANCE inh = GetModuleHandleA(NULL);
+				win->event.type = RGFW_keyReleased;
+				RGFW_keyboard[win->event.keyCode].current = 0;
+				RGFW_keyCallback(win, win->event.keyCode, win->event.keyName, win->event.lockState, 0);
+				break;
+			}
+			case WM_KEYDOWN: {
+				win->event.keyCode = RGFW_apiKeyCodeToRGFW((u32) msg.wParam);
 
-		WNDCLASSA Class = { 0 }; /* Setup the Window class. */
-		Class.lpszClassName = name;
-		Class.hInstance = inh;
-		Class.hCursor = LoadCursor(NULL, IDC_ARROW);
-		Class.lpfnWndProc = WndProc;
+				RGFW_keyboard[win->event.keyCode].prev = RGFW_isPressed(win, win->event.keyCode);
 
-		RegisterClassA(&Class);
+				static char keyName[16];
+				
+				{
+					GetKeyNameTextA((LONG) msg.lParam, keyName, 16);
 
-		DWORD window_style = WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
+					if ((!(GetKeyState(VK_CAPITAL) & 0x0001) && !(GetKeyState(VK_SHIFT) & 0x8000)) ||
+						((GetKeyState(VK_CAPITAL) & 0x0001) && (GetKeyState(VK_SHIFT) & 0x8000))) {
+						CharLowerBuffA(keyName, 16);
+					}
+				}
+								
+				RGFW_updateLockState(win, (GetKeyState(VK_CAPITAL) & 0x0001), (GetKeyState(VK_NUMLOCK) & 0x0001));
 
-		RECT windowRect, clientRect;
+				strncpy(win->event.keyName, keyName, 16);
 
-		if (!(args & RGFW_NO_BORDER)) {
-			window_style |= WS_CAPTION | WS_SYSMENU | WS_BORDER | WS_VISIBLE | WS_MINIMIZEBOX;
+				if (RGFW_isPressed(win, RGFW_ShiftL) & 0x8000) {
+					ToAscii((UINT) msg.wParam, MapVirtualKey((UINT) msg.wParam, MAPVK_VK_TO_CHAR),
+						keyboardState, (LPWORD) win->event.keyName, 0);
+				}
 
-			if (!(args & RGFW_NO_RESIZE))
-				window_style |= WS_SIZEBOX | WS_MAXIMIZEBOX | WS_THICKFRAME;
-		} else
-			window_style |= WS_POPUP | WS_VISIBLE | WS_SYSMENU | WS_MINIMIZEBOX;
+				win->event.type = RGFW_keyPressed;
+				RGFW_keyboard[win->event.keyCode].current = 1;
+				RGFW_keyCallback(win, win->event.keyCode, win->event.keyName, win->event.lockState, 1);
+				break;
+			}
 
-		HWND dummyWin = CreateWindowA(Class.lpszClassName, name, window_style, win->r.x, win->r.y, win->r.w, win->r.h, 0, 0, inh, 0);
+			case WM_MOUSEMOVE:
+				win->event.type = RGFW_mousePosChanged;
 
-		GetWindowRect(dummyWin, &windowRect);
-		GetClientRect(dummyWin, &clientRect);
+				win->event.point.x = GET_X_LPARAM(msg.lParam);
+				win->event.point.y = GET_Y_LPARAM(msg.lParam);
 
-		win->src.hOffset = (windowRect.bottom - windowRect.top) - (clientRect.bottom - clientRect.top);
-		win->src.window = CreateWindowA(Class.lpszClassName, name, window_style, win->r.x, win->r.y, win->r.w, win->r.h + win->src.hOffset, 0, 0, inh, 0);
+				RGFW_mousePosCallback(win, win->event.point);
 
-		if (args & RGFW_TRANSPARENT_WINDOW) {
-			SetWindowLongA(win->src.window, GWL_EXSTYLE, GetWindowLongA(win->src.window, GWL_EXSTYLE) | WS_EX_LAYERED);
-		}
-		if (args & RGFW_ALLOW_DND) {
-			win->src.winArgs |= RGFW_ALLOW_DND;
-			DragAcceptFiles(win->src.window, TRUE);
-		}
-		win->src.hdc = GetDC(win->src.window);
+				if (win->src.winArgs & RGFW_MOUSE_LEFT) {
+					win->src.winArgs ^= RGFW_MOUSE_LEFT;
+					win->event.type = RGFW_mouseEnter;
+					RGFW_mouseNotifyCallBack(win, win->event.point, 1);
+				}
 
-#ifdef RGFW_DIRECTX
-		assert(FAILED(CreateDXGIFactory(&__uuidof(IDXGIFactory), (void**) &RGFW_dxInfo.pFactory)) == 0);
+				break;
 
-		if (FAILED(RGFW_dxInfo.pFactory->lpVtbl->EnumAdapters(RGFW_dxInfo.pFactory, 0, &RGFW_dxInfo.pAdapter))) {
-			fprintf(stderr, "Failed to enumerate DXGI adapters\n");
-			RGFW_dxInfo.pFactory->lpVtbl->Release(RGFW_dxInfo.pFactory);
-			return NULL;
-		}
+			case WM_LBUTTONDOWN:
+				win->event.button = RGFW_mouseLeft;
+				RGFW_mouseButtons_prev[win->event.button] = RGFW_mouseButtons[win->event.button];
+				RGFW_mouseButtons[win->event.button] = 1;
+				win->event.type = RGFW_mouseButtonPressed;
+				RGFW_mouseButtonCallback(win, win->event.button, win->event.scroll, 1);
+				break;
+			case WM_RBUTTONDOWN:
+				win->event.button = RGFW_mouseRight;
+				win->event.type = RGFW_mouseButtonPressed;
+				RGFW_mouseButtons_prev[win->event.button] = RGFW_mouseButtons[win->event.button];
+				RGFW_mouseButtons[win->event.button] = 1;
+				RGFW_mouseButtonCallback(win, win->event.button, win->event.scroll, 1);
+				break;
+			case WM_MBUTTONDOWN:
+				win->event.button = RGFW_mouseMiddle;
+				win->event.type = RGFW_mouseButtonPressed;
+				RGFW_mouseButtons_prev[win->event.button] = RGFW_mouseButtons[win->event.button];
+				RGFW_mouseButtons[win->event.button] = 1;
+				RGFW_mouseButtonCallback(win, win->event.button, win->event.scroll, 1);
+				break;
 
-		D3D_FEATURE_LEVEL featureLevels[] = { D3D_FEATURE_LEVEL_11_0 };
+			case WM_MOUSEWHEEL:
+				if (msg.wParam > 0)
+					win->event.button = RGFW_mouseScrollUp;
+				else
+					win->event.button = RGFW_mouseScrollDown;
 
-		if (FAILED(D3D11CreateDevice(RGFW_dxInfo.pAdapter, D3D_DRIVER_TYPE_UNKNOWN, NULL, 0, featureLevels, 1, D3D11_SDK_VERSION, &RGFW_dxInfo.pDevice, NULL, &RGFW_dxInfo.pDeviceContext))) {
-			fprintf(stderr, "Failed to create Direct3D device\n");
-			RGFW_dxInfo.pAdapter->lpVtbl->Release(RGFW_dxInfo.pAdapter);
-			RGFW_dxInfo.pFactory->lpVtbl->Release(RGFW_dxInfo.pFactory);
-			return NULL;
-		}
+				RGFW_mouseButtons_prev[win->event.button] = RGFW_mouseButtons[win->event.button];
+				RGFW_mouseButtons[win->event.button] = 1;
 
-		DXGI_SWAP_CHAIN_DESC swapChainDesc = { 0 };
-		swapChainDesc.BufferCount = 1;
-		swapChainDesc.BufferDesc.Width = win->r.w;
-		swapChainDesc.BufferDesc.Height = win->r.h;
-		swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
-		swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
-		swapChainDesc.OutputWindow = win->src.window;
-		swapChainDesc.SampleDesc.Count = 1;
-		swapChainDesc.SampleDesc.Quality = 0;
-		swapChainDesc.Windowed = TRUE;
-		RGFW_dxInfo.pFactory->lpVtbl->CreateSwapChain(RGFW_dxInfo.pFactory, (IUnknown*) RGFW_dxInfo.pDevice, &swapChainDesc, &win->src.swapchain);
+				win->event.scroll = (SHORT) HIWORD(msg.wParam) / (double) WHEEL_DELTA;
 
-		ID3D11Texture2D* pBackBuffer;
-		win->src.swapchain->lpVtbl->GetBuffer(win->src.swapchain, 0, &__uuidof(ID3D11Texture2D), (LPVOID*) &pBackBuffer);
-		RGFW_dxInfo.pDevice->lpVtbl->CreateRenderTargetView(RGFW_dxInfo.pDevice, (ID3D11Resource*) pBackBuffer, NULL, &win->src.renderTargetView);
-		pBackBuffer->lpVtbl->Release(pBackBuffer);
+				win->event.type = RGFW_mouseButtonPressed;
+				RGFW_mouseButtonCallback(win, win->event.button, win->event.scroll, 1);
+				break;
 
-		D3D11_TEXTURE2D_DESC depthStencilDesc = { 0 };
-		depthStencilDesc.Width = win->r.w;
-		depthStencilDesc.Height = win->r.h;
-		depthStencilDesc.MipLevels = 1;
-		depthStencilDesc.ArraySize = 1;
-		depthStencilDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
-		depthStencilDesc.SampleDesc.Count = 1;
-		depthStencilDesc.SampleDesc.Quality = 0;
-		depthStencilDesc.Usage = D3D11_USAGE_DEFAULT;
-		depthStencilDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
+			case WM_LBUTTONUP:
+			
+				win->event.button = RGFW_mouseLeft;
+				win->event.type = RGFW_mouseButtonReleased;
 
-		ID3D11Texture2D* pDepthStencilTexture = NULL;
-		RGFW_dxInfo.pDevice->lpVtbl->CreateTexture2D(RGFW_dxInfo.pDevice, &depthStencilDesc, NULL, &pDepthStencilTexture);
+				RGFW_mouseButtons_prev[win->event.button] = RGFW_mouseButtons[win->event.button];
+				RGFW_mouseButtons[win->event.button] = 0;
+				RGFW_mouseButtonCallback(win, win->event.button, win->event.scroll, 0);
+				break;
+			case WM_RBUTTONUP:
+				win->event.button = RGFW_mouseRight;
+				win->event.type = RGFW_mouseButtonReleased;
 
-		D3D11_DEPTH_STENCIL_VIEW_DESC depthStencilViewDesc = { 0 };
-		depthStencilViewDesc.Format = depthStencilDesc.Format;
-		depthStencilViewDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
-		depthStencilViewDesc.Texture2D.MipSlice = 0;
+				RGFW_mouseButtons_prev[win->event.button] = RGFW_mouseButtons[win->event.button];
+				RGFW_mouseButtons[win->event.button] = 0;
+				RGFW_mouseButtonCallback(win, win->event.button, win->event.scroll, 0);
+				break;
+			case WM_MBUTTONUP:
+				win->event.button = RGFW_mouseMiddle;
+				win->event.type = RGFW_mouseButtonReleased;
 
-		RGFW_dxInfo.pDevice->lpVtbl->CreateDepthStencilView(RGFW_dxInfo.pDevice, (ID3D11Resource*) pDepthStencilTexture, &depthStencilViewDesc, &win->src.pDepthStencilView);
+				RGFW_mouseButtons_prev[win->event.button] = RGFW_mouseButtons[win->event.button];
+				RGFW_mouseButtons[win->event.button] = 0;
+				RGFW_mouseButtonCallback(win, win->event.button, win->event.scroll, 0);
+				break;
 
-		pDepthStencilTexture->lpVtbl->Release(pDepthStencilTexture);
+				/*
+					much of this event is source from glfw
+				*/
+			case WM_DROPFILES: {				
+				win->event.type = RGFW_dnd_init;
 
-		RGFW_dxInfo.pDeviceContext->lpVtbl->OMSetRenderTargets(RGFW_dxInfo.pDeviceContext, 1, &win->src.renderTargetView, win->src.pDepthStencilView);
-#endif
+				drop = (HDROP) msg.wParam;
+				POINT pt;
 
-#ifdef RGFW_OPENGL 
-		HDC dummy_dc = GetDC(dummyWin);
+				/* Move the mouse to the position of the drop */
+				DragQueryPoint(drop, &pt);
 
-		PIXELFORMATDESCRIPTOR pfd = {
-			.nSize = sizeof(pfd),
-			.nVersion = 1,
-			.iPixelType = PFD_TYPE_RGBA,
-			.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
-			.cColorBits = 32,
-			.cAlphaBits = 8,
-			.iLayerType = PFD_MAIN_PLANE,
-			.cDepthBits = 24,
-			.cStencilBits = 8,
-		};
+				win->event.point.x = pt.x;
+				win->event.point.y = pt.y;
 
-		int pixel_format = ChoosePixelFormat(dummy_dc, &pfd);
-		SetPixelFormat(dummy_dc, pixel_format, &pfd);
+				RGFW_dndInitCallback(win, win->event.point);
+			}
+				break;
+			case WM_GETMINMAXINFO:
+			{
+				if (win->src.maxSize.w == 0 && win->src.maxSize.h == 0)
+					break;
 
-		HGLRC dummy_context = wglCreateContext(dummy_dc);
-		wglMakeCurrent(dummy_dc, dummy_context);
+				MINMAXINFO* mmi = (MINMAXINFO*) msg.lParam;
+				mmi->ptMinTrackSize.x = win->src.minSize.w;
+				mmi->ptMinTrackSize.y = win->src.minSize.h;
+				mmi->ptMaxTrackSize.x = win->src.maxSize.w;
+				mmi->ptMaxTrackSize.y = win->src.maxSize.h;
+				return 0;
+			}
+			default:
+				win->event.type = 0;
+				break;
+			}
 
-		if (wglChoosePixelFormatARB == NULL) {
-			wglCreateContextAttribsARB = (wglCreateContextAttribsARB_type) wglGetProcAddress("wglCreateContextAttribsARB");
-			wglChoosePixelFormatARB = (PFNWGLCHOOSEPIXELFORMATARBPROC) wglGetProcAddress("wglChoosePixelFormatARB");
+			TranslateMessage(&msg);
+			DispatchMessageA(&msg);
 		}
 
-		wglMakeCurrent(dummy_dc, 0);
-		wglDeleteContext(dummy_context);
-		ReleaseDC(dummyWin, dummy_dc);
+		else
+			win->event.type = 0;
 
-		if (wglCreateContextAttribsARB != NULL) {
-			PIXELFORMATDESCRIPTOR pfd = (PIXELFORMATDESCRIPTOR){ sizeof(pfd), 1, PFD_TYPE_RGBA, PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, 32, 8, PFD_MAIN_PLANE, 24, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+		if (!IsWindow(win->src.window)) {
+			win->event.type = RGFW_quit;
+			RGFW_windowQuitCallback(win);
+		}
 
-			if (args & RGFW_OPENGL_SOFTWARE)
-				pfd.dwFlags |= PFD_GENERIC_FORMAT | PFD_GENERIC_ACCELERATED;
+		if (win->event.type)
+			return &win->event;
+		else
+			return NULL;
+	}
 
-			if (wglChoosePixelFormatARB != NULL) {
-				i32* pixel_format_attribs = (i32*)RGFW_initAttribs(args & RGFW_OPENGL_SOFTWARE);
+	u8 RGFW_window_isFullscreen(RGFW_window* win) {
+		assert(win != NULL);
 
-				int pixel_format;
-				UINT num_formats;
-				wglChoosePixelFormatARB(win->src.hdc, pixel_format_attribs, 0, 1, &pixel_format, &num_formats);
-				if (!num_formats) {
-					printf("Failed to set the OpenGL 3.3 pixel format.\n");
-				}
+		WINDOWPLACEMENT placement = { 0 };
+		GetWindowPlacement(win->src.window, &placement);
+		return placement.showCmd == SW_SHOWMAXIMIZED;
+	}
 
-				DescribePixelFormat(win->src.hdc, pixel_format, sizeof(pfd), &pfd);
-				if (!SetPixelFormat(win->src.hdc, pixel_format, &pfd)) {
-					printf("Failed to set the OpenGL 3.3 pixel format.\n");
-				}
-			}
+	u8 RGFW_window_isHidden(RGFW_window* win) {
+		assert(win != NULL);
 
-			u32 index = 0;
-			i32 attribs[40];
+		return IsWindowVisible(win->src.window) == 0 && !RGFW_window_isMinimized(win);
+	}
+
+	u8 RGFW_window_isMinimized(RGFW_window* win) {
+		assert(win != NULL);
+
+		WINDOWPLACEMENT placement = { 0 };
+		GetWindowPlacement(win->src.window, &placement);
+		return placement.showCmd == SW_SHOWMINIMIZED;
+	}
 
-			SET_ATTRIB(WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB);
+	u8 RGFW_window_isMaximized(RGFW_window* win) {
+		assert(win != NULL);
 
-			if (RGFW_majorVersion || RGFW_minorVersion) {
-				SET_ATTRIB(WGL_CONTEXT_MAJOR_VERSION_ARB, RGFW_majorVersion);
-				SET_ATTRIB(WGL_CONTEXT_MINOR_VERSION_ARB, RGFW_minorVersion);
-			}
+		WINDOWPLACEMENT placement = { 0 };
+		GetWindowPlacement(win->src.window, &placement);
+		return placement.showCmd == SW_SHOWMAXIMIZED;
+	}
 
-			SET_ATTRIB(WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB);
+	typedef struct { int iIndex; HMONITOR hMonitor; } RGFW_mInfo;
+	BOOL CALLBACK GetMonitorByHandle(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData) {
+		RGFW_UNUSED(hdcMonitor)
+		RGFW_UNUSED(lprcMonitor)
 
-			if (RGFW_majorVersion || RGFW_minorVersion) {
-				SET_ATTRIB(WGL_CONTEXT_MAJOR_VERSION_ARB, RGFW_majorVersion);
-				SET_ATTRIB(WGL_CONTEXT_MINOR_VERSION_ARB, RGFW_minorVersion);
-			}
+		RGFW_mInfo* info = (RGFW_mInfo*) dwData;
+		if (info->hMonitor == hMonitor)
+			return FALSE;
 
-			SET_ATTRIB(0, 0);
+		info->iIndex++;
+		return TRUE;
+	}
+	
+	#ifndef RGFW_NO_MONITOR
+	RGFW_monitor win32CreateMonitor(HMONITOR src) {
+		RGFW_monitor monitor;
+		MONITORINFO monitorInfo;
 
-			win->src.rSurf = (HGLRC)wglCreateContextAttribsARB(win->src.hdc, NULL, attribs);
-		} else {
-			fprintf(stderr, "Failed to create an accelerated OpenGL Context\n");
+		monitorInfo.cbSize = sizeof(MONITORINFO);
+		GetMonitorInfoA(src, &monitorInfo);
 
-			int pixel_format = ChoosePixelFormat(win->src.hdc, &pfd);
-			SetPixelFormat(win->src.hdc, pixel_format, &pfd);
+		RGFW_mInfo info;
+		info.iIndex = 0;
+		info.hMonitor = src;
 
-			win->src.rSurf = wglCreateContext(win->src.hdc);
+		/* get the monitor's index */
+		if (EnumDisplayMonitors(NULL, NULL, GetMonitorByHandle, (LPARAM) &info)) {
+			DISPLAY_DEVICEA dd;
+			dd.cb = sizeof(dd);
+
+			/* loop through the devices until you find a device with the monitor's index */
+			size_t deviceIndex;
+			for (deviceIndex = 0; EnumDisplayDevicesA(0, (DWORD) deviceIndex, &dd, 0); deviceIndex++) {
+				char* deviceName = dd.DeviceName;
+				if (EnumDisplayDevicesA(deviceName, info.iIndex, &dd, 0)) {
+					strncpy(monitor.name, dd.DeviceString, 128); /* copy the monitor's name */
+					break;
+				}
+			}
 		}
-		
-		wglMakeCurrent(win->src.hdc, win->src.rSurf);
-		wglShareLists(RGFW_root->src.rSurf, win->src.rSurf);
-#endif
 
-#ifdef RGFW_OSMESA
-#ifdef RGFW_LINK_OSM ESA
-		OSMesaMakeCurrentSource = (PFN_OSMesaMakeCurrent) GetProcAddress(win->src.hdc, "OSMesaMakeCurrent");
-		OSMesaCreateContextSource = (PFN_OSMesaCreateContext) GetProcAddress(win->src.hdc, "OSMesaCreateContext");
-		OSMesaDestroyContextSource = (PFN_OSMesaDestroyContext) GetProcAddress(win->src.hdc, "OSMesaDestroyContext");
-#endif
-#endif
+		monitor.rect.x = monitorInfo.rcWork.left;
+		monitor.rect.y = monitorInfo.rcWork.top;
+		monitor.rect.w = monitorInfo.rcWork.right - monitorInfo.rcWork.left;
+		monitor.rect.h = monitorInfo.rcWork.bottom - monitorInfo.rcWork.top;
 
-#ifdef RGFW_OPENGL
-		ReleaseDC(win->src.window, win->src.hdc);
-		win->src.hdc = GetDC(win->src.window);
-		wglMakeCurrent(win->src.hdc, win->src.rSurf);
+#ifndef RGFW_NO_DPI
+		if (GetDpiForMonitor != NULL) {
+			u32 x, y;
+			GetDpiForMonitor(src, MDT_ANGULAR_DPI, &x, &y);
+			monitor.scaleX = (float) (x) / (float) USER_DEFAULT_SCREEN_DPI;
+			monitor.scaleY = (float) (y) / (float) USER_DEFAULT_SCREEN_DPI;
+		}
 #endif
 
-		DestroyWindow(dummyWin);
-		RGFW_init_buffer(win);
-
-#ifdef RGFW_VULKAN
-		RGFW_initVulkan(win);
-#endif
+		HDC hdc = GetDC(NULL);
+		/* get pixels per inch */
+		i32 ppiX = GetDeviceCaps(hdc, LOGPIXELSX);
+		i32 ppiY = GetDeviceCaps(hdc, LOGPIXELSY);
+		ReleaseDC(NULL, hdc);
 
-		if (args & RGFW_SCALE_TO_MONITOR)
-			RGFW_window_scaleToMonitor(win);
+		/* Calculate physical height in inches */
+		monitor.physW = GetSystemMetrics(SM_CYSCREEN) / (float) ppiX;
+		monitor.physH = GetSystemMetrics(SM_CXSCREEN) / (float) ppiY;
 
-#ifdef RGFW_EGL
-		RGFW_createOpenGLContext(win);
-#endif
+		return monitor;
+	}
+	#endif /* RGFW_NO_MONITOR */
+	
 
-		if (args & RGFW_HIDE_MOUSE)
-			RGFW_window_showMouse(win, 0);
+	#ifndef RGFW_NO_MONITOR
+	RGFW_monitor RGFW_monitors[6];
+	BOOL CALLBACK GetMonitorHandle(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData) {
+		RGFW_UNUSED(hdcMonitor)
+		RGFW_UNUSED(lprcMonitor)
 
-		ShowWindow(win->src.window, SW_SHOWNORMAL);
+		RGFW_mInfo* info = (RGFW_mInfo*) dwData;
 
-		return win;
-	}
+		if (info->iIndex >= 6)
+			return FALSE;
 
+		RGFW_monitors[info->iIndex] = win32CreateMonitor(hMonitor);
+		info->iIndex++;
 
-	RGFW_area RGFW_getScreenSize(void) {
-		return RGFW_AREA(GetDeviceCaps(GetDC(NULL), HORZRES), GetDeviceCaps(GetDC(NULL), VERTRES));
+		return TRUE;
 	}
 
-	RGFW_vector RGFW_getGlobalMousePoint(void) {
-		POINT p;
-		GetCursorPos(&p);
-
-		return RGFW_VECTOR(p.x, p.y);
+	RGFW_monitor RGFW_getPrimaryMonitor(void) {
+		return win32CreateMonitor(MonitorFromPoint((POINT) { 0, 0 }, MONITOR_DEFAULTTOPRIMARY));
 	}
 
-	RGFW_vector RGFW_window_getMousePoint(RGFW_window* win) {
-		POINT p;
-		GetCursorPos(&p);
-		ScreenToClient(win->src.window, &p);
+	RGFW_monitor* RGFW_getMonitors(void) {
+		RGFW_mInfo info;
+		info.iIndex = 0;
+		while (EnumDisplayMonitors(NULL, NULL, GetMonitorHandle, (LPARAM) &info));
 
-		return RGFW_VECTOR(p.x, p.y);
+		return RGFW_monitors;
 	}
 
-	void RGFW_window_setMinSize(RGFW_window* win, RGFW_area a) {
-		assert(win != NULL);
-		win->src.minSize = a;
+	RGFW_monitor RGFW_window_getMonitor(RGFW_window* win) {
+		HMONITOR src = MonitorFromWindow(win->src.window, MONITOR_DEFAULTTOPRIMARY);
+		return win32CreateMonitor(src);
 	}
+	#endif
 
-	void RGFW_window_setMaxSize(RGFW_window* win, RGFW_area a) {
+	HICON RGFW_loadHandleImage(RGFW_window* win, u8* src, RGFW_area a, BOOL icon) {
 		assert(win != NULL);
-		win->src.maxSize = a;
-	}
 
+		u32 i;
+		HDC dc;
+		HICON handle;
+		HBITMAP color, mask;
+		BITMAPV5HEADER bi;
+		ICONINFO ii;
+		u8* target = NULL;
+		u8* source = src;
 
-	void RGFW_window_minimize(RGFW_window* win) {
-		assert(win != NULL);
+		ZeroMemory(&bi, sizeof(bi));
+		bi.bV5Size = sizeof(bi);
+		bi.bV5Width = a.w;
+		bi.bV5Height = -((LONG) a.h);
+		bi.bV5Planes = 1;
+		bi.bV5BitCount = 32;
+		bi.bV5Compression = BI_BITFIELDS;
+		bi.bV5RedMask = 0x00ff0000;
+		bi.bV5GreenMask = 0x0000ff00;
+		bi.bV5BlueMask = 0x000000ff;
+		bi.bV5AlphaMask = 0xff000000;
 
-		ShowWindow(win->src.window, SW_MINIMIZE);
-	}
+		dc = GetDC(NULL);
+		color = CreateDIBSection(dc,
+			(BITMAPINFO*) &bi,
+			DIB_RGB_COLORS,
+			(void**) &target,
+			NULL,
+			(DWORD) 0);
+		ReleaseDC(NULL, dc);
 
-	void RGFW_window_restore(RGFW_window* win) {
-		assert(win != NULL);
+		mask = CreateBitmap(a.w, a.h, 1, 1, NULL);
 
-		ShowWindow(win->src.window, SW_RESTORE);
-	}
+		for (i = 0; i < a.w * a.h; i++) {
+			target[0] = source[2];
+			target[1] = source[1];
+			target[2] = source[0];
+			target[3] = source[3];
+			target += 4;
+			source += 4;
+		}
 
-	static i32 RGFW_checkXInput(RGFW_Event* e) {
-		static WORD buttons[4];
-		static BYTE triggers[4][2] = { {0, 0}, {0, 0}, {0, 0}, {0, 0} };
+		ZeroMemory(&ii, sizeof(ii));
+		ii.fIcon = icon;
+		ii.xHotspot = 0;
+		ii.yHotspot = 0;
+		ii.hbmMask = mask;
+		ii.hbmColor = color;
 
-		size_t i;
-		for (i = 0; i < 4; i++) {
-			XINPUT_STATE state;
-			if (XInputGetState == NULL ||
-				XInputGetState((DWORD) i, &state) == ERROR_DEVICE_NOT_CONNECTED
-			)
-				return 0;
+		handle = CreateIconIndirect(&ii);
 
-			e->button = 0;
-			if (state.Gamepad.wButtons & XINPUT_GAMEPAD_A && !(buttons[i] & XINPUT_GAMEPAD_A)) {
-				e->button = RGFW_JS_A;
-				e->type = RGFW_jsButtonPressed;
-				buttons[i] = state.Gamepad.wButtons;
-				return 1;
-			} else if (state.Gamepad.wButtons & XINPUT_GAMEPAD_B && !(buttons[i] & XINPUT_GAMEPAD_B))
-				e->button = RGFW_JS_B;
-			else if (state.Gamepad.wButtons & XINPUT_GAMEPAD_Y && !(buttons[i] & XINPUT_GAMEPAD_Y))
-				e->button = RGFW_JS_Y;
-			else if (state.Gamepad.wButtons & XINPUT_GAMEPAD_X && !(buttons[i] & XINPUT_GAMEPAD_X))
-				e->button = RGFW_JS_X;
-			else if (state.Gamepad.wButtons & XINPUT_GAMEPAD_START && !(buttons[i] & XINPUT_GAMEPAD_START))
-				e->button = RGFW_JS_START;
-			else if (state.Gamepad.wButtons & XINPUT_GAMEPAD_BACK && !(buttons[i] & XINPUT_GAMEPAD_BACK))
-				e->button = RGFW_JS_SELECT;
-			else if (state.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_UP && !(buttons[i] & XINPUT_GAMEPAD_DPAD_UP))
-				e->button = RGFW_JS_UP;
-			else if (state.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_DOWN && !(buttons[i] & XINPUT_GAMEPAD_DPAD_DOWN))
-				e->button = RGFW_JS_DOWN;
-			else if (state.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_LEFT && !(buttons[i] & XINPUT_GAMEPAD_DPAD_LEFT))
-				e->button = RGFW_JS_LEFT;
-			else if (state.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_RIGHT && !(buttons[i] & XINPUT_GAMEPAD_DPAD_RIGHT))
-				e->button = RGFW_JS_RIGHT;
-			else if (state.Gamepad.wButtons & XINPUT_GAMEPAD_LEFT_SHOULDER && !(buttons[i] & XINPUT_GAMEPAD_LEFT_SHOULDER))
-				e->button = RGFW_JS_L1;
-			else if (state.Gamepad.wButtons & XINPUT_GAMEPAD_RIGHT_SHOULDER && !(buttons[i] & XINPUT_GAMEPAD_RIGHT_SHOULDER))
-				e->button = RGFW_JS_R1;
-			else if (state.Gamepad.bLeftTrigger && triggers[i][0] == 0)
-				e->button = RGFW_JS_L2;
-			else if (state.Gamepad.bRightTrigger && triggers[i][1] == 0)
-				e->button = RGFW_JS_R2;
-
-			triggers[i][0] = state.Gamepad.bLeftTrigger;
-			triggers[i][1] = state.Gamepad.bRightTrigger;
-
-			if (e->button) {
-				buttons[i] = state.Gamepad.wButtons;
-				e->type = RGFW_jsButtonPressed;
-				return 1;
-			}
+		DeleteObject(color);
+		DeleteObject(mask);
 
-			if (!(state.Gamepad.wButtons & XINPUT_GAMEPAD_A) && (buttons[i] & XINPUT_GAMEPAD_A)) {
-				e->button = RGFW_JS_A;
-				e->type = RGFW_jsButtonReleased;
-				buttons[i] = state.Gamepad.wButtons;
-				return 1;
-			} else if (!(state.Gamepad.wButtons & XINPUT_GAMEPAD_B) && (buttons[i] & XINPUT_GAMEPAD_B))
-				e->button = RGFW_JS_B;
-			else if (!(state.Gamepad.wButtons & XINPUT_GAMEPAD_Y) && (buttons[i] & XINPUT_GAMEPAD_Y))
-				e->button = RGFW_JS_Y;
-			else if (!(state.Gamepad.wButtons & XINPUT_GAMEPAD_X) && (buttons[i] & XINPUT_GAMEPAD_X))
-				e->button = RGFW_JS_X;
-			else if (!(state.Gamepad.wButtons & XINPUT_GAMEPAD_START) && (buttons[i] & XINPUT_GAMEPAD_START))
-				e->button = RGFW_JS_START;
-			else if (!(state.Gamepad.wButtons & XINPUT_GAMEPAD_BACK) && (buttons[i] & XINPUT_GAMEPAD_BACK))
-				e->button = RGFW_JS_SELECT;
-			else if (!(state.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_UP) && (buttons[i] & XINPUT_GAMEPAD_DPAD_UP))
-				e->button = RGFW_JS_UP;
-			else if (!(state.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_DOWN) && (buttons[i] & XINPUT_GAMEPAD_DPAD_DOWN))
-				e->button = RGFW_JS_DOWN;
-			else if (!(state.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_LEFT) && (buttons[i] & XINPUT_GAMEPAD_DPAD_LEFT))
-				e->button = RGFW_JS_LEFT;
-			else if (!(state.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_RIGHT) && (buttons[i] & XINPUT_GAMEPAD_DPAD_RIGHT))
-				e->button = RGFW_JS_RIGHT;
-			else if (!(state.Gamepad.wButtons & XINPUT_GAMEPAD_LEFT_SHOULDER) && (buttons[i] & XINPUT_GAMEPAD_LEFT_SHOULDER))
-				e->button = RGFW_JS_L1;
-			else if (!(state.Gamepad.wButtons & XINPUT_GAMEPAD_RIGHT_SHOULDER) && (buttons[i] & XINPUT_GAMEPAD_RIGHT_SHOULDER))
-				e->button = RGFW_JS_R1;
-			else if (state.Gamepad.bLeftTrigger == 0 && triggers[i][0] != 0)
-				e->button = RGFW_JS_L2;
-			else if (state.Gamepad.bRightTrigger == 0 && triggers[i][1] != 0)
-				e->button = RGFW_JS_R2;
-			
-			buttons[i] = state.Gamepad.wButtons;
+		return handle;
+	}
 
-			if (e->button) {
-				e->type = RGFW_jsButtonReleased;
-				return 1;
-			}
-#define INPUT_DEADZONE  ( 0.24f * (float)(0x7FFF) )  // Default to 24% of the +/- 32767 range.   This is a reasonable default value but can be altered if needed.
+	void RGFW_window_setMouse(RGFW_window* win, u8* image, RGFW_area a, i32 channels) {
+		assert(win != NULL);
+		RGFW_UNUSED(channels)
 
-			if ((state.Gamepad.sThumbLX < INPUT_DEADZONE &&
-				state.Gamepad.sThumbLX > -INPUT_DEADZONE) &&
-				(state.Gamepad.sThumbLY < INPUT_DEADZONE &&
-					state.Gamepad.sThumbLY > -INPUT_DEADZONE))
-			{
-				state.Gamepad.sThumbLX = 0;
-				state.Gamepad.sThumbLY = 0;
-			}
+		HCURSOR cursor = (HCURSOR) RGFW_loadHandleImage(win, image, a, FALSE);
+		SetClassLongPtrA(win->src.window, GCLP_HCURSOR, (LPARAM) cursor);
+		SetCursor(cursor);
+		DestroyCursor(cursor);
+	}
 
-			if ((state.Gamepad.sThumbRX < INPUT_DEADZONE &&
-				state.Gamepad.sThumbRX > -INPUT_DEADZONE) &&
-				(state.Gamepad.sThumbRY < INPUT_DEADZONE &&
-					state.Gamepad.sThumbRY > -INPUT_DEADZONE))
-			{
-				state.Gamepad.sThumbRX = 0;
-				state.Gamepad.sThumbRY = 0;
-			}
+	void RGFW_window_setMouseDefault(RGFW_window* win) {
+		RGFW_window_setMouseStandard(win, RGFW_MOUSE_ARROW);
+	}
 
-			e->axisesCount = 2;
-			RGFW_vector axis1 = RGFW_VECTOR(state.Gamepad.sThumbLX, state.Gamepad.sThumbLY);
-			RGFW_vector axis2 = RGFW_VECTOR(state.Gamepad.sThumbRX, state.Gamepad.sThumbRY);
+	void RGFW_window_setMouseStandard(RGFW_window* win, u8 mouse) {
+		assert(win != NULL);
 
-			if (axis1.x != e->axis[0].x || axis1.y != e->axis[0].y || axis2.x != e->axis[1].x || axis2.y != e->axis[1].y) {
-				e->type = RGFW_jsAxisMove;
+		if (mouse > (sizeof(RGFW_mouseIconSrc) / sizeof(u32)))
+			return;
 
-				e->axis[0] = axis1;
-				e->axis[1] = axis2;
+		char* icon = MAKEINTRESOURCEA(RGFW_mouseIconSrc[mouse]);
 
-				return 1;
-			}
+		SetClassLongPtrA(win->src.window, GCLP_HCURSOR, (LPARAM) LoadCursorA(NULL, icon));
+		SetCursor(LoadCursorA(NULL, icon));
+	}
 
-			e->axis[0] = axis1;
-			e->axis[1] = axis2;
-		}
+	void RGFW_window_hide(RGFW_window* win) {
+		ShowWindow(win->src.window, SW_HIDE);
+	}
 
-		return 0;
+	void RGFW_window_show(RGFW_window* win) {
+		ShowWindow(win->src.window, SW_RESTORE);
 	}
 
-	RGFW_Event* RGFW_window_checkEvent(RGFW_window* win) {
+	void RGFW_window_close(RGFW_window* win) {
 		assert(win != NULL);
 
-		MSG msg;
+#ifdef RGFW_EGL
+		RGFW_closeEGL(win);
+#endif
 
-		if (RGFW_eventWindow.src.window == win->src.window) {
-			if (RGFW_eventWindow.r.x != -1) {
-				win->r.x = RGFW_eventWindow.r.x;
-				win->r.y = RGFW_eventWindow.r.y;
-				win->event.type = RGFW_windowMoved;
+		if (win == RGFW_root) {
+#ifdef RGFW_DIRECTX
+			RGFW_dxInfo.pDeviceContext->lpVtbl->Release(RGFW_dxInfo.pDeviceContext);
+			RGFW_dxInfo.pDevice->lpVtbl->Release(RGFW_dxInfo.pDevice);
+			RGFW_dxInfo.pAdapter->lpVtbl->Release(RGFW_dxInfo.pAdapter);
+			RGFW_dxInfo.pFactory->lpVtbl->Release(RGFW_dxInfo.pFactory);
+#endif
+		
+			if (RGFW_XInput_dll != NULL) {
+				FreeLibrary(RGFW_XInput_dll);
+				RGFW_XInput_dll = NULL;
 			}
 
-			if (RGFW_eventWindow.r.w != -1) {
-				win->r.w = RGFW_eventWindow.r.w;
-				win->r.h = RGFW_eventWindow.r.h;
-				win->event.type = RGFW_windowResized;
+			#ifndef RGFW_NO_DPI
+			if (RGFW_Shcore_dll != NULL) {
+				FreeLibrary(RGFW_Shcore_dll);
+				RGFW_Shcore_dll = NULL;
 			}
+			#endif
 
-			RGFW_eventWindow.src.window = NULL;
-			RGFW_eventWindow.r = RGFW_RECT(-1, -1, -1, -1);
+			if (wglinstance != NULL) {
+				FreeLibrary(wglinstance);
+				wglinstance = NULL;
+			}
 
-			return &win->event;
+			RGFW_root = NULL;
 		}
 
-		win->event.inFocus = (GetForegroundWindow() == win->src.window);
+#ifdef RGFW_DIRECTX
+		win->src.swapchain->lpVtbl->Release(win->src.swapchain);
+		win->src.renderTargetView->lpVtbl->Release(win->src.renderTargetView);
+		win->src.pDepthStencilView->lpVtbl->Release(win->src.pDepthStencilView);
+#endif
 
-		if (RGFW_checkXInput(&win->event))
-			return &win->event;
+#ifdef RGFW_BUFFER
+		DeleteDC(win->src.hdcMem);
+		DeleteObject(win->src.bitmap);
+#endif
 
-		if (win->event.type == RGFW_quit)
-			return NULL;
+#ifdef RGFW_OPENGL
+		wglDeleteContext((HGLRC) win->src.rSurf); /* delete opengl context */
+#endif
+		DeleteDC(win->src.hdc); /* delete device context */
+		DestroyWindow(win->src.window); /* delete window */
 
-		static BYTE keyboardState[256];
+#if defined(RGFW_OSMESA)
+		if (win->buffer != NULL)
+			RGFW_FREE(win->buffer);
+#endif
 
-		if (PeekMessageA(&msg, win->src.window, 0u, 0u, PM_REMOVE)) {
-			switch (msg.message) {
-			case WM_CLOSE:
-			case WM_QUIT:
-				win->event.type = RGFW_quit;
-				break;
+#ifdef RGFW_ALLOC_DROPFILES
+		{
+			u32 i;
+			for (i = 0; i < RGFW_MAX_DROPS; i++)
+				RGFW_FREE(win->event.droppedFiles[i]);
 
-			case WM_ACTIVATE:
-				win->event.inFocus = (LOWORD(msg.wParam) == WA_INACTIVE);
 
-				if (win->event.inFocus)
-					win->event.type = RGFW_focusIn;
-				else
-					win->event.type = RGFW_focusOut;
-				
-				break;
+			RGFW_FREE(win->event.droppedFiles);
+		}
+#endif
 
-			case WM_KEYUP: {
-				win->event.keyCode = RGFW_apiKeyCodeToRGFW((u32) msg.wParam);
-								
-				RGFW_keyboard_prev[win->event.keyCode] = RGFW_isPressedI(win, win->event.keyCode);
+		RGFW_FREE(win);
+	}
 
-				static char keyName[16];
-				
-				{
-					GetKeyNameTextA((LONG) msg.lParam, keyName, 16);
+	void RGFW_window_move(RGFW_window* win, RGFW_vector v) {
+		assert(win != NULL);
 
-					if ((!(GetKeyState(VK_CAPITAL) & 0x0001) && !(GetKeyState(VK_SHIFT) & 0x8000)) ||
-						((GetKeyState(VK_CAPITAL) & 0x0001) && (GetKeyState(VK_SHIFT) & 0x8000))) {
-						CharLowerBuffA(keyName, 16);
-					}
-				}
-				
-				strncpy(win->event.keyName, keyName, 16);
+		win->r.x = v.x;
+		win->r.y = v.y;
+		SetWindowPos(win->src.window, HWND_TOP, win->r.x, win->r.y, 0, 0, SWP_NOSIZE);
+	}
 
-				if (RGFW_isPressedI(win, RGFW_ShiftL)) {
-					ToAscii((UINT) msg.wParam, MapVirtualKey((UINT) msg.wParam, MAPVK_VK_TO_CHAR),
-						keyboardState, (LPWORD) win->event.keyName, 0);
-				}
+	void RGFW_window_resize(RGFW_window* win, RGFW_area a) {
+		assert(win != NULL);
 
-				win->event.type = RGFW_keyReleased;
-				RGFW_keyboard[win->event.keyCode] = 0;
-				break;
-			}
-			case WM_KEYDOWN: {
-				win->event.keyCode = RGFW_apiKeyCodeToRGFW((u32) msg.wParam);
+		win->r.w = a.w;
+		win->r.h = a.h;
+		SetWindowPos(win->src.window, HWND_TOP, 0, 0, win->r.w, win->r.h + win->src.hOffset, SWP_NOMOVE);
+	}
 
-				RGFW_keyboard_prev[win->event.keyCode] = RGFW_isPressedI(win, win->event.keyCode);
 
-				static char keyName[16];
-				
-				{
-					GetKeyNameTextA((LONG) msg.lParam, keyName, 16);
+	void RGFW_window_setName(RGFW_window* win, char* name) {
+		assert(win != NULL);
 
-					if ((!(GetKeyState(VK_CAPITAL) & 0x0001) && !(GetKeyState(VK_SHIFT) & 0x8000)) ||
-						((GetKeyState(VK_CAPITAL) & 0x0001) && (GetKeyState(VK_SHIFT) & 0x8000))) {
-						CharLowerBuffA(keyName, 16);
-					}
-				}
-				
-				strncpy(win->event.keyName, keyName, 16);
+		SetWindowTextA(win->src.window, name);
+	}
 
-				if (RGFW_isPressedI(win, RGFW_ShiftL) & 0x8000) {
-					ToAscii((UINT) msg.wParam, MapVirtualKey((UINT) msg.wParam, MAPVK_VK_TO_CHAR),
-						keyboardState, (LPWORD) win->event.keyName, 0);
-				}
+	/* sourced from GLFW */
+	#ifndef RGFW_NO_PASSTHROUGH
+	void RGFW_window_setMousePassthrough(RGFW_window* win, b8 passthrough) {
+		assert(win != NULL);
+		
+		COLORREF key = 0;
+		BYTE alpha = 0;
+		DWORD flags = 0;
+		DWORD exStyle = GetWindowLongW(win->src.window, GWL_EXSTYLE);
+		
+		if (exStyle & WS_EX_LAYERED)
+			GetLayeredWindowAttributes(win->src.window, &key, &alpha, &flags);
 
-				win->event.type = RGFW_keyPressed;
-				RGFW_keyboard[win->event.keyCode] = 1;
-				break;
+		if (passthrough)
+			exStyle |= (WS_EX_TRANSPARENT | WS_EX_LAYERED);
+		else
+		{
+			exStyle &= ~WS_EX_TRANSPARENT;
+			// NOTE: Window opacity also needs the layered window style so do not
+			//       remove it if the window is alpha blended
+			if (exStyle & WS_EX_LAYERED)
+			{
+				if (!(flags & LWA_ALPHA))
+					exStyle &= ~WS_EX_LAYERED;
 			}
+		}
 
-			case WM_MOUSEMOVE:
-				win->event.point.x = GET_X_LPARAM(msg.lParam);
-				win->event.point.y = GET_Y_LPARAM(msg.lParam);
-
-				win->event.type = RGFW_mousePosChanged;
-				break;
-
-			case WM_LBUTTONDOWN:
-				win->event.button = RGFW_mouseLeft;
-				RGFW_mouseButtons_prev[win->event.button] = RGFW_mouseButtons[win->event.button];
-				RGFW_mouseButtons[win->event.button] = 1;
-				win->event.type = RGFW_mouseButtonPressed;
-				break;
-			case WM_RBUTTONDOWN:
-				win->event.button = RGFW_mouseRight;
-				win->event.type = RGFW_mouseButtonPressed;
-				RGFW_mouseButtons_prev[win->event.button] = RGFW_mouseButtons[win->event.button];
-				RGFW_mouseButtons[win->event.button] = 1;
-				break;
-			case WM_MBUTTONDOWN:
-				win->event.button = RGFW_mouseMiddle;
-				win->event.type = RGFW_mouseButtonPressed;
-				RGFW_mouseButtons_prev[win->event.button] = RGFW_mouseButtons[win->event.button];
-				RGFW_mouseButtons[win->event.button] = 1;
-				break;
-
-			case WM_MOUSEWHEEL:
-				if (msg.wParam > 0)
-					win->event.button = RGFW_mouseScrollUp;
-				else
-					win->event.button = RGFW_mouseScrollDown;
-
-				RGFW_mouseButtons_prev[win->event.button] = RGFW_mouseButtons[win->event.button];
-				RGFW_mouseButtons[win->event.button] = 1;
+		SetWindowLongW(win->src.window, GWL_EXSTYLE, exStyle);
 
-				win->event.scroll = (SHORT) HIWORD(msg.wParam) / (double) WHEEL_DELTA;
+		if (passthrough) {
+			SetLayeredWindowAttributes(win->src.window, key, alpha, flags);
+		}
+	}
+	#endif
 
-				win->event.type = RGFW_mouseButtonPressed;
-				break;
+	/* much of this function is sourced from GLFW */
+	void RGFW_window_setIcon(RGFW_window* win, u8* src, RGFW_area a, i32 channels) {
+		assert(win != NULL);
+		#ifndef RGFW_WIN95
+		RGFW_UNUSED(channels)
 
-			case WM_LBUTTONUP:
-			
-				win->event.button = RGFW_mouseLeft;
-				win->event.type = RGFW_mouseButtonReleased;
+		HICON handle = RGFW_loadHandleImage(win, src, a, TRUE);
 
-				RGFW_mouseButtons_prev[win->event.button] = RGFW_mouseButtons[win->event.button];
-				RGFW_mouseButtons[win->event.button] = 0;
-				break;
-			case WM_RBUTTONUP:
-				win->event.button = RGFW_mouseRight;
-				win->event.type = RGFW_mouseButtonReleased;
+		SetClassLongPtrA(win->src.window, GCLP_HICON, (LPARAM) handle);
 
-				RGFW_mouseButtons_prev[win->event.button] = RGFW_mouseButtons[win->event.button];
-				RGFW_mouseButtons[win->event.button] = 0;
-				break;
-			case WM_MBUTTONUP:
-				win->event.button = RGFW_mouseMiddle;
-				win->event.type = RGFW_mouseButtonReleased;
+		DestroyIcon(handle);
+		#else
+		RGFW_UNUSED(src)
+		RGFW_UNUSED(a)
+		RGFW_UNUSED(channels)
+		#endif
+	}
 
-				RGFW_mouseButtons_prev[win->event.button] = RGFW_mouseButtons[win->event.button];
-				RGFW_mouseButtons[win->event.button] = 0;
-				break;
+	char* RGFW_readClipboard(size_t* size) {
+		/* Open the clipboard */
+		if (OpenClipboard(NULL) == 0)
+			return (char*) "";
 
-				/*
-					much of this event is source from glfw
-				*/
-			case WM_DROPFILES: {
+		/* Get the clipboard data as a Unicode string */
+		HANDLE hData = GetClipboardData(CF_UNICODETEXT);
+		if (hData == NULL) {
+			CloseClipboard();
+			return (char*) "";
+		}
 
-				if (win->event.droppedFilesCount) {
-					u32 i;
-					for (i = 0; i < win->event.droppedFilesCount; i++)
-						win->event.droppedFiles[i][0] = '\0';
-				}
+		wchar_t* wstr = (wchar_t*) GlobalLock(hData);
 
-				win->event.droppedFilesCount = 0;
+		char* text;
 
-				win->event.type = RGFW_dnd;
+		{
+			setlocale(LC_ALL, "en_US.UTF-8");
 
-				HDROP drop = (HDROP) msg.wParam;
-				POINT pt;
-				u32 i;
+			size_t textLen = wcstombs(NULL, wstr, 0);
+			if (textLen == 0)
+				return (char*) "";
 
-				win->event.droppedFilesCount = DragQueryFileW(drop, 0xffffffff, NULL, 0);
-				//win->event.droppedFiles = (char**)RGFW_CALLOC(win->event.droppedFilesCount, sizeof(char*));
+			text = (char*) RGFW_MALLOC((textLen * sizeof(char)) + 1);
 
-				/* Move the mouse to the position of the drop */
-				DragQueryPoint(drop, &pt);
+			wcstombs(text, wstr, (textLen) +1);
 
-				win->event.point.x = pt.x;
-				win->event.point.y = pt.y;
+			if (size != NULL)
+				*size = textLen + 1;
 
-				for (i = 0; i < win->event.droppedFilesCount; i++) {
-					const UINT length = DragQueryFileW(drop, i, NULL, 0);
-					WCHAR* buffer = (WCHAR*) RGFW_CALLOC((size_t) length + 1, sizeof(WCHAR));
+			text[textLen] = '\0';
+		}
 
-					DragQueryFileW(drop, i, buffer, length + 1);
-					strcpy(win->event.droppedFiles[i], createUTF8FromWideStringWin32(buffer));
+		/* Release the clipboard data */
+		GlobalUnlock(hData);
+		CloseClipboard();
 
-					RGFW_FREE(buffer);
-				}
+		return text;
+	}
 
-				DragFinish(drop);
-			}
-							 break;
-			case WM_GETMINMAXINFO:
-			{
-				if (win->src.maxSize.w == 0 && win->src.maxSize.h == 0)
-					break;
+	void RGFW_writeClipboard(const char* text, u32 textLen) {
+		HANDLE object;
+		WCHAR* buffer;
 
-				MINMAXINFO* mmi = (MINMAXINFO*) msg.lParam;
-				mmi->ptMinTrackSize.x = win->src.minSize.w;
-				mmi->ptMinTrackSize.y = win->src.minSize.h;
-				mmi->ptMaxTrackSize.x = win->src.maxSize.w;
-				mmi->ptMaxTrackSize.y = win->src.maxSize.h;
-				return 0;
-			}
-			default:
-				win->event.type = 0;
-				break;
-			}
+		object = GlobalAlloc(GMEM_MOVEABLE, (1 + textLen) * sizeof(WCHAR));
+		if (!object)
+			return;
 
-			TranslateMessage(&msg);
-			DispatchMessageA(&msg);
+		buffer = (WCHAR*) GlobalLock(object);
+		if (!buffer) {
+			GlobalFree(object);
+			return;
 		}
 
-		else
-			win->event.type = 0;
+		MultiByteToWideChar(CP_UTF8, 0, text, -1, buffer, textLen);
+		GlobalUnlock(object);
 
-		win->event.lockState = 0;
+		if (!OpenClipboard(RGFW_root->src.window)) {
+			GlobalFree(object);
+			return;
+		}
 
-		if ((GetKeyState(VK_CAPITAL) & 0x0001) != 0)
-			win->event.lockState |= RGFW_CAPSLOCK;
-		if ((GetKeyState(VK_NUMLOCK) & 0x0001) != 0)
-			win->event.lockState |= RGFW_NUMLOCK;
-		if ((GetKeyState(VK_SCROLL) & 0x0001) != 0)
-			win->event.lockState |= 3;
+		EmptyClipboard();
+		SetClipboardData(CF_UNICODETEXT, object);
+		CloseClipboard();
+	}
 
+	u16 RGFW_registerJoystick(RGFW_window* win, i32 jsNumber) {
+		assert(win != NULL);
 
-		if (!IsWindow(win->src.window))
-			win->event.type = RGFW_quit;
+		RGFW_UNUSED(jsNumber)
 
-		if (win->event.type)
-			return &win->event;
-		else
-			return NULL;
+		return RGFW_registerJoystickF(win, (char*) "");
 	}
 
-	u8 RGFW_window_isFullscreen(RGFW_window* win) {
+	u16 RGFW_registerJoystickF(RGFW_window* win, char* file) {
 		assert(win != NULL);
+		RGFW_UNUSED(file)
 
-		WINDOWPLACEMENT placement = { 0 };
-		GetWindowPlacement(win->src.window, &placement);
-		return placement.showCmd == SW_SHOWMAXIMIZED;
+		return win->src.joystickCount - 1;
 	}
 
-	u8 RGFW_window_isHidden(RGFW_window* win) {
+	void RGFW_window_moveMouse(RGFW_window* win, RGFW_vector p) {
 		assert(win != NULL);
 
-		return IsWindowVisible(win->src.window) == 0 && !RGFW_window_isMinimized(win);
+		SetCursorPos(p.x, p.y);
 	}
 
-	u8 RGFW_window_isMinimized(RGFW_window* win) {
+	#ifdef RGFW_OPENGL
+	void RGFW_window_makeCurrent_OpenGL(RGFW_window* win) {
 		assert(win != NULL);
-
-		WINDOWPLACEMENT placement = { 0 };
-		GetWindowPlacement(win->src.window, &placement);
-		return placement.showCmd == SW_SHOWMINIMIZED;
+		wglMakeCurrent(win->src.hdc, (HGLRC) win->src.rSurf);
 	}
+	#endif
 
-	u8 RGFW_window_isMaximized(RGFW_window* win) {
+	#ifndef RGFW_EGL
+	void RGFW_window_swapInterval(RGFW_window* win, i32 swapInterval) {
 		assert(win != NULL);
+		
+		#if defined(RGFW_OPENGL)
+		typedef BOOL(APIENTRY* PFNWGLSWAPINTERVALEXTPROC)(int interval);
+		static PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT = NULL;
+		static void* loadSwapFunc = (void*) 1;
 
-		WINDOWPLACEMENT placement = { 0 };
-		GetWindowPlacement(win->src.window, &placement);
-		return placement.showCmd == SW_SHOWMAXIMIZED;
-	}
+		if (loadSwapFunc == NULL) {
+			fprintf(stderr, "wglSwapIntervalEXT not supported\n");
+			win->fpsCap = (swapInterval == 1) ? 0 : swapInterval;
+			return;
+		}
 
-	typedef struct { int iIndex; HMONITOR hMonitor; } RGFW_mInfo;
-	BOOL CALLBACK GetMonitorByHandle(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData) {
-		RGFW_UNUSED(hdcMonitor)
-		RGFW_UNUSED(lprcMonitor)
+		if (wglSwapIntervalEXT == NULL) {
+			loadSwapFunc = (void*) wglGetProcAddress("wglSwapIntervalEXT");
+			wglSwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC) loadSwapFunc;
+		}
 
-		RGFW_mInfo* info = (RGFW_mInfo*) dwData;
-		if (info->hMonitor == hMonitor)
-			return FALSE;
+		if (wglSwapIntervalEXT(swapInterval) == FALSE)
+			fprintf(stderr, "Failed to set swap interval\n");
+		#endif
+
+		win->fpsCap = (swapInterval == 1) ? 0 : swapInterval;
 
-		info->iIndex++;
-		return TRUE;
 	}
+	#endif
 
-	RGFW_monitor win32CreateMonitor(HMONITOR src) {
-		RGFW_monitor monitor;
-		MONITORINFO monitorInfo;
+	void RGFW_window_swapBuffers(RGFW_window* win) {
+		assert(win != NULL);
 
-		monitorInfo.cbSize = sizeof(MONITORINFO);
-		GetMonitorInfoA(src, &monitorInfo);
+		RGFW_window_makeCurrent(win);
 
-		RGFW_mInfo info;
-		info.iIndex = 0;
-		info.hMonitor = src;
+		/* clear the window*/
 
-		/* get the monitor's index */
-		if (EnumDisplayMonitors(NULL, NULL, GetMonitorByHandle, (LPARAM) &info)) {
-			DISPLAY_DEVICEA dd;
-			dd.cb = sizeof(dd);
+		if (!(win->src.winArgs & RGFW_NO_CPU_RENDER)) {
+#if defined(RGFW_OSMESA) || defined(RGFW_BUFFER)
+			#ifdef RGFW_OSMESA
+			RGFW_OSMesa_reorganize();
+			#endif
 
-			/* loop through the devices until you find a device with the monitor's index */
-			size_t deviceIndex;
-			for (deviceIndex = 0; EnumDisplayDevicesA(0, (DWORD) deviceIndex, &dd, 0); deviceIndex++) {
-				char* deviceName = dd.DeviceName;
-				if (EnumDisplayDevicesA(deviceName, info.iIndex, &dd, 0)) {
-					strcpy(monitor.name, dd.DeviceString); /* copy the monitor's name */
-					break;
-				}
-			}
+			HGDIOBJ oldbmp = SelectObject(win->src.hdcMem, win->src.bitmap);
+			BitBlt(win->src.hdc, 0, 0, win->r.w, win->r.h, win->src.hdcMem, 0, 0, SRCCOPY);
+			SelectObject(win->src.hdcMem, oldbmp);
+#endif
 		}
 
-		monitor.rect.x = monitorInfo.rcWork.left;
-		monitor.rect.y = monitorInfo.rcWork.top;
-		monitor.rect.w = monitorInfo.rcWork.right - monitorInfo.rcWork.left;
-		monitor.rect.h = monitorInfo.rcWork.bottom - monitorInfo.rcWork.top;
+		if (!(win->src.winArgs & RGFW_NO_GPU_RENDER)) {
+			#ifdef RGFW_EGL
+					eglSwapBuffers(win->src.EGL_display, win->src.EGL_surface);
+			#elif defined(RGFW_OPENGL)
+					SwapBuffers(win->src.hdc);
+			#endif
 
-#ifndef RGFW_NO_DPI
-		if (GetDpiForMonitor != NULL) {
-			u32 x, y;
-			GetDpiForMonitor(src, MDT_ANGULAR_DPI, &x, &y);
-			monitor.scaleX = (float) (x) / (float) USER_DEFAULT_SCREEN_DPI;
-			monitor.scaleY = (float) (y) / (float) USER_DEFAULT_SCREEN_DPI;
+			#if defined(RGFW_WINDOWS) && defined(RGFW_DIRECTX)
+					win->src.swapchain->lpVtbl->Present(win->src.swapchain, 0, 0);
+			#endif
 		}
-#endif
-
-		HDC hdc = GetDC(NULL);
-		/* get pixels per inch */
-		i32 ppiX = GetDeviceCaps(hdc, LOGPIXELSX);
-		i32 ppiY = GetDeviceCaps(hdc, LOGPIXELSY);
-		ReleaseDC(NULL, hdc);
-
-		/* Calculate physical height in inches */
-		monitor.physW = GetSystemMetrics(SM_CYSCREEN) / (float) ppiX;
-		monitor.physH = GetSystemMetrics(SM_CXSCREEN) / (float) ppiY;
 
-		return monitor;
+		RGFW_window_checkFPS(win);
 	}
 
-	RGFW_monitor RGFW_monitors[6];
-	BOOL CALLBACK GetMonitorHandle(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData) {
-		RGFW_UNUSED(hdcMonitor)
-		RGFW_UNUSED(lprcMonitor)
-
-		RGFW_mInfo* info = (RGFW_mInfo*) dwData;
+	char* createUTF8FromWideStringWin32(const WCHAR* source) {
+		char* target;
+		i32 size;
 
-		if (info->iIndex >= 6)
-			return FALSE;
+		size = WideCharToMultiByte(CP_UTF8, 0, source, -1, NULL, 0, NULL, NULL);
+		if (!size) {
+			return NULL;
+		}
 
-		RGFW_monitors[info->iIndex] = win32CreateMonitor(hMonitor);
-		info->iIndex++;
+		target = (char*) RGFW_CALLOC(size, 1);
 
-		return TRUE;
-	}
+		if (!WideCharToMultiByte(CP_UTF8, 0, source, -1, target, size, NULL, NULL)) {
+			RGFW_FREE(target);
+			return NULL;
+		}
 
-	RGFW_monitor RGFW_getPrimaryMonitor(void) {
-		return win32CreateMonitor(MonitorFromPoint((POINT) { 0, 0 }, MONITOR_DEFAULTTOPRIMARY));
+		return target;
 	}
 
-	RGFW_monitor* RGFW_getMonitors(void) {
-		RGFW_mInfo info;
-		info.iIndex = 0;
-		while (EnumDisplayMonitors(NULL, NULL, GetMonitorHandle, (LPARAM) &info));
+	u64 RGFW_getTimeNS(void) {
+		LARGE_INTEGER frequency;
+		QueryPerformanceFrequency(&frequency);
 
-		return RGFW_monitors;
-	}
+		LARGE_INTEGER counter;
+		QueryPerformanceCounter(&counter);
 
-	RGFW_monitor RGFW_window_getMonitor(RGFW_window* win) {
-		HMONITOR src = MonitorFromWindow(win->src.window, MONITOR_DEFAULTTOPRIMARY);
-		return win32CreateMonitor(src);
+		return (u64) (counter.QuadPart * 1e9 / frequency.QuadPart);
 	}
 
-	HICON RGFW_loadHandleImage(RGFW_window* win, u8* src, RGFW_area a, BOOL icon) {
-		assert(win != NULL);
+	u64 RGFW_getTime(void) {
+		LARGE_INTEGER frequency;
+		QueryPerformanceFrequency(&frequency);
 
-		u32 i;
-		HDC dc;
-		HICON handle;
-		HBITMAP color, mask;
-		BITMAPV5HEADER bi;
-		ICONINFO ii;
-		u8* target = NULL;
-		u8* source = src;
+		LARGE_INTEGER counter;
+		QueryPerformanceCounter(&counter);
+		return (u64) (counter.QuadPart / (double) frequency.QuadPart);
+	}
+	
+	void RGFW_sleep(u64 ms) {
+		Sleep(ms);
+	}
 
-		ZeroMemory(&bi, sizeof(bi));
-		bi.bV5Size = sizeof(bi);
-		bi.bV5Width = a.w;
-		bi.bV5Height = -((LONG) a.h);
-		bi.bV5Planes = 1;
-		bi.bV5BitCount = 32;
-		bi.bV5Compression = BI_BITFIELDS;
-		bi.bV5RedMask = 0x00ff0000;
-		bi.bV5GreenMask = 0x0000ff00;
-		bi.bV5BlueMask = 0x000000ff;
-		bi.bV5AlphaMask = 0xff000000;
+#ifndef RGFW_NO_THREADS
+	RGFW_thread RGFW_createThread(RGFW_threadFunc_ptr ptr, void* args) { return CreateThread(NULL, 0, ptr, args, 0, NULL); }
+	void RGFW_cancelThread(RGFW_thread thread) { CloseHandle((HANDLE) thread); }
+	void RGFW_joinThread(RGFW_thread thread) { WaitForSingleObject((HANDLE) thread, INFINITE); }
+	void RGFW_setThreadPriority(RGFW_thread thread, u8 priority) { SetThreadPriority((HANDLE) thread, priority); }
+#endif
+#endif /* RGFW_WINDOWS */
 
-		dc = GetDC(NULL);
-		color = CreateDIBSection(dc,
-			(BITMAPINFO*) &bi,
-			DIB_RGB_COLORS,
-			(void**) &target,
-			NULL,
-			(DWORD) 0);
-		ReleaseDC(NULL, dc);
+/*
+	End of Windows defines
+*/
 
-		mask = CreateBitmap(a.w, a.h, 1, 1, NULL);
 
-		for (i = 0; i < a.w * a.h; i++) {
-			target[0] = source[2];
-			target[1] = source[1];
-			target[2] = source[0];
-			target[3] = source[3];
-			target += 4;
-			source += 4;
-		}
 
-		ZeroMemory(&ii, sizeof(ii));
-		ii.fIcon = icon;
-		ii.xHotspot = 0;
-		ii.yHotspot = 0;
-		ii.hbmMask = mask;
-		ii.hbmColor = color;
+/* 
 
-		handle = CreateIconIndirect(&ii);
+	Start of MacOS defines
 
-		DeleteObject(color);
-		DeleteObject(mask);
 
-		return handle;
-	}
+*/
 
-	void RGFW_window_setMouse(RGFW_window* win, u8* image, RGFW_area a, i32 channels) {
-		assert(win != NULL);
-		RGFW_UNUSED(channels)
+#if defined(RGFW_MACOS)
+	/*
+		based on silicon.h
+		start of cocoa wrapper
+	*/
 
-		HCURSOR cursor = (HCURSOR) RGFW_loadHandleImage(win, image, a, FALSE);
-		SetClassLongPtrA(win->src.window, GCLP_HCURSOR, (LPARAM) cursor);
-		SetCursor(cursor);
-		DestroyCursor(cursor);
-	}
+#include <CoreVideo/CVDisplayLink.h>
+#include <ApplicationServices/ApplicationServices.h>
+#include <objc/runtime.h>
+#include <objc/message.h>
+#include <mach/mach_time.h>
 
-	void RGFW_window_setMouseDefault(RGFW_window* win) {
-		RGFW_window_setMouseStandard(win, RGFW_MOUSE_ARROW);
-	}
+	typedef CGRect NSRect;
+	typedef CGPoint NSPoint;
+	typedef CGSize NSSize;
 
-	void RGFW_window_setMouseStandard(RGFW_window* win, u8 mouse) {
-		assert(win != NULL);
+	typedef void NSBitmapImageRep;
+	typedef void NSCursor;
+	typedef void NSDraggingInfo;
+	typedef void NSWindow;
+	typedef void NSApplication;
+	typedef void NSScreen;
+	typedef void NSEvent;
+	typedef void NSString;
+	typedef void NSOpenGLContext;
+	typedef void NSPasteboard;
+	typedef void NSColor;
+	typedef void NSArray;
+	typedef void NSImageRep;
+	typedef void NSImage;
+	typedef void NSOpenGLView;
 
-		if (mouse > (sizeof(RGFW_mouseIconSrc) / sizeof(u32)))
-			return;
-		
-		mouse = RGFW_mouseIconSrc[mouse];
 
-		char* icon = MAKEINTRESOURCEA(mouse);
+	typedef const char* NSPasteboardType;
+	typedef unsigned long NSUInteger;
+	typedef long NSInteger;
+	typedef NSInteger NSModalResponse;
 
-		SetClassLongPtrA(win->src.window, GCLP_HCURSOR, (LPARAM) LoadCursorA(NULL, icon));
-		SetCursor(LoadCursorA(NULL, icon));
-	}
+#ifdef __arm64__
+	/* ARM just uses objc_msgSend */
+#define abi_objc_msgSend_stret objc_msgSend
+#define abi_objc_msgSend_fpret objc_msgSend
+#else /* __i386__ */ 
+	/* x86 just uses abi_objc_msgSend_fpret and (NSColor *)objc_msgSend_id respectively */
+#define abi_objc_msgSend_stret objc_msgSend_stret
+#define abi_objc_msgSend_fpret objc_msgSend_fpret
+#endif
 
-	void RGFW_window_hide(RGFW_window* win) {
-		ShowWindow(win->src.window, SW_HIDE);
+#define NSAlloc(nsclass) objc_msgSend_id((id)nsclass, sel_registerName("alloc"))
+#define objc_msgSend_bool			((BOOL (*)(id, SEL))objc_msgSend)
+#define objc_msgSend_void			((void (*)(id, SEL))objc_msgSend)
+#define objc_msgSend_void_id		((void (*)(id, SEL, id))objc_msgSend)
+#define objc_msgSend_uint			((NSUInteger (*)(id, SEL))objc_msgSend)
+#define objc_msgSend_void_bool		((void (*)(id, SEL, BOOL))objc_msgSend)
+#define objc_msgSend_void_SEL		((void (*)(id, SEL, SEL))objc_msgSend)
+#define objc_msgSend_id				((id (*)(id, SEL))objc_msgSend)
+
+	void NSRelease(id obj) {
+		objc_msgSend_void(obj, sel_registerName("release"));
 	}
 
-	void RGFW_window_show(RGFW_window* win) {
-		ShowWindow(win->src.window, SW_RESTORE);
+	#define release NSRelease
+
+	NSString* NSString_stringWithUTF8String(const char* str) {	
+		return ((id(*)(id, SEL, const char*))objc_msgSend)
+			((id)objc_getClass("NSString"), sel_registerName("stringWithUTF8String:"), str);
 	}
 
-	void RGFW_window_close(RGFW_window* win) {
-		assert(win != NULL);
+	const char* NSString_to_char(NSString* str) {
+		return ((const char* (*)(id, SEL)) objc_msgSend) (str, sel_registerName("UTF8String"));
+	}
 
-#ifdef RGFW_VULKAN
-		for (u32 i = 0; i < win->src.image_count; i++) {
-			vkDestroyFramebuffer(RGFW_vulkan_info.device, RGFW_vulkan_info.framebuffers[i], NULL);
-		}
+	void si_impl_func_to_SEL_with_name(const char* class_name, const char* register_name, void* function) {
+		Class selected_class;
 
-		for (u32 i = 0; i < win->src.image_count; i++) {
-			vkDestroyImageView(RGFW_vulkan_info.device, win->src.swapchain_image_views[i], NULL);
+		if (strcmp(class_name, "NSView") == 0) {
+			selected_class = objc_getClass("ViewClass");
+		} else if (strcmp(class_name, "NSWindow") == 0) {
+			selected_class = objc_getClass("WindowClass");
+		} else {
+			selected_class = objc_getClass(class_name);
 		}
 
-		vkDestroySwapchainKHR(RGFW_vulkan_info.device, win->src.swapchain, NULL);
-		vkDestroySurfaceKHR(RGFW_vulkan_info.instance, win->src.rSurf, NULL);
-		RGFW_FREE(win->src.swapchain_image_views);
-		RGFW_FREE(win->src.swapchain_images);
-#endif
-
-#ifdef RGFW_EGL
-		RGFW_closeEGL(win);
-#endif
+		class_addMethod(selected_class, sel_registerName(register_name), (IMP) function, 0);
+	}
 
-		if (win == RGFW_root) {
-#ifdef RGFW_DIRECTX
-			RGFW_dxInfo.pDeviceContext->lpVtbl->Release(RGFW_dxInfo.pDeviceContext);
-			RGFW_dxInfo.pDevice->lpVtbl->Release(RGFW_dxInfo.pDevice);
-			RGFW_dxInfo.pAdapter->lpVtbl->Release(RGFW_dxInfo.pAdapter);
-			RGFW_dxInfo.pFactory->lpVtbl->Release(RGFW_dxInfo.pFactory);
-#endif
-		
-			if (RGFW_XInput_dll != NULL) {
-				FreeLibrary(RGFW_XInput_dll);
-				RGFW_XInput_dll = NULL;
-			}
+	/* Header for the array. */
+	typedef struct siArrayHeader {
+		size_t count;
+		/* TODO(EimaMei): Add a `type_width` later on. */
+	} siArrayHeader;
 
-			#ifndef RGFW_NO_DPI
-			if (RGFW_Shcore_dll != NULL) {
-				FreeLibrary(RGFW_Shcore_dll);
-				RGFW_Shcore_dll = NULL;
-			}
-			#endif
+	/* Gets the header of the siArray. */
+#define SI_ARRAY_HEADER(s) ((siArrayHeader*)s - 1)
 
-			if (wglinstance != NULL) {
-				FreeLibrary(wglinstance);
-				wglinstance = NULL;
-			}
+	void* si_array_init_reserve(size_t sizeof_element, size_t count) {
+		siArrayHeader* ptr = malloc(sizeof(siArrayHeader) + (sizeof_element * count));
+		void* array = ptr + sizeof(siArrayHeader);
 
-			RGFW_root = NULL;
-		}
+		siArrayHeader* header = SI_ARRAY_HEADER(array);
+		header->count = count;
 
-#ifdef RGFW_DIRECTX
-		win->src.swapchain->lpVtbl->Release(win->src.swapchain);
-		win->src.renderTargetView->lpVtbl->Release(win->src.renderTargetView);
-		win->src.pDepthStencilView->lpVtbl->Release(win->src.pDepthStencilView);
-#endif
+		return array;
+	}
 
-#ifdef RGFW_BUFFER
-		DeleteDC(win->src.hdcMem);
-		DeleteObject(win->src.bitmap);
-#endif
+#define si_array_len(array) (SI_ARRAY_HEADER(array)->count)
+#define si_func_to_SEL(class_name, function) si_impl_func_to_SEL_with_name(class_name, #function":", function)
+	/* Creates an Objective-C method (SEL) from a regular C function with the option to set the register name.*/
+#define si_func_to_SEL_with_name(class_name, register_name, function) si_impl_func_to_SEL_with_name(class_name, register_name":", function)
+	
+	unsigned char* NSBitmapImageRep_bitmapData(NSBitmapImageRep* imageRep) {
+		return ((unsigned char* (*)(id, SEL))objc_msgSend)
+			(imageRep, sel_registerName("bitmapData"));
+	}
 
-#ifdef RGFW_OPENGL
-		wglDeleteContext((HGLRC) win->src.rSurf); /* delete opengl context */
-#endif
-		DeleteDC(win->src.hdc); /* delete device context */
-		DestroyWindow(win->src.window); /* delete window */
+#define NS_ENUM(type, name) type name; enum
 
-#if defined(RGFW_OSMESA)
-		if (win->buffer != NULL)
-			RGFW_FREE(win->buffer);
-#endif
+	typedef NS_ENUM(NSUInteger, NSBitmapFormat) {
+		NSBitmapFormatAlphaFirst = 1 << 0,       // 0 means is alpha last (RGBA, CMYKA, etc.)
+			NSBitmapFormatAlphaNonpremultiplied = 1 << 1,       // 0 means is premultiplied
+			NSBitmapFormatFloatingPointSamples = 1 << 2,  // 0 is integer
 
-#ifdef RGFW_ALLOC_DROPFILES
-		{
-			u32 i;
-			for (i = 0; i < RGFW_MAX_DROPS; i++)
-				RGFW_FREE(win->event.droppedFiles[i]);
+			NSBitmapFormatSixteenBitLittleEndian API_AVAILABLE(macos(10.10)) = (1 << 8),
+			NSBitmapFormatThirtyTwoBitLittleEndian API_AVAILABLE(macos(10.10)) = (1 << 9),
+			NSBitmapFormatSixteenBitBigEndian API_AVAILABLE(macos(10.10)) = (1 << 10),
+			NSBitmapFormatThirtyTwoBitBigEndian API_AVAILABLE(macos(10.10)) = (1 << 11)
+	};
 
+	NSBitmapImageRep* NSBitmapImageRep_initWithBitmapData(unsigned char** planes, NSInteger width, NSInteger height, NSInteger bps, NSInteger spp, bool alpha, bool isPlanar, const char* colorSpaceName, NSBitmapFormat bitmapFormat, NSInteger rowBytes, NSInteger pixelBits) {
+		void* func = sel_registerName("initWithBitmapDataPlanes:pixelsWide:pixelsHigh:bitsPerSample:samplesPerPixel:hasAlpha:isPlanar:colorSpaceName:bitmapFormat:bytesPerRow:bitsPerPixel:");
 
-			RGFW_FREE(win->event.droppedFiles);
-		}
-#endif
+		return (NSBitmapImageRep*) ((id(*)(id, SEL, unsigned char**, NSInteger, NSInteger, NSInteger, NSInteger, bool, bool, const char*, NSBitmapFormat, NSInteger, NSInteger))objc_msgSend)
+			(NSAlloc((id)objc_getClass("NSBitmapImageRep")), func, planes, width, height, bps, spp, alpha, isPlanar, NSString_stringWithUTF8String(colorSpaceName), bitmapFormat, rowBytes, pixelBits);
+	}
 
-		RGFW_FREE(win);
+	NSColor* NSColor_colorWithSRGB(CGFloat red, CGFloat green, CGFloat blue, CGFloat alpha) {
+		void* nsclass = objc_getClass("NSColor");
+		void* func = sel_registerName("colorWithSRGBRed:green:blue:alpha:");
+		return ((id(*)(id, SEL, CGFloat, CGFloat, CGFloat, CGFloat))objc_msgSend)
+			(nsclass, func, red, green, blue, alpha);
 	}
 
-	void RGFW_window_move(RGFW_window* win, RGFW_vector v) {
-		assert(win != NULL);
+	NSCursor* NSCursor_initWithImage(NSImage* newImage, NSPoint aPoint) {
+		void* func = sel_registerName("initWithImage:hotSpot:");
+		void* nsclass = objc_getClass("NSCursor");
 
-		win->r.x = v.x;
-		win->r.y = v.y;
-		SetWindowPos(win->src.window, HWND_TOP, win->r.x, win->r.y, 0, 0, SWP_NOSIZE);
+		return (NSCursor*) ((id(*)(id, SEL, id, NSPoint))objc_msgSend)
+			(NSAlloc(nsclass), func, newImage, aPoint);
 	}
 
-	void RGFW_window_resize(RGFW_window* win, RGFW_area a) {
-		assert(win != NULL);
+	void NSImage_addRepresentation(NSImage* image, NSImageRep* imageRep) {
+		void* func = sel_registerName("addRepresentation:");
+		objc_msgSend_void_id(image, func, imageRep);
+	}
 
-		win->r.w = a.w;
-		win->r.h = a.h;
-		SetWindowPos(win->src.window, HWND_TOP, 0, 0, win->r.w, win->r.h + win->src.hOffset, SWP_NOMOVE);
+	NSImage* NSImage_initWithSize(NSSize size) {
+		void* func = sel_registerName("initWithSize:");
+		return ((id(*)(id, SEL, NSSize))objc_msgSend)
+			(NSAlloc((id)objc_getClass("NSImage")), func, size);
 	}
+#define NS_OPENGL_ENUM_DEPRECATED(minVers, maxVers) API_AVAILABLE(macos(minVers))
+	typedef NS_ENUM(NSInteger, NSOpenGLContextParameter) {
+		NSOpenGLContextParameterSwapInterval           NS_OPENGL_ENUM_DEPRECATED(10.0, 10.14) = 222, /* 1 param.  0 -> Don't sync, 1 -> Sync to vertical retrace     */
+			NSOpenGLContextParameterSurfaceOrder           NS_OPENGL_ENUM_DEPRECATED(10.0, 10.14) = 235, /* 1 param.  1 -> Above Window (default), -1 -> Below Window    */
+			NSOpenGLContextParameterSurfaceOpacity         NS_OPENGL_ENUM_DEPRECATED(10.0, 10.14) = 236, /* 1 param.  1-> Surface is opaque (default), 0 -> non-opaque   */
+			NSOpenGLContextParameterSurfaceBackingSize     NS_OPENGL_ENUM_DEPRECATED(10.0, 10.14) = 304, /* 2 params.  Width/height of surface backing size              */
+			NSOpenGLContextParameterReclaimResources       NS_OPENGL_ENUM_DEPRECATED(10.0, 10.14) = 308, /* 0 params.                                                    */
+			NSOpenGLContextParameterCurrentRendererID      NS_OPENGL_ENUM_DEPRECATED(10.0, 10.14) = 309, /* 1 param.   Retrieves the current renderer ID                 */
+			NSOpenGLContextParameterGPUVertexProcessing    NS_OPENGL_ENUM_DEPRECATED(10.0, 10.14) = 310, /* 1 param.   Currently processing vertices with GPU (get)      */
+			NSOpenGLContextParameterGPUFragmentProcessing  NS_OPENGL_ENUM_DEPRECATED(10.0, 10.14) = 311, /* 1 param.   Currently processing fragments with GPU (get)     */
+			NSOpenGLContextParameterHasDrawable            NS_OPENGL_ENUM_DEPRECATED(10.0, 10.14) = 314, /* 1 param.   Boolean returned if drawable is attached          */
+			NSOpenGLContextParameterMPSwapsInFlight        NS_OPENGL_ENUM_DEPRECATED(10.0, 10.14) = 315, /* 1 param.   Max number of swaps queued by the MP GL engine    */
 
+			NSOpenGLContextParameterSwapRectangle API_DEPRECATED("", macos(10.0, 10.14)) = 200, /* 4 params.  Set or get the swap rectangle {x, y, w, h} */
+			NSOpenGLContextParameterSwapRectangleEnable API_DEPRECATED("", macos(10.0, 10.14)) = 201, /* Enable or disable the swap rectangle */
+			NSOpenGLContextParameterRasterizationEnable API_DEPRECATED("", macos(10.0, 10.14)) = 221, /* Enable or disable all rasterization */
+			NSOpenGLContextParameterStateValidation API_DEPRECATED("", macos(10.0, 10.14)) = 301, /* Validate state for multi-screen functionality */
+			NSOpenGLContextParameterSurfaceSurfaceVolatile API_DEPRECATED("", macos(10.0, 10.14)) = 306, /* 1 param.   Surface volatile state */
+	};
 
-	void RGFW_window_setName(RGFW_window* win, char* name) {
-		assert(win != NULL);
 
-		SetWindowTextA(win->src.window, name);
+	void NSOpenGLContext_setValues(NSOpenGLContext* context, const int* vals, NSOpenGLContextParameter param) {
+		void* func = sel_registerName("setValues:forParameter:");
+		((void (*)(id, SEL, const int*, NSOpenGLContextParameter))objc_msgSend)
+			(context, func, vals, param);
 	}
 
-	/* much of this function is sourced from GLFW */
-	void RGFW_window_setIcon(RGFW_window* win, u8* src, RGFW_area a, i32 channels) {
-		assert(win != NULL);
-		RGFW_UNUSED(channels)
-
-		HICON handle = RGFW_loadHandleImage(win, src, a, TRUE);
+	void* NSOpenGLPixelFormat_initWithAttributes(const uint32_t* attribs) {
+		void* func = sel_registerName("initWithAttributes:");
+		return (void*) ((id(*)(id, SEL, const uint32_t*))objc_msgSend)
+			(NSAlloc((id)objc_getClass("NSOpenGLPixelFormat")), func, attribs);
+	}
 
-		SetClassLongPtrA(win->src.window, GCLP_HICON, (LPARAM) handle);
+	NSOpenGLView* NSOpenGLView_initWithFrame(NSRect frameRect, uint32_t* format) {
+		void* func = sel_registerName("initWithFrame:pixelFormat:");
+		return (NSOpenGLView*) ((id(*)(id, SEL, NSRect, uint32_t*))objc_msgSend)
+			(NSAlloc((id)objc_getClass("NSOpenGLView")), func, frameRect, format);
+	}
 
-		DestroyIcon(handle);
+	void NSCursor_performSelector(NSCursor* cursor, void* selector) {
+		void* func = sel_registerName("performSelector:");
+		objc_msgSend_void_SEL(cursor, func, selector);
 	}
 
-	char* RGFW_readClipboard(size_t* size) {
-		/* Open the clipboard */
-		if (OpenClipboard(NULL) == 0)
-			return (char*) "";
+	NSPasteboard* NSPasteboard_generalPasteboard(void) {
+		return (NSPasteboard*) objc_msgSend_id((id)objc_getClass("NSPasteboard"), sel_registerName("generalPasteboard"));
+	}
 
-		/* Get the clipboard data as a Unicode string */
-		HANDLE hData = GetClipboardData(CF_UNICODETEXT);
-		if (hData == NULL) {
-			CloseClipboard();
-			return (char*) "";
-		}
+	NSString** cstrToNSStringArray(char** strs, size_t len) {
+		static NSString* nstrs[6];
+		size_t i;
+		for (i = 0; i < len; i++)
+			nstrs[i] = NSString_stringWithUTF8String(strs[i]);
 
-		wchar_t* wstr = (wchar_t*) GlobalLock(hData);
+		return nstrs;
+	}
 
-		char* text;
+	const char* NSPasteboard_stringForType(NSPasteboard* pasteboard, NSPasteboardType dataType) {
+		void* func = sel_registerName("stringForType:");
+		return (const char*) NSString_to_char(((id(*)(id, SEL, const char*))objc_msgSend)(pasteboard, func, NSString_stringWithUTF8String(dataType)));
+	}
 
-		{
-			setlocale(LC_ALL, "en_US.UTF-8");
+	NSArray* c_array_to_NSArray(void* array, size_t len) {
+		SEL func = sel_registerName("initWithObjects:count:");
+		void* nsclass = objc_getClass("NSArray");
+		return ((id (*)(id, SEL, void*, NSUInteger))objc_msgSend)
+					(NSAlloc(nsclass), func, array, len);
+	}
+ 
+	void NSregisterForDraggedTypes(void* view, NSPasteboardType* newTypes, size_t len) {
+		NSString** ntypes = cstrToNSStringArray((char**)newTypes, len);
 
-			size_t textLen = wcstombs(NULL, wstr, 0);
-			if (textLen == 0)
-				return (char*) "";
+		NSArray* array = c_array_to_NSArray(ntypes, len);
+		objc_msgSend_void_id(view, sel_registerName("registerForDraggedTypes:"), array);
+		NSRelease(array);
+	}
 
-			text = (char*) RGFW_MALLOC((textLen * sizeof(char)) + 1);
+	NSInteger NSPasteBoard_declareTypes(NSPasteboard* pasteboard, NSPasteboardType* newTypes, size_t len, void* owner) {
+		NSString** ntypes = cstrToNSStringArray((char**)newTypes, len);
 
-			wcstombs(text, wstr, (textLen) +1);
+		void* func = sel_registerName("declareTypes:owner:");
 
-			if (size != NULL)
-				*size = textLen + 1;
-		}
+		NSArray* array = c_array_to_NSArray(ntypes, len);
 
-		/* Release the clipboard data */
-		GlobalUnlock(hData);
-		CloseClipboard();
+		NSInteger output = ((NSInteger(*)(id, SEL, id, void*))objc_msgSend)
+			(pasteboard, func, array, owner);
+		NSRelease(array);
 
-		return text;
+		return output;
 	}
 
-	void RGFW_writeClipboard(const char* text, u32 textLen) {
-		HANDLE object;
-		WCHAR* buffer;
+	bool NSPasteBoard_setString(NSPasteboard* pasteboard, const char* stringToWrite, NSPasteboardType dataType) {
+		void* func = sel_registerName("setString:forType:");
+		return ((bool (*)(id, SEL, id, NSPasteboardType))objc_msgSend)
+			(pasteboard, func, NSString_stringWithUTF8String(stringToWrite), NSString_stringWithUTF8String(dataType));
+	}
 
-		object = GlobalAlloc(GMEM_MOVEABLE, (1 + textLen) * sizeof(WCHAR));
-		if (!object)
-			return;
+	void NSRetain(id obj) { objc_msgSend_void(obj, sel_registerName("retain")); }
 
-		buffer = (WCHAR*) GlobalLock(object);
-		if (!buffer) {
-			GlobalFree(object);
-			return;
-		}
+	typedef enum NSApplicationActivationPolicy {
+		NSApplicationActivationPolicyRegular,
+		NSApplicationActivationPolicyAccessory,
+		NSApplicationActivationPolicyProhibited
+	} NSApplicationActivationPolicy;
 
-		MultiByteToWideChar(CP_UTF8, 0, text, -1, buffer, textLen);
-		GlobalUnlock(object);
+	typedef NS_ENUM(u32, NSBackingStoreType) {
+		NSBackingStoreRetained = 0,
+			NSBackingStoreNonretained = 1,
+			NSBackingStoreBuffered = 2
+	};
 
-		if (!OpenClipboard(RGFW_root->src.window)) {
-			GlobalFree(object);
-			return;
-		}
+	typedef NS_ENUM(u32, NSWindowStyleMask) {
+		NSWindowStyleMaskBorderless = 0,
+			NSWindowStyleMaskTitled = 1 << 0,
+			NSWindowStyleMaskClosable = 1 << 1,
+			NSWindowStyleMaskMiniaturizable = 1 << 2,
+			NSWindowStyleMaskResizable = 1 << 3,
+			NSWindowStyleMaskTexturedBackground = 1 << 8, /* deprecated */
+			NSWindowStyleMaskUnifiedTitleAndToolbar = 1 << 12,
+			NSWindowStyleMaskFullScreen = 1 << 14,
+			NSWindowStyleMaskFullSizeContentView = 1 << 15,
+			NSWindowStyleMaskUtilityWindow = 1 << 4,
+			NSWindowStyleMaskDocModalWindow = 1 << 6,
+			NSWindowStyleMaskNonactivatingPanel = 1 << 7,
+			NSWindowStyleMaskHUDWindow = 1 << 13
+	};
 
-		EmptyClipboard();
-		SetClipboardData(CF_UNICODETEXT, object);
-		CloseClipboard();
-	}
+	typedef const char* NSPasteboardType;
+	NSPasteboardType const NSPasteboardTypeString = "public.utf8-plain-text"; // Replaces NSStringPboardType
 
-	u16 RGFW_registerJoystick(RGFW_window* win, i32 jsNumber) {
-		assert(win != NULL);
 
-		RGFW_UNUSED(jsNumber)
 
-		return RGFW_registerJoystickF(win, (char*) "");
-	}
+	typedef NS_ENUM(i32, NSDragOperation) {
+		NSDragOperationNone = 0,
+			NSDragOperationCopy = 1,
+			NSDragOperationLink = 2,
+			NSDragOperationGeneric = 4,
+			NSDragOperationPrivate = 8,
+			NSDragOperationMove = 16,
+			NSDragOperationDelete = 32,
+			NSDragOperationEvery = ULONG_MAX,
 
-	u16 RGFW_registerJoystickF(RGFW_window* win, char* file) {
-		assert(win != NULL);
-		RGFW_UNUSED(file)
+			//NSDragOperationAll_Obsolete	API_DEPRECATED("", macos(10.0,10.10)) = 15, // Use NSDragOperationEvery
+			//NSDragOperationAll API_DEPRECATED("", macos(10.0,10.10)) = NSDragOperationAll_Obsolete, // Use NSDragOperationEvery
+	};
 
-		return win->src.joystickCount - 1;
+	void* NSArray_objectAtIndex(NSArray* array, NSUInteger index) {
+		void* func = sel_registerName("objectAtIndex:");
+		return ((id(*)(id, SEL, NSUInteger))objc_msgSend)(array, func, index);
 	}
 
-	void RGFW_window_moveMouse(RGFW_window* win, RGFW_vector p) {
-		assert(win != NULL);
+	const char** NSPasteboard_readObjectsForClasses(NSPasteboard* pasteboard, Class* classArray, size_t len, void* options) {
+		void* func = sel_registerName("readObjectsForClasses:options:");
 
-		SetCursorPos(p.x, p.y);
-	}
+		NSArray* array = c_array_to_NSArray(classArray, len);
 
-	char* createUTF8FromWideStringWin32(const WCHAR* source) {
-		char* target;
-		i32 size;
+		NSArray* output = (NSArray*) ((id(*)(id, SEL, id, void*))objc_msgSend)
+			(pasteboard, func, array, options);
 
-		size = WideCharToMultiByte(CP_UTF8, 0, source, -1, NULL, 0, NULL, NULL);
-		if (!size) {
-			return NULL;
-		}
+		NSRelease(array);
+		NSUInteger count = ((NSUInteger(*)(id, SEL))objc_msgSend)(output, sel_registerName("count"));
 
-		target = (char*) RGFW_CALLOC(size, 1);
+		const char** res = si_array_init_reserve(sizeof(const char*), count);
 
-		if (!WideCharToMultiByte(CP_UTF8, 0, source, -1, target, size, NULL, NULL)) {
-			RGFW_FREE(target);
-			return NULL;
+		void* path_func = sel_registerName("path");
+
+		for (NSUInteger i = 0; i < count; i++) {
+			void* url = NSArray_objectAtIndex(output, i);
+			NSString* url_str = ((id(*)(id, SEL))objc_msgSend)(url, path_func);
+			res[i] = NSString_to_char(url_str);
 		}
 
-		return target;
+		return res;
 	}
 
-#ifndef RGFW_NO_THREADS
-	RGFW_thread RGFW_createThread(RGFW_threadFunc_ptr ptr, void* args) { return CreateThread(NULL, 0, ptr, args, 0, NULL); }
-	void RGFW_cancelThread(RGFW_thread thread) { CloseHandle((HANDLE) thread); }
-	void RGFW_joinThread(RGFW_thread thread) { WaitForSingleObject((HANDLE) thread, INFINITE); }
-	void RGFW_setThreadPriority(RGFW_thread thread, u8 priority) { SetThreadPriority((HANDLE) thread, priority); }
-#endif
-#endif
+	void* NSWindow_contentView(NSWindow* window) {
+		void* func = sel_registerName("contentView");
+		return objc_msgSend_id(window, func);
+	}
 
-#if defined(RGFW_MACOS)
+	/*
+		End of cocoa wrapper
+	*/
+
+	char* RGFW_mouseIconSrc[] = {"arrowCursor", "arrowCursor", "IBeamCursor", "crosshairCursor", "pointingHandCursor", "resizeLeftRightCursor", "resizeUpDownCursor", "_windowResizeNorthWestSouthEastCursor", "_windowResizeNorthEastSouthWestCursor", "closedHandCursor", "operationNotAllowedCursor"};
 
 	void* RGFWnsglFramework = NULL;
 
@@ -5362,20 +5475,18 @@ static HMODULE wglinstance = NULL;
 		return kCVReturnSuccess; 
 	}
 
-	RGFW_window* RGFW_windows[10];
-	u32 RGFW_windows_size = 0;
-
 	id NSWindow_delegate(RGFW_window* win) {
 		return (id) objc_msgSend_id(win->src.window, sel_registerName("delegate"));
 	}
 
 	u32 RGFW_OnClose(void* self) {
-		u32 i;
-		for (i = 0; i < RGFW_windows_size; i++)
-			if (RGFW_windows[i] && NSWindow_delegate(RGFW_windows[i]) == self) {
-				RGFW_windows[i]->event.type = RGFW_quit;
-				return true;
-			}
+		RGFW_window* win = NULL;
+		object_getInstanceVariable(self, "RGFW_window", (void*)&win);
+		if (win == NULL)
+			return true;
+
+		win->event.type = RGFW_quit;
+		RGFW_windowQuitCallback(win);
 
 		return true;
 	}
@@ -5386,13 +5497,44 @@ static HMODULE wglinstance = NULL;
 
 	NSDragOperation draggingEntered(id self, SEL sel, id sender) { 
 		RGFW_UNUSED(sender); RGFW_UNUSED(self); RGFW_UNUSED(sel);  
+
+		printf("hi\n");
 		return NSDragOperationCopy; 
 	}
 	NSDragOperation draggingUpdated(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 true;
+		
+		if (!(win->src.winArgs & RGFW_ALLOW_DND)) {
+			return false;
+		}
+
+		win->event.type = RGFW_dnd_init;
+		win->src.dndPassed = 0;
+
+		NSPoint p = ((NSPoint(*)(id, SEL)) objc_msgSend)(sender, sel_registerName("draggingLocation"));
+
+		win->event.point = RGFW_VECTOR((u32) p.x, (u32) (win->r.h - p.y));
+		RGFW_dndInitCallback(win, win->event.point);
+
 		return NSDragOperationCopy; 
 	}
-	bool prepareForDragOperation(void) { return true; }
+	bool prepareForDragOperation(id self) {
+		RGFW_window* win = NULL;
+		object_getInstanceVariable(self, "RGFW_window", (void*)&win);
+		if (win == NULL)
+			return true;
+		
+		if (!(win->src.winArgs & RGFW_ALLOW_DND)) {
+			return false;
+		}
+
+		return true;
+	}
 
 	void RGFW__osxDraggingEnded(id self, SEL sel, id sender) { RGFW_UNUSED(sender); RGFW_UNUSED(self); RGFW_UNUSED(sel);  return; }
 
@@ -5400,16 +5542,15 @@ static HMODULE wglinstance = NULL;
 	bool performDragOperation(id self, SEL sel, id sender) {
 		RGFW_UNUSED(sender); RGFW_UNUSED(self); RGFW_UNUSED(sel); 
 
-		NSWindow* window = objc_msgSend_id(sender, sel_registerName("draggingDestinationWindow"));
+		RGFW_window* win = NULL;
+		object_getInstanceVariable(self, "RGFW_window", (void*)&win);
+		if (win == NULL)
+			return true;
+
+		//NSWindow* window = objc_msgSend_id(sender, sel_registerName("draggingDestinationWindow"));
 		u32 i;
 		bool found = 0;
 
-		for (i = 0; i < RGFW_windows_size; i++)
-			if (RGFW_windows[i]->src.window == window) {
-				found = 1;
-				break;
-			}
-
 		if (!found)
 			i = 0;
 
@@ -5418,20 +5559,23 @@ static HMODULE wglinstance = NULL;
 		
 		char** droppedFiles = (char**) NSPasteboard_readObjectsForClasses(pasteBoard, array, 1, NULL);
 
-		RGFW_windows[i]->event.droppedFilesCount = si_array_len(droppedFiles);
+		win->event.droppedFilesCount = si_array_len(droppedFiles);
 
 		u32 y;
 
-		for (y = 0; y < RGFW_windows[i]->event.droppedFilesCount; y++)
-			strcpy(RGFW_windows[i]->event.droppedFiles[y], droppedFiles[y]);
+		for (y = 0; y < win->event.droppedFilesCount; y++) {
+			strncpy(win->event.droppedFiles[y], droppedFiles[y], RGFW_MAX_PATH);
 
-		RGFW_windows[i]->event.type = RGFW_dnd;
-		RGFW_windows[i]->src.dndPassed = 0;
+			win->event.droppedFiles[y][RGFW_MAX_PATH - 1] = '\0';
+		}
+
+		win->event.type = RGFW_dnd;
+		win->src.dndPassed = 0;
 
 		NSPoint p = ((NSPoint(*)(id, SEL)) objc_msgSend)(sender, sel_registerName("draggingLocation"));
+		win->event.point = RGFW_VECTOR((u32) p.x, (u32) (win->r.h - p.y));
 
-		RGFW_windows[i]->event.point.x = (i32)p.x;
-		RGFW_windows[i]->event.point.x = (i32)p.y;
+		RGFW_dndCallback(win, win->event.droppedFiles, win->event.droppedFilesCount);
 		return true;
 	}
 
@@ -5468,41 +5612,62 @@ static HMODULE wglinstance = NULL;
 	NSSize RGFW__osxWindowResize(void* self, SEL sel, NSSize frameSize) {
 		RGFW_UNUSED(sel); 
 
-		u32 i;
-		for (i = 0; i < RGFW_windows_size; i++) {
-			if (RGFW_windows[i] && NSWindow_delegate(RGFW_windows[i]) == self) {
-				RGFW_windows[i]->r.w = frameSize.width;
-				RGFW_windows[i]->r.h = frameSize.height;
-				RGFW_windows[i]->event.type = RGFW_windowResized;
-
-				return frameSize;
-			}
-		}
-
+		RGFW_window* win = NULL;
+		object_getInstanceVariable(self, "RGFW_window", (void*)&win);
+		if (win == NULL)
+			return frameSize;
+		
+		win->r.w = frameSize.width;
+		win->r.h = frameSize.height;
+		win->event.type = RGFW_windowResized;
+		RGFW_windowResizeCallback(win, win->r);
 		return frameSize;
 	}
 
 	void RGFW__osxWindowMove(void* self, SEL sel) {
 		RGFW_UNUSED(sel); 
 
-		u32 i;
-		for (i = 0; i < RGFW_windows_size; i++) {
-			if (RGFW_windows[i] && NSWindow_delegate(RGFW_windows[i]) == self) {
-				NSRect frame = ((NSRect(*)(id, SEL))abi_objc_msgSend_stret)(RGFW_windows[i]->src.window, sel_registerName("frame"));
-				RGFW_windows[i]->r.x = (i32) frame.origin.x;
-				RGFW_windows[i]->r.y = (i32) frame.origin.y;
+		RGFW_window* win = NULL;
+		object_getInstanceVariable(self, "RGFW_window", (void*)&win);
+		if (win == NULL)
+			return;
+		
+		NSRect frame = ((NSRect(*)(id, SEL))abi_objc_msgSend_stret)(win->src.window, sel_registerName("frame"));
+		win->r.x = (i32) frame.origin.x;
+		win->r.y = (i32) frame.origin.y;
+
+		win->event.type = RGFW_windowMoved;
+		RGFW_windowMoveCallback(win, win->r);
+	}
+
+	void RGFW__osxUpdateLayer(void* self, SEL sel) {
+		RGFW_UNUSED(sel);
 
-				RGFW_windows[i]->event.type = RGFW_windowMoved;
-				return;
-			}
-		}
+		RGFW_window* win = NULL;
+		object_getInstanceVariable(self, "RGFW_window", (void*)&win);
+		if (win == NULL)
+			return;
+		
+		win->event.type = RGFW_windowRefresh;
+		RGFW_windowRefreshCallback(win);
 	}
 
-	#ifdef __cplusplus
-	#define APPKIT_EXTERN		extern "C"
-	#else
-	#define APPKIT_EXTERN		extern
-	#endif
+	RGFWDEF void RGFW_init_buffer(RGFW_window* win);
+	void RGFW_init_buffer(RGFW_window* win) {
+		#if defined(RGFW_OSMESA) || defined(RGFW_BUFFER)
+			if (RGFW_bufferSize.w == 0 && RGFW_bufferSize.h == 0)
+				RGFW_bufferSize = RGFW_getScreenSize();
+				
+			win->buffer = RGFW_MALLOC(RGFW_bufferSize.w * RGFW_bufferSize.h * 4);
+
+		#ifdef RGFW_OSMESA
+				win->src.rSurf = OSMesaCreateContext(OSMESA_RGBA, NULL);
+				OSMesaMakeCurrent(win->src.rSurf, win->buffer, GL_UNSIGNED_BYTE, win->r.w, win->r.h);
+		#endif
+		#else
+		RGFW_UNUSED(win); /* if buffer rendering is not being used */
+		#endif
+	}
 
 	NSPasteboardType const NSPasteboardTypeURL = "public.url";
 	NSPasteboardType const NSPasteboardTypeFileURL  = "public.file-url";
@@ -5527,6 +5692,8 @@ static HMODULE wglinstance = NULL;
 		}
 
 		RGFW_window* win = RGFW_window_basic_init(rect, args);
+		
+		RGFW_window_setMouseDefault(win);
 
 		NSRect windowRect;
 		windowRect.origin.x = win->r.x;
@@ -5554,6 +5721,7 @@ static HMODULE wglinstance = NULL;
 		objc_msgSend_void_id(win->src.window, sel_registerName("setTitle:"), str);
 
 #ifdef RGFW_OPENGL
+	if ((args & RGFW_NO_INIT_API) == 0) {
 		void* attrs = RGFW_initAttribs(args & RGFW_OPENGL_SOFTWARE);
 		void* format = NSOpenGLPixelFormat_initWithAttributes(attrs);
 
@@ -5568,17 +5736,17 @@ static HMODULE wglinstance = NULL;
 				printf("Switching to software rendering\n");
 		}
 
-		win->src.view = NSOpenGLView_initWithFrame(NSMakeRect(0, 0, win->r.w, win->r.h), format);
+		win->src.view = NSOpenGLView_initWithFrame((NSRect){{0, 0}, {win->r.w, win->r.h}}, format);
 		objc_msgSend_void(win->src.view, sel_registerName("prepareOpenGL"));
 		win->src.rSurf = objc_msgSend_id(win->src.view, sel_registerName("openGLContext"));
-
-#else
-		NSRect contentRect = NSMakeRect(0, 0, win->r.w, win->r.h);
+	} else
+#endif
+	{
+		NSRect contentRect = (NSRect){{0, 0}, {win->r.w, win->r.h}};
 		win->src.view = ((id(*)(id, SEL, NSRect))objc_msgSend)
 			(NSAlloc((id)objc_getClass("NSView")), sel_registerName("initWithFrame:"),
 				contentRect);
-#endif
-
+	}
 
 		void* contentView = NSWindow_contentView(win->src.window);
 		objc_msgSend_void_bool(contentView, sel_registerName("setWantsLayer:"), true);
@@ -5586,21 +5754,22 @@ static HMODULE wglinstance = NULL;
 		objc_msgSend_void_id(win->src.window, sel_registerName("setContentView:"), win->src.view);
 
 #ifdef RGFW_OPENGL
-		objc_msgSend_void(win->src.rSurf, sel_registerName("makeCurrentContext"));
+		if ((args & RGFW_NO_INIT_API) == 0)
+			objc_msgSend_void(win->src.rSurf, sel_registerName("makeCurrentContext"));
 #endif
 		if (args & RGFW_TRANSPARENT_WINDOW) {
 #ifdef RGFW_OPENGL
+		if ((args & RGFW_NO_INIT_API) == 0) {
 			i32 opacity = 0;
-			NSOpenGLContext_setValues(win->src.rSurf, &opacity, 304);
+			#define NSOpenGLCPSurfaceOpacity 236
+			NSOpenGLContext_setValues(win->src.rSurf, &opacity, NSOpenGLCPSurfaceOpacity);
+		}
 #endif
 
 			objc_msgSend_void_bool(win->src.window, sel_registerName("setOpaque:"), false);
 
 			objc_msgSend_void_id(win->src.window, sel_registerName("setBackgroundColor:"),
 				NSColor_colorWithSRGB(0, 0, 0, 0));
-
-			((void (*)(id, SEL, CGFloat))objc_msgSend)
-				(win->src.window, sel_registerName("setAlphaValue:"), 0x00);
 		}
 
 		win->src.display = CGMainDisplayID();
@@ -5610,12 +5779,10 @@ static HMODULE wglinstance = NULL;
 
 		RGFW_init_buffer(win);
 
-#ifdef RGFW_VULKAN
-		RGFW_initVulkan(win);
-#endif
-
+		#ifndef RGFW_NO_MONITOR
 		if (args & RGFW_SCALE_TO_MONITOR)
 			RGFW_window_scaleToMonitor(win);
+		#endif
 
 		if (args & RGFW_HIDE_MOUSE)
 			RGFW_window_showMouse(win, 0);
@@ -5624,9 +5791,15 @@ static HMODULE wglinstance = NULL;
 			NSMoveToResourceDir();
 
 		Class delegateClass = objc_allocateClassPair(objc_getClass("NSObject"), "WindowDelegate", 0);
-		
+
+		class_addIvar(
+			delegateClass, "RGFW_window",
+			sizeof(RGFW_window*), rint(log2(sizeof(RGFW_window*))),
+			"L"
+		);
 
 		class_addMethod(delegateClass, sel_registerName("windowWillResize:toSize:"), (IMP) RGFW__osxWindowResize, "{NSSize=ff}@:{NSSize=ff}");
+		class_addMethod(delegateClass, sel_registerName("updateLayer:"), (IMP) RGFW__osxUpdateLayer, "");
 		class_addMethod(delegateClass, sel_registerName("windowWillMove:"), (IMP) RGFW__osxWindowMove, "");
 		class_addMethod(delegateClass, sel_registerName("windowDidMove:"), (IMP) RGFW__osxWindowMove, "");
 		class_addMethod(delegateClass, sel_registerName("draggingEntered:"), (IMP)draggingEntered, "l@:@");
@@ -5661,16 +5834,7 @@ static HMODULE wglinstance = NULL;
 
 		objc_msgSend_void(win->src.window, sel_registerName("makeKeyWindow"));
 
-		NSApplication_finishLaunching(NSApp);
-
-		RGFW_windows_size++;
-
-		size_t i;
-		for (i = 0; i < RGFW_windows_size; i++)
-			if (!RGFW_windows[i]) {
-				RGFW_windows[i] = win;
-				break;
-			}
+		objc_msgSend_void(NSApp, sel_registerName("finishLaunching"));
 
 		if (RGFW_root == NULL)
 			RGFW_root = win;
@@ -5681,6 +5845,19 @@ static HMODULE wglinstance = NULL;
 		return win;
 	}
 
+	void RGFW_window_setBorder(RGFW_window* win, u8 border) {
+		NSBackingStoreType storeType = NSWindowStyleMaskBorderless;
+		if (!border) {
+			storeType = NSWindowStyleMaskTitled | NSWindowStyleMaskClosable | NSWindowStyleMaskMiniaturizable;
+		}
+		if (!(win->src.winArgs & RGFW_NO_RESIZE)) {
+			storeType |= NSWindowStyleMaskResizable;
+		}
+		
+		((void (*)(id, SEL, NSBackingStoreType))objc_msgSend)(win->src.window, sel_registerName("setStyleMask:"), storeType);
+
+		objc_msgSend_void_bool(win->src.window, sel_registerName("setHasShadow:"), border);
+	}
 
 	RGFW_area RGFW_getScreenSize(void) {
 		static CGDirectDisplayID display = 0;
@@ -5704,7 +5881,7 @@ static HMODULE wglinstance = NULL;
 	RGFW_vector RGFW_window_getMousePoint(RGFW_window* win) {
 		NSPoint p =  ((NSPoint(*)(id, SEL)) objc_msgSend)(win->src.window, sel_registerName("mouseLocationOutsideOfEventStream"));
 
-		return RGFW_VECTOR((u32) p.x, (u32) (p.y));
+		return RGFW_VECTOR((u32) p.x, (u32) (win->r.h - p.y));
 	}
 
 	u32 RGFW_keysPressed[10]; /*10 keys at a time*/
@@ -5798,16 +5975,17 @@ static HMODULE wglinstance = NULL;
 		NSEventModifierFlagShift = 1 << 17,
 		NSEventModifierFlagControl = 1 << 18,
 		NSEventModifierFlagOption = 1 << 19,
-		NSEventModifierFlagCommand = 1 << 20
+		NSEventModifierFlagCommand = 1 << 20,
+		NSEventModifierFlagNumericPad = 1 << 21
 	} NSEventModifierFlags;
 
 	RGFW_Event* RGFW_window_checkEvent(RGFW_window* win) {
 		assert(win != NULL);
-
+		
 		if (win->event.type == RGFW_quit)
-			return &win->event;
+			return NULL;
 
-		if (win->event.type == RGFW_dnd && win->src.dndPassed == 0) {
+		if ((win->event.type == RGFW_dnd || win->event.type == RGFW_dnd_init) && win->src.dndPassed == 0) {
 			win->src.dndPassed = 1;
 			return &win->event;
 		}
@@ -5816,7 +5994,7 @@ static HMODULE wglinstance = NULL;
 		if (eventFunc == NULL)
 			eventFunc = sel_registerName("nextEventMatchingMask:untilDate:inMode:dequeue:");
 		
-		if ((win->event.type == RGFW_windowMoved || win->event.type == RGFW_windowResized) && win->event.keyCode != 120) {
+		if ((win->event.type == RGFW_windowMoved || win->event.type == RGFW_windowResized || win->event.type == RGFW_windowRefresh) && win->event.keyCode != 120) {
 			win->event.keyCode = 120;
 			return &win->event;
 		}
@@ -5824,7 +6002,6 @@ static HMODULE wglinstance = NULL;
 		NSEvent* e = (NSEvent*) ((id(*)(id, SEL, NSEventMask, void*, NSString*, bool))objc_msgSend)
 			(NSApp, eventFunc, ULONG_MAX, NULL, NSString_stringWithUTF8String("kCFRunLoopDefaultMode"), true);
 
-
 		if (e == NULL)
 			return NULL;
 
@@ -5844,29 +6021,32 @@ static HMODULE wglinstance = NULL;
 		win->event.droppedFilesCount = 0;
 		win->event.type = 0;
 
-		bool isKey = (bool) objc_msgSend_bool(win->src.window, sel_registerName("isKeyWindow"));
-		
-		if (win->event.inFocus != isKey) {
-			win->event.inFocus = isKey;
-			
-			if (win->event.inFocus)
-				win->event.type = RGFW_focusIn;
-			else
-				win->event.type = RGFW_focusOut;
+		switch (objc_msgSend_uint(e, sel_registerName("type"))) {
+			case NSEventTypeMouseEntered: {
+				win->event.type = RGFW_mouseEnter;
+				NSPoint p = ((NSPoint(*)(id, SEL)) objc_msgSend)(e, sel_registerName("locationInWindow"));
 
-			return &win->event;
-		}
+				win->event.point = RGFW_VECTOR((u32) p.x, (u32) (win->r.h - p.y));
+				RGFW_mouseNotifyCallBack(win, win->event.point, 1);
+				break;
+			}
+			
+			case NSEventTypeMouseExited:
+				win->event.type = RGFW_mouseLeave;
+				RGFW_mouseNotifyCallBack(win, win->event.point, 0);
+				break;
 
-		switch (objc_msgSend_uint(e, sel_registerName("type"))) {
 			case NSEventTypeKeyDown: {
 				u32 key = (u16) objc_msgSend_uint(e, sel_registerName("keyCode"));
 				win->event.keyCode = RGFW_apiKeyCodeToRGFW(key);
-				RGFW_keyboard_prev[win->event.keyCode] = RGFW_keyboard[win->event.keyCode];
+				RGFW_keyboard[win->event.keyCode].prev = RGFW_keyboard[win->event.keyCode].current;
 
 				win->event.type = RGFW_keyPressed;
-				win->event.keyName = (char*)(const char*) NSString_to_char(objc_msgSend_id(e, sel_registerName("characters")));
+				char* str = (char*)(const char*) NSString_to_char(objc_msgSend_id(e, sel_registerName("characters")));
+				strncpy(win->event.keyName, str, 16);
+				RGFW_keyboard[win->event.keyCode].current = 1;
 
-				RGFW_keyboard[win->event.keyCode] = 1;
+				RGFW_keyCallback(win, win->event.keyCode, win->event.keyName, win->event.lockState, 1);
 				break;
 			}
 
@@ -5874,86 +6054,53 @@ static HMODULE wglinstance = NULL;
 				u32 key = (u16) objc_msgSend_uint(e, sel_registerName("keyCode"));
 				win->event.keyCode = RGFW_apiKeyCodeToRGFW(key);;
 
-				RGFW_keyboard_prev[win->event.keyCode] = RGFW_keyboard[win->event.keyCode];
+				RGFW_keyboard[win->event.keyCode].prev = RGFW_keyboard[win->event.keyCode].current;
 
 				win->event.type = RGFW_keyReleased;
-				win->event.keyName = (char*)(const char*) NSString_to_char(objc_msgSend_id(e, sel_registerName("characters")));
+				char* str = (char*)(const char*) NSString_to_char(objc_msgSend_id(e, sel_registerName("characters")));
+				strncpy(win->event.keyName, str, 16);
 
-				RGFW_keyboard[win->event.keyCode] = 0;
+				RGFW_keyboard[win->event.keyCode].current = 0;
+				RGFW_keyCallback(win, win->event.keyCode, win->event.keyName, win->event.lockState, 0);
 				break;
 			}
 
 			case NSEventTypeFlagsChanged: {
 				u32 flags = objc_msgSend_uint(e, sel_registerName("modifierFlags"));
-				memcpy(RGFW_keyboard_prev + RGFW_CapsLock, RGFW_keyboard + RGFW_CapsLock, 9);
-
-				if ((flags & NSEventModifierFlagCapsLock) && !RGFW_wasPressedI(win, RGFW_CapsLock)) {
-					RGFW_keyboard[RGFW_CapsLock] = 1;
-					win->event.type = RGFW_keyPressed;
-					win->event.keyCode = RGFW_apiKeyCodeToRGFW(57);
-					break;
-				} if (!(flags & NSEventModifierFlagCapsLock) && RGFW_wasPressedI(win, RGFW_CapsLock)) {
-					RGFW_keyboard[RGFW_CapsLock] = 0;
-					win->event.type = RGFW_keyReleased;
-					win->event.keyCode = RGFW_apiKeyCodeToRGFW(57);
-					break;
-				}
-
-				if ((flags & NSEventModifierFlagOption) && !RGFW_wasPressedI(win, RGFW_AltL)) {
-					RGFW_keyboard[RGFW_AltL] = 1;
-					RGFW_keyboard[RGFW_AltR] = 1;
-					win->event.type = RGFW_keyPressed;
-					win->event.keyCode = RGFW_apiKeyCodeToRGFW(58);
-					break;
-				} if (!(flags & NSEventModifierFlagOption) && RGFW_wasPressedI(win, RGFW_AltL)) {
-					RGFW_keyboard[RGFW_AltL] = 0;
-					RGFW_keyboard[RGFW_AltR] = 0;
-					win->event.type = RGFW_keyReleased;
-					win->event.keyCode = RGFW_apiKeyCodeToRGFW(58);
-					break;
-				} 
-
-				if ((flags & NSEventModifierFlagControl) && !RGFW_wasPressedI(win, RGFW_ControlL)) {
-					RGFW_keyboard[RGFW_ControlL] = 1;
-					RGFW_keyboard[RGFW_ControlR] = 1;
-					win->event.type = RGFW_keyPressed;
-					win->event.keyCode = RGFW_apiKeyCodeToRGFW(59);
-					break;
-				} if (!(flags & NSEventModifierFlagControl) && RGFW_wasPressedI(win, RGFW_ControlL)) {
-					RGFW_keyboard[RGFW_ControlL] = 0;
-					RGFW_keyboard[RGFW_ControlR] = 0;
-					win->event.type = RGFW_keyReleased;
-					win->event.keyCode = 59;
-					break;
+				RGFW_updateLockState(win, ((u32)(flags & NSEventModifierFlagCapsLock) % 255), ((flags & NSEventModifierFlagNumericPad) % 255));
+				
+				u8 i;
+				for (i = 0; i < 9; i++)
+					RGFW_keyboard[i + RGFW_CapsLock].prev = 0;
+				
+				for (i = 0; i < 5; i++) {
+					u32 shift = (1 << (i + 16));
+					u32 key = i + RGFW_CapsLock;
+
+					if ((flags & shift) && !RGFW_wasPressed(win, key)) {
+						RGFW_keyboard[key].current = 1;
+
+						if (key != RGFW_CapsLock)
+							RGFW_keyboard[key+ 4].current = 1;
+						
+						win->event.type = RGFW_keyPressed;
+						win->event.keyCode = key;
+						break;
+					} 
+					
+					if (!(flags & shift) && RGFW_wasPressed(win, key)) {
+						RGFW_keyboard[key].current = 0;
+						
+						if (key != RGFW_CapsLock)
+							RGFW_keyboard[key + 4].current = 0;
+
+						win->event.type = RGFW_keyReleased;
+						win->event.keyCode = key;
+						break;
+					}
 				}
 
-				if ((flags & NSEventModifierFlagCommand) && !RGFW_wasPressedI(win, RGFW_SuperL)) {
-					RGFW_keyboard[RGFW_SuperL] = 1;
-					RGFW_keyboard[RGFW_SuperR] = 1;
-					win->event.type = RGFW_keyPressed;
-					win->event.keyCode = RGFW_apiKeyCodeToRGFW(55);
-					break;
-				} if (!(flags & NSEventModifierFlagCommand) && RGFW_wasPressedI(win, RGFW_SuperL)) {
-					RGFW_keyboard[RGFW_SuperL] = 0;
-					RGFW_keyboard[RGFW_SuperR] = 0;
-					win->event.type = RGFW_keyReleased;
-					win->event.keyCode = RGFW_apiKeyCodeToRGFW(55);
-					break;
-				} 
-
-				if ((flags & NSEventModifierFlagShift) && !RGFW_wasPressedI(win, RGFW_ShiftL)) {
-					RGFW_keyboard[RGFW_ShiftL] = 1;
-					RGFW_keyboard[RGFW_ShiftR] = 1;
-					win->event.type = RGFW_keyPressed;
-					win->event.keyCode = RGFW_apiKeyCodeToRGFW(56);
-					break;
-				} if (!(flags & NSEventModifierFlagShift) && RGFW_wasPressedI(win, RGFW_ShiftL)) {
-					RGFW_keyboard[RGFW_ShiftL] = 0;
-					RGFW_keyboard[RGFW_ShiftR] = 0;
-					win->event.type = RGFW_keyReleased;
-					win->event.keyCode = RGFW_apiKeyCodeToRGFW(56);
-					break;
-				}
+				RGFW_keyCallback(win, win->event.keyCode, win->event.keyName, win->event.lockState, win->event.type == RGFW_keyPressed);
 
 				break;
 			}
@@ -5963,8 +6110,18 @@ static HMODULE wglinstance = NULL;
 			case NSEventTypeMouseMoved:
 				win->event.type = RGFW_mousePosChanged;
 				NSPoint p = ((NSPoint(*)(id, SEL)) objc_msgSend)(e, sel_registerName("locationInWindow"));
-
 				win->event.point = RGFW_VECTOR((u32) p.x, (u32) (win->r.h - p.y));
+
+				if ((win->src.winArgs & RGFW_HOLD_MOUSE)) {
+					p.x = ((CGFloat(*)(id, SEL))abi_objc_msgSend_fpret)(e, sel_registerName("deltaX"));
+					p.y = ((CGFloat(*)(id, SEL))abi_objc_msgSend_fpret)(e, sel_registerName("deltaY"));
+					
+					p.x = ((win->r.w / 2)) + p.x;
+					p.y = ((win->r.h / 2)) + p.y;
+					win->event.point = RGFW_VECTOR((u32) p.x, (u32) (p.y));
+				}
+
+				RGFW_mousePosCallback(win, win->event.point);
 				break;
 
 			case NSEventTypeLeftMouseDown:
@@ -5972,6 +6129,7 @@ static HMODULE wglinstance = NULL;
 				win->event.type = RGFW_mouseButtonPressed;
 				RGFW_mouseButtons_prev[win->event.button] = RGFW_mouseButtons[win->event.button];
 				RGFW_mouseButtons[win->event.button] = 1;
+				RGFW_mouseButtonCallback(win, win->event.button, win->event.scroll, 1);
 				break;
 
 			case NSEventTypeOtherMouseDown:
@@ -5979,6 +6137,7 @@ static HMODULE wglinstance = NULL;
 				win->event.type = RGFW_mouseButtonPressed;
 				RGFW_mouseButtons_prev[win->event.button] = RGFW_mouseButtons[win->event.button];
 				RGFW_mouseButtons[win->event.button] = 1;
+				RGFW_mouseButtonCallback(win, win->event.button, win->event.scroll, 1);
 				break;
 
 			case NSEventTypeRightMouseDown:
@@ -5986,6 +6145,7 @@ static HMODULE wglinstance = NULL;
 				win->event.type = RGFW_mouseButtonPressed;
 				RGFW_mouseButtons_prev[win->event.button] = RGFW_mouseButtons[win->event.button];
 				RGFW_mouseButtons[win->event.button] = 1;
+				RGFW_mouseButtonCallback(win, win->event.button, win->event.scroll, 1);
 				break;
 
 			case NSEventTypeLeftMouseUp:
@@ -5993,6 +6153,7 @@ static HMODULE wglinstance = NULL;
 				win->event.type = RGFW_mouseButtonReleased;
 				RGFW_mouseButtons_prev[win->event.button] = RGFW_mouseButtons[win->event.button];
 				RGFW_mouseButtons[win->event.button] = 0;
+				RGFW_mouseButtonCallback(win, win->event.button, win->event.scroll, 0);
 				break;
 
 			case NSEventTypeOtherMouseUp:
@@ -6000,6 +6161,15 @@ static HMODULE wglinstance = NULL;
 				RGFW_mouseButtons_prev[win->event.button] = RGFW_mouseButtons[win->event.button];
 				RGFW_mouseButtons[win->event.button] = 0;
 				win->event.type = RGFW_mouseButtonReleased;
+				RGFW_mouseButtonCallback(win, win->event.button, win->event.scroll, 0);
+				break;
+
+			case NSEventTypeRightMouseUp:
+				win->event.button = RGFW_mouseRight;
+				RGFW_mouseButtons_prev[win->event.button] = RGFW_mouseButtons[win->event.button];
+				RGFW_mouseButtons[win->event.button] = 0;
+				win->event.type = RGFW_mouseButtonReleased;
+				RGFW_mouseButtonCallback(win, win->event.button, win->event.scroll, 0);
 				break;
 
 			case NSEventTypeScrollWheel: {
@@ -6017,15 +6187,10 @@ static HMODULE wglinstance = NULL;
 
 				win->event.scroll = deltaY;
 
-				win->event.type = RGFW_mouseButtonReleased;
+				win->event.type = RGFW_mouseButtonPressed;
+				RGFW_mouseButtonCallback(win, win->event.button, win->event.scroll, 1);
 				break;
 			}
-			case NSEventTypeRightMouseUp:
-				win->event.button = RGFW_mouseRight;
-				RGFW_mouseButtons_prev[win->event.button] = RGFW_mouseButtons[win->event.button];
-				RGFW_mouseButtons[win->event.button] = 0;
-				win->event.type = RGFW_mouseButtonReleased;
-				break;
 
 			default:
 				break;
@@ -6043,7 +6208,7 @@ static HMODULE wglinstance = NULL;
 		win->r.x = v.x;
 		win->r.y = v.y;
 		((void(*)(id, SEL, NSRect, bool, bool))objc_msgSend)
-			(win->src.window, sel_registerName("setFrame:display:animate:"), NSMakeRect(win->r.x, win->r.y, win->r.w, win->r.h), true, true);
+			(win->src.window, sel_registerName("setFrame:display:animate:"), (NSRect){{win->r.x, win->r.y}, {win->r.w, win->r.h}}, true, true);
 	}
 
 	void RGFW_window_resize(RGFW_window* win, RGFW_area a) {
@@ -6052,7 +6217,7 @@ static HMODULE wglinstance = NULL;
 		win->r.w = a.w;
 		win->r.h = a.h;
 		((void(*)(id, SEL, NSRect, bool, bool))objc_msgSend)
-			(win->src.window, sel_registerName("setFrame:display:animate:"), NSMakeRect(win->r.x, win->r.y, win->r.w, win->r.h), true, true);
+			(win->src.window, sel_registerName("setFrame:display:animate:"), (NSRect){{win->r.x, win->r.y}, {win->r.w, win->r.h}}, true, true);
 	}
 
 	void RGFW_window_minimize(RGFW_window* win) {
@@ -6074,14 +6239,26 @@ static HMODULE wglinstance = NULL;
 		objc_msgSend_void_id(win->src.window, sel_registerName("setTitle:"), str);
 	}
 
+	#ifndef RGFW_NO_PASSTHROUGH
+	void RGFW_window_setMousePassthrough(RGFW_window* win, b8 passthrough) {
+		objc_msgSend_void_bool(win->src.window, sel_registerName("setIgnoresMouseEvents:"), passthrough);
+	}
+	#endif
+
 	void RGFW_window_setMinSize(RGFW_window* win, RGFW_area a) {
+		if (a.w == 0 && a.h == 0)
+			return;
+
 		((void (*)(id, SEL, NSSize))objc_msgSend)
-			(win->src.window, sel_registerName("setMinSize:"), NSMakeSize(a.w, a.h));
+			(win->src.window, sel_registerName("setMinSize:"), (NSSize){a.w, a.h});
 	}
 
 	void RGFW_window_setMaxSize(RGFW_window* win, RGFW_area a) {
+		if (a.w == 0 && a.h == 0)
+			return;
+
 		((void (*)(id, SEL, NSSize))objc_msgSend)
-			(win->src.window, sel_registerName("setMaxSize:"), NSMakeSize(a.w, a.h));
+			(win->src.window, sel_registerName("setMaxSize:"), (NSSize){a.w, a.h});
 	}
 
 	void RGFW_window_setIcon(RGFW_window* win, u8* data, RGFW_area area, i32 channels) {
@@ -6093,7 +6270,7 @@ static HMODULE wglinstance = NULL;
 		memcpy(NSBitmapImageRep_bitmapData(representation), data, area.w * area.h * channels);
 
 		// Add ze representation.
-		void* dock_image = NSImage_initWithSize(NSMakeSize(area.w, area.h));
+		void* dock_image = NSImage_initWithSize((NSSize){area.w, area.h});
 		NSImage_addRepresentation(dock_image, (void*) representation);
 
 		// Finally, set the dock image to it.
@@ -6123,11 +6300,11 @@ static HMODULE wglinstance = NULL;
 		memcpy(NSBitmapImageRep_bitmapData(representation), image, a.w * a.h * channels);
 
 		// Add ze representation.
-		void* cursor_image = NSImage_initWithSize(NSMakeSize(a.w, a.h));
+		void* cursor_image = NSImage_initWithSize((NSSize){a.w, a.h});
 		NSImage_addRepresentation(cursor_image, representation);
 
 		// Finally, set the cursor image.
-		void* cursor = NSCursor_initWithImage(cursor_image, NSMakePoint(0, 0));
+		void* cursor = NSCursor_initWithImage(cursor_image, (NSPoint){0.0, 0.0});
 
 		objc_msgSend_void(cursor, sel_registerName("set"));
 
@@ -6166,11 +6343,15 @@ static HMODULE wglinstance = NULL;
 		objc_msgSend_void(mouse, sel_registerName("set"));
 	}
 
+	void RGFW_clipCursor(RGFW_rect r) { 
+		CGWarpMouseCursorPosition(CGPointMake(r.x + (r.w / 2), r.y + (r.h / 2)));
+		CGAssociateMouseAndMouseCursorPosition((!r.x && !r.y && r.w && !r.h));
+	}
+
 	void RGFW_window_moveMouse(RGFW_window* win, RGFW_vector v) {
 		RGFW_UNUSED(win);
-		assert(win != NULL);
 
-		CGWarpMouseCursorPosition(CGPointMake(v.x, v.y));
+		CGWarpMouseCursorPosition(CGPointMake(v.x, v.y));		
 	}
 
 
@@ -6248,221 +6429,76 @@ static HMODULE wglinstance = NULL;
 		return RGFW_NSCreateMonitor(primary);
 	}
 
-	RGFW_monitor RGFW_window_getMonitor(RGFW_window* win) {
-		return RGFW_NSCreateMonitor(win->src.display);
-	}
-
-#ifdef __cplusplus
-#define APPKIT_EXTERN		extern "C"
-#else
-#define APPKIT_EXTERN		extern
-#endif
-
-	char* RGFW_readClipboard(size_t* size) {
-		char* clip = (char*)NSPasteboard_stringForType(NSPasteboard_generalPasteboard(), NSPasteboardTypeString);
-		size_t clip_len = strlen(clip); 
-
-		char* str = (char*)RGFW_MALLOC(sizeof(char) * clip_len);
-		strcpy(str, clip);
-
-		if (size != NULL)
-			*size = clip_len;
-		return str;
-	}
-
-	void RGFW_writeClipboard(const char* text, u32 textLen) {
-		RGFW_UNUSED(textLen);
-
-		NSPasteboardType array[] = { NSPasteboardTypeString, NULL };
-		NSPasteBoard_declareTypes(NSPasteboard_generalPasteboard(), array, 1, NULL);
-
-		NSPasteBoard_setString(NSPasteboard_generalPasteboard(), text, NSPasteboardTypeString);
-	}
-
-	u16 RGFW_registerJoystick(RGFW_window* win, i32 jsNumber) {
-		RGFW_UNUSED(jsNumber);
-
-		assert(win != NULL);
-
-		return RGFW_registerJoystickF(win, (char*) "");
-	}
-
-	u16 RGFW_registerJoystickF(RGFW_window* win, char* file) {
-		RGFW_UNUSED(file);
-
-		assert(win != NULL);
-
-		return win->src.joystickCount - 1;
-	}
-
-	void RGFW_window_close(RGFW_window* win) {
-		assert(win != NULL);
-
-#ifdef RGFW_VULKAN
-		for (int i = 0; i < win->src.image_count; i++) {
-			vkDestroyFramebuffer(RGFW_vulkan_info.device, RGFW_vulkan_info.framebuffers[i], NULL);
-		}
-
-		for (int i = 0; i < win->src.image_count; i++) {
-			vkDestroyImageView(RGFW_vulkan_info.device, win->src.swapchain_image_views[i], NULL);
-		}
-
-		vkDestroySwapchainKHR(RGFW_vulkan_info.device, win->src.swapchain, NULL);
-		vkDestroySurfaceKHR(RGFW_vulkan_info.instance, win->src.rSurf, NULL);
-		RGFW_FREE(win->src.swapchain_image_views);
-		RGFW_FREE(win->src.swapchain_images);
-#endif
-
-		release(win->src.view);
-
-#ifdef RGFW_ALLOC_DROPFILES
-		{
-			u32 i;
-			for (i = 0; i < RGFW_MAX_DROPS; i++)
-				RGFW_FREE(win->event.droppedFiles[i]);
-
-
-			RGFW_FREE(win->event.droppedFiles);
-		}
-#endif
-
-		u32 i;
-		for (i = 0; i < RGFW_windows_size; i++)
-			if (RGFW_windows[i]->src.window == win->src.window) {
-				RGFW_windows[i] = NULL;
-				break;
-			}
-
-		if (!i) {
-			RGFW_windows_size = 0;
-
-			objc_msgSend_void_id(NSApp, sel_registerName("terminate:"), (id) win->src.window);
-			NSApp = NULL;
-		}
-
-#ifdef RGFW_BUFFER
-		release(win->src.bitmap);
-		release(win->src.image);
-#endif
-
-		CVDisplayLinkStop(win->src.displayLink);
-		CVDisplayLinkRelease(win->src.displayLink);
-
-		RGFW_FREE(win);
-	}
-#endif
-
-#if defined(RGFW_X11) || defined(RGFW_MACOS)
-
-#ifndef RGFW_NO_THREADS
-#include <pthread.h>
-
-	RGFW_thread RGFW_createThread(RGFW_threadFunc_ptr ptr, void* args) {
-		RGFW_UNUSED(args);
-		
-		RGFW_thread t;
-		pthread_create((pthread_t*) &t, NULL, *ptr, NULL);
-		return t;
-	}
-	void RGFW_cancelThread(RGFW_thread thread) { pthread_cancel((pthread_t) thread); }
-	void RGFW_joinThread(RGFW_thread thread) { pthread_join((pthread_t) thread, NULL); }
-#ifdef __linux__
-	void RGFW_setThreadPriority(RGFW_thread thread, u8 priority) { pthread_setschedprio(thread, priority); }
-#endif
-#endif
-#endif
-
-	void RGFW_window_makeCurrent_OpenGL(RGFW_window* win) {
-		assert(win != NULL);
-
-#ifdef RGFW_OPENGL
-#ifdef RGFW_X11
-		glXMakeCurrent((Display*) win->src.display, (Drawable) win->src.window, (GLXContext) win->src.rSurf);
-#endif
-#ifdef RGFW_WINDOWS
-		wglMakeCurrent(win->src.hdc, (HGLRC) win->src.rSurf);
-#endif
-#if defined(RGFW_MACOS)
-		objc_msgSend_void(win->src.rSurf, sel_registerName("makeCurrentContext"));
-#endif
-#else
-#ifdef RGFW_EGL
-		eglMakeCurrent(win->src.EGL_display, win->src.EGL_surface, win->src.EGL_surface, win->src.EGL_context);
-#endif
-#endif
-
-	}
-
-	void RGFW_window_makeCurrent(RGFW_window* win) {
-		assert(win != NULL);
-
-#if defined(RGFW_WINDOWS) && defined(RGFW_DIRECTX)
-		RGFW_dxInfo.pDeviceContext->lpVtbl->OMSetRenderTargets(RGFW_dxInfo.pDeviceContext, 1, &win->src.renderTargetView, NULL);
-#endif
-
-#ifdef RGFW_OPENGL
-		RGFW_window_makeCurrent_OpenGL(win);
-#endif
-	}
-
-	void RGFW_window_swapInterval(RGFW_window* win, i32 swapInterval) {
-		assert(win != NULL);
-
-#ifdef RGFW_OPENGL
-#ifdef RGFW_X11
-		((PFNGLXSWAPINTERVALEXTPROC) glXGetProcAddress((GLubyte*) "glXSwapIntervalEXT"))((Display*) win->src.display, (Window) win->src.window, swapInterval);
-#endif
-#ifdef RGFW_WINDOWS
+	RGFW_monitor RGFW_window_getMonitor(RGFW_window* win) {
+		return RGFW_NSCreateMonitor(win->src.display);
+	}
 
-		typedef BOOL(APIENTRY* PFNWGLSWAPINTERVALEXTPROC)(int interval);
-		static PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT = NULL;
-		static void* loadSwapFunc = (void*) 1;
+	char* RGFW_readClipboard(size_t* size) {
+		char* clip = (char*)NSPasteboard_stringForType(NSPasteboard_generalPasteboard(), NSPasteboardTypeString);
+		
+		size_t clip_len = 1;
 
-		if (loadSwapFunc == NULL) {
-			fprintf(stderr, "wglSwapIntervalEXT not supported\n");
-			win->fpsCap = (swapInterval == 1) ? 0 : swapInterval;
-			return;
+		if (clip != NULL) {
+			clip_len = strlen(clip) + 1; 
 		}
 
-		if (wglSwapIntervalEXT == NULL) {
-			loadSwapFunc = (void*) wglGetProcAddress("wglSwapIntervalEXT");
-			wglSwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC) loadSwapFunc;
+		char* str = (char*)RGFW_MALLOC(sizeof(char) * clip_len);
+		
+		if (clip != NULL) {
+			strncpy(str, clip, clip_len);
 		}
 
-		if (wglSwapIntervalEXT(swapInterval) == FALSE)
-			fprintf(stderr, "Failed to set swap interval\n");
-
-#endif
-#if defined(RGFW_MACOS)
-		NSOpenGLContext_setValues(win->src.rSurf, &swapInterval, 222);
-#endif
-#endif
+		str[clip_len] = '\0';
+		
+		if (size != NULL)
+			*size = clip_len;
+		return str;
+	}
 
-#ifdef RGFW_EGL
-		eglSwapInterval(win->src.EGL_display, swapInterval);
-#endif
+	void RGFW_writeClipboard(const char* text, u32 textLen) {
+		RGFW_UNUSED(textLen);
 
-		win->fpsCap = (swapInterval == 1) ? 0 : swapInterval;
+		NSPasteboardType array[] = { NSPasteboardTypeString, NULL };
+		NSPasteBoard_declareTypes(NSPasteboard_generalPasteboard(), array, 1, NULL);
 
+		NSPasteBoard_setString(NSPasteboard_generalPasteboard(), text, NSPasteboardTypeString);
 	}
 
-	void RGFW_window_setGPURender(RGFW_window* win, i8 set) {
-		if (!set && !(win->src.winArgs & RGFW_NO_GPU_RENDER))
-			win->src.winArgs |= RGFW_NO_GPU_RENDER;
+	u16 RGFW_registerJoystick(RGFW_window* win, i32 jsNumber) {
+		RGFW_UNUSED(jsNumber);
 
-		else if (set && win->src.winArgs & RGFW_NO_GPU_RENDER)
-			win->src.winArgs ^= RGFW_NO_GPU_RENDER;
+		assert(win != NULL);
+
+		return RGFW_registerJoystickF(win, (char*) "");
 	}
 
-	void RGFW_window_setCPURender(RGFW_window* win, i8 set) {
-		if (!set && !(win->src.winArgs & RGFW_NO_CPU_RENDER))
-			win->src.winArgs |= RGFW_NO_CPU_RENDER;
+	u16 RGFW_registerJoystickF(RGFW_window* win, char* file) {
+		RGFW_UNUSED(file);
 
-		else if (set && win->src.winArgs & RGFW_NO_CPU_RENDER)
-			win->src.winArgs ^= RGFW_NO_CPU_RENDER;
+		assert(win != NULL);
+
+		return win->src.joystickCount - 1;
+	}
+
+	#ifdef RGFW_OPENGL
+	void RGFW_window_makeCurrent_OpenGL(RGFW_window* win) {
+		assert(win != NULL);
+		objc_msgSend_void(win->src.rSurf, sel_registerName("makeCurrentContext"));
 	}
+	#endif
 
+	#if !defined(RGFW_EGL)
+	void RGFW_window_swapInterval(RGFW_window* win, i32 swapInterval) {
+		assert(win != NULL);
+		#if defined(RGFW_OPENGL)
+		
+		NSOpenGLContext_setValues(win->src.rSurf, &swapInterval, 222);
+		#endif
 
+		win->fpsCap = (swapInterval == 1) ? 0 : swapInterval;
+	}
+	#endif
+	
 	void RGFW_window_swapBuffers(RGFW_window* win) {
 		assert(win != NULL);
 
@@ -6472,56 +6508,17 @@ static HMODULE wglinstance = NULL;
 
 		if (!(win->src.winArgs & RGFW_NO_CPU_RENDER)) {
 #if defined(RGFW_OSMESA) || defined(RGFW_BUFFER)
-#ifdef RGFW_OSMESA
-			u8* row = (u8*) RGFW_MALLOC(win->r.w * 3);
-
-			i32 half_height = win->r.h / 2;
-			i32 stride = win->r.w * 3;
-
-			i32 y;
-			for (y = 0; y < half_height; ++y) {
-				i32 top_offset = y * stride;
-				i32 bottom_offset = (win->r.h - y - 1) * stride;
-				memcpy(row, win->buffer + top_offset, stride);
-				memcpy(win->buffer + top_offset, win->buffer + bottom_offset, stride);
-				memcpy(win->buffer + bottom_offset, row, stride);
-			}
-
-			RGFW_FREE(row);
-#endif
-
-#ifdef RGFW_X11
-			RGFW_area area = RGFW_getScreenSize();
-
-#ifndef RGFW_X11_DONT_CONVERT_BGR
-			win->src.bitmap->data = (char*) win->buffer;
-			u32 x, y;
-			for (y = 0; y < (u32)win->r.h; y++) {
-				for (x = 0; x < (u32)win->r.w; x++) {
-					u32 index = (y * 4 * area.w) + x * 4;
-
-					u8 red = win->src.bitmap->data[index];
-					win->src.bitmap->data[index] = win->buffer[index + 2];
-					win->src.bitmap->data[index + 2] = red;
-				}
-			}
-#endif
+			#ifdef RGFW_OSMESA
+			RGFW_OSMesa_reorganize();
+			#endif
 
-			XPutImage(win->src.display, (Window) win->src.window, XDefaultGC(win->src.display, XDefaultScreen(win->src.display)), win->src.bitmap, 0, 0, 0, 0, win->r.w, win->r.h);
-#endif
-#ifdef RGFW_WINDOWS
-			HGDIOBJ oldbmp = SelectObject(win->src.hdcMem, win->src.bitmap);
-			BitBlt(win->src.hdc, 0, 0, win->r.w, win->r.h, win->src.hdcMem, 0, 0, SRCCOPY);
-			SelectObject(win->src.hdcMem, oldbmp);
-#endif	
-#if defined(RGFW_MACOS)
-			RGFW_area area = RGFW_getScreenSize();
+			RGFW_area area = RGFW_bufferSize;
 			void* view = NSWindow_contentView(win->src.window);
 			void* layer = objc_msgSend_id(view, sel_registerName("layer"));
 
 			((void(*)(id, SEL, NSRect))objc_msgSend)(layer,
 				sel_registerName("setFrame:"),
-				NSMakeRect(0, 0, win->r.w, win->r.h));
+				(NSRect){{0, 0}, {win->r.w, win->r.h}});
 
 			NSBitmapImageRep* rep = NSBitmapImageRep_initWithBitmapData(
 				&win->buffer, win->r.w, win->r.h, 8, 4, true, false,
@@ -6534,14 +6531,6 @@ static HMODULE wglinstance = NULL;
 
 			release(image);
 			release(rep);
-#endif
-#endif
-
-#ifdef RGFW_VULKAN
-#ifdef RGFW_PRINT_ERRORS
-			fprintf(stderr, "RGFW_window_swapBuffers %s\n", "RGFW_window_swapBuffers is not yet supported for Vulkan");
-			RGFW_error = 1;
-#endif
 #endif
 		}
 
@@ -6549,161 +6538,94 @@ static HMODULE wglinstance = NULL;
 			#ifdef RGFW_EGL
 					eglSwapBuffers(win->src.EGL_display, win->src.EGL_surface);
 			#elif defined(RGFW_OPENGL)
-			#if defined(RGFW_X11) && defined(RGFW_OPENGL)
-					glXSwapBuffers((Display*) win->src.display, (Window) win->src.window);
-			#elif defined(RGFW_WINDOWS)
-					SwapBuffers(win->src.hdc);
-			#elif defined(RGFW_MACOS)
-					NSOpenGLContext_flushBuffer(win->src.rSurf);
-			#endif
-			#endif
-
-			#if defined(RGFW_WINDOWS) && defined(RGFW_DIRECTX)
-					win->src.swapchain->lpVtbl->Present(win->src.swapchain, 0, 0);
+					objc_msgSend_void(win->src.rSurf, sel_registerName("flushBuffer"));
 			#endif
 		}
 
 		RGFW_window_checkFPS(win);
 	}
 
-	void RGFW_window_maximize(RGFW_window* win) {
-		assert(win != NULL);
-
-		RGFW_area screen = RGFW_getScreenSize();
-
-		RGFW_window_move(win, RGFW_VECTOR(0, 0));
-		RGFW_window_resize(win, screen);
-	}
-
-	u8 RGFW_window_shouldClose(RGFW_window* win) {
+	void RGFW_window_close(RGFW_window* win) {
 		assert(win != NULL);
+		release(win->src.view);
 
-		/* || RGFW_isPressedI(win, RGFW_Escape) */
-		return (win->event.type == RGFW_quit || RGFW_isPressedI(win, RGFW_Escape));
-	}
-
-	void RGFW_window_setShouldClose(RGFW_window* win) { win->event.type = RGFW_quit; }
+#ifdef RGFW_ALLOC_DROPFILES
+		{
+			u32 i;
+			for (i = 0; i < RGFW_MAX_DROPS; i++)
+				RGFW_FREE(win->event.droppedFiles[i]);
 
-	void RGFW_window_moveToMonitor(RGFW_window* win, RGFW_monitor m) {
-		RGFW_window_move(win, RGFW_VECTOR(m.rect.x + win->r.x, m.rect.y + win->r.y));
-	}
 
-	void RGFW_window_mouseHold(RGFW_window* win, RGFW_area area) {
-		if (!(win->src.winArgs & RGFW_HOLD_MOUSE)) {
-			#ifdef RGFW_WINDOWS
-			RECT rect = {win->r.x, win->r.y, win->r.x + win->r.w, win->r.y + win->r.h};
-			ClipCursor(&rect);
-			#endif
+			RGFW_FREE(win->event.droppedFiles);
 		}
-
-		win->src.winArgs |= RGFW_HOLD_MOUSE;
-
-		if (!area.w && !area.h)
-			area = RGFW_AREA(win->r.w / 2, win->r.h / 2);
-
-		RGFW_window_moveMouse(win, RGFW_VECTOR(win->r.x + (area.w), win->r.y + (area.h)));
-	}
-
-	void RGFW_window_mouseUnhold(RGFW_window* win) {
-		win->src.winArgs ^= RGFW_HOLD_MOUSE;
-
-		#ifdef RGFW_WINDOWS
-		ClipCursor(NULL);
-		#endif
-	}
-
-	void RGFW_sleep(u64 ms) {
-#ifndef RGFW_WINDOWS
-		struct timespec time;
-		time.tv_sec = 0;
-		time.tv_nsec = ms * 1e+6;
-
-		nanosleep(&time, NULL);
-#else
-		Sleep(ms);
 #endif
-	}
-
-	void RGFW_window_checkFPS(RGFW_window* win) {
-		u64 deltaTime = RGFW_getTimeNS() - win->event.frameTime;
-
-		u64 fps = round(1e+9 / deltaTime);
-		win->event.fps = fps;
-
-		if (win->fpsCap && fps > win->fpsCap) {
-			u64 frameTimeNS = 1e+9 / win->fpsCap;
-			u64 sleepTimeMS = (frameTimeNS - deltaTime) / 1e6;
-
-			if (sleepTimeMS > 0) {
-				RGFW_sleep(sleepTimeMS);
-				win->event.frameTime = 0;
-			}
-		}
-
-		win->event.frameTime = RGFW_getTimeNS();
-		
-		if (win->fpsCap) {
-			u64 deltaTime = RGFW_getTimeNS() - win->event.frameTime2;
 
-			win->event.fps = round(1e+9 / deltaTime);
-			
-			win->event.frameTime2 = RGFW_getTimeNS();
+		if (RGFW_root == win) {
+			objc_msgSend_void_id(NSApp, sel_registerName("terminate:"), (id) win->src.window);
+			NSApp = NULL;
 		}
-	}
 
-#ifdef __APPLE__
-#include <mach/mach_time.h>
+#ifdef RGFW_BUFFER
+		release(win->src.bitmap);
+		release(win->src.image);
 #endif
 
-	u64 RGFW_getTimeNS(void) {
-#ifdef RGFW_WINDOWS
-		LARGE_INTEGER frequency;
-		QueryPerformanceFrequency(&frequency);
-
-		LARGE_INTEGER counter;
-		QueryPerformanceCounter(&counter);
+		CVDisplayLinkStop(win->src.displayLink);
+		CVDisplayLinkRelease(win->src.displayLink);
 
-		return (u64) (counter.QuadPart * 1e9 / frequency.QuadPart);
-#elif defined(__unix__)
-		struct timespec ts = { 0 };
-		clock_gettime(1, &ts);
-		unsigned long long int nanoSeconds = (unsigned long long int)ts.tv_sec*1000000000LLU + (unsigned long long int)ts.tv_nsec;
+		RGFW_FREE(win);
+	}
 
-		return nanoSeconds;
-#elif defined(__APPLE__)
+	u64 RGFW_getTimeNS(void) {
 		static mach_timebase_info_data_t timebase_info;
 		if (timebase_info.denom == 0) {
 			mach_timebase_info(&timebase_info);
 		}
 		return mach_absolute_time() * timebase_info.numer / timebase_info.denom;
-#endif
-		return 0;
 	}
 
 	u64 RGFW_getTime(void) {
-#ifdef RGFW_WINDOWS
-		LARGE_INTEGER frequency;
-		QueryPerformanceFrequency(&frequency);
-
-		LARGE_INTEGER counter;
-		QueryPerformanceCounter(&counter);
-		return (u64) (counter.QuadPart / (double) frequency.QuadPart);
-#elif defined(__unix__)
-		struct timespec ts = { 0 };
-		clock_gettime(1, &ts);
-		unsigned long long int nanoSeconds = (unsigned long long int)ts.tv_sec*1000000000LLU + (unsigned long long int)ts.tv_nsec;
-
-		return (double)(nanoSeconds) * 1e-9;
-#elif defined(__APPLE__)
 		static mach_timebase_info_data_t timebase_info;
 		if (timebase_info.denom == 0) {
 			mach_timebase_info(&timebase_info);
 		}
 		return (double) mach_absolute_time() * (double) timebase_info.numer / ((double) timebase_info.denom * 1e9);
+	}
+#endif /* RGFW_MACOS */
+
+/*
+	End of MaOS defines
+*/
+
+/* unix (macOS, linux) only stuff */
+#if defined(RGFW_X11) || defined(RGFW_MACOS)
+/* unix threading */
+#ifndef RGFW_NO_THREADS
+#include <pthread.h>
+
+	RGFW_thread RGFW_createThread(RGFW_threadFunc_ptr ptr, void* args) {
+		RGFW_UNUSED(args);
+		
+		RGFW_thread t;
+		pthread_create((pthread_t*) &t, NULL, *ptr, NULL);
+		return t;
+	}
+	void RGFW_cancelThread(RGFW_thread thread) { pthread_cancel((pthread_t) thread); }
+	void RGFW_joinThread(RGFW_thread thread) { pthread_join((pthread_t) thread, NULL); }
+#ifdef __linux__
+	void RGFW_setThreadPriority(RGFW_thread thread, u8 priority) { pthread_setschedprio(thread, priority); }
 #endif
-		return 0;
+#endif
+/* unix sleep */
+	void RGFW_sleep(u64 ms) {
+		struct timespec time;
+		time.tv_sec = 0;
+		time.tv_nsec = ms * 1e+6;
+
+		nanosleep(&time, NULL);
 	}
 
+#endif /* end of unix / mac stuff*/
 #endif /*RGFW_IMPLEMENTATION*/
 
 #ifdef __cplusplus
diff --git a/src/platforms/rcore_desktop_rgfw.c b/src/platforms/rcore_desktop_rgfw.c
index 7dfe1f51c..5bd08217f 100644
--- a/src/platforms/rcore_desktop_rgfw.c
+++ b/src/platforms/rcore_desktop_rgfw.c
@@ -8,19 +8,17 @@
 *       - MacOS (Cocoa)
 *
 *   LIMITATIONS:
-*       - Limitation 01
-*       - Limitation 02
+*       - TODO
 *
 *   POSSIBLE IMPROVEMENTS:
-*       - Improvement 01
-*       - Improvement 02
+*       - TODO
 *
 *   ADDITIONAL NOTES:
 *       - TRACELOG() function is located in raylib [utils] module
 *
 *   CONFIGURATION:
-*       #define RCORE_PLATFORM_CUSTOM_FLAG
-*           Custom flag for rcore on target platform -not used-
+*       #define RCORE_PLATFORM_RGFW
+*           Custom flag for rcore on target platform RGFW
 *
 *   DEPENDENCIES:
 *       - RGFW.h (main library): Windowing and inputs management
@@ -244,7 +242,7 @@ bool WindowShouldClose(void)
 
 // Toggle fullscreen mode
 void ToggleFullscreen(void)
-{
+{   
     RGFW_window_maximize(platform.window);
     ToggleBorderlessWindowed();
 }
@@ -252,10 +250,9 @@ void ToggleFullscreen(void)
 // Toggle borderless windowed mode
 void ToggleBorderlessWindowed(void)
 {
-    CORE.Window.flags & FLAG_WINDOW_UNDECORATED;
-
-    if (platform.window != NULL)
-        TRACELOG(LOG_WARNING, "ToggleBorderlessWindowed() after window creation not available on target platform");
+    if (platform.window != NULL) {
+        RGFW_window_setBorder(platform.window, CORE.Window.flags & FLAG_WINDOW_UNDECORATED);
+    }
 }
 
 // Set window state: maximized, if resizable
@@ -292,6 +289,7 @@ void SetWindowState(unsigned int flags)
     }
     if (flags & FLAG_WINDOW_RESIZABLE)
     {
+        printf("%i %i\n", platform.window->r.w, platform.window->r.h);
         RGFW_window_setMaxSize(platform.window, RGFW_AREA(platform.window->r.w, platform.window->r.h));
         RGFW_window_setMinSize(platform.window, RGFW_AREA(platform.window->r.w, platform.window->r.h));
     }
@@ -313,7 +311,7 @@ void SetWindowState(unsigned int flags)
     }
     if (flags & FLAG_WINDOW_UNFOCUSED)
     {
-        TRACELOG(LOG_WARNING, "SetWindowState() - FLAG_WINDOW_UNFOCUSED is not supported on PLATFORM_DESKTOP_SDL");
+        TRACELOG(LOG_WARNING, "SetWindowState() - FLAG_WINDOW_UNFOCUSED is not supported on PLATFORM_DESKTOP_RGFW");
     }
     if (flags & FLAG_WINDOW_TOPMOST)
     {
@@ -325,7 +323,7 @@ void SetWindowState(unsigned int flags)
     }
     if (flags & FLAG_WINDOW_TRANSPARENT)
     {
-        TRACELOG(LOG_WARNING, "SetWindowState() - FLAG_WINDOW_TRANSPARENT is not supported on PLATFORM_DESKTOP_RGFW");
+        TRACELOG(LOG_WARNING, "SetWindowState() - FLAG_WINDOW_TRANSPARENT post window creation post window creation is not supported on PLATFORM_DESKTOP_RGFW");
     }
     if (flags & FLAG_WINDOW_HIGHDPI)
     {
@@ -333,7 +331,7 @@ void SetWindowState(unsigned int flags)
     }
     if (flags & FLAG_WINDOW_MOUSE_PASSTHROUGH)
     {
-        TRACELOG(LOG_WARNING, "SetWindowState() - FLAG_WINDOW_MOUSE_PASSTHROUGH is not supported on PLATFORM_DESKTOP_RGFW");
+        RGFW_window_setMousePassthrough(platform.window, flags & FLAG_WINDOW_MOUSE_PASSTHROUGH);
     }
     if (flags & FLAG_BORDERLESS_WINDOWED_MODE)
     {
@@ -408,7 +406,7 @@ void ClearWindowState(unsigned int flags)
     }
     if (flags & FLAG_WINDOW_MOUSE_PASSTHROUGH)
     {
-        //SDL_SetWindowGrab(platform.window, SDL_TRUE);
+        RGFW_window_setMousePassthrough(platform.window, flags & FLAG_WINDOW_MOUSE_PASSTHROUGH);
         TRACELOG(LOG_WARNING, "ClearWindowState() - FLAG_WINDOW_MOUSE_PASSTHROUGH is not supported on PLATFORM_DESKTOP_RGFW");
     }
     if (flags & FLAG_BORDERLESS_WINDOWED_MODE)
@@ -566,16 +564,16 @@ int GetMonitorCount(void)
 // Get number of monitors
 int GetCurrentMonitor(void)
 {
-    int current = 0;
     RGFW_monitor *mons = RGFW_getMonitors();
     RGFW_monitor mon = RGFW_window_getMonitor(platform.window);
 
     for (int i = 0; i < 6; i++)
     {
-        if ((mons[i].rect.x ==  mon.rect.x) && (mons[i].rect.y ==  mon.rect.y)) current = i;
+        if ((mons[i].rect.x ==  mon.rect.x) && (mons[i].rect.y ==  mon.rect.y))
+            return i;
     }
 
-    return current;
+    return 0;
 }
 
 // Get selected monitor position
@@ -760,6 +758,62 @@ void SetMouseCursor(int cursor)
 
 static KeyboardKey ConvertScancodeToKey(u32 keycode);
 
+/* 
+    TODO, try to make this better (RSGL uses this method too :I ) 
+    sourced from RSGL obviously -> ColleagueRiley
+*/
+char RSGL_keystrToChar(const char* str) {
+    if (str[1] == 0)
+        return str[0];
+
+
+    static const char* map[] = {
+        "asciitilde", "`",
+        "grave", "~",
+        "exclam", "!",
+        "at", "@",
+        "numbersign", "#",
+        "dollar", "$",
+        "percent", "%%",
+        "asciicircum", "^",
+        "ampersand", "&",
+        "asterisk", "*",
+        "parenleft", "(",
+        "parenright", ")",
+        "underscore", "_",
+        "minus", "-",
+        "plus", "+",
+        "equal", "=",
+        "braceleft", "{",
+        "bracketleft", "[",
+        "bracketright", "]",
+        "braceright", "}",
+        "colon", ":",
+        "semicolon", ";",
+        "quotedbl", "\"",
+        "apostrophe", "'",
+        "bar", "|",
+        "backslash", "\'",
+        "less", "<",
+        "comma", ",",
+        "greater", ">",
+        "period", ".",
+        "question", "?",
+        "slash", "/",
+        "space", " ",
+        "Return", "\n",
+        "Enter", "\n",
+        "enter", "\n",
+    };
+
+    u8 i = 0;
+    for (i = 0; i < (sizeof(map) / sizeof(char*)); i += 2)
+        if (strcmp(map[i], str) == 0)
+            return *map[i + 1];
+
+    return '\0';
+}
+
 // Register all input events
 void PollInputEvents(void)
 {
@@ -924,7 +978,7 @@ void PollInputEvents(void)
                 if (CORE.Input.Keyboard.charPressedQueueCount < MAX_CHAR_PRESSED_QUEUE)
                 {
                     // Add character (codepoint) to the queue
-                    CORE.Input.Keyboard.charPressedQueue[CORE.Input.Keyboard.charPressedQueueCount] = RGFW_keystrToChar(event->keyName);
+                    CORE.Input.Keyboard.charPressedQueue[CORE.Input.Keyboard.charPressedQueueCount] = RSGL_keystrToChar(event->keyName);
                     CORE.Input.Keyboard.charPressedQueueCount++;
                 }
             } break;