[PATCH 2/2] composite: add panoramix support
Adam Jackson
ajax at redhat.com
Wed Nov 10 12:35:05 PST 2010
From: David Reveman <davidr at novell.com>
Taken from:
50d2d8c8969c165582d215c6e85c4be9eac02b6a
dbffd0d44a33dcc84898c7a891d7ba212f65cbb8
9b5b102163b4eaa1b70647354fcab4f6e461c94c
75f9b98af31abf537ac6616c99f3797deb7ba017
07fba8b1f77a6bca44ea6568b346a18ce9d1e61d
With minor style fixes, ported to dixLookupResourceByType, and ported
away from client->noClientException and xalloc/xfree.
v2: Fix a memory leak in PanoramiXCompositeNameWindowPixmap, spotted by
James Jones.
Signed-off-by: Adam Jackson <ajax at redhat.com>
---
Xext/panoramiX.c | 7 +
composite/compext.c | 361 ++++++++++++++++++++++++++++++++++++++++++++++-
composite/compint.h | 3 +
composite/compoverlay.c | 17 ++-
composite/compwindow.c | 22 +++-
configure.ac | 2 +-
6 files changed, 398 insertions(+), 14 deletions(-)
diff --git a/Xext/panoramiX.c b/Xext/panoramiX.c
index 5a395fc..e6334bd 100644
--- a/Xext/panoramiX.c
+++ b/Xext/panoramiX.c
@@ -56,6 +56,9 @@ Equipment Corporation.
#ifdef XFIXES
#include "xfixesint.h"
#endif
+#ifdef COMPOSITE
+#include "compint.h"
+#endif
#include "modinit.h"
#include "protocol-versions.h"
@@ -587,6 +590,10 @@ void PanoramiXExtensionInit(int argc, char *argv[])
#ifdef XFIXES
PanoramiXFixesInit ();
#endif
+#ifdef COMPOSITE
+ PanoramiXCompositeInit ();
+#endif
+
}
extern Bool CreateConnectionBlock(void);
diff --git a/composite/compext.c b/composite/compext.c
index 30d9dc2..f7205c8 100644
--- a/composite/compext.c
+++ b/composite/compext.c
@@ -535,13 +535,6 @@ CompositeExtensionInit (void)
if (GetPictureScreenIfSet(pScreen) == NULL)
return;
}
-#ifdef PANORAMIX
- /* Xinerama's rewriting of window drawing before Composite gets to it
- * breaks Composite.
- */
- if (!noPanoramiXExtension)
- return;
-#endif
CompositeClientWindowType = CreateNewResourceType
(FreeCompositeClientWindow, "CompositeClientWindow");
@@ -582,3 +575,357 @@ CompositeExtensionInit (void)
/* Initialization succeeded */
noCompositeExtension = FALSE;
}
+
+#ifdef PANORAMIX
+#include "panoramiXsrv.h"
+
+int (*PanoramiXSaveCompositeVector[CompositeNumberRequests]) (ClientPtr);
+
+static int
+PanoramiXCompositeRedirectWindow (ClientPtr client)
+{
+ PanoramiXRes *win;
+ int rc = 0, j;
+ REQUEST(xCompositeRedirectWindowReq);
+
+ REQUEST_SIZE_MATCH(xCompositeRedirectWindowReq);
+
+ if ((rc = dixLookupResourceByType((void **)&win, stuff->window, XRT_WINDOW,
+ client, DixUnknownAccess))) {
+ client->errorValue = stuff->window;
+ return (rc == BadValue) ? BadWindow : rc;
+ }
+
+ FOR_NSCREENS_FORWARD(j) {
+ stuff->window = win->info[j].id;
+ rc = (*PanoramiXSaveCompositeVector[stuff->compositeReqType]) (client);
+ if (rc != Success) break;
+ }
+
+ return rc;
+}
+
+static int
+PanoramiXCompositeRedirectSubwindows (ClientPtr client)
+{
+ PanoramiXRes *win;
+ int rc = 0, j;
+ REQUEST(xCompositeRedirectSubwindowsReq);
+
+ REQUEST_SIZE_MATCH(xCompositeRedirectSubwindowsReq);
+
+ if ((rc = dixLookupResourceByType((void **)&win, stuff->window, XRT_WINDOW,
+ client, DixUnknownAccess))) {
+ client->errorValue = stuff->window;
+ return (rc == BadValue) ? BadWindow : rc;
+ }
+
+ FOR_NSCREENS_FORWARD(j) {
+ stuff->window = win->info[j].id;
+ rc = (*PanoramiXSaveCompositeVector[stuff->compositeReqType]) (client);
+ if (rc != Success) break;
+ }
+
+ return rc;
+}
+
+static int
+PanoramiXCompositeUnredirectWindow (ClientPtr client)
+{
+ PanoramiXRes *win;
+ int rc = 0, j;
+ REQUEST(xCompositeUnredirectWindowReq);
+
+ REQUEST_SIZE_MATCH(xCompositeUnredirectWindowReq);
+
+ if ((rc = dixLookupResourceByType((void **)&win, stuff->window, XRT_WINDOW,
+ client, DixUnknownAccess))) {
+ client->errorValue = stuff->window;
+ return (rc == BadValue) ? BadWindow : rc;
+ }
+
+ FOR_NSCREENS_FORWARD(j) {
+ stuff->window = win->info[j].id;
+ rc = (*PanoramiXSaveCompositeVector[stuff->compositeReqType]) (client);
+ if (rc != Success) break;
+ }
+
+ return rc;
+}
+
+static int
+PanoramiXCompositeUnredirectSubwindows (ClientPtr client)
+{
+ PanoramiXRes *win;
+ int rc = 0, j;
+ REQUEST(xCompositeUnredirectSubwindowsReq);
+
+ REQUEST_SIZE_MATCH(xCompositeUnredirectSubwindowsReq);
+
+ if ((rc = dixLookupResourceByType((void **)&win, stuff->window, XRT_WINDOW,
+ client, DixUnknownAccess))) {
+ client->errorValue = stuff->window;
+ return (rc == BadValue) ? BadWindow : rc;
+ }
+
+ FOR_NSCREENS_FORWARD(j) {
+ rc = (*PanoramiXSaveCompositeVector[stuff->compositeReqType]) (client);
+ if (rc != Success) break;
+ }
+
+ return rc;
+}
+
+static int
+PanoramiXCompositeNameWindowPixmap (ClientPtr client)
+{
+ WindowPtr pWin;
+ CompWindowPtr cw;
+ PixmapPtr pPixmap;
+ int rc;
+ PanoramiXRes *win, *newPix;
+ int i;
+ REQUEST(xCompositeNameWindowPixmapReq);
+
+ REQUEST_SIZE_MATCH(xCompositeNameWindowPixmapReq);
+
+ if ((rc = dixLookupResourceByType((void **)&win, stuff->window, XRT_WINDOW,
+ client, DixUnknownAccess))) {
+ client->errorValue = stuff->window;
+ return (rc == BadValue) ? BadWindow : rc;
+ }
+
+ LEGAL_NEW_RESOURCE (stuff->pixmap, client);
+
+ if(!(newPix = malloc(sizeof(PanoramiXRes))))
+ return BadAlloc;
+
+ newPix->type = XRT_PIXMAP;
+ newPix->u.pix.shared = FALSE;
+ newPix->info[0].id = stuff->pixmap;
+
+ for (i = 1; i < PanoramiXNumScreens; i++)
+ newPix->info[i].id = FakeClientID (client->index);
+
+ FOR_NSCREENS(i) {
+ rc = dixLookupResourceByType ((void **) &pWin, win->info[i].id,
+ RT_WINDOW, client, DixGetAttrAccess);
+ if (rc != Success)
+ {
+ client->errorValue = stuff->window;
+ free (newPix);
+ return (rc == BadValue) ? BadWindow : rc;
+ }
+
+ if (!pWin->viewable)
+ {
+ free (newPix);
+ return BadMatch;
+ }
+
+ cw = GetCompWindow (pWin);
+ if (!cw)
+ {
+ free (newPix);
+ return BadMatch;
+ }
+
+ pPixmap = (*pWin->drawable.pScreen->GetWindowPixmap) (pWin);
+ if (!pPixmap)
+ {
+ free (newPix);
+ return BadMatch;
+ }
+
+ if (!AddResource (newPix->info[i].id, RT_PIXMAP,
+ (pointer) pPixmap))
+ return BadAlloc;
+
+ ++pPixmap->refcnt;
+ }
+
+ if (!AddResource (stuff->pixmap, XRT_PIXMAP, (pointer) newPix))
+ return BadAlloc;
+
+ return Success;
+}
+
+
+static int
+PanoramiXCompositeGetOverlayWindow (ClientPtr client)
+{
+ REQUEST(xCompositeGetOverlayWindowReq);
+ xCompositeGetOverlayWindowReply rep;
+ WindowPtr pWin;
+ ScreenPtr pScreen;
+ CompScreenPtr cs;
+ CompOverlayClientPtr pOc;
+ int rc;
+ PanoramiXRes *win, *overlayWin = NULL;
+ int i;
+
+ REQUEST_SIZE_MATCH(xCompositeGetOverlayWindowReq);
+
+ if ((rc = dixLookupResourceByType((void **)&win, stuff->window, XRT_WINDOW,
+ client, DixUnknownAccess))) {
+ client->errorValue = stuff->window;
+ return (rc == BadValue) ? BadWindow : rc;
+ }
+
+ cs = GetCompScreen(screenInfo.screens[0]);
+ if (!cs->pOverlayWin)
+ {
+ if(!(overlayWin = malloc(sizeof(PanoramiXRes))))
+ return BadAlloc;
+
+ overlayWin->type = XRT_WINDOW;
+ overlayWin->u.win.root = FALSE;
+ }
+
+ FOR_NSCREENS_BACKWARD(i) {
+ rc = dixLookupResourceByType((pointer *)&pWin, win->info[i].id,
+ RT_WINDOW, client, DixGetAttrAccess);
+ if (rc != Success)
+ {
+ client->errorValue = stuff->window;
+ return (rc == BadValue) ? BadWindow : rc;
+ }
+ pScreen = pWin->drawable.pScreen;
+
+ /*
+ * Create an OverlayClient structure to mark this client's
+ * interest in the overlay window
+ */
+ pOc = compCreateOverlayClient(pScreen, client);
+ if (pOc == NULL)
+ return BadAlloc;
+
+ /*
+ * Make sure the overlay window exists
+ */
+ cs = GetCompScreen(pScreen);
+ if (cs->pOverlayWin == NULL)
+ if (!compCreateOverlayWindow(pScreen))
+ {
+ FreeResource (pOc->resource, RT_NONE);
+ return BadAlloc;
+ }
+
+ rc = XaceHook(XACE_RESOURCE_ACCESS, client,
+ cs->pOverlayWin->drawable.id,
+ RT_WINDOW, cs->pOverlayWin, RT_NONE, NULL,
+ DixGetAttrAccess);
+ if (rc != Success)
+ {
+ FreeResource (pOc->resource, RT_NONE);
+ return rc;
+ }
+ }
+
+ if (overlayWin)
+ {
+ FOR_NSCREENS(i) {
+ cs = GetCompScreen(screenInfo.screens[i]);
+ overlayWin->info[i].id = cs->pOverlayWin->drawable.id;
+ }
+
+ AddResource(overlayWin->info[0].id, XRT_WINDOW, overlayWin);
+ }
+
+ cs = GetCompScreen(screenInfo.screens[0]);
+
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.length = 0;
+ rep.overlayWin = cs->pOverlayWin->drawable.id;
+
+ if (client->swapped)
+ {
+ int n;
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.length, n);
+ swapl(&rep.overlayWin, n);
+ }
+ (void) WriteToClient(client, sz_xCompositeGetOverlayWindowReply, (char *)&rep);
+
+ return Success;
+}
+
+static int
+PanoramiXCompositeReleaseOverlayWindow (ClientPtr client)
+{
+ REQUEST(xCompositeReleaseOverlayWindowReq);
+ WindowPtr pWin;
+ ScreenPtr pScreen;
+ CompOverlayClientPtr pOc;
+ PanoramiXRes *win;
+ int i, rc;
+
+ REQUEST_SIZE_MATCH(xCompositeReleaseOverlayWindowReq);
+
+ if ((rc = dixLookupResourceByType((void **)&win, stuff->window, XRT_WINDOW,
+ client, DixUnknownAccess))) {
+ client->errorValue = stuff->window;
+ return (rc == BadValue) ? BadWindow : rc;
+ }
+
+ FOR_NSCREENS_BACKWARD(i) {
+ if ((rc = dixLookupResourceByType((void **)&pWin, win->info[i].id,
+ XRT_WINDOW, client,
+ DixUnknownAccess))) {
+ client->errorValue = stuff->window;
+ return (rc == BadValue) ? BadWindow : rc;
+ }
+ pScreen = pWin->drawable.pScreen;
+
+ /*
+ * Has client queried a reference to the overlay window
+ * on this screen? If not, generate an error.
+ */
+ pOc = compFindOverlayClient (pWin->drawable.pScreen, client);
+ if (pOc == NULL)
+ return BadMatch;
+
+ /* The delete function will free the client structure */
+ FreeResource (pOc->resource, RT_NONE);
+ }
+
+ return Success;
+}
+
+void
+PanoramiXCompositeInit (void)
+{
+ int i;
+
+ for (i = 0; i < CompositeNumberRequests; i++)
+ PanoramiXSaveCompositeVector[i] = ProcCompositeVector[i];
+ /*
+ * Stuff in Xinerama aware request processing hooks
+ */
+ ProcCompositeVector[X_CompositeRedirectWindow] =
+ PanoramiXCompositeRedirectWindow;
+ ProcCompositeVector[X_CompositeRedirectSubwindows] =
+ PanoramiXCompositeRedirectSubwindows;
+ ProcCompositeVector[X_CompositeUnredirectWindow] =
+ PanoramiXCompositeUnredirectWindow;
+ ProcCompositeVector[X_CompositeUnredirectSubwindows] =
+ PanoramiXCompositeUnredirectSubwindows;
+ ProcCompositeVector[X_CompositeNameWindowPixmap] =
+ PanoramiXCompositeNameWindowPixmap;
+ ProcCompositeVector[X_CompositeGetOverlayWindow] =
+ PanoramiXCompositeGetOverlayWindow;
+ ProcCompositeVector[X_CompositeReleaseOverlayWindow] =
+ PanoramiXCompositeReleaseOverlayWindow;
+}
+
+void
+PanoramiXCompositeReset (void)
+{
+ int i;
+
+ for (i = 0; i < CompositeNumberRequests; i++)
+ ProcCompositeVector[i] = PanoramiXSaveCompositeVector[i];
+}
+
+#endif
diff --git a/composite/compint.h b/composite/compint.h
index 80083b0..ae41c44 100644
--- a/composite/compint.h
+++ b/composite/compint.h
@@ -326,4 +326,7 @@ int
compConfigNotify(WindowPtr pWin, int x, int y, int w, int h,
int bw, WindowPtr pSib);
+void PanoramiXCompositeInit (void);
+void PanoramiXCompositeReset (void);
+
#endif /* _COMPINT_H_ */
diff --git a/composite/compoverlay.c b/composite/compoverlay.c
index 67b566c..3bace79 100644
--- a/composite/compoverlay.c
+++ b/composite/compoverlay.c
@@ -48,6 +48,10 @@
#include "compint.h"
#include "xace.h"
+#ifdef PANORAMIX
+#include "panoramiXsrv.h"
+#endif
+
/*
* Delete the given overlay client list element from its screen list.
*/
@@ -128,10 +132,19 @@ compCreateOverlayWindow (ScreenPtr pScreen)
WindowPtr pWin;
XID attrs[] = { None, TRUE }; /* backPixmap, overrideRedirect */
int result;
+ int w = pScreen->width;
+ int h = pScreen->height;
+
+#ifdef PANORAMIX
+ if (!noPanoramiXExtension)
+ {
+ w = PanoramiXPixWidth;
+ h = PanoramiXPixHeight;
+ }
+#endif
pWin = cs->pOverlayWin =
- CreateWindow (cs->overlayWid, pRoot,
- 0, 0, pScreen->width, pScreen->height, 0,
+ CreateWindow (cs->overlayWid, pRoot, 0, 0, w, h, 0,
InputOutput, CWBackPixmap | CWOverrideRedirect, &attrs[0],
pRoot->drawable.depth,
serverClient, pScreen->rootVisual, &result);
diff --git a/composite/compwindow.c b/composite/compwindow.c
index 8849dc3..f80b5db 100644
--- a/composite/compwindow.c
+++ b/composite/compwindow.c
@@ -47,6 +47,10 @@
#include "compint.h"
+#ifdef PANORAMIX
+#include "panoramiXsrv.h"
+#endif
+
#ifdef COMPOSITE_DEBUG
static int
compCheckWindow (WindowPtr pWin, pointer data)
@@ -172,16 +176,26 @@ updateOverlayWindow(ScreenPtr pScreen)
CompScreenPtr cs;
WindowPtr pWin; /* overlay window */
XID vlist[2];
+ int w = pScreen->width;
+ int h = pScreen->height;
+
+#ifdef PANORAMIX
+ if (!noPanoramiXExtension)
+ {
+ w = PanoramiXPixWidth;
+ h = PanoramiXPixHeight;
+ }
+#endif
cs = GetCompScreen(pScreen);
if ((pWin = cs->pOverlayWin) != NULL) {
- if ((pWin->drawable.width == pScreen->width) &&
- (pWin->drawable.height == pScreen->height))
+ if ((pWin->drawable.width == w) &&
+ (pWin->drawable.height == h))
return Success;
/* Let's resize the overlay window. */
- vlist[0] = pScreen->width;
- vlist[1] = pScreen->height;
+ vlist[0] = w;
+ vlist[1] = h;
return ConfigureWindow(pWin, CWWidth | CWHeight, vlist, wClient(pWin));
}
diff --git a/configure.ac b/configure.ac
index e8f9473..b05f0c1 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1979,7 +1979,7 @@ if test "x$DMX" = xyes; then
fi
DMX_INCLUDES="$XEXT_INC $RENDER_INC $RECORD_INC"
XDMX_CFLAGS="$DMXMODULES_CFLAGS"
- XDMX_LIBS="$FB_LIB $MI_LIB $RENDER_LIB $RECORD_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $MIEXT_SHADOW_LIB $MIEXT_DAMAGE_LIB $XEXT_LIB $MAIN_LIB $DIX_LIB $OS_LIB $FIXES_LIB"
+ XDMX_LIBS="$FB_LIB $MI_LIB $RENDER_LIB $RECORD_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $MIEXT_SHADOW_LIB $MIEXT_DAMAGE_LIB $XEXT_LIB $COMPOSITE_LIB $DAMAGE_LIB $MAIN_LIB $DIX_LIB $CONFIG_LIB $OS_LIB $FIXES_LIB"
XDMX_SYS_LIBS="$DMXMODULES_LIBS"
AC_SUBST([XDMX_CFLAGS])
AC_SUBST([XDMX_LIBS])
--
1.7.2.3
More information about the xorg-devel
mailing list