src/video/windib/SDL_dibvideo.c
author Ozkan Sezer <sezeroz@gmail.com>
Sat, 14 Sep 2019 17:00:50 +0300
branchSDL-1.2
changeset 13077 cd46eb772bee
parent 12980 32075e9e2135
permissions -rw-r--r--
make SDL_qsort.c to actually link (missing SDL_stdinc.h include)

also sync its comments with version 1.15 from mainstream
     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 	if (!video->pitch) {
   679 		return(NULL);
   680 	}
   681 
   682 	/* Small fix for WinCE/Win32 - when activating window
   683 	   SDL_VideoSurface is equal to zero, so activating code
   684 	   is not called properly for fullscreen windows because
   685 	   macros WINDIB_FULLSCREEN uses SDL_VideoSurface
   686 	*/
   687 	SDL_VideoSurface = video;
   688 
   689 #if defined(_WIN32_WCE)
   690 	if ( flags & SDL_FULLSCREEN )
   691 		video->flags |= SDL_FULLSCREEN;
   692 #endif
   693 
   694 #ifndef NO_CHANGEDISPLAYSETTINGS
   695 	/* Set fullscreen mode if appropriate */
   696 	if ( (flags & SDL_FULLSCREEN) == SDL_FULLSCREEN ) {
   697 		DEVMODE settings;
   698 		BOOL changed;
   699 
   700 		SDL_memset(&settings, 0, sizeof(DEVMODE));
   701 		settings.dmSize = sizeof(DEVMODE);
   702 
   703 #ifdef _WIN32_WCE
   704 		// try to rotate screen to fit requested resolution
   705 		if( this->hidden->supportRotation )
   706 		{
   707 			DWORD rotation;
   708 
   709 			// ask current mode
   710 			settings.dmFields = DM_DISPLAYORIENTATION;
   711 			ChangeDisplaySettingsEx(NULL, &settings, NULL, CDS_TEST, NULL);
   712 			rotation = settings.dmDisplayOrientation;
   713 
   714 			if( (width > GetDeviceCaps(GetDC(NULL), HORZRES))
   715 				&& (height < GetDeviceCaps(GetDC(NULL), VERTRES)))
   716 			{
   717 				switch( rotation )
   718 				{
   719 				case DMDO_0:
   720 					settings.dmDisplayOrientation = DMDO_90;
   721 					break;
   722 				case DMDO_270:
   723 					settings.dmDisplayOrientation = DMDO_180;
   724 					break;
   725 				}
   726 				if( settings.dmDisplayOrientation != rotation )
   727 				{
   728 					// go to landscape
   729 					this->hidden->origRotation = rotation;
   730 					ChangeDisplaySettingsEx(NULL,&settings,NULL,CDS_RESET,NULL);
   731 				}
   732 			}
   733 			if( (width < GetDeviceCaps(GetDC(NULL), HORZRES))
   734 				&& (height > GetDeviceCaps(GetDC(NULL), VERTRES)))
   735 			{
   736 				switch( rotation )
   737 				{
   738 				case DMDO_90:
   739 					settings.dmDisplayOrientation = DMDO_0;
   740 					break;
   741 				case DMDO_180:
   742 					settings.dmDisplayOrientation = DMDO_270;
   743 					break;
   744 				}
   745 				if( settings.dmDisplayOrientation != rotation )
   746 				{
   747 					// go to portrait
   748 					this->hidden->origRotation = rotation;
   749 					ChangeDisplaySettingsEx(NULL,&settings,NULL,CDS_RESET,NULL);
   750 				}
   751 			}
   752 
   753 		}
   754 #endif
   755 
   756 #ifndef _WIN32_WCE
   757 		settings.dmBitsPerPel = video->format->BitsPerPixel;
   758 		settings.dmPelsWidth = width;
   759 		settings.dmPelsHeight = height;
   760 		settings.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL;
   761 		if ( width <= (int)SDL_desktop_mode.dmPelsWidth &&
   762 		     height <= (int)SDL_desktop_mode.dmPelsHeight ) {
   763 			settings.dmDisplayFrequency = SDL_desktop_mode.dmDisplayFrequency;
   764 			settings.dmFields |= DM_DISPLAYFREQUENCY;
   765 		}
   766 		changed = (ChangeDisplaySettings(&settings, CDS_FULLSCREEN) == DISP_CHANGE_SUCCESSFUL);
   767 		if ( ! changed && (settings.dmFields & DM_DISPLAYFREQUENCY) ) {
   768 			settings.dmFields &= ~DM_DISPLAYFREQUENCY;
   769 			changed = (ChangeDisplaySettings(&settings, CDS_FULLSCREEN) == DISP_CHANGE_SUCCESSFUL);
   770 		}
   771 #else
   772 		changed = 1;
   773 #endif
   774 		if ( changed ) {
   775 			video->flags |= SDL_FULLSCREEN;
   776 			SDL_fullscreen_mode = settings;
   777 		}
   778 
   779 	}
   780 #endif /* !NO_CHANGEDISPLAYSETTINGS */
   781 
   782 	/* Reset the palette and create a new one if necessary */
   783 	if ( grab_palette ) {
   784 		DIB_ReleaseStaticColors(SDL_Window);
   785 		grab_palette = FALSE;
   786 	}
   787 	if ( screen_pal != NULL ) {
   788 	/*	RJR: March 28, 2000
   789 		delete identity palette if switching from a palettized mode */
   790 		DeleteObject(screen_pal);
   791 		screen_pal = NULL;
   792 	}
   793 	if ( screen_logpal != NULL ) {
   794 		SDL_free(screen_logpal);
   795 		screen_logpal = NULL;
   796 	}
   797 
   798 	if ( bpp <= 8 )
   799 	{
   800 	/*	RJR: March 28, 2000
   801 		create identity palette switching to a palettized mode */
   802 		DIB_CreatePalette(this, bpp);
   803 	}
   804 
   805 	style = GetWindowLong(SDL_Window, GWL_STYLE);
   806 	style &= ~(resizestyle|WS_MAXIMIZE);
   807 	if ( (video->flags & SDL_FULLSCREEN) == SDL_FULLSCREEN ) {
   808 		style &= ~windowstyle;
   809 		style |= directstyle;
   810 	} else {
   811 #ifndef NO_CHANGEDISPLAYSETTINGS
   812 		if ( (prev_flags & SDL_FULLSCREEN) == SDL_FULLSCREEN ) {
   813 			ChangeDisplaySettings(NULL, CDS_FULLSCREEN);
   814 		}
   815 #endif
   816 		if ( flags & SDL_NOFRAME ) {
   817 			style &= ~windowstyle;
   818 			style |= directstyle;
   819 			video->flags |= SDL_NOFRAME;
   820 		} else {
   821 			style &= ~directstyle;
   822 			style |= windowstyle;
   823 			if ( flags & SDL_RESIZABLE ) {
   824 				style |= resizestyle;
   825 				video->flags |= SDL_RESIZABLE;
   826 			}
   827 		}
   828 #if WS_MAXIMIZE && !defined(_WIN32_WCE)
   829 		if (IsZoomed(SDL_Window)) style |= WS_MAXIMIZE;
   830 #endif
   831 	}
   832 
   833 	/* DJM: Don't piss of anyone who has setup his own window */
   834 	if ( !SDL_windowid )
   835 		SetWindowLong(SDL_Window, GWL_STYLE, style);
   836 
   837 	/* Delete the old bitmap if necessary */
   838 	if ( screen_bmp != NULL ) {
   839 		DeleteObject(screen_bmp);
   840 	}
   841 	if ( ! (flags & SDL_OPENGL) ) {
   842 		BOOL is16bitmode = (video->format->BytesPerPixel == 2);
   843 
   844 		/* Suss out the bitmap info header */
   845 		binfo_size = sizeof(*binfo);
   846 		if( is16bitmode ) {
   847 			/* 16bit modes, palette area used for rgb bitmasks */
   848 			binfo_size += 3*sizeof(DWORD);
   849 		} else if ( video->format->palette ) {
   850 			binfo_size += video->format->palette->ncolors *
   851 							sizeof(RGBQUAD);
   852 		}
   853 		binfo = (BITMAPINFO *)SDL_malloc(binfo_size);
   854 		if ( ! binfo ) {
   855 			if ( video != current ) {
   856 				SDL_FreeSurface(video);
   857 			}
   858 			SDL_OutOfMemory();
   859 			return(NULL);
   860 		}
   861 
   862 		binfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
   863 		binfo->bmiHeader.biWidth = video->w;
   864 		binfo->bmiHeader.biHeight = -video->h;	/* -ve for topdown bitmap */
   865 		binfo->bmiHeader.biPlanes = 1;
   866 		binfo->bmiHeader.biSizeImage = video->h * video->pitch;
   867 		binfo->bmiHeader.biXPelsPerMeter = 0;
   868 		binfo->bmiHeader.biYPelsPerMeter = 0;
   869 		binfo->bmiHeader.biClrUsed = 0;
   870 		binfo->bmiHeader.biClrImportant = 0;
   871 		binfo->bmiHeader.biBitCount = video->format->BitsPerPixel;
   872 
   873 		if ( is16bitmode ) {
   874 			/* BI_BITFIELDS tells CreateDIBSection about the rgb masks in the palette */
   875 			binfo->bmiHeader.biCompression = BI_BITFIELDS;
   876 			((Uint32*)binfo->bmiColors)[0] = video->format->Rmask;
   877 			((Uint32*)binfo->bmiColors)[1] = video->format->Gmask;
   878 			((Uint32*)binfo->bmiColors)[2] = video->format->Bmask;
   879 		} else {
   880 			binfo->bmiHeader.biCompression = BI_RGB;	/* BI_BITFIELDS for 565 vs 555 */
   881 			if ( video->format->palette ) {
   882 				SDL_memset(binfo->bmiColors, 0,
   883 					video->format->palette->ncolors*sizeof(RGBQUAD));
   884 			}
   885 		}
   886 
   887 		/* Create the offscreen bitmap buffer */
   888 		hdc = GetDC(SDL_Window);
   889 		screen_bmp = CreateDIBSection(hdc, binfo, DIB_RGB_COLORS,
   890 					(void **)(&video->pixels), NULL, 0);
   891 		ReleaseDC(SDL_Window, hdc);
   892 		SDL_free(binfo);
   893 		if ( screen_bmp == NULL ) {
   894 			if ( video != current ) {
   895 				SDL_FreeSurface(video);
   896 			}
   897 			SDL_SetError("Couldn't create DIB section");
   898 			return(NULL);
   899 		}
   900 		this->UpdateRects = DIB_NormalUpdate;
   901 
   902 		/* Set video surface flags */
   903 		if ( screen_pal && (flags & (SDL_FULLSCREEN|SDL_HWPALETTE)) ) {
   904 			grab_palette = TRUE;
   905 		}
   906 		if ( screen_pal ) {
   907 			/* BitBlt() maps colors for us */
   908 			video->flags |= SDL_HWPALETTE;
   909 		}
   910 	}
   911 	DIB_ResizeWindow(this, width, height, prev_w, prev_h, flags);
   912 	SDL_resizing = 0;
   913 
   914 	/* Set up for OpenGL */
   915 	if ( flags & SDL_OPENGL ) {
   916 		if ( WIN_GL_SetupWindow(this) < 0 ) {
   917 			return(NULL);
   918 		}
   919 		video->flags |= SDL_OPENGL;
   920 	}
   921 
   922 	/* JC 14 Mar 2006
   923 		Flush the message loop or this can cause big problems later
   924 		Especially if the user decides to use dialog boxes or assert()!
   925 	*/
   926 	WIN_FlushMessageQueue();
   927 
   928 	/* We're live! */
   929 	return(video);
   930 }
   931 
   932 /* We don't actually allow hardware surfaces in the DIB driver */
   933 static int DIB_AllocHWSurface(_THIS, SDL_Surface *surface)
   934 {
   935 	return(-1);
   936 }
   937 static void DIB_FreeHWSurface(_THIS, SDL_Surface *surface)
   938 {
   939 	return;
   940 }
   941 static int DIB_LockHWSurface(_THIS, SDL_Surface *surface)
   942 {
   943 	return(0);
   944 }
   945 static void DIB_UnlockHWSurface(_THIS, SDL_Surface *surface)
   946 {
   947 	return;
   948 }
   949 
   950 static void DIB_NormalUpdate(_THIS, int numrects, SDL_Rect *rects)
   951 {
   952 	HDC hdc, mdc;
   953 	int i;
   954 
   955 	hdc = GetDC(SDL_Window);
   956 	if ( screen_pal ) {
   957 		SelectPalette(hdc, screen_pal, FALSE);
   958 	}
   959 	mdc = CreateCompatibleDC(hdc);
   960 	SelectObject(mdc, screen_bmp);
   961 	for ( i=0; i<numrects; ++i ) {
   962 		BitBlt(hdc, rects[i].x, rects[i].y, rects[i].w, rects[i].h,
   963 					mdc, rects[i].x, rects[i].y, SRCCOPY);
   964 	}
   965 	DeleteDC(mdc);
   966 	ReleaseDC(SDL_Window, hdc);
   967 }
   968 
   969 static int FindPaletteIndex(LOGPALETTE *pal, BYTE r, BYTE g, BYTE b)
   970 {
   971 	PALETTEENTRY *entry;
   972 	int i;
   973 	int nentries = pal->palNumEntries;
   974 
   975 	for ( i = 0; i < nentries; ++i ) {
   976 		entry = &pal->palPalEntry[i];
   977 		if ( entry->peRed == r && entry->peGreen == g && entry->peBlue == b ) {
   978 			return i;
   979 		}
   980 	}
   981 	return -1;
   982 }
   983 
   984 static BOOL CheckPaletteEntry(LOGPALETTE *pal, int index, BYTE r, BYTE g, BYTE b)
   985 {
   986 	PALETTEENTRY *entry;
   987 	BOOL moved = 0;
   988 
   989 	entry = &pal->palPalEntry[index];
   990 	if ( entry->peRed != r || entry->peGreen != g || entry->peBlue != b ) {
   991 		int found = FindPaletteIndex(pal, r, g, b);
   992 		if ( found >= 0 ) {
   993 			pal->palPalEntry[found] = *entry;
   994 		}
   995 		entry->peRed = r;
   996 		entry->peGreen = g;
   997 		entry->peBlue = b;
   998 		moved = 1;
   999 	}
  1000 	entry->peFlags = 0;
  1001 
  1002 	return moved;
  1003 }
  1004 
  1005 int DIB_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors)
  1006 {
  1007 #if !defined(_WIN32_WCE) || (_WIN32_WCE >= 400)
  1008 	HDC hdc, mdc;
  1009 	RGBQUAD *pal;
  1010 #else
  1011 	HDC hdc;
  1012 #endif
  1013 	int i;
  1014 	int moved_entries = 0;
  1015 
  1016 	/* Update the display palette */
  1017 	hdc = GetDC(SDL_Window);
  1018 	if ( screen_pal ) {
  1019 		PALETTEENTRY *entry;
  1020 
  1021 		for ( i=0; i<ncolors; ++i ) {
  1022 			entry = &screen_logpal->palPalEntry[firstcolor+i];
  1023 			entry->peRed   = colors[i].r;
  1024 			entry->peGreen = colors[i].g;
  1025 			entry->peBlue  = colors[i].b;
  1026 			entry->peFlags = PC_NOCOLLAPSE;
  1027 		}
  1028 #if defined(SYSPAL_NOSTATIC) && !defined(_WIN32_WCE)
  1029 		/* Check to make sure black and white are in position */
  1030 		if ( GetSystemPaletteUse(hdc) != SYSPAL_NOSTATIC256 ) {
  1031 			moved_entries += CheckPaletteEntry(screen_logpal, 0, 0x00, 0x00, 0x00);
  1032 			moved_entries += CheckPaletteEntry(screen_logpal, screen_logpal->palNumEntries-1, 0xff, 0xff, 0xff);
  1033 		}
  1034 		/* FIXME:
  1035 		   If we don't have full access to the palette, what we
  1036 		   really want to do is find the 236 most diverse colors
  1037 		   in the desired palette, set those entries (10-245) and
  1038 		   then map everything into the new system palette.
  1039 		 */
  1040 #endif
  1041 
  1042 #ifndef _WIN32_WCE
  1043 		/* Copy the entries into the system palette */
  1044 		UnrealizeObject(screen_pal);
  1045 #endif
  1046 		SetPaletteEntries(screen_pal, 0, screen_logpal->palNumEntries, screen_logpal->palPalEntry);
  1047 		SelectPalette(hdc, screen_pal, FALSE);
  1048 		RealizePalette(hdc);
  1049 	}
  1050 
  1051 #if !defined(_WIN32_WCE) || (_WIN32_WCE >= 400)
  1052 	/* Copy palette colors into DIB palette */
  1053 	pal = SDL_stack_alloc(RGBQUAD, ncolors);
  1054 	for ( i=0; i<ncolors; ++i ) {
  1055 		pal[i].rgbRed = colors[i].r;
  1056 		pal[i].rgbGreen = colors[i].g;
  1057 		pal[i].rgbBlue = colors[i].b;
  1058 		pal[i].rgbReserved = 0;
  1059 	}
  1060 
  1061 	/* Set the DIB palette and update the display */
  1062 	mdc = CreateCompatibleDC(hdc);
  1063 	SelectObject(mdc, screen_bmp);
  1064 	SetDIBColorTable(mdc, firstcolor, ncolors, pal);
  1065 	if ( moved_entries || !grab_palette ) {
  1066 		BitBlt(hdc, 0, 0, this->screen->w, this->screen->h,
  1067 		       mdc, 0, 0, SRCCOPY);
  1068 	}
  1069 	DeleteDC(mdc);
  1070 	SDL_stack_free(pal);
  1071 #endif
  1072 	ReleaseDC(SDL_Window, hdc);
  1073 	return(1);
  1074 }
  1075 
  1076 
  1077 static void DIB_CheckGamma(_THIS)
  1078 {
  1079 #ifndef NO_GAMMA_SUPPORT
  1080 	HDC hdc;
  1081 	WORD ramp[3*256];
  1082 
  1083 	/* If we fail to get gamma, disable gamma control */
  1084 	hdc = GetDC(SDL_Window);
  1085 	if ( ! GetDeviceGammaRamp(hdc, ramp) ) {
  1086 		this->GetGammaRamp = NULL;
  1087 		this->SetGammaRamp = NULL;
  1088 	}
  1089 	ReleaseDC(SDL_Window, hdc);
  1090 #endif /* !NO_GAMMA_SUPPORT */
  1091 }
  1092 void DIB_SwapGamma(_THIS)
  1093 {
  1094 #ifndef NO_GAMMA_SUPPORT
  1095 	HDC hdc;
  1096 
  1097 	if ( gamma_saved ) {
  1098 		hdc = GetDC(SDL_Window);
  1099 		if ( SDL_GetAppState() & SDL_APPINPUTFOCUS ) {
  1100 			/* About to leave active state, restore gamma */
  1101 			SetDeviceGammaRamp(hdc, gamma_saved);
  1102 		} else {
  1103 			/* About to enter active state, set game gamma */
  1104 			GetDeviceGammaRamp(hdc, gamma_saved);
  1105 			SetDeviceGammaRamp(hdc, this->gamma);
  1106 		}
  1107 		ReleaseDC(SDL_Window, hdc);
  1108 	}
  1109 #endif /* !NO_GAMMA_SUPPORT */
  1110 }
  1111 void DIB_QuitGamma(_THIS)
  1112 {
  1113 #ifndef NO_GAMMA_SUPPORT
  1114 	if ( gamma_saved ) {
  1115 		/* Restore the original gamma if necessary */
  1116 		if ( SDL_GetAppState() & SDL_APPINPUTFOCUS ) {
  1117 			HDC hdc;
  1118 
  1119 			hdc = GetDC(SDL_Window);
  1120 			SetDeviceGammaRamp(hdc, gamma_saved);
  1121 			ReleaseDC(SDL_Window, hdc);
  1122 		}
  1123 
  1124 		/* Free the saved gamma memory */
  1125 		SDL_free(gamma_saved);
  1126 		gamma_saved = 0;
  1127 	}
  1128 #endif /* !NO_GAMMA_SUPPORT */
  1129 }
  1130 
  1131 int DIB_SetGammaRamp(_THIS, Uint16 *ramp)
  1132 {
  1133 #ifdef NO_GAMMA_SUPPORT
  1134 	SDL_SetError("SDL compiled without gamma ramp support");
  1135 	return -1;
  1136 #else
  1137 	HDC hdc;
  1138 	BOOL succeeded;
  1139 
  1140 	/* Set the ramp for the display */
  1141 	if ( ! gamma_saved ) {
  1142 		gamma_saved = (WORD *)SDL_malloc(3*256*sizeof(*gamma_saved));
  1143 		if ( ! gamma_saved ) {
  1144 			SDL_OutOfMemory();
  1145 			return -1;
  1146 		}
  1147 		hdc = GetDC(SDL_Window);
  1148 		GetDeviceGammaRamp(hdc, gamma_saved);
  1149 		ReleaseDC(SDL_Window, hdc);
  1150 	}
  1151 	if ( SDL_GetAppState() & SDL_APPINPUTFOCUS ) {
  1152 		hdc = GetDC(SDL_Window);
  1153 		succeeded = SetDeviceGammaRamp(hdc, ramp);
  1154 		ReleaseDC(SDL_Window, hdc);
  1155 	} else {
  1156 		succeeded = TRUE;
  1157 	}
  1158 	return succeeded ? 0 : -1;
  1159 #endif /* !NO_GAMMA_SUPPORT */
  1160 }
  1161 
  1162 int DIB_GetGammaRamp(_THIS, Uint16 *ramp)
  1163 {
  1164 #ifdef NO_GAMMA_SUPPORT
  1165 	SDL_SetError("SDL compiled without gamma ramp support");
  1166 	return -1;
  1167 #else
  1168 	HDC hdc;
  1169 	BOOL succeeded;
  1170 
  1171 	/* Get the ramp from the display */
  1172 	hdc = GetDC(SDL_Window);
  1173 	succeeded = GetDeviceGammaRamp(hdc, ramp);
  1174 	ReleaseDC(SDL_Window, hdc);
  1175 	return succeeded ? 0 : -1;
  1176 #endif /* !NO_GAMMA_SUPPORT */
  1177 }
  1178 
  1179 void DIB_VideoQuit(_THIS)
  1180 {
  1181 	int i, j;
  1182 
  1183 	/* Destroy the window and everything associated with it */
  1184 	if ( SDL_Window ) {
  1185 		/* Delete the screen bitmap (also frees screen->pixels) */
  1186 		if ( this->screen ) {
  1187 			if ( grab_palette ) {
  1188 				DIB_ReleaseStaticColors(SDL_Window);
  1189 			}
  1190 #ifndef NO_CHANGEDISPLAYSETTINGS
  1191 			if ( this->screen->flags & SDL_FULLSCREEN ) {
  1192 				ChangeDisplaySettings(NULL, CDS_FULLSCREEN);
  1193 				ShowWindow(SDL_Window, SW_HIDE);
  1194 			}
  1195 #endif
  1196 			if ( this->screen->flags & SDL_OPENGL ) {
  1197 				WIN_GL_ShutDown(this);
  1198 			}
  1199 			this->screen->pixels = NULL;
  1200 		}
  1201 		if ( screen_pal != NULL ) {
  1202 			DeleteObject(screen_pal);
  1203 			screen_pal = NULL;
  1204 		}
  1205 		if ( screen_logpal != NULL ) {
  1206 			SDL_free(screen_logpal);
  1207 			screen_logpal = NULL;
  1208 		}
  1209 		if ( screen_bmp ) {
  1210 			DeleteObject(screen_bmp);
  1211 			screen_bmp = NULL;
  1212 		}
  1213 		if ( screen_icn ) {
  1214 			DestroyIcon(screen_icn);
  1215 			screen_icn = NULL;
  1216 		}
  1217 		DIB_QuitGamma(this);
  1218 		DIB_DestroyWindow(this);
  1219 
  1220 		SDL_Window = NULL;
  1221 
  1222 #if defined(_WIN32_WCE)
  1223 
  1224 // Unload wince aygshell library to prevent leak
  1225 		if( aygshell ) 
  1226 		{
  1227 			FreeLibrary(aygshell);
  1228 			aygshell = NULL;
  1229 		}
  1230 #endif
  1231 	}
  1232 
  1233 	for ( i=0; i < SDL_arraysize(SDL_modelist); ++i ) {
  1234 		if ( !SDL_modelist[i] ) {
  1235 			continue;
  1236 		}
  1237 		for ( j=0; SDL_modelist[i][j]; ++j ) {
  1238 			SDL_free(SDL_modelist[i][j]);
  1239 		}
  1240 		SDL_free(SDL_modelist[i]);
  1241 		SDL_modelist[i] = NULL;
  1242 		SDL_nummodes[i] = 0;
  1243 	}
  1244 }
  1245 
  1246 /* Exported for the windows message loop only */
  1247 static void DIB_GrabStaticColors(HWND window)
  1248 {
  1249 #if defined(SYSPAL_NOSTATIC) && !defined(_WIN32_WCE)
  1250 	HDC hdc;
  1251 
  1252 	hdc = GetDC(window);
  1253 	SetSystemPaletteUse(hdc, SYSPAL_NOSTATIC256);
  1254 	if ( GetSystemPaletteUse(hdc) != SYSPAL_NOSTATIC256 ) {
  1255 		SetSystemPaletteUse(hdc, SYSPAL_NOSTATIC);
  1256 	}
  1257 	ReleaseDC(window, hdc);
  1258 #endif
  1259 }
  1260 static void DIB_ReleaseStaticColors(HWND window)
  1261 {
  1262 #if defined(SYSPAL_NOSTATIC) && !defined(_WIN32_WCE)
  1263 	HDC hdc;
  1264 
  1265 	hdc = GetDC(window);
  1266 	SetSystemPaletteUse(hdc, SYSPAL_STATIC);
  1267 	ReleaseDC(window, hdc);
  1268 #endif
  1269 }
  1270 static void DIB_Activate(_THIS, BOOL active, BOOL minimized)
  1271 {
  1272 	if ( grab_palette ) {
  1273 		if ( !active ) {
  1274 			DIB_ReleaseStaticColors(SDL_Window);
  1275 			DIB_RealizePalette(this);
  1276 		} else if ( !minimized ) {
  1277 			DIB_GrabStaticColors(SDL_Window);
  1278 			DIB_RealizePalette(this);
  1279 		}
  1280 	}
  1281 }
  1282 static void DIB_RealizePalette(_THIS)
  1283 {
  1284 	if ( screen_pal != NULL ) {
  1285 		HDC hdc;
  1286 
  1287 		hdc = GetDC(SDL_Window);
  1288 #ifndef _WIN32_WCE
  1289 		UnrealizeObject(screen_pal);
  1290 #endif
  1291 		SelectPalette(hdc, screen_pal, FALSE);
  1292 		if ( RealizePalette(hdc) ) {
  1293 			InvalidateRect(SDL_Window, NULL, FALSE);
  1294 		}
  1295 		ReleaseDC(SDL_Window, hdc);
  1296 	}
  1297 }
  1298 static void DIB_PaletteChanged(_THIS, HWND window)
  1299 {
  1300 	if ( window != SDL_Window ) {
  1301 		DIB_RealizePalette(this);
  1302 	}
  1303 }
  1304 
  1305 /* Exported for the windows message loop only */
  1306 static void DIB_WinPAINT(_THIS, HDC hdc)
  1307 {
  1308 	HDC mdc;
  1309 
  1310 	if ( screen_pal ) {
  1311 		SelectPalette(hdc, screen_pal, FALSE);
  1312 	}
  1313 	mdc = CreateCompatibleDC(hdc);
  1314 	SelectObject(mdc, screen_bmp);
  1315 	BitBlt(hdc, 0, 0, SDL_VideoSurface->w, SDL_VideoSurface->h,
  1316 							mdc, 0, 0, SRCCOPY);
  1317 	DeleteDC(mdc);
  1318 }
  1319 
  1320 /* Stub in case DirectX isn't available */
  1321 #if !SDL_AUDIO_DRIVER_DSOUND
  1322 void DX5_SoundFocus(HWND hwnd)
  1323 {
  1324 	return;
  1325 }
  1326 #endif