src/video/windib/SDL_dibvideo.c
author Ryan C. Gordon
Tue, 26 Jun 2007 20:02:40 +0000
branchSDL-1.2
changeset 3981 b0d021cf41b6
parent 3976 8582c6a5ca16
child 3992 c75679dce60c
permissions -rw-r--r--
windib target can now control screensaver with SDL_VIDEO_ALLOW_SCREENSAVER.

Fixes Bugzilla #415.
slouken@0
     1
/*
slouken@0
     2
    SDL - Simple DirectMedia Layer
slouken@1312
     3
    Copyright (C) 1997-2006 Sam Lantinga
slouken@0
     4
slouken@0
     5
    This library is free software; you can redistribute it and/or
slouken@1312
     6
    modify it under the terms of the GNU Lesser General Public
slouken@0
     7
    License as published by the Free Software Foundation; either
slouken@1312
     8
    version 2.1 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@1312
    13
    Lesser General Public License for more details.
slouken@0
    14
slouken@1312
    15
    You should have received a copy of the GNU Lesser General Public
slouken@1312
    16
    License along with this library; if not, write to the Free Software
slouken@1312
    17
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
slouken@0
    18
slouken@0
    19
    Sam Lantinga
slouken@252
    20
    slouken@libsdl.org
slouken@0
    21
*/
slouken@1402
    22
#include "SDL_config.h"
slouken@0
    23
slouken@1433
    24
#define WIN32_LEAN_AND_MEAN
slouken@1433
    25
#include <windows.h>
icculus@1152
    26
slouken@0
    27
/* Not yet in the mingw32 cross-compile headers */
slouken@0
    28
#ifndef CDS_FULLSCREEN
slouken@0
    29
#define CDS_FULLSCREEN	4
slouken@0
    30
#endif
slouken@0
    31
slouken@0
    32
#include "SDL_syswm.h"
slouken@1361
    33
#include "../SDL_sysvideo.h"
slouken@1361
    34
#include "../SDL_pixels_c.h"
slouken@1361
    35
#include "../../events/SDL_sysevents.h"
slouken@1361
    36
#include "../../events/SDL_events_c.h"
slouken@0
    37
#include "SDL_dibvideo.h"
slouken@1361
    38
#include "../wincommon/SDL_syswm_c.h"
slouken@1361
    39
#include "../wincommon/SDL_sysmouse_c.h"
slouken@0
    40
#include "SDL_dibevents_c.h"
slouken@1361
    41
#include "../wincommon/SDL_wingl_c.h"
slouken@0
    42
slouken@0
    43
#ifdef _WIN32_WCE
slouken@0
    44
#define NO_GETDIBITS
slouken@0
    45
#define NO_GAMMA_SUPPORT
slouken@1465
    46
  #if _WIN32_WCE < 420
slouken@1465
    47
    #define NO_CHANGEDISPLAYSETTINGS
slouken@1465
    48
  #else
slouken@1465
    49
    #define ChangeDisplaySettings(lpDevMode, dwFlags) ChangeDisplaySettingsEx(NULL, (lpDevMode), 0, (dwFlags), 0)
slouken@1465
    50
  #endif
slouken@0
    51
#endif
slouken@453
    52
#ifndef WS_MAXIMIZE
slouken@766
    53
#define WS_MAXIMIZE	0
slouken@766
    54
#endif
slouken@766
    55
#ifndef WS_THICKFRAME
slouken@766
    56
#define WS_THICKFRAME	0
slouken@453
    57
#endif
slouken@453
    58
#ifndef SWP_NOCOPYBITS
slouken@453
    59
#define SWP_NOCOPYBITS	0
slouken@453
    60
#endif
slouken@453
    61
#ifndef PC_NOCOLLAPSE
slouken@453
    62
#define PC_NOCOLLAPSE	0
slouken@453
    63
#endif
slouken@0
    64
slouken@1465
    65
#ifdef _WIN32_WCE
slouken@1465
    66
// defined and used in SDL_sysevents.c
slouken@1465
    67
extern HINSTANCE aygshell;
slouken@1465
    68
#endif
slouken@1465
    69
slouken@0
    70
/* Initialization/Query functions */
slouken@0
    71
static int DIB_VideoInit(_THIS, SDL_PixelFormat *vformat);
slouken@0
    72
static SDL_Rect **DIB_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags);
slouken@0
    73
SDL_Surface *DIB_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags);
slouken@0
    74
static int DIB_SetColors(_THIS, int firstcolor, int ncolors,
slouken@0
    75
			 SDL_Color *colors);
slouken@0
    76
static void DIB_CheckGamma(_THIS);
slouken@338
    77
void DIB_SwapGamma(_THIS);
slouken@338
    78
void DIB_QuitGamma(_THIS);
slouken@338
    79
int DIB_SetGammaRamp(_THIS, Uint16 *ramp);
slouken@338
    80
int DIB_GetGammaRamp(_THIS, Uint16 *ramp);
slouken@0
    81
static void DIB_VideoQuit(_THIS);
slouken@0
    82
slouken@0
    83
/* Hardware surface functions */
slouken@0
    84
static int DIB_AllocHWSurface(_THIS, SDL_Surface *surface);
slouken@0
    85
static int DIB_LockHWSurface(_THIS, SDL_Surface *surface);
slouken@0
    86
static void DIB_UnlockHWSurface(_THIS, SDL_Surface *surface);
slouken@0
    87
static void DIB_FreeHWSurface(_THIS, SDL_Surface *surface);
slouken@0
    88
slouken@0
    89
/* Windows message handling functions */
slouken@0
    90
static void DIB_RealizePalette(_THIS);
slouken@0
    91
static void DIB_PaletteChanged(_THIS, HWND window);
slouken@0
    92
static void DIB_WinPAINT(_THIS, HDC hdc);
slouken@0
    93
slouken@0
    94
/* helper fn */
slouken@0
    95
static int DIB_SussScreenDepth();
slouken@0
    96
slouken@0
    97
/* DIB driver bootstrap functions */
slouken@0
    98
slouken@0
    99
static int DIB_Available(void)
slouken@0
   100
{
slouken@0
   101
	return(1);
slouken@0
   102
}
slouken@0
   103
slouken@0
   104
static void DIB_DeleteDevice(SDL_VideoDevice *device)
slouken@0
   105
{
slouken@0
   106
	if ( device ) {
slouken@0
   107
		if ( device->hidden ) {
slouken@1336
   108
			SDL_free(device->hidden);
slouken@0
   109
		}
slouken@0
   110
		if ( device->gl_data ) {
slouken@1336
   111
			SDL_free(device->gl_data);
slouken@0
   112
		}
slouken@1336
   113
		SDL_free(device);
slouken@0
   114
	}
slouken@0
   115
}
slouken@0
   116
slouken@0
   117
