winshadgdi.c revision 9ace9065
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/* 3805b261ecSmrg * Local function prototypes 3905b261ecSmrg */ 4005b261ecSmrg 4105b261ecSmrg#ifdef XWIN_MULTIWINDOW 4205b261ecSmrgstatic wBOOL CALLBACK 4305b261ecSmrgwinRedrawAllProcShadowGDI (HWND hwnd, LPARAM lParam); 4405b261ecSmrg 4505b261ecSmrgstatic wBOOL CALLBACK 4605b261ecSmrgwinRedrawDamagedWindowShadowGDI (HWND hwnd, LPARAM lParam); 4705b261ecSmrg#endif 4805b261ecSmrg 4905b261ecSmrgstatic Bool 5005b261ecSmrgwinAllocateFBShadowGDI (ScreenPtr pScreen); 5105b261ecSmrg 5205b261ecSmrgstatic void 5305b261ecSmrgwinShadowUpdateGDI (ScreenPtr pScreen, 5405b261ecSmrg shadowBufPtr pBuf); 5505b261ecSmrg 5605b261ecSmrgstatic Bool 5705b261ecSmrgwinCloseScreenShadowGDI (int nIndex, ScreenPtr pScreen); 5805b261ecSmrg 5905b261ecSmrgstatic Bool 6005b261ecSmrgwinInitVisualsShadowGDI (ScreenPtr pScreen); 6105b261ecSmrg 6205b261ecSmrgstatic Bool 6305b261ecSmrgwinAdjustVideoModeShadowGDI (ScreenPtr pScreen); 6405b261ecSmrg 6505b261ecSmrgstatic Bool 6605b261ecSmrgwinBltExposedRegionsShadowGDI (ScreenPtr pScreen); 6705b261ecSmrg 6805b261ecSmrgstatic Bool 6905b261ecSmrgwinActivateAppShadowGDI (ScreenPtr pScreen); 7005b261ecSmrg 7105b261ecSmrgstatic Bool 7205b261ecSmrgwinRedrawScreenShadowGDI (ScreenPtr pScreen); 7305b261ecSmrg 7405b261ecSmrgstatic Bool 7505b261ecSmrgwinRealizeInstalledPaletteShadowGDI (ScreenPtr pScreen); 7605b261ecSmrg 7705b261ecSmrgstatic Bool 7805b261ecSmrgwinInstallColormapShadowGDI (ColormapPtr pColormap); 7905b261ecSmrg 8005b261ecSmrgstatic Bool 8105b261ecSmrgwinStoreColorsShadowGDI (ColormapPtr pmap, 8205b261ecSmrg int ndef, 8305b261ecSmrg xColorItem *pdefs); 8405b261ecSmrg 8505b261ecSmrgstatic Bool 8605b261ecSmrgwinCreateColormapShadowGDI (ColormapPtr pColormap); 8705b261ecSmrg 8805b261ecSmrgstatic Bool 8905b261ecSmrgwinDestroyColormapShadowGDI (ColormapPtr pColormap); 9005b261ecSmrg 9105b261ecSmrg 9205b261ecSmrg/* 9305b261ecSmrg * Internal function to get the DIB format that is compatible with the screen 9405b261ecSmrg */ 9505b261ecSmrg 9605b261ecSmrgstatic 9705b261ecSmrgBool 9805b261ecSmrgwinQueryScreenDIBFormat (ScreenPtr pScreen, BITMAPINFOHEADER *pbmih) 9905b261ecSmrg{ 10005b261ecSmrg winScreenPriv(pScreen); 10105b261ecSmrg HBITMAP hbmp; 10205b261ecSmrg#if CYGDEBUG 10305b261ecSmrg LPDWORD pdw = NULL; 10405b261ecSmrg#endif 10505b261ecSmrg 10605b261ecSmrg /* Create a memory bitmap compatible with the screen */ 10705b261ecSmrg hbmp = CreateCompatibleBitmap (pScreenPriv->hdcScreen, 1, 1); 10805b261ecSmrg if (hbmp == NULL) 10905b261ecSmrg { 11005b261ecSmrg ErrorF ("winQueryScreenDIBFormat - CreateCompatibleBitmap failed\n"); 11105b261ecSmrg return FALSE; 11205b261ecSmrg } 11305b261ecSmrg 11405b261ecSmrg /* Initialize our bitmap info header */ 11505b261ecSmrg ZeroMemory (pbmih, sizeof (BITMAPINFOHEADER) + 256 * sizeof (RGBQUAD)); 11605b261ecSmrg pbmih->biSize = sizeof (BITMAPINFOHEADER); 11705b261ecSmrg 11805b261ecSmrg /* Get the biBitCount */ 11905b261ecSmrg if (!GetDIBits (pScreenPriv->hdcScreen, 12005b261ecSmrg hbmp, 12105b261ecSmrg 0, 1, 12205b261ecSmrg NULL, 12305b261ecSmrg (BITMAPINFO*) pbmih, 12405b261ecSmrg DIB_RGB_COLORS)) 12505b261ecSmrg { 12605b261ecSmrg ErrorF ("winQueryScreenDIBFormat - First call to GetDIBits failed\n"); 12705b261ecSmrg DeleteObject (hbmp); 12805b261ecSmrg return FALSE; 12905b261ecSmrg } 13005b261ecSmrg 13105b261ecSmrg#if CYGDEBUG 13205b261ecSmrg /* Get a pointer to bitfields */ 13305b261ecSmrg pdw = (DWORD*) ((CARD8*)pbmih + sizeof (BITMAPINFOHEADER)); 13405b261ecSmrg 13505b261ecSmrg winDebug ("winQueryScreenDIBFormat - First call masks: %08x %08x %08x\n", 13605b261ecSmrg pdw[0], pdw[1], pdw[2]); 13705b261ecSmrg#endif 13805b261ecSmrg 13905b261ecSmrg /* Get optimal color table, or the optimal bitfields */ 14005b261ecSmrg if (!GetDIBits (pScreenPriv->hdcScreen, 14105b261ecSmrg hbmp, 14205b261ecSmrg 0, 1, 14305b261ecSmrg NULL, 14405b261ecSmrg (BITMAPINFO*)pbmih, 14505b261ecSmrg DIB_RGB_COLORS)) 14605b261ecSmrg { 14705b261ecSmrg ErrorF ("winQueryScreenDIBFormat - Second call to GetDIBits " 14805b261ecSmrg "failed\n"); 14905b261ecSmrg DeleteObject (hbmp); 15005b261ecSmrg return FALSE; 15105b261ecSmrg } 15205b261ecSmrg 15305b261ecSmrg /* Free memory */ 15405b261ecSmrg DeleteObject (hbmp); 15505b261ecSmrg 15605b261ecSmrg return TRUE; 15705b261ecSmrg} 15805b261ecSmrg 15905b261ecSmrg 16005b261ecSmrg/* 16105b261ecSmrg * Internal function to determine the GDI bits per rgb and bit masks 16205b261ecSmrg */ 16305b261ecSmrg 16405b261ecSmrgstatic 16505b261ecSmrgBool 16605b261ecSmrgwinQueryRGBBitsAndMasks (ScreenPtr pScreen) 16705b261ecSmrg{ 16805b261ecSmrg winScreenPriv(pScreen); 16905b261ecSmrg BITMAPINFOHEADER *pbmih = NULL; 17005b261ecSmrg Bool fReturn = TRUE; 17105b261ecSmrg LPDWORD pdw = NULL; 17205b261ecSmrg DWORD dwRedBits, dwGreenBits, dwBlueBits; 17305b261ecSmrg 17405b261ecSmrg /* Color masks for 8 bpp are standardized */ 17505b261ecSmrg if (GetDeviceCaps (pScreenPriv->hdcScreen, RASTERCAPS) & RC_PALETTE) 17605b261ecSmrg { 17705b261ecSmrg /* 17805b261ecSmrg * RGB BPP for 8 bit palletes is always 8 17905b261ecSmrg * and the color masks are always 0. 18005b261ecSmrg */ 18105b261ecSmrg pScreenPriv->dwBitsPerRGB = 8; 18205b261ecSmrg pScreenPriv->dwRedMask = 0x0L; 18305b261ecSmrg pScreenPriv->dwGreenMask = 0x0L; 18405b261ecSmrg pScreenPriv->dwBlueMask = 0x0L; 18505b261ecSmrg return TRUE; 18605b261ecSmrg } 18705b261ecSmrg 18805b261ecSmrg /* Color masks for 24 bpp are standardized */ 18905b261ecSmrg if (GetDeviceCaps (pScreenPriv->hdcScreen, PLANES) 19005b261ecSmrg * GetDeviceCaps (pScreenPriv->hdcScreen, BITSPIXEL) == 24) 19105b261ecSmrg { 19205b261ecSmrg ErrorF ("winQueryRGBBitsAndMasks - GetDeviceCaps (BITSPIXEL) " 19305b261ecSmrg "returned 24 for the screen. Using default 24bpp masks.\n"); 19405b261ecSmrg 19505b261ecSmrg /* 8 bits per primary color */ 19605b261ecSmrg pScreenPriv->dwBitsPerRGB = 8; 19705b261ecSmrg 19805b261ecSmrg /* Set screen privates masks */ 19905b261ecSmrg pScreenPriv->dwRedMask = WIN_24BPP_MASK_RED; 20005b261ecSmrg pScreenPriv->dwGreenMask = WIN_24BPP_MASK_GREEN; 20105b261ecSmrg pScreenPriv->dwBlueMask = WIN_24BPP_MASK_BLUE; 20205b261ecSmrg 20305b261ecSmrg return TRUE; 20405b261ecSmrg } 20505b261ecSmrg 20605b261ecSmrg /* Allocate a bitmap header and color table */ 20705b261ecSmrg pbmih = (BITMAPINFOHEADER*) malloc (sizeof (BITMAPINFOHEADER) 20805b261ecSmrg + 256 * sizeof (RGBQUAD)); 20905b261ecSmrg if (pbmih == NULL) 21005b261ecSmrg { 21105b261ecSmrg ErrorF ("winQueryRGBBitsAndMasks - malloc failed\n"); 21205b261ecSmrg return FALSE; 21305b261ecSmrg } 21405b261ecSmrg 21505b261ecSmrg /* Get screen description */ 21605b261ecSmrg if (winQueryScreenDIBFormat (pScreen, pbmih)) 21705b261ecSmrg { 21805b261ecSmrg /* Get a pointer to bitfields */ 21905b261ecSmrg pdw = (DWORD*) ((CARD8*)pbmih + sizeof (BITMAPINFOHEADER)); 22005b261ecSmrg 22105b261ecSmrg#if CYGDEBUG 22205b261ecSmrg winDebug ("%s - Masks: %08x %08x %08x\n", __FUNCTION__, 22305b261ecSmrg pdw[0], pdw[1], pdw[2]); 22405b261ecSmrg winDebug ("%s - Bitmap: %dx%d %d bpp %d planes\n", __FUNCTION__, 22505b261ecSmrg pbmih->biWidth, pbmih->biHeight, pbmih->biBitCount, pbmih->biPlanes); 22605b261ecSmrg winDebug ("%s - Compression: %d %s\n", __FUNCTION__, 22705b261ecSmrg pbmih->biCompression, 22805b261ecSmrg (pbmih->biCompression == BI_RGB?"(BI_RGB)": 22905b261ecSmrg (pbmih->biCompression == BI_RLE8?"(BI_RLE8)": 23005b261ecSmrg (pbmih->biCompression == BI_RLE4?"(BI_RLE4)": 23105b261ecSmrg (pbmih->biCompression == BI_BITFIELDS?"(BI_BITFIELDS)":"" 23205b261ecSmrg ))))); 23305b261ecSmrg#endif 23405b261ecSmrg 23505b261ecSmrg /* Handle BI_RGB case, which is returned by Wine */ 23605b261ecSmrg if (pbmih->biCompression == BI_RGB) 23705b261ecSmrg { 23805b261ecSmrg dwRedBits = 5; 23905b261ecSmrg dwGreenBits = 5; 24005b261ecSmrg dwBlueBits = 5; 24105b261ecSmrg 24205b261ecSmrg pScreenPriv->dwBitsPerRGB = 5; 24305b261ecSmrg 24405b261ecSmrg /* Set screen privates masks */ 24505b261ecSmrg pScreenPriv->dwRedMask = 0x7c00; 24605b261ecSmrg pScreenPriv->dwGreenMask = 0x03e0; 24705b261ecSmrg pScreenPriv->dwBlueMask = 0x001f; 24805b261ecSmrg } 24905b261ecSmrg else 25005b261ecSmrg { 25105b261ecSmrg /* Count the number of bits in each mask */ 25205b261ecSmrg dwRedBits = winCountBits (pdw[0]); 25305b261ecSmrg dwGreenBits = winCountBits (pdw[1]); 25405b261ecSmrg dwBlueBits = winCountBits (pdw[2]); 25505b261ecSmrg 25605b261ecSmrg /* Find maximum bits per red, green, blue */ 25705b261ecSmrg if (dwRedBits > dwGreenBits && dwRedBits > dwBlueBits) 25805b261ecSmrg pScreenPriv->dwBitsPerRGB = dwRedBits; 25905b261ecSmrg else if (dwGreenBits > dwRedBits && dwGreenBits > dwBlueBits) 26005b261ecSmrg pScreenPriv->dwBitsPerRGB = dwGreenBits; 26105b261ecSmrg else 26205b261ecSmrg pScreenPriv->dwBitsPerRGB = dwBlueBits; 26305b261ecSmrg 26405b261ecSmrg /* Set screen privates masks */ 26505b261ecSmrg pScreenPriv->dwRedMask = pdw[0]; 26605b261ecSmrg pScreenPriv->dwGreenMask = pdw[1]; 26705b261ecSmrg pScreenPriv->dwBlueMask = pdw[2]; 26805b261ecSmrg } 26905b261ecSmrg } 27005b261ecSmrg else 27105b261ecSmrg { 27205b261ecSmrg ErrorF ("winQueryRGBBitsAndMasks - winQueryScreenDIBFormat failed\n"); 27305b261ecSmrg free (pbmih); 27405b261ecSmrg fReturn = FALSE; 27505b261ecSmrg } 27605b261ecSmrg 27705b261ecSmrg /* Free memory */ 27805b261ecSmrg free (pbmih); 27905b261ecSmrg 28005b261ecSmrg return fReturn; 28105b261ecSmrg} 28205b261ecSmrg 28305b261ecSmrg 28405b261ecSmrg#ifdef XWIN_MULTIWINDOW 28505b261ecSmrg/* 28605b261ecSmrg * Redraw all ---? 28705b261ecSmrg */ 28805b261ecSmrg 28905b261ecSmrgstatic wBOOL CALLBACK 29005b261ecSmrgwinRedrawAllProcShadowGDI (HWND hwnd, LPARAM lParam) 29105b261ecSmrg{ 29205b261ecSmrg if (hwnd == (HWND)lParam) 29305b261ecSmrg return TRUE; 29405b261ecSmrg InvalidateRect (hwnd, NULL, FALSE); 29505b261ecSmrg UpdateWindow (hwnd); 29605b261ecSmrg return TRUE; 29705b261ecSmrg} 29805b261ecSmrg 29905b261ecSmrgstatic wBOOL CALLBACK 30005b261ecSmrgwinRedrawDamagedWindowShadowGDI (HWND hwnd, LPARAM lParam) 30105b261ecSmrg{ 30205b261ecSmrg BoxPtr pDamage = (BoxPtr)lParam; 30305b261ecSmrg RECT rcClient, rcDamage, rcRedraw; 30405b261ecSmrg POINT topLeft, bottomRight; 30505b261ecSmrg 30605b261ecSmrg if (IsIconic (hwnd)) 30705b261ecSmrg return TRUE; /* Don't care minimized windows */ 30805b261ecSmrg 30905b261ecSmrg /* Convert the damaged area from Screen coords to Client coords */ 31005b261ecSmrg topLeft.x = pDamage->x1; topLeft.y = pDamage->y1; 31105b261ecSmrg bottomRight.x = pDamage->x2; bottomRight.y = pDamage->y2; 31205b261ecSmrg topLeft.x += GetSystemMetrics (SM_XVIRTUALSCREEN); 31305b261ecSmrg bottomRight.x += GetSystemMetrics (SM_XVIRTUALSCREEN); 31405b261ecSmrg topLeft.y += GetSystemMetrics (SM_YVIRTUALSCREEN); 31505b261ecSmrg bottomRight.y += GetSystemMetrics (SM_YVIRTUALSCREEN); 31605b261ecSmrg ScreenToClient (hwnd, &topLeft); 31705b261ecSmrg ScreenToClient (hwnd, &bottomRight); 31805b261ecSmrg SetRect (&rcDamage, topLeft.x, topLeft.y, bottomRight.x, bottomRight.y); 31905b261ecSmrg 32005b261ecSmrg GetClientRect (hwnd, &rcClient); 32105b261ecSmrg 32205b261ecSmrg if (IntersectRect (&rcRedraw, &rcClient, &rcDamage)) 32305b261ecSmrg { 32405b261ecSmrg InvalidateRect (hwnd, &rcRedraw, FALSE); 32505b261ecSmrg UpdateWindow (hwnd); 32605b261ecSmrg } 32705b261ecSmrg return TRUE; 32805b261ecSmrg} 32905b261ecSmrg#endif 33005b261ecSmrg 33105b261ecSmrg 33205b261ecSmrg/* 33305b261ecSmrg * Allocate a DIB for the shadow framebuffer GDI server 33405b261ecSmrg */ 33505b261ecSmrg 33605b261ecSmrgstatic Bool 33705b261ecSmrgwinAllocateFBShadowGDI (ScreenPtr pScreen) 33805b261ecSmrg{ 33905b261ecSmrg winScreenPriv(pScreen); 34005b261ecSmrg winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; 34105b261ecSmrg DIBSECTION dibsection; 34205b261ecSmrg Bool fReturn = TRUE; 34305b261ecSmrg 34405b261ecSmrg /* Describe shadow bitmap to be created */ 3459ace9065Smrg pScreenPriv->pbmih->biWidth = pScreenInfo->dwWidth; 3469ace9065Smrg pScreenPriv->pbmih->biHeight = -pScreenInfo->dwHeight; 3479ace9065Smrg 34805b261ecSmrg ErrorF ("winAllocateFBShadowGDI - Creating DIB with width: %d height: %d " 34905b261ecSmrg "depth: %d\n", 3509ace9065Smrg (int) pScreenPriv->pbmih->biWidth, (int) -pScreenPriv->pbmih->biHeight, pScreenPriv->pbmih->biBitCount); 35105b261ecSmrg 35205b261ecSmrg /* Create a DI shadow bitmap with a bit pointer */ 35305b261ecSmrg pScreenPriv->hbmpShadow = CreateDIBSection (pScreenPriv->hdcScreen, 3549ace9065Smrg (BITMAPINFO *) pScreenPriv->pbmih, 35505b261ecSmrg DIB_RGB_COLORS, 35605b261ecSmrg (VOID**) &pScreenInfo->pfb, 35705b261ecSmrg NULL, 35805b261ecSmrg 0); 35905b261ecSmrg if (pScreenPriv->hbmpShadow == NULL || pScreenInfo->pfb == NULL) 36005b261ecSmrg { 36105b261ecSmrg winW32Error (2, "winAllocateFBShadowGDI - CreateDIBSection failed:"); 36205b261ecSmrg return FALSE; 36305b261ecSmrg } 36405b261ecSmrg else 36505b261ecSmrg { 36605b261ecSmrg#if CYGDEBUG 36705b261ecSmrg winDebug ("winAllocateFBShadowGDI - Shadow buffer allocated\n"); 36805b261ecSmrg#endif 36905b261ecSmrg } 37005b261ecSmrg 37105b261ecSmrg /* Get information about the bitmap that was allocated */ 37205b261ecSmrg GetObject (pScreenPriv->hbmpShadow, 37305b261ecSmrg sizeof (dibsection), 37405b261ecSmrg &dibsection); 37505b261ecSmrg 37605b261ecSmrg#if CYGDEBUG || YES 37705b261ecSmrg /* Print information about bitmap allocated */ 37805b261ecSmrg winDebug ("winAllocateFBShadowGDI - Dibsection width: %d height: %d " 37905b261ecSmrg "depth: %d size image: %d\n", 38005b261ecSmrg (int) dibsection.dsBmih.biWidth, (int) dibsection.dsBmih.biHeight, 38105b261ecSmrg dibsection.dsBmih.biBitCount, 38205b261ecSmrg (int) dibsection.dsBmih.biSizeImage); 38305b261ecSmrg#endif 38405b261ecSmrg 38505b261ecSmrg /* Select the shadow bitmap into the shadow DC */ 38605b261ecSmrg SelectObject (pScreenPriv->hdcShadow, 38705b261ecSmrg pScreenPriv->hbmpShadow); 38805b261ecSmrg 38905b261ecSmrg#if CYGDEBUG 39005b261ecSmrg winDebug ("winAllocateFBShadowGDI - Attempting a shadow blit\n"); 39105b261ecSmrg#endif 39205b261ecSmrg 39305b261ecSmrg /* Do a test blit from the shadow to the screen, I think */ 39405b261ecSmrg fReturn = BitBlt (pScreenPriv->hdcScreen, 39505b261ecSmrg 0, 0, 39605b261ecSmrg pScreenInfo->dwWidth, pScreenInfo->dwHeight, 39705b261ecSmrg pScreenPriv->hdcShadow, 39805b261ecSmrg 0, 0, 39905b261ecSmrg SRCCOPY); 40005b261ecSmrg if (fReturn) 40105b261ecSmrg { 40205b261ecSmrg#if CYGDEBUG 40305b261ecSmrg winDebug ("winAllocateFBShadowGDI - Shadow blit success\n"); 40405b261ecSmrg#endif 40505b261ecSmrg } 40605b261ecSmrg else 40705b261ecSmrg { 40805b261ecSmrg winW32Error (2, "winAllocateFBShadowGDI - Shadow blit failure\n"); 40905b261ecSmrg#if 0 41005b261ecSmrg return FALSE; 41105b261ecSmrg#else 41205b261ecSmrg /* ago: ignore this error. The blit fails with wine, but does not 41305b261ecSmrg * cause any problems later. */ 41405b261ecSmrg 41505b261ecSmrg fReturn = TRUE; 41605b261ecSmrg#endif 41705b261ecSmrg } 41805b261ecSmrg 41905b261ecSmrg /* Look for height weirdness */ 42005b261ecSmrg if (dibsection.dsBmih.biHeight < 0) 42105b261ecSmrg { 42205b261ecSmrg dibsection.dsBmih.biHeight = -dibsection.dsBmih.biHeight; 42305b261ecSmrg } 42405b261ecSmrg 42505b261ecSmrg /* Set screeninfo stride */ 42605b261ecSmrg pScreenInfo->dwStride = ((dibsection.dsBmih.biSizeImage 42705b261ecSmrg / dibsection.dsBmih.biHeight) 42805b261ecSmrg * 8) / pScreenInfo->dwBPP; 42905b261ecSmrg 43005b261ecSmrg#if CYGDEBUG || YES 43105b261ecSmrg winDebug ("winAllocateFBShadowGDI - Created shadow stride: %d\n", 43205b261ecSmrg (int) pScreenInfo->dwStride); 43305b261ecSmrg#endif 43405b261ecSmrg 43505b261ecSmrg#ifdef XWIN_MULTIWINDOW 43605b261ecSmrg /* Redraw all windows */ 43705b261ecSmrg if (pScreenInfo->fMultiWindow) 43805b261ecSmrg EnumThreadWindows (g_dwCurrentThreadID, winRedrawAllProcShadowGDI, 0); 43905b261ecSmrg#endif 44005b261ecSmrg 44105b261ecSmrg return fReturn; 44205b261ecSmrg} 44305b261ecSmrg 4449ace9065Smrgstatic void 4459ace9065SmrgwinFreeFBShadowGDI (ScreenPtr pScreen) 4469ace9065Smrg{ 4479ace9065Smrg winScreenPriv(pScreen); 4489ace9065Smrg winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; 4499ace9065Smrg 4509ace9065Smrg /* Free the shadow bitmap */ 4519ace9065Smrg DeleteObject (pScreenPriv->hbmpShadow); 4529ace9065Smrg 4539ace9065Smrg /* Invalidate the ScreenInfo's fb pointer */ 4549ace9065Smrg pScreenInfo->pfb = NULL; 4559ace9065Smrg} 45605b261ecSmrg 45705b261ecSmrg/* 45805b261ecSmrg * Blit the damaged regions of the shadow fb to the screen 45905b261ecSmrg */ 46005b261ecSmrg 46105b261ecSmrgstatic void 46205b261ecSmrgwinShadowUpdateGDI (ScreenPtr pScreen, 46305b261ecSmrg shadowBufPtr pBuf) 46405b261ecSmrg{ 46505b261ecSmrg winScreenPriv(pScreen); 46605b261ecSmrg winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; 4676747b715Smrg RegionPtr damage = shadowDamage(pBuf); 4686747b715Smrg DWORD dwBox = RegionNumRects (damage); 4696747b715Smrg BoxPtr pBox = RegionRects (damage); 47005b261ecSmrg int x, y, w, h; 47105b261ecSmrg HRGN hrgnTemp = NULL, hrgnCombined = NULL; 47205b261ecSmrg#ifdef XWIN_UPDATESTATS 47305b261ecSmrg static DWORD s_dwNonUnitRegions = 0; 47405b261ecSmrg static DWORD s_dwTotalUpdates = 0; 47505b261ecSmrg static DWORD s_dwTotalBoxes = 0; 47605b261ecSmrg#endif 4776747b715Smrg BoxPtr pBoxExtents = RegionExtents(damage); 47805b261ecSmrg 47905b261ecSmrg /* 48005b261ecSmrg * Return immediately if the app is not active 48105b261ecSmrg * and we are fullscreen, or if we have a bad display depth 48205b261ecSmrg */ 48305b261ecSmrg if ((!pScreenPriv->fActive && pScreenInfo->fFullScreen) 48405b261ecSmrg || pScreenPriv->fBadDepth) return; 48505b261ecSmrg 48605b261ecSmrg#ifdef XWIN_UPDATESTATS 48705b261ecSmrg ++s_dwTotalUpdates; 48805b261ecSmrg s_dwTotalBoxes += dwBox; 48905b261ecSmrg 49005b261ecSmrg if (dwBox != 1) 49105b261ecSmrg { 49205b261ecSmrg ++s_dwNonUnitRegions; 49305b261ecSmrg ErrorF ("winShadowUpdatGDI - dwBox: %d\n", dwBox); 49405b261ecSmrg } 49505b261ecSmrg 49605b261ecSmrg if ((s_dwTotalUpdates % 100) == 0) 49705b261ecSmrg ErrorF ("winShadowUpdateGDI - %d%% non-unity regions, avg boxes: %d " 49805b261ecSmrg "nu: %d tu: %d\n", 49905b261ecSmrg (s_dwNonUnitRegions * 100) / s_dwTotalUpdates, 50005b261ecSmrg s_dwTotalBoxes / s_dwTotalUpdates, 50105b261ecSmrg s_dwNonUnitRegions, s_dwTotalUpdates); 50205b261ecSmrg#endif /* XWIN_UPDATESTATS */ 50305b261ecSmrg 50405b261ecSmrg /* 50505b261ecSmrg * Handle small regions with multiple blits, 50605b261ecSmrg * handle large regions by creating a clipping region and 50705b261ecSmrg * doing a single blit constrained to that clipping region. 50805b261ecSmrg */ 50905b261ecSmrg if (!pScreenInfo->fMultiWindow && 51005b261ecSmrg (pScreenInfo->dwClipUpdatesNBoxes == 0 || 51105b261ecSmrg dwBox < pScreenInfo->dwClipUpdatesNBoxes)) 51205b261ecSmrg { 51305b261ecSmrg /* Loop through all boxes in the damaged region */ 51405b261ecSmrg while (dwBox--) 51505b261ecSmrg { 51605b261ecSmrg /* 51705b261ecSmrg * Calculate x offset, y offset, width, and height for 51805b261ecSmrg * current damage box 51905b261ecSmrg */ 52005b261ecSmrg x = pBox->x1; 52105b261ecSmrg y = pBox->y1; 52205b261ecSmrg w = pBox->x2 - pBox->x1; 52305b261ecSmrg h = pBox->y2 - pBox->y1; 52405b261ecSmrg 52505b261ecSmrg BitBlt (pScreenPriv->hdcScreen, 52605b261ecSmrg x, y, 52705b261ecSmrg w, h, 52805b261ecSmrg pScreenPriv->hdcShadow, 52905b261ecSmrg x, y, 53005b261ecSmrg SRCCOPY); 53105b261ecSmrg 53205b261ecSmrg /* Get a pointer to the next box */ 53305b261ecSmrg ++pBox; 53405b261ecSmrg } 53505b261ecSmrg } 53605b261ecSmrg else if (!pScreenInfo->fMultiWindow) 53705b261ecSmrg { 53805b261ecSmrg /* Compute a GDI region from the damaged region */ 53905b261ecSmrg hrgnCombined = CreateRectRgn (pBox->x1, pBox->y1, pBox->x2, pBox->y2); 54005b261ecSmrg dwBox--; 54105b261ecSmrg pBox++; 54205b261ecSmrg while (dwBox--) 54305b261ecSmrg { 54405b261ecSmrg hrgnTemp = CreateRectRgn (pBox->x1, pBox->y1, pBox->x2, pBox->y2); 54505b261ecSmrg CombineRgn (hrgnCombined, hrgnCombined, hrgnTemp, RGN_OR); 54605b261ecSmrg DeleteObject (hrgnTemp); 54705b261ecSmrg pBox++; 54805b261ecSmrg } 54905b261ecSmrg 55005b261ecSmrg /* Install the GDI region as a clipping region */ 55105b261ecSmrg SelectClipRgn (pScreenPriv->hdcScreen, hrgnCombined); 55205b261ecSmrg DeleteObject (hrgnCombined); 55305b261ecSmrg hrgnCombined = NULL; 55405b261ecSmrg 55505b261ecSmrg /* 55605b261ecSmrg * Blit the shadow buffer to the screen, 55705b261ecSmrg * constrained to the clipping region. 55805b261ecSmrg */ 55905b261ecSmrg BitBlt (pScreenPriv->hdcScreen, 56005b261ecSmrg pBoxExtents->x1, pBoxExtents->y1, 56105b261ecSmrg pBoxExtents->x2 - pBoxExtents->x1, 56205b261ecSmrg pBoxExtents->y2 - pBoxExtents->y1, 56305b261ecSmrg pScreenPriv->hdcShadow, 56405b261ecSmrg pBoxExtents->x1, pBoxExtents->y1, 56505b261ecSmrg SRCCOPY); 56605b261ecSmrg 56705b261ecSmrg /* Reset the clip region */ 56805b261ecSmrg SelectClipRgn (pScreenPriv->hdcScreen, NULL); 56905b261ecSmrg } 57005b261ecSmrg 57105b261ecSmrg#ifdef XWIN_MULTIWINDOW 57205b261ecSmrg /* Redraw all multiwindow windows */ 57305b261ecSmrg if (pScreenInfo->fMultiWindow) 57405b261ecSmrg EnumThreadWindows (g_dwCurrentThreadID, 57505b261ecSmrg winRedrawDamagedWindowShadowGDI, 57605b261ecSmrg (LPARAM)pBoxExtents); 57705b261ecSmrg#endif 57805b261ecSmrg} 57905b261ecSmrg 58005b261ecSmrg 5819ace9065Smrgstatic Bool 5829ace9065SmrgwinInitScreenShadowGDI (ScreenPtr pScreen) 5839ace9065Smrg{ 5849ace9065Smrg winScreenPriv(pScreen); 5859ace9065Smrg 5869ace9065Smrg /* Get device contexts for the screen and shadow bitmap */ 5879ace9065Smrg pScreenPriv->hdcScreen = GetDC (pScreenPriv->hwndScreen); 5889ace9065Smrg pScreenPriv->hdcShadow = CreateCompatibleDC (pScreenPriv->hdcScreen); 5899ace9065Smrg 5909ace9065Smrg /* Allocate bitmap info header */ 5919ace9065Smrg pScreenPriv->pbmih = (BITMAPINFOHEADER*) malloc (sizeof (BITMAPINFOHEADER) 5929ace9065Smrg + 256 * sizeof (RGBQUAD)); 5939ace9065Smrg if (pScreenPriv->pbmih == NULL) 5949ace9065Smrg { 5959ace9065Smrg ErrorF ("winInitScreenShadowGDI - malloc () failed\n"); 5969ace9065Smrg return FALSE; 5979ace9065Smrg } 5989ace9065Smrg 5999ace9065Smrg /* Query the screen format */ 6009ace9065Smrg if (!winQueryScreenDIBFormat (pScreen, pScreenPriv->pbmih)) 6019ace9065Smrg { 6029ace9065Smrg ErrorF ("winInitScreenShadowGDI - winQueryScreenDIBFormat failed\n"); 6039ace9065Smrg return FALSE; 6049ace9065Smrg } 6059ace9065Smrg 6069ace9065Smrg /* Determine our color masks */ 6079ace9065Smrg if (!winQueryRGBBitsAndMasks (pScreen)) 6089ace9065Smrg { 6099ace9065Smrg ErrorF ("winInitScreenShadowGDI - winQueryRGBBitsAndMasks failed\n"); 6109ace9065Smrg return FALSE; 6119ace9065Smrg } 6129ace9065Smrg 6139ace9065Smrg return winAllocateFBShadowGDI(pScreen); 6149ace9065Smrg} 6159ace9065Smrg 61605b261ecSmrg/* See Porting Layer Definition - p. 33 */ 61705b261ecSmrg/* 61805b261ecSmrg * We wrap whatever CloseScreen procedure was specified by fb; 61905b261ecSmrg * a pointer to said procedure is stored in our privates. 62005b261ecSmrg */ 62105b261ecSmrg 62205b261ecSmrgstatic Bool 62305b261ecSmrgwinCloseScreenShadowGDI (int nIndex, ScreenPtr pScreen) 62405b261ecSmrg{ 62505b261ecSmrg winScreenPriv(pScreen); 62605b261ecSmrg winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; 62705b261ecSmrg Bool fReturn; 62805b261ecSmrg 62905b261ecSmrg#if CYGDEBUG 63005b261ecSmrg winDebug ("winCloseScreenShadowGDI - Freeing screen resources\n"); 63105b261ecSmrg#endif 63205b261ecSmrg 63305b261ecSmrg /* Flag that the screen is closed */ 63405b261ecSmrg pScreenPriv->fClosed = TRUE; 63505b261ecSmrg pScreenPriv->fActive = FALSE; 63605b261ecSmrg 63705b261ecSmrg /* Call the wrapped CloseScreen procedure */ 63805b261ecSmrg WIN_UNWRAP(CloseScreen); 63905b261ecSmrg fReturn = (*pScreen->CloseScreen) (nIndex, pScreen); 64005b261ecSmrg 64105b261ecSmrg /* Delete the window property */ 64205b261ecSmrg RemoveProp (pScreenPriv->hwndScreen, WIN_SCR_PROP); 64305b261ecSmrg 64405b261ecSmrg /* Free the shadow DC; which allows the bitmap to be freed */ 64505b261ecSmrg DeleteDC (pScreenPriv->hdcShadow); 6469ace9065Smrg 6479ace9065Smrg winFreeFBShadowGDI(pScreen); 64805b261ecSmrg 64905b261ecSmrg /* Free the screen DC */ 65005b261ecSmrg ReleaseDC (pScreenPriv->hwndScreen, pScreenPriv->hdcScreen); 65105b261ecSmrg 65205b261ecSmrg /* Delete tray icon, if we have one */ 65305b261ecSmrg if (!pScreenInfo->fNoTrayIcon) 65405b261ecSmrg winDeleteNotifyIcon (pScreenPriv); 65505b261ecSmrg 65605b261ecSmrg /* Free the exit confirmation dialog box, if it exists */ 65705b261ecSmrg if (g_hDlgExit != NULL) 65805b261ecSmrg { 65905b261ecSmrg DestroyWindow (g_hDlgExit); 66005b261ecSmrg g_hDlgExit = NULL; 66105b261ecSmrg } 66205b261ecSmrg 66305b261ecSmrg /* Kill our window */ 66405b261ecSmrg if (pScreenPriv->hwndScreen) 66505b261ecSmrg { 66605b261ecSmrg DestroyWindow (pScreenPriv->hwndScreen); 66705b261ecSmrg pScreenPriv->hwndScreen = NULL; 66805b261ecSmrg } 66905b261ecSmrg 67005b261ecSmrg#if defined(XWIN_CLIPBOARD) || defined(XWIN_MULTIWINDOW) 67105b261ecSmrg /* Destroy the thread startup mutex */ 67205b261ecSmrg pthread_mutex_destroy (&pScreenPriv->pmServerStarted); 67305b261ecSmrg#endif 67405b261ecSmrg 67505b261ecSmrg /* Invalidate our screeninfo's pointer to the screen */ 67605b261ecSmrg pScreenInfo->pScreen = NULL; 67705b261ecSmrg 67805b261ecSmrg /* Free the screen privates for this screen */ 67905b261ecSmrg free ((pointer) pScreenPriv); 68005b261ecSmrg 68105b261ecSmrg return fReturn; 68205b261ecSmrg} 68305b261ecSmrg 68405b261ecSmrg 68505b261ecSmrg/* 68605b261ecSmrg * Tell mi what sort of visuals we need. 68705b261ecSmrg * 68805b261ecSmrg * Generally we only need one visual, as our screen can only 68905b261ecSmrg * handle one format at a time, I believe. You may want 69005b261ecSmrg * to verify that last sentence. 69105b261ecSmrg */ 69205b261ecSmrg 69305b261ecSmrgstatic Bool 69405b261ecSmrgwinInitVisualsShadowGDI (ScreenPtr pScreen) 69505b261ecSmrg{ 69605b261ecSmrg winScreenPriv(pScreen); 69705b261ecSmrg winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; 69805b261ecSmrg 69905b261ecSmrg /* Display debugging information */ 70005b261ecSmrg ErrorF ("winInitVisualsShadowGDI - Masks %08x %08x %08x BPRGB %d d %d " 70105b261ecSmrg "bpp %d\n", 70205b261ecSmrg (unsigned int) pScreenPriv->dwRedMask, 70305b261ecSmrg (unsigned int) pScreenPriv->dwGreenMask, 70405b261ecSmrg (unsigned int) pScreenPriv->dwBlueMask, 70505b261ecSmrg (int) pScreenPriv->dwBitsPerRGB, 70605b261ecSmrg (int) pScreenInfo->dwDepth, 70705b261ecSmrg (int) pScreenInfo->dwBPP); 70805b261ecSmrg 70905b261ecSmrg /* Create a single visual according to the Windows screen depth */ 71005b261ecSmrg switch (pScreenInfo->dwDepth) 71105b261ecSmrg { 71205b261ecSmrg case 24: 71305b261ecSmrg case 16: 71405b261ecSmrg case 15: 71505b261ecSmrg /* Setup the real visual */ 71605b261ecSmrg if (!miSetVisualTypesAndMasks (pScreenInfo->dwDepth, 71705b261ecSmrg TrueColorMask, 71805b261ecSmrg pScreenPriv->dwBitsPerRGB, 71905b261ecSmrg -1, 72005b261ecSmrg pScreenPriv->dwRedMask, 72105b261ecSmrg pScreenPriv->dwGreenMask, 72205b261ecSmrg pScreenPriv->dwBlueMask)) 72305b261ecSmrg { 72405b261ecSmrg ErrorF ("winInitVisualsShadowGDI - miSetVisualTypesAndMasks " 72505b261ecSmrg "failed\n"); 72605b261ecSmrg return FALSE; 72705b261ecSmrg } 72805b261ecSmrg 72905b261ecSmrg#ifdef XWIN_EMULATEPSEUDO 73005b261ecSmrg if (!pScreenInfo->fEmulatePseudo) 73105b261ecSmrg break; 73205b261ecSmrg 73305b261ecSmrg /* Setup a pseudocolor visual */ 73405b261ecSmrg if (!miSetVisualTypesAndMasks (8, 73505b261ecSmrg PseudoColorMask, 73605b261ecSmrg 8, 73705b261ecSmrg -1, 73805b261ecSmrg 0, 73905b261ecSmrg 0, 74005b261ecSmrg 0)) 74105b261ecSmrg { 74205b261ecSmrg ErrorF ("winInitVisualsShadowGDI - miSetVisualTypesAndMasks " 74305b261ecSmrg "failed for PseudoColor\n"); 74405b261ecSmrg return FALSE; 74505b261ecSmrg } 74605b261ecSmrg#endif 74705b261ecSmrg break; 74805b261ecSmrg 74905b261ecSmrg case 8: 75005b261ecSmrg if (!miSetVisualTypesAndMasks (pScreenInfo->dwDepth, 75105b261ecSmrg PseudoColorMask, 75205b261ecSmrg pScreenPriv->dwBitsPerRGB, 75305b261ecSmrg PseudoColor, 75405b261ecSmrg pScreenPriv->dwRedMask, 75505b261ecSmrg pScreenPriv->dwGreenMask, 75605b261ecSmrg pScreenPriv->dwBlueMask)) 75705b261ecSmrg { 75805b261ecSmrg ErrorF ("winInitVisualsShadowGDI - miSetVisualTypesAndMasks " 75905b261ecSmrg "failed\n"); 76005b261ecSmrg return FALSE; 76105b261ecSmrg } 76205b261ecSmrg break; 76305b261ecSmrg 76405b261ecSmrg default: 76505b261ecSmrg ErrorF ("winInitVisualsShadowGDI - Unknown screen depth\n"); 76605b261ecSmrg return FALSE; 76705b261ecSmrg } 76805b261ecSmrg 76905b261ecSmrg#if CYGDEBUG 77005b261ecSmrg winDebug ("winInitVisualsShadowGDI - Returning\n"); 77105b261ecSmrg#endif 77205b261ecSmrg 77305b261ecSmrg return TRUE; 77405b261ecSmrg} 77505b261ecSmrg 77605b261ecSmrg 77705b261ecSmrg/* 77805b261ecSmrg * Adjust the proposed video mode 77905b261ecSmrg */ 78005b261ecSmrg 78105b261ecSmrgstatic Bool 78205b261ecSmrgwinAdjustVideoModeShadowGDI (ScreenPtr pScreen) 78305b261ecSmrg{ 78405b261ecSmrg winScreenPriv(pScreen); 78505b261ecSmrg winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; 78605b261ecSmrg HDC hdc; 78705b261ecSmrg DWORD dwBPP; 78805b261ecSmrg 78905b261ecSmrg hdc = GetDC (NULL); 79005b261ecSmrg 79105b261ecSmrg /* We're in serious trouble if we can't get a DC */ 79205b261ecSmrg if (hdc == NULL) 79305b261ecSmrg { 79405b261ecSmrg ErrorF ("winAdjustVideoModeShadowGDI - GetDC () failed\n"); 79505b261ecSmrg return FALSE; 79605b261ecSmrg } 79705b261ecSmrg 79805b261ecSmrg /* Query GDI for current display depth */ 79905b261ecSmrg dwBPP = GetDeviceCaps (hdc, BITSPIXEL); 80005b261ecSmrg 8019ace9065Smrg /* GDI cannot change the screen depth, so always use GDI's depth */ 8029ace9065Smrg pScreenInfo->dwBPP = dwBPP; 80305b261ecSmrg 80405b261ecSmrg /* Release our DC */ 80505b261ecSmrg ReleaseDC (NULL, hdc); 80605b261ecSmrg hdc = NULL; 80705b261ecSmrg 80805b261ecSmrg return TRUE; 80905b261ecSmrg} 81005b261ecSmrg 81105b261ecSmrg 81205b261ecSmrg/* 81305b261ecSmrg * Blt exposed regions to the screen 81405b261ecSmrg */ 81505b261ecSmrg 81605b261ecSmrgstatic Bool 81705b261ecSmrgwinBltExposedRegionsShadowGDI (ScreenPtr pScreen) 81805b261ecSmrg{ 81905b261ecSmrg winScreenPriv(pScreen); 82005b261ecSmrg winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; 82105b261ecSmrg winPrivCmapPtr pCmapPriv = NULL; 82205b261ecSmrg HDC hdcUpdate; 82305b261ecSmrg PAINTSTRUCT ps; 82405b261ecSmrg 82505b261ecSmrg /* BeginPaint gives us an hdc that clips to the invalidated region */ 82605b261ecSmrg hdcUpdate = BeginPaint (pScreenPriv->hwndScreen, &ps); 82705b261ecSmrg 82805b261ecSmrg /* Realize the palette, if we have one */ 82905b261ecSmrg if (pScreenPriv->pcmapInstalled != NULL) 83005b261ecSmrg { 83105b261ecSmrg pCmapPriv = winGetCmapPriv (pScreenPriv->pcmapInstalled); 83205b261ecSmrg 83305b261ecSmrg SelectPalette (hdcUpdate, pCmapPriv->hPalette, FALSE); 83405b261ecSmrg RealizePalette (hdcUpdate); 83505b261ecSmrg } 83605b261ecSmrg 83705b261ecSmrg /* Our BitBlt will be clipped to the invalidated region */ 83805b261ecSmrg BitBlt (hdcUpdate, 83905b261ecSmrg 0, 0, 84005b261ecSmrg pScreenInfo->dwWidth, pScreenInfo->dwHeight, 84105b261ecSmrg pScreenPriv->hdcShadow, 84205b261ecSmrg 0, 0, 84305b261ecSmrg SRCCOPY); 84405b261ecSmrg 84505b261ecSmrg /* EndPaint frees the DC */ 84605b261ecSmrg EndPaint (pScreenPriv->hwndScreen, &ps); 84705b261ecSmrg 84805b261ecSmrg#ifdef XWIN_MULTIWINDOW 84905b261ecSmrg /* Redraw all windows */ 85005b261ecSmrg if (pScreenInfo->fMultiWindow) 85105b261ecSmrg EnumThreadWindows(g_dwCurrentThreadID, winRedrawAllProcShadowGDI, 85205b261ecSmrg (LPARAM)pScreenPriv->hwndScreen); 85305b261ecSmrg#endif 85405b261ecSmrg 85505b261ecSmrg return TRUE; 85605b261ecSmrg} 85705b261ecSmrg 85805b261ecSmrg 85905b261ecSmrg/* 86005b261ecSmrg * Do any engine-specific appliation-activation processing 86105b261ecSmrg */ 86205b261ecSmrg 86305b261ecSmrgstatic Bool 86405b261ecSmrgwinActivateAppShadowGDI (ScreenPtr pScreen) 86505b261ecSmrg{ 86605b261ecSmrg winScreenPriv(pScreen); 86705b261ecSmrg winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; 86805b261ecSmrg 86905b261ecSmrg /* 87005b261ecSmrg * 2004/04/12 - Harold - We perform the restoring or minimizing 87105b261ecSmrg * manually for ShadowGDI in fullscreen modes so that this engine 87205b261ecSmrg * will perform just like ShadowDD and ShadowDDNL in fullscreen mode; 87305b261ecSmrg * if we do not do this then our fullscreen window will appear in the 87405b261ecSmrg * z-order when it is deactivated and it can be uncovered by resizing 87505b261ecSmrg * or minimizing another window that is on top of it, which is not how 87605b261ecSmrg * the DirectDraw engines work. Therefore we keep this code here to 87705b261ecSmrg * make sure that all engines work the same in fullscreen mode. 87805b261ecSmrg */ 87905b261ecSmrg 88005b261ecSmrg /* 88105b261ecSmrg * Are we active? 88205b261ecSmrg * Are we fullscreen? 88305b261ecSmrg */ 88405b261ecSmrg if (pScreenPriv->fActive 88505b261ecSmrg && pScreenInfo->fFullScreen) 88605b261ecSmrg { 88705b261ecSmrg /* 88805b261ecSmrg * Activating, attempt to bring our window 88905b261ecSmrg * to the top of the display 89005b261ecSmrg */ 89105b261ecSmrg ShowWindow (pScreenPriv->hwndScreen, SW_RESTORE); 89205b261ecSmrg } 89305b261ecSmrg else if (!pScreenPriv->fActive 89405b261ecSmrg && pScreenInfo->fFullScreen) 89505b261ecSmrg { 89605b261ecSmrg /* 89705b261ecSmrg * Deactivating, stuff our window onto the 89805b261ecSmrg * task bar. 89905b261ecSmrg */ 90005b261ecSmrg ShowWindow (pScreenPriv->hwndScreen, SW_MINIMIZE); 90105b261ecSmrg } 90205b261ecSmrg 90305b261ecSmrg return TRUE; 90405b261ecSmrg} 90505b261ecSmrg 90605b261ecSmrg 90705b261ecSmrg/* 90805b261ecSmrg * Reblit the shadow framebuffer to the screen. 90905b261ecSmrg */ 91005b261ecSmrg 91105b261ecSmrgstatic Bool 91205b261ecSmrgwinRedrawScreenShadowGDI (ScreenPtr pScreen) 91305b261ecSmrg{ 91405b261ecSmrg winScreenPriv(pScreen); 91505b261ecSmrg winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; 91605b261ecSmrg 91705b261ecSmrg /* Redraw the whole window, to take account for the new colors */ 91805b261ecSmrg BitBlt (pScreenPriv->hdcScreen, 91905b261ecSmrg 0, 0, 92005b261ecSmrg pScreenInfo->dwWidth, pScreenInfo->dwHeight, 92105b261ecSmrg pScreenPriv->hdcShadow, 92205b261ecSmrg 0, 0, 92305b261ecSmrg SRCCOPY); 92405b261ecSmrg 92505b261ecSmrg#ifdef XWIN_MULTIWINDOW 92605b261ecSmrg /* Redraw all windows */ 92705b261ecSmrg if (pScreenInfo->fMultiWindow) 92805b261ecSmrg EnumThreadWindows(g_dwCurrentThreadID, winRedrawAllProcShadowGDI, 0); 92905b261ecSmrg#endif 93005b261ecSmrg 93105b261ecSmrg return TRUE; 93205b261ecSmrg} 93305b261ecSmrg 93405b261ecSmrg 93505b261ecSmrg 93605b261ecSmrg/* 93705b261ecSmrg * Realize the currently installed colormap 93805b261ecSmrg */ 93905b261ecSmrg 94005b261ecSmrgstatic Bool 94105b261ecSmrgwinRealizeInstalledPaletteShadowGDI (ScreenPtr pScreen) 94205b261ecSmrg{ 94305b261ecSmrg winScreenPriv(pScreen); 94405b261ecSmrg winPrivCmapPtr pCmapPriv = NULL; 94505b261ecSmrg 94605b261ecSmrg#if CYGDEBUG 94705b261ecSmrg winDebug ("winRealizeInstalledPaletteShadowGDI\n"); 94805b261ecSmrg#endif 94905b261ecSmrg 95005b261ecSmrg /* Don't do anything if there is not a colormap */ 95105b261ecSmrg if (pScreenPriv->pcmapInstalled == NULL) 95205b261ecSmrg { 95305b261ecSmrg#if CYGDEBUG 95405b261ecSmrg winDebug ("winRealizeInstalledPaletteShadowGDI - No colormap " 95505b261ecSmrg "installed\n"); 95605b261ecSmrg#endif 95705b261ecSmrg return TRUE; 95805b261ecSmrg } 95905b261ecSmrg 96005b261ecSmrg pCmapPriv = winGetCmapPriv (pScreenPriv->pcmapInstalled); 96105b261ecSmrg 96205b261ecSmrg /* Realize our palette for the screen */ 96305b261ecSmrg if (RealizePalette (pScreenPriv->hdcScreen) == GDI_ERROR) 96405b261ecSmrg { 96505b261ecSmrg ErrorF ("winRealizeInstalledPaletteShadowGDI - RealizePalette () " 96605b261ecSmrg "failed\n"); 96705b261ecSmrg return FALSE; 96805b261ecSmrg } 96905b261ecSmrg 97005b261ecSmrg /* Set the DIB color table */ 97105b261ecSmrg if (SetDIBColorTable (pScreenPriv->hdcShadow, 97205b261ecSmrg 0, 97305b261ecSmrg WIN_NUM_PALETTE_ENTRIES, 97405b261ecSmrg pCmapPriv->rgbColors) == 0) 97505b261ecSmrg { 97605b261ecSmrg ErrorF ("winRealizeInstalledPaletteShadowGDI - SetDIBColorTable () " 97705b261ecSmrg "failed\n"); 97805b261ecSmrg return FALSE; 97905b261ecSmrg } 98005b261ecSmrg 98105b261ecSmrg return TRUE; 98205b261ecSmrg} 98305b261ecSmrg 98405b261ecSmrg 98505b261ecSmrg/* 98605b261ecSmrg * Install the specified colormap 98705b261ecSmrg */ 98805b261ecSmrg 98905b261ecSmrgstatic Bool 99005b261ecSmrgwinInstallColormapShadowGDI (ColormapPtr pColormap) 99105b261ecSmrg{ 99205b261ecSmrg ScreenPtr pScreen = pColormap->pScreen; 99305b261ecSmrg winScreenPriv(pScreen); 99405b261ecSmrg winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; 99505b261ecSmrg winCmapPriv(pColormap); 99605b261ecSmrg 99705b261ecSmrg /* 99805b261ecSmrg * Tell Windows to install the new colormap 99905b261ecSmrg */ 100005b261ecSmrg if (SelectPalette (pScreenPriv->hdcScreen, 100105b261ecSmrg pCmapPriv->hPalette, 100205b261ecSmrg FALSE) == NULL) 100305b261ecSmrg { 100405b261ecSmrg ErrorF ("winInstallColormapShadowGDI - SelectPalette () failed\n"); 100505b261ecSmrg return FALSE; 100605b261ecSmrg } 100705b261ecSmrg 100805b261ecSmrg /* Realize the palette */ 100905b261ecSmrg if (GDI_ERROR == RealizePalette (pScreenPriv->hdcScreen)) 101005b261ecSmrg { 101105b261ecSmrg ErrorF ("winInstallColormapShadowGDI - RealizePalette () failed\n"); 101205b261ecSmrg return FALSE; 101305b261ecSmrg } 101405b261ecSmrg 101505b261ecSmrg /* Set the DIB color table */ 101605b261ecSmrg if (SetDIBColorTable (pScreenPriv->hdcShadow, 101705b261ecSmrg 0, 101805b261ecSmrg WIN_NUM_PALETTE_ENTRIES, 101905b261ecSmrg pCmapPriv->rgbColors) == 0) 102005b261ecSmrg { 102105b261ecSmrg ErrorF ("winInstallColormapShadowGDI - SetDIBColorTable () failed\n"); 102205b261ecSmrg return FALSE; 102305b261ecSmrg } 102405b261ecSmrg 102505b261ecSmrg /* Redraw the whole window, to take account for the new colors */ 102605b261ecSmrg BitBlt (pScreenPriv->hdcScreen, 102705b261ecSmrg 0, 0, 102805b261ecSmrg pScreenInfo->dwWidth, pScreenInfo->dwHeight, 102905b261ecSmrg pScreenPriv->hdcShadow, 103005b261ecSmrg 0, 0, 103105b261ecSmrg SRCCOPY); 103205b261ecSmrg 103305b261ecSmrg /* Save a pointer to the newly installed colormap */ 103405b261ecSmrg pScreenPriv->pcmapInstalled = pColormap; 103505b261ecSmrg 103605b261ecSmrg#ifdef XWIN_MULTIWINDOW 103705b261ecSmrg /* Redraw all windows */ 103805b261ecSmrg if (pScreenInfo->fMultiWindow) 103905b261ecSmrg EnumThreadWindows (g_dwCurrentThreadID, winRedrawAllProcShadowGDI, 0); 104005b261ecSmrg#endif 104105b261ecSmrg 104205b261ecSmrg return TRUE; 104305b261ecSmrg} 104405b261ecSmrg 104505b261ecSmrg 104605b261ecSmrg/* 104705b261ecSmrg * Store the specified colors in the specified colormap 104805b261ecSmrg */ 104905b261ecSmrg 105005b261ecSmrgstatic Bool 105105b261ecSmrgwinStoreColorsShadowGDI (ColormapPtr pColormap, 105205b261ecSmrg int ndef, 105305b261ecSmrg xColorItem *pdefs) 105405b261ecSmrg{ 105505b261ecSmrg ScreenPtr pScreen = pColormap->pScreen; 105605b261ecSmrg winScreenPriv(pScreen); 105705b261ecSmrg winCmapPriv(pColormap); 105805b261ecSmrg ColormapPtr curpmap = pScreenPriv->pcmapInstalled; 105905b261ecSmrg 106005b261ecSmrg /* Put the X colormap entries into the Windows logical palette */ 106105b261ecSmrg if (SetPaletteEntries (pCmapPriv->hPalette, 106205b261ecSmrg pdefs[0].pixel, 106305b261ecSmrg ndef, 106405b261ecSmrg pCmapPriv->peColors + pdefs[0].pixel) == 0) 106505b261ecSmrg { 106605b261ecSmrg ErrorF ("winStoreColorsShadowGDI - SetPaletteEntries () failed\n"); 106705b261ecSmrg return FALSE; 106805b261ecSmrg } 106905b261ecSmrg 107005b261ecSmrg /* Don't install the Windows palette if the colormap is not installed */ 107105b261ecSmrg if (pColormap != curpmap) 107205b261ecSmrg { 107305b261ecSmrg return TRUE; 107405b261ecSmrg } 107505b261ecSmrg 107605b261ecSmrg /* Try to install the newly modified colormap */ 107705b261ecSmrg if (!winInstallColormapShadowGDI (pColormap)) 107805b261ecSmrg { 107905b261ecSmrg ErrorF ("winInstallColormapShadowGDI - winInstallColormapShadowGDI " 108005b261ecSmrg "failed\n"); 108105b261ecSmrg return FALSE; 108205b261ecSmrg } 108305b261ecSmrg 108405b261ecSmrg#if 0 108505b261ecSmrg /* Tell Windows that the palette has changed */ 108605b261ecSmrg RealizePalette (pScreenPriv->hdcScreen); 108705b261ecSmrg 108805b261ecSmrg /* Set the DIB color table */ 108905b261ecSmrg if (SetDIBColorTable (pScreenPriv->hdcShadow, 109005b261ecSmrg pdefs[0].pixel, 109105b261ecSmrg ndef, 109205b261ecSmrg pCmapPriv->rgbColors + pdefs[0].pixel) == 0) 109305b261ecSmrg { 109405b261ecSmrg ErrorF ("winInstallColormapShadowGDI - SetDIBColorTable () failed\n"); 109505b261ecSmrg return FALSE; 109605b261ecSmrg } 109705b261ecSmrg 109805b261ecSmrg /* Save a pointer to the newly installed colormap */ 109905b261ecSmrg pScreenPriv->pcmapInstalled = pColormap; 110005b261ecSmrg#endif 110105b261ecSmrg 110205b261ecSmrg return TRUE; 110305b261ecSmrg} 110405b261ecSmrg 110505b261ecSmrg 110605b261ecSmrg/* 110705b261ecSmrg * Colormap initialization procedure 110805b261ecSmrg */ 110905b261ecSmrg 111005b261ecSmrgstatic Bool 111105b261ecSmrgwinCreateColormapShadowGDI (ColormapPtr pColormap) 111205b261ecSmrg{ 111305b261ecSmrg LPLOGPALETTE lpPaletteNew = NULL; 111405b261ecSmrg DWORD dwEntriesMax; 111505b261ecSmrg VisualPtr pVisual; 111605b261ecSmrg HPALETTE hpalNew = NULL; 111705b261ecSmrg winCmapPriv(pColormap); 111805b261ecSmrg 111905b261ecSmrg /* Get a pointer to the visual that the colormap belongs to */ 112005b261ecSmrg pVisual = pColormap->pVisual; 112105b261ecSmrg 112205b261ecSmrg /* Get the maximum number of palette entries for this visual */ 112305b261ecSmrg dwEntriesMax = pVisual->ColormapEntries; 112405b261ecSmrg 112505b261ecSmrg /* Allocate a Windows logical color palette with max entries */ 112605b261ecSmrg lpPaletteNew = malloc (sizeof (LOGPALETTE) 112705b261ecSmrg + (dwEntriesMax - 1) * sizeof (PALETTEENTRY)); 112805b261ecSmrg if (lpPaletteNew == NULL) 112905b261ecSmrg { 113005b261ecSmrg ErrorF ("winCreateColormapShadowGDI - Couldn't allocate palette " 113105b261ecSmrg "with %d entries\n", 113205b261ecSmrg (int) dwEntriesMax); 113305b261ecSmrg return FALSE; 113405b261ecSmrg } 113505b261ecSmrg 113605b261ecSmrg /* Zero out the colormap */ 113705b261ecSmrg ZeroMemory (lpPaletteNew, sizeof (LOGPALETTE) 113805b261ecSmrg + (dwEntriesMax - 1) * sizeof (PALETTEENTRY)); 113905b261ecSmrg 114005b261ecSmrg /* Set the logical palette structure */ 114105b261ecSmrg lpPaletteNew->palVersion = 0x0300; 114205b261ecSmrg lpPaletteNew->palNumEntries = dwEntriesMax; 114305b261ecSmrg 114405b261ecSmrg /* Tell Windows to create the palette */ 114505b261ecSmrg hpalNew = CreatePalette (lpPaletteNew); 114605b261ecSmrg if (hpalNew == NULL) 114705b261ecSmrg { 114805b261ecSmrg ErrorF ("winCreateColormapShadowGDI - CreatePalette () failed\n"); 114905b261ecSmrg free (lpPaletteNew); 115005b261ecSmrg return FALSE; 115105b261ecSmrg } 115205b261ecSmrg 115305b261ecSmrg /* Save the Windows logical palette handle in the X colormaps' privates */ 115405b261ecSmrg pCmapPriv->hPalette = hpalNew; 115505b261ecSmrg 115605b261ecSmrg /* Free the palette initialization memory */ 115705b261ecSmrg free (lpPaletteNew); 115805b261ecSmrg 115905b261ecSmrg return TRUE; 116005b261ecSmrg} 116105b261ecSmrg 116205b261ecSmrg 116305b261ecSmrg/* 116405b261ecSmrg * Colormap destruction procedure 116505b261ecSmrg */ 116605b261ecSmrg 116705b261ecSmrgstatic Bool 116805b261ecSmrgwinDestroyColormapShadowGDI (ColormapPtr pColormap) 116905b261ecSmrg{ 117005b261ecSmrg winScreenPriv(pColormap->pScreen); 117105b261ecSmrg winCmapPriv(pColormap); 117205b261ecSmrg 117305b261ecSmrg /* 117405b261ecSmrg * Is colormap to be destroyed the default? 117505b261ecSmrg * 117605b261ecSmrg * Non-default colormaps should have had winUninstallColormap 117705b261ecSmrg * called on them before we get here. The default colormap 117805b261ecSmrg * will not have had winUninstallColormap called on it. Thus, 117905b261ecSmrg * we need to handle the default colormap in a special way. 118005b261ecSmrg */ 118105b261ecSmrg if (pColormap->flags & IsDefault) 118205b261ecSmrg { 118305b261ecSmrg#if CYGDEBUG 118405b261ecSmrg winDebug ("winDestroyColormapShadowGDI - Destroying default " 118505b261ecSmrg "colormap\n"); 118605b261ecSmrg#endif 118705b261ecSmrg 118805b261ecSmrg /* 118905b261ecSmrg * FIXME: Walk the list of all screens, popping the default 119005b261ecSmrg * palette out of each screen device context. 119105b261ecSmrg */ 119205b261ecSmrg 119305b261ecSmrg /* Pop the palette out of the device context */ 119405b261ecSmrg SelectPalette (pScreenPriv->hdcScreen, 119505b261ecSmrg GetStockObject (DEFAULT_PALETTE), 119605b261ecSmrg FALSE); 119705b261ecSmrg 119805b261ecSmrg /* Clear our private installed colormap pointer */ 119905b261ecSmrg pScreenPriv->pcmapInstalled = NULL; 120005b261ecSmrg } 120105b261ecSmrg 120205b261ecSmrg /* Try to delete the logical palette */ 120305b261ecSmrg if (DeleteObject (pCmapPriv->hPalette) == 0) 120405b261ecSmrg { 120505b261ecSmrg ErrorF ("winDestroyColormap - DeleteObject () failed\n"); 120605b261ecSmrg return FALSE; 120705b261ecSmrg } 120805b261ecSmrg 120905b261ecSmrg /* Invalidate the colormap privates */ 121005b261ecSmrg pCmapPriv->hPalette = NULL; 121105b261ecSmrg 121205b261ecSmrg return TRUE; 121305b261ecSmrg} 121405b261ecSmrg 121505b261ecSmrg 121605b261ecSmrg/* 121705b261ecSmrg * Set engine specific funtions 121805b261ecSmrg */ 121905b261ecSmrg 122005b261ecSmrgBool 122105b261ecSmrgwinSetEngineFunctionsShadowGDI (ScreenPtr pScreen) 122205b261ecSmrg{ 122305b261ecSmrg winScreenPriv(pScreen); 122405b261ecSmrg winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; 122505b261ecSmrg 122605b261ecSmrg /* Set our pointers */ 122705b261ecSmrg pScreenPriv->pwinAllocateFB = winAllocateFBShadowGDI; 12289ace9065Smrg pScreenPriv->pwinFreeFB = winFreeFBShadowGDI; 122905b261ecSmrg pScreenPriv->pwinShadowUpdate = winShadowUpdateGDI; 12309ace9065Smrg pScreenPriv->pwinInitScreen = winInitScreenShadowGDI; 123105b261ecSmrg pScreenPriv->pwinCloseScreen = winCloseScreenShadowGDI; 123205b261ecSmrg pScreenPriv->pwinInitVisuals = winInitVisualsShadowGDI; 123305b261ecSmrg pScreenPriv->pwinAdjustVideoMode = winAdjustVideoModeShadowGDI; 123405b261ecSmrg if (pScreenInfo->fFullScreen) 123505b261ecSmrg pScreenPriv->pwinCreateBoundingWindow = winCreateBoundingWindowFullScreen; 123605b261ecSmrg else 123705b261ecSmrg pScreenPriv->pwinCreateBoundingWindow = winCreateBoundingWindowWindowed; 123805b261ecSmrg pScreenPriv->pwinFinishScreenInit = winFinishScreenInitFB; 123905b261ecSmrg pScreenPriv->pwinBltExposedRegions = winBltExposedRegionsShadowGDI; 124005b261ecSmrg pScreenPriv->pwinActivateApp = winActivateAppShadowGDI; 124105b261ecSmrg pScreenPriv->pwinRedrawScreen = winRedrawScreenShadowGDI; 124205b261ecSmrg pScreenPriv->pwinRealizeInstalledPalette = 124305b261ecSmrg winRealizeInstalledPaletteShadowGDI; 124405b261ecSmrg pScreenPriv->pwinInstallColormap = winInstallColormapShadowGDI; 124505b261ecSmrg pScreenPriv->pwinStoreColors = winStoreColorsShadowGDI; 124605b261ecSmrg pScreenPriv->pwinCreateColormap = winCreateColormapShadowGDI; 124705b261ecSmrg pScreenPriv->pwinDestroyColormap = winDestroyColormapShadowGDI; 124805b261ecSmrg pScreenPriv->pwinHotKeyAltTab = (winHotKeyAltTabProcPtr) (void (*)(void))NoopDDA; 124905b261ecSmrg pScreenPriv->pwinCreatePrimarySurface 125005b261ecSmrg = (winCreatePrimarySurfaceProcPtr) (void (*)(void))NoopDDA; 125105b261ecSmrg pScreenPriv->pwinReleasePrimarySurface 125205b261ecSmrg = (winReleasePrimarySurfaceProcPtr) (void (*)(void))NoopDDA; 125305b261ecSmrg#ifdef XWIN_MULTIWINDOW 125405b261ecSmrg pScreenPriv->pwinFinishCreateWindowsWindow = 125505b261ecSmrg (winFinishCreateWindowsWindowProcPtr) (void (*)(void))NoopDDA; 125605b261ecSmrg#endif 125705b261ecSmrg 125805b261ecSmrg return TRUE; 125905b261ecSmrg} 1260