src/video/windib/SDL_dibvideo.c
author Ryan C. Gordon <icculus@icculus.org>
Tue, 27 Sep 2005 09:00:42 +0000
changeset 1145 d31afac94eff
parent 971 96671ebc50a4
child 1152 51a8702d8ecd
permissions -rw-r--r--
Patch from Martin Lange (mala-sdl at hotmail.com) to unregister SDL's win32
windowclass when shutting down the video subsystem...this allows you to
safely unload/reload the SDL shared library on Windows between
initializations.

Discussion is here:
http://www.devolution.com/pipermail/sdl/2005-February/067424.html
slouken@0
     1
/*
slouken@0
     2
    SDL - Simple DirectMedia Layer
slouken@0
     3
    Copyright (C) 1997, 1998, 1999  Sam Lantinga
slouken@0
     4
slouken@0
     5
    This library is free software; you can redistribute it and/or
slouken@0
     6
    modify it under the terms of the GNU Library General Public
slouken@0
     7
    License as published by the Free Software Foundation; either
slouken@0
     8
    version 2 of the License, or (at your option) any later version.
slouken@0
     9
slouken@0
    10
    This library is distributed in the hope that it will be useful,
slouken@0
    11
    but WITHOUT ANY WARRANTY; without even the implied warranty of
slouken@0
    12
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
slouken@0
    13
    Library General Public License for more details.
slouken@0
    14
slouken@0
    15
    You should have received a copy of the GNU Library General Public
slouken@0
    16
    License along with this library; if not, write to the Free
slouken@0
    17
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
slouken@0
    18
slouken@0
    19
    Sam Lantinga
slouken@252
    20
    slouken@libsdl.org
slouken@0
    21
*/
slouken@0
    22
slouken@0
    23
#ifdef SAVE_RCSID
slouken@0
    24
static char rcsid =
slouken@0
    25
 "@(#) $Id$";
slouken@0
    26
#endif
slouken@0
    27
slouken@0
    28
#include <stdio.h>
slouken@0
    29
#include <stdlib.h>
slouken@0
    30
#include <malloc.h>
slouken@0
    31
#include <windows.h>
slouken@515
    32
#if defined(WIN32_PLATFORM_PSPC)
slouken@515
    33
#include <aygshell.h>                      // Add Pocket PC includes
slouken@515
    34
#pragma comment( lib, "aygshell" )         // Link Pocket PC library
slouken@514
    35
#endif
slouken@0
    36
slouken@0
    37
/* Not yet in the mingw32 cross-compile headers */
slouken@0
    38
#ifndef CDS_FULLSCREEN
slouken@0
    39
#define CDS_FULLSCREEN	4
slouken@0
    40
#endif
slouken@0
    41
slouken@0
    42
#include "SDL.h"
slouken@0
    43
#include "SDL_mutex.h"
slouken@0
    44
#include "SDL_syswm.h"
slouken@0
    45
#include "SDL_sysvideo.h"
slouken@0
    46
#include "SDL_sysevents.h"
slouken@0
    47
#include "SDL_events_c.h"
slouken@0
    48
#include "SDL_pixels_c.h"
slouken@0
    49
#include "SDL_dibvideo.h"
slouken@0
    50
#include "SDL_syswm_c.h"
slouken@0
    51
#include "SDL_sysmouse_c.h"
slouken@0
    52
#include "SDL_dibevents_c.h"
slouken@0
    53
#include "SDL_wingl_c.h"
slouken@0
    54
slouken@0
    55
#ifdef _WIN32_WCE
slouken@0
    56
#define NO_GETDIBITS
slouken@0
    57
#define NO_CHANGEDISPLAYSETTINGS
slouken@0
    58
#define NO_GAMMA_SUPPORT
slouken@0
    59
#endif
slouken@453
    60
#ifndef WS_MAXIMIZE
slouken@766
    61
#define WS_MAXIMIZE	0
slouken@766
    62
#endif
slouken@766
    63
#ifndef WS_THICKFRAME
slouken@766
    64
#define WS_THICKFRAME	0
slouken@453
    65
#endif
slouken@453
    66
#ifndef SWP_NOCOPYBITS
slouken@453
    67
#define SWP_NOCOPYBITS	0
slouken@453
    68
#endif
slouken@453
    69
#ifndef PC_NOCOLLAPSE
slouken@453
    70
#define PC_NOCOLLAPSE	0
slouken@453
    71
#endif
slouken@0
    72
slouken@0
    73
/* Initialization/Query functions */
slouken@0
    74
static int DIB_VideoInit(_THIS, SDL_PixelFormat *vformat);
slouken@0
    75
static SDL_Rect **DIB_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags);
slouken@0
    76
SDL_Surface *DIB_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags);
slouken@0
    77
static int DIB_SetColors(_THIS, int firstcolor, int ncolors,
slouken@0
    78
			 SDL_Color *colors);
slouken@0
    79
static void DIB_CheckGamma(_THIS);
slouken@338
    80
void DIB_SwapGamma(_THIS);
slouken@338
    81
void DIB_QuitGamma(_THIS);
slouken@338
    82
int DIB_SetGammaRamp(_THIS, Uint16 *ramp);
slouken@338
    83
int DIB_GetGammaRamp(_THIS, Uint16 *ramp);
slouken@0
    84
static void DIB_VideoQuit(_THIS);
slouken@0
    85
slouken@0
    86
/* Hardware surface functions */
slouken@0
    87
static int DIB_AllocHWSurface(_THIS, SDL_Surface *surface);
slouken@0
    88
static int DIB_LockHWSurface(_THIS, SDL_Surface *surface);
slouken@0
    89
static void DIB_UnlockHWSurface(_THIS, SDL_Surface *surface);
slouken@0
    90
static void DIB_FreeHWSurface(_THIS, SDL_Surface *surface);
slouken@0
    91
slouken@0
    92
/* Windows message handling functions */
slouken@0
    93
static void DIB_RealizePalette(_THIS);
slouken@0
    94
static void DIB_PaletteChanged(_THIS, HWND window);
slouken@0
    95
static void DIB_WinPAINT(_THIS, HDC hdc);
slouken@0
    96
slouken@0
    97
/* helper fn */
slouken@0
    98
static int DIB_SussScreenDepth();
slouken@0
    99
slouken@0
   100
/* DIB driver bootstrap functions */
slouken@0
   101
slouken@0
   102
static int DIB_Available(void)
slouken@0
   103
{
slouken@0
   104
	return(1);
slouken@0
   105
}
slouken@0
   106
slouken@0
   107
static void DIB_DeleteDevice(SDL_VideoDevice *device)
slouken@0
   108
{
slouken@0
   109
	if ( device ) {
slouken@0
   110
		if ( device->hidden ) {
slouken@0
   111
			free(device->hidden);
slouken@0
   112
		}
slouken@0
   113
		if ( device->gl_data ) {
slouken@0
   114
			free(device->gl_data);
slouken@0
   115
		}
slouken@0
   116
		free(device);
slouken@0
   117
	}
slouken@0
   118
}
slouken@0
   119
slouken@0
   120
