1706f2543Smrg/* 2706f2543Smrg *Copyright (C) 2001-2004 Harold L Hunt II All Rights Reserved. 3706f2543Smrg * 4706f2543Smrg *Permission is hereby granted, free of charge, to any person obtaining 5706f2543Smrg * a copy of this software and associated documentation files (the 6706f2543Smrg *"Software"), to deal in the Software without restriction, including 7706f2543Smrg *without limitation the rights to use, copy, modify, merge, publish, 8706f2543Smrg *distribute, sublicense, and/or sell copies of the Software, and to 9706f2543Smrg *permit persons to whom the Software is furnished to do so, subject to 10706f2543Smrg *the following conditions: 11706f2543Smrg * 12706f2543Smrg *The above copyright notice and this permission notice shall be 13706f2543Smrg *included in all copies or substantial portions of the Software. 14706f2543Smrg * 15706f2543Smrg *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16706f2543Smrg *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17706f2543Smrg *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18706f2543Smrg *NONINFRINGEMENT. IN NO EVENT SHALL HAROLD L HUNT II BE LIABLE FOR 19706f2543Smrg *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 20706f2543Smrg *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 21706f2543Smrg *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22706f2543Smrg * 23706f2543Smrg *Except as contained in this notice, the name of Harold L Hunt II 24706f2543Smrg *shall not be used in advertising or otherwise to promote the sale, use 25706f2543Smrg *or other dealings in this Software without prior written authorization 26706f2543Smrg *from Harold L Hunt II. 27706f2543Smrg * 28706f2543Smrg * Authors: Harold L Hunt II 29706f2543Smrg */ 30706f2543Smrg 31706f2543Smrg#ifdef HAVE_XWIN_CONFIG_H 32706f2543Smrg#include <xwin-config.h> 33706f2543Smrg#endif 34706f2543Smrg#include "win.h" 35706f2543Smrg 36706f2543Smrg 37706f2543Smrg/* 38706f2543Smrg * Local function prototypes 39706f2543Smrg */ 40706f2543Smrg 41706f2543Smrg#ifdef XWIN_MULTIWINDOW 42706f2543Smrgstatic wBOOL CALLBACK 43706f2543SmrgwinRedrawAllProcShadowGDI (HWND hwnd, LPARAM lParam); 44706f2543Smrg 45706f2543Smrgstatic wBOOL CALLBACK 46706f2543SmrgwinRedrawDamagedWindowShadowGDI (HWND hwnd, LPARAM lParam); 47706f2543Smrg#endif 48706f2543Smrg 49706f2543Smrgstatic Bool 50706f2543SmrgwinAllocateFBShadowGDI (ScreenPtr pScreen); 51706f2543Smrg 52706f2543Smrgstatic void 53706f2543SmrgwinShadowUpdateGDI (ScreenPtr pScreen, 54706f2543Smrg shadowBufPtr pBuf); 55706f2543Smrg 56706f2543Smrgstatic Bool 57706f2543SmrgwinCloseScreenShadowGDI (int nIndex, ScreenPtr pScreen); 58706f2543Smrg 59706f2543Smrgstatic Bool 60706f2543SmrgwinInitVisualsShadowGDI (ScreenPtr pScreen); 61706f2543Smrg 62706f2543Smrgstatic Bool 63706f2543SmrgwinAdjustVideoModeShadowGDI (ScreenPtr pScreen); 64706f2543Smrg 65706f2543Smrgstatic Bool 66706f2543SmrgwinBltExposedRegionsShadowGDI (ScreenPtr pScreen); 67706f2543Smrg 68706f2543Smrgstatic Bool 69706f2543SmrgwinActivateAppShadowGDI (ScreenPtr pScreen); 70706f2543Smrg 71706f2543Smrgstatic Bool 72706f2543SmrgwinRedrawScreenShadowGDI (ScreenPtr pScreen); 73706f2543Smrg 74706f2543Smrgstatic Bool 75706f2543SmrgwinRealizeInstalledPaletteShadowGDI (ScreenPtr pScreen); 76706f2543Smrg 77706f2543Smrgstatic Bool 78706f2543SmrgwinInstallColormapShadowGDI (ColormapPtr pColormap); 79706f2543Smrg 80706f2543Smrgstatic Bool 81706f2543SmrgwinStoreColorsShadowGDI (ColormapPtr pmap, 82706f2543Smrg int ndef, 83706f2543Smrg xColorItem *pdefs); 84706f2543Smrg 85706f2543Smrgstatic Bool 86706f2543SmrgwinCreateColormapShadowGDI (ColormapPtr pColormap); 87706f2543Smrg 88706f2543Smrgstatic Bool 89706f2543SmrgwinDestroyColormapShadowGDI (ColormapPtr pColormap); 90706f2543Smrg 91706f2543Smrg 92706f2543Smrg/* 93706f2543Smrg * Internal function to get the DIB format that is compatible with the screen 94706f2543Smrg */ 95706f2543Smrg 96706f2543Smrgstatic 97706f2543SmrgBool 98706f2543SmrgwinQueryScreenDIBFormat (ScreenPtr pScreen, BITMAPINFOHEADER *pbmih) 99706f2543Smrg{ 100706f2543Smrg winScreenPriv(pScreen); 101706f2543Smrg HBITMAP hbmp; 102706f2543Smrg#if CYGDEBUG 103706f2543Smrg LPDWORD pdw = NULL; 104706f2543Smrg#endif 105706f2543Smrg 106706f2543Smrg /* Create a memory bitmap compatible with the screen */ 107706f2543Smrg hbmp = CreateCompatibleBitmap (pScreenPriv->hdcScreen, 1, 1); 108706f2543Smrg if (hbmp == NULL) 109706f2543Smrg { 110706f2543Smrg ErrorF ("winQueryScreenDIBFormat - CreateCompatibleBitmap failed\n"); 111706f2543Smrg return FALSE; 112706f2543Smrg } 113706f2543Smrg 114706f2543Smrg /* Initialize our bitmap info header */ 115706f2543Smrg ZeroMemory (pbmih, sizeof (BITMAPINFOHEADER) + 256 * sizeof (RGBQUAD)); 116706f2543Smrg pbmih->biSize = sizeof (BITMAPINFOHEADER); 117706f2543Smrg 118706f2543Smrg /* Get the biBitCount */ 119706f2543Smrg if (!GetDIBits (pScreenPriv->hdcScreen, 120706f2543Smrg hbmp, 121706f2543Smrg 0, 1, 122706f2543Smrg NULL, 123706f2543Smrg (BITMAPINFO*) pbmih, 124706f2543Smrg DIB_RGB_COLORS)) 125706f2543Smrg { 126706f2543Smrg ErrorF ("winQueryScreenDIBFormat - First call to GetDIBits failed\n"); 127706f2543Smrg DeleteObject (hbmp); 128706f2543Smrg return FALSE; 129706f2543Smrg } 130706f2543Smrg 131706f2543Smrg#if CYGDEBUG 132706f2543Smrg /* Get a pointer to bitfields */ 133706f2543Smrg pdw = (DWORD*) ((CARD8*)pbmih + sizeof (BITMAPINFOHEADER)); 134706f2543Smrg 135706f2543Smrg winDebug ("winQueryScreenDIBFormat - First call masks: %08x %08x %08x\n", 136706f2543Smrg pdw[0], pdw[1], pdw[2]); 137706f2543Smrg#endif 138706f2543Smrg 139706f2543Smrg /* Get optimal color table, or the optimal bitfields */ 140706f2543Smrg if (!GetDIBits (pScreenPriv->hdcScreen, 141706f2543Smrg hbmp, 142706f2543Smrg 0, 1, 143706f2543Smrg NULL, 144706f2543Smrg (BITMAPINFO*)pbmih, 145706f2543Smrg DIB_RGB_COLORS)) 146706f2543Smrg { 147706f2543Smrg ErrorF ("winQueryScreenDIBFormat - Second call to GetDIBits " 148706f2543Smrg "failed\n"); 149706f2543Smrg DeleteObject (hbmp); 150706f2543Smrg return FALSE; 151706f2543Smrg } 152706f2543Smrg 153706f2543Smrg /* Free memory */ 154706f2543Smrg DeleteObject (hbmp); 155706f2543Smrg 156706f2543Smrg return TRUE; 157706f2543Smrg} 158706f2543Smrg 159706f2543Smrg 160706f2543Smrg/* 161706f2543Smrg * Internal function to determine the GDI bits per rgb and bit masks 162706f2543Smrg */ 163706f2543Smrg 164706f2543Smrgstatic 165706f2543SmrgBool 166706f2543SmrgwinQueryRGBBitsAndMasks (ScreenPtr pScreen) 167706f2543Smrg{ 168706f2543Smrg winScreenPriv(pScreen); 169706f2543Smrg BITMAPINFOHEADER *pbmih = NULL; 170706f2543Smrg Bool fReturn = TRUE; 171706f2543Smrg LPDWORD pdw = NULL; 172706f2543Smrg DWORD dwRedBits, dwGreenBits, dwBlueBits; 173706f2543Smrg 174706f2543Smrg /* Color masks for 8 bpp are standardized */ 175706f2543Smrg if (GetDeviceCaps (pScreenPriv->hdcScreen, RASTERCAPS) & RC_PALETTE) 176706f2543Smrg { 177706f2543Smrg /* 178706f2543Smrg * RGB BPP for 8 bit palletes is always 8 179706f2543Smrg * and the color masks are always 0. 180706f2543Smrg */ 181706f2543Smrg pScreenPriv->dwBitsPerRGB = 8; 182706f2543Smrg pScreenPriv->dwRedMask = 0x0L; 183706f2543Smrg pScreenPriv->dwGreenMask = 0x0L; 184706f2543Smrg pScreenPriv->dwBlueMask = 0x0L; 185706f2543Smrg return TRUE; 186706f2543Smrg } 187706f2543Smrg 188706f2543Smrg /* Color masks for 24 bpp are standardized */ 189706f2543Smrg if (GetDeviceCaps (pScreenPriv->hdcScreen, PLANES) 190706f2543Smrg * GetDeviceCaps (pScreenPriv->hdcScreen, BITSPIXEL) == 24) 191706f2543Smrg { 192706f2543Smrg ErrorF ("winQueryRGBBitsAndMasks - GetDeviceCaps (BITSPIXEL) " 193706f2543Smrg "returned 24 for the screen. Using default 24bpp masks.\n"); 194706f2543Smrg 195706f2543Smrg /* 8 bits per primary color */ 196706f2543Smrg pScreenPriv->dwBitsPerRGB = 8; 197706f2543Smrg 198706f2543Smrg /* Set screen privates masks */ 199706f2543Smrg pScreenPriv->dwRedMask = WIN_24BPP_MASK_RED; 200706f2543Smrg pScreenPriv->dwGreenMask = WIN_24BPP_MASK_GREEN; 201706f2543Smrg pScreenPriv->dwBlueMask = WIN_24BPP_MASK_BLUE; 202706f2543Smrg 203706f2543Smrg return TRUE; 204706f2543Smrg } 205706f2543Smrg 206706f2543Smrg /* Allocate a bitmap header and color table */ 207706f2543Smrg pbmih = (BITMAPINFOHEADER*) malloc (sizeof (BITMAPINFOHEADER) 208706f2543Smrg + 256 * sizeof (RGBQUAD)); 209706f2543Smrg if (pbmih == NULL) 210706f2543Smrg { 211706f2543Smrg ErrorF ("winQueryRGBBitsAndMasks - malloc failed\n"); 212706f2543Smrg return FALSE; 213706f2543Smrg } 214706f2543Smrg 215706f2543Smrg /* Get screen description */ 216706f2543Smrg if (winQueryScreenDIBFormat (pScreen, pbmih)) 217706f2543Smrg { 218706f2543Smrg /* Get a pointer to bitfields */ 219706f2543Smrg pdw = (DWORD*) ((CARD8*)pbmih + sizeof (BITMAPINFOHEADER)); 220706f2543Smrg 221706f2543Smrg#if CYGDEBUG 222706f2543Smrg winDebug ("%s - Masks: %08x %08x %08x\n", __FUNCTION__, 223706f2543Smrg pdw[0], pdw[1], pdw[2]); 224706f2543Smrg winDebug ("%s - Bitmap: %dx%d %d bpp %d planes\n", __FUNCTION__, 225706f2543Smrg pbmih->biWidth, pbmih->biHeight, pbmih->biBitCount, pbmih->biPlanes); 226706f2543Smrg winDebug ("%s - Compression: %d %s\n", __FUNCTION__, 227706f2543Smrg pbmih->biCompression, 228706f2543Smrg (pbmih->biCompression == BI_RGB?"(BI_RGB)": 229706f2543Smrg (pbmih->biCompression == BI_RLE8?"(BI_RLE8)": 230706f2543Smrg (pbmih->biCompression == BI_RLE4?"(BI_RLE4)": 231706f2543Smrg (pbmih->biCompression == BI_BITFIELDS?"(BI_BITFIELDS)":"" 232706f2543Smrg ))))); 233706f2543Smrg#endif 234706f2543Smrg 235706f2543Smrg /* Handle BI_RGB case, which is returned by Wine */ 236706f2543Smrg if (pbmih->biCompression == BI_RGB) 237706f2543Smrg { 238706f2543Smrg dwRedBits = 5; 239706f2543Smrg dwGreenBits = 5; 240706f2543Smrg dwBlueBits = 5; 241706f2543Smrg 242706f2543Smrg pScreenPriv->dwBitsPerRGB = 5; 243706f2543Smrg 244706f2543Smrg /* Set screen privates masks */ 245706f2543Smrg pScreenPriv->dwRedMask = 0x7c00; 246706f2543Smrg pScreenPriv->dwGreenMask = 0x03e0; 247706f2543Smrg pScreenPriv->dwBlueMask = 0x001f; 248706f2543Smrg } 249706f2543Smrg else 250706f2543Smrg { 251706f2543Smrg /* Count the number of bits in each mask */ 252706f2543Smrg dwRedBits = winCountBits (pdw[0]); 253706f2543Smrg dwGreenBits = winCountBits (pdw[1]); 254706f2543Smrg dwBlueBits = winCountBits (pdw[2]); 255706f2543Smrg 256706f2543Smrg /* Find maximum bits per red, green, blue */ 257706f2543Smrg if (dwRedBits > dwGreenBits && dwRedBits > dwBlueBits) 258706f2543Smrg pScreenPriv->dwBitsPerRGB = dwRedBits; 259706f2543Smrg else if (dwGreenBits > dwRedBits && dwGreenBits > dwBlueBits) 260706f2543Smrg pScreenPriv->dwBitsPerRGB = dwGreenBits; 261706f2543Smrg else 262706f2543Smrg pScreenPriv->dwBitsPerRGB = dwBlueBits; 263706f2543Smrg 264706f2543Smrg /* Set screen privates masks */ 265706f2543Smrg pScreenPriv->dwRedMask = pdw[0]; 266706f2543Smrg pScreenPriv->dwGreenMask = pdw[1]; 267706f2543Smrg pScreenPriv->dwBlueMask = pdw[2]; 268706f2543Smrg } 269706f2543Smrg } 270706f2543Smrg else 271706f2543Smrg { 272706f2543Smrg ErrorF ("winQueryRGBBitsAndMasks - winQueryScreenDIBFormat failed\n"); 273706f2543Smrg free (pbmih); 274706f2543Smrg fReturn = FALSE; 275706f2543Smrg } 276706f2543Smrg 277706f2543Smrg /* Free memory */ 278706f2543Smrg free (pbmih); 279706f2543Smrg 280706f2543Smrg return fReturn; 281706f2543Smrg} 282706f2543Smrg 283706f2543Smrg 284706f2543Smrg#ifdef XWIN_MULTIWINDOW 285706f2543Smrg/* 286706f2543Smrg * Redraw all ---? 287706f2543Smrg */ 288706f2543Smrg 289706f2543Smrgstatic wBOOL CALLBACK 290706f2543SmrgwinRedrawAllProcShadowGDI (HWND hwnd, LPARAM lParam) 291706f2543Smrg{ 292706f2543Smrg if (hwnd == (HWND)lParam) 293706f2543Smrg return TRUE; 294706f2543Smrg InvalidateRect (hwnd, NULL, FALSE); 295706f2543Smrg UpdateWindow (hwnd); 296706f2543Smrg return TRUE; 297706f2543Smrg} 298706f2543Smrg 299706f2543Smrgstatic wBOOL CALLBACK 300706f2543SmrgwinRedrawDamagedWindowShadowGDI (HWND hwnd, LPARAM lParam) 301706f2543Smrg{ 302706f2543Smrg BoxPtr pDamage = (BoxPtr)lParam; 303706f2543Smrg RECT rcClient, rcDamage, rcRedraw; 304706f2543Smrg POINT topLeft, bottomRight; 305706f2543Smrg 306706f2543Smrg if (IsIconic (hwnd)) 307706f2543Smrg return TRUE; /* Don't care minimized windows */ 308706f2543Smrg 309706f2543Smrg /* Convert the damaged area from Screen coords to Client coords */ 310706f2543Smrg topLeft.x = pDamage->x1; topLeft.y = pDamage->y1; 311706f2543Smrg bottomRight.x = pDamage->x2; bottomRight.y = pDamage->y2; 312706f2543Smrg topLeft.x += GetSystemMetrics (SM_XVIRTUALSCREEN); 313706f2543Smrg bottomRight.x += GetSystemMetrics (SM_XVIRTUALSCREEN); 314706f2543Smrg topLeft.y += GetSystemMetrics (SM_YVIRTUALSCREEN); 315706f2543Smrg bottomRight.y += GetSystemMetrics (SM_YVIRTUALSCREEN); 316706f2543Smrg ScreenToClient (hwnd, &topLeft); 317706f2543Smrg ScreenToClient (hwnd, &bottomRight); 318706f2543Smrg SetRect (&rcDamage, topLeft.x, topLeft.y, bottomRight.x, bottomRight.y); 319706f2543Smrg 320706f2543Smrg GetClientRect (hwnd, &rcClient); 321706f2543Smrg 322706f2543Smrg if (IntersectRect (&rcRedraw, &rcClient, &rcDamage)) 323706f2543Smrg { 324706f2543Smrg InvalidateRect (hwnd, &rcRedraw, FALSE); 325706f2543Smrg UpdateWindow (hwnd); 326706f2543Smrg } 327706f2543Smrg return TRUE; 328706f2543Smrg} 329706f2543Smrg#endif 330706f2543Smrg 331706f2543Smrg 332706f2543Smrg/* 333706f2543Smrg * Allocate a DIB for the shadow framebuffer GDI server 334706f2543Smrg */ 335706f2543Smrg 336706f2543Smrgstatic Bool 337706f2543SmrgwinAllocateFBShadowGDI (ScreenPtr pScreen) 338706f2543Smrg{ 339706f2543Smrg winScreenPriv(pScreen); 340706f2543Smrg winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; 341706f2543Smrg DIBSECTION dibsection; 342706f2543Smrg Bool fReturn = TRUE; 343706f2543Smrg 344706f2543Smrg /* Describe shadow bitmap to be created */ 345706f2543Smrg pScreenPriv->pbmih->biWidth = pScreenInfo->dwWidth; 346706f2543Smrg pScreenPriv->pbmih->biHeight = -pScreenInfo->dwHeight; 347706f2543Smrg 348706f2543Smrg ErrorF ("winAllocateFBShadowGDI - Creating DIB with width: %d height: %d " 349706f2543Smrg "depth: %d\n", 350706f2543Smrg (int) pScreenPriv->pbmih->biWidth, (int) -pScreenPriv->pbmih->biHeight, pScreenPriv->pbmih->biBitCount); 351706f2543Smrg 352706f2543Smrg /* Create a DI shadow bitmap with a bit pointer */ 353706f2543Smrg pScreenPriv->hbmpShadow = CreateDIBSection (pScreenPriv->hdcScreen, 354706f2543Smrg (BITMAPINFO *) pScreenPriv->pbmih, 355706f2543Smrg DIB_RGB_COLORS, 356706f2543Smrg (VOID**) &pScreenInfo->pfb, 357706f2543Smrg NULL, 358706f2543Smrg 0); 359706f2543Smrg if (pScreenPriv->hbmpShadow == NULL || pScreenInfo->pfb == NULL) 360706f2543Smrg { 361706f2543Smrg winW32Error (2, "winAllocateFBShadowGDI - CreateDIBSection failed:"); 362706f2543Smrg return FALSE; 363706f2543Smrg } 364706f2543Smrg else 365706f2543Smrg { 366706f2543Smrg#if CYGDEBUG 367706f2543Smrg winDebug ("winAllocateFBShadowGDI - Shadow buffer allocated\n"); 368706f2543Smrg#endif 369706f2543Smrg } 370706f2543Smrg 371706f2543Smrg /* Get information about the bitmap that was allocated */ 372706f2543Smrg GetObject (pScreenPriv->hbmpShadow, 373706f2543Smrg sizeof (dibsection), 374706f2543Smrg &dibsection); 375706f2543Smrg 376706f2543Smrg#if CYGDEBUG || YES 377706f2543Smrg /* Print information about bitmap allocated */ 378706f2543Smrg winDebug ("winAllocateFBShadowGDI - Dibsection width: %d height: %d " 379706f2543Smrg "depth: %d size image: %d\n", 380706f2543Smrg (int) dibsection.dsBmih.biWidth, (int) dibsection.dsBmih.biHeight, 381706f2543Smrg dibsection.dsBmih.biBitCount, 382706f2543Smrg (int) dibsection.dsBmih.biSizeImage); 383706f2543Smrg#endif 384706f2543Smrg 385706f2543Smrg /* Select the shadow bitmap into the shadow DC */ 386706f2543Smrg SelectObject (pScreenPriv->hdcShadow, 387706f2543Smrg pScreenPriv->hbmpShadow); 388706f2543Smrg 389706f2543Smrg#if CYGDEBUG 390706f2543Smrg winDebug ("winAllocateFBShadowGDI - Attempting a shadow blit\n"); 391706f2543Smrg#endif 392706f2543Smrg 393706f2543Smrg /* Do a test blit from the shadow to the screen, I think */ 394706f2543Smrg fReturn = BitBlt (pScreenPriv->hdcScreen, 395706f2543Smrg 0, 0, 396706f2543Smrg pScreenInfo->dwWidth, pScreenInfo->dwHeight, 397706f2543Smrg pScreenPriv->hdcShadow, 398706f2543Smrg 0, 0, 399706f2543Smrg SRCCOPY); 400706f2543Smrg if (fReturn) 401706f2543Smrg { 402706f2543Smrg#if CYGDEBUG 403706f2543Smrg winDebug ("winAllocateFBShadowGDI - Shadow blit success\n"); 404706f2543Smrg#endif 405706f2543Smrg } 406706f2543Smrg else 407706f2543Smrg { 408706f2543Smrg winW32Error (2, "winAllocateFBShadowGDI - Shadow blit failure\n"); 409706f2543Smrg#if 0 410706f2543Smrg return FALSE; 411706f2543Smrg#else 412706f2543Smrg /* ago: ignore this error. The blit fails with wine, but does not 413706f2543Smrg * cause any problems later. */ 414706f2543Smrg 415706f2543Smrg fReturn = TRUE; 416706f2543Smrg#endif 417706f2543Smrg } 418706f2543Smrg 419706f2543Smrg /* Look for height weirdness */ 420706f2543Smrg if (dibsection.dsBmih.biHeight < 0) 421706f2543Smrg { 422706f2543Smrg dibsection.dsBmih.biHeight = -dibsection.dsBmih.biHeight; 423706f2543Smrg } 424706f2543Smrg 425706f2543Smrg /* Set screeninfo stride */ 426706f2543Smrg pScreenInfo->dwStride = ((dibsection.dsBmih.biSizeImage 427706f2543Smrg / dibsection.dsBmih.biHeight) 428706f2543Smrg * 8) / pScreenInfo->dwBPP; 429706f2543Smrg 430706f2543Smrg#if CYGDEBUG || YES 431706f2543Smrg winDebug ("winAllocateFBShadowGDI - Created shadow stride: %d\n", 432706f2543Smrg (int) pScreenInfo->dwStride); 433706f2543Smrg#endif 434706f2543Smrg 435706f2543Smrg#ifdef XWIN_MULTIWINDOW 436706f2543Smrg /* Redraw all windows */ 437706f2543Smrg if (pScreenInfo->fMultiWindow) 438706f2543Smrg EnumThreadWindows (g_dwCurrentThreadID, winRedrawAllProcShadowGDI, 0); 439706f2543Smrg#endif 440706f2543Smrg 441706f2543Smrg return fReturn; 442706f2543Smrg} 443706f2543Smrg 444706f2543Smrgstatic void 445706f2543SmrgwinFreeFBShadowGDI (ScreenPtr pScreen) 446706f2543Smrg{ 447706f2543Smrg winScreenPriv(pScreen); 448706f2543Smrg winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; 449706f2543Smrg 450706f2543Smrg /* Free the shadow bitmap */ 451706f2543Smrg DeleteObject (pScreenPriv->hbmpShadow); 452706f2543Smrg 453706f2543Smrg /* Invalidate the ScreenInfo's fb pointer */ 454706f2543Smrg pScreenInfo->pfb = NULL; 455706f2543Smrg} 456706f2543Smrg 457706f2543Smrg/* 458706f2543Smrg * Blit the damaged regions of the shadow fb to the screen 459706f2543Smrg */ 460706f2543Smrg 461706f2543Smrgstatic void 462706f2543SmrgwinShadowUpdateGDI (ScreenPtr pScreen, 463706f2543Smrg shadowBufPtr pBuf) 464706f2543Smrg{ 465706f2543Smrg winScreenPriv(pScreen); 466706f2543Smrg winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; 467706f2543Smrg RegionPtr damage = shadowDamage(pBuf); 468706f2543Smrg DWORD dwBox = RegionNumRects (damage); 469706f2543Smrg BoxPtr pBox = RegionRects (damage); 470706f2543Smrg int x, y, w, h; 471706f2543Smrg HRGN hrgnTemp = NULL, hrgnCombined = NULL; 472706f2543Smrg#ifdef XWIN_UPDATESTATS 473706f2543Smrg static DWORD s_dwNonUnitRegions = 0; 474706f2543Smrg static DWORD s_dwTotalUpdates = 0; 475706f2543Smrg static DWORD s_dwTotalBoxes = 0; 476706f2543Smrg#endif 477706f2543Smrg BoxPtr pBoxExtents = RegionExtents(damage); 478706f2543Smrg 479706f2543Smrg /* 480706f2543Smrg * Return immediately if the app is not active 481706f2543Smrg * and we are fullscreen, or if we have a bad display depth 482706f2543Smrg */ 483706f2543Smrg if ((!pScreenPriv->fActive && pScreenInfo->fFullScreen) 484706f2543Smrg || pScreenPriv->fBadDepth) return; 485706f2543Smrg 486706f2543Smrg#ifdef XWIN_UPDATESTATS 487706f2543Smrg ++s_dwTotalUpdates; 488706f2543Smrg s_dwTotalBoxes += dwBox; 489706f2543Smrg 490706f2543Smrg if (dwBox != 1) 491706f2543Smrg { 492706f2543Smrg ++s_dwNonUnitRegions; 493706f2543Smrg ErrorF ("winShadowUpdatGDI - dwBox: %d\n", dwBox); 494706f2543Smrg } 495706f2543Smrg 496706f2543Smrg if ((s_dwTotalUpdates % 100) == 0) 497706f2543Smrg ErrorF ("winShadowUpdateGDI - %d%% non-unity regions, avg boxes: %d " 498706f2543Smrg "nu: %d tu: %d\n", 499706f2543Smrg (s_dwNonUnitRegions * 100) / s_dwTotalUpdates, 500706f2543Smrg s_dwTotalBoxes / s_dwTotalUpdates, 501706f2543Smrg s_dwNonUnitRegions, s_dwTotalUpdates); 502706f2543Smrg#endif /* XWIN_UPDATESTATS */ 503706f2543Smrg 504706f2543Smrg /* 505706f2543Smrg * Handle small regions with multiple blits, 506706f2543Smrg * handle large regions by creating a clipping region and 507706f2543Smrg * doing a single blit constrained to that clipping region. 508706f2543Smrg */ 509706f2543Smrg if (!pScreenInfo->fMultiWindow && 510706f2543Smrg (pScreenInfo->dwClipUpdatesNBoxes == 0 || 511706f2543Smrg dwBox < pScreenInfo->dwClipUpdatesNBoxes)) 512706f2543Smrg { 513706f2543Smrg /* Loop through all boxes in the damaged region */ 514706f2543Smrg while (dwBox--) 515706f2543Smrg { 516706f2543Smrg /* 517706f2543Smrg * Calculate x offset, y offset, width, and height for 518706f2543Smrg * current damage box 519706f2543Smrg */ 520706f2543Smrg x = pBox->x1; 521706f2543Smrg y = pBox->y1; 522706f2543Smrg w = pBox->x2 - pBox->x1; 523706f2543Smrg h = pBox->y2 - pBox->y1; 524706f2543Smrg 525706f2543Smrg BitBlt (pScreenPriv->hdcScreen, 526706f2543Smrg x, y, 527706f2543Smrg w, h, 528706f2543Smrg pScreenPriv->hdcShadow, 529706f2543Smrg x, y, 530706f2543Smrg SRCCOPY); 531706f2543Smrg 532706f2543Smrg /* Get a pointer to the next box */ 533706f2543Smrg ++pBox; 534706f2543Smrg } 535706f2543Smrg } 536706f2543Smrg else if (!pScreenInfo->fMultiWindow) 537706f2543Smrg { 538706f2543Smrg /* Compute a GDI region from the damaged region */ 539706f2543Smrg hrgnCombined = CreateRectRgn (pBox->x1, pBox->y1, pBox->x2, pBox->y2); 540706f2543Smrg dwBox--; 541706f2543Smrg pBox++; 542706f2543Smrg while (dwBox--) 543706f2543Smrg { 544706f2543Smrg hrgnTemp = CreateRectRgn (pBox->x1, pBox->y1, pBox->x2, pBox->y2); 545706f2543Smrg CombineRgn (hrgnCombined, hrgnCombined, hrgnTemp, RGN_OR); 546706f2543Smrg DeleteObject (hrgnTemp); 547706f2543Smrg pBox++; 548706f2543Smrg } 549706f2543Smrg 550706f2543Smrg /* Install the GDI region as a clipping region */ 551706f2543Smrg SelectClipRgn (pScreenPriv->hdcScreen, hrgnCombined); 552706f2543Smrg DeleteObject (hrgnCombined); 553706f2543Smrg hrgnCombined = NULL; 554706f2543Smrg 555706f2543Smrg /* 556706f2543Smrg * Blit the shadow buffer to the screen, 557706f2543Smrg * constrained to the clipping region. 558706f2543Smrg */ 559706f2543Smrg BitBlt (pScreenPriv->hdcScreen, 560706f2543Smrg pBoxExtents->x1, pBoxExtents->y1, 561706f2543Smrg pBoxExtents->x2 - pBoxExtents->x1, 562706f2543Smrg pBoxExtents->y2 - pBoxExtents->y1, 563706f2543Smrg pScreenPriv->hdcShadow, 564706f2543Smrg pBoxExtents->x1, pBoxExtents->y1, 565706f2543Smrg SRCCOPY); 566706f2543Smrg 567706f2543Smrg /* Reset the clip region */ 568706f2543Smrg SelectClipRgn (pScreenPriv->hdcScreen, NULL); 569706f2543Smrg } 570706f2543Smrg 571706f2543Smrg#ifdef XWIN_MULTIWINDOW 572706f2543Smrg /* Redraw all multiwindow windows */ 573706f2543Smrg if (pScreenInfo->fMultiWindow) 574706f2543Smrg EnumThreadWindows (g_dwCurrentThreadID, 575706f2543Smrg winRedrawDamagedWindowShadowGDI, 576706f2543Smrg (LPARAM)pBoxExtents); 577706f2543Smrg#endif 578706f2543Smrg} 579706f2543Smrg 580706f2543Smrg 581706f2543Smrgstatic Bool 582706f2543SmrgwinInitScreenShadowGDI (ScreenPtr pScreen) 583706f2543Smrg{ 584706f2543Smrg winScreenPriv(pScreen); 585706f2543Smrg 586706f2543Smrg /* Get device contexts for the screen and shadow bitmap */ 587706f2543Smrg pScreenPriv->hdcScreen = GetDC (pScreenPriv->hwndScreen); 588706f2543Smrg pScreenPriv->hdcShadow = CreateCompatibleDC (pScreenPriv->hdcScreen); 589706f2543Smrg 590706f2543Smrg /* Allocate bitmap info header */ 591706f2543Smrg pScreenPriv->pbmih = (BITMAPINFOHEADER*) malloc (sizeof (BITMAPINFOHEADER) 592706f2543Smrg + 256 * sizeof (RGBQUAD)); 593706f2543Smrg if (pScreenPriv->pbmih == NULL) 594706f2543Smrg { 595706f2543Smrg ErrorF ("winInitScreenShadowGDI - malloc () failed\n"); 596706f2543Smrg return FALSE; 597706f2543Smrg } 598706f2543Smrg 599706f2543Smrg /* Query the screen format */ 600706f2543Smrg if (!winQueryScreenDIBFormat (pScreen, pScreenPriv->pbmih)) 601706f2543Smrg { 602706f2543Smrg ErrorF ("winInitScreenShadowGDI - winQueryScreenDIBFormat failed\n"); 603706f2543Smrg return FALSE; 604706f2543Smrg } 605706f2543Smrg 606706f2543Smrg /* Determine our color masks */ 607706f2543Smrg if (!winQueryRGBBitsAndMasks (pScreen)) 608706f2543Smrg { 609706f2543Smrg ErrorF ("winInitScreenShadowGDI - winQueryRGBBitsAndMasks failed\n"); 610706f2543Smrg return FALSE; 611706f2543Smrg } 612706f2543Smrg 613706f2543Smrg return winAllocateFBShadowGDI(pScreen); 614706f2543Smrg} 615706f2543Smrg 616706f2543Smrg/* See Porting Layer Definition - p. 33 */ 617706f2543Smrg/* 618706f2543Smrg * We wrap whatever CloseScreen procedure was specified by fb; 619706f2543Smrg * a pointer to said procedure is stored in our privates. 620706f2543Smrg */ 621706f2543Smrg 622706f2543Smrgstatic Bool 623706f2543SmrgwinCloseScreenShadowGDI (int nIndex, ScreenPtr pScreen) 624706f2543Smrg{ 625706f2543Smrg winScreenPriv(pScreen); 626706f2543Smrg winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; 627706f2543Smrg Bool fReturn; 628706f2543Smrg 629706f2543Smrg#if CYGDEBUG 630706f2543Smrg winDebug ("winCloseScreenShadowGDI - Freeing screen resources\n"); 631706f2543Smrg#endif 632706f2543Smrg 633706f2543Smrg /* Flag that the screen is closed */ 634706f2543Smrg pScreenPriv->fClosed = TRUE; 635706f2543Smrg pScreenPriv->fActive = FALSE; 636706f2543Smrg 637706f2543Smrg /* Call the wrapped CloseScreen procedure */ 638706f2543Smrg WIN_UNWRAP(CloseScreen); 639706f2543Smrg fReturn = (*pScreen->CloseScreen) (nIndex, pScreen); 640706f2543Smrg 641706f2543Smrg /* Delete the window property */ 642706f2543Smrg RemoveProp (pScreenPriv->hwndScreen, WIN_SCR_PROP); 643706f2543Smrg 644706f2543Smrg /* Free the shadow DC; which allows the bitmap to be freed */ 645706f2543Smrg DeleteDC (pScreenPriv->hdcShadow); 646706f2543Smrg 647706f2543Smrg winFreeFBShadowGDI(pScreen); 648706f2543Smrg 649706f2543Smrg /* Free the screen DC */ 650706f2543Smrg ReleaseDC (pScreenPriv->hwndScreen, pScreenPriv->hdcScreen); 651706f2543Smrg 652706f2543Smrg /* Delete tray icon, if we have one */ 653706f2543Smrg if (!pScreenInfo->fNoTrayIcon) 654706f2543Smrg winDeleteNotifyIcon (pScreenPriv); 655706f2543Smrg 656706f2543Smrg /* Free the exit confirmation dialog box, if it exists */ 657706f2543Smrg if (g_hDlgExit != NULL) 658706f2543Smrg { 659706f2543Smrg DestroyWindow (g_hDlgExit); 660706f2543Smrg g_hDlgExit = NULL; 661706f2543Smrg } 662706f2543Smrg 663706f2543Smrg /* Kill our window */ 664706f2543Smrg if (pScreenPriv->hwndScreen) 665706f2543Smrg { 666706f2543Smrg DestroyWindow (pScreenPriv->hwndScreen); 667706f2543Smrg pScreenPriv->hwndScreen = NULL; 668706f2543Smrg } 669706f2543Smrg 670706f2543Smrg#if defined(XWIN_CLIPBOARD) || defined(XWIN_MULTIWINDOW) 671706f2543Smrg /* Destroy the thread startup mutex */ 672706f2543Smrg pthread_mutex_destroy (&pScreenPriv->pmServerStarted); 673706f2543Smrg#endif 674706f2543Smrg 675706f2543Smrg /* Invalidate our screeninfo's pointer to the screen */ 676706f2543Smrg pScreenInfo->pScreen = NULL; 677706f2543Smrg 678706f2543Smrg /* Free the screen privates for this screen */ 679706f2543Smrg free ((pointer) pScreenPriv); 680706f2543Smrg 681706f2543Smrg return fReturn; 682706f2543Smrg} 683706f2543Smrg 684706f2543Smrg 685706f2543Smrg/* 686706f2543Smrg * Tell mi what sort of visuals we need. 687706f2543Smrg * 688706f2543Smrg * Generally we only need one visual, as our screen can only 689706f2543Smrg * handle one format at a time, I believe. You may want 690706f2543Smrg * to verify that last sentence. 691706f2543Smrg */ 692706f2543Smrg 693706f2543Smrgstatic Bool 694706f2543SmrgwinInitVisualsShadowGDI (ScreenPtr pScreen) 695706f2543Smrg{ 696706f2543Smrg winScreenPriv(pScreen); 697706f2543Smrg winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; 698706f2543Smrg 699706f2543Smrg /* Display debugging information */ 700706f2543Smrg ErrorF ("winInitVisualsShadowGDI - Masks %08x %08x %08x BPRGB %d d %d " 701706f2543Smrg "bpp %d\n", 702706f2543Smrg (unsigned int) pScreenPriv->dwRedMask, 703706f2543Smrg (unsigned int) pScreenPriv->dwGreenMask, 704706f2543Smrg (unsigned int) pScreenPriv->dwBlueMask, 705706f2543Smrg (int) pScreenPriv->dwBitsPerRGB, 706706f2543Smrg (int) pScreenInfo->dwDepth, 707706f2543Smrg (int) pScreenInfo->dwBPP); 708706f2543Smrg 709706f2543Smrg /* Create a single visual according to the Windows screen depth */ 710706f2543Smrg switch (pScreenInfo->dwDepth) 711706f2543Smrg { 712706f2543Smrg case 24: 713706f2543Smrg case 16: 714706f2543Smrg case 15: 715706f2543Smrg /* Setup the real visual */ 716706f2543Smrg if (!miSetVisualTypesAndMasks (pScreenInfo->dwDepth, 717706f2543Smrg TrueColorMask, 718706f2543Smrg pScreenPriv->dwBitsPerRGB, 719706f2543Smrg -1, 720706f2543Smrg pScreenPriv->dwRedMask, 721706f2543Smrg pScreenPriv->dwGreenMask, 722706f2543Smrg pScreenPriv->dwBlueMask)) 723706f2543Smrg { 724706f2543Smrg ErrorF ("winInitVisualsShadowGDI - miSetVisualTypesAndMasks " 725706f2543Smrg "failed\n"); 726706f2543Smrg return FALSE; 727706f2543Smrg } 728706f2543Smrg 729706f2543Smrg#ifdef XWIN_EMULATEPSEUDO 730706f2543Smrg if (!pScreenInfo->fEmulatePseudo) 731706f2543Smrg break; 732706f2543Smrg 733706f2543Smrg /* Setup a pseudocolor visual */ 734706f2543Smrg if (!miSetVisualTypesAndMasks (8, 735706f2543Smrg PseudoColorMask, 736706f2543Smrg 8, 737706f2543Smrg -1, 738706f2543Smrg 0, 739706f2543Smrg 0, 740706f2543Smrg 0)) 741706f2543Smrg { 742706f2543Smrg ErrorF ("winInitVisualsShadowGDI - miSetVisualTypesAndMasks " 743706f2543Smrg "failed for PseudoColor\n"); 744706f2543Smrg return FALSE; 745706f2543Smrg } 746706f2543Smrg#endif 747706f2543Smrg break; 748706f2543Smrg 749706f2543Smrg case 8: 750706f2543Smrg if (!miSetVisualTypesAndMasks (pScreenInfo->dwDepth, 751706f2543Smrg PseudoColorMask, 752706f2543Smrg pScreenPriv->dwBitsPerRGB, 753706f2543Smrg PseudoColor, 754706f2543Smrg pScreenPriv->dwRedMask, 755706f2543Smrg pScreenPriv->dwGreenMask, 756706f2543Smrg pScreenPriv->dwBlueMask)) 757706f2543Smrg { 758706f2543Smrg ErrorF ("winInitVisualsShadowGDI - miSetVisualTypesAndMasks " 759706f2543Smrg "failed\n"); 760706f2543Smrg return FALSE; 761706f2543Smrg } 762706f2543Smrg break; 763706f2543Smrg 764706f2543Smrg default: 765706f2543Smrg ErrorF ("winInitVisualsShadowGDI - Unknown screen depth\n"); 766706f2543Smrg return FALSE; 767706f2543Smrg } 768706f2543Smrg 769706f2543Smrg#if CYGDEBUG 770706f2543Smrg winDebug ("winInitVisualsShadowGDI - Returning\n"); 771706f2543Smrg#endif 772706f2543Smrg 773706f2543Smrg return TRUE; 774706f2543Smrg} 775706f2543Smrg 776706f2543Smrg 777706f2543Smrg/* 778706f2543Smrg * Adjust the proposed video mode 779706f2543Smrg */ 780706f2543Smrg 781706f2543Smrgstatic Bool 782706f2543SmrgwinAdjustVideoModeShadowGDI (ScreenPtr pScreen) 783706f2543Smrg{ 784706f2543Smrg winScreenPriv(pScreen); 785706f2543Smrg winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; 786706f2543Smrg HDC hdc; 787706f2543Smrg DWORD dwBPP; 788706f2543Smrg 789706f2543Smrg hdc = GetDC (NULL); 790706f2543Smrg 791706f2543Smrg /* We're in serious trouble if we can't get a DC */ 792706f2543Smrg if (hdc == NULL) 793706f2543Smrg { 794706f2543Smrg ErrorF ("winAdjustVideoModeShadowGDI - GetDC () failed\n"); 795706f2543Smrg return FALSE; 796706f2543Smrg } 797706f2543Smrg 798706f2543Smrg /* Query GDI for current display depth */ 799706f2543Smrg dwBPP = GetDeviceCaps (hdc, BITSPIXEL); 800706f2543Smrg 801706f2543Smrg /* GDI cannot change the screen depth, so always use GDI's depth */ 802706f2543Smrg pScreenInfo->dwBPP = dwBPP; 803706f2543Smrg 804706f2543Smrg /* Release our DC */ 805706f2543Smrg ReleaseDC (NULL, hdc); 806706f2543Smrg hdc = NULL; 807706f2543Smrg 808706f2543Smrg return TRUE; 809706f2543Smrg} 810706f2543Smrg 811706f2543Smrg 812706f2543Smrg/* 813706f2543Smrg * Blt exposed regions to the screen 814706f2543Smrg */ 815706f2543Smrg 816706f2543Smrgstatic Bool 817706f2543SmrgwinBltExposedRegionsShadowGDI (ScreenPtr pScreen) 818706f2543Smrg{ 819706f2543Smrg winScreenPriv(pScreen); 820706f2543Smrg winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; 821706f2543Smrg winPrivCmapPtr pCmapPriv = NULL; 822706f2543Smrg HDC hdcUpdate; 823706f2543Smrg PAINTSTRUCT ps; 824706f2543Smrg 825706f2543Smrg /* BeginPaint gives us an hdc that clips to the invalidated region */ 826706f2543Smrg hdcUpdate = BeginPaint (pScreenPriv->hwndScreen, &ps); 827706f2543Smrg 828706f2543Smrg /* Realize the palette, if we have one */ 829706f2543Smrg if (pScreenPriv->pcmapInstalled != NULL) 830706f2543Smrg { 831706f2543Smrg pCmapPriv = winGetCmapPriv (pScreenPriv->pcmapInstalled); 832706f2543Smrg 833706f2543Smrg SelectPalette (hdcUpdate, pCmapPriv->hPalette, FALSE); 834706f2543Smrg RealizePalette (hdcUpdate); 835706f2543Smrg } 836706f2543Smrg 837706f2543Smrg /* Our BitBlt will be clipped to the invalidated region */ 838706f2543Smrg BitBlt (hdcUpdate, 839706f2543Smrg 0, 0, 840706f2543Smrg pScreenInfo->dwWidth, pScreenInfo->dwHeight, 841706f2543Smrg pScreenPriv->hdcShadow, 842706f2543Smrg 0, 0, 843706f2543Smrg SRCCOPY); 844706f2543Smrg 845706f2543Smrg /* EndPaint frees the DC */ 846706f2543Smrg EndPaint (pScreenPriv->hwndScreen, &ps); 847706f2543Smrg 848706f2543Smrg#ifdef XWIN_MULTIWINDOW 849706f2543Smrg /* Redraw all windows */ 850706f2543Smrg if (pScreenInfo->fMultiWindow) 851706f2543Smrg EnumThreadWindows(g_dwCurrentThreadID, winRedrawAllProcShadowGDI, 852706f2543Smrg (LPARAM)pScreenPriv->hwndScreen); 853706f2543Smrg#endif 854706f2543Smrg 855706f2543Smrg return TRUE; 856706f2543Smrg} 857706f2543Smrg 858706f2543Smrg 859706f2543Smrg/* 860706f2543Smrg * Do any engine-specific appliation-activation processing 861706f2543Smrg */ 862706f2543Smrg 863706f2543Smrgstatic Bool 864706f2543SmrgwinActivateAppShadowGDI (ScreenPtr pScreen) 865706f2543Smrg{ 866706f2543Smrg winScreenPriv(pScreen); 867706f2543Smrg winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; 868706f2543Smrg 869706f2543Smrg /* 870706f2543Smrg * 2004/04/12 - Harold - We perform the restoring or minimizing 871706f2543Smrg * manually for ShadowGDI in fullscreen modes so that this engine 872706f2543Smrg * will perform just like ShadowDD and ShadowDDNL in fullscreen mode; 873706f2543Smrg * if we do not do this then our fullscreen window will appear in the 874706f2543Smrg * z-order when it is deactivated and it can be uncovered by resizing 875706f2543Smrg * or minimizing another window that is on top of it, which is not how 876706f2543Smrg * the DirectDraw engines work. Therefore we keep this code here to 877706f2543Smrg * make sure that all engines work the same in fullscreen mode. 878706f2543Smrg */ 879706f2543Smrg 880706f2543Smrg /* 881706f2543Smrg * Are we active? 882706f2543Smrg * Are we fullscreen? 883706f2543Smrg */ 884706f2543Smrg if (pScreenPriv->fActive 885706f2543Smrg && pScreenInfo->fFullScreen) 886706f2543Smrg { 887706f2543Smrg /* 888706f2543Smrg * Activating, attempt to bring our window 889706f2543Smrg * to the top of the display 890706f2543Smrg */ 891706f2543Smrg ShowWindow (pScreenPriv->hwndScreen, SW_RESTORE); 892706f2543Smrg } 893706f2543Smrg else if (!pScreenPriv->fActive 894706f2543Smrg && pScreenInfo->fFullScreen) 895706f2543Smrg { 896706f2543Smrg /* 897706f2543Smrg * Deactivating, stuff our window onto the 898706f2543Smrg * task bar. 899706f2543Smrg */ 900706f2543Smrg ShowWindow (pScreenPriv->hwndScreen, SW_MINIMIZE); 901706f2543Smrg } 902706f2543Smrg 903706f2543Smrg return TRUE; 904706f2543Smrg} 905706f2543Smrg 906706f2543Smrg 907706f2543Smrg/* 908706f2543Smrg * Reblit the shadow framebuffer to the screen. 909706f2543Smrg */ 910706f2543Smrg 911706f2543Smrgstatic Bool 912706f2543SmrgwinRedrawScreenShadowGDI (ScreenPtr pScreen) 913706f2543Smrg{ 914706f2543Smrg winScreenPriv(pScreen); 915706f2543Smrg winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; 916706f2543Smrg 917706f2543Smrg /* Redraw the whole window, to take account for the new colors */ 918706f2543Smrg BitBlt (pScreenPriv->hdcScreen, 919706f2543Smrg 0, 0, 920706f2543Smrg pScreenInfo->dwWidth, pScreenInfo->dwHeight, 921706f2543Smrg pScreenPriv->hdcShadow, 922706f2543Smrg 0, 0, 923706f2543Smrg SRCCOPY); 924706f2543Smrg 925706f2543Smrg#ifdef XWIN_MULTIWINDOW 926706f2543Smrg /* Redraw all windows */ 927706f2543Smrg if (pScreenInfo->fMultiWindow) 928706f2543Smrg EnumThreadWindows(g_dwCurrentThreadID, winRedrawAllProcShadowGDI, 0); 929706f2543Smrg#endif 930706f2543Smrg 931706f2543Smrg return TRUE; 932706f2543Smrg} 933706f2543Smrg 934706f2543Smrg 935706f2543Smrg 936706f2543Smrg/* 937706f2543Smrg * Realize the currently installed colormap 938706f2543Smrg */ 939706f2543Smrg 940706f2543Smrgstatic Bool 941706f2543SmrgwinRealizeInstalledPaletteShadowGDI (ScreenPtr pScreen) 942706f2543Smrg{ 943706f2543Smrg winScreenPriv(pScreen); 944706f2543Smrg winPrivCmapPtr pCmapPriv = NULL; 945706f2543Smrg 946706f2543Smrg#if CYGDEBUG 947706f2543Smrg winDebug ("winRealizeInstalledPaletteShadowGDI\n"); 948706f2543Smrg#endif 949706f2543Smrg 950706f2543Smrg /* Don't do anything if there is not a colormap */ 951706f2543Smrg if (pScreenPriv->pcmapInstalled == NULL) 952706f2543Smrg { 953706f2543Smrg#if CYGDEBUG 954706f2543Smrg winDebug ("winRealizeInstalledPaletteShadowGDI - No colormap " 955706f2543Smrg "installed\n"); 956706f2543Smrg#endif 957706f2543Smrg return TRUE; 958706f2543Smrg } 959706f2543Smrg 960706f2543Smrg pCmapPriv = winGetCmapPriv (pScreenPriv->pcmapInstalled); 961706f2543Smrg 962706f2543Smrg /* Realize our palette for the screen */ 963706f2543Smrg if (RealizePalette (pScreenPriv->hdcScreen) == GDI_ERROR) 964706f2543Smrg { 965706f2543Smrg ErrorF ("winRealizeInstalledPaletteShadowGDI - RealizePalette () " 966706f2543Smrg "failed\n"); 967706f2543Smrg return FALSE; 968706f2543Smrg } 969706f2543Smrg 970706f2543Smrg /* Set the DIB color table */ 971706f2543Smrg if (SetDIBColorTable (pScreenPriv->hdcShadow, 972706f2543Smrg 0, 973706f2543Smrg WIN_NUM_PALETTE_ENTRIES, 974706f2543Smrg pCmapPriv->rgbColors) == 0) 975706f2543Smrg { 976706f2543Smrg ErrorF ("winRealizeInstalledPaletteShadowGDI - SetDIBColorTable () " 977706f2543Smrg "failed\n"); 978706f2543Smrg return FALSE; 979706f2543Smrg } 980706f2543Smrg 981706f2543Smrg return TRUE; 982706f2543Smrg} 983706f2543Smrg 984706f2543Smrg 985706f2543Smrg/* 986706f2543Smrg * Install the specified colormap 987706f2543Smrg */ 988706f2543Smrg 989706f2543Smrgstatic Bool 990706f2543SmrgwinInstallColormapShadowGDI (ColormapPtr pColormap) 991706f2543Smrg{ 992706f2543Smrg ScreenPtr pScreen = pColormap->pScreen; 993706f2543Smrg winScreenPriv(pScreen); 994706f2543Smrg winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; 995706f2543Smrg winCmapPriv(pColormap); 996706f2543Smrg 997706f2543Smrg /* 998706f2543Smrg * Tell Windows to install the new colormap 999706f2543Smrg */ 1000706f2543Smrg if (SelectPalette (pScreenPriv->hdcScreen, 1001706f2543Smrg pCmapPriv->hPalette, 1002706f2543Smrg FALSE) == NULL) 1003706f2543Smrg { 1004706f2543Smrg ErrorF ("winInstallColormapShadowGDI - SelectPalette () failed\n"); 1005706f2543Smrg return FALSE; 1006706f2543Smrg } 1007706f2543Smrg 1008706f2543Smrg /* Realize the palette */ 1009706f2543Smrg if (GDI_ERROR == RealizePalette (pScreenPriv->hdcScreen)) 1010706f2543Smrg { 1011706f2543Smrg ErrorF ("winInstallColormapShadowGDI - RealizePalette () failed\n"); 1012706f2543Smrg return FALSE; 1013706f2543Smrg } 1014706f2543Smrg 1015706f2543Smrg /* Set the DIB color table */ 1016706f2543Smrg if (SetDIBColorTable (pScreenPriv->hdcShadow, 1017706f2543Smrg 0, 1018706f2543Smrg WIN_NUM_PALETTE_ENTRIES, 1019706f2543Smrg pCmapPriv->rgbColors) == 0) 1020706f2543Smrg { 1021706f2543Smrg ErrorF ("winInstallColormapShadowGDI - SetDIBColorTable () failed\n"); 1022706f2543Smrg return FALSE; 1023706f2543Smrg } 1024706f2543Smrg 1025706f2543Smrg /* Redraw the whole window, to take account for the new colors */ 1026706f2543Smrg BitBlt (pScreenPriv->hdcScreen, 1027706f2543Smrg 0, 0, 1028706f2543Smrg pScreenInfo->dwWidth, pScreenInfo->dwHeight, 1029706f2543Smrg pScreenPriv->hdcShadow, 1030706f2543Smrg 0, 0, 1031706f2543Smrg SRCCOPY); 1032706f2543Smrg 1033706f2543Smrg /* Save a pointer to the newly installed colormap */ 1034706f2543Smrg pScreenPriv->pcmapInstalled = pColormap; 1035706f2543Smrg 1036706f2543Smrg#ifdef XWIN_MULTIWINDOW 1037706f2543Smrg /* Redraw all windows */ 1038706f2543Smrg if (pScreenInfo->fMultiWindow) 1039706f2543Smrg EnumThreadWindows (g_dwCurrentThreadID, winRedrawAllProcShadowGDI, 0); 1040706f2543Smrg#endif 1041706f2543Smrg 1042706f2543Smrg return TRUE; 1043706f2543Smrg} 1044706f2543Smrg 1045706f2543Smrg 1046706f2543Smrg/* 1047706f2543Smrg * Store the specified colors in the specified colormap 1048706f2543Smrg */ 1049706f2543Smrg 1050706f2543Smrgstatic Bool 1051706f2543SmrgwinStoreColorsShadowGDI (ColormapPtr pColormap, 1052706f2543Smrg int ndef, 1053706f2543Smrg xColorItem *pdefs) 1054706f2543Smrg{ 1055706f2543Smrg ScreenPtr pScreen = pColormap->pScreen; 1056706f2543Smrg winScreenPriv(pScreen); 1057706f2543Smrg winCmapPriv(pColormap); 1058706f2543Smrg ColormapPtr curpmap = pScreenPriv->pcmapInstalled; 1059706f2543Smrg 1060706f2543Smrg /* Put the X colormap entries into the Windows logical palette */ 1061706f2543Smrg if (SetPaletteEntries (pCmapPriv->hPalette, 1062706f2543Smrg pdefs[0].pixel, 1063706f2543Smrg ndef, 1064706f2543Smrg pCmapPriv->peColors + pdefs[0].pixel) == 0) 1065706f2543Smrg { 1066706f2543Smrg ErrorF ("winStoreColorsShadowGDI - SetPaletteEntries () failed\n"); 1067706f2543Smrg return FALSE; 1068706f2543Smrg } 1069706f2543Smrg 1070706f2543Smrg /* Don't install the Windows palette if the colormap is not installed */ 1071706f2543Smrg if (pColormap != curpmap) 1072706f2543Smrg { 1073706f2543Smrg return TRUE; 1074706f2543Smrg } 1075706f2543Smrg 1076706f2543Smrg /* Try to install the newly modified colormap */ 1077706f2543Smrg if (!winInstallColormapShadowGDI (pColormap)) 1078706f2543Smrg { 1079706f2543Smrg ErrorF ("winInstallColormapShadowGDI - winInstallColormapShadowGDI " 1080706f2543Smrg "failed\n"); 1081706f2543Smrg return FALSE; 1082706f2543Smrg } 1083706f2543Smrg 1084706f2543Smrg#if 0 1085706f2543Smrg /* Tell Windows that the palette has changed */ 1086706f2543Smrg RealizePalette (pScreenPriv->hdcScreen); 1087706f2543Smrg 1088706f2543Smrg /* Set the DIB color table */ 1089706f2543Smrg if (SetDIBColorTable (pScreenPriv->hdcShadow, 1090706f2543Smrg pdefs[0].pixel, 1091706f2543Smrg ndef, 1092706f2543Smrg pCmapPriv->rgbColors + pdefs[0].pixel) == 0) 1093706f2543Smrg { 1094706f2543Smrg ErrorF ("winInstallColormapShadowGDI - SetDIBColorTable () failed\n"); 1095706f2543Smrg return FALSE; 1096706f2543Smrg } 1097706f2543Smrg 1098706f2543Smrg /* Save a pointer to the newly installed colormap */ 1099706f2543Smrg pScreenPriv->pcmapInstalled = pColormap; 1100706f2543Smrg#endif 1101706f2543Smrg 1102706f2543Smrg return TRUE; 1103706f2543Smrg} 1104706f2543Smrg 1105706f2543Smrg 1106706f2543Smrg/* 1107706f2543Smrg * Colormap initialization procedure 1108706f2543Smrg */ 1109706f2543Smrg 1110706f2543Smrgstatic Bool 1111706f2543SmrgwinCreateColormapShadowGDI (ColormapPtr pColormap) 1112706f2543Smrg{ 1113706f2543Smrg LPLOGPALETTE lpPaletteNew = NULL; 1114706f2543Smrg DWORD dwEntriesMax; 1115706f2543Smrg VisualPtr pVisual; 1116706f2543Smrg HPALETTE hpalNew = NULL; 1117706f2543Smrg winCmapPriv(pColormap); 1118706f2543Smrg 1119706f2543Smrg /* Get a pointer to the visual that the colormap belongs to */ 1120706f2543Smrg pVisual = pColormap->pVisual; 1121706f2543Smrg 1122706f2543Smrg /* Get the maximum number of palette entries for this visual */ 1123706f2543Smrg dwEntriesMax = pVisual->ColormapEntries; 1124706f2543Smrg 1125706f2543Smrg /* Allocate a Windows logical color palette with max entries */ 1126706f2543Smrg lpPaletteNew = malloc (sizeof (LOGPALETTE) 1127706f2543Smrg + (dwEntriesMax - 1) * sizeof (PALETTEENTRY)); 1128706f2543Smrg if (lpPaletteNew == NULL) 1129706f2543Smrg { 1130706f2543Smrg ErrorF ("winCreateColormapShadowGDI - Couldn't allocate palette " 1131706f2543Smrg "with %d entries\n", 1132706f2543Smrg (int) dwEntriesMax); 1133706f2543Smrg return FALSE; 1134706f2543Smrg } 1135706f2543Smrg 1136706f2543Smrg /* Zero out the colormap */ 1137706f2543Smrg ZeroMemory (lpPaletteNew, sizeof (LOGPALETTE) 1138706f2543Smrg + (dwEntriesMax - 1) * sizeof (PALETTEENTRY)); 1139706f2543Smrg 1140706f2543Smrg /* Set the logical palette structure */ 1141706f2543Smrg lpPaletteNew->palVersion = 0x0300; 1142706f2543Smrg lpPaletteNew->palNumEntries = dwEntriesMax; 1143706f2543Smrg 1144706f2543Smrg /* Tell Windows to create the palette */ 1145706f2543Smrg hpalNew = CreatePalette (lpPaletteNew); 1146706f2543Smrg if (hpalNew == NULL) 1147706f2543Smrg { 1148706f2543Smrg ErrorF ("winCreateColormapShadowGDI - CreatePalette () failed\n"); 1149706f2543Smrg free (lpPaletteNew); 1150706f2543Smrg return FALSE; 1151706f2543Smrg } 1152706f2543Smrg 1153706f2543Smrg /* Save the Windows logical palette handle in the X colormaps' privates */ 1154706f2543Smrg pCmapPriv->hPalette = hpalNew; 1155706f2543Smrg 1156706f2543Smrg /* Free the palette initialization memory */ 1157706f2543Smrg free (lpPaletteNew); 1158706f2543Smrg 1159706f2543Smrg return TRUE; 1160706f2543Smrg} 1161706f2543Smrg 1162706f2543Smrg 1163706f2543Smrg/* 1164706f2543Smrg * Colormap destruction procedure 1165706f2543Smrg */ 1166706f2543Smrg 1167706f2543Smrgstatic Bool 1168706f2543SmrgwinDestroyColormapShadowGDI (ColormapPtr pColormap) 1169706f2543Smrg{ 1170706f2543Smrg winScreenPriv(pColormap->pScreen); 1171706f2543Smrg winCmapPriv(pColormap); 1172706f2543Smrg 1173706f2543Smrg /* 1174706f2543Smrg * Is colormap to be destroyed the default? 1175706f2543Smrg * 1176706f2543Smrg * Non-default colormaps should have had winUninstallColormap 1177706f2543Smrg * called on them before we get here. The default colormap 1178706f2543Smrg * will not have had winUninstallColormap called on it. Thus, 1179706f2543Smrg * we need to handle the default colormap in a special way. 1180706f2543Smrg */ 1181706f2543Smrg if (pColormap->flags & IsDefault) 1182706f2543Smrg { 1183706f2543Smrg#if CYGDEBUG 1184706f2543Smrg winDebug ("winDestroyColormapShadowGDI - Destroying default " 1185706f2543Smrg "colormap\n"); 1186706f2543Smrg#endif 1187706f2543Smrg 1188706f2543Smrg /* 1189706f2543Smrg * FIXME: Walk the list of all screens, popping the default 1190706f2543Smrg * palette out of each screen device context. 1191706f2543Smrg */ 1192706f2543Smrg 1193706f2543Smrg /* Pop the palette out of the device context */ 1194706f2543Smrg SelectPalette (pScreenPriv->hdcScreen, 1195706f2543Smrg GetStockObject (DEFAULT_PALETTE), 1196706f2543Smrg FALSE); 1197706f2543Smrg 1198706f2543Smrg /* Clear our private installed colormap pointer */ 1199706f2543Smrg pScreenPriv->pcmapInstalled = NULL; 1200706f2543Smrg } 1201706f2543Smrg 1202706f2543Smrg /* Try to delete the logical palette */ 1203706f2543Smrg if (DeleteObject (pCmapPriv->hPalette) == 0) 1204706f2543Smrg { 1205706f2543Smrg ErrorF ("winDestroyColormap - DeleteObject () failed\n"); 1206706f2543Smrg return FALSE; 1207706f2543Smrg } 1208706f2543Smrg 1209706f2543Smrg /* Invalidate the colormap privates */ 1210706f2543Smrg pCmapPriv->hPalette = NULL; 1211706f2543Smrg 1212706f2543Smrg return TRUE; 1213706f2543Smrg} 1214706f2543Smrg 1215706f2543Smrg 1216706f2543Smrg/* 1217706f2543Smrg * Set engine specific funtions 1218706f2543Smrg */ 1219706f2543Smrg 1220706f2543SmrgBool 1221706f2543SmrgwinSetEngineFunctionsShadowGDI (ScreenPtr pScreen) 1222706f2543Smrg{ 1223706f2543Smrg winScreenPriv(pScreen); 1224706f2543Smrg winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; 1225706f2543Smrg 1226706f2543Smrg /* Set our pointers */ 1227706f2543Smrg pScreenPriv->pwinAllocateFB = winAllocateFBShadowGDI; 1228706f2543Smrg pScreenPriv->pwinFreeFB = winFreeFBShadowGDI; 1229706f2543Smrg pScreenPriv->pwinShadowUpdate = winShadowUpdateGDI; 1230706f2543Smrg pScreenPriv->pwinInitScreen = winInitScreenShadowGDI; 1231706f2543Smrg pScreenPriv->pwinCloseScreen = winCloseScreenShadowGDI; 1232706f2543Smrg pScreenPriv->pwinInitVisuals = winInitVisualsShadowGDI; 1233706f2543Smrg pScreenPriv->pwinAdjustVideoMode = winAdjustVideoModeShadowGDI; 1234706f2543Smrg if (pScreenInfo->fFullScreen) 1235706f2543Smrg pScreenPriv->pwinCreateBoundingWindow = winCreateBoundingWindowFullScreen; 1236706f2543Smrg else 1237706f2543Smrg pScreenPriv->pwinCreateBoundingWindow = winCreateBoundingWindowWindowed; 1238706f2543Smrg pScreenPriv->pwinFinishScreenInit = winFinishScreenInitFB; 1239706f2543Smrg pScreenPriv->pwinBltExposedRegions = winBltExposedRegionsShadowGDI; 1240706f2543Smrg pScreenPriv->pwinActivateApp = winActivateAppShadowGDI; 1241706f2543Smrg pScreenPriv->pwinRedrawScreen = winRedrawScreenShadowGDI; 1242706f2543Smrg pScreenPriv->pwinRealizeInstalledPalette = 1243706f2543Smrg winRealizeInstalledPaletteShadowGDI; 1244706f2543Smrg pScreenPriv->pwinInstallColormap = winInstallColormapShadowGDI; 1245706f2543Smrg pScreenPriv->pwinStoreColors = winStoreColorsShadowGDI; 1246706f2543Smrg pScreenPriv->pwinCreateColormap = winCreateColormapShadowGDI; 1247706f2543Smrg pScreenPriv->pwinDestroyColormap = winDestroyColormapShadowGDI; 1248706f2543Smrg pScreenPriv->pwinHotKeyAltTab = (winHotKeyAltTabProcPtr) (void (*)(void))NoopDDA; 1249706f2543Smrg pScreenPriv->pwinCreatePrimarySurface 1250706f2543Smrg = (winCreatePrimarySurfaceProcPtr) (void (*)(void))NoopDDA; 1251706f2543Smrg pScreenPriv->pwinReleasePrimarySurface 1252706f2543Smrg = (winReleasePrimarySurfaceProcPtr) (void (*)(void))NoopDDA; 1253706f2543Smrg#ifdef XWIN_MULTIWINDOW 1254706f2543Smrg pScreenPriv->pwinFinishCreateWindowsWindow = 1255706f2543Smrg (winFinishCreateWindowsWindowProcPtr) (void (*)(void))NoopDDA; 1256706f2543Smrg#endif 1257706f2543Smrg 1258706f2543Smrg return TRUE; 1259706f2543Smrg} 1260