Blender  V2.93
GHOST_DisplayManagerWin32.cpp
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
17  * All rights reserved.
18  */
19 
25 #include "GHOST_Debug.h"
26 
27 #define WIN32_LEAN_AND_MEAN
28 #include <windows.h>
29 
30 // We do not support multiple monitors at the moment
31 #define COMPILE_MULTIMON_STUBS
32 #include <multimon.h>
33 
35 {
36 }
37 
39 {
40  numDisplays = ::GetSystemMetrics(SM_CMONITORS);
41  return numDisplays > 0 ? GHOST_kSuccess : GHOST_kFailure;
42 }
43 
44 static BOOL get_dd(DWORD d, DISPLAY_DEVICE *dd)
45 {
46  dd->cb = sizeof(DISPLAY_DEVICE);
47  return ::EnumDisplayDevices(NULL, d, dd, 0);
48 }
49 
50 /*
51  * When you call EnumDisplaySettings with iModeNum set to zero, the operating system
52  * initializes and caches information about the display device. When you call
53  * EnumDisplaySettings with iModeNum set to a non-zero value, the function returns
54  * the information that was cached the last time the function was called with iModeNum
55  * set to zero.
56  */
58  GHOST_TInt32 &numSettings) const
59 {
60  DISPLAY_DEVICE display_device;
61  if (!get_dd(display, &display_device))
62  return GHOST_kFailure;
63 
64  numSettings = 0;
65  DEVMODE dm;
66  while (::EnumDisplaySettings(display_device.DeviceName, numSettings, &dm)) {
67  numSettings++;
68  }
69  return GHOST_kSuccess;
70 }
71 
73  GHOST_TInt32 index,
74  GHOST_DisplaySetting &setting) const
75 {
76  DISPLAY_DEVICE display_device;
77  if (!get_dd(display, &display_device))
78  return GHOST_kFailure;
79 
80  GHOST_TSuccess success;
81  DEVMODE dm;
82  if (::EnumDisplaySettings(display_device.DeviceName, index, &dm)) {
83 #ifdef WITH_GHOST_DEBUG
84  printf("display mode: width=%d, height=%d, bpp=%d, frequency=%d\n",
85  dm.dmPelsWidth,
86  dm.dmPelsHeight,
87  dm.dmBitsPerPel,
88  dm.dmDisplayFrequency);
89 #endif // WITH_GHOST_DEBUG
90  setting.xPixels = dm.dmPelsWidth;
91  setting.yPixels = dm.dmPelsHeight;
92  setting.bpp = dm.dmBitsPerPel;
93  /* When you call the EnumDisplaySettings function, the dmDisplayFrequency member
94  * may return with the value 0 or 1. These values represent the display hardware's
95  * default refresh rate. This default rate is typically set by switches on a display
96  * card or computer motherboard, or by a configuration program that does not use
97  * Win32 display functions such as ChangeDisplaySettings.
98  */
99  /* First, we tried to explicitly set the frequency to 60 if EnumDisplaySettings
100  * returned 0 or 1 but this doesn't work since later on an exact match will
101  * be searched. And this will never happen if we change it to 60. Now we rely
102  * on the default h/w setting.
103  */
104  setting.frequency = dm.dmDisplayFrequency;
105  success = GHOST_kSuccess;
106  }
107  else {
108  success = GHOST_kFailure;
109  }
110  return success;
111 }
112 
114  GHOST_TUns8 display, GHOST_DisplaySetting &setting) const
115 {
116  return getDisplaySetting(display, ENUM_CURRENT_SETTINGS, setting);
117 }
118 
120  GHOST_TUns8 display, const GHOST_DisplaySetting &setting)
121 {
122  DISPLAY_DEVICE display_device;
123  if (!get_dd(display, &display_device))
124  return GHOST_kFailure;
125 
126  GHOST_DisplaySetting match;
127  findMatch(display, setting, match);
128  DEVMODE dm;
129  int i = 0;
130  while (::EnumDisplaySettings(display_device.DeviceName, i++, &dm)) {
131  if ((dm.dmBitsPerPel == match.bpp) && (dm.dmPelsWidth == match.xPixels) &&
132  (dm.dmPelsHeight == match.yPixels) && (dm.dmDisplayFrequency == match.frequency)) {
133  break;
134  }
135  }
136  /*
137  * dm.dmBitsPerPel = match.bpp;
138  * dm.dmPelsWidth = match.xPixels;
139  * dm.dmPelsHeight = match.yPixels;
140  * dm.dmDisplayFrequency = match.frequency;
141  * dm.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT | DM_DISPLAYFREQUENCY;
142  * dm.dmSize = sizeof(DEVMODE);
143  * dm.dmDriverExtra = 0;
144  */
145 #ifdef WITH_GHOST_DEBUG
146  printf("display change: Requested settings:\n");
147  printf(" dmBitsPerPel=%d\n", dm.dmBitsPerPel);
148  printf(" dmPelsWidth=%d\n", dm.dmPelsWidth);
149  printf(" dmPelsHeight=%d\n", dm.dmPelsHeight);
150  printf(" dmDisplayFrequency=%d\n", dm.dmDisplayFrequency);
151 #endif // WITH_GHOST_DEBUG
152 
153  LONG status = ::ChangeDisplaySettings(&dm, CDS_FULLSCREEN);
154 #ifdef WITH_GHOST_DEBUG
155  switch (status) {
156  case DISP_CHANGE_SUCCESSFUL:
157  printf("display change: The settings change was successful.\n");
158  break;
159  case DISP_CHANGE_RESTART:
160  printf(
161  "display change: The computer must be restarted in order for the graphics mode to "
162  "work.\n");
163  break;
164  case DISP_CHANGE_BADFLAGS:
165  printf("display change: An invalid set of flags was passed in.\n");
166  break;
167  case DISP_CHANGE_BADPARAM:
168  printf(
169  "display change: An invalid parameter was passed in. "
170  "This can include an invalid flag or combination of flags.\n");
171  break;
172  case DISP_CHANGE_FAILED:
173  printf("display change: The display driver failed the specified graphics mode.\n");
174  break;
175  case DISP_CHANGE_BADMODE:
176  printf("display change: The graphics mode is not supported.\n");
177  break;
178  case DISP_CHANGE_NOTUPDATED:
179  printf("display change: Windows NT: Unable to write settings to the registry.\n");
180  break;
181  default:
182  printf("display change: Return value invalid\n");
183  break;
184  }
185 #endif // WITH_GHOST_DEBUG
186  return status == DISP_CHANGE_SUCCESSFUL ? GHOST_kSuccess : GHOST_kFailure;
187 }
static BOOL get_dd(DWORD d, DISPLAY_DEVICE *dd)
int GHOST_TInt32
Definition: GHOST_Types.h:63
GHOST_TSuccess
Definition: GHOST_Types.h:91
@ GHOST_kFailure
Definition: GHOST_Types.h:91
@ GHOST_kSuccess
Definition: GHOST_Types.h:91
unsigned char GHOST_TUns8
Definition: GHOST_Types.h:60
GHOST_TSuccess setCurrentDisplaySetting(GHOST_TUns8 display, const GHOST_DisplaySetting &setting)
GHOST_TSuccess getNumDisplays(GHOST_TUns8 &numDisplays) const
GHOST_TSuccess getDisplaySetting(GHOST_TUns8 display, GHOST_TInt32 index, GHOST_DisplaySetting &setting) const
GHOST_TSuccess getNumDisplaySettings(GHOST_TUns8 display, GHOST_TInt32 &numSettings) const
GHOST_TSuccess getCurrentDisplaySetting(GHOST_TUns8 display, GHOST_DisplaySetting &setting) const
GHOST_TSuccess findMatch(GHOST_TUns8 display, const GHOST_DisplaySetting &setting, GHOST_DisplaySetting &match) const
GHOST_TUns32 bpp
Definition: GHOST_Types.h:584
GHOST_TUns32 xPixels
Definition: GHOST_Types.h:580
GHOST_TUns32 frequency
Definition: GHOST_Types.h:586
GHOST_TUns32 yPixels
Definition: GHOST_Types.h:582