static SDL_VideoDevice *DIB_CreateDevice(int devindex)
slouken@0
   118
{
slouken@0
   119
	SDL_VideoDevice *device;
slouken@0
   120
slouken@0
   121
	/* Initialize all variables that we clean on shutdown */
slouken@1336
   122
	device = (SDL_VideoDevice *)SDL_malloc(sizeof(SDL_VideoDevice));
slouken@0
   123
	if ( device ) {
slouken@1336
   124
		SDL_memset(device, 0, (sizeof *device));
slouken@0
   125
		device->hidden = (struct SDL_PrivateVideoData *)
slouken@1336
   126
				SDL_malloc((sizeof *device->hidden));
slouken@0
   127
		device->gl_data = (struct SDL_PrivateGLData *)
slouken@1336
   128
				SDL_malloc((sizeof *device->gl_data));
slouken@0
   129
	}
slouken@0
   130
	if ( (device == NULL) || (device->hidden == NULL) ||
slouken@0
   131
		                 (device->gl_data == NULL) ) {
slouken@0
   132
		SDL_OutOfMemory();
slouken@0
   133
		DIB_DeleteDevice(device);
slouken@0
   134
		return(NULL);
slouken@0
   135
	}
slouken@1336
   136
	SDL_memset(device->hidden, 0, (sizeof *device->hidden));
slouken@1336
   137
	SDL_memset(device->gl_data, 0, (sizeof *device->gl_data));
slouken@0
   138
slouken@0
   139
	/* Set the function pointers */
slouken@0
   140
	device->VideoInit = DIB_VideoInit;
slouken@0
   141
	device->ListModes = DIB_ListModes;
slouken@0
   142
	device->SetVideoMode = DIB_SetVideoMode;
slouken@0
   143
	device->UpdateMouse = WIN_UpdateMouse;
slouken@0
   144
	device->SetColors = DIB_SetColors;
slouken@0
   145
	device->UpdateRects = NULL;
slouken@0
   146
	device->VideoQuit = DIB_VideoQuit;
slouken@0
   147
	device->AllocHWSurface = DIB_AllocHWSurface;
slouken@0
   148
	device->CheckHWBlit = NULL;
slouken@0
   149
	device->FillHWRect = NULL;
slouken@0
   150
	device->SetHWColorKey = NULL;
slouken@0
   151
	device->SetHWAlpha = NULL;
slouken@0
   152
	device->LockHWSurface = DIB_LockHWSurface;
slouken@0
   153
	device->UnlockHWSurface = DIB_UnlockHWSurface;
slouken@0
   154
	device->FlipHWSurface = NULL;
slouken@0
   155
	device->FreeHWSurface = DIB_FreeHWSurface;
slouken@0
   156
	device->SetGammaRamp = DIB_SetGammaRamp;
slouken@0
   157
	device->GetGammaRamp = DIB_GetGammaRamp;
slouken@1361
   158
#if SDL_VIDEO_OPENGL
slouken@453
   159
	device->GL_LoadLibrary = WIN_GL_LoadLibrary;
slouken@453
   160
	device->GL_GetProcAddress = WIN_GL_GetProcAddress;
slouken@453
   161
	device->GL_GetAttribute = WIN_GL_GetAttribute;
slouken@453
   162
	device->GL_MakeCurrent = WIN_GL_MakeCurrent;
slouken@453
   163
	device->GL_SwapBuffers = WIN_GL_SwapBuffers;
slouken@0
   164
#endif
slouken@0
   165
	device->SetCaption = WIN_SetWMCaption;
slouken@0
   166
	device->SetIcon = WIN_SetWMIcon;
slouken@0
   167
	device->IconifyWindow = WIN_IconifyWindow;
slouken@0
   168
	device->GrabInput = WIN_GrabInput;
slouken@0
   169
	device->GetWMInfo = WIN_GetWMInfo;
slouken@0
   170
	device->FreeWMCursor = WIN_FreeWMCursor;
slouken@0
   171
	device->CreateWMCursor = WIN_CreateWMCursor;
slouken@0
   172
	device->ShowWMCursor = WIN_ShowWMCursor;
slouken@0
   173
	device->WarpWMCursor = WIN_WarpWMCursor;
slouken@0
   174
	device->CheckMouseMode = WIN_CheckMouseMode;
slouken@0
   175
	device->InitOSKeymap = DIB_InitOSKeymap;
slouken@0
   176
	device->PumpEvents = DIB_PumpEvents;
slouken@0
   177
slouken@0
   178
	/* Set up the windows message handling functions */
slouken@0
   179
	WIN_RealizePalette = DIB_RealizePalette;
slouken@0
   180
	WIN_PaletteChanged = DIB_PaletteChanged;
slouken@0
   181
	WIN_WinPAINT = DIB_WinPAINT;
slouken@0
   182
	HandleMessage = DIB_HandleMessage;
slouken@0
   183
slouken@0
   184
	device->free = DIB_DeleteDevice;
slouken@0
   185
slouken@0
   186
	/* We're finally ready */
slouken@0
   187
	return device;
slouken@0
   188
}
slouken@0
   189
slouken@0
   190
VideoBootStrap WINDIB_bootstrap = {
icculus@1152
   191
	"windib", "Win95/98/NT/2000/CE GDI",
slouken@0
   192
	DIB_Available, DIB_CreateDevice
slouken@0
   193
};
slouken@0
   194
slouken@0
   195
static int cmpmodes(const void *va, const void *vb)
slouken@0
   196
{
slouken@0
   197
    SDL_Rect *a = *(SDL_Rect **)va;
slouken@0
   198
    SDL_Rect *b = *(SDL_Rect **)vb;
slouken@966
   199
    if ( a->w == b->w )
slouken@966
   200
        return b->h - a->h;
slouken@966
   201
    else
slouken@966
   202
        return b->w - a->w;
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@1336
   224
	mode = (SDL_Rect *)SDL_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@1336
   237
	       SDL_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@1336
   241
		SDL_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
static HPALETTE DIB_CreatePalette(int bpp)
slouken@0
   252
{
slouken@0
   253
/*	RJR: March 28, 2000
slouken@0
   254
	moved palette creation here from "DIB_VideoInit" */
slouken@0
   255
slouken@0
   256
	HPALETTE handle = NULL;
slouken@0
   257
	
slouken@0
   258
	if ( bpp <= 8 )
slouken@0
   259
	{
slouken@0
   260
		LOGPALETTE *palette;
slouken@0
   261
		HDC hdc;
slouken@0
   262
		int ncolors;
slouken@0
   263
		int i;
slouken@0
   264
slouken@0
   265
		ncolors = 1;
slouken@0
   266
		for ( i=0; i<bpp; ++i ) {
slouken@0
   267
			ncolors *= 2;
slouken@0
   268
		}
slouken@1336
   269
		palette = (LOGPALETTE *)SDL_malloc(sizeof(*palette)+
slouken@0
   270
					ncolors*sizeof(PALETTEENTRY));
slouken@0
   271
		palette->palVersion = 0x300;
slouken@0
   272
		palette->palNumEntries = ncolors;
slouken@0
   273
		hdc = GetDC(SDL_Window);
slouken@0
   274
		GetSystemPaletteEntries(hdc, 0, ncolors, palette->palPalEntry);
slouken@0
   275
		ReleaseDC(SDL_Window, hdc);
slouken@0
   276
		handle = CreatePalette(palette);
slouken@1336
   277
		SDL_free(palette);
slouken@0
   278
	}
slouken@0
   279
	
slouken@0
   280
	return handle;
slouken@0
   281
}
slouken@0
   282
slouken@0
   283
int DIB_VideoInit(_THIS, SDL_PixelFormat *vformat)
slouken@0
   284
{
icculus@3981
   285
	const char *env = NULL;
slouken@0
   286
#ifndef NO_CHANGEDISPLAYSETTINGS
slouken@0
   287
	int i;
slouken@0
   288
	DEVMODE settings;
slouken@0
   289
#endif
slouken@0
   290
slouken@0
   291
	/* Create the window */
slouken@0
   292
	if ( DIB_CreateWindow(this) < 0 ) {
slouken@0
   293
		return(-1);
slouken@0
   294
	}
slouken@1523
   295
slouken@1361
   296
#if !SDL_AUDIO_DISABLED
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@1465
   329
slouken@1465
   330
	settings.dmSize = sizeof(DEVMODE);
slouken@1465
   331
	settings.dmDriverExtra = 0;
slouken@1465
   332
#ifdef _WIN32_WCE
slouken@1465
   333
	settings.dmFields = DM_DISPLAYQUERYORIENTATION;
slouken@1465
   334
	this->hidden->supportRotation = ChangeDisplaySettingsEx(NULL, &settings, NULL, CDS_TEST, NULL) == DISP_CHANGE_SUCCESSFUL;
slouken@1465
   335
#endif
slouken@1295
   336
	/* Query for the desktop resolution */
slouken@1295
   337
	EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &SDL_desktop_mode);
slouken@1545
   338
	this->info.current_w = SDL_desktop_mode.dmPelsWidth;
slouken@1545
   339
	this->info.current_h = SDL_desktop_mode.dmPelsHeight;
slouken@1295
   340
slouken@0
   341
	/* Query for the list of available video modes */
slouken@0
   342
	for ( i=0; EnumDisplaySettings(NULL, i, &settings); ++i ) {
slouken@0
   343
		DIB_AddMode(this, settings.dmBitsPerPel,
slouken@0
   344
			settings.dmPelsWidth, settings.dmPelsHeight);
slouken@1465
   345
#ifdef _WIN32_WCE		
slouken@1465
   346
		if( this->hidden->supportRotation )
slouken@1465
   347
			DIB_AddMode(this, settings.dmBitsPerPel,
slouken@1465
   348
				settings.dmPelsHeight, settings.dmPelsWidth);
slouken@1465
   349
#endif
slouken@0
   350
	}
slouken@0
   351
	/* Sort the mode lists */
slouken@0
   352
	for ( i=0; i<NUM_MODELISTS; ++i ) {
slouken@0
   353
		if ( SDL_nummodes[i] > 0 ) {
slouken@1336
   354
			SDL_qsort(SDL_modelist[i], SDL_nummodes[i], sizeof *SDL_modelist[i], cmpmodes);
slouken@0
   355
		}
slouken@0
   356
	}
slouken@1465
   357
#else
slouken@1465
   358
	// WinCE and fullscreen mode:
slouken@1465
   359
	// We use only vformat->BitsPerPixel that allow SDL to
slouken@1465
   360
	// emulate other bpp (8, 32) and use triple buffer, 
slouken@1465
   361
	// because SDL surface conversion is much faster than the WinCE one.
slouken@1465
   362
	// Although it should be tested on devices with graphics accelerator.
slouken@1465
   363
slouken@1771
   364
	DIB_AddMode(this, vformat->BitsPerPixel,
slouken@1465
   365
			GetDeviceCaps(GetDC(NULL), HORZRES), 
slouken@1465
   366
			GetDeviceCaps(GetDC(NULL), VERTRES));
slouken@1465
   367
slouken@0
   368
#endif /* !NO_CHANGEDISPLAYSETTINGS */
slouken@0
   369
slouken@0
   370
	/* Grab an identity palette if we are in a palettized mode */
slouken@0
   371
	if ( vformat->BitsPerPixel <= 8 ) {
slouken@0
   372
	/*	RJR: March 28, 2000
slouken@0
   373
		moved palette creation to "DIB_CreatePalette" */
slouken@0
   374
		screen_pal = DIB_CreatePalette(vformat->BitsPerPixel);
slouken@0
   375
	}
slouken@0
   376
slouken@0
   377
	/* Fill in some window manager capabilities */
slouken@0
   378
	this->info.wm_available = 1;
slouken@0
   379
slouken@1465
   380
#ifdef _WIN32_WCE
slouken@1465
   381
	this->hidden->origRotation = -1;
slouken@1465
   382
#endif
slouken@1465
   383
icculus@3981
   384
	/* Allow environment override of screensaver disable. */
icculus@3981
   385
	env = SDL_getenv("SDL_VIDEO_ALLOW_SCREENSAVER");
icculus@3981
   386
	this->hidden->allow_screensaver = ( (env && SDL_atoi(env)) ? 1 : 0 );
icculus@3981
   387
slouken@0
   388
	/* We're done! */
slouken@0
   389
	return(0);
slouken@0
   390
}
slouken@0
   391
