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