Merge branch 'master' into multi-monitor Conflicts: CMakeLists.txt readme.html src/CMakeLists.txt src/cocoa_platform.h src/win32_platform.h src/x11_platform.h tests/events.c
diff --git a/.gitignore b/.gitignore index da61d80..1366b5f 100644 --- a/.gitignore +++ b/.gitignore
@@ -1,9 +1,9 @@ +.DS_Store +Makefile +CMakeCache.txt CMakeFiles cmake_install.cmake -CMakeCache.txt -Makefile cmake_uninstall.cmake -.DS_Store docs/Doxyfile src/config.h src/glfw3.pc @@ -13,14 +13,17 @@ src/glfw3.lib src/glfw3.dll src/glfw3dll.lib +examples/*.app +examples/*.exe examples/boing examples/gears examples/heightmap examples/splitview examples/triangle examples/wave -examples/*.app -examples/*.exe +src/config.h +tests/*.app +tests/*.exe tests/accuracy tests/clipboard tests/defaults @@ -38,6 +41,5 @@ tests/tearing tests/threads tests/title +tests/version tests/windows -tests/*.app -tests/*.exe
diff --git a/CMakeLists.txt b/CMakeLists.txt index 08542a6..ba257c9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt
@@ -30,15 +30,6 @@ find_package(OpenGL REQUIRED) endif() -if (NOT WIN32) - set(CMAKE_THREAD_PREFER_PTHREADS YES) -endif() - -find_package(Threads) -if (CMAKE_THREAD_LIBS_INIT) - list(APPEND glfw_LIBRARIES ${CMAKE_THREAD_LIBS_INIT}) -endif() - #-------------------------------------------------------------------- # Enable all warnings on GCC, regardless of OS #--------------------------------------------------------------------
diff --git a/examples/boing.c b/examples/boing.c index 5a1993f..a5914f9 100644 --- a/examples/boing.c +++ b/examples/boing.c
@@ -579,7 +579,7 @@ glfwWindowHint(GLFW_DEPTH_BITS, 16); - window = glfwCreateWindow( 400, 400, GLFW_WINDOWED, "Boing (classic Amiga demo)", NULL ); + window = glfwCreateWindow( 400, 400, "Boing (classic Amiga demo)", NULL, NULL ); if (!window) { fprintf( stderr, "Failed to open GLFW window\n" );
diff --git a/examples/gears.c b/examples/gears.c index b056251..cc4b29a 100644 --- a/examples/gears.c +++ b/examples/gears.c
@@ -340,7 +340,7 @@ glfwWindowHint(GLFW_DEPTH_BITS, 16); - window = glfwCreateWindow( 300, 300, GLFW_WINDOWED, "Gears", NULL ); + window = glfwCreateWindow( 300, 300, "Gears", NULL, NULL ); if (!window) { fprintf( stderr, "Failed to open GLFW window\n" );
diff --git a/examples/heightmap.c b/examples/heightmap.c index 6abaa1e..60ac99d 100644 --- a/examples/heightmap.c +++ b/examples/heightmap.c
@@ -587,7 +587,7 @@ glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_FALSE); - window = glfwCreateWindow(800, 600, GLFW_WINDOWED, "GLFW OpenGL3 Heightmap demo", NULL); + window = glfwCreateWindow(800, 600, "GLFW OpenGL3 Heightmap demo", NULL, NULL); if (! window ) { fprintf(stderr, "ERROR: Unable to create the OpenGL context and associated window\n");
diff --git a/examples/splitview.c b/examples/splitview.c index 965a183..9b3e085 100644 --- a/examples/splitview.c +++ b/examples/splitview.c
@@ -453,7 +453,7 @@ glfwWindowHint(GLFW_DEPTH_BITS, 16); // Open OpenGL window - window = glfwCreateWindow(500, 500, GLFW_WINDOWED, "Split view demo", NULL); + window = glfwCreateWindow(500, 500, "Split view demo", NULL, NULL); if (!window) { fprintf(stderr, "Failed to open GLFW window\n");
diff --git a/examples/triangle.c b/examples/triangle.c index 3a1cef9..52e1149 100644 --- a/examples/triangle.c +++ b/examples/triangle.c
@@ -23,7 +23,7 @@ } // Open a window and create its OpenGL context - window = glfwCreateWindow(640, 480, GLFW_WINDOWED, "Spinning Triangle", NULL); + window = glfwCreateWindow(640, 480, "Spinning Triangle", NULL, NULL); if (!window) { fprintf(stderr, "Failed to open GLFW window\n");
diff --git a/examples/wave.c b/examples/wave.c index 7b4b4c3..a1bfde5 100644 --- a/examples/wave.c +++ b/examples/wave.c
@@ -399,7 +399,7 @@ exit(EXIT_FAILURE); } - window = glfwCreateWindow(640, 480, GLFW_WINDOWED, "Wave Simulation", NULL); + window = glfwCreateWindow(640, 480, "Wave Simulation", NULL, NULL); if (!window) { fprintf(stderr, "Could not open window\n");
diff --git a/include/GL/glfw3.h b/include/GL/glfw3.h index 298c3d5..d102d94 100644 --- a/include/GL/glfw3.h +++ b/include/GL/glfw3.h
@@ -56,6 +56,8 @@ */ /*! @defgroup input Input handling */ +/*! @defgroup monitor Monitor handling + */ /*! @defgroup opengl OpenGL support */ /*! @defgroup time Time input @@ -66,8 +68,6 @@ * context creation and window management. GLFW supports multiple windows, * which can be either a normal desktop window or a fullscreen window. */ -/*! @defgroup monitor Monitor handling - */ /************************************************************************* @@ -453,15 +453,6 @@ * Other definitions *************************************************************************/ -/*! @brief A regular, overlapped window. - * @ingroup window - */ -#define GLFW_WINDOWED 0x00010001 -/*! @brief A fullscreen window that may changed the monitor's resolution. - * @ingroup window - */ -#define GLFW_FULLSCREEN 0x00010002 - /*! @defgroup paramhints Window parameters and hints * @ingroup window * @{ */ @@ -692,6 +683,13 @@ */ #define GLFW_GAMMA_RAMP_SIZE 256 +/* Monitor constants */ +#define GLFW_MONITOR_PHYSICAL_WIDTH 0x00060001 +#define GLFW_MONITOR_PHYSICAL_HEIGHT 0x00060002 +#define GLFW_MONITOR_POS_X 0x00060003 +#define GLFW_MONITOR_POS_Y 0x00060004 +#define GLFW_MONITOR_CONNECTED 0x00061000 +#define GLFW_MONITOR_DISCONNECTED 0x00061001 /************************************************************************* * Typedefs @@ -702,6 +700,11 @@ */ typedef void (*GLFWglproc)(void); +/*! @brief Monitor handle type. + * @ingroup monitor + */ +typedef void* GLFWmonitor; + /*! @brief Window handle type. * @ingroup window */ @@ -811,6 +814,13 @@ */ typedef void (* GLFWcharfun)(GLFWwindow,int); +/*! @brief The function signature for monitor configuration callbacks. + * @param[in] monitor The monitor that was connected or disconnected. + * @param[in] event @ref GLFW_MONITOR_CONNECTED or @ref + * GLFW_MONITOR_DISCONNECTED. + */ +typedef void (* GLFWmonitorfun)(GLFWmonitor,int); + /* @brief Video mode type. * @ingroup monitor */ @@ -948,17 +958,68 @@ */ GLFWAPI void glfwSetErrorCallback(GLFWerrorfun cbfun); -/*! @brief This function will be replaced when the @c multi-monitor branch is - * merged. +/*! @brief Returns the currently connected monitors. + * @param[out] count The size of the returned array. + * @return An array of monitor handles. * @ingroup monitor */ -GLFWAPI GLFWvidmode* glfwGetVideoModes(int* count); +GLFWAPI GLFWmonitor* glfwGetMonitors(int* count); -/*! @brief This function will be replaced when the @c multi-monitor branch is - * merged. +/*! @brief Returns the primary monitor. + * @return The primary monitor. * @ingroup monitor */ -GLFWAPI void glfwGetDesktopMode(GLFWvidmode* mode); +GLFWAPI GLFWmonitor glfwGetPrimaryMonitor(void); + +/*! @brief Returns a property of the specified monitor. + * @ingroup monitor + */ +GLFWAPI int glfwGetMonitorParam(GLFWmonitor monitor, int param); + +/*! @brief Returns the name of the specified monitor. + * @param[in] monitor The monitor to query. + * @return The UTF-8 encoded name of the monitor. + * @ingroup monitor + */ +GLFWAPI const char* glfwGetMonitorName(GLFWmonitor monitor); + +/*! @brief Sets the user pointer of the specified monitor. + * @param[in] monitor The monitor whose pointer to set. + * @param[in] pointer The new value. + * @ingroup monitor + * + * @see glfwGetMonitorUserPointer + */ +GLFWAPI void glfwSetMonitorUserPointer(GLFWmonitor monitor, void* pointer); + +/*! @brief Returns the user pointer of the specified monitor. + * @param[in] monitor The monitor whose pointer to return. + * @ingroup monitor + * + * @sa glfwSetMonitorUserPointer + */ +GLFWAPI void* glfwGetMonitorUserPointer(GLFWmonitor monitor); + +/*! @brief Sets the monitor configuration callback. + * @param[in] cbfun The new callback, or @c NULL to remove the currently set. + * @ingroup monitor + */ +GLFWAPI void glfwSetMonitorCallback(GLFWmonitorfun cbfun); + +/*! @brief Returns the available video modes for the specified monitor. + * @param[in] monitor The monitor to query. + * @param[out] count The number of video modes in the returned array. + * @return An array of video modes. + * @ingroup monitor + */ +GLFWAPI GLFWvidmode* glfwGetVideoModes(GLFWmonitor monitor, int* count); + +/*! @brief Returns the current mode of the specified monitor. + * @param[in] monitor The monitor to query. + * @param[out] mode The current mode of the monitor. + * @ingroup monitor + */ +GLFWAPI void glfwGetVideoMode(GLFWmonitor monitor, GLFWvidmode* mode); /*! @brief Sets the system gamma ramp to one generated from the specified * exponent. @@ -1093,8 +1154,9 @@ * greater than zero. * @param[in] height The desired height, in pixels, of the window. This must * be greater than zero. - * @param[in] mode One of @ref GLFW_WINDOWED or @ref GLFW_FULLSCREEN. * @param[in] title The initial, UTF-8 encoded window title. + * @param[in] monitor The monitor to use for fullscreen mode, or @c NULL to use + * windowed mode. * @param[in] share The window whose context to share resources with, or @c * NULL to not share resources. * @return The handle of the created window, or @c NULL if an error occurred. @@ -1130,7 +1192,7 @@ * * @sa glfwDestroyWindow */ -GLFWAPI GLFWwindow glfwCreateWindow(int width, int height, int mode, const char* title, GLFWwindow share); +GLFWAPI GLFWwindow glfwCreateWindow(int width, int height, const char* title, GLFWmonitor monitor, GLFWwindow share); /*! @brief Destroys the specified window and its context. * @param[in] window The window to destroy. @@ -1234,6 +1296,13 @@ */ GLFWAPI void glfwHideWindow(GLFWwindow window); +/*! @brief Returns the monitor that the window uses for fullscreen mode + * @param[in] window The window to query. + * @return The monitor, or @c NULL if the window is in windowed mode. + * @ingroup window + */ +GLFWAPI GLFWmonitor glfwGetWindowMonitor(GLFWwindow window); + /*! @brief Returns a property of the specified window. * @param[in] window The window to query. * @param[in] param The property whose value to return.
diff --git a/readme.html b/readme.html index 8e25c74..190b05f 100644 --- a/readme.html +++ b/readme.html
@@ -267,6 +267,11 @@ <h3>v3.0</h3> <ul> + <li>Added <code>GLFWmonitor</code> monitor handle type and updated monitor-related functions to take a monitor handle</li> + <li>Added <code>glfwGetMonitors</code> and <code>glfwGetPrimaryMonitor</code> for enumerating available monitors</li> + <li>Added <code>glfwGetMonitorParam</code> and <code>glfwGetMonitorName</code> for retrieving monitor properties</li> + <li>Added <code>glfwSetMonitorUserPointer</code> and <code>glfwGetMonitorUserPointer</code> for per-monitor user pointers</li> + <li>Added <code>glfwSetMonitorCallback</code> and <code>GLFWmonitorfun</code> for notification of changes in the set of available monitors</li> <li>Added <code>GLFWwindow</code> window handle type and updated window-related functions and callbacks to take a window handle</li> <li>Added <code>glfwDefaultWindowHints</code> function for resetting all window hints to their default values</li> <li>Added <code>glfwMakeContextCurrent</code> function for making the context of the specified window current</li> @@ -274,6 +279,7 @@ <li>Added <code>glfwSetErrorCallback</code> function and <code>GLFWerrorfun</code> type for receiving more specific and/or nested errors</li> <li>Added <code>glfwSetWindowUserPointer</code> and <code>glfwGetWindowUserPointer</code> functions for per-window user pointers</li> <li>Added <code>glfwGetVersionString</code> function for determining which code paths were enabled at compile time</li> + <li>Added <code>glfwGetWindowMonitor</code> for querying the monitor, if any, of the specified window</li> <li>Added <code>glfwSetWindowPosCallback</code> function and <code>GLFWwindowposfun</code> type for reciving window position events</li> <li>Added <code>glfwSetWindowFocusCallback</code> function and <code>GLFWwindowfocusfun</code> type for receiving window focus events</li> <li>Added <code>glfwSetWindowIconifyCallback</code> function and <code>GLFWwindowiconifyfun</code> type for receiving window iconification events</li> @@ -298,11 +304,10 @@ <li>Changed buffer bit depth parameters of <code>glfwOpenWindow</code> to window hints</li> <li>Changed <code>glfwOpenWindow</code> and <code>glfwSetWindowTitle</code> to use UTF-8 encoded strings</li> <li>Changed <code>glfwGetProcAddress</code> to return a (generic) function pointer</li> - <li>Changed <code>glfwGetVideoModes</code> to return a dynamic, unlimited number of video modes</li> + <li>Changed <code>glfwGetVideoModes</code> to return a dynamic, unlimited number of video modes for the specified monitor</li> <li>Renamed <code>glfw.h</code> to <code>glfw3.h</code> to avoid conflicts with 2.x series</li> <li>Renamed <code>glfwOpenWindowHint</code> to <code>glfwWindowHint</code></li> <li>Renamed <code>GLFW_ACTIVE</code> to <code>GLFW_FOCUSED</code></li> - <li>Renamed <code>GLFW_WINDOW</code> token to <code>GLFW_WINDOWED</code></li> <li>Renamed <code>GLFW_WINDOW_NO_RESIZE</code> to <code>GLFW_RESIZABLE</code></li> <li>Renamed <code>GLFW_BUILD_DLL</code> to <code>_GLFW_BUILD_DLL</code></li> <li>Renamed <code>version</code> test to <code>glfwinfo</code></li> @@ -310,6 +315,7 @@ <li>Renamed <code>glfwGetJoystickPos</code> to <code>glfwGetJoystickAxes</code> to match <code>glfwGetJoystickButtons</code></li> <li>Renamed mouse position functions to cursor position equivalents</li> <li>Replaced <code>glfwOpenWindow</code> and <code>glfwCloseWindow</code> with <code>glfwCreateWindow</code> and <code>glfwDestroyWindow</code></li> + <li>Replaced <code>glfwGetDesktopMode</code> width <code>glfwGetVideoMode</code></li> <li>Replaced ad hoc build system with CMake</li> <li>Replaced layout-dependent key codes with single, platform-independent set based on US layout</li> <li>Replaced mouse wheel interface with two-dimensional, floating point scrolling interface</li> @@ -327,6 +333,7 @@ <li>Removed <code>glfwGetNumberOfProcessors</code> function</li> <li>Removed <code>glfwGetGLVersion</code> function</li> <li>Removed <code>GLFW_OPENED</code> window parameter</li> + <li>Removed <code>GLFW_WINDOW</code> and <code>GLFW_FULLSCREEN</code></li> <li>Removed nonsensical key actions for Unicode character input</li> <li>Removed <code>GLFWCALL</code> and <code>GLFWAPIENTRY</code> macros for stdcall calling convention</li> <li>Removed <code>GLFW_ACCELERATED</code> window parameter</li> @@ -925,6 +932,9 @@ <li>David Medlock, for doing the initial Lua port</li> + <li>Marcel Metz, for the initial implementation of multi-monitor support on + X11 and Win32</li> + <li>Kenneth Miller, for his many and detailed bug reports on Win32</li> <li>Jeff Molofee, the author of the excellent OpenGL tutorials at <a
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 3d11ef3..05ee10e 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt
@@ -1,3 +1,4 @@ + include_directories(${GLFW_SOURCE_DIR}/src ${GLFW_BINARY_DIR}/src ${glfw_INCLUDE_DIRS}) @@ -7,13 +8,13 @@ endif() set(common_HEADERS ${GLFW_SOURCE_DIR}/include/GL/glfw3.h internal.h) -set(common_SOURCES clipboard.c context.c fullscreen.c gamma.c init.c input.c - joystick.c time.c window.c) +set(common_SOURCES clipboard.c context.c gamma.c init.c input.c joystick.c + monitor.c time.c window.c) if (_GLFW_COCOA) set(glfw_HEADERS ${common_HEADERS} cocoa_platform.h) - set(glfw_SOURCES ${common_SOURCES} cocoa_clipboard.m cocoa_fullscreen.m - cocoa_gamma.c cocoa_init.m cocoa_joystick.m cocoa_time.c + set(glfw_SOURCES ${common_SOURCES} cocoa_clipboard.m cocoa_gamma.c + cocoa_init.m cocoa_joystick.m cocoa_monitor.m cocoa_time.c cocoa_window.m) if (GLFW_NATIVE_API) @@ -21,8 +22,8 @@ endif() elseif (_GLFW_WIN32) set(glfw_HEADERS ${common_HEADERS} win32_platform.h) - set(glfw_SOURCES ${common_SOURCES} win32_clipboard.c win32_fullscreen.c - win32_gamma.c win32_init.c win32_joystick.c win32_time.c + set(glfw_SOURCES ${common_SOURCES} win32_clipboard.c win32_gamma.c + win32_init.c win32_joystick.c win32_monitor.c win32_time.c win32_window.c) if (GLFW_NATIVE_API) @@ -30,8 +31,8 @@ endif() elseif (_GLFW_X11) set(glfw_HEADERS ${common_HEADERS} x11_platform.h) - set(glfw_SOURCES ${common_SOURCES} x11_clipboard.c x11_fullscreen.c - x11_gamma.c x11_init.c x11_joystick.c x11_keysym2unicode.c + set(glfw_SOURCES ${common_SOURCES} x11_clipboard.c x11_gamma.c x11_init.c + x11_joystick.c x11_keysym2unicode.c x11_monitor.c x11_time.c x11_window.c) if (GLFW_NATIVE_API)
diff --git a/src/cocoa_init.m b/src/cocoa_init.m index 3bb61c1..95e752e 100644 --- a/src/cocoa_init.m +++ b/src/cocoa_init.m
@@ -92,8 +92,6 @@ changeToResourcesDirectory(); - _glfwLibrary.NS.desktopMode = CGDisplayCopyDisplayMode(CGMainDisplayID()); - // Save the original gamma ramp _glfwLibrary.originalRampSize = CGDisplayGammaTableCapacity(CGMainDisplayID()); _glfwPlatformGetGammaRamp(&_glfwLibrary.originalRamp); @@ -135,8 +133,6 @@ if (_glfwLibrary.rampChanged) _glfwPlatformSetGammaRamp(&_glfwLibrary.originalRamp); - CGDisplayModeRelease(_glfwLibrary.NS.desktopMode); - [NSApp setDelegate:nil]; [_glfwLibrary.NS.delegate release]; _glfwLibrary.NS.delegate = nil;
diff --git a/src/cocoa_fullscreen.m b/src/cocoa_monitor.m similarity index 66% rename from src/cocoa_fullscreen.m rename to src/cocoa_monitor.m index 47f8673..46fa11e 100644 --- a/src/cocoa_fullscreen.m +++ b/src/cocoa_monitor.m
@@ -1,10 +1,11 @@ //======================================================================== // GLFW - An OpenGL library // Platform: Cocoa -// API Version: 3.0 +// API version: 3.0 // WWW: http://www.glfw.org/ //------------------------------------------------------------------------ -// Copyright (c) 2009-2010 Camilla Berglund <elmindreda@elmindreda.org> +// Copyright (c) 2002-2006 Marcus Geelnard +// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org> // // This software is provided 'as-is', without any express or implied // warranty. In no event will the authors be held liable for any damages @@ -32,6 +33,41 @@ #include <stdlib.h> #include <limits.h> +#include <IOKit/graphics/IOGraphicsLib.h> + + +//======================================================================== +// Get the name of the specified display +//======================================================================== + +const char* getDisplayName(CGDirectDisplayID displayID) +{ + char* name; + CFDictionaryRef info, names; + CFStringRef value; + CFIndex size; + + info = IODisplayCreateInfoDictionary(CGDisplayIOServicePort(displayID), + kIODisplayOnlyPreferredName); + names = CFDictionaryGetValue(info, CFSTR(kDisplayProductName)); + + if (!CFDictionaryGetValueIfPresent(names, CFSTR("en_US"), + (const void**) &value)) + { + CFRelease(info); + return strdup("Unknown"); + } + + size = CFStringGetMaximumSizeForEncoding(CFStringGetLength(value), + kCFStringEncodingUTF8); + name = (char*) malloc(size + 1); + CFStringGetCString(value, name, size, kCFStringEncodingUTF8); + + CFRelease(info); + + return name; +} + //======================================================================== // Check whether the display mode should be included in enumeration @@ -167,6 +203,8 @@ return GL_FALSE; } + _glfwLibrary.NS.previousMode = CGDisplayCopyDisplayMode(CGMainDisplayID()); + CGDisplayCapture(CGMainDisplayID()); CGDisplaySetDisplayMode(CGMainDisplayID(), bestMode, NULL); @@ -182,7 +220,7 @@ void _glfwRestoreVideoMode(void) { CGDisplaySetDisplayMode(CGMainDisplayID(), - _glfwLibrary.NS.desktopMode, + _glfwLibrary.NS.previousMode, NULL); CGDisplayRelease(CGMainDisplayID()); @@ -194,16 +232,74 @@ ////////////////////////////////////////////////////////////////////////// //======================================================================== +// Return a list of available monitors +//======================================================================== + +_GLFWmonitor** _glfwPlatformGetMonitors(int* count) +{ + uint32_t i, found = 0, monitorCount; + _GLFWmonitor** monitors; + CGDirectDisplayID* displays; + + *count = 0; + + CGGetActiveDisplayList(0, NULL, &monitorCount); + + displays = (CGDirectDisplayID*) calloc(monitorCount, sizeof(CGDirectDisplayID)); + if (!displays) + { + _glfwSetError(GLFW_OUT_OF_MEMORY, NULL); + return NULL; + } + + monitors = (_GLFWmonitor**) calloc(monitorCount, sizeof(_GLFWmonitor*)); + if (!monitors) + { + _glfwSetError(GLFW_OUT_OF_MEMORY, NULL); + return NULL; + } + + for (i = 0; i < monitorCount; i++) + { + const CGSize size = CGDisplayScreenSize(displays[i]); + const CGRect bounds = CGDisplayBounds(displays[i]); + + monitors[found] = _glfwCreateMonitor(getDisplayName(displays[i]), + CGDisplayIsMain(displays[i]), + size.width, size.height, + bounds.origin.x, bounds.origin.y); + + monitors[found]->NS.displayID = displays[i]; + found++; + } + + free(displays); + + *count = monitorCount; + return monitors; +} + + +//======================================================================== +// Destroy a monitor struct +//======================================================================== + +void _glfwPlatformDestroyMonitor(_GLFWmonitor* monitor) +{ +} + + +//======================================================================== // Get a list of available video modes //======================================================================== -GLFWvidmode* _glfwPlatformGetVideoModes(int* found) +GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* found) { CFArrayRef modes; CFIndex count, i; GLFWvidmode* result; - modes = CGDisplayCopyAllDisplayModes(CGMainDisplayID(), NULL); + modes = CGDisplayCopyAllDisplayModes(monitor->NS.displayID, NULL); count = CFArrayGetCount(modes); result = (GLFWvidmode*) malloc(sizeof(GLFWvidmode) * count); @@ -227,11 +323,15 @@ //======================================================================== -// Get the desktop video mode +// Get the current video mode for the specified monitor //======================================================================== -void _glfwPlatformGetDesktopMode(GLFWvidmode *mode) +void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode *mode) { - *mode = vidmodeFromCGDisplayMode(_glfwLibrary.NS.desktopMode); + CGDisplayModeRef displayMode; + + displayMode = CGDisplayCopyDisplayMode(monitor->NS.displayID); + *mode = vidmodeFromCGDisplayMode(displayMode); + CGDisplayModeRelease(displayMode); }
diff --git a/src/cocoa_platform.h b/src/cocoa_platform.h index 21589a6..51fecbb 100644 --- a/src/cocoa_platform.h +++ b/src/cocoa_platform.h
@@ -48,6 +48,7 @@ #define _GLFW_PLATFORM_WINDOW_STATE _GLFWwindowNS NS #define _GLFW_PLATFORM_LIBRARY_WINDOW_STATE _GLFWlibraryNS NS +#define _GLFW_PLATFORM_MONITOR_STATE _GLFWmonitorNS NS //======================================================================== @@ -82,7 +83,7 @@ double resolution; } timer; - CGDisplayModeRef desktopMode; + CGDisplayModeRef previousMode; CGEventSourceRef eventSource; id delegate; id autoreleasePool; @@ -91,6 +92,16 @@ } _GLFWlibraryNS; +//------------------------------------------------------------------------ +// Platform-specific monitor structure +//------------------------------------------------------------------------ +typedef struct _GLFWmonitorNS +{ + CGDirectDisplayID displayID; + +} _GLFWmonitorNS; + + //======================================================================== // Prototypes for platform specific internal functions //========================================================================
diff --git a/src/cocoa_window.m b/src/cocoa_window.m index 040277a..d8f5a4e 100644 --- a/src/cocoa_window.m +++ b/src/cocoa_window.m
@@ -673,7 +673,9 @@ { unsigned int styleMask = 0; - if (wndconfig->mode == GLFW_WINDOWED) + if (wndconfig->monitor) + styleMask = NSBorderlessWindowMask; + else { styleMask = NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask; @@ -681,8 +683,6 @@ if (wndconfig->resizable) styleMask |= NSResizableWindowMask; } - else - styleMask = NSBorderlessWindowMask; window->NS.object = [[NSWindow alloc] initWithContentRect:NSMakeRect(wndconfig->positionX, wndconfig->positionY, window->width, window->height) @@ -794,7 +794,7 @@ ADD_ATTR(NSOpenGLPFADoubleBuffer); - if (wndconfig->mode == GLFW_FULLSCREEN) + if (wndconfig->monitor) { ADD_ATTR(NSOpenGLPFANoRecovery); ADD_ATTR2(NSOpenGLPFAScreenMask, @@ -928,7 +928,7 @@ [window->NSGL.context setView:[window->NS.object contentView]]; - if (wndconfig->mode == GLFW_FULLSCREEN) + if (wndconfig->monitor) { int bpp = colorBits + fbconfig->alphaBits; @@ -961,7 +961,7 @@ { [window->NS.object orderOut:nil]; - if (window->mode == GLFW_FULLSCREEN) + if (window->monitor) { [[window->NS.object contentView] exitFullScreenModeWithOptions:nil]; @@ -1064,19 +1064,17 @@ void _glfwPlatformPollEvents(void) { - NSEvent* event; - - do + for (;;) { - event = [NSApp nextEventMatchingMask:NSAnyEventMask - untilDate:[NSDate distantPast] - inMode:NSDefaultRunLoopMode - dequeue:YES]; + NSEvent* event = [NSApp nextEventMatchingMask:NSAnyEventMask + untilDate:[NSDate distantPast] + inMode:NSDefaultRunLoopMode + dequeue:YES]; + if (event == nil) + break; - if (event) - [NSApp sendEvent:event]; + [NSApp sendEvent:event]; } - while (event); [_glfwLibrary.NS.autoreleasePool drain]; _glfwLibrary.NS.autoreleasePool = [[NSAutoreleasePool alloc] init]; @@ -1087,7 +1085,7 @@ // Wait for new window and input events //======================================================================== -void _glfwPlatformWaitEvents( void ) +void _glfwPlatformWaitEvents(void) { // I wanted to pass NO to dequeue:, and rely on PollEvents to // dequeue and send. For reasons not at all clear to me, passing @@ -1108,7 +1106,7 @@ void _glfwPlatformSetCursorPos(_GLFWwindow* window, int x, int y) { - if (window->mode == GLFW_FULLSCREEN) + if (window->monitor) { CGPoint globalPoint = CGPointMake(x, y); CGDisplayMoveCursorToPoint(CGMainDisplayID(), globalPoint);
diff --git a/src/fullscreen.c b/src/fullscreen.c deleted file mode 100644 index f59046d..0000000 --- a/src/fullscreen.c +++ /dev/null
@@ -1,162 +0,0 @@ -//======================================================================== -// GLFW - An OpenGL library -// Platform: Any -// API version: 3.0 -// WWW: http://www.glfw.org/ -//------------------------------------------------------------------------ -// Copyright (c) 2002-2006 Marcus Geelnard -// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org> -// Copyright (c) 2012 Torsten Walluhn <tw@mad-cad.net> -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would -// be appreciated but is not required. -// -// 2. Altered source versions must be plainly marked as such, and must not -// be misrepresented as being the original software. -// -// 3. This notice may not be removed or altered from any source -// distribution. -// -//======================================================================== - -#include "internal.h" - -#include <stdlib.h> -#if defined(_MSC_VER) - #include <malloc.h> -#endif - - -//======================================================================== -// Lexical comparison function for GLFW video modes, used by qsort -//======================================================================== - -static int compareVideoModes(const void* firstPtr, const void* secondPtr) -{ - int firstBPP, secondBPP, firstSize, secondSize; - GLFWvidmode* first = (GLFWvidmode*) firstPtr; - GLFWvidmode* second = (GLFWvidmode*) secondPtr; - - // First sort on color bits per pixel - - firstBPP = first->redBits + - first->greenBits + - first->blueBits; - secondBPP = second->redBits + - second->greenBits + - second->blueBits; - - if (firstBPP != secondBPP) - return firstBPP - secondBPP; - - // Then sort on screen area, in pixels - - firstSize = first->width * first->height; - secondSize = second->width * second->height; - - return firstSize - secondSize; -} - - -////////////////////////////////////////////////////////////////////////// -////// GLFW internal API ////// -////////////////////////////////////////////////////////////////////////// - -//======================================================================== -// Lexical comparison of GLFW video modes -//======================================================================== - -int _glfwCompareVideoModes(const GLFWvidmode* first, const GLFWvidmode* second) -{ - return compareVideoModes(first, second); -} - - -//======================================================================== -// Convert BPP to RGB bits based on "best guess" -//======================================================================== - -void _glfwSplitBPP(int bpp, int* red, int* green, int* blue) -{ - int delta; - - // We assume that by 32 the user really meant 24 - if (bpp == 32) - bpp = 24; - - // Convert "bits per pixel" to red, green & blue sizes - - *red = *green = *blue = bpp / 3; - delta = bpp - (*red * 3); - if (delta >= 1) - *green = *green + 1; - - if (delta == 2) - *red = *red + 1; -} - - -////////////////////////////////////////////////////////////////////////// -////// GLFW public API ////// -////////////////////////////////////////////////////////////////////////// - -//======================================================================== -// Get a list of available video modes -//======================================================================== - -GLFWAPI GLFWvidmode* glfwGetVideoModes(int* count) -{ - if (!_glfwInitialized) - { - _glfwSetError(GLFW_NOT_INITIALIZED, NULL); - return NULL; - } - - if (count == NULL) - { - _glfwSetError(GLFW_INVALID_VALUE, NULL); - return NULL; - } - - free(_glfwLibrary.modes); - - _glfwLibrary.modes = _glfwPlatformGetVideoModes(count); - if (_glfwLibrary.modes) - qsort(_glfwLibrary.modes, *count, sizeof(GLFWvidmode), compareVideoModes); - - return _glfwLibrary.modes; -} - - -//======================================================================== -// Get the desktop video mode -//======================================================================== - -GLFWAPI void glfwGetDesktopMode(GLFWvidmode* mode) -{ - if (!_glfwInitialized) - { - _glfwSetError(GLFW_NOT_INITIALIZED, NULL); - return; - } - - if (mode == NULL) - { - _glfwSetError(GLFW_INVALID_VALUE, - "glfwGetDesktopMode: Parameter 'mode' cannot be NULL"); - return; - } - - _glfwPlatformGetDesktopMode(mode); -} -
diff --git a/src/init.c b/src/init.c index 4d7b731..e0a1e6f 100644 --- a/src/init.c +++ b/src/init.c
@@ -127,6 +127,13 @@ return GL_FALSE; } + _glfwLibrary.monitors = _glfwPlatformGetMonitors(&_glfwLibrary.monitorCount); + if (!_glfwLibrary.monitors) + { + _glfwPlatformTerminate(); + return GL_FALSE; + } + _glfwInitialized = GL_TRUE; // Not all window hints have zero as their default value @@ -149,12 +156,11 @@ while (_glfwLibrary.windowListHead) glfwDestroyWindow(_glfwLibrary.windowListHead); + _glfwDestroyMonitors(); + if (!_glfwPlatformTerminate()) return; - if (_glfwLibrary.modes) - free(_glfwLibrary.modes); - _glfwInitialized = GL_FALSE; }
diff --git a/src/internal.h b/src/internal.h index d2619e2..1ca3b11 100644 --- a/src/internal.h +++ b/src/internal.h
@@ -49,6 +49,7 @@ typedef struct _GLFWfbconfig _GLFWfbconfig; typedef struct _GLFWwindow _GLFWwindow; typedef struct _GLFWlibrary _GLFWlibrary; +typedef struct _GLFWmonitor _GLFWmonitor; //------------------------------------------------------------------------ @@ -121,7 +122,6 @@ //------------------------------------------------------------------------ struct _GLFWwndconfig { - int mode; const char* title; int refreshRate; GLboolean resizable; @@ -135,6 +135,7 @@ GLboolean glDebug; int glProfile; int glRobustness; + _GLFWmonitor* monitor; _GLFWwindow* share; }; @@ -183,6 +184,7 @@ GLboolean visible; // GL_TRUE if this window is visible int refreshRate; // monitor refresh rate void* userPointer; + _GLFWmonitor* monitor; // Window input state GLboolean stickyKeys; @@ -221,6 +223,30 @@ //------------------------------------------------------------------------ +// Display structure +//------------------------------------------------------------------------ +struct _GLFWmonitor +{ + void* userPointer; + + char* name; + + GLboolean primary; + + // physical dimensions in millimeters. + int physicalWidth; + int physicalHeight; + // logical orientation of the screen on the desktop + int positionX; + int positionY; + + GLFWvidmode* modes; + + // These are defined in the current port's platform.h + _GLFW_PLATFORM_MONITOR_STATE; +}; + +//------------------------------------------------------------------------ // Library global data //------------------------------------------------------------------------ struct _GLFWlibrary @@ -230,13 +256,15 @@ _GLFWwindow* windowListHead; _GLFWwindow* focusedWindow; + _GLFWmonitor** monitors; + int monitorCount; + GLFWmonitorfun monitorCallback; + GLFWgammaramp currentRamp; GLFWgammaramp originalRamp; int originalRampSize; GLboolean rampChanged; - GLFWvidmode* modes; - // This is defined in the current port's platform.h _GLFW_PLATFORM_LIBRARY_WINDOW_STATE; _GLFW_PLATFORM_LIBRARY_OPENGL_STATE; @@ -269,9 +297,13 @@ void _glfwPlatformSetCursorPos(_GLFWwindow* window, int x, int y); void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode); +// Monitor support +_GLFWmonitor** _glfwPlatformGetMonitors(int* count); +void _glfwPlatformDestroyMonitor(_GLFWmonitor* monitor); + // Video mode support -GLFWvidmode* _glfwPlatformGetVideoModes(int* count); -void _glfwPlatformGetDesktopMode(GLFWvidmode* mode); +GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count); +void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode); // Gamma ramp support void _glfwPlatformGetGammaRamp(GLFWgammaramp* ramp); @@ -339,6 +371,9 @@ void _glfwInputCursorMotion(_GLFWwindow* window, int x, int y); void _glfwInputCursorEnter(_GLFWwindow* window, int entered); +// Monitor event notification (monitor.c) +void _glfwInputMonitorChange(void); + //======================================================================== // Prototypes for internal utility functions @@ -363,5 +398,12 @@ GLboolean _glfwIsValidContextConfig(_GLFWwndconfig* wndconfig); GLboolean _glfwIsValidContext(_GLFWwndconfig* wndconfig); +// Monitor management (monitor.c) +_GLFWmonitor* _glfwCreateMonitor(const char* name, + GLboolean primary, + int physicalWidth, int physicalHeight, + int x, int y); +void _glfwDestroyMonitor(_GLFWmonitor* monitor); +void _glfwDestroyMonitors(void); #endif // _internal_h_
diff --git a/src/monitor.c b/src/monitor.c new file mode 100644 index 0000000..2d2d532 --- /dev/null +++ b/src/monitor.c
@@ -0,0 +1,433 @@ +//======================================================================== +// GLFW - An OpenGL framework +// Platform: Any +// API version: 3.0 +// WWW: http://www.glfw.org/ +//------------------------------------------------------------------------ +// Copyright (c) 2002-2006 Marcus Geelnard +// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org> +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would +// be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not +// be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source +// distribution. +// +//======================================================================== + +#include "internal.h" + +#include <string.h> +#include <stdlib.h> +#if defined(_MSC_VER) + #include <malloc.h> + #define strdup _strdup +#endif + + +//======================================================================== +// Lexical comparison function for GLFW video modes, used by qsort +//======================================================================== + +static int compareVideoModes(const void* firstPtr, const void* secondPtr) +{ + int firstBPP, secondBPP, firstSize, secondSize; + GLFWvidmode* first = (GLFWvidmode*) firstPtr; + GLFWvidmode* second = (GLFWvidmode*) secondPtr; + + // First sort on color bits per pixel + + firstBPP = first->redBits + + first->greenBits + + first->blueBits; + secondBPP = second->redBits + + second->greenBits + + second->blueBits; + + if (firstBPP != secondBPP) + return firstBPP - secondBPP; + + // Then sort on screen area, in pixels + + firstSize = first->width * first->height; + secondSize = second->width * second->height; + + return firstSize - secondSize; +} + + +////////////////////////////////////////////////////////////////////////// +////// GLFW internal API ////// +////////////////////////////////////////////////////////////////////////// + +//======================================================================== +// Create a monitor struct from the specified information +//======================================================================== + +_GLFWmonitor* _glfwCreateMonitor(const char* name, + GLboolean primary, + int physicalWidth, int physicalHeight, + int x, int y) +{ + _GLFWmonitor* monitor = (_GLFWmonitor*) calloc(1, sizeof(_GLFWmonitor)); + if (!monitor) + { + _glfwSetError(GLFW_OUT_OF_MEMORY, NULL); + return NULL; + } + + monitor->name = strdup(name); + monitor->primary = primary; + monitor->physicalWidth = physicalWidth; + monitor->physicalHeight = physicalHeight; + monitor->positionX = x; + monitor->positionY = y; + + return monitor; +} + + +//======================================================================== +// Destroy the specified monitor +//======================================================================== + +void _glfwDestroyMonitor(_GLFWmonitor* monitor) +{ + if (monitor == NULL) + return; + + _glfwPlatformDestroyMonitor(monitor); + + free(monitor->modes); + free(monitor->name); + free(monitor); +} + + +//======================================================================== +// Enumerate monitors and notify user of changes +//======================================================================== + +void _glfwInputMonitorChange(void) +{ + int i, j, monitorCount; + _GLFWmonitor** monitors; + + monitors = _glfwPlatformGetMonitors(&monitorCount); + + for (i = 0; i < monitorCount; i++) + { + for (j = 0; j < _glfwLibrary.monitorCount; j++) + { + if (_glfwLibrary.monitors[j] == NULL) + continue; + + if (strcmp(monitors[i]->name, _glfwLibrary.monitors[j]->name) == 0) + { + // This monitor was connected before, so re-use the existing + // monitor object to preserve its address and user pointer + + _glfwDestroyMonitor(monitors[i]); + monitors[i] = _glfwLibrary.monitors[j]; + _glfwLibrary.monitors[j] = NULL; + break; + } + } + + if (j == _glfwLibrary.monitorCount) + { + // This monitor was not connected before + _glfwLibrary.monitorCallback(monitors[i], GLFW_MONITOR_CONNECTED); + } + } + + for (i = 0; i < _glfwLibrary.monitorCount; i++) + { + _GLFWwindow* window; + + if (_glfwLibrary.monitors[i] == NULL) + continue; + + // This monitor is no longer connected + _glfwLibrary.monitorCallback(_glfwLibrary.monitors[i], + GLFW_MONITOR_DISCONNECTED); + + for (window = _glfwLibrary.windowListHead; window; window = window->next) + { + if (window->monitor == _glfwLibrary.monitors[i]) + window->monitor = NULL; + } + } + + _glfwDestroyMonitors(); + + _glfwLibrary.monitors = monitors; + _glfwLibrary.monitorCount = monitorCount; +} + + +//======================================================================== +// Destroy all monitors +//======================================================================== + +void _glfwDestroyMonitors(void) +{ + int i; + + for (i = 0; i < _glfwLibrary.monitorCount; i++) + _glfwDestroyMonitor(_glfwLibrary.monitors[i]); + + free(_glfwLibrary.monitors); + _glfwLibrary.monitors = NULL; + _glfwLibrary.monitorCount = 0; +} + + +//======================================================================== +// Lexical comparison of GLFW video modes +//======================================================================== + +int _glfwCompareVideoModes(const GLFWvidmode* first, const GLFWvidmode* second) +{ + return compareVideoModes(first, second); +} + + +//======================================================================== +// Convert BPP to RGB bits based on "best guess" +//======================================================================== + +void _glfwSplitBPP(int bpp, int* red, int* green, int* blue) +{ + int delta; + + // We assume that by 32 the user really meant 24 + if (bpp == 32) + bpp = 24; + + // Convert "bits per pixel" to red, green & blue sizes + + *red = *green = *blue = bpp / 3; + delta = bpp - (*red * 3); + if (delta >= 1) + *green = *green + 1; + + if (delta == 2) + *red = *red + 1; +} + + +////////////////////////////////////////////////////////////////////////// +////// GLFW public API ////// +////////////////////////////////////////////////////////////////////////// + +//======================================================================== +// Return the currently connected monitors +//======================================================================== + +GLFWAPI GLFWmonitor* glfwGetMonitors(int* count) +{ + if (!_glfwInitialized) + { + _glfwSetError(GLFW_NOT_INITIALIZED, NULL); + return NULL; + } + + if (count == NULL) + { + _glfwSetError(GLFW_INVALID_VALUE, NULL); + return NULL; + } + + *count = _glfwLibrary.monitorCount; + return (GLFWmonitor*) _glfwLibrary.monitors; +} + + +//======================================================================== +// Get the primary monitor +//======================================================================== + +GLFWAPI GLFWmonitor glfwGetPrimaryMonitor(void) +{ + int i; + GLFWmonitor handle = NULL; + + if (!_glfwInitialized) + { + _glfwSetError(GLFW_NOT_INITIALIZED, NULL); + return NULL; + } + + for (i = 0; i < _glfwLibrary.monitorCount; i++) + { + if (_glfwLibrary.monitors[i]->primary) + { + handle = _glfwLibrary.monitors[i]; + break; + } + } + + if (!handle) + { + _glfwSetError(GLFW_PLATFORM_ERROR, NULL); + return NULL; + } + + return handle; +} + + +//======================================================================== +// Get monitor parameter +//======================================================================== + +GLFWAPI int glfwGetMonitorParam(GLFWmonitor handle, int param) +{ + _GLFWmonitor* monitor = (_GLFWmonitor*) handle; + + if (!_glfwInitialized) + { + _glfwSetError(GLFW_NOT_INITIALIZED, NULL); + return 0; + } + + if (monitor == NULL) + { + _glfwSetError(GLFW_INVALID_VALUE, + "glfwGetMonitorParam: Invalid monitor handle"); + return 0; + } + + switch (param) + { + case GLFW_MONITOR_PHYSICAL_WIDTH: + return monitor->physicalWidth; + case GLFW_MONITOR_PHYSICAL_HEIGHT: + return monitor->physicalHeight; + case GLFW_MONITOR_POS_X: + return monitor->positionX; + case GLFW_MONITOR_POS_Y: + return monitor->positionY; + } + + _glfwSetError(GLFW_INVALID_ENUM, + "glfwGetMonitorParam: Invalid enum value for 'param' parameter"); + return 0; +} + + +//======================================================================== +// Get monitor string +//======================================================================== + +GLFWAPI const char* glfwGetMonitorName(GLFWmonitor handle) +{ + _GLFWmonitor* monitor = (_GLFWmonitor*) handle; + + if (!_glfwInitialized) + { + _glfwSetError(GLFW_NOT_INITIALIZED, NULL); + return NULL; + } + + if (monitor == NULL) + { + _glfwSetError(GLFW_INVALID_VALUE, + "glfwGetMonitorString: Invalid monitor handle"); + return NULL; + } + + return monitor->name; +} + + +//======================================================================== +// Set a callback function for monitor events +//======================================================================== + +GLFWAPI void glfwSetMonitorCallback(GLFWmonitorfun cbfun) +{ + if (!_glfwInitialized) + { + _glfwSetError(GLFW_NOT_INITIALIZED, NULL); + return; + } + + _glfwLibrary.monitorCallback= cbfun; +} + + +//======================================================================== +// Get a list of available video modes +//======================================================================== + +GLFWAPI GLFWvidmode* glfwGetVideoModes(GLFWmonitor handle, int* count) +{ + _GLFWmonitor* monitor = (_GLFWmonitor*) handle; + + if (!_glfwInitialized) + { + _glfwSetError(GLFW_NOT_INITIALIZED, NULL); + return NULL; + } + + if (monitor == NULL) + { + _glfwSetError(GLFW_INVALID_VALUE, + "glfwGetVideoModes: Invalid monitor handle"); + return 0; + } + + if (count == NULL) + { + _glfwSetError(GLFW_INVALID_VALUE, NULL); + return NULL; + } + + free(monitor->modes); + + monitor->modes = _glfwPlatformGetVideoModes(monitor, count); + if (monitor->modes) + qsort(monitor->modes, *count, sizeof(GLFWvidmode), compareVideoModes); + + return monitor->modes; +} + + +//======================================================================== +// Get the current video mode for the specified monitor +//======================================================================== + +GLFWAPI void glfwGetVideoMode(GLFWmonitor handle, GLFWvidmode* mode) +{ + _GLFWmonitor* monitor = (_GLFWmonitor*) handle; + + if (!_glfwInitialized) + { + _glfwSetError(GLFW_NOT_INITIALIZED, NULL); + return; + } + + if (mode == NULL) + { + _glfwSetError(GLFW_INVALID_VALUE, NULL); + return; + } + + _glfwPlatformGetVideoMode(monitor, mode); +} +
diff --git a/src/win32_fullscreen.c b/src/win32_monitor.c similarity index 68% rename from src/win32_fullscreen.c rename to src/win32_monitor.c index 26740d1..02b3a48 100644 --- a/src/win32_fullscreen.c +++ b/src/win32_monitor.c
@@ -1,6 +1,6 @@ //======================================================================== // GLFW - An OpenGL library -// Platform: Win32 +// Platform: X11 (Unix) // API version: 3.0 // WWW: http://www.glfw.org/ //------------------------------------------------------------------------ @@ -31,9 +31,18 @@ #include "internal.h" #include <stdlib.h> +#include <string.h> #include <limits.h> #include <malloc.h> +// These constants are missing on MinGW +#ifndef EDS_ROTATEDMODE + #define EDS_ROTATEDMODE 0x00000004 +#endif +#ifndef DISPLAY_DEVICE_ACTIVE + #define DISPLAY_DEVICE_ACTIVE 0x00000001 +#endif + //======================================================================== // Return closest video mode by dimensions, refresh rate and bits per pixel @@ -180,12 +189,116 @@ ////////////////////////////////////////////////////////////////////////// //======================================================================== +// Return a list of available monitors +//======================================================================== + +_GLFWmonitor** _glfwPlatformGetMonitors(int* count) +{ + int size = 0, found = 0; + _GLFWmonitor** monitors = NULL; + DWORD adapterIndex = 0; + + for (;;) + { + // Enumerate display adapters + + DISPLAY_DEVICE adapter, monitor; + DEVMODE settings; + const char* name; + HDC dc; + + ZeroMemory(&adapter, sizeof(DISPLAY_DEVICE)); + adapter.cb = sizeof(DISPLAY_DEVICE); + + if (!EnumDisplayDevices(NULL, adapterIndex, &adapter, 0)) + break; + + adapterIndex++; + + if ((adapter.StateFlags & DISPLAY_DEVICE_MIRRORING_DRIVER) || + !(adapter.StateFlags & DISPLAY_DEVICE_ACTIVE)) + { + continue; + } + + ZeroMemory(&settings, sizeof(DEVMODE)); + settings.dmSize = sizeof(DEVMODE); + + EnumDisplaySettingsEx(adapter.DeviceName, + ENUM_CURRENT_SETTINGS, + &settings, + EDS_ROTATEDMODE); + + name = _glfwCreateUTF8FromWideString(adapter.DeviceName); + if (!name) + { + // TODO: wat + return NULL; + } + + if (found == size) + { + if (size) + size *= 2; + else + size = 4; + + monitors = (_GLFWmonitor**) realloc(monitors, sizeof(_GLFWmonitor*) * size); + if (!monitors) + { + // TODO: wat + return NULL; + } + } + + ZeroMemory(&monitor, sizeof(DISPLAY_DEVICE)); + monitor.cb = sizeof(DISPLAY_DEVICE); + + EnumDisplayDevices(adapter.DeviceName, 0, &monitor, 0); + dc = CreateDC(L"DISPLAY", monitor.DeviceString, NULL, NULL); + + const GLboolean primary = adapter.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE; + + monitors[found] = _glfwCreateMonitor(name, primary, + GetDeviceCaps(dc, HORZSIZE), + GetDeviceCaps(dc, VERTSIZE), + settings.dmPosition.x, + settings.dmPosition.y); + + DeleteDC(dc); + + if (!monitors[found]) + { + // TODO: wat + return NULL; + } + + monitors[found]->Win32.name = _wcsdup(adapter.DeviceName); + found++; + } + + *count = found; + return monitors; +} + + +//======================================================================== +// Destroy a monitor struct +//======================================================================== + +void _glfwPlatformDestroyMonitor(_GLFWmonitor* monitor) +{ + free(monitor->Win32.name); +} + + +//======================================================================== // Get a list of available video modes //======================================================================== -GLFWvidmode* _glfwPlatformGetVideoModes(int* found) +GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* found) { - int dmIndex = 0, count = 0; + int modeIndex = 0, count = 0; GLFWvidmode* result = NULL; *found = 0; @@ -199,10 +312,10 @@ ZeroMemory(&dm, sizeof(DEVMODE)); dm.dmSize = sizeof(DEVMODE); - if (!EnumDisplaySettings(NULL, dmIndex, &dm)) + if (!EnumDisplaySettings(monitor->Win32.name, modeIndex, &dm)) break; - dmIndex++; + modeIndex++; if (dm.dmBitsPerPel < 15) { @@ -213,9 +326,9 @@ mode.width = dm.dmPelsWidth; mode.height = dm.dmPelsHeight; _glfwSplitBPP(dm.dmBitsPerPel, - &mode.redBits, - &mode.greenBits, - &mode.blueBits); + &mode.redBits, + &mode.greenBits, + &mode.blueBits); for (i = 0; i < *found; i++) { @@ -259,18 +372,18 @@ //======================================================================== -// Get the desktop video mode +// Get the current video mode for the specified monitor //======================================================================== -void _glfwPlatformGetDesktopMode(GLFWvidmode* mode) +void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode) { DEVMODE dm; - // Get desktop display mode + ZeroMemory(&dm, sizeof(DEVMODE)); dm.dmSize = sizeof(DEVMODE); - EnumDisplaySettings(NULL, ENUM_REGISTRY_SETTINGS, &dm); - // Return desktop mode parameters + EnumDisplaySettings(monitor->Win32.name, ENUM_REGISTRY_SETTINGS, &dm); + mode->width = dm.dmPelsWidth; mode->height = dm.dmPelsHeight; _glfwSplitBPP(dm.dmBitsPerPel,
diff --git a/src/win32_platform.h b/src/win32_platform.h index 30d5534..4a6495a 100644 --- a/src/win32_platform.h +++ b/src/win32_platform.h
@@ -62,6 +62,7 @@ #include <windows.h> #include <mmsystem.h> +#include <dbt.h> //======================================================================== @@ -117,6 +118,7 @@ #define _GLFW_PLATFORM_WINDOW_STATE _GLFWwindowWin32 Win32 #define _GLFW_PLATFORM_LIBRARY_WINDOW_STATE _GLFWlibraryWin32 Win32 +#define _GLFW_PLATFORM_MONITOR_STATE _GLFWmonitorWin32 Win32 //======================================================================== @@ -190,6 +192,16 @@ } _GLFWlibraryWin32; +//------------------------------------------------------------------------ +// Platform-specific monitor structure +//------------------------------------------------------------------------ +typedef struct _GLFWmonitorWin32 +{ + WCHAR* name; + +} _GLFWmonitorWin32; + + //======================================================================== // Prototypes for platform specific internal functions //========================================================================
diff --git a/src/win32_window.c b/src/win32_window.c index a99f08d..3f2228c 100644 --- a/src/win32_window.c +++ b/src/win32_window.c
@@ -30,7 +30,6 @@ #include "internal.h" -#include <stdio.h> #include <stdlib.h> #include <malloc.h> #include <windowsx.h> @@ -348,7 +347,7 @@ if (window->cursorMode == GLFW_CURSOR_CAPTURED) showCursor(window); - if (window->mode == GLFW_FULLSCREEN) + if (window->monitor) { if (!iconified) { @@ -371,7 +370,7 @@ if (window->cursorMode == GLFW_CURSOR_CAPTURED) captureCursor(window); - if (window->mode == GLFW_FULLSCREEN) + if (window->monitor) { if (!_glfwLibrary.Win32.monitor.modeChanged) { @@ -404,7 +403,7 @@ case SC_SCREENSAVE: case SC_MONITORPOWER: { - if (window->mode == GLFW_FULLSCREEN) + if (window->monitor) { // We are running in fullscreen mode, so disallow // screen saver and screen blanking @@ -641,6 +640,16 @@ break; } + + case WM_DEVICECHANGE: + { + if (DBT_DEVNODES_CHANGED == wParam) + { + _glfwInputMonitorChange(); + return TRUE; + } + break; + } } // Pass all unhandled messages to DefWindowProc @@ -722,8 +731,7 @@ const _GLFWfbconfig* fbconfig) { DWORD dwStyle, dwExStyle; - int fullWidth, fullHeight; - RECT wa; + int positionX, positionY, fullWidth, fullHeight; POINT pos; WCHAR* wideTitle; @@ -732,7 +740,7 @@ dwExStyle = WS_EX_APPWINDOW; // Set window style, depending on fullscreen mode - if (window->mode == GLFW_FULLSCREEN) + if (window->monitor) { dwStyle |= WS_POPUP; @@ -766,16 +774,21 @@ // Adjust window size for frame and title bar getFullWindowSize(window, window->width, window->height, &fullWidth, &fullHeight); - // Adjust window position to working area (e.g. if the task bar is at - // the top of the display). Fullscreen windows are always opened in - // the upper left corner regardless of the desktop working area. - if (window->mode == GLFW_FULLSCREEN) - wa.left = wa.top = 0; + if (window->monitor) + { + // Fullscreen windows are always opened in the upper left corner + // regardless of the desktop working area + positionX = wndconfig->monitor->positionX; + positionY = wndconfig->monitor->positionY; + } else { + RECT wa; SystemParametersInfo(SPI_GETWORKAREA, 0, &wa, 0); - wa.left += wndconfig->positionX; - wa.top += wndconfig->positionY; + + // Adjust window position to working area + positionX = wndconfig->positionX + wa.left; + positionY = wndconfig->positionY + wa.top; } wideTitle = _glfwCreateWideStringFromUTF8(wndconfig->title); @@ -790,7 +803,7 @@ _GLFW_WNDCLASSNAME, wideTitle, window->Win32.dwStyle, - wa.left, wa.top, // Window position + positionX, positionY, fullWidth, // Decorated window width fullHeight, // Decorated window height NULL, // No parent window @@ -864,7 +877,7 @@ return GL_FALSE; } - if (window->mode == GLFW_FULLSCREEN) + if (window->monitor) { int bpp = fbconfig->redBits + fbconfig->greenBits + fbconfig->blueBits; if (bpp < 15 || bpp >= 24) @@ -968,7 +981,7 @@ return GL_FALSE; } - if (window->mode == GLFW_FULLSCREEN) + if (window->monitor) { // Place the window above all topmost windows _glfwPlatformShowWindow(window); @@ -988,7 +1001,7 @@ { destroyWindow(window); - if (window->mode == GLFW_FULLSCREEN) + if (window->monitor) { if (_glfwLibrary.Win32.monitor.modeChanged) { @@ -1027,7 +1040,7 @@ { GLboolean sizeChanged = GL_FALSE; - if (window->mode == GLFW_FULLSCREEN) + if (window->monitor) { if (width > window->width || height > window->height) { @@ -1251,3 +1264,4 @@ } } +
diff --git a/src/window.c b/src/window.c index d402646..9e43083 100644 --- a/src/window.c +++ b/src/window.c
@@ -206,7 +206,8 @@ //======================================================================== GLFWAPI GLFWwindow glfwCreateWindow(int width, int height, - int mode, const char* title, + const char* title, + GLFWmonitor monitor, GLFWwindow share) { _GLFWfbconfig fbconfig; @@ -240,7 +241,6 @@ fbconfig.sRGB = _glfwLibrary.hints.sRGB ? GL_TRUE : GL_FALSE; // Set up desired window config - wndconfig.mode = mode; wndconfig.title = title; wndconfig.refreshRate = Max(_glfwLibrary.hints.refreshRate, 0); wndconfig.resizable = _glfwLibrary.hints.resizable ? GL_TRUE : GL_FALSE; @@ -254,6 +254,7 @@ wndconfig.glDebug = _glfwLibrary.hints.glDebug ? GL_TRUE : GL_FALSE; wndconfig.glProfile = _glfwLibrary.hints.glProfile; wndconfig.glRobustness = _glfwLibrary.hints.glRobustness ? GL_TRUE : GL_FALSE; + wndconfig.monitor = (_GLFWmonitor*) monitor; wndconfig.share = (_GLFWwindow*) share; // Check the OpenGL bits of the window config @@ -263,13 +264,6 @@ // Save the currently current context so it can be restored later previous = glfwGetCurrentContext(); - if (mode != GLFW_WINDOWED && mode != GLFW_FULLSCREEN) - { - _glfwSetError(GLFW_INVALID_ENUM, - "glfwCreateWindow: Invalid window mode"); - return GL_FALSE; - } - if (width <= 0 || height <= 0) { _glfwSetError(GLFW_INVALID_VALUE, @@ -290,9 +284,9 @@ // Remember window settings window->width = width; window->height = height; - window->mode = mode; window->resizable = wndconfig.resizable; window->cursorMode = GLFW_CURSOR_NORMAL; + window->monitor = (_GLFWmonitor*) monitor; // Open the actual window and create its context if (!_glfwPlatformCreateWindow(window, &wndconfig, &fbconfig)) @@ -333,10 +327,10 @@ // The GLFW specification states that fullscreen windows have the cursor // captured by default - if (mode == GLFW_FULLSCREEN) + if (wndconfig.monitor) glfwSetInputMode(window, GLFW_CURSOR_MODE, GLFW_CURSOR_CAPTURED); - if (mode == GLFW_WINDOWED && wndconfig.visible) + if (wndconfig.monitor == NULL && wndconfig.visible) glfwShowWindow(window); return window; @@ -587,7 +581,7 @@ _glfwPlatformSetWindowSize(window, width, height); - if (window->mode == GLFW_FULLSCREEN) + if (window->monitor) { // Refresh window parameters (may have changed due to changed video // modes) @@ -636,7 +630,7 @@ _glfwPlatformRestoreWindow(window); - if (window->mode == GLFW_FULLSCREEN) + if (window->monitor) _glfwPlatformRefreshWindowParams(window); } @@ -655,7 +649,7 @@ return; } - if (window->mode == GLFW_FULLSCREEN) + if (window->monitor) return; _glfwPlatformShowWindow(window); @@ -676,7 +670,7 @@ return; } - if (window->mode == GLFW_FULLSCREEN) + if (window->monitor) return; _glfwPlatformHideWindow(window); @@ -739,6 +733,24 @@ //======================================================================== +// Get window monitor +//======================================================================== + +GLFWAPI GLFWmonitor glfwGetWindowMonitor(GLFWwindow handle) +{ + _GLFWwindow* window = (_GLFWwindow*) handle; + + if (!_glfwInitialized) + { + _glfwSetError(GLFW_NOT_INITIALIZED, NULL); + return NULL; + } + + return (GLFWmonitor) window->monitor; +} + + +//======================================================================== // Set the user pointer for the specified window //========================================================================
diff --git a/src/x11_gamma.c b/src/x11_gamma.c index 148ae74..f963b5a 100644 --- a/src/x11_gamma.c +++ b/src/x11_gamma.c
@@ -59,9 +59,9 @@ _glfwLibrary.originalRampSize = XRRGetCrtcGammaSize(_glfwLibrary.X11.display, rr->crtcs[0]); - if (!_glfwLibrary.originalRampSize) + if (_glfwLibrary.originalRampSize == 0) { - // This is probably Nvidia RandR with broken gamma support + // This is probably older Nvidia RandR with broken gamma support // Flag it as useless and try Xf86VidMode below, if available _glfwLibrary.X11.RandR.gammaBroken = GL_TRUE; }
diff --git a/src/x11_fullscreen.c b/src/x11_monitor.c similarity index 67% rename from src/x11_fullscreen.c rename to src/x11_monitor.c index 9b1121f..e9e0a88 100644 --- a/src/x11_fullscreen.c +++ b/src/x11_monitor.c
@@ -1,6 +1,6 @@ //======================================================================== // GLFW - An OpenGL library -// Platform: X11 +// Platform: X11 (Unix) // API version: 3.0 // WWW: http://www.glfw.org/ //------------------------------------------------------------------------ @@ -50,9 +50,8 @@ // List available resolutions //======================================================================== -static _GLFWvidsize* getResolutions(int* found) +static _GLFWvidsize* getResolutions(_GLFWmonitor* monitor, int* found) { - int i, j; _GLFWvidsize* result = NULL; *found = 0; @@ -62,50 +61,42 @@ if (_glfwLibrary.X11.RandR.available) { #if defined(_GLFW_HAS_XRANDR) - XRRScreenConfiguration* sc; - XRRScreenSize* sizes; + XRRScreenResources* sr; + int i, j, count = monitor->X11.output->nmode; - sc = XRRGetScreenInfo(_glfwLibrary.X11.display, _glfwLibrary.X11.root); - sizes = XRRConfigSizes(sc, found); + sr = XRRGetScreenResources(_glfwLibrary.X11.display, + _glfwLibrary.X11.root); - result = (_GLFWvidsize*) malloc(sizeof(_GLFWvidsize) * *found); + result = (_GLFWvidsize*) malloc(sizeof(_GLFWvidsize) * count); - for (i = 0; i < *found; i++) - { - result[i].width = sizes[i].width; - result[i].height = sizes[i].height; - } - - XRRFreeScreenConfigInfo(sc); -#endif /*_GLFW_HAS_XRANDR*/ - } - else if (_glfwLibrary.X11.VidMode.available) - { -#if defined(_GLFW_HAS_XF86VIDMODE) - XF86VidModeModeInfo** modes; - int modeCount; - - XF86VidModeGetAllModeLines(_glfwLibrary.X11.display, - _glfwLibrary.X11.screen, - &modeCount, &modes); - - result = (_GLFWvidsize*) malloc(sizeof(_GLFWvidsize) * modeCount); - - for (i = 0; i < modeCount; i++) + for (i = 0; i < count; i++) { _GLFWvidsize size; - size.width = modes[i]->hdisplay; - size.height = modes[i]->vdisplay; + + for (j = 0; j < sr->nmode; j++) + { + if (sr->modes[j].id == monitor->X11.output->modes[i]) + break; + } + + if (j == sr->nmode) + continue; + + size.width = sr->modes[j].width; + size.height = sr->modes[j].height; for (j = 0; j < *found; j++) { - if (memcmp(result + j, &size, sizeof(_GLFWvidsize)) == 0) + if (result[j].width == size.width && + result[j].height == size.height) + { break; + } } if (j < *found) { - // This size is a duplicate, so skip it + // This is a duplicate, so skip it continue; } @@ -113,8 +104,8 @@ (*found)++; } - XFree(modes); -#endif /*_GLFW_HAS_XF86VIDMODE*/ + XRRFreeScreenResources(sr); +#endif /*_GLFW_HAS_XRANDR*/ } if (result == NULL) @@ -207,46 +198,6 @@ return bestsize; #endif /*_GLFW_HAS_XRANDR*/ } - else if (_glfwLibrary.X11.VidMode.available) - { -#if defined(_GLFW_HAS_XF86VIDMODE) - XF86VidModeModeInfo** modelist; - int bestmode, modecount; - - // Get a list of all available display modes - XF86VidModeGetAllModeLines(_glfwLibrary.X11.display, - _glfwLibrary.X11.screen, - &modecount, &modelist); - - // Find the best matching mode - bestmode = -1; - bestmatch = INT_MAX; - for (i = 0; i < modecount; i++) - { - match = (*width - modelist[i]->hdisplay) * - (*width - modelist[i]->hdisplay) + - (*height - modelist[i]->vdisplay) * - (*height - modelist[i]->vdisplay); - if (match < bestmatch) - { - bestmatch = match; - bestmode = i; - } - } - - if (bestmode != -1) - { - // Report width & height of best matching mode - *width = modelist[bestmode]->hdisplay; - *height = modelist[bestmode]->vdisplay; - } - - XFree(modelist); - - if (bestmode != -1) - return bestmode; -#endif /*_GLFW_HAS_XF86VIDMODE*/ - } // Default: Simply use the screen resolution *width = DisplayWidth(_glfwLibrary.X11.display, _glfwLibrary.X11.screen); @@ -308,50 +259,6 @@ XRRFreeScreenConfigInfo(sc); #endif /*_GLFW_HAS_XRANDR*/ } - else if (_glfwLibrary.X11.VidMode.available) - { -#if defined(_GLFW_HAS_XF86VIDMODE) - XF86VidModeModeInfo **modelist; - int modecount; - - // Get a list of all available display modes - XF86VidModeGetAllModeLines(_glfwLibrary.X11.display, - _glfwLibrary.X11.screen, - &modecount, &modelist); - - // Unlock mode switch if necessary - if (_glfwLibrary.X11.FS.modeChanged) - { - XF86VidModeLockModeSwitch(_glfwLibrary.X11.display, - _glfwLibrary.X11.screen, - 0); - } - - // Change the video mode to the desired mode - XF86VidModeSwitchToMode(_glfwLibrary.X11.display, - _glfwLibrary.X11.screen, - modelist[mode]); - - // Set viewport to upper left corner (where our window will be) - XF86VidModeSetViewPort(_glfwLibrary.X11.display, - _glfwLibrary.X11.screen, - 0, 0); - - // Lock mode switch - XF86VidModeLockModeSwitch(_glfwLibrary.X11.display, - _glfwLibrary.X11.screen, - 1); - - // Remember old mode and flag that we have changed the mode - if (!_glfwLibrary.X11.FS.modeChanged) - { - _glfwLibrary.X11.FS.oldMode = *modelist[0]; - _glfwLibrary.X11.FS.modeChanged = GL_TRUE; - } - - XFree(modelist); -#endif /*_GLFW_HAS_XF86VIDMODE*/ - } } @@ -400,20 +307,6 @@ } #endif /*_GLFW_HAS_XRANDR*/ } - else if (_glfwLibrary.X11.VidMode.available) - { -#if defined(_GLFW_HAS_XF86VIDMODE) - // Unlock mode switch - XF86VidModeLockModeSwitch(_glfwLibrary.X11.display, - _glfwLibrary.X11.screen, - 0); - - // Change the video mode back to the old mode - XF86VidModeSwitchToMode(_glfwLibrary.X11.display, - _glfwLibrary.X11.screen, - &_glfwLibrary.X11.FS.oldMode); -#endif /*_GLFW_HAS_XF86VIDMODE*/ - } _glfwLibrary.X11.FS.modeChanged = GL_FALSE; } @@ -426,10 +319,105 @@ //======================================================================== +// Return a list of available monitors +//======================================================================== + +_GLFWmonitor** _glfwPlatformGetMonitors(int* count) +{ + int found = 0; + _GLFWmonitor** monitors = NULL; + + if (_glfwLibrary.X11.RandR.available) + { +#if defined (_GLFW_HAS_XRANDR) + int i; + XRRScreenResources* sr; + + sr = XRRGetScreenResources(_glfwLibrary.X11.display, + _glfwLibrary.X11.root); + + monitors = (_GLFWmonitor**) calloc(sr->noutput, sizeof(_GLFWmonitor*)); + if (!monitors) + { + XRRFreeScreenResources(sr); + + _glfwSetError(GLFW_OUT_OF_MEMORY, NULL); + return NULL; + } + + for (i = 0; i < sr->noutput; i++) + { + XRROutputInfo* oi; + XRRCrtcInfo* ci; + int physicalWidth, physicalHeight; + + oi = XRRGetOutputInfo(_glfwLibrary.X11.display, sr, sr->outputs[i]); + if (oi->connection != RR_Connected) + { + XRRFreeOutputInfo(oi); + continue; + } + + if (oi->mm_width && oi->mm_height) + { + physicalWidth = oi->mm_width; + physicalHeight = oi->mm_height; + } + else + { + physicalWidth = DisplayWidthMM(_glfwLibrary.X11.display, + _glfwLibrary.X11.screen); + physicalHeight = DisplayHeightMM(_glfwLibrary.X11.display, + _glfwLibrary.X11.screen); + } + + ci = XRRGetCrtcInfo(_glfwLibrary.X11.display, sr, oi->crtc); + + monitors[found] = _glfwCreateMonitor(oi->name, + i == 0, + physicalWidth, physicalHeight, + ci->x, ci->y); + + XRRFreeCrtcInfo(ci); + + if (!monitors[found]) + { + // TODO: wat + return NULL; + } + + // This is retained until the monitor object is destroyed + monitors[found]->X11.output = oi; + found++; + } +#endif /*_GLFW_HAS_XRANDR*/ + } + + *count = found; + return monitors; +} + + +//======================================================================== +// Destroy a monitor struct +//======================================================================== + +void _glfwPlatformDestroyMonitor(_GLFWmonitor* monitor) +{ + if (_glfwLibrary.X11.RandR.available) + { +#if defined (_GLFW_HAS_XRANDR) + XRRFreeOutputInfo(monitor->X11.output); +#endif /*_GLFW_HAS_XRANDR*/ + } +} + + +//======================================================================== // List available video modes //======================================================================== -GLFWvidmode* _glfwPlatformGetVideoModes(int* found) +GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* found) { XVisualInfo* visuals; XVisualInfo dummy; @@ -488,7 +476,7 @@ // Build all permutations of channel depths and resolutions - sizes = getResolutions(&sizeCount); + sizes = getResolutions(monitor, &sizeCount); result = (GLFWvidmode*) malloc(sizeof(GLFWvidmode) * rgbCount * sizeCount); *found = 0; @@ -515,40 +503,54 @@ //======================================================================== -// Get the desktop video mode +// Get the current video mode for the specified monitor //======================================================================== -void _glfwPlatformGetDesktopMode(GLFWvidmode* mode) +void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode) { - int bpp; - - // Get and split display depth - bpp = DefaultDepth(_glfwLibrary.X11.display, _glfwLibrary.X11.screen); - _glfwSplitBPP(bpp, &mode->redBits, &mode->greenBits, &mode->blueBits); - - if (_glfwLibrary.X11.FS.modeChanged) + if (_glfwLibrary.X11.RandR.available) { - if (_glfwLibrary.X11.RandR.available) +#if defined (_GLFW_HAS_XRANDR) + XRRScreenResources* sr; + XRRCrtcInfo* ci; + + sr = XRRGetScreenResources(_glfwLibrary.X11.display, + _glfwLibrary.X11.root); + if (!sr) { -#if defined(_GLFW_HAS_XRANDR) - mode->width = _glfwLibrary.X11.FS.oldWidth; - mode->height = _glfwLibrary.X11.FS.oldHeight; + _glfwSetError(GLFW_PLATFORM_ERROR, + "X11: Failed to retrieve RandR screen resources"); + return; + } + + ci = XRRGetCrtcInfo(_glfwLibrary.X11.display, + sr, monitor->X11.output->crtc); + if (!ci) + { + XRRFreeScreenResources(sr); + + _glfwSetError(GLFW_PLATFORM_ERROR, + "X11: Failed to retrieve RandR crtc info"); + return; + } + + mode->width = ci->width; + mode->height = ci->height; + + XRRFreeCrtcInfo(ci); + XRRFreeScreenResources(sr); #endif /*_GLFW_HAS_XRANDR*/ - } - else if (_glfwLibrary.X11.VidMode.available) - { -#if defined(_GLFW_HAS_XF86VIDMODE) - mode->width = _glfwLibrary.X11.FS.oldMode.hdisplay; - mode->height = _glfwLibrary.X11.FS.oldMode.vdisplay; -#endif /*_GLFW_HAS_XF86VIDMODE*/ - } } else { mode->width = DisplayWidth(_glfwLibrary.X11.display, - _glfwLibrary.X11.screen); + _glfwLibrary.X11.screen); mode->height = DisplayHeight(_glfwLibrary.X11.display, - _glfwLibrary.X11.screen); + _glfwLibrary.X11.screen); } + + _glfwSplitBPP(DefaultDepth(_glfwLibrary.X11.display, + _glfwLibrary.X11.screen), + &mode->redBits, &mode->greenBits, &mode->blueBits); }
diff --git a/src/x11_platform.h b/src/x11_platform.h index 87c46d8..6e94cd5 100644 --- a/src/x11_platform.h +++ b/src/x11_platform.h
@@ -67,6 +67,7 @@ #define _GLFW_PLATFORM_WINDOW_STATE _GLFWwindowX11 X11 #define _GLFW_PLATFORM_LIBRARY_WINDOW_STATE _GLFWlibraryX11 X11 +#define _GLFW_PLATFORM_MONITOR_STATE _GLFWmonitorX11 X11 // Clipboard format atom indices #define _GLFW_CLIPBOARD_FORMAT_UTF8 0 @@ -217,6 +218,20 @@ } _GLFWlibraryX11; +//------------------------------------------------------------------------ +// Platform-specific monitor structure +//------------------------------------------------------------------------ +typedef struct _GLFWmonitorX11 +{ +#if defined(_GLFW_HAS_XRANDR) + XRROutputInfo* output; +#else + int dummy; +#endif /*_GLFW_HAS_XRANDR*/ + +} _GLFWmonitorX11; + + //======================================================================== // Prototypes for platform specific internal functions //========================================================================
diff --git a/src/x11_window.c b/src/x11_window.c index bc880d7..54436d2 100644 --- a/src/x11_window.c +++ b/src/x11_window.c
@@ -103,11 +103,11 @@ wa.colormap = window->X11.colormap; wa.border_pixel = 0; wa.event_mask = StructureNotifyMask | KeyPressMask | KeyReleaseMask | - PointerMotionMask | ButtonPressMask | ButtonReleaseMask | - ExposureMask | FocusChangeMask | VisibilityChangeMask | - EnterWindowMask | LeaveWindowMask; + PointerMotionMask | ButtonPressMask | ButtonReleaseMask | + ExposureMask | FocusChangeMask | VisibilityChangeMask | + EnterWindowMask | LeaveWindowMask; - if (wndconfig->mode == GLFW_WINDOWED) + if (wndconfig->monitor == NULL) { // The /only/ reason for setting the background pixel here is that // otherwise our window won't get any decorations on systems using @@ -144,7 +144,7 @@ window->X11.positionY = wndconfig->positionY; } - if (window->mode == GLFW_FULLSCREEN && !_glfwLibrary.X11.hasEWMH) + if (window->monitor && !_glfwLibrary.X11.hasEWMH) { // This is the butcher's way of removing window decorations // Setting the override-redirect attribute on a window makes the window @@ -221,6 +221,13 @@ hints->flags = 0; + if (wndconfig->monitor) + { + hints->flags |= PPosition; + hints->x = wndconfig->monitor->positionX; + hints->y = wndconfig->monitor->positionY; + } + if (!wndconfig->resizable) { hints->flags |= (PMinSize | PMaxSize); @@ -247,7 +254,7 @@ // Un-grab cursor (in windowed mode only; in fullscreen mode we still // want the cursor grabbed in order to confine the cursor to the window // area) - if (window->X11.cursorGrabbed && window->mode == GLFW_WINDOWED) + if (window->X11.cursorGrabbed && window->monitor == NULL) { XUngrabPointer(_glfwLibrary.X11.display, CurrentTime); window->X11.cursorGrabbed = GL_FALSE; @@ -295,7 +302,7 @@ // Un-grab cursor (in windowed mode only; in fullscreen mode we still // want the cursor grabbed in order to confine the cursor to the window // area) - if (window->X11.cursorGrabbed && window->mode == GLFW_WINDOWED) + if (window->X11.cursorGrabbed && window->monitor == NULL) { XUngrabPointer(_glfwLibrary.X11.display, CurrentTime); window->X11.cursorGrabbed = GL_FALSE; @@ -825,6 +832,7 @@ case RRScreenChangeNotify: { XRRUpdateConfiguration(event); + _glfwInputMonitorChange(); break; } } @@ -855,18 +863,18 @@ if (!createWindow(window, wndconfig)) return GL_FALSE; - if (wndconfig->mode == GLFW_FULLSCREEN) - { #if defined(_GLFW_HAS_XRANDR) - // Request screen change notifications - if (_glfwLibrary.X11.RandR.available) - { - XRRSelectInput(_glfwLibrary.X11.display, - window->X11.handle, - RRScreenChangeNotifyMask); - } + // Request screen change notifications + if (_glfwLibrary.X11.RandR.available) + { + XRRSelectInput(_glfwLibrary.X11.display, + window->X11.handle, + RRScreenChangeNotifyMask); + } #endif /*_GLFW_HAS_XRANDR*/ + if (wndconfig->monitor) + { _glfwPlatformShowWindow(window); enterFullscreenMode(window); } @@ -901,7 +909,7 @@ void _glfwPlatformDestroyWindow(_GLFWwindow* window) { - if (window->mode == GLFW_FULLSCREEN) + if (window->monitor) leaveFullscreenMode(window); _glfwDestroyContext(window); @@ -973,7 +981,7 @@ rate = window->refreshRate; - if (window->mode == GLFW_FULLSCREEN) + if (window->monitor) { // Get the closest matching video mode for the specified window size mode = _glfwGetClosestVideoMode(&width, &height, &rate); @@ -993,15 +1001,17 @@ XFree(hints); } - // Change window size before changing fullscreen mode? - if (window->mode == GLFW_FULLSCREEN && (width > window->width)) + if (window->monitor) { - XResizeWindow(_glfwLibrary.X11.display, window->X11.handle, width, height); - sizeChanged = GL_TRUE; - } + // Change window size before changing fullscreen mode? + if (width > window->width) + { + XResizeWindow(_glfwLibrary.X11.display, + window->X11.handle, + width, height); + sizeChanged = GL_TRUE; + } - if (window->mode == GLFW_FULLSCREEN) - { // Change video mode, keeping current refresh rate _glfwSetVideoModeMODE(mode, window->refreshRate); } @@ -1096,22 +1106,6 @@ XRRFreeScreenConfigInfo(sc); #endif /*_GLFW_HAS_XRANDR*/ } - else if (_glfwLibrary.X11.VidMode.available) - { -#if defined(_GLFW_HAS_XF86VIDMODE) - XF86VidModeModeLine modeline; - int dotclock; - float pixels_per_second, pixels_per_frame; - - // Use the XF86VidMode extension to get current video mode - XF86VidModeGetModeLine(_glfwLibrary.X11.display, - _glfwLibrary.X11.screen, - &dotclock, &modeline); - pixels_per_second = 1000.0f * (float) dotclock; - pixels_per_frame = (float) modeline.htotal * modeline.vtotal; - window->refreshRate = (int) (pixels_per_second / pixels_per_frame + 0.5); -#endif /*_GLFW_HAS_XF86VIDMODE*/ - } else { // Zero means unknown according to the GLFW spec
diff --git a/tests/accuracy.c b/tests/accuracy.c index d320f64..e26d045 100644 --- a/tests/accuracy.c +++ b/tests/accuracy.c
@@ -86,7 +86,7 @@ exit(EXIT_FAILURE); } - window = glfwCreateWindow(window_width, window_height, GLFW_WINDOWED, "", NULL); + window = glfwCreateWindow(window_width, window_height, "", NULL, NULL); if (!window) { glfwTerminate();
diff --git a/tests/clipboard.c b/tests/clipboard.c index c3746f1..b986174 100644 --- a/tests/clipboard.c +++ b/tests/clipboard.c
@@ -125,7 +125,7 @@ exit(EXIT_FAILURE); } - window = glfwCreateWindow(200, 200, GLFW_WINDOWED, "Clipboard Test", NULL); + window = glfwCreateWindow(200, 200, "Clipboard Test", NULL, NULL); if (!window) { glfwTerminate();
diff --git a/tests/defaults.c b/tests/defaults.c index b1103ca..cd576f3 100644 --- a/tests/defaults.c +++ b/tests/defaults.c
@@ -85,7 +85,7 @@ glfwWindowHint(GLFW_VISIBLE, GL_FALSE); - window = glfwCreateWindow(640, 480, GLFW_WINDOWED, "Defaults", NULL); + window = glfwCreateWindow(640, 480, "Defaults", NULL, NULL); if (!window) { glfwTerminate();
diff --git a/tests/events.c b/tests/events.c index 46bde2a..e812ef3 100644 --- a/tests/events.c +++ b/tests/events.c
@@ -337,6 +337,32 @@ get_character_string(character)); } +void monitor_callback(GLFWmonitor monitor, int event) +{ + if (event == GLFW_MONITOR_CONNECTED) + { + GLFWvidmode mode; + glfwGetVideoMode(monitor, &mode); + + printf("%08x at %0.3f: Monitor %s (%ix%i at %ix%i, %ix%i mm) was connected\n", + counter++, + glfwGetTime(), + glfwGetMonitorName(monitor), + mode.width, mode.height, + glfwGetMonitorParam(monitor, GLFW_MONITOR_POS_X), + glfwGetMonitorParam(monitor, GLFW_MONITOR_POS_Y), + glfwGetMonitorParam(monitor, GLFW_MONITOR_PHYSICAL_WIDTH), + glfwGetMonitorParam(monitor, GLFW_MONITOR_PHYSICAL_HEIGHT)); + } + else + { + printf("%08x at %0.3f: Monitor %s was disconnected\n", + counter++, + glfwGetTime(), + glfwGetMonitorName(monitor)); + } +} + int main(void) { GLFWwindow window; @@ -352,7 +378,7 @@ printf("Library initialized\n"); - window = glfwCreateWindow(640, 480, GLFW_WINDOWED, "Event Linter", NULL); + window = glfwCreateWindow(640, 480, "Event Linter", NULL, NULL); if (!window) { glfwTerminate(); @@ -363,6 +389,8 @@ printf("Window opened\n"); + glfwSetMonitorCallback(monitor_callback); + glfwSetWindowPosCallback(window, window_pos_callback); glfwSetWindowSizeCallback(window, window_size_callback); glfwSetWindowCloseCallback(window, window_close_callback);
diff --git a/tests/fsaa.c b/tests/fsaa.c index 735a1f5..a80f79e 100644 --- a/tests/fsaa.c +++ b/tests/fsaa.c
@@ -95,7 +95,7 @@ glfwWindowHint(GLFW_FSAA_SAMPLES, samples); - window = glfwCreateWindow(800, 400, GLFW_WINDOWED, "Aliasing Detector", NULL); + window = glfwCreateWindow(800, 400, "Aliasing Detector", NULL, NULL); if (!window) { glfwTerminate();
diff --git a/tests/fsfocus.c b/tests/fsfocus.c index a87d136..5024ab7 100644 --- a/tests/fsfocus.c +++ b/tests/fsfocus.c
@@ -82,7 +82,7 @@ exit(EXIT_FAILURE); } - window = glfwCreateWindow(640, 480, GLFW_FULLSCREEN, "Fullscreen focus", NULL); + window = glfwCreateWindow(640, 480, "Fullscreen focus", glfwGetPrimaryMonitor(), NULL); if (!window) { glfwTerminate();
diff --git a/tests/gamma.c b/tests/gamma.c index 8b995af..ebbe1ff 100644 --- a/tests/gamma.c +++ b/tests/gamma.c
@@ -97,7 +97,7 @@ int main(int argc, char** argv) { int width, height, ch; - int mode = GLFW_WINDOWED; + GLFWmonitor monitor = NULL; GLFWwindow window; while ((ch = getopt(argc, argv, "fh")) != -1) @@ -109,7 +109,7 @@ exit(EXIT_SUCCESS); case 'f': - mode = GLFW_FULLSCREEN; + monitor = glfwGetPrimaryMonitor(); break; default: @@ -124,12 +124,12 @@ exit(EXIT_FAILURE); } - if (mode == GLFW_FULLSCREEN) + if (monitor) { - GLFWvidmode desktop_mode; - glfwGetDesktopMode(&desktop_mode); - width = desktop_mode.width; - height = desktop_mode.height; + GLFWvidmode mode; + glfwGetVideoMode(monitor, &mode); + width = mode.width; + height = mode.height; } else { @@ -137,7 +137,7 @@ height = 200; } - window = glfwCreateWindow(width, height, mode, "Gamma Test", NULL); + window = glfwCreateWindow(width, height, "Gamma Test", monitor, NULL); if (!window) { glfwTerminate();
diff --git a/tests/glfwinfo.c b/tests/glfwinfo.c index 5e46fe1..b3e0474 100644 --- a/tests/glfwinfo.c +++ b/tests/glfwinfo.c
@@ -268,7 +268,7 @@ // We assume here that we stand a better chance of success by leaving all // possible details of pixel format selection to GLFW - window = glfwCreateWindow(200, 200, GLFW_WINDOWED, "Version", NULL); + window = glfwCreateWindow(200, 200, "Version", NULL, NULL); if (!window) { glfwTerminate();
diff --git a/tests/iconify.c b/tests/iconify.c index b0b6b6a..46c996e 100644 --- a/tests/iconify.c +++ b/tests/iconify.c
@@ -92,9 +92,15 @@ int main(int argc, char** argv) { int width, height, ch; - int mode = GLFW_WINDOWED; + GLFWmonitor monitor = NULL; GLFWwindow window; + if (!glfwInit()) + { + fprintf(stderr, "Failed to initialize GLFW: %s\n", glfwErrorString(glfwGetError())); + exit(EXIT_FAILURE); + } + while ((ch = getopt(argc, argv, "fh")) != -1) { switch (ch) @@ -104,7 +110,7 @@ exit(EXIT_SUCCESS); case 'f': - mode = GLFW_FULLSCREEN; + monitor = glfwGetPrimaryMonitor(); break; default: @@ -113,18 +119,12 @@ } } - if (!glfwInit()) + if (monitor) { - fprintf(stderr, "Failed to initialize GLFW: %s\n", glfwErrorString(glfwGetError())); - exit(EXIT_FAILURE); - } - - if (mode == GLFW_FULLSCREEN) - { - GLFWvidmode desktop_mode; - glfwGetDesktopMode(&desktop_mode); - width = desktop_mode.width; - height = desktop_mode.height; + GLFWvidmode mode; + glfwGetVideoMode(monitor, &mode); + width = mode.width; + height = mode.height; } else { @@ -132,7 +132,7 @@ height = 480; } - window = glfwCreateWindow(width, height, mode, "Iconify", NULL); + window = glfwCreateWindow(width, height, "Iconify", monitor, NULL); if (!window) { glfwTerminate();
diff --git a/tests/joysticks.c b/tests/joysticks.c index 2b24368..560dd20 100644 --- a/tests/joysticks.c +++ b/tests/joysticks.c
@@ -191,7 +191,7 @@ exit(EXIT_FAILURE); } - window = glfwCreateWindow(640, 480, GLFW_WINDOWED, "Joystick Test", NULL); + window = glfwCreateWindow(640, 480, "Joystick Test", NULL, NULL); if (!window) { glfwTerminate();
diff --git a/tests/modes.c b/tests/modes.c index e1f13fa..ecf5425 100644 --- a/tests/modes.c +++ b/tests/modes.c
@@ -90,32 +90,42 @@ } } -static void list_modes(void) +static void list_modes(GLFWmonitor monitor) { - int count, i; - GLFWvidmode desktop_mode; - GLFWvidmode* modes = glfwGetVideoModes(&count); + int count, widthMM, heightMM, dpi, i; + GLFWvidmode mode; + GLFWvidmode* modes = glfwGetVideoModes(monitor, &count); - glfwGetDesktopMode(&desktop_mode); - printf("Desktop mode: %s\n", format_mode(&desktop_mode)); + glfwGetVideoMode(monitor, &mode); - printf("Available modes:\n"); + printf("Name: %s\n", glfwGetMonitorName(monitor)); + printf("Current mode: %s\n", format_mode(&mode)); + printf("Virtual position: %i %i\n", + glfwGetMonitorParam(monitor, GLFW_MONITOR_POS_X), + glfwGetMonitorParam(monitor, GLFW_MONITOR_POS_Y)); + + widthMM = glfwGetMonitorParam(monitor, GLFW_MONITOR_PHYSICAL_WIDTH); + heightMM = glfwGetMonitorParam(monitor, GLFW_MONITOR_PHYSICAL_HEIGHT); + dpi = (int) ((float) mode.width * 25.4f / (float) widthMM); + printf("Physical size: %i x %i mm (%i dpi)\n", widthMM, heightMM, dpi); + + printf("Modes:\n"); for (i = 0; i < count; i++) { printf("%3u: %s", (unsigned int) i, format_mode(modes + i)); - if (memcmp(&desktop_mode, modes + i, sizeof(GLFWvidmode)) == 0) - printf(" (desktop mode)"); + if (memcmp(&mode, modes + i, sizeof(GLFWvidmode)) == 0) + printf(" (current mode)"); putchar('\n'); } } -static void test_modes(void) +static void test_modes(GLFWmonitor monitor) { int i, count; - GLFWvidmode* modes = glfwGetVideoModes(&count); + GLFWvidmode* modes = glfwGetVideoModes(monitor, &count); for (i = 0; i < count; i++) { @@ -126,10 +136,14 @@ glfwWindowHint(GLFW_GREEN_BITS, mode->greenBits); glfwWindowHint(GLFW_BLUE_BITS, mode->blueBits); - printf("Testing mode %u: %s", (unsigned int) i, format_mode(mode)); + printf("Testing mode %u on monitor %s: %s\n", + (unsigned int) i, + glfwGetMonitorName(monitor), + format_mode(mode)); window_handle = glfwCreateWindow(mode->width, mode->height, - GLFW_FULLSCREEN, "Video Mode Test", + "Video Mode Test", + glfwGetPrimaryMonitor(), NULL); if (!window_handle) { @@ -195,7 +209,8 @@ int main(int argc, char** argv) { - int ch, mode = LIST_MODE; + int ch, i, count, mode = LIST_MODE; + GLFWmonitor* monitors; while ((ch = getopt(argc, argv, "th")) != -1) { @@ -221,10 +236,15 @@ if (!glfwInit()) exit(EXIT_FAILURE); - if (mode == LIST_MODE) - list_modes(); - else if (mode == TEST_MODE) - test_modes(); + monitors = glfwGetMonitors(&count); + + for (i = 0; i < count; i++) + { + if (mode == LIST_MODE) + list_modes(monitors[i]); + else if (mode == TEST_MODE) + test_modes(monitors[i]); + } glfwTerminate(); exit(EXIT_SUCCESS);
diff --git a/tests/peter.c b/tests/peter.c index 30690e6..5a294ee 100644 --- a/tests/peter.c +++ b/tests/peter.c
@@ -92,7 +92,7 @@ static GLboolean open_window(void) { - window_handle = glfwCreateWindow(640, 480, GLFW_WINDOWED, "Peter Detector", NULL); + window_handle = glfwCreateWindow(640, 480, "Peter Detector", NULL, NULL); if (!window_handle) return GL_FALSE;
diff --git a/tests/reopen.c b/tests/reopen.c index 212c108..5097b65 100644 --- a/tests/reopen.c +++ b/tests/reopen.c
@@ -41,19 +41,6 @@ static GLFWwindow window_handle = NULL; static GLboolean closed = GL_FALSE; -static const char* get_mode_name(int mode) -{ - switch (mode) - { - case GLFW_WINDOWED: - return "windowed"; - case GLFW_FULLSCREEN: - return "fullscreen"; - default: - return "unknown"; - } -} - static void window_size_callback(GLFWwindow window, int width, int height) { glViewport(0, 0, width, height); @@ -80,22 +67,18 @@ } } -static GLboolean open_window(int width, int height, int mode) +static GLboolean open_window(int width, int height, GLFWmonitor monitor) { double base; - if (!glfwInit()) - { - fprintf(stderr, "Failed to initialize GLFW: %s\n", glfwErrorString(glfwGetError())); - return GL_FALSE; - } - base = glfwGetTime(); - window_handle = glfwCreateWindow(width, height, mode, "Window Re-opener", NULL); + window_handle = glfwCreateWindow(width, height, "Window Re-opener", monitor, NULL); if (!window_handle) { - fprintf(stderr, "Failed to open %s mode GLFW window: %s\n", get_mode_name(mode), glfwErrorString(glfwGetError())); + fprintf(stderr, "Failed to open %s mode GLFW window: %s\n", + monitor ? "fullscreen" : "windowed", + glfwErrorString(glfwGetError())); return GL_FALSE; } @@ -107,7 +90,7 @@ glfwSetKeyCallback(window_handle, key_callback); printf("Opening %s mode window took %0.3f seconds\n", - get_mode_name(mode), + monitor ? "fullscreen" : "windowed", glfwGetTime() - base); return GL_TRUE; @@ -121,17 +104,26 @@ window_handle = NULL; printf("Closing window took %0.3f seconds\n", glfwGetTime() - base); - - glfwTerminate(); } int main(int argc, char** argv) { int count = 0; + if (!glfwInit()) + { + fprintf(stderr, "Failed to initialize GLFW: %s\n", glfwErrorString(glfwGetError())); + return GL_FALSE; + } + for (;;) { - if (!open_window(640, 480, (count & 1) ? GLFW_FULLSCREEN : GLFW_WINDOWED)) + GLFWmonitor monitor = NULL; + + if (count & 1) + monitor = glfwGetPrimaryMonitor(); + + if (!open_window(640, 480, monitor)) { glfwTerminate(); exit(EXIT_FAILURE);
diff --git a/tests/sharing.c b/tests/sharing.c index 0042a85..69c4c4c 100644 --- a/tests/sharing.c +++ b/tests/sharing.c
@@ -57,7 +57,7 @@ glfwWindowHint(GLFW_POSITION_X, posX); glfwWindowHint(GLFW_POSITION_Y, posY); - window = glfwCreateWindow(WIDTH, HEIGHT, GLFW_WINDOWED, title, share); + window = glfwCreateWindow(WIDTH, HEIGHT, title, NULL, share); if (!window) return NULL;
diff --git a/tests/tearing.c b/tests/tearing.c index 63ece2b..881d7b5 100644 --- a/tests/tearing.c +++ b/tests/tearing.c
@@ -70,7 +70,7 @@ exit(EXIT_FAILURE); } - window = glfwCreateWindow(640, 480, GLFW_WINDOWED, "", NULL); + window = glfwCreateWindow(640, 480, "", NULL, NULL); if (!window) { fprintf(stderr, "Failed to open GLFW window: %s\n", glfwErrorString(glfwGetError()));
diff --git a/tests/threads.c b/tests/threads.c index 8b06b1d..27cb7b0 100644 --- a/tests/threads.c +++ b/tests/threads.c
@@ -92,9 +92,8 @@ glfwWindowHint(GLFW_POSITION_X, 200 + 250 * i); glfwWindowHint(GLFW_POSITION_Y, 200); threads[i].window = glfwCreateWindow(200, 200, - GLFW_WINDOWED, threads[i].title, - NULL); + NULL, NULL); if (!threads[i].window) { fprintf(stderr, "Failed to open GLFW window: %s\n",
diff --git a/tests/title.c b/tests/title.c index 62690f9..f7e216a 100644 --- a/tests/title.c +++ b/tests/title.c
@@ -47,7 +47,7 @@ exit(EXIT_FAILURE); } - window = glfwCreateWindow(400, 400, GLFW_WINDOWED, "English 日本語 русский язык 官話", NULL); + window = glfwCreateWindow(400, 400, "English 日本語 русский язык 官話", NULL, NULL); if (!window) { fprintf(stderr, "Failed to open GLFW window: %s\n", glfwErrorString(glfwGetError()));
diff --git a/tests/windows.c b/tests/windows.c index 187248c..dc2eec7 100644 --- a/tests/windows.c +++ b/tests/windows.c
@@ -57,7 +57,7 @@ { glfwWindowHint(GLFW_POSITION_X, 100 + (i & 1) * 300); glfwWindowHint(GLFW_POSITION_Y, 100 + (i >> 1) * 300); - windows[i] = glfwCreateWindow(200, 200, GLFW_WINDOWED, titles[i], NULL); + windows[i] = glfwCreateWindow(200, 200, titles[i], NULL, NULL); if (!windows[i]) { fprintf(stderr, "Failed to open GLFW window: %s\n",