static SDL_VideoDevice *DIB_CreateDevice(int devindex)
slouken@0
   121
{
slouken@0
   122
	SDL_VideoDevice *device;
slouken@0
   123
slouken@0
   124
	/* Initialize all variables that we clean on shutdown */
slouken@0
   125
	device = (SDL_VideoDevice *)malloc(sizeof(SDL_VideoDevice));
slouken@0
   126
	if ( device ) {
slouken@0
   127
		memset(device, 0, (sizeof *device));
slouken@0
   128
		device->hidden = (struct SDL_PrivateVideoData *)
slouken@0
   129
				malloc((sizeof *device->hidden));
slouken@0
   130
		device->gl_data = (struct SDL_PrivateGLData *)
slouken@0
   131
				malloc((sizeof *device->gl_data));
slouken@0
   132
	}
slouken@0
   133
	if ( (device == NULL) || (device->hidden == NULL) ||
slouken@0
   134
		                 (device->gl_data == NULL) ) {
slouken@0
   135
		SDL_OutOfMemory();
slouken@0
   136
		DIB_DeleteDevice(device);
slouken@0
   137
		return(NULL);
slouken@0
   138
	}
slouken@0
   139
	memset(device->hidden, 0, (sizeof *device->hidden));
slouken@0
   140
	memset(device->gl_data, 0, (sizeof *device->gl_data));
slouken@0
   141
slouken@0
   142
	/* Set the function pointers */
slouken@0
   143
	device->VideoInit = DIB_VideoInit;
slouken@0
   144
	device->ListModes = DIB_ListModes;
slouken@0
   145
	device->SetVideoMode = DIB_SetVideoMode;
slouken@0
   146
	device->UpdateMouse = WIN_UpdateMouse;
slouken@0
   147
	device->SetColors = DIB_SetColors;
slouken@0
   148
	device->UpdateRects = NULL;
slouken@0
   149
	device->VideoQuit = DIB_VideoQuit;
slouken@0
   150
	device->AllocHWSurface = DIB_AllocHWSurface;
slouken@0
   151
	device->CheckHWBlit = NULL;
slouken@0
   152
	device->FillHWRect = NULL;
slouken@0
   153
	device->SetHWColorKey = NULL;
slouken@0
   154
	device->SetHWAlpha = NULL;
slouken@0
   155
	device->LockHWSurface = DIB_LockHWSurface;
slouken@0
   156
	device->UnlockHWSurface = DIB_UnlockHWSurface;
slouken@0
   157
	device->FlipHWSurface = NULL;
slouken@0
   158
	device->FreeHWSurface = DIB_FreeHWSurface;
slouken@0
   159
	device->SetGammaRamp = DIB_SetGammaRamp;
slouken@0
   160
	device->GetGammaRamp = DIB_GetGammaRamp;
slouken@0
   161
#ifdef HAVE_OPENGL
slouken@453
   162
	device->GL_LoadLibrary = WIN_GL_LoadLibrary;
slouken@453
   163
	device->GL_GetProcAddress = WIN_GL_GetProcAddress;
slouken@453
   164
	device->GL_GetAttribute = WIN_GL_GetAttribute;
slouken@453
   165
	device->GL_MakeCurrent = WIN_GL_MakeCurrent;
slouken@453
   166
	device->GL_SwapBuffers = WIN_GL_SwapBuffers;
slouken@0
   167
#endif
slouken@0
   168
	device->SetCaption = WIN_SetWMCaption;
slouken@0
   169
	device->SetIcon = WIN_SetWMIcon;
slouken@0
   170
	device->IconifyWindow = WIN_IconifyWindow;
slouken@0
   171
	device->GrabInput = WIN_GrabInput;
slouken@0
   172
	device->GetWMInfo = WIN_GetWMInfo;
slouken@0
   173
	device->FreeWMCursor = WIN_FreeWMCursor;
slouken@0
   174
	device->CreateWMCursor = WIN_CreateWMCursor;
slouken@0
   175
	device->ShowWMCursor = WIN_ShowWMCursor;
slouken@0
   176
	device->WarpWMCursor = WIN_WarpWMCursor;
slouken@0
   177
	device->CheckMouseMode = WIN_CheckMouseMode;
slouken@0
   178
	device->InitOSKeymap = DIB_InitOSKeymap;
slouken@0
   179
	device->PumpEvents = DIB_PumpEvents;
slouken@0
   180
slouken@0
   181
	/* Set up the windows message handling functions */
slouken@0
   182
	WIN_RealizePalette = DIB_RealizePalette;
slouken@0
   183
	WIN_PaletteChanged = DIB_PaletteChanged;
slouken@0
   184
	WIN_WinPAINT = DIB_WinPAINT;
slouken@0
   185
	HandleMessage = DIB_HandleMessage;
slouken@0
   186
slouken@0
   187
	device->free = DIB_DeleteDevice;
slouken@0
   188
slouken@0
   189
	/* We're finally ready */
slouken@0
   190
	return device;
slouken@0
   191
}
slouken@0
   192
slouken@0
   193
VideoBootStrap WINDIB_bootstrap = {
slouken@0
   194
	"windib", "Win95/98/NT/2000 GDI",
slouken@0
   195
	DIB_Available, DIB_CreateDevice
slouken@0
   196
};
slouken@0
   197
slouken@0
   198
#ifndef NO_CHANGEDISPLAYSETTINGS
slouken@0
   199
slouken@0
   200
static int cmpmodes(const void *va, const void *vb)
slouken@0
   201
{
slouken@0
   202
    SDL_Rect *a = *(SDL_Rect **)va;
slouken@0
   203
    SDL_Rect *b = *(SDL_Rect **)vb;
slouken@966
   204
    if ( a->w == b->w )
slouken@966
   205
        return b->h - a->h;
slouken@966
   206
    else
slouken@966
   207
        return b->w - a->w;
slouken@0
   208
}
slouken@0
   209
slouken@0
   210
static int DIB_AddMode(_THIS, int bpp, int w, int h)
slouken@0
   211
{
slouken@0
   212
	SDL_Rect *mode;
slouken@0
   213
	int i, index;
slouken@0
   214
	int next_mode;
slouken@0
   215
slouken@0
   216
	/* Check to see if we already have this mode */
slouken@0
   217
	if ( bpp < 8 ) {  /* Not supported */
slouken@0
   218
		return(0);
slouken@0
   219
	}
slouken@0
   220
	index = ((bpp+7)/8)-1;
slouken@0
   221
	for ( i=0; i<SDL_nummodes[index]; ++i ) {
slouken@0
   222
		mode = SDL_modelist[index][i];
slouken@0
   223
		if ( (mode->w == w) && (mode->h == h) ) {
slouken@0
   224
			return(0);
slouken@0
   225
		}
slouken@0
   226
	}
slouken@0
   227
slouken@0
   228
	/* Set up the new video mode rectangle */
slouken@0
   229
	mode = (SDL_Rect *)malloc(sizeof *mode);
slouken@0
   230
	if ( mode == NULL ) {
slouken@0
   231
		SDL_OutOfMemory();
slouken@0
   232
		return(-1);
slouken@0
   233
	}
slouken@0
   234
	mode->x = 0;
slouken@0
   235
	mode->y = 0;
slouken@0
   236
	mode->w = w;
slouken@0
   237
	mode->h = h;
slouken@0
   238
slouken@0
   239
	/* Allocate the new list of modes, and fill in the new mode */
slouken@0
   240
	next_mode = SDL_nummodes[index];
slouken@0
   241
	SDL_modelist[index] = (SDL_Rect **)
slouken@0
   242
	       realloc(SDL_modelist[index], (1+next_mode+1)*sizeof(SDL_Rect *));
slouken@0
   243
	if ( SDL_modelist[index] == NULL ) {
slouken@0
   244
		SDL_OutOfMemory();
slouken@0
   245
		SDL_nummodes[index] = 0;
slouken@0
   246
		free(mode);
slouken@0
   247
		return(-1);
slouken@0
   248
	}
slouken@0
   249
	SDL_modelist[index][next_mode] = mode;
slouken@0
   250
	SDL_modelist[index][next_mode+1] = NULL;
slouken@0
   251
	SDL_nummodes[index]++;
slouken@0
   252
slouken@0
   253
	return(0);
slouken@0
   254
}
slouken@0
   255
