summaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
Diffstat (limited to 'hw')
-rw-r--r--hw/xwin/man/XWin.man6
-rw-r--r--hw/xwin/win.h38
-rw-r--r--hw/xwin/winallpriv.c14
-rw-r--r--hw/xwin/winengine.c2
-rw-r--r--hw/xwin/winmultiwindowwindow.c4
-rw-r--r--hw/xwin/winmultiwindowwm.c46
-rw-r--r--hw/xwin/winmultiwindowwndproc.c42
-rw-r--r--hw/xwin/winprocarg.c11
-rw-r--r--hw/xwin/winscrinit.c9
-rw-r--r--hw/xwin/winshaddd.c6
-rw-r--r--hw/xwin/winshadddnl.c7
-rw-r--r--hw/xwin/winshadgdi.c194
-rw-r--r--hw/xwin/winwindow.h2
-rw-r--r--hw/xwin/winwndproc.c22
14 files changed, 264 insertions, 139 deletions
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 816b030ca..d73fc96cd 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 512d1a967..c3f4feda2 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 66b6d979f..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;
@@ -2053,7 +2088,7 @@ winApplyHints(WMInfoPtr pWMInfo, Window iWindow, HWND hWnd, HWND * zstyle, Bool
(unsigned char **) &pAtom) == Success) {
if (pAtom && nitems == 1) {
if (*pAtom == dockWindow) {
- hint = (hint & ~HINT_NOFRAME) | HINT_SIZEBOX; /* Xming puts a sizebox on dock windows */
+ hint = (hint & ~HINT_NOFRAME) | HINT_SKIPTASKBAR | HINT_SIZEBOX; /* Xming puts a sizebox on dock windows */
*zstyle = HWND_TOPMOST;
}
else if (*pAtom == splashWindow) {
@@ -2076,8 +2111,11 @@ winApplyHints(WMInfoPtr pWMInfo, Window iWindow, HWND hWnd, HWND * zstyle, Bool
if (!(hint & ~HINT_SKIPTASKBAR))
hint |= HINT_BORDER | HINT_SIZEBOX | HINT_CAPTION;
- /* Not maximizable if a maximum size is specified */
- hint |= HINT_NOMAXIMIZE;
+ /* Not maximizable if a maximum size is specified, and that size
+ is smaller (in either dimension) than the screen size */
+ if ((normal_hint->max_width < GetSystemMetrics(SM_CXVIRTUALSCREEN))
+ || (normal_hint->max_height < GetSystemMetrics(SM_CYVIRTUALSCREEN)))
+ hint |= HINT_NOMAXIMIZE;
if (normal_hint->flags & PMinSize) {
/*
diff --git a/hw/xwin/winmultiwindowwndproc.c b/hw/xwin/winmultiwindowwndproc.c
index 4123a80f6..29b3db875 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 95a3e2355..84df00d08 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 a8477aac8..fa94c8d21 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;