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>
37 * Local function prototypes
40 #ifdef XWIN_MULTIWINDOW
41 static wBOOL CALLBACK
winRedrawAllProcShadowGDI(HWND hwnd
, LPARAM lParam
);
43 static wBOOL CALLBACK
winRedrawDamagedWindowShadowGDI(HWND hwnd
, LPARAM lParam
);
47 winAllocateFBShadowGDI(ScreenPtr pScreen
);
50 winShadowUpdateGDI(ScreenPtr pScreen
, shadowBufPtr pBuf
);
53 winCloseScreenShadowGDI(ScreenPtr pScreen
);
56 winInitVisualsShadowGDI(ScreenPtr pScreen
);
59 winAdjustVideoModeShadowGDI(ScreenPtr pScreen
);
62 winBltExposedRegionsShadowGDI(ScreenPtr pScreen
);
65 winActivateAppShadowGDI(ScreenPtr pScreen
);
68 winRedrawScreenShadowGDI(ScreenPtr pScreen
);
71 winRealizeInstalledPaletteShadowGDI(ScreenPtr pScreen
);
74 winInstallColormapShadowGDI(ColormapPtr pColormap
);
77 winStoreColorsShadowGDI(ColormapPtr pmap
, int ndef
, xColorItem
* pdefs
);
80 winCreateColormapShadowGDI(ColormapPtr pColormap
);
83 winDestroyColormapShadowGDI(ColormapPtr pColormap
);
86 * Internal function to get the DIB format that is compatible with the screen
91 winQueryScreenDIBFormat(ScreenPtr pScreen
, BITMAPINFOHEADER
* pbmih
)
93 winScreenPriv(pScreen
);
100 /* Create a memory bitmap compatible with the screen */
101 hbmp
= CreateCompatibleBitmap(pScreenPriv
->hdcScreen
, 1, 1);
103 ErrorF("winQueryScreenDIBFormat - CreateCompatibleBitmap failed\n");
107 /* Initialize our bitmap info header */
108 ZeroMemory(pbmih
, sizeof(BITMAPINFOHEADER
) + 256 * sizeof(RGBQUAD
));
109 pbmih
->biSize
= sizeof(BITMAPINFOHEADER
);
111 /* Get the biBitCount */
112 if (!GetDIBits(pScreenPriv
->hdcScreen
,
113 hbmp
, 0, 1, NULL
, (BITMAPINFO
*) pbmih
, DIB_RGB_COLORS
)) {
114 ErrorF("winQueryScreenDIBFormat - First call to GetDIBits failed\n");
120 /* Get a pointer to bitfields */
121 pdw
= (DWORD
*) ((CARD8
*) pbmih
+ sizeof(BITMAPINFOHEADER
));
123 winDebug("winQueryScreenDIBFormat - First call masks: %08x %08x %08x\n",
124 pdw
[0], pdw
[1], pdw
[2]);
127 /* Get optimal color table, or the optimal bitfields */
128 if (!GetDIBits(pScreenPriv
->hdcScreen
,
129 hbmp
, 0, 1, NULL
, (BITMAPINFO
*) pbmih
, DIB_RGB_COLORS
)) {
130 ErrorF("winQueryScreenDIBFormat - Second call to GetDIBits "
143 * Internal function to determine the GDI bits per rgb and bit masks
148 winQueryRGBBitsAndMasks(ScreenPtr pScreen
)
150 winScreenPriv(pScreen
);
151 BITMAPINFOHEADER
*pbmih
= NULL
;
154 DWORD dwRedBits
, dwGreenBits
, dwBlueBits
;
156 /* Color masks for 8 bpp are standardized */
157 if (GetDeviceCaps(pScreenPriv
->hdcScreen
, RASTERCAPS
) & RC_PALETTE
) {
159 * RGB BPP for 8 bit palletes is always 8
160 * and the color masks are always 0.
162 pScreenPriv
->dwBitsPerRGB
= 8;
163 pScreenPriv
->dwRedMask
= 0x0L
;
164 pScreenPriv
->dwGreenMask
= 0x0L
;
165 pScreenPriv
->dwBlueMask
= 0x0L
;
169 /* Color masks for 24 bpp are standardized */
170 if (GetDeviceCaps(pScreenPriv
->hdcScreen
, PLANES
)
171 * GetDeviceCaps(pScreenPriv
->hdcScreen
, BITSPIXEL
) == 24) {
172 ErrorF("winQueryRGBBitsAndMasks - GetDeviceCaps (BITSPIXEL) "
173 "returned 24 for the screen. Using default 24bpp masks.\n");
175 /* 8 bits per primary color */
176 pScreenPriv
->dwBitsPerRGB
= 8;
178 /* Set screen privates masks */
179 pScreenPriv
->dwRedMask
= WIN_24BPP_MASK_RED
;
180 pScreenPriv
->dwGreenMask
= WIN_24BPP_MASK_GREEN
;
181 pScreenPriv
->dwBlueMask
= WIN_24BPP_MASK_BLUE
;
186 /* Allocate a bitmap header and color table */
187 pbmih
= (BITMAPINFOHEADER
*) malloc(sizeof(BITMAPINFOHEADER
)
188 + 256 * sizeof(RGBQUAD
));
190 ErrorF("winQueryRGBBitsAndMasks - malloc failed\n");
194 /* Get screen description */
195 if (winQueryScreenDIBFormat(pScreen
, pbmih
)) {
196 /* Get a pointer to bitfields */
197 pdw
= (DWORD
*) ((CARD8
*) pbmih
+ sizeof(BITMAPINFOHEADER
));
200 winDebug("%s - Masks: %08x %08x %08x\n", __FUNCTION__
,
201 pdw
[0], pdw
[1], pdw
[2]);
202 winDebug("%s - Bitmap: %dx%d %d bpp %d planes\n", __FUNCTION__
,
203 pbmih
->biWidth
, pbmih
->biHeight
, pbmih
->biBitCount
,
205 winDebug("%s - Compression: %d %s\n", __FUNCTION__
,
206 pbmih
->biCompression
,
207 (pbmih
->biCompression
==
208 BI_RGB
? "(BI_RGB)" : (pbmih
->biCompression
==
209 BI_RLE8
? "(BI_RLE8)" : (pbmih
->
223 /* Handle BI_RGB case, which is returned by Wine */
224 if (pbmih
->biCompression
== BI_RGB
) {
229 pScreenPriv
->dwBitsPerRGB
= 5;
231 /* Set screen privates masks */
232 pScreenPriv
->dwRedMask
= 0x7c00;
233 pScreenPriv
->dwGreenMask
= 0x03e0;
234 pScreenPriv
->dwBlueMask
= 0x001f;
237 /* Count the number of bits in each mask */
238 dwRedBits
= winCountBits(pdw
[0]);
239 dwGreenBits
= winCountBits(pdw
[1]);
240 dwBlueBits
= winCountBits(pdw
[2]);
242 /* Find maximum bits per red, green, blue */
243 if (dwRedBits
> dwGreenBits
&& dwRedBits
> dwBlueBits
)
244 pScreenPriv
->dwBitsPerRGB
= dwRedBits
;
245 else if (dwGreenBits
> dwRedBits
&& dwGreenBits
> dwBlueBits
)
246 pScreenPriv
->dwBitsPerRGB
= dwGreenBits
;
248 pScreenPriv
->dwBitsPerRGB
= dwBlueBits
;
250 /* Set screen privates masks */
251 pScreenPriv
->dwRedMask
= pdw
[0];
252 pScreenPriv
->dwGreenMask
= pdw
[1];
253 pScreenPriv
->dwBlueMask
= pdw
[2];
257 ErrorF("winQueryRGBBitsAndMasks - winQueryScreenDIBFormat failed\n");
267 #ifdef XWIN_MULTIWINDOW
272 static wBOOL CALLBACK
273 winRedrawAllProcShadowGDI(HWND hwnd
, LPARAM lParam
)
275 if (hwnd
== (HWND
) lParam
)
277 InvalidateRect(hwnd
, NULL
, FALSE
);
282 static wBOOL CALLBACK
283 winRedrawDamagedWindowShadowGDI(HWND hwnd
, LPARAM lParam
)
285 BoxPtr pDamage
= (BoxPtr
) lParam
;
286 RECT rcClient
, rcDamage
, rcRedraw
;
287 POINT topLeft
, bottomRight
;
290 return TRUE
; /* Don't care minimized windows */
292 /* Convert the damaged area from Screen coords to Client coords */
293 topLeft
.x
= pDamage
->x1
;
294 topLeft
.y
= pDamage
->y1
;
295 bottomRight
.x
= pDamage
->x2
;
296 bottomRight
.y
= pDamage
->y2
;
297 topLeft
.x
+= GetSystemMetrics(SM_XVIRTUALSCREEN
);
298 bottomRight
.x
+= GetSystemMetrics(SM_XVIRTUALSCREEN
);
299 topLeft
.y
+= GetSystemMetrics(SM_YVIRTUALSCREEN
);
300 bottomRight
.y
+= GetSystemMetrics(SM_YVIRTUALSCREEN
);
301 ScreenToClient(hwnd
, &topLeft
);
302 ScreenToClient(hwnd
, &bottomRight
);
303 SetRect(&rcDamage
, topLeft
.x
, topLeft
.y
, bottomRight
.x
, bottomRight
.y
);
305 GetClientRect(hwnd
, &rcClient
);
307 if (IntersectRect(&rcRedraw
, &rcClient
, &rcDamage
)) {
308 InvalidateRect(hwnd
, &rcRedraw
, FALSE
);
316 * Allocate a DIB for the shadow framebuffer GDI server
320 winAllocateFBShadowGDI(ScreenPtr pScreen
)
322 winScreenPriv(pScreen
);
323 winScreenInfo
*pScreenInfo
= pScreenPriv
->pScreenInfo
;
324 DIBSECTION dibsection
;
327 /* Describe shadow bitmap to be created */
328 pScreenPriv
->pbmih
->biWidth
= pScreenInfo
->dwWidth
;
329 pScreenPriv
->pbmih
->biHeight
= -pScreenInfo
->dwHeight
;
331 ErrorF("winAllocateFBShadowGDI - Creating DIB with width: %d height: %d "
333 (int) pScreenPriv
->pbmih
->biWidth
,
334 (int) -pScreenPriv
->pbmih
->biHeight
, pScreenPriv
->pbmih
->biBitCount
);
336 /* Create a DI shadow bitmap with a bit pointer */
337 pScreenPriv
->hbmpShadow
= CreateDIBSection(pScreenPriv
->hdcScreen
,
338 (BITMAPINFO
*) pScreenPriv
->
339 pbmih
, DIB_RGB_COLORS
,
340 (VOID
**) &pScreenInfo
->pfb
,
342 if (pScreenPriv
->hbmpShadow
== NULL
|| pScreenInfo
->pfb
== NULL
) {
343 winW32Error(2, "winAllocateFBShadowGDI - CreateDIBSection failed:");
348 winDebug("winAllocateFBShadowGDI - Shadow buffer allocated\n");
352 /* Get information about the bitmap that was allocated */
353 GetObject(pScreenPriv
->hbmpShadow
, sizeof(dibsection
), &dibsection
);
356 /* Print information about bitmap allocated */
357 winDebug("winAllocateFBShadowGDI - Dibsection width: %d height: %d "
358 "depth: %d size image: %d\n",
359 (int) dibsection
.dsBmih
.biWidth
, (int) dibsection
.dsBmih
.biHeight
,
360 dibsection
.dsBmih
.biBitCount
, (int) dibsection
.dsBmih
.biSizeImage
);
363 /* Select the shadow bitmap into the shadow DC */
364 SelectObject(pScreenPriv
->hdcShadow
, pScreenPriv
->hbmpShadow
);
367 winDebug("winAllocateFBShadowGDI - Attempting a shadow blit\n");
370 /* Do a test blit from the shadow to the screen, I think */
371 fReturn
= BitBlt(pScreenPriv
->hdcScreen
,
373 pScreenInfo
->dwWidth
, pScreenInfo
->dwHeight
,
374 pScreenPriv
->hdcShadow
, 0, 0, SRCCOPY
);
377 winDebug("winAllocateFBShadowGDI - Shadow blit success\n");
381 winW32Error(2, "winAllocateFBShadowGDI - Shadow blit failure\n");
385 /* ago: ignore this error. The blit fails with wine, but does not
386 * cause any problems later. */
392 /* Look for height weirdness */
393 if (dibsection
.dsBmih
.biHeight
< 0) {
394 dibsection
.dsBmih
.biHeight
= -dibsection
.dsBmih
.biHeight
;
397 /* Set screeninfo stride */
398 pScreenInfo
->dwStride
= ((dibsection
.dsBmih
.biSizeImage
399 / dibsection
.dsBmih
.biHeight
)
400 * 8) / pScreenInfo
->dwBPP
;
403 winDebug("winAllocateFBShadowGDI - Created shadow stride: %d\n",
404 (int) pScreenInfo
->dwStride
);
407 #ifdef XWIN_MULTIWINDOW
408 /* Redraw all windows */
409 if (pScreenInfo
->fMultiWindow
)
410 EnumThreadWindows(g_dwCurrentThreadID
, winRedrawAllProcShadowGDI
, 0);
417 winFreeFBShadowGDI(ScreenPtr pScreen
)
419 winScreenPriv(pScreen
);
420 winScreenInfo
*pScreenInfo
= pScreenPriv
->pScreenInfo
;
422 /* Free the shadow bitmap */
423 DeleteObject(pScreenPriv
->hbmpShadow
);
425 /* Invalidate the ScreenInfo's fb pointer */
426 pScreenInfo
->pfb
= NULL
;
430 * Blit the damaged regions of the shadow fb to the screen
434 winShadowUpdateGDI(ScreenPtr pScreen
, shadowBufPtr pBuf
)
436 winScreenPriv(pScreen
);
437 winScreenInfo
*pScreenInfo
= pScreenPriv
->pScreenInfo
;
438 RegionPtr damage
= shadowDamage(pBuf
);
439 DWORD dwBox
= RegionNumRects(damage
);
440 BoxPtr pBox
= RegionRects(damage
);
442 HRGN hrgnCombined
= NULL
;
444 #ifdef XWIN_UPDATESTATS
445 static DWORD s_dwNonUnitRegions
= 0;
446 static DWORD s_dwTotalUpdates
= 0;
447 static DWORD s_dwTotalBoxes
= 0;
449 BoxPtr pBoxExtents
= RegionExtents(damage
);
452 * Return immediately if the app is not active
453 * and we are fullscreen, or if we have a bad display depth
455 if ((!pScreenPriv
->fActive
&& pScreenInfo
->fFullScreen
)
456 || pScreenPriv
->fBadDepth
)
459 #ifdef XWIN_UPDATESTATS
461 s_dwTotalBoxes
+= dwBox
;
464 ++s_dwNonUnitRegions
;
465 ErrorF("winShadowUpdatGDI - dwBox: %d\n", dwBox
);
468 if ((s_dwTotalUpdates
% 100) == 0)
469 ErrorF("winShadowUpdateGDI - %d%% non-unity regions, avg boxes: %d "
471 (s_dwNonUnitRegions
* 100) / s_dwTotalUpdates
,
472 s_dwTotalBoxes
/ s_dwTotalUpdates
,
473 s_dwNonUnitRegions
, s_dwTotalUpdates
);
474 #endif /* XWIN_UPDATESTATS */
477 * Handle small regions with multiple blits,
478 * handle large regions by creating a clipping region and
479 * doing a single blit constrained to that clipping region.
481 if (!pScreenInfo
->fMultiWindow
&&
482 (pScreenInfo
->dwClipUpdatesNBoxes
== 0 ||
483 dwBox
< pScreenInfo
->dwClipUpdatesNBoxes
)) {
484 /* Loop through all boxes in the damaged region */
487 * Calculate x offset, y offset, width, and height for
492 w
= pBox
->x2
- pBox
->x1
;
493 h
= pBox
->y2
- pBox
->y1
;
495 BitBlt(pScreenPriv
->hdcScreen
,
496 x
, y
, w
, h
, pScreenPriv
->hdcShadow
, x
, y
, SRCCOPY
);
498 /* Get a pointer to the next box */
502 else if (!pScreenInfo
->fMultiWindow
) {
504 /* Compute a GDI region from the damaged region */
506 CreateRectRgn(pBoxExtents
->x1
, pBoxExtents
->y1
, pBoxExtents
->x2
,
509 /* Install the GDI region as a clipping region */
510 SelectClipRgn(pScreenPriv
->hdcScreen
, hrgnCombined
);
511 DeleteObject(hrgnCombined
);
515 * Blit the shadow buffer to the screen,
516 * constrained to the clipping region.
518 BitBlt(pScreenPriv
->hdcScreen
,
519 pBoxExtents
->x1
, pBoxExtents
->y1
,
520 pBoxExtents
->x2
- pBoxExtents
->x1
,
521 pBoxExtents
->y2
- pBoxExtents
->y1
,
522 pScreenPriv
->hdcShadow
,
523 pBoxExtents
->x1
, pBoxExtents
->y1
, SRCCOPY
);
525 /* Reset the clip region */
526 SelectClipRgn(pScreenPriv
->hdcScreen
, NULL
);
529 #ifdef XWIN_MULTIWINDOW
530 /* Redraw all multiwindow windows */
531 if (pScreenInfo
->fMultiWindow
)
532 EnumThreadWindows(g_dwCurrentThreadID
,
533 winRedrawDamagedWindowShadowGDI
,
534 (LPARAM
) pBoxExtents
);
539 winInitScreenShadowGDI(ScreenPtr pScreen
)
541 winScreenPriv(pScreen
);
543 /* Get device contexts for the screen and shadow bitmap */
544 pScreenPriv
->hdcScreen
= GetDC(pScreenPriv
->hwndScreen
);
545 pScreenPriv
->hdcShadow
= CreateCompatibleDC(pScreenPriv
->hdcScreen
);
547 /* Allocate bitmap info header */
548 pScreenPriv
->pbmih
= (BITMAPINFOHEADER
*) malloc(sizeof(BITMAPINFOHEADER
)
549 + 256 * sizeof(RGBQUAD
));
550 if (pScreenPriv
->pbmih
== NULL
) {
551 ErrorF("winInitScreenShadowGDI - malloc () failed\n");
555 /* Query the screen format */
556 if (!winQueryScreenDIBFormat(pScreen
, pScreenPriv
->pbmih
)) {
557 ErrorF("winInitScreenShadowGDI - winQueryScreenDIBFormat failed\n");
561 /* Determine our color masks */
562 if (!winQueryRGBBitsAndMasks(pScreen
)) {
563 ErrorF("winInitScreenShadowGDI - winQueryRGBBitsAndMasks failed\n");
567 return winAllocateFBShadowGDI(pScreen
);
570 /* See Porting Layer Definition - p. 33 */
572 * We wrap whatever CloseScreen procedure was specified by fb;
573 * a pointer to said procedure is stored in our privates.
577 winCloseScreenShadowGDI(ScreenPtr pScreen
)
579 winScreenPriv(pScreen
);
580 winScreenInfo
*pScreenInfo
= pScreenPriv
->pScreenInfo
;
584 winDebug("winCloseScreenShadowGDI - Freeing screen resources\n");
587 /* Flag that the screen is closed */
588 pScreenPriv
->fClosed
= TRUE
;
589 pScreenPriv
->fActive
= FALSE
;
591 /* Call the wrapped CloseScreen procedure */
592 WIN_UNWRAP(CloseScreen
);
593 if (pScreen
->CloseScreen
)
594 fReturn
= (*pScreen
->CloseScreen
) (pScreen
);
596 /* Delete the window property */
597 RemoveProp(pScreenPriv
->hwndScreen
, WIN_SCR_PROP
);
599 /* Free the shadow DC; which allows the bitmap to be freed */
600 DeleteDC(pScreenPriv
->hdcShadow
);
602 winFreeFBShadowGDI(pScreen
);
604 /* Free the screen DC */
605 ReleaseDC(pScreenPriv
->hwndScreen
, pScreenPriv
->hdcScreen
);
607 /* Delete tray icon, if we have one */
608 if (!pScreenInfo
->fNoTrayIcon
)
609 winDeleteNotifyIcon(pScreenPriv
);
611 /* Free the exit confirmation dialog box, if it exists */
612 if (g_hDlgExit
!= NULL
) {
613 DestroyWindow(g_hDlgExit
);
617 /* Kill our window */
618 if (pScreenPriv
->hwndScreen
) {
619 DestroyWindow(pScreenPriv
->hwndScreen
);
620 pScreenPriv
->hwndScreen
= NULL
;
623 #if defined(XWIN_CLIPBOARD) || defined(XWIN_MULTIWINDOW)
624 /* Destroy the thread startup mutex */
625 pthread_mutex_destroy(&pScreenPriv
->pmServerStarted
);
628 /* Invalidate our screeninfo's pointer to the screen */
629 pScreenInfo
->pScreen
= NULL
;
631 /* Free the screen privates for this screen */
632 free((pointer
) pScreenPriv
);
638 * Tell mi what sort of visuals we need.
640 * Generally we only need one visual, as our screen can only
641 * handle one format at a time, I believe. You may want
642 * to verify that last sentence.
646 winInitVisualsShadowGDI(ScreenPtr pScreen
)
648 winScreenPriv(pScreen
);
649 winScreenInfo
*pScreenInfo
= pScreenPriv
->pScreenInfo
;
651 /* Display debugging information */
652 ErrorF("winInitVisualsShadowGDI - Masks %08x %08x %08x BPRGB %d d %d "
654 (unsigned int) pScreenPriv
->dwRedMask
,
655 (unsigned int) pScreenPriv
->dwGreenMask
,
656 (unsigned int) pScreenPriv
->dwBlueMask
,
657 (int) pScreenPriv
->dwBitsPerRGB
,
658 (int) pScreenInfo
->dwDepth
, (int) pScreenInfo
->dwBPP
);
660 /* Create a single visual according to the Windows screen depth */
661 switch (pScreenInfo
->dwDepth
) {
665 /* Setup the real visual */
666 if (!miSetVisualTypesAndMasks(pScreenInfo
->dwDepth
,
668 pScreenPriv
->dwBitsPerRGB
,
670 pScreenPriv
->dwRedMask
,
671 pScreenPriv
->dwGreenMask
,
672 pScreenPriv
->dwBlueMask
)) {
673 ErrorF("winInitVisualsShadowGDI - miSetVisualTypesAndMasks "
678 #ifdef XWIN_EMULATEPSEUDO
679 if (!pScreenInfo
->fEmulatePseudo
)
682 /* Setup a pseudocolor visual */
683 if (!miSetVisualTypesAndMasks(8, PseudoColorMask
, 8, -1, 0, 0, 0)) {
684 ErrorF("winInitVisualsShadowGDI - miSetVisualTypesAndMasks "
685 "failed for PseudoColor\n");
692 if (!miSetVisualTypesAndMasks(pScreenInfo
->dwDepth
,
694 pScreenPriv
->dwBitsPerRGB
,
696 pScreenPriv
->dwRedMask
,
697 pScreenPriv
->dwGreenMask
,
698 pScreenPriv
->dwBlueMask
)) {
699 ErrorF("winInitVisualsShadowGDI - miSetVisualTypesAndMasks "
706 ErrorF("winInitVisualsShadowGDI - Unknown screen depth\n");
711 winDebug("winInitVisualsShadowGDI - Returning\n");
718 * Adjust the proposed video mode
722 winAdjustVideoModeShadowGDI(ScreenPtr pScreen
)
724 winScreenPriv(pScreen
);
725 winScreenInfo
*pScreenInfo
= pScreenPriv
->pScreenInfo
;
731 /* We're in serious trouble if we can't get a DC */
733 ErrorF("winAdjustVideoModeShadowGDI - GetDC () failed\n");
737 /* Query GDI for current display depth */
738 dwBPP
= GetDeviceCaps(hdc
, BITSPIXEL
);
740 /* GDI cannot change the screen depth, so always use GDI's depth */
741 pScreenInfo
->dwBPP
= dwBPP
;
744 ReleaseDC(NULL
, hdc
);
751 * Blt exposed regions to the screen
755 winBltExposedRegionsShadowGDI(ScreenPtr pScreen
)
757 winScreenPriv(pScreen
);
758 winScreenInfo
*pScreenInfo
= pScreenPriv
->pScreenInfo
;
759 winPrivCmapPtr pCmapPriv
= NULL
;
763 /* BeginPaint gives us an hdc that clips to the invalidated region */
764 hdcUpdate
= BeginPaint(pScreenPriv
->hwndScreen
, &ps
);
766 /* Realize the palette, if we have one */
767 if (pScreenPriv
->pcmapInstalled
!= NULL
) {
768 pCmapPriv
= winGetCmapPriv(pScreenPriv
->pcmapInstalled
);
770 SelectPalette(hdcUpdate
, pCmapPriv
->hPalette
, FALSE
);
771 RealizePalette(hdcUpdate
);
774 /* Our BitBlt will be clipped to the invalidated region */
777 pScreenInfo
->dwWidth
, pScreenInfo
->dwHeight
,
778 pScreenPriv
->hdcShadow
, 0, 0, SRCCOPY
);
780 /* EndPaint frees the DC */
781 EndPaint(pScreenPriv
->hwndScreen
, &ps
);
783 #ifdef XWIN_MULTIWINDOW
784 /* Redraw all windows */
785 if (pScreenInfo
->fMultiWindow
)
786 EnumThreadWindows(g_dwCurrentThreadID
, winRedrawAllProcShadowGDI
,
787 (LPARAM
) pScreenPriv
->hwndScreen
);
794 * Do any engine-specific appliation-activation processing
798 winActivateAppShadowGDI(ScreenPtr pScreen
)
800 winScreenPriv(pScreen
);
801 winScreenInfo
*pScreenInfo
= pScreenPriv
->pScreenInfo
;
804 * 2004/04/12 - Harold - We perform the restoring or minimizing
805 * manually for ShadowGDI in fullscreen modes so that this engine
806 * will perform just like ShadowDD and ShadowDDNL in fullscreen mode;
807 * if we do not do this then our fullscreen window will appear in the
808 * z-order when it is deactivated and it can be uncovered by resizing
809 * or minimizing another window that is on top of it, which is not how
810 * the DirectDraw engines work. Therefore we keep this code here to
811 * make sure that all engines work the same in fullscreen mode.
818 if (pScreenPriv
->fActive
&& pScreenInfo
->fFullScreen
) {
820 * Activating, attempt to bring our window
821 * to the top of the display
823 ShowWindow(pScreenPriv
->hwndScreen
, SW_RESTORE
);
825 else if (!pScreenPriv
->fActive
&& pScreenInfo
->fFullScreen
) {
827 * Deactivating, stuff our window onto the
830 ShowWindow(pScreenPriv
->hwndScreen
, SW_MINIMIZE
);
837 * Reblit the shadow framebuffer to the screen.
841 winRedrawScreenShadowGDI(ScreenPtr pScreen
)
843 winScreenPriv(pScreen
);
844 winScreenInfo
*pScreenInfo
= pScreenPriv
->pScreenInfo
;
846 /* Redraw the whole window, to take account for the new colors */
847 BitBlt(pScreenPriv
->hdcScreen
,
849 pScreenInfo
->dwWidth
, pScreenInfo
->dwHeight
,
850 pScreenPriv
->hdcShadow
, 0, 0, SRCCOPY
);
852 #ifdef XWIN_MULTIWINDOW
853 /* Redraw all windows */
854 if (pScreenInfo
->fMultiWindow
)
855 EnumThreadWindows(g_dwCurrentThreadID
, winRedrawAllProcShadowGDI
, 0);
862 * Realize the currently installed colormap
866 winRealizeInstalledPaletteShadowGDI(ScreenPtr pScreen
)
868 winScreenPriv(pScreen
);
869 winPrivCmapPtr pCmapPriv
= NULL
;
872 winDebug("winRealizeInstalledPaletteShadowGDI\n");
875 /* Don't do anything if there is not a colormap */
876 if (pScreenPriv
->pcmapInstalled
== NULL
) {
878 winDebug("winRealizeInstalledPaletteShadowGDI - No colormap "
884 pCmapPriv
= winGetCmapPriv(pScreenPriv
->pcmapInstalled
);
886 /* Realize our palette for the screen */
887 if (RealizePalette(pScreenPriv
->hdcScreen
) == GDI_ERROR
) {
888 ErrorF("winRealizeInstalledPaletteShadowGDI - RealizePalette () "
893 /* Set the DIB color table */
894 if (SetDIBColorTable(pScreenPriv
->hdcShadow
,
896 WIN_NUM_PALETTE_ENTRIES
, pCmapPriv
->rgbColors
) == 0) {
897 ErrorF("winRealizeInstalledPaletteShadowGDI - SetDIBColorTable () "
906 * Install the specified colormap
910 winInstallColormapShadowGDI(ColormapPtr pColormap
)
912 ScreenPtr pScreen
= pColormap
->pScreen
;
914 winScreenPriv(pScreen
);
915 winScreenInfo
*pScreenInfo
= pScreenPriv
->pScreenInfo
;
917 winCmapPriv(pColormap
);
920 * Tell Windows to install the new colormap
922 if (SelectPalette(pScreenPriv
->hdcScreen
,
923 pCmapPriv
->hPalette
, FALSE
) == NULL
) {
924 ErrorF("winInstallColormapShadowGDI - SelectPalette () failed\n");
928 /* Realize the palette */
929 if (GDI_ERROR
== RealizePalette(pScreenPriv
->hdcScreen
)) {
930 ErrorF("winInstallColormapShadowGDI - RealizePalette () failed\n");
934 /* Set the DIB color table */
935 if (SetDIBColorTable(pScreenPriv
->hdcShadow
,
937 WIN_NUM_PALETTE_ENTRIES
, pCmapPriv
->rgbColors
) == 0) {
938 ErrorF("winInstallColormapShadowGDI - SetDIBColorTable () failed\n");
942 /* Redraw the whole window, to take account for the new colors */
943 BitBlt(pScreenPriv
->hdcScreen
,
945 pScreenInfo
->dwWidth
, pScreenInfo
->dwHeight
,
946 pScreenPriv
->hdcShadow
, 0, 0, SRCCOPY
);
948 /* Save a pointer to the newly installed colormap */
949 pScreenPriv
->pcmapInstalled
= pColormap
;
951 #ifdef XWIN_MULTIWINDOW
952 /* Redraw all windows */
953 if (pScreenInfo
->fMultiWindow
)
954 EnumThreadWindows(g_dwCurrentThreadID
, winRedrawAllProcShadowGDI
, 0);
961 * Store the specified colors in the specified colormap
965 winStoreColorsShadowGDI(ColormapPtr pColormap
, int ndef
, xColorItem
* pdefs
)
967 ScreenPtr pScreen
= pColormap
->pScreen
;
969 winScreenPriv(pScreen
);
970 winCmapPriv(pColormap
);
971 ColormapPtr curpmap
= pScreenPriv
->pcmapInstalled
;
973 /* Put the X colormap entries into the Windows logical palette */
974 if (SetPaletteEntries(pCmapPriv
->hPalette
,
976 ndef
, pCmapPriv
->peColors
+ pdefs
[0].pixel
) == 0) {
977 ErrorF("winStoreColorsShadowGDI - SetPaletteEntries () failed\n");
981 /* Don't install the Windows palette if the colormap is not installed */
982 if (pColormap
!= curpmap
) {
986 /* Try to install the newly modified colormap */
987 if (!winInstallColormapShadowGDI(pColormap
)) {
988 ErrorF("winInstallColormapShadowGDI - winInstallColormapShadowGDI "
994 /* Tell Windows that the palette has changed */
995 RealizePalette(pScreenPriv
->hdcScreen
);
997 /* Set the DIB color table */
998 if (SetDIBColorTable(pScreenPriv
->hdcShadow
,
1000 ndef
, pCmapPriv
->rgbColors
+ pdefs
[0].pixel
) == 0) {
1001 ErrorF("winInstallColormapShadowGDI - SetDIBColorTable () failed\n");
1005 /* Save a pointer to the newly installed colormap */
1006 pScreenPriv
->pcmapInstalled
= pColormap
;
1013 * Colormap initialization procedure
1017 winCreateColormapShadowGDI(ColormapPtr pColormap
)
1019 LPLOGPALETTE lpPaletteNew
= NULL
;
1022 HPALETTE hpalNew
= NULL
;
1024 winCmapPriv(pColormap
);
1026 /* Get a pointer to the visual that the colormap belongs to */
1027 pVisual
= pColormap
->pVisual
;
1029 /* Get the maximum number of palette entries for this visual */
1030 dwEntriesMax
= pVisual
->ColormapEntries
;
1032 /* Allocate a Windows logical color palette with max entries */
1033 lpPaletteNew
= malloc(sizeof(LOGPALETTE
)
1034 + (dwEntriesMax
- 1) * sizeof(PALETTEENTRY
));
1035 if (lpPaletteNew
== NULL
) {
1036 ErrorF("winCreateColormapShadowGDI - Couldn't allocate palette "
1037 "with %d entries\n", (int) dwEntriesMax
);
1041 /* Zero out the colormap */
1042 ZeroMemory(lpPaletteNew
, sizeof(LOGPALETTE
)
1043 + (dwEntriesMax
- 1) * sizeof(PALETTEENTRY
));
1045 /* Set the logical palette structure */
1046 lpPaletteNew
->palVersion
= 0x0300;
1047 lpPaletteNew
->palNumEntries
= dwEntriesMax
;
1049 /* Tell Windows to create the palette */
1050 hpalNew
= CreatePalette(lpPaletteNew
);
1051 if (hpalNew
== NULL
) {
1052 ErrorF("winCreateColormapShadowGDI - CreatePalette () failed\n");
1057 /* Save the Windows logical palette handle in the X colormaps' privates */
1058 pCmapPriv
->hPalette
= hpalNew
;
1060 /* Free the palette initialization memory */
1067 * Colormap destruction procedure
1071 winDestroyColormapShadowGDI(ColormapPtr pColormap
)
1073 winScreenPriv(pColormap
->pScreen
);
1074 winCmapPriv(pColormap
);
1077 * Is colormap to be destroyed the default?
1079 * Non-default colormaps should have had winUninstallColormap
1080 * called on them before we get here. The default colormap
1081 * will not have had winUninstallColormap called on it. Thus,
1082 * we need to handle the default colormap in a special way.
1084 if (pColormap
->flags
& IsDefault
) {
1086 winDebug("winDestroyColormapShadowGDI - Destroying default "
1091 * FIXME: Walk the list of all screens, popping the default
1092 * palette out of each screen device context.
1095 /* Pop the palette out of the device context */
1096 SelectPalette(pScreenPriv
->hdcScreen
,
1097 GetStockObject(DEFAULT_PALETTE
), FALSE
);
1099 /* Clear our private installed colormap pointer */
1100 pScreenPriv
->pcmapInstalled
= NULL
;
1103 /* Try to delete the logical palette */
1104 if (DeleteObject(pCmapPriv
->hPalette
) == 0) {
1105 ErrorF("winDestroyColormap - DeleteObject () failed\n");
1109 /* Invalidate the colormap privates */
1110 pCmapPriv
->hPalette
= NULL
;
1116 * Set engine specific funtions
1120 winSetEngineFunctionsShadowGDI(ScreenPtr pScreen
)
1122 winScreenPriv(pScreen
);
1123 winScreenInfo
*pScreenInfo
= pScreenPriv
->pScreenInfo
;
1125 /* Set our pointers */
1126 pScreenPriv
->pwinAllocateFB
= winAllocateFBShadowGDI
;
1127 pScreenPriv
->pwinFreeFB
= winFreeFBShadowGDI
;
1128 pScreenPriv
->pwinShadowUpdate
= winShadowUpdateGDI
;
1129 pScreenPriv
->pwinInitScreen
= winInitScreenShadowGDI
;
1130 pScreenPriv
->pwinCloseScreen
= winCloseScreenShadowGDI
;
1131 pScreenPriv
->pwinInitVisuals
= winInitVisualsShadowGDI
;
1132 pScreenPriv
->pwinAdjustVideoMode
= winAdjustVideoModeShadowGDI
;
1133 if (pScreenInfo
->fFullScreen
)
1134 pScreenPriv
->pwinCreateBoundingWindow
=
1135 winCreateBoundingWindowFullScreen
;
1137 pScreenPriv
->pwinCreateBoundingWindow
= winCreateBoundingWindowWindowed
;
1138 pScreenPriv
->pwinFinishScreenInit
= winFinishScreenInitFB
;
1139 pScreenPriv
->pwinBltExposedRegions
= winBltExposedRegionsShadowGDI
;
1140 pScreenPriv
->pwinActivateApp
= winActivateAppShadowGDI
;
1141 pScreenPriv
->pwinRedrawScreen
= winRedrawScreenShadowGDI
;
1142 pScreenPriv
->pwinRealizeInstalledPalette
=
1143 winRealizeInstalledPaletteShadowGDI
;
1144 pScreenPriv
->pwinInstallColormap
= winInstallColormapShadowGDI
;
1145 pScreenPriv
->pwinStoreColors
= winStoreColorsShadowGDI
;
1146 pScreenPriv
->pwinCreateColormap
= winCreateColormapShadowGDI
;
1147 pScreenPriv
->pwinDestroyColormap
= winDestroyColormapShadowGDI
;
1148 pScreenPriv
->pwinHotKeyAltTab
=
1149 (winHotKeyAltTabProcPtr
) (void (*)(void)) NoopDDA
;
1150 pScreenPriv
->pwinCreatePrimarySurface
=
1151 (winCreatePrimarySurfaceProcPtr
) (void (*)(void)) NoopDDA
;
1152 pScreenPriv
->pwinReleasePrimarySurface
=
1153 (winReleasePrimarySurfaceProcPtr
) (void (*)(void)) NoopDDA
;
1154 #ifdef XWIN_MULTIWINDOW
1155 pScreenPriv
->pwinFinishCreateWindowsWindow
=
1156 (winFinishCreateWindowsWindowProcPtr
) (void (*)(void)) NoopDDA
;