slouken@0
   392
/* We support any format at any dimension */
slouken@0
   393
SDL_Rect **DIB_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags)
slouken@0
   394
{
slouken@0
   395
	if ( (flags & SDL_FULLSCREEN) == SDL_FULLSCREEN ) {
slouken@0
   396
		return(SDL_modelist[((format->BitsPerPixel+7)/8)-1]);
slouken@0
   397
	} else {
slouken@0
   398
		return((SDL_Rect **)-1);
slouken@0
   399
	}
slouken@0
   400
}
slouken@0
   401
slouken@0
   402
slouken@0
   403
/*
slouken@0
   404
  Helper fn to work out which screen depth windows is currently using.
slouken@0
   405
  15 bit mode is considered 555 format, 16 bit is 565.
slouken@0
   406
  returns 0 for unknown mode.
slouken@0
   407
  (Derived from code in sept 1999 Windows Developer Journal
slouken@0
   408
  http://www.wdj.com/code/archive.html)
slouken@0
   409
*/
slouken@0
   410
static int DIB_SussScreenDepth()
slouken@0
   411
{
slouken@0
   412
#ifdef NO_GETDIBITS
slouken@0
   413
	int depth;
slouken@0
   414
	HDC hdc;
slouken@0
   415
slouken@0
   416
	hdc = GetDC(SDL_Window);
slouken@0
   417
	depth = GetDeviceCaps(hdc, PLANES) * GetDeviceCaps(hdc, BITSPIXEL);
slouken@0
   418
	ReleaseDC(SDL_Window, hdc);
slouken@0
   419
	return(depth);
slouken@0
   420
#else
slouken@1881
   421
    int depth;
slouken@0
   422
    int dib_size;
slouken@0
   423
    LPBITMAPINFOHEADER dib_hdr;
slouken@0
   424
    HDC hdc;
slouken@0
   425
    HBITMAP hbm;
slouken@0
   426
slouken@0
   427
    /* Allocate enough space for a DIB header plus palette (for
slouken@0
   428
     * 8-bit modes) or bitfields (for 16- and 32-bit modes)
slouken@0
   429
     */
slouken@0
   430
    dib_size = sizeof(BITMAPINFOHEADER) + 256 * sizeof (RGBQUAD);
slouken@1336
   431
    dib_hdr = (LPBITMAPINFOHEADER) SDL_malloc(dib_size);
slouken@1336
   432
    SDL_memset(dib_hdr, 0, dib_size);
slouken@0
   433
    dib_hdr->biSize = sizeof(BITMAPINFOHEADER);
slouken@0
   434
    
slouken@0
   435
    /* Get a device-dependent bitmap that's compatible with the
slouken@0
   436
       screen.
slouken@0
   437
     */
slouken@0
   438
    hdc = GetDC(NULL);
slouken@0
   439
    hbm = CreateCompatibleBitmap( hdc, 1, 1 );
slouken@0
   440
slouken@0
   441
    /* Convert the DDB to a DIB.  We need to call GetDIBits twice:
slouken@0
   442
     * the first call just fills in the BITMAPINFOHEADER; the 
slouken@0
   443
     * second fills in the bitfields or palette.
slouken@0
   444
     */
slouken@0
   445
    GetDIBits(hdc, hbm, 0, 1, NULL, (LPBITMAPINFO) dib_hdr, DIB_RGB_COLORS);
slouken@0
   446
    GetDIBits(hdc, hbm, 0, 1, NULL, (LPBITMAPINFO) dib_hdr, DIB_RGB_COLORS);
slouken@0
   447
    DeleteObject(hbm);
slouken@0
   448
    ReleaseDC(NULL, hdc);
slouken@0
   449
slouken@1881
   450
    depth = 0;
slouken@0
   451
    switch( dib_hdr->biBitCount )
slouken@0
   452
    {
slouken@1881
   453
    case 8:     depth = 8; break;
slouken@1881
   454
    case 24:    depth = 24; break;
slouken@1881
   455
    case 32:    depth = 32; break;
slouken@0
   456
    case 16:
slouken@0
   457
        if( dib_hdr->biCompression == BI_BITFIELDS ) {
slouken@0
   458
            /* check the red mask */
slouken@0
   459
            switch( ((DWORD*)((char*)dib_hdr + dib_hdr->biSize))[0] ) {
slouken@1881
   460
                case 0xf800: depth = 16; break;   /* 565 */
slouken@1881
   461
                case 0x7c00: depth = 15; break;   /* 555 */
slouken@0
   462
            }
slouken@0
   463
        }
slouken@0
   464
    }
slouken@1881
   465
    SDL_free(dib_hdr);
slouken@1881
   466
    return depth;
slouken@0
   467
#endif /* NO_GETDIBITS */
slouken@0
   468
}
slouken@0
   469
