diff options
author | Jon TURNEY <jon.turney@dronecode.org.uk> | 2015-08-11 16:13:57 +0100 |
---|---|---|
committer | Jon TURNEY <jon.turney@dronecode.org.uk> | 2015-08-11 16:51:16 +0100 |
commit | f626bf33ea5a04702b883508a52731721889bde6 (patch) | |
tree | 90a369c23e195173257a47ba522a539ff1b6cc80 | |
parent | e18c17fdb1ebab8a4c1171d37eee36fe603d0abc (diff) | |
parent | 53ac43f75c4a6f26e9045b7e8ff78203ed807446 (diff) |
Merge branch 'engine-enhancements' into cygwin-patches-for-1.17
-rw-r--r-- | configure.ac | 2 | ||||
-rw-r--r-- | hw/xwin/man/XWin.man | 6 | ||||
-rw-r--r-- | hw/xwin/win.h | 38 | ||||
-rw-r--r-- | hw/xwin/winallpriv.c | 14 | ||||
-rw-r--r-- | hw/xwin/winengine.c | 2 | ||||
-rw-r--r-- | hw/xwin/winmultiwindowwindow.c | 4 | ||||
-rw-r--r-- | hw/xwin/winmultiwindowwm.c | 37 | ||||
-rw-r--r-- | hw/xwin/winmultiwindowwndproc.c | 42 | ||||
-rw-r--r-- | hw/xwin/winprocarg.c | 11 | ||||
-rw-r--r-- | hw/xwin/winscrinit.c | 9 | ||||
-rw-r--r-- | hw/xwin/winshaddd.c | 6 | ||||
-rw-r--r-- | hw/xwin/winshadddnl.c | 7 | ||||
-rw-r--r-- | hw/xwin/winshadgdi.c | 194 | ||||
-rw-r--r-- | hw/xwin/winwindow.h | 2 | ||||
-rw-r--r-- | hw/xwin/winwndproc.c | 22 |
15 files changed, 259 insertions, 137 deletions
diff --git a/configure.ac b/configure.ac index 4083b447b..8d20e9c22 100644 --- a/configure.ac +++ b/configure.ac @@ -2158,7 +2158,7 @@ if test "x$XWIN" = xyes; then AC_DEFINE_UNQUOTED(__VENDORDWEBSUPPORT__, ["$VENDOR_WEB"], [Vendor web address for support]) AC_CHECK_TOOL(WINDRES, windres) - PKG_CHECK_MODULES([XWINMODULES],[x11 xdmcp xau xfixes x11-xcb xcb-image xcb-icccm]) + PKG_CHECK_MODULES([XWINMODULES],[x11 xdmcp xau xfixes x11-xcb xcb-image xcb-icccm xcomposite]) if test "x$WINDOWSWM" = xauto; then PKG_CHECK_EXISTS($WINDOWSWMPROTO, [WINDOWSWM=yes], [WINDOWSWM=no]) diff --git a/hw/xwin/man/XWin.man b/hw/xwin/man/XWin.man index 3a4173842..589b0815e 100644 --- a/hw/xwin/man/XWin.man +++ b/hw/xwin/man/XWin.man @@ -175,6 +175,12 @@ on its own is equivalent to \fB\-resize=randr\fP Add the host name to the window title for X applications which are running on remote hosts, when that information is available and it's useful to do so. The default is enabled. +.TP 8 +.B \-compositewm +Experimental. +Use Composite extension redirection to maintain a bitmap image of each top-level +X window, so window contents which are occluded show correctly in task bar and +task switcher previews. .SH OPTIONS CONTROLLING WINDOWS INTEGRATION .TP 8 diff --git a/hw/xwin/win.h b/hw/xwin/win.h index 86b4a3075..911415b8c 100644 --- a/hw/xwin/win.h +++ b/hw/xwin/win.h @@ -163,7 +163,6 @@ #include "mipointer.h" #include "X11/keysym.h" #include "micoord.h" -#include "dix.h" #include "miline.h" #include "shadow.h" #include "fb.h" @@ -273,6 +272,8 @@ typedef Bool (*winFinishScreenInitProcPtr) (int, ScreenPtr, int, char **); typedef Bool (*winBltExposedRegionsProcPtr) (ScreenPtr); +typedef Bool (*winBltExposedWindowRegionProcPtr) (ScreenPtr, WindowPtr); + typedef Bool (*winActivateAppProcPtr) (ScreenPtr); typedef Bool (*winRedrawScreenProcPtr) (ScreenPtr pScreen); @@ -288,38 +289,13 @@ typedef Bool (*winCreateColormapProcPtr) (ColormapPtr pColormap); typedef Bool (*winDestroyColormapProcPtr) (ColormapPtr pColormap); -typedef Bool (*winHotKeyAltTabProcPtr) (ScreenPtr); - typedef Bool (*winCreatePrimarySurfaceProcPtr) (ScreenPtr); typedef Bool (*winReleasePrimarySurfaceProcPtr) (ScreenPtr); -typedef Bool (*winFinishCreateWindowsWindowProcPtr) (WindowPtr pWin); - typedef Bool (*winCreateScreenResourcesProc) (ScreenPtr); /* - * GC (graphics context) privates - */ - -typedef struct { - HDC hdc; - HDC hdcMem; -} winPrivGCRec, *winPrivGCPtr; - -/* - * Pixmap privates - */ - -typedef struct { - HDC hdcSelected; - HBITMAP hBitmap; - BYTE *pbBits; - DWORD dwScanlineBytes; - BITMAPINFOHEADER *pbmih; -} winPrivPixmapRec, *winPrivPixmapPtr; - -/* * Colormap privates */ @@ -330,6 +306,7 @@ typedef struct { PALETTEENTRY peColors[WIN_NUM_PALETTE_ENTRIES]; } winPrivCmapRec, *winPrivCmapPtr; + /* * Windows Cursor handling. */ @@ -412,6 +389,7 @@ typedef struct { Bool fRootless; #ifdef XWIN_MULTIWINDOW Bool fMultiWindow; + Bool fCompositeWM; #endif #if defined(XWIN_MULTIWINDOW) || defined(XWIN_MULTIWINDOWEXTWM) Bool fMultiMonitorOverride; @@ -534,6 +512,7 @@ typedef struct _winPrivScreenRec { winCreateBoundingWindowProcPtr pwinCreateBoundingWindow; winFinishScreenInitProcPtr pwinFinishScreenInit; winBltExposedRegionsProcPtr pwinBltExposedRegions; + winBltExposedWindowRegionProcPtr pwinBltExposedWindowRegion; winActivateAppProcPtr pwinActivateApp; winRedrawScreenProcPtr pwinRedrawScreen; winRealizeInstalledPaletteProcPtr pwinRealizeInstalledPalette; @@ -541,17 +520,10 @@ typedef struct _winPrivScreenRec { winStoreColorsProcPtr pwinStoreColors; winCreateColormapProcPtr pwinCreateColormap; winDestroyColormapProcPtr pwinDestroyColormap; - winHotKeyAltTabProcPtr pwinHotKeyAltTab; winCreatePrimarySurfaceProcPtr pwinCreatePrimarySurface; winReleasePrimarySurfaceProcPtr pwinReleasePrimarySurface; - winCreateScreenResourcesProc pwinCreateScreenResources; -#ifdef XWIN_MULTIWINDOW - /* Window Procedures for MultiWindow mode */ - winFinishCreateWindowsWindowProcPtr pwinFinishCreateWindowsWindow; -#endif - /* Window Procedures for Rootless mode */ CreateWindowProcPtr CreateWindow; DestroyWindowProcPtr DestroyWindow; diff --git a/hw/xwin/winallpriv.c b/hw/xwin/winallpriv.c index 629af92c9..ff9827222 100644 --- a/hw/xwin/winallpriv.c +++ b/hw/xwin/winallpriv.c @@ -79,20 +79,6 @@ winAllocatePrivates(ScreenPtr pScreen) /* Save the screen private pointer */ winSetScreenPriv(pScreen, pScreenPriv); - /* Reserve GC memory for our privates */ - if (!dixRegisterPrivateKey - (g_iGCPrivateKey, PRIVATE_GC, sizeof(winPrivGCRec))) { - ErrorF("winAllocatePrivates - AllocateGCPrivate () failed\n"); - return FALSE; - } - - /* Reserve Pixmap memory for our privates */ - if (!dixRegisterPrivateKey - (g_iPixmapPrivateKey, PRIVATE_PIXMAP, sizeof(winPrivPixmapRec))) { - ErrorF("winAllocatePrivates - AllocatePixmapPrivates () failed\n"); - return FALSE; - } - /* Reserve Window memory for our privates */ if (!dixRegisterPrivateKey (g_iWindowPrivateKey, PRIVATE_WINDOW, sizeof(winPrivWinRec))) { diff --git a/hw/xwin/winengine.c b/hw/xwin/winengine.c index 296059e27..55dc0d079 100644 --- a/hw/xwin/winengine.c +++ b/hw/xwin/winengine.c @@ -223,7 +223,7 @@ winSetEngine(ScreenPtr pScreen) return TRUE; } - return TRUE; + return FALSE; } /* diff --git a/hw/xwin/winmultiwindowwindow.c b/hw/xwin/winmultiwindowwindow.c index ee8aadd2b..027cf6c67 100644 --- a/hw/xwin/winmultiwindowwindow.c +++ b/hw/xwin/winmultiwindowwindow.c @@ -550,7 +550,6 @@ winCreateWindowsTopLevelWindow(WindowPtr pWin) HWND hFore = NULL; winWindowPriv(pWin); - winPrivScreenPtr pScreenPriv = pWinPriv->pScreenPriv; WinXSizeHints hints; Window daddyId; DWORD dwStyle, dwExStyle; @@ -690,9 +689,6 @@ winCreateWindowsTopLevelWindow(WindowPtr pWin) /* Flag that this Windows window handles its own activation */ SetProp(hWnd, WIN_NEEDMANAGE_PROP, (HANDLE) 0); - - /* Call engine-specific create window procedure */ - (*pScreenPriv->pwinFinishCreateWindowsWindow) (pWin); } static void diff --git a/hw/xwin/winmultiwindowwm.c b/hw/xwin/winmultiwindowwm.c index e4d49565c..860df9ac9 100644 --- a/hw/xwin/winmultiwindowwm.c +++ b/hw/xwin/winmultiwindowwm.c @@ -65,6 +65,7 @@ #include <X11/Xproto.h> #include <X11/Xutil.h> #include <X11/cursorfont.h> +#include <X11/extensions/Xcomposite.h> #include <X11/Xwindows.h> /* Local headers */ @@ -145,6 +146,7 @@ typedef struct _WMInfo { Atom atmVertMaxState; Atom atmHorzMaxState; Bool fAllowOtherWM; + Bool fCompositeWM; } WMInfoRec, *WMInfoPtr; typedef struct _WMProcArgRec { @@ -1321,6 +1323,38 @@ winMultiWindowXMsgProc(void *pArg) atmWindowType = XInternAtom(pProcArg->pDisplay, "_NET_WM_WINDOW_TYPE", False); atmNormalHints = XInternAtom(pProcArg->pDisplay, "WM_NORMAL_HINTS", False); + /* + Enable Composite extension and redirect subwindows of the root window + */ + if (pProcArg->pWMInfo->fCompositeWM) + { + int composite_event_base, composite_error_base; + if (XCompositeQueryExtension(pProcArg->pDisplay, + &composite_event_base, + &composite_error_base)) + { + XCompositeRedirectSubwindows(pProcArg->pDisplay, + XRootWindow(pProcArg->pDisplay, + pProcArg->dwScreen), + CompositeRedirectAutomatic); + + /* + We use automatic updating of the root window for two + reasons: + + 1) redirected window contents are mirrored to the root + window so that the root window draws correctly when shown. + + 2) updating the root window causes damage against the + shadow framebuffer, which ultimately causes WM_PAINT to be + sent to the affected window(s) to cause the damage regions + to be redrawn. + */ + + ErrorF("Using Composite redirection\n"); + } + } + /* Loop until we explicitly break out */ while (1) { if (g_shutdown) @@ -1518,7 +1552,7 @@ winInitWM(void **ppWMInfo, pthread_t * ptWMProc, pthread_t * ptXMsgProc, pthread_mutex_t * ppmServerStarted, - int dwScreen, HWND hwndScreen, BOOL allowOtherWM) + int dwScreen, HWND hwndScreen, BOOL allowOtherWM, BOOL compositeWM) { WMProcArgPtr pArg = malloc(sizeof(WMProcArgRec)); WMInfoPtr pWMInfo = malloc(sizeof(WMInfoRec)); @@ -1541,6 +1575,7 @@ winInitWM(void **ppWMInfo, /* Set a return pointer to the Window Manager info structure */ *ppWMInfo = pWMInfo; pWMInfo->fAllowOtherWM = allowOtherWM; + pWMInfo->fCompositeWM = compositeWM; /* Setup the argument structure for the thread function */ pArg->dwScreen = dwScreen; diff --git a/hw/xwin/winmultiwindowwndproc.c b/hw/xwin/winmultiwindowwndproc.c index cebdcf7e8..9c2423a7a 100644 --- a/hw/xwin/winmultiwindowwndproc.c +++ b/hw/xwin/winmultiwindowwndproc.c @@ -328,7 +328,6 @@ LRESULT CALLBACK winTopLevelWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { POINT ptMouse; - HDC hdcUpdate; PAINTSTRUCT ps; WindowPtr pWin = NULL; winPrivWinPtr pWinPriv = NULL; @@ -483,18 +482,9 @@ winTopLevelWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) case WM_PAINT: /* Only paint if our window handle is valid */ - if (hwndScreen == NULL) + if (hwnd == NULL) break; - /* BeginPaint gives us an hdc that clips to the invalidated region */ - hdcUpdate = BeginPaint(hwnd, &ps); - /* Avoid the BitBlt's if the PAINTSTRUCT 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 XWIN_GLX_WINDOWS if (pWinPriv->fWglUsed) { /* @@ -504,36 +494,16 @@ winTopLevelWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) XXX: For now, just leave it alone, but ideally we want to send an expose event to the window so it really redraws the affected region... */ + BeginPaint(hwnd, &ps); ValidateRect(hwnd, &(ps.rcPaint)); + EndPaint(hwnd, &ps); } else #endif - /* Try to copy from the shadow buffer */ - if (!BitBlt(hdcUpdate, - ps.rcPaint.left, ps.rcPaint.top, - ps.rcPaint.right - ps.rcPaint.left, - ps.rcPaint.bottom - ps.rcPaint.top, - s_pScreenPriv->hdcShadow, - ps.rcPaint.left + pWin->drawable.x, - ps.rcPaint.top + pWin->drawable.y, SRCCOPY)) { - LPVOID lpMsgBuf; - - /* Display a fancy 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("winTopLevelWindowProc - BitBlt failed: %s\n", - (LPSTR) lpMsgBuf); - LocalFree(lpMsgBuf); - } + /* Call the engine dependent repainter */ + if (*s_pScreenPriv->pwinBltExposedWindowRegion) + (*s_pScreenPriv->pwinBltExposedWindowRegion) (s_pScreen, pWin); - /* EndPaint frees the DC */ - EndPaint(hwnd, &ps); return 0; case WM_MOUSEMOVE: diff --git a/hw/xwin/winprocarg.c b/hw/xwin/winprocarg.c index 475745f08..8deac9d8a 100644 --- a/hw/xwin/winprocarg.c +++ b/hw/xwin/winprocarg.c @@ -135,6 +135,7 @@ winInitializeScreenDefaults(void) defaultScreenInfo.fRootless = FALSE; #ifdef XWIN_MULTIWINDOW defaultScreenInfo.fMultiWindow = FALSE; + defaultScreenInfo.fCompositeWM = FALSE; #endif #if defined(XWIN_MULTIWINDOW) || defined(XWIN_MULTIWINDOWEXTWM) defaultScreenInfo.fMultiMonitorOverride = FALSE; @@ -618,6 +619,16 @@ ddxProcessArgument(int argc, char *argv[], int i) /* Indicate that we have processed this argument */ return 1; } + + /* + * Look for the '-compositewm' argument + */ + if (IS_OPTION("-compositewm")) { + screenInfoPtr->fCompositeWM = TRUE; + + /* Indicate that we have processed this argument */ + return 1; + } #endif /* diff --git a/hw/xwin/winscrinit.c b/hw/xwin/winscrinit.c index 31d5fdd36..8de95ec3b 100644 --- a/hw/xwin/winscrinit.c +++ b/hw/xwin/winscrinit.c @@ -541,6 +541,11 @@ winFinishScreenInitFB(int i, ScreenPtr pScreen, int argc, char **argv) || pScreenInfo->fInternalWM #endif ) { + if ((pScreenInfo->dwBPP == 8) && (pScreenInfo->fCompositeWM)) { + ErrorF("-compositewm disabled due to 8bpp depth\n"); + pScreenInfo->fCompositeWM = FALSE; + } + #if CYGDEBUG || YES winDebug("winFinishScreenInitFB - Calling winInitWM.\n"); #endif @@ -554,7 +559,9 @@ winFinishScreenInitFB(int i, ScreenPtr pScreen, int argc, char **argv) #ifdef XWIN_MULTIWINDOWEXTWM pScreenInfo->fInternalWM || #endif - FALSE)) { + FALSE, + pScreenInfo->fCompositeWM + )) { ErrorF("winFinishScreenInitFB - winInitWM () failed.\n"); return FALSE; } diff --git a/hw/xwin/winshaddd.c b/hw/xwin/winshaddd.c index 4904eb440..fd40fa680 100644 --- a/hw/xwin/winshaddd.c +++ b/hw/xwin/winshaddd.c @@ -1208,14 +1208,8 @@ winSetEngineFunctionsShadowDD(ScreenPtr pScreen) pScreenPriv->pwinStoreColors = winStoreColorsShadowDD; pScreenPriv->pwinCreateColormap = winCreateColormapShadowDD; pScreenPriv->pwinDestroyColormap = winDestroyColormapShadowDD; - pScreenPriv->pwinHotKeyAltTab = - (winHotKeyAltTabProcPtr) (void (*)(void)) NoopDDA; pScreenPriv->pwinCreatePrimarySurface = winCreatePrimarySurfaceShadowDD; pScreenPriv->pwinReleasePrimarySurface = winReleasePrimarySurfaceShadowDD; -#ifdef XWIN_MULTIWINDOW - pScreenPriv->pwinFinishCreateWindowsWindow = - (winFinishCreateWindowsWindowProcPtr) (void (*)(void)) NoopDDA; -#endif return TRUE; } diff --git a/hw/xwin/winshadddnl.c b/hw/xwin/winshadddnl.c index 48599b266..43e80358e 100644 --- a/hw/xwin/winshadddnl.c +++ b/hw/xwin/winshadddnl.c @@ -1200,6 +1200,7 @@ winSetEngineFunctionsShadowDDNL(ScreenPtr pScreen) pScreenPriv->pwinCreateBoundingWindow = winCreateBoundingWindowWindowed; pScreenPriv->pwinFinishScreenInit = winFinishScreenInitFB; pScreenPriv->pwinBltExposedRegions = winBltExposedRegionsShadowDDNL; + pScreenPriv->pwinBltExposedWindowRegion = NULL; pScreenPriv->pwinActivateApp = winActivateAppShadowDDNL; pScreenPriv->pwinRedrawScreen = winRedrawScreenShadowDDNL; pScreenPriv->pwinRealizeInstalledPalette @@ -1208,14 +1209,8 @@ winSetEngineFunctionsShadowDDNL(ScreenPtr pScreen) pScreenPriv->pwinStoreColors = winStoreColorsShadowDDNL; pScreenPriv->pwinCreateColormap = winCreateColormapShadowDDNL; pScreenPriv->pwinDestroyColormap = winDestroyColormapShadowDDNL; - pScreenPriv->pwinHotKeyAltTab = - (winHotKeyAltTabProcPtr) (void (*)(void)) NoopDDA; pScreenPriv->pwinCreatePrimarySurface = winCreatePrimarySurfaceShadowDDNL; pScreenPriv->pwinReleasePrimarySurface = winReleasePrimarySurfaceShadowDDNL; -#ifdef XWIN_MULTIWINDOW - pScreenPriv->pwinFinishCreateWindowsWindow - = (winFinishCreateWindowsWindowProcPtr) (void (*)(void)) NoopDDA; -#endif return TRUE; } diff --git a/hw/xwin/winshadgdi.c b/hw/xwin/winshadgdi.c index 3d222ad4b..5f06a448e 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; } diff --git a/hw/xwin/winwindow.h b/hw/xwin/winwindow.h index f27094f4d..e3e1fb972 100644 --- a/hw/xwin/winwindow.h +++ b/hw/xwin/winwindow.h @@ -144,7 +144,7 @@ winInitWM(void **ppWMInfo, pthread_t * ptWMProc, pthread_t * ptXMsgProc, pthread_mutex_t * ppmServerStarted, - int dwScreen, HWND hwndScreen, BOOL allowOtherWM); + int dwScreen, HWND hwndScreen, BOOL allowOtherWM, BOOL compositeWM); void winDeinitMultiWindowWM(void); diff --git a/hw/xwin/winwndproc.c b/hw/xwin/winwndproc.c index 999bea3c0..49be5a172 100644 --- a/hw/xwin/winwndproc.c +++ b/hw/xwin/winwndproc.c @@ -294,22 +294,16 @@ winWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) * the display dimensions change. */ - /* - * NOTE: The non-DirectDraw engines set the ReleasePrimarySurface - * and CreatePrimarySurface function pointers to point - * to the no operation function, NoopDDA. This allows us - * to blindly call these functions, even if they are not - * relevant to the current engine (e.g., Shadow GDI). - */ - winDebug ("winWindowProc - WM_DISPLAYCHANGE - Releasing and recreating primary surface\n"); /* Release the old primary surface */ - (*s_pScreenPriv->pwinReleasePrimarySurface) (s_pScreen); + if (*s_pScreenPriv->pwinReleasePrimarySurface) + (*s_pScreenPriv->pwinReleasePrimarySurface) (s_pScreen); /* Create the new primary surface */ - (*s_pScreenPriv->pwinCreatePrimarySurface) (s_pScreen); + if (*s_pScreenPriv->pwinCreatePrimarySurface) + (*s_pScreenPriv->pwinCreatePrimarySurface) (s_pScreen); } } @@ -1111,14 +1105,6 @@ winWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) winFixShiftKeys(iScanCode); return 0; - case WM_HOTKEY: - if (s_pScreenPriv == NULL) - break; - - /* Call the engine-specific hot key handler */ - (*s_pScreenPriv->pwinHotKeyAltTab) (s_pScreen); - return 0; - case WM_ACTIVATE: if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) break; |