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; }
static Bool winQueryRGBBitsAndMasks (ScreenPtr pScreen) { winScreenPriv(pScreen); BITMAPINFOHEADER *pbmih = NULL; Bool fReturn = TRUE; LPDWORD pdw = NULL; DWORD dwRedBits, dwGreenBits, dwBlueBits; /* Color masks for 8 bpp are standardized */ if (GetDeviceCaps (pScreenPriv->hdcScreen, RASTERCAPS) & RC_PALETTE) { /* * RGB BPP for 8 bit palletes is always 8 * and the color masks are always 0. */ pScreenPriv->dwBitsPerRGB = 8; pScreenPriv->dwRedMask = 0x0L; pScreenPriv->dwGreenMask = 0x0L; pScreenPriv->dwBlueMask = 0x0L; return TRUE; } /* Color masks for 24 bpp are standardized */ if (GetDeviceCaps (pScreenPriv->hdcScreen, PLANES) * GetDeviceCaps (pScreenPriv->hdcScreen, BITSPIXEL) == 24) { ErrorF ("winQueryRGBBitsAndMasks - GetDeviceCaps (BITSPIXEL) " "returned 24 for the screen. Using default 24bpp masks.\n"); /* 8 bits per primary color */ pScreenPriv->dwBitsPerRGB = 8; /* Set screen privates masks */ pScreenPriv->dwRedMask = WIN_24BPP_MASK_RED; pScreenPriv->dwGreenMask = WIN_24BPP_MASK_GREEN; pScreenPriv->dwBlueMask = WIN_24BPP_MASK_BLUE; return TRUE; } /* Allocate a bitmap header and color table */ pbmih = (BITMAPINFOHEADER*) malloc (sizeof (BITMAPINFOHEADER) + 256 * sizeof (RGBQUAD)); if (pbmih == NULL) { ErrorF ("winQueryRGBBitsAndMasks - malloc failed\n"); return FALSE; } /* Get screen description */ if (winQueryScreenDIBFormat (pScreen, pbmih)) { /* Get a pointer to bitfields */ pdw = (DWORD*) ((CARD8*)pbmih + sizeof (BITMAPINFOHEADER)); #if CYGDEBUG winDebug ("%s - Masks: %08x %08x %08x\n", __FUNCTION__, pdw[0], pdw[1], pdw[2]); winDebug ("%s - Bitmap: %dx%d %d bpp %d planes\n", __FUNCTION__, pbmih->biWidth, pbmih->biHeight, pbmih->biBitCount, pbmih->biPlanes); winDebug ("%s - Compression: %d %s\n", __FUNCTION__, pbmih->biCompression, (pbmih->biCompression == BI_RGB?"(BI_RGB)": (pbmih->biCompression == BI_RLE8?"(BI_RLE8)": (pbmih->biCompression == BI_RLE4?"(BI_RLE4)": (pbmih->biCompression == BI_BITFIELDS?"(BI_BITFIELDS)":"" ))))); #endif /* Handle BI_RGB case, which is returned by Wine */ if (pbmih->biCompression == BI_RGB) { dwRedBits = 5; dwGreenBits = 5; dwBlueBits = 5; pScreenPriv->dwBitsPerRGB = 5; /* Set screen privates masks */ pScreenPriv->dwRedMask = 0x7c00; pScreenPriv->dwGreenMask = 0x03e0; pScreenPriv->dwBlueMask = 0x001f; } else { /* Count the number of bits in each mask */ dwRedBits = winCountBits (pdw[0]); dwGreenBits = winCountBits (pdw[1]); dwBlueBits = winCountBits (pdw[2]); /* Find maximum bits per red, green, blue */ if (dwRedBits > dwGreenBits && dwRedBits > dwBlueBits) pScreenPriv->dwBitsPerRGB = dwRedBits; else if (dwGreenBits > dwRedBits && dwGreenBits > dwBlueBits) pScreenPriv->dwBitsPerRGB = dwGreenBits; else pScreenPriv->dwBitsPerRGB = dwBlueBits; /* Set screen privates masks */ pScreenPriv->dwRedMask = pdw[0]; pScreenPriv->dwGreenMask = pdw[1]; pScreenPriv->dwBlueMask = pdw[2]; } } else { ErrorF ("winQueryRGBBitsAndMasks - winQueryScreenDIBFormat failed\n"); free (pbmih); fReturn = FALSE; } /* Free memory */ free (pbmih); return fReturn; }
static Bool winQueryRGBBitsAndMasks (ScreenPtr pScreen) { winScreenPriv(pScreen); BITMAPINFOHEADER *pbmih = NULL; Bool fReturn = TRUE; LPDWORD pdw = NULL; DWORD dwRedBits, dwGreenBits, dwBlueBits; /* Color masks for 8 bpp are standardized */ if (GetDeviceCaps (pScreenPriv->hdcScreen, RASTERCAPS) & RC_PALETTE) { /* * RGB BPP for 8 bit palletes is always 8 * and the color masks are always 0. */ pScreenPriv->dwBitsPerRGB = 8; pScreenPriv->dwRedMask = 0x0L; pScreenPriv->dwGreenMask = 0x0L; pScreenPriv->dwBlueMask = 0x0L; return TRUE; } /* Color masks for 24 bpp are standardized */ if (GetDeviceCaps (pScreenPriv->hdcScreen, PLANES) * GetDeviceCaps (pScreenPriv->hdcScreen, BITSPIXEL) == 24) { ErrorF ("winQueryRGBBitsAndMasks - GetDeviceCaps (BITSPIXEL) " "returned 24 for the screen. Using default 24bpp masks.\n"); /* 8 bits per primary color */ pScreenPriv->dwBitsPerRGB = 8; /* Set screen privates masks */ pScreenPriv->dwRedMask = WIN_24BPP_MASK_RED; pScreenPriv->dwGreenMask = WIN_24BPP_MASK_GREEN; pScreenPriv->dwBlueMask = WIN_24BPP_MASK_BLUE; return TRUE; } /* Allocate a bitmap header and color table */ pbmih = (BITMAPINFOHEADER*) malloc (sizeof (BITMAPINFOHEADER) + 256 * sizeof (RGBQUAD)); if (pbmih == NULL) { ErrorF ("winQueryRGBBitsAndMasks - malloc failed\n"); return FALSE; } /* Get screen description */ if (winQueryScreenDIBFormat (pScreen, pbmih)) { /* Get a pointer to bitfields */ pdw = (DWORD*) ((CARD8*)pbmih + sizeof (BITMAPINFOHEADER)); #if CYGDEBUG ErrorF ("winQueryRGBBitsAndMasks - Masks: %08x %08x %08x\n", pdw[0], pdw[1], pdw[2]); #endif /* Count the number of bits in each mask */ dwRedBits = winCountBits (pdw[0]); dwGreenBits = winCountBits (pdw[1]); dwBlueBits = winCountBits (pdw[2]); /* Find maximum bits per red, green, blue */ if (dwRedBits > dwGreenBits && dwRedBits > dwBlueBits) pScreenPriv->dwBitsPerRGB = dwRedBits; else if (dwGreenBits > dwRedBits && dwGreenBits > dwBlueBits) pScreenPriv->dwBitsPerRGB = dwGreenBits; else pScreenPriv->dwBitsPerRGB = dwBlueBits; /* Set screen privates masks */ pScreenPriv->dwRedMask = pdw[0]; pScreenPriv->dwGreenMask = pdw[1]; pScreenPriv->dwBlueMask = pdw[2]; } else { ErrorF ("winQueryRGBBitsAndMasks - winQueryScreenDIBFormat failed\n"); free (pbmih); fReturn = FALSE; } /* Free memory */ free (pbmih); return fReturn; }