slouken@0
   256
#endif /* !NO_CHANGEDISPLAYSETTINGS */
slouken@0
   257
slouken@0
   258
static HPALETTE DIB_CreatePalette(int bpp)
slouken@0
   259
{
slouken@0
   260
/*	RJR: March 28, 2000
slouken@0
   261
	moved palette creation here from "DIB_VideoInit" */
slouken@0
   262
slouken@0
   263
	HPALETTE handle = NULL;
slouken@0
   264
	
slouken@0
   265
	if ( bpp <= 8 )
slouken@0
   266
	{
slouken@0
   267
		LOGPALETTE *palette;
slouken@0
   268
		HDC hdc;
slouken@0
   269
		int ncolors;
slouken@0
   270
		int i;
slouken@0
   271
slouken@0
   272
		ncolors = 1;
slouken@0
   273
		for ( i=0; i<bpp; ++i ) {
slouken@0
   274
			ncolors *= 2;
slouken@0
   275
		}
slouken@0
   276
		palette = (LOGPALETTE *)malloc(sizeof(*palette)+
slouken@0
   277
					ncolors*sizeof(PALETTEENTRY));
slouken@0
   278
		palette->palVersion = 0x300;
slouken@0
   279
		palette->palNumEntries = ncolors;
slouken@0
   280
		hdc = GetDC(SDL_Window);
slouken@0
   281
		GetSystemPaletteEntries(hdc, 0, ncolors, palette->palPalEntry);
slouken@0
   282
		ReleaseDC(SDL_Window, hdc);
slouken@0
   283
		handle = CreatePalette(palette);
slouken@0
   284
		free(palette);
slouken@0
   285
	}
slouken@0
   286
	
slouken@0
   287
	return handle;
slouken@0
   288
}
slouken@0
   289
slouken@0
   290
int DIB_VideoInit(_THIS, SDL_PixelFormat *vformat)
slouken@0
   291
{
slouken@0
   292
#ifndef NO_CHANGEDISPLAYSETTINGS
slouken@0
   293
	int i;
slouken@0
   294
	DEVMODE settings;
slouken@0
   295
#endif
slouken@0
   296
slouken@0
   297
	/* Create the window */
slouken@0
   298
	if ( DIB_CreateWindow(this) < 0 ) {
slouken@0
   299
		return(-1);
slouken@0
   300
	}
slouken@169
   301
#ifndef DISABLE_AUDIO
slouken@0
   302
	DX5_SoundFocus(SDL_Window);
slouken@169
   303
#endif
slouken@0
   304
slouken@0
   305
	/* Determine the screen depth */
slouken@0
   306
	vformat->BitsPerPixel = DIB_SussScreenDepth();
slouken@0
   307
	switch (vformat->BitsPerPixel) {
slouken@0
   308
		case 15:
slouken@0
   309
			vformat->Rmask = 0x00007c00;
slouken@0
   310
			vformat->Gmask = 0x000003e0;
slouken@0
   311
			vformat->Bmask = 0x0000001f;
slouken@0
   312
			vformat->BitsPerPixel = 16;
slouken@0
   313
			break;
slouken@0
   314
		case 16:
slouken@0
   315
			vformat->Rmask = 0x0000f800;
slouken@0
   316
			vformat->Gmask = 0x000007e0;
slouken@0
   317
			vformat->Bmask = 0x0000001f;
slouken@0
   318
			break;
slouken@0
   319
		case 24:
slouken@0
   320
		case 32:
slouken@0
   321
			/* GDI defined as 8-8-8 */
slouken@0
   322
			vformat->Rmask = 0x00ff0000;
slouken@0
   323
			vformat->Gmask = 0x0000ff00;
slouken@0
   324
			vformat->Bmask = 0x000000ff;
slouken@0
   325
			break;
slouken@0
   326
		default:
slouken@0
   327
			break;
slouken@0
   328
	}
slouken@0
   329
slouken@0
   330
	/* See if gamma is supported on this screen */
slouken@0
   331
	DIB_CheckGamma(this);
slouken@0
   332
slouken@0
   333
#ifndef NO_CHANGEDISPLAYSETTINGS
slouken@0
   334
	/* Query for the list of available video modes */
slouken@0
   335
	for ( i=0; EnumDisplaySettings(NULL, i, &settings); ++i ) {
slouken@0
   336
		DIB_AddMode(this, settings.dmBitsPerPel,
slouken@0
   337
			settings.dmPelsWidth, settings.dmPelsHeight);
slouken@0
   338
	}
slouken@0
   339
	/* Sort the mode lists */
slouken@0
   340
	for ( i=0; i<NUM_MODELISTS; ++i ) {
slouken@0
   341
		if ( SDL_nummodes[i] > 0 ) {
slouken@0
   342
			qsort(SDL_modelist[i], SDL_nummodes[i], sizeof *SDL_modelist[i], cmpmodes);
slouken@0
   343
		}
slouken@0
   344
	}
slouken@0
   345
#endif /* !NO_CHANGEDISPLAYSETTINGS */
slouken@0
   346
slouken@0
   347
	/* Grab an identity palette if we are in a palettized mode */
slouken@0
   348
	if ( vformat->BitsPerPixel <= 8 ) {
slouken@0
   349
	/*	RJR: March 28, 2000
slouken@0
   350
		moved palette creation to "DIB_CreatePalette" */
slouken@0
   351
		screen_pal = DIB_CreatePalette(vformat->BitsPerPixel);
slouken@0
   352
	}
slouken@0
   353
slouken@0
   354
	/* Fill in some window manager capabilities */
slouken@0
   355
	this->info.wm_available = 1;
slouken@0
   356
slouken@0
   357
	/* We're done! */
slouken@0
   358
	return(0);
slouken@0
   359
}
slouken@0
   360
slouken@0
   361
/* We support any format at any dimension */
slouken@0
   362
SDL_Rect **DIB_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags)
slouken@0
   363
{
slouken@0
   364
#ifdef NO_CHANGEDISPLAYSETTINGS
slouken@0
   365
	return((SDL_Rect **)-1);
slouken@0
   366
#else
slouken@0
   367
	if ( (flags & SDL_FULLSCREEN) == SDL_FULLSCREEN ) {
slouken@0
   368
		return(SDL_modelist[((format->BitsPerPixel+7)/8)-1]);
slouken@0
   369
	} else {
slouken@0
   370
		return((SDL_Rect **)-1);
slouken@0
   371
	}
slouken@0
   372
#endif
slouken@0
   373
}
slouken@0
   374
slouken@0
   375
slouken@0
   376
/*
slouken@0
   377
  Helper fn to work out which screen depth windows is currently using.
slouken@0
   378
  15 bit mode is considered 555 format, 16 bit is 565.
slouken@0
   379
  returns 0 for unknown mode.
slouken@0
   380
  (Derived from code in sept 1999 Windows Developer Journal
slouken@0
   381
  http://www.wdj.com/code/archive.html)
slouken@0
   382
*/
slouken@0
   383
