2 *Copyright (C) 2001-2004 Harold L Hunt II All Rights Reserved.
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:
12 *The above copyright notice and this permission notice shall be
13 *included in all copies or substantial portions of the Software.
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 HAROLD L HUNT II 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.
23 *Except as contained in this notice, the name of Harold L Hunt II
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 Harold L Hunt II.
28 * Authors: Harold L Hunt II
31 #ifdef HAVE_XWIN_CONFIG_H
32 #include <xwin-config.h>
41 #ifdef XWIN_MULTIWINDOW
42 extern DWORD g_dwCurrentThreadID
;
44 extern HWND g_hDlgExit
;
48 * Local function prototypes
51 #ifdef XWIN_MULTIWINDOW
53 winRedrawAllProcShadowGDI (HWND hwnd
, LPARAM lParam
);
56 winRedrawDamagedWindowShadowGDI (HWND hwnd
, LPARAM lParam
);
60 winAllocateFBShadowGDI (ScreenPtr pScreen
);
63 winShadowUpdateGDI (ScreenPtr pScreen
,
67 winCloseScreenShadowGDI (int nIndex
, ScreenPtr pScreen
);
70 winInitVisualsShadowGDI (ScreenPtr pScreen
);
73 winAdjustVideoModeShadowGDI (ScreenPtr pScreen
);
76 winBltExposedRegionsShadowGDI (ScreenPtr pScreen
);
79 winActivateAppShadowGDI (ScreenPtr pScreen
);
82 winRedrawScreenShadowGDI (ScreenPtr pScreen
);
85 winRealizeInstalledPaletteShadowGDI (ScreenPtr pScreen
);
88 winInstallColormapShadowGDI (ColormapPtr pColormap
);
91 winStoreColorsShadowGDI (ColormapPtr pmap
,
96 winCreateColormapShadowGDI (ColormapPtr pColormap
);
99 winDestroyColormapShadowGDI (ColormapPtr pColormap
);
103 * Internal function to get the DIB format that is compatible with the screen
108 winQueryScreenDIBFormat (ScreenPtr pScreen
, BITMAPINFOHEADER
*pbmih
)
110 winScreenPriv(pScreen
);
116 /* Create a memory bitmap compatible with the screen */
117 hbmp
= CreateCompatibleBitmap (pScreenPriv
->hdcScreen
, 1, 1);
120 ErrorF ("winQueryScreenDIBFormat - CreateCompatibleBitmap failed\n");
124 /* Initialize our bitmap info header */
125 ZeroMemory (pbmih
, sizeof (BITMAPINFOHEADER
) + 256 * sizeof (RGBQUAD
));
126 pbmih
->biSize
= sizeof (BITMAPINFOHEADER
);
128 /* Get the biBitCount */
129 if (!GetDIBits (pScreenPriv
->hdcScreen
,
136 ErrorF ("winQueryScreenDIBFormat - First call to GetDIBits failed\n");
142 /* Get a pointer to bitfields */
143 pdw
= (DWORD
*) ((CARD8
*)pbmih
+ sizeof (BITMAPINFOHEADER
));
145 winDebug ("winQueryScreenDIBFormat - First call masks: %08x %08x %08x\n",
146 pdw
[0], pdw
[1], pdw
[2]);
149 /* Get optimal color table, or the optimal bitfields */
150 if (!GetDIBits (pScreenPriv
->hdcScreen
,
157 ErrorF ("winQueryScreenDIBFormat - Second call to GetDIBits "
171 * Internal function to determine the GDI bits per rgb and bit masks
176 winQueryRGBBitsAndMasks (ScreenPtr pScreen
)
178 winScreenPriv(pScreen
);
179 BITMAPINFOHEADER
*pbmih
= NULL
;
182 DWORD dwRedBits
, dwGreenBits
, dwBlueBits
;
184 /* Color masks for 8 bpp are standardized */
185 if (GetDeviceCaps (pScreenPriv
->hdcScreen
, RASTERCAPS
) & RC_PALETTE
)
188 * RGB BPP for 8 bit palletes is always 8
189 * and the color masks are always 0.
191 pScreenPriv
->dwBitsPerRGB
= 8;
192 pScreenPriv
->dwRedMask
= 0x0L
;
193 pScreenPriv
->dwGreenMask
= 0x0L
;
194 pScreenPriv
->dwBlueMask
= 0x0L
;
198 /* Color masks for 24 bpp are standardized */
199 if (GetDeviceCaps (pScreenPriv
->hdcScreen
, PLANES
)
200 * GetDeviceCaps (pScreenPriv
->hdcScreen
, BITSPIXEL
) == 24)
202 ErrorF ("winQueryRGBBitsAndMasks - GetDeviceCaps (BITSPIXEL) "
203 "returned 24 for the screen. Using default 24bpp masks.\n");
205 /* 8 bits per primary color */
206 pScreenPriv
->dwBitsPerRGB
= 8;
208 /* Set screen privates masks */
209 pScreenPriv
->dwRedMask
= WIN_24BPP_MASK_RED
;
210 pScreenPriv
->dwGreenMask
= WIN_24BPP_MASK_GREEN
;
211 pScreenPriv
->dwBlueMask
= WIN_24BPP_MASK_BLUE
;
216 /* Allocate a bitmap header and color table */
217 pbmih
= (BITMAPINFOHEADER
*) malloc (sizeof (BITMAPINFOHEADER
)
218 + 256 * sizeof (RGBQUAD
));
221 ErrorF ("winQueryRGBBitsAndMasks - malloc failed\n");
225 /* Get screen description */
226 if (winQueryScreenDIBFormat (pScreen
, pbmih
))
228 /* Get a pointer to bitfields */
229 pdw
= (DWORD
*) ((CARD8
*)pbmih
+ sizeof (BITMAPINFOHEADER
));
232 winDebug ("%s - Masks: %08x %08x %08x\n", __FUNCTION__
,
233 pdw
[0], pdw
[1], pdw
[2]);
234 winDebug ("%s - Bitmap: %dx%d %d bpp %d planes\n", __FUNCTION__
,
235 pbmih
->biWidth
, pbmih
->biHeight
, pbmih
->biBitCount
, pbmih
->biPlanes
);
236 winDebug ("%s - Compression: %d %s\n", __FUNCTION__
,
237 pbmih
->biCompression
,
238 (pbmih
->biCompression
== BI_RGB
?"(BI_RGB)":
239 (pbmih
->biCompression
== BI_RLE8
?"(BI_RLE8)":
240 (pbmih
->biCompression
== BI_RLE4
?"(BI_RLE4)":
241 (pbmih
->biCompression
== BI_BITFIELDS
?"(BI_BITFIELDS)":""
245 /* Handle BI_RGB case, which is returned by Wine */
246 if (pbmih
->biCompression
== BI_RGB
)
252 pScreenPriv
->dwBitsPerRGB
= 5;
254 /* Set screen privates masks */
255 pScreenPriv
->dwRedMask
= 0x7c00;
256 pScreenPriv
->dwGreenMask
= 0x03e0;
257 pScreenPriv
->dwBlueMask
= 0x001f;
261 /* Count the number of bits in each mask */
262 dwRedBits
= winCountBits (pdw
[0]);
263 dwGreenBits
= winCountBits (pdw
[1]);
264 dwBlueBits
= winCountBits (pdw
[2]);
266 /* Find maximum bits per red, green, blue */
267 if (dwRedBits
> dwGreenBits
&& dwRedBits
> dwBlueBits
)
268 pScreenPriv
->dwBitsPerRGB
= dwRedBits
;
269 else if (dwGreenBits
> dwRedBits
&& dwGreenBits
> dwBlueBits
)
270 pScreenPriv
->dwBitsPerRGB
= dwGreenBits
;
272 pScreenPriv
->dwBitsPerRGB
= dwBlueBits
;
274 /* Set screen privates masks */
275 pScreenPriv
->dwRedMask
= pdw
[0];
276 pScreenPriv
->dwGreenMask
= pdw
[1];
277 pScreenPriv
->dwBlueMask
= pdw
[2];
282 ErrorF ("winQueryRGBBitsAndMasks - winQueryScreenDIBFormat failed\n");
294 #ifdef XWIN_MULTIWINDOW
299 static wBOOL CALLBACK
300 winRedrawAllProcShadowGDI (HWND hwnd
, LPARAM lParam
)
302 if (hwnd
== (HWND
)lParam
)
304 InvalidateRect (hwnd
, NULL
, FALSE
);
309 static wBOOL CALLBACK
310 winRedrawDamagedWindowShadowGDI (HWND hwnd
, LPARAM lParam
)
312 BoxPtr pDamage
= (BoxPtr
)lParam
;
313 RECT rcClient
, rcDamage
, rcRedraw
;
314 POINT topLeft
, bottomRight
;
317 return TRUE
; /* Don't care minimized windows */
319 /* Convert the damaged area from Screen coords to Client coords */
320 topLeft
.x
= pDamage
->x1
; topLeft
.y
= pDamage
->y1
;
321 bottomRight
.x
= pDamage
->x2
; bottomRight
.y
= pDamage
->y2
;
322 topLeft
.x
+= GetSystemMetrics (SM_XVIRTUALSCREEN
);
323 bottomRight
.x
+= GetSystemMetrics (SM_XVIRTUALSCREEN
);
324 topLeft
.y
+= GetSystemMetrics (SM_YVIRTUALSCREEN
);
325 bottomRight
.y
+= GetSystemMetrics (SM_YVIRTUALSCREEN
);
326 ScreenToClient (hwnd
, &topLeft
);
327 ScreenToClient (hwnd
, &bottomRight
);
328 SetRect (&rcDamage
, topLeft
.x
, topLeft
.y
, bottomRight
.x
, bottomRight
.y
);
330 GetClientRect (hwnd
, &rcClient
);
332 if (IntersectRect (&rcRedraw
, &rcClient
, &rcDamage
))
334 InvalidateRect (hwnd
, &rcRedraw
, FALSE
);
343 * Allocate a DIB for the shadow framebuffer GDI server
347 winAllocateFBShadowGDI (ScreenPtr pScreen
)
349 winScreenPriv(pScreen
);
350 winScreenInfo
*pScreenInfo
= pScreenPriv
->pScreenInfo
;
351 BITMAPINFOHEADER
*pbmih
= NULL
;
352 DIBSECTION dibsection
;
355 /* Get device contexts for the screen and shadow bitmap */
356 pScreenPriv
->hdcScreen
= GetDC (pScreenPriv
->hwndScreen
);
357 pScreenPriv
->hdcShadow
= CreateCompatibleDC (pScreenPriv
->hdcScreen
);
359 /* Allocate bitmap info header */
360 pbmih
= (BITMAPINFOHEADER
*) malloc (sizeof (BITMAPINFOHEADER
)
361 + 256 * sizeof (RGBQUAD
));
364 ErrorF ("winAllocateFBShadowGDI - malloc () failed\n");
368 /* Query the screen format */
369 fReturn
= winQueryScreenDIBFormat (pScreen
, pbmih
);
371 /* Describe shadow bitmap to be created */
372 pbmih
->biWidth
= pScreenInfo
->dwWidth
;
373 pbmih
->biHeight
= -pScreenInfo
->dwHeight
;
375 ErrorF ("winAllocateFBShadowGDI - Creating DIB with width: %d height: %d "
377 (int) pbmih
->biWidth
, (int) -pbmih
->biHeight
, pbmih
->biBitCount
);
379 /* Create a DI shadow bitmap with a bit pointer */
380 pScreenPriv
->hbmpShadow
= CreateDIBSection (pScreenPriv
->hdcScreen
,
381 (BITMAPINFO
*) pbmih
,
383 (VOID
**) &pScreenInfo
->pfb
,
386 if (pScreenPriv
->hbmpShadow
== NULL
|| pScreenInfo
->pfb
== NULL
)
388 winW32Error (2, "winAllocateFBShadowGDI - CreateDIBSection failed:");
394 winDebug ("winAllocateFBShadowGDI - Shadow buffer allocated\n");
398 /* Get information about the bitmap that was allocated */
399 GetObject (pScreenPriv
->hbmpShadow
,
404 /* Print information about bitmap allocated */
405 winDebug ("winAllocateFBShadowGDI - Dibsection width: %d height: %d "
406 "depth: %d size image: %d\n",
407 (int) dibsection
.dsBmih
.biWidth
, (int) dibsection
.dsBmih
.biHeight
,
408 dibsection
.dsBmih
.biBitCount
,
409 (int) dibsection
.dsBmih
.biSizeImage
);
412 /* Select the shadow bitmap into the shadow DC */
413 SelectObject (pScreenPriv
->hdcShadow
,
414 pScreenPriv
->hbmpShadow
);
417 winDebug ("winAllocateFBShadowGDI - Attempting a shadow blit\n");
420 /* Do a test blit from the shadow to the screen, I think */
421 fReturn
= BitBlt (pScreenPriv
->hdcScreen
,
423 pScreenInfo
->dwWidth
, pScreenInfo
->dwHeight
,
424 pScreenPriv
->hdcShadow
,
430 winDebug ("winAllocateFBShadowGDI - Shadow blit success\n");
435 winW32Error (2, "winAllocateFBShadowGDI - Shadow blit failure\n");
439 /* ago: ignore this error. The blit fails with wine, but does not
440 * cause any problems later. */
446 /* Look for height weirdness */
447 if (dibsection
.dsBmih
.biHeight
< 0)
449 dibsection
.dsBmih
.biHeight
= -dibsection
.dsBmih
.biHeight
;
452 /* Set screeninfo stride */
453 pScreenInfo
->dwStride
= ((dibsection
.dsBmih
.biSizeImage
454 / dibsection
.dsBmih
.biHeight
)
455 * 8) / pScreenInfo
->dwBPP
;
458 winDebug ("winAllocateFBShadowGDI - Created shadow stride: %d\n",
459 (int) pScreenInfo
->dwStride
);
462 /* See if the shadow bitmap will be larger than the DIB size limit */
463 if (pScreenInfo
->dwWidth
* pScreenInfo
->dwHeight
* pScreenInfo
->dwBPP
464 >= WIN_DIB_MAXIMUM_SIZE
)
466 ErrorF ("winAllocateFBShadowGDI - Requested DIB (bitmap) "
467 "will be larger than %d MB. The surface may fail to be "
468 "allocated on Windows 95, 98, or Me, due to a %d MB limit in "
469 "DIB size. This limit does not apply to Windows NT/2000, and "
470 "this message may be ignored on those platforms.\n",
471 WIN_DIB_MAXIMUM_SIZE_MB
, WIN_DIB_MAXIMUM_SIZE_MB
);
474 /* Determine our color masks */
475 if (!winQueryRGBBitsAndMasks (pScreen
))
477 ErrorF ("winAllocateFBShadowGDI - winQueryRGBBitsAndMasks failed\n");
481 #ifdef XWIN_MULTIWINDOW
482 /* Redraw all windows */
483 if (pScreenInfo
->fMultiWindow
)
484 EnumThreadWindows (g_dwCurrentThreadID
, winRedrawAllProcShadowGDI
, 0);
492 * Blit the damaged regions of the shadow fb to the screen
496 winShadowUpdateGDI (ScreenPtr pScreen
,
499 winScreenPriv(pScreen
);
500 winScreenInfo
*pScreenInfo
= pScreenPriv
->pScreenInfo
;
501 RegionPtr damage
= &pBuf
->damage
;
502 DWORD dwBox
= REGION_NUM_RECTS (damage
);
503 BoxPtr pBox
= REGION_RECTS (damage
);
505 HRGN hrgnTemp
= NULL
, hrgnCombined
= NULL
;
506 #ifdef XWIN_UPDATESTATS
507 static DWORD s_dwNonUnitRegions
= 0;
508 static DWORD s_dwTotalUpdates
= 0;
509 static DWORD s_dwTotalBoxes
= 0;
511 BoxPtr pBoxExtents
= REGION_EXTENTS (pScreen
, damage
);
514 * Return immediately if the app is not active
515 * and we are fullscreen, or if we have a bad display depth
517 if ((!pScreenPriv
->fActive
&& pScreenInfo
->fFullScreen
)
518 || pScreenPriv
->fBadDepth
) return;
520 #ifdef XWIN_UPDATESTATS
522 s_dwTotalBoxes
+= dwBox
;
526 ++s_dwNonUnitRegions
;
527 ErrorF ("winShadowUpdatGDI - dwBox: %d\n", dwBox
);
530 if ((s_dwTotalUpdates
% 100) == 0)
531 ErrorF ("winShadowUpdateGDI - %d%% non-unity regions, avg boxes: %d "
533 (s_dwNonUnitRegions
* 100) / s_dwTotalUpdates
,
534 s_dwTotalBoxes
/ s_dwTotalUpdates
,
535 s_dwNonUnitRegions
, s_dwTotalUpdates
);
536 #endif /* XWIN_UPDATESTATS */
539 * Handle small regions with multiple blits,
540 * handle large regions by creating a clipping region and
541 * doing a single blit constrained to that clipping region.
543 if (!pScreenInfo
->fMultiWindow
&&
544 (pScreenInfo
->dwClipUpdatesNBoxes
== 0 ||
545 dwBox
< pScreenInfo
->dwClipUpdatesNBoxes
))
547 /* Loop through all boxes in the damaged region */
551 * Calculate x offset, y offset, width, and height for
556 w
= pBox
->x2
- pBox
->x1
;
557 h
= pBox
->y2
- pBox
->y1
;
559 BitBlt (pScreenPriv
->hdcScreen
,
562 pScreenPriv
->hdcShadow
,
566 /* Get a pointer to the next box */
570 else if (!pScreenInfo
->fMultiWindow
)
572 /* Compute a GDI region from the damaged region */
573 hrgnCombined
= CreateRectRgn (pBox
->x1
, pBox
->y1
, pBox
->x2
, pBox
->y2
);
578 hrgnTemp
= CreateRectRgn (pBox
->x1
, pBox
->y1
, pBox
->x2
, pBox
->y2
);
579 CombineRgn (hrgnCombined
, hrgnCombined
, hrgnTemp
, RGN_OR
);
580 DeleteObject (hrgnTemp
);
584 /* Install the GDI region as a clipping region */
585 SelectClipRgn (pScreenPriv
->hdcScreen
, hrgnCombined
);
586 DeleteObject (hrgnCombined
);
590 * Blit the shadow buffer to the screen,
591 * constrained to the clipping region.
593 BitBlt (pScreenPriv
->hdcScreen
,
594 pBoxExtents
->x1
, pBoxExtents
->y1
,
595 pBoxExtents
->x2
- pBoxExtents
->x1
,
596 pBoxExtents
->y2
- pBoxExtents
->y1
,
597 pScreenPriv
->hdcShadow
,
598 pBoxExtents
->x1
, pBoxExtents
->y1
,
601 /* Reset the clip region */
602 SelectClipRgn (pScreenPriv
->hdcScreen
, NULL
);
605 #ifdef XWIN_MULTIWINDOW
606 /* Redraw all multiwindow windows */
607 if (pScreenInfo
->fMultiWindow
)
608 EnumThreadWindows (g_dwCurrentThreadID
,
609 winRedrawDamagedWindowShadowGDI
,
610 (LPARAM
)pBoxExtents
);
615 /* See Porting Layer Definition - p. 33 */
617 * We wrap whatever CloseScreen procedure was specified by fb;
618 * a pointer to said procedure is stored in our privates.
622 winCloseScreenShadowGDI (int nIndex
, ScreenPtr pScreen
)
624 winScreenPriv(pScreen
);
625 winScreenInfo
*pScreenInfo
= pScreenPriv
->pScreenInfo
;
629 winDebug ("winCloseScreenShadowGDI - Freeing screen resources\n");
632 /* Flag that the screen is closed */
633 pScreenPriv
->fClosed
= TRUE
;
634 pScreenPriv
->fActive
= FALSE
;
636 /* Call the wrapped CloseScreen procedure */
637 WIN_UNWRAP(CloseScreen
);
638 fReturn
= (*pScreen
->CloseScreen
) (nIndex
, pScreen
);
640 /* Delete the window property */
641 RemoveProp (pScreenPriv
->hwndScreen
, WIN_SCR_PROP
);
643 /* Free the shadow DC; which allows the bitmap to be freed */
644 DeleteDC (pScreenPriv
->hdcShadow
);
646 /* Free the shadow bitmap */
647 DeleteObject (pScreenPriv
->hbmpShadow
);
649 /* Free the screen DC */
650 ReleaseDC (pScreenPriv
->hwndScreen
, pScreenPriv
->hdcScreen
);
652 /* Delete tray icon, if we have one */
653 if (!pScreenInfo
->fNoTrayIcon
)
654 winDeleteNotifyIcon (pScreenPriv
);
656 /* Free the exit confirmation dialog box, if it exists */
657 if (g_hDlgExit
!= NULL
)
659 DestroyWindow (g_hDlgExit
);
663 /* Kill our window */
664 if (pScreenPriv
->hwndScreen
)
666 DestroyWindow (pScreenPriv
->hwndScreen
);
667 pScreenPriv
->hwndScreen
= NULL
;
670 #if defined(XWIN_CLIPBOARD) || defined(XWIN_MULTIWINDOW)
671 /* Destroy the thread startup mutex */
672 pthread_mutex_destroy (&pScreenPriv
->pmServerStarted
);
675 /* Invalidate our screeninfo's pointer to the screen */
676 pScreenInfo
->pScreen
= NULL
;
678 /* Invalidate the ScreenInfo's fb pointer */
679 pScreenInfo
->pfb
= NULL
;
681 /* Free the screen privates for this screen */
682 free ((pointer
) pScreenPriv
);
689 * Tell mi what sort of visuals we need.
691 * Generally we only need one visual, as our screen can only
692 * handle one format at a time, I believe. You may want
693 * to verify that last sentence.
697 winInitVisualsShadowGDI (ScreenPtr pScreen
)
699 winScreenPriv(pScreen
);
700 winScreenInfo
*pScreenInfo
= pScreenPriv
->pScreenInfo
;
702 /* Display debugging information */
703 ErrorF ("winInitVisualsShadowGDI - Masks %08x %08x %08x BPRGB %d d %d "
705 (unsigned int) pScreenPriv
->dwRedMask
,
706 (unsigned int) pScreenPriv
->dwGreenMask
,
707 (unsigned int) pScreenPriv
->dwBlueMask
,
708 (int) pScreenPriv
->dwBitsPerRGB
,
709 (int) pScreenInfo
->dwDepth
,
710 (int) pScreenInfo
->dwBPP
);
712 /* Create a single visual according to the Windows screen depth */
713 switch (pScreenInfo
->dwDepth
)
718 #if defined(XFree86Server)
719 /* Setup the real visual */
720 if (!miSetVisualTypesAndMasks (pScreenInfo
->dwDepth
,
722 pScreenPriv
->dwBitsPerRGB
,
724 pScreenPriv
->dwRedMask
,
725 pScreenPriv
->dwGreenMask
,
726 pScreenPriv
->dwBlueMask
))
728 ErrorF ("winInitVisualsShadowGDI - miSetVisualTypesAndMasks "
733 #ifdef XWIN_EMULATEPSEUDO
734 if (!pScreenInfo
->fEmulatePseudo
)
737 /* Setup a pseudocolor visual */
738 if (!miSetVisualTypesAndMasks (8,
746 ErrorF ("winInitVisualsShadowGDI - miSetVisualTypesAndMasks "
747 "failed for PseudoColor\n");
751 #else /* XFree86Server */
752 /* Setup the real visual */
753 if (!fbSetVisualTypesAndMasks (pScreenInfo
->dwDepth
,
755 pScreenPriv
->dwBitsPerRGB
,
756 pScreenPriv
->dwRedMask
,
757 pScreenPriv
->dwGreenMask
,
758 pScreenPriv
->dwBlueMask
))
760 ErrorF ("winInitVisualsShadowGDI - fbSetVisualTypesAndMasks "
761 "failed for TrueColor\n");
765 #ifdef XWIN_EMULATEPSEUDO
766 if (!pScreenInfo
->fEmulatePseudo
)
769 /* Setup a pseudocolor visual */
770 if (!fbSetVisualTypesAndMasks (8,
777 ErrorF ("winInitVisualsShadowGDI - fbSetVisualTypesAndMasks "
778 "failed for PseudoColor\n");
782 #endif /* XFree86Server */
786 #if defined(XFree86Server)
787 if (!miSetVisualTypesAndMasks (pScreenInfo
->dwDepth
,
789 pScreenPriv
->dwBitsPerRGB
,
791 pScreenPriv
->dwRedMask
,
792 pScreenPriv
->dwGreenMask
,
793 pScreenPriv
->dwBlueMask
))
795 ErrorF ("winInitVisualsShadowGDI - miSetVisualTypesAndMasks "
799 #else /* XFree86Server */
800 if (!fbSetVisualTypesAndMasks (pScreenInfo
->dwDepth
,
802 pScreenPriv
->dwBitsPerRGB
,
803 pScreenPriv
->dwRedMask
,
804 pScreenPriv
->dwGreenMask
,
805 pScreenPriv
->dwBlueMask
))
807 ErrorF ("winInitVisualsShadowGDI - fbSetVisualTypesAndMasks "
815 ErrorF ("winInitVisualsShadowGDI - Unknown screen depth\n");
820 winDebug ("winInitVisualsShadowGDI - Returning\n");
828 * Adjust the proposed video mode
832 winAdjustVideoModeShadowGDI (ScreenPtr pScreen
)
834 winScreenPriv(pScreen
);
835 winScreenInfo
*pScreenInfo
= pScreenPriv
->pScreenInfo
;
841 /* We're in serious trouble if we can't get a DC */
844 ErrorF ("winAdjustVideoModeShadowGDI - GetDC () failed\n");
848 /* Query GDI for current display depth */
849 dwBPP
= GetDeviceCaps (hdc
, BITSPIXEL
);
851 /* GDI cannot change the screen depth */
852 if (pScreenInfo
->dwBPP
== WIN_DEFAULT_BPP
)
854 /* No -depth parameter passed, let the user know the depth being used */
855 ErrorF ("winAdjustVideoModeShadowGDI - Using Windows display "
856 "depth of %d bits per pixel\n", (int) dwBPP
);
858 /* Use GDI's depth */
859 pScreenInfo
->dwBPP
= dwBPP
;
861 else if (dwBPP
!= pScreenInfo
->dwBPP
)
863 /* Warn user if GDI depth is different than -depth parameter */
864 ErrorF ("winAdjustVideoModeShadowGDI - Command line bpp: %d, "\
865 "using bpp: %d\n", (int) pScreenInfo
->dwBPP
, (int) dwBPP
);
867 /* We'll use GDI's depth */
868 pScreenInfo
->dwBPP
= dwBPP
;
872 ReleaseDC (NULL
, hdc
);
880 * Blt exposed regions to the screen
884 winBltExposedRegionsShadowGDI (ScreenPtr pScreen
)
886 winScreenPriv(pScreen
);
887 winScreenInfo
*pScreenInfo
= pScreenPriv
->pScreenInfo
;
888 winPrivCmapPtr pCmapPriv
= NULL
;
892 /* BeginPaint gives us an hdc that clips to the invalidated region */
893 hdcUpdate
= BeginPaint (pScreenPriv
->hwndScreen
, &ps
);
895 /* Realize the palette, if we have one */
896 if (pScreenPriv
->pcmapInstalled
!= NULL
)
898 pCmapPriv
= winGetCmapPriv (pScreenPriv
->pcmapInstalled
);
900 SelectPalette (hdcUpdate
, pCmapPriv
->hPalette
, FALSE
);
901 RealizePalette (hdcUpdate
);
904 /* Our BitBlt will be clipped to the invalidated region */
907 pScreenInfo
->dwWidth
, pScreenInfo
->dwHeight
,
908 pScreenPriv
->hdcShadow
,
912 /* EndPaint frees the DC */
913 EndPaint (pScreenPriv
->hwndScreen
, &ps
);
915 #ifdef XWIN_MULTIWINDOW
916 /* Redraw all windows */
917 if (pScreenInfo
->fMultiWindow
)
918 EnumThreadWindows(g_dwCurrentThreadID
, winRedrawAllProcShadowGDI
,
919 (LPARAM
)pScreenPriv
->hwndScreen
);
927 * Do any engine-specific appliation-activation processing
931 winActivateAppShadowGDI (ScreenPtr pScreen
)
933 winScreenPriv(pScreen
);
934 winScreenInfo
*pScreenInfo
= pScreenPriv
->pScreenInfo
;
937 * 2004/04/12 - Harold - We perform the restoring or minimizing
938 * manually for ShadowGDI in fullscreen modes so that this engine
939 * will perform just like ShadowDD and ShadowDDNL in fullscreen mode;
940 * if we do not do this then our fullscreen window will appear in the
941 * z-order when it is deactivated and it can be uncovered by resizing
942 * or minimizing another window that is on top of it, which is not how
943 * the DirectDraw engines work. Therefore we keep this code here to
944 * make sure that all engines work the same in fullscreen mode.
951 if (pScreenPriv
->fActive
952 && pScreenInfo
->fFullScreen
)
955 * Activating, attempt to bring our window
956 * to the top of the display
958 ShowWindow (pScreenPriv
->hwndScreen
, SW_RESTORE
);
960 else if (!pScreenPriv
->fActive
961 && pScreenInfo
->fFullScreen
)
964 * Deactivating, stuff our window onto the
967 ShowWindow (pScreenPriv
->hwndScreen
, SW_MINIMIZE
);
975 * Reblit the shadow framebuffer to the screen.
979 winRedrawScreenShadowGDI (ScreenPtr pScreen
)
981 winScreenPriv(pScreen
);
982 winScreenInfo
*pScreenInfo
= pScreenPriv
->pScreenInfo
;
984 /* Redraw the whole window, to take account for the new colors */
985 BitBlt (pScreenPriv
->hdcScreen
,
987 pScreenInfo
->dwWidth
, pScreenInfo
->dwHeight
,
988 pScreenPriv
->hdcShadow
,
992 #ifdef XWIN_MULTIWINDOW
993 /* Redraw all windows */
994 if (pScreenInfo
->fMultiWindow
)
995 EnumThreadWindows(g_dwCurrentThreadID
, winRedrawAllProcShadowGDI
, 0);
1004 * Realize the currently installed colormap
1008 winRealizeInstalledPaletteShadowGDI (ScreenPtr pScreen
)
1010 winScreenPriv(pScreen
);
1011 winPrivCmapPtr pCmapPriv
= NULL
;
1014 winDebug ("winRealizeInstalledPaletteShadowGDI\n");
1017 /* Don't do anything if there is not a colormap */
1018 if (pScreenPriv
->pcmapInstalled
== NULL
)
1021 winDebug ("winRealizeInstalledPaletteShadowGDI - No colormap "
1027 pCmapPriv
= winGetCmapPriv (pScreenPriv
->pcmapInstalled
);
1029 /* Realize our palette for the screen */
1030 if (RealizePalette (pScreenPriv
->hdcScreen
) == GDI_ERROR
)
1032 ErrorF ("winRealizeInstalledPaletteShadowGDI - RealizePalette () "
1037 /* Set the DIB color table */
1038 if (SetDIBColorTable (pScreenPriv
->hdcShadow
,
1040 WIN_NUM_PALETTE_ENTRIES
,
1041 pCmapPriv
->rgbColors
) == 0)
1043 ErrorF ("winRealizeInstalledPaletteShadowGDI - SetDIBColorTable () "
1053 * Install the specified colormap
1057 winInstallColormapShadowGDI (ColormapPtr pColormap
)
1059 ScreenPtr pScreen
= pColormap
->pScreen
;
1060 winScreenPriv(pScreen
);
1061 winScreenInfo
*pScreenInfo
= pScreenPriv
->pScreenInfo
;
1062 winCmapPriv(pColormap
);
1065 * Tell Windows to install the new colormap
1067 if (SelectPalette (pScreenPriv
->hdcScreen
,
1068 pCmapPriv
->hPalette
,
1071 ErrorF ("winInstallColormapShadowGDI - SelectPalette () failed\n");
1075 /* Realize the palette */
1076 if (GDI_ERROR
== RealizePalette (pScreenPriv
->hdcScreen
))
1078 ErrorF ("winInstallColormapShadowGDI - RealizePalette () failed\n");
1082 /* Set the DIB color table */
1083 if (SetDIBColorTable (pScreenPriv
->hdcShadow
,
1085 WIN_NUM_PALETTE_ENTRIES
,
1086 pCmapPriv
->rgbColors
) == 0)
1088 ErrorF ("winInstallColormapShadowGDI - SetDIBColorTable () failed\n");
1092 /* Redraw the whole window, to take account for the new colors */
1093 BitBlt (pScreenPriv
->hdcScreen
,
1095 pScreenInfo
->dwWidth
, pScreenInfo
->dwHeight
,
1096 pScreenPriv
->hdcShadow
,
1100 /* Save a pointer to the newly installed colormap */
1101 pScreenPriv
->pcmapInstalled
= pColormap
;
1103 #ifdef XWIN_MULTIWINDOW
1104 /* Redraw all windows */
1105 if (pScreenInfo
->fMultiWindow
)
1106 EnumThreadWindows (g_dwCurrentThreadID
, winRedrawAllProcShadowGDI
, 0);
1114 * Store the specified colors in the specified colormap
1118 winStoreColorsShadowGDI (ColormapPtr pColormap
,
1122 ScreenPtr pScreen
= pColormap
->pScreen
;
1123 winScreenPriv(pScreen
);
1124 winCmapPriv(pColormap
);
1125 ColormapPtr curpmap
= pScreenPriv
->pcmapInstalled
;
1127 /* Put the X colormap entries into the Windows logical palette */
1128 if (SetPaletteEntries (pCmapPriv
->hPalette
,
1131 pCmapPriv
->peColors
+ pdefs
[0].pixel
) == 0)
1133 ErrorF ("winStoreColorsShadowGDI - SetPaletteEntries () failed\n");
1137 /* Don't install the Windows palette if the colormap is not installed */
1138 if (pColormap
!= curpmap
)
1143 /* Try to install the newly modified colormap */
1144 if (!winInstallColormapShadowGDI (pColormap
))
1146 ErrorF ("winInstallColormapShadowGDI - winInstallColormapShadowGDI "
1152 /* Tell Windows that the palette has changed */
1153 RealizePalette (pScreenPriv
->hdcScreen
);
1155 /* Set the DIB color table */
1156 if (SetDIBColorTable (pScreenPriv
->hdcShadow
,
1159 pCmapPriv
->rgbColors
+ pdefs
[0].pixel
) == 0)
1161 ErrorF ("winInstallColormapShadowGDI - SetDIBColorTable () failed\n");
1165 /* Save a pointer to the newly installed colormap */
1166 pScreenPriv
->pcmapInstalled
= pColormap
;
1174 * Colormap initialization procedure
1178 winCreateColormapShadowGDI (ColormapPtr pColormap
)
1180 LPLOGPALETTE lpPaletteNew
= NULL
;
1183 HPALETTE hpalNew
= NULL
;
1184 winCmapPriv(pColormap
);
1186 /* Get a pointer to the visual that the colormap belongs to */
1187 pVisual
= pColormap
->pVisual
;
1189 /* Get the maximum number of palette entries for this visual */
1190 dwEntriesMax
= pVisual
->ColormapEntries
;
1192 /* Allocate a Windows logical color palette with max entries */
1193 lpPaletteNew
= malloc (sizeof (LOGPALETTE
)
1194 + (dwEntriesMax
- 1) * sizeof (PALETTEENTRY
));
1195 if (lpPaletteNew
== NULL
)
1197 ErrorF ("winCreateColormapShadowGDI - Couldn't allocate palette "
1198 "with %d entries\n",
1199 (int) dwEntriesMax
);
1203 /* Zero out the colormap */
1204 ZeroMemory (lpPaletteNew
, sizeof (LOGPALETTE
)
1205 + (dwEntriesMax
- 1) * sizeof (PALETTEENTRY
));
1207 /* Set the logical palette structure */
1208 lpPaletteNew
->palVersion
= 0x0300;
1209 lpPaletteNew
->palNumEntries
= dwEntriesMax
;
1211 /* Tell Windows to create the palette */
1212 hpalNew
= CreatePalette (lpPaletteNew
);
1213 if (hpalNew
== NULL
)
1215 ErrorF ("winCreateColormapShadowGDI - CreatePalette () failed\n");
1216 free (lpPaletteNew
);
1220 /* Save the Windows logical palette handle in the X colormaps' privates */
1221 pCmapPriv
->hPalette
= hpalNew
;
1223 /* Free the palette initialization memory */
1224 free (lpPaletteNew
);
1231 * Colormap destruction procedure
1235 winDestroyColormapShadowGDI (ColormapPtr pColormap
)
1237 winScreenPriv(pColormap
->pScreen
);
1238 winCmapPriv(pColormap
);
1241 * Is colormap to be destroyed the default?
1243 * Non-default colormaps should have had winUninstallColormap
1244 * called on them before we get here. The default colormap
1245 * will not have had winUninstallColormap called on it. Thus,
1246 * we need to handle the default colormap in a special way.
1248 if (pColormap
->flags
& IsDefault
)
1251 winDebug ("winDestroyColormapShadowGDI - Destroying default "
1256 * FIXME: Walk the list of all screens, popping the default
1257 * palette out of each screen device context.
1260 /* Pop the palette out of the device context */
1261 SelectPalette (pScreenPriv
->hdcScreen
,
1262 GetStockObject (DEFAULT_PALETTE
),
1265 /* Clear our private installed colormap pointer */
1266 pScreenPriv
->pcmapInstalled
= NULL
;
1269 /* Try to delete the logical palette */
1270 if (DeleteObject (pCmapPriv
->hPalette
) == 0)
1272 ErrorF ("winDestroyColormap - DeleteObject () failed\n");
1276 /* Invalidate the colormap privates */
1277 pCmapPriv
->hPalette
= NULL
;
1284 * Set engine specific funtions
1288 winSetEngineFunctionsShadowGDI (ScreenPtr pScreen
)
1290 winScreenPriv(pScreen
);
1291 winScreenInfo
*pScreenInfo
= pScreenPriv
->pScreenInfo
;
1293 /* Set our pointers */
1294 pScreenPriv
->pwinAllocateFB
= winAllocateFBShadowGDI
;
1295 pScreenPriv
->pwinShadowUpdate
= winShadowUpdateGDI
;
1296 pScreenPriv
->pwinCloseScreen
= winCloseScreenShadowGDI
;
1297 pScreenPriv
->pwinInitVisuals
= winInitVisualsShadowGDI
;
1298 pScreenPriv
->pwinAdjustVideoMode
= winAdjustVideoModeShadowGDI
;
1299 if (pScreenInfo
->fFullScreen
)
1300 pScreenPriv
->pwinCreateBoundingWindow
= winCreateBoundingWindowFullScreen
;
1302 pScreenPriv
->pwinCreateBoundingWindow
= winCreateBoundingWindowWindowed
;
1303 pScreenPriv
->pwinFinishScreenInit
= winFinishScreenInitFB
;
1304 pScreenPriv
->pwinBltExposedRegions
= winBltExposedRegionsShadowGDI
;
1305 pScreenPriv
->pwinActivateApp
= winActivateAppShadowGDI
;
1306 pScreenPriv
->pwinRedrawScreen
= winRedrawScreenShadowGDI
;
1307 pScreenPriv
->pwinRealizeInstalledPalette
=
1308 winRealizeInstalledPaletteShadowGDI
;
1309 pScreenPriv
->pwinInstallColormap
= winInstallColormapShadowGDI
;
1310 pScreenPriv
->pwinStoreColors
= winStoreColorsShadowGDI
;
1311 pScreenPriv
->pwinCreateColormap
= winCreateColormapShadowGDI
;
1312 pScreenPriv
->pwinDestroyColormap
= winDestroyColormapShadowGDI
;
1313 pScreenPriv
->pwinHotKeyAltTab
= (winHotKeyAltTabProcPtr
) (void (*)(void))NoopDDA
;
1314 pScreenPriv
->pwinCreatePrimarySurface
1315 = (winCreatePrimarySurfaceProcPtr
) (void (*)(void))NoopDDA
;
1316 pScreenPriv
->pwinReleasePrimarySurface
1317 = (winReleasePrimarySurfaceProcPtr
) (void (*)(void))NoopDDA
;
1318 #ifdef XWIN_MULTIWINDOW
1319 pScreenPriv
->pwinFinishCreateWindowsWindow
=
1320 (winFinishCreateWindowsWindowProcPtr
) (void (*)(void))NoopDDA
;