SDL_dibvideo.c
上传用户:sun1608
上传日期:2007-02-02
资源大小:6116k
文件大小:25k
源码类别:

流媒体/Mpeg4/MP4

开发平台:

Visual C++

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