This commit is contained in:
Camilla Berglund 2012-09-12 19:35:52 +02:00
parent 83f5b920b9
commit 830f2b439c
16 changed files with 287 additions and 284 deletions

View File

@ -529,15 +529,14 @@ GLFWAPI const char* glfwErrorString(int error);
GLFWAPI void glfwSetErrorCallback(GLFWerrorfun cbfun); GLFWAPI void glfwSetErrorCallback(GLFWerrorfun cbfun);
/* Monitor functions */ /* Monitor functions */
GLFWAPI GLFWmonitor* glfwGetMonitors(int* count);
GLFWAPI GLFWmonitor glfwGetPrimaryMonitor(void);
GLFWAPI int glfwGetMonitorParam(GLFWmonitor monitor, int param); GLFWAPI int glfwGetMonitorParam(GLFWmonitor monitor, int param);
GLFWAPI const char* glfwGetMonitorString(GLFWmonitor monitor, int param); GLFWAPI const char* glfwGetMonitorString(GLFWmonitor monitor, int param);
GLFWAPI void glfwSetMonitorUserPointer(GLFWmonitor monitor, void* pointer); GLFWAPI void glfwSetMonitorUserPointer(GLFWmonitor monitor, void* pointer);
GLFWAPI void* glfwGetMonitorUserPointer(GLFWmonitor monitor); GLFWAPI void* glfwGetMonitorUserPointer(GLFWmonitor monitor);
GLFWAPI void glfwSetMonitorCallback(GLFWmonitorfun cbfun); GLFWAPI void glfwSetMonitorCallback(GLFWmonitorfun cbfun);
/* Monitor discovery */
GLFWAPI GLFWmonitor glfwGetNextMonitor(GLFWmonitor iterator);
/* Video mode functions */ /* Video mode functions */
GLFWAPI GLFWvidmode* glfwGetVideoModes(GLFWmonitor monitor, int* count); GLFWAPI GLFWvidmode* glfwGetVideoModes(GLFWmonitor monitor, int* count);
GLFWAPI void glfwGetVideoMode(GLFWmonitor monitor, GLFWvidmode* mode); GLFWAPI void glfwGetVideoMode(GLFWmonitor monitor, GLFWvidmode* mode);

View File

@ -130,6 +130,13 @@ GLFWAPI int glfwInit(void)
return GL_FALSE; return GL_FALSE;
} }
_glfwLibrary.monitors = _glfwPlatformGetMonitors(&_glfwLibrary.monitorCount);
if (!_glfwLibrary.monitors)
{
_glfwPlatformTerminate();
return GL_FALSE;
}
atexit(glfwTerminate); atexit(glfwTerminate);
_glfwInitialized = GL_TRUE; _glfwInitialized = GL_TRUE;
@ -151,6 +158,8 @@ GLFWAPI void glfwTerminate(void)
while (_glfwLibrary.windowListHead) while (_glfwLibrary.windowListHead)
glfwDestroyWindow(_glfwLibrary.windowListHead); glfwDestroyWindow(_glfwLibrary.windowListHead);
_glfwDestroyMonitors();
if (!_glfwPlatformTerminate()) if (!_glfwPlatformTerminate())
return; return;

View File

