src/video/windib/SDL_dibvideo.c
author Sam Lantinga <slouken@libsdl.org>
Sun, 04 Jan 2004 15:48:44 +0000
changeset 766 ed57c876700d
parent 515 230b156829ed
child 833 31fa08b36380
permissions -rw-r--r--
Date: Wed, 26 Nov 2003 01:52:02 +0800
From: "Andy Pfiffer"
Subject: [SDL] patch: PocketPC 2000 diffs for release_1_2_6

I was making a backup of my current workspace of SDL for PocketPC,
and thought I would send out my diffs.

Apologies in advance if the patch has become whitespace mangled.

These diffs are relative to CVS tag release_1_2_6, and contain (I think)
all changes that have been mentioned on the mailing list in the last
few months.

I only have PocketPC 2000 & an ARM-based device (iPaq 3635), and I
only use Embedded Visual Tools 3.0, so I can't say for sure if it
breaks other PocketPC 200[023] builds.
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@0
   204
    if(a->w > b->w)
slouken@0
   205
        return -1;
slouken@0
   206
    return b->h - a->h;
slouken@0
   207
}
slouken@0
   208
slouken@0
   209
static int DIB_AddMode(_THIS, int bpp, int w, int h)
slouken@0
   210
{
slouken@0
   211
	SDL_Rect *mode;
slouken@0
   212
	int i, index;
slouken@0
   213
	int next_mode;
slouken@0
   214
slouken@0
   215
	/* Check to see if we already have this mode */
slouken@0
   216
	if ( bpp < 8 ) {  /* Not supported */
slouken@0
   217
		return(0);
slouken@0
   218
	}
slouken@0
   219
	index = ((bpp+7)/8)-1;
slouken@0
   220
	for ( i=0; i<SDL_nummodes[index]; ++i ) {
slouken@0
   221
		mode = SDL_modelist[index][i];
slouken@0
   222
		if ( (mode->w == w) && (mode->h == h) ) {
slouken@0
   223
			return(0);
slouken@0
   224
		}
slouken@0
   225
	}
slouken@0
   226
slouken@0
   227
	/* Set up the new video mode rectangle */
slouken@0
   228
	mode = (SDL_Rect *)malloc(sizeof *mode);
slouken@0
   229
	if ( mode == NULL ) {
slouken@0
   230
		SDL_OutOfMemory();
slouken@0
   231
		return(-1);
slouken@0
   232
	}
slouken@0
   233
	mode->x = 0;
slouken@0
   234
	mode->y = 0;
slouken@0
   235
	mode->w = w;
slouken@0
   236
	mode->h = h;
slouken@0
   237
slouken@0
   238
	/* Allocate the new list of modes, and fill in the new mode */
slouken@0
   239
	next_mode = SDL_nummodes[index];
slouken@0
   240
	SDL_modelist[index] = (SDL_Rect **)
slouken@0
   241
	       realloc(SDL_modelist[index], (1+next_mode+1)*sizeof(SDL_Rect *));
slouken@0
   242
	if ( SDL_modelist[index] == NULL ) {
slouken@0
   243
		SDL_OutOfMemory();
slouken@0
   244
		SDL_nummodes[index] = 0;
slouken@0
   245
		free(mode);
slouken@0
   246
		return(-1);
slouken@0
   247
	}
slouken@0
   248
	SDL_modelist[index][next_mode] = mode;
slouken@0
   249
	SDL_modelist[index][next_mode+1] = NULL;
slouken@0
   250
	SDL_nummodes[index]++;
slouken@0
   251
slouken@0
   252
	return(0);
slouken@0
   253
}
slouken@0
   254
slouken@0
   255
#endif /* !NO_CHANGEDISPLAYSETTINGS */
slouken@0
   256
slouken@0
   257
static HPALETTE DIB_CreatePalette(int bpp)
slouken@0
   258
{
slouken@0
   259
/*	RJR: March 28, 2000
slouken@0
   260
	moved palette creation here from "DIB_VideoInit" */
slouken@0
   261
slouken@0
   262
	HPALETTE handle = NULL;
slouken@0
   263
	
slouken@0
   264
	if ( bpp <= 8 )
slouken@0
   265
	{
slouken@0
   266
		LOGPALETTE *palette;
slouken@0
   267
		HDC hdc;
slouken@0
   268
		int ncolors;
slouken@0
   269
		int i;
slouken@0
   270
slouken@0
   271
		ncolors = 1;
slouken@0
   272
		for ( i=0; i<bpp; ++i ) {
slouken@0
   273
			ncolors *= 2;
slouken@0
   274
		}
slouken@0
   275
		palette = (LOGPALETTE *)malloc(sizeof(*palette)+
slouken@0
   276
					ncolors*sizeof(PALETTEENTRY));
slouken@0
   277
		palette->palVersion = 0x300;
slouken@0
   278
		palette->palNumEntries = ncolors;
slouken@0
   279
		hdc = GetDC(SDL_Window);
slouken@0
   280
		GetSystemPaletteEntries(hdc, 0, ncolors, palette->palPalEntry);
slouken@0
   281
		ReleaseDC(SDL_Window, hdc);
slouken@0
   282
		handle = CreatePalette(palette);
slouken@0
   283
		free(palette);
slouken@0
   284
	}
slouken@0
   285
	
slouken@0
   286
	return handle;
slouken@0
   287
}
slouken@0
   288
slouken@0
   289
