static Bool winInitScreenShadowGDI(ScreenPtr pScreen) { winScreenPriv(pScreen); /* Get device contexts for the screen and shadow bitmap */ pScreenPriv->hdcScreen = GetDC(pScreenPriv->hwndScreen); pScreenPriv->hdcShadow = CreateCompatibleDC(pScreenPriv->hdcScreen); /* Allocate bitmap info header */ pScreenPriv->pbmih = malloc(sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD)); if (pScreenPriv->pbmih == NULL) { ErrorF("winInitScreenShadowGDI - malloc () failed\n"); return FALSE; } /* Query the screen format */ if (!winQueryScreenDIBFormat(pScreen, pScreenPriv->pbmih)) { ErrorF("winInitScreenShadowGDI - winQueryScreenDIBFormat failed\n"); return FALSE; } /* Determine our color masks */ if (!winQueryRGBBitsAndMasks(pScreen)) { ErrorF("winInitScreenShadowGDI - winQueryRGBBitsAndMasks failed\n"); return FALSE; } return winAllocateFBShadowGDI(pScreen); }
static Bool winAllocateFBShadowGDI (ScreenPtr pScreen) { winScreenPriv(pScreen); winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; BITMAPINFOHEADER *pbmih = NULL; DIBSECTION dibsection; Bool fReturn = TRUE; /* Get device contexts for the screen and shadow bitmap */ pScreenPriv->hdcScreen = GetDC (pScreenPriv->hwndScreen); pScreenPriv->hdcShadow = CreateCompatibleDC (pScreenPriv->hdcScreen); /* Allocate bitmap info header */ pbmih = (BITMAPINFOHEADER*) malloc (sizeof (BITMAPINFOHEADER) + 256 * sizeof (RGBQUAD)); if (pbmih == NULL) { ErrorF ("winAllocateFBShadowGDI - malloc () failed\n"); return FALSE; } /* Query the screen format */ fReturn = winQueryScreenDIBFormat (pScreen, pbmih); /* Describe shadow bitmap to be created */ pbmih->biWidth = pScreenInfo->dwWidth; pbmih->biHeight = -pScreenInfo->dwHeight; ErrorF ("winAllocateFBShadowGDI - Creating DIB with width: %d height: %d " "depth: %d\n", (int) pbmih->biWidth, (int) -pbmih->biHeight, pbmih->biBitCount); /* Create a DI shadow bitmap with a bit pointer */ pScreenPriv->hbmpShadow = CreateDIBSection (pScreenPriv->hdcScreen, (BITMAPINFO *) pbmih, DIB_RGB_COLORS, (VOID**) &pScreenInfo->pfb, NULL, 0); if (pScreenPriv->hbmpShadow == NULL || pScreenInfo->pfb == NULL) { winW32Error (2, "winAllocateFBShadowGDI - CreateDIBSection failed:"); return FALSE; } else { #if CYGDEBUG winDebug ("winAllocateFBShadowGDI - Shadow buffer allocated\n"); #endif } /* Get information about the bitmap that was allocated */ GetObject (pScreenPriv->hbmpShadow, sizeof (dibsection), &dibsection); #if CYGDEBUG || YES /* Print information about bitmap allocated */ winDebug ("winAllocateFBShadowGDI - Dibsection width: %d height: %d " "depth: %d size image: %d\n", (int) dibsection.dsBmih.biWidth, (int) dibsection.dsBmih.biHeight, dibsection.dsBmih.biBitCount, (int) dibsection.dsBmih.biSizeImage); #endif /* Select the shadow bitmap into the shadow DC */ SelectObject (pScreenPriv->hdcShadow, pScreenPriv->hbmpShadow); #if CYGDEBUG winDebug ("winAllocateFBShadowGDI - Attempting a shadow blit\n"); #endif /* Do a test blit from the shadow to the screen, I think */ fReturn = BitBlt (pScreenPriv->hdcScreen, 0, 0, pScreenInfo->dwWidth, pScreenInfo->dwHeight, pScreenPriv->hdcShadow, 0, 0, SRCCOPY); if (fReturn) { #if CYGDEBUG winDebug ("winAllocateFBShadowGDI - Shadow blit success\n"); #endif } else { winW32Error (2, "winAllocateFBShadowGDI - Shadow blit failure\n"); #if 0 return FALSE; #else /* ago: ignore this error. The blit fails with wine, but does not * cause any problems later. */ fReturn = TRUE; #endif } /* Look for height weirdness */ if (dibsection.dsBmih.biHeight < 0) { dibsection.dsBmih.biHeight = -dibsection.dsBmih.biHeight; } /* Set screeninfo stride */ pScreenInfo->dwStride = ((dibsection.dsBmih.biSizeImage / dibsection.dsBmih.biHeight) * 8) / pScreenInfo->dwBPP; #if CYGDEBUG || YES winDebug ("winAllocateFBShadowGDI - Created shadow stride: %d\n", (int) pScreenInfo->dwStride); #endif /* See if the shadow bitmap will be larger than the DIB size limit */ if (pScreenInfo->dwWidth * pScreenInfo->dwHeight * pScreenInfo->dwBPP >= WIN_DIB_MAXIMUM_SIZE) { ErrorF ("winAllocateFBShadowGDI - Requested DIB (bitmap) " "will be larger than %d MB. The surface may fail to be " "allocated on Windows 95, 98, or Me, due to a %d MB limit in " "DIB size. This limit does not apply to Windows NT/2000, and " "this message may be ignored on those platforms.\n", WIN_DIB_MAXIMUM_SIZE_MB, WIN_DIB_MAXIMUM_SIZE_MB); } /* Determine our color masks */ if (!winQueryRGBBitsAndMasks (pScreen)) { ErrorF ("winAllocateFBShadowGDI - winQueryRGBBitsAndMasks failed\n"); return FALSE; } #ifdef XWIN_MULTIWINDOW /* Redraw all windows */ if (pScreenInfo->fMultiWindow) EnumThreadWindows (g_dwCurrentThreadID, winRedrawAllProcShadowGDI, 0); #endif return fReturn; }