src/video/windib/SDL_dibvideo.c

/* [<][>]
[^][v][top][bottom][index][help] */

FUNCTIONS

This source file includes following functions.
  1. DIB_Available
  2. DIB_DeleteDevice
  3. DIB_CreateDevice
  4. cmpmodes
  5. DIB_AddMode
  6. DIB_CreatePalette
  7. DIB_VideoInit
  8. DIB_ListModes
  9. DIB_SussScreenDepth
  10. DIB_SetVideoMode
  11. DIB_AllocHWSurface
  12. DIB_FreeHWSurface
  13. DIB_LockHWSurface
  14. DIB_UnlockHWSurface
  15. DIB_NormalUpdate
  16. DIB_SetColors
  17. DIB_CheckGamma
  18. DIB_SwapGamma
  19. DIB_QuitGamma
  20. DIB_SetGammaRamp
  21. DIB_GetGammaRamp
  22. DIB_VideoQuit
  23. DIB_FocusPalette
  24. DIB_RealizePalette
  25. DIB_PaletteChanged
  26. DIB_WinPAINT
  27. DX5_SoundFocus

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

/* [<][>][^][v][top][bottom][index][help] */