int DIB_VideoInit(_THIS, SDL_PixelFormat *vformat)
slouken@0
   290
{
slouken@0
   291
#ifndef NO_CHANGEDISPLAYSETTINGS
slouken@0
   292
	int i;
slouken@0
   293
	DEVMODE settings;
slouken@0
   294
#endif
slouken@0
   295
slouken@0
   296
	/* Create the window */
slouken@0
   297
	if ( DIB_CreateWindow(this) < 0 ) {
slouken@0
   298
		return(-1);
slouken@0
   299
	}
slouken@169
   300
#ifndef DISABLE_AUDIO
slouken@0
   301
	DX5_SoundFocus(SDL_Window);
slouken@169
   302
#endif
slouken@0
   303
slouken@0
   304
	/* Determine the screen depth */
slouken@0
   305
	vformat->BitsPerPixel = DIB_SussScreenDepth();
slouken@0
   306
	switch (vformat->BitsPerPixel) {
slouken@0
   307
		case 15:
slouken@0
   308
			vformat->Rmask = 0x00007c00;
slouken@0
   309
			vformat->Gmask = 0x000003e0;
slouken@0
   310
			vformat->Bmask = 0x0000001f;
slouken@0
   311
			vformat->BitsPerPixel = 16;
slouken@0
   312
			break;
slouken@0
   313
		case 16:
slouken@0
   314
			vformat->Rmask = 0x0000f800;
slouken@0
   315
			vformat->Gmask = 0x000007e0;
slouken@0
   316
			vformat->Bmask = 0x0000001f;
slouken@0
   317
			break;
slouken@0
   318
		case 24:
slouken@0
   319
		case 32:
slouken@0
   320
			/* GDI defined as 8-8-8 */
slouken@0
   321
			vformat->Rmask = 0x00ff0000;
slouken@0
   322
			vformat->Gmask = 0x0000ff00;
slouken@0
   323
			vformat->Bmask = 0x000000ff;
slouken@0
   324
			break;
slouken@0
   325
		default:
slouken@0
   326
			break;
slouken@0
   327
	}
slouken@0
   328
slouken@0
   329
	/* See if gamma is supported on this screen */
slouken@0
   330
	DIB_CheckGamma(this);
slouken@0
   331
slouken@0
   332
#ifndef NO_CHANGEDISPLAYSETTINGS
slouken@0
   333
	/* Query for the list of available video modes */
slouken@0
   334
	for ( i=0; EnumDisplaySettings(NULL, i, &settings); ++i ) {
slouken@0
   335
		DIB_AddMode(this, settings.dmBitsPerPel,
slouken@0
   336
			settings.dmPelsWidth, settings.dmPelsHeight);
slouken@0
   337
	}
slouken@0
   338
	/* Sort the mode lists */
slouken@0
   339
	for ( i=0; i<NUM_MODELISTS; ++i ) {
slouken@0
   340
		if ( SDL_nummodes[i] > 0 ) {
slouken@0
   341
			qsort(SDL_modelist[i], SDL_nummodes[i], sizeof *SDL_modelist[i], cmpmodes);
slouken@0
   342
		}
slouken@0
   343
	}
slouken@0
   344
#endif /* !NO_CHANGEDISPLAYSETTINGS */
slouken@0
   345
slouken@0
   346
	/* Grab an identity palette if we are in a palettized mode */
slouken@0
   347
	if ( vformat->BitsPerPixel <= 8 ) {
slouken@0
   348
	/*	RJR: March 28, 2000
slouken@0
   349
		moved palette creation to "DIB_CreatePalette" */
slouken@0
   350
		screen_pal = DIB_CreatePalette(vformat->BitsPerPixel);
slouken@0
   351
	}
slouken@0
   352
slouken@0
   353
	/* Fill in some window manager capabilities */
slouken@0
   354
	this->info.wm_available = 1;
slouken@0
   355
slouken@0
   356
	/* We're done! */
slouken@0
   357
	return(0);
slouken@0
   358
}
slouken@0
   359
slouken@0
   360
/* We support any format at any dimension */
slouken@0
   361
SDL_Rect **DIB_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags)
slouken@0
   362
{
slouken@0
   363
#ifdef NO_CHANGEDISPLAYSETTINGS
slouken@0
   364
	return((SDL_Rect **)-1);
slouken@0
   365
#else
slouken@0
   366
	if ( (flags & SDL_FULLSCREEN) == SDL_FULLSCREEN ) {
slouken@0
   367
		return(SDL_modelist[((format->BitsPerPixel+7)/8)-1]);
slouken@0
   368
	} else {
slouken@0
   369
		return((SDL_Rect **)-1);
slouken@0
   370
	}
slouken@0
   371
#endif
slouken@0
   372
}
slouken@0
   373
slouken@0
   374
slouken@0
   375
/*
slouken@0
   376
  Helper fn to work out which screen depth windows is currently using.
slouken@0
   377
  15 bit mode is considered 555 format, 16 bit is 565.
slouken@0
   378
  returns 0 for unknown mode.
slouken@0
   379
  (Derived from code in sept 1999 Windows Developer Journal
slouken@0
   380
  http://www.wdj.com/code/archive.html)
slouken@0
   381
*/
slouken@0
   382
