]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/libsdl/contrib/src/video/windib/SDL_dibvideo.c
update
[l4.git] / l4 / pkg / libsdl / contrib / src / video / windib / SDL_dibvideo.c
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