static int DIB_SussScreenDepth()
slouken@0
   384
{
slouken@0
   385
#ifdef NO_GETDIBITS
slouken@0
   386
	int depth;
slouken@0
   387
	HDC hdc;
slouken@0
   388
slouken@0
   389
	hdc = GetDC(SDL_Window);
slouken@0
   390
	depth = GetDeviceCaps(hdc, PLANES) * GetDeviceCaps(hdc, BITSPIXEL);
slouken@0
   391
	ReleaseDC(SDL_Window, hdc);
slouken@112
   392
#ifndef _WIN32_WCE
slouken@112
   393
	// AFAIK 16 bit CE devices have indeed RGB 565
slouken@0
   394
	if ( depth == 16 ) {
slouken@0
   395
		depth = 15;	/* GDI defined as RGB 555 */
slouken@0
   396
	}
slouken@112
   397
#endif
slouken@0
   398
	return(depth);
slouken@0
   399
#else
slouken@0
   400
    int dib_size;
slouken@0
   401
    LPBITMAPINFOHEADER dib_hdr;
slouken@0
   402
    HDC hdc;
slouken@0
   403
    HBITMAP hbm;
slouken@0
   404
slouken@0
   405
    /* Allocate enough space for a DIB header plus palette (for
slouken@0
   406
     * 8-bit modes) or bitfields (for 16- and 32-bit modes)
slouken@0
   407
     */
slouken@0
   408
    dib_size = sizeof(BITMAPINFOHEADER) + 256 * sizeof (RGBQUAD);
slouken@0
   409
    dib_hdr = (LPBITMAPINFOHEADER) malloc(dib_size);
slouken@0
   410
    memset(dib_hdr, 0, dib_size);
slouken@0
   411
    dib_hdr->biSize = sizeof(BITMAPINFOHEADER);
slouken@0
   412
    
slouken@0
   413
    /* Get a device-dependent bitmap that's compatible with the
slouken@0
   414
       screen.
slouken@0
   415
     */
slouken@0
   416
    hdc = GetDC(NULL);
slouken@0
   417
    hbm = CreateCompatibleBitmap( hdc, 1, 1 );
slouken@0
   418
slouken@0
   419
    /* Convert the DDB to a DIB.  We need to call GetDIBits twice:
slouken@0
   420
     * the first call just fills in the BITMAPINFOHEADER; the 
slouken@0
   421
     * second fills in the bitfields or palette.
slouken@0
   422
     */
slouken@0
   423
    GetDIBits(hdc, hbm, 0, 1, NULL, (LPBITMAPINFO) dib_hdr, DIB_RGB_COLORS);
slouken@0
   424
    GetDIBits(hdc, hbm, 0, 1, NULL, (LPBITMAPINFO) dib_hdr, DIB_RGB_COLORS);
slouken@0
   425
    DeleteObject(hbm);
slouken@0
   426
    ReleaseDC(NULL, hdc);
slouken@0
   427
slouken@0
   428
    switch( dib_hdr->biBitCount )
slouken@0
   429
    {
slouken@0
   430
    case 8:     return 8;
slouken@0
   431
    case 24:    return 24;
slouken@0
   432
    case 32:    return 32;
slouken@0
   433
    case 16:
slouken@0
   434
        if( dib_hdr->biCompression == BI_BITFIELDS ) {
slouken@0
   435
            /* check the red mask */
slouken@0
   436
            switch( ((DWORD*)((char*)dib_hdr + dib_hdr->biSize))[0] ) {
slouken@0
   437
                case 0xf800: return 16;    /* 565 */
slouken@0
   438
                case 0x7c00: return 15;    /* 555 */
slouken@0
   439
            }
slouken@0
   440
        }
slouken@0
   441
    }
slouken@0
   442
    return 0;    /* poo. */
slouken@0
   443
#endif /* NO_GETDIBITS */
slouken@0
   444
}
slouken@0
   445
slouken@0
   446
slouken@0
   447
/* Various screen update functions available */
slouken@0
   448
static void DIB_NormalUpdate(_THIS, int numrects, SDL_Rect *rects);
slouken@0
   449
slouken@0
   450
SDL_Surface *DIB_SetVideoMode(_THIS, SDL_Surface *current,
slouken@0
   451
				int width, int height, int bpp, Uint32 flags)