@ -206,8 +206,6 @@ struct _GLFWwindow
//------------------------------------------------------------------------ //------------------------------------------------------------------------
struct _GLFWmonitor struct _GLFWmonitor
{ {
struct _GLFWmonitor* next;
void* userPointer; void* userPointer;
char* name; char* name;
@ -234,7 +232,9 @@ struct _GLFWlibrary
_GLFWwindow* windowListHead; _GLFWwindow* windowListHead;
_GLFWwindow* activeWindow; _GLFWwindow* activeWindow;
_GLFWwindow* cursorLockWindow; _GLFWwindow* cursorLockWindow;
_GLFWmonitor* monitorListHead;
_GLFWmonitor** monitors;
int monitorCount;
GLFWwindowsizefun windowSizeCallback; GLFWwindowsizefun windowSizeCallback;
GLFWwindowclosefun windowCloseCallback; GLFWwindowclosefun windowCloseCallback;
@ -286,6 +286,10 @@ void _glfwPlatformDisableSystemKeys(_GLFWwindow* window);
void _glfwPlatformSetCursorPos(_GLFWwindow* window, int x, int y); void _glfwPlatformSetCursorPos(_GLFWwindow* window, int x, int y);
void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode); void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode);
// Monitor support
_GLFWmonitor** _glfwPlatformGetMonitors(int* count);
void _glfwPlatformDestroyMonitor(_GLFWmonitor* monitor);
// Video mode support // Video mode support
GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count); GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count);
void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode); void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode);
@ -357,6 +361,9 @@ void _glfwInputMouseClick(_GLFWwindow* window, int button, int action);
void _glfwInputCursorMotion(_GLFWwindow* window, int x, int y); void _glfwInputCursorMotion(_GLFWwindow* window, int x, int y);
void _glfwInputCursorEnter(_GLFWwindow* window, int entered); void _glfwInputCursorEnter(_GLFWwindow* window, int entered);
// Monitor event notification (monitor.c)
void _glfwInputMonitorChange(void);
//======================================================================== //========================================================================
// Prototypes for internal utility functions // Prototypes for internal utility functions
@ -385,8 +392,10 @@ GLboolean _glfwIsValidContextConfig(_GLFWwndconfig* wndconfig);
GLboolean _glfwIsValidContext(_GLFWwndconfig* wndconfig); GLboolean _glfwIsValidContext(_GLFWwndconfig* wndconfig);
// Monitor management (monitor.c) // Monitor management (monitor.c)
void _glfwInitMonitors(void); _GLFWmonitor* _glfwCreateMonitor(const char* name,
void _glfwRefreshMonitors(void); int physicalWidth, int physicalHeight,
void _glfwTerminateMonitors(void); int screenX, int screenY);
void _glfwDestroyMonitor(_GLFWmonitor* monitor);
void _glfwDestroyMonitors(void);
#endif // _internal_h_ #endif // _internal_h_

View File