static int DIB_SussScreenDepth()
slouken@0
   383
{
slouken@0
   384
#ifdef NO_GETDIBITS
slouken@0
   385
	int depth;
slouken@0
   386
	HDC hdc;
slouken@0
   387
slouken@0
   388
	hdc = GetDC(SDL_Window);
slouken@0
   389
	depth = GetDeviceCaps(hdc, PLANES) * GetDeviceCaps(hdc, BITSPIXEL);
slouken@0
   390
	ReleaseDC(SDL_Window, hdc);
slouken@112
   391
#ifndef _WIN32_WCE
slouken@112
   392
	// AFAIK 16 bit CE devices have indeed RGB 565
slouken@0
   393
	if ( depth == 16 ) {
slouken@0
   394
		depth = 15;	/* GDI defined as RGB 555 */
slouken@0
   395
	}
slouken@112
   396
#endif
slouken@0
   397
	return(depth);
slouken@0
   398
#else
slouken@0
   399
    int dib_size;
slouken@0
   400
    LPBITMAPINFOHEADER dib_hdr;
slouken@0
   401
    HDC hdc;
slouken@0
   402
    HBITMAP hbm;
slouken@0
   403
slouken@0
   404
    /* Allocate enough space for a DIB header plus palette (for
slouken@0
   405
     * 8-bit modes) or bitfields (for 16- and 32-bit modes)
slouken@0
   406
     */
slouken@0
   407
    dib_size = sizeof(BITMAPINFOHEADER) + 256 * sizeof (RGBQUAD);
slouken@0
   408
    dib_hdr = (LPBITMAPINFOHEADER) malloc(dib_size);
slouken@0
   409
    memset(dib_hdr, 0, dib_size);
slouken@0
   410
    dib_hdr->biSize = sizeof(BITMAPINFOHEADER);
slouken@0
   411
    
slouken@0
   412
    /* Get a device-dependent bitmap that's compatible with the
slouken@0
   413
       screen.
slouken@0
   414
     */
slouken@0
   415
    hdc = GetDC(NULL);
slouken@0
   416
    hbm = CreateCompatibleBitmap( hdc, 1, 1 );
slouken@0
   417
slouken@0
   418
    /* Convert the DDB to a DIB.  We need to call GetDIBits twice:
slouken@0
   419
     * the first call just fills in the BITMAPINFOHEADER; the 
slouken@0
   420
     * second fills in the bitfields or palette.
slouken@0
   421
     */
slouken@0
   422
    GetDIBits(hdc, hbm, 0, 1, NULL, (LPBITMAPINFO) dib_hdr, DIB_RGB_COLORS);
slouken@0
   423
    GetDIBits(hdc, hbm, 0, 1, NULL, (LPBITMAPINFO) dib_hdr, DIB_RGB_COLORS);
slouken@0
   424
    DeleteObject(hbm);
slouken@0
   425
    ReleaseDC(NULL, hdc);
slouken@0
   426
slouken@0
   427
    switch( dib_hdr->biBitCount )
slouken@0
   428
    {
slouken@0
   429
    case 8:     return 8;
slouken@0
   430
    case 24:    return 24;
slouken@0
   431
    case 32:    return 32;
slouken@0
   432
    case 16:
slouken@0
   433
        if( dib_hdr->biCompression == BI_BITFIELDS ) {
slouken@0
   434
            /* check the red mask */
slouken@0
   435
            switch( ((DWORD*)((char*)dib_hdr + dib_hdr->biSize))[0] ) {
slouken@0
   436
                case 0xf800: return 16;    /* 565 */
slouken@0
   437
                case 0x7c00: return 15;    /* 555 */
slouken@0
   438
            }
slouken@0
   439
        }
slouken@0
   440
    }
slouken@0
   441
    return 0;    /* poo. */
slouken@0
   442
#endif /* NO_GETDIBITS */
slouken@0
   443
}
slouken@0
   444
slouken@0
   445
slouken@0
   446
/* Various screen update functions available */
slouken@0
   447
static void DIB_NormalUpdate(_THIS, int numrects, SDL_Rect *rects);
slouken@0
   448
slouken@0
   449
SDL_Surface *DIB_SetVideoMode(_THIS, SDL_Surface *current,
slouken@0
   450
				int width, int height, int bpp, Uint32 flags)
