|
1 /* |
|
2 SDL - Simple DirectMedia Layer |
|
3 Copyright (C) 1997-2006 Sam Lantinga |
|
4 |
|
5 This library is free software; you can redistribute it and/or |
|
6 modify it under the terms of the GNU Lesser General Public |
|
7 License as published by the Free Software Foundation; either |
|
8 version 2.1 of the License, or (at your option) any later version. |
|
9 |
|
10 This library is distributed in the hope that it will be useful, |
|
11 but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
13 Lesser General Public License for more details. |
|
14 |
|
15 You should have received a copy of the GNU Lesser General Public |
|
16 License along with this library; if not, write to the Free Software |
|
17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
|
18 |
|
19 Sam Lantinga |
|
20 slouken@libsdl.org |
|
21 */ |
|
22 #include "SDL_config.h" |
|
23 |
|
24 #define WIN32_LEAN_AND_MEAN |
|
25 #include <windows.h> |
|
26 |
|
27 /* Not yet in the mingw32 cross-compile headers */ |
|
28 #ifndef CDS_FULLSCREEN |
|
29 #define CDS_FULLSCREEN 4 |
|
30 #endif |
|
31 |
|
32 #include "SDL_syswm.h" |
|
33 #include "../SDL_sysvideo.h" |
|
34 #include "../SDL_pixels_c.h" |
|
35 #include "../../events/SDL_sysevents.h" |
|
36 #include "../../events/SDL_events_c.h" |
|
37 #include "SDL_dibvideo.h" |
|
38 #include "../wincommon/SDL_syswm_c.h" |
|
39 #include "../wincommon/SDL_sysmouse_c.h" |
|
40 #include "SDL_dibevents_c.h" |
|
41 #include "../wincommon/SDL_wingl_c.h" |
|
42 |
|
43 #ifdef _WIN32_WCE |
|
44 #define NO_GETDIBITS |
|
45 #define NO_GAMMA_SUPPORT |
|
46 #if _WIN32_WCE < 420 |
|
47 #define NO_CHANGEDISPLAYSETTINGS |
|
48 #else |
|
49 #define ChangeDisplaySettings(lpDevMode, dwFlags) ChangeDisplaySettingsEx(NULL, (lpDevMode), 0, (dwFlags), 0) |
|
50 #endif |
|
51 #endif |
|
52 #ifndef WS_MAXIMIZE |
|
53 #define WS_MAXIMIZE 0 |
|
54 #endif |
|
55 #ifndef WS_THICKFRAME |
|
56 #define WS_THICKFRAME 0 |
|
57 #endif |
|
58 #ifndef SWP_NOCOPYBITS |
|
59 #define SWP_NOCOPYBITS 0 |
|
60 #endif |
|
61 #ifndef PC_NOCOLLAPSE |
|
62 #define PC_NOCOLLAPSE 0 |
|
63 #endif |
|
64 #ifndef SYSPAL_NOSTATIC256 |
|
65 #define SYSPAL_NOSTATIC256 3 |
|
66 #endif |
|
67 |
|
68 #ifdef _WIN32_WCE |
|
69 // defined and used in SDL_sysevents.c |
|
70 extern HINSTANCE aygshell; |
|
71 #endif |
|
72 |
|
73 /* Initialization/Query functions */ |
|
74 static int DIB_VideoInit(_THIS, SDL_PixelFormat *vformat); |
|
75 static SDL_Rect **DIB_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags); |
|
76 SDL_Surface *DIB_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags); |
|
77 static int DIB_SetColors(_THIS, int firstcolor, int ncolors, |
|
78 SDL_Color *colors); |
|
79 static void DIB_CheckGamma(_THIS); |
|
80 void DIB_SwapGamma(_THIS); |
|
81 void DIB_QuitGamma(_THIS); |
|
82 int DIB_SetGammaRamp(_THIS, Uint16 *ramp); |
|
83 int DIB_GetGammaRamp(_THIS, Uint16 *ramp); |
|
84 static void DIB_VideoQuit(_THIS); |
|
85 |
|
86 /* Hardware surface functions */ |
|
87 static int DIB_AllocHWSurface(_THIS, SDL_Surface *surface); |
|
88 static int DIB_LockHWSurface(_THIS, SDL_Surface *surface); |
|
89 static void DIB_UnlockHWSurface(_THIS, SDL_Surface *surface); |
|
90 static void DIB_FreeHWSurface(_THIS, SDL_Surface *surface); |
|
91 |
|
92 /* Windows message handling functions */ |
|
93 static void DIB_GrabStaticColors(HWND window); |
|
94 static void DIB_ReleaseStaticColors(HWND window); |
|
95 static void DIB_Activate(_THIS, BOOL active, BOOL minimized); |
|
96 static void DIB_RealizePalette(_THIS); |
|
97 static void DIB_PaletteChanged(_THIS, HWND window); |
|
98 static void DIB_WinPAINT(_THIS, HDC hdc); |
|
99 |
|
100 /* helper fn */ |
|
101 static int DIB_SussScreenDepth(); |
|
102 |
|
103 /* DIB driver bootstrap functions */ |
|
104 |
|
105 static int DIB_Available(void) |
|
106 { |
|
107 return(1); |
|
108 } |
|
109 |
|
110 static void DIB_DeleteDevice(SDL_VideoDevice *device) |
|
111 { |
|
112 if ( device ) { |
|
113 if ( device->hidden ) { |
|
114 SDL_free(device->hidden); |
|
115 } |
|
116 if ( device->gl_data ) { |
|
117 SDL_free(device->gl_data); |
|
118 } |
|
119 SDL_free(device); |
|
120 } |
|
121 } |
|
122 |
|
123 static SDL_VideoDevice *DIB_CreateDevice(int devindex) |
|
124 { |
|
125 SDL_VideoDevice *device; |
|
126 |
|
127 /* Initialize all variables that we clean on shutdown */ |
|
128 device = (SDL_VideoDevice *)SDL_malloc(sizeof(SDL_VideoDevice)); |
|
129 if ( device ) { |
|
130 SDL_memset(device, 0, (sizeof *device)); |
|
131 device->hidden = (struct SDL_PrivateVideoData *) |
|
132 SDL_malloc((sizeof *device->hidden)); |
|
133 device->gl_data = (struct SDL_PrivateGLData *) |
|
134 SDL_malloc((sizeof *device->gl_data)); |
|
135 } |
|
136 if ( (device == NULL) || (device->hidden == NULL) || |
|
137 (device->gl_data == NULL) ) { |
|
138 SDL_OutOfMemory(); |
|
139 DIB_DeleteDevice(device); |
|
140 return(NULL); |
|
141 } |
|
142 SDL_memset(device->hidden, 0, (sizeof *device->hidden)); |
|
143 SDL_memset(device->gl_data, 0, (sizeof *device->gl_data)); |
|
144 |
|
145 /* Set the function pointers */ |
|
146 device->VideoInit = DIB_VideoInit; |
|
147 device->ListModes = DIB_ListModes; |
|
148 device->SetVideoMode = DIB_SetVideoMode; |
|
149 device->UpdateMouse = WIN_UpdateMouse; |
|
150 device->SetColors = DIB_SetColors; |
|
151 device->UpdateRects = NULL; |
|
152 device->VideoQuit = DIB_VideoQuit; |
|
153 device->AllocHWSurface = DIB_AllocHWSurface; |
|
154 device->CheckHWBlit = NULL; |
|
155 device->FillHWRect = NULL; |
|
156 device->SetHWColorKey = NULL; |
|
157 device->SetHWAlpha = NULL; |
|
158 device->LockHWSurface = DIB_LockHWSurface; |
|
159 device->UnlockHWSurface = DIB_UnlockHWSurface; |
|
160 device->FlipHWSurface = NULL; |
|
161 device->FreeHWSurface = DIB_FreeHWSurface; |
|
162 device->SetGammaRamp = DIB_SetGammaRamp; |
|
163 device->GetGammaRamp = DIB_GetGammaRamp; |
|
164 #if SDL_VIDEO_OPENGL |
|
165 device->GL_LoadLibrary = WIN_GL_LoadLibrary; |
|
166 device->GL_GetProcAddress = WIN_GL_GetProcAddress; |
|
167 device->GL_GetAttribute = WIN_GL_GetAttribute; |
|
168 device->GL_MakeCurrent = WIN_GL_MakeCurrent; |
|
169 device->GL_SwapBuffers = WIN_GL_SwapBuffers; |
|
170 #endif |
|
171 device->SetCaption = WIN_SetWMCaption; |
|
172 device->SetIcon = WIN_SetWMIcon; |
|
173 device->IconifyWindow = WIN_IconifyWindow; |
|
174 device->GrabInput = WIN_GrabInput; |
|
175 device->GetWMInfo = WIN_GetWMInfo; |
|
176 device->FreeWMCursor = WIN_FreeWMCursor; |
|
177 device->CreateWMCursor = WIN_CreateWMCursor; |
|
178 device->ShowWMCursor = WIN_ShowWMCursor; |
|
179 device->WarpWMCursor = WIN_WarpWMCursor; |
|
180 device->CheckMouseMode = WIN_CheckMouseMode; |
|
181 device->InitOSKeymap = DIB_InitOSKeymap; |
|
182 device->PumpEvents = DIB_PumpEvents; |
|
183 |
|
184 /* Set up the windows message handling functions */ |
|
185 WIN_Activate = DIB_Activate; |
|
186 WIN_RealizePalette = DIB_RealizePalette; |
|
187 WIN_PaletteChanged = DIB_PaletteChanged; |
|
188 WIN_WinPAINT = DIB_WinPAINT; |
|
189 HandleMessage = DIB_HandleMessage; |
|
190 |
|
191 device->free = DIB_DeleteDevice; |
|
192 |
|
193 /* We're finally ready */ |
|
194 return device; |
|
195 } |
|
196 |
|
197 VideoBootStrap WINDIB_bootstrap = { |
|
198 "windib", "Win95/98/NT/2000/CE GDI", |
|
199 DIB_Available, DIB_CreateDevice |
|
200 }; |
|
201 |
|
202 static int cmpmodes(const void *va, const void *vb) |
|
203 { |
|
204 SDL_Rect *a = *(SDL_Rect **)va; |
|
205 SDL_Rect *b = *(SDL_Rect **)vb; |
|
206 if ( a->w == b->w ) |
|
207 return b->h - a->h; |
|
208 else |
|
209 return b->w - a->w; |
|
210 } |
|
211 |
|
212 static int DIB_AddMode(_THIS, int bpp, int w, int h) |
|
213 { |
|
214 SDL_Rect *mode; |
|
215 int i, index; |
|
216 int next_mode; |
|
217 |
|
218 /* Check to see if we already have this mode */ |
|
219 if ( bpp < 8 || bpp > 32 ) { /* Not supported */ |
|
220 return(0); |
|
221 } |
|
222 index = ((bpp+7)/8)-1; |
|
223 for ( i=0; i<SDL_nummodes[index]; ++i ) { |
|
224 mode = SDL_modelist[index][i]; |
|
225 if ( (mode->w == w) && (mode->h == h) ) { |
|
226 return(0); |
|
227 } |
|
228 } |
|
229 |
|
230 /* Set up the new video mode rectangle */ |
|
231 mode = (SDL_Rect *)SDL_malloc(sizeof *mode); |
|
232 if ( mode == NULL ) { |
|
233 SDL_OutOfMemory(); |
|
234 return(-1); |
|
235 } |
|
236 mode->x = 0; |
|
237 mode->y = 0; |
|
238 mode->w = w; |
|
239 mode->h = h; |
|
240 |
|
241 /* Allocate the new list of modes, and fill in the new mode */ |
|
242 next_mode = SDL_nummodes[index]; |
|
243 SDL_modelist[index] = (SDL_Rect **) |
|
244 SDL_realloc(SDL_modelist[index], (1+next_mode+1)*sizeof(SDL_Rect *)); |
|
245 if ( SDL_modelist[index] == NULL ) { |
|
246 SDL_OutOfMemory(); |
|
247 SDL_nummodes[index] = 0; |
|
248 SDL_free(mode); |
|
249 return(-1); |
|
250 } |
|
251 SDL_modelist[index][next_mode] = mode; |
|
252 SDL_modelist[index][next_mode+1] = NULL; |
|
253 SDL_nummodes[index]++; |
|
254 |
|
255 return(0); |
|
256 } |
|
257 |
|
258 static void DIB_CreatePalette(_THIS, int bpp) |
|
259 { |
|
260 /* RJR: March 28, 2000 |
|
261 moved palette creation here from "DIB_VideoInit" */ |
|
262 |
|
263 LOGPALETTE *palette; |
|
264 HDC hdc; |
|
265 int ncolors; |
|
266 |
|
267 ncolors = (1 << bpp); |
|
268 palette = (LOGPALETTE *)SDL_malloc(sizeof(*palette)+ |
|
269 ncolors*sizeof(PALETTEENTRY)); |
|
270 palette->palVersion = 0x300; |
|
271 palette->palNumEntries = ncolors; |
|
272 hdc = GetDC(SDL_Window); |
|
273 GetSystemPaletteEntries(hdc, 0, ncolors, palette->palPalEntry); |
|
274 ReleaseDC(SDL_Window, hdc); |
|
275 screen_pal = CreatePalette(palette); |
|
276 screen_logpal = palette; |
|
277 } |
|
278 |
|
279 int DIB_VideoInit(_THIS, SDL_PixelFormat *vformat) |
|
280 { |
|
281 const char *env = NULL; |
|
282 #ifndef NO_CHANGEDISPLAYSETTINGS |
|
283 int i; |
|
284 DEVMODE settings; |
|
285 #endif |
|
286 |
|
287 /* Create the window */ |
|
288 if ( DIB_CreateWindow(this) < 0 ) { |
|
289 return(-1); |
|
290 } |
|
291 |
|
292 #if !SDL_AUDIO_DISABLED |
|
293 DX5_SoundFocus(SDL_Window); |
|
294 #endif |
|
295 |
|
296 /* Determine the screen depth */ |
|
297 vformat->BitsPerPixel = DIB_SussScreenDepth(); |
|
298 switch (vformat->BitsPerPixel) { |
|
299 case 15: |
|
300 vformat->Rmask = 0x00007c00; |
|
301 vformat->Gmask = 0x000003e0; |
|
302 vformat->Bmask = 0x0000001f; |
|
303 vformat->BitsPerPixel = 16; |
|
304 break; |
|
305 case 16: |
|
306 vformat->Rmask = 0x0000f800; |
|
307 vformat->Gmask = 0x000007e0; |
|
308 vformat->Bmask = 0x0000001f; |
|
309 break; |
|
310 case 24: |
|
311 case 32: |
|
312 /* GDI defined as 8-8-8 */ |
|
313 vformat->Rmask = 0x00ff0000; |
|
314 vformat->Gmask = 0x0000ff00; |
|
315 vformat->Bmask = 0x000000ff; |
|
316 break; |
|
317 default: |
|
318 break; |
|
319 } |
|
320 |
|
321 /* See if gamma is supported on this screen */ |
|
322 DIB_CheckGamma(this); |
|
323 |
|
324 #ifndef NO_CHANGEDISPLAYSETTINGS |
|
325 |
|
326 settings.dmSize = sizeof(DEVMODE); |
|
327 settings.dmDriverExtra = 0; |
|
328 #ifdef _WIN32_WCE |
|
329 settings.dmFields = DM_DISPLAYQUERYORIENTATION; |
|
330 this->hidden->supportRotation = ChangeDisplaySettingsEx(NULL, &settings, NULL, CDS_TEST, NULL) == DISP_CHANGE_SUCCESSFUL; |
|
331 #endif |
|
332 /* Query for the desktop resolution */ |
|
333 EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &SDL_desktop_mode); |
|
334 this->info.current_w = SDL_desktop_mode.dmPelsWidth; |
|
335 this->info.current_h = SDL_desktop_mode.dmPelsHeight; |
|
336 |
|
337 /* Query for the list of available video modes */ |
|
338 for ( i=0; EnumDisplaySettings(NULL, i, &settings); ++i ) { |
|
339 DIB_AddMode(this, settings.dmBitsPerPel, |
|
340 settings.dmPelsWidth, settings.dmPelsHeight); |
|
341 #ifdef _WIN32_WCE |
|
342 if( this->hidden->supportRotation ) |
|
343 DIB_AddMode(this, settings.dmBitsPerPel, |
|
344 settings.dmPelsHeight, settings.dmPelsWidth); |
|
345 #endif |
|
346 } |
|
347 /* Sort the mode lists */ |
|
348 for ( i=0; i<NUM_MODELISTS; ++i ) { |
|
349 if ( SDL_nummodes[i] > 0 ) { |
|
350 SDL_qsort(SDL_modelist[i], SDL_nummodes[i], sizeof *SDL_modelist[i], cmpmodes); |
|
351 } |
|
352 } |
|
353 #else |
|
354 // WinCE and fullscreen mode: |
|
355 // We use only vformat->BitsPerPixel that allow SDL to |
|
356 // emulate other bpp (8, 32) and use triple buffer, |
|
357 // because SDL surface conversion is much faster than the WinCE one. |
|
358 // Although it should be tested on devices with graphics accelerator. |
|
359 |
|
360 DIB_AddMode(this, vformat->BitsPerPixel, |
|
361 GetDeviceCaps(GetDC(NULL), HORZRES), |
|
362 GetDeviceCaps(GetDC(NULL), VERTRES)); |
|
363 |
|
364 #endif /* !NO_CHANGEDISPLAYSETTINGS */ |
|
365 |
|
366 /* Grab an identity palette if we are in a palettized mode */ |
|
367 if ( vformat->BitsPerPixel <= 8 ) { |
|
368 /* RJR: March 28, 2000 |
|
369 moved palette creation to "DIB_CreatePalette" */ |
|
370 DIB_CreatePalette(this, vformat->BitsPerPixel); |
|
371 } |
|
372 |
|
373 /* Fill in some window manager capabilities */ |
|
374 this->info.wm_available = 1; |
|
375 |
|
376 #ifdef _WIN32_WCE |
|
377 this->hidden->origRotation = -1; |
|
378 #endif |
|
379 |
|
380 /* Allow environment override of screensaver disable. */ |
|
381 env = SDL_getenv("SDL_VIDEO_ALLOW_SCREENSAVER"); |
|
382 this->hidden->allow_screensaver = ( (env && SDL_atoi(env)) ? 1 : 0 ); |
|
383 |
|
384 /* We're done! */ |
|
385 return(0); |
|
386 } |
|
387 |
|
388 /* We support any format at any dimension */ |
|
389 SDL_Rect **DIB_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags) |
|
390 { |
|
391 if ( (flags & SDL_FULLSCREEN) == SDL_FULLSCREEN ) { |
|
392 return(SDL_modelist[((format->BitsPerPixel+7)/8)-1]); |
|
393 } else { |
|
394 return((SDL_Rect **)-1); |
|
395 } |
|
396 } |
|
397 |
|
398 |
|
399 /* |
|
400 Helper fn to work out which screen depth windows is currently using. |
|
401 15 bit mode is considered 555 format, 16 bit is 565. |
|
402 returns 0 for unknown mode. |
|
403 (Derived from code in sept 1999 Windows Developer Journal |
|
404 http://www.wdj.com/code/archive.html) |
|
405 */ |
|
406 static int DIB_SussScreenDepth() |
|
407 { |
|
408 #ifdef NO_GETDIBITS |
|
409 int depth; |
|
410 HDC hdc; |
|
411 |
|
412 hdc = GetDC(SDL_Window); |
|
413 depth = GetDeviceCaps(hdc, PLANES) * GetDeviceCaps(hdc, BITSPIXEL); |
|
414 ReleaseDC(SDL_Window, hdc); |
|
415 return(depth); |
|
416 #else |
|
417 int depth; |
|
418 int dib_size; |
|
419 LPBITMAPINFOHEADER dib_hdr; |
|
420 HDC hdc; |
|
421 HBITMAP hbm; |
|
422 |
|
423 /* Allocate enough space for a DIB header plus palette (for |
|
424 * 8-bit modes) or bitfields (for 16- and 32-bit modes) |
|
425 */ |
|
426 dib_size = sizeof(BITMAPINFOHEADER) + 256 * sizeof (RGBQUAD); |
|
427 dib_hdr = (LPBITMAPINFOHEADER) SDL_malloc(dib_size); |
|
428 SDL_memset(dib_hdr, 0, dib_size); |
|
429 dib_hdr->biSize = sizeof(BITMAPINFOHEADER); |
|
430 |
|
431 /* Get a device-dependent bitmap that's compatible with the |
|
432 screen. |
|
433 */ |
|
434 hdc = GetDC(NULL); |
|
435 hbm = CreateCompatibleBitmap( hdc, 1, 1 ); |
|
436 |
|
437 /* Convert the DDB to a DIB. We need to call GetDIBits twice: |
|
438 * the first call just fills in the BITMAPINFOHEADER; the |
|
439 * second fills in the bitfields or palette. |
|
440 */ |
|
441 GetDIBits(hdc, hbm, 0, 1, NULL, (LPBITMAPINFO) dib_hdr, DIB_RGB_COLORS); |
|
442 GetDIBits(hdc, hbm, 0, 1, NULL, (LPBITMAPINFO) dib_hdr, DIB_RGB_COLORS); |
|
443 DeleteObject(hbm); |
|
444 ReleaseDC(NULL, hdc); |
|
445 |
|
446 depth = 0; |
|
447 switch( dib_hdr->biBitCount ) |
|
448 { |
|
449 case 8: depth = 8; break; |
|
450 case 24: depth = 24; break; |
|
451 case 32: depth = 32; break; |
|
452 case 16: |
|
453 if( dib_hdr->biCompression == BI_BITFIELDS ) { |
|
454 /* check the red mask */ |
|
455 switch( ((DWORD*)((char*)dib_hdr + dib_hdr->biSize))[0] ) { |
|
456 case 0xf800: depth = 16; break; /* 565 */ |
|
457 case 0x7c00: depth = 15; break; /* 555 */ |
|
458 } |
|
459 } |
|
460 } |
|
461 SDL_free(dib_hdr); |
|
462 return depth; |
|
463 #endif /* NO_GETDIBITS */ |
|
464 } |
|
465 |
|
466 |
|
467 /* Various screen update functions available */ |
|
468 static void DIB_NormalUpdate(_THIS, int numrects, SDL_Rect *rects); |
|
469 |
|
470 SDL_Surface *DIB_SetVideoMode(_THIS, SDL_Surface *current, |
|
471 int width, int height, int bpp, Uint32 flags) |
|
472 { |
|
473 SDL_Surface *video; |
|
474 int prev_w, prev_h; |
|
475 Uint32 prev_flags; |
|
476 DWORD style; |
|
477 const DWORD directstyle = |
|
478 (WS_POPUP); |
|
479 const DWORD windowstyle = |
|
480 (WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX); |
|
481 const DWORD resizestyle = |
|
482 (WS_THICKFRAME|WS_MAXIMIZEBOX); |
|
483 int binfo_size; |
|
484 BITMAPINFO *binfo; |
|
485 HDC hdc; |
|
486 RECT bounds; |
|
487 int x, y; |
|
488 Uint32 Rmask, Gmask, Bmask; |
|
489 |
|
490 prev_flags = current->flags; |
|
491 |
|
492 /* Clean up any GL context that may be hanging around */ |
|
493 if ( current->flags & SDL_OPENGL ) { |
|
494 WIN_GL_ShutDown(this); |
|
495 } |
|
496 SDL_resizing = 1; |
|
497 |
|
498 /* Recalculate the bitmasks if necessary */ |
|
499 if ( bpp == current->format->BitsPerPixel ) { |
|
500 video = current; |
|
501 } else { |
|
502 switch (bpp) { |
|
503 case 15: |
|
504 case 16: |
|
505 if ( DIB_SussScreenDepth() == 15 ) { |
|
506 /* 5-5-5 */ |
|
507 Rmask = 0x00007c00; |
|
508 Gmask = 0x000003e0; |
|
509 Bmask = 0x0000001f; |
|
510 } else { |
|
511 /* 5-6-5 */ |
|
512 Rmask = 0x0000f800; |
|
513 Gmask = 0x000007e0; |
|
514 Bmask = 0x0000001f; |
|
515 } |
|
516 break; |
|
517 case 24: |
|
518 case 32: |
|
519 /* GDI defined as 8-8-8 */ |
|
520 Rmask = 0x00ff0000; |
|
521 Gmask = 0x0000ff00; |
|
522 Bmask = 0x000000ff; |
|
523 break; |
|
524 default: |
|
525 Rmask = 0x00000000; |
|
526 Gmask = 0x00000000; |
|
527 Bmask = 0x00000000; |
|
528 break; |
|
529 } |
|
530 video = SDL_CreateRGBSurface(SDL_SWSURFACE, |
|
531 0, 0, bpp, Rmask, Gmask, Bmask, 0); |
|
532 if ( video == NULL ) { |
|
533 SDL_OutOfMemory(); |
|
534 return(NULL); |
|
535 } |
|
536 } |
|
537 |
|
538 /* Fill in part of the video surface */ |
|
539 prev_w = video->w; |
|
540 prev_h = video->h; |
|
541 video->flags = 0; /* Clear flags */ |
|
542 video->w = width; |
|
543 video->h = height; |
|
544 video->pitch = SDL_CalculatePitch(video); |
|
545 |
|
546 /* Small fix for WinCE/Win32 - when activating window |
|
547 SDL_VideoSurface is equal to zero, so activating code |
|
548 is not called properly for fullscreen windows because |
|
549 macros WINDIB_FULLSCREEN uses SDL_VideoSurface |
|
550 */ |
|
551 SDL_VideoSurface = video; |
|
552 |
|
553 #if defined(_WIN32_WCE) |
|
554 if ( flags & SDL_FULLSCREEN ) |
|
555 video->flags |= SDL_FULLSCREEN; |
|
556 #endif |
|
557 |
|
558 #ifndef NO_CHANGEDISPLAYSETTINGS |
|
559 /* Set fullscreen mode if appropriate */ |
|
560 if ( (flags & SDL_FULLSCREEN) == SDL_FULLSCREEN ) { |
|
561 DEVMODE settings; |
|
562 BOOL changed; |
|
563 |
|
564 SDL_memset(&settings, 0, sizeof(DEVMODE)); |
|
565 settings.dmSize = sizeof(DEVMODE); |
|
566 |
|
567 #ifdef _WIN32_WCE |
|
568 // try to rotate screen to fit requested resolution |
|
569 if( this->hidden->supportRotation ) |
|
570 { |
|
571 DWORD rotation; |
|
572 |
|
573 // ask current mode |
|
574 settings.dmFields = DM_DISPLAYORIENTATION; |
|
575 ChangeDisplaySettingsEx(NULL, &settings, NULL, CDS_TEST, NULL); |
|
576 rotation = settings.dmDisplayOrientation; |
|
577 |
|
578 if( (width > GetDeviceCaps(GetDC(NULL), HORZRES)) |
|
579 && (height < GetDeviceCaps(GetDC(NULL), VERTRES))) |
|
580 { |
|
581 switch( rotation ) |
|
582 { |
|
583 case DMDO_0: |
|
584 settings.dmDisplayOrientation = DMDO_90; |
|
585 break; |
|
586 case DMDO_270: |
|
587 settings.dmDisplayOrientation = DMDO_180; |
|
588 break; |
|
589 } |
|
590 if( settings.dmDisplayOrientation != rotation ) |
|
591 { |
|
592 // go to landscape |
|
593 this->hidden->origRotation = rotation; |
|
594 ChangeDisplaySettingsEx(NULL,&settings,NULL,CDS_RESET,NULL); |
|
595 } |
|
596 } |
|
597 if( (width < GetDeviceCaps(GetDC(NULL), HORZRES)) |
|
598 && (height > GetDeviceCaps(GetDC(NULL), VERTRES))) |
|
599 { |
|
600 switch( rotation ) |
|
601 { |
|
602 case DMDO_90: |
|
603 settings.dmDisplayOrientation = DMDO_0; |
|
604 break; |
|
605 case DMDO_180: |
|
606 settings.dmDisplayOrientation = DMDO_270; |
|
607 break; |
|
608 } |
|
609 if( settings.dmDisplayOrientation != rotation ) |
|
610 { |
|
611 // go to portrait |
|
612 this->hidden->origRotation = rotation; |
|
613 ChangeDisplaySettingsEx(NULL,&settings,NULL,CDS_RESET,NULL); |
|
614 } |
|
615 } |
|
616 |
|
617 } |
|
618 #endif |
|
619 |
|
620 #ifndef _WIN32_WCE |
|
621 settings.dmBitsPerPel = video->format->BitsPerPixel; |
|
622 settings.dmPelsWidth = width; |
|
623 settings.dmPelsHeight = height; |
|
624 settings.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL; |
|
625 if ( width <= (int)SDL_desktop_mode.dmPelsWidth && |
|
626 height <= (int)SDL_desktop_mode.dmPelsHeight ) { |
|
627 settings.dmDisplayFrequency = SDL_desktop_mode.dmDisplayFrequency; |
|
628 settings.dmFields |= DM_DISPLAYFREQUENCY; |
|
629 } |
|
630 changed = (ChangeDisplaySettings(&settings, CDS_FULLSCREEN) == DISP_CHANGE_SUCCESSFUL); |
|
631 if ( ! changed && (settings.dmFields & DM_DISPLAYFREQUENCY) ) { |
|
632 settings.dmFields &= ~DM_DISPLAYFREQUENCY; |
|
633 changed = (ChangeDisplaySettings(&settings, CDS_FULLSCREEN) == DISP_CHANGE_SUCCESSFUL); |
|
634 } |
|
635 #else |
|
636 changed = 1; |
|
637 #endif |
|
638 if ( changed ) { |
|
639 video->flags |= SDL_FULLSCREEN; |
|
640 SDL_fullscreen_mode = settings; |
|
641 } |
|
642 |
|
643 } |
|
644 #endif /* !NO_CHANGEDISPLAYSETTINGS */ |
|
645 |
|
646 /* Reset the palette and create a new one if necessary */ |
|
647 if ( grab_palette ) { |
|
648 DIB_ReleaseStaticColors(SDL_Window); |
|
649 grab_palette = FALSE; |
|
650 } |
|
651 if ( screen_pal != NULL ) { |
|
652 /* RJR: March 28, 2000 |
|
653 delete identity palette if switching from a palettized mode */ |
|
654 DeleteObject(screen_pal); |
|
655 screen_pal = NULL; |
|
656 } |
|
657 if ( screen_logpal != NULL ) { |
|
658 SDL_free(screen_logpal); |
|
659 screen_logpal = NULL; |
|
660 } |
|
661 |
|
662 if ( bpp <= 8 ) |
|
663 { |
|
664 /* RJR: March 28, 2000 |
|
665 create identity palette switching to a palettized mode */ |
|
666 DIB_CreatePalette(this, bpp); |
|
667 } |
|
668 |
|
669 style = GetWindowLong(SDL_Window, GWL_STYLE); |
|
670 style &= ~(resizestyle|WS_MAXIMIZE); |
|
671 if ( (video->flags & SDL_FULLSCREEN) == SDL_FULLSCREEN ) { |
|
672 style &= ~windowstyle; |
|
673 style |= directstyle; |
|
674 } else { |
|
675 #ifndef NO_CHANGEDISPLAYSETTINGS |
|
676 if ( (prev_flags & SDL_FULLSCREEN) == SDL_FULLSCREEN ) { |
|
677 ChangeDisplaySettings(NULL, 0); |
|
678 } |
|
679 #endif |
|
680 if ( flags & SDL_NOFRAME ) { |
|
681 style &= ~windowstyle; |
|
682 style |= directstyle; |
|
683 video->flags |= SDL_NOFRAME; |
|
684 } else { |
|
685 style &= ~directstyle; |
|
686 style |= windowstyle; |
|
687 if ( flags & SDL_RESIZABLE ) { |
|
688 style |= resizestyle; |
|
689 video->flags |= SDL_RESIZABLE; |
|
690 } |
|
691 } |
|
692 #if WS_MAXIMIZE |
|
693 if (IsZoomed(SDL_Window)) style |= WS_MAXIMIZE; |
|
694 #endif |
|
695 } |
|
696 |
|
697 /* DJM: Don't piss of anyone who has setup his own window */ |
|
698 if ( !SDL_windowid ) |
|
699 SetWindowLong(SDL_Window, GWL_STYLE, style); |
|
700 |
|
701 /* Delete the old bitmap if necessary */ |
|
702 if ( screen_bmp != NULL ) { |
|
703 DeleteObject(screen_bmp); |
|
704 } |
|
705 if ( ! (flags & SDL_OPENGL) ) { |
|
706 BOOL is16bitmode = (video->format->BytesPerPixel == 2); |
|
707 |
|
708 /* Suss out the bitmap info header */ |
|
709 binfo_size = sizeof(*binfo); |
|
710 if( is16bitmode ) { |
|
711 /* 16bit modes, palette area used for rgb bitmasks */ |
|
712 binfo_size += 3*sizeof(DWORD); |
|
713 } else if ( video->format->palette ) { |
|
714 binfo_size += video->format->palette->ncolors * |
|
715 sizeof(RGBQUAD); |
|
716 } |
|
717 binfo = (BITMAPINFO *)SDL_malloc(binfo_size); |
|
718 if ( ! binfo ) { |
|
719 if ( video != current ) { |
|
720 SDL_FreeSurface(video); |
|
721 } |
|
722 SDL_OutOfMemory(); |
|
723 return(NULL); |
|
724 } |
|
725 |
|
726 binfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); |
|
727 binfo->bmiHeader.biWidth = video->w; |
|
728 binfo->bmiHeader.biHeight = -video->h; /* -ve for topdown bitmap */ |
|
729 binfo->bmiHeader.biPlanes = 1; |
|
730 binfo->bmiHeader.biSizeImage = video->h * video->pitch; |
|
731 binfo->bmiHeader.biXPelsPerMeter = 0; |
|
732 binfo->bmiHeader.biYPelsPerMeter = 0; |
|
733 binfo->bmiHeader.biClrUsed = 0; |
|
734 binfo->bmiHeader.biClrImportant = 0; |
|
735 binfo->bmiHeader.biBitCount = video->format->BitsPerPixel; |
|
736 |
|
737 if ( is16bitmode ) { |
|
738 /* BI_BITFIELDS tells CreateDIBSection about the rgb masks in the palette */ |
|
739 binfo->bmiHeader.biCompression = BI_BITFIELDS; |
|
740 ((Uint32*)binfo->bmiColors)[0] = video->format->Rmask; |
|
741 ((Uint32*)binfo->bmiColors)[1] = video->format->Gmask; |
|
742 ((Uint32*)binfo->bmiColors)[2] = video->format->Bmask; |
|
743 } else { |
|
744 binfo->bmiHeader.biCompression = BI_RGB; /* BI_BITFIELDS for 565 vs 555 */ |
|
745 if ( video->format->palette ) { |
|
746 SDL_memset(binfo->bmiColors, 0, |
|
747 video->format->palette->ncolors*sizeof(RGBQUAD)); |
|
748 } |
|
749 } |
|
750 |
|
751 /* Create the offscreen bitmap buffer */ |
|
752 hdc = GetDC(SDL_Window); |
|
753 screen_bmp = CreateDIBSection(hdc, binfo, DIB_RGB_COLORS, |
|
754 (void **)(&video->pixels), NULL, 0); |
|
755 ReleaseDC(SDL_Window, hdc); |
|
756 SDL_free(binfo); |
|
757 if ( screen_bmp == NULL ) { |
|
758 if ( video != current ) { |
|
759 SDL_FreeSurface(video); |
|
760 } |
|
761 SDL_SetError("Couldn't create DIB section"); |
|
762 return(NULL); |
|
763 } |
|
764 this->UpdateRects = DIB_NormalUpdate; |
|
765 |
|
766 /* Set video surface flags */ |
|
767 if ( screen_pal && (flags & (SDL_FULLSCREEN|SDL_HWPALETTE)) ) { |
|
768 grab_palette = TRUE; |
|
769 } |
|
770 /* BitBlt() maps colors for us */ |
|
771 video->flags |= SDL_HWPALETTE; |
|
772 } |
|
773 #ifndef _WIN32_WCE |
|
774 /* Resize the window */ |
|
775 if ( !SDL_windowid && !IsZoomed(SDL_Window) ) { |
|
776 #else |
|
777 if ( !SDL_windowid ) { |
|
778 #endif |
|
779 HWND top; |
|
780 UINT swp_flags; |
|
781 const char *window = NULL; |
|
782 const char *center = NULL; |
|
783 |
|
784 if ( video->w != prev_w || video->h != prev_h ) { |
|
785 window = SDL_getenv("SDL_VIDEO_WINDOW_POS"); |
|
786 center = SDL_getenv("SDL_VIDEO_CENTERED"); |
|
787 if ( window ) { |
|
788 if ( SDL_sscanf(window, "%d,%d", &x, &y) == 2 ) { |
|
789 SDL_windowX = x; |
|
790 SDL_windowY = y; |
|
791 } |
|
792 if ( SDL_strcmp(window, "center") == 0 ) { |
|
793 center = window; |
|
794 } |
|
795 } |
|
796 } |
|
797 swp_flags = (SWP_NOCOPYBITS | SWP_SHOWWINDOW); |
|
798 |
|
799 bounds.left = SDL_windowX; |
|
800 bounds.top = SDL_windowY; |
|
801 bounds.right = SDL_windowX+video->w; |
|
802 bounds.bottom = SDL_windowY+video->h; |
|
803 #ifndef _WIN32_WCE |
|
804 AdjustWindowRectEx(&bounds, GetWindowLong(SDL_Window, GWL_STYLE), (GetMenu(SDL_Window) != NULL), 0); |
|
805 #else |
|
806 // The bMenu parameter must be FALSE; menu bars are not supported |
|
807 AdjustWindowRectEx(&bounds, GetWindowLong(SDL_Window, GWL_STYLE), 0, 0); |
|
808 #endif |
|
809 width = bounds.right-bounds.left; |
|
810 height = bounds.bottom-bounds.top; |
|
811 if ( (flags & SDL_FULLSCREEN) ) { |
|
812 x = (GetSystemMetrics(SM_CXSCREEN)-width)/2; |
|
813 y = (GetSystemMetrics(SM_CYSCREEN)-height)/2; |
|
814 } else if ( center ) { |
|
815 x = (GetSystemMetrics(SM_CXSCREEN)-width)/2; |
|
816 y = (GetSystemMetrics(SM_CYSCREEN)-height)/2; |
|
817 } else if ( SDL_windowX || SDL_windowY || window ) { |
|
818 x = bounds.left; |
|
819 y = bounds.top; |
|
820 } else { |
|
821 x = y = -1; |
|
822 swp_flags |= SWP_NOMOVE; |
|
823 } |
|
824 if ( flags & SDL_FULLSCREEN ) { |
|
825 top = HWND_TOPMOST; |
|
826 } else { |
|
827 top = HWND_NOTOPMOST; |
|
828 } |
|
829 SetWindowPos(SDL_Window, top, x, y, width, height, swp_flags); |
|
830 if ( !(flags & SDL_FULLSCREEN) ) { |
|
831 SDL_windowX = SDL_bounds.left; |
|
832 SDL_windowY = SDL_bounds.top; |
|
833 } |
|
834 SetForegroundWindow(SDL_Window); |
|
835 } |
|
836 SDL_resizing = 0; |
|
837 |
|
838 /* Set up for OpenGL */ |
|
839 if ( flags & SDL_OPENGL ) { |
|
840 if ( WIN_GL_SetupWindow(this) < 0 ) { |
|
841 return(NULL); |
|
842 } |
|
843 video->flags |= SDL_OPENGL; |
|
844 } |
|
845 |
|
846 /* JC 14 Mar 2006 |
|
847 Flush the message loop or this can cause big problems later |
|
848 Especially if the user decides to use dialog boxes or assert()! |
|
849 */ |
|
850 WIN_FlushMessageQueue(); |
|
851 |
|
852 /* We're live! */ |
|
853 return(video); |
|
854 } |
|
855 |
|
856 /* We don't actually allow hardware surfaces in the DIB driver */ |
|
857 static int DIB_AllocHWSurface(_THIS, SDL_Surface *surface) |
|
858 { |
|
859 return(-1); |
|
860 } |
|
861 static void DIB_FreeHWSurface(_THIS, SDL_Surface *surface) |
|
862 { |
|
863 return; |
|
864 } |
|
865 static int DIB_LockHWSurface(_THIS, SDL_Surface *surface) |
|
866 { |
|
867 return(0); |
|
868 } |
|
869 static void DIB_UnlockHWSurface(_THIS, SDL_Surface *surface) |
|
870 { |
|
871 return; |
|
872 } |
|
873 |
|
874 static void DIB_NormalUpdate(_THIS, int numrects, SDL_Rect *rects) |
|
875 { |
|
876 HDC hdc, mdc; |
|
877 int i; |
|
878 |
|
879 hdc = GetDC(SDL_Window); |
|
880 if ( screen_pal ) { |
|
881 SelectPalette(hdc, screen_pal, FALSE); |
|
882 } |
|
883 mdc = CreateCompatibleDC(hdc); |
|
884 SelectObject(mdc, screen_bmp); |
|
885 for ( i=0; i<numrects; ++i ) { |
|
886 BitBlt(hdc, rects[i].x, rects[i].y, rects[i].w, rects[i].h, |
|
887 mdc, rects[i].x, rects[i].y, SRCCOPY); |
|
888 } |
|
889 DeleteDC(mdc); |
|
890 ReleaseDC(SDL_Window, hdc); |
|
891 } |
|
892 |
|
893 static int FindPaletteIndex(LOGPALETTE *pal, BYTE r, BYTE g, BYTE b) |
|
894 { |
|
895 PALETTEENTRY *entry; |
|
896 int i; |
|
897 int nentries = pal->palNumEntries; |
|
898 |
|
899 for ( i = 0; i < nentries; ++i ) { |
|
900 entry = &pal->palPalEntry[i]; |
|
901 if ( entry->peRed == r && entry->peGreen == g && entry->peBlue == b ) { |
|
902 return i; |
|
903 } |
|
904 } |
|
905 return -1; |
|
906 } |
|
907 |
|
908 static BOOL CheckPaletteEntry(LOGPALETTE *pal, int index, BYTE r, BYTE g, BYTE b) |
|
909 { |
|
910 PALETTEENTRY *entry; |
|
911 BOOL moved = 0; |
|
912 |
|
913 entry = &pal->palPalEntry[index]; |
|
914 if ( entry->peRed != r || entry->peGreen != g || entry->peBlue != b ) { |
|
915 int found = FindPaletteIndex(pal, r, g, b); |
|
916 if ( found >= 0 ) { |
|
917 pal->palPalEntry[found] = *entry; |
|
918 } |
|
919 entry->peRed = r; |
|
920 entry->peGreen = g; |
|
921 entry->peBlue = b; |
|
922 moved = 1; |
|
923 } |
|
924 entry->peFlags = 0; |
|
925 |
|
926 return moved; |
|
927 } |
|
928 |
|
929 int DIB_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors) |
|
930 { |
|
931 #if !defined(_WIN32_WCE) || (_WIN32_WCE >= 400) |
|
932 HDC hdc, mdc; |
|
933 RGBQUAD *pal; |
|
934 #else |
|
935 HDC hdc; |
|
936 #endif |
|
937 int i; |
|
938 int moved_entries = 0; |
|
939 |
|
940 /* Update the display palette */ |
|
941 hdc = GetDC(SDL_Window); |
|
942 if ( screen_pal ) { |
|
943 PALETTEENTRY *entry; |
|
944 |
|
945 for ( i=0; i<ncolors; ++i ) { |
|
946 entry = &screen_logpal->palPalEntry[firstcolor+i]; |
|
947 entry->peRed = colors[i].r; |
|
948 entry->peGreen = colors[i].g; |
|
949 entry->peBlue = colors[i].b; |
|
950 entry->peFlags = PC_NOCOLLAPSE; |
|
951 } |
|
952 #ifdef SYSPAL_NOSTATIC |
|
953 /* Check to make sure black and white are in position */ |
|
954 if ( GetSystemPaletteUse(hdc) != SYSPAL_NOSTATIC256 ) { |
|
955 moved_entries += CheckPaletteEntry(screen_logpal, 0, 0x00, 0x00, 0x00); |
|
956 moved_entries += CheckPaletteEntry(screen_logpal, screen_logpal->palNumEntries-1, 0xff, 0xff, 0xff); |
|
957 } |
|
958 /* FIXME: |
|
959 If we don't have full access to the palette, what we |
|
960 really want to do is find the 236 most diverse colors |
|
961 in the desired palette, set those entries (10-245) and |
|
962 then map everything into the new system palette. |
|
963 */ |
|
964 #endif |
|
965 |
|
966 #ifndef _WIN32_WCE |
|
967 /* Copy the entries into the system palette */ |
|
968 UnrealizeObject(screen_pal); |
|
969 #endif |
|
970 SetPaletteEntries(screen_pal, 0, screen_logpal->palNumEntries, screen_logpal->palPalEntry); |
|
971 SelectPalette(hdc, screen_pal, FALSE); |
|
972 RealizePalette(hdc); |
|
973 } |
|
974 |
|
975 #if !defined(_WIN32_WCE) || (_WIN32_WCE >= 400) |
|
976 /* Copy palette colors into DIB palette */ |
|
977 pal = SDL_stack_alloc(RGBQUAD, ncolors); |
|
978 for ( i=0; i<ncolors; ++i ) { |
|
979 pal[i].rgbRed = colors[i].r; |
|
980 pal[i].rgbGreen = colors[i].g; |
|
981 pal[i].rgbBlue = colors[i].b; |
|
982 pal[i].rgbReserved = 0; |
|
983 } |
|
984 |
|
985 /* Set the DIB palette and update the display */ |
|
986 mdc = CreateCompatibleDC(hdc); |
|
987 SelectObject(mdc, screen_bmp); |
|
988 SetDIBColorTable(mdc, firstcolor, ncolors, pal); |
|
989 if ( moved_entries || !grab_palette ) { |
|
990 BitBlt(hdc, 0, 0, this->screen->w, this->screen->h, |
|
991 mdc, 0, 0, SRCCOPY); |
|
992 } |
|
993 DeleteDC(mdc); |
|
994 SDL_stack_free(pal); |
|
995 #endif |
|
996 ReleaseDC(SDL_Window, hdc); |
|
997 return(1); |
|
998 } |
|
999 |
|
1000 |
|
1001 static void DIB_CheckGamma(_THIS) |
|
1002 { |
|
1003 #ifndef NO_GAMMA_SUPPORT |
|
1004 HDC hdc; |
|
1005 WORD ramp[3*256]; |
|
1006 |
|
1007 /* If we fail to get gamma, disable gamma control */ |
|
1008 hdc = GetDC(SDL_Window); |
|
1009 if ( ! GetDeviceGammaRamp(hdc, ramp) ) { |
|
1010 this->GetGammaRamp = NULL; |
|
1011 this->SetGammaRamp = NULL; |
|
1012 } |
|
1013 ReleaseDC(SDL_Window, hdc); |
|
1014 #endif /* !NO_GAMMA_SUPPORT */ |
|
1015 } |
|
1016 void DIB_SwapGamma(_THIS) |
|
1017 { |
|
1018 #ifndef NO_GAMMA_SUPPORT |
|
1019 HDC hdc; |
|
1020 |
|
1021 if ( gamma_saved ) { |
|
1022 hdc = GetDC(SDL_Window); |
|
1023 if ( SDL_GetAppState() & SDL_APPINPUTFOCUS ) { |
|
1024 /* About to leave active state, restore gamma */ |
|
1025 SetDeviceGammaRamp(hdc, gamma_saved); |
|
1026 } else { |
|
1027 /* About to enter active state, set game gamma */ |
|
1028 GetDeviceGammaRamp(hdc, gamma_saved); |
|
1029 SetDeviceGammaRamp(hdc, this->gamma); |
|
1030 } |
|
1031 ReleaseDC(SDL_Window, hdc); |
|
1032 } |
|
1033 #endif /* !NO_GAMMA_SUPPORT */ |
|
1034 } |
|
1035 void DIB_QuitGamma(_THIS) |
|
1036 { |
|
1037 #ifndef NO_GAMMA_SUPPORT |
|
1038 if ( gamma_saved ) { |
|
1039 /* Restore the original gamma if necessary */ |
|
1040 if ( SDL_GetAppState() & SDL_APPINPUTFOCUS ) { |
|
1041 HDC hdc; |
|
1042 |
|
1043 hdc = GetDC(SDL_Window); |
|
1044 SetDeviceGammaRamp(hdc, gamma_saved); |
|
1045 ReleaseDC(SDL_Window, hdc); |
|
1046 } |
|
1047 |
|
1048 /* Free the saved gamma memory */ |
|
1049 SDL_free(gamma_saved); |
|
1050 gamma_saved = 0; |
|
1051 } |
|
1052 #endif /* !NO_GAMMA_SUPPORT */ |
|
1053 } |
|
1054 |
|
1055 int DIB_SetGammaRamp(_THIS, Uint16 *ramp) |
|
1056 { |
|
1057 #ifdef NO_GAMMA_SUPPORT |
|
1058 SDL_SetError("SDL compiled without gamma ramp support"); |
|
1059 return -1; |
|
1060 #else |
|
1061 HDC hdc; |
|
1062 BOOL succeeded; |
|
1063 |
|
1064 /* Set the ramp for the display */ |
|
1065 if ( ! gamma_saved ) { |
|
1066 gamma_saved = (WORD *)SDL_malloc(3*256*sizeof(*gamma_saved)); |
|
1067 if ( ! gamma_saved ) { |
|
1068 SDL_OutOfMemory(); |
|
1069 return -1; |
|
1070 } |
|
1071 hdc = GetDC(SDL_Window); |
|
1072 GetDeviceGammaRamp(hdc, gamma_saved); |
|
1073 ReleaseDC(SDL_Window, hdc); |
|
1074 } |
|
1075 if ( SDL_GetAppState() & SDL_APPINPUTFOCUS ) { |
|
1076 hdc = GetDC(SDL_Window); |
|
1077 succeeded = SetDeviceGammaRamp(hdc, ramp); |
|
1078 ReleaseDC(SDL_Window, hdc); |
|
1079 } else { |
|
1080 succeeded = TRUE; |
|
1081 } |
|
1082 return succeeded ? 0 : -1; |
|
1083 #endif /* !NO_GAMMA_SUPPORT */ |
|
1084 } |
|
1085 |
|
1086 int DIB_GetGammaRamp(_THIS, Uint16 *ramp) |
|
1087 { |
|
1088 #ifdef NO_GAMMA_SUPPORT |
|
1089 SDL_SetError("SDL compiled without gamma ramp support"); |
|
1090 return -1; |
|
1091 #else |
|
1092 HDC hdc; |
|
1093 BOOL succeeded; |
|
1094 |
|
1095 /* Get the ramp from the display */ |
|
1096 hdc = GetDC(SDL_Window); |
|
1097 succeeded = GetDeviceGammaRamp(hdc, ramp); |
|
1098 ReleaseDC(SDL_Window, hdc); |
|
1099 return succeeded ? 0 : -1; |
|
1100 #endif /* !NO_GAMMA_SUPPORT */ |
|
1101 } |
|
1102 |
|
1103 void DIB_VideoQuit(_THIS) |
|
1104 { |
|
1105 int i, j; |
|
1106 |
|
1107 /* Destroy the window and everything associated with it */ |
|
1108 if ( SDL_Window ) { |
|
1109 /* Delete the screen bitmap (also frees screen->pixels) */ |
|
1110 if ( this->screen ) { |
|
1111 if ( grab_palette ) { |
|
1112 DIB_ReleaseStaticColors(SDL_Window); |
|
1113 } |
|
1114 #ifndef NO_CHANGEDISPLAYSETTINGS |
|
1115 if ( this->screen->flags & SDL_FULLSCREEN ) { |
|
1116 ChangeDisplaySettings(NULL, 0); |
|
1117 ShowWindow(SDL_Window, SW_HIDE); |
|
1118 } |
|
1119 #endif |
|
1120 if ( this->screen->flags & SDL_OPENGL ) { |
|
1121 WIN_GL_ShutDown(this); |
|
1122 } |
|
1123 this->screen->pixels = NULL; |
|
1124 } |
|
1125 if ( screen_pal != NULL ) { |
|
1126 DeleteObject(screen_pal); |
|
1127 screen_pal = NULL; |
|
1128 } |
|
1129 if ( screen_logpal != NULL ) { |
|
1130 SDL_free(screen_logpal); |
|
1131 screen_logpal = NULL; |
|
1132 } |
|
1133 if ( screen_bmp ) { |
|
1134 DeleteObject(screen_bmp); |
|
1135 screen_bmp = NULL; |
|
1136 } |
|
1137 if ( screen_icn ) { |
|
1138 DestroyIcon(screen_icn); |
|
1139 screen_icn = NULL; |
|
1140 } |
|
1141 DIB_QuitGamma(this); |
|
1142 DIB_DestroyWindow(this); |
|
1143 |
|
1144 SDL_Window = NULL; |
|
1145 |
|
1146 #if defined(_WIN32_WCE) |
|
1147 |
|
1148 // Unload wince aygshell library to prevent leak |
|
1149 if( aygshell ) |
|
1150 { |
|
1151 FreeLibrary(aygshell); |
|
1152 aygshell = NULL; |
|
1153 } |
|
1154 #endif |
|
1155 } |
|
1156 |
|
1157 for ( i=0; i < SDL_arraysize(SDL_modelist); ++i ) { |
|
1158 if ( !SDL_modelist[i] ) { |
|
1159 continue; |
|
1160 } |
|
1161 for ( j=0; SDL_modelist[i][j]; ++j ) { |
|
1162 SDL_free(SDL_modelist[i][j]); |
|
1163 } |
|
1164 SDL_free(SDL_modelist[i]); |
|
1165 SDL_modelist[i] = NULL; |
|
1166 SDL_nummodes[i] = 0; |
|
1167 } |
|
1168 } |
|
1169 |
|
1170 /* Exported for the windows message loop only */ |
|
1171 static void DIB_GrabStaticColors(HWND window) |
|
1172 { |
|
1173 #ifdef SYSPAL_NOSTATIC |
|
1174 HDC hdc; |
|
1175 |
|
1176 hdc = GetDC(window); |
|
1177 SetSystemPaletteUse(hdc, SYSPAL_NOSTATIC256); |
|
1178 if ( GetSystemPaletteUse(hdc) != SYSPAL_NOSTATIC256 ) { |
|
1179 SetSystemPaletteUse(hdc, SYSPAL_NOSTATIC); |
|
1180 } |
|
1181 ReleaseDC(window, hdc); |
|
1182 #endif |
|
1183 } |
|
1184 static void DIB_ReleaseStaticColors(HWND window) |
|
1185 { |
|
1186 #ifdef SYSPAL_NOSTATIC |
|
1187 HDC hdc; |
|
1188 |
|
1189 hdc = GetDC(window); |
|
1190 SetSystemPaletteUse(hdc, SYSPAL_STATIC); |
|
1191 ReleaseDC(window, hdc); |
|
1192 #endif |
|
1193 } |
|
1194 static void DIB_Activate(_THIS, BOOL active, BOOL minimized) |
|
1195 { |
|
1196 if ( grab_palette ) { |
|
1197 if ( !active ) { |
|
1198 DIB_ReleaseStaticColors(SDL_Window); |
|
1199 DIB_RealizePalette(this); |
|
1200 } else if ( !minimized ) { |
|
1201 DIB_GrabStaticColors(SDL_Window); |
|
1202 DIB_RealizePalette(this); |
|
1203 } |
|
1204 } |
|
1205 } |
|
1206 static void DIB_RealizePalette(_THIS) |
|
1207 { |
|
1208 if ( screen_pal != NULL ) { |
|
1209 HDC hdc; |
|
1210 |
|
1211 hdc = GetDC(SDL_Window); |
|
1212 #ifndef _WIN32_WCE |
|
1213 UnrealizeObject(screen_pal); |
|
1214 #endif |
|
1215 SelectPalette(hdc, screen_pal, FALSE); |
|
1216 if ( RealizePalette(hdc) ) { |
|
1217 InvalidateRect(SDL_Window, NULL, FALSE); |
|
1218 } |
|
1219 ReleaseDC(SDL_Window, hdc); |
|
1220 } |
|
1221 } |
|
1222 static void DIB_PaletteChanged(_THIS, HWND window) |
|
1223 { |
|
1224 if ( window != SDL_Window ) { |
|
1225 DIB_RealizePalette(this); |
|
1226 } |
|
1227 } |
|
1228 |
|
1229 /* Exported for the windows message loop only */ |
|
1230 static void DIB_WinPAINT(_THIS, HDC hdc) |
|
1231 { |
|
1232 HDC mdc; |
|
1233 |
|
1234 if ( screen_pal ) { |
|
1235 SelectPalette(hdc, screen_pal, FALSE); |
|
1236 } |
|
1237 mdc = CreateCompatibleDC(hdc); |
|
1238 SelectObject(mdc, screen_bmp); |
|
1239 BitBlt(hdc, 0, 0, SDL_VideoSurface->w, SDL_VideoSurface->h, |
|
1240 mdc, 0, 0, SRCCOPY); |
|
1241 DeleteDC(mdc); |
|
1242 } |
|
1243 |
|
1244 /* Stub in case DirectX isn't available */ |
|
1245 #if !SDL_AUDIO_DRIVER_DSOUND |
|
1246 void DX5_SoundFocus(HWND hwnd) |
|
1247 { |
|
1248 return; |
|
1249 } |
|
1250 #endif |