Added glfwGetMirroredMonitor.

This commit is contained in:
Camilla Berglund 2014-09-15 18:18:51 +02:00
parent b19fb4c24d
commit c8d4bae93a
10 changed files with 93 additions and 37 deletions

View File

@ -74,6 +74,7 @@ GLFW bundles a number of dependencies in the `deps/` directory.
- Added `glfwSetCharModsCallback` for receiving character events with modifiers - Added `glfwSetCharModsCallback` for receiving character events with modifiers
- Added `glfwGetWindowFrameSize` for retrieving the size of the frame around - Added `glfwGetWindowFrameSize` for retrieving the size of the frame around
the client area of a window the client area of a window
- Added `glfwGetMirroredMonitor` for discovering monitor mirroring sets
- Added `GLFW_AUTO_ICONIFY` for controlling whether full screen windows - Added `GLFW_AUTO_ICONIFY` for controlling whether full screen windows
automatically iconify (and restore the previous video mode) on focus loss automatically iconify (and restore the previous video mode) on focus loss
- Added `GLFW_DONT_CARE` for indicating that any value is acceptable - Added `GLFW_DONT_CARE` for indicating that any value is acceptable

View File

@ -1279,6 +1279,28 @@ GLFWAPI GLFWmonitor** glfwGetMonitors(int* count);
*/ */
GLFWAPI GLFWmonitor* glfwGetPrimaryMonitor(void); GLFWAPI GLFWmonitor* glfwGetPrimaryMonitor(void);
/*! @brief Returns the monitor mirrored by the specified monitor.
*
* This function returns the monitor that the specified monitor mirrors.
*
* @param[in] monitor The monitor to query.
* @return The monitor mirrored by the specified monitor, or `NULL` if the
* monitor does not mirror another monitor or an [error](@ref error_handling)
* occurred.
*
* @par Thread Safety
* This function may only be called from the main thread.
*
* @sa @ref monitor_monitors
* @sa glfwGetMonitors
*
* @par History
* Added in GLFW 3.1.
*
* @ingroup monitor
*/
GLFWAPI GLFWmonitor* glfwGetMirroredMonitor(GLFWmonitor* monitor);
/*! @brief Returns the position of the monitor's viewport on the virtual screen. /*! @brief Returns the position of the monitor's viewport on the virtual screen.
* *
* This function returns the position, in screen coordinates, of the upper-left * This function returns the position, in screen coordinates, of the upper-left

View File

@ -273,7 +273,7 @@ _GLFWmonitor** _glfwPlatformGetMonitors(int* count)
const CGSize size = CGDisplayScreenSize(displays[i]); const CGSize size = CGDisplayScreenSize(displays[i]);
char* name = getDisplayName(displays[i]); char* name = getDisplayName(displays[i]);
monitors[found] = _glfwAllocMonitor(name, size.width, size.height); monitors[found] = _glfwCreateMonitor(name, size.width, size.height);
monitors[found]->ns.displayID = displays[i]; monitors[found]->ns.displayID = displays[i];
free(name); free(name);
@ -295,7 +295,7 @@ _GLFWmonitor** _glfwPlatformGetMonitors(int* count)
found++; found++;
else else
{ {
_glfwFreeMonitor(monitors[found]); _glfwDestroyMonitor(monitors[found]);
monitors[found] = NULL; monitors[found] = NULL;
} }
} }

View File

@ -166,7 +166,7 @@ GLFWAPI void glfwTerminate(void)
_glfwPlatformSetGammaRamp(monitor, &monitor->originalRamp); _glfwPlatformSetGammaRamp(monitor, &monitor->originalRamp);
} }
_glfwFreeMonitors(_glfw.monitors, _glfw.monitorCount); _glfwDestroyMonitors(_glfw.monitors, _glfw.monitorCount);
_glfw.monitors = NULL; _glfw.monitors = NULL;
_glfw.monitorCount = 0; _glfw.monitorCount = 0;

View File

@ -286,6 +286,7 @@ struct _GLFWmonitor
// Physical dimensions in millimeters. // Physical dimensions in millimeters.
int widthMM, heightMM; int widthMM, heightMM;
int mirroring;
GLFWvidmode* modes; GLFWvidmode* modes;
int modeCount; int modeCount;
@ -859,18 +860,19 @@ void _glfwFreeGammaArrays(GLFWgammaramp* ramp);
* @param[in] name The name of the monitor. * @param[in] name The name of the monitor.
* @param[in] widthMM The width, in mm, of the monitor's display area. * @param[in] widthMM The width, in mm, of the monitor's display area.
* @param[in] heightMM The height, in mm, of the monitor's display area. * @param[in] heightMM The height, in mm, of the monitor's display area.
* @param[in] mirroring The monitor this monitor is mirroring, or `NULL`.
* @return The newly created object. * @return The newly created object.
* @ingroup utility * @ingroup utility
*/ */
_GLFWmonitor* _glfwAllocMonitor(const char* name, int widthMM, int heightMM); _GLFWmonitor* _glfwCreateMonitor(const char* name, int widthMM, int heightMM, int mirroring);
/*! @brief Frees a monitor object and any data associated with it. /*! @brief Frees a monitor object and any data associated with it.
* @ingroup utility * @ingroup utility
*/ */
void _glfwFreeMonitor(_GLFWmonitor* monitor); void _glfwDestroyMonitor(_GLFWmonitor* monitor);
/*! @ingroup utility /*! @ingroup utility
*/ */
void _glfwFreeMonitors(_GLFWmonitor** monitors, int count); void _glfwDestroyMonitors(_GLFWmonitor** monitors, int count);
#endif // _internal_h_ #endif // _internal_h_

