/*
    SDL - Simple DirectMedia Layer
    Copyright (C) 1997-2006 Sam Lantinga

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2.1 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA

    Sam Lantinga
    slouken@libsdl.org
*/
#include "SDL_config.h"

#define WIN32_LEAN_AND_MEAN
#include <windows.h>

/* Not yet in the mingw32 cross-compile headers */
#ifndef CDS_FULLSCREEN
#define CDS_FULLSCREEN	4
#endif

#include "SDL_syswm.h"
#include "../SDL_sysvideo.h"
#include "../SDL_pixels_c.h"
#include "../../events/SDL_sysevents.h"
#include "../../events/SDL_events_c.h"
#include "SDL_dibvideo.h"
#include "../wincommon/SDL_syswm_c.h"
#include "../wincommon/SDL_sysmouse_c.h"
#include "SDL_dibevents_c.h"
#include "../wincommon/SDL_wingl_c.h"

#ifdef _WIN32_WCE
#define NO_GETDIBITS
#define NO_GAMMA_SUPPORT
  #if _WIN32_WCE < 420
    #define NO_CHANGEDISPLAYSETTINGS
  #else
    #define ChangeDisplaySettings(lpDevMode, dwFlags) ChangeDisplaySettingsEx(NULL, (lpDevMode), 0, (dwFlags), 0)
  #endif
#endif
#ifndef WS_MAXIMIZE
#define WS_MAXIMIZE	0
#endif
#ifndef WS_THICKFRAME
#define WS_THICKFRAME	0
#endif
#ifndef SWP_NOCOPYBITS
#define SWP_NOCOPYBITS	0
#endif
#ifndef PC_NOCOLLAPSE
#define PC_NOCOLLAPSE	0
#endif

#ifdef _WIN32_WCE
// defined and used in SDL_sysevents.c
extern HINSTANCE aygshell;
#endif

/* Initialization/Query functions */
static int DIB_VideoInit(_THIS, SDL_PixelFormat *vformat);
static SDL_Rect **DIB_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags);
SDL_Surface *DIB_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags);
static int DIB_SetColors(_THIS, int firstcolor, int ncolors,
			 SDL_Color *colors);
static void DIB_CheckGamma(_THIS);
void DIB_SwapGamma(_THIS);
void DIB_QuitGamma(_THIS);
int DIB_SetGammaRamp(_THIS, Uint16 *ramp);
int DIB_GetGammaRamp(_THIS, Uint16 *ramp);
static void DIB_VideoQuit(_THIS);

/* Hardware surface functions */
static int DIB_AllocHWSurface(_THIS, SDL_Surface *surface);
static int DIB_LockHWSurface(_THIS, SDL_Surface *surface);
static void DIB_UnlockHWSurface(_THIS, SDL_Surface *surface);
static void DIB_FreeHWSurface(_THIS, SDL_Surface *surface);

/* Windows message handling functions */
static void DIB_GrabStaticColors(HWND window);
static void DIB_ReleaseStaticColors(HWND window);
static void DIB_Activate(_THIS, BOOL active, BOOL minimized);
static void DIB_RealizePalette(_THIS);
static void DIB_PaletteChanged(_THIS, HWND window);
static void DIB_WinPAINT(_THIS, HDC hdc);

static void DIB_GetWinPos(_THIS, int* px, int *py);
static void DIB_SetWinPos(_THIS, int  x, int  y);
static int  DIB_IsWinVisible(_THIS, int recenter);
static int  DIB_GetMonitorDPI(_THIS, int* xDpi, int *yDpi);
static int  DIB_GetMonitorRect(_THIS, SDL_Rect*  rect);

/* helper fn */
static int DIB_SussScreenDepth();

/* DIB driver bootstrap functions */

static int DIB_Available(void)
{
	return(1);
}

static void DIB_DeleteDevice(SDL_VideoDevice *device)
{
	if ( device ) {
		if ( device->hidden ) {
			SDL_free(device->hidden);
		}
		if ( device->gl_data ) {
			SDL_free(device->gl_data);
		}
		SDL_free(device);
	}
}

static SDL_VideoDevice *DIB_CreateDevice(int devindex)
{
	SDL_VideoDevice *device;

	/* Initialize all variables that we clean on shutdown */
	device = (SDL_VideoDevice *)SDL_malloc(sizeof(SDL_VideoDevice));
	if ( device ) {
		SDL_memset(device, 0, (sizeof *device));
		device->hidden = (struct SDL_PrivateVideoData *)
				SDL_malloc((sizeof *device->hidden));
		device->gl_data = (struct SDL_PrivateGLData *)
				SDL_malloc((sizeof *device->gl_data));
	}
	if ( (device == NULL) || (device->hidden == NULL) ||
		                 (device->gl_data == NULL) ) {
		SDL_OutOfMemory();
		DIB_DeleteDevice(device);
		return(NULL);
	}
	SDL_memset(device->hidden, 0, (sizeof *device->hidden));
	SDL_memset(device->gl_data, 0, (sizeof *device->gl_data));

	/* Set the function pointers */
	device->VideoInit = DIB_VideoInit;
	device->ListModes = DIB_ListModes;
	device->SetVideoMode = DIB_SetVideoMode;
	device->UpdateMouse = WIN_UpdateMouse;
	device->SetColors = DIB_SetColors;
	device->UpdateRects = NULL;
	device->VideoQuit = DIB_VideoQuit;
	device->AllocHWSurface = DIB_AllocHWSurface;
	device->CheckHWBlit = NULL;
	device->FillHWRect = NULL;
	device->SetHWColorKey = NULL;
	device->SetHWAlpha = NULL;
	device->LockHWSurface = DIB_LockHWSurface;
	device->UnlockHWSurface = DIB_UnlockHWSurface;
	device->FlipHWSurface = NULL;
	device->FreeHWSurface = DIB_FreeHWSurface;
	device->SetGammaRamp = DIB_SetGammaRamp;
	device->GetGammaRamp = DIB_GetGammaRamp;
#if SDL_VIDEO_OPENGL
	device->GL_LoadLibrary = WIN_GL_LoadLibrary;
	device->GL_GetProcAddress = WIN_GL_GetProcAddress;
	device->GL_GetAttribute = WIN_GL_GetAttribute;
	device->GL_MakeCurrent = WIN_GL_MakeCurrent;
	device->GL_SwapBuffers = WIN_GL_SwapBuffers;
#endif
	device->SetCaption = WIN_SetWMCaption;
	device->SetIcon = WIN_SetWMIcon;
	device->IconifyWindow = WIN_IconifyWindow;
	device->GrabInput = WIN_GrabInput;
	device->GetWMInfo = WIN_GetWMInfo;
	device->FreeWMCursor = WIN_FreeWMCursor;
	device->CreateWMCursor = WIN_CreateWMCursor;
	device->ShowWMCursor = WIN_ShowWMCursor;
	device->WarpWMCursor = WIN_WarpWMCursor;
	device->CheckMouseMode = WIN_CheckMouseMode;
	device->InitOSKeymap = DIB_InitOSKeymap;
	device->PumpEvents = DIB_PumpEvents;

    device->GetWindowPos = DIB_GetWinPos;
    device->SetWindowPos = DIB_SetWinPos;
    device->IsWindowVisible = DIB_IsWinVisible;
    device->GetMonitorDPI = DIB_GetMonitorDPI;
    device->GetMonitorRect = DIB_GetMonitorRect;

	/* Set up the windows message handling functions */
	WIN_Activate = DIB_Activate;
	WIN_RealizePalette = DIB_RealizePalette;
	WIN_PaletteChanged = DIB_PaletteChanged;
	WIN_WinPAINT = DIB_WinPAINT;
	HandleMessage = DIB_HandleMessage;

	device->free = DIB_DeleteDevice;

	/* We're finally ready */
	return device;
}

