winshadddnl.c revision 35c4bbdf
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
45static Bool
46 winAllocateFBShadowDDNL(ScreenPtr pScreen);
47
48static void
49 winShadowUpdateDDNL(ScreenPtr pScreen, shadowBufPtr pBuf);
50
51static Bool
52 winCloseScreenShadowDDNL(ScreenPtr pScreen);
53
54static Bool
55 winInitVisualsShadowDDNL(ScreenPtr pScreen);
56
57static Bool
58 winAdjustVideoModeShadowDDNL(ScreenPtr pScreen);
59
60static Bool
61 winBltExposedRegionsShadowDDNL(ScreenPtr pScreen);
62
63static Bool
64 winActivateAppShadowDDNL(ScreenPtr pScreen);
65
66static Bool
67 winRedrawScreenShadowDDNL(ScreenPtr pScreen);
68
69static Bool
70 winRealizeInstalledPaletteShadowDDNL(ScreenPtr pScreen);
71
72static Bool
73 winInstallColormapShadowDDNL(ColormapPtr pColormap);
74
75static Bool
76 winStoreColorsShadowDDNL(ColormapPtr pmap, int ndef, xColorItem * pdefs);
77
78static Bool
79 winCreateColormapShadowDDNL(ColormapPtr pColormap);
80
81static Bool
82 winDestroyColormapShadowDDNL(ColormapPtr pColormap);
83
84static Bool
85 winCreatePrimarySurfaceShadowDDNL(ScreenPtr pScreen);
86
87static 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
96static Bool
97winCreatePrimarySurfaceShadowDDNL(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
157static Bool
158winReleasePrimarySurfaceShadowDDNL(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
192Bool
193winAllocateFBShadowDDNL(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
474static void
475winFreeFBShadowDDNL(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
518static void
519winShadowUpdateDDNL(ScreenPtr pScreen, shadowBufPtr pBuf)
520{
521    winScreenPriv(pScreen);
522    winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
523    RegionPtr damage = shadowDamage(pBuf);
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
639static Bool
640winInitScreenShadowDDNL(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
656static Bool
657winCloseScreenShadowDDNL(ScreenPtr pScreen)
658{
659    winScreenPriv(pScreen);
660    winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
661    Bool fReturn;
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#if defined(XWIN_CLIPBOARD) || defined(XWIN_MULTIWINDOW)
701    /* Destroy the thread startup mutex */
702    pthread_mutex_destroy(&pScreenPriv->pmServerStarted);
703#endif
704
705    /* Kill our screeninfo's pointer to the screen */
706    pScreenInfo->pScreen = NULL;
707
708    /* Free the screen privates for this screen */
709    free((void *) pScreenPriv);
710
711    return fReturn;
712}
713
714/*
715 * Tell mi what sort of visuals we need.
716 *
717 * Generally we only need one visual, as our screen can only
718 * handle one format at a time, I believe.  You may want
719 * to verify that last sentence.
720 */
721
722static Bool
723winInitVisualsShadowDDNL(ScreenPtr pScreen)
724{
725    winScreenPriv(pScreen);
726    winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
727    DWORD dwRedBits, dwGreenBits, dwBlueBits;
728
729    /* Count the number of ones in each color mask */
730    dwRedBits = winCountBits(pScreenPriv->dwRedMask);
731    dwGreenBits = winCountBits(pScreenPriv->dwGreenMask);
732    dwBlueBits = winCountBits(pScreenPriv->dwBlueMask);
733
734    /* Store the maximum number of ones in a color mask as the bitsPerRGB */
735    if (dwRedBits == 0 || dwGreenBits == 0 || dwBlueBits == 0)
736        pScreenPriv->dwBitsPerRGB = 8;
737    else if (dwRedBits > dwGreenBits && dwRedBits > dwBlueBits)
738        pScreenPriv->dwBitsPerRGB = dwRedBits;
739    else if (dwGreenBits > dwRedBits && dwGreenBits > dwBlueBits)
740        pScreenPriv->dwBitsPerRGB = dwGreenBits;
741    else
742        pScreenPriv->dwBitsPerRGB = dwBlueBits;
743
744    winDebug("winInitVisualsShadowDDNL - Masks %08x %08x %08x BPRGB %d d %d "
745             "bpp %d\n",
746             (unsigned int) pScreenPriv->dwRedMask,
747             (unsigned int) pScreenPriv->dwGreenMask,
748             (unsigned int) pScreenPriv->dwBlueMask,
749             (int) pScreenPriv->dwBitsPerRGB,
750             (int) pScreenInfo->dwDepth, (int) pScreenInfo->dwBPP);
751
752    /* Create a single visual according to the Windows screen depth */
753    switch (pScreenInfo->dwDepth) {
754    case 24:
755    case 16:
756    case 15:
757        /* Setup the real visual */
758        if (!miSetVisualTypesAndMasks(pScreenInfo->dwDepth,
759                                      TrueColorMask,
760                                      pScreenPriv->dwBitsPerRGB,
761                                      -1,
762                                      pScreenPriv->dwRedMask,
763                                      pScreenPriv->dwGreenMask,
764                                      pScreenPriv->dwBlueMask)) {
765            ErrorF("winInitVisualsShadowDDNL - miSetVisualTypesAndMasks "
766                   "failed for TrueColor\n");
767            return FALSE;
768        }
769
770#ifdef XWIN_EMULATEPSEUDO
771        if (!pScreenInfo->fEmulatePseudo)
772            break;
773
774        /* Setup a pseudocolor visual */
775        if (!miSetVisualTypesAndMasks(8, PseudoColorMask, 8, -1, 0, 0, 0)) {
776            ErrorF("winInitVisualsShadowDDNL - miSetVisualTypesAndMasks "
777                   "failed for PseudoColor\n");
778            return FALSE;
779        }
780#endif
781        break;
782
783    case 8:
784        if (!miSetVisualTypesAndMasks(pScreenInfo->dwDepth,
785                                      pScreenInfo->fFullScreen
786                                      ? PseudoColorMask : StaticColorMask,
787                                      pScreenPriv->dwBitsPerRGB,
788                                      pScreenInfo->fFullScreen
789                                      ? PseudoColor : StaticColor,
790                                      pScreenPriv->dwRedMask,
791                                      pScreenPriv->dwGreenMask,
792                                      pScreenPriv->dwBlueMask)) {
793            ErrorF("winInitVisualsShadowDDNL - miSetVisualTypesAndMasks "
794                   "failed\n");
795            return FALSE;
796        }
797        break;
798
799    default:
800        ErrorF("winInitVisualsShadowDDNL - Unknown screen depth\n");
801        return FALSE;
802    }
803
804#if CYGDEBUG
805    winDebug("winInitVisualsShadowDDNL - Returning\n");
806#endif
807
808    return TRUE;
809}
810
811/*
812 * Adjust the user proposed video mode
813 */
814
815static Bool
816winAdjustVideoModeShadowDDNL(ScreenPtr pScreen)
817{
818    winScreenPriv(pScreen);
819    winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
820    HDC hdc = NULL;
821    DWORD dwBPP;
822
823    /* We're in serious trouble if we can't get a DC */
824    hdc = GetDC(NULL);
825    if (hdc == NULL) {
826        ErrorF("winAdjustVideoModeShadowDDNL - GetDC () failed\n");
827        return FALSE;
828    }
829
830    /* Query GDI for current display depth */
831    dwBPP = GetDeviceCaps(hdc, BITSPIXEL);
832
833    /* DirectDraw can only change the depth in fullscreen mode */
834    if (!(pScreenInfo->fFullScreen && (pScreenInfo->dwBPP != WIN_DEFAULT_BPP))) {
835        /* Otherwise, We'll use GDI's depth */
836        pScreenInfo->dwBPP = dwBPP;
837    }
838
839    /* Release our DC */
840    ReleaseDC(NULL, hdc);
841
842    return TRUE;
843}
844
845/*
846 * Blt exposed regions to the screen
847 */
848
849static Bool
850winBltExposedRegionsShadowDDNL(ScreenPtr pScreen)
851{
852    winScreenPriv(pScreen);
853    winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
854    RECT rcSrc, rcDest;
855    POINT ptOrigin;
856    HDC hdcUpdate;
857    PAINTSTRUCT ps;
858    HRESULT ddrval = DD_OK;
859    Bool fReturn = TRUE;
860    int i;
861
862    /* Quite common case. The primary surface was lost (maybe because of depth
863     * change). Try to create a new primary surface. Bail out if this fails */
864    if (pScreenPriv->pddsPrimary4 == NULL && pScreenPriv->fRetryCreateSurface &&
865        !winCreatePrimarySurfaceShadowDDNL(pScreen)) {
866        Sleep(100);
867        return FALSE;
868    }
869    if (pScreenPriv->pddsPrimary4 == NULL)
870        return FALSE;
871
872    /* BeginPaint gives us an hdc that clips to the invalidated region */
873    hdcUpdate = BeginPaint(pScreenPriv->hwndScreen, &ps);
874    if (hdcUpdate == NULL) {
875        fReturn = FALSE;
876        ErrorF("winBltExposedRegionsShadowDDNL - BeginPaint () returned "
877               "a NULL device context handle.  Aborting blit attempt.\n");
878        goto winBltExposedRegionsShadowDDNL_Exit;
879    }
880
881    /* Get the origin of the window in the screen coords */
882    ptOrigin.x = pScreenInfo->dwXOffset;
883    ptOrigin.y = pScreenInfo->dwYOffset;
884
885    MapWindowPoints(pScreenPriv->hwndScreen,
886                    HWND_DESKTOP, (LPPOINT) &ptOrigin, 1);
887    rcDest.left = ptOrigin.x;
888    rcDest.right = ptOrigin.x + pScreenInfo->dwWidth;
889    rcDest.top = ptOrigin.y;
890    rcDest.bottom = ptOrigin.y + pScreenInfo->dwHeight;
891
892    /* Source can be entire shadow surface, as Blt should clip for us */
893    rcSrc.left = 0;
894    rcSrc.top = 0;
895    rcSrc.right = pScreenInfo->dwWidth;
896    rcSrc.bottom = pScreenInfo->dwHeight;
897
898    /* Try to regain the primary surface and blit again if we've lost it */
899    for (i = 0; i <= WIN_REGAIN_SURFACE_RETRIES; ++i) {
900        /* Our Blt should be clipped to the invalidated region */
901        ddrval = IDirectDrawSurface4_Blt(pScreenPriv->pddsPrimary4,
902                                         &rcDest,
903                                         pScreenPriv->pddsShadow4,
904                                         &rcSrc, DDBLT_WAIT, NULL);
905        if (ddrval == DDERR_SURFACELOST) {
906            /* Surface was lost */
907            winErrorFVerb(1, "winBltExposedRegionsShadowDDNL - "
908                          "IDirectDrawSurface4_Blt reported that the primary "
909                          "surface was lost, trying to restore, retry: %d\n",
910                          i + 1);
911
912            /* Try to restore the surface, once */
913
914            ddrval = IDirectDrawSurface4_Restore(pScreenPriv->pddsPrimary4);
915            winDebug("winBltExposedRegionsShadowDDNL - "
916                     "IDirectDrawSurface4_Restore returned: ");
917            if (ddrval == DD_OK)
918                winDebug("DD_OK\n");
919            else if (ddrval == DDERR_WRONGMODE)
920                winDebug("DDERR_WRONGMODE\n");
921            else if (ddrval == DDERR_INCOMPATIBLEPRIMARY)
922                winDebug("DDERR_INCOMPATIBLEPRIMARY\n");
923            else if (ddrval == DDERR_UNSUPPORTED)
924                winDebug("DDERR_UNSUPPORTED\n");
925            else if (ddrval == DDERR_INVALIDPARAMS)
926                winDebug("DDERR_INVALIDPARAMS\n");
927            else if (ddrval == DDERR_INVALIDOBJECT)
928                winDebug("DDERR_INVALIDOBJECT\n");
929            else
930                winDebug("unknown error: %08x\n", (unsigned int) ddrval);
931
932            /* Loop around to try the blit one more time */
933            continue;
934        }
935        else if (FAILED(ddrval)) {
936            fReturn = FALSE;
937            winErrorFVerb(1, "winBltExposedRegionsShadowDDNL - "
938                          "IDirectDrawSurface4_Blt failed, but surface not "
939                          "lost: %08x %d\n",
940                          (unsigned int) ddrval, (int) ddrval);
941            goto winBltExposedRegionsShadowDDNL_Exit;
942        }
943        else {
944            /* Success, stop looping */
945            break;
946        }
947    }
948
949 winBltExposedRegionsShadowDDNL_Exit:
950    /* EndPaint frees the DC */
951    if (hdcUpdate != NULL)
952        EndPaint(pScreenPriv->hwndScreen, &ps);
953    return fReturn;
954}
955
956/*
957 * Do any engine-specific application-activation processing
958 */
959
960static Bool
961winActivateAppShadowDDNL(ScreenPtr pScreen)
962{
963    winScreenPriv(pScreen);
964
965    /*
966     * Do we have a surface?
967     * Are we active?
968     * Are we full screen?
969     */
970    if (pScreenPriv != NULL
971        && pScreenPriv->pddsPrimary4 != NULL && pScreenPriv->fActive) {
972        /* Primary surface was lost, restore it */
973        IDirectDrawSurface4_Restore(pScreenPriv->pddsPrimary4);
974    }
975
976    return TRUE;
977}
978
979/*
980 * Reblit the shadow framebuffer to the screen.
981 */
982
983static Bool
984winRedrawScreenShadowDDNL(ScreenPtr pScreen)
985{
986    winScreenPriv(pScreen);
987    winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
988    HRESULT ddrval = DD_OK;
989    RECT rcSrc, rcDest;
990    POINT ptOrigin;
991
992    /* Return immediately if we didn't get needed surfaces */
993    if (!pScreenPriv->pddsPrimary4 || !pScreenPriv->pddsShadow4)
994        return FALSE;
995
996    /* Get the origin of the window in the screen coords */
997    ptOrigin.x = pScreenInfo->dwXOffset;
998    ptOrigin.y = pScreenInfo->dwYOffset;
999    MapWindowPoints(pScreenPriv->hwndScreen,
1000                    HWND_DESKTOP, (LPPOINT) &ptOrigin, 1);
1001    rcDest.left = ptOrigin.x;
1002    rcDest.right = ptOrigin.x + pScreenInfo->dwWidth;
1003    rcDest.top = ptOrigin.y;
1004    rcDest.bottom = ptOrigin.y + pScreenInfo->dwHeight;
1005
1006    /* Source can be entire shadow surface, as Blt should clip for us */
1007    rcSrc.left = 0;
1008    rcSrc.top = 0;
1009    rcSrc.right = pScreenInfo->dwWidth;
1010    rcSrc.bottom = pScreenInfo->dwHeight;
1011
1012    /* Redraw the whole window, to take account for the new colors */
1013    ddrval = IDirectDrawSurface4_Blt(pScreenPriv->pddsPrimary4,
1014                                     &rcDest,
1015                                     pScreenPriv->pddsShadow4,
1016                                     &rcSrc, DDBLT_WAIT, NULL);
1017    if (FAILED(ddrval)) {
1018        ErrorF("winRedrawScreenShadowDDNL - IDirectDrawSurface4_Blt () "
1019               "failed: %08x\n", (unsigned int) ddrval);
1020    }
1021
1022    return TRUE;
1023}
1024
1025/*
1026 * Realize the currently installed colormap
1027 */
1028
1029static Bool
1030winRealizeInstalledPaletteShadowDDNL(ScreenPtr pScreen)
1031{
1032    return TRUE;
1033}
1034
1035/*
1036 * Install the specified colormap
1037 */
1038
1039static Bool
1040winInstallColormapShadowDDNL(ColormapPtr pColormap)
1041{
1042    ScreenPtr pScreen = pColormap->pScreen;
1043
1044    winScreenPriv(pScreen);
1045    winCmapPriv(pColormap);
1046    HRESULT ddrval = DD_OK;
1047
1048    /* Install the DirectDraw palette on the primary surface */
1049    ddrval = IDirectDrawSurface4_SetPalette(pScreenPriv->pddsPrimary4,
1050                                            pCmapPriv->lpDDPalette);
1051    if (FAILED(ddrval)) {
1052        ErrorF("winInstallColormapShadowDDNL - Failed installing the "
1053               "DirectDraw palette.\n");
1054        return FALSE;
1055    }
1056
1057    /* Save a pointer to the newly installed colormap */
1058    pScreenPriv->pcmapInstalled = pColormap;
1059
1060    return TRUE;
1061}
1062
1063/*
1064 * Store the specified colors in the specified colormap
1065 */
1066
1067static Bool
1068winStoreColorsShadowDDNL(ColormapPtr pColormap, int ndef, xColorItem * pdefs)
1069{
1070    ScreenPtr pScreen = pColormap->pScreen;
1071
1072    winScreenPriv(pScreen);
1073    winCmapPriv(pColormap);
1074    ColormapPtr curpmap = pScreenPriv->pcmapInstalled;
1075    HRESULT ddrval = DD_OK;
1076
1077    /* Put the X colormap entries into the Windows logical palette */
1078    ddrval = IDirectDrawPalette_SetEntries(pCmapPriv->lpDDPalette,
1079                                           0,
1080                                           pdefs[0].pixel,
1081                                           ndef,
1082                                           pCmapPriv->peColors
1083                                           + pdefs[0].pixel);
1084    if (FAILED(ddrval)) {
1085        ErrorF("winStoreColorsShadowDDNL - SetEntries () failed: %08x\n",
1086               (unsigned int) ddrval);
1087        return FALSE;
1088    }
1089
1090    /* Don't install the DirectDraw palette if the colormap is not installed */
1091    if (pColormap != curpmap) {
1092        return TRUE;
1093    }
1094
1095    if (!winInstallColormapShadowDDNL(pColormap)) {
1096        ErrorF("winStoreColorsShadowDDNL - Failed installing colormap\n");
1097        return FALSE;
1098    }
1099
1100    return TRUE;
1101}
1102
1103/*
1104 * Colormap initialization procedure
1105 */
1106
1107static Bool
1108winCreateColormapShadowDDNL(ColormapPtr pColormap)
1109{
1110    HRESULT ddrval = DD_OK;
1111    ScreenPtr pScreen = pColormap->pScreen;
1112
1113    winScreenPriv(pScreen);
1114    winCmapPriv(pColormap);
1115
1116    /* Create a DirectDraw palette */
1117    ddrval = IDirectDraw4_CreatePalette(pScreenPriv->pdd4,
1118                                        DDPCAPS_8BIT | DDPCAPS_ALLOW256,
1119                                        pCmapPriv->peColors,
1120                                        &pCmapPriv->lpDDPalette, NULL);
1121    if (FAILED(ddrval)) {
1122        ErrorF("winCreateColormapShadowDDNL - CreatePalette failed\n");
1123        return FALSE;
1124    }
1125
1126    return TRUE;
1127}
1128
1129/*
1130 * Colormap destruction procedure
1131 */
1132
1133static Bool
1134winDestroyColormapShadowDDNL(ColormapPtr pColormap)
1135{
1136    winScreenPriv(pColormap->pScreen);
1137    winCmapPriv(pColormap);
1138    HRESULT ddrval = DD_OK;
1139
1140    /*
1141     * Is colormap to be destroyed the default?
1142     *
1143     * Non-default colormaps should have had winUninstallColormap
1144     * called on them before we get here.  The default colormap
1145     * will not have had winUninstallColormap called on it.  Thus,
1146     * we need to handle the default colormap in a special way.
1147     */
1148    if (pColormap->flags & IsDefault) {
1149#if CYGDEBUG
1150        winDebug
1151            ("winDestroyColormapShadowDDNL - Destroying default colormap\n");
1152#endif
1153
1154        /*
1155         * FIXME: Walk the list of all screens, popping the default
1156         * palette out of each screen device context.
1157         */
1158
1159        /* Pop the palette out of the primary surface */
1160        ddrval = IDirectDrawSurface4_SetPalette(pScreenPriv->pddsPrimary4,
1161                                                NULL);
1162        if (FAILED(ddrval)) {
1163            ErrorF("winDestroyColormapShadowDDNL - Failed freeing the "
1164                   "default colormap DirectDraw palette.\n");
1165            return FALSE;
1166        }
1167
1168        /* Clear our private installed colormap pointer */
1169        pScreenPriv->pcmapInstalled = NULL;
1170    }
1171
1172    /* Release the palette */
1173    IDirectDrawPalette_Release(pCmapPriv->lpDDPalette);
1174
1175    /* Invalidate the colormap privates */
1176    pCmapPriv->lpDDPalette = NULL;
1177
1178    return TRUE;
1179}
1180
1181/*
1182 * Set pointers to our engine specific functions
1183 */
1184
1185Bool
1186winSetEngineFunctionsShadowDDNL(ScreenPtr pScreen)
1187{
1188    winScreenPriv(pScreen);
1189    winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
1190
1191    /* Set our pointers */
1192    pScreenPriv->pwinAllocateFB = winAllocateFBShadowDDNL;
1193    pScreenPriv->pwinFreeFB = winFreeFBShadowDDNL;
1194    pScreenPriv->pwinShadowUpdate = winShadowUpdateDDNL;
1195    pScreenPriv->pwinInitScreen = winInitScreenShadowDDNL;
1196    pScreenPriv->pwinCloseScreen = winCloseScreenShadowDDNL;
1197    pScreenPriv->pwinInitVisuals = winInitVisualsShadowDDNL;
1198    pScreenPriv->pwinAdjustVideoMode = winAdjustVideoModeShadowDDNL;
1199    if (pScreenInfo->fFullScreen)
1200        pScreenPriv->pwinCreateBoundingWindow =
1201            winCreateBoundingWindowFullScreen;
1202    else
1203        pScreenPriv->pwinCreateBoundingWindow = winCreateBoundingWindowWindowed;
1204    pScreenPriv->pwinFinishScreenInit = winFinishScreenInitFB;
1205    pScreenPriv->pwinBltExposedRegions = winBltExposedRegionsShadowDDNL;
1206    pScreenPriv->pwinActivateApp = winActivateAppShadowDDNL;
1207    pScreenPriv->pwinRedrawScreen = winRedrawScreenShadowDDNL;
1208    pScreenPriv->pwinRealizeInstalledPalette
1209        = winRealizeInstalledPaletteShadowDDNL;
1210    pScreenPriv->pwinInstallColormap = winInstallColormapShadowDDNL;
1211    pScreenPriv->pwinStoreColors = winStoreColorsShadowDDNL;
1212    pScreenPriv->pwinCreateColormap = winCreateColormapShadowDDNL;
1213    pScreenPriv->pwinDestroyColormap = winDestroyColormapShadowDDNL;
1214    pScreenPriv->pwinHotKeyAltTab =
1215        (winHotKeyAltTabProcPtr) (void (*)(void)) NoopDDA;
1216    pScreenPriv->pwinCreatePrimarySurface = winCreatePrimarySurfaceShadowDDNL;
1217    pScreenPriv->pwinReleasePrimarySurface = winReleasePrimarySurfaceShadowDDNL;
1218#ifdef XWIN_MULTIWINDOW
1219    pScreenPriv->pwinFinishCreateWindowsWindow
1220        = (winFinishCreateWindowsWindowProcPtr) (void (*)(void)) NoopDDA;
1221#endif
1222
1223    return TRUE;
1224}
1225