slouken@0
   451
{
slouken@0
   452
	SDL_Surface *video;
slouken@0
   453
	Uint32 prev_flags;
slouken@0
   454
	DWORD style;
slouken@0
   455
	const DWORD directstyle =
slouken@0
   456
			(WS_POPUP);
slouken@0
   457
	const DWORD windowstyle = 
slouken@0
   458
			(WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX);
slouken@0
   459
	const DWORD resizestyle =
slouken@0
   460
			(WS_THICKFRAME|WS_MAXIMIZEBOX);
slouken@0
   461
	int binfo_size;
slouken@0
   462
	BITMAPINFO *binfo;
slouken@0
   463
	HDC hdc;
slouken@0
   464
	RECT bounds;
slouken@0
   465
	int x, y;
slouken@0
   466
	BOOL was_visible;
slouken@0
   467
	Uint32 Rmask, Gmask, Bmask;
slouken@0
   468
slouken@0
   469
	/* See whether or not we should center the window */
slouken@0
   470
	was_visible = IsWindowVisible(SDL_Window);
slouken@0
   471
slouken@0
   472
	/* Clean up any GL context that may be hanging around */
slouken@0
   473
	if ( current->flags & SDL_OPENGL ) {
slouken@0
   474
		WIN_GL_ShutDown(this);
slouken@0
   475
	}
slouken@0
   476
slouken@0
   477
	/* Recalculate the bitmasks if necessary */
slouken@0
   478
	if ( bpp == current->format->BitsPerPixel ) {
slouken@0
   479
		video = current;
slouken@0
   480
	} else {
slouken@0
   481
		switch (bpp) {
slouken@0
   482
			case 15:
slouken@0
   483
			case 16:
slouken@0
   484
				if ( DIB_SussScreenDepth() == 15 ) {
slouken@0
   485
					/* 5-5-5 */
slouken@0
   486
					Rmask = 0x00007c00;
slouken@0
   487
					Gmask = 0x000003e0;
slouken@0
   488
					Bmask = 0x0000001f;
slouken@0
   489
				} else {
slouken@0
   490
					/* 5-6-5 */
slouken@0
   491
					Rmask = 0x0000f800;
slouken@0
   492
					Gmask = 0x000007e0;
slouken@0
   493
					Bmask = 0x0000001f;
slouken@0
   494
				}
slouken@0
   495
				break;
slouken@0
   496
			case 24:
slouken@0
   497
			case 32:
slouken@0
   498
				/* GDI defined as 8-8-8 */
slouken@0
   499
				Rmask = 0x00ff0000;
slouken@0
   500
				Gmask = 0x0000ff00;
slouken@0
   501
				Bmask = 0x000000ff;
slouken@0
   502
				break;
slouken@0
   503
			default:
slouken@0
   504
				Rmask = 0x00000000;
slouken@0
   505
				Gmask = 0x00000000;
slouken@0
   506
				Bmask = 0x00000000;
slouken@0
   507
				break;
slouken@0
   508
		}
slouken@0
   509
		video = SDL_CreateRGBSurface(SDL_SWSURFACE,
slouken@0
   510
					0, 0, bpp, Rmask, Gmask, Bmask, 0);
slouken@0
   511
		if ( video == NULL ) {
slouken@0
   512
			SDL_OutOfMemory();
slouken@0
   513
			return(NULL);
slouken@0
   514
		}
slouken@0
   515
	}
slouken@0
   516
slouken@0
   517
	/* Fill in part of the video surface */
slouken@0
   518
	prev_flags = video->flags;
slouken@0
   519
	video->flags = 0;	/* Clear flags */
slouken@0
   520
	video->w = width;
slouken@0
   521
	video->h = height;
slouken@0
   522
	video->pitch = SDL_CalculatePitch(video);
slouken@0
   523
slouken@515
   524
#ifdef WIN32_PLATFORM_PSPC
slouken@514
   525
	 /* Stuff to hide that $#!^%#$ WinCE taskbar in fullscreen... */
slouken@514
   526
	if ( flags & SDL_FULLSCREEN ) {
slouken@514
   527
		if ( !(prev_flags & SDL_FULLSCREEN) ) {
slouken@514
   528
			SHFullScreen(SDL_Window, SHFS_HIDETASKBAR);
slouken@514
   529
			SHFullScreen(SDL_Window, SHFS_HIDESIPBUTTON);
slouken@514
   530
			ShowWindow(FindWindow(TEXT("HHTaskBar"),NULL),SW_HIDE);
slouken@514
   531
		}
slouken@514
   532
		video->flags |= SDL_FULLSCREEN;
slouken@514
   533
	} else {
slouken@514
   534
		if ( prev_flags & SDL_FULLSCREEN ) {
slouken@514
   535
			SHFullScreen(SDL_Window, SHFS_SHOWTASKBAR);
slouken@514
   536
			SHFullScreen(SDL_Window, SHFS_SHOWSIPBUTTON);
slouken@514
   537
			ShowWindow(FindWindow(TEXT("HHTaskBar"),NULL),SW_SHOWNORMAL);
slouken@514
   538
		}
slouken@514
   539
	}
slouken@514
   540
#endif
slouken@0
   541
#ifndef NO_CHANGEDISPLAYSETTINGS
slouken@0
   542
	/* Set fullscreen mode if appropriate */
slouken@0
   543
	if ( (flags & SDL_FULLSCREEN) == SDL_FULLSCREEN ) {
slouken@0
   544
		DEVMODE settings;
slouken@0
   545
slouken@0
   546
		memset(&settings, 0, sizeof(DEVMODE));
slouken@0
   547
		settings.dmSize = sizeof(DEVMODE);
slouken@0
   548
		settings.dmBitsPerPel = video->format->BitsPerPixel;
slouken@0
   549
		settings.dmPelsWidth = width;
slouken@0
   550
		settings.dmPelsHeight = height;
slouken@0
   551
		settings.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL;
slouken@0
   552
		if ( ChangeDisplaySettings(&settings, CDS_FULLSCREEN) == DISP_CHANGE_SUCCESSFUL ) {
slouken@0
   553
			video->flags |= SDL_FULLSCREEN;
slouken@304
   554
			SDL_fullscreen_mode = settings;
slouken@0
   555
		}
slouken@0
   556
	}
slouken@0
   557
#endif /* !NO_CHANGEDISPLAYSETTINGS */
slouken@0
   558
slouken@45
   559
	/* Reset the palette and create a new one if necessary */
slouken@45
   560
	if ( screen_pal != NULL ) {
slouken@45
   561
	/*	RJR: March 28, 2000
slouken@45
   562
		delete identity palette if switching from a palettized mode */
slouken@45
   563
		DeleteObject(screen_pal);
slouken@45
   564
		screen_pal = NULL;
slouken@45
   565
	}
slouken@45
   566
	if ( bpp <= 8 )
slouken@45
   567
	{
slouken@45
   568
	/*	RJR: March 28, 2000
slouken@45
   569
		create identity palette switching to a palettized mode */
slouken@45
   570
		screen_pal = DIB_CreatePalette(bpp);
slouken@45
   571
	}
slouken@45
   572
slouken@0
   573
	style = GetWindowLong(SDL_Window, GWL_STYLE);
slouken@0
   574
	style &= ~(resizestyle|WS_MAXIMIZE);
slouken@0
   575
	if ( (video->flags & SDL_FULLSCREEN) == SDL_FULLSCREEN ) {
slouken@0
   576
		style &= ~windowstyle;
slouken@0
   577
		style |= directstyle;
slouken@0
   578
	} else {
slouken@0
   579
#ifndef NO_CHANGEDISPLAYSETTINGS
slouken@0
   580
		if ( (prev_flags & SDL_FULLSCREEN) == SDL_FULLSCREEN ) {
slouken@0
   581
			ChangeDisplaySettings(NULL, 0);
slouken@0
   582
		}
slouken@0
   583
#endif
slouken@0
   584
		if ( flags & SDL_NOFRAME ) {
slouken@0
   585
			style &= ~windowstyle;
slouken@0
   586
			style |= directstyle;
slouken@0
   587
			video->flags |= SDL_NOFRAME;
slouken@0
   588
		} else {
slouken@0
   589
			style &= ~directstyle;
slouken@0
   590
			style |= windowstyle;
slouken@0
   591
			if ( flags & SDL_RESIZABLE ) {
slouken@0
   592
				style |= resizestyle;
slouken@0
   593
				video->flags |= SDL_RESIZABLE;
slouken@0
   594
			}
slouken@0
   595
		}
slouken@453
   596
#if WS_MAXIMIZE
slouken@0
   597
		if (IsZoomed(SDL_Window)) style |= WS_MAXIMIZE;
slouken@36
   598
#endif
slouken@0
   599
	}
slouken@145
   600
slouken@448
   601
	/* DJM: Don't piss of anyone who has setup his own window */
slouken@448
   602
	if (!SDL_windowid)
slouken@448
   603
		SetWindowLong(SDL_Window, GWL_STYLE, style);
slouken@0
   604
slouken@0
   605
	/* Delete the old bitmap if necessary */
slouken@0
   606
	if ( screen_bmp != NULL ) {
slouken@0
   607
		DeleteObject(screen_bmp);
slouken@0
   608
	}
slouken@0
   609
	if ( ! (flags & SDL_OPENGL) ) {
slouken@0
   610
		BOOL is16bitmode = (video->format->BytesPerPixel == 2);
slouken@0
   611
slouken@0
   612
		/* Suss out the bitmap info header */
slouken@0
   613
		binfo_size = sizeof(*binfo);
slouken@0
   614
		if( is16bitmode ) {
slouken@0
   615
			/* 16bit modes, palette area used for rgb bitmasks */
slouken@0
   616
			binfo_size += 3*sizeof(DWORD);
slouken@0
   617
		} else if ( video->format->palette ) {
slouken@0
   618
			binfo_size += video->format->palette->ncolors *
slouken@0
   619
							sizeof(RGBQUAD);
slouken@0
   620
		}
slouken@0
   621
		binfo = (BITMAPINFO *)malloc(binfo_size);
slouken@0
   622
		if ( ! binfo ) {
slouken@0
   623
			if ( video != current ) {
slouken@0
   624
				SDL_FreeSurface(video);
slouken@0
   625
			}
slouken@0
   626
			SDL_OutOfMemory();
slouken@0
   627
			return(NULL);
slouken@0
   628
		}
slouken@0
   629
slouken@0
   630
		binfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
slouken@0
   631
		binfo->bmiHeader.biWidth = video->w;
slouken@0
   632
		binfo->bmiHeader.biHeight = -video->h;	/* -ve for topdown bitmap */
slouken@0
   633
		binfo->bmiHeader.biPlanes = 1;
slouken@0
   634
		binfo->bmiHeader.biSizeImage = video->h * video->pitch;
slouken@0
   635
		binfo->bmiHeader.biXPelsPerMeter = 0;
slouken@0
   636
		binfo->bmiHeader.biYPelsPerMeter = 0;
slouken@0
   637
		binfo->bmiHeader.biClrUsed = 0;
slouken@0
   638
		binfo->bmiHeader.biClrImportant = 0;
slouken@0
   639
		binfo->bmiHeader.biBitCount = video->format->BitsPerPixel;
slouken@0
   640
slouken@0
   641
		if ( is16bitmode ) {
slouken@0
   642
			/* BI_BITFIELDS tells CreateDIBSection about the rgb masks in the palette */
slouken@0
   643
			binfo->bmiHeader.biCompression = BI_BITFIELDS;
slouken@0
   644
			((Uint32*)binfo->bmiColors)[0] = video->format->Rmask;
slouken@0
   645
			((Uint32*)binfo->bmiColors)[1] = video->format->Gmask;
slouken@0
   646
			((Uint32*)binfo->bmiColors)[2] = video->format->Bmask;
slouken@0
   647
		} else {
slouken@0
   648
			binfo->bmiHeader.biCompression = BI_RGB;	/* BI_BITFIELDS for 565 vs 555 */
slouken@0
   649
			if ( video->format->palette ) {
slouken@0
   650
				memset(binfo->bmiColors, 0,
slouken@0
   651
					video->format->palette->ncolors*sizeof(RGBQUAD));
slouken@0
   652
			}
slouken@0
   653
		}
slouken@0
   654
slouken@0
   655
		/* Create the offscreen bitmap buffer */
slouken@0
   656
		hdc = GetDC(SDL_Window);
slouken@0
   657
		screen_bmp = CreateDIBSection(hdc, binfo, DIB_RGB_COLORS,
slouken@0
   658
					(void **)(&video->pixels), NULL, 0);
slouken@0
   659
		ReleaseDC(SDL_Window, hdc);
slouken@0
   660
		free(binfo);
slouken@0
   661
		if ( screen_bmp == NULL ) {
slouken@0
   662
			if ( video != current ) {
slouken@0
   663
				SDL_FreeSurface(video);
slouken@0
   664
			}
slouken@0
   665
			SDL_SetError("Couldn't create DIB section");
slouken@0
   666
			return(NULL);
slouken@0
   667
		}
slouken@0
   668
		this->UpdateRects = DIB_NormalUpdate;
slouken@0
   669
slouken@0
   670
		/* Set video surface flags */
slouken@0
   671
		if ( bpp <= 8 ) {
slouken@0
   672
			/* BitBlt() maps colors for us */
slouken@0
   673
			video->flags |= SDL_HWPALETTE;
slouken@0
   674
		}
slouken@0
   675
	}
slouken@0
   676
slouken@0
   677
	/* Resize the window */
slouken@0
   678
	if ( SDL_windowid == NULL ) {
slouken@448
   679
		HWND top;
slouken@0
   680
		UINT swp_flags;
slouken@0
   681
slouken@0
   682
		SDL_resizing = 1;
slouken@0
   683
		bounds.left = 0;
slouken@0
   684
		bounds.top = 0;
slouken@0
   685
		bounds.right = video->w;
slouken@0
   686
		bounds.bottom = video->h;
slouken@453
   687
		AdjustWindowRectEx(&bounds, GetWindowLong(SDL_Window, GWL_STYLE), FALSE, 0);
slouken@0
   688
		width = bounds.right-bounds.left;
slouken@0
   689
		height = bounds.bottom-bounds.top;
slouken@0
   690
		x = (GetSystemMetrics(SM_CXSCREEN)-width)/2;
slouken@0
   691
		y = (GetSystemMetrics(SM_CYSCREEN)-height)/2;
slouken@0
   692
		if ( y < 0 ) { /* Cover up title bar for more client area */
slouken@0
   693
			y -= GetSystemMetrics(SM_CYCAPTION)/2;
slouken@0
   694
		}
slouken@448
   695
		swp_flags = (SWP_NOCOPYBITS | SWP_FRAMECHANGED | SWP_SHOWWINDOW);
slouken@0
   696
		if ( was_visible && !(flags & SDL_FULLSCREEN) ) {
slouken@0
   697
			swp_flags |= SWP_NOMOVE;
slouken@0
   698
		}
slouken@448
   699
		if ( flags & SDL_FULLSCREEN ) {
slouken@448
   700
			top = HWND_TOPMOST;
slouken@448
   701
		} else {
slouken@448
   702
			top = HWND_NOTOPMOST;
slouken@448
   703
		}
slouken@448
   704
		SetWindowPos(SDL_Window, top, x, y, width, height, swp_flags);
slouken@0
   705
		SDL_resizing = 0;
slouken@0
   706
		SetForegroundWindow(SDL_Window);
slouken@0
   707
	}
slouken@0
   708
slouken@0
   709
	/* Set up for OpenGL */
slouken@0
   710
	if ( flags & SDL_OPENGL ) {
slouken@0
   711
		if ( WIN_GL_SetupWindow(this) < 0 ) {
slouken@0
   712
			return(NULL);
slouken@0
   713
		}
slouken@0
   714
		video->flags |= SDL_OPENGL;
slouken@0
   715
	}
slouken@36
   716
slouken@0
   717
	/* We're live! */
slouken@0
   718
	return(video);
slouken@0
   719
}
slouken@0
   720