VideoBootStrap WINDIB_bootstrap = {
	"windib", "Win95/98/NT/2000/CE GDI",
	DIB_Available, DIB_CreateDevice
};

static int cmpmodes(const void *va, const void *vb)
{
    SDL_Rect *a = *(SDL_Rect **)va;
    SDL_Rect *b = *(SDL_Rect **)vb;
    if ( a->w == b->w )
        return b->h - a->h;
    else
        return b->w - a->w;
}

static int DIB_AddMode(_THIS, int bpp, int w, int h)
{
	SDL_Rect *mode;
	int i, index;
	int next_mode;

	/* Check to see if we already have this mode */
	if ( bpp < 8 ) {  /* Not supported */
		return(0);
	}
	index = ((bpp+7)/8)-1;
	for ( i=0; i<SDL_nummodes[index]; ++i ) {
		mode = SDL_modelist[index][i];
		if ( (mode->w == w) && (mode->h == h) ) {
			return(0);
		}
	}

	/* Set up the new video mode rectangle */
	mode = (SDL_Rect *)SDL_malloc(sizeof *mode);
	if ( mode == NULL ) {
		SDL_OutOfMemory();
		return(-1);
	}
	mode->x = 0;
	mode->y = 0;
	mode->w = w;
	mode->h = h;

	/* Allocate the new list of modes, and fill in the new mode */
	next_mode = SDL_nummodes[index];
	SDL_modelist[index] = (SDL_Rect **)
	       SDL_realloc(SDL_modelist[index], (1+next_mode+1)*sizeof(SDL_Rect *));
	if ( SDL_modelist[index] == NULL ) {
		SDL_OutOfMemory();
		SDL_nummodes[index] = 0;
		SDL_free(mode);
		return(-1);
	}
	SDL_modelist[index][next_mode] = mode;
	SDL_modelist[index][next_mode+1] = NULL;
	SDL_nummodes[index]++;

	return(0);
}

static void DIB_CreatePalette(_THIS, int bpp)
{
/*	RJR: March 28, 2000
	moved palette creation here from "DIB_VideoInit" */

	LOGPALETTE *palette;
	HDC hdc;
	int ncolors;

	ncolors = (1 << bpp);
	palette = (LOGPALETTE *)SDL_malloc(sizeof(*palette)+
				ncolors*sizeof(PALETTEENTRY));
	palette->palVersion = 0x300;
	palette->palNumEntries = ncolors;
	hdc = GetDC(SDL_Window);
	GetSystemPaletteEntries(hdc, 0, ncolors, palette->palPalEntry);
	ReleaseDC(SDL_Window, hdc);
	screen_pal = CreatePalette(palette);
	screen_logpal = palette;
}

int DIB_VideoInit(_THIS, SDL_PixelFormat *vformat)
{
	const char *env = NULL;
#ifndef NO_CHANGEDISPLAYSETTINGS
	int i;
	DEVMODE settings;
#endif

	/* Create the window */
	if ( DIB_CreateWindow(this) < 0 ) {
		return(-1);
	}

#if !SDL_AUDIO_DISABLED
	DX5_SoundFocus(SDL_Window);
#endif

	/* Determine the screen depth */
	vformat->BitsPerPixel = DIB_SussScreenDepth();
	switch (vformat->BitsPerPixel) {
		case 15:
			vformat->Rmask = 0x00007c00;
			vformat->Gmask = 0x000003e0;
			vformat->Bmask = 0x0000001f;
			vformat->BitsPerPixel = 16;
			break;
		case 16:
			vformat->Rmask = 0x0000f800;
			vformat->Gmask = 0x000007e0;
			vformat->Bmask = 0x0000001f;
			break;
		case 24:
		case 32:
			/* GDI defined as 8-8-8 */
			vformat->Rmask = 0x00ff0000;
			vformat->Gmask = 0x0000ff00;
			vformat->Bmask = 0x000000ff;
			break;
		default:
			break;
	}

	/* See if gamma is supported on this screen */
	DIB_CheckGamma(this);

#ifndef NO_CHANGEDISPLAYSETTINGS

	settings.dmSize = sizeof(DEVMODE);
	settings.dmDriverExtra = 0;
#ifdef _WIN32_WCE
	settings.dmFields = DM_DISPLAYQUERYORIENTATION;
	this->hidden->supportRotation = ChangeDisplaySettingsEx(NULL, &settings, NULL, CDS_TEST, NULL) == DISP_CHANGE_SUCCESSFUL;
#endif
	/* Query for the desktop resolution */
	EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &SDL_desktop_mode);
	this->info.current_w = SDL_desktop_mode.dmPelsWidth;
	this->info.current_h = SDL_desktop_mode.dmPelsHeight;

	/* Query for the list of available video modes */
	for ( i=0; EnumDisplaySettings(NULL, i, &settings); ++i ) {
		DIB_AddMode(this, settings.dmBitsPerPel,
			settings.dmPelsWidth, settings.dmPelsHeight);
#ifdef _WIN32_WCE
		if( this->hidden->supportRotation )
			DIB_AddMode(this, settings.dmBitsPerPel,
				settings.dmPelsHeight, settings.dmPelsWidth);
#endif
	}
	/* Sort the mode lists */
	for ( i=0; i<NUM_MODELISTS; ++i ) {
		if ( SDL_nummodes[i] > 0 ) {
			SDL_qsort(SDL_modelist[i], SDL_nummodes[i], sizeof *SDL_modelist[i], cmpmodes);
		}
	}
