Blender  V3.3
GHOST_DisplayManagerWin32.cpp
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2001-2002 NaN Holding BV. All rights reserved. */
3 
9 #include "GHOST_Debug.h"
10 
11 #define WIN32_LEAN_AND_MEAN
12 #include <windows.h>
13 
14 // We do not support multiple monitors at the moment
15 #define COMPILE_MULTIMON_STUBS
16 #include <multimon.h>
17 
19 {
20 }
21 
23 {
24  numDisplays = ::GetSystemMetrics(SM_CMONITORS);
25  return numDisplays > 0 ? GHOST_kSuccess : GHOST_kFailure;
26 }
27 
28 static BOOL get_dd(DWORD d, DISPLAY_DEVICE *dd)
29 {
30  dd->cb = sizeof(DISPLAY_DEVICE);
31  return ::EnumDisplayDevices(NULL, d, dd, 0);
32 }
33 
34 /*
35  * When you call EnumDisplaySettings with iModeNum set to zero, the operating system
36  * initializes and caches information about the display device. When you call
37  * EnumDisplaySettings with iModeNum set to a non-zero value, the function returns
38  * the information that was cached the last time the function was called with iModeNum
39  * set to zero.
40  */
42  int32_t &numSettings) const
43 {
44  DISPLAY_DEVICE display_device;
45  if (!get_dd(display, &display_device))
46  return GHOST_kFailure;
47 
48  numSettings = 0;
49  DEVMODE dm;
50  while (::EnumDisplaySettings(display_device.DeviceName, numSettings, &dm)) {
51  numSettings++;
52  }
53  return GHOST_kSuccess;
54 }
55 
57  int32_t index,
58  GHOST_DisplaySetting &setting) const
59 {
60  DISPLAY_DEVICE display_device;
61  if (!get_dd(display, &display_device))
62  return GHOST_kFailure;
63 
64  GHOST_TSuccess success;
65  DEVMODE dm;
66  if (::EnumDisplaySettings(display_device.DeviceName, index, &dm)) {
67 #ifdef WITH_GHOST_DEBUG
68  printf("display mode: width=%d, height=%d, bpp=%d, frequency=%d\n",
69  dm.dmPelsWidth,
70  dm.dmPelsHeight,
71  dm.dmBitsPerPel,
72  dm.dmDisplayFrequency);
73 #endif // WITH_GHOST_DEBUG
74  setting.xPixels = dm.dmPelsWidth;
75  setting.yPixels = dm.dmPelsHeight;
76  setting.bpp = dm.dmBitsPerPel;
77  /* When you call the EnumDisplaySettings function, the dmDisplayFrequency member
78  * may return with the value 0 or 1. These values represent the display hardware's
79  * default refresh rate. This default rate is typically set by switches on a display
80  * card or computer motherboard, or by a configuration program that does not use
81  * Win32 display functions such as ChangeDisplaySettings.
82  */
83  /* First, we tried to explicitly set the frequency to 60 if EnumDisplaySettings
84  * returned 0 or 1 but this doesn't work since later on an exact match will
85  * be searched. And this will never happen if we change it to 60. Now we rely
86  * on the default h/w setting.
87  */
88  setting.frequency = dm.dmDisplayFrequency;
89  success = GHOST_kSuccess;
90  }
91  else {
92  success = GHOST_kFailure;
93  }
94  return success;
95 }
96 
98  uint8_t display, GHOST_DisplaySetting &setting) const
99 {
100  return getDisplaySetting(display, ENUM_CURRENT_SETTINGS, setting);
101 }
102 
104  uint8_t display, const GHOST_DisplaySetting &setting)
105 {
106  DISPLAY_DEVICE display_device;
107  if (!get_dd(display, &display_device))
108  return GHOST_kFailure;
109 
110  GHOST_DisplaySetting match;
111  findMatch(display, setting, match);
112  DEVMODE dm;
113  int i = 0;
114  while (::EnumDisplaySettings(display_device.DeviceName, i++, &dm)) {
115  if ((dm.dmBitsPerPel == match.bpp) && (dm.dmPelsWidth == match.xPixels) &&
116  (dm.dmPelsHeight == match.yPixels) && (dm.dmDisplayFrequency == match.frequency)) {
117  break;
118  }
119  }
120  /*
121  * dm.dmBitsPerPel = match.bpp;
122  * dm.dmPelsWidth = match.xPixels;
123  * dm.dmPelsHeight = match.yPixels;
124  * dm.dmDisplayFrequency = match.frequency;
125  * dm.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT | DM_DISPLAYFREQUENCY;
126  * dm.dmSize = sizeof(DEVMODE);
127  * dm.dmDriverExtra = 0;
128  */
129 #ifdef WITH_GHOST_DEBUG
130  printf("display change: Requested settings:\n");
131  printf(" dmBitsPerPel=%d\n", dm.dmBitsPerPel);
132  printf(" dmPelsWidth=%d\n", dm.dmPelsWidth);
133  printf(" dmPelsHeight=%d\n", dm.dmPelsHeight);
134  printf(" dmDisplayFrequency=%d\n", dm.dmDisplayFrequency);
135 #endif // WITH_GHOST_DEBUG
136 
137  LONG status = ::ChangeDisplaySettings(&dm, CDS_FULLSCREEN);
138 #ifdef WITH_GHOST_DEBUG
139  switch (status) {
140  case DISP_CHANGE_SUCCESSFUL:
141  printf("display change: The settings change was successful.\n");
142  break;
143  case DISP_CHANGE_RESTART:
144  printf(
145  "display change: The computer must be restarted in order for the graphics mode to "
146  "work.\n");
147  break;
148  case DISP_CHANGE_BADFLAGS:
149  printf("display change: An invalid set of flags was passed in.\n");
150  break;
151  case DISP_CHANGE_BADPARAM:
152  printf(
153  "display change: An invalid parameter was passed in. "
154  "This can include an invalid flag or combination of flags.\n");
155  break;
156  case DISP_CHANGE_FAILED:
157  printf("display change: The display driver failed the specified graphics mode.\n");
158  break;
159  case DISP_CHANGE_BADMODE:
160  printf("display change: The graphics mode is not supported.\n");
161  break;
162  case DISP_CHANGE_NOTUPDATED:
163  printf("display change: Windows NT: Unable to write settings to the registry.\n");
164  break;
165  default:
166  printf("display change: Return value invalid\n");
167  break;
168  }
169 #endif // WITH_GHOST_DEBUG
170  return status == DISP_CHANGE_SUCCESSFUL ? GHOST_kSuccess : GHOST_kFailure;
171 }
static BOOL get_dd(DWORD d, DISPLAY_DEVICE *dd)
GHOST_TSuccess
Definition: GHOST_Types.h:74
@ GHOST_kFailure
Definition: GHOST_Types.h:74
@ GHOST_kSuccess
Definition: GHOST_Types.h:74
GHOST_TSuccess getNumDisplaySettings(uint8_t display, int32_t &numSettings) const
GHOST_TSuccess getDisplaySetting(uint8_t display, int32_t index, GHOST_DisplaySetting &setting) const
GHOST_TSuccess setCurrentDisplaySetting(uint8_t display, const GHOST_DisplaySetting &setting)
GHOST_TSuccess getNumDisplays(uint8_t &numDisplays) const
GHOST_TSuccess getCurrentDisplaySetting(uint8_t display, GHOST_DisplaySetting &setting) const
GHOST_TSuccess findMatch(uint8_t display, const GHOST_DisplaySetting &setting, GHOST_DisplaySetting &match) const
signed int int32_t
Definition: stdint.h:77
unsigned char uint8_t
Definition: stdint.h:78