View File

@ -100,7 +100,8 @@ void _glfwInputMonitorChange(void)
{ {
if (_glfwPlatformIsSameMonitor(_glfw.monitors[i], monitors[j])) if (_glfwPlatformIsSameMonitor(_glfw.monitors[i], monitors[j]))
{ {
_glfwFreeMonitor(_glfw.monitors[i]); monitors[j]->mirroring = _glfw.monitors[i]->mirroring;
_glfwDestroyMonitor(_glfw.monitors[i]);
_glfw.monitors[i] = monitors[j]; _glfw.monitors[i] = monitors[j];
break; break;
} }
@ -154,7 +155,7 @@ void _glfwInputMonitorChange(void)
_glfw.callbacks.monitor((GLFWmonitor*) _glfw.monitors[i], GLFW_CONNECTED); _glfw.callbacks.monitor((GLFWmonitor*) _glfw.monitors[i], GLFW_CONNECTED);
} }
_glfwFreeMonitors(monitors, monitorCount); _glfwDestroyMonitors(monitors, monitorCount);
} }
@ -162,17 +163,20 @@ void _glfwInputMonitorChange(void)
////// GLFW internal API ////// ////// GLFW internal API //////
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
_GLFWmonitor* _glfwAllocMonitor(const char* name, int widthMM, int heightMM) _GLFWmonitor* _glfwCreateMonitor(const char* name,
int widthMM, int heightMM,
int mirroring)
{ {
_GLFWmonitor* monitor = calloc(1, sizeof(_GLFWmonitor)); _GLFWmonitor* monitor = calloc(1, sizeof(_GLFWmonitor));
monitor->name = strdup(name); monitor->name = strdup(name);
monitor->widthMM = widthMM; monitor->widthMM = widthMM;
monitor->heightMM = heightMM; monitor->heightMM = heightMM;
monitor->mirroring = mirroring;
return monitor; return monitor;
} }
void _glfwFreeMonitor(_GLFWmonitor* monitor) void _glfwDestroyMonitor(_GLFWmonitor* monitor)
{ {
if (monitor == NULL) if (monitor == NULL)
return; return;
@ -185,6 +189,16 @@ void _glfwFreeMonitor(_GLFWmonitor* monitor)
free(monitor); free(monitor);
} }
void _glfwDestroyMonitors(_GLFWmonitor** monitors, int count)
{
int i;
for (i = 0; i < count; i++)
_glfwDestroyMonitor(monitors[i]);
free(monitors);
}
void _glfwAllocGammaArrays(GLFWgammaramp* ramp, unsigned int size) void _glfwAllocGammaArrays(GLFWgammaramp* ramp, unsigned int size)
{ {
ramp->red = calloc(size, sizeof(unsigned short)); ramp->red = calloc(size, sizeof(unsigned short));
@ -202,16 +216,6 @@ void _glfwFreeGammaArrays(GLFWgammaramp* ramp)
memset(ramp, 0, sizeof(GLFWgammaramp)); memset(ramp, 0, sizeof(GLFWgammaramp));
} }
void _glfwFreeMonitors(_GLFWmonitor** monitors, int count)
{
int i;
for (i = 0; i < count; i++)
_glfwFreeMonitor(monitors[i]);
free(monitors);
}
const GLFWvidmode* _glfwChooseVideoMode(_GLFWmonitor* monitor, const GLFWvidmode* _glfwChooseVideoMode(_GLFWmonitor* monitor,
const GLFWvidmode* desired) const GLFWvidmode* desired)
{ {
@ -307,6 +311,17 @@ GLFWAPI GLFWmonitor* glfwGetPrimaryMonitor(void)
return (GLFWmonitor*) _glfw.monitors[0]; return (GLFWmonitor*) _glfw.monitors[0];
} }
GLFWAPI GLFWmonitor* glfwGetMirroredMonitor(GLFWmonitor* handle)
{
_GLFWmonitor* monitor = (_GLFWmonitor*) handle;
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
if (monitor->mirroring == -1)
return NULL;
return (GLFWmonitor*) _glfw.monitors[monitor->mirroring];
}
GLFWAPI void glfwGetMonitorPos(GLFWmonitor* handle, int* xpos, int* ypos) GLFWAPI void glfwGetMonitorPos(GLFWmonitor* handle, int* xpos, int* ypos)
{ {
_GLFWmonitor* monitor = (_GLFWmonitor*) handle; _GLFWmonitor* monitor = (_GLFWmonitor*) handle;

View File

@ -103,7 +103,7 @@ void _glfwRestoreVideoMode(_GLFWmonitor* monitor)
_GLFWmonitor** _glfwPlatformGetMonitors(int* count) _GLFWmonitor** _glfwPlatformGetMonitors(int* count)
{ {
int size = 0, found = 0; int size = 0, found = 0, primaryIndex = 0, mirroring;
_GLFWmonitor** monitors = NULL; _GLFWmonitor** monitors = NULL;
DWORD adapterIndex, displayIndex; DWORD adapterIndex, displayIndex;
@ -140,6 +140,9 @@ _GLFWmonitor** _glfwPlatformGetMonitors(int* count)
monitors = realloc(monitors, sizeof(_GLFWmonitor*) * size); monitors = realloc(monitors, sizeof(_GLFWmonitor*) * size);
} }
if (displayIndex == 0)
mirroring = -1;
name = _glfwCreateUTF8FromWideString(display.DeviceString); name = _glfwCreateUTF8FromWideString(display.DeviceString);
if (!name) if (!name)
{ {
@ -150,13 +153,17 @@ _GLFWmonitor** _glfwPlatformGetMonitors(int* count)
dc = CreateDCW(L"DISPLAY", adapter.DeviceName, NULL, NULL); dc = CreateDCW(L"DISPLAY", adapter.DeviceName, NULL, NULL);
monitors[found] = _glfwAllocMonitor(name, monitors[found] = _glfwCreateMonitor(name,
GetDeviceCaps(dc, HORZSIZE), GetDeviceCaps(dc, HORZSIZE),
GetDeviceCaps(dc, VERTSIZE)); GetDeviceCaps(dc, VERTSIZE),
mirroring);
DeleteDC(dc); DeleteDC(dc);
free(name); free(name);
if (displayIndex == 0)
mirroring = found;
wcscpy(monitors[found]->win32.adapterName, adapter.DeviceName); wcscpy(monitors[found]->win32.adapterName, adapter.DeviceName);
wcscpy(monitors[found]->win32.displayName, display.DeviceName); wcscpy(monitors[found]->win32.displayName, display.DeviceName);

View File

@ -127,7 +127,7 @@ void _glfwAddOutput(uint32_t name, uint32_t version)
return; return;
} }
monitor = _glfwAllocMonitor(name_str, 0, 0); monitor = _glfwCreateMonitor(name_str, 0, 0);
output = wl_registry_bind(_glfw.wl.registry, output = wl_registry_bind(_glfw.wl.registry,
name, name,
@ -135,7 +135,7 @@ void _glfwAddOutput(uint32_t name, uint32_t version)
2); 2);
if (!output) if (!output)
{ {
_glfwFreeMonitor(monitor); _glfwDestroyMonitor(monitor);
return; return;
} }

View File

@ -238,9 +238,9 @@ _GLFWmonitor** _glfwPlatformGetMonitors(int* count)
monitors = realloc(monitors, sizeof(_GLFWmonitor*) * size); monitors = realloc(monitors, sizeof(_GLFWmonitor*) * size);
} }
monitors[found] = _glfwAllocMonitor(oi->name, monitors[found] = _glfwCreateMonitor(oi->name,
oi->mm_width, oi->mm_width, oi->mm_height,
oi->mm_height); -1);
monitors[found]->x11.output = ci->outputs[j]; monitors[found]->x11.output = ci->outputs[j];
monitors[found]->x11.crtc = oi->crtc; monitors[found]->x11.crtc = oi->crtc;
@ -284,11 +284,12 @@ _GLFWmonitor** _glfwPlatformGetMonitors(int* count)
if (!monitors) if (!monitors)
{ {
monitors = calloc(1, sizeof(_GLFWmonitor*)); monitors = calloc(1, sizeof(_GLFWmonitor*));
monitors[0] = _glfwAllocMonitor("Display", monitors[0] = _glfwCreateMonitor("Display",
DisplayWidthMM(_glfw.x11.display, DisplayWidthMM(_glfw.x11.display,
_glfw.x11.screen), _glfw.x11.screen),
DisplayHeightMM(_glfw.x11.display, DisplayHeightMM(_glfw.x11.display,
_glfw.x11.screen)); _glfw.x11.screen),
-1);
found = 1; found = 1;
} }