slouken@0
   470
slouken@0
   471
/* Various screen update functions available */
slouken@0
   472
static void DIB_NormalUpdate(_THIS, int numrects, SDL_Rect *rects);
slouken@0
   473
slouken@0
   474
SDL_Surface *DIB_SetVideoMode(_THIS, SDL_Surface *current,
slouken@0
   475
				int width, int height, int bpp, Uint32 flags)
slouken@0
   476
{
slouken@0
   477
	SDL_Surface *video;
slouken@0
   478
	Uint32 prev_flags;
slouken@0
   479
	DWORD style;
slouken@0
   480
	const DWORD directstyle =
slouken@0
   481
			(WS_POPUP);
slouken@0
   482
	const DWORD windowstyle = 
slouken@0
   483
			(WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX);
slouken@0
   484
	const DWORD resizestyle =
slouken@0
   485
			(WS_THICKFRAME|WS_MAXIMIZEBOX);
slouken@0
   486
	int binfo_size;
slouken@0
   487
	BITMAPINFO *binfo;
slouken@0
   488
	HDC hdc;
slouken@0
   489
	RECT bounds;
slouken@0
   490
	int x, y;
slouken@0
   491
	Uint32 Rmask, Gmask, Bmask;
slouken@0
   492
slouken@0
   493
	/* Clean up any GL context that may be hanging around */
slouken@0
   494
	if ( current->flags & SDL_OPENGL ) {
slouken@0
   495
		WIN_GL_ShutDown(this);
slouken@0
   496
	}
slouken@1291
   497
	SDL_resizing = 1;
slouken@0
   498
slouken@0
   499
	/* Recalculate the bitmasks if necessary */
slouken@0
   500
	if ( bpp == current->format->BitsPerPixel ) {
slouken@0
   501
		video = current;
slouken@0
   502
	} else {
slouken@0
   503
		switch (bpp) {
slouken@0
   504
			case 15:
slouken@0
   505
			case 16:
slouken@0
   506
				if ( DIB_SussScreenDepth() == 15 ) {
slouken@0
   507
					/* 5-5-5 */
slouken@0
   508
					Rmask = 0x00007c00;
slouken@0
   509
					Gmask = 0x000003e0;
slouken@0
   510
					Bmask = 0x0000001f;
slouken@0
   511
				} else {
slouken@0
   512
					/* 5-6-5 */
slouken@0
   513
					Rmask = 0x0000f800;
slouken@0
   514
					Gmask = 0x000007e0;
slouken@0
   515
					Bmask = 0x0000001f;
slouken@0
   516
				}
slouken@0
   517
				break;
slouken@0
   518
			case 24:
slouken@0
   519
			case 32:
slouken@0
   520
				/* GDI defined as 8-8-8 */
slouken@0
   521
				Rmask = 0x00ff0000;
slouken@0
   522
				Gmask = 0x0000ff00;
slouken@0
   523
				Bmask = 0x000000ff;
slouken@0
   524
				break;
slouken@0
   525
			default:
slouken@0
   526
				Rmask = 0x00000000;
slouken@0
   527
				Gmask = 0x00000000;
slouken@0
   528
				Bmask = 0x00000000;
slouken@0
   529
				break;
slouken@0
   530
		}
slouken@0
   531
		video = SDL_CreateRGBSurface(SDL_SWSURFACE,
slouken@0
   532
					0, 0, bpp, Rmask, Gmask, Bmask, 0);
slouken@0
   533
		if ( video == NULL ) {
slouken@0
   534
			SDL_OutOfMemory();
slouken@0
   535
			return(NULL);
slouken@0
   536
		}
slouken@0
   537
	}
slouken@0
   538
slouken@0
   539
	/* Fill in part of the video surface */
slouken@0
   540
	prev_flags = video->flags;
slouken@0
   541
	video->flags = 0;	/* Clear flags */
slouken@0
   542
	video->w = width;
slouken@0
   543
	video->h = height;
slouken@0
   544
	video->pitch = SDL_CalculatePitch(video);
slouken@0
   545
icculus@1152
   546
	/* Small fix for WinCE/Win32 - when activating window
icculus@1152
   547
	   SDL_VideoSurface is equal to zero, so activating code
icculus@1152
   548
	   is not called properly for fullscreen windows because
icculus@1152
   549
	   macros WINDIB_FULLSCREEN uses SDL_VideoSurface
icculus@1152
   550
	*/
icculus@1152
   551
	SDL_VideoSurface = video;
icculus@1152
   552
icculus@1152
   553
#if defined(_WIN32_WCE)
icculus@1152
   554
	if ( flags & SDL_FULLSCREEN )
slouken@514
   555
		video->flags |= SDL_FULLSCREEN;
slouken@514
   556
#endif
icculus@1152
   557
slouken@0
   558
#ifndef NO_CHANGEDISPLAYSETTINGS
slouken@0
   559
	/* Set fullscreen mode if appropriate */
slouken@0
   560
	if ( (flags & SDL_FULLSCREEN) == SDL_FULLSCREEN ) {
slouken@0
   561
		DEVMODE settings;
slouken@1295
   562
		BOOL changed;
slouken@0
   563
slouken@1336
   564
		SDL_memset(&settings, 0, sizeof(DEVMODE));
slouken@0
   565
		settings.dmSize = sizeof(DEVMODE);
slouken@1465
   566
slouken@1465
   567
#ifdef _WIN32_WCE
slouken@1465
   568
		// try to rotate screen to fit requested resolution
slouken@1465
   569
		if( this->hidden->supportRotation )
slouken@1465
   570
		{
slouken@1465
   571
			DWORD rotation;
slouken@1465
   572
slouken@1465
   573
			// ask current mode
slouken@1465
   574
			settings.dmFields = DM_DISPLAYORIENTATION;
slouken@1465
   575
			ChangeDisplaySettingsEx(NULL, &settings, NULL, CDS_TEST, NULL);
slouken@1465
   576
			rotation = settings.dmDisplayOrientation;
slouken@1465
   577
slouken@1465
   578
			if( (width > GetDeviceCaps(GetDC(NULL), HORZRES))
slouken@1465
   579
				&& (height < GetDeviceCaps(GetDC(NULL), VERTRES)))
slouken@1465
   580
			{
slouken@1465
   581
				switch( rotation )
slouken@1465
   582
				{
slouken@1465
   583
				case DMDO_0:
slouken@1465
   584
					settings.dmDisplayOrientation = DMDO_90;
slouken@1465
   585
					break;
slouken@1465
   586
				case DMDO_270:
slouken@1465
   587
					settings.dmDisplayOrientation = DMDO_180;
slouken@1465
   588
					break;
slouken@1465
   589
				}
slouken@1465
   590
				if( settings.dmDisplayOrientation != rotation )
slouken@1465
   591
				{
slouken@1465
   592
					// go to landscape
slouken@1465
   593
					this->hidden->origRotation = rotation;
slouken@1465
   594
					ChangeDisplaySettingsEx(NULL,&settings,NULL,CDS_RESET,NULL);
slouken@1465
   595
				}
slouken@1465
   596
			}
slouken@1465
   597
			if( (width < GetDeviceCaps(GetDC(NULL), HORZRES))
slouken@1465
   598
				&& (height > GetDeviceCaps(GetDC(NULL), VERTRES)))
slouken@1465
   599
			{
slouken@1465
   600
				switch( rotation )
slouken@1465
   601
				{
slouken@1465
   602
				case DMDO_90:
slouken@1465
   603
					settings.dmDisplayOrientation = DMDO_0;
slouken@1465
   604
					break;
slouken@1465
   605
				case DMDO_180:
slouken@1465
   606
					settings.dmDisplayOrientation = DMDO_270;
slouken@1465
   607
					break;
slouken@1465
   608
				}
slouken@1465
   609
				if( settings.dmDisplayOrientation != rotation )
slouken@1465
   610
				{
slouken@1465
   611
					// go to portrait
slouken@1465
   612
					this->hidden->origRotation = rotation;
slouken@1465
   613
					ChangeDisplaySettingsEx(NULL,&settings,NULL,CDS_RESET,NULL);
slouken@1465
   614
				}
slouken@1465
   615
			}
slouken@1465
   616
slouken@1465
   617
		}
slouken@1465
   618
#endif
slouken@1465
   619
slouken@1465
   620
#ifndef _WIN32_WCE
slouken@0
   621
		settings.dmBitsPerPel = video->format->BitsPerPixel;
slouken@0
   622
		settings.dmPelsWidth = width;
slouken@0
   623
		settings.dmPelsHeight = height;
slouken@0
   624
		settings.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL;
slouken@1330
   625
		if ( width <= (int)SDL_desktop_mode.dmPelsWidth &&
slouken@1330
   626
		     height <= (int)SDL_desktop_mode.dmPelsHeight ) {
slouken@1295
   627
			settings.dmDisplayFrequency = SDL_desktop_mode.dmDisplayFrequency;
slouken@1295
   628
			settings.dmFields |= DM_DISPLAYFREQUENCY;
slouken@1295
   629
		}
slouken@1295
   630
		changed = (ChangeDisplaySettings(&settings, CDS_FULLSCREEN) == DISP_CHANGE_SUCCESSFUL);
slouken@1295
   631
		if ( ! changed && (settings.dmFields & DM_DISPLAYFREQUENCY) ) {
slouken@1295
   632
			settings.dmFields &= ~DM_DISPLAYFREQUENCY;
slouken@1295
   633
			changed = (ChangeDisplaySettings(&settings, CDS_FULLSCREEN) == DISP_CHANGE_SUCCESSFUL);
slouken@1295
   634
		}
slouken@1465
   635
#else
slouken@1465
   636
		changed = 1;
slouken@1465
   637
#endif
slouken@1295
   638
		if ( changed ) {
slouken@0
   639
			video->flags |= SDL_FULLSCREEN;
slouken@304
   640
			SDL_fullscreen_mode = settings;
slouken@0
   641
		}
slouken@1465
   642
slouken@0
   643
	}
slouken@0
   644
#endif /* !NO_CHANGEDISPLAYSETTINGS */
slouken@0
   645
slouken@45
   646
	/* Reset the palette and create a new one if necessary */
slouken@45
   647
	if ( screen_pal != NULL ) {
slouken@45
   648
	/*	RJR: March 28, 2000
slouken@45
   649
		delete identity palette if switching from a palettized mode */
slouken@45
   650
		DeleteObject(screen_pal);
slouken@45
   651
		screen_pal = NULL;
slouken@45
   652
	}
slouken@45
   653
	if ( bpp <= 8 )
slouken@45
   654
	{
slouken@45
   655
	/*	RJR: March 28, 2000
slouken@45
   656
		create identity palette switching to a palettized mode */
slouken@45
   657
		screen_pal = DIB_CreatePalette(bpp);
slouken@45
   658
	}
slouken@45
   659
slouken@1480
   660
	style = GetWindowLong(SDL_Window, GWL_STYLE);
slouken@0
   661
	style &= ~(resizestyle|WS_MAXIMIZE);
slouken@0
   662
	if ( (video->flags & SDL_FULLSCREEN) == SDL_FULLSCREEN ) {
slouken@0
   663
		style &= ~windowstyle;
slouken@0
   664
		style |= directstyle;
slouken@0
   665
	} else {
slouken@0
   666
#ifndef NO_CHANGEDISPLAYSETTINGS
slouken@0
   667
		if ( (prev_flags & SDL_FULLSCREEN) == SDL_FULLSCREEN ) {
slouken@0
   668
			ChangeDisplaySettings(NULL, 0);
slouken@0
   669
		}
slouken@0
   670
#endif
slouken@0
   671
		if ( flags & SDL_NOFRAME ) {
slouken@0
   672
			style &= ~windowstyle;
slouken@0
   673
			style |= directstyle;
slouken@0
   674
			video->flags |= SDL_NOFRAME;
slouken@0
   675
		} else {
slouken@0
   676
			style &= ~directstyle;
slouken@0
   677
			style |= windowstyle;
slouken@0
   678
			if ( flags & SDL_RESIZABLE ) {
slouken@0
   679
				style |= resizestyle;
slouken@0
   680
				video->flags |= SDL_RESIZABLE;
slouken@0
   681
			}
slouken@0
   682
		}
slouken@453
   683
#if WS_MAXIMIZE
slouken@0
   684
		if (IsZoomed(SDL_Window)) style |= WS_MAXIMIZE;
slouken@36
   685
#endif
slouken@0
   686
	}
slouken@145
   687
slouken@448
   688
	/* DJM: Don't piss of anyone who has setup his own window */
slouken@1280
   689
	if ( !SDL_windowid )
slouken@1480
   690
		SetWindowLong(SDL_Window, GWL_STYLE, style);
slouken@0
   691
slouken@0
   692
	/* Delete the old bitmap if necessary */
slouken@0
   693
	if ( screen_bmp != NULL ) {
slouken@0
   694
		DeleteObject(screen_bmp);
slouken@0
   695
	}
slouken@0
   696
	if ( ! (flags & SDL_OPENGL) ) {
slouken@0
   697
		BOOL is16bitmode = (video->format->BytesPerPixel == 2);
slouken@0
   698
slouken@0
   699
		/* Suss out the bitmap info header */
slouken@0
   700
		binfo_size = sizeof(*binfo);
slouken@0
   701
		if( is16bitmode ) {
slouken@0
   702
			/* 16bit modes, palette area used for rgb bitmasks */
slouken@0
   703
			binfo_size += 3*sizeof(DWORD);
slouken@0
   704
		} else if ( video->format->palette ) {
slouken@0
   705
			binfo_size += video->format->palette->ncolors *
slouken@0
   706
							sizeof(RGBQUAD);
slouken@0
   707
		}
slouken@1336
   708
		binfo = (BITMAPINFO *)SDL_malloc(binfo_size);
slouken@0
   709
		if ( ! binfo ) {
slouken@0
   710
			if ( video != current ) {
slouken@0
   711
				SDL_FreeSurface(video);
slouken@0
   712
			}
slouken@0
   713
			SDL_OutOfMemory();
slouken@0
   714
			return(NULL);
slouken@0
   715
		}
slouken@0
   716
slouken@0
   717
		binfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
slouken@0
   718
		binfo->bmiHeader.biWidth = video->w;
slouken@0
   719
		binfo->bmiHeader.biHeight = -video->h;	/* -ve for topdown bitmap */
slouken@0
   720
		binfo->bmiHeader.biPlanes = 1;
slouken@0
   721
		binfo->bmiHeader.biSizeImage = video->h * video->pitch;
slouken@0
   722
		binfo->bmiHeader.biXPelsPerMeter = 0;
slouken@0
   723
		binfo->bmiHeader.biYPelsPerMeter = 0;
slouken@0
   724
		binfo->bmiHeader.biClrUsed = 0;
slouken@0
   725
		binfo->bmiHeader.biClrImportant = 0;
slouken@0
   726
		binfo->bmiHeader.biBitCount = video->format->BitsPerPixel;
slouken@0
   727
slouken@0
   728
		if ( is16bitmode ) {
slouken@0
   729
			/* BI_BITFIELDS tells CreateDIBSection about the rgb masks in the palette */
slouken@0
   730
			binfo->bmiHeader.biCompression = BI_BITFIELDS;
slouken@0
   731
			((Uint32*)binfo->bmiColors)[0] = video->format->Rmask;
slouken@0
   732
			((Uint32*)binfo->bmiColors)[1] = video->format->Gmask;
slouken@0
   733
			((Uint32*)binfo->bmiColors)[2] = video->format->Bmask;
slouken@0
   734
		} else {
slouken@0
   735
			binfo->bmiHeader.biCompression = BI_RGB;	/* BI_BITFIELDS for 565 vs 555 */
slouken@0
   736
			if ( video->format->palette ) {
slouken@1336
   737
				SDL_memset(binfo->bmiColors, 0,
slouken@0
   738
					video->format->palette->ncolors*sizeof(RGBQUAD));
slouken@0
   739
			}
slouken@0
   740
		}
slouken@0
   741
slouken@0
   742
		/* Create the offscreen bitmap buffer */
slouken@0
   743
		hdc = GetDC(SDL_Window);
slouken@0
   744
		screen_bmp = CreateDIBSection(hdc, binfo, DIB_RGB_COLORS,
slouken@0
   745
					(void **)(&video->pixels), NULL, 0);
slouken@0
   746
		ReleaseDC(SDL_Window, hdc);
slouken@1336
   747
		SDL_free(binfo);
slouken@0
   748
		if ( screen_bmp == NULL ) {
slouken@0
   749
			if ( video != current ) {
slouken@0
   750
				SDL_FreeSurface(video);
slouken@0
   751
			}
slouken@0
   752
			SDL_SetError("Couldn't create DIB section");
slouken@0
   753
			return(NULL);
slouken@0
   754
		}
slouken@0
   755
		this->UpdateRects = DIB_NormalUpdate;
slouken@0
   756
slouken@0
   757
		/* Set video surface flags */
slouken@0
   758
		if ( bpp <= 8 ) {
slouken@3976
   759
			if ( (video->flags & SDL_FULLSCREEN) == SDL_FULLSCREEN ) {
slouken@3976
   760
				hdc = GetDC(SDL_Window);
slouken@3976
   761
				SetSystemPaletteUse(hdc, SYSPAL_NOSTATIC);
slouken@3976
   762
				ReleaseDC(SDL_Window, hdc);
slouken@3976
   763
			}
slouken@0
   764
			/* BitBlt() maps colors for us */
slouken@0
   765
			video->flags |= SDL_HWPALETTE;
slouken@0
   766
		}
slouken@0
   767
	}
slouken@1465
   768
#ifndef _WIN32_WCE
slouken@0
   769
	/* Resize the window */
slouken@1290
   770
	if ( !SDL_windowid && !IsZoomed(SDL_Window) ) {
slouken@1465
   771
#else
slouken@1465
   772
	if ( !SDL_windowid ) {
slouken@1465
   773
#endif
slouken@448
   774
		HWND top;
slouken@0
   775
		UINT swp_flags;
slouken@1290
   776
		const char *window = NULL;
slouken@1290
   777
		const char *center = NULL;
slouken@833
   778
slouken@833
   779
		if ( !SDL_windowX && !SDL_windowY ) {
slouken@1336
   780
			window = SDL_getenv("SDL_VIDEO_WINDOW_POS");
slouken@1336
   781
			center = SDL_getenv("SDL_VIDEO_CENTERED");
slouken@833
   782
			if ( window ) {
slouken@1336
   783
				if ( SDL_sscanf(window, "%d,%d", &x, &y) == 2 ) {
slouken@833
   784
					SDL_windowX = x;
slouken@833
   785
					SDL_windowY = y;
slouken@833
   786
				}
slouken@1336
   787
				if ( SDL_strcmp(window, "center") == 0 ) {
slouken@833
   788
					center = window;
slouken@833
   789
				}
slouken@833
   790
			}
slouken@833
   791
		}
slouken@833
   792
		swp_flags = (SWP_NOCOPYBITS | SWP_SHOWWINDOW);
slouken@0
   793
slouken@833
   794
		bounds.left = SDL_windowX;
slouken@833
   795
		bounds.top = SDL_windowY;
slouken@833
   796
		bounds.right = SDL_windowX+video->w;
slouken@833
   797
		bounds.bottom = SDL_windowY+video->h;
slouken@3868
   798
#ifndef _WIN32_WCE
slouken@1882
   799
		AdjustWindowRectEx(&bounds, GetWindowLong(SDL_Window, GWL_STYLE), (GetMenu(SDL_Window) != NULL), 0);
slouken@3868
   800
#else
slouken@3868
   801
		// The bMenu parameter must be FALSE; menu bars are not supported
slouken@3868
   802
		AdjustWindowRectEx(&bounds, GetWindowLong(SDL_Window, GWL_STYLE), 0, 0);
slouken@3868
   803
#endif
slouken@0
   804
		width = bounds.right-bounds.left;
slouken@0
   805
		height = bounds.bottom-bounds.top;
slouken@833
   806
		if ( (flags & SDL_FULLSCREEN) ) {
slouken@833
   807
			x = (GetSystemMetrics(SM_CXSCREEN)-width)/2;
slouken@833
   808
			y = (GetSystemMetrics(SM_CYSCREEN)-height)/2;
slouken@971
   809
		} else if ( center ) {
slouken@971
   810
			x = (GetSystemMetrics(SM_CXSCREEN)-width)/2;
slouken@971
   811
			y = (GetSystemMetrics(SM_CYSCREEN)-height)/2;
slouken@833
   812
		} else if ( SDL_windowX || SDL_windowY || window ) {
slouken@833
   813
			x = bounds.left;
slouken@833
   814
			y = bounds.top;
slouken@833
   815
		} else {
slouken@833
   816
			x = y = -1;
slouken@833
   817
			swp_flags |= SWP_NOMOVE;
slouken@833
   818
		}
slouken@448
   819
		if ( flags & SDL_FULLSCREEN ) {
slouken@448
   820
			top = HWND_TOPMOST;
slouken@448
   821
		} else {
slouken@448
   822
			top = HWND_NOTOPMOST;
slouken@448
   823
		}
slouken@448
   824
		SetWindowPos(SDL_Window, top, x, y, width, height, swp_flags);
slouken@1291
   825
		if ( !(flags & SDL_FULLSCREEN) ) {
slouken@1291
   826
			SDL_windowX = SDL_bounds.left;
slouken@1291
   827
			SDL_windowY = SDL_bounds.top;
slouken@1291
   828
		}
slouken@0
   829
		SetForegroundWindow(SDL_Window);
slouken@0
   830
	}
slouken@1291
   831
	SDL_resizing = 0;
slouken@0
   832
slouken@0
   833
	/* Set up for OpenGL */
slouken@0
   834
	if ( flags & SDL_OPENGL ) {
slouken@0
   835
		if ( WIN_GL_SetupWindow(this) < 0 ) {
slouken@0
   836
			return(NULL);
slouken@0
   837
		}
slouken@0
   838
		video->flags |= SDL_OPENGL;
slouken@0
   839
	}
slouken@36
   840
slouken@1523
   841
	/* JC 14 Mar 2006
slouken@1523
   842
		Flush the message loop or this can cause big problems later
slouken@1523
   843
		Especially if the user decides to use dialog boxes or assert()!
slouken@1523
   844
	*/
slouken@1523
   845
	WIN_FlushMessageQueue();
slouken@1523
   846
slouken@0
   847
	/* We're live! */
slouken@0
   848
	return(video);
slouken@0
   849
}
slouken@0
   850
slouken@0
   851
/* We don't actually allow hardware surfaces in the DIB driver */
slouken@0
   852
static int DIB_AllocHWSurface(_THIS, SDL_Surface *surface)
slouken@0
   853
{
slouken@0
   854
	return(-1);
slouken@0
   855
}
slouken@0
   856
static void DIB_FreeHWSurface(_THIS, SDL_Surface *surface)
slouken@0
   857
{
slouken@0
   858
	return;
slouken@0
   859
}
slouken@0
   860
static int DIB_LockHWSurface(_THIS, SDL_Surface *surface)
slouken@0
   861
{
slouken@0
   862
	return(0);
slouken@0
   863
}
slouken@0
   864
static void DIB_UnlockHWSurface(_THIS, SDL_Surface *surface)
slouken@0
   865
{
slouken@0
   866
	return;
slouken@0
   867
}
slouken@0
   868
slouken@0
   869
static void DIB_NormalUpdate(_THIS, int numrects, SDL_Rect *rects)
slouken@0
   870
{
slouken@0
   871
	HDC hdc, mdc;
slouken@0
   872
	int i;
slouken@0
   873
slouken@0
   874
	hdc = GetDC(SDL_Window);
slouken@0
   875
	if ( screen_pal ) {
slouken@0
   876
		SelectPalette(hdc, screen_pal, FALSE);
slouken@0
   877
	}
slouken@0
   878
	mdc = CreateCompatibleDC(hdc);
slouken@0
   879
	SelectObject(mdc, screen_bmp);
slouken@0
   880
	for ( i=0; i<numrects; ++i ) {
slouken@0
   881
		BitBlt(hdc, rects[i].x, rects[i].y, rects[i].w, rects[i].h,
slouken@0
   882
					mdc, rects[i].x, rects[i].y, SRCCOPY);
slouken@0
   883
	}
slouken@0
   884
	DeleteDC(mdc);
slouken@0
   885
	ReleaseDC(SDL_Window, hdc);
slouken@0
   886
}
slouken@0
   887
icculus@1251
   888
slouken@0
   889
int DIB_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors)
slouken@0
   890
{
slouken@1292
   891
#if !defined(_WIN32_WCE) || (_WIN32_WCE >= 400)
slouken@1292
   892
	HDC hdc, mdc;
slouken@0
   893
	RGBQUAD *pal;
slouken@1292
   894
#else
icculus@1251
   895
	HDC hdc;
slouken@36
   896
#endif
slouken@1292
   897
	int i;
slouken@0
   898
slouken@0
   899
	/* Update the display palette */
slouken@0
   900
	hdc = GetDC(SDL_Window);
slouken@0
   901
	if ( screen_pal ) {
slouken@0
   902
		PALETTEENTRY *entries;
slouken@0
   903
slouken@1330
   904
		entries = SDL_stack_alloc(PALETTEENTRY, ncolors);
slouken@0
   905
		for ( i=0; i<ncolors; ++i ) {
slouken@0
   906
			entries[i].peRed   = colors[i].r;
slouken@0
   907
			entries[i].peGreen = colors[i].g;
slouken@0
   908
			entries[i].peBlue  = colors[i].b;
slouken@0
   909
			entries[i].peFlags = PC_NOCOLLAPSE;
slouken@0
   910
		}
slouken@0
   911
		SetPaletteEntries(screen_pal, firstcolor, ncolors, entries);
slouken@0
   912
		SelectPalette(hdc, screen_pal, FALSE);
slouken@0
   913
		RealizePalette(hdc);
slouken@1330
   914
		SDL_stack_free(entries);
slouken@0
   915
	}
slouken@0
   916
slouken@1292
   917
#if !defined(_WIN32_WCE) || (_WIN32_WCE >= 400)
slouken@0
   918
	/* Copy palette colors into DIB palette */
slouken@1330
   919
	pal = SDL_stack_alloc(RGBQUAD, ncolors);
slouken@0
   920
	for ( i=0; i<ncolors; ++i ) {
slouken@0
   921
		pal[i].rgbRed = colors[i].r;
slouken@0
   922
		pal[i].rgbGreen = colors[i].g;
slouken@0
   923
		pal[i].rgbBlue = colors[i].b;
slouken@0
   924
		pal[i].rgbReserved = 0;
slouken@0
   925
	}
slouken@0
   926
slouken@0
   927
	/* Set the DIB palette and update the display */
slouken@0
   928
	mdc = CreateCompatibleDC(hdc);
slouken@0
   929
	SelectObject(mdc, screen_bmp);
slouken@0
   930
	SetDIBColorTable(mdc, firstcolor, ncolors, pal);
slouken@0
   931
	BitBlt(hdc, 0, 0, this->screen->w, this->screen->h,
slouken@0
   932
	       mdc, 0, 0, SRCCOPY);
slouken@0
   933
	DeleteDC(mdc);
slouken@1330
   934
	SDL_stack_free(pal);
slouken@36
   935
#endif
slouken@0
   936
	ReleaseDC(SDL_Window, hdc);
slouken@0
   937
	return(1);
slouken@0
   938
}
slouken@0
   939