slouken@0
   452
{
slouken@0
   453
	SDL_Surface *video;
slouken@0
   454
	Uint32 prev_flags;
slouken@0
   455
	DWORD style;
slouken@0
   456
	const DWORD directstyle =
slouken@0
   457
			(WS_POPUP);
slouken@0
   458
	const DWORD windowstyle = 
slouken@0
   459
			(WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX);
slouken@0
   460
	const DWORD resizestyle =
slouken@0
   461
			(WS_THICKFRAME|WS_MAXIMIZEBOX);
slouken@0
   462
	int binfo_size;
slouken@0
   463
	BITMAPINFO *binfo;
slouken@0
   464
	HDC hdc;
slouken@0
   465
	RECT bounds;
slouken@0
   466
	int x, y;
slouken@0
   467
	Uint32 Rmask, Gmask, Bmask;
slouken@0
   468
slouken@0
   469
	/* Clean up any GL context that may be hanging around */
slouken@0
   470
	if ( current->flags & SDL_OPENGL ) {
slouken@0
   471
		WIN_GL_ShutDown(this);
slouken@0
   472
	}
slouken@0
   473
slouken@0
   474
	/* Recalculate the bitmasks if necessary */
slouken@0
   475
	if ( bpp == current->format->BitsPerPixel ) {
slouken@0
   476
		video = current;
slouken@0
   477
	} else {
slouken@0
   478
		switch (bpp) {
slouken@0
   479
			case 15:
slouken@0
   480
			case 16:
slouken@0
   481
				if ( DIB_SussScreenDepth() == 15 ) {
slouken@0
   482
					/* 5-5-5 */
slouken@0
   483
					Rmask = 0x00007c00;
slouken@0
   484
					Gmask = 0x000003e0;
slouken@0
   485
					Bmask = 0x0000001f;
slouken@0
   486
				} else {
slouken@0
   487
					/* 5-6-5 */
slouken@0
   488
					Rmask = 0x0000f800;
slouken@0
   489
					Gmask = 0x000007e0;
slouken@0
   490
					Bmask = 0x0000001f;
slouken@0
   491
				}
slouken@0
   492
				break;
slouken@0
   493
			case 24:
slouken@0
   494
			case 32:
slouken@0
   495
				/* GDI defined as 8-8-8 */
slouken@0
   496
				Rmask = 0x00ff0000;
slouken@0
   497
				Gmask = 0x0000ff00;
slouken@0
   498
				Bmask = 0x000000ff;
slouken@0
   499
				break;
slouken@0
   500
			default:
slouken@0
   501
				Rmask = 0x00000000;
slouken@0
   502
				Gmask = 0x00000000;
slouken@0
   503
				Bmask = 0x00000000;
slouken@0
   504
				break;
slouken@0
   505
		}
slouken@0
   506
		video = SDL_CreateRGBSurface(SDL_SWSURFACE,
slouken@0
   507
					0, 0, bpp, Rmask, Gmask, Bmask, 0);
slouken@0
   508
		if ( video == NULL ) {
slouken@0
   509
			SDL_OutOfMemory();
slouken@0
   510
			return(NULL);
slouken@0
   511
		}
slouken@0
   512
	}
slouken@0
   513
slouken@0
   514
	/* Fill in part of the video surface */
slouken@0
   515
	prev_flags = video->flags;
slouken@0
   516
	video->flags = 0;	/* Clear flags */
slouken@0
   517
	video->w = width;
slouken@0
   518
	video->h = height;
slouken@0
   519
	video->pitch = SDL_CalculatePitch(video);
slouken@0
   520
slouken@515
   521
#ifdef WIN32_PLATFORM_PSPC
slouken@514
   522
	 /* Stuff to hide that $#!^%#$ WinCE taskbar in fullscreen... */
slouken@514
   523
	if ( flags & SDL_FULLSCREEN ) {
slouken@514
   524
		if ( !(prev_flags & SDL_FULLSCREEN) ) {
slouken@514
   525
			SHFullScreen(SDL_Window, SHFS_HIDETASKBAR);
slouken@514
   526
			SHFullScreen(SDL_Window, SHFS_HIDESIPBUTTON);
slouken@514
   527
			ShowWindow(FindWindow(TEXT("HHTaskBar"),NULL),SW_HIDE);
slouken@514
   528
		}
slouken@514
   529
		video->flags |= SDL_FULLSCREEN;
slouken@514
   530
	} else {
slouken@514
   531
		if ( prev_flags & SDL_FULLSCREEN ) {
slouken@514
   532
			SHFullScreen(SDL_Window, SHFS_SHOWTASKBAR);
slouken@514
   533
			SHFullScreen(SDL_Window, SHFS_SHOWSIPBUTTON);
slouken@514
   534
			ShowWindow(FindWindow(TEXT("HHTaskBar"),NULL),SW_SHOWNORMAL);
slouken@514
   535
		}
slouken@514
   536
	}
slouken@514
   537
#endif
slouken@0
   538
#ifndef NO_CHANGEDISPLAYSETTINGS
slouken@0
   539
	/* Set fullscreen mode if appropriate */
slouken@0
   540
	if ( (flags & SDL_FULLSCREEN) == SDL_FULLSCREEN ) {
slouken@0
   541
		DEVMODE settings;
slouken@0
   542
slouken@0
   543
		memset(&settings, 0, sizeof(DEVMODE));
slouken@0
   544
		settings.dmSize = sizeof(DEVMODE);
slouken@0
   545
		settings.dmBitsPerPel = video->format->BitsPerPixel;
slouken@0
   546
		settings.dmPelsWidth = width;
slouken@0
   547
		settings.dmPelsHeight = height;
slouken@0
   548
		settings.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL;
slouken@0
   549
		if ( ChangeDisplaySettings(&settings, CDS_FULLSCREEN) == DISP_CHANGE_SUCCESSFUL ) {
slouken@0
   550
			video->flags |= SDL_FULLSCREEN;
slouken@304
   551
			SDL_fullscreen_mode = settings;
slouken@0
   552
		}
slouken@0
   553
	}
slouken@0
   554
#endif /* !NO_CHANGEDISPLAYSETTINGS */
slouken@0
   555
slouken@45
   556
	/* Reset the palette and create a new one if necessary */
slouken@45
   557
	if ( screen_pal != NULL ) {
slouken@45
   558
	/*	RJR: March 28, 2000
slouken@45
   559
		delete identity palette if switching from a palettized mode */
slouken@45
   560
		DeleteObject(screen_pal);
slouken@45
   561
		screen_pal = NULL;
slouken@45
   562
	}
slouken@45
   563
	if ( bpp <= 8 )
slouken@45
   564
	{
slouken@45
   565
	/*	RJR: March 28, 2000
slouken@45
   566
		create identity palette switching to a palettized mode */
slouken@45
   567
		screen_pal = DIB_CreatePalette(bpp);
slouken@45
   568
	}
slouken@45
   569
slouken@0
   570
	style = GetWindowLong(SDL_Window, GWL_STYLE);
slouken@0
   571
	style &= ~(resizestyle|WS_MAXIMIZE);
slouken@0
   572
	if ( (video->flags & SDL_FULLSCREEN) == SDL_FULLSCREEN ) {
slouken@0
   573
		style &= ~windowstyle;
slouken@0
   574
		style |= directstyle;
slouken@0
   575
	} else {
slouken@0
   576
#ifndef NO_CHANGEDISPLAYSETTINGS
slouken@0
   577
		if ( (prev_flags & SDL_FULLSCREEN) == SDL_FULLSCREEN ) {
slouken@0
   578
			ChangeDisplaySettings(NULL, 0);
slouken@0
   579
		}
slouken@0
   580
#endif
slouken@0
   581
		if ( flags & SDL_NOFRAME ) {
slouken@0
   582
			style &= ~windowstyle;
slouken@0
   583
			style |= directstyle;
slouken@0
   584
			video->flags |= SDL_NOFRAME;
slouken@0
   585
		} else {
slouken@0
   586
			style &= ~directstyle;
slouken@0
   587
			style |= windowstyle;
slouken@0
   588
			if ( flags & SDL_RESIZABLE ) {
slouken@0
   589
				style |= resizestyle;
slouken@0
   590
				video->flags |= SDL_RESIZABLE;
slouken@0
   591
			}
slouken@0
   592
		}
slouken@453
   593
#if WS_MAXIMIZE
slouken@0
   594
		if (IsZoomed(SDL_Window)) style |= WS_MAXIMIZE;
slouken@36
   595
#endif
slouken@0
   596
	}
slouken@145
   597
slouken@448
   598
	/* DJM: Don't piss of anyone who has setup his own window */
slouken@833
   599
	if ( SDL_windowid == NULL )
slouken@448
   600
		SetWindowLong(SDL_Window, GWL_STYLE, style);
slouken@0
   601
slouken@0
   602
	/* Delete the old bitmap if necessary */
slouken@0
   603
	if ( screen_bmp != NULL ) {
slouken@0
   604
		DeleteObject(screen_bmp);
slouken@0
   605
	}
slouken@0
   606
	if ( ! (flags & SDL_OPENGL) ) {
slouken@0
   607
		BOOL is16bitmode = (video->format->BytesPerPixel == 2);
slouken@0
   608
slouken@0
   609
		/* Suss out the bitmap info header */
slouken@0
   610
		binfo_size = sizeof(*binfo);
slouken@0
   611
		if( is16bitmode ) {
slouken@0
   612
			/* 16bit modes, palette area used for rgb bitmasks */
slouken@0
   613
			binfo_size += 3*sizeof(DWORD);
slouken@0
   614
		} else if ( video->format->palette ) {
slouken@0
   615
			binfo_size += video->format->palette->ncolors *
slouken@0
   616
							sizeof(RGBQUAD);
slouken@0
   617
		}
slouken@0
   618
		binfo = (BITMAPINFO *)malloc(binfo_size);
slouken@0
   619
		if ( ! binfo ) {
slouken@0
   620
			if ( video != current ) {
slouken@0
   621
				SDL_FreeSurface(video);
slouken@0
   622
			}
slouken@0
   623
			SDL_OutOfMemory();
slouken@0
   624
			return(NULL);
slouken@0
   625
		}
slouken@0
   626
slouken@0
   627
		binfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
slouken@0
   628
		binfo->bmiHeader.biWidth = video->w;
slouken@0
   629
		binfo->bmiHeader.biHeight = -video->h;	/* -ve for topdown bitmap */
slouken@0
   630
		binfo->bmiHeader.biPlanes = 1;
slouken@0
   631
		binfo->bmiHeader.biSizeImage = video->h * video->pitch;
slouken@0
   632
		binfo->bmiHeader.biXPelsPerMeter = 0;
slouken@0
   633
		binfo->bmiHeader.biYPelsPerMeter = 0;
slouken@0
   634
		binfo->bmiHeader.biClrUsed = 0;
slouken@0
   635
		binfo->bmiHeader.biClrImportant = 0;
slouken@0
   636
		binfo->bmiHeader.biBitCount = video->format->BitsPerPixel;
slouken@0
   637
slouken@0
   638
		if ( is16bitmode ) {
slouken@0
   639
			/* BI_BITFIELDS tells CreateDIBSection about the rgb masks in the palette */
slouken@0
   640
			binfo->bmiHeader.biCompression = BI_BITFIELDS;
slouken@0
   641
			((Uint32*)binfo->bmiColors)[0] = video->format->Rmask;
slouken@0
   642
			((Uint32*)binfo->bmiColors)[1] = video->format->Gmask;
slouken@0
   643
			((Uint32*)binfo->bmiColors)[2] = video->format->Bmask;
slouken@0
   644
		} else {
slouken@0
   645
			binfo->bmiHeader.biCompression = BI_RGB;	/* BI_BITFIELDS for 565 vs 555 */
slouken@0
   646
			if ( video->format->palette ) {
slouken@0
   647
				memset(binfo->bmiColors, 0,
slouken@0
   648
					video->format->palette->ncolors*sizeof(RGBQUAD));
slouken@0
   649
			}
slouken@0
   650
		}
slouken@0
   651
slouken@0
   652
		/* Create the offscreen bitmap buffer */
slouken@0
   653
		hdc = GetDC(SDL_Window);
slouken@0
   654
		screen_bmp = CreateDIBSection(hdc, binfo, DIB_RGB_COLORS,
slouken@0
   655
					(void **)(&video->pixels), NULL, 0);
slouken@0
   656
		ReleaseDC(SDL_Window, hdc);
slouken@0
   657
		free(binfo);
slouken@0
   658
		if ( screen_bmp == NULL ) {
slouken@0
   659
			if ( video != current ) {
slouken@0
   660
				SDL_FreeSurface(video);
slouken@0
   661
			}
slouken@0
   662
			SDL_SetError("Couldn't create DIB section");
slouken@0
   663
			return(NULL);
slouken@0
   664
		}
slouken@0
   665
		this->UpdateRects = DIB_NormalUpdate;
slouken@0
   666
slouken@0
   667
		/* Set video surface flags */
slouken@0
   668
		if ( bpp <= 8 ) {
slouken@0
   669
			/* BitBlt() maps colors for us */
slouken@0
   670
			video->flags |= SDL_HWPALETTE;
slouken@0
   671
		}
slouken@0
   672
	}
slouken@0
   673
slouken@0
   674
	/* Resize the window */
slouken@0
   675
	if ( SDL_windowid == NULL ) {
slouken@448
   676
		HWND top;
slouken@0
   677
		UINT swp_flags;
slouken@833
   678
		const char *window = getenv("SDL_VIDEO_WINDOW_POS");
slouken@833
   679
		const char *center = getenv("SDL_VIDEO_CENTERED");
slouken@833
   680
slouken@833
   681
		if ( !SDL_windowX && !SDL_windowY ) {
slouken@833
   682
			if ( window ) {
slouken@833
   683
				if ( sscanf(window, "%d,%d", &x, &y) == 2 ) {
slouken@833
   684
					SDL_windowX = x;
slouken@833
   685
					SDL_windowY = y;
slouken@833
   686
				}
slouken@833
   687
				if ( strcmp(window, "center") == 0 ) {
slouken@833
   688
					center = window;
slouken@833
   689
					window = NULL;
slouken@833
   690
				}
slouken@833
   691
			}
slouken@833
   692
		}
slouken@833
   693
		swp_flags = (SWP_NOCOPYBITS | SWP_SHOWWINDOW);
slouken@0
   694
slouken@0
   695
		SDL_resizing = 1;
slouken@833
   696
		bounds.left = SDL_windowX;
slouken@833
   697
		bounds.top = SDL_windowY;
slouken@833
   698
		bounds.right = SDL_windowX+video->w;
slouken@833
   699
		bounds.bottom = SDL_windowY+video->h;
slouken@453
   700
		AdjustWindowRectEx(&bounds, GetWindowLong(SDL_Window, GWL_STYLE), FALSE, 0);
slouken@0
   701
		width = bounds.right-bounds.left;
slouken@0
   702
		height = bounds.bottom-bounds.top;
slouken@833
   703
		if ( (flags & SDL_FULLSCREEN) ) {
slouken@833
   704
			x = (GetSystemMetrics(SM_CXSCREEN)-width)/2;
slouken@833
   705
			y = (GetSystemMetrics(SM_CYSCREEN)-height)/2;
slouken@971
   706
		} else if ( center ) {
slouken@971
   707
			x = (GetSystemMetrics(SM_CXSCREEN)-width)/2;
slouken@971
   708
			y = (GetSystemMetrics(SM_CYSCREEN)-height)/2;
slouken@833
   709
		} else if ( SDL_windowX || SDL_windowY || window ) {
slouken@833
   710
			x = bounds.left;
slouken@833
   711
			y = bounds.top;
slouken@833
   712
		} else {
slouken@833
   713
			x = y = -1;
slouken@833
   714
			swp_flags |= SWP_NOMOVE;
slouken@833
   715
		}
slouken@0
   716
		if ( y < 0 ) { /* Cover up title bar for more client area */
slouken@0
   717
			y -= GetSystemMetrics(SM_CYCAPTION)/2;
slouken@0
   718
		}
slouken@448
   719
		if ( flags & SDL_FULLSCREEN ) {
slouken@448
   720
			top = HWND_TOPMOST;
slouken@448
   721
		} else {
slouken@448
   722
			top = HWND_NOTOPMOST;
slouken@448
   723
		}
slouken@448
   724
		SetWindowPos(SDL_Window, top, x, y, width, height, swp_flags);
slouken@0
   725
		SDL_resizing = 0;
slouken@0
   726
		SetForegroundWindow(SDL_Window);
slouken@0
   727
	}
slouken@0
   728
slouken@0
   729
	/* Set up for OpenGL */
slouken@0
   730
	if ( flags & SDL_OPENGL ) {
slouken@0
   731
		if ( WIN_GL_SetupWindow(this) < 0 ) {
slouken@0
   732
			return(NULL);
slouken@0
   733
		}
slouken@0
   734
		video->flags |= SDL_OPENGL;
slouken@0
   735
	}
slouken@36
   736
slouken@0
   737
	/* We're live! */
slouken@0
   738
	return(video);
slouken@0
   739
}
slouken@0
   740
