win32_monitor.c
Go to the documentation of this file.
1 //========================================================================
2 // GLFW 3.3 Win32 - www.glfw.org
3 //------------------------------------------------------------------------
4 // Copyright (c) 2002-2006 Marcus Geelnard
5 // Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
6 //
7 // This software is provided 'as-is', without any express or implied
8 // warranty. In no event will the authors be held liable for any damages
9 // arising from the use of this software.
10 //
11 // Permission is granted to anyone to use this software for any purpose,
12 // including commercial applications, and to alter it and redistribute it
13 // freely, subject to the following restrictions:
14 //
15 // 1. The origin of this software must not be misrepresented; you must not
16 // claim that you wrote the original software. If you use this software
17 // in a product, an acknowledgment in the product documentation would
18 // be appreciated but is not required.
19 //
20 // 2. Altered source versions must be plainly marked as such, and must not
21 // be misrepresented as being the original software.
22 //
23 // 3. This notice may not be removed or altered from any source
24 // distribution.
25 //
26 //========================================================================
27 
28 #include "internal.h"
29 
30 #include <stdlib.h>
31 #include <string.h>
32 #include <limits.h>
33 #include <malloc.h>
34 
35 
36 // Callback for EnumDisplayMonitors in createMonitor
37 //
38 static BOOL CALLBACK monitorCallback(HMONITOR handle,
39  HDC dc,
40  RECT* rect,
41  LPARAM data)
42 {
43  MONITORINFOEXW mi;
44  ZeroMemory(&mi, sizeof(mi));
45  mi.cbSize = sizeof(mi);
46 
47  if (GetMonitorInfoW(handle, (MONITORINFO*) &mi))
48  {
49  _GLFWmonitor* monitor = (_GLFWmonitor*) data;
50  if (wcscmp(mi.szDevice, monitor->win32.adapterName) == 0)
51  monitor->win32.handle = handle;
52  }
53 
54  return TRUE;
55 }
56 
57 // Create monitor from an adapter and (optionally) a display
58 //
59 static _GLFWmonitor* createMonitor(DISPLAY_DEVICEW* adapter,
60  DISPLAY_DEVICEW* display)
61 {
62  _GLFWmonitor* monitor;
63  int widthMM, heightMM;
64  char* name;
65  HDC dc;
66  DEVMODEW dm;
67  RECT rect;
68 
69  if (display)
70  name = _glfwCreateUTF8FromWideStringWin32(display->DeviceString);
71  else
72  name = _glfwCreateUTF8FromWideStringWin32(adapter->DeviceString);
73  if (!name)
74  return NULL;
75 
76  ZeroMemory(&dm, sizeof(dm));
77  dm.dmSize = sizeof(dm);
78  EnumDisplaySettingsW(adapter->DeviceName, ENUM_CURRENT_SETTINGS, &dm);
79 
80  dc = CreateDCW(L"DISPLAY", adapter->DeviceName, NULL, NULL);
81 
83  {
84  widthMM = GetDeviceCaps(dc, HORZSIZE);
85  heightMM = GetDeviceCaps(dc, VERTSIZE);
86  }
87  else
88  {
89  widthMM = (int) (dm.dmPelsWidth * 25.4f / GetDeviceCaps(dc, LOGPIXELSX));
90  heightMM = (int) (dm.dmPelsHeight * 25.4f / GetDeviceCaps(dc, LOGPIXELSY));
91  }
92 
93  DeleteDC(dc);
94 
95  monitor = _glfwAllocMonitor(name, widthMM, heightMM);
96  free(name);
97 
98  if (adapter->StateFlags & DISPLAY_DEVICE_MODESPRUNED)
99  monitor->win32.modesPruned = GLFW_TRUE;
100 
101  wcscpy(monitor->win32.adapterName, adapter->DeviceName);
102  WideCharToMultiByte(CP_UTF8, 0,
103  adapter->DeviceName, -1,
104  monitor->win32.publicAdapterName,
105  sizeof(monitor->win32.publicAdapterName),
106  NULL, NULL);
107 
108  if (display)
109  {
110  wcscpy(monitor->win32.displayName, display->DeviceName);
111  WideCharToMultiByte(CP_UTF8, 0,
112  display->DeviceName, -1,
113  monitor->win32.publicDisplayName,
114  sizeof(monitor->win32.publicDisplayName),
115  NULL, NULL);
116  }
117 
118  rect.left = dm.dmPosition.x;
119  rect.top = dm.dmPosition.y;
120  rect.right = dm.dmPosition.x + dm.dmPelsWidth;
121  rect.bottom = dm.dmPosition.y + dm.dmPelsHeight;
122 
123  EnumDisplayMonitors(NULL, &rect, monitorCallback, (LPARAM) monitor);
124  return monitor;
125 }
126 
127 
131 
132 // Poll for changes in the set of connected monitors
133 //
135 {
136  int i, disconnectedCount;
137  _GLFWmonitor** disconnected = NULL;
138  DWORD adapterIndex, displayIndex;
139  DISPLAY_DEVICEW adapter, display;
140  _GLFWmonitor* monitor;
141 
142  disconnectedCount = _glfw.monitorCount;
143  if (disconnectedCount)
144  {
145  disconnected = calloc(_glfw.monitorCount, sizeof(_GLFWmonitor*));
146  memcpy(disconnected,
147  _glfw.monitors,
148  _glfw.monitorCount * sizeof(_GLFWmonitor*));
149  }
150 
151  for (adapterIndex = 0; ; adapterIndex++)
152  {
153  int type = _GLFW_INSERT_LAST;
154 
155  ZeroMemory(&adapter, sizeof(adapter));
156  adapter.cb = sizeof(adapter);
157 
158  if (!EnumDisplayDevicesW(NULL, adapterIndex, &adapter, 0))
159  break;
160 
161  if (!(adapter.StateFlags & DISPLAY_DEVICE_ACTIVE))
162  continue;
163 
164  if (adapter.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE)
165  type = _GLFW_INSERT_FIRST;
166 
167  for (displayIndex = 0; ; displayIndex++)
168  {
169  ZeroMemory(&display, sizeof(display));
170  display.cb = sizeof(display);
171 
172  if (!EnumDisplayDevicesW(adapter.DeviceName, displayIndex, &display, 0))
173  break;
174 
175  if (!(display.StateFlags & DISPLAY_DEVICE_ACTIVE))
176  continue;
177 
178  for (i = 0; i < disconnectedCount; i++)
179  {
180  if (disconnected[i] &&
181  wcscmp(disconnected[i]->win32.displayName,
182  display.DeviceName) == 0)
183  {
184  disconnected[i] = NULL;
185  break;
186  }
187  }
188 
189  if (i < disconnectedCount)
190  continue;
191 
192  monitor = createMonitor(&adapter, &display);
193  if (!monitor)
194  {
195  free(disconnected);
196  return;
197  }
198 
199  _glfwInputMonitor(monitor, GLFW_CONNECTED, type);
200 
201  type = _GLFW_INSERT_LAST;
202  }
203 
204  // HACK: If an active adapter does not have any display devices
205  // (as sometimes happens), add it directly as a monitor
206  if (displayIndex == 0)
207  {
208  for (i = 0; i < disconnectedCount; i++)
209  {
210  if (disconnected[i] &&
211  wcscmp(disconnected[i]->win32.adapterName,
212  adapter.DeviceName) == 0)
213  {
214  disconnected[i] = NULL;
215  break;
216  }
217  }
218 
219  if (i < disconnectedCount)
220  continue;
221 
222  monitor = createMonitor(&adapter, NULL);
223  if (!monitor)
224  {
225  free(disconnected);
226  return;
227  }
228 
229  _glfwInputMonitor(monitor, GLFW_CONNECTED, type);
230  }
231  }
232 
233  for (i = 0; i < disconnectedCount; i++)
234  {
235  if (disconnected[i])
236  _glfwInputMonitor(disconnected[i], GLFW_DISCONNECTED, 0);
237  }
238 
239  free(disconnected);
240 }
241 
242 // Change the current video mode
243 //
244 void _glfwSetVideoModeWin32(_GLFWmonitor* monitor, const GLFWvidmode* desired)
245 {
246  GLFWvidmode current;
247  const GLFWvidmode* best;
248  DEVMODEW dm;
249  LONG result;
250 
251  best = _glfwChooseVideoMode(monitor, desired);
252  _glfwPlatformGetVideoMode(monitor, &current);
253  if (_glfwCompareVideoModes(&current, best) == 0)
254  return;
255 
256  ZeroMemory(&dm, sizeof(dm));
257  dm.dmSize = sizeof(dm);
258  dm.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL |
259  DM_DISPLAYFREQUENCY;
260  dm.dmPelsWidth = best->width;
261  dm.dmPelsHeight = best->height;
262  dm.dmBitsPerPel = best->redBits + best->greenBits + best->blueBits;
263  dm.dmDisplayFrequency = best->refreshRate;
264 
265  if (dm.dmBitsPerPel < 15 || dm.dmBitsPerPel >= 24)
266  dm.dmBitsPerPel = 32;
267 
268  result = ChangeDisplaySettingsExW(monitor->win32.adapterName,
269  &dm,
270  NULL,
271  CDS_FULLSCREEN,
272  NULL);
273  if (result == DISP_CHANGE_SUCCESSFUL)
274  monitor->win32.modeChanged = GLFW_TRUE;
275  else
276  {
277  const char* description = "Unknown error";
278 
279  if (result == DISP_CHANGE_BADDUALVIEW)
280  description = "The system uses DualView";
281  else if (result == DISP_CHANGE_BADFLAGS)
282  description = "Invalid flags";
283  else if (result == DISP_CHANGE_BADMODE)
284  description = "Graphics mode not supported";
285  else if (result == DISP_CHANGE_BADPARAM)
286  description = "Invalid parameter";
287  else if (result == DISP_CHANGE_FAILED)
288  description = "Graphics mode failed";
289  else if (result == DISP_CHANGE_NOTUPDATED)
290  description = "Failed to write to registry";
291  else if (result == DISP_CHANGE_RESTART)
292  description = "Computer restart required";
293 
295  "Win32: Failed to set video mode: %s",
296  description);
297  }
298 }
299 
300 // Restore the previously saved (original) video mode
301 //
303 {
304  if (monitor->win32.modeChanged)
305  {
306  ChangeDisplaySettingsExW(monitor->win32.adapterName,
307  NULL, NULL, CDS_FULLSCREEN, NULL);
308  monitor->win32.modeChanged = GLFW_FALSE;
309  }
310 }
311 
312 void _glfwGetMonitorContentScaleWin32(HMONITOR handle, float* xscale, float* yscale)
313 {
314  UINT xdpi, ydpi;
315 
317  GetDpiForMonitor(handle, MDT_EFFECTIVE_DPI, &xdpi, &ydpi);
318  else
319  {
320  const HDC dc = GetDC(NULL);
321  xdpi = GetDeviceCaps(dc, LOGPIXELSX);
322  ydpi = GetDeviceCaps(dc, LOGPIXELSY);
323  ReleaseDC(NULL, dc);
324  }
325 
326  if (xscale)
327  *xscale = xdpi / (float) USER_DEFAULT_SCREEN_DPI;
328  if (yscale)
329  *yscale = ydpi / (float) USER_DEFAULT_SCREEN_DPI;
330 }
331 
332 
336 
338 {
339 }
340 
342 {
343  DEVMODEW dm;
344  ZeroMemory(&dm, sizeof(dm));
345  dm.dmSize = sizeof(dm);
346 
347  EnumDisplaySettingsExW(monitor->win32.adapterName,
348  ENUM_CURRENT_SETTINGS,
349  &dm,
351 
352  if (xpos)
353  *xpos = dm.dmPosition.x;
354  if (ypos)
355  *ypos = dm.dmPosition.y;
356 }
357 
359  float* xscale, float* yscale)
360 {
361  _glfwGetMonitorContentScaleWin32(monitor->win32.handle, xscale, yscale);
362 }
363 
365 {
366  int modeIndex = 0, size = 0;
368 
369  *count = 0;
370 
371  for (;;)
372  {
373  int i;
375  DEVMODEW dm;
376 
377  ZeroMemory(&dm, sizeof(dm));
378  dm.dmSize = sizeof(dm);
379 
380  if (!EnumDisplaySettingsW(monitor->win32.adapterName, modeIndex, &dm))
381  break;
382 
383  modeIndex++;
384 
385  // Skip modes with less than 15 BPP
386  if (dm.dmBitsPerPel < 15)
387  continue;
388 
389  mode.width = dm.dmPelsWidth;
390  mode.height = dm.dmPelsHeight;
391  mode.refreshRate = dm.dmDisplayFrequency;
392  _glfwSplitBPP(dm.dmBitsPerPel,
393  &mode.redBits,
394  &mode.greenBits,
395  &mode.blueBits);
396 
397  for (i = 0; i < *count; i++)
398  {
399  if (_glfwCompareVideoModes(result + i, &mode) == 0)
400  break;
401  }
402 
403  // Skip duplicate modes
404  if (i < *count)
405  continue;
406 
407  if (monitor->win32.modesPruned)
408  {
409  // Skip modes not supported by the connected displays
410  if (ChangeDisplaySettingsExW(monitor->win32.adapterName,
411  &dm,
412  NULL,
413  CDS_TEST,
414  NULL) != DISP_CHANGE_SUCCESSFUL)
415  {
416  continue;
417  }
418  }
419 
420  if (*count == size)
421  {
422  size += 128;
423  result = (GLFWvidmode*) realloc(result, size * sizeof(GLFWvidmode));
424  }
425 
426  (*count)++;
427  result[*count - 1] = mode;
428  }
429 
430  if (!*count)
431  {
432  // HACK: Report the current mode if no valid modes were found
433  result = calloc(1, sizeof(GLFWvidmode));
434  _glfwPlatformGetVideoMode(monitor, result);
435  *count = 1;
436  }
437 
438  return result;
439 }
440 
442 {
443  DEVMODEW dm;
444  ZeroMemory(&dm, sizeof(dm));
445  dm.dmSize = sizeof(dm);
446 
447  EnumDisplaySettingsW(monitor->win32.adapterName, ENUM_CURRENT_SETTINGS, &dm);
448 
449  mode->width = dm.dmPelsWidth;
450  mode->height = dm.dmPelsHeight;
451  mode->refreshRate = dm.dmDisplayFrequency;
452  _glfwSplitBPP(dm.dmBitsPerPel,
453  &mode->redBits,
454  &mode->greenBits,
455  &mode->blueBits);
456 }
457 
459 {
460  HDC dc;
461  WORD values[768];
462 
463  dc = CreateDCW(L"DISPLAY", monitor->win32.adapterName, NULL, NULL);
464  GetDeviceGammaRamp(dc, values);
465  DeleteDC(dc);
466 
467  _glfwAllocGammaArrays(ramp, 256);
468 
469  memcpy(ramp->red, values + 0, 256 * sizeof(unsigned short));
470  memcpy(ramp->green, values + 256, 256 * sizeof(unsigned short));
471  memcpy(ramp->blue, values + 512, 256 * sizeof(unsigned short));
472 }
473 
475 {
476  HDC dc;
477  WORD values[768];
478 
479  if (ramp->size != 256)
480  {
482  "Win32: Gamma ramp size must be 256");
483  return;
484  }
485 
486  memcpy(values + 0, ramp->red, 256 * sizeof(unsigned short));
487  memcpy(values + 256, ramp->green, 256 * sizeof(unsigned short));
488  memcpy(values + 512, ramp->blue, 256 * sizeof(unsigned short));
489 
490  dc = CreateDCW(L"DISPLAY", monitor->win32.adapterName, NULL, NULL);
491  SetDeviceGammaRamp(dc, values);
492  DeleteDC(dc);
493 }
494 
495 
499 
501 {
502  _GLFWmonitor* monitor = (_GLFWmonitor*) handle;
504  return monitor->win32.publicAdapterName;
505 }
506 
508 {
509  _GLFWmonitor* monitor = (_GLFWmonitor*) handle;
511  return monitor->win32.publicDisplayName;
512 }
513 
int redBits
Definition: glfw3.h:1535
void _glfwGetMonitorContentScaleWin32(HMONITOR handle, float *xscale, float *yscale)
int height
Definition: glfw3.h:1532
void _glfwRestoreVideoModeWin32(_GLFWmonitor *monitor)
#define DISPLAY_DEVICE_ACTIVE
#define IsWindows8Point1OrGreater()
int blueBits
Definition: glfw3.h:1541
GLuint const GLchar * name
static BOOL CALLBACK monitorCallback(HMONITOR handle, HDC dc, RECT *rect, LPARAM data)
Definition: win32_monitor.c:38
#define GLFWAPI
Definition: glfw3.h:240
void _glfwAllocGammaArrays(GLFWgammaramp *ramp, unsigned int size)
Definition: monitor.c:192
int width
Definition: glfw3.h:1529
GLuint64 GLenum void * handle
Definition: glext.h:7785
void _glfwPlatformGetVideoMode(_GLFWmonitor *monitor, GLFWvidmode *mode)
void _glfwSplitBPP(int bpp, int *red, int *green, int *blue)
Definition: monitor.c:272
struct GLFWmonitor GLFWmonitor
char * _glfwCreateUTF8FromWideStringWin32(const WCHAR *source)
Definition: win32_init.c:412
_GLFWmonitor * _glfwAllocMonitor(const char *name, int widthMM, int heightMM)
Definition: monitor.c:161
#define EDS_ROTATEDMODE
GLFWvidmode * _glfwPlatformGetVideoModes(_GLFWmonitor *monitor, int *count)
#define GLFW_FALSE
Zero.
Definition: glfw3.h:287
int refreshRate
Definition: glfw3.h:1544
unsigned short * red
Definition: glfw3.h:1563
void _glfwPlatformFreeMonitor(_GLFWmonitor *monitor)
unsigned short * green
Definition: glfw3.h:1566
void _glfwPlatformGetMonitorContentScale(_GLFWmonitor *monitor, float *xscale, float *yscale)
int greenBits
Definition: glfw3.h:1538
#define GLFW_DISCONNECTED
Definition: glfw3.h:1059
#define GLFW_CONNECTED
Definition: glfw3.h:1058
#define _GLFW_REQUIRE_INIT_OR_RETURN(x)
Definition: internal.h:210
GLenum mode
void _glfwPlatformGetGammaRamp(_GLFWmonitor *monitor, GLFWgammaramp *ramp)
GLsizeiptr size
#define GLFW_PLATFORM_ERROR
A platform-specific error occurred that does not match any of the more specific categories.
Definition: glfw3.h:726
_GLFWlibrary _glfw
Definition: init.c:44
int monitorCount
Definition: internal.h:529
unsigned int size
Definition: glfw3.h:1572
void _glfwInputError(int code, const char *format,...)
Definition: init.c:129
GLFWAPI const char * glfwGetWin32Monitor(GLFWmonitor *handle)
void _glfwPollMonitorsWin32(void)
void _glfwInputMonitor(_GLFWmonitor *monitor, int action, int placement)
Definition: monitor.c:91
void _glfwSetVideoModeWin32(_GLFWmonitor *monitor, const GLFWvidmode *desired)
int _glfwCompareVideoModes(const GLFWvidmode *first, const GLFWvidmode *second)
Definition: monitor.c:265
#define GetDpiForMonitor
GLsizei const GLfloat * values
#define GLFW_TRUE
One.
Definition: glfw3.h:279
Definition: example.hpp:70
#define _GLFW_INSERT_FIRST
Definition: internal.h:51
Gamma ramp.
Definition: glfw3.h:1559
unsigned short * blue
Definition: glfw3.h:1569
Video mode type.
Definition: glfw3.h:1525
GLenum type
GLFWAPI const char * glfwGetWin32Adapter(GLFWmonitor *handle)
static double xpos
Definition: splitview.c:33
static _GLFWmonitor * createMonitor(DISPLAY_DEVICEW *adapter, DISPLAY_DEVICEW *display)
Definition: win32_monitor.c:59
GLint GLsizei count
void display(void)
Definition: boing.c:194
#define NULL
Definition: tinycthread.c:47
#define TRUE
Definition: tinycthread.c:50
int i
_GLFWmonitor ** monitors
Definition: internal.h:528
#define USER_DEFAULT_SCREEN_DPI
void _glfwPlatformGetMonitorPos(_GLFWmonitor *monitor, int *xpos, int *ypos)
const GLFWvidmode * _glfwChooseVideoMode(_GLFWmonitor *monitor, const GLFWvidmode *desired)
Definition: monitor.c:213
GLuint64EXT * result
Definition: glext.h:10921
Definition: parser.hpp:150
void _glfwPlatformSetGammaRamp(_GLFWmonitor *monitor, const GLFWgammaramp *ramp)
static double ypos
Definition: splitview.c:33
#define _GLFW_INSERT_LAST
Definition: internal.h:52


librealsense2
Author(s): Sergey Dorodnicov , Doron Hirshberg , Mark Horn , Reagan Lopez , Itay Carpis
autogenerated on Mon May 3 2021 02:50:23