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