icculus@1251
   940
slouken@0
   941
static void DIB_CheckGamma(_THIS)
slouken@0
   942
{
slouken@0
   943
#ifndef NO_GAMMA_SUPPORT
slouken@0
   944
	HDC hdc;
slouken@0
   945
	WORD ramp[3*256];
slouken@0
   946
slouken@0
   947
	/* If we fail to get gamma, disable gamma control */
slouken@0
   948
	hdc = GetDC(SDL_Window);
slouken@0
   949
	if ( ! GetDeviceGammaRamp(hdc, ramp) ) {
slouken@0
   950
		this->GetGammaRamp = NULL;
slouken@0
   951
		this->SetGammaRamp = NULL;
slouken@0
   952
	}
slouken@0
   953
	ReleaseDC(SDL_Window, hdc);
slouken@0
   954
#endif /* !NO_GAMMA_SUPPORT */
slouken@0
   955
}
slouken@338
   956
void DIB_SwapGamma(_THIS)
slouken@0
   957
{
slouken@0
   958
#ifndef NO_GAMMA_SUPPORT
slouken@0
   959
	HDC hdc;
slouken@0
   960
slouken@0
   961
	if ( gamma_saved ) {
slouken@0
   962
		hdc = GetDC(SDL_Window);
slouken@0
   963
		if ( SDL_GetAppState() & SDL_APPINPUTFOCUS ) {
slouken@0
   964
			/* About to leave active state, restore gamma */
slouken@0
   965
			SetDeviceGammaRamp(hdc, gamma_saved);
slouken@0
   966
		} else {
slouken@0
   967
			/* About to enter active state, set game gamma */
slouken@0
   968
			GetDeviceGammaRamp(hdc, gamma_saved);
slouken@0
   969
			SetDeviceGammaRamp(hdc, this->gamma);
slouken@0
   970
		}
slouken@0
   971
		ReleaseDC(SDL_Window, hdc);
slouken@0
   972
	}
slouken@0
   973
#endif /* !NO_GAMMA_SUPPORT */
slouken@0
   974
}
slouken@338
   975
