summaryrefslogtreecommitdiff
path: root/hw/xwin/winshadgdi.c
diff options
context:
space:
mode:
Diffstat (limited to 'hw/xwin/winshadgdi.c')
-rw-r--r--hw/xwin/winshadgdi.c194
1 files changed, 179 insertions, 15 deletions
diff --git a/hw/xwin/winshadgdi.c b/hw/xwin/winshadgdi.c
index bf655174d..797152f13 100644
--- a/hw/xwin/winshadgdi.c
+++ b/hw/xwin/winshadgdi.c
@@ -62,6 +62,9 @@ static Bool
winBltExposedRegionsShadowGDI(ScreenPtr pScreen);
static Bool
+ winBltExposedWindowRegionShadowGDI(ScreenPtr pScreen, WindowPtr pWin);
+
+static Bool
winActivateAppShadowGDI(ScreenPtr pScreen);
static Bool
@@ -760,6 +763,12 @@ winBltExposedRegionsShadowGDI(ScreenPtr pScreen)
/* BeginPaint gives us an hdc that clips to the invalidated region */
hdcUpdate = BeginPaint(pScreenPriv->hwndScreen, &ps);
+ /* Avoid the BitBlt if the PAINTSTRUCT region is bogus */
+ if (ps.rcPaint.right == 0 && ps.rcPaint.bottom == 0 &&
+ ps.rcPaint.left == 0 && ps.rcPaint.top == 0) {
+ EndPaint(pScreenPriv->hwndScreen, &ps);
+ return 0;
+ }
/* Realize the palette, if we have one */
if (pScreenPriv->pcmapInstalled != NULL) {
@@ -769,11 +778,30 @@ winBltExposedRegionsShadowGDI(ScreenPtr pScreen)
RealizePalette(hdcUpdate);
}
- /* Our BitBlt will be clipped to the invalidated region */
- BitBlt(hdcUpdate,
- 0, 0,
- pScreenInfo->dwWidth, pScreenInfo->dwHeight,
- pScreenPriv->hdcShadow, 0, 0, SRCCOPY);
+ /* Try to copy from the shadow buffer to the invalidated region */
+ if (!BitBlt(hdcUpdate,
+ ps.rcPaint.left, ps.rcPaint.top,
+ ps.rcPaint.right - ps.rcPaint.left,
+ ps.rcPaint.bottom - ps.rcPaint.top,
+ pScreenPriv->hdcShadow,
+ ps.rcPaint.left,
+ ps.rcPaint.top,
+ SRCCOPY)) {
+ LPVOID lpMsgBuf;
+
+ /* Display an error message */
+ FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FORMAT_MESSAGE_FROM_SYSTEM |
+ FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL,
+ GetLastError(),
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+ (LPTSTR) &lpMsgBuf, 0, NULL);
+
+ ErrorF("winBltExposedRegionsShadowGDI - BitBlt failed: %s\n",
+ (LPSTR) lpMsgBuf);
+ LocalFree(lpMsgBuf);
+ }
/* EndPaint frees the DC */
EndPaint(pScreenPriv->hwndScreen, &ps);
@@ -789,6 +817,149 @@ winBltExposedRegionsShadowGDI(ScreenPtr pScreen)
}
/*
+ * Blt exposed region to the given HWND
+ */
+
+static Bool
+winBltExposedWindowRegionShadowGDI(ScreenPtr pScreen, WindowPtr pWin)
+{
+ winScreenPriv(pScreen);
+ winPrivWinPtr pWinPriv = winGetWindowPriv(pWin);
+
+ HWND hWnd = pWinPriv->hWnd;
+ HDC hdcUpdate;
+ PAINTSTRUCT ps;
+
+ hdcUpdate = BeginPaint(hWnd, &ps);
+ /* Avoid the BitBlt if the PAINTSTRUCT region is bogus */
+ if (ps.rcPaint.right == 0 && ps.rcPaint.bottom == 0 &&
+ ps.rcPaint.left == 0 && ps.rcPaint.top == 0) {
+ EndPaint(hWnd, &ps);
+ return 0;
+ }
+
+#ifdef COMPOSITE
+ if (pWin->redirectDraw != RedirectDrawNone) {
+ HBITMAP hBitmap;
+ HDC hdcPixmap;
+ PixmapPtr pPixmap = (*pScreen->GetWindowPixmap) (pWin);
+
+ /*
+ This is kind of clunky, and possibly not very efficient.
+
+ Would it be more efficient to only create the DIB bitmap when the
+ composite bitmap is realloced and store it in a window private?
+
+ But we still end up copying and converting all the bits from the
+ window pixmap into a DDB for every update.
+
+ Perhaps better still would be to wrap the screen CreatePixmap routine
+ so it uses CreateDIBSection()?
+ */
+
+ BITMAPV4HEADER bmih;
+ memset(&bmih, sizeof(bmih), 0);
+ bmih.bV4Size = sizeof(BITMAPV4HEADER);
+ bmih.bV4Width = pPixmap->drawable.width;
+ bmih.bV4Height = -pPixmap->drawable.height; /* top-down bitmap */
+ bmih.bV4Planes = 1;
+ bmih.bV4BitCount = pPixmap->drawable.bitsPerPixel;
+ bmih.bV4SizeImage = 0;
+ /* window pixmap format is the same as the screen pixmap */
+ assert(pPixmap->drawable.bitsPerPixel > 8);
+ bmih.bV4V4Compression = BI_BITFIELDS;
+ bmih.bV4RedMask = pScreenPriv->dwRedMask;
+ bmih.bV4GreenMask = pScreenPriv->dwGreenMask;
+ bmih.bV4BlueMask = pScreenPriv->dwBlueMask;
+ bmih.bV4AlphaMask = 0;
+
+ /* Create the window bitmap from the pixmap */
+ hBitmap = CreateDIBitmap(pScreenPriv->hdcScreen,
+ (BITMAPINFOHEADER *)&bmih, CBM_INIT,
+ pPixmap->devPrivate.ptr, (BITMAPINFO *)&bmih,
+ DIB_RGB_COLORS);
+
+ /* Select the window bitmap into a screen-compatible DC */
+ hdcPixmap = CreateCompatibleDC(pScreenPriv->hdcScreen);
+ SelectObject(hdcPixmap, hBitmap);
+
+ /* Blt from the window bitmap to the invalidated region */
+ if (!BitBlt(hdcUpdate,
+ ps.rcPaint.left, ps.rcPaint.top,
+ ps.rcPaint.right - ps.rcPaint.left,
+ ps.rcPaint.bottom - ps.rcPaint.top,
+ hdcPixmap,
+ ps.rcPaint.left + pWin->borderWidth,
+ ps.rcPaint.top + pWin->borderWidth,
+ SRCCOPY))
+ ErrorF("winBltExposedWindowRegionShadowGDI - BitBlt failed: 0x%08x\n",
+ GetLastError());
+
+ /* Release */
+ DeleteDC(hdcPixmap);
+ DeleteObject(hBitmap);
+ }
+ else
+#endif
+ {
+ /* Try to copy from the shadow buffer to the invalidated region */
+ /* XXX: looks like those coordinates should get transformed ??? */
+ if (!BitBlt(hdcUpdate,
+ ps.rcPaint.left, ps.rcPaint.top,
+ ps.rcPaint.right - ps.rcPaint.left,
+ ps.rcPaint.bottom - ps.rcPaint.top,
+ pScreenPriv->hdcShadow,
+ ps.rcPaint.left + pWin->drawable.x,
+ ps.rcPaint.top + pWin->drawable.y,
+ SRCCOPY)) {
+ LPVOID lpMsgBuf;
+
+ /* Display an error message */
+ FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FORMAT_MESSAGE_FROM_SYSTEM |
+ FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL,
+ GetLastError(),
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+ (LPTSTR) &lpMsgBuf, 0, NULL);
+
+ ErrorF("winBltExposedWindowRegionShadowGDI - BitBlt failed: %s\n",
+ (LPSTR) lpMsgBuf);
+ LocalFree(lpMsgBuf);
+ }
+ }
+
+ /* If part of the invalidated region is outside the window (which can happen
+ if the native window is being re-sized), fill that area with black */
+ if (ps.rcPaint.right > ps.rcPaint.left + pWin->drawable.width) {
+ BitBlt(hdcUpdate,
+ ps.rcPaint.left + pWin->drawable.width,
+ ps.rcPaint.top,
+ ps.rcPaint.right - (ps.rcPaint.left + pWin->drawable.width),
+ ps.rcPaint.bottom - ps.rcPaint.top,
+ NULL,
+ 0, 0,
+ BLACKNESS);
+ }
+
+ if (ps.rcPaint.bottom > ps.rcPaint.top + pWin->drawable.height) {
+ BitBlt(hdcUpdate,
+ ps.rcPaint.left,
+ ps.rcPaint.top + pWin->drawable.height,
+ ps.rcPaint.right - ps.rcPaint.left,
+ ps.rcPaint.bottom - (ps.rcPaint.top + pWin->drawable.height),
+ NULL,
+ 0, 0,
+ BLACKNESS);
+ }
+
+ /* EndPaint frees the DC */
+ EndPaint(hWnd, &ps);
+
+ return TRUE;
+}
+
+/*
* Do any engine-specific appliation-activation processing
*/
@@ -1135,6 +1306,7 @@ winSetEngineFunctionsShadowGDI(ScreenPtr pScreen)
pScreenPriv->pwinCreateBoundingWindow = winCreateBoundingWindowWindowed;
pScreenPriv->pwinFinishScreenInit = winFinishScreenInitFB;
pScreenPriv->pwinBltExposedRegions = winBltExposedRegionsShadowGDI;
+ pScreenPriv->pwinBltExposedWindowRegion = winBltExposedWindowRegionShadowGDI;
pScreenPriv->pwinActivateApp = winActivateAppShadowGDI;
pScreenPriv->pwinRedrawScreen = winRedrawScreenShadowGDI;
pScreenPriv->pwinRealizeInstalledPalette =
@@ -1143,16 +1315,8 @@ winSetEngineFunctionsShadowGDI(ScreenPtr pScreen)
pScreenPriv->pwinStoreColors = winStoreColorsShadowGDI;
pScreenPriv->pwinCreateColormap = winCreateColormapShadowGDI;
pScreenPriv->pwinDestroyColormap = winDestroyColormapShadowGDI;
- pScreenPriv->pwinHotKeyAltTab =
- (winHotKeyAltTabProcPtr) (void (*)(void)) NoopDDA;
- pScreenPriv->pwinCreatePrimarySurface =
- (winCreatePrimarySurfaceProcPtr) (void (*)(void)) NoopDDA;
- pScreenPriv->pwinReleasePrimarySurface =
- (winReleasePrimarySurfaceProcPtr) (void (*)(void)) NoopDDA;
-#ifdef XWIN_MULTIWINDOW
- pScreenPriv->pwinFinishCreateWindowsWindow =
- (winFinishCreateWindowsWindowProcPtr) (void (*)(void)) NoopDDA;
-#endif
+ pScreenPriv->pwinCreatePrimarySurface = NULL;
+ pScreenPriv->pwinReleasePrimarySurface = NULL;
return TRUE;
}