slouken@0
   721
/* We don't actually allow hardware surfaces in the DIB driver */
slouken@0
   722
static int DIB_AllocHWSurface(_THIS, SDL_Surface *surface)
slouken@0
   723
{
slouken@0
   724
	return(-1);
slouken@0
   725
}
slouken@0
   726
static void DIB_FreeHWSurface(_THIS, SDL_Surface *surface)
slouken@0
   727
{
slouken@0
   728
	return;
slouken@0
   729
}
slouken@0
   730
static int DIB_LockHWSurface(_THIS, SDL_Surface *surface)
slouken@0
   731
{
slouken@0
   732
	return(0);
slouken@0
   733
}
slouken@0
   734
static void DIB_UnlockHWSurface(_THIS, SDL_Surface *surface)
slouken@0
   735
{
slouken@0
   736
	return;
slouken@0
   737
}
slouken@0
   738
slouken@0
   739
static void DIB_NormalUpdate(_THIS, int numrects, SDL_Rect *rects)
slouken@0
   740
{
slouken@0
   741
	HDC hdc, mdc;
slouken@0
   742
	int i;
slouken@0
   743
slouken@0
   744
	hdc = GetDC(SDL_Window);
slouken@0
   745
	if ( screen_pal ) {
slouken@0
   746
		SelectPalette(hdc, screen_pal, FALSE);
slouken@0
   747
	}
slouken@0
   748
	mdc = CreateCompatibleDC(hdc);
slouken@0
   749
	SelectObject(mdc, screen_bmp);
slouken@0
   750
	for ( i=0; i<numrects; ++i ) {
slouken@0
   751
		BitBlt(hdc, rects[i].x, rects[i].y, rects[i].w, rects[i].h,
slouken@0
   752
					mdc, rects[i].x, rects[i].y, SRCCOPY);
slouken@0
   753
	}
slouken@0
   754
	DeleteDC(mdc);
slouken@0
   755
	ReleaseDC(SDL_Window, hdc);
slouken@0
   756
}
slouken@0
   757
