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 
34 #ifdef HAVE_XWIN_CONFIG_H
35 #include <xwin-config.h>
36 #endif
37 #include "win.h"
38 
39 #define FAIL_MSG_MAX_BLT	10
40 
41 /*
42  * Local prototypes
43  */
44 
45 static Bool
46  winAllocateFBShadowDDNL(ScreenPtr pScreen);
47 
48 static void
49  winShadowUpdateDDNL(ScreenPtr pScreen, shadowBufPtr pBuf);
50 
51 static Bool
52  winCloseScreenShadowDDNL(ScreenPtr pScreen);
53 
54 static Bool
55  winInitVisualsShadowDDNL(ScreenPtr pScreen);
56 
57 static Bool
58  winAdjustVideoModeShadowDDNL(ScreenPtr pScreen);
59 
60 static Bool
61  winBltExposedRegionsShadowDDNL(ScreenPtr pScreen);
62 
63 static Bool
64  winActivateAppShadowDDNL(ScreenPtr pScreen);
65 
66 static Bool
67  winRedrawScreenShadowDDNL(ScreenPtr pScreen);
68 
69 static Bool
70  winRealizeInstalledPaletteShadowDDNL(ScreenPtr pScreen);
71 
72 static Bool
73  winInstallColormapShadowDDNL(ColormapPtr pColormap);
74 
75 static Bool
76  winStoreColorsShadowDDNL(ColormapPtr pmap, int ndef, xColorItem * pdefs);
77 
78 static Bool
79  winCreateColormapShadowDDNL(ColormapPtr pColormap);
80 
81 static Bool
82  winDestroyColormapShadowDDNL(ColormapPtr pColormap);
83 
84 static Bool
85  winCreatePrimarySurfaceShadowDDNL(ScreenPtr pScreen);
86 
87 static Bool
88  winReleasePrimarySurfaceShadowDDNL(ScreenPtr pScreen);
89 
90 /*
91  * Create the primary surface and attach the clipper.
92  * Used for both the initial surface creation and during
93  * WM_DISPLAYCHANGE messages.
94  */
95 
96 static Bool
winCreatePrimarySurfaceShadowDDNL(ScreenPtr pScreen)97 winCreatePrimarySurfaceShadowDDNL(ScreenPtr pScreen)
98 {
99     winScreenPriv(pScreen);
100     HRESULT ddrval = DD_OK;
101     DDSURFACEDESC2 ddsd;
102 
103     winDebug("winCreatePrimarySurfaceShadowDDNL - Creating primary surface\n");
104 
105     /* Describe the primary surface */
106     ZeroMemory(&ddsd, sizeof(ddsd));
107     ddsd.dwSize = sizeof(ddsd);
108     ddsd.dwFlags = DDSD_CAPS;
109     ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
110 
111     /* Create the primary surface */
112     ddrval = IDirectDraw4_CreateSurface(pScreenPriv->pdd4,
113                                         &ddsd,
114                                         &pScreenPriv->pddsPrimary4, NULL);
115     pScreenPriv->fRetryCreateSurface = FALSE;
116     if (FAILED(ddrval)) {
117         if (ddrval == DDERR_NOEXCLUSIVEMODE) {
118             /* Recreating the surface failed. Mark screen to retry later */
119             pScreenPriv->fRetryCreateSurface = TRUE;
120             winDebug("winCreatePrimarySurfaceShadowDDNL - Could not create "
121                      "primary surface: DDERR_NOEXCLUSIVEMODE\n");
122         }
123         else {
124             ErrorF("winCreatePrimarySurfaceShadowDDNL - Could not create "
125                    "primary surface: %08x\n", (unsigned int) ddrval);
126         }
127         return FALSE;
128     }
129 
130 #if 1
131     winDebug("winCreatePrimarySurfaceShadowDDNL - Created primary surface\n");
132 #endif
133 
134     /* Attach our clipper to our primary surface handle */
135     ddrval = IDirectDrawSurface4_SetClipper(pScreenPriv->pddsPrimary4,
136                                             pScreenPriv->pddcPrimary);
137     if (FAILED(ddrval)) {
138         ErrorF("winCreatePrimarySurfaceShadowDDNL - Primary attach clipper "
139                "failed: %08x\n", (unsigned int) ddrval);
140         return FALSE;
141     }
142 
143 #if 1
144     winDebug("winCreatePrimarySurfaceShadowDDNL - Attached clipper to primary "
145              "surface\n");
146 #endif
147 
148     /* Everything was correct */
149     return TRUE;
150 }
151 
152 /*
153  * Detach the clipper and release the primary surface.
154  * Called from WM_DISPLAYCHANGE.
155  */
156 
157 static Bool
winReleasePrimarySurfaceShadowDDNL(ScreenPtr pScreen)158 winReleasePrimarySurfaceShadowDDNL(ScreenPtr pScreen)
159 {
160     winScreenPriv(pScreen);
161 
162     winDebug("winReleasePrimarySurfaceShadowDDNL - Hello\n");
163 
164     /* Release the primary surface and clipper, if they exist */
165     if (pScreenPriv->pddsPrimary4) {
166         /*
167          * Detach the clipper from the primary surface.
168          * NOTE: We do this explicity for clarity.  The Clipper is not released.
169          */
170         IDirectDrawSurface4_SetClipper(pScreenPriv->pddsPrimary4, NULL);
171 
172         winDebug("winReleasePrimarySurfaceShadowDDNL - Detached clipper\n");
173 
174         /* Release the primary surface */
175         IDirectDrawSurface4_Release(pScreenPriv->pddsPrimary4);
176         pScreenPriv->pddsPrimary4 = NULL;
177     }
178 
179     winDebug("winReleasePrimarySurfaceShadowDDNL - Released primary surface\n");
180 
181     return TRUE;
182 }
183 
184 /*
185  * Create a DirectDraw surface for the shadow framebuffer; also create
186  * a primary surface object so we can blit to the display.
187  *
188  * Install a DirectDraw clipper on our primary surface object
189  * that clips our blits to the unobscured client area of our display window.
190  */
191 
192 Bool
winAllocateFBShadowDDNL(ScreenPtr pScreen)193 winAllocateFBShadowDDNL(ScreenPtr pScreen)
194 {
195     winScreenPriv(pScreen);
196     winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
197     HRESULT ddrval = DD_OK;
198     DDSURFACEDESC2 ddsdShadow;
199     char *lpSurface = NULL;
200     DDPIXELFORMAT ddpfPrimary;
201 
202 #if CYGDEBUG
203     winDebug("winAllocateFBShadowDDNL - w %u h %u d %u\n",
204              (unsigned int)pScreenInfo->dwWidth,
205              (unsigned int)pScreenInfo->dwHeight,
206              (unsigned int)pScreenInfo->dwDepth);
207 #endif
208 
209     /* Set the padded screen width */
210     pScreenInfo->dwPaddedWidth = PixmapBytePad(pScreenInfo->dwWidth,
211                                                pScreenInfo->dwBPP);
212 
213     /* Allocate memory for our shadow surface */
214     lpSurface = malloc(pScreenInfo->dwPaddedWidth * pScreenInfo->dwHeight);
215     if (lpSurface == NULL) {
216         ErrorF("winAllocateFBShadowDDNL - Could not allocate bits\n");
217         return FALSE;
218     }
219 
220     /*
221      * Initialize the framebuffer memory so we don't get a
222      * strange display at startup
223      */
224     ZeroMemory(lpSurface, pScreenInfo->dwPaddedWidth * pScreenInfo->dwHeight);
225 
226     /* Create a clipper */
227     ddrval = (*g_fpDirectDrawCreateClipper) (0,
228                                              &pScreenPriv->pddcPrimary, NULL);
229     if (FAILED(ddrval)) {
230         ErrorF("winAllocateFBShadowDDNL - Could not attach clipper: %08x\n",
231                (unsigned int) ddrval);
232         return FALSE;
233     }
234 
235 #if CYGDEBUG
236     winDebug("winAllocateFBShadowDDNL - Created a clipper\n");
237 #endif
238 
239     /* Attach the clipper to our display window */
240     ddrval = IDirectDrawClipper_SetHWnd(pScreenPriv->pddcPrimary,
241                                         0, pScreenPriv->hwndScreen);
242     if (FAILED(ddrval)) {
243         ErrorF("winAllocateFBShadowDDNL - Clipper not attached "
244                "to window: %08x\n", (unsigned int) ddrval);
245         return FALSE;
246     }
247 
248 #if CYGDEBUG
249     winDebug("winAllocateFBShadowDDNL - Attached clipper to window\n");
250 #endif
251 
252     /* Create a DirectDraw object, store the address at lpdd */
253     ddrval = (*g_fpDirectDrawCreate) (NULL,
254                                       (LPDIRECTDRAW *) &pScreenPriv->pdd,
255                                       NULL);
256     if (FAILED(ddrval)) {
257         ErrorF("winAllocateFBShadowDDNL - Could not start "
258                "DirectDraw: %08x\n", (unsigned int) ddrval);
259         return FALSE;
260     }
261 
262 #if CYGDEBUG
263     winDebug("winAllocateFBShadowDDNL - Created and initialized DD\n");
264 #endif
265 
266     /* Get a DirectDraw4 interface pointer */
267     ddrval = IDirectDraw_QueryInterface(pScreenPriv->pdd,
268                                         &IID_IDirectDraw4,
269                                         (LPVOID *) &pScreenPriv->pdd4);
270     if (FAILED(ddrval)) {
271         ErrorF("winAllocateFBShadowDDNL - Failed DD4 query: %08x\n",
272                (unsigned int) ddrval);
273         return FALSE;
274     }
275 
276     /* Are we full screen? */
277     if (pScreenInfo->fFullScreen) {
278         DDSURFACEDESC2 ddsdCurrent;
279         DWORD dwRefreshRateCurrent = 0;
280         HDC hdc = NULL;
281 
282         /* Set the cooperative level to full screen */
283         ddrval = IDirectDraw4_SetCooperativeLevel(pScreenPriv->pdd4,
284                                                   pScreenPriv->hwndScreen,
285                                                   DDSCL_EXCLUSIVE
286                                                   | DDSCL_FULLSCREEN);
287         if (FAILED(ddrval)) {
288             ErrorF("winAllocateFBShadowDDNL - Could not set "
289                    "cooperative level: %08x\n", (unsigned int) ddrval);
290             return FALSE;
291         }
292 
293         /*
294          * We only need to get the current refresh rate for comparison
295          * if a refresh rate has been passed on the command line.
296          */
297         if (pScreenInfo->dwRefreshRate != 0) {
298             ZeroMemory(&ddsdCurrent, sizeof(ddsdCurrent));
299             ddsdCurrent.dwSize = sizeof(ddsdCurrent);
300 
301             /* Get information about current display settings */
302             ddrval = IDirectDraw4_GetDisplayMode(pScreenPriv->pdd4,
303                                                  &ddsdCurrent);
304             if (FAILED(ddrval)) {
305                 ErrorF("winAllocateFBShadowDDNL - Could not get current "
306                        "refresh rate: %08x.  Continuing.\n",
307                        (unsigned int) ddrval);
308                 dwRefreshRateCurrent = 0;
309             }
310             else {
311                 /* Grab the current refresh rate */
312                 dwRefreshRateCurrent = ddsdCurrent.u2.dwRefreshRate;
313             }
314         }
315 
316         /* Clean up the refresh rate */
317         if (dwRefreshRateCurrent == pScreenInfo->dwRefreshRate) {
318             /*
319              * Refresh rate is non-specified or equal to current.
320              */
321             pScreenInfo->dwRefreshRate = 0;
322         }
323 
324         /* Grab a device context for the screen */
325         hdc = GetDC(NULL);
326         if (hdc == NULL) {
327             ErrorF("winAllocateFBShadowDDNL - GetDC () failed\n");
328             return FALSE;
329         }
330 
331         /* Only change the video mode when different than current mode */
332         if (!pScreenInfo->fMultipleMonitors
333             && (pScreenInfo->dwWidth != GetSystemMetrics(SM_CXSCREEN)
334                 || pScreenInfo->dwHeight != GetSystemMetrics(SM_CYSCREEN)
335                 || pScreenInfo->dwBPP != GetDeviceCaps(hdc, BITSPIXEL)
336                 || pScreenInfo->dwRefreshRate != 0)) {
337             winDebug("winAllocateFBShadowDDNL - Changing video mode\n");
338 
339             /* Change the video mode to the mode requested, and use the driver default refresh rate on failure */
340             ddrval = IDirectDraw4_SetDisplayMode(pScreenPriv->pdd4,
341                                                  pScreenInfo->dwWidth,
342                                                  pScreenInfo->dwHeight,
343                                                  pScreenInfo->dwBPP,
344                                                  pScreenInfo->dwRefreshRate, 0);
345             if (FAILED(ddrval)) {
346                 ErrorF("winAllocateFBShadowDDNL - Could not set "
347                        "full screen display mode: %08x\n",
348                        (unsigned int) ddrval);
349                 ErrorF
350                     ("winAllocateFBShadowDDNL - Using default driver refresh rate\n");
351                 ddrval =
352                     IDirectDraw4_SetDisplayMode(pScreenPriv->pdd4,
353                                                 pScreenInfo->dwWidth,
354                                                 pScreenInfo->dwHeight,
355                                                 pScreenInfo->dwBPP, 0, 0);
356                 if (FAILED(ddrval)) {
357                     ErrorF
358                         ("winAllocateFBShadowDDNL - Could not set default refresh rate "
359                          "full screen display mode: %08x\n",
360                          (unsigned int) ddrval);
361                     return FALSE;
362                 }
363             }
364         }
365         else {
366             winDebug("winAllocateFBShadowDDNL - Not changing video mode\n");
367         }
368 
369         /* Release our DC */
370         ReleaseDC(NULL, hdc);
371         hdc = NULL;
372     }
373     else {
374         /* Set the cooperative level for windowed mode */
375         ddrval = IDirectDraw4_SetCooperativeLevel(pScreenPriv->pdd4,
376                                                   pScreenPriv->hwndScreen,
377                                                   DDSCL_NORMAL);
378         if (FAILED(ddrval)) {
379             ErrorF("winAllocateFBShadowDDNL - Could not set "
380                    "cooperative level: %08x\n", (unsigned int) ddrval);
381             return FALSE;
382         }
383     }
384 
385     /* Create the primary surface */
386     if (!winCreatePrimarySurfaceShadowDDNL(pScreen)) {
387         ErrorF("winAllocateFBShadowDDNL - winCreatePrimarySurfaceShadowDDNL "
388                "failed\n");
389         return FALSE;
390     }
391 
392     /* Get primary surface's pixel format */
393     ZeroMemory(&ddpfPrimary, sizeof(ddpfPrimary));
394     ddpfPrimary.dwSize = sizeof(ddpfPrimary);
395     ddrval = IDirectDrawSurface4_GetPixelFormat(pScreenPriv->pddsPrimary4,
396                                                 &ddpfPrimary);
397     if (FAILED(ddrval)) {
398         ErrorF("winAllocateFBShadowDDNL - Could not get primary "
399                "pixformat: %08x\n", (unsigned int) ddrval);
400         return FALSE;
401     }
402 
403 #if CYGDEBUG
404     winDebug("winAllocateFBShadowDDNL - Primary masks: %08x %08x %08x "
405              "dwRGBBitCount: %u\n",
406              (unsigned int)ddpfPrimary.u2.dwRBitMask,
407              (unsigned int)ddpfPrimary.u3.dwGBitMask,
408              (unsigned int)ddpfPrimary.u4.dwBBitMask,
409              (unsigned int)ddpfPrimary.u1.dwRGBBitCount);
410 #endif
411 
412     /* Describe the shadow surface to be created */
413     /*
414      * NOTE: Do not use a DDSCAPS_VIDEOMEMORY surface,
415      * as drawing, locking, and unlocking take forever
416      * with video memory surfaces.  In addition,
417      * video memory is a somewhat scarce resource,
418      * so you shouldn't be allocating video memory when
419      * you have the option of using system memory instead.
420      */
421     ZeroMemory(&ddsdShadow, sizeof(ddsdShadow));
422     ddsdShadow.dwSize = sizeof(ddsdShadow);
423     ddsdShadow.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH
424         | DDSD_LPSURFACE | DDSD_PITCH | DDSD_PIXELFORMAT;
425     ddsdShadow.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;
426     ddsdShadow.dwHeight = pScreenInfo->dwHeight;
427     ddsdShadow.dwWidth = pScreenInfo->dwWidth;
428     ddsdShadow.u1.lPitch = pScreenInfo->dwPaddedWidth;
429     ddsdShadow.lpSurface = lpSurface;
430     ddsdShadow.u4.ddpfPixelFormat = ddpfPrimary;
431 
432     winDebug("winAllocateFBShadowDDNL - lPitch: %d\n",
433              (int) pScreenInfo->dwPaddedWidth);
434 
435     /* Create the shadow surface */
436     ddrval = IDirectDraw4_CreateSurface(pScreenPriv->pdd4,
437                                         &ddsdShadow,
438                                         &pScreenPriv->pddsShadow4, NULL);
439     if (FAILED(ddrval)) {
440         ErrorF("winAllocateFBShadowDDNL - Could not create shadow "
441                "surface: %08x\n", (unsigned int) ddrval);
442         return FALSE;
443     }
444 
445 #if CYGDEBUG || YES
446     winDebug("winAllocateFBShadowDDNL - Created shadow pitch: %d\n",
447              (int) ddsdShadow.u1.lPitch);
448 #endif
449 
450     /* Grab the pitch from the surface desc */
451     pScreenInfo->dwStride = (ddsdShadow.u1.lPitch * 8)
452         / pScreenInfo->dwBPP;
453 
454 #if CYGDEBUG || YES
455     winDebug("winAllocateFBShadowDDNL - Created shadow stride: %d\n",
456              (int) pScreenInfo->dwStride);
457 #endif
458 
459     /* Save the pointer to our surface memory */
460     pScreenInfo->pfb = lpSurface;
461 
462     /* Grab the masks from the surface description */
463     pScreenPriv->dwRedMask = ddsdShadow.u4.ddpfPixelFormat.u2.dwRBitMask;
464     pScreenPriv->dwGreenMask = ddsdShadow.u4.ddpfPixelFormat.u3.dwGBitMask;
465     pScreenPriv->dwBlueMask = ddsdShadow.u4.ddpfPixelFormat.u4.dwBBitMask;
466 
467 #if CYGDEBUG
468     winDebug("winAllocateFBShadowDDNL - Returning\n");
469 #endif
470 
471     return TRUE;
472 }
473 
474 static void
winFreeFBShadowDDNL(ScreenPtr pScreen)475 winFreeFBShadowDDNL(ScreenPtr pScreen)
476 {
477     winScreenPriv(pScreen);
478     winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
479 
480     /* Free the shadow surface, if there is one */
481     if (pScreenPriv->pddsShadow4) {
482         IDirectDrawSurface4_Release(pScreenPriv->pddsShadow4);
483         free(pScreenInfo->pfb);
484         pScreenInfo->pfb = NULL;
485         pScreenPriv->pddsShadow4 = NULL;
486     }
487 
488     /* Detach the clipper from the primary surface and release the primary surface, if there is one */
489     winReleasePrimarySurfaceShadowDDNL(pScreen);
490 
491     /* Release the clipper object */
492     if (pScreenPriv->pddcPrimary) {
493         IDirectDrawClipper_Release(pScreenPriv->pddcPrimary);
494         pScreenPriv->pddcPrimary = NULL;
495     }
496 
497     /* Free the DirectDraw4 object, if there is one */
498     if (pScreenPriv->pdd4) {
499         IDirectDraw4_RestoreDisplayMode(pScreenPriv->pdd4);
500         IDirectDraw4_Release(pScreenPriv->pdd4);
501         pScreenPriv->pdd4 = NULL;
502     }
503 
504     /* Free the DirectDraw object, if there is one */
505     if (pScreenPriv->pdd) {
506         IDirectDraw_Release(pScreenPriv->pdd);
507         pScreenPriv->pdd = NULL;
508     }
509 
510     /* Invalidate the ScreenInfo's fb pointer */
511     pScreenInfo->pfb = NULL;
512 }
513 
514 /*
515  * Transfer the damaged regions of the shadow framebuffer to the display.
516  */
517 
518 static void
winShadowUpdateDDNL(ScreenPtr pScreen,shadowBufPtr pBuf)519 winShadowUpdateDDNL(ScreenPtr pScreen, shadowBufPtr pBuf)
520 {
521     winScreenPriv(pScreen);
522     winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
523     RegionPtr damage = DamageRegion(pBuf->pDamage);
524     HRESULT ddrval = DD_OK;
525     RECT rcDest, rcSrc;
526     POINT ptOrigin;
527     DWORD dwBox = RegionNumRects(damage);
528     BoxPtr pBox = RegionRects(damage);
529     HRGN hrgnCombined = NULL;
530 
531     /*
532      * Return immediately if the app is not active
533      * and we are fullscreen, or if we have a bad display depth
534      */
535     if ((!pScreenPriv->fActive && pScreenInfo->fFullScreen)
536         || pScreenPriv->fBadDepth)
537         return;
538 
539     /* Return immediately if we didn't get needed surfaces */
540     if (!pScreenPriv->pddsPrimary4 || !pScreenPriv->pddsShadow4)
541         return;
542 
543     /* Get the origin of the window in the screen coords */
544     ptOrigin.x = pScreenInfo->dwXOffset;
545     ptOrigin.y = pScreenInfo->dwYOffset;
546     MapWindowPoints(pScreenPriv->hwndScreen,
547                     HWND_DESKTOP, (LPPOINT) &ptOrigin, 1);
548 
549     /*
550      * Handle small regions with multiple blits,
551      * handle large regions by creating a clipping region and
552      * doing a single blit constrained to that clipping region.
553      */
554     if (pScreenInfo->dwClipUpdatesNBoxes == 0
555         || dwBox < pScreenInfo->dwClipUpdatesNBoxes) {
556         /* Loop through all boxes in the damaged region */
557         while (dwBox--) {
558             /* Assign damage box to source rectangle */
559             rcSrc.left = pBox->x1;
560             rcSrc.top = pBox->y1;
561             rcSrc.right = pBox->x2;
562             rcSrc.bottom = pBox->y2;
563 
564             /* Calculate destination rectangle */
565             rcDest.left = ptOrigin.x + rcSrc.left;
566             rcDest.top = ptOrigin.y + rcSrc.top;
567             rcDest.right = ptOrigin.x + rcSrc.right;
568             rcDest.bottom = ptOrigin.y + rcSrc.bottom;
569 
570             /* Blit the damaged areas */
571             ddrval = IDirectDrawSurface4_Blt(pScreenPriv->pddsPrimary4,
572                                              &rcDest,
573                                              pScreenPriv->pddsShadow4,
574                                              &rcSrc, DDBLT_WAIT, NULL);
575             if (FAILED(ddrval)) {
576                 static int s_iFailCount = 0;
577 
578                 if (s_iFailCount < FAIL_MSG_MAX_BLT) {
579                     ErrorF("winShadowUpdateDDNL - IDirectDrawSurface4_Blt () "
580                            "failed: %08x\n", (unsigned int) ddrval);
581 
582                     ++s_iFailCount;
583 
584                     if (s_iFailCount == FAIL_MSG_MAX_BLT) {
585                         ErrorF("winShadowUpdateDDNL - IDirectDrawSurface4_Blt "
586                                "failure message maximum (%d) reached.  No "
587                                "more failure messages will be printed.\n",
588                                FAIL_MSG_MAX_BLT);
589                     }
590                 }
591             }
592 
593             /* Get a pointer to the next box */
594             ++pBox;
595         }
596     }
597     else {
598         BoxPtr pBoxExtents = RegionExtents(damage);
599 
600         /* Compute a GDI region from the damaged region */
601         hrgnCombined =
602             CreateRectRgn(pBoxExtents->x1, pBoxExtents->y1, pBoxExtents->x2,
603                           pBoxExtents->y2);
604 
605         /* Install the GDI region as a clipping region */
606         SelectClipRgn(pScreenPriv->hdcScreen, hrgnCombined);
607         DeleteObject(hrgnCombined);
608         hrgnCombined = NULL;
609 
610 #if CYGDEBUG
611         winDebug("winShadowUpdateDDNL - be x1 %d y1 %d x2 %d y2 %d\n",
612                  pBoxExtents->x1, pBoxExtents->y1,
613                  pBoxExtents->x2, pBoxExtents->y2);
614 #endif
615 
616         /* Calculating a bounding box for the source is easy */
617         rcSrc.left = pBoxExtents->x1;
618         rcSrc.top = pBoxExtents->y1;
619         rcSrc.right = pBoxExtents->x2;
620         rcSrc.bottom = pBoxExtents->y2;
621 
622         /* Calculating a bounding box for the destination is trickier */
623         rcDest.left = ptOrigin.x + rcSrc.left;
624         rcDest.top = ptOrigin.y + rcSrc.top;
625         rcDest.right = ptOrigin.x + rcSrc.right;
626         rcDest.bottom = ptOrigin.y + rcSrc.bottom;
627 
628         /* Our Blt should be clipped to the invalidated region */
629         ddrval = IDirectDrawSurface4_Blt(pScreenPriv->pddsPrimary4,
630                                          &rcDest,
631                                          pScreenPriv->pddsShadow4,
632                                          &rcSrc, DDBLT_WAIT, NULL);
633 
634         /* Reset the clip region */
635         SelectClipRgn(pScreenPriv->hdcScreen, NULL);
636     }
637 }
638 
639 static Bool
winInitScreenShadowDDNL(ScreenPtr pScreen)640 winInitScreenShadowDDNL(ScreenPtr pScreen)
641 {
642     winScreenPriv(pScreen);
643 
644     /* Get a device context for the screen  */
645     pScreenPriv->hdcScreen = GetDC(pScreenPriv->hwndScreen);
646 
647     return winAllocateFBShadowDDNL(pScreen);
648 }
649 
650 /*
651  * Call the wrapped CloseScreen function.
652  *
653  * Free our resources and private structures.
654  */
655 
656 static Bool
winCloseScreenShadowDDNL(ScreenPtr pScreen)657 winCloseScreenShadowDDNL(ScreenPtr pScreen)
658 {
659     winScreenPriv(pScreen);
660     winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
661     Bool fReturn = TRUE;
662 
663 #if CYGDEBUG
664     winDebug("winCloseScreenShadowDDNL - Freeing screen resources\n");
665 #endif
666 
667     /* Flag that the screen is closed */
668     pScreenPriv->fClosed = TRUE;
669     pScreenPriv->fActive = FALSE;
670 
671     /* Call the wrapped CloseScreen procedure */
672     WIN_UNWRAP(CloseScreen);
673     if (pScreen->CloseScreen)
674         fReturn = (*pScreen->CloseScreen) (pScreen);
675 
676     winFreeFBShadowDDNL(pScreen);
677 
678     /* Free the screen DC */
679     ReleaseDC(pScreenPriv->hwndScreen, pScreenPriv->hdcScreen);
680 
681     /* Delete the window property */
682     RemoveProp(pScreenPriv->hwndScreen, WIN_SCR_PROP);
683 
684     /* Delete tray icon, if we have one */
685     if (!pScreenInfo->fNoTrayIcon)
686         winDeleteNotifyIcon(pScreenPriv);
687 
688     /* Free the exit confirmation dialog box, if it exists */
689     if (g_hDlgExit != NULL) {
690         DestroyWindow(g_hDlgExit);
691         g_hDlgExit = NULL;
692     }
693 
694     /* Kill our window */
695     if (pScreenPriv->hwndScreen) {
696         DestroyWindow(pScreenPriv->hwndScreen);
697         pScreenPriv->hwndScreen = NULL;
698     }
699 
700     /* Destroy the thread startup mutex */
701     pthread_mutex_destroy(&pScreenPriv->pmServerStarted);
702 
703     /* Kill our screeninfo's pointer to the screen */
704     pScreenInfo->pScreen = NULL;
705 
706     /* Free the screen privates for this screen */
707     free((void *) pScreenPriv);
708 
709     return fReturn;
710 }
711 
712 /*
713  * Tell mi what sort of visuals we need.
714  *
715  * Generally we only need one visual, as our screen can only
716  * handle one format at a time, I believe.  You may want
717  * to verify that last sentence.
718  */
719 
720 static Bool
winInitVisualsShadowDDNL(ScreenPtr pScreen)721 winInitVisualsShadowDDNL(ScreenPtr pScreen)
722 {
723     winScreenPriv(pScreen);
724     winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
725     DWORD dwRedBits, dwGreenBits, dwBlueBits;
726 
727     /* Count the number of ones in each color mask */
728     dwRedBits = winCountBits(pScreenPriv->dwRedMask);
729     dwGreenBits = winCountBits(pScreenPriv->dwGreenMask);
730     dwBlueBits = winCountBits(pScreenPriv->dwBlueMask);
731 
732     /* Store the maximum number of ones in a color mask as the bitsPerRGB */
733     if (dwRedBits == 0 || dwGreenBits == 0 || dwBlueBits == 0)
734         pScreenPriv->dwBitsPerRGB = 8;
735     else if (dwRedBits > dwGreenBits && dwRedBits > dwBlueBits)
736         pScreenPriv->dwBitsPerRGB = dwRedBits;
737     else if (dwGreenBits > dwRedBits && dwGreenBits > dwBlueBits)
738         pScreenPriv->dwBitsPerRGB = dwGreenBits;
739     else
740         pScreenPriv->dwBitsPerRGB = dwBlueBits;
741 
742     winDebug("winInitVisualsShadowDDNL - Masks %08x %08x %08x BPRGB %d d %d "
743              "bpp %d\n",
744              (unsigned int) pScreenPriv->dwRedMask,
745              (unsigned int) pScreenPriv->dwGreenMask,
746              (unsigned int) pScreenPriv->dwBlueMask,
747              (int) pScreenPriv->dwBitsPerRGB,
748              (int) pScreenInfo->dwDepth, (int) pScreenInfo->dwBPP);
749 
750     /* Create a single visual according to the Windows screen depth */
751     switch (pScreenInfo->dwDepth) {
752     case 24:
753     case 16:
754     case 15:
755         /* Setup the real visual */
756         if (!miSetVisualTypesAndMasks(pScreenInfo->dwDepth,
757                                       TrueColorMask,
758                                       pScreenPriv->dwBitsPerRGB,
759                                       -1,
760                                       pScreenPriv->dwRedMask,
761                                       pScreenPriv->dwGreenMask,
762                                       pScreenPriv->dwBlueMask)) {
763             ErrorF("winInitVisualsShadowDDNL - miSetVisualTypesAndMasks "
764                    "failed for TrueColor\n");
765             return FALSE;
766         }
767 
768 #ifdef XWIN_EMULATEPSEUDO
769         if (!pScreenInfo->fEmulatePseudo)
770             break;
771 
772         /* Setup a pseudocolor visual */
773         if (!miSetVisualTypesAndMasks(8, PseudoColorMask, 8, -1, 0, 0, 0)) {
774             ErrorF("winInitVisualsShadowDDNL - miSetVisualTypesAndMasks "
775                    "failed for PseudoColor\n");
776             return FALSE;
777         }
778 #endif
779         break;
780 
781     case 8:
782         if (!miSetVisualTypesAndMasks(pScreenInfo->dwDepth,
783                                       pScreenInfo->fFullScreen
784                                       ? PseudoColorMask : StaticColorMask,
785                                       pScreenPriv->dwBitsPerRGB,
786                                       pScreenInfo->fFullScreen
787                                       ? PseudoColor : StaticColor,
788                                       pScreenPriv->dwRedMask,
789                                       pScreenPriv->dwGreenMask,
790                                       pScreenPriv->dwBlueMask)) {
791             ErrorF("winInitVisualsShadowDDNL - miSetVisualTypesAndMasks "
792                    "failed\n");
793             return FALSE;
794         }
795         break;
796 
797     default:
798         ErrorF("winInitVisualsShadowDDNL - Unknown screen depth\n");
799         return FALSE;
800     }
801 
802 #if CYGDEBUG
803     winDebug("winInitVisualsShadowDDNL - Returning\n");
804 #endif
805 
806     return TRUE;
807 }
808 
809 /*
810  * Adjust the user proposed video mode
811  */
812 
813 static Bool
winAdjustVideoModeShadowDDNL(ScreenPtr pScreen)814 winAdjustVideoModeShadowDDNL(ScreenPtr pScreen)
815 {
816     winScreenPriv(pScreen);
817     winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
818     HDC hdc = NULL;
819     DWORD dwBPP;
820 
821     /* We're in serious trouble if we can't get a DC */
822     hdc = GetDC(NULL);
823     if (hdc == NULL) {
824         ErrorF("winAdjustVideoModeShadowDDNL - GetDC () failed\n");
825         return FALSE;
826     }
827 
828     /* Query GDI for current display depth */
829     dwBPP = GetDeviceCaps(hdc, BITSPIXEL);
830 
831     /* DirectDraw can only change the depth in fullscreen mode */
832     if (!(pScreenInfo->fFullScreen && (pScreenInfo->dwBPP != WIN_DEFAULT_BPP))) {
833         /* Otherwise, We'll use GDI's depth */
834         pScreenInfo->dwBPP = dwBPP;
835     }
836 
837     /* Release our DC */
838     ReleaseDC(NULL, hdc);
839 
840     return TRUE;
841 }
842 
843 /*
844  * Blt exposed regions to the screen
845  */
846 
847 static Bool
winBltExposedRegionsShadowDDNL(ScreenPtr pScreen)848 winBltExposedRegionsShadowDDNL(ScreenPtr pScreen)
849 {
850     winScreenPriv(pScreen);
851     winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
852     RECT rcSrc, rcDest;
853     POINT ptOrigin;
854     HDC hdcUpdate;
855     PAINTSTRUCT ps;
856     HRESULT ddrval = DD_OK;
857     Bool fReturn = TRUE;
858     int i;
859 
860     /* Quite common case. The primary surface was lost (maybe because of depth
861      * change). Try to create a new primary surface. Bail out if this fails */
862     if (pScreenPriv->pddsPrimary4 == NULL && pScreenPriv->fRetryCreateSurface &&
863         !winCreatePrimarySurfaceShadowDDNL(pScreen)) {
864         Sleep(100);
865         return FALSE;
866     }
867     if (pScreenPriv->pddsPrimary4 == NULL)
868         return FALSE;
869 
870     /* BeginPaint gives us an hdc that clips to the invalidated region */
871     hdcUpdate = BeginPaint(pScreenPriv->hwndScreen, &ps);
872     if (hdcUpdate == NULL) {
873         fReturn = FALSE;
874         ErrorF("winBltExposedRegionsShadowDDNL - BeginPaint () returned "
875                "a NULL device context handle.  Aborting blit attempt.\n");
876         goto winBltExposedRegionsShadowDDNL_Exit;
877     }
878 
879     /* Get the origin of the window in the screen coords */
880     ptOrigin.x = pScreenInfo->dwXOffset;
881     ptOrigin.y = pScreenInfo->dwYOffset;
882 
883     MapWindowPoints(pScreenPriv->hwndScreen,
884                     HWND_DESKTOP, (LPPOINT) &ptOrigin, 1);
885     rcDest.left = ptOrigin.x;
886     rcDest.right = ptOrigin.x + pScreenInfo->dwWidth;
887     rcDest.top = ptOrigin.y;
888     rcDest.bottom = ptOrigin.y + pScreenInfo->dwHeight;
889 
890     /* Source can be entire shadow surface, as Blt should clip for us */
891     rcSrc.left = 0;
892     rcSrc.top = 0;
893     rcSrc.right = pScreenInfo->dwWidth;
894     rcSrc.bottom = pScreenInfo->dwHeight;
895 
896     /* Try to regain the primary surface and blit again if we've lost it */
897     for (i = 0; i <= WIN_REGAIN_SURFACE_RETRIES; ++i) {
898         /* Our Blt should be clipped to the invalidated region */
899         ddrval = IDirectDrawSurface4_Blt(pScreenPriv->pddsPrimary4,
900                                          &rcDest,
901                                          pScreenPriv->pddsShadow4,
902                                          &rcSrc, DDBLT_WAIT, NULL);
903         if (ddrval == DDERR_SURFACELOST) {
904             /* Surface was lost */
905             winErrorFVerb(1, "winBltExposedRegionsShadowDDNL - "
906                           "IDirectDrawSurface4_Blt reported that the primary "
907                           "surface was lost, trying to restore, retry: %d\n",
908                           i + 1);
909 
910             /* Try to restore the surface, once */
911 
912             ddrval = IDirectDrawSurface4_Restore(pScreenPriv->pddsPrimary4);
913             winDebug("winBltExposedRegionsShadowDDNL - "
914                      "IDirectDrawSurface4_Restore returned: ");
915             if (ddrval == DD_OK)
916                 winDebug("DD_OK\n");
917             else if (ddrval == DDERR_WRONGMODE)
918                 winDebug("DDERR_WRONGMODE\n");
919             else if (ddrval == DDERR_INCOMPATIBLEPRIMARY)
920                 winDebug("DDERR_INCOMPATIBLEPRIMARY\n");
921             else if (ddrval == DDERR_UNSUPPORTED)
922                 winDebug("DDERR_UNSUPPORTED\n");
923             else if (ddrval == DDERR_INVALIDPARAMS)
924                 winDebug("DDERR_INVALIDPARAMS\n");
925             else if (ddrval == DDERR_INVALIDOBJECT)
926                 winDebug("DDERR_INVALIDOBJECT\n");
927             else
928                 winDebug("unknown error: %08x\n", (unsigned int) ddrval);
929 
930             /* Loop around to try the blit one more time */
931             continue;
932         }
933         else if (FAILED(ddrval)) {
934             fReturn = FALSE;
935             winErrorFVerb(1, "winBltExposedRegionsShadowDDNL - "
936                           "IDirectDrawSurface4_Blt failed, but surface not "
937                           "lost: %08x %d\n",
938                           (unsigned int) ddrval, (int) ddrval);
939             goto winBltExposedRegionsShadowDDNL_Exit;
940         }
941         else {
942             /* Success, stop looping */
943             break;
944         }
945     }
946 
947  winBltExposedRegionsShadowDDNL_Exit:
948     /* EndPaint frees the DC */
949     if (hdcUpdate != NULL)
950         EndPaint(pScreenPriv->hwndScreen, &ps);
951     return fReturn;
952 }
953 
954 /*
955  * Do any engine-specific application-activation processing
956  */
957 
958 static Bool
winActivateAppShadowDDNL(ScreenPtr pScreen)959 winActivateAppShadowDDNL(ScreenPtr pScreen)
960 {
961     winScreenPriv(pScreen);
962 
963     /*
964      * Do we have a surface?
965      * Are we active?
966      * Are we full screen?
967      */
968     if (pScreenPriv != NULL
969         && pScreenPriv->pddsPrimary4 != NULL && pScreenPriv->fActive) {
970         /* Primary surface was lost, restore it */
971         IDirectDrawSurface4_Restore(pScreenPriv->pddsPrimary4);
972     }
973 
974     return TRUE;
975 }
976 
977 /*
978  * Reblit the shadow framebuffer to the screen.
979  */
980 
981 static Bool
winRedrawScreenShadowDDNL(ScreenPtr pScreen)982 winRedrawScreenShadowDDNL(ScreenPtr pScreen)
983 {
984     winScreenPriv(pScreen);
985     winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
986     HRESULT ddrval = DD_OK;
987     RECT rcSrc, rcDest;
988     POINT ptOrigin;
989 
990     /* Return immediately if we didn't get needed surfaces */
991     if (!pScreenPriv->pddsPrimary4 || !pScreenPriv->pddsShadow4)
992         return FALSE;
993 
994     /* Get the origin of the window in the screen coords */
995     ptOrigin.x = pScreenInfo->dwXOffset;
996     ptOrigin.y = pScreenInfo->dwYOffset;
997     MapWindowPoints(pScreenPriv->hwndScreen,
998                     HWND_DESKTOP, (LPPOINT) &ptOrigin, 1);
999     rcDest.left = ptOrigin.x;
1000     rcDest.right = ptOrigin.x + pScreenInfo->dwWidth;
1001     rcDest.top = ptOrigin.y;
1002     rcDest.bottom = ptOrigin.y + pScreenInfo->dwHeight;
1003 
1004     /* Source can be entire shadow surface, as Blt should clip for us */
1005     rcSrc.left = 0;
1006     rcSrc.top = 0;
1007     rcSrc.right = pScreenInfo->dwWidth;
1008     rcSrc.bottom = pScreenInfo->dwHeight;
1009 
1010     /* Redraw the whole window, to take account for the new colors */
1011     ddrval = IDirectDrawSurface4_Blt(pScreenPriv->pddsPrimary4,
1012                                      &rcDest,
1013                                      pScreenPriv->pddsShadow4,
1014                                      &rcSrc, DDBLT_WAIT, NULL);
1015     if (FAILED(ddrval)) {
1016         ErrorF("winRedrawScreenShadowDDNL - IDirectDrawSurface4_Blt () "
1017                "failed: %08x\n", (unsigned int) ddrval);
1018     }
1019 
1020     return TRUE;
1021 }
1022 
1023 /*
1024  * Realize the currently installed colormap
1025  */
1026 
1027 static Bool
winRealizeInstalledPaletteShadowDDNL(ScreenPtr pScreen)1028 winRealizeInstalledPaletteShadowDDNL(ScreenPtr pScreen)
1029 {
1030     return TRUE;
1031 }
1032 
1033 /*
1034  * Install the specified colormap
1035  */
1036 
1037 static Bool
winInstallColormapShadowDDNL(ColormapPtr pColormap)1038 winInstallColormapShadowDDNL(ColormapPtr pColormap)
1039 {
1040     ScreenPtr pScreen = pColormap->pScreen;
1041 
1042     winScreenPriv(pScreen);
1043     winCmapPriv(pColormap);
1044     HRESULT ddrval = DD_OK;
1045 
1046     /* Install the DirectDraw palette on the primary surface */
1047     ddrval = IDirectDrawSurface4_SetPalette(pScreenPriv->pddsPrimary4,
1048                                             pCmapPriv->lpDDPalette);
1049     if (FAILED(ddrval)) {
1050         ErrorF("winInstallColormapShadowDDNL - Failed installing the "
1051                "DirectDraw palette.\n");
1052         return FALSE;
1053     }
1054 
1055     /* Save a pointer to the newly installed colormap */
1056     pScreenPriv->pcmapInstalled = pColormap;
1057 
1058     return TRUE;
1059 }
1060 
1061 /*
1062  * Store the specified colors in the specified colormap
1063  */
1064 
1065 static Bool
winStoreColorsShadowDDNL(ColormapPtr pColormap,int ndef,xColorItem * pdefs)1066 winStoreColorsShadowDDNL(ColormapPtr pColormap, int ndef, xColorItem * pdefs)
1067 {
1068     ScreenPtr pScreen = pColormap->pScreen;
1069 
1070     winScreenPriv(pScreen);
1071     winCmapPriv(pColormap);
1072     ColormapPtr curpmap = pScreenPriv->pcmapInstalled;
1073     HRESULT ddrval = DD_OK;
1074 
1075     /* Put the X colormap entries into the Windows logical palette */
1076     ddrval = IDirectDrawPalette_SetEntries(pCmapPriv->lpDDPalette,
1077                                            0,
1078                                            pdefs[0].pixel,
1079                                            ndef,
1080                                            pCmapPriv->peColors
1081                                            + pdefs[0].pixel);
1082     if (FAILED(ddrval)) {
1083         ErrorF("winStoreColorsShadowDDNL - SetEntries () failed: %08x\n",
1084                (unsigned int) ddrval);
1085         return FALSE;
1086     }
1087 
1088     /* Don't install the DirectDraw palette if the colormap is not installed */
1089     if (pColormap != curpmap) {
1090         return TRUE;
1091     }
1092 
1093     if (!winInstallColormapShadowDDNL(pColormap)) {
1094         ErrorF("winStoreColorsShadowDDNL - Failed installing colormap\n");
1095         return FALSE;
1096     }
1097 
1098     return TRUE;
1099 }
1100 
1101 /*
1102  * Colormap initialization procedure
1103  */
1104 
1105 static Bool
winCreateColormapShadowDDNL(ColormapPtr pColormap)1106 winCreateColormapShadowDDNL(ColormapPtr pColormap)
1107 {
1108     HRESULT ddrval = DD_OK;
1109     ScreenPtr pScreen = pColormap->pScreen;
1110 
1111     winScreenPriv(pScreen);
1112     winCmapPriv(pColormap);
1113 
1114     /* Create a DirectDraw palette */
1115     ddrval = IDirectDraw4_CreatePalette(pScreenPriv->pdd4,
1116                                         DDPCAPS_8BIT | DDPCAPS_ALLOW256,
1117                                         pCmapPriv->peColors,
1118                                         &pCmapPriv->lpDDPalette, NULL);
1119     if (FAILED(ddrval)) {
1120         ErrorF("winCreateColormapShadowDDNL - CreatePalette failed\n");
1121         return FALSE;
1122     }
1123 
1124     return TRUE;
1125 }
1126 
1127 /*
1128  * Colormap destruction procedure
1129  */
1130 
1131 static Bool
winDestroyColormapShadowDDNL(ColormapPtr pColormap)1132 winDestroyColormapShadowDDNL(ColormapPtr pColormap)
1133 {
1134     winScreenPriv(pColormap->pScreen);
1135     winCmapPriv(pColormap);
1136     HRESULT ddrval = DD_OK;
1137 
1138     /*
1139      * Is colormap to be destroyed the default?
1140      *
1141      * Non-default colormaps should have had winUninstallColormap
1142      * called on them before we get here.  The default colormap
1143      * will not have had winUninstallColormap called on it.  Thus,
1144      * we need to handle the default colormap in a special way.
1145      */
1146     if (pColormap->flags & IsDefault) {
1147 #if CYGDEBUG
1148         winDebug
1149             ("winDestroyColormapShadowDDNL - Destroying default colormap\n");
1150 #endif
1151 
1152         /*
1153          * FIXME: Walk the list of all screens, popping the default
1154          * palette out of each screen device context.
1155          */
1156 
1157         /* Pop the palette out of the primary surface */
1158         ddrval = IDirectDrawSurface4_SetPalette(pScreenPriv->pddsPrimary4,
1159                                                 NULL);
1160         if (FAILED(ddrval)) {
1161             ErrorF("winDestroyColormapShadowDDNL - Failed freeing the "
1162                    "default colormap DirectDraw palette.\n");
1163             return FALSE;
1164         }
1165 
1166         /* Clear our private installed colormap pointer */
1167         pScreenPriv->pcmapInstalled = NULL;
1168     }
1169 
1170     /* Release the palette */
1171     IDirectDrawPalette_Release(pCmapPriv->lpDDPalette);
1172 
1173     /* Invalidate the colormap privates */
1174     pCmapPriv->lpDDPalette = NULL;
1175 
1176     return TRUE;
1177 }
1178 
1179 /*
1180  * Set pointers to our engine specific functions
1181  */
1182 
1183 Bool
winSetEngineFunctionsShadowDDNL(ScreenPtr pScreen)1184 winSetEngineFunctionsShadowDDNL(ScreenPtr pScreen)
1185 {
1186     winScreenPriv(pScreen);
1187     winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
1188 
1189     /* Set our pointers */
1190     pScreenPriv->pwinAllocateFB = winAllocateFBShadowDDNL;
1191     pScreenPriv->pwinFreeFB = winFreeFBShadowDDNL;
1192     pScreenPriv->pwinShadowUpdate = winShadowUpdateDDNL;
1193     pScreenPriv->pwinInitScreen = winInitScreenShadowDDNL;
1194     pScreenPriv->pwinCloseScreen = winCloseScreenShadowDDNL;
1195     pScreenPriv->pwinInitVisuals = winInitVisualsShadowDDNL;
1196     pScreenPriv->pwinAdjustVideoMode = winAdjustVideoModeShadowDDNL;
1197     if (pScreenInfo->fFullScreen)
1198         pScreenPriv->pwinCreateBoundingWindow =
1199             winCreateBoundingWindowFullScreen;
1200     else
1201         pScreenPriv->pwinCreateBoundingWindow = winCreateBoundingWindowWindowed;
1202     pScreenPriv->pwinFinishScreenInit = winFinishScreenInitFB;
1203     pScreenPriv->pwinBltExposedRegions = winBltExposedRegionsShadowDDNL;
1204     pScreenPriv->pwinBltExposedWindowRegion = NULL;
1205     pScreenPriv->pwinActivateApp = winActivateAppShadowDDNL;
1206     pScreenPriv->pwinRedrawScreen = winRedrawScreenShadowDDNL;
1207     pScreenPriv->pwinRealizeInstalledPalette
1208         = winRealizeInstalledPaletteShadowDDNL;
1209     pScreenPriv->pwinInstallColormap = winInstallColormapShadowDDNL;
1210     pScreenPriv->pwinStoreColors = winStoreColorsShadowDDNL;
1211     pScreenPriv->pwinCreateColormap = winCreateColormapShadowDDNL;
1212     pScreenPriv->pwinDestroyColormap = winDestroyColormapShadowDDNL;
1213     pScreenPriv->pwinCreatePrimarySurface = winCreatePrimarySurfaceShadowDDNL;
1214     pScreenPriv->pwinReleasePrimarySurface = winReleasePrimarySurfaceShadowDDNL;
1215 
1216     return TRUE;
1217 }
1218