#else
	// WinCE and fullscreen mode:
	// We use only vformat->BitsPerPixel that allow SDL to
	// emulate other bpp (8, 32) and use triple buffer,
	// because SDL surface conversion is much faster than the WinCE one.
	// Although it should be tested on devices with graphics accelerator.

	DIB_AddMode(this, vformat->BitsPerPixel,
			GetDeviceCaps(GetDC(NULL), HORZRES),
			GetDeviceCaps(GetDC(NULL), VERTRES));

#endif /* !NO_CHANGEDISPLAYSETTINGS */

	/* Grab an identity palette if we are in a palettized mode */
	if ( vformat->BitsPerPixel <= 8 ) {
	/*	RJR: March 28, 2000
		moved palette creation to "DIB_CreatePalette" */
		DIB_CreatePalette(this, vformat->BitsPerPixel);
	}

	/* Fill in some window manager capabilities */
	this->info.wm_available = 1;

#ifdef _WIN32_WCE
	this->hidden->origRotation = -1;
#endif

	/* Allow environment override of screensaver disable. */
	env = SDL_getenv("SDL_VIDEO_ALLOW_SCREENSAVER");
	this->hidden->allow_screensaver = ( (env && SDL_atoi(env)) ? 1 : 0 );

	/* We're done! */
	return(0);
}

/* We support any format at any dimension */
SDL_Rect **DIB_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags)
{
	if ( (flags & SDL_FULLSCREEN) == SDL_FULLSCREEN ) {
		return(SDL_modelist[((format->BitsPerPixel+7)/8)-1]);
	} else {
		return((SDL_Rect **)-1);
	}
}


/*
  Helper fn to work out which screen depth windows is currently using.
  15 bit mode is considered 555 format, 16 bit is 565.
  returns 0 for unknown mode.
  (Derived from code in sept 1999 Windows Developer Journal
  http://www.wdj.com/code/archive.html)
*/
static int DIB_SussScreenDepth()
{
#ifdef NO_GETDIBITS
	int depth;
	HDC hdc;

	hdc = GetDC(SDL_Window);
	depth = GetDeviceCaps(hdc, PLANES) * GetDeviceCaps(hdc, BITSPIXEL);
	ReleaseDC(SDL_Window, hdc);
	return(depth);
#else
    int depth;
    int dib_size;
    LPBITMAPINFOHEADER dib_hdr;
    HDC hdc;
    HBITMAP hbm;

    /* Allocate enough space for a DIB header plus palette (for
     * 8-bit modes) or bitfields (for 16- and 32-bit modes)
     */
    dib_size = sizeof(BITMAPINFOHEADER) + 256 * sizeof (RGBQUAD);
    dib_hdr = (LPBITMAPINFOHEADER) SDL_malloc(dib_size);
    SDL_memset(dib_hdr, 0, dib_size);
    dib_hdr->biSize = sizeof(BITMAPINFOHEADER);

    /* Get a device-dependent bitmap that's compatible with the
       screen.
     */
    hdc = GetDC(NULL);
    hbm = CreateCompatibleBitmap( hdc, 1, 1 );

    /* Convert the DDB to a DIB.  We need to call GetDIBits twice:
     * the first call just fills in the BITMAPINFOHEADER; the
     * second fills in the bitfields or palette.
     */
    GetDIBits(hdc, hbm, 0, 1, NULL, (LPBITMAPINFO) dib_hdr, DIB_RGB_COLORS);
    GetDIBits(hdc, hbm, 0, 1, NULL, (LPBITMAPINFO) dib_hdr, DIB_RGB_COLORS);
    DeleteObject(hbm);
    ReleaseDC(NULL, hdc);

    depth = 0;
    switch( dib_hdr->biBitCount )
    {
    case 8:     depth = 8; break;
    case 24:    depth = 24; break;
    case 32:    depth = 32; break;
    case 16:
        if( dib_hdr->biCompression == BI_BITFIELDS ) {
            /* check the red mask */
            switch( ((DWORD*)((char*)dib_hdr + dib_hdr->biSize))[0] ) {
                case 0xf800: depth = 16; break;   /* 565 */
                case 0x7c00: depth = 15; break;   /* 555 */
            }
        }
    }
    SDL_free(dib_hdr);
    return depth;
#endif /* NO_GETDIBITS */
}


/* Various screen update functions available */
static void DIB_NormalUpdate(_THIS, int numrects, SDL_Rect *rects);