slouken@0
   758
int DIB_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors)
slouken@0
   759
{
slouken@0
   760
	RGBQUAD *pal;
slouken@0
   761
	int i;
slouken@36
   762
#ifndef _WIN32_WCE
slouken@0
   763
	HDC hdc, mdc;
slouken@36
   764
#else
slouken@36
   765
	HDC hdc;
slouken@36
   766
#endif
slouken@0
   767
slouken@0
   768
	/* Update the display palette */
slouken@0
   769
	hdc = GetDC(SDL_Window);
slouken@0
   770
	if ( screen_pal ) {
slouken@0
   771
		PALETTEENTRY *entries;
slouken@0
   772
slouken@0
   773
		entries = (PALETTEENTRY *)alloca(ncolors*sizeof(PALETTEENTRY));
slouken@0
   774
		for ( i=0; i<ncolors; ++i ) {
slouken@0
   775
			entries[i].peRed   = colors[i].r;
slouken@0
   776
			entries[i].peGreen = colors[i].g;
slouken@0
   777
			entries[i].peBlue  = colors[i].b;
slouken@0
   778
			entries[i].peFlags = PC_NOCOLLAPSE;
slouken@0
   779
		}
slouken@0
   780
		SetPaletteEntries(screen_pal, firstcolor, ncolors, entries);
slouken@0
   781
		SelectPalette(hdc, screen_pal, FALSE);
slouken@0
   782
		RealizePalette(hdc);
slouken@0
   783
	}
slouken@0
   784
slouken@0
   785
	/* Copy palette colors into DIB palette */
slouken@0
   786
	pal = (RGBQUAD *)alloca(ncolors*sizeof(RGBQUAD));
slouken@0
   787
	for ( i=0; i<ncolors; ++i ) {
slouken@0
   788
		pal[i].rgbRed = colors[i].r;
slouken@0
   789
		pal[i].rgbGreen = colors[i].g;
slouken@0
   790
		pal[i].rgbBlue = colors[i].b;
slouken@0
   791
		pal[i].rgbReserved = 0;
slouken@0
   792
	}
slouken@0
   793
slouken@0
   794
	/* Set the DIB palette and update the display */
slouken@36
   795
#ifndef _WIN32_WCE
slouken@0
   796
	mdc = CreateCompatibleDC(hdc);
slouken@0
   797
	SelectObject(mdc, screen_bmp);
slouken@0
   798
	SetDIBColorTable(mdc, firstcolor, ncolors, pal);
slouken@0
   799
	BitBlt(hdc, 0, 0, this->screen->w, this->screen->h,
slouken@0
   800
	       mdc, 0, 0, SRCCOPY);
slouken@0
   801
	DeleteDC(mdc);
slouken@36
   802
#endif
slouken@0
   803
	ReleaseDC(SDL_Window, hdc);
slouken@0
   804
	return(1);
slouken@0
   805
}
slouken@0
   806
