From 135194a9604237557f722bd093955281bde5f97b Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Thu, 9 Sep 2010 18:15:32 +0200 Subject: [PATCH] Initial pass for multi-window support. --- include/GL/glfw.h | 70 ++-- lib/enable.c | 115 +++--- lib/glext.c | 20 +- lib/init.c | 7 - lib/input.c | 93 ++--- lib/internal.h | 142 +++++-- lib/window.c | 377 +++++++++--------- lib/x11/platform.h | 151 ++----- lib/x11/x11_enable.c | 14 +- lib/x11/x11_fullscreen.c | 104 ++--- lib/x11/x11_glext.c | 5 +- lib/x11/x11_init.c | 42 +- lib/x11/x11_time.c | 10 +- lib/x11/x11_window.c | 842 +++++++++++++++++++-------------------- 14 files changed, 986 insertions(+), 1006 deletions(-) diff --git a/include/GL/glfw.h b/include/GL/glfw.h index ca72988e..1f2bb8ad 100644 --- a/include/GL/glfw.h +++ b/include/GL/glfw.h @@ -306,7 +306,6 @@ extern "C" { #define GLFW_FULLSCREEN 0x00010002 /* glfwGetWindowParam tokens */ -#define GLFW_OPENED 0x00020001 #define GLFW_ACTIVE 0x00020002 #define GLFW_ICONIFIED 0x00020003 #define GLFW_ACCELERATED 0x00020004 @@ -356,6 +355,8 @@ extern "C" { * Typedefs *************************************************************************/ +typedef struct _GLFWwindow* GLFWwindow; + /* The video mode structure used by glfwGetVideoModes() */ typedef struct { int width, height; @@ -382,41 +383,42 @@ GLFWAPI int glfwInit(void); GLFWAPI void glfwTerminate(void); GLFWAPI void glfwGetVersion(int* major, int* minor, int* rev); -/* Window handling */ -GLFWAPI int glfwOpenWindow(int width, int height, int redbits, int greenbits, int bluebits, int alphabits, int depthbits, int stencilbits, int mode); -GLFWAPI void glfwOpenWindowHint(int target, int hint); -GLFWAPI void glfwCloseWindow(void); -GLFWAPI void glfwSetWindowTitle(const char* title); -GLFWAPI void glfwGetWindowSize(int* width, int* height); -GLFWAPI void glfwSetWindowSize(int width, int height); -GLFWAPI void glfwSetWindowPos(int x, int y); -GLFWAPI void glfwIconifyWindow(void); -GLFWAPI void glfwRestoreWindow(void); -GLFWAPI void glfwSwapBuffers(void); -GLFWAPI void glfwSwapInterval(int interval); -GLFWAPI int glfwGetWindowParam(int param); -GLFWAPI void glfwSetWindowSizeCallback(GLFWwindowsizefun cbfun); -GLFWAPI void glfwSetWindowCloseCallback(GLFWwindowclosefun cbfun); -GLFWAPI void glfwSetWindowRefreshCallback(GLFWwindowrefreshfun cbfun); - /* Video mode functions */ GLFWAPI int glfwGetVideoModes(GLFWvidmode* list, int maxcount); GLFWAPI void glfwGetDesktopMode(GLFWvidmode* mode); -/* Input handling */ +/* Window handling */ +GLFWAPI GLFWwindow glfwOpenWindow(int width, int height, int redbits, int greenbits, int bluebits, int alphabits, int depthbits, int stencilbits, int mode); +GLFWAPI void glfwOpenWindowHint(int target, int hint); +GLFWAPI void glfwMakeWindowCurrent(GLFWwindow window); +GLFWAPI void glfwCloseWindow(GLFWwindow window); +GLFWAPI void glfwSetWindowTitle(GLFWwindow, const char* title); +GLFWAPI void glfwGetWindowSize(GLFWwindow, int* width, int* height); +GLFWAPI void glfwSetWindowSize(GLFWwindow, int width, int height); +GLFWAPI void glfwSetWindowPos(GLFWwindow, int x, int y); +GLFWAPI void glfwIconifyWindow(GLFWwindow window); +GLFWAPI void glfwRestoreWindow(GLFWwindow window); +GLFWAPI int glfwGetWindowParam(GLFWwindow window, int param); +GLFWAPI void glfwSetWindowSizeCallback(GLFWwindow window, GLFWwindowsizefun cbfun); +GLFWAPI void glfwSetWindowCloseCallback(GLFWwindow window, GLFWwindowclosefun cbfun); +GLFWAPI void glfwSetWindowRefreshCallback(GLFWwindow window, GLFWwindowrefreshfun cbfun); + +/* Event handling */ GLFWAPI void glfwPollEvents(void); GLFWAPI void glfwWaitEvents(void); -GLFWAPI int glfwGetKey(int key); -GLFWAPI int glfwGetMouseButton(int button); -GLFWAPI void glfwGetMousePos(int* xpos, int* ypos); -GLFWAPI void glfwSetMousePos(int xpos, int ypos); -GLFWAPI int glfwGetMouseWheel(void); -GLFWAPI void glfwSetMouseWheel(int pos); -GLFWAPI void glfwSetKeyCallback(GLFWkeyfun cbfun); -GLFWAPI void glfwSetCharCallback(GLFWcharfun cbfun); -GLFWAPI void glfwSetMouseButtonCallback(GLFWmousebuttonfun cbfun); -GLFWAPI void glfwSetMousePosCallback(GLFWmouseposfun cbfun); -GLFWAPI void glfwSetMouseWheelCallback(GLFWmousewheelfun cbfun); + +/* Input handling */ +GLFWAPI int glfwGetKey(GLFWwindow window, int key); +GLFWAPI int glfwGetMouseButton(GLFWwindow window, int button); +GLFWAPI void glfwGetMousePos(GLFWwindow window, int* xpos, int* ypos); +GLFWAPI void glfwSetMousePos(GLFWwindow window, int xpos, int ypos); +GLFWAPI int glfwGetMouseWheel(GLFWwindow window); +GLFWAPI void glfwSetMouseWheel(GLFWwindow window, int pos); +GLFWAPI void glfwSetKeyCallback(GLFWwindow window, GLFWkeyfun cbfun); +GLFWAPI void glfwSetCharCallback(GLFWwindow window, GLFWcharfun cbfun); +GLFWAPI void glfwSetMouseButtonCallback(GLFWwindow window, GLFWmousebuttonfun cbfun); +GLFWAPI void glfwSetMousePosCallback(GLFWwindow window, GLFWmouseposfun cbfun); +GLFWAPI void glfwSetMouseWheelCallback(GLFWwindow window, GLFWmousewheelfun cbfun); /* Joystick input */ GLFWAPI int glfwGetJoystickParam(int joy, int param); @@ -427,14 +429,16 @@ GLFWAPI int glfwGetJoystickButtons(int joy, unsigned char* buttons, int numbutto GLFWAPI double glfwGetTime(void); GLFWAPI void glfwSetTime(double time); -/* Extension support */ +/* OpenGL support */ +GLFWAPI void glfwSwapBuffers(void); +GLFWAPI void glfwSwapInterval(int interval); GLFWAPI int glfwExtensionSupported(const char* extension); GLFWAPI void* glfwGetProcAddress(const char* procname); GLFWAPI void glfwGetGLVersion(int* major, int* minor, int* rev); /* Enable/disable functions */ -GLFWAPI void glfwEnable(int token); -GLFWAPI void glfwDisable(int token); +GLFWAPI void glfwEnable(GLFWwindow window, int token); +GLFWAPI void glfwDisable(GLFWwindow window, int token); #ifdef __cplusplus diff --git a/lib/enable.c b/lib/enable.c index f8a3d0bf..e20f8942 100644 --- a/lib/enable.c +++ b/lib/enable.c @@ -39,55 +39,56 @@ // Enable (show) mouse cursor //======================================================================== -static void enableMouseCursor(void) +static void enableMouseCursor(_GLFWwindow* window) { int centerPosX, centerPosY; - if (!_glfwWin.opened || !_glfwWin.mouseLock) + if (_glfwLibrary.cursorLockWindow != window) return; // Show mouse cursor - _glfwPlatformShowMouseCursor(); + _glfwPlatformShowMouseCursor(window); - centerPosX = _glfwWin.width / 2; - centerPosY = _glfwWin.height / 2; + centerPosX = window->width / 2; + centerPosY = window->height / 2; - if (centerPosX != _glfwInput.MousePosX || centerPosY != _glfwInput.MousePosY) + if (centerPosX != window->mousePosX || centerPosY != window->mousePosY) { - _glfwPlatformSetMouseCursorPos(centerPosX, centerPosY); + _glfwPlatformSetMouseCursorPos(window, centerPosX, centerPosY); - _glfwInput.MousePosX = centerPosX; - _glfwInput.MousePosY = centerPosY; + window->mousePosX = centerPosX; + window->mousePosY = centerPosY; - if (_glfwWin.mousePosCallback) + if (window->mousePosCallback) { - _glfwWin.mousePosCallback(_glfwInput.MousePosX, - _glfwInput.MousePosY); + window->mousePosCallback(window->mousePosX, + window->mousePosY); } } // From now on the mouse is unlocked - _glfwWin.mouseLock = GL_FALSE; + _glfwLibrary.cursorLockWindow = NULL; } //======================================================================== // Disable (hide) mouse cursor //======================================================================== -static void disableMouseCursor(void) +static void disableMouseCursor(_GLFWwindow* window) { - if (!_glfwWin.opened || _glfwWin.mouseLock) + if (_glfwLibrary.cursorLockWindow) return; // Hide mouse cursor - _glfwPlatformHideMouseCursor(); + _glfwPlatformHideMouseCursor(window); // Move cursor to the middle of the window - _glfwPlatformSetMouseCursorPos(_glfwWin.width >> 1, - _glfwWin.height >> 1); + _glfwPlatformSetMouseCursorPos(window, + window->width / 2, + window->height / 2); // From now on the mouse is locked - _glfwWin.mouseLock = GL_TRUE; + _glfwLibrary.cursorLockWindow = window; } @@ -95,26 +96,26 @@ static void disableMouseCursor(void) // Enable sticky keys //======================================================================== -static void enableStickyKeys(void) +static void enableStickyKeys(_GLFWwindow* window) { - _glfwInput.StickyKeys = 1; + window->stickyKeys = GL_TRUE; } //======================================================================== // Disable sticky keys //======================================================================== -static void disableStickyKeys(void) +static void disableStickyKeys(_GLFWwindow* window) { int i; - _glfwInput.StickyKeys = 0; + window->stickyKeys = GL_FALSE; // Release all sticky keys for (i = 0; i <= GLFW_KEY_LAST; i++) { - if (_glfwInput.Key[i] == 2) - _glfwInput.Key[i] = 0; + if (window->key[i] == GLFW_STICK) + window->key[i] = GLFW_RELEASE; } } @@ -123,26 +124,26 @@ static void disableStickyKeys(void) // Enable sticky mouse buttons //======================================================================== -static void enableStickyMouseButtons(void) +static void enableStickyMouseButtons(_GLFWwindow* window) { - _glfwInput.StickyMouseButtons = 1; + window->stickyMouseButtons = GL_TRUE; } //======================================================================== // Disable sticky mouse buttons //======================================================================== -static void disableStickyMouseButtons(void) +static void disableStickyMouseButtons(_GLFWwindow* window) { int i; - _glfwInput.StickyMouseButtons = 0; + window->stickyMouseButtons = GL_FALSE; // Release all sticky mouse buttons for (i = 0; i <= GLFW_MOUSE_BUTTON_LAST; i++) { - if (_glfwInput.MouseButton[i] == 2) - _glfwInput.MouseButton[i] = 0; + if (window->mouseButton[i] == GLFW_STICK) + window->mouseButton[i] = GLFW_RELEASE; } } @@ -151,30 +152,30 @@ static void disableStickyMouseButtons(void) // Enable system keys //======================================================================== -static void enableSystemKeys(void) +static void enableSystemKeys(_GLFWwindow* window) { - if (!_glfwWin.sysKeysDisabled) + if (!window->sysKeysDisabled) return; - _glfwPlatformEnableSystemKeys(); + _glfwPlatformEnableSystemKeys(window); // Indicate that system keys are no longer disabled - _glfwWin.sysKeysDisabled = GL_FALSE; + window->sysKeysDisabled = GL_FALSE; } //======================================================================== // Disable system keys //======================================================================== -static void disableSystemKeys(void) +static void disableSystemKeys(_GLFWwindow* window) { - if (_glfwWin.sysKeysDisabled) + if (window->sysKeysDisabled) return; - _glfwPlatformDisableSystemKeys(); + _glfwPlatformDisableSystemKeys(window); // Indicate that system keys are now disabled - _glfwWin.sysKeysDisabled = GL_TRUE; + window->sysKeysDisabled = GL_TRUE; } @@ -182,18 +183,18 @@ static void disableSystemKeys(void) // Enable key repeat //======================================================================== -static void enableKeyRepeat(void) +static void enableKeyRepeat(_GLFWwindow* window) { - _glfwInput.KeyRepeat = 1; + window->keyRepeat = GL_TRUE; } //======================================================================== // Disable key repeat //======================================================================== -static void disableKeyRepeat(void) +static void disableKeyRepeat(_GLFWwindow* window) { - _glfwInput.KeyRepeat = 0; + window->keyRepeat = GL_FALSE; } @@ -202,10 +203,10 @@ static void disableKeyRepeat(void) //************************************************************************ //======================================================================== -// Enable certain GLFW/window/system functions. +// Enable certain GLFW/window/system functions //======================================================================== -GLFWAPI void glfwEnable(int token) +GLFWAPI void glfwEnable(GLFWwindow window, int token) { if (!_glfwInitialized) return; @@ -213,19 +214,19 @@ GLFWAPI void glfwEnable(int token) switch (token) { case GLFW_MOUSE_CURSOR: - enableMouseCursor(); + enableMouseCursor(window); break; case GLFW_STICKY_KEYS: - enableStickyKeys(); + enableStickyKeys(window); break; case GLFW_STICKY_MOUSE_BUTTONS: - enableStickyMouseButtons(); + enableStickyMouseButtons(window); break; case GLFW_SYSTEM_KEYS: - enableSystemKeys(); + enableSystemKeys(window); break; case GLFW_KEY_REPEAT: - enableKeyRepeat(); + enableKeyRepeat(window); break; default: break; @@ -234,10 +235,10 @@ GLFWAPI void glfwEnable(int token) //======================================================================== -// Disable certain GLFW/window/system functions. +// Disable certain GLFW/window/system functions //======================================================================== -GLFWAPI void glfwDisable(int token) +GLFWAPI void glfwDisable(GLFWwindow window, int token) { if (!_glfwInitialized) return; @@ -245,19 +246,19 @@ GLFWAPI void glfwDisable(int token) switch (token) { case GLFW_MOUSE_CURSOR: - disableMouseCursor(); + disableMouseCursor(window); break; case GLFW_STICKY_KEYS: - disableStickyKeys(); + disableStickyKeys(window); break; case GLFW_STICKY_MOUSE_BUTTONS: - disableStickyMouseButtons(); + disableStickyMouseButtons(window); break; case GLFW_SYSTEM_KEYS: - disableSystemKeys(); + disableSystemKeys(window); break; case GLFW_KEY_REPEAT: - disableKeyRepeat(); + disableKeyRepeat(window); break; default: break; diff --git a/lib/glext.c b/lib/glext.c index 296c7f51..ef4c23f0 100644 --- a/lib/glext.c +++ b/lib/glext.c @@ -132,15 +132,17 @@ GLFWAPI int glfwExtensionSupported(const char* extension) GLint count; int i; - if (!_glfwInitialized || !_glfwWin.opened) + if (!_glfwInitialized || !_glfwLibrary.window) return GL_FALSE; + _GLFWwindow* window = _glfwLibrary.window; + // Extension names should not have spaces where = (GLubyte*) strchr(extension, ' '); if (where || *extension == '\0') return GL_FALSE; - if (_glfwWin.glMajor < 3) + if (window->glMajor < 3) { // Check if extension is in the old style OpenGL extensions string @@ -159,7 +161,7 @@ GLFWAPI int glfwExtensionSupported(const char* extension) for (i = 0; i < count; i++) { - if (strcmp((const char*) _glfwWin.GetStringi(GL_EXTENSIONS, i), + if (strcmp((const char*) window->GetStringi(GL_EXTENSIONS, i), extension) == 0) { return GL_TRUE; @@ -182,7 +184,7 @@ GLFWAPI int glfwExtensionSupported(const char* extension) GLFWAPI void* glfwGetProcAddress(const char* procname) { - if (!_glfwInitialized || !_glfwWin.opened) + if (!_glfwInitialized || !_glfwLibrary.window) return NULL; return _glfwPlatformGetProcAddress(procname); @@ -195,16 +197,18 @@ GLFWAPI void* glfwGetProcAddress(const char* procname) GLFWAPI void glfwGetGLVersion(int* major, int* minor, int* rev) { - if (!_glfwInitialized || !_glfwWin.opened) + if (!_glfwInitialized || !_glfwLibrary.window) return; + _GLFWwindow* window = _glfwLibrary.window; + if (major != NULL) - *major = _glfwWin.glMajor; + *major = window->glMajor; if (minor != NULL) - *minor = _glfwWin.glMinor; + *minor = window->glMinor; if (rev != NULL) - *rev = _glfwWin.glRevision; + *rev = window->glRevision; } diff --git a/lib/init.c b/lib/init.c index 7f77ff33..761d5c61 100644 --- a/lib/init.c +++ b/lib/init.c @@ -48,13 +48,6 @@ GLFWAPI int glfwInit(void) return GL_TRUE; memset(&_glfwLibrary, 0, sizeof(_glfwLibrary)); - memset(&_glfwWin, 0, sizeof(_glfwWin )); - - // Window is not yet opened - _glfwWin.opened = GL_FALSE; - - // Default enable/disable settings - _glfwWin.sysKeysDisabled = GL_FALSE; // Clear window hints _glfwClearWindowHints(); diff --git a/lib/input.c b/lib/input.c index d6a638c8..f75ede7b 100644 --- a/lib/input.c +++ b/lib/input.c @@ -35,23 +35,23 @@ // //======================================================================== -GLFWAPI int glfwGetKey(int key) +GLFWAPI int glfwGetKey(GLFWwindow window, int key) { - if (!_glfwInitialized || !_glfwWin.opened) + if (!_glfwInitialized) return GLFW_RELEASE; // Is it a valid key? if (key < 0 || key > GLFW_KEY_LAST) return GLFW_RELEASE; - if (_glfwInput.Key[key] == GLFW_STICK) + if (window->key[key] == GLFW_STICK) { // Sticky mode: release key now - _glfwInput.Key[key] = GLFW_RELEASE; + window->key[key] = GLFW_RELEASE; return GLFW_PRESS; } - return (int) _glfwInput.Key[key]; + return (int) window->key[key]; } @@ -59,23 +59,23 @@ GLFWAPI int glfwGetKey(int key) // //======================================================================== -GLFWAPI int glfwGetMouseButton(int button) +GLFWAPI int glfwGetMouseButton(GLFWwindow window, int button) { - if (!_glfwInitialized || !_glfwWin.opened) + if (!_glfwInitialized) return GLFW_RELEASE; // Is it a valid mouse button? if (button < 0 || button > GLFW_MOUSE_BUTTON_LAST) return GLFW_RELEASE; - if (_glfwInput.MouseButton[button] == GLFW_STICK) + if (window->mouseButton[button] == GLFW_STICK) { // Sticky mode: release mouse button now - _glfwInput.MouseButton[button] = GLFW_RELEASE; + window->mouseButton[button] = GLFW_RELEASE; return GLFW_PRESS; } - return (int) _glfwInput.MouseButton[button]; + return (int) window->mouseButton[button]; } @@ -83,17 +83,17 @@ GLFWAPI int glfwGetMouseButton(int button) // //======================================================================== -GLFWAPI void glfwGetMousePos(int* xpos, int* ypos) +GLFWAPI void glfwGetMousePos(GLFWwindow window, int* xpos, int* ypos) { - if (!_glfwInitialized || !_glfwWin.opened) + if (!_glfwInitialized) return; // Return mouse position if (xpos != NULL) - *xpos = _glfwInput.MousePosX; + *xpos = window->mousePosX; if (ypos != NULL) - *ypos = _glfwInput.MousePosY; + *ypos = window->mousePosY; } @@ -101,25 +101,25 @@ GLFWAPI void glfwGetMousePos(int* xpos, int* ypos) // //======================================================================== -GLFWAPI void glfwSetMousePos(int xpos, int ypos) +GLFWAPI void glfwSetMousePos(GLFWwindow window, int xpos, int ypos) { - if (!_glfwInitialized || !_glfwWin.opened) + if (!_glfwInitialized) return; // Don't do anything if the mouse position did not change - if (xpos == _glfwInput.MousePosX && ypos == _glfwInput.MousePosY) + if (xpos == window->mousePosX && ypos == window->mousePosY) return; // Set GLFW mouse position - _glfwInput.MousePosX = xpos; - _glfwInput.MousePosY = ypos; + window->mousePosX = xpos; + window->mousePosY = ypos; // If we have a locked mouse, do not change cursor position - if (_glfwWin.mouseLock) + if (_glfwLibrary.cursorLockWindow) return; // Update physical cursor position - _glfwPlatformSetMouseCursorPos(xpos, ypos); + _glfwPlatformSetMouseCursorPos(window, xpos, ypos); } @@ -127,13 +127,12 @@ GLFWAPI void glfwSetMousePos(int xpos, int ypos) // //======================================================================== -GLFWAPI int glfwGetMouseWheel(void) +GLFWAPI int glfwGetMouseWheel(GLFWwindow window) { - if (!_glfwInitialized || !_glfwWin.opened) + if (!_glfwInitialized) return 0; - // Return mouse wheel position - return _glfwInput.WheelPos; + return window->wheelPos; } @@ -141,13 +140,12 @@ GLFWAPI int glfwGetMouseWheel(void) // //======================================================================== -GLFWAPI void glfwSetMouseWheel(int pos) +GLFWAPI void glfwSetMouseWheel(GLFWwindow window, int pos) { - if (!_glfwInitialized || !_glfwWin.opened) + if (!_glfwInitialized) return; - // Set mouse wheel position - _glfwInput.WheelPos = pos; + window->wheelPos = pos; } @@ -155,13 +153,12 @@ GLFWAPI void glfwSetMouseWheel(int pos) // Set callback function for keyboard input //======================================================================== -GLFWAPI void glfwSetKeyCallback(GLFWkeyfun cbfun) +GLFWAPI void glfwSetKeyCallback(GLFWwindow window, GLFWkeyfun cbfun) { - if (!_glfwInitialized || !_glfwWin.opened) + if (!_glfwInitialized) return; - // Set callback function - _glfwWin.keyCallback = cbfun; + window->keyCallback = cbfun; } @@ -169,13 +166,12 @@ GLFWAPI void glfwSetKeyCallback(GLFWkeyfun cbfun) // Set callback function for character input //======================================================================== -GLFWAPI void glfwSetCharCallback(GLFWcharfun cbfun) +GLFWAPI void glfwSetCharCallback(GLFWwindow window, GLFWcharfun cbfun) { - if (!_glfwInitialized || !_glfwWin.opened) + if (!_glfwInitialized) return; - // Set callback function - _glfwWin.charCallback = cbfun; + window->charCallback = cbfun; } @@ -183,13 +179,12 @@ GLFWAPI void glfwSetCharCallback(GLFWcharfun cbfun) // Set callback function for mouse clicks //======================================================================== -GLFWAPI void glfwSetMouseButtonCallback(GLFWmousebuttonfun cbfun) +GLFWAPI void glfwSetMouseButtonCallback(GLFWwindow window, GLFWmousebuttonfun cbfun) { - if (!_glfwInitialized || !_glfwWin.opened) + if (!_glfwInitialized) return; - // Set callback function - _glfwWin.mouseButtonCallback = cbfun; + window->mouseButtonCallback = cbfun; } @@ -197,18 +192,18 @@ GLFWAPI void glfwSetMouseButtonCallback(GLFWmousebuttonfun cbfun) // Set callback function for mouse moves //======================================================================== -GLFWAPI void glfwSetMousePosCallback(GLFWmouseposfun cbfun) +GLFWAPI void glfwSetMousePosCallback(GLFWwindow window, GLFWmouseposfun cbfun) { - if (!_glfwInitialized || !_glfwWin.opened) + if (!_glfwInitialized || !_glfwLibrary.window) return; // Set callback function - _glfwWin.mousePosCallback = cbfun; + _glfwLibrary.window->mousePosCallback = cbfun; // Call the callback function to let the application know the current // mouse position if (cbfun) - cbfun(_glfwInput.MousePosX, _glfwInput.MousePosY); + cbfun(window->mousePosX, window->mousePosY); } @@ -216,17 +211,17 @@ GLFWAPI void glfwSetMousePosCallback(GLFWmouseposfun cbfun) // Set callback function for mouse wheel //======================================================================== -GLFWAPI void glfwSetMouseWheelCallback(GLFWmousewheelfun cbfun) +GLFWAPI void glfwSetMouseWheelCallback(GLFWwindow window, GLFWmousewheelfun cbfun) { - if (!_glfwInitialized || !_glfwWin.opened) + if (!_glfwInitialized) return; // Set callback function - _glfwWin.mouseWheelCallback = cbfun; + window->mouseWheelCallback = cbfun; // Call the callback function to let the application know the current // mouse wheel position if (cbfun) - cbfun(_glfwInput.WheelPos); + cbfun(window->wheelPos); } diff --git a/lib/internal.h b/lib/internal.h index a7d09afe..cb217b98 100644 --- a/lib/internal.h +++ b/lib/internal.h @@ -51,6 +51,14 @@ #define GLFW_STICK 2 +//------------------------------------------------------------------------ +// Platform specific definitions goes in platform.h (which also includes +// glfw.h) +//------------------------------------------------------------------------ + +#include "platform.h" + + //------------------------------------------------------------------------ // Window opening hints (set by glfwOpenWindowHint) // A bucket of semi-random stuff bunched together for historical reasons @@ -75,14 +83,6 @@ typedef struct { } _GLFWhints; -//------------------------------------------------------------------------ -// Platform specific definitions goes in platform.h (which also includes -// glfw.h) -//------------------------------------------------------------------------ - -#include "platform.h" - - //------------------------------------------------------------------------ // Parameters relating to the creation of the context and window but not // directly related to the properties of the framebuffer @@ -126,6 +126,81 @@ typedef struct { } _GLFWfbconfig; +//------------------------------------------------------------------------ +// Window structure +//------------------------------------------------------------------------ +typedef struct _GLFWwindow { + + // User callback functions + GLFWwindowsizefun windowSizeCallback; + GLFWwindowclosefun windowCloseCallback; + GLFWwindowrefreshfun windowRefreshCallback; + GLFWmousebuttonfun mouseButtonCallback; + GLFWmouseposfun mousePosCallback; + GLFWmousewheelfun mouseWheelCallback; + GLFWkeyfun keyCallback; + GLFWcharfun charCallback; + + // User selected window settings + int mode; + GLboolean sysKeysDisabled; // System keys disabled flag + GLboolean windowNoResize; // Resize- and maximize gadgets disabled flag + int refreshRate; // Vertical monitor refresh rate + + // Input + GLboolean stickyKeys; + GLboolean stickyMouseButtons; + GLboolean keyRepeat; + int mousePosX, mousePosY; + int wheelPos; + char mouseButton[GLFW_MOUSE_BUTTON_LAST + 1]; + char key[GLFW_KEY_LAST + 1]; + int lastChar; + + // Window status & parameters + GLboolean active; // Application active flag + GLboolean iconified; // Window iconified flag + int width, height; // Window width and heigth + GLboolean accelerated; // GL_TRUE if window is HW accelerated + + // Framebuffer attributes + int redBits; + int greenBits; + int blueBits; + int alphaBits; + int depthBits; + int stencilBits; + int accumRedBits; + int accumGreenBits; + int accumBlueBits; + int accumAlphaBits; + int auxBuffers; + GLboolean stereo; + int samples; + + // OpenGL extensions and context attributes + int glMajor, glMinor, glRevision; + int glForward, glDebug, glProfile; + + PFNGLGETSTRINGIPROC GetStringi; + + _GLFW_PLATFORM_WINDOW_STATE; +} _GLFWwindow; + + +//------------------------------------------------------------------------ +// Library global data +//------------------------------------------------------------------------ +typedef struct { + _GLFWhints hints; + _GLFWwindow* window; + _GLFWwindow* currentWindow; + _GLFWwindow* cursorLockWindow; + + _GLFW_PLATFORM_LIBRARY_STATE; +} _GLFWlibrary; + + //======================================================================== // System independent global variables (GLFW internals) //======================================================================== @@ -137,6 +212,8 @@ int _glfwInitialized = 0; GLFWGLOBAL int _glfwInitialized; #endif +GLFWGLOBAL _GLFWlibrary _glfwLibrary; + //======================================================================== // Prototypes for platform specific implementation functions @@ -147,17 +224,13 @@ int _glfwPlatformInit(void); int _glfwPlatformTerminate(void); // Enable/Disable -void _glfwPlatformEnableSystemKeys(void); -void _glfwPlatformDisableSystemKeys(void); +void _glfwPlatformEnableSystemKeys(_GLFWwindow* window); +void _glfwPlatformDisableSystemKeys(_GLFWwindow* window); // Fullscreen int _glfwPlatformGetVideoModes(GLFWvidmode* list, int maxcount); void _glfwPlatformGetDesktopMode(GLFWvidmode* mode); -// OpenGL extensions -int _glfwPlatformExtensionSupported(const char* extension); -void* _glfwPlatformGetProcAddress(const char* procname); - // Joystick int _glfwPlatformGetJoystickParam(int joy, int param); int _glfwPlatformGetJoystickPos(int joy, float* pos, int numaxes); @@ -168,21 +241,28 @@ double _glfwPlatformGetTime(void); void _glfwPlatformSetTime(double time); // Window management -int _glfwPlatformOpenWindow(int width, int height, const _GLFWwndconfig* wndconfig, const _GLFWfbconfig* fbconfig); -void _glfwPlatformCloseWindow(void); -void _glfwPlatformSetWindowTitle(const char* title); -void _glfwPlatformSetWindowSize(int width, int height); -void _glfwPlatformSetWindowPos(int x, int y); -void _glfwPlatformIconifyWindow(void); -void _glfwPlatformRestoreWindow(void); +int _glfwPlatformOpenWindow(_GLFWwindow* window, int width, int height, const _GLFWwndconfig* wndconfig, const _GLFWfbconfig* fbconfig); +int _glfwPlatformMakeWindowCurrent(_GLFWwindow* window); +void _glfwPlatformCloseWindow(_GLFWwindow* window); +void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char* title); +void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height); +void _glfwPlatformSetWindowPos(_GLFWwindow* window, int x, int y); +void _glfwPlatformIconifyWindow(_GLFWwindow* window); +void _glfwPlatformRestoreWindow(_GLFWwindow* window); +void _glfwPlatformHideMouseCursor(_GLFWwindow* window); +void _glfwPlatformShowMouseCursor(_GLFWwindow* window); +void _glfwPlatformSetMouseCursorPos(_GLFWwindow* window, int x, int y); + +// Event management +void _glfwPlatformPollEvents(void); +void _glfwPlatformWaitEvents(void); + +// OpenGL context management void _glfwPlatformSwapBuffers(void); void _glfwPlatformSwapInterval(int interval); void _glfwPlatformRefreshWindowParams(void); -void _glfwPlatformPollEvents(void); -void _glfwPlatformWaitEvents(void); -void _glfwPlatformHideMouseCursor(void); -void _glfwPlatformShowMouseCursor(void); -void _glfwPlatformSetMouseCursorPos(int x, int y); +int _glfwPlatformExtensionSupported(const char* extension); +void* _glfwPlatformGetProcAddress(const char* procname); //======================================================================== @@ -193,11 +273,11 @@ void _glfwPlatformSetMouseCursorPos(int x, int y); void _glfwClearWindowHints(void); // Input handling (window.c) -void _glfwClearInput(void); -void _glfwInputDeactivation(void); -void _glfwInputKey(int key, int action); -void _glfwInputChar(int character, int action); -void _glfwInputMouseClick(int button, int action); +void _glfwClearInput(_GLFWwindow* window); +void _glfwInputDeactivation(_GLFWwindow* window); +void _glfwInputKey(_GLFWwindow* window, int key, int action); +void _glfwInputChar(_GLFWwindow* window, int character, int action); +void _glfwInputMouseClick(_GLFWwindow* window, int button, int action); // OpenGL extensions (glext.c) void _glfwParseGLVersion(int* major, int* minor, int* rev); diff --git a/lib/window.c b/lib/window.c index cd0f44d6..1363ffa9 100644 --- a/lib/window.c +++ b/lib/window.c @@ -32,6 +32,7 @@ #include #include +#include //************************************************************************ @@ -58,22 +59,22 @@ void _glfwClearWindowHints(void) // Handle the input tracking part of window deactivation //======================================================================== -void _glfwInputDeactivation(void) +void _glfwInputDeactivation(_GLFWwindow* window) { int i; // Release all keyboard keys for (i = 0; i <= GLFW_KEY_LAST; i++) { - if(_glfwInput.Key[i] == GLFW_PRESS) - _glfwInputKey(i, GLFW_RELEASE); + if (window->key[i] == GLFW_PRESS) + _glfwInputKey(window, i, GLFW_RELEASE); } // Release all mouse buttons for (i = 0; i <= GLFW_MOUSE_BUTTON_LAST; i++) { - if (_glfwInput.MouseButton[i] == GLFW_PRESS) - _glfwInputMouseClick(i, GLFW_RELEASE); + if (window->mouseButton[i] == GLFW_PRESS) + _glfwInputMouseClick(window, i, GLFW_RELEASE); } } @@ -82,34 +83,34 @@ void _glfwInputDeactivation(void) // Clear all input state //======================================================================== -void _glfwClearInput(void) +void _glfwClearInput(_GLFWwindow* window) { int i; // Release all keyboard keys for (i = 0; i <= GLFW_KEY_LAST; i++) - _glfwInput.Key[i] = GLFW_RELEASE; + window->key[i] = GLFW_RELEASE; // Clear last character - _glfwInput.LastChar = 0; + window->lastChar = 0; // Release all mouse buttons for (i = 0; i <= GLFW_MOUSE_BUTTON_LAST; i++) - _glfwInput.MouseButton[i] = GLFW_RELEASE; + window->mouseButton[i] = GLFW_RELEASE; // Set mouse position to (0,0) - _glfwInput.MousePosX = 0; - _glfwInput.MousePosY = 0; + window->mousePosX = 0; + window->mousePosY = 0; // Set mouse wheel position to 0 - _glfwInput.WheelPos = 0; + window->wheelPos = 0; // The default is to use non sticky keys and mouse buttons - _glfwInput.StickyKeys = GL_FALSE; - _glfwInput.StickyMouseButtons = GL_FALSE; + window->stickyKeys = GL_FALSE; + window->stickyMouseButtons = GL_FALSE; // The default is to disable key repeat - _glfwInput.KeyRepeat = GL_FALSE; + window->keyRepeat = GL_FALSE; } @@ -117,30 +118,30 @@ void _glfwClearInput(void) // Register keyboard activity //======================================================================== -void _glfwInputKey(int key, int action) +void _glfwInputKey(_GLFWwindow* window, int key, int action) { - int keyrepeat = 0; + GLboolean keyrepeat = GL_FALSE; if (key < 0 || key > GLFW_KEY_LAST) return; // Are we trying to release an already released key? - if (action == GLFW_RELEASE && _glfwInput.Key[key] != GLFW_PRESS) + if (action == GLFW_RELEASE && window->key[key] != GLFW_PRESS) return; // Register key action - if(action == GLFW_RELEASE && _glfwInput.StickyKeys) - _glfwInput.Key[key] = GLFW_STICK; + if(action == GLFW_RELEASE && window->stickyKeys) + window->key[key] = GLFW_STICK; else { - keyrepeat = (_glfwInput.Key[key] == GLFW_PRESS) && + keyrepeat = (window->key[key] == GLFW_PRESS) && (action == GLFW_PRESS); - _glfwInput.Key[key] = (char) action; + window->key[key] = (char) action; } // Call user callback function - if (_glfwWin.keyCallback && (_glfwInput.KeyRepeat || !keyrepeat) ) - _glfwWin.keyCallback(key, action); + if (window->keyCallback && (window->keyRepeat || !keyrepeat) ) + window->keyCallback(key, action); } @@ -148,7 +149,7 @@ void _glfwInputKey(int key, int action) // Register (keyboard) character activity //======================================================================== -void _glfwInputChar(int character, int action) +void _glfwInputChar(_GLFWwindow* window, int character, int action) { int keyrepeat = 0; @@ -157,14 +158,14 @@ void _glfwInputChar(int character, int action) return; // Is this a key repeat? - if (action == GLFW_PRESS && _glfwInput.LastChar == character) + if (action == GLFW_PRESS && window->lastChar == character) keyrepeat = 1; // Store this character as last character (or clear it, if released) if (action == GLFW_PRESS) - _glfwInput.LastChar = character; + window->lastChar = character; else - _glfwInput.LastChar = 0; + window->lastChar = 0; if (action != GLFW_PRESS) { @@ -184,8 +185,8 @@ void _glfwInputChar(int character, int action) return; } - if (_glfwWin.charCallback && (_glfwInput.KeyRepeat || !keyrepeat)) - _glfwWin.charCallback(character, action); + if (window->charCallback && (window->keyRepeat || !keyrepeat)) + window->charCallback(character, action); } @@ -193,20 +194,19 @@ void _glfwInputChar(int character, int action) // Register mouse button clicks //======================================================================== -void _glfwInputMouseClick(int button, int action) +void _glfwInputMouseClick(_GLFWwindow* window, int button, int action) { - if (button >= 0 && button <= GLFW_MOUSE_BUTTON_LAST) - { - // Register mouse button action - if (action == GLFW_RELEASE && _glfwInput.StickyMouseButtons) - _glfwInput.MouseButton[button] = GLFW_STICK; - else - _glfwInput.MouseButton[button] = (char) action; + if (button < 0 || button > GLFW_MOUSE_BUTTON_LAST) + return; - // Call user callback function - if (_glfwWin.mouseButtonCallback) - _glfwWin.mouseButtonCallback(button, action); - } + // Register mouse button action + if (action == GLFW_RELEASE && window->stickyMouseButtons) + window->mouseButton[button] = GLFW_STICK; + else + window->mouseButton[button] = (char) action; + + if (window->mouseButtonCallback) + window->mouseButtonCallback(button, action); } @@ -393,16 +393,25 @@ const _GLFWfbconfig* _glfwChooseFBConfig(const _GLFWfbconfig* desired, // Create the GLFW window and its associated context //======================================================================== -GLFWAPI int glfwOpenWindow(int width, int height, - int redbits, int greenbits, int bluebits, - int alphabits, int depthbits, int stencilbits, - int mode) +GLFWAPI GLFWwindow glfwOpenWindow(int width, int height, + int redbits, int greenbits, int bluebits, + int alphabits, int depthbits, int stencilbits, + int mode) { _GLFWfbconfig fbconfig; _GLFWwndconfig wndconfig; + _GLFWwindow* window; - if (!_glfwInitialized || _glfwWin.opened) - return GL_FALSE; + if (!_glfwInitialized || _glfwLibrary.window) + return NULL; + + window = (_GLFWwindow*) malloc(sizeof(_GLFWwindow)); + if (!window) + return NULL; + + _glfwLibrary.window = window; + + memset(window, 0, sizeof(_GLFWwindow)); // Set up desired framebuffer config fbconfig.redBits = Max(redbits, 0); @@ -429,19 +438,25 @@ GLFWAPI int glfwOpenWindow(int width, int height, wndconfig.glDebug = _glfwLibrary.hints.glDebug ? GL_TRUE : GL_FALSE; wndconfig.glProfile = _glfwLibrary.hints.glProfile; + // Clear for next open call + _glfwClearWindowHints(); + if (wndconfig.glMajor == 1 && wndconfig.glMinor > 5) { // OpenGL 1.x series ended with version 1.5 + glfwCloseWindow(window); return GL_FALSE; } else if (wndconfig.glMajor == 2 && wndconfig.glMinor > 1) { // OpenGL 2.x series ended with version 2.1 + glfwCloseWindow(window); return GL_FALSE; } else if (wndconfig.glMajor == 3 && wndconfig.glMinor > 3) { // OpenGL 3.x series ended with version 3.3 + glfwCloseWindow(window); return GL_FALSE; } else @@ -453,37 +468,26 @@ GLFWAPI int glfwOpenWindow(int width, int height, (wndconfig.glMajor < 3 || (wndconfig.glMajor == 3 && wndconfig.glMinor < 2))) { // Context profiles are only defined for OpenGL version 3.2 and above + glfwCloseWindow(window); return GL_FALSE; } if (wndconfig.glForward && wndconfig.glMajor < 3) { // Forward-compatible contexts are only defined for OpenGL version 3.0 and above + glfwCloseWindow(window); return GL_FALSE; } - // Clear for next open call - _glfwClearWindowHints(); - - // Check input arguments if (mode != GLFW_WINDOW && mode != GLFW_FULLSCREEN) + { + // Invalid window mode + glfwCloseWindow(window); return GL_FALSE; + } // Clear GLFW window state - _glfwWin.active = GL_TRUE; - _glfwWin.iconified = GL_FALSE; - _glfwWin.mouseLock = GL_FALSE; - _glfwClearInput(); - - // Unregister all callback functions - _glfwWin.windowSizeCallback = NULL; - _glfwWin.windowCloseCallback = NULL; - _glfwWin.windowRefreshCallback = NULL; - _glfwWin.keyCallback = NULL; - _glfwWin.charCallback = NULL; - _glfwWin.mousePosCallback = NULL; - _glfwWin.mouseButtonCallback = NULL; - _glfwWin.mouseWheelCallback = NULL; + _glfwClearInput(window); // Check width & height if (width > 0 && height <= 0) @@ -504,52 +508,68 @@ GLFWAPI int glfwOpenWindow(int width, int height, } // Remember window settings - _glfwWin.width = width; - _glfwWin.height = height; - _glfwWin.fullscreen = (mode == GLFW_FULLSCREEN ? GL_TRUE : GL_FALSE); + window->width = width; + window->height = height; + window->mode = mode; // Platform specific window opening routine - if (!_glfwPlatformOpenWindow(width, height, &wndconfig, &fbconfig)) - return GL_FALSE; - - // Flag that window is now opened - _glfwWin.opened = GL_TRUE; - - // Get window parameters (such as color buffer bits etc) - _glfwPlatformRefreshWindowParams(); - - // Get OpenGL version - _glfwParseGLVersion(&_glfwWin.glMajor, &_glfwWin.glMinor, - &_glfwWin.glRevision); - - if (_glfwWin.glMajor < wndconfig.glMajor || - (_glfwWin.glMajor == wndconfig.glMajor && - _glfwWin.glMinor < wndconfig.glMinor)) + if (!_glfwPlatformOpenWindow(window, width, height, &wndconfig, &fbconfig)) { - _glfwPlatformCloseWindow(); + glfwCloseWindow(window); return GL_FALSE; } - if (_glfwWin.glMajor > 2) + // Get window parameters (such as color buffer bits etc) + glfwMakeWindowCurrent(window); + _glfwPlatformRefreshWindowParams(); + + // Get OpenGL version + _glfwParseGLVersion(&window->glMajor, &window->glMinor, &window->glRevision); + + if (window->glMajor < wndconfig.glMajor || + (window->glMajor == wndconfig.glMajor && + window->glMinor < wndconfig.glMinor)) { - _glfwWin.GetStringi = (PFNGLGETSTRINGIPROC) glfwGetProcAddress("glGetStringi"); - if (!_glfwWin.GetStringi) + // The desired OpenGL version is greater than the actual version + // This only happens if the machine lacks {GLX|WGL}_ARB_create_context + glfwCloseWindow(window); + return GL_FALSE; + } + + if (window->glMajor > 2) + { + window->GetStringi = (PFNGLGETSTRINGIPROC) glfwGetProcAddress("glGetStringi"); + if (!window->GetStringi) { - _glfwPlatformCloseWindow(); + glfwCloseWindow(window); return GL_FALSE; } } // If full-screen mode was requested, disable mouse cursor if (mode == GLFW_FULLSCREEN) - glfwDisable(GLFW_MOUSE_CURSOR); + glfwDisable(window, GLFW_MOUSE_CURSOR); // Start by clearing the front buffer to black (avoid ugly desktop // remains in our OpenGL window) glClear(GL_COLOR_BUFFER_BIT); _glfwPlatformSwapBuffers(); - return GL_TRUE; + return window; +} + + +//======================================================================== +// Make the OpenGL context associated with the specified window current +//======================================================================== + +GLFWAPI void glfwMakeWindowCurrent(GLFWwindow window) +{ + if (_glfwLibrary.currentWindow == window) + return; + + _glfwPlatformMakeWindowCurrent(window); + _glfwLibrary.currentWindow = window; } @@ -616,18 +636,24 @@ GLFWAPI void glfwOpenWindowHint(int target, int hint) // Properly kill the window / video display //======================================================================== -GLFWAPI void glfwCloseWindow(void) +GLFWAPI void glfwCloseWindow(GLFWwindow window) { if (!_glfwInitialized) return; // Show mouse pointer again (if hidden) - glfwEnable(GLFW_MOUSE_CURSOR); + if (window == _glfwLibrary.cursorLockWindow) + glfwEnable(window, GLFW_MOUSE_CURSOR); - _glfwPlatformCloseWindow(); + if (window == _glfwLibrary.currentWindow) + glfwMakeWindowCurrent(NULL); - memset(&_glfwWin, 0, sizeof(_glfwWin)); - _glfwWin.opened = GL_FALSE; + _glfwPlatformCloseWindow(window); + + free(window); + + // Yuck + _glfwLibrary.window = NULL; } @@ -635,13 +661,12 @@ GLFWAPI void glfwCloseWindow(void) // Set the window title //======================================================================== -GLFWAPI void glfwSetWindowTitle(const char* title) +GLFWAPI void glfwSetWindowTitle(GLFWwindow window, const char* title) { - if (!_glfwInitialized || !_glfwWin.opened) + if (!_glfwInitialized) return; - // Set window title - _glfwPlatformSetWindowTitle(title); + _glfwPlatformSetWindowTitle(window, title); } @@ -649,13 +674,16 @@ GLFWAPI void glfwSetWindowTitle(const char* title) // Get the window size //======================================================================== -GLFWAPI void glfwGetWindowSize(int* width, int* height) +GLFWAPI void glfwGetWindowSize(GLFWwindow window, int* width, int* height) { + if (!_glfwInitialized) + return; + if (width != NULL) - *width = _glfwWin.width; + *width = window->width; if (height != NULL) - *height = _glfwWin.height; + *height = window->height; } @@ -663,21 +691,23 @@ GLFWAPI void glfwGetWindowSize(int* width, int* height) // Set the window size //======================================================================== -GLFWAPI void glfwSetWindowSize(int width, int height) +GLFWAPI void glfwSetWindowSize(GLFWwindow window, int width, int height) { - if (!_glfwInitialized || !_glfwWin.opened || _glfwWin.iconified) + if (!_glfwInitialized || window->iconified) return; // Don't do anything if the window size did not change - if (width == _glfwWin.width && height == _glfwWin.height) + if (width == window->width && height == window->height) return; - // Change window size - _glfwPlatformSetWindowSize(width, height); + _glfwPlatformSetWindowSize(window, width, height); - // Refresh window parameters (may have changed due to changed video - // modes) - _glfwPlatformRefreshWindowParams(); + if (window->mode == GLFW_FULLSCREEN) + { + // Refresh window parameters (may have changed due to changed video + // modes) + _glfwPlatformRefreshWindowParams(); + } } @@ -685,16 +715,14 @@ GLFWAPI void glfwSetWindowSize(int width, int height) // Set the window position //======================================================================== -GLFWAPI void glfwSetWindowPos(int x, int y) +GLFWAPI void glfwSetWindowPos(GLFWwindow window, int x, int y) { - if (!_glfwInitialized || !_glfwWin.opened || _glfwWin.fullscreen || - _glfwWin.iconified) + if (!_glfwInitialized || window->mode == GLFW_FULLSCREEN || window->iconified) { return; } - // Set window position - _glfwPlatformSetWindowPos(x, y); + _glfwPlatformSetWindowPos(window, x, y); } @@ -702,13 +730,12 @@ GLFWAPI void glfwSetWindowPos(int x, int y) // Window iconification //======================================================================== -GLFWAPI void glfwIconifyWindow(void) +GLFWAPI void glfwIconifyWindow(GLFWwindow window) { - if (!_glfwInitialized || !_glfwWin.opened || _glfwWin.iconified) + if (!_glfwInitialized || window->iconified) return; - // Iconify window - _glfwPlatformIconifyWindow(); + _glfwPlatformIconifyWindow(window); } @@ -716,30 +743,29 @@ GLFWAPI void glfwIconifyWindow(void) // Window un-iconification //======================================================================== -GLFWAPI void glfwRestoreWindow(void) +GLFWAPI void glfwRestoreWindow(GLFWwindow window) { - if (!_glfwInitialized || !_glfwWin.opened || !_glfwWin.iconified) + if (!_glfwInitialized || !window->iconified) return; // Restore iconified window - _glfwPlatformRestoreWindow(); + _glfwPlatformRestoreWindow(window); - // Refresh window parameters - _glfwPlatformRefreshWindowParams(); + if (window->mode == GLFW_FULLSCREEN) + _glfwPlatformRefreshWindowParams(); } //======================================================================== -// Swap buffers (double-buffering) and poll any new events +// Swap buffers (double-buffering) //======================================================================== GLFWAPI void glfwSwapBuffers(void) { - if (!_glfwInitialized || !_glfwWin.opened) + if (!_glfwInitialized) return; - // Update display-buffer - if (_glfwWin.opened) + if (_glfwLibrary.currentWindow) _glfwPlatformSwapBuffers(); } @@ -750,10 +776,9 @@ GLFWAPI void glfwSwapBuffers(void) GLFWAPI void glfwSwapInterval(int interval) { - if (!_glfwInitialized || !_glfwWin.opened) + if (!_glfwInitialized) return; - // Set double buffering swap interval _glfwPlatformSwapInterval(interval); } @@ -762,70 +787,59 @@ GLFWAPI void glfwSwapInterval(int interval) // Get window parameter //======================================================================== -GLFWAPI int glfwGetWindowParam(int param) +GLFWAPI int glfwGetWindowParam(GLFWwindow window, int param) { if (!_glfwInitialized) return 0; - if (!_glfwWin.opened) - { - if (param == GLFW_OPENED) - return GL_FALSE; - - return 0; - } - - // Window parameters switch (param) { - case GLFW_OPENED: - return GL_TRUE; case GLFW_ACTIVE: - return _glfwWin.active; + return window->active; case GLFW_ICONIFIED: - return _glfwWin.iconified; + return window->iconified; case GLFW_ACCELERATED: - return _glfwWin.accelerated; + return window->accelerated; case GLFW_RED_BITS: - return _glfwWin.redBits; + return window->redBits; case GLFW_GREEN_BITS: - return _glfwWin.greenBits; + return window->greenBits; case GLFW_BLUE_BITS: - return _glfwWin.blueBits; + return window->blueBits; case GLFW_ALPHA_BITS: - return _glfwWin.alphaBits; + return window->alphaBits; case GLFW_DEPTH_BITS: - return _glfwWin.depthBits; + return window->depthBits; case GLFW_STENCIL_BITS: - return _glfwWin.stencilBits; + return window->stencilBits; case GLFW_ACCUM_RED_BITS: - return _glfwWin.accumRedBits; + return window->accumRedBits; case GLFW_ACCUM_GREEN_BITS: - return _glfwWin.accumGreenBits; + return window->accumGreenBits; case GLFW_ACCUM_BLUE_BITS: - return _glfwWin.accumBlueBits; + return window->accumBlueBits; case GLFW_ACCUM_ALPHA_BITS: - return _glfwWin.accumAlphaBits; + return window->accumAlphaBits; case GLFW_AUX_BUFFERS: - return _glfwWin.auxBuffers; + return window->auxBuffers; case GLFW_STEREO: - return _glfwWin.stereo; + return window->stereo; case GLFW_REFRESH_RATE: - return _glfwWin.refreshRate; + return window->refreshRate; case GLFW_WINDOW_NO_RESIZE: - return _glfwWin.windowNoResize; + return window->windowNoResize; case GLFW_FSAA_SAMPLES: - return _glfwWin.samples; + return window->samples; case GLFW_OPENGL_VERSION_MAJOR: - return _glfwWin.glMajor; + return window->glMajor; case GLFW_OPENGL_VERSION_MINOR: - return _glfwWin.glMinor; + return window->glMinor; case GLFW_OPENGL_FORWARD_COMPAT: - return _glfwWin.glForward; + return window->glForward; case GLFW_OPENGL_DEBUG_CONTEXT: - return _glfwWin.glDebug; + return window->glDebug; case GLFW_OPENGL_PROFILE: - return _glfwWin.glProfile; + return window->glProfile; default: return 0; } @@ -836,31 +850,29 @@ GLFWAPI int glfwGetWindowParam(int param) // Set callback function for window size changes //======================================================================== -GLFWAPI void glfwSetWindowSizeCallback(GLFWwindowsizefun cbfun) +GLFWAPI void glfwSetWindowSizeCallback(GLFWwindow window, GLFWwindowsizefun cbfun) { - if (!_glfwInitialized || !_glfwWin.opened) + if (!_glfwInitialized) return; - // Set callback function - _glfwWin.windowSizeCallback = cbfun; + window->windowSizeCallback = cbfun; // Call the callback function to let the application know the current // window size if (cbfun) - cbfun(_glfwWin.width, _glfwWin.height); + cbfun(window->width, window->height); } //======================================================================== // Set callback function for window close events //======================================================================== -GLFWAPI void glfwSetWindowCloseCallback(GLFWwindowclosefun cbfun) +GLFWAPI void glfwSetWindowCloseCallback(GLFWwindow window, GLFWwindowclosefun cbfun) { - if (!_glfwInitialized || !_glfwWin.opened) + if (!_glfwInitialized) return; - // Set callback function - _glfwWin.windowCloseCallback = cbfun; + window->windowCloseCallback = cbfun; } @@ -868,13 +880,12 @@ GLFWAPI void glfwSetWindowCloseCallback(GLFWwindowclosefun cbfun) // Set callback function for window refresh events //======================================================================== -GLFWAPI void glfwSetWindowRefreshCallback(GLFWwindowrefreshfun cbfun) +GLFWAPI void glfwSetWindowRefreshCallback(GLFWwindow window, GLFWwindowrefreshfun cbfun) { - if (!_glfwInitialized || !_glfwWin.opened) + if (!_glfwInitialized) return; - // Set callback function - _glfwWin.windowRefreshCallback = cbfun; + window->windowRefreshCallback = cbfun; } @@ -884,10 +895,9 @@ GLFWAPI void glfwSetWindowRefreshCallback(GLFWwindowrefreshfun cbfun) GLFWAPI void glfwPollEvents(void) { - if (!_glfwInitialized || !_glfwWin.opened) + if (!_glfwInitialized) return; - // Poll for new events _glfwPlatformPollEvents(); } @@ -898,10 +908,9 @@ GLFWAPI void glfwPollEvents(void) GLFWAPI void glfwWaitEvents(void) { - if (!_glfwInitialized || !_glfwWin.opened) + if (!_glfwInitialized) return; - // Poll for new events _glfwPlatformWaitEvents(); } diff --git a/lib/x11/platform.h b/lib/x11/platform.h index 1d82d18f..718be78c 100644 --- a/lib/x11/platform.h +++ b/lib/x11/platform.h @@ -161,6 +161,10 @@ typedef const GLubyte* (APIENTRY *PFNGLGETSTRINGIPROC)(GLenum, GLuint); #endif /*GL_VERSION_3_0*/ +#define _GLFW_PLATFORM_WINDOW_STATE _GLFWwindowX11 X11 +#define _GLFW_PLATFORM_LIBRARY_STATE _GLFWlibraryX11 X11 + + //======================================================================== // Global variables (GLFW internals) @@ -169,59 +173,7 @@ typedef const GLubyte* (APIENTRY *PFNGLGETSTRINGIPROC)(GLenum, GLuint); //------------------------------------------------------------------------ // Window structure //------------------------------------------------------------------------ -typedef struct _GLFWwin_struct _GLFWwin; - -struct _GLFWwin_struct { - -// ========= PLATFORM INDEPENDENT MANDATORY PART ========================= - - // User callback functions - GLFWwindowsizefun windowSizeCallback; - GLFWwindowclosefun windowCloseCallback; - GLFWwindowrefreshfun windowRefreshCallback; - GLFWmousebuttonfun mouseButtonCallback; - GLFWmouseposfun mousePosCallback; - GLFWmousewheelfun mouseWheelCallback; - GLFWkeyfun keyCallback; - GLFWcharfun charCallback; - - // User selected window settings - int fullscreen; // Fullscreen flag - int mouseLock; // Mouse-lock flag - int sysKeysDisabled; // System keys disabled flag - int windowNoResize; // Resize- and maximize gadgets disabled flag - int refreshRate; // Vertical monitor refresh rate - - // Window status & parameters - int opened; // Flag telling if window is opened or not - int active; // Application active flag - int iconified; // Window iconified flag - int width, height; // Window width and heigth - int accelerated; // GL_TRUE if window is HW accelerated - - // Framebuffer attributes - int redBits; - int greenBits; - int blueBits; - int alphaBits; - int depthBits; - int stencilBits; - int accumRedBits; - int accumGreenBits; - int accumBlueBits; - int accumAlphaBits; - int auxBuffers; - int stereo; - int samples; - - // OpenGL extensions and context attributes - int glMajor, glMinor, glRevision; - int glForward, glDebug, glProfile; - - PFNGLGETSTRINGIPROC GetStringi; - - -// ========= PLATFORM SPECIFIC PART ====================================== +typedef struct _GLFWwindowX11 { // Platform specific window resources Colormap colormap; // Window colormap @@ -238,6 +190,8 @@ struct _GLFWwin_struct { Atom wmActiveWindow; // _NET_ACTIVE_WINDOW atom Cursor cursor; // Invisible cursor for hidden cursor + int mouseMoved, cursorPosX, cursorPosY; + // GLX extensions PFNGLXSWAPINTERVALSGIPROC SwapIntervalSGI; PFNGLXGETFBCONFIGATTRIBSGIXPROC GetFBConfigAttribSGIX; @@ -258,6 +212,30 @@ struct _GLFWwin_struct { GLboolean pointerGrabbed; // True if pointer is currently grabbed GLboolean pointerHidden; // True if pointer is currently hidden +} _GLFWwindowX11; + + +//------------------------------------------------------------------------ +// Platform-specific ibrary global data +//------------------------------------------------------------------------ +typedef struct { + Display* display; + + // Server-side GLX version + int glxMajor, glxMinor; + + struct { + int available; + int eventBase; + int errorBase; + } XF86VidMode; + + struct { + int available; + int eventBase; + int errorBase; + } XRandR; + // Screensaver data struct { int changed; @@ -280,69 +258,6 @@ struct _GLFWwin_struct { Rotation oldRotation; #endif } FS; -}; - -GLFWGLOBAL _GLFWwin _glfwWin; - - -//------------------------------------------------------------------------ -// User input status (most of this should go in _GLFWwin) -//------------------------------------------------------------------------ -GLFWGLOBAL struct { - -// ========= PLATFORM INDEPENDENT MANDATORY PART ========================= - - // Mouse status - int MousePosX, MousePosY; - int WheelPos; - char MouseButton[ GLFW_MOUSE_BUTTON_LAST+1 ]; - - // Keyboard status - char Key[ GLFW_KEY_LAST+1 ]; - int LastChar; - - // User selected settings - int StickyKeys; - int StickyMouseButtons; - int KeyRepeat; - - -// ========= PLATFORM SPECIFIC PART ====================================== - - // Platform specific internal variables - int MouseMoved, CursorPosX, CursorPosY; - -} _glfwInput; - - -//------------------------------------------------------------------------ -// Library global data -//------------------------------------------------------------------------ -GLFWGLOBAL struct { - -// ========= PLATFORM INDEPENDENT MANDATORY PART ========================= - - // Window opening hints - _GLFWhints hints; - -// ========= PLATFORM SPECIFIC PART ====================================== - - Display* display; - - // Server-side GLX version - int glxMajor, glxMinor; - - struct { - int available; - int eventBase; - int errorBase; - } XF86VidMode; - - struct { - int available; - int eventBase; - int errorBase; - } XRandR; // Timer data struct { @@ -355,7 +270,7 @@ GLFWGLOBAL struct { void* libGL; // dlopen handle for libGL.so } Libs; #endif -} _glfwLibrary; +} _GLFWlibraryX11; //------------------------------------------------------------------------ @@ -382,7 +297,7 @@ void _glfwInitTimer(void); int _glfwGetClosestVideoMode(int screen, int* width, int* height, int* rate); void _glfwSetVideoModeMODE(int screen, int mode, int rate); void _glfwSetVideoMode(int screen, int* width, int* height, int* rate); -void _glfwRestoreVideoMode(void); +void _glfwRestoreVideoMode(int screen); // Joystick input void _glfwInitJoysticks(void); diff --git a/lib/x11/x11_enable.c b/lib/x11/x11_enable.c index aa672c89..e23e7785 100644 --- a/lib/x11/x11_enable.c +++ b/lib/x11/x11_enable.c @@ -39,12 +39,12 @@ // Enable system keys //======================================================================== -void _glfwPlatformEnableSystemKeys(void) +void _glfwPlatformEnableSystemKeys(_GLFWwindow* window) { - if (_glfwWin.keyboardGrabbed) + if (window->X11.keyboardGrabbed) { - XUngrabKeyboard(_glfwLibrary.display, CurrentTime); - _glfwWin.keyboardGrabbed = GL_FALSE; + XUngrabKeyboard(_glfwLibrary.X11.display, CurrentTime); + window->X11.keyboardGrabbed = GL_FALSE; } } @@ -52,13 +52,13 @@ void _glfwPlatformEnableSystemKeys(void) // Disable system keys //======================================================================== -void _glfwPlatformDisableSystemKeys(void) +void _glfwPlatformDisableSystemKeys(_GLFWwindow* window) { - if (XGrabKeyboard(_glfwLibrary.display, _glfwWin.window, + if (XGrabKeyboard(_glfwLibrary.X11.display, window->X11.window, True, GrabModeAsync, GrabModeAsync, CurrentTime) == GrabSuccess) { - _glfwWin.keyboardGrabbed = GL_TRUE; + window->X11.keyboardGrabbed = GL_TRUE; } } diff --git a/lib/x11/x11_fullscreen.c b/lib/x11/x11_fullscreen.c index 1d3a4f01..c59e1e4c 100644 --- a/lib/x11/x11_fullscreen.c +++ b/lib/x11/x11_fullscreen.c @@ -75,10 +75,10 @@ int _glfwGetClosestVideoMode(int screen, int* width, int* height, int* rate) XRRScreenConfiguration* sc; XRRScreenSize* sizelist; - if (_glfwLibrary.XRandR.available) + if (_glfwLibrary.X11.XRandR.available) { - sc = XRRGetScreenInfo(_glfwLibrary.display, - RootWindow(_glfwLibrary.display, screen)); + sc = XRRGetScreenInfo(_glfwLibrary.X11.display, + RootWindow(_glfwLibrary.X11.display, screen)); sizelist = XRRConfigSizes(sc, &sizecount); @@ -174,8 +174,8 @@ int _glfwGetClosestVideoMode(int screen, int* width, int* height, int* rate) #endif // Default: Simply use the screen resolution - *width = DisplayWidth(_glfwLibrary.display, screen); - *height = DisplayHeight(_glfwLibrary.display, screen); + *width = DisplayWidth(_glfwLibrary.X11.display, screen); + *height = DisplayHeight(_glfwLibrary.X11.display, screen); return 0; } @@ -191,25 +191,25 @@ void _glfwSetVideoModeMODE(int screen, int mode, int rate) XRRScreenConfiguration* sc; Window root; - if (_glfwLibrary.XRandR.available) + if (_glfwLibrary.X11.XRandR.available) { - root = RootWindow(_glfwLibrary.display, screen); - sc = XRRGetScreenInfo(_glfwLibrary.display, root); + root = RootWindow(_glfwLibrary.X11.display, screen); + sc = XRRGetScreenInfo(_glfwLibrary.X11.display, root); // Remember old size and flag that we have changed the mode - if (!_glfwWin.FS.modeChanged) + if (!_glfwLibrary.X11.FS.modeChanged) { - _glfwWin.FS.oldSizeID = XRRConfigCurrentConfiguration(sc, &_glfwWin.FS.oldRotation); - _glfwWin.FS.oldWidth = DisplayWidth(_glfwLibrary.display, screen); - _glfwWin.FS.oldHeight = DisplayHeight(_glfwLibrary.display, screen); + _glfwLibrary.X11.FS.oldSizeID = XRRConfigCurrentConfiguration(sc, &_glfwLibrary.X11.FS.oldRotation); + _glfwLibrary.X11.FS.oldWidth = DisplayWidth(_glfwLibrary.X11.display, screen); + _glfwLibrary.X11.FS.oldHeight = DisplayHeight(_glfwLibrary.X11.display, screen); - _glfwWin.FS.modeChanged = GL_TRUE; + _glfwLibrary.X11.FS.modeChanged = GL_TRUE; } if (rate > 0) { // Set desired configuration - XRRSetScreenConfigAndRate(_glfwLibrary.display, + XRRSetScreenConfigAndRate(_glfwLibrary.X11.display, sc, root, mode, @@ -220,7 +220,7 @@ void _glfwSetVideoModeMODE(int screen, int mode, int rate) else { // Set desired configuration - XRRSetScreenConfig(_glfwLibrary.display, + XRRSetScreenConfig(_glfwLibrary.X11.display, sc, root, mode, @@ -235,31 +235,31 @@ void _glfwSetVideoModeMODE(int screen, int mode, int rate) int modecount; // Use the XF86VidMode extension to control video resolution - if (_glfwLibrary.XF86VidMode.available) + if (_glfwLibrary.X11.XF86VidMode.available) { // Get a list of all available display modes - XF86VidModeGetAllModeLines(_glfwLibrary.display, screen, + XF86VidModeGetAllModeLines(_glfwLibrary.X11.display, screen, &modecount, &modelist); // Unlock mode switch if necessary - if (_glfwWin.FS.modeChanged) - XF86VidModeLockModeSwitch(_glfwLibrary.display, screen, 0); + if (_glfwLibrary.X11.FS.modeChanged) + XF86VidModeLockModeSwitch(_glfwLibrary.X11.display, screen, 0); // Change the video mode to the desired mode - XF86VidModeSwitchToMode(_glfwLibrary.display, screen, + XF86VidModeSwitchToMode(_glfwLibrary.X11.display, screen, modelist[mode]); // Set viewport to upper left corner (where our window will be) - XF86VidModeSetViewPort(_glfwLibrary.display, screen, 0, 0); + XF86VidModeSetViewPort(_glfwLibrary.X11.display, screen, 0, 0); // Lock mode switch - XF86VidModeLockModeSwitch(_glfwLibrary.display, screen, 1); + XF86VidModeLockModeSwitch(_glfwLibrary.X11.display, screen, 1); // Remember old mode and flag that we have changed the mode - if (!_glfwWin.FS.modeChanged) + if (!_glfwLibrary.X11.FS.modeChanged) { - _glfwWin.FS.oldMode = *modelist[0]; - _glfwWin.FS.modeChanged = GL_TRUE; + _glfwLibrary.X11.FS.oldMode = *modelist[0]; + _glfwLibrary.X11.FS.modeChanged = GL_TRUE; } // Free mode list @@ -289,42 +289,44 @@ void _glfwSetVideoMode(int screen, int* width, int* height, int* rate) // Restore the previously saved (original) video mode //======================================================================== -void _glfwRestoreVideoMode(void) +void _glfwRestoreVideoMode(int screen) { - if (_glfwWin.FS.modeChanged) + if (_glfwLibrary.X11.FS.modeChanged) { #if defined(_GLFW_HAS_XRANDR) - if (_glfwLibrary.XRandR.available) + Window root = RootWindow(_glfwLibrary.X11.display, screen); + + if (_glfwLibrary.X11.XRandR.available) { XRRScreenConfiguration* sc; - if (_glfwLibrary.XRandR.available) + if (_glfwLibrary.X11.XRandR.available) { - sc = XRRGetScreenInfo(_glfwLibrary.display, _glfwWin.root); + sc = XRRGetScreenInfo(_glfwLibrary.X11.display, root); - XRRSetScreenConfig(_glfwLibrary.display, + XRRSetScreenConfig(_glfwLibrary.X11.display, sc, - _glfwWin.root, - _glfwWin.FS.oldSizeID, - _glfwWin.FS.oldRotation, + root, + _glfwLibrary.X11.FS.oldSizeID, + _glfwLibrary.X11.FS.oldRotation, CurrentTime); XRRFreeScreenConfigInfo(sc); } } #elif defined(_GLFW_HAS_XF86VIDMODE) - if (_glfwLibrary.XF86VidMode.available) + if (_glfwLibrary.X11.XF86VidMode.available) { // Unlock mode switch - XF86VidModeLockModeSwitch(_glfwLibrary.display, _glfwWin.screen, 0); + XF86VidModeLockModeSwitch(_glfwLibrary.X11.display, screen, 0); // Change the video mode back to the old mode - XF86VidModeSwitchToMode(_glfwLibrary.display, - _glfwWin.screen, - &_glfwWin.FS.oldMode); + XF86VidModeSwitchToMode(_glfwLibrary.X11.display, + screen, + &_glfwLibrary.X11.FS.oldMode); } #endif - _glfwWin.FS.modeChanged = GL_FALSE; + _glfwLibrary.X11.FS.modeChanged = GL_FALSE; } } @@ -364,7 +366,7 @@ int _glfwPlatformGetVideoModes(GLFWvidmode* list, int maxcount) #endif // Get display and screen - dpy = _glfwLibrary.display; + dpy = _glfwLibrary.X11.display; screen = DefaultScreen(dpy); // Get list of visuals @@ -410,7 +412,7 @@ int _glfwPlatformGetVideoModes(GLFWvidmode* list, int maxcount) // Build resolution array #if defined(_GLFW_HAS_XRANDR) - if (_glfwLibrary.XRandR.available) + if (_glfwLibrary.X11.XRandR.available) { sc = XRRGetScreenInfo(dpy, RootWindow(dpy, screen)); sizelist = XRRConfigSizes(sc, &sizecount); @@ -505,7 +507,7 @@ void _glfwPlatformGetDesktopMode(GLFWvidmode* mode) #endif // Get display and screen - dpy = _glfwLibrary.display; + dpy = _glfwLibrary.X11.display; screen = DefaultScreen(dpy); // Get display depth @@ -515,23 +517,23 @@ void _glfwPlatformGetDesktopMode(GLFWvidmode* mode) BPP2RGB(bpp, &mode->redBits, &mode->greenBits, &mode->blueBits); #if defined(_GLFW_HAS_XRANDR) - if (_glfwLibrary.XRandR.available) + if (_glfwLibrary.X11.XRandR.available) { - if (_glfwWin.FS.modeChanged) + if (_glfwLibrary.X11.FS.modeChanged) { - mode->width = _glfwWin.FS.oldWidth; - mode->height = _glfwWin.FS.oldHeight; + mode->width = _glfwLibrary.X11.FS.oldWidth; + mode->height = _glfwLibrary.X11.FS.oldHeight; return; } } #elif defined(_GLFW_HAS_XF86VIDMODE) - if (_glfwLibrary.XF86VidMode.available) + if (_glfwLibrary.X11.XF86VidMode.available) { - if (_glfwWin.FS.modeChanged) + if (_glfwLibrary.X11.FS.modeChanged) { // The old (desktop) mode is stored in _glfwWin.FS.oldMode - mode->width = _glfwWin.FS.oldMode.hdisplay; - mode->height = _glfwWin.FS.oldMode.vdisplay; + mode->width = _glfwLibrary.X11.FS.oldMode.hdisplay; + mode->height = _glfwLibrary.X11.FS.oldMode.vdisplay; } else { diff --git a/lib/x11/x11_glext.c b/lib/x11/x11_glext.c index 41064e0f..e5d47a7d 100644 --- a/lib/x11/x11_glext.c +++ b/lib/x11/x11_glext.c @@ -65,8 +65,9 @@ int _glfwPlatformExtensionSupported(const char* extension) const GLubyte* extensions; // Get list of GLX extensions - extensions = (const GLubyte*) glXQueryExtensionsString(_glfwLibrary.display, - _glfwWin.screen); + // Yuck + extensions = (const GLubyte*) glXQueryExtensionsString(_glfwLibrary.X11.display, + _glfwLibrary.window->X11.screen); if (extensions != NULL) { if (_glfwStringInExtensionString(extension, extensions)) diff --git a/lib/x11/x11_init.c b/lib/x11/x11_init.c index 15603965..cf712f42 100644 --- a/lib/x11/x11_init.c +++ b/lib/x11/x11_init.c @@ -82,8 +82,8 @@ static void glfw_atexit(void) static int initDisplay(void) { // Open display - _glfwLibrary.display = XOpenDisplay(0); - if (!_glfwLibrary.display) + _glfwLibrary.X11.display = XOpenDisplay(0); + if (!_glfwLibrary.X11.display) { fprintf(stderr, "Failed to open X display\n"); return GL_FALSE; @@ -91,36 +91,36 @@ static int initDisplay(void) // Check for XF86VidMode extension #ifdef _GLFW_HAS_XF86VIDMODE - _glfwLibrary.XF86VidMode.available = - XF86VidModeQueryExtension(_glfwLibrary.display, - &_glfwLibrary.XF86VidMode.eventBase, - &_glfwLibrary.XF86VidMode.errorBase); + _glfwLibrary.X11.XF86VidMode.available = + XF86VidModeQueryExtension(_glfwLibrary.X11.display, + &_glfwLibrary.X11.XF86VidMode.eventBase, + &_glfwLibrary.X11.XF86VidMode.errorBase); #else - _glfwLibrary.XF86VidMode.available = 0; + _glfwLibrary.X11.XF86VidMode.available = 0; #endif // Check for XRandR extension #ifdef _GLFW_HAS_XRANDR - _glfwLibrary.XRandR.available = - XRRQueryExtension(_glfwLibrary.display, - &_glfwLibrary.XRandR.eventBase, - &_glfwLibrary.XRandR.errorBase); + _glfwLibrary.X11.XRandR.available = + XRRQueryExtension(_glfwLibrary.X11.display, + &_glfwLibrary.X11.XRandR.eventBase, + &_glfwLibrary.X11.XRandR.errorBase); #else - _glfwLibrary.XRandR.available = 0; + _glfwLibrary.X11.XRandR.available = 0; #endif // Fullscreen & screen saver settings // Check if GLX is supported on this display - if (!glXQueryExtension(_glfwLibrary.display, NULL, NULL)) + if (!glXQueryExtension(_glfwLibrary.X11.display, NULL, NULL)) { fprintf(stderr, "GLX not supported\n"); return GL_FALSE; } // Retrieve GLX version - if (!glXQueryVersion(_glfwLibrary.display, - &_glfwLibrary.glxMajor, - &_glfwLibrary.glxMinor)) + if (!glXQueryVersion(_glfwLibrary.X11.display, + &_glfwLibrary.X11.glxMajor, + &_glfwLibrary.X11.glxMinor)) { fprintf(stderr, "Unable to query GLX version\n"); return GL_FALSE; @@ -137,10 +137,10 @@ static int initDisplay(void) static void terminateDisplay(void) { // Open display - if (_glfwLibrary.display) + if (_glfwLibrary.X11.display) { - XCloseDisplay(_glfwLibrary.display); - _glfwLibrary.display = NULL; + XCloseDisplay(_glfwLibrary.X11.display); + _glfwLibrary.X11.display = NULL; } } @@ -180,8 +180,8 @@ int _glfwPlatformInit(void) int _glfwPlatformTerminate(void) { - // Close OpenGL window - glfwCloseWindow(); + if (_glfwLibrary.window) + glfwCloseWindow(_glfwLibrary.window); // Terminate display terminateDisplay(); diff --git a/lib/x11/x11_time.c b/lib/x11/x11_time.c index 744881b5..f779326d 100644 --- a/lib/x11/x11_time.c +++ b/lib/x11/x11_time.c @@ -40,12 +40,12 @@ void _glfwInitTimer(void) struct timeval tv; // "Resolution" is 1 us - _glfwLibrary.Timer.resolution = 1e-6; + _glfwLibrary.X11.Timer.resolution = 1e-6; // Set start-time for timer gettimeofday(&tv, NULL); - _glfwLibrary.Timer.t0 = (long long) tv.tv_sec * (long long) 1000000 + - (long long) tv.tv_usec; + _glfwLibrary.X11.Timer.t0 = (long long) tv.tv_sec * (long long) 1000000 + + (long long) tv.tv_usec; } @@ -66,7 +66,7 @@ double _glfwPlatformGetTime(void) t = (long long) tv.tv_sec * (long long) 1000000 + (long long) tv.tv_usec; - return (double)(t - _glfwLibrary.Timer.t0) * _glfwLibrary.Timer.resolution; + return (double)(t - _glfwLibrary.X11.Timer.t0) * _glfwLibrary.X11.Timer.resolution; } @@ -84,6 +84,6 @@ void _glfwPlatformSetTime(double t) (long long) tv.tv_usec; // Calulate new starting time - _glfwLibrary.Timer.t0 = t0 - (long long)(t / _glfwLibrary.Timer.resolution); + _glfwLibrary.X11.Timer.t0 = t0 - (long long)(t / _glfwLibrary.X11.Timer.resolution); } diff --git a/lib/x11/x11_window.c b/lib/x11/x11_window.c index 7a12edce..35d1fc44 100644 --- a/lib/x11/x11_window.c +++ b/lib/x11/x11_window.c @@ -78,7 +78,7 @@ static unsigned long getWindowProperty(Window window, int actualFormat; unsigned long itemCount, bytesAfter; - XGetWindowProperty(_glfwLibrary.display, + XGetWindowProperty(_glfwLibrary.X11.display, window, property, 0, @@ -106,7 +106,7 @@ static Atom getSupportedAtom(Atom* supportedAtoms, unsigned long atomCount, const char* atomName) { - Atom atom = XInternAtom(_glfwLibrary.display, atomName, True); + Atom atom = XInternAtom(_glfwLibrary.X11.display, atomName, True); if (atom != None) { unsigned long i; @@ -126,7 +126,7 @@ static Atom getSupportedAtom(Atom* supportedAtoms, // Check whether the running window manager is EWMH-compliant //======================================================================== -static GLboolean checkForEWMH(void) +static GLboolean checkForEWMH(_GLFWwindow* window) { Window* windowFromRoot = NULL; Window* windowFromChild = NULL; @@ -134,17 +134,17 @@ static GLboolean checkForEWMH(void) // Hey kids; let's see if the window manager supports EWMH! // First we need a couple of atoms, which should already be there - Atom supportingWmCheck = XInternAtom(_glfwLibrary.display, + Atom supportingWmCheck = XInternAtom(_glfwLibrary.X11.display, "_NET_SUPPORTING_WM_CHECK", True); - Atom wmSupported = XInternAtom(_glfwLibrary.display, + Atom wmSupported = XInternAtom(_glfwLibrary.X11.display, "_NET_SUPPORTED", True); if (supportingWmCheck == None || wmSupported == None) return GL_FALSE; // Then we look for the _NET_SUPPORTING_WM_CHECK property of the root window - if (getWindowProperty(_glfwWin.root, + if (getWindowProperty(window->X11.root, supportingWmCheck, XA_WINDOW, (unsigned char**) &windowFromRoot) != 1) @@ -182,28 +182,28 @@ static GLboolean checkForEWMH(void) unsigned long atomCount; // Now we need to check the _NET_SUPPORTED property of the root window - atomCount = getWindowProperty(_glfwWin.root, + atomCount = getWindowProperty(window->X11.root, wmSupported, XA_ATOM, (unsigned char**) &supportedAtoms); // See which of the atoms we support that are supported by the WM - _glfwWin.wmState = getSupportedAtom(supportedAtoms, - atomCount, - "_NET_WM_STATE"); + window->X11.wmState = getSupportedAtom(supportedAtoms, + atomCount, + "_NET_WM_STATE"); - _glfwWin.wmStateFullscreen = getSupportedAtom(supportedAtoms, + window->X11.wmStateFullscreen = getSupportedAtom(supportedAtoms, + atomCount, + "_NET_WM_STATE_FULLSCREEN"); + + window->X11.wmPing = getSupportedAtom(supportedAtoms, + atomCount, + "_NET_WM_PING"); + + window->X11.wmActiveWindow = getSupportedAtom(supportedAtoms, atomCount, - "_NET_WM_STATE_FULLSCREEN"); - - _glfwWin.wmPing = getSupportedAtom(supportedAtoms, - atomCount, - "_NET_WM_PING"); - - _glfwWin.wmActiveWindow = getSupportedAtom(supportedAtoms, - atomCount, - "_NET_ACTIVE_WINDOW"); + "_NET_ACTIVE_WINDOW"); XFree(supportedAtoms); @@ -221,7 +221,7 @@ static int translateKey(int keycode) // Try secondary keysym, for numeric keypad keys // Note: This way we always force "NumLock = ON", which at least // enables GLFW users to detect numeric keypad keys - key = XKeycodeToKeysym(_glfwLibrary.display, keycode, 1); + key = XKeycodeToKeysym(_glfwLibrary.X11.display, keycode, 1); switch (key) { // Numeric keypad @@ -243,7 +243,7 @@ static int translateKey(int keycode) } // Now try pimary keysym - key = XKeycodeToKeysym(_glfwLibrary.display, keycode, 0); + key = XKeycodeToKeysym(_glfwLibrary.X11.display, keycode, 0); switch (key) { // Special keys (non character keys) @@ -386,17 +386,17 @@ static Cursor createNULLCursor(Display* display, Window root) // NOTE: Do not call this unless we have found GLX 1.3+ or GLX_SGIX_fbconfig //======================================================================== -static int getFBConfigAttrib(GLXFBConfig fbconfig, int attrib) +static int getFBConfigAttrib(_GLFWwindow* window, GLXFBConfig fbconfig, int attrib) { int value; - if (_glfwWin.has_GLX_SGIX_fbconfig) + if (window->X11.has_GLX_SGIX_fbconfig) { - _glfwWin.GetFBConfigAttribSGIX(_glfwLibrary.display, - fbconfig, attrib, &value); + window->X11.GetFBConfigAttribSGIX(_glfwLibrary.X11.display, + fbconfig, attrib, &value); } else - glXGetFBConfigAttrib(_glfwLibrary.display, fbconfig, attrib, &value); + glXGetFBConfigAttrib(_glfwLibrary.X11.display, fbconfig, attrib, &value); return value; } @@ -406,7 +406,7 @@ static int getFBConfigAttrib(GLXFBConfig fbconfig, int attrib) // Return a list of available and usable framebuffer configs //======================================================================== -static _GLFWfbconfig* getFBConfigs(unsigned int* found) +static _GLFWfbconfig* getFBConfigs(_GLFWwindow* window, unsigned int* found) { GLXFBConfig* fbconfigs; _GLFWfbconfig* result; @@ -414,21 +414,21 @@ static _GLFWfbconfig* getFBConfigs(unsigned int* found) *found = 0; - if (_glfwLibrary.glxMajor == 1 && _glfwLibrary.glxMinor < 3) + if (_glfwLibrary.X11.glxMajor == 1 && _glfwLibrary.X11.glxMinor < 3) { - if (!_glfwWin.has_GLX_SGIX_fbconfig) + if (!window->X11.has_GLX_SGIX_fbconfig) { fprintf(stderr, "GLXFBConfigs are not supported by the X server\n"); return NULL; } } - if (_glfwWin.has_GLX_SGIX_fbconfig) + if (window->X11.has_GLX_SGIX_fbconfig) { - fbconfigs = _glfwWin.ChooseFBConfigSGIX(_glfwLibrary.display, - _glfwWin.screen, - NULL, - &count); + fbconfigs = window->X11.ChooseFBConfigSGIX(_glfwLibrary.X11.display, + window->X11.screen, + NULL, + &count); if (!count) { fprintf(stderr, "No GLXFBConfigs returned\n"); @@ -437,7 +437,7 @@ static _GLFWfbconfig* getFBConfigs(unsigned int* found) } else { - fbconfigs = glXGetFBConfigs(_glfwLibrary.display, _glfwWin.screen, &count); + fbconfigs = glXGetFBConfigs(_glfwLibrary.X11.display, window->X11.screen, &count); if (!count) { fprintf(stderr, "No GLXFBConfigs returned\n"); @@ -454,47 +454,47 @@ static _GLFWfbconfig* getFBConfigs(unsigned int* found) for (i = 0; i < count; i++) { - if (!getFBConfigAttrib(fbconfigs[i], GLX_DOUBLEBUFFER) || - !getFBConfigAttrib(fbconfigs[i], GLX_VISUAL_ID)) + if (!getFBConfigAttrib(window, fbconfigs[i], GLX_DOUBLEBUFFER) || + !getFBConfigAttrib(window, fbconfigs[i], GLX_VISUAL_ID)) { // Only consider double-buffered GLXFBConfigs with associated visuals continue; } - if (!(getFBConfigAttrib(fbconfigs[i], GLX_RENDER_TYPE) & GLX_RGBA_BIT)) + if (!(getFBConfigAttrib(window, fbconfigs[i], GLX_RENDER_TYPE) & GLX_RGBA_BIT)) { // Only consider RGBA GLXFBConfigs continue; } - if (!(getFBConfigAttrib(fbconfigs[i], GLX_DRAWABLE_TYPE) & GLX_WINDOW_BIT)) + if (!(getFBConfigAttrib(window, fbconfigs[i], GLX_DRAWABLE_TYPE) & GLX_WINDOW_BIT)) { // Only consider window GLXFBConfigs continue; } - result[*found].redBits = getFBConfigAttrib(fbconfigs[i], GLX_RED_SIZE); - result[*found].greenBits = getFBConfigAttrib(fbconfigs[i], GLX_GREEN_SIZE); - result[*found].blueBits = getFBConfigAttrib(fbconfigs[i], GLX_BLUE_SIZE); + result[*found].redBits = getFBConfigAttrib(window, fbconfigs[i], GLX_RED_SIZE); + result[*found].greenBits = getFBConfigAttrib(window, fbconfigs[i], GLX_GREEN_SIZE); + result[*found].blueBits = getFBConfigAttrib(window, fbconfigs[i], GLX_BLUE_SIZE); - result[*found].alphaBits = getFBConfigAttrib(fbconfigs[i], GLX_ALPHA_SIZE); - result[*found].depthBits = getFBConfigAttrib(fbconfigs[i], GLX_DEPTH_SIZE); - result[*found].stencilBits = getFBConfigAttrib(fbconfigs[i], GLX_STENCIL_SIZE); + result[*found].alphaBits = getFBConfigAttrib(window, fbconfigs[i], GLX_ALPHA_SIZE); + result[*found].depthBits = getFBConfigAttrib(window, fbconfigs[i], GLX_DEPTH_SIZE); + result[*found].stencilBits = getFBConfigAttrib(window, fbconfigs[i], GLX_STENCIL_SIZE); - result[*found].accumRedBits = getFBConfigAttrib(fbconfigs[i], GLX_ACCUM_RED_SIZE); - result[*found].accumGreenBits = getFBConfigAttrib(fbconfigs[i], GLX_ACCUM_GREEN_SIZE); - result[*found].accumBlueBits = getFBConfigAttrib(fbconfigs[i], GLX_ACCUM_BLUE_SIZE); - result[*found].accumAlphaBits = getFBConfigAttrib(fbconfigs[i], GLX_ACCUM_ALPHA_SIZE); + result[*found].accumRedBits = getFBConfigAttrib(window, fbconfigs[i], GLX_ACCUM_RED_SIZE); + result[*found].accumGreenBits = getFBConfigAttrib(window, fbconfigs[i], GLX_ACCUM_GREEN_SIZE); + result[*found].accumBlueBits = getFBConfigAttrib(window, fbconfigs[i], GLX_ACCUM_BLUE_SIZE); + result[*found].accumAlphaBits = getFBConfigAttrib(window, fbconfigs[i], GLX_ACCUM_ALPHA_SIZE); - result[*found].auxBuffers = getFBConfigAttrib(fbconfigs[i], GLX_AUX_BUFFERS); - result[*found].stereo = getFBConfigAttrib(fbconfigs[i], GLX_STEREO); + result[*found].auxBuffers = getFBConfigAttrib(window, fbconfigs[i], GLX_AUX_BUFFERS); + result[*found].stereo = getFBConfigAttrib(window, fbconfigs[i], GLX_STEREO); - if (_glfwWin.has_GLX_ARB_multisample) - result[*found].samples = getFBConfigAttrib(fbconfigs[i], GLX_SAMPLES); + if (window->X11.has_GLX_ARB_multisample) + result[*found].samples = getFBConfigAttrib(window, fbconfigs[i], GLX_SAMPLES); else result[*found].samples = 0; - result[*found].platformID = (GLFWintptr) getFBConfigAttrib(fbconfigs[i], GLX_FBCONFIG_ID); + result[*found].platformID = (GLFWintptr) getFBConfigAttrib(window, fbconfigs[i], GLX_FBCONFIG_ID); (*found)++; } @@ -513,7 +513,7 @@ static _GLFWfbconfig* getFBConfigs(unsigned int* found) attribs[index++] = attribName; \ attribs[index++] = attribValue; -static int createContext(const _GLFWwndconfig* wndconfig, GLXFBConfigID fbconfigID) +static int createContext(_GLFWwindow* window, const _GLFWwndconfig* wndconfig, GLXFBConfigID fbconfigID) { int attribs[40]; int flags, dummy, index; @@ -526,17 +526,17 @@ static int createContext(const _GLFWwndconfig* wndconfig, GLXFBConfigID fbconfig setGLXattrib(attribs, index, GLX_FBCONFIG_ID, (int) fbconfigID); setGLXattrib(attribs, index, None, None); - if (_glfwWin.has_GLX_SGIX_fbconfig) + if (window->X11.has_GLX_SGIX_fbconfig) { - fbconfig = _glfwWin.ChooseFBConfigSGIX(_glfwLibrary.display, - _glfwWin.screen, + fbconfig = window->X11.ChooseFBConfigSGIX(_glfwLibrary.X11.display, + window->X11.screen, attribs, &dummy); } else { - fbconfig = glXChooseFBConfig(_glfwLibrary.display, - _glfwWin.screen, + fbconfig = glXChooseFBConfig(_glfwLibrary.X11.display, + window->X11.screen, attribs, &dummy); } @@ -549,18 +549,18 @@ static int createContext(const _GLFWwndconfig* wndconfig, GLXFBConfigID fbconfig } // Retrieve the corresponding visual - if (_glfwWin.has_GLX_SGIX_fbconfig) + if (window->X11.has_GLX_SGIX_fbconfig) { - _glfwWin.visual = _glfwWin.GetVisualFromFBConfigSGIX(_glfwLibrary.display, - *fbconfig); + window->X11.visual = window->X11.GetVisualFromFBConfigSGIX(_glfwLibrary.X11.display, + *fbconfig); } else { - _glfwWin.visual = glXGetVisualFromFBConfig(_glfwLibrary.display, - *fbconfig); + window->X11.visual = glXGetVisualFromFBConfig(_glfwLibrary.X11.display, + *fbconfig); } - if (_glfwWin.visual == NULL) + if (window->X11.visual == NULL) { XFree(fbconfig); @@ -568,7 +568,7 @@ static int createContext(const _GLFWwndconfig* wndconfig, GLXFBConfigID fbconfig return GL_FALSE; } - if (_glfwWin.has_GLX_ARB_create_context) + if (window->X11.has_GLX_ARB_create_context) { index = 0; @@ -595,7 +595,7 @@ static int createContext(const _GLFWwndconfig* wndconfig, GLXFBConfigID fbconfig if (wndconfig->glProfile) { - if (!_glfwWin.has_GLX_ARB_create_context_profile) + if (!window->X11.has_GLX_ARB_create_context_profile) { fprintf(stderr, "OpenGL profile requested but GLX_ARB_create_context_profile " "is unavailable\n"); @@ -612,41 +612,41 @@ static int createContext(const _GLFWwndconfig* wndconfig, GLXFBConfigID fbconfig setGLXattrib(attribs, index, None, None); - _glfwWin.context = _glfwWin.CreateContextAttribsARB(_glfwLibrary.display, - *fbconfig, - NULL, - True, - attribs); + window->X11.context = window->X11.CreateContextAttribsARB(_glfwLibrary.X11.display, + *fbconfig, + NULL, + True, + attribs); } else { - if (_glfwWin.has_GLX_SGIX_fbconfig) + if (window->X11.has_GLX_SGIX_fbconfig) { - _glfwWin.context = _glfwWin.CreateContextWithConfigSGIX(_glfwLibrary.display, - *fbconfig, - GLX_RGBA_TYPE, - NULL, - True); + window->X11.context = window->X11.CreateContextWithConfigSGIX(_glfwLibrary.X11.display, + *fbconfig, + GLX_RGBA_TYPE, + NULL, + True); } else { - _glfwWin.context = glXCreateNewContext(_glfwLibrary.display, - *fbconfig, - GLX_RGBA_TYPE, - NULL, - True); + window->X11.context = glXCreateNewContext(_glfwLibrary.X11.display, + *fbconfig, + GLX_RGBA_TYPE, + NULL, + True); } } XFree(fbconfig); - if (_glfwWin.context == NULL) + if (window->X11.context == NULL) { fprintf(stderr, "Unable to create OpenGL context\n"); return GL_FALSE; } - _glfwWin.fbconfigID = fbconfigID; + window->X11.fbconfigID = fbconfigID; return GL_TRUE; } @@ -658,66 +658,51 @@ static int createContext(const _GLFWwndconfig* wndconfig, GLXFBConfigID fbconfig // Initialize GLX-specific extensions //======================================================================== -static void initGLXExtensions(void) +static void initGLXExtensions(_GLFWwindow* window) { - // This needs to include every function pointer loaded below - _glfwWin.SwapIntervalSGI = NULL; - _glfwWin.GetFBConfigAttribSGIX = NULL; - _glfwWin.ChooseFBConfigSGIX = NULL; - _glfwWin.CreateContextWithConfigSGIX = NULL; - _glfwWin.GetVisualFromFBConfigSGIX = NULL; - _glfwWin.CreateContextAttribsARB = NULL; - - // This needs to include every extension used below - _glfwWin.has_GLX_SGIX_fbconfig = GL_FALSE; - _glfwWin.has_GLX_SGI_swap_control = GL_FALSE; - _glfwWin.has_GLX_ARB_multisample = GL_FALSE; - _glfwWin.has_GLX_ARB_create_context = GL_FALSE; - _glfwWin.has_GLX_ARB_create_context_profile = GL_FALSE; - if (_glfwPlatformExtensionSupported("GLX_SGI_swap_control")) { - _glfwWin.SwapIntervalSGI = (PFNGLXSWAPINTERVALSGIPROC) + window->X11.SwapIntervalSGI = (PFNGLXSWAPINTERVALSGIPROC) _glfwPlatformGetProcAddress("glXSwapIntervalSGI"); - if (_glfwWin.SwapIntervalSGI) - _glfwWin.has_GLX_SGI_swap_control = GL_TRUE; + if (window->X11.SwapIntervalSGI) + window->X11.has_GLX_SGI_swap_control = GL_TRUE; } if (_glfwPlatformExtensionSupported("GLX_SGIX_fbconfig")) { - _glfwWin.GetFBConfigAttribSGIX = (PFNGLXGETFBCONFIGATTRIBSGIXPROC) + window->X11.GetFBConfigAttribSGIX = (PFNGLXGETFBCONFIGATTRIBSGIXPROC) _glfwPlatformGetProcAddress("glXGetFBConfigAttribSGIX"); - _glfwWin.ChooseFBConfigSGIX = (PFNGLXCHOOSEFBCONFIGSGIXPROC) + window->X11.ChooseFBConfigSGIX = (PFNGLXCHOOSEFBCONFIGSGIXPROC) _glfwPlatformGetProcAddress("glXChooseFBConfigSGIX"); - _glfwWin.CreateContextWithConfigSGIX = (PFNGLXCREATECONTEXTWITHCONFIGSGIXPROC) + window->X11.CreateContextWithConfigSGIX = (PFNGLXCREATECONTEXTWITHCONFIGSGIXPROC) _glfwPlatformGetProcAddress("glXCreateContextWithConfigSGIX"); - _glfwWin.GetVisualFromFBConfigSGIX = (PFNGLXGETVISUALFROMFBCONFIGSGIXPROC) + window->X11.GetVisualFromFBConfigSGIX = (PFNGLXGETVISUALFROMFBCONFIGSGIXPROC) _glfwPlatformGetProcAddress("glXGetVisualFromFBConfigSGIX"); - if (_glfwWin.GetFBConfigAttribSGIX && - _glfwWin.ChooseFBConfigSGIX && - _glfwWin.CreateContextWithConfigSGIX && - _glfwWin.GetVisualFromFBConfigSGIX) + if (window->X11.GetFBConfigAttribSGIX && + window->X11.ChooseFBConfigSGIX && + window->X11.CreateContextWithConfigSGIX && + window->X11.GetVisualFromFBConfigSGIX) { - _glfwWin.has_GLX_SGIX_fbconfig = GL_TRUE; + window->X11.has_GLX_SGIX_fbconfig = GL_TRUE; } } if (_glfwPlatformExtensionSupported("GLX_ARB_multisample")) - _glfwWin.has_GLX_ARB_multisample = GL_TRUE; + window->X11.has_GLX_ARB_multisample = GL_TRUE; if (_glfwPlatformExtensionSupported("GLX_ARB_create_context")) { - _glfwWin.CreateContextAttribsARB = (PFNGLXCREATECONTEXTATTRIBSARBPROC) + window->X11.CreateContextAttribsARB = (PFNGLXCREATECONTEXTATTRIBSARBPROC) _glfwPlatformGetProcAddress("glXCreateContextAttribsARB"); - if (_glfwWin.CreateContextAttribsARB) - _glfwWin.has_GLX_ARB_create_context = GL_TRUE; + if (window->X11.CreateContextAttribsARB) + window->X11.has_GLX_ARB_create_context = GL_TRUE; } if (_glfwPlatformExtensionSupported("GLX_ARB_create_context_profile")) - _glfwWin.has_GLX_ARB_create_context_profile = GL_TRUE; + window->X11.has_GLX_ARB_create_context_profile = GL_TRUE; } @@ -725,7 +710,8 @@ static void initGLXExtensions(void) // Create the X11 window (and its colormap) //======================================================================== -static GLboolean createWindow(int width, int height, +static GLboolean createWindow(_GLFWwindow* window, + int width, int height, const _GLFWwndconfig* wndconfig) { XEvent event; @@ -735,16 +721,16 @@ static GLboolean createWindow(int width, int height, // Every window needs a colormap // Create one based on the visual used by the current context - _glfwWin.colormap = XCreateColormap(_glfwLibrary.display, - _glfwWin.root, - _glfwWin.visual->visual, + window->X11.colormap = XCreateColormap(_glfwLibrary.X11.display, + window->X11.root, + window->X11.visual->visual, AllocNone); // Create the actual window { wamask = CWBorderPixel | CWColormap | CWEventMask; - wa.colormap = _glfwWin.colormap; + wa.colormap = window->X11.colormap; wa.border_pixel = 0; wa.event_mask = StructureNotifyMask | KeyPressMask | KeyReleaseMask | PointerMotionMask | ButtonPressMask | ButtonReleaseMask | @@ -755,34 +741,31 @@ static GLboolean createWindow(int width, int height, // The /only/ reason we are setting the background pixel here is // that otherwise our window wont get any decorations on systems // using Compiz on Intel hardware - wa.background_pixel = BlackPixel(_glfwLibrary.display, _glfwWin.screen); + wa.background_pixel = BlackPixel(_glfwLibrary.X11.display, window->X11.screen); wamask |= CWBackPixel; } - _glfwWin.window = XCreateWindow( - _glfwLibrary.display, - _glfwWin.root, + window->X11.window = XCreateWindow( + _glfwLibrary.X11.display, + window->X11.root, 0, 0, // Upper left corner of this window on root - _glfwWin.width, _glfwWin.height, + window->width, window->height, 0, // Border width - _glfwWin.visual->depth, // Color depth + window->X11.visual->depth, // Color depth InputOutput, - _glfwWin.visual->visual, + window->X11.visual->visual, wamask, &wa ); - if (!_glfwWin.window) - { - _glfwPlatformCloseWindow(); + if (!window->X11.window) return GL_FALSE; - } } // Check whether an EWMH-compliant window manager is running - _glfwWin.hasEWMH = checkForEWMH(); + window->X11.hasEWMH = checkForEWMH(window); - if (_glfwWin.fullscreen && !_glfwWin.hasEWMH) + if (window->mode == GLFW_FULLSCREEN && !window->X11.hasEWMH) { // This is the butcher's way of removing window decorations // Setting the override-redirect attribute on a window makes the window @@ -794,16 +777,16 @@ static GLboolean createWindow(int width, int height, XSetWindowAttributes attributes; attributes.override_redirect = True; - XChangeWindowAttributes(_glfwLibrary.display, - _glfwWin.window, + XChangeWindowAttributes(_glfwLibrary.X11.display, + window->X11.window, CWOverrideRedirect, &attributes); - _glfwWin.overrideRedirect = GL_TRUE; + window->X11.overrideRedirect = GL_TRUE; } // Find or create the protocol atom for window close notifications - _glfwWin.wmDeleteWindow = XInternAtom(_glfwLibrary.display, + window->X11.wmDeleteWindow = XInternAtom(_glfwLibrary.X11.display, "WM_DELETE_WINDOW", False); @@ -814,18 +797,18 @@ static GLboolean createWindow(int width, int height, // The WM_DELETE_WINDOW ICCCM protocol // Basic window close notification protocol - if (_glfwWin.wmDeleteWindow != None) - protocols[count++] = _glfwWin.wmDeleteWindow; + if (window->X11.wmDeleteWindow != None) + protocols[count++] = window->X11.wmDeleteWindow; // The _NET_WM_PING EWMH protocol // Tells the WM to ping our window and flag us as unresponsive if we // don't reply within a few seconds - if (_glfwWin.wmPing != None) - protocols[count++] = _glfwWin.wmPing; + if (window->X11.wmPing != None) + protocols[count++] = window->X11.wmPing; if (count > 0) { - XSetWMProtocols(_glfwLibrary.display, _glfwWin.window, + XSetWMProtocols(_glfwLibrary.X11.display, window->X11.window, protocols, count); } } @@ -834,15 +817,12 @@ static GLboolean createWindow(int width, int height, { XWMHints* hints = XAllocWMHints(); if (!hints) - { - _glfwPlatformCloseWindow(); return GL_FALSE; - } hints->flags = StateHint; hints->initial_state = NormalState; - XSetWMHints(_glfwLibrary.display, _glfwWin.window, hints); + XSetWMHints(_glfwLibrary.X11.display, window->X11.window, hints); XFree(hints); } @@ -850,30 +830,27 @@ static GLboolean createWindow(int width, int height, { XSizeHints* hints = XAllocSizeHints(); if (!hints) - { - _glfwPlatformCloseWindow(); return GL_FALSE; - } hints->flags = 0; if (wndconfig->windowNoResize) { hints->flags |= (PMinSize | PMaxSize); - hints->min_width = hints->max_width = _glfwWin.width; - hints->min_height = hints->max_height = _glfwWin.height; + hints->min_width = hints->max_width = window->width; + hints->min_height = hints->max_height = window->height; } - XSetWMNormalHints(_glfwLibrary.display, _glfwWin.window, hints); + XSetWMNormalHints(_glfwLibrary.X11.display, window->X11.window, hints); XFree(hints); } - _glfwPlatformSetWindowTitle("GLFW Window"); + _glfwPlatformSetWindowTitle(window, "GLFW Window"); // Make sure the window is mapped before proceeding - XMapWindow(_glfwLibrary.display, _glfwWin.window); - XPeekIfEvent(_glfwLibrary.display, &event, isMapNotify, - (char*) _glfwWin.window); + XMapWindow(_glfwLibrary.X11.display, window->X11.window); + XPeekIfEvent(_glfwLibrary.X11.display, &event, isMapNotify, + (char*) window->X11.window); return GL_TRUE; } @@ -883,31 +860,31 @@ static GLboolean createWindow(int width, int height, // Enter fullscreen mode //======================================================================== -static void enterFullscreenMode(void) +static void enterFullscreenMode(_GLFWwindow* window) { - if (!_glfwWin.Saver.changed) + if (!_glfwLibrary.X11.Saver.changed) { // Remember old screen saver settings - XGetScreenSaver(_glfwLibrary.display, - &_glfwWin.Saver.timeout, &_glfwWin.Saver.interval, - &_glfwWin.Saver.blanking, &_glfwWin.Saver.exposure); + XGetScreenSaver(_glfwLibrary.X11.display, + &_glfwLibrary.X11.Saver.timeout, &_glfwLibrary.X11.Saver.interval, + &_glfwLibrary.X11.Saver.blanking, &_glfwLibrary.X11.Saver.exposure); // Disable screen saver - XSetScreenSaver(_glfwLibrary.display, 0, 0, DontPreferBlanking, + XSetScreenSaver(_glfwLibrary.X11.display, 0, 0, DontPreferBlanking, DefaultExposures); - _glfwWin.Saver.changed = GL_TRUE; + _glfwLibrary.X11.Saver.changed = GL_TRUE; } - _glfwSetVideoMode(_glfwWin.screen, - &_glfwWin.width, &_glfwWin.height, - &_glfwWin.refreshRate); + _glfwSetVideoMode(window->X11.screen, + &window->width, &window->height, + &window->refreshRate); - if (_glfwWin.hasEWMH && - _glfwWin.wmState != None && - _glfwWin.wmStateFullscreen != None) + if (window->X11.hasEWMH && + window->X11.wmState != None && + window->X11.wmStateFullscreen != None) { - if (_glfwWin.wmActiveWindow != None) + if (window->X11.wmActiveWindow != None) { // Ask the window manager to raise and focus the GLFW window // Only focused windows with the _NET_WM_STATE_FULLSCREEN state end @@ -917,14 +894,14 @@ static void enterFullscreenMode(void) memset(&event, 0, sizeof(event)); event.type = ClientMessage; - event.xclient.window = _glfwWin.window; + event.xclient.window = window->X11.window; event.xclient.format = 32; // Data is 32-bit longs - event.xclient.message_type = _glfwWin.wmActiveWindow; + event.xclient.message_type = window->X11.wmActiveWindow; event.xclient.data.l[0] = 1; // Sender is a normal application event.xclient.data.l[1] = 0; // We don't really know the timestamp - XSendEvent(_glfwLibrary.display, - _glfwWin.root, + XSendEvent(_glfwLibrary.X11.display, + window->X11.root, False, SubstructureNotifyMask | SubstructureRedirectMask, &event); @@ -938,68 +915,68 @@ static void enterFullscreenMode(void) memset(&event, 0, sizeof(event)); event.type = ClientMessage; - event.xclient.window = _glfwWin.window; + event.xclient.window = window->X11.window; event.xclient.format = 32; // Data is 32-bit longs - event.xclient.message_type = _glfwWin.wmState; + event.xclient.message_type = window->X11.wmState; event.xclient.data.l[0] = _NET_WM_STATE_ADD; - event.xclient.data.l[1] = _glfwWin.wmStateFullscreen; + event.xclient.data.l[1] = window->X11.wmStateFullscreen; event.xclient.data.l[2] = 0; // No secondary property event.xclient.data.l[3] = 1; // Sender is a normal application - XSendEvent(_glfwLibrary.display, - _glfwWin.root, + XSendEvent(_glfwLibrary.X11.display, + window->X11.root, False, SubstructureNotifyMask | SubstructureRedirectMask, &event); } - else if (_glfwWin.overrideRedirect) + else if (window->X11.overrideRedirect) { // In override-redirect mode, we have divorced ourselves from the // window manager, so we need to do everything manually - XRaiseWindow(_glfwLibrary.display, _glfwWin.window); - XSetInputFocus(_glfwLibrary.display, _glfwWin.window, + XRaiseWindow(_glfwLibrary.X11.display, window->X11.window); + XSetInputFocus(_glfwLibrary.X11.display, window->X11.window, RevertToParent, CurrentTime); - XMoveWindow(_glfwLibrary.display, _glfwWin.window, 0, 0); - XResizeWindow(_glfwLibrary.display, _glfwWin.window, - _glfwWin.width, _glfwWin.height); + XMoveWindow(_glfwLibrary.X11.display, window->X11.window, 0, 0); + XResizeWindow(_glfwLibrary.X11.display, window->X11.window, + window->width, window->height); } - if (_glfwWin.mouseLock) - _glfwPlatformHideMouseCursor(); + if (_glfwLibrary.cursorLockWindow == window) + _glfwPlatformHideMouseCursor(window); // HACK: Try to get window inside viewport (for virtual displays) by moving // the mouse cursor to the upper left corner (and then to the center) // This hack should be harmless on saner systems as well - XWarpPointer(_glfwLibrary.display, None, _glfwWin.window, 0,0,0,0, 0,0); - XWarpPointer(_glfwLibrary.display, None, _glfwWin.window, 0,0,0,0, - _glfwWin.width / 2, _glfwWin.height / 2); + XWarpPointer(_glfwLibrary.X11.display, None, window->X11.window, 0,0,0,0, 0,0); + XWarpPointer(_glfwLibrary.X11.display, None, window->X11.window, 0,0,0,0, + window->width / 2, window->height / 2); } //======================================================================== // Leave fullscreen mode //======================================================================== -static void leaveFullscreenMode(void) +static void leaveFullscreenMode(_GLFWwindow* window) { - _glfwRestoreVideoMode(); + _glfwRestoreVideoMode(window->X11.screen); // Did we change the screen saver setting? - if (_glfwWin.Saver.changed) + if (_glfwLibrary.X11.Saver.changed) { // Restore old screen saver settings - XSetScreenSaver(_glfwLibrary.display, - _glfwWin.Saver.timeout, - _glfwWin.Saver.interval, - _glfwWin.Saver.blanking, - _glfwWin.Saver.exposure); + XSetScreenSaver(_glfwLibrary.X11.display, + _glfwLibrary.X11.Saver.timeout, + _glfwLibrary.X11.Saver.interval, + _glfwLibrary.X11.Saver.blanking, + _glfwLibrary.X11.Saver.exposure); - _glfwWin.Saver.changed = GL_FALSE; + _glfwLibrary.X11.Saver.changed = GL_FALSE; } - if (_glfwWin.hasEWMH && - _glfwWin.wmState != None && - _glfwWin.wmStateFullscreen != None) + if (window->X11.hasEWMH && + window->X11.wmState != None && + window->X11.wmStateFullscreen != None) { // Ask the window manager to make the GLFW window a normal window // Normal windows usually have frames and other decorations @@ -1008,23 +985,23 @@ static void leaveFullscreenMode(void) memset(&event, 0, sizeof(event)); event.type = ClientMessage; - event.xclient.window = _glfwWin.window; + event.xclient.window = window->X11.window; event.xclient.format = 32; // Data is 32-bit longs - event.xclient.message_type = _glfwWin.wmState; + event.xclient.message_type = window->X11.wmState; event.xclient.data.l[0] = _NET_WM_STATE_REMOVE; - event.xclient.data.l[1] = _glfwWin.wmStateFullscreen; + event.xclient.data.l[1] = window->X11.wmStateFullscreen; event.xclient.data.l[2] = 0; // No secondary property event.xclient.data.l[3] = 1; // Sender is a normal application - XSendEvent(_glfwLibrary.display, - _glfwWin.root, + XSendEvent(_glfwLibrary.X11.display, + window->X11.root, False, SubstructureNotifyMask | SubstructureRedirectMask, &event); } - if (_glfwWin.mouseLock) - _glfwPlatformShowMouseCursor(); + if (_glfwLibrary.cursorLockWindow == window) + _glfwPlatformShowMouseCursor(window); } //======================================================================== @@ -1034,8 +1011,11 @@ static void leaveFullscreenMode(void) static GLboolean processSingleEvent(void) { + // Yuck + _GLFWwindow* window = _glfwLibrary.window; + XEvent event; - XNextEvent(_glfwLibrary.display, &event); + XNextEvent(_glfwLibrary.X11.display, &event); switch (event.type) { @@ -1044,11 +1024,10 @@ static GLboolean processSingleEvent(void) // A keyboard key was pressed // Translate and report key press - _glfwInputKey(translateKey(event.xkey.keycode), GLFW_PRESS); + _glfwInputKey(window, translateKey(event.xkey.keycode), GLFW_PRESS); // Translate and report character input - if (_glfwWin.charCallback) - _glfwInputChar(translateChar(&event.xkey), GLFW_PRESS); + _glfwInputChar(window, translateChar(&event.xkey), GLFW_PRESS); break; } @@ -1061,10 +1040,10 @@ static GLboolean processSingleEvent(void) // will get KeyRelease/KeyPress pairs with similar or identical // time stamps. User selected key repeat filtering is handled in // _glfwInputKey()/_glfwInputChar(). - if (XEventsQueued(_glfwLibrary.display, QueuedAfterReading)) + if (XEventsQueued(_glfwLibrary.X11.display, QueuedAfterReading)) { XEvent nextEvent; - XPeekEvent(_glfwLibrary.display, &nextEvent); + XPeekEvent(_glfwLibrary.X11.display, &nextEvent); if (nextEvent.type == KeyPress && nextEvent.xkey.window == event.xkey.window && @@ -1084,11 +1063,10 @@ static GLboolean processSingleEvent(void) } // Translate and report key release - _glfwInputKey(translateKey(event.xkey.keycode), GLFW_RELEASE); + _glfwInputKey(window, translateKey(event.xkey.keycode), GLFW_RELEASE); // Translate and report character input - if (_glfwWin.charCallback) - _glfwInputChar(translateChar(&event.xkey), GLFW_RELEASE); + _glfwInputChar(window, translateChar(&event.xkey), GLFW_RELEASE); break; } @@ -1098,25 +1076,25 @@ static GLboolean processSingleEvent(void) // A mouse button was pressed or a scrolling event occurred if (event.xbutton.button == Button1) - _glfwInputMouseClick(GLFW_MOUSE_BUTTON_LEFT, GLFW_PRESS); + _glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_LEFT, GLFW_PRESS); else if (event.xbutton.button == Button2) - _glfwInputMouseClick(GLFW_MOUSE_BUTTON_MIDDLE, GLFW_PRESS); + _glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_MIDDLE, GLFW_PRESS); else if (event.xbutton.button == Button3) - _glfwInputMouseClick(GLFW_MOUSE_BUTTON_RIGHT, GLFW_PRESS); + _glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_RIGHT, GLFW_PRESS); // XFree86 3.3.2 and later translates mouse wheel up/down into // mouse button 4 & 5 presses else if (event.xbutton.button == Button4) { - _glfwInput.WheelPos++; // To verify: is this up or down? - if (_glfwWin.mouseWheelCallback) - _glfwWin.mouseWheelCallback(_glfwInput.WheelPos); + window->wheelPos++; // To verify: is this up or down? + if (window->mouseWheelCallback) + window->mouseWheelCallback(window->wheelPos); } else if (event.xbutton.button == Button5) { - _glfwInput.WheelPos--; - if (_glfwWin.mouseWheelCallback) - _glfwWin.mouseWheelCallback(_glfwInput.WheelPos); + window->wheelPos--; + if (window->mouseWheelCallback) + window->mouseWheelCallback(window->wheelPos); } break; } @@ -1127,17 +1105,20 @@ static GLboolean processSingleEvent(void) if (event.xbutton.button == Button1) { - _glfwInputMouseClick(GLFW_MOUSE_BUTTON_LEFT, + _glfwInputMouseClick(window, + GLFW_MOUSE_BUTTON_LEFT, GLFW_RELEASE); } else if (event.xbutton.button == Button2) { - _glfwInputMouseClick(GLFW_MOUSE_BUTTON_MIDDLE, + _glfwInputMouseClick(window, + GLFW_MOUSE_BUTTON_MIDDLE, GLFW_RELEASE); } else if (event.xbutton.button == Button3) { - _glfwInputMouseClick(GLFW_MOUSE_BUTTON_RIGHT, + _glfwInputMouseClick(window, + GLFW_MOUSE_BUTTON_RIGHT, GLFW_RELEASE); } break; @@ -1147,35 +1128,35 @@ static GLboolean processSingleEvent(void) { // The mouse cursor was moved - if (event.xmotion.x != _glfwInput.CursorPosX || - event.xmotion.y != _glfwInput.CursorPosY) + if (event.xmotion.x != window->X11.cursorPosX || + event.xmotion.y != window->X11.cursorPosY) { // The mouse cursor was moved and we didn't do it - if (_glfwWin.mouseLock) + if (_glfwLibrary.cursorLockWindow == window) { - if (_glfwWin.pointerHidden) + if (window->X11.pointerHidden) { - _glfwInput.MousePosX += event.xmotion.x - - _glfwInput.CursorPosX; - _glfwInput.MousePosY += event.xmotion.y - - _glfwInput.CursorPosY; + window->mousePosX += event.xmotion.x - + window->X11.cursorPosX; + window->mousePosY += event.xmotion.y - + window->X11.cursorPosY; } } else { - _glfwInput.MousePosX = event.xmotion.x; - _glfwInput.MousePosY = event.xmotion.y; + window->mousePosX = event.xmotion.x; + window->mousePosY = event.xmotion.y; } - _glfwInput.CursorPosX = event.xmotion.x; - _glfwInput.CursorPosY = event.xmotion.y; - _glfwInput.MouseMoved = GL_TRUE; + window->X11.cursorPosX = event.xmotion.x; + window->X11.cursorPosY = event.xmotion.y; + window->X11.mouseMoved = GL_TRUE; - if (_glfwWin.mousePosCallback) + if (window->mousePosCallback) { - _glfwWin.mousePosCallback(_glfwInput.MousePosX, - _glfwInput.MousePosY); + window->mousePosCallback(window->mousePosX, + window->mousePosY); } } break; @@ -1183,17 +1164,17 @@ static GLboolean processSingleEvent(void) case ConfigureNotify: { - if (event.xconfigure.width != _glfwWin.width || - event.xconfigure.height != _glfwWin.height) + if (event.xconfigure.width != window->width || + event.xconfigure.height != window->height) { // The window was resized - _glfwWin.width = event.xconfigure.width; - _glfwWin.height = event.xconfigure.height; - if (_glfwWin.windowSizeCallback) + window->width = event.xconfigure.width; + window->height = event.xconfigure.height; + if (window->windowSizeCallback) { - _glfwWin.windowSizeCallback(_glfwWin.width, - _glfwWin.height); + window->windowSizeCallback(window->width, + window->height); } } break; @@ -1201,21 +1182,21 @@ static GLboolean processSingleEvent(void) case ClientMessage: { - if ((Atom) event.xclient.data.l[ 0 ] == _glfwWin.wmDeleteWindow) + if ((Atom) event.xclient.data.l[ 0 ] == window->X11.wmDeleteWindow) { // The window manager was asked to close the window, for example by // the user pressing a 'close' window decoration button return GL_TRUE; } - else if (_glfwWin.wmPing != None && - (Atom) event.xclient.data.l[ 0 ] == _glfwWin.wmPing) + else if (window->X11.wmPing != None && + (Atom) event.xclient.data.l[ 0 ] == window->X11.wmPing) { // The window manager is pinging us to make sure we are still // responding to events - event.xclient.window = _glfwWin.root; - XSendEvent(_glfwLibrary.display, + event.xclient.window = window->X11.root; + XSendEvent(_glfwLibrary.X11.display, event.xclient.window, False, SubstructureNotifyMask | SubstructureRedirectMask, @@ -1229,7 +1210,7 @@ static GLboolean processSingleEvent(void) { // The window was mapped - _glfwWin.iconified = GL_FALSE; + window->iconified = GL_FALSE; break; } @@ -1237,7 +1218,7 @@ static GLboolean processSingleEvent(void) { // The window was unmapped - _glfwWin.iconified = GL_TRUE; + window->iconified = GL_TRUE; break; } @@ -1245,10 +1226,10 @@ static GLboolean processSingleEvent(void) { // The window gained focus - _glfwWin.active = GL_TRUE; + window->active = GL_TRUE; - if (_glfwWin.mouseLock) - _glfwPlatformHideMouseCursor(); + if (_glfwLibrary.cursorLockWindow == window) + _glfwPlatformHideMouseCursor(window); break; } @@ -1257,11 +1238,11 @@ static GLboolean processSingleEvent(void) { // The window lost focus - _glfwWin.active = GL_FALSE; - _glfwInputDeactivation(); + window->active = GL_FALSE; + _glfwInputDeactivation(window); - if (_glfwWin.mouseLock) - _glfwPlatformShowMouseCursor(); + if (_glfwLibrary.cursorLockWindow == window) + _glfwPlatformShowMouseCursor(window); break; } @@ -1270,8 +1251,8 @@ static GLboolean processSingleEvent(void) { // The window's contents was damaged - if (_glfwWin.windowRefreshCallback) - _glfwWin.windowRefreshCallback(); + if (window->windowRefreshCallback) + window->windowRefreshCallback(); break; } @@ -1283,7 +1264,7 @@ static GLboolean processSingleEvent(void) default: { #if defined(_GLFW_HAS_XRANDR) - switch (event.type - _glfwLibrary.XRandR.eventBase) + switch (event.type - _glfwLibrary.X11.XRandR.eventBase) { case RRScreenChangeNotify: { @@ -1312,41 +1293,25 @@ static GLboolean processSingleEvent(void) // the OpenGL rendering context is created //======================================================================== -int _glfwPlatformOpenWindow(int width, int height, +int _glfwPlatformOpenWindow(_GLFWwindow* window, + int width, int height, const _GLFWwndconfig* wndconfig, const _GLFWfbconfig* fbconfig) { _GLFWfbconfig closest; - // Clear platform specific GLFW window state - _glfwWin.visual = (XVisualInfo*)NULL; - _glfwWin.colormap = (Colormap)0; - _glfwWin.context = (GLXContext)NULL; - _glfwWin.window = (Window)0; - _glfwWin.pointerGrabbed = GL_FALSE; - _glfwWin.pointerHidden = GL_FALSE; - _glfwWin.keyboardGrabbed = GL_FALSE; - _glfwWin.overrideRedirect = GL_FALSE; - _glfwWin.FS.modeChanged = GL_FALSE; - _glfwWin.Saver.changed = GL_FALSE; - _glfwWin.refreshRate = wndconfig->refreshRate; - _glfwWin.windowNoResize = wndconfig->windowNoResize; - - _glfwWin.wmDeleteWindow = None; - _glfwWin.wmPing = None; - _glfwWin.wmState = None; - _glfwWin.wmStateFullscreen = None; - _glfwWin.wmActiveWindow = None; + window->refreshRate = wndconfig->refreshRate; + window->windowNoResize = wndconfig->windowNoResize; // As the 2.x API doesn't understand multiple display devices, we hardcode // this choice and hope for the best - _glfwWin.screen = DefaultScreen(_glfwLibrary.display); - _glfwWin.root = RootWindow(_glfwLibrary.display, _glfwWin.screen); + window->X11.screen = DefaultScreen(_glfwLibrary.X11.display); + window->X11.root = RootWindow(_glfwLibrary.X11.display, window->X11.screen); // Create the invisible cursor for hidden cursor mode - _glfwWin.cursor = createNULLCursor(_glfwLibrary.display, _glfwWin.root); + window->X11.cursor = createNULLCursor(_glfwLibrary.X11.display, window->X11.root); - initGLXExtensions(); + initGLXExtensions(window); // Choose the best available fbconfig { @@ -1354,18 +1319,14 @@ int _glfwPlatformOpenWindow(int width, int height, _GLFWfbconfig* fbconfigs; const _GLFWfbconfig* result; - fbconfigs = getFBConfigs(&fbcount); + fbconfigs = getFBConfigs(window, &fbcount); if (!fbconfigs) - { - _glfwPlatformCloseWindow(); return GL_FALSE; - } result = _glfwChooseFBConfig(fbconfig, fbconfigs, fbcount); if (!result) { free(fbconfigs); - _glfwPlatformCloseWindow(); return GL_FALSE; } @@ -1373,30 +1334,24 @@ int _glfwPlatformOpenWindow(int width, int height, free(fbconfigs); } - if (!createContext(wndconfig, (GLXFBConfigID) closest.platformID)) - { - _glfwPlatformCloseWindow(); + if (!createContext(window, wndconfig, (GLXFBConfigID) closest.platformID)) return GL_FALSE; - } - if (!createWindow(width, height, wndconfig)) - { - _glfwPlatformCloseWindow(); + if (!createWindow(window, width, height, wndconfig)) return GL_FALSE; - } if (wndconfig->mode == GLFW_FULLSCREEN) { #if defined(_GLFW_HAS_XRANDR) // Request screen change notifications - if (_glfwLibrary.XRandR.available) + if (_glfwLibrary.X11.XRandR.available) { - XRRSelectInput(_glfwLibrary.display, - _glfwWin.window, + XRRSelectInput(_glfwLibrary.X11.display, + window->X11.window, RRScreenChangeNotifyMask); } #endif - enterFullscreenMode(); + enterFullscreenMode(window); } // Process the window map event and any other that may have arrived @@ -1404,71 +1359,85 @@ int _glfwPlatformOpenWindow(int width, int height, // Retrieve and set initial cursor position { - Window window, root; + Window cursorWindow, cursorRoot; int windowX, windowY, rootX, rootY; unsigned int mask; - XQueryPointer(_glfwLibrary.display, - _glfwWin.window, - &root, - &window, + XQueryPointer(_glfwLibrary.X11.display, + window->X11.window, + &cursorRoot, + &cursorWindow, &rootX, &rootY, &windowX, &windowY, &mask); // TODO: Probably check for some corner cases here. - _glfwInput.MousePosX = windowX; - _glfwInput.MousePosY = windowY; + window->mousePosX = windowX; + window->mousePosY = windowY; } - // Connect the context to the window - glXMakeCurrent(_glfwLibrary.display, _glfwWin.window, _glfwWin.context); - return GL_TRUE; } +//======================================================================== +// Make the OpenGL context associated with the specified window current +//======================================================================== + +int _glfwPlatformMakeWindowCurrent(_GLFWwindow* window) +{ + if (window) + { + glXMakeCurrent(_glfwLibrary.X11.display, + window->X11.window, + window->X11.context); + } + else + glXMakeCurrent(_glfwLibrary.X11.display, None, NULL); +} + + //======================================================================== // Properly kill the window/video display //======================================================================== -void _glfwPlatformCloseWindow(void) +void _glfwPlatformCloseWindow(_GLFWwindow* window) { - if (_glfwWin.fullscreen) - leaveFullscreenMode(); + if (window->mode == GLFW_FULLSCREEN) + leaveFullscreenMode(window); - if (_glfwWin.context) + if (window->X11.context) { // Release and destroy the context - glXMakeCurrent(_glfwLibrary.display, None, NULL); - glXDestroyContext(_glfwLibrary.display, _glfwWin.context); - _glfwWin.context = NULL; + glXMakeCurrent(_glfwLibrary.X11.display, None, NULL); + glXDestroyContext(_glfwLibrary.X11.display, window->X11.context); + window->X11.context = NULL; } - if (_glfwWin.visual) + if (window->X11.visual) { - XFree(_glfwWin.visual); - _glfwWin.visual = NULL; + XFree(window->X11.visual); + window->X11.visual = NULL; } - if (_glfwWin.window) + if (window->X11.window) { - XUnmapWindow(_glfwLibrary.display, _glfwWin.window); - XDestroyWindow(_glfwLibrary.display, _glfwWin.window); - _glfwWin.window = (Window) 0; + XUnmapWindow(_glfwLibrary.X11.display, window->X11.window); + XDestroyWindow(_glfwLibrary.X11.display, window->X11.window); + window->X11.window = (Window) 0; } - if (_glfwWin.colormap) + if (window->X11.colormap) { - XFreeColormap(_glfwLibrary.display, _glfwWin.colormap); - _glfwWin.colormap = (Colormap) 0; + XFreeColormap(_glfwLibrary.X11.display, window->X11.colormap); + window->X11.colormap = (Colormap) 0; } - if (_glfwWin.cursor) + if (window->X11.cursor) { - XFreeCursor(_glfwLibrary.display, _glfwWin.cursor); - _glfwWin.cursor = (Cursor) 0; + XFreeCursor(_glfwLibrary.X11.display, window->X11.cursor); + window->X11.cursor = (Cursor) 0; } } @@ -1477,11 +1446,11 @@ void _glfwPlatformCloseWindow(void) // Set the window title //======================================================================== -void _glfwPlatformSetWindowTitle(const char* title) +void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char* title) { // Set window & icon title - XStoreName(_glfwLibrary.display, _glfwWin.window, title); - XSetIconName(_glfwLibrary.display, _glfwWin.window, title); + XStoreName(_glfwLibrary.X11.display, window->X11.window, title); + XSetIconName(_glfwLibrary.X11.display, window->X11.window, title); } @@ -1489,20 +1458,20 @@ void _glfwPlatformSetWindowTitle(const char* title) // Set the window size //======================================================================== -void _glfwPlatformSetWindowSize(int width, int height) +void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height) { int mode = 0, rate, sizeChanged = GL_FALSE; XSizeHints* sizehints; - rate = _glfwWin.refreshRate; + rate = window->refreshRate; - if (_glfwWin.fullscreen) + if (window->mode == GLFW_FULLSCREEN) { // Get the closest matching video mode for the specified window size - mode = _glfwGetClosestVideoMode(_glfwWin.screen, &width, &height, &rate); + mode = _glfwGetClosestVideoMode(window->X11.screen, &width, &height, &rate); } - if (_glfwWin.windowNoResize) + if (window->windowNoResize) { // Update window size restrictions to match new window size @@ -1512,26 +1481,26 @@ void _glfwPlatformSetWindowSize(int width, int height) sizehints->min_width = sizehints->max_width = width; sizehints->min_height = sizehints->max_height = height; - XSetWMNormalHints(_glfwLibrary.display, _glfwWin.window, sizehints); + XSetWMNormalHints(_glfwLibrary.X11.display, window->X11.window, sizehints); XFree(sizehints); } // Change window size before changing fullscreen mode? - if (_glfwWin.fullscreen && (width > _glfwWin.width)) + if (window->mode == GLFW_FULLSCREEN && (width > window->width)) { - XResizeWindow(_glfwLibrary.display, _glfwWin.window, width, height); + XResizeWindow(_glfwLibrary.X11.display, window->X11.window, width, height); sizeChanged = GL_TRUE; } - if (_glfwWin.fullscreen) + if (window->mode == GLFW_FULLSCREEN) { // Change video mode, keeping current refresh rate - _glfwSetVideoModeMODE(_glfwWin.screen, mode, _glfwWin.refreshRate); + _glfwSetVideoModeMODE(window->X11.screen, mode, window->refreshRate); } // Set window size (if not already changed) if (!sizeChanged) - XResizeWindow(_glfwLibrary.display, _glfwWin.window, width, height); + XResizeWindow(_glfwLibrary.X11.display, window->X11.window, width, height); } @@ -1539,9 +1508,9 @@ void _glfwPlatformSetWindowSize(int width, int height) // Set the window position. //======================================================================== -void _glfwPlatformSetWindowPos(int x, int y) +void _glfwPlatformSetWindowPos(_GLFWwindow* window, int x, int y) { - XMoveWindow(_glfwLibrary.display, _glfwWin.window, x, y); + XMoveWindow(_glfwLibrary.X11.display, window->X11.window, x, y); } @@ -1549,16 +1518,16 @@ void _glfwPlatformSetWindowPos(int x, int y) // Window iconification //======================================================================== -void _glfwPlatformIconifyWindow(void) +void _glfwPlatformIconifyWindow(_GLFWwindow* window) { - if (_glfwWin.overrideRedirect) + if (window->X11.overrideRedirect) { // We can't iconify/restore override-redirect windows, as that's // performed by the window manager return; } - XIconifyWindow(_glfwLibrary.display, _glfwWin.window, _glfwWin.screen); + XIconifyWindow(_glfwLibrary.X11.display, window->X11.window, window->X11.screen); } @@ -1566,27 +1535,27 @@ void _glfwPlatformIconifyWindow(void) // Window un-iconification //======================================================================== -void _glfwPlatformRestoreWindow(void) +void _glfwPlatformRestoreWindow(_GLFWwindow* window) { - if (_glfwWin.overrideRedirect) + if (window->X11.overrideRedirect) { // We can't iconify/restore override-redirect windows, as that's // performed by the window manager return; } - XMapWindow(_glfwLibrary.display, _glfwWin.window); + XMapWindow(_glfwLibrary.X11.display, window->X11.window); } //======================================================================== -// Swap OpenGL buffers and poll any new events +// Swap OpenGL buffers //======================================================================== void _glfwPlatformSwapBuffers(void) { - // Update display-buffer - glXSwapBuffers(_glfwLibrary.display, _glfwWin.window); + glXSwapBuffers(_glfwLibrary.X11.display, + _glfwLibrary.currentWindow->X11.window); } @@ -1596,8 +1565,10 @@ void _glfwPlatformSwapBuffers(void) void _glfwPlatformSwapInterval(int interval) { - if (_glfwWin.has_GLX_SGI_swap_control) - _glfwWin.SwapIntervalSGI(interval); + _GLFWwindow* window = _glfwLibrary.currentWindow; + + if (window->X11.has_GLX_SGI_swap_control) + window->X11.SwapIntervalSGI(interval); } @@ -1616,19 +1587,21 @@ void _glfwPlatformRefreshWindowParams(void) int dotclock; float pixels_per_second, pixels_per_frame; #endif - int attribs[] = { GLX_FBCONFIG_ID, _glfwWin.fbconfigID, None }; + _GLFWwindow* window = _glfwLibrary.currentWindow; - if (_glfwWin.has_GLX_SGIX_fbconfig) + int attribs[] = { GLX_FBCONFIG_ID, window->X11.fbconfigID, None }; + + if (window->X11.has_GLX_SGIX_fbconfig) { - fbconfig = _glfwWin.ChooseFBConfigSGIX(_glfwLibrary.display, - _glfwWin.screen, - attribs, - &dummy); + fbconfig = window->X11.ChooseFBConfigSGIX(_glfwLibrary.X11.display, + window->X11.screen, + attribs, + &dummy); } else { - fbconfig = glXChooseFBConfig(_glfwLibrary.display, - _glfwWin.screen, + fbconfig = glXChooseFBConfig(_glfwLibrary.X11.display, + window->X11.screen, attribs, &dummy); } @@ -1644,50 +1617,50 @@ void _glfwPlatformRefreshWindowParams(void) // There is no clear definition of an "accelerated" context on X11/GLX, and // true sounds better than false, so we hardcode true here - _glfwWin.accelerated = GL_TRUE; + window->accelerated = GL_TRUE; - _glfwWin.redBits = getFBConfigAttrib(*fbconfig, GLX_RED_SIZE); - _glfwWin.greenBits = getFBConfigAttrib(*fbconfig, GLX_GREEN_SIZE); - _glfwWin.blueBits = getFBConfigAttrib(*fbconfig, GLX_BLUE_SIZE); + window->redBits = getFBConfigAttrib(window, *fbconfig, GLX_RED_SIZE); + window->greenBits = getFBConfigAttrib(window, *fbconfig, GLX_GREEN_SIZE); + window->blueBits = getFBConfigAttrib(window, *fbconfig, GLX_BLUE_SIZE); - _glfwWin.alphaBits = getFBConfigAttrib(*fbconfig, GLX_ALPHA_SIZE); - _glfwWin.depthBits = getFBConfigAttrib(*fbconfig, GLX_DEPTH_SIZE); - _glfwWin.stencilBits = getFBConfigAttrib(*fbconfig, GLX_STENCIL_SIZE); + window->alphaBits = getFBConfigAttrib(window, *fbconfig, GLX_ALPHA_SIZE); + window->depthBits = getFBConfigAttrib(window, *fbconfig, GLX_DEPTH_SIZE); + window->stencilBits = getFBConfigAttrib(window, *fbconfig, GLX_STENCIL_SIZE); - _glfwWin.accumRedBits = getFBConfigAttrib(*fbconfig, GLX_ACCUM_RED_SIZE); - _glfwWin.accumGreenBits = getFBConfigAttrib(*fbconfig, GLX_ACCUM_GREEN_SIZE); - _glfwWin.accumBlueBits = getFBConfigAttrib(*fbconfig, GLX_ACCUM_BLUE_SIZE); - _glfwWin.accumAlphaBits = getFBConfigAttrib(*fbconfig, GLX_ACCUM_ALPHA_SIZE); + window->accumRedBits = getFBConfigAttrib(window, *fbconfig, GLX_ACCUM_RED_SIZE); + window->accumGreenBits = getFBConfigAttrib(window, *fbconfig, GLX_ACCUM_GREEN_SIZE); + window->accumBlueBits = getFBConfigAttrib(window, *fbconfig, GLX_ACCUM_BLUE_SIZE); + window->accumAlphaBits = getFBConfigAttrib(window, *fbconfig, GLX_ACCUM_ALPHA_SIZE); - _glfwWin.auxBuffers = getFBConfigAttrib(*fbconfig, GLX_AUX_BUFFERS); - _glfwWin.stereo = getFBConfigAttrib(*fbconfig, GLX_STEREO) ? 1 : 0; + window->auxBuffers = getFBConfigAttrib(window, *fbconfig, GLX_AUX_BUFFERS); + window->stereo = getFBConfigAttrib(window, *fbconfig, GLX_STEREO) ? GL_TRUE : GL_FALSE; // Get FSAA buffer sample count - if (_glfwWin.has_GLX_ARB_multisample) - _glfwWin.samples = getFBConfigAttrib(*fbconfig, GLX_SAMPLES); + if (window->X11.has_GLX_ARB_multisample) + window->samples = getFBConfigAttrib(window, *fbconfig, GLX_SAMPLES); else - _glfwWin.samples = 0; + window->samples = 0; // Default to refresh rate unknown (=0 according to GLFW spec) - _glfwWin.refreshRate = 0; + window->refreshRate = 0; // Retrieve refresh rate if possible #if defined(_GLFW_HAS_XRANDR) - if (_glfwLibrary.XRandR.available) + if (_glfwLibrary.X11.XRandR.available) { - sc = XRRGetScreenInfo(_glfwLibrary.display, _glfwWin.root); - _glfwWin.refreshRate = XRRConfigCurrentRate(sc); + sc = XRRGetScreenInfo(_glfwLibrary.X11.display, window->X11.root); + window->refreshRate = XRRConfigCurrentRate(sc); XRRFreeScreenConfigInfo(sc); } #elif defined(_GLFW_HAS_XF86VIDMODE) - if (_glfwLibrary.XF86VidMode.available) + if (_glfwLibrary.X11.XF86VidMode.available) { // Use the XF86VidMode extension to get current video mode - XF86VidModeGetModeLine(_glfwLibrary.display, _glfwWin.screen, + XF86VidModeGetModeLine(_glfwLibrary.X11.display, window->X11.screen, &dotclock, &modeline); pixels_per_second = 1000.0f * (float) dotclock; pixels_per_frame = (float) modeline.htotal * modeline.vtotal; - _glfwWin.refreshRate = (int)(pixels_per_second/pixels_per_frame+0.5); + window->refreshRate = (int)(pixels_per_second/pixels_per_frame+0.5); } #endif @@ -1703,28 +1676,31 @@ void _glfwPlatformPollEvents(void) { GLboolean closeRequested = GL_FALSE; + _GLFWwindow* window = _glfwLibrary.window; + // Flag that the cursor has not moved - _glfwInput.MouseMoved = GL_FALSE; + window->X11.mouseMoved = GL_FALSE; // Process all pending events - while (XPending(_glfwLibrary.display)) + while (XPending(_glfwLibrary.X11.display)) { if (processSingleEvent()) closeRequested = GL_TRUE; } // Did we get mouse movement in fully enabled hidden cursor mode? - if (_glfwInput.MouseMoved && _glfwWin.pointerHidden) + if (window->X11.mouseMoved && window->X11.pointerHidden) { - _glfwPlatformSetMouseCursorPos(_glfwWin.width / 2, - _glfwWin.height / 2); + _glfwPlatformSetMouseCursorPos(window, + window->width / 2, + window->height / 2); } - if (closeRequested && _glfwWin.windowCloseCallback) - closeRequested = _glfwWin.windowCloseCallback(); + if (closeRequested && window->windowCloseCallback) + closeRequested = window->windowCloseCallback(); if (closeRequested) - glfwCloseWindow(); + glfwCloseWindow(window); } @@ -1737,8 +1713,8 @@ void _glfwPlatformWaitEvents(void) XEvent event; // Block waiting for an event to arrive - XNextEvent(_glfwLibrary.display, &event); - XPutBackEvent(_glfwLibrary.display, &event); + XNextEvent(_glfwLibrary.X11.display, &event); + XPutBackEvent(_glfwLibrary.X11.display, &event); _glfwPlatformPollEvents(); } @@ -1748,25 +1724,25 @@ void _glfwPlatformWaitEvents(void) // Hide mouse cursor (lock it) //======================================================================== -void _glfwPlatformHideMouseCursor(void) +void _glfwPlatformHideMouseCursor(_GLFWwindow* window) { // Hide cursor - if (!_glfwWin.pointerHidden) + if (!window->X11.pointerHidden) { - XDefineCursor(_glfwLibrary.display, _glfwWin.window, _glfwWin.cursor); - _glfwWin.pointerHidden = GL_TRUE; + XDefineCursor(_glfwLibrary.X11.display, window->X11.window, window->X11.cursor); + window->X11.pointerHidden = GL_TRUE; } // Grab cursor to user window - if (!_glfwWin.pointerGrabbed) + if (!window->X11.pointerGrabbed) { - if (XGrabPointer(_glfwLibrary.display, _glfwWin.window, True, + if (XGrabPointer(_glfwLibrary.X11.display, window->X11.window, True, ButtonPressMask | ButtonReleaseMask | PointerMotionMask, GrabModeAsync, GrabModeAsync, - _glfwWin.window, None, CurrentTime) == + window->X11.window, None, CurrentTime) == GrabSuccess) { - _glfwWin.pointerGrabbed = GL_TRUE; + window->X11.pointerGrabbed = GL_TRUE; } } } @@ -1776,22 +1752,22 @@ void _glfwPlatformHideMouseCursor(void) // Show mouse cursor (unlock it) //======================================================================== -void _glfwPlatformShowMouseCursor(void) +void _glfwPlatformShowMouseCursor(_GLFWwindow* window) { // Un-grab cursor (only in windowed mode: in fullscreen mode we still // want the mouse grabbed in order to confine the cursor to the window // area) - if (_glfwWin.pointerGrabbed) + if (window->X11.pointerGrabbed) { - XUngrabPointer(_glfwLibrary.display, CurrentTime); - _glfwWin.pointerGrabbed = GL_FALSE; + XUngrabPointer(_glfwLibrary.X11.display, CurrentTime); + window->X11.pointerGrabbed = GL_FALSE; } // Show cursor - if (_glfwWin.pointerHidden) + if (window->X11.pointerHidden) { - XUndefineCursor(_glfwLibrary.display, _glfwWin.window); - _glfwWin.pointerHidden = GL_FALSE; + XUndefineCursor(_glfwLibrary.X11.display, window->X11.window); + window->X11.pointerHidden = GL_FALSE; } } @@ -1800,12 +1776,12 @@ void _glfwPlatformShowMouseCursor(void) // Set physical mouse cursor position //======================================================================== -void _glfwPlatformSetMouseCursorPos(int x, int y) +void _glfwPlatformSetMouseCursorPos(_GLFWwindow* window, int x, int y) { // Store the new position so we can recognise it later - _glfwInput.CursorPosX = x; - _glfwInput.CursorPosY = y; + window->X11.cursorPosX = x; + window->X11.cursorPosY = y; - XWarpPointer(_glfwLibrary.display, None, _glfwWin.window, 0,0,0,0, x, y); + XWarpPointer(_glfwLibrary.X11.display, None, window->X11.window, 0,0,0,0, x, y); }