zenilib  0.5.3.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
SDL_windowsmodes.c
Go to the documentation of this file.
1 /*
2  Simple DirectMedia Layer
3  Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
4 
5  This software is provided 'as-is', without any express or implied
6  warranty. In no event will the authors be held liable for any damages
7  arising from the use of this software.
8 
9  Permission is granted to anyone to use this software for any purpose,
10  including commercial applications, and to alter it and redistribute it
11  freely, subject to the following restrictions:
12 
13  1. The origin of this software must not be misrepresented; you must not
14  claim that you wrote the original software. If you use this software
15  in a product, an acknowledgment in the product documentation would be
16  appreciated but is not required.
17  2. Altered source versions must be plainly marked as such, and must not be
18  misrepresented as being the original software.
19  3. This notice may not be removed or altered from any source distribution.
20 */
21 #include "SDL_config.h"
22 
23 #if SDL_VIDEO_DRIVER_WINDOWS
24 
25 #include "SDL_windowsvideo.h"
26 
27 /* Windows CE compatibility */
28 #ifndef CDS_FULLSCREEN
29 #define CDS_FULLSCREEN 0
30 #endif
31 
32 static SDL_bool
33 WIN_GetDisplayMode(LPCTSTR deviceName, DWORD index, SDL_DisplayMode * mode)
34 {
36  DEVMODE devmode;
37  HDC hdc;
38 
39  devmode.dmSize = sizeof(devmode);
40  devmode.dmDriverExtra = 0;
41  if (!EnumDisplaySettings(deviceName, index, &devmode)) {
42  return SDL_FALSE;
43  }
44 
45  data = (SDL_DisplayModeData *) SDL_malloc(sizeof(*data));
46  if (!data) {
47  return SDL_FALSE;
48  }
49  data->DeviceMode = devmode;
50  data->DeviceMode.dmFields =
51  (DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT | DM_DISPLAYFREQUENCY |
52  DM_DISPLAYFLAGS);
53 
54  /* Fill in the mode information */
56  mode->w = devmode.dmPelsWidth;
57  mode->h = devmode.dmPelsHeight;
58  mode->refresh_rate = devmode.dmDisplayFrequency;
59  mode->driverdata = data;
60 
61  if (index == ENUM_CURRENT_SETTINGS
62  && (hdc = CreateDC(deviceName, NULL, NULL, NULL)) != NULL) {
63  char bmi_data[sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD)];
64  LPBITMAPINFO bmi;
65  HBITMAP hbm;
66 
67  SDL_zero(bmi_data);
68  bmi = (LPBITMAPINFO) bmi_data;
69  bmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
70 
71  hbm = CreateCompatibleBitmap(hdc, 1, 1);
72  GetDIBits(hdc, hbm, 0, 1, NULL, bmi, DIB_RGB_COLORS);
73  GetDIBits(hdc, hbm, 0, 1, NULL, bmi, DIB_RGB_COLORS);
74  DeleteObject(hbm);
75  DeleteDC(hdc);
76  if (bmi->bmiHeader.biCompression == BI_BITFIELDS) {
77  switch (*(Uint32 *) bmi->bmiColors) {
78  case 0x00FF0000:
80  break;
81  case 0x000000FF:
83  break;
84  case 0xF800:
86  break;
87  case 0x7C00:
89  break;
90  }
91  } else if (bmi->bmiHeader.biBitCount == 8) {
93  } else if (bmi->bmiHeader.biBitCount == 4) {
95  }
96  } else {
97  /* FIXME: Can we tell what this will be? */
98  if ((devmode.dmFields & DM_BITSPERPEL) == DM_BITSPERPEL) {
99  switch (devmode.dmBitsPerPel) {
100  case 32:
102  break;
103  case 24:
105  break;
106  case 16:
108  break;
109  case 15:
111  break;
112  case 8:
114  break;
115  case 4:
117  break;
118  }
119  }
120  }
121  return SDL_TRUE;
122 }
123 
124 static SDL_bool
125 WIN_AddDisplay(LPTSTR DeviceName)
126 {
128  SDL_DisplayData *displaydata;
130  DISPLAY_DEVICE device;
131 
132 #ifdef DEBUG_MODES
133  printf("Display: %s\n", WIN_StringToUTF8(DeviceName));
134 #endif
135  if (!WIN_GetDisplayMode(DeviceName, ENUM_CURRENT_SETTINGS, &mode)) {
136  return SDL_FALSE;
137  }
138 
139  displaydata = (SDL_DisplayData *) SDL_malloc(sizeof(*displaydata));
140  if (!displaydata) {
141  return SDL_FALSE;
142  }
143  SDL_memcpy(displaydata->DeviceName, DeviceName,
144  sizeof(displaydata->DeviceName));
145 
146  SDL_zero(display);
147  device.cb = sizeof(device);
148  if (EnumDisplayDevices(DeviceName, 0, &device, 0)) {
149  display.name = WIN_StringToUTF8(device.DeviceString);
150  }
151  display.desktop_mode = mode;
152  display.current_mode = mode;
153  display.driverdata = displaydata;
154  SDL_AddVideoDisplay(&display);
155  SDL_free(display.name);
156  return SDL_TRUE;
157 }
158 
159 int
161 {
162  int pass;
163  DWORD i, j, count;
164  DISPLAY_DEVICE device;
165 
166  device.cb = sizeof(device);
167 
168  /* Get the primary display in the first pass */
169  for (pass = 0; pass < 2; ++pass) {
170  for (i = 0; ; ++i) {
171  TCHAR DeviceName[32];
172 
173  if (!EnumDisplayDevices(NULL, i, &device, 0)) {
174  break;
175  }
176  if (!(device.StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP)) {
177  continue;
178  }
179  if (pass == 0) {
180  if (!(device.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE)) {
181  continue;
182  }
183  } else {
184  if (device.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE) {
185  continue;
186  }
187  }
188  SDL_memcpy(DeviceName, device.DeviceName, sizeof(DeviceName));
189 #ifdef DEBUG_MODES
190  printf("Device: %s\n", WIN_StringToUTF8(DeviceName));
191 #endif
192  count = 0;
193  for (j = 0; ; ++j) {
194  if (!EnumDisplayDevices(DeviceName, j, &device, 0)) {
195  break;
196  }
197  if (!(device.StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP)) {
198  continue;
199  }
200  if (pass == 0) {
201  if (!(device.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE)) {
202  continue;
203  }
204  } else {
205  if (device.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE) {
206  continue;
207  }
208  }
209  count += WIN_AddDisplay(device.DeviceName);
210  }
211  if (count == 0) {
212  WIN_AddDisplay(DeviceName);
213  }
214  }
215  }
216  if (_this->num_displays == 0) {
217  return SDL_SetError("No displays available");
218  }
219  return 0;
220 }
221 
222 int
224 {
226 
227  rect->x = (int)data->DeviceMode.dmPosition.x;
228  rect->y = (int)data->DeviceMode.dmPosition.y;
229  rect->w = data->DeviceMode.dmPelsWidth;
230  rect->h = data->DeviceMode.dmPelsHeight;
231 
232  return 0;
233 }
234 
235 void
237 {
238  SDL_DisplayData *data = (SDL_DisplayData *) display->driverdata;
239  DWORD i;
240  SDL_DisplayMode mode;
241 
242  for (i = 0;; ++i) {
243  if (!WIN_GetDisplayMode(data->DeviceName, i, &mode)) {
244  break;
245  }
246  if (SDL_ISPIXELFORMAT_INDEXED(mode.format)) {
247  /* We don't support palettized modes now */
248  SDL_free(mode.driverdata);
249  continue;
250  }
251  if (mode.format != SDL_PIXELFORMAT_UNKNOWN) {
252  if (!SDL_AddDisplayMode(display, &mode)) {
253  SDL_free(mode.driverdata);
254  }
255  }
256  else {
257  SDL_free(mode.driverdata);
258  }
259  }
260 }
261 
262 int
264 {
265  SDL_DisplayData *displaydata = (SDL_DisplayData *) display->driverdata;
267  LONG status;
268 
269  status =
270  ChangeDisplaySettingsEx(displaydata->DeviceName, &data->DeviceMode,
271  NULL, CDS_FULLSCREEN, NULL);
272  if (status != DISP_CHANGE_SUCCESSFUL) {
273  const char *reason = "Unknown reason";
274  switch (status) {
275  case DISP_CHANGE_BADFLAGS:
276  reason = "DISP_CHANGE_BADFLAGS";
277  break;
278  case DISP_CHANGE_BADMODE:
279  reason = "DISP_CHANGE_BADMODE";
280  break;
281  case DISP_CHANGE_BADPARAM:
282  reason = "DISP_CHANGE_BADPARAM";
283  break;
284  case DISP_CHANGE_FAILED:
285  reason = "DISP_CHANGE_FAILED";
286  break;
287  }
288  return SDL_SetError("ChangeDisplaySettingsEx() failed: %s", reason);
289  }
290  EnumDisplaySettings(displaydata->DeviceName, ENUM_CURRENT_SETTINGS, &data->DeviceMode);
291  return 0;
292 }
293 
294 void
296 {
297  /* All fullscreen windows should have restored modes by now */
298 }
299 
300 #endif /* SDL_VIDEO_DRIVER_WINDOWS */
301 
302 /* vi: set ts=4 sw=4 expandtab: */
void WIN_QuitModes(_THIS)
#define NULL
Definition: ftobjs.h:61
#define SDL_ISPIXELFORMAT_INDEXED(format)
Definition: SDL_pixels.h:129
SDL_bool
Definition: SDL_stdinc.h:116
DECLSPEC void SDLCALL SDL_free(void *mem)
The structure that defines a display mode.
Definition: SDL_video.h:53
int32_t j
Definition: e_log.c:102
char * display
Definition: visualinfo.c:85
int WIN_InitModes(_THIS)
int SDL_AddVideoDisplay(const SDL_VideoDisplay *display)
Definition: SDL_video.c:568
typedef HDC(WINAPI *PFNWGLGETCURRENTREADDCARBPROC)(VOID)
static SDL_VideoDevice * _this
Definition: SDL_video.c:92
uint32_t Uint32
An unsigned 32-bit integer type.
Definition: SDL_stdinc.h:145
void WIN_GetDisplayModes(_THIS, SDL_VideoDisplay *display)
TCHAR DeviceName[32]
int WIN_GetDisplayBounds(_THIS, SDL_VideoDisplay *display, SDL_Rect *rect)
int
Definition: SDL_systhread.c:37
for(;;)
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl2ext.h:848
#define _THIS
void * driverdata
Definition: SDL_video.h:59
GLint GLsizei count
Definition: gl2ext.h:1011
int WIN_SetDisplayMode(_THIS, SDL_VideoDisplay *display, SDL_DisplayMode *mode)
SDL_DisplayMode current_mode
Definition: SDL_sysvideo.h:120
#define WIN_StringToUTF8(S)
Definition: SDL_windows.h:41
DECLSPEC int SDLCALL SDL_SetError(const char *fmt,...)
Definition: SDL_error.c:53
DECLSPEC void *SDLCALL SDL_malloc(size_t size)
GLuint index
Definition: glew.h:1800
int x
Definition: SDL_rect.h:65
int w
Definition: SDL_rect.h:66
#define BI_BITFIELDS
Definition: SDL_bmp.c:46
SDL_DisplayMode desktop_mode
Definition: SDL_sysvideo.h:119
DECLSPEC void *SDLCALL SDL_memcpy(void *dst, const void *src, size_t len)
Definition: SDL_string.c:293
int h
Definition: SDL_rect.h:66
typedef DWORD(WINAPI *XInputGetState_t)(DWORD dwUserIndex
SDL_bool SDL_AddDisplayMode(SDL_VideoDisplay *display, const SDL_DisplayMode *mode)
Definition: SDL_video.c:666
#define SDL_zero(x)
Definition: SDL_stdinc.h:254
Uint32 format
Definition: SDL_video.h:55
int i
Definition: pngrutil.c:1377
int y
Definition: SDL_rect.h:65
GLenum mode
Definition: glew.h:2394
A rectangle, with the origin at the upper left.
Definition: SDL_rect.h:63