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