SDL_Surface *DIB_SetVideoMode(_THIS, SDL_Surface *current,
				int width, int height, int bpp, Uint32 flags)
{
	SDL_Surface *video;
	int prev_w, prev_h;
	Uint32 prev_flags;
	DWORD style;
	const DWORD directstyle =
			(WS_POPUP);
	const DWORD windowstyle =
			(WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX);
	const DWORD resizestyle =
			(WS_THICKFRAME|WS_MAXIMIZEBOX);
	int binfo_size;
	BITMAPINFO *binfo;
	HDC hdc;
	RECT bounds;
	int x, y;
	Uint32 Rmask, Gmask, Bmask;

	/* Clean up any GL context that may be hanging around */
	if ( current->flags & SDL_OPENGL ) {
		WIN_GL_ShutDown(this);
	}
	SDL_resizing = 1;

	/* Recalculate the bitmasks if necessary */
	if ( bpp == current->format->BitsPerPixel ) {
		video = current;
	} else {
		switch (bpp) {
			case 15:
			case 16:
				if ( DIB_SussScreenDepth() == 15 ) {
					/* 5-5-5 */
					Rmask = 0x00007c00;
					Gmask = 0x000003e0;
					Bmask = 0x0000001f;
				} else {
					/* 5-6-5 */
					Rmask = 0x0000f800;
					Gmask = 0x000007e0;
					Bmask = 0x0000001f;
				}
				break;
			case 24:
			case 32:
				/* GDI defined as 8-8-8 */
				Rmask = 0x00ff0000;
				Gmask = 0x0000ff00;
				Bmask = 0x000000ff;
				break;
			default:
				Rmask = 0x00000000;
				Gmask = 0x00000000;
				Bmask = 0x00000000;
				break;
		}
		video = SDL_CreateRGBSurface(SDL_SWSURFACE,
					0, 0, bpp, Rmask, Gmask, Bmask, 0);
		if ( video == NULL ) {
			SDL_OutOfMemory();
			return(NULL);
		}
	}

	/* Fill in part of the video surface */
	prev_flags = video->flags;
	prev_w = video->w;
	prev_h = video->h;
	video->flags = 0;	/* Clear flags */
	video->w = width;
	video->h = height;
	video->pitch = SDL_CalculatePitch(video);

	/* Small fix for WinCE/Win32 - when activating window
	   SDL_VideoSurface is equal to zero, so activating code
	   is not called properly for fullscreen windows because
	   macros WINDIB_FULLSCREEN uses SDL_VideoSurface
	*/
	SDL_VideoSurface = video;

#if defined(_WIN32_WCE)
	if ( flags & SDL_FULLSCREEN )
		video->flags |= SDL_FULLSCREEN;
#endif

#ifndef NO_CHANGEDISPLAYSETTINGS
	/* Set fullscreen mode if appropriate */
	if ( (flags & SDL_FULLSCREEN) == SDL_FULLSCREEN ) {
		DEVMODE settings;
		BOOL changed;

		SDL_memset(&settings, 0, sizeof(DEVMODE));
		settings.dmSize = sizeof(DEVMODE);

#ifdef _WIN32_WCE
		// try to rotate screen to fit requested resolution
		if( this->hidden->supportRotation )
		{
			DWORD rotation;

			// ask current mode
			settings.dmFields = DM_DISPLAYORIENTATION;
			ChangeDisplaySettingsEx(NULL, &settings, NULL, CDS_TEST, NULL);
			rotation = settings.dmDisplayOrientation;

			if( (width > GetDeviceCaps(GetDC(NULL), HORZRES))
				&& (height < GetDeviceCaps(GetDC(NULL), VERTRES)))
			{
				switch( rotation )
				{
				case DMDO_0:
					settings.dmDisplayOrientation = DMDO_90;
					break;
				case DMDO_270:
					settings.dmDisplayOrientation = DMDO_180;
					break;
				}
				if( settings.dmDisplayOrientation != rotation )
				{
					// go to landscape
					this->hidden->origRotation = rotation;
					ChangeDisplaySettingsEx(NULL,&settings,NULL,CDS_RESET,NULL);
				}
			}
			if( (width < GetDeviceCaps(GetDC(NULL), HORZRES))
				&& (height > GetDeviceCaps(GetDC(NULL), VERTRES)))
			{
				switch( rotation )
				{
				case DMDO_90:
					settings.dmDisplayOrientation = DMDO_0;
					break;
				case DMDO_180:
					settings.dmDisplayOrientation = DMDO_270;
					break;
				}
				if( settings.dmDisplayOrientation != rotation )
				{
					// go to portrait
					this->hidden->origRotation = rotation;
					ChangeDisplaySettingsEx(NULL,&settings,NULL,CDS_RESET,NULL);
				}
			}

		}
#endif

#ifndef _WIN32_WCE
		settings.dmBitsPerPel = video->format->BitsPerPixel;
		settings.dmPelsWidth = width;
		settings.dmPelsHeight = height;
		settings.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL;
		if ( width <= (int)SDL_desktop_mode.dmPelsWidth &&
		     height <= (int)SDL_desktop_mode.dmPelsHeight ) {
			settings.dmDisplayFrequency = SDL_desktop_mode.dmDisplayFrequency;
			settings.dmFields |= DM_DISPLAYFREQUENCY;
		}
		changed = (ChangeDisplaySettings(&settings, CDS_FULLSCREEN) == DISP_CHANGE_SUCCESSFUL);
		if ( ! changed && (settings.dmFields & DM_DISPLAYFREQUENCY) ) {
			settings.dmFields &= ~DM_DISPLAYFREQUENCY;
			changed = (ChangeDisplaySettings(&settings, CDS_FULLSCREEN) == DISP_CHANGE_SUCCESSFUL);
		}
#else
		changed = 1;
#endif
		if ( changed ) {
			video->flags |= SDL_FULLSCREEN;
			SDL_fullscreen_mode = settings;
		}

	}
#endif /* !NO_CHANGEDISPLAYSETTINGS */

	/* Reset the palette and create a new one if necessary */
	if ( grab_palette ) {
		DIB_ReleaseStaticColors(SDL_Window);
		grab_palette = FALSE;
	}
	if ( screen_pal != NULL ) {
	/*	RJR: March 28, 2000
		delete identity palette if switching from a palettized mode */
		DeleteObject(screen_pal);
		screen_pal = NULL;
	}
	if ( screen_logpal != NULL ) {
		SDL_free(screen_logpal);
		screen_logpal = NULL;
	}

	if ( bpp <= 8 )
	{
	/*	RJR: March 28, 2000
		create identity palette switching to a palettized mode */
		DIB_CreatePalette(this, bpp);
	}

	style = GetWindowLong(SDL_Window, GWL_STYLE);
	style &= ~(resizestyle|WS_MAXIMIZE);
	if ( (video->flags & SDL_FULLSCREEN) == SDL_FULLSCREEN ) {
		style &= ~windowstyle;
		style |= directstyle;
	} else {
#ifndef NO_CHANGEDISPLAYSETTINGS
		if ( (prev_flags & SDL_FULLSCREEN) == SDL_FULLSCREEN ) {
			ChangeDisplaySettings(NULL, 0);
		}
#endif
		if ( flags & SDL_NOFRAME ) {
			style &= ~windowstyle;
			style |= directstyle;
			video->flags |= SDL_NOFRAME;
		} else {
			style &= ~directstyle;
			style |= windowstyle;
			if ( flags & SDL_RESIZABLE ) {
				style |= resizestyle;
				video->flags |= SDL_RESIZABLE;
			}
		}
#if WS_MAXIMIZE
		if (IsZoomed(SDL_Window)) style |= WS_MAXIMIZE;
#endif
	}

	/* DJM: Don't piss of anyone who has setup his own window */
	if ( !SDL_windowid )
		SetWindowLong(SDL_Window, GWL_STYLE, style);

	/* Delete the old bitmap if necessary */
	if ( screen_bmp != NULL ) {
		DeleteObject(screen_bmp);
	}
	if ( ! (flags & SDL_OPENGL) ) {
		BOOL is16bitmode = (video->format->BytesPerPixel == 2);

		/* Suss out the bitmap info header */
		binfo_size = sizeof(*binfo);
		if( is16bitmode ) {
			/* 16bit modes, palette area used for rgb bitmasks */
			binfo_size += 3*sizeof(DWORD);
		} else if ( video->format->palette ) {
			binfo_size += video->format->palette->ncolors *
							sizeof(RGBQUAD);
		}
		binfo = (BITMAPINFO *)SDL_malloc(binfo_size);
		if ( ! binfo ) {
			if ( video != current ) {
				SDL_FreeSurface(video);
			}
			SDL_OutOfMemory();
			return(NULL);
		}

		binfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
		binfo->bmiHeader.biWidth = video->w;
		binfo->bmiHeader.biHeight = -video->h;	/* -ve for topdown bitmap */
		binfo->bmiHeader.biPlanes = 1;
		binfo->bmiHeader.biSizeImage = video->h * video->pitch;
		binfo->bmiHeader.biXPelsPerMeter = 0;
		binfo->bmiHeader.biYPelsPerMeter = 0;
		binfo->bmiHeader.biClrUsed = 0;
		binfo->bmiHeader.biClrImportant = 0;
		binfo->bmiHeader.biBitCount = video->format->BitsPerPixel;

		if ( is16bitmode ) {
			/* BI_BITFIELDS tells CreateDIBSection about the rgb masks in the palette */
			binfo->bmiHeader.biCompression = BI_BITFIELDS;
			((Uint32*)binfo->bmiColors)[0] = video->format->Rmask;
			((Uint32*)binfo->bmiColors)[1] = video->format->Gmask;
			((Uint32*)binfo->bmiColors)[2] = video->format->Bmask;
		} else {
			binfo->bmiHeader.biCompression = BI_RGB;	/* BI_BITFIELDS for 565 vs 555 */
			if ( video->format->palette ) {
				SDL_memset(binfo->bmiColors, 0,
					video->format->palette->ncolors*sizeof(RGBQUAD));
			}
		}

		/* Create the offscreen bitmap buffer */
		hdc = GetDC(SDL_Window);
		screen_bmp = CreateDIBSection(hdc, binfo, DIB_RGB_COLORS,
					(void **)(&video->pixels), NULL, 0);
		ReleaseDC(SDL_Window, hdc);
		SDL_free(binfo);
		if ( screen_bmp == NULL ) {
			if ( video != current ) {
				SDL_FreeSurface(video);
			}
			SDL_SetError("Couldn't create DIB section");
			return(NULL);
		}
		this->UpdateRects = DIB_NormalUpdate;

		/* Set video surface flags */
		if ( screen_pal && (flags & (SDL_FULLSCREEN|SDL_HWPALETTE)) ) {
			grab_palette = TRUE;
		}
		/* BitBlt() maps colors for us */
		video->flags |= SDL_HWPALETTE;
	}
#ifndef _WIN32_WCE
	/* Resize the window */
	if ( !SDL_windowid && !IsZoomed(SDL_Window) ) {
#else
	if ( !SDL_windowid ) {
#endif
		HWND top;
		UINT swp_flags;
		const char *window = NULL;
		const char *center = NULL;

		if ( video->w != prev_w || video->h != prev_h ) {
			window = SDL_getenv("SDL_VIDEO_WINDOW_POS");
			center = SDL_getenv("SDL_VIDEO_CENTERED");
			if ( window ) {
				if ( SDL_sscanf(window, "%d,%d", &x, &y) == 2 ) {
					SDL_windowX = x;
					SDL_windowY = y;
				}
				if ( SDL_strcmp(window, "center") == 0 ) {
					center = window;
				}
			}
		}
		swp_flags = (SWP_NOCOPYBITS | SWP_SHOWWINDOW);

		bounds.left = SDL_windowX;
		bounds.top = SDL_windowY;
		bounds.right = SDL_windowX+video->w;
		bounds.bottom = SDL_windowY+video->h;
#ifndef _WIN32_WCE
		AdjustWindowRectEx(&bounds, GetWindowLong(SDL_Window, GWL_STYLE), (GetMenu(SDL_Window) != NULL), 0);
#else
		// The bMenu parameter must be FALSE; menu bars are not supported
		AdjustWindowRectEx(&bounds, GetWindowLong(SDL_Window, GWL_STYLE), 0, 0);
#endif
		width = bounds.right-bounds.left;
		height = bounds.bottom-bounds.top;
		if ( (flags & SDL_FULLSCREEN) ) {
			x = (GetSystemMetrics(SM_CXSCREEN)-width)/2;
			y = (GetSystemMetrics(SM_CYSCREEN)-height)/2;
		} else if ( center ) {
			x = (GetSystemMetrics(SM_CXSCREEN)-width)/2;
			y = (GetSystemMetrics(SM_CYSCREEN)-height)/2;
		} else if ( SDL_windowX || SDL_windowY || window ) {
			x = bounds.left;
			y = bounds.top;
		} else {
			x = y = -1;
			swp_flags |= SWP_NOMOVE;
		}
		if ( flags & SDL_FULLSCREEN ) {
			top = HWND_TOPMOST;
		} else {
			top = HWND_NOTOPMOST;
		}
		SetWindowPos(SDL_Window, top, x, y, width, height, swp_flags);
		if ( !(flags & SDL_FULLSCREEN) ) {
			SDL_windowX = SDL_bounds.left;
			SDL_windowY = SDL_bounds.top;
		}
		SetForegroundWindow(SDL_Window);
	}
	SDL_resizing = 0;

	/* Set up for OpenGL */
	if ( flags & SDL_OPENGL ) {
		if ( WIN_GL_SetupWindow(this) < 0 ) {
			return(NULL);
		}
		video->flags |= SDL_OPENGL;
	}

	/* JC 14 Mar 2006
		Flush the message loop or this can cause big problems later
		Especially if the user decides to use dialog boxes or assert()!
	*/
	WIN_FlushMessageQueue();

	/* We're live! */
	return(video);
}

/* We don't actually allow hardware surfaces in the DIB driver */
static int DIB_AllocHWSurface(_THIS, SDL_Surface *surface)
{
	return(-1);
}
static void DIB_FreeHWSurface(_THIS, SDL_Surface *surface)
{
	return;
}
static int DIB_LockHWSurface(_THIS, SDL_Surface *surface)
{
	return(0);
}
static void DIB_UnlockHWSurface(_THIS, SDL_Surface *surface)
{
	return;
}

static void DIB_NormalUpdate(_THIS, int numrects, SDL_Rect *rects)
{
	HDC hdc, mdc;
	int i;

	hdc = GetDC(SDL_Window);
	if ( screen_pal ) {
		SelectPalette(hdc, screen_pal, FALSE);
	}
	mdc = CreateCompatibleDC(hdc);
	SelectObject(mdc, screen_bmp);
	for ( i=0; i<numrects; ++i ) {
		BitBlt(hdc, rects[i].x, rects[i].y, rects[i].w, rects[i].h,
					mdc, rects[i].x, rects[i].y, SRCCOPY);
	}
	DeleteDC(mdc);
	ReleaseDC(SDL_Window, hdc);
}

static int FindPaletteIndex(LOGPALETTE *pal, BYTE r, BYTE g, BYTE b)
{
	PALETTEENTRY *entry;
	int i;
	int nentries = pal->palNumEntries;

	for ( i = 0; i < nentries; ++i ) {
		entry = &pal->palPalEntry[i];
		if ( entry->peRed == r && entry->peGreen == g && entry->peBlue == b ) {
			return i;
		}
	}
	return -1;
}

static BOOL CheckPaletteEntry(LOGPALETTE *pal, int index, BYTE r, BYTE g, BYTE b)
{
	PALETTEENTRY *entry;
	BOOL moved = 0;

	entry = &pal->palPalEntry[index];
	if ( entry->peRed != r || entry->peGreen != g || entry->peBlue != b ) {
		int found = FindPaletteIndex(pal, r, g, b);
		if ( found >= 0 ) {
			pal->palPalEntry[found] = *entry;
		}
		entry->peRed = r;
		entry->peGreen = g;
		entry->peBlue = b;
		moved = 1;
	}
	entry->peFlags = 0;

	return moved;
}

int DIB_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors)
{
#if !defined(_WIN32_WCE) || (_WIN32_WCE >= 400)
	HDC hdc, mdc;
	RGBQUAD *pal;
#else
	HDC hdc;
#endif
	int i;
	int moved_entries = 0;

	/* Update the display palette */
	hdc = GetDC(SDL_Window);
	if ( screen_pal ) {
		PALETTEENTRY *entry;

		for ( i=0; i<ncolors; ++i ) {
			entry = &screen_logpal->palPalEntry[firstcolor+i];
			entry->peRed   = colors[i].r;
			entry->peGreen = colors[i].g;
			entry->peBlue  = colors[i].b;
			entry->peFlags = PC_NOCOLLAPSE;
		}
#ifdef SYSPAL_NOSTATIC
		/* Check to make sure black and white are in position */
		if ( GetSystemPaletteUse(hdc) != SYSPAL_NOSTATIC256 ) {
			moved_entries += CheckPaletteEntry(screen_logpal, 0, 0x00, 0x00, 0x00);
			moved_entries += CheckPaletteEntry(screen_logpal, screen_logpal->palNumEntries-1, 0xff, 0xff, 0xff);
		}
		/* FIXME:
		   If we don't have full access to the palette, what we
		   really want to do is find the 236 most diverse colors
		   in the desired palette, set those entries (10-245) and
		   then map everything into the new system palette.
		 */
#endif

#ifndef _WIN32_WCE
		/* Copy the entries into the system palette */
		UnrealizeObject(screen_pal);
#endif
		SetPaletteEntries(screen_pal, 0, screen_logpal->palNumEntries, screen_logpal->palPalEntry);
		SelectPalette(hdc, screen_pal, FALSE);
		RealizePalette(hdc);
	}

#if !defined(_WIN32_WCE) || (_WIN32_WCE >= 400)
	/* Copy palette colors into DIB palette */
	pal = SDL_stack_alloc(RGBQUAD, ncolors);
	for ( i=0; i<ncolors; ++i ) {
		pal[i].rgbRed = colors[i].r;
		pal[i].rgbGreen = colors[i].g;
		pal[i].rgbBlue = colors[i].b;
		pal[i].rgbReserved = 0;
	}

	/* Set the DIB palette and update the display */
	mdc = CreateCompatibleDC(hdc);
	SelectObject(mdc, screen_bmp);
	SetDIBColorTable(mdc, firstcolor, ncolors, pal);
	if ( moved_entries || !grab_palette ) {
		BitBlt(hdc, 0, 0, this->screen->w, this->screen->h,
		       mdc, 0, 0, SRCCOPY);
	}
	DeleteDC(mdc);
	SDL_stack_free(pal);
#endif
	ReleaseDC(SDL_Window, hdc);
	return(1);
}


