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
40 static wBOOL CALLBACK winRedrawAllProcShadowGDI(HWND hwnd, LPARAM lParam);
41
42 static wBOOL CALLBACK winRedrawDamagedWindowShadowGDI(HWND hwnd, LPARAM lParam);
43
44 static Bool
45 winAllocateFBShadowGDI(ScreenPtr pScreen);
46
47 static void
48 winShadowUpdateGDI(ScreenPtr pScreen, shadowBufPtr pBuf);
49
50 static Bool
51 winCloseScreenShadowGDI(ScreenPtr pScreen);
52
53 static Bool
54 winInitVisualsShadowGDI(ScreenPtr pScreen);
55
56 static Bool
57 winAdjustVideoModeShadowGDI(ScreenPtr pScreen);
58
59 static Bool
60 winBltExposedRegionsShadowGDI(ScreenPtr pScreen);
61
62 static Bool
63 winBltExposedWindowRegionShadowGDI(ScreenPtr pScreen, WindowPtr pWin);
64
65 static Bool
66 winActivateAppShadowGDI(ScreenPtr pScreen);
67
68 static Bool
69 winRedrawScreenShadowGDI(ScreenPtr pScreen);
70
71 static Bool
72 winRealizeInstalledPaletteShadowGDI(ScreenPtr pScreen);
73
74 static Bool
75 winInstallColormapShadowGDI(ColormapPtr pColormap);
76
77 static Bool
78 winStoreColorsShadowGDI(ColormapPtr pmap, int ndef, xColorItem * pdefs);
79
80 static Bool
81 winCreateColormapShadowGDI(ColormapPtr pColormap);
82
83 static Bool
84 winDestroyColormapShadowGDI(ColormapPtr pColormap);
85
86 /*
87 * Internal function to get the DIB format that is compatible with the screen
88 */
89
90 static
91 Bool
winQueryScreenDIBFormat(ScreenPtr pScreen,BITMAPINFOHEADER * pbmih)92 winQueryScreenDIBFormat(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
147 static
148 Bool
winQueryRGBBitsAndMasks(ScreenPtr pScreen)149 winQueryRGBBitsAndMasks(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
271 static wBOOL CALLBACK
winRedrawAllProcShadowGDI(HWND hwnd,LPARAM lParam)272 winRedrawAllProcShadowGDI(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
281 static wBOOL CALLBACK
winRedrawDamagedWindowShadowGDI(HWND hwnd,LPARAM lParam)282 winRedrawDamagedWindowShadowGDI(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
317 static Bool
winAllocateFBShadowGDI(ScreenPtr pScreen)318 winAllocateFBShadowGDI(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
412 static void
winFreeFBShadowGDI(ScreenPtr pScreen)413 winFreeFBShadowGDI(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
429 static void
winShadowUpdateGDI(ScreenPtr pScreen,shadowBufPtr pBuf)430 winShadowUpdateGDI(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
532 static Bool
winInitScreenShadowGDI(ScreenPtr pScreen)533 winInitScreenShadowGDI(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
569 static Bool
winCloseScreenShadowGDI(ScreenPtr pScreen)570 winCloseScreenShadowGDI(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
636 static Bool
winInitVisualsShadowGDI(ScreenPtr pScreen)637 winInitVisualsShadowGDI(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
712 static Bool
winAdjustVideoModeShadowGDI(ScreenPtr pScreen)713 winAdjustVideoModeShadowGDI(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
745 static Bool
winBltExposedRegionsShadowGDI(ScreenPtr pScreen)746 winBltExposedRegionsShadowGDI(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
811 static Bool
winBltExposedWindowRegionShadowGDI(ScreenPtr pScreen,WindowPtr pWin)812 winBltExposedWindowRegionShadowGDI(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
933 static Bool
winActivateAppShadowGDI(ScreenPtr pScreen)934 winActivateAppShadowGDI(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
976 static Bool
winRedrawScreenShadowGDI(ScreenPtr pScreen)977 winRedrawScreenShadowGDI(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
999 static Bool
winRealizeInstalledPaletteShadowGDI(ScreenPtr pScreen)1000 winRealizeInstalledPaletteShadowGDI(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
1043 static Bool
winInstallColormapShadowGDI(ColormapPtr pColormap)1044 winInstallColormapShadowGDI(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
1096 static Bool
winStoreColorsShadowGDI(ColormapPtr pColormap,int ndef,xColorItem * pdefs)1097 winStoreColorsShadowGDI(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
1148 static Bool
winCreateColormapShadowGDI(ColormapPtr pColormap)1149 winCreateColormapShadowGDI(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
1202 static Bool
winDestroyColormapShadowGDI(ColormapPtr pColormap)1203 winDestroyColormapShadowGDI(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
1251 Bool
winSetEngineFunctionsShadowGDI(ScreenPtr pScreen)1252 winSetEngineFunctionsShadowGDI(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