slouken@0
   741
/* We don't actually allow hardware surfaces in the DIB driver */
slouken@0
   742
static int DIB_AllocHWSurface(_THIS, SDL_Surface *surface)
slouken@0
   743
{
slouken@0
   744
	return(-1);
slouken@0
   745
}
slouken@0
   746
static void DIB_FreeHWSurface(_THIS, SDL_Surface *surface)
slouken@0
   747
{
slouken@0
   748
	return;
slouken@0
   749
}
slouken@0
   750
static int DIB_LockHWSurface(_THIS, SDL_Surface *surface)
slouken@0
   751
{
slouken@0
   752
	return(0);
slouken@0
   753
}
slouken@0
   754
static void DIB_UnlockHWSurface(_THIS, SDL_Surface *surface)
slouken@0
   755
{
slouken@0
   756
	return;
slouken@0
   757
}
slouken@0
   758
slouken@0
   759
static void DIB_NormalUpdate(_THIS, int numrects, SDL_Rect *rects)
slouken@0
   760
{
slouken@0
   761
	HDC hdc, mdc;
slouken@0
   762
	int i;
slouken@0
   763
slouken@0
   764
	hdc = GetDC(SDL_Window);
slouken@0
   765
	if ( screen_pal ) {
slouken@0
   766
		SelectPalette(hdc, screen_pal, FALSE);
slouken@0
   767
	}
slouken@0
   768
	mdc = CreateCompatibleDC(hdc);
slouken@0
   769
	SelectObject(mdc, screen_bmp);
slouken@0
   770
	for ( i=0; i<numrects; ++i ) {
slouken@0
   771
		BitBlt(hdc, rects[i].x, rects[i].y, rects[i].w, rects[i].h,
slouken@0
   772
					mdc, rects[i].x, rects[i].y, SRCCOPY);
slouken@0
   773
	}
slouken@0
   774
	DeleteDC(mdc);
slouken@0
   775
	ReleaseDC(SDL_Window, hdc);
slouken@0
   776
}
slouken@0
   777