slouken@0
   807
static void DIB_CheckGamma(_THIS)
slouken@0
   808
{
slouken@0
   809
#ifndef NO_GAMMA_SUPPORT
slouken@0
   810
	HDC hdc;
slouken@0
   811
	WORD ramp[3*256];
slouken@0
   812
slouken@0
   813
	/* If we fail to get gamma, disable gamma control */
slouken@0
   814
	hdc = GetDC(SDL_Window);
slouken@0
   815
	if ( ! GetDeviceGammaRamp(hdc, ramp) ) {
slouken@0
   816
		this->GetGammaRamp = NULL;
slouken@0
   817
		this->SetGammaRamp = NULL;
slouken@0
   818
	}
slouken@0
   819
	ReleaseDC(SDL_Window, hdc);
slouken@0
   820
#endif /* !NO_GAMMA_SUPPORT */
slouken@0
   821
}
slouken@338
   822
void DIB_SwapGamma(_THIS)
slouken@0
   823
{
slouken@0
   824
#ifndef NO_GAMMA_SUPPORT
slouken@0
   825
	HDC hdc;
slouken@0
   826
slouken@0
   827
	if ( gamma_saved ) {
slouken@0
   828
		hdc = GetDC(SDL_Window);
slouken@0
   829
		if ( SDL_GetAppState() & SDL_APPINPUTFOCUS ) {
slouken@0
   830
			/* About to leave active state, restore gamma */
slouken@0
   831
			SetDeviceGammaRamp(hdc, gamma_saved);
slouken@0
   832
		} else {
slouken@0
   833
			/* About to enter active state, set game gamma */
slouken@0
   834
			GetDeviceGammaRamp(hdc, gamma_saved);
slouken@0
   835
			SetDeviceGammaRamp(hdc, this->gamma);
slouken@0
   836
		}
slouken@0
   837
		ReleaseDC(SDL_Window, hdc);
slouken@0
   838
	}
slouken@0
   839
#endif /* !NO_GAMMA_SUPPORT */
slouken@0
   840
}
slouken@338
   841
void DIB_QuitGamma(_THIS)
slouken@0
   842
{
slouken@0
   843
#ifndef NO_GAMMA_SUPPORT
slouken@0
   844
	if ( gamma_saved ) {
slouken@0
   845
		/* Restore the original gamma if necessary */
slouken@0
   846
		if ( SDL_GetAppState() & SDL_APPINPUTFOCUS ) {
slouken@0
   847
			HDC hdc;
slouken@0
   848
slouken@0
   849
			hdc = GetDC(SDL_Window);
slouken@0
   850
			SetDeviceGammaRamp(hdc, gamma_saved);
slouken@0
   851
			ReleaseDC(SDL_Window, hdc);
slouken@0
   852
		}
slouken@0
   853
slouken@0
   854
		/* Free the saved gamma memory */
slouken@0
   855
		free(gamma_saved);
slouken@0
   856
		gamma_saved = 0;
slouken@0
   857
	}
slouken@0
   858
#endif /* !NO_GAMMA_SUPPORT */
slouken@0
   859
}
slouken@0
   860
slouken@338
   861
int DIB_SetGammaRamp(_THIS, Uint16 *ramp)
slouken@0
   862
{
slouken@338
   863
#ifdef NO_GAMMA_SUPPORT
slouken@338
   864
	SDL_SetError("SDL compiled without gamma ramp support");
slouken@338
   865
	return -1;
slouken@338
   866
#else
slouken@0
   867
	HDC hdc;
slouken@0
   868
	BOOL succeeded;
slouken@0
   869
slouken@0
   870
	/* Set the ramp for the display */
slouken@0
   871
	if ( ! gamma_saved ) {
slouken@0
   872
		gamma_saved = (WORD *)malloc(3*256*sizeof(*gamma_saved));
slouken@0
   873
		if ( ! gamma_saved ) {
slouken@0
   874
			SDL_OutOfMemory();
slouken@0
   875
			return -1;
slouken@0
   876
		}
slouken@0
   877
		hdc = GetDC(SDL_Window);
slouken@0
   878
		GetDeviceGammaRamp(hdc, gamma_saved);
slouken@0
   879
		ReleaseDC(SDL_Window, hdc);
slouken@0
   880
	}
slouken@0
   881
	if ( SDL_GetAppState() & SDL_APPINPUTFOCUS ) {
slouken@0
   882
		hdc = GetDC(SDL_Window);
slouken@0
   883
		succeeded = SetDeviceGammaRamp(hdc, ramp);
slouken@0
   884
		ReleaseDC(SDL_Window, hdc);
slouken@0
   885
	} else {
slouken@0
   886
		succeeded = TRUE;
slouken@0
   887
	}
slouken@0
   888
	return succeeded ? 0 : -1;
slouken@338
   889
#endif /* !NO_GAMMA_SUPPORT */
slouken@0
   890
}
slouken@0
   891
slouken@338
   892