static void DIB_CheckGamma(_THIS)
{
#ifndef NO_GAMMA_SUPPORT
	HDC hdc;
	WORD ramp[3*256];

	/* If we fail to get gamma, disable gamma control */
	hdc = GetDC(SDL_Window);
	if ( ! GetDeviceGammaRamp(hdc, ramp) ) {
		this->GetGammaRamp = NULL;
		this->SetGammaRamp = NULL;
	}
	ReleaseDC(SDL_Window, hdc);
#endif /* !NO_GAMMA_SUPPORT */
}
void DIB_SwapGamma(_THIS)
{
#ifndef NO_GAMMA_SUPPORT
	HDC hdc;

	if ( gamma_saved ) {
		hdc = GetDC(SDL_Window);
		if ( SDL_GetAppState() & SDL_APPINPUTFOCUS ) {
			/* About to leave active state, restore gamma */
			SetDeviceGammaRamp(hdc, gamma_saved);
		} else {
			/* About to enter active state, set game gamma */
			GetDeviceGammaRamp(hdc, gamma_saved);
			SetDeviceGammaRamp(hdc, this->gamma);
		}
		ReleaseDC(SDL_Window, hdc);
	}
#endif /* !NO_GAMMA_SUPPORT */
}
void DIB_QuitGamma(_THIS)
{
#ifndef NO_GAMMA_SUPPORT
	if ( gamma_saved ) {
		/* Restore the original gamma if necessary */
		if ( SDL_GetAppState() & SDL_APPINPUTFOCUS ) {
			HDC hdc;

			hdc = GetDC(SDL_Window);
			SetDeviceGammaRamp(hdc, gamma_saved);
			ReleaseDC(SDL_Window, hdc);
		}

		/* Free the saved gamma memory */
		SDL_free(gamma_saved);
		gamma_saved = 0;
	}
#endif /* !NO_GAMMA_SUPPORT */
}