slouken@0
   778
int DIB_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors)
slouken@0
   779
{
slouken@0
   780
	RGBQUAD *pal;
slouken@0
   781
	int i;
slouken@36
   782
#ifndef _WIN32_WCE
slouken@0
   783
	HDC hdc, mdc;
slouken@36
   784
#else
slouken@36
   785
	HDC hdc;
slouken@36
   786
#endif
slouken@0
   787
slouken@0
   788
	/* Update the display palette */
slouken@0
   789
	hdc = GetDC(SDL_Window);
slouken@0
   790
	if ( screen_pal ) {
slouken@0
   791
		PALETTEENTRY *entries;
slouken@0
   792
slouken@0
   793
		entries = (PALETTEENTRY *)alloca(ncolors*sizeof(PALETTEENTRY));
slouken@0
   794
		for ( i=0; i<ncolors; ++i ) {
slouken@0
   795
			entries[i].peRed   = colors[i].r;
slouken@0
   796
			entries[i].peGreen = colors[i].g;
slouken@0
   797
			entries[i].peBlue  = colors[i].b;
slouken@0
   798
			entries[i].peFlags = PC_NOCOLLAPSE;
slouken@0
   799
		}
slouken@0
   800
		SetPaletteEntries(screen_pal, firstcolor, ncolors, entries);
slouken@0
   801
		SelectPalette(hdc, screen_pal, FALSE);
slouken@0
   802
		RealizePalette(hdc);
slouken@0
   803
	}
slouken@0
   804
slouken@0
   805
	/* Copy palette colors into DIB palette */
slouken@0
   806
	pal = (RGBQUAD *)alloca(ncolors*sizeof(RGBQUAD));
slouken@0
   807
	for ( i=0; i<ncolors; ++i ) {
slouken@0
   808
		pal[i].rgbRed = colors[i].r;
slouken@0
   809
		pal[i].rgbGreen = colors[i].g;
slouken@0
   810
		pal[i].rgbBlue = colors[i].b;
slouken@0
   811
		pal[i].rgbReserved = 0;
slouken@0
   812
	}
slouken@0
   813
slouken@0
   814
	/* Set the DIB palette and update the display */
slouken@36
   815
#ifndef _WIN32_WCE
slouken@0
   816
	mdc = CreateCompatibleDC(hdc);
slouken@0
   817
	SelectObject(mdc, screen_bmp);
slouken@0
   818
	SetDIBColorTable(mdc, firstcolor, ncolors, pal);
slouken@0
   819
	BitBlt(hdc, 0, 0, this->screen->w, this->screen->h,
slouken@0
   820
	       mdc, 0, 0, SRCCOPY);
slouken@0
   821
	DeleteDC(mdc);
slouken@36
   822
#endif
slouken@0
   823
	ReleaseDC(SDL_Window, hdc);
slouken@0
   824
	return(1);
slouken@0
   825
}
slouken@0
   826
slouken@0
   827
static void DIB_CheckGamma(_THIS)
slouken@0
   828
{
slouken@0
   829
#ifndef NO_GAMMA_SUPPORT
slouken@0
   830
	HDC hdc;
slouken@0
   831
	WORD ramp[3*256];
slouken@0
   832
slouken@0
   833
	/* If we fail to get gamma, disable gamma control */
slouken@0
   834
	hdc = GetDC(SDL_Window);
slouken@0
   835
	if ( ! GetDeviceGammaRamp(hdc, ramp) ) {
slouken@0
   836
		this->GetGammaRamp = NULL;
slouken@0
   837
		this->SetGammaRamp = NULL;
slouken@0
   838
	}
slouken@0
   839
	ReleaseDC(SDL_Window, hdc);
slouken@0
   840
#endif /* !NO_GAMMA_SUPPORT */
slouken@0
   841
}
slouken@338
   842
void DIB_SwapGamma(_THIS)
slouken@0
   843
{
slouken@0
   844
#ifndef NO_GAMMA_SUPPORT
slouken@0
   845
	HDC hdc;
slouken@0
   846
slouken@0
   847
	if ( gamma_saved ) {
slouken@0
   848
		hdc = GetDC(SDL_Window);
slouken@0
   849
		if ( SDL_GetAppState() & SDL_APPINPUTFOCUS ) {
slouken@0
   850
			/* About to leave active state, restore gamma */
slouken@0
   851
			SetDeviceGammaRamp(hdc, gamma_saved);
slouken@0
   852
		} else {
slouken@0
   853
			/* About to enter active state, set game gamma */
slouken@0
   854
			GetDeviceGammaRamp(hdc, gamma_saved);
slouken@0
   855
			SetDeviceGammaRamp(hdc, this->gamma);
slouken@0
   856
		}
slouken@0
   857
		ReleaseDC(SDL_Window, hdc);
slouken@0
   858
	}
slouken@0
   859
#endif /* !NO_GAMMA_SUPPORT */
slouken@0
   860
}
slouken@338
   861
void DIB_QuitGamma(_THIS)
slouken@0
   862
{
slouken@0
   863
#ifndef NO_GAMMA_SUPPORT
slouken@0
   864
	if ( gamma_saved ) {
slouken@0
   865
		/* Restore the original gamma if necessary */
slouken@0
   866
		if ( SDL_GetAppState() & SDL_APPINPUTFOCUS ) {
slouken@0
   867
			HDC hdc;
slouken@0
   868
slouken@0
   869
			hdc = GetDC(SDL_Window);
slouken@0
   870
			SetDeviceGammaRamp(hdc, gamma_saved);
slouken@0
   871
			ReleaseDC(SDL_Window, hdc);
slouken@0
   872
		}
slouken@0
   873
slouken@0
   874
		/* Free the saved gamma memory */
slouken@0
   875
		free(gamma_saved);
slouken@0
   876
		gamma_saved = 0;
slouken@0
   877
	}
slouken@0
   878
#endif /* !NO_GAMMA_SUPPORT */
slouken@0
   879
}
slouken@0
   880
slouken@338
   881
