From 6f970f57533a77e45f8199e956391acc014599d5 Mon Sep 17 00:00:00 2001 From: Marcel Metz Date: Mon, 30 Jan 2012 12:04:16 +0100 Subject: [PATCH 1/5] Made monitor list cleanup shared. --- src/internal.h | 5 +++++ src/monitor.c | 10 ++++++++++ src/win32_monitor.c | 6 ------ src/win32_platform.h | 1 - src/x11_monitor.c | 6 ------ src/x11_platform.h | 1 - 6 files changed, 15 insertions(+), 14 deletions(-) diff --git a/src/internal.h b/src/internal.h index 91d507c1..84c2485e 100644 --- a/src/internal.h +++ b/src/internal.h @@ -387,5 +387,10 @@ const _GLFWfbconfig* _glfwChooseFBConfig(const _GLFWfbconfig* desired, GLboolean _glfwIsValidContextConfig(_GLFWwndconfig* wndconfig); GLboolean _glfwIsValidContext(_GLFWwindow* window, _GLFWwndconfig* wndconfig); +// Monitor management (monitor.c) +void _glfwTerminateMonitors(void); + +// platform specific (*_monitor.c) +_GLFWmonitor* _glfwDestroyMonitor(_GLFWmonitor* monitor); #endif // _internal_h_ diff --git a/src/monitor.c b/src/monitor.c index 3263eb9f..c219abb6 100644 --- a/src/monitor.c +++ b/src/monitor.c @@ -145,3 +145,13 @@ GLFWAPI void glfwSetMonitorDeviceCallback(GLFWmonitordevicefun cbfun) _glfwLibrary.monitorCallback= cbfun; } +//======================================================================== +// Delete the monitor list. +//======================================================================== + +void _glfwTerminateMonitors(void) +{ + while (_glfwLibrary.monitorListHead) + _glfwLibrary.monitorListHead = _glfwDestroyMonitor(_glfwLibrary.monitorListHead); +} + diff --git a/src/win32_monitor.c b/src/win32_monitor.c index 7b03b9fb..367aec18 100644 --- a/src/win32_monitor.c +++ b/src/win32_monitor.c @@ -223,9 +223,3 @@ void _glfwRefreshMonitors(void) _glfwLibrary.monitorListHead = newMonitorList; } -void _glfwTerminateMonitors(void) -{ - while (_glfwLibrary.monitorListHead) - _glfwLibrary.monitorListHead = _glfwDestroyMonitor(_glfwLibrary.monitorListHead); -} - diff --git a/src/win32_platform.h b/src/win32_platform.h index 3c2892c7..aa8352af 100644 --- a/src/win32_platform.h +++ b/src/win32_platform.h @@ -339,7 +339,6 @@ void _glfwInitTimer(void); // Monitor support void _glfwInitMonitors(void); void _glfwRefreshMonitors(void); -void _glfwTerminateMonitors(void); // Fullscreen support void _glfwSetVideoMode(int* width, int* height, diff --git a/src/x11_monitor.c b/src/x11_monitor.c index e827fb35..05625933 100644 --- a/src/x11_monitor.c +++ b/src/x11_monitor.c @@ -128,9 +128,3 @@ void _glfwInitMonitors(void) } } -void _glfwTerminateMonitors(void) -{ - while (_glfwLibrary.monitorListHead) - _glfwLibrary.monitorListHead = _glfwDestroyMonitor(_glfwLibrary.monitorListHead); -} - diff --git a/src/x11_platform.h b/src/x11_platform.h index 41e8167e..a9be40ae 100644 --- a/src/x11_platform.h +++ b/src/x11_platform.h @@ -281,7 +281,6 @@ void _glfwTerminateJoysticks(void); // Monitors void _glfwInitMonitors(void); -void _glfwTerminateMonitors(void); // Unicode support long _glfwKeySym2Unicode(KeySym keysym); From f228d2302410bdb78a020083c1832744142e867c Mon Sep 17 00:00:00 2001 From: Marcel Metz Date: Mon, 30 Jan 2012 12:33:32 +0100 Subject: [PATCH 2/5] Moved platform specific monitor list creation part to separate functions. --- src/internal.h | 19 ++++++++----------- src/monitor.c | 9 +++++++++ src/win32_monitor.c | 44 ++++++++------------------------------------ src/win32_platform.h | 2 ++ src/x11_monitor.c | 10 +++++++--- src/x11_platform.h | 3 ++- 6 files changed, 36 insertions(+), 51 deletions(-) diff --git a/src/internal.h b/src/internal.h index 84c2485e..1e84bbc6 100644 --- a/src/internal.h +++ b/src/internal.h @@ -65,6 +65,13 @@ // extensions and not all operating systems come with an up-to-date version #include "../support/GL/glext.h" +typedef struct _GLFWhints _GLFWhints; +typedef struct _GLFWwndconfig _GLFWwndconfig; +typedef struct _GLFWfbconfig _GLFWfbconfig; +typedef struct _GLFWwindow _GLFWwindow; +typedef struct _GLFWlibrary _GLFWlibrary; +typedef struct _GLFWmonitor _GLFWmonitor; + #if defined(_GLFW_COCOA_NSGL) #include "cocoa_platform.h" #elif defined(_GLFW_WIN32_WGL) @@ -75,14 +82,6 @@ #error "No supported platform selected" #endif -typedef struct _GLFWhints _GLFWhints; -typedef struct _GLFWwndconfig _GLFWwndconfig; -typedef struct _GLFWfbconfig _GLFWfbconfig; -typedef struct _GLFWwindow _GLFWwindow; -typedef struct _GLFWlibrary _GLFWlibrary; -typedef struct _GLFWmonitor _GLFWmonitor; - - //------------------------------------------------------------------------ // Window hints, set by glfwOpenWindowHint and consumed by glfwOpenWindow // A bucket of semi-random stuff lumped together for historical reasons @@ -388,9 +387,7 @@ GLboolean _glfwIsValidContextConfig(_GLFWwndconfig* wndconfig); GLboolean _glfwIsValidContext(_GLFWwindow* window, _GLFWwndconfig* wndconfig); // Monitor management (monitor.c) +void _glfwInitMonitors(void); void _glfwTerminateMonitors(void); -// platform specific (*_monitor.c) -_GLFWmonitor* _glfwDestroyMonitor(_GLFWmonitor* monitor); - #endif // _internal_h_ diff --git a/src/monitor.c b/src/monitor.c index c219abb6..138637f8 100644 --- a/src/monitor.c +++ b/src/monitor.c @@ -145,6 +145,15 @@ GLFWAPI void glfwSetMonitorDeviceCallback(GLFWmonitordevicefun cbfun) _glfwLibrary.monitorCallback= cbfun; } +//======================================================================== +// Initialize the monitor list. +//======================================================================== + +void _glfwInitMonitors(void) +{ + _glfwLibrary.monitorListHead = _glfwCreateMonitors(); +} + //======================================================================== // Delete the monitor list. //======================================================================== diff --git a/src/win32_monitor.c b/src/win32_monitor.c index 367aec18..7aad70d9 100644 --- a/src/win32_monitor.c +++ b/src/win32_monitor.c @@ -83,29 +83,21 @@ _GLFWmonitor* _glfwDestroyMonitor(_GLFWmonitor* monitor) return result; } -// todo: This is ugly. The platform should only allocate a list of the current devices. -// The platform independent code should be in charge of the handling for the initial -// setup, refreshing and freeing the list. -void _glfwInitMonitors(void) +_GLFWmonitor* _glfwCreateMonitors(void) { - _GLFWmonitor** curMonitor; - DISPLAY_DEVICE adapter; DWORD adapterNum; - DISPLAY_DEVICE monitor; - DEVMODE setting; - DWORD settingNum; - - curMonitor = &_glfwLibrary.monitorListHead; + _GLFWmonitor* monitorList; + _GLFWmonitor** curMonitor; adapter.cb = sizeof(DISPLAY_DEVICE); adapterNum = 0; - monitor.cb = sizeof(DISPLAY_DEVICE); setting.dmSize = sizeof(DEVMODE); - settingNum = 0; + monitorList = NULL; + curMonitor = &monitorList; while (EnumDisplayDevices(NULL, adapterNum++, &adapter, 0)) { @@ -121,36 +113,16 @@ void _glfwInitMonitors(void) curMonitor = _glfwCreateMonitor(curMonitor, &adapter, &monitor, &setting); } + + return monitorList; } void _glfwRefreshMonitors(void) { - DISPLAY_DEVICE adapter; - DWORD adapterNum = 0; - - DISPLAY_DEVICE monitor; - - DEVMODE setting; - - _GLFWmonitor* newMonitorList = NULL; - _GLFWmonitor** curMonitor = &newMonitorList; - _GLFWmonitor* curNewMonitor; _GLFWmonitor* curOldMonitor; - while (EnumDisplayDevices(NULL, adapterNum++, &adapter, 0)) - { - if (adapter.StateFlags & DISPLAY_DEVICE_MIRRORING_DRIVER || !(adapter.StateFlags & DISPLAY_DEVICE_ACTIVE)) - continue; - - EnumDisplaySettingsEx(adapter.DeviceName, ENUM_CURRENT_SETTINGS, &setting, EDS_ROTATEDMODE); - - EnumDisplayDevices(adapter.DeviceName, 0, &monitor, 0); - - curMonitor = _glfwCreateMonitor(curMonitor, &adapter, &monitor, &setting); - } - - curNewMonitor = newMonitorList; + curNewMonitor = _glfwCreateMonitors(); curOldMonitor = _glfwLibrary.monitorListHead; while (_glfwLibrary.monitorCallback && (curNewMonitor || curOldMonitor)) diff --git a/src/win32_platform.h b/src/win32_platform.h index aa8352af..64cc61ff 100644 --- a/src/win32_platform.h +++ b/src/win32_platform.h @@ -339,6 +339,8 @@ void _glfwInitTimer(void); // Monitor support void _glfwInitMonitors(void); void _glfwRefreshMonitors(void); +_GLFWmonitor* _glfwCreateMonitors(void); +_GLFWmonitor* _glfwDestroyMonitor(_GLFWmonitor* monitor); // Fullscreen support void _glfwSetVideoMode(int* width, int* height, diff --git a/src/x11_monitor.c b/src/x11_monitor.c index 05625933..d22bcda7 100644 --- a/src/x11_monitor.c +++ b/src/x11_monitor.c @@ -77,9 +77,11 @@ _GLFWmonitor* _glfwDestroyMonitor(_GLFWmonitor* monitor) return result; } -void _glfwInitMonitors(void) +_GLFWmonitor* _glfwCreateMonitors(void) { - _glfwLibrary.monitorListHead = NULL; + _GLFWmonitor* monitorList; + + monitorList = NULL; if (_glfwLibrary.X11.RandR.available) { @@ -88,7 +90,7 @@ void _glfwInitMonitors(void) int outputIDX; _GLFWmonitor** curMonitor; - curMonitor = &_glfwLibrary.monitorListHead; + curMonitor = &monitorList; resources = XRRGetScreenResources(_glfwLibrary.X11.display, _glfwLibrary.X11.root); @@ -126,5 +128,7 @@ void _glfwInitMonitors(void) } #endif /*_GLFW_HAS_XRANDR*/ } + + return monitorList; } diff --git a/src/x11_platform.h b/src/x11_platform.h index a9be40ae..6e7d8f64 100644 --- a/src/x11_platform.h +++ b/src/x11_platform.h @@ -280,7 +280,8 @@ void _glfwInitJoysticks(void); void _glfwTerminateJoysticks(void); // Monitors -void _glfwInitMonitors(void); +_GLFWmonitor* _glfwCreateMonitors(void); +_GLFWmonitor* _glfwDestroyMonitor(_GLFWmonitor* monitor); // Unicode support long _glfwKeySym2Unicode(KeySym keysym); From df64773a448625bbca170bd0ea4d52bf5612bfc1 Mon Sep 17 00:00:00 2001 From: Marcel Metz Date: Mon, 30 Jan 2012 14:55:23 +0100 Subject: [PATCH 3/5] Moved monitor callback to shared implementation. --- src/internal.h | 1 + src/monitor.c | 84 ++++++++++++++++++++++++++++++++++++++++++++ src/win32_monitor.c | 78 ---------------------------------------- src/win32_platform.h | 2 -- 4 files changed, 85 insertions(+), 80 deletions(-) diff --git a/src/internal.h b/src/internal.h index 1e84bbc6..c9a7ccc3 100644 --- a/src/internal.h +++ b/src/internal.h @@ -388,6 +388,7 @@ GLboolean _glfwIsValidContext(_GLFWwindow* window, _GLFWwndconfig* wndconfig); // Monitor management (monitor.c) void _glfwInitMonitors(void); +void _glfwRefreshMonitors(void); void _glfwTerminateMonitors(void); #endif // _internal_h_ diff --git a/src/monitor.c b/src/monitor.c index 138637f8..0cc8f511 100644 --- a/src/monitor.c +++ b/src/monitor.c @@ -154,6 +154,90 @@ void _glfwInitMonitors(void) _glfwLibrary.monitorListHead = _glfwCreateMonitors(); } +//======================================================================== +// Refresh monitor list and notify callback. +//======================================================================== + +void _glfwRefreshMonitors(void) +{ + _GLFWmonitor* newMonitorList; + _GLFWmonitor* curNewMonitor; + _GLFWmonitor* curOldMonitor; + + newMonitorList = _glfwCreateMonitors(); + curNewMonitor = newMonitorList; + curOldMonitor = _glfwLibrary.monitorListHead; + + while (_glfwLibrary.monitorCallback && (curNewMonitor || curOldMonitor)) + { + _GLFWmonitor* lookAheadOldMonitor; + _GLFWmonitor* lookAheadNewMonitor; + + if (curOldMonitor && curNewMonitor && !strcmp(curOldMonitor->name, curOldMonitor->name)) + { + curNewMonitor = curNewMonitor->next; + curOldMonitor = curOldMonitor->next; + continue; + } + + if (curNewMonitor && !curOldMonitor) + { + _glfwLibrary.monitorCallback(curNewMonitor, GLFW_MONITOR_CONNECTED); + curNewMonitor = curNewMonitor->next; + continue; + } + + if (!curNewMonitor && curOldMonitor) + { + _glfwLibrary.monitorCallback(curOldMonitor, GLFW_MONITOR_DISCONNECTED); + curOldMonitor = curOldMonitor->next; + continue; + } + + lookAheadOldMonitor = curOldMonitor->next; + lookAheadNewMonitor = curNewMonitor->next; + + while (lookAheadOldMonitor && !strcmp(curNewMonitor->name, lookAheadOldMonitor->name)) + lookAheadOldMonitor = lookAheadOldMonitor->next; + + while (lookAheadNewMonitor && !strcmp(curOldMonitor->name, lookAheadNewMonitor->name)) + lookAheadNewMonitor = lookAheadNewMonitor->next; + + if (!lookAheadOldMonitor) + { + // nothing found in the old monitor list, that matches the current new monitor. + _glfwLibrary.monitorCallback(curNewMonitor, GLFW_MONITOR_CONNECTED); + curNewMonitor = curNewMonitor->next; + } + else + { + while (strcmp(curOldMonitor->name, lookAheadOldMonitor->name)) + { + _glfwLibrary.monitorCallback(curOldMonitor, GLFW_MONITOR_DISCONNECTED); + curOldMonitor = curOldMonitor->next; + } + } + + if (!lookAheadNewMonitor) + { + // nothing found in the new monitor list, that matches the current old monitor. + _glfwLibrary.monitorCallback(curOldMonitor, GLFW_MONITOR_DISCONNECTED); + curOldMonitor = curOldMonitor->next; + } + else + { + while (strcmp(curNewMonitor->name, lookAheadNewMonitor->name)) + { + _glfwLibrary.monitorCallback(curNewMonitor, GLFW_MONITOR_CONNECTED); + curNewMonitor = curNewMonitor->next; + } + } + } + + _glfwTerminateMonitors(); + _glfwLibrary.monitorListHead = newMonitorList; +} + //======================================================================== // Delete the monitor list. //======================================================================== diff --git a/src/win32_monitor.c b/src/win32_monitor.c index 7aad70d9..506394b0 100644 --- a/src/win32_monitor.c +++ b/src/win32_monitor.c @@ -117,81 +117,3 @@ _GLFWmonitor* _glfwCreateMonitors(void) return monitorList; } -void _glfwRefreshMonitors(void) -{ - _GLFWmonitor* curNewMonitor; - _GLFWmonitor* curOldMonitor; - - curNewMonitor = _glfwCreateMonitors(); - curOldMonitor = _glfwLibrary.monitorListHead; - - while (_glfwLibrary.monitorCallback && (curNewMonitor || curOldMonitor)) - { - _GLFWmonitor* lookAheadOldMonitor; - _GLFWmonitor* lookAheadNewMonitor; - - if (curOldMonitor && curNewMonitor && !strcmp(curOldMonitor->name, curOldMonitor->name)) - { - curNewMonitor = curNewMonitor->next; - curOldMonitor = curOldMonitor->next; - continue; - } - - if (curNewMonitor && !curOldMonitor) - { - _glfwLibrary.monitorCallback(curNewMonitor, GLFW_MONITOR_CONNECTED); - curNewMonitor = curNewMonitor->next; - continue; - } - - if (!curNewMonitor && curOldMonitor) - { - _glfwLibrary.monitorCallback(curOldMonitor, GLFW_MONITOR_DISCONNECTED); - curOldMonitor = curOldMonitor->next; - continue; - } - - lookAheadOldMonitor = curOldMonitor->next; - lookAheadNewMonitor = curNewMonitor->next; - - while (lookAheadOldMonitor && !strcmp(curNewMonitor->name, lookAheadOldMonitor->name)) - lookAheadOldMonitor = lookAheadOldMonitor->next; - - while (lookAheadNewMonitor && !strcmp(curOldMonitor->name, lookAheadNewMonitor->name)) - lookAheadNewMonitor = lookAheadNewMonitor->next; - - if (!lookAheadOldMonitor) - { - // nothing found in the old monitor list, that matches the current new monitor. - _glfwLibrary.monitorCallback(curNewMonitor, GLFW_MONITOR_CONNECTED); - curNewMonitor = curNewMonitor->next; - } - else - { - while (strcmp(curOldMonitor->name, lookAheadOldMonitor->name)) - { - _glfwLibrary.monitorCallback(curOldMonitor, GLFW_MONITOR_DISCONNECTED); - curOldMonitor = curOldMonitor->next; - } - } - - if (!lookAheadNewMonitor) - { - // nothing found in the new monitor list, that matches the current old monitor. - _glfwLibrary.monitorCallback(curOldMonitor, GLFW_MONITOR_DISCONNECTED); - curOldMonitor = curOldMonitor->next; - } - else - { - while (strcmp(curNewMonitor->name, lookAheadNewMonitor->name)) - { - _glfwLibrary.monitorCallback(curNewMonitor, GLFW_MONITOR_CONNECTED); - curNewMonitor = curNewMonitor->next; - } - } - } - - _glfwTerminateMonitors(); - _glfwLibrary.monitorListHead = newMonitorList; -} - diff --git a/src/win32_platform.h b/src/win32_platform.h index 64cc61ff..4a1dded8 100644 --- a/src/win32_platform.h +++ b/src/win32_platform.h @@ -337,8 +337,6 @@ typedef struct _GLFWmonitorWin32 void _glfwInitTimer(void); // Monitor support -void _glfwInitMonitors(void); -void _glfwRefreshMonitors(void); _GLFWmonitor* _glfwCreateMonitors(void); _GLFWmonitor* _glfwDestroyMonitor(_GLFWmonitor* monitor); From a69974403e5778fd77c5d2d66efda166a89fbdad Mon Sep 17 00:00:00 2001 From: Marcel Metz Date: Mon, 30 Jan 2012 16:21:21 +0100 Subject: [PATCH 4/5] Added x11 support for monitor PnP detection. --- src/x11_window.c | 19 ++++++++++--------- tests/events.c | 2 +- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/x11_window.c b/src/x11_window.c index 641b3c84..04f55be5 100644 --- a/src/x11_window.c +++ b/src/x11_window.c @@ -1366,6 +1366,7 @@ static void processSingleEvent(void) { // Show XRandR that we really care XRRUpdateConfiguration(&event); + _glfwRefreshMonitors(); break; } } @@ -1423,18 +1424,18 @@ int _glfwPlatformOpenWindow(_GLFWwindow* window, 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->mode == GLFW_FULLSCREEN) + { enterFullscreenMode(window); } diff --git a/tests/events.c b/tests/events.c index 1a1280a3..1d4bf64e 100644 --- a/tests/events.c +++ b/tests/events.c @@ -345,7 +345,7 @@ static void char_callback(GLFWwindow window, int character) void monitor_callback(GLFWmonitor monitor, int event) { - printf("%08x at %0.3f: Monitor %s %s", + printf("%08x at %0.3f: Monitor %s %s\n", counter++, glfwGetTime(), glfwGetMonitorString(monitor, GLFW_MONITOR_NAME), From 5a16042c8abd5a9182b8cebc81167c902a410c1e Mon Sep 17 00:00:00 2001 From: Marcel Metz Date: Tue, 31 Jan 2012 23:47:01 +0100 Subject: [PATCH 5/5] Fixed mingw compile errors. --- src/win32_fullscreen.c | 2 +- src/win32_monitor.c | 5 +++++ src/win32_platform.h | 2 +- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/win32_fullscreen.c b/src/win32_fullscreen.c index 08f5e93e..682b6757 100644 --- a/src/win32_fullscreen.c +++ b/src/win32_fullscreen.c @@ -229,7 +229,7 @@ int _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, GLFWvidmode* list, int ma } if (list && maxcount) - memcpy(list, vidModes, sizeof(GLFWvidmode) * min(vidModesCount, maxcount)); + memcpy(list, vidModes, sizeof(GLFWvidmode) * ((vidModesCount < maxcount) ? vidModesCount : maxcount)); free(vidModes); diff --git a/src/win32_monitor.c b/src/win32_monitor.c index 506394b0..452b347e 100644 --- a/src/win32_monitor.c +++ b/src/win32_monitor.c @@ -38,6 +38,11 @@ #define EDS_ROTATEDMODE 0x00000004 #endif +// The MinGW upstream lacks this +#ifndef DISPLAY_DEVICE_ACTIVE +#define DISPLAY_DEVICE_ACTIVE 0x00000001 +#endif + ////////////////////////////////////////////////////////////////////////// ////// GLFW platform API ////// diff --git a/src/win32_platform.h b/src/win32_platform.h index 4a1dded8..28eeaf32 100644 --- a/src/win32_platform.h +++ b/src/win32_platform.h @@ -47,7 +47,7 @@ #include #include -#include +#include // This path may need to be changed if you build GLFW using your own setup // We ship and use our own copy of wglext.h since GLFW uses fairly new