int DIB_SetGammaRamp(_THIS, Uint16 *ramp)
{
#ifdef NO_GAMMA_SUPPORT
	SDL_SetError("SDL compiled without gamma ramp support");
	return -1;
#else
	HDC hdc;
	BOOL succeeded;

	/* Set the ramp for the display */
	if ( ! gamma_saved ) {
		gamma_saved = (WORD *)SDL_malloc(3*256*sizeof(*gamma_saved));
		if ( ! gamma_saved ) {
			SDL_OutOfMemory();
			return -1;
		}
		hdc = GetDC(SDL_Window);
		GetDeviceGammaRamp(hdc, gamma_saved);
		ReleaseDC(SDL_Window, hdc);
	}
	if ( SDL_GetAppState() & SDL_APPINPUTFOCUS ) {
		hdc = GetDC(SDL_Window);
		succeeded = SetDeviceGammaRamp(hdc, ramp);
		ReleaseDC(SDL_Window, hdc);
	} else {
		succeeded = TRUE;
	}
	return succeeded ? 0 : -1;
#endif /* !NO_GAMMA_SUPPORT */
}

int DIB_GetGammaRamp(_THIS, Uint16 *ramp)
{
#ifdef NO_GAMMA_SUPPORT
	SDL_SetError("SDL compiled without gamma ramp support");
	return -1;
#else
	HDC hdc;
	BOOL succeeded;

	/* Get the ramp from the display */
	hdc = GetDC(SDL_Window);
	succeeded = GetDeviceGammaRamp(hdc, ramp);
	ReleaseDC(SDL_Window, hdc);
	return succeeded ? 0 : -1;
#endif /* !NO_GAMMA_SUPPORT */
}

