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