Implemented monitor (dis)connect callback for win32.

This commit is contained in:
Marcel Metz 2011-10-14 14:32:06 -04:00
parent 784f60365e
commit 85d4bfcff5
3 changed files with 116 additions and 2 deletions

View File

@ -83,6 +83,9 @@ _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** curMonitor;
@ -106,7 +109,7 @@ void _glfwInitMonitors(void)
while (EnumDisplayDevices(NULL, adapterNum++, &adapter, 0))
{
if (adapter.StateFlags & DISPLAY_DEVICE_MIRRORING_DRIVER)
if (adapter.StateFlags & DISPLAY_DEVICE_MIRRORING_DRIVER || !(adapter.StateFlags & DISPLAY_DEVICE_ACTIVE))
continue;
EnumDisplaySettingsEx(adapter.DeviceName,
@ -120,6 +123,106 @@ void _glfwInitMonitors(void)
}
}
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;
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;
}
void _glfwTerminateMonitors(void)
{
while (_glfwLibrary.monitorListHead)

View File

@ -42,6 +42,7 @@
#include <windows.h>
#include <mmsystem.h>
#include <Dbt.h>
// 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
@ -332,6 +333,7 @@ void _glfwInitTimer(void);
// Monitor support
void _glfwInitMonitors(void);
void _glfwRefreshMonitors(void);
void _glfwTerminateMonitors(void);
// Fullscreen support

View File

@ -30,7 +30,6 @@
#include "internal.h"
#include <stdio.h>
#include <stdlib.h>
@ -1104,6 +1103,16 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
break;
}
case WM_DEVICECHANGE:
{
if (DBT_DEVNODES_CHANGED == wParam)
{
_glfwRefreshMonitors();
return TRUE;
}
break;
}
}
// Pass all unhandled messages to DefWindowProc