void DIB_VideoQuit(_THIS)
{
	int i, j;

	/* Destroy the window and everything associated with it */
	if ( SDL_Window ) {
		/* Delete the screen bitmap (also frees screen->pixels) */
		if ( this->screen ) {
			if ( grab_palette ) {
				DIB_ReleaseStaticColors(SDL_Window);
			}
#ifndef NO_CHANGEDISPLAYSETTINGS
			if ( this->screen->flags & SDL_FULLSCREEN ) {
				ChangeDisplaySettings(NULL, 0);
				ShowWindow(SDL_Window, SW_HIDE);
			}
#endif
			if ( this->screen->flags & SDL_OPENGL ) {
				WIN_GL_ShutDown(this);
			}
			this->screen->pixels = NULL;
		}
		if ( screen_pal != NULL ) {
			DeleteObject(screen_pal);
			screen_pal = NULL;
		}
		if ( screen_logpal != NULL ) {
			SDL_free(screen_logpal);
			screen_logpal = NULL;
		}
		if ( screen_bmp ) {
			DeleteObject(screen_bmp);
			screen_bmp = NULL;
		}
		if ( screen_icn ) {
			DestroyIcon(screen_icn);
			screen_icn = NULL;
		}
		DIB_QuitGamma(this);
		DIB_DestroyWindow(this);

		SDL_Window = NULL;

#if defined(_WIN32_WCE)

// Unload wince aygshell library to prevent leak
		if( aygshell )
		{
			FreeLibrary(aygshell);
			aygshell = NULL;
		}
#endif
	}

	for ( i=0; i < SDL_arraysize(SDL_modelist); ++i ) {
		if ( !SDL_modelist[i] ) {
			continue;
		}
		for ( j=0; SDL_modelist[i][j]; ++j ) {
			SDL_free(SDL_modelist[i][j]);
		}
		SDL_free(SDL_modelist[i]);
		SDL_modelist[i] = NULL;
		SDL_nummodes[i] = 0;
	}
}