int DIB_SetGammaRamp(_THIS, Uint16 *ramp)
slouken@0
   882
{
slouken@338
   883
#ifdef NO_GAMMA_SUPPORT
slouken@338
   884
	SDL_SetError("SDL compiled without gamma ramp support");
slouken@338
   885
	return -1;
slouken@338
   886
#else
slouken@0
   887
	HDC hdc;
slouken@0
   888
	BOOL succeeded;
slouken@0
   889
slouken@0
   890
	/* Set the ramp for the display */
slouken@0
   891
	if ( ! gamma_saved ) {
slouken@0
   892
		gamma_saved = (WORD *)malloc(3*256*sizeof(*gamma_saved));
slouken@0
   893
		if ( ! gamma_saved ) {
slouken@0
   894
			SDL_OutOfMemory();
slouken@0
   895
			return -1;
slouken@0
   896
		}
slouken@0
   897
		hdc = GetDC(SDL_Window);
slouken@0
   898
		GetDeviceGammaRamp(hdc, gamma_saved);
slouken@0
   899
		ReleaseDC(SDL_Window, hdc);
slouken@0
   900
	}
slouken@0
   901
	if ( SDL_GetAppState() & SDL_APPINPUTFOCUS ) {
slouken@0
   902
		hdc = GetDC(SDL_Window);
slouken@0
   903
		succeeded = SetDeviceGammaRamp(hdc, ramp);
slouken@0
   904
		ReleaseDC(SDL_Window, hdc);
slouken@0
   905
	} else {
slouken@0
   906
		succeeded = TRUE;
slouken@0
   907
	}
slouken@0
   908
	return succeeded ? 0 : -1;
slouken@338
   909
#endif /* !NO_GAMMA_SUPPORT */
slouken@0
   910
}
slouken@0
   911
slouken@338
   912
int DIB_GetGammaRamp(_THIS, Uint16 *ramp)
slouken@0
   913
{
slouken@338
   914
#ifdef NO_GAMMA_SUPPORT
slouken@338
   915
	SDL_SetError("SDL compiled without gamma ramp support");
slouken@338
   916
	return -1;
slouken@338
   917
#else
slouken@0
   918
	HDC hdc;
slouken@0
   919
	BOOL succeeded;
slouken@0
   920
slouken@0
   921
	/* Get the ramp from the display */
slouken@0
   922
	hdc = GetDC(SDL_Window);
slouken@0
   923
	succeeded = GetDeviceGammaRamp(hdc, ramp);
slouken@0
   924
	ReleaseDC(SDL_Window, hdc);
slouken@0
   925
	return succeeded ? 0 : -1;
slouken@338
   926
#endif /* !NO_GAMMA_SUPPORT */
slouken@0
   927
}
slouken@0
   928
slouken@442
   929
static void FlushMessageQueue()
slouken@442
   930
{
slouken@442
   931
	MSG  msg;
slouken@442
   932
	while ( PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) ) {
slouken@442
   933
		if ( msg.message == WM_QUIT ) break;
slouken@442
   934
		TranslateMessage( &msg );
slouken@442
   935
		DispatchMessage( &msg );
slouken@442
   936
	}
slouken@442
   937
}
slouken@442
   938
slouken@0
   939
void DIB_VideoQuit(_THIS)
slouken@0
   940
{
slouken@0
   941
	/* Destroy the window and everything associated with it */
slouken@0
   942
	if ( SDL_Window ) {
slouken@0
   943
		/* Delete the screen bitmap (also frees screen->pixels) */
slouken@0
   944
		if ( this->screen ) {
slouken@515
   945
#ifdef WIN32_PLATFORM_PSPC
slouken@515
   946
			if ( this->screen->flags & SDL_FULLSCREEN ) {
slouken@515
   947
				/* Unhide taskbar, etc. */
slouken@515
   948
				SHFullScreen(SDL_Window, SHFS_SHOWTASKBAR);
slouken@515
   949
				SHFullScreen(SDL_Window, SHFS_SHOWSIPBUTTON);
slouken@515
   950
				ShowWindow(FindWindow(TEXT("HHTaskBar"),NULL),SW_SHOWNORMAL);
slouken@515
   951
			}
slouken@515
   952
#endif
slouken@0
   953
#ifndef NO_CHANGEDISPLAYSETTINGS
slouken@0
   954
			if ( this->screen->flags & SDL_FULLSCREEN ) {
slouken@0
   955
				ChangeDisplaySettings(NULL, 0);
slouken@376
   956
				ShowWindow(SDL_Window, SW_HIDE);
slouken@0
   957
			}
slouken@0
   958
#endif
slouken@0
   959
			if ( this->screen->flags & SDL_OPENGL ) {
slouken@0
   960
				WIN_GL_ShutDown(this);
slouken@0
   961
			}
slouken@0
   962
			this->screen->pixels = NULL;
slouken@0
   963
		}
slouken@0
   964
		if ( screen_bmp ) {
slouken@0
   965
			DeleteObject(screen_bmp);
slouken@0
   966
			screen_bmp = NULL;
slouken@0
   967
		}
slouken@0
   968
		if ( screen_icn ) {
slouken@0
   969
			DestroyIcon(screen_icn);
slouken@0
   970
			screen_icn = NULL;
slouken@0
   971
		}
slouken@0
   972
		DIB_QuitGamma(this);
slouken@0
   973
		DIB_DestroyWindow(this);
icculus@1145
   974
		SDL_UnregisterApp();
slouken@442
   975
		FlushMessageQueue();
slouken@0
   976
slouken@0
   977
		SDL_Window = NULL;
slouken@0
   978
	}
slouken@0
   979
}
slouken@0
   980
slouken@0
   981
/* Exported for the windows message loop only */
slouken@0
   982
static void DIB_FocusPalette(_THIS, int foreground)
slouken@0
   983
{
slouken@0
   984
	if ( screen_pal != NULL ) {
slouken@0
   985
		HDC hdc;
slouken@0
   986
slouken@0
   987
		hdc = GetDC(SDL_Window);
slouken@0
   988
		SelectPalette(hdc, screen_pal, FALSE);
slouken@0
   989
		if ( RealizePalette(hdc) )
slouken@0
   990
			InvalidateRect(SDL_Window, NULL, FALSE);
slouken@0
   991
		ReleaseDC(SDL_Window, hdc);
slouken@0
   992
	}
slouken@0
   993
}
slouken@0
   994
static void DIB_RealizePalette(_THIS)
slouken@0
   995
{
slouken@0
   996
	DIB_FocusPalette(this, 1);
slouken@0
   997
}
slouken@0
   998
static void DIB_PaletteChanged(_THIS, HWND window)
slouken@0
   999
{
slouken@0
  1000
	if ( window != SDL_Window ) {
slouken@0
  1001
		DIB_FocusPalette(this, 0);
slouken@0
  1002
	}
slouken@0
  1003
}
slouken@0
  1004
slouken@0
  1005
/* Exported for the windows message loop only */
slouken@0
  1006
static void DIB_WinPAINT(_THIS, HDC hdc)
slouken@0
  1007
{
slouken@0
  1008
	HDC mdc;
slouken@0
  1009
slouken@0
  1010
	if ( screen_pal ) {
slouken@0
  1011
		SelectPalette(hdc, screen_pal, FALSE);
slouken@0
  1012
	}
slouken@0
  1013
	mdc = CreateCompatibleDC(hdc);
slouken@0
  1014
	SelectObject(mdc, screen_bmp);
slouken@0
  1015
	BitBlt(hdc, 0, 0, SDL_VideoSurface->w, SDL_VideoSurface->h,
slouken@0
  1016
							mdc, 0, 0, SRCCOPY);
slouken@0
  1017
	DeleteDC(mdc);
slouken@0
  1018
}
slouken@0
  1019
slouken@0
  1020
/* Stub in case DirectX isn't available */
slouken@0
  1021
#ifndef ENABLE_DIRECTX
slouken@0
  1022
void DX5_SoundFocus(HWND hwnd)
slouken@0
  1023
{
slouken@0
  1024
	return;
slouken@0
  1025
}
slouken@0
  1026
#endif