winshaddd.c 40 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222
  1. /*
  2. *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved.
  3. *
  4. *Permission is hereby granted, free of charge, to any person obtaining
  5. * a copy of this software and associated documentation files (the
  6. *"Software"), to deal in the Software without restriction, including
  7. *without limitation the rights to use, copy, modify, merge, publish,
  8. *distribute, sublicense, and/or sell copies of the Software, and to
  9. *permit persons to whom the Software is furnished to do so, subject to
  10. *the following conditions:
  11. *
  12. *The above copyright notice and this permission notice shall be
  13. *included in all copies or substantial portions of the Software.
  14. *
  15. *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  16. *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  17. *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  18. *NONINFRINGEMENT. IN NO EVENT SHALL THE XFREE86 PROJECT BE LIABLE FOR
  19. *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
  20. *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  21. *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  22. *
  23. *Except as contained in this notice, the name of the XFree86 Project
  24. *shall not be used in advertising or otherwise to promote the sale, use
  25. *or other dealings in this Software without prior written authorization
  26. *from the XFree86 Project.
  27. *
  28. * Authors: Dakshinamurthy Karra
  29. * Suhaib M Siddiqi
  30. * Peter Busch
  31. * Harold L Hunt II
  32. */
  33. #ifdef HAVE_XWIN_CONFIG_H
  34. #include <xwin-config.h>
  35. #endif
  36. #include "win.h"
  37. /*
  38. * Local prototypes
  39. */
  40. static Bool
  41. winAllocateFBShadowDD(ScreenPtr pScreen);
  42. static void
  43. winShadowUpdateDD(ScreenPtr pScreen, shadowBufPtr pBuf);
  44. static Bool
  45. winCloseScreenShadowDD(ScreenPtr pScreen);
  46. static Bool
  47. winInitVisualsShadowDD(ScreenPtr pScreen);
  48. static Bool
  49. winAdjustVideoModeShadowDD(ScreenPtr pScreen);
  50. static Bool
  51. winBltExposedRegionsShadowDD(ScreenPtr pScreen);
  52. static Bool
  53. winActivateAppShadowDD(ScreenPtr pScreen);
  54. static Bool
  55. winRedrawScreenShadowDD(ScreenPtr pScreen);
  56. static Bool
  57. winRealizeInstalledPaletteShadowDD(ScreenPtr pScreen);
  58. static Bool
  59. winInstallColormapShadowDD(ColormapPtr pColormap);
  60. static Bool
  61. winStoreColorsShadowDD(ColormapPtr pmap, int ndef, xColorItem * pdefs);
  62. static Bool
  63. winCreateColormapShadowDD(ColormapPtr pColormap);
  64. static Bool
  65. winDestroyColormapShadowDD(ColormapPtr pColormap);
  66. static Bool
  67. winCreatePrimarySurfaceShadowDD(ScreenPtr pScreen);
  68. static Bool
  69. winReleasePrimarySurfaceShadowDD(ScreenPtr pScreen);
  70. /*
  71. * Create the primary surface and attach the clipper.
  72. * Used for both the initial surface creation and during
  73. * WM_DISPLAYCHANGE messages.
  74. */
  75. static Bool
  76. winCreatePrimarySurfaceShadowDD(ScreenPtr pScreen)
  77. {
  78. winScreenPriv(pScreen);
  79. HRESULT ddrval = DD_OK;
  80. DDSURFACEDESC ddsd;
  81. /* Describe the primary surface */
  82. ZeroMemory(&ddsd, sizeof(ddsd));
  83. ddsd.dwSize = sizeof(ddsd);
  84. ddsd.dwFlags = DDSD_CAPS;
  85. ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
  86. /* Create the primary surface */
  87. ddrval = IDirectDraw2_CreateSurface(pScreenPriv->pdd2,
  88. &ddsd, &pScreenPriv->pddsPrimary, NULL);
  89. if (FAILED(ddrval)) {
  90. ErrorF("winCreatePrimarySurfaceShadowDD - Could not create primary "
  91. "surface: %08x\n", (unsigned int) ddrval);
  92. return FALSE;
  93. }
  94. #if CYGDEBUG
  95. winDebug("winCreatePrimarySurfaceShadowDD - Created primary surface\n");
  96. #endif
  97. /*
  98. * Attach a clipper to the primary surface that will clip our blits to our
  99. * display window.
  100. */
  101. ddrval = IDirectDrawSurface2_SetClipper(pScreenPriv->pddsPrimary,
  102. pScreenPriv->pddcPrimary);
  103. if (FAILED(ddrval)) {
  104. ErrorF("winCreatePrimarySurfaceShadowDD - Primary attach clipper "
  105. "failed: %08x\n", (unsigned int) ddrval);
  106. return FALSE;
  107. }
  108. #if CYGDEBUG
  109. winDebug("winCreatePrimarySurfaceShadowDD - Attached clipper to "
  110. "primary surface\n");
  111. #endif
  112. /* Everything was correct */
  113. return TRUE;
  114. }
  115. /*
  116. * Detach the clipper and release the primary surface.
  117. * Called from WM_DISPLAYCHANGE.
  118. */
  119. static Bool
  120. winReleasePrimarySurfaceShadowDD(ScreenPtr pScreen)
  121. {
  122. winScreenPriv(pScreen);
  123. ErrorF("winReleasePrimarySurfaceShadowDD - Hello\n");
  124. /* Release the primary surface and clipper, if they exist */
  125. if (pScreenPriv->pddsPrimary) {
  126. /*
  127. * Detach the clipper from the primary surface.
  128. * NOTE: We do this explicity for clarity. The Clipper is not released.
  129. */
  130. IDirectDrawSurface2_SetClipper(pScreenPriv->pddsPrimary, NULL);
  131. ErrorF("winReleasePrimarySurfaceShadowDD - Detached clipper\n");
  132. /* Release the primary surface */
  133. IDirectDrawSurface2_Release(pScreenPriv->pddsPrimary);
  134. pScreenPriv->pddsPrimary = NULL;
  135. }
  136. ErrorF("winReleasePrimarySurfaceShadowDD - Released primary surface\n");
  137. return TRUE;
  138. }
  139. /*
  140. * Create a DirectDraw surface for the shadow framebuffer; also create
  141. * a primary surface object so we can blit to the display.
  142. *
  143. * Install a DirectDraw clipper on our primary surface object
  144. * that clips our blits to the unobscured client area of our display window.
  145. */
  146. static Bool
  147. winAllocateFBShadowDD(ScreenPtr pScreen)
  148. {
  149. winScreenPriv(pScreen);
  150. winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
  151. HRESULT ddrval = DD_OK;
  152. DDSURFACEDESC ddsd;
  153. DDSURFACEDESC *pddsdShadow = NULL;
  154. #if CYGDEBUG
  155. winDebug("winAllocateFBShadowDD\n");
  156. #endif
  157. /* Create a clipper */
  158. ddrval = (*g_fpDirectDrawCreateClipper) (0,
  159. &pScreenPriv->pddcPrimary, NULL);
  160. if (FAILED(ddrval)) {
  161. ErrorF("winAllocateFBShadowDD - Could not create clipper: %08x\n",
  162. (unsigned int) ddrval);
  163. return FALSE;
  164. }
  165. #if CYGDEBUG
  166. winDebug("winAllocateFBShadowDD - Created a clipper\n");
  167. #endif
  168. /* Attach the clipper to our display window */
  169. ddrval = IDirectDrawClipper_SetHWnd(pScreenPriv->pddcPrimary,
  170. 0, pScreenPriv->hwndScreen);
  171. if (FAILED(ddrval)) {
  172. ErrorF("winAllocateFBShadowDD - Clipper not attached to "
  173. "window: %08x\n", (unsigned int) ddrval);
  174. return FALSE;
  175. }
  176. #if CYGDEBUG
  177. winDebug("winAllocateFBShadowDD - Attached clipper to window\n");
  178. #endif
  179. /* Create a DirectDraw object, store the address at lpdd */
  180. ddrval = (*g_fpDirectDrawCreate) (NULL, &pScreenPriv->pdd, NULL);
  181. if (FAILED(ddrval)) {
  182. ErrorF("winAllocateFBShadowDD - Could not start DirectDraw: %08x\n",
  183. (unsigned int) ddrval);
  184. return FALSE;
  185. }
  186. #if CYGDEBUG
  187. winDebug("winAllocateFBShadowDD () - Created and initialized DD\n");
  188. #endif
  189. /* Get a DirectDraw2 interface pointer */
  190. ddrval = IDirectDraw_QueryInterface(pScreenPriv->pdd,
  191. &IID_IDirectDraw2,
  192. (LPVOID *) &pScreenPriv->pdd2);
  193. if (FAILED(ddrval)) {
  194. ErrorF("winAllocateFBShadowDD - Failed DD2 query: %08x\n",
  195. (unsigned int) ddrval);
  196. return FALSE;
  197. }
  198. /* Are we full screen? */
  199. if (pScreenInfo->fFullScreen) {
  200. DDSURFACEDESC ddsdCurrent;
  201. DWORD dwRefreshRateCurrent = 0;
  202. HDC hdc = NULL;
  203. /* Set the cooperative level to full screen */
  204. ddrval = IDirectDraw2_SetCooperativeLevel(pScreenPriv->pdd2,
  205. pScreenPriv->hwndScreen,
  206. DDSCL_EXCLUSIVE
  207. | DDSCL_FULLSCREEN);
  208. if (FAILED(ddrval)) {
  209. ErrorF("winAllocateFBShadowDD - Could not set "
  210. "cooperative level: %08x\n", (unsigned int) ddrval);
  211. return FALSE;
  212. }
  213. /*
  214. * We only need to get the current refresh rate for comparison
  215. * if a refresh rate has been passed on the command line.
  216. */
  217. if (pScreenInfo->dwRefreshRate != 0) {
  218. ZeroMemory(&ddsdCurrent, sizeof(ddsdCurrent));
  219. ddsdCurrent.dwSize = sizeof(ddsdCurrent);
  220. /* Get information about current display settings */
  221. ddrval = IDirectDraw2_GetDisplayMode(pScreenPriv->pdd2,
  222. &ddsdCurrent);
  223. if (FAILED(ddrval)) {
  224. ErrorF("winAllocateFBShadowDD - Could not get current "
  225. "refresh rate: %08x. Continuing.\n",
  226. (unsigned int) ddrval);
  227. dwRefreshRateCurrent = 0;
  228. }
  229. else {
  230. /* Grab the current refresh rate */
  231. dwRefreshRateCurrent = ddsdCurrent.u2.dwRefreshRate;
  232. }
  233. }
  234. /* Clean up the refresh rate */
  235. if (dwRefreshRateCurrent == pScreenInfo->dwRefreshRate) {
  236. /*
  237. * Refresh rate is non-specified or equal to current.
  238. */
  239. pScreenInfo->dwRefreshRate = 0;
  240. }
  241. /* Grab a device context for the screen */
  242. hdc = GetDC(NULL);
  243. if (hdc == NULL) {
  244. ErrorF("winAllocateFBShadowDD - GetDC () failed\n");
  245. return FALSE;
  246. }
  247. /* Only change the video mode when different than current mode */
  248. if (!pScreenInfo->fMultipleMonitors
  249. && (pScreenInfo->dwWidth != GetSystemMetrics(SM_CXSCREEN)
  250. || pScreenInfo->dwHeight != GetSystemMetrics(SM_CYSCREEN)
  251. || pScreenInfo->dwBPP != GetDeviceCaps(hdc, BITSPIXEL)
  252. || pScreenInfo->dwRefreshRate != 0)) {
  253. ErrorF("winAllocateFBShadowDD - Changing video mode\n");
  254. /* Change the video mode to the mode requested, and use the driver default refresh rate on failure */
  255. ddrval = IDirectDraw2_SetDisplayMode(pScreenPriv->pdd2,
  256. pScreenInfo->dwWidth,
  257. pScreenInfo->dwHeight,
  258. pScreenInfo->dwBPP,
  259. pScreenInfo->dwRefreshRate, 0);
  260. if (FAILED(ddrval)) {
  261. ErrorF("winAllocateFBShadowDD - Could not set "
  262. "full screen display mode: %08x\n",
  263. (unsigned int) ddrval);
  264. ErrorF
  265. ("winAllocateFBShadowDD - Using default driver refresh rate\n");
  266. ddrval =
  267. IDirectDraw2_SetDisplayMode(pScreenPriv->pdd2,
  268. pScreenInfo->dwWidth,
  269. pScreenInfo->dwHeight,
  270. pScreenInfo->dwBPP, 0, 0);
  271. if (FAILED(ddrval)) {
  272. ErrorF
  273. ("winAllocateFBShadowDD - Could not set default refresh rate "
  274. "full screen display mode: %08x\n",
  275. (unsigned int) ddrval);
  276. return FALSE;
  277. }
  278. }
  279. }
  280. else {
  281. ErrorF("winAllocateFBShadowDD - Not changing video mode\n");
  282. }
  283. /* Release our DC */
  284. ReleaseDC(NULL, hdc);
  285. hdc = NULL;
  286. }
  287. else {
  288. /* Set the cooperative level for windowed mode */
  289. ddrval = IDirectDraw2_SetCooperativeLevel(pScreenPriv->pdd2,
  290. pScreenPriv->hwndScreen,
  291. DDSCL_NORMAL);
  292. if (FAILED(ddrval)) {
  293. ErrorF("winAllocateFBShadowDD - Could not set "
  294. "cooperative level: %08x\n", (unsigned int) ddrval);
  295. return FALSE;
  296. }
  297. }
  298. /* Create the primary surface */
  299. if (!winCreatePrimarySurfaceShadowDD(pScreen)) {
  300. ErrorF("winAllocateFBShadowDD - winCreatePrimarySurfaceShadowDD "
  301. "failed\n");
  302. return FALSE;
  303. }
  304. /* Describe the shadow surface to be created */
  305. /* NOTE: Do not use a DDSCAPS_VIDEOMEMORY surface,
  306. * as drawing, locking, and unlocking take forever
  307. * with video memory surfaces. In addition,
  308. * video memory is a somewhat scarce resource,
  309. * so you shouldn't be allocating video memory when
  310. * you have the option of using system memory instead.
  311. */
  312. ZeroMemory(&ddsd, sizeof(ddsd));
  313. ddsd.dwSize = sizeof(ddsd);
  314. ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
  315. ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;
  316. ddsd.dwHeight = pScreenInfo->dwHeight;
  317. ddsd.dwWidth = pScreenInfo->dwWidth;
  318. /* Create the shadow surface */
  319. ddrval = IDirectDraw2_CreateSurface(pScreenPriv->pdd2,
  320. &ddsd, &pScreenPriv->pddsShadow, NULL);
  321. if (FAILED(ddrval)) {
  322. ErrorF("winAllocateFBShadowDD - Could not create shadow "
  323. "surface: %08x\n", (unsigned int) ddrval);
  324. return FALSE;
  325. }
  326. #if CYGDEBUG
  327. winDebug("winAllocateFBShadowDD - Created shadow\n");
  328. #endif
  329. /* Allocate a DD surface description for our screen privates */
  330. pddsdShadow = pScreenPriv->pddsdShadow = malloc(sizeof(DDSURFACEDESC));
  331. if (pddsdShadow == NULL) {
  332. ErrorF("winAllocateFBShadowDD - Could not allocate surface "
  333. "description memory\n");
  334. return FALSE;
  335. }
  336. ZeroMemory(pddsdShadow, sizeof(*pddsdShadow));
  337. pddsdShadow->dwSize = sizeof(*pddsdShadow);
  338. #if CYGDEBUG
  339. winDebug("winAllocateFBShadowDD - Locking shadow\n");
  340. #endif
  341. /* Lock the shadow surface */
  342. ddrval = IDirectDrawSurface2_Lock(pScreenPriv->pddsShadow,
  343. NULL, pddsdShadow, DDLOCK_WAIT, NULL);
  344. if (FAILED(ddrval) || pddsdShadow->lpSurface == NULL) {
  345. ErrorF("winAllocateFBShadowDD - Could not lock shadow "
  346. "surface: %08x\n", (unsigned int) ddrval);
  347. return FALSE;
  348. }
  349. #if CYGDEBUG
  350. winDebug("winAllocateFBShadowDD - Locked shadow\n");
  351. #endif
  352. /* We don't know how to deal with anything other than RGB */
  353. if (!(pddsdShadow->ddpfPixelFormat.dwFlags & DDPF_RGB)) {
  354. ErrorF("winAllocateFBShadowDD - Color format other than RGB\n");
  355. return FALSE;
  356. }
  357. /* Grab the pitch from the surface desc */
  358. pScreenInfo->dwStride = (pddsdShadow->u1.lPitch * 8)
  359. / pScreenInfo->dwBPP;
  360. /* Save the pointer to our surface memory */
  361. pScreenInfo->pfb = pddsdShadow->lpSurface;
  362. /* Grab the color depth and masks from the surface description */
  363. pScreenPriv->dwRedMask = pddsdShadow->ddpfPixelFormat.u2.dwRBitMask;
  364. pScreenPriv->dwGreenMask = pddsdShadow->ddpfPixelFormat.u3.dwGBitMask;
  365. pScreenPriv->dwBlueMask = pddsdShadow->ddpfPixelFormat.u4.dwBBitMask;
  366. #if CYGDEBUG
  367. winDebug("winAllocateFBShadowDD - Returning\n");
  368. #endif
  369. return TRUE;
  370. }
  371. static void
  372. winFreeFBShadowDD(ScreenPtr pScreen)
  373. {
  374. winScreenPriv(pScreen);
  375. winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
  376. /* Free the shadow surface, if there is one */
  377. if (pScreenPriv->pddsShadow) {
  378. IDirectDrawSurface2_Unlock(pScreenPriv->pddsShadow, NULL);
  379. IDirectDrawSurface2_Release(pScreenPriv->pddsShadow);
  380. pScreenPriv->pddsShadow = NULL;
  381. }
  382. /* Detach the clipper from the primary surface and release the primary surface, if there is one */
  383. winReleasePrimarySurfaceShadowDD(pScreen);
  384. /* Release the clipper object */
  385. if (pScreenPriv->pddcPrimary) {
  386. IDirectDrawClipper_Release(pScreenPriv->pddcPrimary);
  387. pScreenPriv->pddcPrimary = NULL;
  388. }
  389. /* Free the DirectDraw2 object, if there is one */
  390. if (pScreenPriv->pdd2) {
  391. IDirectDraw2_RestoreDisplayMode(pScreenPriv->pdd2);
  392. IDirectDraw2_Release(pScreenPriv->pdd2);
  393. pScreenPriv->pdd2 = NULL;
  394. }
  395. /* Free the DirectDraw object, if there is one */
  396. if (pScreenPriv->pdd) {
  397. IDirectDraw_Release(pScreenPriv->pdd);
  398. pScreenPriv->pdd = NULL;
  399. }
  400. /* Invalidate the ScreenInfo's fb pointer */
  401. pScreenInfo->pfb = NULL;
  402. }
  403. /*
  404. * Transfer the damaged regions of the shadow framebuffer to the display.
  405. */
  406. static void
  407. winShadowUpdateDD(ScreenPtr pScreen, shadowBufPtr pBuf)
  408. {
  409. winScreenPriv(pScreen);
  410. winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
  411. RegionPtr damage = shadowDamage(pBuf);
  412. HRESULT ddrval = DD_OK;
  413. RECT rcDest, rcSrc;
  414. POINT ptOrigin;
  415. DWORD dwBox = RegionNumRects(damage);
  416. BoxPtr pBox = RegionRects(damage);
  417. HRGN hrgnCombined = NULL;
  418. /*
  419. * Return immediately if the app is not active
  420. * and we are fullscreen, or if we have a bad display depth
  421. */
  422. if ((!pScreenPriv->fActive && pScreenInfo->fFullScreen)
  423. || pScreenPriv->fBadDepth)
  424. return;
  425. /* Return immediately if we didn't get needed surfaces */
  426. if (!pScreenPriv->pddsPrimary || !pScreenPriv->pddsShadow)
  427. return;
  428. /* Get the origin of the window in the screen coords */
  429. ptOrigin.x = pScreenInfo->dwXOffset;
  430. ptOrigin.y = pScreenInfo->dwYOffset;
  431. MapWindowPoints(pScreenPriv->hwndScreen,
  432. HWND_DESKTOP, (LPPOINT) &ptOrigin, 1);
  433. /* Unlock the shadow surface, so we can blit */
  434. ddrval = IDirectDrawSurface2_Unlock(pScreenPriv->pddsShadow, NULL);
  435. if (FAILED(ddrval)) {
  436. ErrorF("winShadowUpdateDD - Unlock failed\n");
  437. return;
  438. }
  439. /*
  440. * Handle small regions with multiple blits,
  441. * handle large regions by creating a clipping region and
  442. * doing a single blit constrained to that clipping region.
  443. */
  444. if (pScreenInfo->dwClipUpdatesNBoxes == 0
  445. || dwBox < pScreenInfo->dwClipUpdatesNBoxes) {
  446. /* Loop through all boxes in the damaged region */
  447. while (dwBox--) {
  448. /* Assign damage box to source rectangle */
  449. rcSrc.left = pBox->x1;
  450. rcSrc.top = pBox->y1;
  451. rcSrc.right = pBox->x2;
  452. rcSrc.bottom = pBox->y2;
  453. /* Calculate destination rectange */
  454. rcDest.left = ptOrigin.x + rcSrc.left;
  455. rcDest.top = ptOrigin.y + rcSrc.top;
  456. rcDest.right = ptOrigin.x + rcSrc.right;
  457. rcDest.bottom = ptOrigin.y + rcSrc.bottom;
  458. /* Blit the damaged areas */
  459. ddrval = IDirectDrawSurface2_Blt(pScreenPriv->pddsPrimary,
  460. &rcDest,
  461. pScreenPriv->pddsShadow,
  462. &rcSrc, DDBLT_WAIT, NULL);
  463. /* Get a pointer to the next box */
  464. ++pBox;
  465. }
  466. }
  467. else {
  468. BoxPtr pBoxExtents = RegionExtents(damage);
  469. /* Compute a GDI region from the damaged region */
  470. hrgnCombined =
  471. CreateRectRgn(pBoxExtents->x1, pBoxExtents->y1, pBoxExtents->x2,
  472. pBoxExtents->y2);
  473. /* Install the GDI region as a clipping region */
  474. SelectClipRgn(pScreenPriv->hdcScreen, hrgnCombined);
  475. DeleteObject(hrgnCombined);
  476. hrgnCombined = NULL;
  477. /* Calculating a bounding box for the source is easy */
  478. rcSrc.left = pBoxExtents->x1;
  479. rcSrc.top = pBoxExtents->y1;
  480. rcSrc.right = pBoxExtents->x2;
  481. rcSrc.bottom = pBoxExtents->y2;
  482. /* Calculating a bounding box for the destination is trickier */
  483. rcDest.left = ptOrigin.x + rcSrc.left;
  484. rcDest.top = ptOrigin.y + rcSrc.top;
  485. rcDest.right = ptOrigin.x + rcSrc.right;
  486. rcDest.bottom = ptOrigin.y + rcSrc.bottom;
  487. /* Our Blt should be clipped to the invalidated region */
  488. ddrval = IDirectDrawSurface2_Blt(pScreenPriv->pddsPrimary,
  489. &rcDest,
  490. pScreenPriv->pddsShadow,
  491. &rcSrc, DDBLT_WAIT, NULL);
  492. /* Reset the clip region */
  493. SelectClipRgn(pScreenPriv->hdcScreen, NULL);
  494. }
  495. /* Relock the shadow surface */
  496. ddrval = IDirectDrawSurface2_Lock(pScreenPriv->pddsShadow,
  497. NULL,
  498. pScreenPriv->pddsdShadow,
  499. DDLOCK_WAIT, NULL);
  500. if (FAILED(ddrval)) {
  501. ErrorF("winShadowUpdateDD - Lock failed\n");
  502. return;
  503. }
  504. /* Has our memory pointer changed? */
  505. if (pScreenInfo->pfb != pScreenPriv->pddsdShadow->lpSurface) {
  506. ErrorF("winShadowUpdateDD - Memory location of the shadow "
  507. "surface has changed, trying to update the root window "
  508. "pixmap header to point to the new address. If you get "
  509. "this message and " PROJECT_NAME " freezes or crashes "
  510. "after this message then send a problem report and your "
  511. "%s file to " BUILDERADDR "\n", g_pszLogFile);
  512. /* Location of shadow framebuffer has changed */
  513. winUpdateFBPointer(pScreen, pScreenPriv->pddsdShadow->lpSurface);
  514. }
  515. }
  516. static Bool
  517. winInitScreenShadowDD(ScreenPtr pScreen)
  518. {
  519. winScreenPriv(pScreen);
  520. /* Get a device context for the screen */
  521. pScreenPriv->hdcScreen = GetDC(pScreenPriv->hwndScreen);
  522. return winAllocateFBShadowDD(pScreen);
  523. }
  524. /*
  525. * Call the wrapped CloseScreen function.
  526. *
  527. * Free our resources and private structures.
  528. */
  529. static Bool
  530. winCloseScreenShadowDD(ScreenPtr pScreen)
  531. {
  532. winScreenPriv(pScreen);
  533. winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
  534. Bool fReturn;
  535. #if CYGDEBUG
  536. winDebug("winCloseScreenShadowDD - Freeing screen resources\n");
  537. #endif
  538. /* Flag that the screen is closed */
  539. pScreenPriv->fClosed = TRUE;
  540. pScreenPriv->fActive = FALSE;
  541. /* Call the wrapped CloseScreen procedure */
  542. WIN_UNWRAP(CloseScreen);
  543. if (pScreen->CloseScreen)
  544. fReturn = (*pScreen->CloseScreen) (pScreen);
  545. winFreeFBShadowDD(pScreen);
  546. /* Free the screen DC */
  547. ReleaseDC(pScreenPriv->hwndScreen, pScreenPriv->hdcScreen);
  548. /* Delete the window property */
  549. RemoveProp(pScreenPriv->hwndScreen, WIN_SCR_PROP);
  550. /* Delete tray icon, if we have one */
  551. if (!pScreenInfo->fNoTrayIcon)
  552. winDeleteNotifyIcon(pScreenPriv);
  553. /* Free the exit confirmation dialog box, if it exists */
  554. if (g_hDlgExit != NULL) {
  555. DestroyWindow(g_hDlgExit);
  556. g_hDlgExit = NULL;
  557. }
  558. /* Kill our window */
  559. if (pScreenPriv->hwndScreen) {
  560. DestroyWindow(pScreenPriv->hwndScreen);
  561. pScreenPriv->hwndScreen = NULL;
  562. }
  563. #if defined(XWIN_CLIPBOARD) || defined(XWIN_MULTIWINDOW)
  564. /* Destroy the thread startup mutex */
  565. pthread_mutex_destroy(&pScreenPriv->pmServerStarted);
  566. #endif
  567. /* Kill our screeninfo's pointer to the screen */
  568. pScreenInfo->pScreen = NULL;
  569. /* Free the screen privates for this screen */
  570. free((void *) pScreenPriv);
  571. return fReturn;
  572. }
  573. /*
  574. * Tell mi what sort of visuals we need.
  575. *
  576. * Generally we only need one visual, as our screen can only
  577. * handle one format at a time, I believe. You may want
  578. * to verify that last sentence.
  579. */
  580. static Bool
  581. winInitVisualsShadowDD(ScreenPtr pScreen)
  582. {
  583. winScreenPriv(pScreen);
  584. winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
  585. DWORD dwRedBits, dwGreenBits, dwBlueBits;
  586. /* Count the number of ones in each color mask */
  587. dwRedBits = winCountBits(pScreenPriv->dwRedMask);
  588. dwGreenBits = winCountBits(pScreenPriv->dwGreenMask);
  589. dwBlueBits = winCountBits(pScreenPriv->dwBlueMask);
  590. /* Store the maximum number of ones in a color mask as the bitsPerRGB */
  591. if (dwRedBits == 0 || dwGreenBits == 0 || dwBlueBits == 0)
  592. pScreenPriv->dwBitsPerRGB = 8;
  593. else if (dwRedBits > dwGreenBits && dwRedBits > dwBlueBits)
  594. pScreenPriv->dwBitsPerRGB = dwRedBits;
  595. else if (dwGreenBits > dwRedBits && dwGreenBits > dwBlueBits)
  596. pScreenPriv->dwBitsPerRGB = dwGreenBits;
  597. else
  598. pScreenPriv->dwBitsPerRGB = dwBlueBits;
  599. ErrorF("winInitVisualsShadowDD - Masks %08x %08x %08x BPRGB %d d %d "
  600. "bpp %d\n",
  601. (unsigned int) pScreenPriv->dwRedMask,
  602. (unsigned int) pScreenPriv->dwGreenMask,
  603. (unsigned int) pScreenPriv->dwBlueMask,
  604. (int) pScreenPriv->dwBitsPerRGB,
  605. (int) pScreenInfo->dwDepth, (int) pScreenInfo->dwBPP);
  606. /* Create a single visual according to the Windows screen depth */
  607. switch (pScreenInfo->dwDepth) {
  608. case 24:
  609. case 16:
  610. case 15:
  611. /* Create the real visual */
  612. if (!miSetVisualTypesAndMasks(pScreenInfo->dwDepth,
  613. TrueColorMask,
  614. pScreenPriv->dwBitsPerRGB,
  615. TrueColor,
  616. pScreenPriv->dwRedMask,
  617. pScreenPriv->dwGreenMask,
  618. pScreenPriv->dwBlueMask)) {
  619. ErrorF("winInitVisualsShadowDD - miSetVisualTypesAndMasks "
  620. "failed for TrueColor\n");
  621. return FALSE;
  622. }
  623. #ifdef XWIN_EMULATEPSEUDO
  624. if (!pScreenInfo->fEmulatePseudo)
  625. break;
  626. /* Setup a pseudocolor visual */
  627. if (!miSetVisualTypesAndMasks(8, PseudoColorMask, 8, -1, 0, 0, 0)) {
  628. ErrorF("winInitVisualsShadowDD - miSetVisualTypesAndMasks "
  629. "failed for PseudoColor\n");
  630. return FALSE;
  631. }
  632. #endif
  633. break;
  634. case 8:
  635. if (!miSetVisualTypesAndMasks(pScreenInfo->dwDepth,
  636. pScreenInfo->fFullScreen
  637. ? PseudoColorMask : StaticColorMask,
  638. pScreenPriv->dwBitsPerRGB,
  639. pScreenInfo->fFullScreen
  640. ? PseudoColor : StaticColor,
  641. pScreenPriv->dwRedMask,
  642. pScreenPriv->dwGreenMask,
  643. pScreenPriv->dwBlueMask)) {
  644. ErrorF("winInitVisualsShadowDD - miSetVisualTypesAndMasks "
  645. "failed\n");
  646. return FALSE;
  647. }
  648. break;
  649. default:
  650. ErrorF("winInitVisualsShadowDD - Unknown screen depth\n");
  651. return FALSE;
  652. }
  653. #if CYGDEBUG
  654. winDebug("winInitVisualsShadowDD - Returning\n");
  655. #endif
  656. return TRUE;
  657. }
  658. /*
  659. * Adjust the user proposed video mode
  660. */
  661. static Bool
  662. winAdjustVideoModeShadowDD(ScreenPtr pScreen)
  663. {
  664. winScreenPriv(pScreen);
  665. winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
  666. HDC hdc = NULL;
  667. DWORD dwBPP;
  668. /* We're in serious trouble if we can't get a DC */
  669. hdc = GetDC(NULL);
  670. if (hdc == NULL) {
  671. ErrorF("winAdjustVideoModeShadowDD - GetDC () failed\n");
  672. return FALSE;
  673. }
  674. /* Query GDI for current display depth */
  675. dwBPP = GetDeviceCaps(hdc, BITSPIXEL);
  676. /* DirectDraw can only change the depth in fullscreen mode */
  677. if (!(pScreenInfo->fFullScreen && (pScreenInfo->dwBPP != WIN_DEFAULT_BPP))) {
  678. /* Otherwise, We'll use GDI's depth */
  679. pScreenInfo->dwBPP = dwBPP;
  680. }
  681. /* Release our DC */
  682. ReleaseDC(NULL, hdc);
  683. return TRUE;
  684. }
  685. /*
  686. * Blt exposed regions to the screen
  687. */
  688. static Bool
  689. winBltExposedRegionsShadowDD(ScreenPtr pScreen)
  690. {
  691. winScreenPriv(pScreen);
  692. winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
  693. RECT rcSrc, rcDest;
  694. POINT ptOrigin;
  695. HDC hdcUpdate = NULL;
  696. PAINTSTRUCT ps;
  697. HRESULT ddrval = DD_OK;
  698. Bool fReturn = TRUE;
  699. Bool fLocked = TRUE;
  700. int i;
  701. /* BeginPaint gives us an hdc that clips to the invalidated region */
  702. hdcUpdate = BeginPaint(pScreenPriv->hwndScreen, &ps);
  703. if (hdcUpdate == NULL) {
  704. ErrorF("winBltExposedRegionsShadowDD - BeginPaint () returned "
  705. "a NULL device context handle. Aborting blit attempt.\n");
  706. return FALSE;
  707. }
  708. /* Unlock the shadow surface, so we can blit */
  709. ddrval = IDirectDrawSurface2_Unlock(pScreenPriv->pddsShadow, NULL);
  710. if (FAILED(ddrval)) {
  711. fReturn = FALSE;
  712. goto winBltExposedRegionsShadowDD_Exit;
  713. }
  714. else {
  715. /* Flag that we have unlocked the shadow surface */
  716. fLocked = FALSE;
  717. }
  718. /* Get the origin of the window in the screen coords */
  719. ptOrigin.x = pScreenInfo->dwXOffset;
  720. ptOrigin.y = pScreenInfo->dwYOffset;
  721. MapWindowPoints(pScreenPriv->hwndScreen,
  722. HWND_DESKTOP, (LPPOINT) &ptOrigin, 1);
  723. rcDest.left = ptOrigin.x;
  724. rcDest.right = ptOrigin.x + pScreenInfo->dwWidth;
  725. rcDest.top = ptOrigin.y;
  726. rcDest.bottom = ptOrigin.y + pScreenInfo->dwHeight;
  727. /* Source can be enter shadow surface, as Blt should clip */
  728. rcSrc.left = 0;
  729. rcSrc.top = 0;
  730. rcSrc.right = pScreenInfo->dwWidth;
  731. rcSrc.bottom = pScreenInfo->dwHeight;
  732. /* Try to regain the primary surface and blit again if we've lost it */
  733. for (i = 0; i <= WIN_REGAIN_SURFACE_RETRIES; ++i) {
  734. /* Our Blt should be clipped to the invalidated region */
  735. ddrval = IDirectDrawSurface2_Blt(pScreenPriv->pddsPrimary,
  736. &rcDest,
  737. pScreenPriv->pddsShadow,
  738. &rcSrc, DDBLT_WAIT, NULL);
  739. if (ddrval == DDERR_SURFACELOST) {
  740. /* Surface was lost */
  741. ErrorF("winBltExposedRegionsShadowDD - IDirectDrawSurface2_Blt "
  742. "reported that the primary surface was lost, "
  743. "trying to restore, retry: %d\n", i + 1);
  744. /* Try to restore the surface, once */
  745. ddrval = IDirectDrawSurface2_Restore(pScreenPriv->pddsPrimary);
  746. ErrorF("winBltExposedRegionsShadowDD - "
  747. "IDirectDrawSurface2_Restore returned: ");
  748. if (ddrval == DD_OK)
  749. ErrorF("DD_OK\n");
  750. else if (ddrval == DDERR_WRONGMODE)
  751. ErrorF("DDERR_WRONGMODE\n");
  752. else if (ddrval == DDERR_INCOMPATIBLEPRIMARY)
  753. ErrorF("DDERR_INCOMPATIBLEPRIMARY\n");
  754. else if (ddrval == DDERR_UNSUPPORTED)
  755. ErrorF("DDERR_UNSUPPORTED\n");
  756. else if (ddrval == DDERR_INVALIDPARAMS)
  757. ErrorF("DDERR_INVALIDPARAMS\n");
  758. else if (ddrval == DDERR_INVALIDOBJECT)
  759. ErrorF("DDERR_INVALIDOBJECT\n");
  760. else
  761. ErrorF("unknown error: %08x\n", (unsigned int) ddrval);
  762. /* Loop around to try the blit one more time */
  763. continue;
  764. }
  765. else if (FAILED(ddrval)) {
  766. fReturn = FALSE;
  767. ErrorF("winBltExposedRegionsShadowDD - IDirectDrawSurface2_Blt "
  768. "failed, but surface not lost: %08x %d\n",
  769. (unsigned int) ddrval, (int) ddrval);
  770. goto winBltExposedRegionsShadowDD_Exit;
  771. }
  772. else {
  773. /* Success, stop looping */
  774. break;
  775. }
  776. }
  777. /* Relock the shadow surface */
  778. ddrval = IDirectDrawSurface2_Lock(pScreenPriv->pddsShadow,
  779. NULL,
  780. pScreenPriv->pddsdShadow,
  781. DDLOCK_WAIT, NULL);
  782. if (FAILED(ddrval)) {
  783. fReturn = FALSE;
  784. ErrorF("winBltExposedRegionsShadowDD - IDirectDrawSurface2_Lock "
  785. "failed\n");
  786. goto winBltExposedRegionsShadowDD_Exit;
  787. }
  788. else {
  789. /* Indicate that we have relocked the shadow surface */
  790. fLocked = TRUE;
  791. }
  792. /* Has our memory pointer changed? */
  793. if (pScreenInfo->pfb != pScreenPriv->pddsdShadow->lpSurface)
  794. winUpdateFBPointer(pScreen, pScreenPriv->pddsdShadow->lpSurface);
  795. winBltExposedRegionsShadowDD_Exit:
  796. /* EndPaint frees the DC */
  797. if (hdcUpdate != NULL)
  798. EndPaint(pScreenPriv->hwndScreen, &ps);
  799. /*
  800. * Relock the surface if it is not locked. We don't care if locking fails,
  801. * as it will cause the server to shutdown within a few more operations.
  802. */
  803. if (!fLocked) {
  804. IDirectDrawSurface2_Lock(pScreenPriv->pddsShadow,
  805. NULL,
  806. pScreenPriv->pddsdShadow, DDLOCK_WAIT, NULL);
  807. /* Has our memory pointer changed? */
  808. if (pScreenInfo->pfb != pScreenPriv->pddsdShadow->lpSurface)
  809. winUpdateFBPointer(pScreen, pScreenPriv->pddsdShadow->lpSurface);
  810. fLocked = TRUE;
  811. }
  812. return fReturn;
  813. }
  814. /*
  815. * Do any engine-specific appliation-activation processing
  816. */
  817. static Bool
  818. winActivateAppShadowDD(ScreenPtr pScreen)
  819. {
  820. winScreenPriv(pScreen);
  821. /*
  822. * Do we have a surface?
  823. * Are we active?
  824. * Are we fullscreen?
  825. */
  826. if (pScreenPriv != NULL
  827. && pScreenPriv->pddsPrimary != NULL && pScreenPriv->fActive) {
  828. /* Primary surface was lost, restore it */
  829. IDirectDrawSurface2_Restore(pScreenPriv->pddsPrimary);
  830. }
  831. return TRUE;
  832. }
  833. /*
  834. * Reblit the shadow framebuffer to the screen.
  835. */
  836. static Bool
  837. winRedrawScreenShadowDD(ScreenPtr pScreen)
  838. {
  839. winScreenPriv(pScreen);
  840. winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
  841. HRESULT ddrval = DD_OK;
  842. RECT rcSrc, rcDest;
  843. POINT ptOrigin;
  844. /* Get the origin of the window in the screen coords */
  845. ptOrigin.x = pScreenInfo->dwXOffset;
  846. ptOrigin.y = pScreenInfo->dwYOffset;
  847. MapWindowPoints(pScreenPriv->hwndScreen,
  848. HWND_DESKTOP, (LPPOINT) &ptOrigin, 1);
  849. rcDest.left = ptOrigin.x;
  850. rcDest.right = ptOrigin.x + pScreenInfo->dwWidth;
  851. rcDest.top = ptOrigin.y;
  852. rcDest.bottom = ptOrigin.y + pScreenInfo->dwHeight;
  853. /* Source can be entire shadow surface, as Blt should clip for us */
  854. rcSrc.left = 0;
  855. rcSrc.top = 0;
  856. rcSrc.right = pScreenInfo->dwWidth;
  857. rcSrc.bottom = pScreenInfo->dwHeight;
  858. /* Redraw the whole window, to take account for the new colors */
  859. ddrval = IDirectDrawSurface2_Blt(pScreenPriv->pddsPrimary,
  860. &rcDest,
  861. pScreenPriv->pddsShadow,
  862. &rcSrc, DDBLT_WAIT, NULL);
  863. if (FAILED(ddrval)) {
  864. ErrorF("winRedrawScreenShadowDD - IDirectDrawSurface_Blt () "
  865. "failed: %08x\n", (unsigned int) ddrval);
  866. }
  867. return TRUE;
  868. }
  869. /*
  870. * Realize the currently installed colormap
  871. */
  872. static Bool
  873. winRealizeInstalledPaletteShadowDD(ScreenPtr pScreen)
  874. {
  875. return TRUE;
  876. }
  877. /*
  878. * Install the specified colormap
  879. */
  880. static Bool
  881. winInstallColormapShadowDD(ColormapPtr pColormap)
  882. {
  883. ScreenPtr pScreen = pColormap->pScreen;
  884. winScreenPriv(pScreen);
  885. winCmapPriv(pColormap);
  886. HRESULT ddrval = DD_OK;
  887. /* Install the DirectDraw palette on the primary surface */
  888. ddrval = IDirectDrawSurface2_SetPalette(pScreenPriv->pddsPrimary,
  889. pCmapPriv->lpDDPalette);
  890. if (FAILED(ddrval)) {
  891. ErrorF("winInstallColormapShadowDD - Failed installing the "
  892. "DirectDraw palette.\n");
  893. return FALSE;
  894. }
  895. /* Save a pointer to the newly installed colormap */
  896. pScreenPriv->pcmapInstalled = pColormap;
  897. return TRUE;
  898. }
  899. /*
  900. * Store the specified colors in the specified colormap
  901. */
  902. static Bool
  903. winStoreColorsShadowDD(ColormapPtr pColormap, int ndef, xColorItem * pdefs)
  904. {
  905. ScreenPtr pScreen = pColormap->pScreen;
  906. winScreenPriv(pScreen);
  907. winCmapPriv(pColormap);
  908. ColormapPtr curpmap = pScreenPriv->pcmapInstalled;
  909. HRESULT ddrval = DD_OK;
  910. /* Put the X colormap entries into the Windows logical palette */
  911. ddrval = IDirectDrawPalette_SetEntries(pCmapPriv->lpDDPalette,
  912. 0,
  913. pdefs[0].pixel,
  914. ndef,
  915. pCmapPriv->peColors
  916. + pdefs[0].pixel);
  917. if (FAILED(ddrval)) {
  918. ErrorF("winStoreColorsShadowDD - SetEntries () failed\n");
  919. return FALSE;
  920. }
  921. /* Don't install the DirectDraw palette if the colormap is not installed */
  922. if (pColormap != curpmap) {
  923. return TRUE;
  924. }
  925. if (!winInstallColormapShadowDD(pColormap)) {
  926. ErrorF("winStoreColorsShadowDD - Failed installing colormap\n");
  927. return FALSE;
  928. }
  929. return TRUE;
  930. }
  931. /*
  932. * Colormap initialization procedure
  933. */
  934. static Bool
  935. winCreateColormapShadowDD(ColormapPtr pColormap)
  936. {
  937. HRESULT ddrval = DD_OK;
  938. ScreenPtr pScreen = pColormap->pScreen;
  939. winScreenPriv(pScreen);
  940. winCmapPriv(pColormap);
  941. /* Create a DirectDraw palette */
  942. ddrval = IDirectDraw2_CreatePalette(pScreenPriv->pdd,
  943. DDPCAPS_8BIT | DDPCAPS_ALLOW256,
  944. pCmapPriv->peColors,
  945. &pCmapPriv->lpDDPalette, NULL);
  946. if (FAILED(ddrval)) {
  947. ErrorF("winCreateColormapShadowDD - CreatePalette failed\n");
  948. return FALSE;
  949. }
  950. return TRUE;
  951. }
  952. /*
  953. * Colormap destruction procedure
  954. */
  955. static Bool
  956. winDestroyColormapShadowDD(ColormapPtr pColormap)
  957. {
  958. winScreenPriv(pColormap->pScreen);
  959. winCmapPriv(pColormap);
  960. HRESULT ddrval = DD_OK;
  961. /*
  962. * Is colormap to be destroyed the default?
  963. *
  964. * Non-default colormaps should have had winUninstallColormap
  965. * called on them before we get here. The default colormap
  966. * will not have had winUninstallColormap called on it. Thus,
  967. * we need to handle the default colormap in a special way.
  968. */
  969. if (pColormap->flags & IsDefault) {
  970. #if CYGDEBUG
  971. winDebug("winDestroyColormapShadowDD - Destroying default "
  972. "colormap\n");
  973. #endif
  974. /*
  975. * FIXME: Walk the list of all screens, popping the default
  976. * palette out of each screen device context.
  977. */
  978. /* Pop the palette out of the primary surface */
  979. ddrval = IDirectDrawSurface2_SetPalette(pScreenPriv->pddsPrimary, NULL);
  980. if (FAILED(ddrval)) {
  981. ErrorF("winDestroyColormapShadowDD - Failed freeing the "
  982. "default colormap DirectDraw palette.\n");
  983. return FALSE;
  984. }
  985. /* Clear our private installed colormap pointer */
  986. pScreenPriv->pcmapInstalled = NULL;
  987. }
  988. /* Release the palette */
  989. IDirectDrawPalette_Release(pCmapPriv->lpDDPalette);
  990. /* Invalidate the colormap privates */
  991. pCmapPriv->lpDDPalette = NULL;
  992. return TRUE;
  993. }
  994. /*
  995. * Set engine specific functions
  996. */
  997. Bool
  998. winSetEngineFunctionsShadowDD(ScreenPtr pScreen)
  999. {
  1000. winScreenPriv(pScreen);
  1001. winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
  1002. /* Set our pointers */
  1003. pScreenPriv->pwinAllocateFB = winAllocateFBShadowDD;
  1004. pScreenPriv->pwinFreeFB = winFreeFBShadowDD;
  1005. pScreenPriv->pwinShadowUpdate = winShadowUpdateDD;
  1006. pScreenPriv->pwinInitScreen = winInitScreenShadowDD;
  1007. pScreenPriv->pwinCloseScreen = winCloseScreenShadowDD;
  1008. pScreenPriv->pwinInitVisuals = winInitVisualsShadowDD;
  1009. pScreenPriv->pwinAdjustVideoMode = winAdjustVideoModeShadowDD;
  1010. if (pScreenInfo->fFullScreen)
  1011. pScreenPriv->pwinCreateBoundingWindow =
  1012. winCreateBoundingWindowFullScreen;
  1013. else
  1014. pScreenPriv->pwinCreateBoundingWindow = winCreateBoundingWindowWindowed;
  1015. pScreenPriv->pwinFinishScreenInit = winFinishScreenInitFB;
  1016. pScreenPriv->pwinBltExposedRegions = winBltExposedRegionsShadowDD;
  1017. pScreenPriv->pwinActivateApp = winActivateAppShadowDD;
  1018. pScreenPriv->pwinRedrawScreen = winRedrawScreenShadowDD;
  1019. pScreenPriv->pwinRealizeInstalledPalette
  1020. = winRealizeInstalledPaletteShadowDD;
  1021. pScreenPriv->pwinInstallColormap = winInstallColormapShadowDD;
  1022. pScreenPriv->pwinStoreColors = winStoreColorsShadowDD;
  1023. pScreenPriv->pwinCreateColormap = winCreateColormapShadowDD;
  1024. pScreenPriv->pwinDestroyColormap = winDestroyColormapShadowDD;
  1025. pScreenPriv->pwinHotKeyAltTab =
  1026. (winHotKeyAltTabProcPtr) (void (*)(void)) NoopDDA;
  1027. pScreenPriv->pwinCreatePrimarySurface = winCreatePrimarySurfaceShadowDD;
  1028. pScreenPriv->pwinReleasePrimarySurface = winReleasePrimarySurfaceShadowDD;
  1029. #ifdef XWIN_MULTIWINDOW
  1030. pScreenPriv->pwinFinishCreateWindowsWindow =
  1031. (winFinishCreateWindowsWindowProcPtr) (void (*)(void)) NoopDDA;
  1032. #endif
  1033. return TRUE;
  1034. }