/* Exported for the windows message loop only */
static void DIB_GrabStaticColors(HWND window)
{
#ifdef SYSPAL_NOSTATIC
	HDC hdc;

	hdc = GetDC(window);
	SetSystemPaletteUse(hdc, SYSPAL_NOSTATIC256);
	if ( GetSystemPaletteUse(hdc) != SYSPAL_NOSTATIC256 ) {
		SetSystemPaletteUse(hdc, SYSPAL_NOSTATIC);
	}
	ReleaseDC(window, hdc);
#endif
}
static void DIB_ReleaseStaticColors(HWND window)
{
#ifdef SYSPAL_NOSTATIC
	HDC hdc;

	hdc = GetDC(window);
	SetSystemPaletteUse(hdc, SYSPAL_STATIC);
	ReleaseDC(window, hdc);
#endif
}
static void DIB_Activate(_THIS, BOOL active, BOOL minimized)
{
	if ( grab_palette ) {
		if ( !active ) {
			DIB_ReleaseStaticColors(SDL_Window);
			DIB_RealizePalette(this);
		} else if ( !minimized ) {
			DIB_GrabStaticColors(SDL_Window);
			DIB_RealizePalette(this);
		}
	}
}
static void DIB_RealizePalette(_THIS)
{
	if ( screen_pal != NULL ) {
		HDC hdc;

		hdc = GetDC(SDL_Window);
#ifndef _WIN32_WCE
		UnrealizeObject(screen_pal);
#endif
		SelectPalette(hdc, screen_pal, FALSE);
		if ( RealizePalette(hdc) ) {
			InvalidateRect(SDL_Window, NULL, FALSE);
		}
		ReleaseDC(SDL_Window, hdc);
	}
}
static void DIB_PaletteChanged(_THIS, HWND window)
{
	if ( window != SDL_Window ) {
		DIB_RealizePalette(this);
	}
}

/* Exported for the windows message loop only */
static void DIB_WinPAINT(_THIS, HDC hdc)
{
	HDC mdc;

	if ( screen_pal ) {
		SelectPalette(hdc, screen_pal, FALSE);
	}
	mdc = CreateCompatibleDC(hdc);
	SelectObject(mdc, screen_bmp);
	BitBlt(hdc, 0, 0, SDL_VideoSurface->w, SDL_VideoSurface->h,
							mdc, 0, 0, SRCCOPY);
	DeleteDC(mdc);
}

static void DIB_GetWinPos(_THIS, int* px, int *py)
{
	RECT  rect;
	GetWindowRect(SDL_Window, &rect);
	*px = rect.left;
	*py = rect.top;
}

static void DIB_SetWinPos(_THIS, int  x, int  y)
{
    SetWindowPos(SDL_Window, HWND_TOPMOST, 
                 x, y, 0, 0, SWP_NOSIZE|SWP_NOZORDER);
}

typedef struct {
    int   result;
    int   first;
    RECT  wrect;
    RECT  primary;
} VisibilityData;


BOOL CALLBACK visibility_cb(HMONITOR  hMonitor,
                            HDC       hdcMonitor,
                            LPRECT    mrect,
                            LPARAM    dwData)
{
    VisibilityData*  data = (VisibilityData*)dwData;
    
    if ( data->first ) {
        data->first   = 0;
        data->primary = mrect[0];
    }
    
    if ( data->wrect.left   >= mrect->left   &&
         data->wrect.right  <= mrect->right  &&
         data->wrect.top    >= mrect->top    &&
         data->wrect.bottom <= mrect->bottom )
    {
        data->result = 1;
        return FALSE;
    }
    return TRUE;
}

static int  DIB_IsWinVisible(_THIS, int  recenter)
{
    VisibilityData  data;
    data.result = 0;
    data.first  = 1;
    
    GetWindowRect(SDL_Window, &data.wrect);

    EnumDisplayMonitors(NULL, NULL, visibility_cb, (LPARAM)&data);
    
    if ( !data.result && recenter ) {
        int  new_x = 10;
        int  new_y = 10;

        if ( !data.first ) {
            int  primary_w = data.primary.right  - data.primary.left;
            int  primary_h = data.primary.bottom - data.primary.top;

            new_x = data.primary.left + (primary_w - this->screen->w)/2;
            new_y = data.primary.top  + (primary_h - this->screen->h)/2;
        }
        DIB_SetWinPos(this, new_x, new_y);
    }
    return  data.result;
}

static int  DIB_GetMonitorDPI(_THIS, int* xDpi, int *yDpi)
{
    HDC  displayDC = CreateDC( "DISPLAY", NULL, NULL, NULL );
    int  xdpi, ydpi;

    if (displayDC == NULL) {
        return -1;
    }
    xdpi = GetDeviceCaps( displayDC, LOGPIXELSX );
    ydpi = GetDeviceCaps( displayDC, LOGPIXELSY );

    DeleteDC(displayDC);

    /* sanity checks */
    if (xdpi < 20 || xdpi > 400 || ydpi < 20 || ydpi > 400) {
        return -1;
    }

    *xDpi = xdpi;
    *yDpi = ydpi;
    return 0;
}


typedef struct {
    int   first;
    RECT  wrect;
	long  bestArea;
	RECT  bestRect;
	RECT  primary;
} ProximityData;

BOOL CALLBACK proximity_cb(HMONITOR  hMonitor,
                           HDC       hdcMonitor,
                           LPRECT    mrect,
                           LPARAM    dwData)
{
    ProximityData*  data = (ProximityData*)dwData;
    int   x1, y1, x2, y2, area;
	
	x1 = mrect->left;
	x2 = mrect->right;
	y1 = mrect->top;
	y2 = mrect->bottom;

	if (data->first) {
		data->primary = mrect[0];
	}
	
	if (x1 < data->wrect.left)
		x1 = data->wrect.left;
    if (x2 > data->wrect.right)
		x2 = data->wrect.right;
	if (y1 < data->wrect.top)
		y1 = data->wrect.top;
	if (y2 > data->wrect.bottom)
		y2 = data->wrect.bottom;
	
	if (x1 >= x2 || y1 >= y2)
		return TRUE;

	area = (x2-x1)*(y2-y1);
	if (data->first || area > data->bestArea) {
		data->first    = 0;
		data->bestRect = mrect[0];
		data->bestArea = area;
	}
    return TRUE;
}

static int  DIB_GetMonitorRect(_THIS, SDL_Rect*  rect)
{
    ProximityData  data;
	RECT*          sr;

    data.first  = 1;
    GetWindowRect(SDL_Window, &data.wrect);

    EnumDisplayMonitors(NULL, NULL, proximity_cb, (LPARAM)&data);

	if (data.first)
		return -1;

	sr = &data.bestRect;

	rect->x = sr->left;
	rect->y = sr->top;
	rect->w = sr->right - sr->left;
	rect->h = sr->bottom - sr->top;
	
	return 0;
}

/* Stub in case DirectX isn't available */
#if !SDL_AUDIO_DRIVER_DSOUND
void DX5_SoundFocus(HWND hwnd)
{
	return;
}
#endif