int DIB_GetGammaRamp(_THIS, Uint16 *ramp)
slouken@0
   893
{
slouken@338
   894
#ifdef NO_GAMMA_SUPPORT
slouken@338
   895
	SDL_SetError("SDL compiled without gamma ramp support");
slouken@338
   896
	return -1;
slouken@338
   897
#else
slouken@0
   898
	HDC hdc;
slouken@0
   899
	BOOL succeeded;
slouken@0
   900
slouken@0
   901
	/* Get the ramp from the display */
slouken@0
   902
	hdc = GetDC(SDL_Window);
slouken@0
   903
	succeeded = GetDeviceGammaRamp(hdc, ramp);
slouken@0
   904
	ReleaseDC(SDL_Window, hdc);
slouken@0
   905
	return succeeded ? 0 : -1;
slouken@338
   906
#endif /* !NO_GAMMA_SUPPORT */
slouken@0
   907
}
slouken@0
   908
slouken@442
   909
static void FlushMessageQueue()
slouken@442
   910
{
slouken@442
   911
	MSG  msg;
slouken@442
   912
	while ( PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) ) {
slouken@442
   913
		if ( msg.message == WM_QUIT ) break;
slouken@442
   914
		TranslateMessage( &msg );
slouken@442
   915
		DispatchMessage( &msg );
slouken@442
   916
	}
slouken@442
   917
}
slouken@442
   918
slouken@0
   919
void DIB_VideoQuit(_THIS)
slouken@0
   920
{
slouken@0
   921
	/* Destroy the window and everything associated with it */
slouken@0
   922
	if ( SDL_Window ) {
slouken@0
   923
		/* Delete the screen bitmap (also frees screen->pixels) */
slouken@0
   924
		if ( this->screen ) {
slouken@515
   925
#ifdef WIN32_PLATFORM_PSPC
slouken@515
   926
			if ( this->screen->flags & SDL_FULLSCREEN ) {
slouken@515
   927
				/* Unhide taskbar, etc. */
slouken@515
   928
				SHFullScreen(SDL_Window, SHFS_SHOWTASKBAR);
slouken@515
   929
				SHFullScreen(SDL_Window, SHFS_SHOWSIPBUTTON);
slouken@515
   930
				ShowWindow(FindWindow(TEXT("HHTaskBar"),NULL),SW_SHOWNORMAL);
slouken@515
   931
			}
slouken@515
   932
#endif
slouken@0
   933
#ifndef NO_CHANGEDISPLAYSETTINGS
slouken@0
   934
			if ( this->screen->flags & SDL_FULLSCREEN ) {
slouken@0
   935
				ChangeDisplaySettings(NULL, 0);
slouken@376
   936
				ShowWindow(SDL_Window, SW_HIDE);
slouken@0
   937
			}
slouken@0
   938
#endif
slouken@0
   939
			if ( this->screen->flags & SDL_OPENGL ) {
slouken@0
   940
				WIN_GL_ShutDown(this);
slouken@0
   941
			}
slouken@0
   942
			this->screen->pixels = NULL;
slouken@0
   943
		}
slouken@0
   944
		if ( screen_bmp ) {
slouken@0
   945
			DeleteObject(screen_bmp);
slouken@0
   946
			screen_bmp = NULL;
slouken@0
   947
		}
slouken@0
   948
		if ( screen_icn ) {
slouken@0
   949
			DestroyIcon(screen_icn);
slouken@0
   950
			screen_icn = NULL;
slouken@0
   951
		}
slouken@0
   952
		DIB_QuitGamma(this);
slouken@0
   953
		DIB_DestroyWindow(this);
slouken@442
   954
		FlushMessageQueue();
slouken@0
   955
slouken@0
   956
		SDL_Window = NULL;
slouken@0
   957
	}
slouken@0
   958
}
slouken@0
   959
slouken@0
   960
/* Exported for the windows message loop only */
slouken@0
   961
static void DIB_FocusPalette(_THIS, int foreground)
slouken@0
   962
{
slouken@0
   963
	if ( screen_pal != NULL ) {
slouken@0
   964
		HDC hdc;
slouken@0
   965
slouken@0
   966
		hdc = GetDC(SDL_Window);
slouken@0
   967
		SelectPalette(hdc, screen_pal, FALSE);
slouken@0
   968
		if ( RealizePalette(hdc) )
slouken@0
   969
			InvalidateRect(SDL_Window, NULL, FALSE);
slouken@0
   970
		ReleaseDC(SDL_Window, hdc);
slouken@0
   971
	}
slouken@0
   972
}
slouken@0
   973
static void DIB_RealizePalette(_THIS)
slouken@0
   974
{
slouken@0
   975
	DIB_FocusPalette(this, 1);
slouken@0
   976
}
slouken@0
   977
static void DIB_PaletteChanged(_THIS, HWND window)
slouken@0
   978
{
slouken@0
   979
	if ( window != SDL_Window ) {
slouken@0
   980
		DIB_FocusPalette(this, 0);
slouken@0
   981
	}
slouken@0
   982
}
slouken@0
   983
slouken@0
   984
/* Exported for the windows message loop only */
slouken@0
   985
static void DIB_WinPAINT(_THIS, HDC hdc)
slouken@0
   986
{
slouken@0
   987
	HDC mdc;
slouken@0
   988
slouken@0
   989
	if ( screen_pal ) {
slouken@0
   990
		SelectPalette(hdc, screen_pal, FALSE);
slouken@0
   991
	}
slouken@0
   992
	mdc = CreateCompatibleDC(hdc);
slouken@0
   993
	SelectObject(mdc, screen_bmp);
slouken@0
   994
	BitBlt(hdc, 0, 0, SDL_VideoSurface->w, SDL_VideoSurface->h,
slouken@0
   995
							mdc, 0, 0, SRCCOPY);
slouken@0
   996
	DeleteDC(mdc);
slouken@0
   997
}
slouken@0
   998
slouken@0
   999
/* Stub in case DirectX isn't available */
slouken@0
  1000
#ifndef ENABLE_DIRECTX
slouken@0
  1001
void DX5_SoundFocus(HWND hwnd)
slouken@0
  1002
{
slouken@0
  1003
	return;
slouken@0
  1004
}
slouken@0
  1005
#endif