1/* 2 *Copyright (C) 2001-2004 Harold L Hunt II All Rights Reserved. 3 * 4 *Permission is hereby granted, free of charge, to any person obtaining 5 * a copy of this software and associated documentation files (the 6 *"Software"), to deal in the Software without restriction, including 7 *without limitation the rights to use, copy, modify, merge, publish, 8 *distribute, sublicense, and/or sell copies of the Software, and to 9 *permit persons to whom the Software is furnished to do so, subject to 10 *the following conditions: 11 * 12 *The above copyright notice and this permission notice shall be 13 *included in all copies or substantial portions of the Software. 14 * 15 *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 *NONINFRINGEMENT. IN NO EVENT SHALL HAROLD L HUNT II BE LIABLE FOR 19 *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 20 *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 21 *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 * 23 *Except as contained in this notice, the name of Harold L Hunt II 24 *shall not be used in advertising or otherwise to promote the sale, use 25 *or other dealings in this Software without prior written authorization 26 *from Harold L Hunt II. 27 * 28 * Authors: Harold L Hunt II 29 */ 30 31#ifdef HAVE_XWIN_CONFIG_H 32#include <xwin-config.h> 33#endif 34#include "win.h" 35 36/* 37 * Local function prototypes 38 */ 39 40static wBOOL CALLBACK winRedrawAllProcShadowGDI(HWND hwnd, LPARAM lParam); 41 42static wBOOL CALLBACK winRedrawDamagedWindowShadowGDI(HWND hwnd, LPARAM lParam); 43 44static Bool 45 winAllocateFBShadowGDI(ScreenPtr pScreen); 46 47static void 48 winShadowUpdateGDI(ScreenPtr pScreen, shadowBufPtr pBuf); 49 50static Bool 51 winCloseScreenShadowGDI(ScreenPtr pScreen); 52 53static Bool 54 winInitVisualsShadowGDI(ScreenPtr pScreen); 55 56static Bool 57 winAdjustVideoModeShadowGDI(ScreenPtr pScreen); 58 59static Bool 60 winBltExposedRegionsShadowGDI(ScreenPtr pScreen); 61 62static Bool 63 winBltExposedWindowRegionShadowGDI(ScreenPtr pScreen, WindowPtr pWin); 64 65static Bool 66 winActivateAppShadowGDI(ScreenPtr pScreen); 67 68static Bool 69 winRedrawScreenShadowGDI(ScreenPtr pScreen); 70 71static Bool 72 winRealizeInstalledPaletteShadowGDI(ScreenPtr pScreen); 73 74static Bool 75 winInstallColormapShadowGDI(ColormapPtr pColormap); 76 77static Bool 78 winStoreColorsShadowGDI(ColormapPtr pmap, int ndef, xColorItem * pdefs); 79 80static Bool 81 winCreateColormapShadowGDI(ColormapPtr pColormap); 82 83static Bool 84 winDestroyColormapShadowGDI(ColormapPtr pColormap); 85 86/* 87 * Internal function to get the DIB format that is compatible with the screen 88 */ 89 90static 91 Bool 92winQueryScreenDIBFormat(ScreenPtr pScreen, BITMAPINFOHEADER * pbmih) 93{ 94 winScreenPriv(pScreen); 95 HBITMAP hbmp; 96 97#if CYGDEBUG 98 LPDWORD pdw = NULL; 99#endif 100 101 /* Create a memory bitmap compatible with the screen */ 102 hbmp = CreateCompatibleBitmap(pScreenPriv->hdcScreen, 1, 1); 103 if (hbmp == NULL) { 104 ErrorF("winQueryScreenDIBFormat - CreateCompatibleBitmap failed\n"); 105 return FALSE; 106 } 107 108 /* Initialize our bitmap info header */ 109 ZeroMemory(pbmih, sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD)); 110 pbmih->biSize = sizeof(BITMAPINFOHEADER); 111 112 /* Get the biBitCount */ 113 if (!GetDIBits(pScreenPriv->hdcScreen, 114 hbmp, 0, 1, NULL, (BITMAPINFO *) pbmih, DIB_RGB_COLORS)) { 115 ErrorF("winQueryScreenDIBFormat - First call to GetDIBits failed\n"); 116 DeleteObject(hbmp); 117 return FALSE; 118 } 119 120#if CYGDEBUG 121 /* Get a pointer to bitfields */ 122 pdw = (DWORD *) ((CARD8 *) pbmih + sizeof(BITMAPINFOHEADER)); 123 124 winDebug("winQueryScreenDIBFormat - First call masks: %08x %08x %08x\n", 125 (unsigned int)pdw[0], (unsigned int)pdw[1], (unsigned int)pdw[2]); 126#endif 127 128 /* Get optimal color table, or the optimal bitfields */ 129 if (!GetDIBits(pScreenPriv->hdcScreen, 130 hbmp, 0, 1, NULL, (BITMAPINFO *) pbmih, DIB_RGB_COLORS)) { 131 ErrorF("winQueryScreenDIBFormat - Second call to GetDIBits " 132 "failed\n"); 133 DeleteObject(hbmp); 134 return FALSE; 135 } 136 137 /* Free memory */ 138 DeleteObject(hbmp); 139 140 return TRUE; 141} 142 143/* 144 * Internal function to determine the GDI bits per rgb and bit masks 145 */ 146 147static 148 Bool 149winQueryRGBBitsAndMasks(ScreenPtr pScreen) 150{ 151 winScreenPriv(pScreen); 152 BITMAPINFOHEADER *pbmih = NULL; 153 Bool fReturn = TRUE; 154 LPDWORD pdw = NULL; 155 DWORD dwRedBits, dwGreenBits, dwBlueBits; 156 157 /* Color masks for 8 bpp are standardized */ 158 if (GetDeviceCaps(pScreenPriv->hdcScreen, RASTERCAPS) & RC_PALETTE) { 159 /* 160 * RGB BPP for 8 bit palletes is always 8 161 * and the color masks are always 0. 162 */ 163 pScreenPriv->dwBitsPerRGB = 8; 164 pScreenPriv->dwRedMask = 0x0L; 165 pScreenPriv->dwGreenMask = 0x0L; 166 pScreenPriv->dwBlueMask = 0x0L; 167 return TRUE; 168 } 169 170 /* Color masks for 24 bpp are standardized */ 171 if (GetDeviceCaps(pScreenPriv->hdcScreen, PLANES) 172 * GetDeviceCaps(pScreenPriv->hdcScreen, BITSPIXEL) == 24) { 173 ErrorF("winQueryRGBBitsAndMasks - GetDeviceCaps (BITSPIXEL) " 174 "returned 24 for the screen. Using default 24bpp masks.\n"); 175 176 /* 8 bits per primary color */ 177 pScreenPriv->dwBitsPerRGB = 8; 178 179 /* Set screen privates masks */ 180 pScreenPriv->dwRedMask = WIN_24BPP_MASK_RED; 181 pScreenPriv->dwGreenMask = WIN_24BPP_MASK_GREEN; 182 pScreenPriv->dwBlueMask = WIN_24BPP_MASK_BLUE; 183 184 return TRUE; 185 } 186 187 /* Allocate a bitmap header and color table */ 188 pbmih = malloc(sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD)); 189 if (pbmih == NULL) { 190 ErrorF("winQueryRGBBitsAndMasks - malloc failed\n"); 191 return FALSE; 192 } 193 194 /* Get screen description */ 195 if (winQueryScreenDIBFormat(pScreen, pbmih)) { 196 /* Get a pointer to bitfields */ 197 pdw = (DWORD *) ((CARD8 *) pbmih + sizeof(BITMAPINFOHEADER)); 198 199#if CYGDEBUG 200 winDebug("%s - Masks: %08x %08x %08x\n", __FUNCTION__, 201 (unsigned int)pdw[0], (unsigned int)pdw[1], (unsigned int)pdw[2]); 202 winDebug("%s - Bitmap: %dx%d %d bpp %d planes\n", __FUNCTION__, 203 (int)pbmih->biWidth, (int)pbmih->biHeight, pbmih->biBitCount, 204 pbmih->biPlanes); 205 winDebug("%s - Compression: %u %s\n", __FUNCTION__, 206 (unsigned int)pbmih->biCompression, 207 (pbmih->biCompression == 208 BI_RGB ? "(BI_RGB)" : (pbmih->biCompression == 209 BI_RLE8 ? "(BI_RLE8)" : (pbmih-> 210 biCompression 211 == 212 BI_RLE4 ? 213 "(BI_RLE4)" 214 : (pbmih-> 215 biCompression 216 == 217 BI_BITFIELDS 218 ? 219 "(BI_BITFIELDS)" 220 : ""))))); 221#endif 222 223 /* Handle BI_RGB case, which is returned by Wine */ 224 if (pbmih->biCompression == BI_RGB) { 225 dwRedBits = 5; 226 dwGreenBits = 5; 227 dwBlueBits = 5; 228 229 pScreenPriv->dwBitsPerRGB = 5; 230 231 /* Set screen privates masks */ 232 pScreenPriv->dwRedMask = 0x7c00; 233 pScreenPriv->dwGreenMask = 0x03e0; 234 pScreenPriv->dwBlueMask = 0x001f; 235 } 236 else { 237 /* Count the number of bits in each mask */ 238 dwRedBits = winCountBits(pdw[0]); 239 dwGreenBits = winCountBits(pdw[1]); 240 dwBlueBits = winCountBits(pdw[2]); 241 242 /* Find maximum bits per red, green, blue */ 243 if (dwRedBits > dwGreenBits && dwRedBits > dwBlueBits) 244 pScreenPriv->dwBitsPerRGB = dwRedBits; 245 else if (dwGreenBits > dwRedBits && dwGreenBits > dwBlueBits) 246 pScreenPriv->dwBitsPerRGB = dwGreenBits; 247 else 248 pScreenPriv->dwBitsPerRGB = dwBlueBits; 249 250 /* Set screen privates masks */ 251 pScreenPriv->dwRedMask = pdw[0]; 252 pScreenPriv->dwGreenMask = pdw[1]; 253 pScreenPriv->dwBlueMask = pdw[2]; 254 } 255 } 256 else { 257 ErrorF("winQueryRGBBitsAndMasks - winQueryScreenDIBFormat failed\n"); 258 fReturn = FALSE; 259 } 260 261 /* Free memory */ 262 free(pbmih); 263 264 return fReturn; 265} 266 267/* 268 * Redraw all ---? 269 */ 270 271static wBOOL CALLBACK 272winRedrawAllProcShadowGDI(HWND hwnd, LPARAM lParam) 273{ 274 if (hwnd == (HWND) lParam) 275 return TRUE; 276 InvalidateRect(hwnd, NULL, FALSE); 277 UpdateWindow(hwnd); 278 return TRUE; 279} 280 281static wBOOL CALLBACK 282winRedrawDamagedWindowShadowGDI(HWND hwnd, LPARAM lParam) 283{ 284 BoxPtr pDamage = (BoxPtr) lParam; 285 RECT rcClient, rcDamage, rcRedraw; 286 POINT topLeft, bottomRight; 287 288 if (IsIconic(hwnd)) 289 return TRUE; /* Don't care minimized windows */ 290 291 /* Convert the damaged area from Screen coords to Client coords */ 292 topLeft.x = pDamage->x1; 293 topLeft.y = pDamage->y1; 294 bottomRight.x = pDamage->x2; 295 bottomRight.y = pDamage->y2; 296 topLeft.x += GetSystemMetrics(SM_XVIRTUALSCREEN); 297 bottomRight.x += GetSystemMetrics(SM_XVIRTUALSCREEN); 298 topLeft.y += GetSystemMetrics(SM_YVIRTUALSCREEN); 299 bottomRight.y += GetSystemMetrics(SM_YVIRTUALSCREEN); 300 ScreenToClient(hwnd, &topLeft); 301 ScreenToClient(hwnd, &bottomRight); 302 SetRect(&rcDamage, topLeft.x, topLeft.y, bottomRight.x, bottomRight.y); 303 304 GetClientRect(hwnd, &rcClient); 305 306 if (IntersectRect(&rcRedraw, &rcClient, &rcDamage)) { 307 InvalidateRect(hwnd, &rcRedraw, FALSE); 308 UpdateWindow(hwnd); 309 } 310 return TRUE; 311} 312 313/* 314 * Allocate a DIB for the shadow framebuffer GDI server 315 */ 316 317static Bool 318winAllocateFBShadowGDI(ScreenPtr pScreen) 319{ 320 winScreenPriv(pScreen); 321 winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; 322 DIBSECTION dibsection; 323 Bool fReturn = TRUE; 324 325 /* Describe shadow bitmap to be created */ 326 pScreenPriv->pbmih->biWidth = pScreenInfo->dwWidth; 327 pScreenPriv->pbmih->biHeight = -pScreenInfo->dwHeight; 328 329 ErrorF("winAllocateFBShadowGDI - Creating DIB with width: %d height: %d " 330 "depth: %d\n", 331 (int) pScreenPriv->pbmih->biWidth, 332 (int) -pScreenPriv->pbmih->biHeight, pScreenPriv->pbmih->biBitCount); 333 334 /* Create a DI shadow bitmap with a bit pointer */ 335 pScreenPriv->hbmpShadow = CreateDIBSection(pScreenPriv->hdcScreen, 336 (BITMAPINFO *) pScreenPriv-> 337 pbmih, DIB_RGB_COLORS, 338 (VOID **) &pScreenInfo->pfb, 339 NULL, 0); 340 if (pScreenPriv->hbmpShadow == NULL || pScreenInfo->pfb == NULL) { 341 winW32Error(2, "winAllocateFBShadowGDI - CreateDIBSection failed:"); 342 return FALSE; 343 } 344 else { 345#if CYGDEBUG 346 winDebug("winAllocateFBShadowGDI - Shadow buffer allocated\n"); 347#endif 348 } 349 350 /* Get information about the bitmap that was allocated */ 351 GetObject(pScreenPriv->hbmpShadow, sizeof(dibsection), &dibsection); 352 353#if CYGDEBUG || YES 354 /* Print information about bitmap allocated */ 355 winDebug("winAllocateFBShadowGDI - Dibsection width: %d height: %d " 356 "depth: %d size image: %d\n", 357 (int) dibsection.dsBmih.biWidth, (int) dibsection.dsBmih.biHeight, 358 dibsection.dsBmih.biBitCount, (int) dibsection.dsBmih.biSizeImage); 359#endif 360 361 /* Select the shadow bitmap into the shadow DC */ 362 SelectObject(pScreenPriv->hdcShadow, pScreenPriv->hbmpShadow); 363 364#if CYGDEBUG 365 winDebug("winAllocateFBShadowGDI - Attempting a shadow blit\n"); 366#endif 367 368 /* Do a test blit from the shadow to the screen, I think */ 369 fReturn = BitBlt(pScreenPriv->hdcScreen, 370 0, 0, 371 pScreenInfo->dwWidth, pScreenInfo->dwHeight, 372 pScreenPriv->hdcShadow, 0, 0, SRCCOPY); 373 if (fReturn) { 374#if CYGDEBUG 375 winDebug("winAllocateFBShadowGDI - Shadow blit success\n"); 376#endif 377 } 378 else { 379 winW32Error(2, "winAllocateFBShadowGDI - Shadow blit failure\n"); 380#if 0 381 return FALSE; 382#else 383 /* ago: ignore this error. The blit fails with wine, but does not 384 * cause any problems later. */ 385 386 fReturn = TRUE; 387#endif 388 } 389 390 /* Look for height weirdness */ 391 if (dibsection.dsBmih.biHeight < 0) { 392 dibsection.dsBmih.biHeight = -dibsection.dsBmih.biHeight; 393 } 394 395 /* Set screeninfo stride */ 396 pScreenInfo->dwStride = ((dibsection.dsBmih.biSizeImage 397 / dibsection.dsBmih.biHeight) 398 * 8) / pScreenInfo->dwBPP; 399 400#if CYGDEBUG || YES 401 winDebug("winAllocateFBShadowGDI - Created shadow stride: %d\n", 402 (int) pScreenInfo->dwStride); 403#endif 404 405 /* Redraw all windows */ 406 if (pScreenInfo->fMultiWindow) 407 EnumThreadWindows(g_dwCurrentThreadID, winRedrawAllProcShadowGDI, 0); 408 409 return fReturn; 410} 411 412static void 413winFreeFBShadowGDI(ScreenPtr pScreen) 414{ 415 winScreenPriv(pScreen); 416 winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; 417 418 /* Free the shadow bitmap */ 419 DeleteObject(pScreenPriv->hbmpShadow); 420 421 /* Invalidate the ScreenInfo's fb pointer */ 422 pScreenInfo->pfb = NULL; 423} 424 425/* 426 * Blit the damaged regions of the shadow fb to the screen 427 */ 428 429static void 430winShadowUpdateGDI(ScreenPtr pScreen, shadowBufPtr pBuf) 431{ 432 winScreenPriv(pScreen); 433 winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; 434 RegionPtr damage = DamageRegion(pBuf->pDamage); 435 DWORD dwBox = RegionNumRects(damage); 436 BoxPtr pBox = RegionRects(damage); 437 int x, y, w, h; 438 HRGN hrgnCombined = NULL; 439 440#ifdef XWIN_UPDATESTATS 441 static DWORD s_dwNonUnitRegions = 0; 442 static DWORD s_dwTotalUpdates = 0; 443 static DWORD s_dwTotalBoxes = 0; 444#endif 445 BoxPtr pBoxExtents = RegionExtents(damage); 446 447 /* 448 * Return immediately if the app is not active 449 * and we are fullscreen, or if we have a bad display depth 450 */ 451 if ((!pScreenPriv->fActive && pScreenInfo->fFullScreen) 452 || pScreenPriv->fBadDepth) 453 return; 454 455#ifdef XWIN_UPDATESTATS 456 ++s_dwTotalUpdates; 457 s_dwTotalBoxes += dwBox; 458 459 if (dwBox != 1) { 460 ++s_dwNonUnitRegions; 461 ErrorF("winShadowUpdatGDI - dwBox: %d\n", dwBox); 462 } 463 464 if ((s_dwTotalUpdates % 100) == 0) 465 ErrorF("winShadowUpdateGDI - %d%% non-unity regions, avg boxes: %d " 466 "nu: %d tu: %d\n", 467 (s_dwNonUnitRegions * 100) / s_dwTotalUpdates, 468 s_dwTotalBoxes / s_dwTotalUpdates, 469 s_dwNonUnitRegions, s_dwTotalUpdates); 470#endif /* XWIN_UPDATESTATS */ 471 472 /* 473 * Handle small regions with multiple blits, 474 * handle large regions by creating a clipping region and 475 * doing a single blit constrained to that clipping region. 476 */ 477 if (!pScreenInfo->fMultiWindow && 478 (pScreenInfo->dwClipUpdatesNBoxes == 0 || 479 dwBox < pScreenInfo->dwClipUpdatesNBoxes)) { 480 /* Loop through all boxes in the damaged region */ 481 while (dwBox--) { 482 /* 483 * Calculate x offset, y offset, width, and height for 484 * current damage box 485 */ 486 x = pBox->x1; 487 y = pBox->y1; 488 w = pBox->x2 - pBox->x1; 489 h = pBox->y2 - pBox->y1; 490 491 BitBlt(pScreenPriv->hdcScreen, 492 x, y, w, h, pScreenPriv->hdcShadow, x, y, SRCCOPY); 493 494 /* Get a pointer to the next box */ 495 ++pBox; 496 } 497 } 498 else if (!pScreenInfo->fMultiWindow) { 499 500 /* Compute a GDI region from the damaged region */ 501 hrgnCombined = 502 CreateRectRgn(pBoxExtents->x1, pBoxExtents->y1, pBoxExtents->x2, 503 pBoxExtents->y2); 504 505 /* Install the GDI region as a clipping region */ 506 SelectClipRgn(pScreenPriv->hdcScreen, hrgnCombined); 507 DeleteObject(hrgnCombined); 508 hrgnCombined = NULL; 509 510 /* 511 * Blit the shadow buffer to the screen, 512 * constrained to the clipping region. 513 */ 514 BitBlt(pScreenPriv->hdcScreen, 515 pBoxExtents->x1, pBoxExtents->y1, 516 pBoxExtents->x2 - pBoxExtents->x1, 517 pBoxExtents->y2 - pBoxExtents->y1, 518 pScreenPriv->hdcShadow, 519 pBoxExtents->x1, pBoxExtents->y1, SRCCOPY); 520 521 /* Reset the clip region */ 522 SelectClipRgn(pScreenPriv->hdcScreen, NULL); 523 } 524 525 /* Redraw all multiwindow windows */ 526 if (pScreenInfo->fMultiWindow) 527 EnumThreadWindows(g_dwCurrentThreadID, 528 winRedrawDamagedWindowShadowGDI, 529 (LPARAM) pBoxExtents); 530} 531 532static Bool 533winInitScreenShadowGDI(ScreenPtr pScreen) 534{ 535 winScreenPriv(pScreen); 536 537 /* Get device contexts for the screen and shadow bitmap */ 538 pScreenPriv->hdcScreen = GetDC(pScreenPriv->hwndScreen); 539 pScreenPriv->hdcShadow = CreateCompatibleDC(pScreenPriv->hdcScreen); 540 541 /* Allocate bitmap info header */ 542 pScreenPriv->pbmih = malloc(sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD)); 543 if (pScreenPriv->pbmih == NULL) { 544 ErrorF("winInitScreenShadowGDI - malloc () failed\n"); 545 return FALSE; 546 } 547 548 /* Query the screen format */ 549 if (!winQueryScreenDIBFormat(pScreen, pScreenPriv->pbmih)) { 550 ErrorF("winInitScreenShadowGDI - winQueryScreenDIBFormat failed\n"); 551 return FALSE; 552 } 553 554 /* Determine our color masks */ 555 if (!winQueryRGBBitsAndMasks(pScreen)) { 556 ErrorF("winInitScreenShadowGDI - winQueryRGBBitsAndMasks failed\n"); 557 return FALSE; 558 } 559 560 return winAllocateFBShadowGDI(pScreen); 561} 562 563/* See Porting Layer Definition - p. 33 */ 564/* 565 * We wrap whatever CloseScreen procedure was specified by fb; 566 * a pointer to said procedure is stored in our privates. 567 */ 568 569static Bool 570winCloseScreenShadowGDI(ScreenPtr pScreen) 571{ 572 winScreenPriv(pScreen); 573 winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; 574 Bool fReturn = TRUE; 575 576#if CYGDEBUG 577 winDebug("winCloseScreenShadowGDI - Freeing screen resources\n"); 578#endif 579 580 /* Flag that the screen is closed */ 581 pScreenPriv->fClosed = TRUE; 582 pScreenPriv->fActive = FALSE; 583 584 /* Call the wrapped CloseScreen procedure */ 585 WIN_UNWRAP(CloseScreen); 586 if (pScreen->CloseScreen) 587 fReturn = (*pScreen->CloseScreen) (pScreen); 588 589 /* Delete the window property */ 590 RemoveProp(pScreenPriv->hwndScreen, WIN_SCR_PROP); 591 592 /* Free the shadow DC; which allows the bitmap to be freed */ 593 DeleteDC(pScreenPriv->hdcShadow); 594 595 winFreeFBShadowGDI(pScreen); 596 597 /* Free the screen DC */ 598 ReleaseDC(pScreenPriv->hwndScreen, pScreenPriv->hdcScreen); 599 600 /* Delete tray icon, if we have one */ 601 if (!pScreenInfo->fNoTrayIcon) 602 winDeleteNotifyIcon(pScreenPriv); 603 604 /* Free the exit confirmation dialog box, if it exists */ 605 if (g_hDlgExit != NULL) { 606 DestroyWindow(g_hDlgExit); 607 g_hDlgExit = NULL; 608 } 609 610 /* Kill our window */ 611 if (pScreenPriv->hwndScreen) { 612 DestroyWindow(pScreenPriv->hwndScreen); 613 pScreenPriv->hwndScreen = NULL; 614 } 615 616 /* Destroy the thread startup mutex */ 617 pthread_mutex_destroy(&pScreenPriv->pmServerStarted); 618 619 /* Invalidate our screeninfo's pointer to the screen */ 620 pScreenInfo->pScreen = NULL; 621 622 /* Free the screen privates for this screen */ 623 free((void *) pScreenPriv); 624 625 return fReturn; 626} 627 628/* 629 * Tell mi what sort of visuals we need. 630 * 631 * Generally we only need one visual, as our screen can only 632 * handle one format at a time, I believe. You may want 633 * to verify that last sentence. 634 */ 635 636static Bool 637winInitVisualsShadowGDI(ScreenPtr pScreen) 638{ 639 winScreenPriv(pScreen); 640 winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; 641 642 /* Display debugging information */ 643 ErrorF("winInitVisualsShadowGDI - Masks %08x %08x %08x BPRGB %d d %d " 644 "bpp %d\n", 645 (unsigned int) pScreenPriv->dwRedMask, 646 (unsigned int) pScreenPriv->dwGreenMask, 647 (unsigned int) pScreenPriv->dwBlueMask, 648 (int) pScreenPriv->dwBitsPerRGB, 649 (int) pScreenInfo->dwDepth, (int) pScreenInfo->dwBPP); 650 651 /* Create a single visual according to the Windows screen depth */ 652 switch (pScreenInfo->dwDepth) { 653 case 24: 654 case 16: 655 case 15: 656 /* Setup the real visual */ 657 if (!miSetVisualTypesAndMasks(pScreenInfo->dwDepth, 658 TrueColorMask, 659 pScreenPriv->dwBitsPerRGB, 660 -1, 661 pScreenPriv->dwRedMask, 662 pScreenPriv->dwGreenMask, 663 pScreenPriv->dwBlueMask)) { 664 ErrorF("winInitVisualsShadowGDI - miSetVisualTypesAndMasks " 665 "failed\n"); 666 return FALSE; 667 } 668 669#ifdef XWIN_EMULATEPSEUDO 670 if (!pScreenInfo->fEmulatePseudo) 671 break; 672 673 /* Setup a pseudocolor visual */ 674 if (!miSetVisualTypesAndMasks(8, PseudoColorMask, 8, -1, 0, 0, 0)) { 675 ErrorF("winInitVisualsShadowGDI - miSetVisualTypesAndMasks " 676 "failed for PseudoColor\n"); 677 return FALSE; 678 } 679#endif 680 break; 681 682 case 8: 683 if (!miSetVisualTypesAndMasks(pScreenInfo->dwDepth, 684 PseudoColorMask, 685 pScreenPriv->dwBitsPerRGB, 686 PseudoColor, 687 pScreenPriv->dwRedMask, 688 pScreenPriv->dwGreenMask, 689 pScreenPriv->dwBlueMask)) { 690 ErrorF("winInitVisualsShadowGDI - miSetVisualTypesAndMasks " 691 "failed\n"); 692 return FALSE; 693 } 694 break; 695 696 default: 697 ErrorF("winInitVisualsShadowGDI - Unknown screen depth\n"); 698 return FALSE; 699 } 700 701#if CYGDEBUG 702 winDebug("winInitVisualsShadowGDI - Returning\n"); 703#endif 704 705 return TRUE; 706} 707 708/* 709 * Adjust the proposed video mode 710 */ 711 712static Bool 713winAdjustVideoModeShadowGDI(ScreenPtr pScreen) 714{ 715 winScreenPriv(pScreen); 716 winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; 717 HDC hdc; 718 DWORD dwBPP; 719 720 hdc = GetDC(NULL); 721 722 /* We're in serious trouble if we can't get a DC */ 723 if (hdc == NULL) { 724 ErrorF("winAdjustVideoModeShadowGDI - GetDC () failed\n"); 725 return FALSE; 726 } 727 728 /* Query GDI for current display depth */ 729 dwBPP = GetDeviceCaps(hdc, BITSPIXEL); 730 731 /* GDI cannot change the screen depth, so always use GDI's depth */ 732 pScreenInfo->dwBPP = dwBPP; 733 734 /* Release our DC */ 735 ReleaseDC(NULL, hdc); 736 hdc = NULL; 737 738 return TRUE; 739} 740 741/* 742 * Blt exposed regions to the screen 743 */ 744 745static Bool 746winBltExposedRegionsShadowGDI(ScreenPtr pScreen) 747{ 748 winScreenPriv(pScreen); 749 winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; 750 winPrivCmapPtr pCmapPriv = NULL; 751 HDC hdcUpdate; 752 PAINTSTRUCT ps; 753 754 /* BeginPaint gives us an hdc that clips to the invalidated region */ 755 hdcUpdate = BeginPaint(pScreenPriv->hwndScreen, &ps); 756 /* Avoid the BitBlt if the PAINTSTRUCT region is bogus */ 757 if (ps.rcPaint.right == 0 && ps.rcPaint.bottom == 0 && 758 ps.rcPaint.left == 0 && ps.rcPaint.top == 0) { 759 EndPaint(pScreenPriv->hwndScreen, &ps); 760 return 0; 761 } 762 763 /* Realize the palette, if we have one */ 764 if (pScreenPriv->pcmapInstalled != NULL) { 765 pCmapPriv = winGetCmapPriv(pScreenPriv->pcmapInstalled); 766 767 SelectPalette(hdcUpdate, pCmapPriv->hPalette, FALSE); 768 RealizePalette(hdcUpdate); 769 } 770 771 /* Try to copy from the shadow buffer to the invalidated region */ 772 if (!BitBlt(hdcUpdate, 773 ps.rcPaint.left, ps.rcPaint.top, 774 ps.rcPaint.right - ps.rcPaint.left, 775 ps.rcPaint.bottom - ps.rcPaint.top, 776 pScreenPriv->hdcShadow, 777 ps.rcPaint.left, 778 ps.rcPaint.top, 779 SRCCOPY)) { 780 LPVOID lpMsgBuf; 781 782 /* Display an error message */ 783 FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | 784 FORMAT_MESSAGE_FROM_SYSTEM | 785 FORMAT_MESSAGE_IGNORE_INSERTS, 786 NULL, 787 GetLastError(), 788 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), 789 (LPTSTR) &lpMsgBuf, 0, NULL); 790 791 ErrorF("winBltExposedRegionsShadowGDI - BitBlt failed: %s\n", 792 (LPSTR) lpMsgBuf); 793 LocalFree(lpMsgBuf); 794 } 795 796 /* EndPaint frees the DC */ 797 EndPaint(pScreenPriv->hwndScreen, &ps); 798 799 /* Redraw all windows */ 800 if (pScreenInfo->fMultiWindow) 801 EnumThreadWindows(g_dwCurrentThreadID, winRedrawAllProcShadowGDI, 802 (LPARAM) pScreenPriv->hwndScreen); 803 804 return TRUE; 805} 806 807/* 808 * Blt exposed region to the given HWND 809 */ 810 811static Bool 812winBltExposedWindowRegionShadowGDI(ScreenPtr pScreen, WindowPtr pWin) 813{ 814 winScreenPriv(pScreen); 815 winPrivWinPtr pWinPriv = winGetWindowPriv(pWin); 816 817 HWND hWnd = pWinPriv->hWnd; 818 HDC hdcUpdate; 819 PAINTSTRUCT ps; 820 821 hdcUpdate = BeginPaint(hWnd, &ps); 822 /* Avoid the BitBlt if the PAINTSTRUCT region is bogus */ 823 if (ps.rcPaint.right == 0 && ps.rcPaint.bottom == 0 && 824 ps.rcPaint.left == 0 && ps.rcPaint.top == 0) { 825 EndPaint(hWnd, &ps); 826 return 0; 827 } 828 829#ifdef COMPOSITE 830 if (pWin->redirectDraw != RedirectDrawNone) { 831 HBITMAP hBitmap; 832 HDC hdcPixmap; 833 PixmapPtr pPixmap = (*pScreen->GetWindowPixmap) (pWin); 834 winPrivPixmapPtr pPixmapPriv = winGetPixmapPriv(pPixmap); 835 836 /* window pixmap format is the same as the screen pixmap */ 837 assert(pPixmap->drawable.bitsPerPixel > 8); 838 839 /* Get the window bitmap from the pixmap */ 840 hBitmap = pPixmapPriv->hBitmap; 841 842 /* XXX: There may be a need for a slow-path here: If hBitmap is NULL 843 (because we couldn't back the pixmap with a Windows DIB), we should 844 fall-back to creating a Windows DIB from the pixmap, then deleting it 845 after the BitBlt (as this this code did before the fast-path was 846 added). */ 847 if (!hBitmap) { 848 ErrorF("winBltExposedWindowRegionShadowGDI - slow path unimplemented\n"); 849 } 850 851 /* Select the window bitmap into a screen-compatible DC */ 852 hdcPixmap = CreateCompatibleDC(pScreenPriv->hdcScreen); 853 SelectObject(hdcPixmap, hBitmap); 854 855 /* Blt from the window bitmap to the invalidated region */ 856 if (!BitBlt(hdcUpdate, 857 ps.rcPaint.left, ps.rcPaint.top, 858 ps.rcPaint.right - ps.rcPaint.left, 859 ps.rcPaint.bottom - ps.rcPaint.top, 860 hdcPixmap, 861 ps.rcPaint.left + pWin->borderWidth, 862 ps.rcPaint.top + pWin->borderWidth, 863 SRCCOPY)) 864 ErrorF("winBltExposedWindowRegionShadowGDI - BitBlt failed: 0x%08x\n", 865 GetLastError()); 866 867 /* Release DC */ 868 DeleteDC(hdcPixmap); 869 } 870 else 871#endif 872 { 873 /* Try to copy from the shadow buffer to the invalidated region */ 874 if (!BitBlt(hdcUpdate, 875 ps.rcPaint.left, ps.rcPaint.top, 876 ps.rcPaint.right - ps.rcPaint.left, 877 ps.rcPaint.bottom - ps.rcPaint.top, 878 pScreenPriv->hdcShadow, 879 ps.rcPaint.left + pWin->drawable.x, 880 ps.rcPaint.top + pWin->drawable.y, 881 SRCCOPY)) { 882 LPVOID lpMsgBuf; 883 884 /* Display an error message */ 885 FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | 886 FORMAT_MESSAGE_FROM_SYSTEM | 887 FORMAT_MESSAGE_IGNORE_INSERTS, 888 NULL, 889 GetLastError(), 890 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), 891 (LPTSTR) &lpMsgBuf, 0, NULL); 892 893 ErrorF("winBltExposedWindowRegionShadowGDI - BitBlt failed: %s\n", 894 (LPSTR) lpMsgBuf); 895 LocalFree(lpMsgBuf); 896 } 897 } 898 899 /* If part of the invalidated region is outside the window (which can happen 900 if the native window is being re-sized), fill that area with black */ 901 if (ps.rcPaint.right > ps.rcPaint.left + pWin->drawable.width) { 902 BitBlt(hdcUpdate, 903 ps.rcPaint.left + pWin->drawable.width, 904 ps.rcPaint.top, 905 ps.rcPaint.right - (ps.rcPaint.left + pWin->drawable.width), 906 ps.rcPaint.bottom - ps.rcPaint.top, 907 NULL, 908 0, 0, 909 BLACKNESS); 910 } 911 912 if (ps.rcPaint.bottom > ps.rcPaint.top + pWin->drawable.height) { 913 BitBlt(hdcUpdate, 914 ps.rcPaint.left, 915 ps.rcPaint.top + pWin->drawable.height, 916 ps.rcPaint.right - ps.rcPaint.left, 917 ps.rcPaint.bottom - (ps.rcPaint.top + pWin->drawable.height), 918 NULL, 919 0, 0, 920 BLACKNESS); 921 } 922 923 /* EndPaint frees the DC */ 924 EndPaint(hWnd, &ps); 925 926 return TRUE; 927} 928 929/* 930 * Do any engine-specific appliation-activation processing 931 */ 932 933static Bool 934winActivateAppShadowGDI(ScreenPtr pScreen) 935{ 936 winScreenPriv(pScreen); 937 winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; 938 939 /* 940 * 2004/04/12 - Harold - We perform the restoring or minimizing 941 * manually for ShadowGDI in fullscreen modes so that this engine 942 * will perform just like ShadowDD and ShadowDDNL in fullscreen mode; 943 * if we do not do this then our fullscreen window will appear in the 944 * z-order when it is deactivated and it can be uncovered by resizing 945 * or minimizing another window that is on top of it, which is not how 946 * the DirectDraw engines work. Therefore we keep this code here to 947 * make sure that all engines work the same in fullscreen mode. 948 */ 949 950 /* 951 * Are we active? 952 * Are we fullscreen? 953 */ 954 if (pScreenPriv->fActive && pScreenInfo->fFullScreen) { 955 /* 956 * Activating, attempt to bring our window 957 * to the top of the display 958 */ 959 ShowWindow(pScreenPriv->hwndScreen, SW_RESTORE); 960 } 961 else if (!pScreenPriv->fActive && pScreenInfo->fFullScreen) { 962 /* 963 * Deactivating, stuff our window onto the 964 * task bar. 965 */ 966 ShowWindow(pScreenPriv->hwndScreen, SW_MINIMIZE); 967 } 968 969 return TRUE; 970} 971 972/* 973 * Reblit the shadow framebuffer to the screen. 974 */ 975 976static Bool 977winRedrawScreenShadowGDI(ScreenPtr pScreen) 978{ 979 winScreenPriv(pScreen); 980 winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; 981 982 /* Redraw the whole window, to take account for the new colors */ 983 BitBlt(pScreenPriv->hdcScreen, 984 0, 0, 985 pScreenInfo->dwWidth, pScreenInfo->dwHeight, 986 pScreenPriv->hdcShadow, 0, 0, SRCCOPY); 987 988 /* Redraw all windows */ 989 if (pScreenInfo->fMultiWindow) 990 EnumThreadWindows(g_dwCurrentThreadID, winRedrawAllProcShadowGDI, 0); 991 992 return TRUE; 993} 994 995/* 996 * Realize the currently installed colormap 997 */ 998 999static Bool 1000winRealizeInstalledPaletteShadowGDI(ScreenPtr pScreen) 1001{ 1002 winScreenPriv(pScreen); 1003 winPrivCmapPtr pCmapPriv = NULL; 1004 1005#if CYGDEBUG 1006 winDebug("winRealizeInstalledPaletteShadowGDI\n"); 1007#endif 1008 1009 /* Don't do anything if there is not a colormap */ 1010 if (pScreenPriv->pcmapInstalled == NULL) { 1011#if CYGDEBUG 1012 winDebug("winRealizeInstalledPaletteShadowGDI - No colormap " 1013 "installed\n"); 1014#endif 1015 return TRUE; 1016 } 1017 1018 pCmapPriv = winGetCmapPriv(pScreenPriv->pcmapInstalled); 1019 1020 /* Realize our palette for the screen */ 1021 if (RealizePalette(pScreenPriv->hdcScreen) == GDI_ERROR) { 1022 ErrorF("winRealizeInstalledPaletteShadowGDI - RealizePalette () " 1023 "failed\n"); 1024 return FALSE; 1025 } 1026 1027 /* Set the DIB color table */ 1028 if (SetDIBColorTable(pScreenPriv->hdcShadow, 1029 0, 1030 WIN_NUM_PALETTE_ENTRIES, pCmapPriv->rgbColors) == 0) { 1031 ErrorF("winRealizeInstalledPaletteShadowGDI - SetDIBColorTable () " 1032 "failed\n"); 1033 return FALSE; 1034 } 1035 1036 return TRUE; 1037} 1038 1039/* 1040 * Install the specified colormap 1041 */ 1042 1043static Bool 1044winInstallColormapShadowGDI(ColormapPtr pColormap) 1045{ 1046 ScreenPtr pScreen = pColormap->pScreen; 1047 1048 winScreenPriv(pScreen); 1049 winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; 1050 1051 winCmapPriv(pColormap); 1052 1053 /* 1054 * Tell Windows to install the new colormap 1055 */ 1056 if (SelectPalette(pScreenPriv->hdcScreen, 1057 pCmapPriv->hPalette, FALSE) == NULL) { 1058 ErrorF("winInstallColormapShadowGDI - SelectPalette () failed\n"); 1059 return FALSE; 1060 } 1061 1062 /* Realize the palette */ 1063 if (GDI_ERROR == RealizePalette(pScreenPriv->hdcScreen)) { 1064 ErrorF("winInstallColormapShadowGDI - RealizePalette () failed\n"); 1065 return FALSE; 1066 } 1067 1068 /* Set the DIB color table */ 1069 if (SetDIBColorTable(pScreenPriv->hdcShadow, 1070 0, 1071 WIN_NUM_PALETTE_ENTRIES, pCmapPriv->rgbColors) == 0) { 1072 ErrorF("winInstallColormapShadowGDI - SetDIBColorTable () failed\n"); 1073 return FALSE; 1074 } 1075 1076 /* Redraw the whole window, to take account for the new colors */ 1077 BitBlt(pScreenPriv->hdcScreen, 1078 0, 0, 1079 pScreenInfo->dwWidth, pScreenInfo->dwHeight, 1080 pScreenPriv->hdcShadow, 0, 0, SRCCOPY); 1081 1082 /* Save a pointer to the newly installed colormap */ 1083 pScreenPriv->pcmapInstalled = pColormap; 1084 1085 /* Redraw all windows */ 1086 if (pScreenInfo->fMultiWindow) 1087 EnumThreadWindows(g_dwCurrentThreadID, winRedrawAllProcShadowGDI, 0); 1088 1089 return TRUE; 1090} 1091 1092/* 1093 * Store the specified colors in the specified colormap 1094 */ 1095 1096static Bool 1097winStoreColorsShadowGDI(ColormapPtr pColormap, int ndef, xColorItem * pdefs) 1098{ 1099 ScreenPtr pScreen = pColormap->pScreen; 1100 1101 winScreenPriv(pScreen); 1102 winCmapPriv(pColormap); 1103 ColormapPtr curpmap = pScreenPriv->pcmapInstalled; 1104 1105 /* Put the X colormap entries into the Windows logical palette */ 1106 if (SetPaletteEntries(pCmapPriv->hPalette, 1107 pdefs[0].pixel, 1108 ndef, pCmapPriv->peColors + pdefs[0].pixel) == 0) { 1109 ErrorF("winStoreColorsShadowGDI - SetPaletteEntries () failed\n"); 1110 return FALSE; 1111 } 1112 1113 /* Don't install the Windows palette if the colormap is not installed */ 1114 if (pColormap != curpmap) { 1115 return TRUE; 1116 } 1117 1118 /* Try to install the newly modified colormap */ 1119 if (!winInstallColormapShadowGDI(pColormap)) { 1120 ErrorF("winInstallColormapShadowGDI - winInstallColormapShadowGDI " 1121 "failed\n"); 1122 return FALSE; 1123 } 1124 1125#if 0 1126 /* Tell Windows that the palette has changed */ 1127 RealizePalette(pScreenPriv->hdcScreen); 1128 1129 /* Set the DIB color table */ 1130 if (SetDIBColorTable(pScreenPriv->hdcShadow, 1131 pdefs[0].pixel, 1132 ndef, pCmapPriv->rgbColors + pdefs[0].pixel) == 0) { 1133 ErrorF("winInstallColormapShadowGDI - SetDIBColorTable () failed\n"); 1134 return FALSE; 1135 } 1136 1137 /* Save a pointer to the newly installed colormap */ 1138 pScreenPriv->pcmapInstalled = pColormap; 1139#endif 1140 1141 return TRUE; 1142} 1143 1144/* 1145 * Colormap initialization procedure 1146 */ 1147 1148static Bool 1149winCreateColormapShadowGDI(ColormapPtr pColormap) 1150{ 1151 LPLOGPALETTE lpPaletteNew = NULL; 1152 DWORD dwEntriesMax; 1153 VisualPtr pVisual; 1154 HPALETTE hpalNew = NULL; 1155 1156 winCmapPriv(pColormap); 1157 1158 /* Get a pointer to the visual that the colormap belongs to */ 1159 pVisual = pColormap->pVisual; 1160 1161 /* Get the maximum number of palette entries for this visual */ 1162 dwEntriesMax = pVisual->ColormapEntries; 1163 1164 /* Allocate a Windows logical color palette with max entries */ 1165 lpPaletteNew = malloc(sizeof(LOGPALETTE) 1166 + (dwEntriesMax - 1) * sizeof(PALETTEENTRY)); 1167 if (lpPaletteNew == NULL) { 1168 ErrorF("winCreateColormapShadowGDI - Couldn't allocate palette " 1169 "with %d entries\n", (int) dwEntriesMax); 1170 return FALSE; 1171 } 1172 1173 /* Zero out the colormap */ 1174 ZeroMemory(lpPaletteNew, sizeof(LOGPALETTE) 1175 + (dwEntriesMax - 1) * sizeof(PALETTEENTRY)); 1176 1177 /* Set the logical palette structure */ 1178 lpPaletteNew->palVersion = 0x0300; 1179 lpPaletteNew->palNumEntries = dwEntriesMax; 1180 1181 /* Tell Windows to create the palette */ 1182 hpalNew = CreatePalette(lpPaletteNew); 1183 if (hpalNew == NULL) { 1184 ErrorF("winCreateColormapShadowGDI - CreatePalette () failed\n"); 1185 free(lpPaletteNew); 1186 return FALSE; 1187 } 1188 1189 /* Save the Windows logical palette handle in the X colormaps' privates */ 1190 pCmapPriv->hPalette = hpalNew; 1191 1192 /* Free the palette initialization memory */ 1193 free(lpPaletteNew); 1194 1195 return TRUE; 1196} 1197 1198/* 1199 * Colormap destruction procedure 1200 */ 1201 1202static Bool 1203winDestroyColormapShadowGDI(ColormapPtr pColormap) 1204{ 1205 winScreenPriv(pColormap->pScreen); 1206 winCmapPriv(pColormap); 1207 1208 /* 1209 * Is colormap to be destroyed the default? 1210 * 1211 * Non-default colormaps should have had winUninstallColormap 1212 * called on them before we get here. The default colormap 1213 * will not have had winUninstallColormap called on it. Thus, 1214 * we need to handle the default colormap in a special way. 1215 */ 1216 if (pColormap->flags & IsDefault) { 1217#if CYGDEBUG 1218 winDebug("winDestroyColormapShadowGDI - Destroying default " 1219 "colormap\n"); 1220#endif 1221 1222 /* 1223 * FIXME: Walk the list of all screens, popping the default 1224 * palette out of each screen device context. 1225 */ 1226 1227 /* Pop the palette out of the device context */ 1228 SelectPalette(pScreenPriv->hdcScreen, 1229 GetStockObject(DEFAULT_PALETTE), FALSE); 1230 1231 /* Clear our private installed colormap pointer */ 1232 pScreenPriv->pcmapInstalled = NULL; 1233 } 1234 1235 /* Try to delete the logical palette */ 1236 if (DeleteObject(pCmapPriv->hPalette) == 0) { 1237 ErrorF("winDestroyColormap - DeleteObject () failed\n"); 1238 return FALSE; 1239 } 1240 1241 /* Invalidate the colormap privates */ 1242 pCmapPriv->hPalette = NULL; 1243 1244 return TRUE; 1245} 1246 1247/* 1248 * Set engine specific functions 1249 */ 1250 1251Bool 1252winSetEngineFunctionsShadowGDI(ScreenPtr pScreen) 1253{ 1254 winScreenPriv(pScreen); 1255 winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; 1256 1257 /* Set our pointers */ 1258 pScreenPriv->pwinAllocateFB = winAllocateFBShadowGDI; 1259 pScreenPriv->pwinFreeFB = winFreeFBShadowGDI; 1260 pScreenPriv->pwinShadowUpdate = winShadowUpdateGDI; 1261 pScreenPriv->pwinInitScreen = winInitScreenShadowGDI; 1262 pScreenPriv->pwinCloseScreen = winCloseScreenShadowGDI; 1263 pScreenPriv->pwinInitVisuals = winInitVisualsShadowGDI; 1264 pScreenPriv->pwinAdjustVideoMode = winAdjustVideoModeShadowGDI; 1265 if (pScreenInfo->fFullScreen) 1266 pScreenPriv->pwinCreateBoundingWindow = 1267 winCreateBoundingWindowFullScreen; 1268 else 1269 pScreenPriv->pwinCreateBoundingWindow = winCreateBoundingWindowWindowed; 1270 pScreenPriv->pwinFinishScreenInit = winFinishScreenInitFB; 1271 pScreenPriv->pwinBltExposedRegions = winBltExposedRegionsShadowGDI; 1272 pScreenPriv->pwinBltExposedWindowRegion = winBltExposedWindowRegionShadowGDI; 1273 pScreenPriv->pwinActivateApp = winActivateAppShadowGDI; 1274 pScreenPriv->pwinRedrawScreen = winRedrawScreenShadowGDI; 1275 pScreenPriv->pwinRealizeInstalledPalette = 1276 winRealizeInstalledPaletteShadowGDI; 1277 pScreenPriv->pwinInstallColormap = winInstallColormapShadowGDI; 1278 pScreenPriv->pwinStoreColors = winStoreColorsShadowGDI; 1279 pScreenPriv->pwinCreateColormap = winCreateColormapShadowGDI; 1280 pScreenPriv->pwinDestroyColormap = winDestroyColormapShadowGDI; 1281 pScreenPriv->pwinCreatePrimarySurface = NULL; 1282 pScreenPriv->pwinReleasePrimarySurface = NULL; 1283 1284 return TRUE; 1285} 1286