winshadgdi.c revision 35c4bbdf
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 4005b261ecSmrg#ifdef XWIN_MULTIWINDOW 4135c4bbdfSmrgstatic wBOOL CALLBACK winRedrawAllProcShadowGDI(HWND hwnd, LPARAM lParam); 4205b261ecSmrg 4335c4bbdfSmrgstatic wBOOL CALLBACK winRedrawDamagedWindowShadowGDI(HWND hwnd, LPARAM lParam); 4405b261ecSmrg#endif 4505b261ecSmrg 4605b261ecSmrgstatic Bool 4735c4bbdfSmrg winAllocateFBShadowGDI(ScreenPtr pScreen); 4805b261ecSmrg 4905b261ecSmrgstatic void 5035c4bbdfSmrg winShadowUpdateGDI(ScreenPtr pScreen, shadowBufPtr pBuf); 5105b261ecSmrg 5205b261ecSmrgstatic Bool 5335c4bbdfSmrg winCloseScreenShadowGDI(ScreenPtr pScreen); 5405b261ecSmrg 5505b261ecSmrgstatic Bool 5635c4bbdfSmrg winInitVisualsShadowGDI(ScreenPtr pScreen); 5705b261ecSmrg 5805b261ecSmrgstatic Bool 5935c4bbdfSmrg winAdjustVideoModeShadowGDI(ScreenPtr pScreen); 6005b261ecSmrg 6105b261ecSmrgstatic Bool 6235c4bbdfSmrg winBltExposedRegionsShadowGDI(ScreenPtr pScreen); 6305b261ecSmrg 6405b261ecSmrgstatic Bool 6535c4bbdfSmrg winActivateAppShadowGDI(ScreenPtr pScreen); 6605b261ecSmrg 6705b261ecSmrgstatic Bool 6835c4bbdfSmrg winRedrawScreenShadowGDI(ScreenPtr pScreen); 6905b261ecSmrg 7005b261ecSmrgstatic Bool 7135c4bbdfSmrg winRealizeInstalledPaletteShadowGDI(ScreenPtr pScreen); 7205b261ecSmrg 7305b261ecSmrgstatic Bool 7435c4bbdfSmrg winInstallColormapShadowGDI(ColormapPtr pColormap); 7505b261ecSmrg 7605b261ecSmrgstatic Bool 7735c4bbdfSmrg winStoreColorsShadowGDI(ColormapPtr pmap, int ndef, xColorItem * pdefs); 7805b261ecSmrg 7905b261ecSmrgstatic Bool 8035c4bbdfSmrg winCreateColormapShadowGDI(ColormapPtr pColormap); 8105b261ecSmrg 8205b261ecSmrgstatic Bool 8335c4bbdfSmrg winDestroyColormapShadowGDI(ColormapPtr pColormap); 8405b261ecSmrg 8505b261ecSmrg/* 8605b261ecSmrg * Internal function to get the DIB format that is compatible with the screen 8705b261ecSmrg */ 8805b261ecSmrg 8905b261ecSmrgstatic 9035c4bbdfSmrg Bool 9135c4bbdfSmrgwinQueryScreenDIBFormat(ScreenPtr pScreen, BITMAPINFOHEADER * pbmih) 9205b261ecSmrg{ 9335c4bbdfSmrg winScreenPriv(pScreen); 9435c4bbdfSmrg HBITMAP hbmp; 9535c4bbdfSmrg 9605b261ecSmrg#if CYGDEBUG 9735c4bbdfSmrg LPDWORD pdw = NULL; 9805b261ecSmrg#endif 9935c4bbdfSmrg 10035c4bbdfSmrg /* Create a memory bitmap compatible with the screen */ 10135c4bbdfSmrg hbmp = CreateCompatibleBitmap(pScreenPriv->hdcScreen, 1, 1); 10235c4bbdfSmrg if (hbmp == NULL) { 10335c4bbdfSmrg ErrorF("winQueryScreenDIBFormat - CreateCompatibleBitmap failed\n"); 10435c4bbdfSmrg return FALSE; 10505b261ecSmrg } 10635c4bbdfSmrg 10735c4bbdfSmrg /* Initialize our bitmap info header */ 10835c4bbdfSmrg ZeroMemory(pbmih, sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD)); 10935c4bbdfSmrg pbmih->biSize = sizeof(BITMAPINFOHEADER); 11035c4bbdfSmrg 11135c4bbdfSmrg /* Get the biBitCount */ 11235c4bbdfSmrg if (!GetDIBits(pScreenPriv->hdcScreen, 11335c4bbdfSmrg hbmp, 0, 1, NULL, (BITMAPINFO *) pbmih, DIB_RGB_COLORS)) { 11435c4bbdfSmrg ErrorF("winQueryScreenDIBFormat - First call to GetDIBits failed\n"); 11535c4bbdfSmrg DeleteObject(hbmp); 11635c4bbdfSmrg return FALSE; 11705b261ecSmrg } 11805b261ecSmrg 11905b261ecSmrg#if CYGDEBUG 12035c4bbdfSmrg /* Get a pointer to bitfields */ 12135c4bbdfSmrg pdw = (DWORD *) ((CARD8 *) pbmih + sizeof(BITMAPINFOHEADER)); 12205b261ecSmrg 12335c4bbdfSmrg winDebug("winQueryScreenDIBFormat - First call masks: %08x %08x %08x\n", 12435c4bbdfSmrg (unsigned int)pdw[0], (unsigned int)pdw[1], (unsigned int)pdw[2]); 12505b261ecSmrg#endif 12605b261ecSmrg 12735c4bbdfSmrg /* Get optimal color table, or the optimal bitfields */ 12835c4bbdfSmrg if (!GetDIBits(pScreenPriv->hdcScreen, 12935c4bbdfSmrg hbmp, 0, 1, NULL, (BITMAPINFO *) pbmih, DIB_RGB_COLORS)) { 13035c4bbdfSmrg ErrorF("winQueryScreenDIBFormat - Second call to GetDIBits " 13135c4bbdfSmrg "failed\n"); 13235c4bbdfSmrg DeleteObject(hbmp); 13335c4bbdfSmrg return FALSE; 13405b261ecSmrg } 13505b261ecSmrg 13635c4bbdfSmrg /* Free memory */ 13735c4bbdfSmrg DeleteObject(hbmp); 13805b261ecSmrg 13935c4bbdfSmrg return TRUE; 14035c4bbdfSmrg} 14105b261ecSmrg 14205b261ecSmrg/* 14305b261ecSmrg * Internal function to determine the GDI bits per rgb and bit masks 14405b261ecSmrg */ 14505b261ecSmrg 14605b261ecSmrgstatic 14735c4bbdfSmrg Bool 14835c4bbdfSmrgwinQueryRGBBitsAndMasks(ScreenPtr pScreen) 14905b261ecSmrg{ 15035c4bbdfSmrg winScreenPriv(pScreen); 15135c4bbdfSmrg BITMAPINFOHEADER *pbmih = NULL; 15235c4bbdfSmrg Bool fReturn = TRUE; 15335c4bbdfSmrg LPDWORD pdw = NULL; 15435c4bbdfSmrg DWORD dwRedBits, dwGreenBits, dwBlueBits; 15535c4bbdfSmrg 15635c4bbdfSmrg /* Color masks for 8 bpp are standardized */ 15735c4bbdfSmrg if (GetDeviceCaps(pScreenPriv->hdcScreen, RASTERCAPS) & RC_PALETTE) { 15835c4bbdfSmrg /* 15935c4bbdfSmrg * RGB BPP for 8 bit palletes is always 8 16035c4bbdfSmrg * and the color masks are always 0. 16135c4bbdfSmrg */ 16235c4bbdfSmrg pScreenPriv->dwBitsPerRGB = 8; 16335c4bbdfSmrg pScreenPriv->dwRedMask = 0x0L; 16435c4bbdfSmrg pScreenPriv->dwGreenMask = 0x0L; 16535c4bbdfSmrg pScreenPriv->dwBlueMask = 0x0L; 16635c4bbdfSmrg return TRUE; 16705b261ecSmrg } 16805b261ecSmrg 16935c4bbdfSmrg /* Color masks for 24 bpp are standardized */ 17035c4bbdfSmrg if (GetDeviceCaps(pScreenPriv->hdcScreen, PLANES) 17135c4bbdfSmrg * GetDeviceCaps(pScreenPriv->hdcScreen, BITSPIXEL) == 24) { 17235c4bbdfSmrg ErrorF("winQueryRGBBitsAndMasks - GetDeviceCaps (BITSPIXEL) " 17335c4bbdfSmrg "returned 24 for the screen. Using default 24bpp masks.\n"); 17435c4bbdfSmrg 17535c4bbdfSmrg /* 8 bits per primary color */ 17635c4bbdfSmrg pScreenPriv->dwBitsPerRGB = 8; 17735c4bbdfSmrg 17835c4bbdfSmrg /* Set screen privates masks */ 17935c4bbdfSmrg pScreenPriv->dwRedMask = WIN_24BPP_MASK_RED; 18035c4bbdfSmrg pScreenPriv->dwGreenMask = WIN_24BPP_MASK_GREEN; 18135c4bbdfSmrg pScreenPriv->dwBlueMask = WIN_24BPP_MASK_BLUE; 18235c4bbdfSmrg 18335c4bbdfSmrg return TRUE; 18405b261ecSmrg } 18505b261ecSmrg 18635c4bbdfSmrg /* Allocate a bitmap header and color table */ 18735c4bbdfSmrg pbmih = malloc(sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD)); 18835c4bbdfSmrg if (pbmih == NULL) { 18935c4bbdfSmrg ErrorF("winQueryRGBBitsAndMasks - malloc failed\n"); 19035c4bbdfSmrg return FALSE; 19105b261ecSmrg } 19205b261ecSmrg 19335c4bbdfSmrg /* Get screen description */ 19435c4bbdfSmrg if (winQueryScreenDIBFormat(pScreen, pbmih)) { 19535c4bbdfSmrg /* Get a pointer to bitfields */ 19635c4bbdfSmrg pdw = (DWORD *) ((CARD8 *) pbmih + sizeof(BITMAPINFOHEADER)); 19735c4bbdfSmrg 19805b261ecSmrg#if CYGDEBUG 19935c4bbdfSmrg winDebug("%s - Masks: %08x %08x %08x\n", __FUNCTION__, 20035c4bbdfSmrg (unsigned int)pdw[0], (unsigned int)pdw[1], (unsigned int)pdw[2]); 20135c4bbdfSmrg winDebug("%s - Bitmap: %dx%d %d bpp %d planes\n", __FUNCTION__, 20235c4bbdfSmrg (int)pbmih->biWidth, (int)pbmih->biHeight, pbmih->biBitCount, 20335c4bbdfSmrg pbmih->biPlanes); 20435c4bbdfSmrg winDebug("%s - Compression: %u %s\n", __FUNCTION__, 20535c4bbdfSmrg (unsigned int)pbmih->biCompression, 20635c4bbdfSmrg (pbmih->biCompression == 20735c4bbdfSmrg BI_RGB ? "(BI_RGB)" : (pbmih->biCompression == 20835c4bbdfSmrg BI_RLE8 ? "(BI_RLE8)" : (pbmih-> 20935c4bbdfSmrg biCompression 21035c4bbdfSmrg == 21135c4bbdfSmrg BI_RLE4 ? 21235c4bbdfSmrg "(BI_RLE4)" 21335c4bbdfSmrg : (pbmih-> 21435c4bbdfSmrg biCompression 21535c4bbdfSmrg == 21635c4bbdfSmrg BI_BITFIELDS 21735c4bbdfSmrg ? 21835c4bbdfSmrg "(BI_BITFIELDS)" 21935c4bbdfSmrg : ""))))); 22005b261ecSmrg#endif 22105b261ecSmrg 22235c4bbdfSmrg /* Handle BI_RGB case, which is returned by Wine */ 22335c4bbdfSmrg if (pbmih->biCompression == BI_RGB) { 22435c4bbdfSmrg dwRedBits = 5; 22535c4bbdfSmrg dwGreenBits = 5; 22635c4bbdfSmrg dwBlueBits = 5; 22735c4bbdfSmrg 22835c4bbdfSmrg pScreenPriv->dwBitsPerRGB = 5; 22935c4bbdfSmrg 23035c4bbdfSmrg /* Set screen privates masks */ 23135c4bbdfSmrg pScreenPriv->dwRedMask = 0x7c00; 23235c4bbdfSmrg pScreenPriv->dwGreenMask = 0x03e0; 23335c4bbdfSmrg pScreenPriv->dwBlueMask = 0x001f; 23435c4bbdfSmrg } 23535c4bbdfSmrg else { 23635c4bbdfSmrg /* Count the number of bits in each mask */ 23735c4bbdfSmrg dwRedBits = winCountBits(pdw[0]); 23835c4bbdfSmrg dwGreenBits = winCountBits(pdw[1]); 23935c4bbdfSmrg dwBlueBits = winCountBits(pdw[2]); 24035c4bbdfSmrg 24135c4bbdfSmrg /* Find maximum bits per red, green, blue */ 24235c4bbdfSmrg if (dwRedBits > dwGreenBits && dwRedBits > dwBlueBits) 24335c4bbdfSmrg pScreenPriv->dwBitsPerRGB = dwRedBits; 24435c4bbdfSmrg else if (dwGreenBits > dwRedBits && dwGreenBits > dwBlueBits) 24535c4bbdfSmrg pScreenPriv->dwBitsPerRGB = dwGreenBits; 24635c4bbdfSmrg else 24735c4bbdfSmrg pScreenPriv->dwBitsPerRGB = dwBlueBits; 24835c4bbdfSmrg 24935c4bbdfSmrg /* Set screen privates masks */ 25035c4bbdfSmrg pScreenPriv->dwRedMask = pdw[0]; 25135c4bbdfSmrg pScreenPriv->dwGreenMask = pdw[1]; 25235c4bbdfSmrg pScreenPriv->dwBlueMask = pdw[2]; 25305b261ecSmrg } 25405b261ecSmrg } 25535c4bbdfSmrg else { 25635c4bbdfSmrg ErrorF("winQueryRGBBitsAndMasks - winQueryScreenDIBFormat failed\n"); 25735c4bbdfSmrg fReturn = FALSE; 25805b261ecSmrg } 25905b261ecSmrg 26035c4bbdfSmrg /* Free memory */ 26135c4bbdfSmrg free(pbmih); 26205b261ecSmrg 26335c4bbdfSmrg return fReturn; 26405b261ecSmrg} 26505b261ecSmrg 26605b261ecSmrg#ifdef XWIN_MULTIWINDOW 26705b261ecSmrg/* 26805b261ecSmrg * Redraw all ---? 26905b261ecSmrg */ 27005b261ecSmrg 27105b261ecSmrgstatic wBOOL CALLBACK 27235c4bbdfSmrgwinRedrawAllProcShadowGDI(HWND hwnd, LPARAM lParam) 27305b261ecSmrg{ 27435c4bbdfSmrg if (hwnd == (HWND) lParam) 27535c4bbdfSmrg return TRUE; 27635c4bbdfSmrg InvalidateRect(hwnd, NULL, FALSE); 27735c4bbdfSmrg UpdateWindow(hwnd); 27835c4bbdfSmrg return TRUE; 27905b261ecSmrg} 28005b261ecSmrg 28105b261ecSmrgstatic wBOOL CALLBACK 28235c4bbdfSmrgwinRedrawDamagedWindowShadowGDI(HWND hwnd, LPARAM lParam) 28305b261ecSmrg{ 28435c4bbdfSmrg BoxPtr pDamage = (BoxPtr) lParam; 28535c4bbdfSmrg RECT rcClient, rcDamage, rcRedraw; 28635c4bbdfSmrg POINT topLeft, bottomRight; 28735c4bbdfSmrg 28835c4bbdfSmrg if (IsIconic(hwnd)) 28935c4bbdfSmrg return TRUE; /* Don't care minimized windows */ 29035c4bbdfSmrg 29135c4bbdfSmrg /* Convert the damaged area from Screen coords to Client coords */ 29235c4bbdfSmrg topLeft.x = pDamage->x1; 29335c4bbdfSmrg topLeft.y = pDamage->y1; 29435c4bbdfSmrg bottomRight.x = pDamage->x2; 29535c4bbdfSmrg bottomRight.y = pDamage->y2; 29635c4bbdfSmrg topLeft.x += GetSystemMetrics(SM_XVIRTUALSCREEN); 29735c4bbdfSmrg bottomRight.x += GetSystemMetrics(SM_XVIRTUALSCREEN); 29835c4bbdfSmrg topLeft.y += GetSystemMetrics(SM_YVIRTUALSCREEN); 29935c4bbdfSmrg bottomRight.y += GetSystemMetrics(SM_YVIRTUALSCREEN); 30035c4bbdfSmrg ScreenToClient(hwnd, &topLeft); 30135c4bbdfSmrg ScreenToClient(hwnd, &bottomRight); 30235c4bbdfSmrg SetRect(&rcDamage, topLeft.x, topLeft.y, bottomRight.x, bottomRight.y); 30335c4bbdfSmrg 30435c4bbdfSmrg GetClientRect(hwnd, &rcClient); 30535c4bbdfSmrg 30635c4bbdfSmrg if (IntersectRect(&rcRedraw, &rcClient, &rcDamage)) { 30735c4bbdfSmrg InvalidateRect(hwnd, &rcRedraw, FALSE); 30835c4bbdfSmrg UpdateWindow(hwnd); 30905b261ecSmrg } 31035c4bbdfSmrg return TRUE; 31105b261ecSmrg} 31205b261ecSmrg#endif 31305b261ecSmrg 31405b261ecSmrg/* 31505b261ecSmrg * Allocate a DIB for the shadow framebuffer GDI server 31605b261ecSmrg */ 31705b261ecSmrg 31805b261ecSmrgstatic Bool 31935c4bbdfSmrgwinAllocateFBShadowGDI(ScreenPtr pScreen) 32005b261ecSmrg{ 32135c4bbdfSmrg winScreenPriv(pScreen); 32235c4bbdfSmrg winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; 32335c4bbdfSmrg DIBSECTION dibsection; 32435c4bbdfSmrg Bool fReturn = TRUE; 32535c4bbdfSmrg 32635c4bbdfSmrg /* Describe shadow bitmap to be created */ 32735c4bbdfSmrg pScreenPriv->pbmih->biWidth = pScreenInfo->dwWidth; 32835c4bbdfSmrg pScreenPriv->pbmih->biHeight = -pScreenInfo->dwHeight; 32935c4bbdfSmrg 33035c4bbdfSmrg ErrorF("winAllocateFBShadowGDI - Creating DIB with width: %d height: %d " 33135c4bbdfSmrg "depth: %d\n", 33235c4bbdfSmrg (int) pScreenPriv->pbmih->biWidth, 33335c4bbdfSmrg (int) -pScreenPriv->pbmih->biHeight, pScreenPriv->pbmih->biBitCount); 33435c4bbdfSmrg 33535c4bbdfSmrg /* Create a DI shadow bitmap with a bit pointer */ 33635c4bbdfSmrg pScreenPriv->hbmpShadow = CreateDIBSection(pScreenPriv->hdcScreen, 33735c4bbdfSmrg (BITMAPINFO *) pScreenPriv-> 33835c4bbdfSmrg pbmih, DIB_RGB_COLORS, 33935c4bbdfSmrg (VOID **) &pScreenInfo->pfb, 34035c4bbdfSmrg NULL, 0); 34135c4bbdfSmrg if (pScreenPriv->hbmpShadow == NULL || pScreenInfo->pfb == NULL) { 34235c4bbdfSmrg winW32Error(2, "winAllocateFBShadowGDI - CreateDIBSection failed:"); 34335c4bbdfSmrg return FALSE; 34405b261ecSmrg } 34535c4bbdfSmrg else { 34605b261ecSmrg#if CYGDEBUG 34735c4bbdfSmrg winDebug("winAllocateFBShadowGDI - Shadow buffer allocated\n"); 34805b261ecSmrg#endif 34905b261ecSmrg } 35005b261ecSmrg 35135c4bbdfSmrg /* Get information about the bitmap that was allocated */ 35235c4bbdfSmrg GetObject(pScreenPriv->hbmpShadow, sizeof(dibsection), &dibsection); 35305b261ecSmrg 35405b261ecSmrg#if CYGDEBUG || YES 35535c4bbdfSmrg /* Print information about bitmap allocated */ 35635c4bbdfSmrg winDebug("winAllocateFBShadowGDI - Dibsection width: %d height: %d " 35735c4bbdfSmrg "depth: %d size image: %d\n", 35835c4bbdfSmrg (int) dibsection.dsBmih.biWidth, (int) dibsection.dsBmih.biHeight, 35935c4bbdfSmrg dibsection.dsBmih.biBitCount, (int) dibsection.dsBmih.biSizeImage); 36005b261ecSmrg#endif 36105b261ecSmrg 36235c4bbdfSmrg /* Select the shadow bitmap into the shadow DC */ 36335c4bbdfSmrg SelectObject(pScreenPriv->hdcShadow, pScreenPriv->hbmpShadow); 36405b261ecSmrg 36505b261ecSmrg#if CYGDEBUG 36635c4bbdfSmrg winDebug("winAllocateFBShadowGDI - Attempting a shadow blit\n"); 36705b261ecSmrg#endif 36805b261ecSmrg 36935c4bbdfSmrg /* Do a test blit from the shadow to the screen, I think */ 37035c4bbdfSmrg fReturn = BitBlt(pScreenPriv->hdcScreen, 37135c4bbdfSmrg 0, 0, 37235c4bbdfSmrg pScreenInfo->dwWidth, pScreenInfo->dwHeight, 37335c4bbdfSmrg pScreenPriv->hdcShadow, 0, 0, SRCCOPY); 37435c4bbdfSmrg if (fReturn) { 37505b261ecSmrg#if CYGDEBUG 37635c4bbdfSmrg winDebug("winAllocateFBShadowGDI - Shadow blit success\n"); 37705b261ecSmrg#endif 37805b261ecSmrg } 37935c4bbdfSmrg else { 38035c4bbdfSmrg winW32Error(2, "winAllocateFBShadowGDI - Shadow blit failure\n"); 38135c4bbdfSmrg#if 0 38235c4bbdfSmrg return FALSE; 38335c4bbdfSmrg#else 38435c4bbdfSmrg /* ago: ignore this error. The blit fails with wine, but does not 38535c4bbdfSmrg * cause any problems later. */ 38635c4bbdfSmrg 38735c4bbdfSmrg fReturn = TRUE; 38835c4bbdfSmrg#endif 38905b261ecSmrg } 39005b261ecSmrg 39135c4bbdfSmrg /* Look for height weirdness */ 39235c4bbdfSmrg if (dibsection.dsBmih.biHeight < 0) { 39335c4bbdfSmrg dibsection.dsBmih.biHeight = -dibsection.dsBmih.biHeight; 39405b261ecSmrg } 39505b261ecSmrg 39635c4bbdfSmrg /* Set screeninfo stride */ 39735c4bbdfSmrg pScreenInfo->dwStride = ((dibsection.dsBmih.biSizeImage 39835c4bbdfSmrg / dibsection.dsBmih.biHeight) 39935c4bbdfSmrg * 8) / pScreenInfo->dwBPP; 40005b261ecSmrg 40105b261ecSmrg#if CYGDEBUG || YES 40235c4bbdfSmrg winDebug("winAllocateFBShadowGDI - Created shadow stride: %d\n", 40335c4bbdfSmrg (int) pScreenInfo->dwStride); 40405b261ecSmrg#endif 40505b261ecSmrg 40605b261ecSmrg#ifdef XWIN_MULTIWINDOW 40735c4bbdfSmrg /* Redraw all windows */ 40835c4bbdfSmrg if (pScreenInfo->fMultiWindow) 40935c4bbdfSmrg EnumThreadWindows(g_dwCurrentThreadID, winRedrawAllProcShadowGDI, 0); 41005b261ecSmrg#endif 41105b261ecSmrg 41235c4bbdfSmrg return fReturn; 41305b261ecSmrg} 41405b261ecSmrg 4159ace9065Smrgstatic void 41635c4bbdfSmrgwinFreeFBShadowGDI(ScreenPtr pScreen) 4179ace9065Smrg{ 41835c4bbdfSmrg winScreenPriv(pScreen); 41935c4bbdfSmrg winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; 4209ace9065Smrg 42135c4bbdfSmrg /* Free the shadow bitmap */ 42235c4bbdfSmrg DeleteObject(pScreenPriv->hbmpShadow); 4239ace9065Smrg 42435c4bbdfSmrg /* Invalidate the ScreenInfo's fb pointer */ 42535c4bbdfSmrg pScreenInfo->pfb = NULL; 4269ace9065Smrg} 42705b261ecSmrg 42805b261ecSmrg/* 42905b261ecSmrg * Blit the damaged regions of the shadow fb to the screen 43005b261ecSmrg */ 43105b261ecSmrg 43205b261ecSmrgstatic void 43335c4bbdfSmrgwinShadowUpdateGDI(ScreenPtr pScreen, shadowBufPtr pBuf) 43405b261ecSmrg{ 43535c4bbdfSmrg winScreenPriv(pScreen); 43635c4bbdfSmrg winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; 43735c4bbdfSmrg RegionPtr damage = shadowDamage(pBuf); 43835c4bbdfSmrg DWORD dwBox = RegionNumRects(damage); 43935c4bbdfSmrg BoxPtr pBox = RegionRects(damage); 44035c4bbdfSmrg int x, y, w, h; 44135c4bbdfSmrg HRGN hrgnCombined = NULL; 44235c4bbdfSmrg 44305b261ecSmrg#ifdef XWIN_UPDATESTATS 44435c4bbdfSmrg static DWORD s_dwNonUnitRegions = 0; 44535c4bbdfSmrg static DWORD s_dwTotalUpdates = 0; 44635c4bbdfSmrg static DWORD s_dwTotalBoxes = 0; 44705b261ecSmrg#endif 44835c4bbdfSmrg BoxPtr pBoxExtents = RegionExtents(damage); 44905b261ecSmrg 45035c4bbdfSmrg /* 45135c4bbdfSmrg * Return immediately if the app is not active 45235c4bbdfSmrg * and we are fullscreen, or if we have a bad display depth 45335c4bbdfSmrg */ 45435c4bbdfSmrg if ((!pScreenPriv->fActive && pScreenInfo->fFullScreen) 45535c4bbdfSmrg || pScreenPriv->fBadDepth) 45635c4bbdfSmrg return; 45705b261ecSmrg 45805b261ecSmrg#ifdef XWIN_UPDATESTATS 45935c4bbdfSmrg ++s_dwTotalUpdates; 46035c4bbdfSmrg s_dwTotalBoxes += dwBox; 46105b261ecSmrg 46235c4bbdfSmrg if (dwBox != 1) { 46335c4bbdfSmrg ++s_dwNonUnitRegions; 46435c4bbdfSmrg ErrorF("winShadowUpdatGDI - dwBox: %d\n", dwBox); 46505b261ecSmrg } 46635c4bbdfSmrg 46735c4bbdfSmrg if ((s_dwTotalUpdates % 100) == 0) 46835c4bbdfSmrg ErrorF("winShadowUpdateGDI - %d%% non-unity regions, avg boxes: %d " 46935c4bbdfSmrg "nu: %d tu: %d\n", 47035c4bbdfSmrg (s_dwNonUnitRegions * 100) / s_dwTotalUpdates, 47135c4bbdfSmrg s_dwTotalBoxes / s_dwTotalUpdates, 47235c4bbdfSmrg s_dwNonUnitRegions, s_dwTotalUpdates); 47335c4bbdfSmrg#endif /* XWIN_UPDATESTATS */ 47435c4bbdfSmrg 47535c4bbdfSmrg /* 47635c4bbdfSmrg * Handle small regions with multiple blits, 47735c4bbdfSmrg * handle large regions by creating a clipping region and 47835c4bbdfSmrg * doing a single blit constrained to that clipping region. 47935c4bbdfSmrg */ 48035c4bbdfSmrg if (!pScreenInfo->fMultiWindow && 48135c4bbdfSmrg (pScreenInfo->dwClipUpdatesNBoxes == 0 || 48235c4bbdfSmrg dwBox < pScreenInfo->dwClipUpdatesNBoxes)) { 48335c4bbdfSmrg /* Loop through all boxes in the damaged region */ 48435c4bbdfSmrg while (dwBox--) { 48535c4bbdfSmrg /* 48635c4bbdfSmrg * Calculate x offset, y offset, width, and height for 48735c4bbdfSmrg * current damage box 48835c4bbdfSmrg */ 48935c4bbdfSmrg x = pBox->x1; 49035c4bbdfSmrg y = pBox->y1; 49135c4bbdfSmrg w = pBox->x2 - pBox->x1; 49235c4bbdfSmrg h = pBox->y2 - pBox->y1; 49335c4bbdfSmrg 49435c4bbdfSmrg BitBlt(pScreenPriv->hdcScreen, 49535c4bbdfSmrg x, y, w, h, pScreenPriv->hdcShadow, x, y, SRCCOPY); 49635c4bbdfSmrg 49735c4bbdfSmrg /* Get a pointer to the next box */ 49835c4bbdfSmrg ++pBox; 49935c4bbdfSmrg } 50005b261ecSmrg } 50135c4bbdfSmrg else if (!pScreenInfo->fMultiWindow) { 50235c4bbdfSmrg 50335c4bbdfSmrg /* Compute a GDI region from the damaged region */ 50435c4bbdfSmrg hrgnCombined = 50535c4bbdfSmrg CreateRectRgn(pBoxExtents->x1, pBoxExtents->y1, pBoxExtents->x2, 50635c4bbdfSmrg pBoxExtents->y2); 50735c4bbdfSmrg 50835c4bbdfSmrg /* Install the GDI region as a clipping region */ 50935c4bbdfSmrg SelectClipRgn(pScreenPriv->hdcScreen, hrgnCombined); 51035c4bbdfSmrg DeleteObject(hrgnCombined); 51135c4bbdfSmrg hrgnCombined = NULL; 51235c4bbdfSmrg 51335c4bbdfSmrg /* 51435c4bbdfSmrg * Blit the shadow buffer to the screen, 51535c4bbdfSmrg * constrained to the clipping region. 51635c4bbdfSmrg */ 51735c4bbdfSmrg BitBlt(pScreenPriv->hdcScreen, 51835c4bbdfSmrg pBoxExtents->x1, pBoxExtents->y1, 51935c4bbdfSmrg pBoxExtents->x2 - pBoxExtents->x1, 52035c4bbdfSmrg pBoxExtents->y2 - pBoxExtents->y1, 52135c4bbdfSmrg pScreenPriv->hdcShadow, 52235c4bbdfSmrg pBoxExtents->x1, pBoxExtents->y1, SRCCOPY); 52335c4bbdfSmrg 52435c4bbdfSmrg /* Reset the clip region */ 52535c4bbdfSmrg SelectClipRgn(pScreenPriv->hdcScreen, NULL); 52605b261ecSmrg } 52705b261ecSmrg 52805b261ecSmrg#ifdef XWIN_MULTIWINDOW 52935c4bbdfSmrg /* Redraw all multiwindow windows */ 53035c4bbdfSmrg if (pScreenInfo->fMultiWindow) 53135c4bbdfSmrg EnumThreadWindows(g_dwCurrentThreadID, 53235c4bbdfSmrg winRedrawDamagedWindowShadowGDI, 53335c4bbdfSmrg (LPARAM) pBoxExtents); 53405b261ecSmrg#endif 53505b261ecSmrg} 53605b261ecSmrg 5379ace9065Smrgstatic Bool 53835c4bbdfSmrgwinInitScreenShadowGDI(ScreenPtr pScreen) 5399ace9065Smrg{ 54035c4bbdfSmrg winScreenPriv(pScreen); 54135c4bbdfSmrg 54235c4bbdfSmrg /* Get device contexts for the screen and shadow bitmap */ 54335c4bbdfSmrg pScreenPriv->hdcScreen = GetDC(pScreenPriv->hwndScreen); 54435c4bbdfSmrg pScreenPriv->hdcShadow = CreateCompatibleDC(pScreenPriv->hdcScreen); 54535c4bbdfSmrg 54635c4bbdfSmrg /* Allocate bitmap info header */ 54735c4bbdfSmrg pScreenPriv->pbmih = malloc(sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD)); 54835c4bbdfSmrg if (pScreenPriv->pbmih == NULL) { 54935c4bbdfSmrg ErrorF("winInitScreenShadowGDI - malloc () failed\n"); 55035c4bbdfSmrg return FALSE; 5519ace9065Smrg } 5529ace9065Smrg 55335c4bbdfSmrg /* Query the screen format */ 55435c4bbdfSmrg if (!winQueryScreenDIBFormat(pScreen, pScreenPriv->pbmih)) { 55535c4bbdfSmrg ErrorF("winInitScreenShadowGDI - winQueryScreenDIBFormat failed\n"); 55635c4bbdfSmrg return FALSE; 5579ace9065Smrg } 5589ace9065Smrg 55935c4bbdfSmrg /* Determine our color masks */ 56035c4bbdfSmrg if (!winQueryRGBBitsAndMasks(pScreen)) { 56135c4bbdfSmrg ErrorF("winInitScreenShadowGDI - winQueryRGBBitsAndMasks failed\n"); 56235c4bbdfSmrg return FALSE; 5639ace9065Smrg } 5649ace9065Smrg 56535c4bbdfSmrg return winAllocateFBShadowGDI(pScreen); 5669ace9065Smrg} 5679ace9065Smrg 56805b261ecSmrg/* See Porting Layer Definition - p. 33 */ 56905b261ecSmrg/* 57005b261ecSmrg * We wrap whatever CloseScreen procedure was specified by fb; 57105b261ecSmrg * a pointer to said procedure is stored in our privates. 57205b261ecSmrg */ 57305b261ecSmrg 57405b261ecSmrgstatic Bool 57535c4bbdfSmrgwinCloseScreenShadowGDI(ScreenPtr pScreen) 57605b261ecSmrg{ 57735c4bbdfSmrg winScreenPriv(pScreen); 57835c4bbdfSmrg winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; 57935c4bbdfSmrg Bool fReturn; 58005b261ecSmrg 58105b261ecSmrg#if CYGDEBUG 58235c4bbdfSmrg winDebug("winCloseScreenShadowGDI - Freeing screen resources\n"); 58305b261ecSmrg#endif 58405b261ecSmrg 58535c4bbdfSmrg /* Flag that the screen is closed */ 58635c4bbdfSmrg pScreenPriv->fClosed = TRUE; 58735c4bbdfSmrg pScreenPriv->fActive = FALSE; 58805b261ecSmrg 58935c4bbdfSmrg /* Call the wrapped CloseScreen procedure */ 59035c4bbdfSmrg WIN_UNWRAP(CloseScreen); 59135c4bbdfSmrg if (pScreen->CloseScreen) 59235c4bbdfSmrg fReturn = (*pScreen->CloseScreen) (pScreen); 59305b261ecSmrg 59435c4bbdfSmrg /* Delete the window property */ 59535c4bbdfSmrg RemoveProp(pScreenPriv->hwndScreen, WIN_SCR_PROP); 59605b261ecSmrg 59735c4bbdfSmrg /* Free the shadow DC; which allows the bitmap to be freed */ 59835c4bbdfSmrg DeleteDC(pScreenPriv->hdcShadow); 5999ace9065Smrg 60035c4bbdfSmrg winFreeFBShadowGDI(pScreen); 60105b261ecSmrg 60235c4bbdfSmrg /* Free the screen DC */ 60335c4bbdfSmrg ReleaseDC(pScreenPriv->hwndScreen, pScreenPriv->hdcScreen); 60405b261ecSmrg 60535c4bbdfSmrg /* Delete tray icon, if we have one */ 60635c4bbdfSmrg if (!pScreenInfo->fNoTrayIcon) 60735c4bbdfSmrg winDeleteNotifyIcon(pScreenPriv); 60805b261ecSmrg 60935c4bbdfSmrg /* Free the exit confirmation dialog box, if it exists */ 61035c4bbdfSmrg if (g_hDlgExit != NULL) { 61135c4bbdfSmrg DestroyWindow(g_hDlgExit); 61235c4bbdfSmrg g_hDlgExit = NULL; 61305b261ecSmrg } 61405b261ecSmrg 61535c4bbdfSmrg /* Kill our window */ 61635c4bbdfSmrg if (pScreenPriv->hwndScreen) { 61735c4bbdfSmrg DestroyWindow(pScreenPriv->hwndScreen); 61835c4bbdfSmrg pScreenPriv->hwndScreen = NULL; 61905b261ecSmrg } 62005b261ecSmrg 62105b261ecSmrg#if defined(XWIN_CLIPBOARD) || defined(XWIN_MULTIWINDOW) 62235c4bbdfSmrg /* Destroy the thread startup mutex */ 62335c4bbdfSmrg pthread_mutex_destroy(&pScreenPriv->pmServerStarted); 62405b261ecSmrg#endif 62505b261ecSmrg 62635c4bbdfSmrg /* Invalidate our screeninfo's pointer to the screen */ 62735c4bbdfSmrg pScreenInfo->pScreen = NULL; 62805b261ecSmrg 62935c4bbdfSmrg /* Free the screen privates for this screen */ 63035c4bbdfSmrg free((void *) pScreenPriv); 63105b261ecSmrg 63235c4bbdfSmrg return fReturn; 63305b261ecSmrg} 63405b261ecSmrg 63505b261ecSmrg/* 63605b261ecSmrg * Tell mi what sort of visuals we need. 63735c4bbdfSmrg * 63805b261ecSmrg * Generally we only need one visual, as our screen can only 63905b261ecSmrg * handle one format at a time, I believe. You may want 64005b261ecSmrg * to verify that last sentence. 64105b261ecSmrg */ 64205b261ecSmrg 64305b261ecSmrgstatic Bool 64435c4bbdfSmrgwinInitVisualsShadowGDI(ScreenPtr pScreen) 64505b261ecSmrg{ 64635c4bbdfSmrg winScreenPriv(pScreen); 64735c4bbdfSmrg winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; 64835c4bbdfSmrg 64935c4bbdfSmrg /* Display debugging information */ 65035c4bbdfSmrg ErrorF("winInitVisualsShadowGDI - Masks %08x %08x %08x BPRGB %d d %d " 65135c4bbdfSmrg "bpp %d\n", 65235c4bbdfSmrg (unsigned int) pScreenPriv->dwRedMask, 65335c4bbdfSmrg (unsigned int) pScreenPriv->dwGreenMask, 65435c4bbdfSmrg (unsigned int) pScreenPriv->dwBlueMask, 65535c4bbdfSmrg (int) pScreenPriv->dwBitsPerRGB, 65635c4bbdfSmrg (int) pScreenInfo->dwDepth, (int) pScreenInfo->dwBPP); 65735c4bbdfSmrg 65835c4bbdfSmrg /* Create a single visual according to the Windows screen depth */ 65935c4bbdfSmrg switch (pScreenInfo->dwDepth) { 66005b261ecSmrg case 24: 66105b261ecSmrg case 16: 66205b261ecSmrg case 15: 66335c4bbdfSmrg /* Setup the real visual */ 66435c4bbdfSmrg if (!miSetVisualTypesAndMasks(pScreenInfo->dwDepth, 66535c4bbdfSmrg TrueColorMask, 66635c4bbdfSmrg pScreenPriv->dwBitsPerRGB, 66735c4bbdfSmrg -1, 66835c4bbdfSmrg pScreenPriv->dwRedMask, 66935c4bbdfSmrg pScreenPriv->dwGreenMask, 67035c4bbdfSmrg pScreenPriv->dwBlueMask)) { 67135c4bbdfSmrg ErrorF("winInitVisualsShadowGDI - miSetVisualTypesAndMasks " 67235c4bbdfSmrg "failed\n"); 67335c4bbdfSmrg return FALSE; 67435c4bbdfSmrg } 67505b261ecSmrg 67605b261ecSmrg#ifdef XWIN_EMULATEPSEUDO 67735c4bbdfSmrg if (!pScreenInfo->fEmulatePseudo) 67835c4bbdfSmrg break; 67935c4bbdfSmrg 68035c4bbdfSmrg /* Setup a pseudocolor visual */ 68135c4bbdfSmrg if (!miSetVisualTypesAndMasks(8, PseudoColorMask, 8, -1, 0, 0, 0)) { 68235c4bbdfSmrg ErrorF("winInitVisualsShadowGDI - miSetVisualTypesAndMasks " 68335c4bbdfSmrg "failed for PseudoColor\n"); 68435c4bbdfSmrg return FALSE; 68535c4bbdfSmrg } 68605b261ecSmrg#endif 68735c4bbdfSmrg break; 68805b261ecSmrg 68905b261ecSmrg case 8: 69035c4bbdfSmrg if (!miSetVisualTypesAndMasks(pScreenInfo->dwDepth, 69135c4bbdfSmrg PseudoColorMask, 69235c4bbdfSmrg pScreenPriv->dwBitsPerRGB, 69335c4bbdfSmrg PseudoColor, 69435c4bbdfSmrg pScreenPriv->dwRedMask, 69535c4bbdfSmrg pScreenPriv->dwGreenMask, 69635c4bbdfSmrg pScreenPriv->dwBlueMask)) { 69735c4bbdfSmrg ErrorF("winInitVisualsShadowGDI - miSetVisualTypesAndMasks " 69835c4bbdfSmrg "failed\n"); 69935c4bbdfSmrg return FALSE; 70035c4bbdfSmrg } 70135c4bbdfSmrg break; 70205b261ecSmrg 70305b261ecSmrg default: 70435c4bbdfSmrg ErrorF("winInitVisualsShadowGDI - Unknown screen depth\n"); 70535c4bbdfSmrg return FALSE; 70605b261ecSmrg } 70705b261ecSmrg 70805b261ecSmrg#if CYGDEBUG 70935c4bbdfSmrg winDebug("winInitVisualsShadowGDI - Returning\n"); 71005b261ecSmrg#endif 71105b261ecSmrg 71235c4bbdfSmrg return TRUE; 71305b261ecSmrg} 71405b261ecSmrg 71505b261ecSmrg/* 71605b261ecSmrg * Adjust the proposed video mode 71705b261ecSmrg */ 71805b261ecSmrg 71905b261ecSmrgstatic Bool 72035c4bbdfSmrgwinAdjustVideoModeShadowGDI(ScreenPtr pScreen) 72105b261ecSmrg{ 72235c4bbdfSmrg winScreenPriv(pScreen); 72335c4bbdfSmrg winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; 72435c4bbdfSmrg HDC hdc; 72535c4bbdfSmrg DWORD dwBPP; 72635c4bbdfSmrg 72735c4bbdfSmrg hdc = GetDC(NULL); 72835c4bbdfSmrg 72935c4bbdfSmrg /* We're in serious trouble if we can't get a DC */ 73035c4bbdfSmrg if (hdc == NULL) { 73135c4bbdfSmrg ErrorF("winAdjustVideoModeShadowGDI - GetDC () failed\n"); 73235c4bbdfSmrg return FALSE; 73305b261ecSmrg } 73405b261ecSmrg 73535c4bbdfSmrg /* Query GDI for current display depth */ 73635c4bbdfSmrg dwBPP = GetDeviceCaps(hdc, BITSPIXEL); 73705b261ecSmrg 73835c4bbdfSmrg /* GDI cannot change the screen depth, so always use GDI's depth */ 73935c4bbdfSmrg pScreenInfo->dwBPP = dwBPP; 74005b261ecSmrg 74135c4bbdfSmrg /* Release our DC */ 74235c4bbdfSmrg ReleaseDC(NULL, hdc); 74335c4bbdfSmrg hdc = NULL; 74405b261ecSmrg 74535c4bbdfSmrg return TRUE; 74605b261ecSmrg} 74705b261ecSmrg 74805b261ecSmrg/* 74905b261ecSmrg * Blt exposed regions to the screen 75005b261ecSmrg */ 75105b261ecSmrg 75205b261ecSmrgstatic Bool 75335c4bbdfSmrgwinBltExposedRegionsShadowGDI(ScreenPtr pScreen) 75405b261ecSmrg{ 75535c4bbdfSmrg winScreenPriv(pScreen); 75635c4bbdfSmrg winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; 75735c4bbdfSmrg winPrivCmapPtr pCmapPriv = NULL; 75835c4bbdfSmrg HDC hdcUpdate; 75935c4bbdfSmrg PAINTSTRUCT ps; 76035c4bbdfSmrg 76135c4bbdfSmrg /* BeginPaint gives us an hdc that clips to the invalidated region */ 76235c4bbdfSmrg hdcUpdate = BeginPaint(pScreenPriv->hwndScreen, &ps); 76335c4bbdfSmrg 76435c4bbdfSmrg /* Realize the palette, if we have one */ 76535c4bbdfSmrg if (pScreenPriv->pcmapInstalled != NULL) { 76635c4bbdfSmrg pCmapPriv = winGetCmapPriv(pScreenPriv->pcmapInstalled); 76735c4bbdfSmrg 76835c4bbdfSmrg SelectPalette(hdcUpdate, pCmapPriv->hPalette, FALSE); 76935c4bbdfSmrg RealizePalette(hdcUpdate); 77005b261ecSmrg } 77105b261ecSmrg 77235c4bbdfSmrg /* Our BitBlt will be clipped to the invalidated region */ 77335c4bbdfSmrg BitBlt(hdcUpdate, 77435c4bbdfSmrg 0, 0, 77535c4bbdfSmrg pScreenInfo->dwWidth, pScreenInfo->dwHeight, 77635c4bbdfSmrg pScreenPriv->hdcShadow, 0, 0, SRCCOPY); 77705b261ecSmrg 77835c4bbdfSmrg /* EndPaint frees the DC */ 77935c4bbdfSmrg EndPaint(pScreenPriv->hwndScreen, &ps); 78005b261ecSmrg 78105b261ecSmrg#ifdef XWIN_MULTIWINDOW 78235c4bbdfSmrg /* Redraw all windows */ 78335c4bbdfSmrg if (pScreenInfo->fMultiWindow) 78435c4bbdfSmrg EnumThreadWindows(g_dwCurrentThreadID, winRedrawAllProcShadowGDI, 78535c4bbdfSmrg (LPARAM) pScreenPriv->hwndScreen); 78605b261ecSmrg#endif 78705b261ecSmrg 78835c4bbdfSmrg return TRUE; 78905b261ecSmrg} 79005b261ecSmrg 79105b261ecSmrg/* 79205b261ecSmrg * Do any engine-specific appliation-activation processing 79305b261ecSmrg */ 79405b261ecSmrg 79505b261ecSmrgstatic Bool 79635c4bbdfSmrgwinActivateAppShadowGDI(ScreenPtr pScreen) 79705b261ecSmrg{ 79835c4bbdfSmrg winScreenPriv(pScreen); 79935c4bbdfSmrg winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; 80035c4bbdfSmrg 80135c4bbdfSmrg /* 80235c4bbdfSmrg * 2004/04/12 - Harold - We perform the restoring or minimizing 80335c4bbdfSmrg * manually for ShadowGDI in fullscreen modes so that this engine 80435c4bbdfSmrg * will perform just like ShadowDD and ShadowDDNL in fullscreen mode; 80535c4bbdfSmrg * if we do not do this then our fullscreen window will appear in the 80635c4bbdfSmrg * z-order when it is deactivated and it can be uncovered by resizing 80735c4bbdfSmrg * or minimizing another window that is on top of it, which is not how 80835c4bbdfSmrg * the DirectDraw engines work. Therefore we keep this code here to 80935c4bbdfSmrg * make sure that all engines work the same in fullscreen mode. 81035c4bbdfSmrg */ 81135c4bbdfSmrg 81235c4bbdfSmrg /* 81335c4bbdfSmrg * Are we active? 81435c4bbdfSmrg * Are we fullscreen? 81535c4bbdfSmrg */ 81635c4bbdfSmrg if (pScreenPriv->fActive && pScreenInfo->fFullScreen) { 81735c4bbdfSmrg /* 81835c4bbdfSmrg * Activating, attempt to bring our window 81935c4bbdfSmrg * to the top of the display 82035c4bbdfSmrg */ 82135c4bbdfSmrg ShowWindow(pScreenPriv->hwndScreen, SW_RESTORE); 82205b261ecSmrg } 82335c4bbdfSmrg else if (!pScreenPriv->fActive && pScreenInfo->fFullScreen) { 82435c4bbdfSmrg /* 82535c4bbdfSmrg * Deactivating, stuff our window onto the 82635c4bbdfSmrg * task bar. 82735c4bbdfSmrg */ 82835c4bbdfSmrg ShowWindow(pScreenPriv->hwndScreen, SW_MINIMIZE); 82905b261ecSmrg } 83005b261ecSmrg 83135c4bbdfSmrg return TRUE; 83205b261ecSmrg} 83305b261ecSmrg 83405b261ecSmrg/* 83505b261ecSmrg * Reblit the shadow framebuffer to the screen. 83605b261ecSmrg */ 83705b261ecSmrg 83805b261ecSmrgstatic Bool 83935c4bbdfSmrgwinRedrawScreenShadowGDI(ScreenPtr pScreen) 84005b261ecSmrg{ 84135c4bbdfSmrg winScreenPriv(pScreen); 84235c4bbdfSmrg winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; 84305b261ecSmrg 84435c4bbdfSmrg /* Redraw the whole window, to take account for the new colors */ 84535c4bbdfSmrg BitBlt(pScreenPriv->hdcScreen, 84635c4bbdfSmrg 0, 0, 84735c4bbdfSmrg pScreenInfo->dwWidth, pScreenInfo->dwHeight, 84835c4bbdfSmrg pScreenPriv->hdcShadow, 0, 0, SRCCOPY); 84905b261ecSmrg 85005b261ecSmrg#ifdef XWIN_MULTIWINDOW 85135c4bbdfSmrg /* Redraw all windows */ 85235c4bbdfSmrg if (pScreenInfo->fMultiWindow) 85335c4bbdfSmrg EnumThreadWindows(g_dwCurrentThreadID, winRedrawAllProcShadowGDI, 0); 85405b261ecSmrg#endif 85505b261ecSmrg 85635c4bbdfSmrg return TRUE; 85705b261ecSmrg} 85805b261ecSmrg 85905b261ecSmrg/* 86005b261ecSmrg * Realize the currently installed colormap 86105b261ecSmrg */ 86205b261ecSmrg 86305b261ecSmrgstatic Bool 86435c4bbdfSmrgwinRealizeInstalledPaletteShadowGDI(ScreenPtr pScreen) 86505b261ecSmrg{ 86635c4bbdfSmrg winScreenPriv(pScreen); 86735c4bbdfSmrg winPrivCmapPtr pCmapPriv = NULL; 86805b261ecSmrg 86905b261ecSmrg#if CYGDEBUG 87035c4bbdfSmrg winDebug("winRealizeInstalledPaletteShadowGDI\n"); 87105b261ecSmrg#endif 87205b261ecSmrg 87335c4bbdfSmrg /* Don't do anything if there is not a colormap */ 87435c4bbdfSmrg if (pScreenPriv->pcmapInstalled == NULL) { 87505b261ecSmrg#if CYGDEBUG 87635c4bbdfSmrg winDebug("winRealizeInstalledPaletteShadowGDI - No colormap " 87735c4bbdfSmrg "installed\n"); 87805b261ecSmrg#endif 87935c4bbdfSmrg return TRUE; 88005b261ecSmrg } 88105b261ecSmrg 88235c4bbdfSmrg pCmapPriv = winGetCmapPriv(pScreenPriv->pcmapInstalled); 88335c4bbdfSmrg 88435c4bbdfSmrg /* Realize our palette for the screen */ 88535c4bbdfSmrg if (RealizePalette(pScreenPriv->hdcScreen) == GDI_ERROR) { 88635c4bbdfSmrg ErrorF("winRealizeInstalledPaletteShadowGDI - RealizePalette () " 88735c4bbdfSmrg "failed\n"); 88835c4bbdfSmrg return FALSE; 88905b261ecSmrg } 89035c4bbdfSmrg 89135c4bbdfSmrg /* Set the DIB color table */ 89235c4bbdfSmrg if (SetDIBColorTable(pScreenPriv->hdcShadow, 89335c4bbdfSmrg 0, 89435c4bbdfSmrg WIN_NUM_PALETTE_ENTRIES, pCmapPriv->rgbColors) == 0) { 89535c4bbdfSmrg ErrorF("winRealizeInstalledPaletteShadowGDI - SetDIBColorTable () " 89635c4bbdfSmrg "failed\n"); 89735c4bbdfSmrg return FALSE; 89805b261ecSmrg } 89905b261ecSmrg 90035c4bbdfSmrg return TRUE; 90135c4bbdfSmrg} 90205b261ecSmrg 90305b261ecSmrg/* 90405b261ecSmrg * Install the specified colormap 90505b261ecSmrg */ 90605b261ecSmrg 90705b261ecSmrgstatic Bool 90835c4bbdfSmrgwinInstallColormapShadowGDI(ColormapPtr pColormap) 90905b261ecSmrg{ 91035c4bbdfSmrg ScreenPtr pScreen = pColormap->pScreen; 91135c4bbdfSmrg 91235c4bbdfSmrg winScreenPriv(pScreen); 91335c4bbdfSmrg winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; 91435c4bbdfSmrg 91535c4bbdfSmrg winCmapPriv(pColormap); 91635c4bbdfSmrg 91735c4bbdfSmrg /* 91835c4bbdfSmrg * Tell Windows to install the new colormap 91935c4bbdfSmrg */ 92035c4bbdfSmrg if (SelectPalette(pScreenPriv->hdcScreen, 92135c4bbdfSmrg pCmapPriv->hPalette, FALSE) == NULL) { 92235c4bbdfSmrg ErrorF("winInstallColormapShadowGDI - SelectPalette () failed\n"); 92335c4bbdfSmrg return FALSE; 92405b261ecSmrg } 92535c4bbdfSmrg 92635c4bbdfSmrg /* Realize the palette */ 92735c4bbdfSmrg if (GDI_ERROR == RealizePalette(pScreenPriv->hdcScreen)) { 92835c4bbdfSmrg ErrorF("winInstallColormapShadowGDI - RealizePalette () failed\n"); 92935c4bbdfSmrg return FALSE; 93005b261ecSmrg } 93105b261ecSmrg 93235c4bbdfSmrg /* Set the DIB color table */ 93335c4bbdfSmrg if (SetDIBColorTable(pScreenPriv->hdcShadow, 93435c4bbdfSmrg 0, 93535c4bbdfSmrg WIN_NUM_PALETTE_ENTRIES, pCmapPriv->rgbColors) == 0) { 93635c4bbdfSmrg ErrorF("winInstallColormapShadowGDI - SetDIBColorTable () failed\n"); 93735c4bbdfSmrg return FALSE; 93805b261ecSmrg } 93905b261ecSmrg 94035c4bbdfSmrg /* Redraw the whole window, to take account for the new colors */ 94135c4bbdfSmrg BitBlt(pScreenPriv->hdcScreen, 94235c4bbdfSmrg 0, 0, 94335c4bbdfSmrg pScreenInfo->dwWidth, pScreenInfo->dwHeight, 94435c4bbdfSmrg pScreenPriv->hdcShadow, 0, 0, SRCCOPY); 94505b261ecSmrg 94635c4bbdfSmrg /* Save a pointer to the newly installed colormap */ 94735c4bbdfSmrg pScreenPriv->pcmapInstalled = pColormap; 94805b261ecSmrg 94905b261ecSmrg#ifdef XWIN_MULTIWINDOW 95035c4bbdfSmrg /* Redraw all windows */ 95135c4bbdfSmrg if (pScreenInfo->fMultiWindow) 95235c4bbdfSmrg EnumThreadWindows(g_dwCurrentThreadID, winRedrawAllProcShadowGDI, 0); 95305b261ecSmrg#endif 95405b261ecSmrg 95535c4bbdfSmrg return TRUE; 95605b261ecSmrg} 95705b261ecSmrg 95805b261ecSmrg/* 95905b261ecSmrg * Store the specified colors in the specified colormap 96005b261ecSmrg */ 96105b261ecSmrg 96205b261ecSmrgstatic Bool 96335c4bbdfSmrgwinStoreColorsShadowGDI(ColormapPtr pColormap, int ndef, xColorItem * pdefs) 96405b261ecSmrg{ 96535c4bbdfSmrg ScreenPtr pScreen = pColormap->pScreen; 96635c4bbdfSmrg 96735c4bbdfSmrg winScreenPriv(pScreen); 96835c4bbdfSmrg winCmapPriv(pColormap); 96935c4bbdfSmrg ColormapPtr curpmap = pScreenPriv->pcmapInstalled; 97035c4bbdfSmrg 97135c4bbdfSmrg /* Put the X colormap entries into the Windows logical palette */ 97235c4bbdfSmrg if (SetPaletteEntries(pCmapPriv->hPalette, 97335c4bbdfSmrg pdefs[0].pixel, 97435c4bbdfSmrg ndef, pCmapPriv->peColors + pdefs[0].pixel) == 0) { 97535c4bbdfSmrg ErrorF("winStoreColorsShadowGDI - SetPaletteEntries () failed\n"); 97635c4bbdfSmrg return FALSE; 97705b261ecSmrg } 97805b261ecSmrg 97935c4bbdfSmrg /* Don't install the Windows palette if the colormap is not installed */ 98035c4bbdfSmrg if (pColormap != curpmap) { 98135c4bbdfSmrg return TRUE; 98205b261ecSmrg } 98305b261ecSmrg 98435c4bbdfSmrg /* Try to install the newly modified colormap */ 98535c4bbdfSmrg if (!winInstallColormapShadowGDI(pColormap)) { 98635c4bbdfSmrg ErrorF("winInstallColormapShadowGDI - winInstallColormapShadowGDI " 98735c4bbdfSmrg "failed\n"); 98835c4bbdfSmrg return FALSE; 98905b261ecSmrg } 99005b261ecSmrg 99105b261ecSmrg#if 0 99235c4bbdfSmrg /* Tell Windows that the palette has changed */ 99335c4bbdfSmrg RealizePalette(pScreenPriv->hdcScreen); 99435c4bbdfSmrg 99535c4bbdfSmrg /* Set the DIB color table */ 99635c4bbdfSmrg if (SetDIBColorTable(pScreenPriv->hdcShadow, 99735c4bbdfSmrg pdefs[0].pixel, 99835c4bbdfSmrg ndef, pCmapPriv->rgbColors + pdefs[0].pixel) == 0) { 99935c4bbdfSmrg ErrorF("winInstallColormapShadowGDI - SetDIBColorTable () failed\n"); 100035c4bbdfSmrg return FALSE; 100105b261ecSmrg } 100205b261ecSmrg 100335c4bbdfSmrg /* Save a pointer to the newly installed colormap */ 100435c4bbdfSmrg pScreenPriv->pcmapInstalled = pColormap; 100505b261ecSmrg#endif 100605b261ecSmrg 100735c4bbdfSmrg return TRUE; 100805b261ecSmrg} 100905b261ecSmrg 101005b261ecSmrg/* 101105b261ecSmrg * Colormap initialization procedure 101205b261ecSmrg */ 101305b261ecSmrg 101405b261ecSmrgstatic Bool 101535c4bbdfSmrgwinCreateColormapShadowGDI(ColormapPtr pColormap) 101605b261ecSmrg{ 101735c4bbdfSmrg LPLOGPALETTE lpPaletteNew = NULL; 101835c4bbdfSmrg DWORD dwEntriesMax; 101935c4bbdfSmrg VisualPtr pVisual; 102035c4bbdfSmrg HPALETTE hpalNew = NULL; 102135c4bbdfSmrg 102235c4bbdfSmrg winCmapPriv(pColormap); 102335c4bbdfSmrg 102435c4bbdfSmrg /* Get a pointer to the visual that the colormap belongs to */ 102535c4bbdfSmrg pVisual = pColormap->pVisual; 102635c4bbdfSmrg 102735c4bbdfSmrg /* Get the maximum number of palette entries for this visual */ 102835c4bbdfSmrg dwEntriesMax = pVisual->ColormapEntries; 102935c4bbdfSmrg 103035c4bbdfSmrg /* Allocate a Windows logical color palette with max entries */ 103135c4bbdfSmrg lpPaletteNew = malloc(sizeof(LOGPALETTE) 103235c4bbdfSmrg + (dwEntriesMax - 1) * sizeof(PALETTEENTRY)); 103335c4bbdfSmrg if (lpPaletteNew == NULL) { 103435c4bbdfSmrg ErrorF("winCreateColormapShadowGDI - Couldn't allocate palette " 103535c4bbdfSmrg "with %d entries\n", (int) dwEntriesMax); 103635c4bbdfSmrg return FALSE; 103705b261ecSmrg } 103805b261ecSmrg 103935c4bbdfSmrg /* Zero out the colormap */ 104035c4bbdfSmrg ZeroMemory(lpPaletteNew, sizeof(LOGPALETTE) 104135c4bbdfSmrg + (dwEntriesMax - 1) * sizeof(PALETTEENTRY)); 104235c4bbdfSmrg 104335c4bbdfSmrg /* Set the logical palette structure */ 104435c4bbdfSmrg lpPaletteNew->palVersion = 0x0300; 104535c4bbdfSmrg lpPaletteNew->palNumEntries = dwEntriesMax; 104635c4bbdfSmrg 104735c4bbdfSmrg /* Tell Windows to create the palette */ 104835c4bbdfSmrg hpalNew = CreatePalette(lpPaletteNew); 104935c4bbdfSmrg if (hpalNew == NULL) { 105035c4bbdfSmrg ErrorF("winCreateColormapShadowGDI - CreatePalette () failed\n"); 105135c4bbdfSmrg free(lpPaletteNew); 105235c4bbdfSmrg return FALSE; 105305b261ecSmrg } 105405b261ecSmrg 105535c4bbdfSmrg /* Save the Windows logical palette handle in the X colormaps' privates */ 105635c4bbdfSmrg pCmapPriv->hPalette = hpalNew; 105705b261ecSmrg 105835c4bbdfSmrg /* Free the palette initialization memory */ 105935c4bbdfSmrg free(lpPaletteNew); 106005b261ecSmrg 106135c4bbdfSmrg return TRUE; 106205b261ecSmrg} 106305b261ecSmrg 106405b261ecSmrg/* 106505b261ecSmrg * Colormap destruction procedure 106605b261ecSmrg */ 106705b261ecSmrg 106805b261ecSmrgstatic Bool 106935c4bbdfSmrgwinDestroyColormapShadowGDI(ColormapPtr pColormap) 107005b261ecSmrg{ 107135c4bbdfSmrg winScreenPriv(pColormap->pScreen); 107235c4bbdfSmrg winCmapPriv(pColormap); 107335c4bbdfSmrg 107435c4bbdfSmrg /* 107535c4bbdfSmrg * Is colormap to be destroyed the default? 107635c4bbdfSmrg * 107735c4bbdfSmrg * Non-default colormaps should have had winUninstallColormap 107835c4bbdfSmrg * called on them before we get here. The default colormap 107935c4bbdfSmrg * will not have had winUninstallColormap called on it. Thus, 108035c4bbdfSmrg * we need to handle the default colormap in a special way. 108135c4bbdfSmrg */ 108235c4bbdfSmrg if (pColormap->flags & IsDefault) { 108305b261ecSmrg#if CYGDEBUG 108435c4bbdfSmrg winDebug("winDestroyColormapShadowGDI - Destroying default " 108535c4bbdfSmrg "colormap\n"); 108605b261ecSmrg#endif 108735c4bbdfSmrg 108835c4bbdfSmrg /* 108935c4bbdfSmrg * FIXME: Walk the list of all screens, popping the default 109035c4bbdfSmrg * palette out of each screen device context. 109135c4bbdfSmrg */ 109235c4bbdfSmrg 109335c4bbdfSmrg /* Pop the palette out of the device context */ 109435c4bbdfSmrg SelectPalette(pScreenPriv->hdcScreen, 109535c4bbdfSmrg GetStockObject(DEFAULT_PALETTE), FALSE); 109635c4bbdfSmrg 109735c4bbdfSmrg /* Clear our private installed colormap pointer */ 109835c4bbdfSmrg pScreenPriv->pcmapInstalled = NULL; 109905b261ecSmrg } 110035c4bbdfSmrg 110135c4bbdfSmrg /* Try to delete the logical palette */ 110235c4bbdfSmrg if (DeleteObject(pCmapPriv->hPalette) == 0) { 110335c4bbdfSmrg ErrorF("winDestroyColormap - DeleteObject () failed\n"); 110435c4bbdfSmrg return FALSE; 110505b261ecSmrg } 110605b261ecSmrg 110735c4bbdfSmrg /* Invalidate the colormap privates */ 110835c4bbdfSmrg pCmapPriv->hPalette = NULL; 110905b261ecSmrg 111035c4bbdfSmrg return TRUE; 111135c4bbdfSmrg} 111205b261ecSmrg 111305b261ecSmrg/* 111405b261ecSmrg * Set engine specific funtions 111505b261ecSmrg */ 111605b261ecSmrg 111705b261ecSmrgBool 111835c4bbdfSmrgwinSetEngineFunctionsShadowGDI(ScreenPtr pScreen) 111905b261ecSmrg{ 112035c4bbdfSmrg winScreenPriv(pScreen); 112135c4bbdfSmrg winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; 112235c4bbdfSmrg 112335c4bbdfSmrg /* Set our pointers */ 112435c4bbdfSmrg pScreenPriv->pwinAllocateFB = winAllocateFBShadowGDI; 112535c4bbdfSmrg pScreenPriv->pwinFreeFB = winFreeFBShadowGDI; 112635c4bbdfSmrg pScreenPriv->pwinShadowUpdate = winShadowUpdateGDI; 112735c4bbdfSmrg pScreenPriv->pwinInitScreen = winInitScreenShadowGDI; 112835c4bbdfSmrg pScreenPriv->pwinCloseScreen = winCloseScreenShadowGDI; 112935c4bbdfSmrg pScreenPriv->pwinInitVisuals = winInitVisualsShadowGDI; 113035c4bbdfSmrg pScreenPriv->pwinAdjustVideoMode = winAdjustVideoModeShadowGDI; 113135c4bbdfSmrg if (pScreenInfo->fFullScreen) 113235c4bbdfSmrg pScreenPriv->pwinCreateBoundingWindow = 113335c4bbdfSmrg winCreateBoundingWindowFullScreen; 113435c4bbdfSmrg else 113535c4bbdfSmrg pScreenPriv->pwinCreateBoundingWindow = winCreateBoundingWindowWindowed; 113635c4bbdfSmrg pScreenPriv->pwinFinishScreenInit = winFinishScreenInitFB; 113735c4bbdfSmrg pScreenPriv->pwinBltExposedRegions = winBltExposedRegionsShadowGDI; 113835c4bbdfSmrg pScreenPriv->pwinActivateApp = winActivateAppShadowGDI; 113935c4bbdfSmrg pScreenPriv->pwinRedrawScreen = winRedrawScreenShadowGDI; 114035c4bbdfSmrg pScreenPriv->pwinRealizeInstalledPalette = 114135c4bbdfSmrg winRealizeInstalledPaletteShadowGDI; 114235c4bbdfSmrg pScreenPriv->pwinInstallColormap = winInstallColormapShadowGDI; 114335c4bbdfSmrg pScreenPriv->pwinStoreColors = winStoreColorsShadowGDI; 114435c4bbdfSmrg pScreenPriv->pwinCreateColormap = winCreateColormapShadowGDI; 114535c4bbdfSmrg pScreenPriv->pwinDestroyColormap = winDestroyColormapShadowGDI; 114635c4bbdfSmrg pScreenPriv->pwinHotKeyAltTab = 114735c4bbdfSmrg (winHotKeyAltTabProcPtr) (void (*)(void)) NoopDDA; 114835c4bbdfSmrg pScreenPriv->pwinCreatePrimarySurface = 114935c4bbdfSmrg (winCreatePrimarySurfaceProcPtr) (void (*)(void)) NoopDDA; 115035c4bbdfSmrg pScreenPriv->pwinReleasePrimarySurface = 115135c4bbdfSmrg (winReleasePrimarySurfaceProcPtr) (void (*)(void)) NoopDDA; 115205b261ecSmrg#ifdef XWIN_MULTIWINDOW 115335c4bbdfSmrg pScreenPriv->pwinFinishCreateWindowsWindow = 115435c4bbdfSmrg (winFinishCreateWindowsWindowProcPtr) (void (*)(void)) NoopDDA; 115505b261ecSmrg#endif 115605b261ecSmrg 115735c4bbdfSmrg return TRUE; 115805b261ecSmrg} 1159