void DIB_QuitGamma(_THIS)
slouken@0
   976
{
slouken@0
   977
#ifndef NO_GAMMA_SUPPORT
slouken@0
   978
	if ( gamma_saved ) {
slouken@0
   979
		/* Restore the original gamma if necessary */
slouken@0
   980
		if ( SDL_GetAppState() & SDL_APPINPUTFOCUS ) {
slouken@0
   981
			HDC hdc;
slouken@0
   982
slouken@0
   983
			hdc = GetDC(SDL_Window);
slouken@0
   984
			SetDeviceGammaRamp(hdc, gamma_saved);
slouken@0
   985
			ReleaseDC(SDL_Window, hdc);
slouken@0
   986
		}
slouken@0
   987
slouken@0
   988
		/* Free the saved gamma memory */
slouken@1336
   989
		SDL_free(gamma_saved);
slouken@0
   990
		gamma_saved = 0;
slouken@0
   991
	}
slouken@0
   992
#endif /* !NO_GAMMA_SUPPORT */
slouken@0
   993
}
slouken@0
   994
slouken@338
   995
int DIB_SetGammaRamp(_THIS, Uint16 *ramp)
slouken@0
   996
{
slouken@338
   997
#ifdef NO_GAMMA_SUPPORT
slouken@338
   998
	SDL_SetError("SDL compiled without gamma ramp support");
slouken@338
   999
	return -1;
slouken@338
  1000
#else
slouken@0
  1001
	HDC hdc;
slouken@0
  1002
	BOOL succeeded;
slouken@0
  1003
slouken@0
  1004
	/* Set the ramp for the display */
slouken@0
  1005
	if ( ! gamma_saved ) {
slouken@1336
  1006
		gamma_saved = (WORD *)SDL_malloc(3*256*sizeof(*gamma_saved));
slouken@0
  1007
		if ( ! gamma_saved ) {
slouken@0
  1008
			SDL_OutOfMemory();
slouken@0
  1009
			return -1;
slouken@0
  1010
		}
slouken@0
  1011
		hdc = GetDC(SDL_Window);
slouken@0
  1012
		GetDeviceGammaRamp(hdc, gamma_saved);
slouken@0
  1013
		ReleaseDC(SDL_Window, hdc);
slouken@0
  1014
	}
slouken@0
  1015
	if ( SDL_GetAppState() & SDL_APPINPUTFOCUS ) {
slouken@0
  1016
		hdc = GetDC(SDL_Window);
slouken@0
  1017
		succeeded = SetDeviceGammaRamp(hdc, ramp);
slouken@0
  1018
		ReleaseDC(SDL_Window, hdc);
slouken@0
  1019
	} else {
slouken@0
  1020
		succeeded = TRUE;
slouken@0
  1021
	}
slouken@0
  1022
	return succeeded ? 0 : -1;
slouken@338
  1023
#endif /* !NO_GAMMA_SUPPORT */
slouken@0
  1024
}
slouken@0
  1025
