mirror of
https://github.com/glfw/glfw.git
synced 2024-11-22 13:04:35 +00:00
Restructure monitor enumeration
This way is both kinder on event-based enumeration and less work to unwind allocations for when properly implementing GLFW_OUT_OF_MEMORY.
This commit is contained in:
parent
ecda05af29
commit
04f559e28d
@ -322,6 +322,7 @@ int _glfwPlatformInit(void)
|
|||||||
_glfwInitTimerNS();
|
_glfwInitTimerNS();
|
||||||
_glfwInitJoysticksNS();
|
_glfwInitJoysticksNS();
|
||||||
|
|
||||||
|
_glfwPollMonitorsNS();
|
||||||
return GLFW_TRUE;
|
return GLFW_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -209,6 +209,66 @@ static void endFadeReservation(CGDisplayFadeReservationToken token)
|
|||||||
////// GLFW internal API //////
|
////// GLFW internal API //////
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// Poll for changes in the set of connected monitors
|
||||||
|
//
|
||||||
|
void _glfwPollMonitorsNS(void)
|
||||||
|
{
|
||||||
|
uint32_t i, j, displayCount, disconnectedCount;
|
||||||
|
CGDirectDisplayID* displays;
|
||||||
|
_GLFWmonitor** disconnected;
|
||||||
|
|
||||||
|
CGGetOnlineDisplayList(0, NULL, &displayCount);
|
||||||
|
displays = calloc(displayCount, sizeof(CGDirectDisplayID));
|
||||||
|
CGGetOnlineDisplayList(displayCount, displays, &displayCount);
|
||||||
|
|
||||||
|
disconnectedCount = _glfw.monitorCount;
|
||||||
|
disconnected = calloc(_glfw.monitorCount, sizeof(_GLFWmonitor*));
|
||||||
|
memcpy(disconnected, _glfw.monitors, _glfw.monitorCount * sizeof(_GLFWmonitor*));
|
||||||
|
|
||||||
|
for (i = 0; i < displayCount; i++)
|
||||||
|
{
|
||||||
|
_GLFWmonitor* monitor;
|
||||||
|
const uint32_t unitNumber = CGDisplayUnitNumber(displays[i]);
|
||||||
|
|
||||||
|
if (CGDisplayIsAsleep(displays[i]))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
for (j = 0; j < disconnectedCount; j++)
|
||||||
|
{
|
||||||
|
// HACK: Compare unit numbers instead of display IDs to work around
|
||||||
|
// display replacement on machines with automatic graphics
|
||||||
|
// switching
|
||||||
|
if (disconnected[j] && disconnected[j]->ns.unitNumber == unitNumber)
|
||||||
|
{
|
||||||
|
disconnected[j] = NULL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const CGSize size = CGDisplayScreenSize(displays[i]);
|
||||||
|
char* name = getDisplayName(displays[i]);
|
||||||
|
if (!name)
|
||||||
|
name = strdup("Unknown");
|
||||||
|
|
||||||
|
monitor = _glfwAllocMonitor(name, size.width, size.height);
|
||||||
|
monitor->ns.displayID = displays[i];
|
||||||
|
monitor->ns.unitNumber = unitNumber;
|
||||||
|
|
||||||
|
free(name);
|
||||||
|
|
||||||
|
_glfwInputMonitor(monitor, GLFW_CONNECTED, _GLFW_INSERT_LAST);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < disconnectedCount; i++)
|
||||||
|
{
|
||||||
|
if (disconnected[i])
|
||||||
|
_glfwInputMonitor(disconnected[i], GLFW_DISCONNECTED, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
free(disconnected);
|
||||||
|
free(displays);
|
||||||
|
}
|
||||||
|
|
||||||
// Change the current video mode
|
// Change the current video mode
|
||||||
//
|
//
|
||||||
GLFWbool _glfwSetVideoModeNS(_GLFWmonitor* monitor, const GLFWvidmode* desired)
|
GLFWbool _glfwSetVideoModeNS(_GLFWmonitor* monitor, const GLFWvidmode* desired)
|
||||||
@ -288,55 +348,6 @@ void _glfwRestoreVideoModeNS(_GLFWmonitor* monitor)
|
|||||||
////// GLFW platform API //////
|
////// GLFW platform API //////
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
_GLFWmonitor** _glfwPlatformGetMonitors(int* count)
|
|
||||||
{
|
|
||||||
uint32_t i, found = 0, displayCount;
|
|
||||||
_GLFWmonitor** monitors;
|
|
||||||
CGDirectDisplayID* displays;
|
|
||||||
|
|
||||||
*count = 0;
|
|
||||||
|
|
||||||
CGGetOnlineDisplayList(0, NULL, &displayCount);
|
|
||||||
displays = calloc(displayCount, sizeof(CGDirectDisplayID));
|
|
||||||
monitors = calloc(displayCount, sizeof(_GLFWmonitor*));
|
|
||||||
|
|
||||||
CGGetOnlineDisplayList(displayCount, displays, &displayCount);
|
|
||||||
|
|
||||||
for (i = 0; i < displayCount; i++)
|
|
||||||
{
|
|
||||||
_GLFWmonitor* monitor;
|
|
||||||
|
|
||||||
if (CGDisplayIsAsleep(displays[i]))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
const CGSize size = CGDisplayScreenSize(displays[i]);
|
|
||||||
char* name = getDisplayName(displays[i]);
|
|
||||||
if (!name)
|
|
||||||
name = strdup("Unknown");
|
|
||||||
|
|
||||||
monitor = _glfwAllocMonitor(name, size.width, size.height);
|
|
||||||
monitor->ns.displayID = displays[i];
|
|
||||||
monitor->ns.unitNumber = CGDisplayUnitNumber(displays[i]);
|
|
||||||
|
|
||||||
free(name);
|
|
||||||
|
|
||||||
found++;
|
|
||||||
monitors[found - 1] = monitor;
|
|
||||||
}
|
|
||||||
|
|
||||||
free(displays);
|
|
||||||
|
|
||||||
*count = found;
|
|
||||||
return monitors;
|
|
||||||
}
|
|
||||||
|
|
||||||
GLFWbool _glfwPlatformIsSameMonitor(_GLFWmonitor* first, _GLFWmonitor* second)
|
|
||||||
{
|
|
||||||
// HACK: Compare unit numbers instead of display IDs to work around display
|
|
||||||
// replacement on machines with automatic graphics switching
|
|
||||||
return first->ns.unitNumber == second->ns.unitNumber;
|
|
||||||
}
|
|
||||||
|
|
||||||
void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos)
|
void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos)
|
||||||
{
|
{
|
||||||
const CGRect bounds = CGDisplayBounds(monitor->ns.displayID);
|
const CGRect bounds = CGDisplayBounds(monitor->ns.displayID);
|
||||||
|
@ -158,6 +158,7 @@ typedef struct _GLFWtimeNS
|
|||||||
|
|
||||||
void _glfwInitTimerNS(void);
|
void _glfwInitTimerNS(void);
|
||||||
|
|
||||||
|
void _glfwPollMonitorsNS(void);
|
||||||
GLFWbool _glfwSetVideoModeNS(_GLFWmonitor* monitor, const GLFWvidmode* desired);
|
GLFWbool _glfwSetVideoModeNS(_GLFWmonitor* monitor, const GLFWvidmode* desired);
|
||||||
void _glfwRestoreVideoModeNS(_GLFWmonitor* monitor);
|
void _glfwRestoreVideoModeNS(_GLFWmonitor* monitor);
|
||||||
|
|
||||||
|
@ -340,7 +340,7 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
|
|||||||
|
|
||||||
- (void)applicationDidChangeScreenParameters:(NSNotification *) notification
|
- (void)applicationDidChangeScreenParameters:(NSNotification *) notification
|
||||||
{
|
{
|
||||||
_glfwInputMonitorChange();
|
_glfwPollMonitorsNS();
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)applicationDidFinishLaunching:(NSNotification *)notification
|
- (void)applicationDidFinishLaunching:(NSNotification *)notification
|
||||||
|
@ -130,7 +130,6 @@ GLFWAPI int glfwInit(void)
|
|||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
_glfw.monitors = _glfwPlatformGetMonitors(&_glfw.monitorCount);
|
|
||||||
_glfwInitialized = GLFW_TRUE;
|
_glfwInitialized = GLFW_TRUE;
|
||||||
|
|
||||||
_glfw.timerOffset = _glfwPlatformGetTimerValue();
|
_glfw.timerOffset = _glfwPlatformGetTimerValue();
|
||||||
|
@ -48,6 +48,9 @@
|
|||||||
#define GLFW_INCLUDE_NONE
|
#define GLFW_INCLUDE_NONE
|
||||||
#include "../include/GLFW/glfw3.h"
|
#include "../include/GLFW/glfw3.h"
|
||||||
|
|
||||||
|
#define _GLFW_INSERT_FIRST 0
|
||||||
|
#define _GLFW_INSERT_LAST 1
|
||||||
|
|
||||||
typedef int GLFWbool;
|
typedef int GLFWbool;
|
||||||
|
|
||||||
typedef struct _GLFWwndconfig _GLFWwndconfig;
|
typedef struct _GLFWwndconfig _GLFWwndconfig;
|
||||||
@ -563,21 +566,6 @@ const char* _glfwPlatformGetKeyName(int key, int scancode);
|
|||||||
*/
|
*/
|
||||||
int _glfwPlatformGetKeyScancode(int key);
|
int _glfwPlatformGetKeyScancode(int key);
|
||||||
|
|
||||||
/*! @copydoc glfwGetMonitors
|
|
||||||
* @ingroup platform
|
|
||||||
*/
|
|
||||||
_GLFWmonitor** _glfwPlatformGetMonitors(int* count);
|
|
||||||
|
|
||||||
/*! @brief Checks whether two monitor objects represent the same monitor.
|
|
||||||
*
|
|
||||||
* @param[in] first The first monitor.
|
|
||||||
* @param[in] second The second monitor.
|
|
||||||
* @return @c GLFW_TRUE if the monitor objects represent the same monitor, or
|
|
||||||
* @c GLFW_FALSE otherwise.
|
|
||||||
* @ingroup platform
|
|
||||||
*/
|
|
||||||
GLFWbool _glfwPlatformIsSameMonitor(_GLFWmonitor* first, _GLFWmonitor* second);
|
|
||||||
|
|
||||||
/*! @copydoc glfwGetMonitorPos
|
/*! @copydoc glfwGetMonitorPos
|
||||||
* @ingroup platform
|
* @ingroup platform
|
||||||
*/
|
*/
|
||||||
@ -959,7 +947,7 @@ void _glfwInputCursorEnter(_GLFWwindow* window, GLFWbool entered);
|
|||||||
|
|
||||||
/*! @ingroup event
|
/*! @ingroup event
|
||||||
*/
|
*/
|
||||||
void _glfwInputMonitorChange(void);
|
void _glfwInputMonitor(_GLFWmonitor* monitor, int action, int type);
|
||||||
|
|
||||||
/*! @ingroup event
|
/*! @ingroup event
|
||||||
*/
|
*/
|
||||||
|
@ -213,6 +213,7 @@ int _glfwPlatformInit(void)
|
|||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_glfwPollMonitorsMir();
|
||||||
return GLFW_TRUE;
|
return GLFW_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,18 +30,17 @@
|
|||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
////// GLFW platform API //////
|
////// GLFW internal API //////
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
_GLFWmonitor** _glfwPlatformGetMonitors(int* count)
|
// Poll for changes in the set of connected monitors
|
||||||
|
//
|
||||||
|
void _glfwPollMonitorsMir(void)
|
||||||
{
|
{
|
||||||
int i, found = 0;
|
int i;
|
||||||
_GLFWmonitor** monitors = NULL;
|
|
||||||
MirDisplayConfiguration* displayConfig =
|
MirDisplayConfiguration* displayConfig =
|
||||||
mir_connection_create_display_config(_glfw.mir.connection);
|
mir_connection_create_display_config(_glfw.mir.connection);
|
||||||
|
|
||||||
*count = 0;
|
|
||||||
|
|
||||||
for (i = 0; i < displayConfig->num_outputs; i++)
|
for (i = 0; i < displayConfig->num_outputs; i++)
|
||||||
{
|
{
|
||||||
const MirDisplayOutput* out = displayConfig->outputs + i;
|
const MirDisplayOutput* out = displayConfig->outputs + i;
|
||||||
@ -51,32 +50,27 @@ _GLFWmonitor** _glfwPlatformGetMonitors(int* count)
|
|||||||
out->num_modes &&
|
out->num_modes &&
|
||||||
out->current_mode < out->num_modes)
|
out->current_mode < out->num_modes)
|
||||||
{
|
{
|
||||||
found++;
|
_GLFWmonitor* monitor = _glfwAllocMonitor("Unknown",
|
||||||
monitors = realloc(monitors, sizeof(_GLFWmonitor*) * found);
|
|
||||||
monitors[i] = _glfwAllocMonitor("Unknown",
|
|
||||||
out->physical_width_mm,
|
out->physical_width_mm,
|
||||||
out->physical_height_mm);
|
out->physical_height_mm);
|
||||||
|
|
||||||
monitors[i]->mir.x = out->position_x;
|
monitor->mir.x = out->position_x;
|
||||||
monitors[i]->mir.y = out->position_y;
|
monitor->mir.y = out->position_y;
|
||||||
monitors[i]->mir.outputId = out->output_id;
|
monitor->mir.outputId = out->output_id;
|
||||||
monitors[i]->mir.curMode = out->current_mode;
|
monitor->mir.curMode = out->current_mode;
|
||||||
|
monitor->modes = _glfwPlatformGetVideoModes(monitor, &monitor->modeCount);
|
||||||
|
|
||||||
monitors[i]->modes = _glfwPlatformGetVideoModes(monitors[i],
|
_glfwInputMonitor(monitor, GLFW_CONNECTED, _GLFW_INSERT_LAST);
|
||||||
&monitors[i]->modeCount);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mir_display_config_destroy(displayConfig);
|
mir_display_config_destroy(displayConfig);
|
||||||
|
|
||||||
*count = found;
|
|
||||||
return monitors;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GLFWbool _glfwPlatformIsSameMonitor(_GLFWmonitor* first, _GLFWmonitor* second)
|
|
||||||
{
|
//////////////////////////////////////////////////////////////////////////
|
||||||
return first->mir.outputId == second->mir.outputId;
|
////// GLFW platform API //////
|
||||||
}
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos)
|
void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos)
|
||||||
{
|
{
|
||||||
|
@ -86,80 +86,46 @@ static GLFWbool refreshVideoModes(_GLFWmonitor* monitor)
|
|||||||
////// GLFW event API //////
|
////// GLFW event API //////
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void _glfwInputMonitorChange(void)
|
void _glfwInputMonitor(_GLFWmonitor* monitor, int action, int type)
|
||||||
{
|
{
|
||||||
int i, j, monitorCount = _glfw.monitorCount;
|
if (action == GLFW_CONNECTED)
|
||||||
_GLFWmonitor** monitors = _glfw.monitors;
|
{
|
||||||
|
_glfw.monitorCount++;
|
||||||
|
_glfw.monitors =
|
||||||
|
realloc(_glfw.monitors, sizeof(_GLFWmonitor*) * _glfw.monitorCount);
|
||||||
|
|
||||||
_glfw.monitors = _glfwPlatformGetMonitors(&_glfw.monitorCount);
|
if (type == _GLFW_INSERT_FIRST)
|
||||||
|
{
|
||||||
// Re-use still connected monitor objects
|
memmove(_glfw.monitors + 1,
|
||||||
|
_glfw.monitors,
|
||||||
|
(_glfw.monitorCount - 1) * sizeof(_GLFWmonitor*));
|
||||||
|
_glfw.monitors[0] = monitor;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
_glfw.monitors[_glfw.monitorCount - 1] = monitor;
|
||||||
|
}
|
||||||
|
else if (action == GLFW_DISCONNECTED)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < _glfw.monitorCount; i++)
|
for (i = 0; i < _glfw.monitorCount; i++)
|
||||||
{
|
{
|
||||||
for (j = 0; j < monitorCount; j++)
|
if (_glfw.monitors[i] == monitor)
|
||||||
{
|
{
|
||||||
if (_glfwPlatformIsSameMonitor(_glfw.monitors[i], monitors[j]))
|
_glfw.monitorCount--;
|
||||||
{
|
memmove(_glfw.monitors + i,
|
||||||
_glfwFreeMonitor(_glfw.monitors[i]);
|
_glfw.monitors + i + 1,
|
||||||
_glfw.monitors[i] = monitors[j];
|
(_glfw.monitorCount - i) * sizeof(_GLFWmonitor*));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find and report disconnected monitors (not in the new list)
|
|
||||||
|
|
||||||
for (i = 0; i < monitorCount; i++)
|
|
||||||
{
|
|
||||||
_GLFWwindow* window;
|
|
||||||
|
|
||||||
for (j = 0; j < _glfw.monitorCount; j++)
|
|
||||||
{
|
|
||||||
if (monitors[i] == _glfw.monitors[j])
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (j < _glfw.monitorCount)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
for (window = _glfw.windowListHead; window; window = window->next)
|
|
||||||
{
|
|
||||||
if (window->monitor == monitors[i])
|
|
||||||
{
|
|
||||||
int width, height;
|
|
||||||
_glfwPlatformGetWindowSize(window, &width, &height);
|
|
||||||
_glfwPlatformSetWindowMonitor(window, NULL, 0, 0, width, height, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_glfw.callbacks.monitor)
|
if (_glfw.callbacks.monitor)
|
||||||
_glfw.callbacks.monitor((GLFWmonitor*) monitors[i], GLFW_DISCONNECTED);
|
_glfw.callbacks.monitor((GLFWmonitor*) monitor, action);
|
||||||
}
|
|
||||||
|
|
||||||
// Find and report newly connected monitors (not in the old list)
|
if (action == GLFW_DISCONNECTED)
|
||||||
// Re-used monitor objects are then removed from the old list to avoid
|
_glfwFreeMonitor(monitor);
|
||||||
// having them destroyed at the end of this function
|
|
||||||
|
|
||||||
for (i = 0; i < _glfw.monitorCount; i++)
|
|
||||||
{
|
|
||||||
for (j = 0; j < monitorCount; j++)
|
|
||||||
{
|
|
||||||
if (_glfw.monitors[i] == monitors[j])
|
|
||||||
{
|
|
||||||
monitors[j] = NULL;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (j < monitorCount)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (_glfw.callbacks.monitor)
|
|
||||||
_glfw.callbacks.monitor((GLFWmonitor*) _glfw.monitors[i], GLFW_CONNECTED);
|
|
||||||
}
|
|
||||||
|
|
||||||
_glfwFreeMonitors(monitors, monitorCount);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void _glfwInputMonitorWindowChange(_GLFWmonitor* monitor, _GLFWwindow* window)
|
void _glfwInputMonitorWindowChange(_GLFWmonitor* monitor, _GLFWwindow* window)
|
||||||
|
@ -32,18 +32,6 @@
|
|||||||
////// GLFW platform API //////
|
////// GLFW platform API //////
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
_GLFWmonitor** _glfwPlatformGetMonitors(int* count)
|
|
||||||
{
|
|
||||||
// OSMesa is headless, so no monitors
|
|
||||||
*count = 0;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
int _glfwPlatformIsSameMonitor(_GLFWmonitor* first, _GLFWmonitor* second)
|
|
||||||
{
|
|
||||||
return GLFW_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos)
|
void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -433,6 +433,7 @@ int _glfwPlatformInit(void)
|
|||||||
_glfwInitTimerWin32();
|
_glfwInitTimerWin32();
|
||||||
_glfwInitJoysticksWin32();
|
_glfwInitJoysticksWin32();
|
||||||
|
|
||||||
|
_glfwPollMonitorsWin32();
|
||||||
return GLFW_TRUE;
|
return GLFW_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,6 +90,122 @@ static _GLFWmonitor* createMonitor(DISPLAY_DEVICEW* adapter,
|
|||||||
////// GLFW internal API //////
|
////// GLFW internal API //////
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// Poll for changes in the set of connected monitors
|
||||||
|
//
|
||||||
|
void _glfwPollMonitorsWin32(void)
|
||||||
|
{
|
||||||
|
int i, disconnectedCount;
|
||||||
|
_GLFWmonitor** disconnected;
|
||||||
|
DWORD adapterIndex, displayIndex;
|
||||||
|
DISPLAY_DEVICEW adapter, display;
|
||||||
|
GLFWbool hasDisplays = GLFW_FALSE;
|
||||||
|
|
||||||
|
disconnectedCount = _glfw.monitorCount;
|
||||||
|
disconnected = calloc(_glfw.monitorCount, sizeof(_GLFWmonitor*));
|
||||||
|
memcpy(disconnected,
|
||||||
|
_glfw.monitors,
|
||||||
|
_glfw.monitorCount * sizeof(_GLFWmonitor*));
|
||||||
|
|
||||||
|
// HACK: Check if any active adapters have connected displays
|
||||||
|
// If not, this is a headless system or a VMware guest
|
||||||
|
|
||||||
|
for (adapterIndex = 0; ; adapterIndex++)
|
||||||
|
{
|
||||||
|
ZeroMemory(&adapter, sizeof(DISPLAY_DEVICEW));
|
||||||
|
adapter.cb = sizeof(DISPLAY_DEVICEW);
|
||||||
|
|
||||||
|
if (!EnumDisplayDevicesW(NULL, adapterIndex, &adapter, 0))
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (!(adapter.StateFlags & DISPLAY_DEVICE_ACTIVE))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
ZeroMemory(&display, sizeof(DISPLAY_DEVICEW));
|
||||||
|
display.cb = sizeof(DISPLAY_DEVICEW);
|
||||||
|
|
||||||
|
if (EnumDisplayDevicesW(adapter.DeviceName, 0, &display, 0))
|
||||||
|
{
|
||||||
|
hasDisplays = GLFW_TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (adapterIndex = 0; ; adapterIndex++)
|
||||||
|
{
|
||||||
|
int type = _GLFW_INSERT_LAST;
|
||||||
|
|
||||||
|
ZeroMemory(&adapter, sizeof(DISPLAY_DEVICEW));
|
||||||
|
adapter.cb = sizeof(DISPLAY_DEVICEW);
|
||||||
|
|
||||||
|
if (!EnumDisplayDevicesW(NULL, adapterIndex, &adapter, 0))
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (!(adapter.StateFlags & DISPLAY_DEVICE_ACTIVE))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (adapter.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE)
|
||||||
|
type = _GLFW_INSERT_FIRST;
|
||||||
|
|
||||||
|
if (hasDisplays)
|
||||||
|
{
|
||||||
|
for (displayIndex = 0; ; displayIndex++)
|
||||||
|
{
|
||||||
|
ZeroMemory(&display, sizeof(DISPLAY_DEVICEW));
|
||||||
|
display.cb = sizeof(DISPLAY_DEVICEW);
|
||||||
|
|
||||||
|
if (!EnumDisplayDevicesW(adapter.DeviceName, displayIndex, &display, 0))
|
||||||
|
break;
|
||||||
|
|
||||||
|
for (i = 0; i < disconnectedCount; i++)
|
||||||
|
{
|
||||||
|
if (disconnected[i] &&
|
||||||
|
wcscmp(disconnected[i]->win32.displayName,
|
||||||
|
display.DeviceName) == 0)
|
||||||
|
{
|
||||||
|
disconnected[i] = NULL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i < disconnectedCount)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
_glfwInputMonitor(createMonitor(&adapter, &display),
|
||||||
|
GLFW_CONNECTED, type);
|
||||||
|
|
||||||
|
type = _GLFW_INSERT_LAST;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (i = 0; i < disconnectedCount; i++)
|
||||||
|
{
|
||||||
|
if (disconnected[i] &&
|
||||||
|
wcscmp(disconnected[i]->win32.adapterName,
|
||||||
|
adapter.DeviceName) == 0)
|
||||||
|
{
|
||||||
|
disconnected[i] = NULL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i < disconnectedCount)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
_glfwInputMonitor(createMonitor(&adapter, NULL),
|
||||||
|
GLFW_CONNECTED, type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < disconnectedCount; i++)
|
||||||
|
{
|
||||||
|
if (disconnected[i])
|
||||||
|
_glfwInputMonitor(disconnected[i], GLFW_DISCONNECTED, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
free(disconnected);
|
||||||
|
}
|
||||||
|
|
||||||
// Change the current video mode
|
// Change the current video mode
|
||||||
//
|
//
|
||||||
GLFWbool _glfwSetVideoModeWin32(_GLFWmonitor* monitor, const GLFWvidmode* desired)
|
GLFWbool _glfwSetVideoModeWin32(_GLFWmonitor* monitor, const GLFWvidmode* desired)
|
||||||
@ -146,91 +262,6 @@ void _glfwRestoreVideoModeWin32(_GLFWmonitor* monitor)
|
|||||||
////// GLFW platform API //////
|
////// GLFW platform API //////
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
_GLFWmonitor** _glfwPlatformGetMonitors(int* count)
|
|
||||||
{
|
|
||||||
int found = 0;
|
|
||||||
DWORD adapterIndex, displayIndex, primaryIndex = 0;
|
|
||||||
DISPLAY_DEVICEW adapter, display;
|
|
||||||
GLFWbool hasDisplays = GLFW_FALSE;
|
|
||||||
_GLFWmonitor** monitors = NULL;
|
|
||||||
|
|
||||||
*count = 0;
|
|
||||||
|
|
||||||
// HACK: Check if any active adapters have connected displays
|
|
||||||
// If not, this is a headless system or a VMware guest
|
|
||||||
|
|
||||||
for (adapterIndex = 0; ; adapterIndex++)
|
|
||||||
{
|
|
||||||
ZeroMemory(&adapter, sizeof(DISPLAY_DEVICEW));
|
|
||||||
adapter.cb = sizeof(DISPLAY_DEVICEW);
|
|
||||||
|
|
||||||
if (!EnumDisplayDevicesW(NULL, adapterIndex, &adapter, 0))
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (!(adapter.StateFlags & DISPLAY_DEVICE_ACTIVE))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
ZeroMemory(&display, sizeof(DISPLAY_DEVICEW));
|
|
||||||
display.cb = sizeof(DISPLAY_DEVICEW);
|
|
||||||
|
|
||||||
if (EnumDisplayDevicesW(adapter.DeviceName, 0, &display, 0))
|
|
||||||
{
|
|
||||||
hasDisplays = GLFW_TRUE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (adapterIndex = 0; ; adapterIndex++)
|
|
||||||
{
|
|
||||||
ZeroMemory(&adapter, sizeof(DISPLAY_DEVICEW));
|
|
||||||
adapter.cb = sizeof(DISPLAY_DEVICEW);
|
|
||||||
|
|
||||||
if (!EnumDisplayDevicesW(NULL, adapterIndex, &adapter, 0))
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (!(adapter.StateFlags & DISPLAY_DEVICE_ACTIVE))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (adapter.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE)
|
|
||||||
primaryIndex = found;
|
|
||||||
|
|
||||||
if (hasDisplays)
|
|
||||||
{
|
|
||||||
for (displayIndex = 0; ; displayIndex++)
|
|
||||||
{
|
|
||||||
ZeroMemory(&display, sizeof(DISPLAY_DEVICEW));
|
|
||||||
display.cb = sizeof(DISPLAY_DEVICEW);
|
|
||||||
|
|
||||||
if (!EnumDisplayDevicesW(adapter.DeviceName, displayIndex, &display, 0))
|
|
||||||
break;
|
|
||||||
|
|
||||||
found++;
|
|
||||||
monitors = realloc(monitors, sizeof(_GLFWmonitor*) * found);
|
|
||||||
monitors[found - 1] = createMonitor(&adapter, &display);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
found++;
|
|
||||||
monitors = realloc(monitors, sizeof(_GLFWmonitor*) * found);
|
|
||||||
monitors[found - 1] = createMonitor(&adapter, NULL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_GLFW_SWAP_POINTERS(monitors[0], monitors[primaryIndex]);
|
|
||||||
|
|
||||||
*count = found;
|
|
||||||
return monitors;
|
|
||||||
}
|
|
||||||
|
|
||||||
GLFWbool _glfwPlatformIsSameMonitor(_GLFWmonitor* first, _GLFWmonitor* second)
|
|
||||||
{
|
|
||||||
if (wcslen(first->win32.displayName))
|
|
||||||
return wcscmp(first->win32.displayName, second->win32.displayName) == 0;
|
|
||||||
else
|
|
||||||
return wcscmp(first->win32.adapterName, second->win32.adapterName) == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos)
|
void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos)
|
||||||
{
|
{
|
||||||
DEVMODEW settings;
|
DEVMODEW settings;
|
||||||
|
@ -345,6 +345,7 @@ char* _glfwCreateUTF8FromWideStringWin32(const WCHAR* source);
|
|||||||
|
|
||||||
void _glfwInitTimerWin32(void);
|
void _glfwInitTimerWin32(void);
|
||||||
|
|
||||||
|
void _glfwPollMonitorsWin32(void);
|
||||||
GLFWbool _glfwSetVideoModeWin32(_GLFWmonitor* monitor, const GLFWvidmode* desired);
|
GLFWbool _glfwSetVideoModeWin32(_GLFWmonitor* monitor, const GLFWvidmode* desired);
|
||||||
void _glfwRestoreVideoModeWin32(_GLFWmonitor* monitor);
|
void _glfwRestoreVideoModeWin32(_GLFWmonitor* monitor);
|
||||||
|
|
||||||
|
@ -458,7 +458,7 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
|
|||||||
{
|
{
|
||||||
if (wParam == DBT_DEVNODES_CHANGED)
|
if (wParam == DBT_DEVNODES_CHANGED)
|
||||||
{
|
{
|
||||||
_glfwInputMonitorChange();
|
_glfwPollMonitorsWin32();
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
else if (wParam == DBT_DEVICEARRIVAL)
|
else if (wParam == DBT_DEVICEARRIVAL)
|
||||||
|
@ -650,9 +650,6 @@ int _glfwPlatformInit(void)
|
|||||||
_glfw.wl.registry = wl_display_get_registry(_glfw.wl.display);
|
_glfw.wl.registry = wl_display_get_registry(_glfw.wl.display);
|
||||||
wl_registry_add_listener(_glfw.wl.registry, ®istryListener, NULL);
|
wl_registry_add_listener(_glfw.wl.registry, ®istryListener, NULL);
|
||||||
|
|
||||||
_glfw.wl.monitors = calloc(4, sizeof(_GLFWmonitor*));
|
|
||||||
_glfw.wl.monitorsSize = 4;
|
|
||||||
|
|
||||||
createKeyTables();
|
createKeyTables();
|
||||||
|
|
||||||
_glfw.wl.xkb.context = xkb_context_new(0);
|
_glfw.wl.xkb.context = xkb_context_new(0);
|
||||||
|
130
src/wl_monitor.c
130
src/wl_monitor.c
@ -32,12 +32,6 @@
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
|
|
||||||
struct _GLFWvidmodeWayland
|
|
||||||
{
|
|
||||||
GLFWvidmode base;
|
|
||||||
uint32_t flags;
|
|
||||||
};
|
|
||||||
|
|
||||||
static void geometry(void* data,
|
static void geometry(void* data,
|
||||||
struct wl_output* output,
|
struct wl_output* output,
|
||||||
int32_t x,
|
int32_t x,
|
||||||
@ -50,21 +44,15 @@ static void geometry(void* data,
|
|||||||
int32_t transform)
|
int32_t transform)
|
||||||
{
|
{
|
||||||
struct _GLFWmonitor *monitor = data;
|
struct _GLFWmonitor *monitor = data;
|
||||||
char* name;
|
char name[1024];
|
||||||
size_t nameLength;
|
|
||||||
|
|
||||||
monitor->wl.x = x;
|
monitor->wl.x = x;
|
||||||
monitor->wl.y = y;
|
monitor->wl.y = y;
|
||||||
monitor->widthMM = physicalWidth;
|
monitor->widthMM = physicalWidth;
|
||||||
monitor->heightMM = physicalHeight;
|
monitor->heightMM = physicalHeight;
|
||||||
|
|
||||||
nameLength = strlen(make) + 1 + strlen(model) + 1;
|
snprintf(name, sizeof(name), "%s %s", make, model);
|
||||||
name = realloc(monitor->name, nameLength);
|
monitor->name = strdup(name);
|
||||||
if (name)
|
|
||||||
{
|
|
||||||
sprintf(name, "%s %s", make, model);
|
|
||||||
monitor->name = name;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mode(void* data,
|
static void mode(void* data,
|
||||||
@ -75,32 +63,29 @@ static void mode(void* data,
|
|||||||
int32_t refresh)
|
int32_t refresh)
|
||||||
{
|
{
|
||||||
struct _GLFWmonitor *monitor = data;
|
struct _GLFWmonitor *monitor = data;
|
||||||
_GLFWvidmodeWayland mode = { { 0 }, };
|
GLFWvidmode mode;
|
||||||
|
|
||||||
mode.base.width = width;
|
mode.width = width;
|
||||||
mode.base.height = height;
|
mode.height = height;
|
||||||
mode.base.refreshRate = refresh / 1000;
|
mode.redBits = 8;
|
||||||
mode.flags = flags;
|
mode.greenBits = 8;
|
||||||
|
mode.blueBits = 8;
|
||||||
|
mode.refreshRate = refresh / 1000;
|
||||||
|
|
||||||
if (monitor->wl.modesCount + 1 >= monitor->wl.modesSize)
|
monitor->modeCount++;
|
||||||
{
|
monitor->modes =
|
||||||
int size = monitor->wl.modesSize * 2;
|
realloc(monitor->modes, monitor->modeCount * sizeof(GLFWvidmode));
|
||||||
_GLFWvidmodeWayland* modes =
|
monitor->modes[monitor->modeCount - 1] = mode;
|
||||||
realloc(monitor->wl.modes,
|
|
||||||
size * sizeof(_GLFWvidmodeWayland));
|
if (flags & WL_OUTPUT_MODE_CURRENT)
|
||||||
monitor->wl.modes = modes;
|
monitor->wl.currentMode = monitor->modeCount - 1;
|
||||||
monitor->wl.modesSize = size;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
monitor->wl.modes[monitor->wl.modesCount++] = mode;
|
static void done(void* data, struct wl_output* output)
|
||||||
}
|
|
||||||
|
|
||||||
static void done(void* data,
|
|
||||||
struct wl_output* output)
|
|
||||||
{
|
{
|
||||||
struct _GLFWmonitor *monitor = data;
|
struct _GLFWmonitor *monitor = data;
|
||||||
|
|
||||||
monitor->wl.done = GLFW_TRUE;
|
_glfwInputMonitor(monitor, GLFW_CONNECTED, _GLFW_INSERT_LAST);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void scale(void* data,
|
static void scale(void* data,
|
||||||
@ -149,26 +134,10 @@ void _glfwAddOutputWayland(uint32_t name, uint32_t version)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
monitor->wl.modes = calloc(4, sizeof(_GLFWvidmodeWayland));
|
|
||||||
monitor->wl.modesSize = 4;
|
|
||||||
|
|
||||||
monitor->wl.scale = 1;
|
monitor->wl.scale = 1;
|
||||||
|
|
||||||
monitor->wl.output = output;
|
monitor->wl.output = output;
|
||||||
|
|
||||||
wl_output_add_listener(output, &outputListener, monitor);
|
wl_output_add_listener(output, &outputListener, monitor);
|
||||||
|
|
||||||
if (_glfw.wl.monitorsCount + 1 >= _glfw.wl.monitorsSize)
|
|
||||||
{
|
|
||||||
_GLFWmonitor** monitors = _glfw.wl.monitors;
|
|
||||||
int size = _glfw.wl.monitorsSize * 2;
|
|
||||||
|
|
||||||
monitors = realloc(monitors, size * sizeof(_GLFWmonitor*));
|
|
||||||
|
|
||||||
_glfw.wl.monitors = monitors;
|
|
||||||
_glfw.wl.monitorsSize = size;
|
|
||||||
}
|
|
||||||
|
|
||||||
_glfw.wl.monitors[_glfw.wl.monitorsCount++] = monitor;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -176,42 +145,6 @@ void _glfwAddOutputWayland(uint32_t name, uint32_t version)
|
|||||||
////// GLFW platform API //////
|
////// GLFW platform API //////
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
_GLFWmonitor** _glfwPlatformGetMonitors(int* count)
|
|
||||||
{
|
|
||||||
_GLFWmonitor** monitors;
|
|
||||||
_GLFWmonitor* monitor;
|
|
||||||
int i, monitorsCount = _glfw.wl.monitorsCount;
|
|
||||||
|
|
||||||
if (_glfw.wl.monitorsCount == 0)
|
|
||||||
goto err;
|
|
||||||
|
|
||||||
monitors = calloc(monitorsCount, sizeof(_GLFWmonitor*));
|
|
||||||
|
|
||||||
for (i = 0; i < monitorsCount; i++)
|
|
||||||
{
|
|
||||||
_GLFWmonitor* origMonitor = _glfw.wl.monitors[i];
|
|
||||||
monitor = calloc(1, sizeof(_GLFWmonitor));
|
|
||||||
|
|
||||||
monitor->modes =
|
|
||||||
_glfwPlatformGetVideoModes(origMonitor,
|
|
||||||
&origMonitor->wl.modesCount);
|
|
||||||
*monitor = *_glfw.wl.monitors[i];
|
|
||||||
monitors[i] = monitor;
|
|
||||||
}
|
|
||||||
|
|
||||||
*count = monitorsCount;
|
|
||||||
return monitors;
|
|
||||||
|
|
||||||
err:
|
|
||||||
*count = 0;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
GLFWbool _glfwPlatformIsSameMonitor(_GLFWmonitor* first, _GLFWmonitor* second)
|
|
||||||
{
|
|
||||||
return first->wl.output == second->wl.output;
|
|
||||||
}
|
|
||||||
|
|
||||||
void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos)
|
void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos)
|
||||||
{
|
{
|
||||||
if (xpos)
|
if (xpos)
|
||||||
@ -222,30 +155,13 @@ void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos)
|
|||||||
|
|
||||||
GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* found)
|
GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* found)
|
||||||
{
|
{
|
||||||
GLFWvidmode *modes;
|
*found = monitor->modeCount;
|
||||||
int i, modesCount = monitor->wl.modesCount;
|
return monitor->modes;
|
||||||
|
|
||||||
modes = calloc(modesCount, sizeof(GLFWvidmode));
|
|
||||||
|
|
||||||
for (i = 0; i < modesCount; i++)
|
|
||||||
modes[i] = monitor->wl.modes[i].base;
|
|
||||||
|
|
||||||
*found = modesCount;
|
|
||||||
return modes;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode)
|
void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode)
|
||||||
{
|
{
|
||||||
int i;
|
*mode = monitor->modes[monitor->wl.currentMode];
|
||||||
|
|
||||||
for (i = 0; i < monitor->wl.modesCount; i++)
|
|
||||||
{
|
|
||||||
if (monitor->wl.modes[i].flags & WL_OUTPUT_MODE_CURRENT)
|
|
||||||
{
|
|
||||||
*mode = monitor->wl.modes[i].base;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
|
void _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
|
||||||
|
@ -71,10 +71,6 @@ typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR
|
|||||||
#define _GLFW_PLATFORM_LIBRARY_CONTEXT_STATE
|
#define _GLFW_PLATFORM_LIBRARY_CONTEXT_STATE
|
||||||
|
|
||||||
|
|
||||||
// Wayland-specific video mode data
|
|
||||||
//
|
|
||||||
typedef struct _GLFWvidmodeWayland _GLFWvidmodeWayland;
|
|
||||||
|
|
||||||
// Wayland-specific per-window data
|
// Wayland-specific per-window data
|
||||||
//
|
//
|
||||||
typedef struct _GLFWwindowWayland
|
typedef struct _GLFWwindowWayland
|
||||||
@ -126,10 +122,6 @@ typedef struct _GLFWlibraryWayland
|
|||||||
struct wl_surface* cursorSurface;
|
struct wl_surface* cursorSurface;
|
||||||
uint32_t pointerSerial;
|
uint32_t pointerSerial;
|
||||||
|
|
||||||
_GLFWmonitor** monitors;
|
|
||||||
int monitorsCount;
|
|
||||||
int monitorsSize;
|
|
||||||
|
|
||||||
short int keycodes[256];
|
short int keycodes[256];
|
||||||
short int scancodes[GLFW_KEY_LAST + 1];
|
short int scancodes[GLFW_KEY_LAST + 1];
|
||||||
|
|
||||||
@ -155,15 +147,12 @@ typedef struct _GLFWlibraryWayland
|
|||||||
typedef struct _GLFWmonitorWayland
|
typedef struct _GLFWmonitorWayland
|
||||||
{
|
{
|
||||||
struct wl_output* output;
|
struct wl_output* output;
|
||||||
|
int currentMode;
|
||||||
_GLFWvidmodeWayland* modes;
|
|
||||||
int modesCount;
|
|
||||||
int modesSize;
|
|
||||||
GLFWbool done;
|
|
||||||
|
|
||||||
int x;
|
int x;
|
||||||
int y;
|
int y;
|
||||||
int scale;
|
int scale;
|
||||||
|
|
||||||
} _GLFWmonitorWayland;
|
} _GLFWmonitorWayland;
|
||||||
|
|
||||||
// Wayland-specific per-cursor data
|
// Wayland-specific per-cursor data
|
||||||
|
@ -794,6 +794,7 @@ int _glfwPlatformInit(void)
|
|||||||
|
|
||||||
_glfwInitTimerPOSIX();
|
_glfwInitTimerPOSIX();
|
||||||
|
|
||||||
|
_glfwPollMonitorsX11();
|
||||||
return GLFW_TRUE;
|
return GLFW_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,6 +95,130 @@ static GLFWvidmode vidmodeFromModeInfo(const XRRModeInfo* mi,
|
|||||||
////// GLFW internal API //////
|
////// GLFW internal API //////
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// Poll for changes in the set of connected monitors
|
||||||
|
//
|
||||||
|
void _glfwPollMonitorsX11(void)
|
||||||
|
{
|
||||||
|
if (_glfw.x11.randr.available && !_glfw.x11.randr.monitorBroken)
|
||||||
|
{
|
||||||
|
int i, j, disconnectedCount, screenCount = 0;
|
||||||
|
_GLFWmonitor** disconnected;
|
||||||
|
XineramaScreenInfo* screens = NULL;
|
||||||
|
XRRScreenResources* sr = XRRGetScreenResourcesCurrent(_glfw.x11.display,
|
||||||
|
_glfw.x11.root);
|
||||||
|
RROutput primary = XRRGetOutputPrimary(_glfw.x11.display,
|
||||||
|
_glfw.x11.root);
|
||||||
|
|
||||||
|
if (_glfw.x11.xinerama.available)
|
||||||
|
screens = XineramaQueryScreens(_glfw.x11.display, &screenCount);
|
||||||
|
|
||||||
|
disconnectedCount = _glfw.monitorCount;
|
||||||
|
disconnected = calloc(_glfw.monitorCount, sizeof(_GLFWmonitor*));
|
||||||
|
memcpy(disconnected,
|
||||||
|
_glfw.monitors,
|
||||||
|
_glfw.monitorCount * sizeof(_GLFWmonitor*));
|
||||||
|
|
||||||
|
for (i = 0; i < sr->noutput; i++)
|
||||||
|
{
|
||||||
|
int type, widthMM, heightMM;
|
||||||
|
XRROutputInfo* oi;
|
||||||
|
XRRCrtcInfo* ci;
|
||||||
|
_GLFWmonitor* monitor;
|
||||||
|
|
||||||
|
oi = XRRGetOutputInfo(_glfw.x11.display, sr, sr->outputs[i]);
|
||||||
|
if (oi->connection != RR_Connected || oi->crtc == None)
|
||||||
|
{
|
||||||
|
XRRFreeOutputInfo(oi);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (j = 0; j < disconnectedCount; j++)
|
||||||
|
{
|
||||||
|
if (disconnected[j] &&
|
||||||
|
disconnected[j]->x11.output == sr->outputs[i])
|
||||||
|
{
|
||||||
|
disconnected[j] = NULL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (j < disconnectedCount)
|
||||||
|
{
|
||||||
|
XRRFreeOutputInfo(oi);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
ci = XRRGetCrtcInfo(_glfw.x11.display, sr, oi->crtc);
|
||||||
|
if (ci->rotation == RR_Rotate_90 || ci->rotation == RR_Rotate_270)
|
||||||
|
{
|
||||||
|
widthMM = oi->mm_height;
|
||||||
|
heightMM = oi->mm_width;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
widthMM = oi->mm_width;
|
||||||
|
heightMM = oi->mm_height;
|
||||||
|
}
|
||||||
|
|
||||||
|
monitor = _glfwAllocMonitor(oi->name, widthMM, heightMM);
|
||||||
|
monitor->x11.output = sr->outputs[i];
|
||||||
|
monitor->x11.crtc = oi->crtc;
|
||||||
|
|
||||||
|
for (j = 0; j < screenCount; j++)
|
||||||
|
{
|
||||||
|
if (screens[j].x_org == ci->x &&
|
||||||
|
screens[j].y_org == ci->y &&
|
||||||
|
screens[j].width == ci->width &&
|
||||||
|
screens[j].height == ci->height)
|
||||||
|
{
|
||||||
|
monitor->x11.index = j;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (monitor->x11.output == primary)
|
||||||
|
type = _GLFW_INSERT_FIRST;
|
||||||
|
else
|
||||||
|
type = _GLFW_INSERT_LAST;
|
||||||
|
|
||||||
|
_glfwInputMonitor(monitor, GLFW_CONNECTED, type);
|
||||||
|
|
||||||
|
XRRFreeOutputInfo(oi);
|
||||||
|
XRRFreeCrtcInfo(ci);
|
||||||
|
}
|
||||||
|
|
||||||
|
XRRFreeScreenResources(sr);
|
||||||
|
|
||||||
|
if (screens)
|
||||||
|
XFree(screens);
|
||||||
|
|
||||||
|
for (i = 0; i < disconnectedCount; i++)
|
||||||
|
{
|
||||||
|
if (disconnected[i])
|
||||||
|
_glfwInputMonitor(disconnected[i], GLFW_DISCONNECTED, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
free(disconnected);
|
||||||
|
|
||||||
|
if (!_glfw.monitorCount)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"X11: RandR monitor support seems broken");
|
||||||
|
_glfw.x11.randr.monitorBroken = GLFW_TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!_glfw.monitorCount)
|
||||||
|
{
|
||||||
|
const int widthMM = DisplayWidthMM(_glfw.x11.display, _glfw.x11.screen);
|
||||||
|
const int heightMM = DisplayHeightMM(_glfw.x11.display, _glfw.x11.screen);
|
||||||
|
|
||||||
|
_glfwInputMonitor(_glfwAllocMonitor("Display", widthMM, heightMM),
|
||||||
|
GLFW_CONNECTED,
|
||||||
|
_GLFW_INSERT_FIRST);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Set the current video mode for the specified monitor
|
// Set the current video mode for the specified monitor
|
||||||
//
|
//
|
||||||
GLFWbool _glfwSetVideoModeX11(_GLFWmonitor* monitor, const GLFWvidmode* desired)
|
GLFWbool _glfwSetVideoModeX11(_GLFWmonitor* monitor, const GLFWvidmode* desired)
|
||||||
@ -198,119 +322,6 @@ void _glfwRestoreVideoModeX11(_GLFWmonitor* monitor)
|
|||||||
////// GLFW platform API //////
|
////// GLFW platform API //////
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
_GLFWmonitor** _glfwPlatformGetMonitors(int* count)
|
|
||||||
{
|
|
||||||
int i, j, k, found = 0;
|
|
||||||
_GLFWmonitor** monitors = NULL;
|
|
||||||
|
|
||||||
*count = 0;
|
|
||||||
|
|
||||||
if (_glfw.x11.randr.available)
|
|
||||||
{
|
|
||||||
int screenCount = 0;
|
|
||||||
XineramaScreenInfo* screens = NULL;
|
|
||||||
XRRScreenResources* sr = XRRGetScreenResourcesCurrent(_glfw.x11.display,
|
|
||||||
_glfw.x11.root);
|
|
||||||
RROutput primary = XRRGetOutputPrimary(_glfw.x11.display,
|
|
||||||
_glfw.x11.root);
|
|
||||||
|
|
||||||
monitors = calloc(sr->noutput, sizeof(_GLFWmonitor*));
|
|
||||||
|
|
||||||
if (_glfw.x11.xinerama.available)
|
|
||||||
screens = XineramaQueryScreens(_glfw.x11.display, &screenCount);
|
|
||||||
|
|
||||||
for (i = 0; i < sr->ncrtc; i++)
|
|
||||||
{
|
|
||||||
XRRCrtcInfo* ci = XRRGetCrtcInfo(_glfw.x11.display,
|
|
||||||
sr, sr->crtcs[i]);
|
|
||||||
|
|
||||||
for (j = 0; j < ci->noutput; j++)
|
|
||||||
{
|
|
||||||
int widthMM, heightMM;
|
|
||||||
_GLFWmonitor* monitor;
|
|
||||||
XRROutputInfo* oi = XRRGetOutputInfo(_glfw.x11.display,
|
|
||||||
sr, ci->outputs[j]);
|
|
||||||
if (oi->connection != RR_Connected)
|
|
||||||
{
|
|
||||||
XRRFreeOutputInfo(oi);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ci->rotation == RR_Rotate_90 || ci->rotation == RR_Rotate_270)
|
|
||||||
{
|
|
||||||
widthMM = oi->mm_height;
|
|
||||||
heightMM = oi->mm_width;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
widthMM = oi->mm_width;
|
|
||||||
heightMM = oi->mm_height;
|
|
||||||
}
|
|
||||||
|
|
||||||
monitor = _glfwAllocMonitor(oi->name, widthMM, heightMM);
|
|
||||||
monitor->x11.output = ci->outputs[j];
|
|
||||||
monitor->x11.crtc = oi->crtc;
|
|
||||||
|
|
||||||
for (k = 0; k < screenCount; k++)
|
|
||||||
{
|
|
||||||
if (screens[k].x_org == ci->x &&
|
|
||||||
screens[k].y_org == ci->y &&
|
|
||||||
screens[k].width == ci->width &&
|
|
||||||
screens[k].height == ci->height)
|
|
||||||
{
|
|
||||||
monitor->x11.index = k;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
XRRFreeOutputInfo(oi);
|
|
||||||
|
|
||||||
found++;
|
|
||||||
monitors[found - 1] = monitor;
|
|
||||||
|
|
||||||
if (ci->outputs[j] == primary)
|
|
||||||
_GLFW_SWAP_POINTERS(monitors[0], monitors[found - 1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
XRRFreeCrtcInfo(ci);
|
|
||||||
}
|
|
||||||
|
|
||||||
XRRFreeScreenResources(sr);
|
|
||||||
|
|
||||||
if (screens)
|
|
||||||
XFree(screens);
|
|
||||||
|
|
||||||
if (found == 0)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
|
||||||
"X11: RandR monitor support seems broken");
|
|
||||||
|
|
||||||
_glfw.x11.randr.monitorBroken = GLFW_TRUE;
|
|
||||||
free(monitors);
|
|
||||||
monitors = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!monitors)
|
|
||||||
{
|
|
||||||
monitors = calloc(1, sizeof(_GLFWmonitor*));
|
|
||||||
monitors[0] = _glfwAllocMonitor("Display",
|
|
||||||
DisplayWidthMM(_glfw.x11.display,
|
|
||||||
_glfw.x11.screen),
|
|
||||||
DisplayHeightMM(_glfw.x11.display,
|
|
||||||
_glfw.x11.screen));
|
|
||||||
found = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
*count = found;
|
|
||||||
return monitors;
|
|
||||||
}
|
|
||||||
|
|
||||||
GLFWbool _glfwPlatformIsSameMonitor(_GLFWmonitor* first, _GLFWmonitor* second)
|
|
||||||
{
|
|
||||||
return first->x11.crtc == second->x11.crtc;
|
|
||||||
}
|
|
||||||
|
|
||||||
void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos)
|
void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos)
|
||||||
{
|
{
|
||||||
if (_glfw.x11.randr.available && !_glfw.x11.randr.monitorBroken)
|
if (_glfw.x11.randr.available && !_glfw.x11.randr.monitorBroken)
|
||||||
|
@ -290,6 +290,7 @@ typedef struct _GLFWcursorX11
|
|||||||
} _GLFWcursorX11;
|
} _GLFWcursorX11;
|
||||||
|
|
||||||
|
|
||||||
|
void _glfwPollMonitorsX11(void);
|
||||||
GLFWbool _glfwSetVideoModeX11(_GLFWmonitor* monitor, const GLFWvidmode* desired);
|
GLFWbool _glfwSetVideoModeX11(_GLFWmonitor* monitor, const GLFWvidmode* desired);
|
||||||
void _glfwRestoreVideoModeX11(_GLFWmonitor* monitor);
|
void _glfwRestoreVideoModeX11(_GLFWmonitor* monitor);
|
||||||
|
|
||||||
|
@ -910,7 +910,7 @@ static void processEvent(XEvent *event)
|
|||||||
if (event->type == _glfw.x11.randr.eventBase + RRNotify)
|
if (event->type == _glfw.x11.randr.eventBase + RRNotify)
|
||||||
{
|
{
|
||||||
XRRUpdateConfiguration(event);
|
XRRUpdateConfiguration(event);
|
||||||
_glfwInputMonitorChange();
|
_glfwPollMonitorsX11();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user