@ -31,6 +31,7 @@
#include "internal.h" #include "internal.h"
#include <string.h> #include <string.h>
#include <stdlib.h>
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
@ -38,108 +39,115 @@
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
//======================================================================== //========================================================================
// Initialize the monitor list // Create a monitor struct from the specified information
//======================================================================== //========================================================================
void _glfwInitMonitors(void) _GLFWmonitor* _glfwCreateMonitor(const char* name,
int physicalWidth, int physicalHeight,
int screenX, int screenY)
{ {
_glfwLibrary.monitorListHead = _glfwCreateMonitors(); _GLFWmonitor* monitor = (_GLFWmonitor*) calloc(1, sizeof(_GLFWmonitor));
if (!monitor)
{
_glfwSetError(GLFW_OUT_OF_MEMORY, NULL);
return NULL;
}
monitor->name = strdup(name);
monitor->physicalWidth = physicalWidth;
monitor->physicalHeight = physicalHeight;
monitor->screenX = screenX;
monitor->screenY = screenY;
return monitor;
} }
//======================================================================== //========================================================================
// Refresh monitor list and notify callback // Destroy the specified monitor
//======================================================================== //========================================================================
void _glfwRefreshMonitors(void) void _glfwDestroyMonitor(_GLFWmonitor* monitor)
{ {
_GLFWmonitor* newMonitorList; if (monitor == NULL)
_GLFWmonitor* curNewMonitor; return;
_GLFWmonitor* curOldMonitor;
newMonitorList = _glfwCreateMonitors(); _glfwPlatformDestroyMonitor(monitor);
curNewMonitor = newMonitorList;
curOldMonitor = _glfwLibrary.monitorListHead;
while (_glfwLibrary.monitorCallback && (curNewMonitor || curOldMonitor)) free(monitor->modes);
{ free(monitor->name);
_GLFWmonitor* lookAheadOldMonitor; free(monitor);
_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 // Enumerate monitors and notify user of changes
//======================================================================== //========================================================================
void _glfwTerminateMonitors(void) void _glfwInputMonitorChange(void)
{ {
while (_glfwLibrary.monitorListHead) int i, j, monitorCount;
_glfwLibrary.monitorListHead = _glfwDestroyMonitor(_glfwLibrary.monitorListHead); _GLFWmonitor** monitors;
monitors = _glfwPlatformGetMonitors(&monitorCount);
for (i = 0; i < monitorCount; i++)
{
for (j = 0; j < _glfwLibrary.monitorCount; j++)
{
if (_glfwLibrary.monitors[j] == NULL)
continue;
if (strcmp(monitors[i]->name, _glfwLibrary.monitors[j]->name) == 0)
{
// This monitor was connected before, so re-use the existing
// monitor object to preserve its address and user pointer
_glfwDestroyMonitor(monitors[i]);
monitors[i] = _glfwLibrary.monitors[j];
_glfwLibrary.monitors[j] = NULL;
break;
}
}
if (j == _glfwLibrary.monitorCount)
{
// This monitor was not connected before
_glfwLibrary.monitorCallback(monitors[i], GLFW_MONITOR_CONNECTED);
}
}
for (i = 0; i < _glfwLibrary.monitorCount; i++)
{
if (_glfwLibrary.monitors[i] == NULL)
continue;
// This monitor is no longer connected
_glfwLibrary.monitorCallback(_glfwLibrary.monitors[i],
GLFW_MONITOR_DISCONNECTED);
}
_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;
} }
@ -148,26 +156,41 @@ void _glfwTerminateMonitors(void)
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
//======================================================================== //========================================================================
// Iterate through connected monitors // Return the currently connected monitors
//======================================================================== //========================================================================
GLFWAPI GLFWmonitor glfwGetNextMonitor(GLFWmonitor handle) GLFWAPI GLFWmonitor* glfwGetMonitors(int* count)
{ {
_GLFWmonitor* iterator = (_GLFWmonitor*) handle;
_GLFWmonitor* result;
if (!_glfwInitialized) if (!_glfwInitialized)
{ {
_glfwSetError(GLFW_NOT_INITIALIZED, NULL); _glfwSetError(GLFW_NOT_INITIALIZED, NULL);
return NULL; return NULL;
} }
if (iterator == NULL) if (count == NULL)
result = _glfwLibrary.monitorListHead; {
else _glfwSetError(GLFW_INVALID_VALUE, NULL);
result = iterator->next; return NULL;
}
return result; *count = _glfwLibrary.monitorCount;
return (GLFWmonitor*) _glfwLibrary.monitors;
}
//========================================================================
// Get the primary monitor
//========================================================================
GLFWAPI GLFWmonitor glfwGetPrimaryMonitor(void)
{
if (!_glfwInitialized)
{
_glfwSetError(GLFW_NOT_INITIALIZED, NULL);
return NULL;
}
return _glfwLibrary.monitors[0];
} }

View File

@ -185,16 +185,8 @@ void _glfwRestoreVideoMode(void)
GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* found) GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* found)
{ {
int deviceModeIndex = 0, count = 0; int modeIndex = 0, count = 0;
GLFWvidmode* result = NULL; GLFWvidmode* result = NULL;
WCHAR* deviceName;
deviceName = _glfwCreateWideStringFromUTF8(monitor->Win32.name);
if (!deviceName)
{
_glfwSetError(GLFW_PLATFORM_ERROR, "Win32: Failed to convert device name");
return NULL;
}
*found = 0; *found = 0;
@ -207,10 +199,10 @@ GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* found)
ZeroMemory(&dm, sizeof(DEVMODE)); ZeroMemory(&dm, sizeof(DEVMODE));
dm.dmSize = sizeof(DEVMODE); dm.dmSize = sizeof(DEVMODE);
if (!EnumDisplaySettings(deviceName, deviceModeIndex, &dm)) if (!EnumDisplaySettings(monitor->Win32.name, modeIndex, &dm))
break; break;
deviceModeIndex++; modeIndex++;
if (dm.dmBitsPerPel < 15) if (dm.dmBitsPerPel < 15)
{ {
@ -262,7 +254,6 @@ GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* found)
(*found)++; (*found)++;
} }
free(deviceName);
return result; return result;
} }
@ -274,19 +265,11 @@ GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* found)
void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode) void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode)
{ {
DEVMODE dm; DEVMODE dm;
WCHAR* deviceName;
deviceName = _glfwCreateWideStringFromUTF8(monitor->Win32.name);
if (!deviceName)
{
_glfwSetError(GLFW_PLATFORM_ERROR, "Win32: Failed to convert device name");
return;
}
ZeroMemory(&dm, sizeof(DEVMODE)); ZeroMemory(&dm, sizeof(DEVMODE));
dm.dmSize = sizeof(DEVMODE); dm.dmSize = sizeof(DEVMODE);
EnumDisplaySettings(deviceName, ENUM_REGISTRY_SETTINGS, &dm); EnumDisplaySettings(monitor->Win32.name, ENUM_REGISTRY_SETTINGS, &dm);
mode->width = dm.dmPelsWidth; mode->width = dm.dmPelsWidth;
mode->height = dm.dmPelsHeight; mode->height = dm.dmPelsHeight;

View File

@ -178,8 +178,6 @@ int _glfwPlatformInit(void)
_glfwPlatformGetGammaRamp(&_glfwLibrary.originalRamp); _glfwPlatformGetGammaRamp(&_glfwLibrary.originalRamp);
_glfwLibrary.currentRamp = _glfwLibrary.originalRamp; _glfwLibrary.currentRamp = _glfwLibrary.originalRamp;
_glfwInitMonitors();
_glfwInitTimer(); _glfwInitTimer();
return GL_TRUE; return GL_TRUE;
@ -196,8 +194,6 @@ int _glfwPlatformTerminate(void)
if (_glfwLibrary.rampChanged) if (_glfwLibrary.rampChanged)
_glfwPlatformSetGammaRamp(&_glfwLibrary.originalRamp); _glfwPlatformSetGammaRamp(&_glfwLibrary.originalRamp);
_glfwTerminateMonitors();
if (_glfwLibrary.Win32.classAtom) if (_glfwLibrary.Win32.classAtom)
{ {
UnregisterClass(_GLFW_WNDCLASSNAME, _glfwLibrary.Win32.instance); UnregisterClass(_GLFW_WNDCLASSNAME, _glfwLibrary.Win32.instance);

View File

@ -32,6 +32,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <wchar.h>
// The MinGW package for Debian lacks this // The MinGW package for Debian lacks this
#ifndef EDS_ROTATEDMODE #ifndef EDS_ROTATEDMODE
@ -49,34 +50,102 @@
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
//======================================================================== //========================================================================
// Create a monitor struct from the specified information // Return a list of available monitors
//======================================================================== //========================================================================
_GLFWmonitor** _glfwCreateMonitor(_GLFWmonitor** current, _GLFWmonitor** _glfwPlatformGetMonitors(int* count)
DISPLAY_DEVICE* adapter,
DISPLAY_DEVICE* monitor,
DEVMODE* setting)
{ {
HDC dc = NULL; int size = 0, found = 0;
_GLFWmonitor** monitors = NULL;
DWORD adapterIndex = 0;
*current = malloc(sizeof(_GLFWmonitor)); for (;;)
memset(*current, 0, sizeof(_GLFWmonitor)); {
DISPLAY_DEVICE adapter;
DWORD monitorIndex = 0;
dc = CreateDC(L"DISPLAY", monitor->DeviceString, NULL, NULL); ZeroMemory(&adapter, sizeof(DISPLAY_DEVICE));
adapter.cb = sizeof(DISPLAY_DEVICE);
(*current)->physicalWidth = GetDeviceCaps(dc, HORZSIZE); if (!EnumDisplayDevices(NULL, adapterIndex, &adapter, 0))
(*current)->physicalHeight = GetDeviceCaps(dc, VERTSIZE); break;
adapterIndex++;
if ((adapter.StateFlags & DISPLAY_DEVICE_MIRRORING_DRIVER) ||
!(adapter.StateFlags & DISPLAY_DEVICE_ACTIVE))
{
continue;
}
for (;;)
{
DISPLAY_DEVICE monitor;
DEVMODE settings;
const char* name;
HDC dc;
ZeroMemory(&monitor, sizeof(DISPLAY_DEVICE));
monitor.cb = sizeof(DISPLAY_DEVICE);
if (!EnumDisplayDevices(adapter.DeviceName, monitorIndex, &monitor, 0))
break;
ZeroMemory(&settings, sizeof(DEVMODE));
settings.dmSize = sizeof(DEVMODE);
EnumDisplaySettingsEx(adapter.DeviceName,
ENUM_CURRENT_SETTINGS,
&settings,
EDS_ROTATEDMODE);
name = _glfwCreateUTF8FromWideString(monitor.DeviceName);
if (!name)
{
// TODO: wat
return NULL;
}
dc = CreateDC(L"DISPLAY", monitor.DeviceString, NULL, NULL);
if (!dc)
{
// TODO: wat
return NULL;
}
if (found == size)
{
if (size)
size *= 2;
else
size = 4;
monitors = (_GLFWmonitor**) realloc(monitors, sizeof(_GLFWmonitor*) * size);
}
monitors[found] = _glfwCreateMonitor(name,
GetDeviceCaps(dc, HORZSIZE),
GetDeviceCaps(dc, VERTSIZE),
settings.dmPosition.x,
settings.dmPosition.y);
DeleteDC(dc); DeleteDC(dc);
(*current)->name = _glfwCreateUTF8FromWideString(monitor->DeviceName); if (!monitors[found])
{
// TODO: wat
return NULL;
}
(*current)->screenX = setting->dmPosition.x; monitors[found]->Win32.name = wcsdup(monitor.DeviceName);
(*current)->screenY = setting->dmPosition.y;
(*current)->Win32.name = _glfwCreateUTF8FromWideString(adapter->DeviceName); found++;
monitorIndex++;
}
}
return &((*current)->next); *count = found;
return monitors;
} }
@ -84,55 +153,8 @@ _GLFWmonitor** _glfwCreateMonitor(_GLFWmonitor** current,
// Destroy a monitor struct // Destroy a monitor struct
//======================================================================== //========================================================================
_GLFWmonitor* _glfwDestroyMonitor(_GLFWmonitor* monitor) void _glfwPlatformDestroyMonitor(_GLFWmonitor* monitor)
{ {
_GLFWmonitor* result;
result = monitor->next;
free(monitor->Win32.name); free(monitor->Win32.name);
free(monitor->name);
free(monitor);
return result;
}
//========================================================================
// Return a list of available monitors
//========================================================================
_GLFWmonitor* _glfwCreateMonitors(void)
{
DISPLAY_DEVICE adapter;
DWORD adapterNum;
DISPLAY_DEVICE monitor;
DEVMODE setting;
_GLFWmonitor* monitorList;
_GLFWmonitor** curMonitor;
adapter.cb = sizeof(DISPLAY_DEVICE);
adapterNum = 0;
monitor.cb = sizeof(DISPLAY_DEVICE);
setting.dmSize = sizeof(DEVMODE);
monitorList = NULL;
curMonitor = &monitorList;
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);
}
return monitorList;
} }

View File

@ -219,7 +219,7 @@ typedef struct _GLFWlibraryWin32
//------------------------------------------------------------------------ //------------------------------------------------------------------------
typedef struct _GLFWmonitorWin32 typedef struct _GLFWmonitorWin32
{ {
char* name; WCHAR* name;
} _GLFWmonitorWin32; } _GLFWmonitorWin32;
@ -244,10 +244,6 @@ char* _glfwCreateUTF8FromWideString(const WCHAR* source);
// Time // Time
void _glfwInitTimer(void); void _glfwInitTimer(void);
// Monitor support
_GLFWmonitor* _glfwCreateMonitors(void);
_GLFWmonitor* _glfwDestroyMonitor(_GLFWmonitor* monitor);
// OpenGL support // OpenGL support
int _glfwCreateContext(_GLFWwindow* window, int _glfwCreateContext(_GLFWwindow* window,
const _GLFWwndconfig* wndconfig, const _GLFWwndconfig* wndconfig,

View File

@ -670,7 +670,7 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
{ {
if (DBT_DEVNODES_CHANGED == wParam) if (DBT_DEVNODES_CHANGED == wParam)
{ {
_glfwRefreshMonitors(); _glfwInputMonitorChange();
return TRUE; return TRUE;
} }
break; break;

View File

@ -651,8 +651,6 @@ int _glfwPlatformInit(void)
if (!_glfwInitJoysticks()) if (!_glfwInitJoysticks())
return GL_FALSE; return GL_FALSE;
_glfwInitMonitors();
// Start the timer // Start the timer
_glfwInitTimer(); _glfwInitTimer();
@ -676,8 +674,6 @@ int _glfwPlatformTerminate(void)
terminateDisplay(); terminateDisplay();
_glfwTerminateMonitors();
_glfwTerminateJoysticks(); _glfwTerminateJoysticks();
_glfwTerminateOpenGL(); _glfwTerminateOpenGL();

View File

@ -34,111 +34,83 @@
#include <string.h> #include <string.h>
//========================================================================
// Create a monitor struct from the specified information
//========================================================================
#if defined (_GLFW_HAS_XRANDR)
static _GLFWmonitor** createMonitor(_GLFWmonitor** current,
XRROutputInfo* outputInfo,
XRRCrtcInfo* crtcInfo)
{
*current = malloc(sizeof(_GLFWmonitor));
memset(*current, 0, sizeof(_GLFWmonitor));
(*current)->physicalWidth = outputInfo->mm_width;
(*current)->physicalHeight = outputInfo->mm_height;
(*current)->name = strdup(outputInfo->name);
(*current)->screenX = crtcInfo->x;
(*current)->screenY = crtcInfo->y;
(*current)->X11.output = outputInfo;
return &((*current)->next);
}
#endif /*_GLFW_HAS_XRANDR*/
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
////// GLFW platform API ////// ////// GLFW platform API //////
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
//========================================================================
// Destroy a monitor struct
//========================================================================
_GLFWmonitor* _glfwDestroyMonitor(_GLFWmonitor* monitor)
{
_GLFWmonitor* result;
result = monitor->next;
#if defined (_GLFW_HAS_XRANDR)
XRRFreeOutputInfo(monitor->X11.output);
#endif /*_GLFW_HAS_XRANDR*/
free(monitor->modes);
free(monitor->name);
free(monitor);
return result;
}
//======================================================================== //========================================================================
// Return a list of available monitors // Return a list of available monitors
//======================================================================== //========================================================================
_GLFWmonitor* _glfwCreateMonitors(void) _GLFWmonitor** _glfwPlatformGetMonitors(int* count)
{ {
_GLFWmonitor* monitorList = NULL; int found = 0;
_GLFWmonitor** monitors = NULL;
if (_glfwLibrary.X11.RandR.available) if (_glfwLibrary.X11.RandR.available)
{ {
#if defined (_GLFW_HAS_XRANDR) #if defined (_GLFW_HAS_XRANDR)
int oi; int i;
XRRScreenResources* resources; XRRScreenResources* sr;
_GLFWmonitor** monitor = &monitorList;
resources = XRRGetScreenResources(_glfwLibrary.X11.display, sr = XRRGetScreenResources(_glfwLibrary.X11.display,
_glfwLibrary.X11.root); _glfwLibrary.X11.root);
for (oi = 0; oi < resources->noutput; oi++) monitors = (_GLFWmonitor**) calloc(sr->noutput, sizeof(_GLFWmonitor*));
if (!monitors)
{ {
// physical device _glfwSetError(GLFW_OUT_OF_MEMORY, NULL);
XRROutputInfo* outputInfo = NULL; return NULL;
// logical surface
XRRCrtcInfo* crtcInfo = NULL;
outputInfo = XRRGetOutputInfo(_glfwLibrary.X11.display,
resources,
resources->outputs[oi]);
if (outputInfo->connection == RR_Connected)
{
int ci;
for (ci = 0; ci < outputInfo->ncrtc; ci++)
{
if (outputInfo->crtc == outputInfo->crtcs[ci])
{
crtcInfo = XRRGetCrtcInfo(_glfwLibrary.X11.display,
resources,
outputInfo->crtcs[ci]);
break;
}
} }
monitor = createMonitor(monitor, outputInfo, crtcInfo); for (i = 0; i < sr->noutput; i++)
{
XRROutputInfo* oi;
XRRCrtcInfo* ci;
// Freeing of the outputInfo is done in _glfwDestroyMonitor oi = XRRGetOutputInfo(_glfwLibrary.X11.display, sr, sr->outputs[i]);
XRRFreeCrtcInfo(crtcInfo); if (oi->connection != RR_Connected)
{
XRRFreeOutputInfo(oi);
continue;
} }
ci = XRRGetCrtcInfo(_glfwLibrary.X11.display, sr, oi->crtc);
monitors[found] = _glfwCreateMonitor(oi->name,
oi->mm_width, oi->mm_height,
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*/ #endif /*_GLFW_HAS_XRANDR*/
} }
return monitorList; *count = found;
return monitors;
}
//========================================================================
// Destroy a monitor struct
//========================================================================
void _glfwPlatformDestroyMonitor(_GLFWmonitor* monitor)
{
#if defined (_GLFW_HAS_XRANDR)
XRRFreeOutputInfo(monitor->X11.output);
#endif /*_GLFW_HAS_XRANDR*/
} }

View File

@ -325,10 +325,6 @@ void _glfwRestoreVideoMode(void);
int _glfwInitJoysticks(void); int _glfwInitJoysticks(void);
void _glfwTerminateJoysticks(void); void _glfwTerminateJoysticks(void);
// Monitors
_GLFWmonitor* _glfwCreateMonitors(void);
_GLFWmonitor* _glfwDestroyMonitor(_GLFWmonitor* monitor);
// Unicode support // Unicode support
long _glfwKeySym2Unicode(KeySym keysym); long _glfwKeySym2Unicode(KeySym keysym);

View File

@ -810,7 +810,7 @@ static void processEvent(XEvent *event)
case RRScreenChangeNotify: case RRScreenChangeNotify:
{ {
XRRUpdateConfiguration(event); XRRUpdateConfiguration(event);
_glfwRefreshMonitors(); _glfwInputMonitorChange();
break; break;
} }
} }

View File

@ -120,7 +120,7 @@ int main(int argc, char** argv)
if (mode == GLFW_FULLSCREEN) if (mode == GLFW_FULLSCREEN)
{ {
GLFWvidmode mode; GLFWvidmode mode;
glfwGetVideoMode(glfwGetNextMonitor(NULL), &mode); glfwGetVideoMode(glfwGetPrimaryMonitor(), &mode);
width = mode.width; width = mode.width;
height = mode.height; height = mode.height;
} }

View File

@ -101,7 +101,7 @@ int main(int argc, char** argv)
if (mode == GLFW_FULLSCREEN) if (mode == GLFW_FULLSCREEN)
{ {
GLFWvidmode current_mode; GLFWvidmode current_mode;
glfwGetVideoMode(glfwGetNextMonitor(NULL), &current_mode); glfwGetVideoMode(glfwGetPrimaryMonitor(), &current_mode);
width = current_mode.width; width = current_mode.width;
height = current_mode.height; height = current_mode.height;
} }

View File

@ -199,8 +199,8 @@ static void test_modes(GLFWmonitor monitor)
int main(int argc, char** argv) int main(int argc, char** argv)
{ {
int ch, mode = LIST_MODE; int ch, i, count, mode = LIST_MODE;
GLFWmonitor monitor = NULL; GLFWmonitor* monitors;
while ((ch = getopt(argc, argv, "th")) != -1) while ((ch = getopt(argc, argv, "th")) != -1)
{ {
@ -226,12 +226,14 @@ int main(int argc, char** argv)
if (!glfwInit()) if (!glfwInit())
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
while ((monitor = glfwGetNextMonitor(monitor))) monitors = glfwGetMonitors(&count);
for (i = 0; i < count; i++)
{ {
if (mode == LIST_MODE) if (mode == LIST_MODE)
list_modes(monitor); list_modes(monitors[i]);
else if (mode == TEST_MODE) else if (mode == TEST_MODE)
test_modes(monitor); test_modes(monitors[i]);
} }
exit(EXIT_SUCCESS); exit(EXIT_SUCCESS);