slouken@338
  1026
int DIB_GetGammaRamp(_THIS, Uint16 *ramp)
slouken@0
  1027
{
slouken@338
  1028
#ifdef NO_GAMMA_SUPPORT
slouken@338
  1029
	SDL_SetError("SDL compiled without gamma ramp support");
slouken@338
  1030
	return -1;
slouken@338
  1031
#else
slouken@0
  1032
	HDC hdc;
slouken@0
  1033
	BOOL succeeded;
slouken@0
  1034
slouken@0
  1035
	/* Get the ramp from the display */
slouken@0
  1036
	hdc = GetDC(SDL_Window);
slouken@0
  1037
	succeeded = GetDeviceGammaRamp(hdc, ramp);
slouken@0
  1038
	ReleaseDC(SDL_Window, hdc);
slouken@0
  1039
	return succeeded ? 0 : -1;
slouken@338
  1040
#endif /* !NO_GAMMA_SUPPORT */
slouken@0
  1041
}
slouken@0
  1042
slouken@0
  1043
void DIB_VideoQuit(_THIS)
slouken@0
  1044
{
slouken@1881
  1045
	int i, j;
slouken@1881
  1046
slouken@0
  1047
	/* Destroy the window and everything associated with it */
slouken@0
  1048
	if ( SDL_Window ) {
slouken@0
  1049
		/* Delete the screen bitmap (also frees screen->pixels) */
slouken@0
  1050
		if ( this->screen ) {
slouken@0
  1051
#ifndef NO_CHANGEDISPLAYSETTINGS
slouken@0
  1052
			if ( this->screen->flags & SDL_FULLSCREEN ) {
slouken@0
  1053
				ChangeDisplaySettings(NULL, 0);
slouken@376
  1054
				ShowWindow(SDL_Window, SW_HIDE);
slouken@0
  1055
			}
slouken@0
  1056
#endif
slouken@0
  1057
			if ( this->screen->flags & SDL_OPENGL ) {
slouken@0
  1058
				WIN_GL_ShutDown(this);
slouken@0
  1059
			}
slouken@0
  1060
			this->screen->pixels = NULL;
slouken@0
  1061
		}
slouken@0
  1062
		if ( screen_bmp ) {
slouken@0
  1063
			DeleteObject(screen_bmp);
slouken@0
  1064
			screen_bmp = NULL;
slouken@0
  1065
		}
slouken@0
  1066
		if ( screen_icn ) {
slouken@0
  1067
			DestroyIcon(screen_icn);
slouken@0
  1068
			screen_icn = NULL;
slouken@0
  1069
		}
slouken@0
  1070
		DIB_QuitGamma(this);
slouken@0
  1071
		DIB_DestroyWindow(this);
slouken@0
  1072
slouken@0
  1073
		SDL_Window = NULL;
icculus@1152
  1074
icculus@1152
  1075
#if defined(_WIN32_WCE)
icculus@1152
  1076
icculus@1152
  1077
// Unload wince aygshell library to prevent leak
icculus@1152
  1078
		if( aygshell ) 
icculus@1152
  1079
		{
icculus@1152
  1080
			FreeLibrary(aygshell);
icculus@1152
  1081
			aygshell = NULL;
icculus@1152
  1082
		}
icculus@1152
  1083
#endif
slouken@1881
  1084
	}
icculus@1152
  1085
slouken@1881
  1086
	for ( i=0; i < SDL_arraysize(SDL_modelist); ++i ) {
slouken@1881
  1087
		if ( !SDL_modelist[i] ) {
slouken@1881
  1088
			continue;
slouken@1881
  1089
		}
slouken@1881
  1090
		for ( j=0; SDL_modelist[i][j]; ++j ) {
slouken@1881
  1091
			SDL_free(SDL_modelist[i][j]);
slouken@1881
  1092
		}
slouken@1881
  1093
		SDL_free(SDL_modelist[i]);
slouken@1881
  1094
		SDL_modelist[i] = NULL;
slouken@1881
  1095
		SDL_nummodes[i] = 0;
slouken@0
  1096
	}
slouken@0
  1097
}
slouken@0
  1098
