Merge branch 'master' into multi-monitor
Conflicts:
include/GL/glfw3.h
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 5436a18..de15feb 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 237f7e1..539c2de 100644
--- a/include/GL/glfw3.h
+++ b/include/GL/glfw3.h
@@ -58,6 +58,8 @@
*/
/*! @defgroup input Input handling
*/
+/*! @defgroup monitor Monitor handling
+ */
/*! @defgroup time Time input
*/
/*! @defgroup window Window handling
@@ -67,8 +69,6 @@
* multiple windows, which can be either a normal desktop window or
* a fullscreen window.
*/
-/*! @defgroup monitor Monitor handling
- */
/*************************************************************************
@@ -454,15 +454,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
* @{ */
@@ -694,6 +685,39 @@
*/
#define GLFW_GAMMA_RAMP_SIZE 256
+/*! @name Monitor parameters
+ * @{ */
+/*! @brief The physical width, in mm, of the monitor.
+ * @ingroup monitor
+ */
+#define GLFW_MONITOR_WIDTH_MM 0x00060001
+/*! @brief The physical height, in mm, of the monitor.
+ * @ingroup monitor
+ */
+#define GLFW_MONITOR_HEIGHT_MM 0x00060002
+/*! @brief The x-coordinate of the upper-left corner of the monitor on the
+ * virtual desktop.
+ * @ingroup monitor
+ */
+#define GLFW_MONITOR_POS_X 0x00060003
+/*! @brief The y-coordinate of the upper-left corner of the monitor on the
+ * virtual desktop.
+ * @ingroup monitor
+ */
+#define GLFW_MONITOR_POS_Y 0x00060004
+/* @} */
+
+/*! @name Monitor events
+ * @{ */
+/*! @brief The monitor was connected.
+ * @ingroup monitor
+ */
+#define GLFW_CONNECTED 0x00061000
+/*! @brief The monitor was disconnected.
+ * @ingroup monitor
+ */
+#define GLFW_DISCONNECTED 0x00061001
+/* @} */
/*************************************************************************
* Typedefs
@@ -704,6 +728,11 @@
*/
typedef void (*GLFWglproc)(void);
+/*! @brief Monitor handle type.
+ * @ingroup monitor
+ */
+typedef void* GLFWmonitor;
+
/*! @brief Window handle type.
* @ingroup window
*/
@@ -813,6 +842,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
*/
@@ -950,17 +986,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 const 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 const 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.
@@ -1100,8 +1187,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.
@@ -1137,7 +1225,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.
@@ -1241,6 +1329,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..0ae667f
--- /dev/null
+++ b/src/monitor.c
@@ -0,0 +1,432 @@
+//========================================================================
+// 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_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_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 const 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_WIDTH_MM:
+ return monitor->physicalWidth;
+ case GLFW_MONITOR_HEIGHT_MM:
+ 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 const 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 f9048cb..3874837 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 8f08889..211071d 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..aca2e79 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_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_WIDTH_MM),
+ glfwGetMonitorParam(monitor, GLFW_MONITOR_HEIGHT_MM));
+ }
+ 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 04a9d95..3ac0180 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..8a260ea 100644
--- a/tests/modes.c
+++ b/tests/modes.c
@@ -49,7 +49,7 @@
printf(" modes -h\n");
}
-static const char* format_mode(GLFWvidmode* mode)
+static const char* format_mode(const GLFWvidmode* mode)
{
static char buffer[512];
@@ -90,46 +90,60 @@
}
}
-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;
+ const 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_WIDTH_MM);
+ heightMM = glfwGetMonitorParam(monitor, GLFW_MONITOR_HEIGHT_MM);
+ 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);
+ const GLFWvidmode* modes = glfwGetVideoModes(monitor, &count);
for (i = 0; i < count; i++)
{
- GLFWvidmode* mode = modes + i;
+ const GLFWvidmode* mode = modes + i;
GLFWvidmode current;
glfwWindowHint(GLFW_RED_BITS, mode->redBits);
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;
+ const 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",