View File

@ -83,15 +83,23 @@ static void key_callback(GLFWwindow* window, int key, int scancode, int action,
static void list_modes(GLFWmonitor* monitor) static void list_modes(GLFWmonitor* monitor)
{ {
int count, x, y, widthMM, heightMM, dpi, i; int count, x, y, widthMM, heightMM, dpi, i;
GLFWmonitor* mirrored;
const GLFWvidmode* mode = glfwGetVideoMode(monitor); const GLFWvidmode* mode = glfwGetVideoMode(monitor);
const GLFWvidmode* modes = glfwGetVideoModes(monitor, &count); const GLFWvidmode* modes = glfwGetVideoModes(monitor, &count);
glfwGetMonitorPos(monitor, &x, &y); glfwGetMonitorPos(monitor, &x, &y);
glfwGetMonitorPhysicalSize(monitor, &widthMM, &heightMM); glfwGetMonitorPhysicalSize(monitor, &widthMM, &heightMM);
printf("Name: %s (%s)\n", printf("Name: %s", glfwGetMonitorName(monitor));
glfwGetMonitorName(monitor),
glfwGetPrimaryMonitor() == monitor ? "primary" : "secondary"); mirrored = glfwGetMirroredMonitor(monitor);
if (mirrored)
printf(" (mirroring %s)\n", glfwGetMonitorName(mirrored));
else if (glfwGetPrimaryMonitor() == monitor)
printf(" (primary)\n");
else
printf(" (secondary)\n");
printf("Current mode: %s\n", format_mode(mode)); printf("Current mode: %s\n", format_mode(mode));
printf("Virtual position: %i %i\n", x, y); printf("Virtual position: %i %i\n", x, y);