slouken@0
  1099
/* Exported for the windows message loop only */
slouken@0
  1100
static void DIB_FocusPalette(_THIS, int foreground)
slouken@0
  1101
{
slouken@0
  1102
	if ( screen_pal != NULL ) {
slouken@0
  1103
		HDC hdc;
slouken@0
  1104
slouken@0
  1105
		hdc = GetDC(SDL_Window);
slouken@0
  1106
		SelectPalette(hdc, screen_pal, FALSE);
slouken@0
  1107
		if ( RealizePalette(hdc) )
slouken@0
  1108
			InvalidateRect(SDL_Window, NULL, FALSE);
slouken@0
  1109
		ReleaseDC(SDL_Window, hdc);
slouken@0
  1110
	}
slouken@0
  1111
}
slouken@0
  1112
static void DIB_RealizePalette(_THIS)
slouken@0
  1113
{
slouken@0
  1114
	DIB_FocusPalette(this, 1);
slouken@0
  1115
}
slouken@0
  1116
static void DIB_PaletteChanged(_THIS, HWND window)
slouken@0
  1117
{
slouken@0
  1118
	if ( window != SDL_Window ) {
slouken@0
  1119
		DIB_FocusPalette(this, 0);
slouken@0
  1120
	}
slouken@0
  1121
}
slouken@0
  1122
slouken@0
  1123
/* Exported for the windows message loop only */
slouken@0
  1124
static void DIB_WinPAINT(_THIS, HDC hdc)
slouken@0
  1125
{
slouken@0
  1126
	HDC mdc;
slouken@0
  1127
slouken@0
  1128
	if ( screen_pal ) {
slouken@0
  1129
		SelectPalette(hdc, screen_pal, FALSE);
slouken@0
  1130
	}
slouken@0
  1131
	mdc = CreateCompatibleDC(hdc);
slouken@0
  1132
	SelectObject(mdc, screen_bmp);
slouken@0
  1133
	BitBlt(hdc, 0, 0, SDL_VideoSurface->w, SDL_VideoSurface->h,
slouken@0
  1134
							mdc, 0, 0, SRCCOPY);
slouken@0
  1135
	DeleteDC(mdc);
slouken@0
  1136
}
slouken@0
  1137
slouken@0
  1138
/* Stub in case DirectX isn't available */
slouken@1361
  1139
#if !SDL_AUDIO_DRIVER_DSOUND
slouken@0
  1140
void DX5_SoundFocus(HWND hwnd)
slouken@0
  1141
{
slouken@0
  1142
	return;
slouken@0
  1143
}
slouken@0
  1144
#endif