winshadgdi.c revision 1b5d61b8
105b261ecSmrg/* 205b261ecSmrg *Copyright (C) 2001-2004 Harold L Hunt II All Rights Reserved. 305b261ecSmrg * 405b261ecSmrg *Permission is hereby granted, free of charge, to any person obtaining 505b261ecSmrg * a copy of this software and associated documentation files (the 605b261ecSmrg *"Software"), to deal in the Software without restriction, including 705b261ecSmrg *without limitation the rights to use, copy, modify, merge, publish, 805b261ecSmrg *distribute, sublicense, and/or sell copies of the Software, and to 905b261ecSmrg *permit persons to whom the Software is furnished to do so, subject to 1005b261ecSmrg *the following conditions: 1105b261ecSmrg * 1205b261ecSmrg *The above copyright notice and this permission notice shall be 1305b261ecSmrg *included in all copies or substantial portions of the Software. 1405b261ecSmrg * 1505b261ecSmrg *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 1605b261ecSmrg *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 1705b261ecSmrg *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 1805b261ecSmrg *NONINFRINGEMENT. IN NO EVENT SHALL HAROLD L HUNT II BE LIABLE FOR 1905b261ecSmrg *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 2005b261ecSmrg *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 2105b261ecSmrg *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 2205b261ecSmrg * 2305b261ecSmrg *Except as contained in this notice, the name of Harold L Hunt II 2405b261ecSmrg *shall not be used in advertising or otherwise to promote the sale, use 2505b261ecSmrg *or other dealings in this Software without prior written authorization 2605b261ecSmrg *from Harold L Hunt II. 2705b261ecSmrg * 2805b261ecSmrg * Authors: Harold L Hunt II 2905b261ecSmrg */ 3005b261ecSmrg 3105b261ecSmrg#ifdef HAVE_XWIN_CONFIG_H 3205b261ecSmrg#include <xwin-config.h> 3305b261ecSmrg#endif 3405b261ecSmrg#include "win.h" 3505b261ecSmrg 3605b261ecSmrg/* 3705b261ecSmrg * Local function prototypes 3805b261ecSmrg */ 3905b261ecSmrg 4035c4bbdfSmrgstatic wBOOL CALLBACK winRedrawAllProcShadowGDI(HWND hwnd, LPARAM lParam); 4105b261ecSmrg 4235c4bbdfSmrgstatic wBOOL CALLBACK winRedrawDamagedWindowShadowGDI(HWND hwnd, LPARAM lParam); 4305b261ecSmrg 4405b261ecSmrgstatic Bool 4535c4bbdfSmrg winAllocateFBShadowGDI(ScreenPtr pScreen); 4605b261ecSmrg 4705b261ecSmrgstatic void 4835c4bbdfSmrg winShadowUpdateGDI(ScreenPtr pScreen, shadowBufPtr pBuf); 4905b261ecSmrg 5005b261ecSmrgstatic Bool 5135c4bbdfSmrg winCloseScreenShadowGDI(ScreenPtr pScreen); 5205b261ecSmrg 5305b261ecSmrgstatic Bool 5435c4bbdfSmrg winInitVisualsShadowGDI(ScreenPtr pScreen); 5505b261ecSmrg 5605b261ecSmrgstatic Bool 5735c4bbdfSmrg winAdjustVideoModeShadowGDI(ScreenPtr pScreen); 5805b261ecSmrg 5905b261ecSmrgstatic Bool 6035c4bbdfSmrg winBltExposedRegionsShadowGDI(ScreenPtr pScreen); 6105b261ecSmrg 6205b261ecSmrgstatic Bool 6335c4bbdfSmrg winActivateAppShadowGDI(ScreenPtr pScreen); 6405b261ecSmrg 6505b261ecSmrgstatic Bool 6635c4bbdfSmrg winRedrawScreenShadowGDI(ScreenPtr pScreen); 6705b261ecSmrg 6805b261ecSmrgstatic Bool 6935c4bbdfSmrg winRealizeInstalledPaletteShadowGDI(ScreenPtr pScreen); 7005b261ecSmrg 7105b261ecSmrgstatic Bool 7235c4bbdfSmrg winInstallColormapShadowGDI(ColormapPtr pColormap); 7305b261ecSmrg 7405b261ecSmrgstatic Bool 7535c4bbdfSmrg winStoreColorsShadowGDI(ColormapPtr pmap, int ndef, xColorItem * pdefs); 7605b261ecSmrg 7705b261ecSmrgstatic Bool 7835c4bbdfSmrg winCreateColormapShadowGDI(ColormapPtr pColormap); 7905b261ecSmrg 8005b261ecSmrgstatic Bool 8135c4bbdfSmrg winDestroyColormapShadowGDI(ColormapPtr pColormap); 8205b261ecSmrg 8305b261ecSmrg/* 8405b261ecSmrg * Internal function to get the DIB format that is compatible with the screen 8505b261ecSmrg */ 8605b261ecSmrg 8705b261ecSmrgstatic 8835c4bbdfSmrg Bool 8935c4bbdfSmrgwinQueryScreenDIBFormat(ScreenPtr pScreen, BITMAPINFOHEADER * pbmih) 9005b261ecSmrg{ 9135c4bbdfSmrg winScreenPriv(pScreen); 9235c4bbdfSmrg HBITMAP hbmp; 9335c4bbdfSmrg 9405b261ecSmrg#if CYGDEBUG 9535c4bbdfSmrg LPDWORD pdw = NULL; 9605b261ecSmrg#endif 9735c4bbdfSmrg 9835c4bbdfSmrg /* Create a memory bitmap compatible with the screen */ 9935c4bbdfSmrg hbmp = CreateCompatibleBitmap(pScreenPriv->hdcScreen, 1, 1); 10035c4bbdfSmrg if (hbmp == NULL) { 10135c4bbdfSmrg ErrorF("winQueryScreenDIBFormat - CreateCompatibleBitmap failed\n"); 10235c4bbdfSmrg return FALSE; 10305b261ecSmrg } 10435c4bbdfSmrg 10535c4bbdfSmrg /* Initialize our bitmap info header */ 10635c4bbdfSmrg ZeroMemory(pbmih, sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD)); 10735c4bbdfSmrg pbmih->biSize = sizeof(BITMAPINFOHEADER); 10835c4bbdfSmrg 10935c4bbdfSmrg /* Get the biBitCount */ 11035c4bbdfSmrg if (!GetDIBits(pScreenPriv->hdcScreen, 11135c4bbdfSmrg hbmp, 0, 1, NULL, (BITMAPINFO *) pbmih, DIB_RGB_COLORS)) { 11235c4bbdfSmrg ErrorF("winQueryScreenDIBFormat - First call to GetDIBits failed\n"); 11335c4bbdfSmrg DeleteObject(hbmp); 11435c4bbdfSmrg return FALSE; 11505b261ecSmrg } 11605b261ecSmrg 11705b261ecSmrg#if CYGDEBUG 11835c4bbdfSmrg /* Get a pointer to bitfields */ 11935c4bbdfSmrg pdw = (DWORD *) ((CARD8 *) pbmih + sizeof(BITMAPINFOHEADER)); 12005b261ecSmrg 12135c4bbdfSmrg winDebug("winQueryScreenDIBFormat - First call masks: %08x %08x %08x\n", 12235c4bbdfSmrg (unsigned int)pdw[0], (unsigned int)pdw[1], (unsigned int)pdw[2]); 12305b261ecSmrg#endif 12405b261ecSmrg 12535c4bbdfSmrg /* Get optimal color table, or the optimal bitfields */ 12635c4bbdfSmrg if (!GetDIBits(pScreenPriv->hdcScreen, 12735c4bbdfSmrg hbmp, 0, 1, NULL, (BITMAPINFO *) pbmih, DIB_RGB_COLORS)) { 12835c4bbdfSmrg ErrorF("winQueryScreenDIBFormat - Second call to GetDIBits " 12935c4bbdfSmrg "failed\n"); 13035c4bbdfSmrg DeleteObject(hbmp); 13135c4bbdfSmrg return FALSE; 13205b261ecSmrg } 13305b261ecSmrg 13435c4bbdfSmrg /* Free memory */ 13535c4bbdfSmrg DeleteObject(hbmp); 13605b261ecSmrg 13735c4bbdfSmrg return TRUE; 13835c4bbdfSmrg} 13905b261ecSmrg 14005b261ecSmrg/* 14105b261ecSmrg * Internal function to determine the GDI bits per rgb and bit masks 14205b261ecSmrg */ 14305b261ecSmrg 14405b261ecSmrgstatic 14535c4bbdfSmrg Bool 14635c4bbdfSmrgwinQueryRGBBitsAndMasks(ScreenPtr pScreen) 14705b261ecSmrg{ 14835c4bbdfSmrg winScreenPriv(pScreen); 14935c4bbdfSmrg BITMAPINFOHEADER *pbmih = NULL; 15035c4bbdfSmrg Bool fReturn = TRUE; 15135c4bbdfSmrg LPDWORD pdw = NULL; 15235c4bbdfSmrg DWORD dwRedBits, dwGreenBits, dwBlueBits; 15335c4bbdfSmrg 15435c4bbdfSmrg /* Color masks for 8 bpp are standardized */ 15535c4bbdfSmrg if (GetDeviceCaps(pScreenPriv->hdcScreen, RASTERCAPS) & RC_PALETTE) { 15635c4bbdfSmrg /* 15735c4bbdfSmrg * RGB BPP for 8 bit palletes is always 8 15835c4bbdfSmrg * and the color masks are always 0. 15935c4bbdfSmrg */ 16035c4bbdfSmrg pScreenPriv->dwBitsPerRGB = 8; 16135c4bbdfSmrg pScreenPriv->dwRedMask = 0x0L; 16235c4bbdfSmrg pScreenPriv->dwGreenMask = 0x0L; 16335c4bbdfSmrg pScreenPriv->dwBlueMask = 0x0L; 16435c4bbdfSmrg return TRUE; 16505b261ecSmrg } 16605b261ecSmrg 16735c4bbdfSmrg /* Color masks for 24 bpp are standardized */ 16835c4bbdfSmrg if (GetDeviceCaps(pScreenPriv->hdcScreen, PLANES) 16935c4bbdfSmrg * GetDeviceCaps(pScreenPriv->hdcScreen, BITSPIXEL) == 24) { 17035c4bbdfSmrg ErrorF("winQueryRGBBitsAndMasks - GetDeviceCaps (BITSPIXEL) " 17135c4bbdfSmrg "returned 24 for the screen. Using default 24bpp masks.\n"); 17235c4bbdfSmrg 17335c4bbdfSmrg /* 8 bits per primary color */ 17435c4bbdfSmrg pScreenPriv->dwBitsPerRGB = 8; 17535c4bbdfSmrg 17635c4bbdfSmrg /* Set screen privates masks */ 17735c4bbdfSmrg pScreenPriv->dwRedMask = WIN_24BPP_MASK_RED; 17835c4bbdfSmrg pScreenPriv->dwGreenMask = WIN_24BPP_MASK_GREEN; 17935c4bbdfSmrg pScreenPriv->dwBlueMask = WIN_24BPP_MASK_BLUE; 18035c4bbdfSmrg 18135c4bbdfSmrg return TRUE; 18205b261ecSmrg } 18305b261ecSmrg 18435c4bbdfSmrg /* Allocate a bitmap header and color table */ 18535c4bbdfSmrg pbmih = malloc(sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD)); 18635c4bbdfSmrg if (pbmih == NULL) { 18735c4bbdfSmrg ErrorF("winQueryRGBBitsAndMasks - malloc failed\n"); 18835c4bbdfSmrg return FALSE; 18905b261ecSmrg } 19005b261ecSmrg 19135c4bbdfSmrg /* Get screen description */ 19235c4bbdfSmrg if (winQueryScreenDIBFormat(pScreen, pbmih)) { 19335c4bbdfSmrg /* Get a pointer to bitfields */ 19435c4bbdfSmrg pdw = (DWORD *) ((CARD8 *) pbmih + sizeof(BITMAPINFOHEADER)); 19535c4bbdfSmrg 19605b261ecSmrg#if CYGDEBUG 19735c4bbdfSmrg winDebug("%s - Masks: %08x %08x %08x\n", __FUNCTION__, 19835c4bbdfSmrg (unsigned int)pdw[0], (unsigned int)pdw[1], (unsigned int)pdw[2]); 19935c4bbdfSmrg winDebug("%s - Bitmap: %dx%d %d bpp %d planes\n", __FUNCTION__, 20035c4bbdfSmrg (int)pbmih->biWidth, (int)pbmih->biHeight, pbmih->biBitCount, 20135c4bbdfSmrg pbmih->biPlanes); 20235c4bbdfSmrg winDebug("%s - Compression: %u %s\n", __FUNCTION__, 20335c4bbdfSmrg (unsigned int)pbmih->biCompression, 20435c4bbdfSmrg (pbmih->biCompression == 20535c4bbdfSmrg BI_RGB ? "(BI_RGB)" : (pbmih->biCompression == 20635c4bbdfSmrg BI_RLE8 ? "(BI_RLE8)" : (pbmih-> 20735c4bbdfSmrg biCompression 20835c4bbdfSmrg == 20935c4bbdfSmrg BI_RLE4 ? 21035c4bbdfSmrg "(BI_RLE4)" 21135c4bbdfSmrg : (pbmih-> 21235c4bbdfSmrg biCompression 21335c4bbdfSmrg == 21435c4bbdfSmrg BI_BITFIELDS 21535c4bbdfSmrg ? 21635c4bbdfSmrg "(BI_BITFIELDS)" 21735c4bbdfSmrg : ""))))); 21805b261ecSmrg#endif 21905b261ecSmrg 22035c4bbdfSmrg /* Handle BI_RGB case, which is returned by Wine */ 22135c4bbdfSmrg if (pbmih->biCompression == BI_RGB) { 22235c4bbdfSmrg dwRedBits = 5; 22335c4bbdfSmrg dwGreenBits = 5; 22435c4bbdfSmrg dwBlueBits = 5; 22535c4bbdfSmrg 22635c4bbdfSmrg pScreenPriv->dwBitsPerRGB = 5; 22735c4bbdfSmrg 22835c4bbdfSmrg /* Set screen privates masks */ 22935c4bbdfSmrg pScreenPriv->dwRedMask = 0x7c00; 23035c4bbdfSmrg pScreenPriv->dwGreenMask = 0x03e0; 23135c4bbdfSmrg pScreenPriv->dwBlueMask = 0x001f; 23235c4bbdfSmrg } 23335c4bbdfSmrg else { 23435c4bbdfSmrg /* Count the number of bits in each mask */ 23535c4bbdfSmrg dwRedBits = winCountBits(pdw[0]); 23635c4bbdfSmrg dwGreenBits = winCountBits(pdw[1]); 23735c4bbdfSmrg dwBlueBits = winCountBits(pdw[2]); 23835c4bbdfSmrg 23935c4bbdfSmrg /* Find maximum bits per red, green, blue */ 24035c4bbdfSmrg if (dwRedBits > dwGreenBits && dwRedBits > dwBlueBits) 24135c4bbdfSmrg pScreenPriv->dwBitsPerRGB = dwRedBits; 24235c4bbdfSmrg else if (dwGreenBits > dwRedBits && dwGreenBits > dwBlueBits) 24335c4bbdfSmrg pScreenPriv->dwBitsPerRGB = dwGreenBits; 24435c4bbdfSmrg else 24535c4bbdfSmrg pScreenPriv->dwBitsPerRGB = dwBlueBits; 24635c4bbdfSmrg 24735c4bbdfSmrg /* Set screen privates masks */ 24835c4bbdfSmrg pScreenPriv->dwRedMask = pdw[0]; 24935c4bbdfSmrg pScreenPriv->dwGreenMask = pdw[1]; 25035c4bbdfSmrg pScreenPriv->dwBlueMask = pdw[2]; 25105b261ecSmrg } 25205b261ecSmrg } 25335c4bbdfSmrg else { 25435c4bbdfSmrg ErrorF("winQueryRGBBitsAndMasks - winQueryScreenDIBFormat failed\n"); 25535c4bbdfSmrg fReturn = FALSE; 25605b261ecSmrg } 25705b261ecSmrg 25835c4bbdfSmrg /* Free memory */ 25935c4bbdfSmrg free(pbmih); 26005b261ecSmrg 26135c4bbdfSmrg return fReturn; 26205b261ecSmrg} 26305b261ecSmrg 26405b261ecSmrg/* 26505b261ecSmrg * Redraw all ---? 26605b261ecSmrg */ 26705b261ecSmrg 26805b261ecSmrgstatic wBOOL CALLBACK 26935c4bbdfSmrgwinRedrawAllProcShadowGDI(HWND hwnd, LPARAM lParam) 27005b261ecSmrg{ 27135c4bbdfSmrg if (hwnd == (HWND) lParam) 27235c4bbdfSmrg return TRUE; 27335c4bbdfSmrg InvalidateRect(hwnd, NULL, FALSE); 27435c4bbdfSmrg UpdateWindow(hwnd); 27535c4bbdfSmrg return TRUE; 27605b261ecSmrg} 27705b261ecSmrg 27805b261ecSmrgstatic wBOOL CALLBACK 27935c4bbdfSmrgwinRedrawDamagedWindowShadowGDI(HWND hwnd, LPARAM lParam) 28005b261ecSmrg{ 28135c4bbdfSmrg BoxPtr pDamage = (BoxPtr) lParam; 28235c4bbdfSmrg RECT rcClient, rcDamage, rcRedraw; 28335c4bbdfSmrg POINT topLeft, bottomRight; 28435c4bbdfSmrg 28535c4bbdfSmrg if (IsIconic(hwnd)) 28635c4bbdfSmrg return TRUE; /* Don't care minimized windows */ 28735c4bbdfSmrg 28835c4bbdfSmrg /* Convert the damaged area from Screen coords to Client coords */ 28935c4bbdfSmrg topLeft.x = pDamage->x1; 29035c4bbdfSmrg topLeft.y = pDamage->y1; 29135c4bbdfSmrg bottomRight.x = pDamage->x2; 29235c4bbdfSmrg bottomRight.y = pDamage->y2; 29335c4bbdfSmrg topLeft.x += GetSystemMetrics(SM_XVIRTUALSCREEN); 29435c4bbdfSmrg bottomRight.x += GetSystemMetrics(SM_XVIRTUALSCREEN); 29535c4bbdfSmrg topLeft.y += GetSystemMetrics(SM_YVIRTUALSCREEN); 29635c4bbdfSmrg bottomRight.y += GetSystemMetrics(SM_YVIRTUALSCREEN); 29735c4bbdfSmrg ScreenToClient(hwnd, &topLeft); 29835c4bbdfSmrg ScreenToClient(hwnd, &bottomRight); 29935c4bbdfSmrg SetRect(&rcDamage, topLeft.x, topLeft.y, bottomRight.x, bottomRight.y); 30035c4bbdfSmrg 30135c4bbdfSmrg GetClientRect(hwnd, &rcClient); 30235c4bbdfSmrg 30335c4bbdfSmrg if (IntersectRect(&rcRedraw, &rcClient, &rcDamage)) { 30435c4bbdfSmrg InvalidateRect(hwnd, &rcRedraw, FALSE); 30535c4bbdfSmrg UpdateWindow(hwnd); 30605b261ecSmrg } 30735c4bbdfSmrg return TRUE; 30805b261ecSmrg} 30905b261ecSmrg 31005b261ecSmrg/* 31105b261ecSmrg * Allocate a DIB for the shadow framebuffer GDI server 31205b261ecSmrg */ 31305b261ecSmrg 31405b261ecSmrgstatic Bool 31535c4bbdfSmrgwinAllocateFBShadowGDI(ScreenPtr pScreen) 31605b261ecSmrg{ 31735c4bbdfSmrg winScreenPriv(pScreen); 31835c4bbdfSmrg winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; 31935c4bbdfSmrg DIBSECTION dibsection; 32035c4bbdfSmrg Bool fReturn = TRUE; 32135c4bbdfSmrg 32235c4bbdfSmrg /* Describe shadow bitmap to be created */ 32335c4bbdfSmrg pScreenPriv->pbmih->biWidth = pScreenInfo->dwWidth; 32435c4bbdfSmrg pScreenPriv->pbmih->biHeight = -pScreenInfo->dwHeight; 32535c4bbdfSmrg 32635c4bbdfSmrg ErrorF("winAllocateFBShadowGDI - Creating DIB with width: %d height: %d " 32735c4bbdfSmrg "depth: %d\n", 32835c4bbdfSmrg (int) pScreenPriv->pbmih->biWidth, 32935c4bbdfSmrg (int) -pScreenPriv->pbmih->biHeight, pScreenPriv->pbmih->biBitCount); 33035c4bbdfSmrg 33135c4bbdfSmrg /* Create a DI shadow bitmap with a bit pointer */ 33235c4bbdfSmrg pScreenPriv->hbmpShadow = CreateDIBSection(pScreenPriv->hdcScreen, 33335c4bbdfSmrg (BITMAPINFO *) pScreenPriv-> 33435c4bbdfSmrg pbmih, DIB_RGB_COLORS, 33535c4bbdfSmrg (VOID **) &pScreenInfo->pfb, 33635c4bbdfSmrg NULL, 0); 33735c4bbdfSmrg if (pScreenPriv->hbmpShadow == NULL || pScreenInfo->pfb == NULL) { 33835c4bbdfSmrg winW32Error(2, "winAllocateFBShadowGDI - CreateDIBSection failed:"); 33935c4bbdfSmrg return FALSE; 34005b261ecSmrg } 34135c4bbdfSmrg else { 34205b261ecSmrg#if CYGDEBUG 34335c4bbdfSmrg winDebug("winAllocateFBShadowGDI - Shadow buffer allocated\n"); 34405b261ecSmrg#endif 34505b261ecSmrg } 34605b261ecSmrg 34735c4bbdfSmrg /* Get information about the bitmap that was allocated */ 34835c4bbdfSmrg GetObject(pScreenPriv->hbmpShadow, sizeof(dibsection), &dibsection); 34905b261ecSmrg 35005b261ecSmrg#if CYGDEBUG || YES 35135c4bbdfSmrg /* Print information about bitmap allocated */ 35235c4bbdfSmrg winDebug("winAllocateFBShadowGDI - Dibsection width: %d height: %d " 35335c4bbdfSmrg "depth: %d size image: %d\n", 35435c4bbdfSmrg (int) dibsection.dsBmih.biWidth, (int) dibsection.dsBmih.biHeight, 35535c4bbdfSmrg dibsection.dsBmih.biBitCount, (int) dibsection.dsBmih.biSizeImage); 35605b261ecSmrg#endif 35705b261ecSmrg 35835c4bbdfSmrg /* Select the shadow bitmap into the shadow DC */ 35935c4bbdfSmrg SelectObject(pScreenPriv->hdcShadow, pScreenPriv->hbmpShadow); 36005b261ecSmrg 36105b261ecSmrg#if CYGDEBUG 36235c4bbdfSmrg winDebug("winAllocateFBShadowGDI - Attempting a shadow blit\n"); 36305b261ecSmrg#endif 36405b261ecSmrg 36535c4bbdfSmrg /* Do a test blit from the shadow to the screen, I think */ 36635c4bbdfSmrg fReturn = BitBlt(pScreenPriv->hdcScreen, 36735c4bbdfSmrg 0, 0, 36835c4bbdfSmrg pScreenInfo->dwWidth, pScreenInfo->dwHeight, 36935c4bbdfSmrg pScreenPriv->hdcShadow, 0, 0, SRCCOPY); 37035c4bbdfSmrg if (fReturn) { 37105b261ecSmrg#if CYGDEBUG 37235c4bbdfSmrg winDebug("winAllocateFBShadowGDI - Shadow blit success\n"); 37305b261ecSmrg#endif 37405b261ecSmrg } 37535c4bbdfSmrg else { 37635c4bbdfSmrg winW32Error(2, "winAllocateFBShadowGDI - Shadow blit failure\n"); 37735c4bbdfSmrg#if 0 37835c4bbdfSmrg return FALSE; 37935c4bbdfSmrg#else 38035c4bbdfSmrg /* ago: ignore this error. The blit fails with wine, but does not 38135c4bbdfSmrg * cause any problems later. */ 38235c4bbdfSmrg 38335c4bbdfSmrg fReturn = TRUE; 38435c4bbdfSmrg#endif 38505b261ecSmrg } 38605b261ecSmrg 38735c4bbdfSmrg /* Look for height weirdness */ 38835c4bbdfSmrg if (dibsection.dsBmih.biHeight < 0) { 38935c4bbdfSmrg dibsection.dsBmih.biHeight = -dibsection.dsBmih.biHeight; 39005b261ecSmrg } 39105b261ecSmrg 39235c4bbdfSmrg /* Set screeninfo stride */ 39335c4bbdfSmrg pScreenInfo->dwStride = ((dibsection.dsBmih.biSizeImage 39435c4bbdfSmrg / dibsection.dsBmih.biHeight) 39535c4bbdfSmrg * 8) / pScreenInfo->dwBPP; 39605b261ecSmrg 39705b261ecSmrg#if CYGDEBUG || YES 39835c4bbdfSmrg winDebug("winAllocateFBShadowGDI - Created shadow stride: %d\n", 39935c4bbdfSmrg (int) pScreenInfo->dwStride); 40005b261ecSmrg#endif 40105b261ecSmrg 40235c4bbdfSmrg /* Redraw all windows */ 40335c4bbdfSmrg if (pScreenInfo->fMultiWindow) 40435c4bbdfSmrg EnumThreadWindows(g_dwCurrentThreadID, winRedrawAllProcShadowGDI, 0); 40505b261ecSmrg 40635c4bbdfSmrg return fReturn; 40705b261ecSmrg} 40805b261ecSmrg 4099ace9065Smrgstatic void 41035c4bbdfSmrgwinFreeFBShadowGDI(ScreenPtr pScreen) 4119ace9065Smrg{ 41235c4bbdfSmrg winScreenPriv(pScreen); 41335c4bbdfSmrg winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; 4149ace9065Smrg 41535c4bbdfSmrg /* Free the shadow bitmap */ 41635c4bbdfSmrg DeleteObject(pScreenPriv->hbmpShadow); 4179ace9065Smrg 41835c4bbdfSmrg /* Invalidate the ScreenInfo's fb pointer */ 41935c4bbdfSmrg pScreenInfo->pfb = NULL; 4209ace9065Smrg} 42105b261ecSmrg 42205b261ecSmrg/* 42305b261ecSmrg * Blit the damaged regions of the shadow fb to the screen 42405b261ecSmrg */ 42505b261ecSmrg 42605b261ecSmrgstatic void 42735c4bbdfSmrgwinShadowUpdateGDI(ScreenPtr pScreen, shadowBufPtr pBuf) 42805b261ecSmrg{ 42935c4bbdfSmrg winScreenPriv(pScreen); 43035c4bbdfSmrg winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; 4311b5d61b8Smrg RegionPtr damage = DamageRegion(pBuf->pDamage); 43235c4bbdfSmrg DWORD dwBox = RegionNumRects(damage); 43335c4bbdfSmrg BoxPtr pBox = RegionRects(damage); 43435c4bbdfSmrg int x, y, w, h; 43535c4bbdfSmrg HRGN hrgnCombined = NULL; 43635c4bbdfSmrg 43705b261ecSmrg#ifdef XWIN_UPDATESTATS 43835c4bbdfSmrg static DWORD s_dwNonUnitRegions = 0; 43935c4bbdfSmrg static DWORD s_dwTotalUpdates = 0; 44035c4bbdfSmrg static DWORD s_dwTotalBoxes = 0; 44105b261ecSmrg#endif 44235c4bbdfSmrg BoxPtr pBoxExtents = RegionExtents(damage); 44305b261ecSmrg 44435c4bbdfSmrg /* 44535c4bbdfSmrg * Return immediately if the app is not active 44635c4bbdfSmrg * and we are fullscreen, or if we have a bad display depth 44735c4bbdfSmrg */ 44835c4bbdfSmrg if ((!pScreenPriv->fActive && pScreenInfo->fFullScreen) 44935c4bbdfSmrg || pScreenPriv->fBadDepth) 45035c4bbdfSmrg return; 45105b261ecSmrg 45205b261ecSmrg#ifdef XWIN_UPDATESTATS 45335c4bbdfSmrg ++s_dwTotalUpdates; 45435c4bbdfSmrg s_dwTotalBoxes += dwBox; 45505b261ecSmrg 45635c4bbdfSmrg if (dwBox != 1) { 45735c4bbdfSmrg ++s_dwNonUnitRegions; 45835c4bbdfSmrg ErrorF("winShadowUpdatGDI - dwBox: %d\n", dwBox); 45905b261ecSmrg } 46035c4bbdfSmrg 46135c4bbdfSmrg if ((s_dwTotalUpdates % 100) == 0) 46235c4bbdfSmrg ErrorF("winShadowUpdateGDI - %d%% non-unity regions, avg boxes: %d " 46335c4bbdfSmrg "nu: %d tu: %d\n", 46435c4bbdfSmrg (s_dwNonUnitRegions * 100) / s_dwTotalUpdates, 46535c4bbdfSmrg s_dwTotalBoxes / s_dwTotalUpdates, 46635c4bbdfSmrg s_dwNonUnitRegions, s_dwTotalUpdates); 46735c4bbdfSmrg#endif /* XWIN_UPDATESTATS */ 46835c4bbdfSmrg 46935c4bbdfSmrg /* 47035c4bbdfSmrg * Handle small regions with multiple blits, 47135c4bbdfSmrg * handle large regions by creating a clipping region and 47235c4bbdfSmrg * doing a single blit constrained to that clipping region. 47335c4bbdfSmrg */ 47435c4bbdfSmrg if (!pScreenInfo->fMultiWindow && 47535c4bbdfSmrg (pScreenInfo->dwClipUpdatesNBoxes == 0 || 47635c4bbdfSmrg dwBox < pScreenInfo->dwClipUpdatesNBoxes)) { 47735c4bbdfSmrg /* Loop through all boxes in the damaged region */ 47835c4bbdfSmrg while (dwBox--) { 47935c4bbdfSmrg /* 48035c4bbdfSmrg * Calculate x offset, y offset, width, and height for 48135c4bbdfSmrg * current damage box 48235c4bbdfSmrg */ 48335c4bbdfSmrg x = pBox->x1; 48435c4bbdfSmrg y = pBox->y1; 48535c4bbdfSmrg w = pBox->x2 - pBox->x1; 48635c4bbdfSmrg h = pBox->y2 - pBox->y1; 48735c4bbdfSmrg 48835c4bbdfSmrg BitBlt(pScreenPriv->hdcScreen, 48935c4bbdfSmrg x, y, w, h, pScreenPriv->hdcShadow, x, y, SRCCOPY); 49035c4bbdfSmrg 49135c4bbdfSmrg /* Get a pointer to the next box */ 49235c4bbdfSmrg ++pBox; 49335c4bbdfSmrg } 49405b261ecSmrg } 49535c4bbdfSmrg else if (!pScreenInfo->fMultiWindow) { 49635c4bbdfSmrg 49735c4bbdfSmrg /* Compute a GDI region from the damaged region */ 49835c4bbdfSmrg hrgnCombined = 49935c4bbdfSmrg CreateRectRgn(pBoxExtents->x1, pBoxExtents->y1, pBoxExtents->x2, 50035c4bbdfSmrg pBoxExtents->y2); 50135c4bbdfSmrg 50235c4bbdfSmrg /* Install the GDI region as a clipping region */ 50335c4bbdfSmrg SelectClipRgn(pScreenPriv->hdcScreen, hrgnCombined); 50435c4bbdfSmrg DeleteObject(hrgnCombined); 50535c4bbdfSmrg hrgnCombined = NULL; 50635c4bbdfSmrg 50735c4bbdfSmrg /* 50835c4bbdfSmrg * Blit the shadow buffer to the screen, 50935c4bbdfSmrg * constrained to the clipping region. 51035c4bbdfSmrg */ 51135c4bbdfSmrg BitBlt(pScreenPriv->hdcScreen, 51235c4bbdfSmrg pBoxExtents->x1, pBoxExtents->y1, 51335c4bbdfSmrg pBoxExtents->x2 - pBoxExtents->x1, 51435c4bbdfSmrg pBoxExtents->y2 - pBoxExtents->y1, 51535c4bbdfSmrg pScreenPriv->hdcShadow, 51635c4bbdfSmrg pBoxExtents->x1, pBoxExtents->y1, SRCCOPY); 51735c4bbdfSmrg 51835c4bbdfSmrg /* Reset the clip region */ 51935c4bbdfSmrg SelectClipRgn(pScreenPriv->hdcScreen, NULL); 52005b261ecSmrg } 52105b261ecSmrg 52235c4bbdfSmrg /* Redraw all multiwindow windows */ 52335c4bbdfSmrg if (pScreenInfo->fMultiWindow) 52435c4bbdfSmrg EnumThreadWindows(g_dwCurrentThreadID, 52535c4bbdfSmrg winRedrawDamagedWindowShadowGDI, 52635c4bbdfSmrg (LPARAM) pBoxExtents); 52705b261ecSmrg} 52805b261ecSmrg 5299ace9065Smrgstatic Bool 53035c4bbdfSmrgwinInitScreenShadowGDI(ScreenPtr pScreen) 5319ace9065Smrg{ 53235c4bbdfSmrg winScreenPriv(pScreen); 53335c4bbdfSmrg 53435c4bbdfSmrg /* Get device contexts for the screen and shadow bitmap */ 53535c4bbdfSmrg pScreenPriv->hdcScreen = GetDC(pScreenPriv->hwndScreen); 53635c4bbdfSmrg pScreenPriv->hdcShadow = CreateCompatibleDC(pScreenPriv->hdcScreen); 53735c4bbdfSmrg 53835c4bbdfSmrg /* Allocate bitmap info header */ 53935c4bbdfSmrg pScreenPriv->pbmih = malloc(sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD)); 54035c4bbdfSmrg if (pScreenPriv->pbmih == NULL) { 54135c4bbdfSmrg ErrorF("winInitScreenShadowGDI - malloc () failed\n"); 54235c4bbdfSmrg return FALSE; 5439ace9065Smrg } 5449ace9065Smrg 54535c4bbdfSmrg /* Query the screen format */ 54635c4bbdfSmrg if (!winQueryScreenDIBFormat(pScreen, pScreenPriv->pbmih)) { 54735c4bbdfSmrg ErrorF("winInitScreenShadowGDI - winQueryScreenDIBFormat failed\n"); 54835c4bbdfSmrg return FALSE; 5499ace9065Smrg } 5509ace9065Smrg 55135c4bbdfSmrg /* Determine our color masks */ 55235c4bbdfSmrg if (!winQueryRGBBitsAndMasks(pScreen)) { 55335c4bbdfSmrg ErrorF("winInitScreenShadowGDI - winQueryRGBBitsAndMasks failed\n"); 55435c4bbdfSmrg return FALSE; 5559ace9065Smrg } 5569ace9065Smrg 55735c4bbdfSmrg return winAllocateFBShadowGDI(pScreen); 5589ace9065Smrg} 5599ace9065Smrg 56005b261ecSmrg/* See Porting Layer Definition - p. 33 */ 56105b261ecSmrg/* 56205b261ecSmrg * We wrap whatever CloseScreen procedure was specified by fb; 56305b261ecSmrg * a pointer to said procedure is stored in our privates. 56405b261ecSmrg */ 56505b261ecSmrg 56605b261ecSmrgstatic Bool 56735c4bbdfSmrgwinCloseScreenShadowGDI(ScreenPtr pScreen) 56805b261ecSmrg{ 56935c4bbdfSmrg winScreenPriv(pScreen); 57035c4bbdfSmrg winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; 5711b5d61b8Smrg Bool fReturn = TRUE; 57205b261ecSmrg 57305b261ecSmrg#if CYGDEBUG 57435c4bbdfSmrg winDebug("winCloseScreenShadowGDI - Freeing screen resources\n"); 57505b261ecSmrg#endif 57605b261ecSmrg 57735c4bbdfSmrg /* Flag that the screen is closed */ 57835c4bbdfSmrg pScreenPriv->fClosed = TRUE; 57935c4bbdfSmrg pScreenPriv->fActive = FALSE; 58005b261ecSmrg 58135c4bbdfSmrg /* Call the wrapped CloseScreen procedure */ 58235c4bbdfSmrg WIN_UNWRAP(CloseScreen); 58335c4bbdfSmrg if (pScreen->CloseScreen) 58435c4bbdfSmrg fReturn = (*pScreen->CloseScreen) (pScreen); 58505b261ecSmrg 58635c4bbdfSmrg /* Delete the window property */ 58735c4bbdfSmrg RemoveProp(pScreenPriv->hwndScreen, WIN_SCR_PROP); 58805b261ecSmrg 58935c4bbdfSmrg /* Free the shadow DC; which allows the bitmap to be freed */ 59035c4bbdfSmrg DeleteDC(pScreenPriv->hdcShadow); 5919ace9065Smrg 59235c4bbdfSmrg winFreeFBShadowGDI(pScreen); 59305b261ecSmrg 59435c4bbdfSmrg /* Free the screen DC */ 59535c4bbdfSmrg ReleaseDC(pScreenPriv->hwndScreen, pScreenPriv->hdcScreen); 59605b261ecSmrg 59735c4bbdfSmrg /* Delete tray icon, if we have one */ 59835c4bbdfSmrg if (!pScreenInfo->fNoTrayIcon) 59935c4bbdfSmrg winDeleteNotifyIcon(pScreenPriv); 60005b261ecSmrg 60135c4bbdfSmrg /* Free the exit confirmation dialog box, if it exists */ 60235c4bbdfSmrg if (g_hDlgExit != NULL) { 60335c4bbdfSmrg DestroyWindow(g_hDlgExit); 60435c4bbdfSmrg g_hDlgExit = NULL; 60505b261ecSmrg } 60605b261ecSmrg 60735c4bbdfSmrg /* Kill our window */ 60835c4bbdfSmrg if (pScreenPriv->hwndScreen) { 60935c4bbdfSmrg DestroyWindow(pScreenPriv->hwndScreen); 61035c4bbdfSmrg pScreenPriv->hwndScreen = NULL; 61105b261ecSmrg } 61205b261ecSmrg 61335c4bbdfSmrg /* Destroy the thread startup mutex */ 61435c4bbdfSmrg pthread_mutex_destroy(&pScreenPriv->pmServerStarted); 61505b261ecSmrg 61635c4bbdfSmrg /* Invalidate our screeninfo's pointer to the screen */ 61735c4bbdfSmrg pScreenInfo->pScreen = NULL; 61805b261ecSmrg 61935c4bbdfSmrg /* Free the screen privates for this screen */ 62035c4bbdfSmrg free((void *) pScreenPriv); 62105b261ecSmrg 62235c4bbdfSmrg return fReturn; 62305b261ecSmrg} 62405b261ecSmrg 62505b261ecSmrg/* 62605b261ecSmrg * Tell mi what sort of visuals we need. 62735c4bbdfSmrg * 62805b261ecSmrg * Generally we only need one visual, as our screen can only 62905b261ecSmrg * handle one format at a time, I believe. You may want 63005b261ecSmrg * to verify that last sentence. 63105b261ecSmrg */ 63205b261ecSmrg 63305b261ecSmrgstatic Bool 63435c4bbdfSmrgwinInitVisualsShadowGDI(ScreenPtr pScreen) 63505b261ecSmrg{ 63635c4bbdfSmrg winScreenPriv(pScreen); 63735c4bbdfSmrg winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; 63835c4bbdfSmrg 63935c4bbdfSmrg /* Display debugging information */ 64035c4bbdfSmrg ErrorF("winInitVisualsShadowGDI - Masks %08x %08x %08x BPRGB %d d %d " 64135c4bbdfSmrg "bpp %d\n", 64235c4bbdfSmrg (unsigned int) pScreenPriv->dwRedMask, 64335c4bbdfSmrg (unsigned int) pScreenPriv->dwGreenMask, 64435c4bbdfSmrg (unsigned int) pScreenPriv->dwBlueMask, 64535c4bbdfSmrg (int) pScreenPriv->dwBitsPerRGB, 64635c4bbdfSmrg (int) pScreenInfo->dwDepth, (int) pScreenInfo->dwBPP); 64735c4bbdfSmrg 64835c4bbdfSmrg /* Create a single visual according to the Windows screen depth */ 64935c4bbdfSmrg switch (pScreenInfo->dwDepth) { 65005b261ecSmrg case 24: 65105b261ecSmrg case 16: 65205b261ecSmrg case 15: 65335c4bbdfSmrg /* Setup the real visual */ 65435c4bbdfSmrg if (!miSetVisualTypesAndMasks(pScreenInfo->dwDepth, 65535c4bbdfSmrg TrueColorMask, 65635c4bbdfSmrg pScreenPriv->dwBitsPerRGB, 65735c4bbdfSmrg -1, 65835c4bbdfSmrg pScreenPriv->dwRedMask, 65935c4bbdfSmrg pScreenPriv->dwGreenMask, 66035c4bbdfSmrg pScreenPriv->dwBlueMask)) { 66135c4bbdfSmrg ErrorF("winInitVisualsShadowGDI - miSetVisualTypesAndMasks " 66235c4bbdfSmrg "failed\n"); 66335c4bbdfSmrg return FALSE; 66435c4bbdfSmrg } 66505b261ecSmrg 66605b261ecSmrg#ifdef XWIN_EMULATEPSEUDO 66735c4bbdfSmrg if (!pScreenInfo->fEmulatePseudo) 66835c4bbdfSmrg break; 66935c4bbdfSmrg 67035c4bbdfSmrg /* Setup a pseudocolor visual */ 67135c4bbdfSmrg if (!miSetVisualTypesAndMasks(8, PseudoColorMask, 8, -1, 0, 0, 0)) { 67235c4bbdfSmrg ErrorF("winInitVisualsShadowGDI - miSetVisualTypesAndMasks " 67335c4bbdfSmrg "failed for PseudoColor\n"); 67435c4bbdfSmrg return FALSE; 67535c4bbdfSmrg } 67605b261ecSmrg#endif 67735c4bbdfSmrg break; 67805b261ecSmrg 67905b261ecSmrg case 8: 68035c4bbdfSmrg if (!miSetVisualTypesAndMasks(pScreenInfo->dwDepth, 68135c4bbdfSmrg PseudoColorMask, 68235c4bbdfSmrg pScreenPriv->dwBitsPerRGB, 68335c4bbdfSmrg PseudoColor, 68435c4bbdfSmrg pScreenPriv->dwRedMask, 68535c4bbdfSmrg pScreenPriv->dwGreenMask, 68635c4bbdfSmrg pScreenPriv->dwBlueMask)) { 68735c4bbdfSmrg ErrorF("winInitVisualsShadowGDI - miSetVisualTypesAndMasks " 68835c4bbdfSmrg "failed\n"); 68935c4bbdfSmrg return FALSE; 69035c4bbdfSmrg } 69135c4bbdfSmrg break; 69205b261ecSmrg 69305b261ecSmrg default: 69435c4bbdfSmrg ErrorF("winInitVisualsShadowGDI - Unknown screen depth\n"); 69535c4bbdfSmrg return FALSE; 69605b261ecSmrg } 69705b261ecSmrg 69805b261ecSmrg#if CYGDEBUG 69935c4bbdfSmrg winDebug("winInitVisualsShadowGDI - Returning\n"); 70005b261ecSmrg#endif 70105b261ecSmrg 70235c4bbdfSmrg return TRUE; 70305b261ecSmrg} 70405b261ecSmrg 70505b261ecSmrg/* 70605b261ecSmrg * Adjust the proposed video mode 70705b261ecSmrg */ 70805b261ecSmrg 70905b261ecSmrgstatic Bool 71035c4bbdfSmrgwinAdjustVideoModeShadowGDI(ScreenPtr pScreen) 71105b261ecSmrg{ 71235c4bbdfSmrg winScreenPriv(pScreen); 71335c4bbdfSmrg winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; 71435c4bbdfSmrg HDC hdc; 71535c4bbdfSmrg DWORD dwBPP; 71635c4bbdfSmrg 71735c4bbdfSmrg hdc = GetDC(NULL); 71835c4bbdfSmrg 71935c4bbdfSmrg /* We're in serious trouble if we can't get a DC */ 72035c4bbdfSmrg if (hdc == NULL) { 72135c4bbdfSmrg ErrorF("winAdjustVideoModeShadowGDI - GetDC () failed\n"); 72235c4bbdfSmrg return FALSE; 72305b261ecSmrg } 72405b261ecSmrg 72535c4bbdfSmrg /* Query GDI for current display depth */ 72635c4bbdfSmrg dwBPP = GetDeviceCaps(hdc, BITSPIXEL); 72705b261ecSmrg 72835c4bbdfSmrg /* GDI cannot change the screen depth, so always use GDI's depth */ 72935c4bbdfSmrg pScreenInfo->dwBPP = dwBPP; 73005b261ecSmrg 73135c4bbdfSmrg /* Release our DC */ 73235c4bbdfSmrg ReleaseDC(NULL, hdc); 73335c4bbdfSmrg hdc = NULL; 73405b261ecSmrg 73535c4bbdfSmrg return TRUE; 73605b261ecSmrg} 73705b261ecSmrg 73805b261ecSmrg/* 73905b261ecSmrg * Blt exposed regions to the screen 74005b261ecSmrg */ 74105b261ecSmrg 74205b261ecSmrgstatic Bool 74335c4bbdfSmrgwinBltExposedRegionsShadowGDI(ScreenPtr pScreen) 74405b261ecSmrg{ 74535c4bbdfSmrg winScreenPriv(pScreen); 74635c4bbdfSmrg winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; 74735c4bbdfSmrg winPrivCmapPtr pCmapPriv = NULL; 74835c4bbdfSmrg HDC hdcUpdate; 74935c4bbdfSmrg PAINTSTRUCT ps; 75035c4bbdfSmrg 75135c4bbdfSmrg /* BeginPaint gives us an hdc that clips to the invalidated region */ 75235c4bbdfSmrg hdcUpdate = BeginPaint(pScreenPriv->hwndScreen, &ps); 75335c4bbdfSmrg 75435c4bbdfSmrg /* Realize the palette, if we have one */ 75535c4bbdfSmrg if (pScreenPriv->pcmapInstalled != NULL) { 75635c4bbdfSmrg pCmapPriv = winGetCmapPriv(pScreenPriv->pcmapInstalled); 75735c4bbdfSmrg 75835c4bbdfSmrg SelectPalette(hdcUpdate, pCmapPriv->hPalette, FALSE); 75935c4bbdfSmrg RealizePalette(hdcUpdate); 76005b261ecSmrg } 76105b261ecSmrg 76235c4bbdfSmrg /* Our BitBlt will be clipped to the invalidated region */ 76335c4bbdfSmrg BitBlt(hdcUpdate, 76435c4bbdfSmrg 0, 0, 76535c4bbdfSmrg pScreenInfo->dwWidth, pScreenInfo->dwHeight, 76635c4bbdfSmrg pScreenPriv->hdcShadow, 0, 0, SRCCOPY); 76705b261ecSmrg 76835c4bbdfSmrg /* EndPaint frees the DC */ 76935c4bbdfSmrg EndPaint(pScreenPriv->hwndScreen, &ps); 77005b261ecSmrg 77135c4bbdfSmrg /* Redraw all windows */ 77235c4bbdfSmrg if (pScreenInfo->fMultiWindow) 77335c4bbdfSmrg EnumThreadWindows(g_dwCurrentThreadID, winRedrawAllProcShadowGDI, 77435c4bbdfSmrg (LPARAM) pScreenPriv->hwndScreen); 77505b261ecSmrg 77635c4bbdfSmrg return TRUE; 77705b261ecSmrg} 77805b261ecSmrg 77905b261ecSmrg/* 78005b261ecSmrg * Do any engine-specific appliation-activation processing 78105b261ecSmrg */ 78205b261ecSmrg 78305b261ecSmrgstatic Bool 78435c4bbdfSmrgwinActivateAppShadowGDI(ScreenPtr pScreen) 78505b261ecSmrg{ 78635c4bbdfSmrg winScreenPriv(pScreen); 78735c4bbdfSmrg winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; 78835c4bbdfSmrg 78935c4bbdfSmrg /* 79035c4bbdfSmrg * 2004/04/12 - Harold - We perform the restoring or minimizing 79135c4bbdfSmrg * manually for ShadowGDI in fullscreen modes so that this engine 79235c4bbdfSmrg * will perform just like ShadowDD and ShadowDDNL in fullscreen mode; 79335c4bbdfSmrg * if we do not do this then our fullscreen window will appear in the 79435c4bbdfSmrg * z-order when it is deactivated and it can be uncovered by resizing 79535c4bbdfSmrg * or minimizing another window that is on top of it, which is not how 79635c4bbdfSmrg * the DirectDraw engines work. Therefore we keep this code here to 79735c4bbdfSmrg * make sure that all engines work the same in fullscreen mode. 79835c4bbdfSmrg */ 79935c4bbdfSmrg 80035c4bbdfSmrg /* 80135c4bbdfSmrg * Are we active? 80235c4bbdfSmrg * Are we fullscreen? 80335c4bbdfSmrg */ 80435c4bbdfSmrg if (pScreenPriv->fActive && pScreenInfo->fFullScreen) { 80535c4bbdfSmrg /* 80635c4bbdfSmrg * Activating, attempt to bring our window 80735c4bbdfSmrg * to the top of the display 80835c4bbdfSmrg */ 80935c4bbdfSmrg ShowWindow(pScreenPriv->hwndScreen, SW_RESTORE); 81005b261ecSmrg } 81135c4bbdfSmrg else if (!pScreenPriv->fActive && pScreenInfo->fFullScreen) { 81235c4bbdfSmrg /* 81335c4bbdfSmrg * Deactivating, stuff our window onto the 81435c4bbdfSmrg * task bar. 81535c4bbdfSmrg */ 81635c4bbdfSmrg ShowWindow(pScreenPriv->hwndScreen, SW_MINIMIZE); 81705b261ecSmrg } 81805b261ecSmrg 81935c4bbdfSmrg return TRUE; 82005b261ecSmrg} 82105b261ecSmrg 82205b261ecSmrg/* 82305b261ecSmrg * Reblit the shadow framebuffer to the screen. 82405b261ecSmrg */ 82505b261ecSmrg 82605b261ecSmrgstatic Bool 82735c4bbdfSmrgwinRedrawScreenShadowGDI(ScreenPtr pScreen) 82805b261ecSmrg{ 82935c4bbdfSmrg winScreenPriv(pScreen); 83035c4bbdfSmrg winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; 83105b261ecSmrg 83235c4bbdfSmrg /* Redraw the whole window, to take account for the new colors */ 83335c4bbdfSmrg BitBlt(pScreenPriv->hdcScreen, 83435c4bbdfSmrg 0, 0, 83535c4bbdfSmrg pScreenInfo->dwWidth, pScreenInfo->dwHeight, 83635c4bbdfSmrg pScreenPriv->hdcShadow, 0, 0, SRCCOPY); 83705b261ecSmrg 83835c4bbdfSmrg /* Redraw all windows */ 83935c4bbdfSmrg if (pScreenInfo->fMultiWindow) 84035c4bbdfSmrg EnumThreadWindows(g_dwCurrentThreadID, winRedrawAllProcShadowGDI, 0); 84105b261ecSmrg 84235c4bbdfSmrg return TRUE; 84305b261ecSmrg} 84405b261ecSmrg 84505b261ecSmrg/* 84605b261ecSmrg * Realize the currently installed colormap 84705b261ecSmrg */ 84805b261ecSmrg 84905b261ecSmrgstatic Bool 85035c4bbdfSmrgwinRealizeInstalledPaletteShadowGDI(ScreenPtr pScreen) 85105b261ecSmrg{ 85235c4bbdfSmrg winScreenPriv(pScreen); 85335c4bbdfSmrg winPrivCmapPtr pCmapPriv = NULL; 85405b261ecSmrg 85505b261ecSmrg#if CYGDEBUG 85635c4bbdfSmrg winDebug("winRealizeInstalledPaletteShadowGDI\n"); 85705b261ecSmrg#endif 85805b261ecSmrg 85935c4bbdfSmrg /* Don't do anything if there is not a colormap */ 86035c4bbdfSmrg if (pScreenPriv->pcmapInstalled == NULL) { 86105b261ecSmrg#if CYGDEBUG 86235c4bbdfSmrg winDebug("winRealizeInstalledPaletteShadowGDI - No colormap " 86335c4bbdfSmrg "installed\n"); 86405b261ecSmrg#endif 86535c4bbdfSmrg return TRUE; 86605b261ecSmrg } 86705b261ecSmrg 86835c4bbdfSmrg pCmapPriv = winGetCmapPriv(pScreenPriv->pcmapInstalled); 86935c4bbdfSmrg 87035c4bbdfSmrg /* Realize our palette for the screen */ 87135c4bbdfSmrg if (RealizePalette(pScreenPriv->hdcScreen) == GDI_ERROR) { 87235c4bbdfSmrg ErrorF("winRealizeInstalledPaletteShadowGDI - RealizePalette () " 87335c4bbdfSmrg "failed\n"); 87435c4bbdfSmrg return FALSE; 87505b261ecSmrg } 87635c4bbdfSmrg 87735c4bbdfSmrg /* Set the DIB color table */ 87835c4bbdfSmrg if (SetDIBColorTable(pScreenPriv->hdcShadow, 87935c4bbdfSmrg 0, 88035c4bbdfSmrg WIN_NUM_PALETTE_ENTRIES, pCmapPriv->rgbColors) == 0) { 88135c4bbdfSmrg ErrorF("winRealizeInstalledPaletteShadowGDI - SetDIBColorTable () " 88235c4bbdfSmrg "failed\n"); 88335c4bbdfSmrg return FALSE; 88405b261ecSmrg } 88505b261ecSmrg 88635c4bbdfSmrg return TRUE; 88735c4bbdfSmrg} 88805b261ecSmrg 88905b261ecSmrg/* 89005b261ecSmrg * Install the specified colormap 89105b261ecSmrg */ 89205b261ecSmrg 89305b261ecSmrgstatic Bool 89435c4bbdfSmrgwinInstallColormapShadowGDI(ColormapPtr pColormap) 89505b261ecSmrg{ 89635c4bbdfSmrg ScreenPtr pScreen = pColormap->pScreen; 89735c4bbdfSmrg 89835c4bbdfSmrg winScreenPriv(pScreen); 89935c4bbdfSmrg winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; 90035c4bbdfSmrg 90135c4bbdfSmrg winCmapPriv(pColormap); 90235c4bbdfSmrg 90335c4bbdfSmrg /* 90435c4bbdfSmrg * Tell Windows to install the new colormap 90535c4bbdfSmrg */ 90635c4bbdfSmrg if (SelectPalette(pScreenPriv->hdcScreen, 90735c4bbdfSmrg pCmapPriv->hPalette, FALSE) == NULL) { 90835c4bbdfSmrg ErrorF("winInstallColormapShadowGDI - SelectPalette () failed\n"); 90935c4bbdfSmrg return FALSE; 91005b261ecSmrg } 91135c4bbdfSmrg 91235c4bbdfSmrg /* Realize the palette */ 91335c4bbdfSmrg if (GDI_ERROR == RealizePalette(pScreenPriv->hdcScreen)) { 91435c4bbdfSmrg ErrorF("winInstallColormapShadowGDI - RealizePalette () failed\n"); 91535c4bbdfSmrg return FALSE; 91605b261ecSmrg } 91705b261ecSmrg 91835c4bbdfSmrg /* Set the DIB color table */ 91935c4bbdfSmrg if (SetDIBColorTable(pScreenPriv->hdcShadow, 92035c4bbdfSmrg 0, 92135c4bbdfSmrg WIN_NUM_PALETTE_ENTRIES, pCmapPriv->rgbColors) == 0) { 92235c4bbdfSmrg ErrorF("winInstallColormapShadowGDI - SetDIBColorTable () failed\n"); 92335c4bbdfSmrg return FALSE; 92405b261ecSmrg } 92505b261ecSmrg 92635c4bbdfSmrg /* Redraw the whole window, to take account for the new colors */ 92735c4bbdfSmrg BitBlt(pScreenPriv->hdcScreen, 92835c4bbdfSmrg 0, 0, 92935c4bbdfSmrg pScreenInfo->dwWidth, pScreenInfo->dwHeight, 93035c4bbdfSmrg pScreenPriv->hdcShadow, 0, 0, SRCCOPY); 93105b261ecSmrg 93235c4bbdfSmrg /* Save a pointer to the newly installed colormap */ 93335c4bbdfSmrg pScreenPriv->pcmapInstalled = pColormap; 93405b261ecSmrg 93535c4bbdfSmrg /* Redraw all windows */ 93635c4bbdfSmrg if (pScreenInfo->fMultiWindow) 93735c4bbdfSmrg EnumThreadWindows(g_dwCurrentThreadID, winRedrawAllProcShadowGDI, 0); 93805b261ecSmrg 93935c4bbdfSmrg return TRUE; 94005b261ecSmrg} 94105b261ecSmrg 94205b261ecSmrg/* 94305b261ecSmrg * Store the specified colors in the specified colormap 94405b261ecSmrg */ 94505b261ecSmrg 94605b261ecSmrgstatic Bool 94735c4bbdfSmrgwinStoreColorsShadowGDI(ColormapPtr pColormap, int ndef, xColorItem * pdefs) 94805b261ecSmrg{ 94935c4bbdfSmrg ScreenPtr pScreen = pColormap->pScreen; 95035c4bbdfSmrg 95135c4bbdfSmrg winScreenPriv(pScreen); 95235c4bbdfSmrg winCmapPriv(pColormap); 95335c4bbdfSmrg ColormapPtr curpmap = pScreenPriv->pcmapInstalled; 95435c4bbdfSmrg 95535c4bbdfSmrg /* Put the X colormap entries into the Windows logical palette */ 95635c4bbdfSmrg if (SetPaletteEntries(pCmapPriv->hPalette, 95735c4bbdfSmrg pdefs[0].pixel, 95835c4bbdfSmrg ndef, pCmapPriv->peColors + pdefs[0].pixel) == 0) { 95935c4bbdfSmrg ErrorF("winStoreColorsShadowGDI - SetPaletteEntries () failed\n"); 96035c4bbdfSmrg return FALSE; 96105b261ecSmrg } 96205b261ecSmrg 96335c4bbdfSmrg /* Don't install the Windows palette if the colormap is not installed */ 96435c4bbdfSmrg if (pColormap != curpmap) { 96535c4bbdfSmrg return TRUE; 96605b261ecSmrg } 96705b261ecSmrg 96835c4bbdfSmrg /* Try to install the newly modified colormap */ 96935c4bbdfSmrg if (!winInstallColormapShadowGDI(pColormap)) { 97035c4bbdfSmrg ErrorF("winInstallColormapShadowGDI - winInstallColormapShadowGDI " 97135c4bbdfSmrg "failed\n"); 97235c4bbdfSmrg return FALSE; 97305b261ecSmrg } 97405b261ecSmrg 97505b261ecSmrg#if 0 97635c4bbdfSmrg /* Tell Windows that the palette has changed */ 97735c4bbdfSmrg RealizePalette(pScreenPriv->hdcScreen); 97835c4bbdfSmrg 97935c4bbdfSmrg /* Set the DIB color table */ 98035c4bbdfSmrg if (SetDIBColorTable(pScreenPriv->hdcShadow, 98135c4bbdfSmrg pdefs[0].pixel, 98235c4bbdfSmrg ndef, pCmapPriv->rgbColors + pdefs[0].pixel) == 0) { 98335c4bbdfSmrg ErrorF("winInstallColormapShadowGDI - SetDIBColorTable () failed\n"); 98435c4bbdfSmrg return FALSE; 98505b261ecSmrg } 98605b261ecSmrg 98735c4bbdfSmrg /* Save a pointer to the newly installed colormap */ 98835c4bbdfSmrg pScreenPriv->pcmapInstalled = pColormap; 98905b261ecSmrg#endif 99005b261ecSmrg 99135c4bbdfSmrg return TRUE; 99205b261ecSmrg} 99305b261ecSmrg 99405b261ecSmrg/* 99505b261ecSmrg * Colormap initialization procedure 99605b261ecSmrg */ 99705b261ecSmrg 99805b261ecSmrgstatic Bool 99935c4bbdfSmrgwinCreateColormapShadowGDI(ColormapPtr pColormap) 100005b261ecSmrg{ 100135c4bbdfSmrg LPLOGPALETTE lpPaletteNew = NULL; 100235c4bbdfSmrg DWORD dwEntriesMax; 100335c4bbdfSmrg VisualPtr pVisual; 100435c4bbdfSmrg HPALETTE hpalNew = NULL; 100535c4bbdfSmrg 100635c4bbdfSmrg winCmapPriv(pColormap); 100735c4bbdfSmrg 100835c4bbdfSmrg /* Get a pointer to the visual that the colormap belongs to */ 100935c4bbdfSmrg pVisual = pColormap->pVisual; 101035c4bbdfSmrg 101135c4bbdfSmrg /* Get the maximum number of palette entries for this visual */ 101235c4bbdfSmrg dwEntriesMax = pVisual->ColormapEntries; 101335c4bbdfSmrg 101435c4bbdfSmrg /* Allocate a Windows logical color palette with max entries */ 101535c4bbdfSmrg lpPaletteNew = malloc(sizeof(LOGPALETTE) 101635c4bbdfSmrg + (dwEntriesMax - 1) * sizeof(PALETTEENTRY)); 101735c4bbdfSmrg if (lpPaletteNew == NULL) { 101835c4bbdfSmrg ErrorF("winCreateColormapShadowGDI - Couldn't allocate palette " 101935c4bbdfSmrg "with %d entries\n", (int) dwEntriesMax); 102035c4bbdfSmrg return FALSE; 102105b261ecSmrg } 102205b261ecSmrg 102335c4bbdfSmrg /* Zero out the colormap */ 102435c4bbdfSmrg ZeroMemory(lpPaletteNew, sizeof(LOGPALETTE) 102535c4bbdfSmrg + (dwEntriesMax - 1) * sizeof(PALETTEENTRY)); 102635c4bbdfSmrg 102735c4bbdfSmrg /* Set the logical palette structure */ 102835c4bbdfSmrg lpPaletteNew->palVersion = 0x0300; 102935c4bbdfSmrg lpPaletteNew->palNumEntries = dwEntriesMax; 103035c4bbdfSmrg 103135c4bbdfSmrg /* Tell Windows to create the palette */ 103235c4bbdfSmrg hpalNew = CreatePalette(lpPaletteNew); 103335c4bbdfSmrg if (hpalNew == NULL) { 103435c4bbdfSmrg ErrorF("winCreateColormapShadowGDI - CreatePalette () failed\n"); 103535c4bbdfSmrg free(lpPaletteNew); 103635c4bbdfSmrg return FALSE; 103705b261ecSmrg } 103805b261ecSmrg 103935c4bbdfSmrg /* Save the Windows logical palette handle in the X colormaps' privates */ 104035c4bbdfSmrg pCmapPriv->hPalette = hpalNew; 104105b261ecSmrg 104235c4bbdfSmrg /* Free the palette initialization memory */ 104335c4bbdfSmrg free(lpPaletteNew); 104405b261ecSmrg 104535c4bbdfSmrg return TRUE; 104605b261ecSmrg} 104705b261ecSmrg 104805b261ecSmrg/* 104905b261ecSmrg * Colormap destruction procedure 105005b261ecSmrg */ 105105b261ecSmrg 105205b261ecSmrgstatic Bool 105335c4bbdfSmrgwinDestroyColormapShadowGDI(ColormapPtr pColormap) 105405b261ecSmrg{ 105535c4bbdfSmrg winScreenPriv(pColormap->pScreen); 105635c4bbdfSmrg winCmapPriv(pColormap); 105735c4bbdfSmrg 105835c4bbdfSmrg /* 105935c4bbdfSmrg * Is colormap to be destroyed the default? 106035c4bbdfSmrg * 106135c4bbdfSmrg * Non-default colormaps should have had winUninstallColormap 106235c4bbdfSmrg * called on them before we get here. The default colormap 106335c4bbdfSmrg * will not have had winUninstallColormap called on it. Thus, 106435c4bbdfSmrg * we need to handle the default colormap in a special way. 106535c4bbdfSmrg */ 106635c4bbdfSmrg if (pColormap->flags & IsDefault) { 106705b261ecSmrg#if CYGDEBUG 106835c4bbdfSmrg winDebug("winDestroyColormapShadowGDI - Destroying default " 106935c4bbdfSmrg "colormap\n"); 107005b261ecSmrg#endif 107135c4bbdfSmrg 107235c4bbdfSmrg /* 107335c4bbdfSmrg * FIXME: Walk the list of all screens, popping the default 107435c4bbdfSmrg * palette out of each screen device context. 107535c4bbdfSmrg */ 107635c4bbdfSmrg 107735c4bbdfSmrg /* Pop the palette out of the device context */ 107835c4bbdfSmrg SelectPalette(pScreenPriv->hdcScreen, 107935c4bbdfSmrg GetStockObject(DEFAULT_PALETTE), FALSE); 108035c4bbdfSmrg 108135c4bbdfSmrg /* Clear our private installed colormap pointer */ 108235c4bbdfSmrg pScreenPriv->pcmapInstalled = NULL; 108305b261ecSmrg } 108435c4bbdfSmrg 108535c4bbdfSmrg /* Try to delete the logical palette */ 108635c4bbdfSmrg if (DeleteObject(pCmapPriv->hPalette) == 0) { 108735c4bbdfSmrg ErrorF("winDestroyColormap - DeleteObject () failed\n"); 108835c4bbdfSmrg return FALSE; 108905b261ecSmrg } 109005b261ecSmrg 109135c4bbdfSmrg /* Invalidate the colormap privates */ 109235c4bbdfSmrg pCmapPriv->hPalette = NULL; 109305b261ecSmrg 109435c4bbdfSmrg return TRUE; 109535c4bbdfSmrg} 109605b261ecSmrg 109705b261ecSmrg/* 109805b261ecSmrg * Set engine specific funtions 109905b261ecSmrg */ 110005b261ecSmrg 110105b261ecSmrgBool 110235c4bbdfSmrgwinSetEngineFunctionsShadowGDI(ScreenPtr pScreen) 110305b261ecSmrg{ 110435c4bbdfSmrg winScreenPriv(pScreen); 110535c4bbdfSmrg winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; 110635c4bbdfSmrg 110735c4bbdfSmrg /* Set our pointers */ 110835c4bbdfSmrg pScreenPriv->pwinAllocateFB = winAllocateFBShadowGDI; 110935c4bbdfSmrg pScreenPriv->pwinFreeFB = winFreeFBShadowGDI; 111035c4bbdfSmrg pScreenPriv->pwinShadowUpdate = winShadowUpdateGDI; 111135c4bbdfSmrg pScreenPriv->pwinInitScreen = winInitScreenShadowGDI; 111235c4bbdfSmrg pScreenPriv->pwinCloseScreen = winCloseScreenShadowGDI; 111335c4bbdfSmrg pScreenPriv->pwinInitVisuals = winInitVisualsShadowGDI; 111435c4bbdfSmrg pScreenPriv->pwinAdjustVideoMode = winAdjustVideoModeShadowGDI; 111535c4bbdfSmrg if (pScreenInfo->fFullScreen) 111635c4bbdfSmrg pScreenPriv->pwinCreateBoundingWindow = 111735c4bbdfSmrg winCreateBoundingWindowFullScreen; 111835c4bbdfSmrg else 111935c4bbdfSmrg pScreenPriv->pwinCreateBoundingWindow = winCreateBoundingWindowWindowed; 112035c4bbdfSmrg pScreenPriv->pwinFinishScreenInit = winFinishScreenInitFB; 112135c4bbdfSmrg pScreenPriv->pwinBltExposedRegions = winBltExposedRegionsShadowGDI; 112235c4bbdfSmrg pScreenPriv->pwinActivateApp = winActivateAppShadowGDI; 112335c4bbdfSmrg pScreenPriv->pwinRedrawScreen = winRedrawScreenShadowGDI; 112435c4bbdfSmrg pScreenPriv->pwinRealizeInstalledPalette = 112535c4bbdfSmrg winRealizeInstalledPaletteShadowGDI; 112635c4bbdfSmrg pScreenPriv->pwinInstallColormap = winInstallColormapShadowGDI; 112735c4bbdfSmrg pScreenPriv->pwinStoreColors = winStoreColorsShadowGDI; 112835c4bbdfSmrg pScreenPriv->pwinCreateColormap = winCreateColormapShadowGDI; 112935c4bbdfSmrg pScreenPriv->pwinDestroyColormap = winDestroyColormapShadowGDI; 11301b5d61b8Smrg pScreenPriv->pwinCreatePrimarySurface = NULL; 11311b5d61b8Smrg pScreenPriv->pwinReleasePrimarySurface = NULL; 113205b261ecSmrg 113335c4bbdfSmrg return TRUE; 113405b261ecSmrg} 1135