[PATCH] [RFC] xinerama: attempt to unify the two protocol implementations.

Dave Airlie airlied at gmail.com
Mon Oct 25 21:46:08 PDT 2010


From: Dave Airlie <airlied at redhat.com>

randr and panoramiX have had two separate copies of this code for long enough,

this patch sets up a separate xinerama protocol that both randr and panoramix
call into to configure what is sent on the wire.

this needs a lot more testing and fair bit of review, but this is a first
cut to see if people agree with the idea.
---
 Xext/Makefile.am            |    3 +-
 Xext/panoramiX.c            |  253 +++------------------------
 Xext/panoramiXSwap.c        |  142 ---------------
 Xext/xinerama-protocol.c    |  404 +++++++++++++++++++++++++++++++++++++++++++
 include/xinerama-protocol.h |   36 ++++
 randr/randr.c               |    4 +-
 randr/randrstr.h            |    7 +-
 randr/rrcrtc.c              |   44 +++++
 randr/rrxinerama.c          |  387 +----------------------------------------
 9 files changed, 523 insertions(+), 757 deletions(-)
 delete mode 100644 Xext/panoramiXSwap.c
 create mode 100644 Xext/xinerama-protocol.c
 create mode 100644 include/xinerama-protocol.h

diff --git a/Xext/Makefile.am b/Xext/Makefile.am
index e444fd0..6e30751 100644
--- a/Xext/Makefile.am
+++ b/Xext/Makefile.am
@@ -28,6 +28,7 @@ BUILTIN_SRCS =			\
 	sync.c			\
 	syncsrv.h		\
 	xcmisc.c		\
+	xinerama-protocol.c     \
 	xtest.c
 
 # Sources always included in libXextmodule.la & libXext.la. That's right, zero.
@@ -61,7 +62,7 @@ MODULE_SRCS  += $(SCREENSAVER_SRCS)
 endif
 
 # Xinerama extension: making multiple video devices act as one virtual screen
-XINERAMA_SRCS = panoramiX.c panoramiX.h panoramiXh.h panoramiXsrv.h panoramiXprocs.c panoramiXSwap.c 
+XINERAMA_SRCS = panoramiX.c panoramiX.h panoramiXh.h panoramiXsrv.h panoramiXprocs.c
 if XINERAMA
 BUILTIN_SRCS += $(XINERAMA_SRCS)
 if XORG
diff --git a/Xext/panoramiX.c b/Xext/panoramiX.c
index b73c53f..d455e28 100644
--- a/Xext/panoramiX.c
+++ b/Xext/panoramiX.c
@@ -55,6 +55,7 @@ Equipment Corporation.
 #include "picturestr.h"
 #include "modinit.h"
 #include "protocol-versions.h"
+#include "xinerama-protocol.h"
 
 #ifdef GLXPROXY
 extern VisualPtr glxMatchVisual(ScreenPtr pScreen,
@@ -91,7 +92,6 @@ XineramaVisualsEqualProcPtr XineramaVisualsEqualPtr = &VisualsEqual;
  */
 
 static int panoramiXGeneration;
-static int ProcPanoramiXDispatch(ClientPtr client); 
 
 static void PanoramiXResetProc(ExtensionEntry*);
 
@@ -431,12 +431,10 @@ void XineramaReinitData(ScreenPtr pScreen)
  *		Register PanoramiXeen Extension
  *		Initialize global variables.
  */ 
-
 void PanoramiXExtensionInit(int argc, char *argv[])
 {
     int 	     	i;
     Bool	     	success = FALSE;
-    ExtensionEntry 	*extEntry;
     ScreenPtr		pScreen = screenInfo.screens[0];
     PanoramiXScreenPtr	pScreenPriv;
 
@@ -460,12 +458,14 @@ void PanoramiXExtensionInit(int argc, char *argv[])
     }
 
     while (panoramiXGeneration != serverGeneration) {
-	extEntry = AddExtension(PANORAMIX_PROTOCOL_NAME, 0,0, 
-				ProcPanoramiXDispatch,
-				SProcPanoramiXDispatch, PanoramiXResetProc, 
-				StandardMinorOpcode);
-	if (!extEntry)
-	    break;
+
+	if (XineramaProtoInit(PanoramiXResetProc)) {
+	    noPanoramiXExtension = TRUE;
+	    return;
+	}
+
+	if (PanoramiXExtensionDisabledHack)
+	    XineramaProtoDisable();
 
 	/*
 	 *	First make sure all the basic allocations succeed.  If not,
@@ -473,18 +473,28 @@ void PanoramiXExtensionInit(int argc, char *argv[])
 	 */
 
 	for (i = 0; i < PanoramiXNumScreens; i++) {
+	   xXineramaScreenInfo info;
+
 	   pScreen = screenInfo.screens[i];
+
+	   info.x_org = pScreen->x;
+	   info.y_org = pScreen->y;
+	   info.width = pScreen->width;
+	   info.height = pScreen->height;
+	   XineramaProtoRegisterScreen(i, &info, FALSE);
+
 	   pScreenPriv = malloc(sizeof(PanoramiXScreenRec));
 	   dixSetPrivate(&pScreen->devPrivates, PanoramiXScreenKey,
 			 pScreenPriv);
 	   if(!pScreenPriv) {
-		noPanoramiXExtension = TRUE;
-		return;
+	       XineramaProtoDisable();
+	       noPanoramiXExtension = TRUE;
+	       return;
 	   }
-	
+
 	   pScreenPriv->CreateGC = pScreen->CreateGC;
 	   pScreenPriv->CloseScreen = pScreen->CloseScreen;
-	
+
 	   pScreen->CreateGC = XineramaCreateGC;
 	   pScreen->CloseScreen = XineramaCloseScreen;
 	}
@@ -514,11 +524,12 @@ void PanoramiXExtensionInit(int argc, char *argv[])
     }
 
     if (!success) {
+	XineramaProtoDisable();
 	noPanoramiXExtension = TRUE;
 	ErrorF(PANORAMIX_PROTOCOL_NAME " extension failed to initialize\n");
 	return;
     }
-  
+
     XineramaInitData(pScreen);
 
     /*
@@ -887,220 +898,6 @@ static void PanoramiXResetProc(ExtensionEntry* extEntry)
 	ProcVector[i] = SavedProcVector[i];
 }
 
-
-int
-ProcPanoramiXQueryVersion (ClientPtr client)
-{
-    /* REQUEST(xPanoramiXQueryVersionReq); */
-    xPanoramiXQueryVersionReply		rep;
-    register 	int			n;
-
-    REQUEST_SIZE_MATCH (xPanoramiXQueryVersionReq);
-    rep.type = X_Reply;
-    rep.length = 0;
-    rep.sequenceNumber = client->sequence;
-    rep.majorVersion = SERVER_PANORAMIX_MAJOR_VERSION;
-    rep.minorVersion = SERVER_PANORAMIX_MINOR_VERSION;
-    if (client->swapped) { 
-        swaps(&rep.sequenceNumber, n);
-        swapl(&rep.length, n);     
-        swaps(&rep.majorVersion, n);
-        swaps(&rep.minorVersion, n);
-    }
-    WriteToClient(client, sizeof (xPanoramiXQueryVersionReply), (char *)&rep);
-    return Success;
-}
-
-int
-ProcPanoramiXGetState(ClientPtr client)
-{
-	REQUEST(xPanoramiXGetStateReq);
-    	WindowPtr			pWin;
-	xPanoramiXGetStateReply		rep;
-	int			n, rc;
-	
-	REQUEST_SIZE_MATCH(xPanoramiXGetStateReq);
-	rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess);
-	if (rc != Success)
-	    return rc;
-
-	rep.type = X_Reply;
-	rep.length = 0;
-	rep.sequenceNumber = client->sequence;
-	rep.state = !noPanoramiXExtension;
-	rep.window = stuff->window;
-    	if (client->swapped) {
-	    swaps (&rep.sequenceNumber, n);
-	    swapl (&rep.length, n);
-	    swapl (&rep.window, n);
-	}	
-	WriteToClient (client, sizeof (xPanoramiXGetStateReply), (char *) &rep);
-	return Success;
-
-}
-
-int 
-ProcPanoramiXGetScreenCount(ClientPtr client)
-{
-	REQUEST(xPanoramiXGetScreenCountReq);
-    	WindowPtr			pWin;
-	xPanoramiXGetScreenCountReply	rep;
-	int			n, rc;
-
-	REQUEST_SIZE_MATCH(xPanoramiXGetScreenCountReq);
-	rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess);
-	if (rc != Success)
-	    return rc;
-
-	rep.type = X_Reply;
-	rep.length = 0;
-	rep.sequenceNumber = client->sequence;
-	rep.ScreenCount = PanoramiXNumScreens;
-	rep.window = stuff->window;
-    	if (client->swapped) {
-	    swaps (&rep.sequenceNumber, n);
-	    swapl (&rep.length, n);
-	    swapl (&rep.window, n);
-	}	
-	WriteToClient (client, sizeof (xPanoramiXGetScreenCountReply), (char *) &rep);
-	return Success;
-}
-
-int 
-ProcPanoramiXGetScreenSize(ClientPtr client)
-{
-	REQUEST(xPanoramiXGetScreenSizeReq);
-    	WindowPtr			pWin;
-	xPanoramiXGetScreenSizeReply	rep;
-	int			n, rc;
-	
-	if (stuff->screen >= PanoramiXNumScreens)
-	    return BadMatch;
-
-	REQUEST_SIZE_MATCH(xPanoramiXGetScreenSizeReq);
-	rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess);
-	if (rc != Success)
-	    return rc;
-
-	rep.type = X_Reply;
-	rep.length = 0;
-	rep.sequenceNumber = client->sequence;
-		/* screen dimensions */
-	rep.width  = screenInfo.screens[stuff->screen]->width;
-	rep.height = screenInfo.screens[stuff->screen]->height;
-	rep.window = stuff->window;
-	rep.screen = stuff->screen;
-    	if (client->swapped) {
-	    swaps (&rep.sequenceNumber, n);
-	    swapl (&rep.length, n);
-	    swapl (&rep.width, n);
-	    swapl (&rep.height, n);
-	    swapl (&rep.window, n);
-	    swapl (&rep.screen, n);
-	}	
-	WriteToClient (client, sizeof (xPanoramiXGetScreenSizeReply), (char *) &rep);
-	return Success;
-}
-
-
-int
-ProcXineramaIsActive(ClientPtr client)
-{
-    /* REQUEST(xXineramaIsActiveReq); */
-    xXineramaIsActiveReply	rep;
-
-    REQUEST_SIZE_MATCH(xXineramaIsActiveReq);
-
-    rep.type = X_Reply;
-    rep.length = 0;
-    rep.sequenceNumber = client->sequence;
-#if 1
-    {
-	/* The following hack fools clients into thinking that Xinerama
-	 * is disabled even though it is not. */
-	rep.state = !noPanoramiXExtension && !PanoramiXExtensionDisabledHack;
-    }
-#else
-    rep.state = !noPanoramiXExtension;
-#endif
-    if (client->swapped) {
-	int n;
-	swaps (&rep.sequenceNumber, n);
-	swapl (&rep.length, n);
-	swapl (&rep.state, n);
-    }	
-    WriteToClient (client, sizeof (xXineramaIsActiveReply), (char *) &rep);
-    return Success;
-}
-
-
-int
-ProcXineramaQueryScreens(ClientPtr client)
-{
-    /* REQUEST(xXineramaQueryScreensReq); */
-    xXineramaQueryScreensReply	rep;
-
-    REQUEST_SIZE_MATCH(xXineramaQueryScreensReq);
-
-    rep.type = X_Reply;
-    rep.sequenceNumber = client->sequence;
-    rep.number = (noPanoramiXExtension) ? 0 : PanoramiXNumScreens;
-    rep.length = bytes_to_int32(rep.number * sz_XineramaScreenInfo);
-    if (client->swapped) {
-	int n;
-	swaps (&rep.sequenceNumber, n);
-	swapl (&rep.length, n);
-	swapl (&rep.number, n);
-    }	
-    WriteToClient (client, sizeof (xXineramaQueryScreensReply), (char *) &rep);
-
-    if(!noPanoramiXExtension) {
-	xXineramaScreenInfo scratch;
-	int i;
-
-	for(i = 0; i < PanoramiXNumScreens; i++) {
-	    scratch.x_org  = screenInfo.screens[i]->x;
-	    scratch.y_org  = screenInfo.screens[i]->y;
-	    scratch.width  = screenInfo.screens[i]->width;
-	    scratch.height = screenInfo.screens[i]->height;
-	
-	    if(client->swapped) {
-		int n;
-		swaps (&scratch.x_org, n);
-		swaps (&scratch.y_org, n);
-		swaps (&scratch.width, n);
-		swaps (&scratch.height, n);
-	    }
-	    WriteToClient (client, sz_XineramaScreenInfo, (char *) &scratch);
-	}
-    }
-
-    return Success;
-}
-
-
-static int
-ProcPanoramiXDispatch (ClientPtr client)
-{   REQUEST(xReq);
-    switch (stuff->data)
-    {
-	case X_PanoramiXQueryVersion:
-	     return ProcPanoramiXQueryVersion(client);
-	case X_PanoramiXGetState:
-	     return ProcPanoramiXGetState(client);
-	case X_PanoramiXGetScreenCount:
-	     return ProcPanoramiXGetScreenCount(client);
-	case X_PanoramiXGetScreenSize:
-	     return ProcPanoramiXGetScreenSize(client);
-	case X_XineramaIsActive:
-	     return ProcXineramaIsActive(client);
-	case X_XineramaQueryScreens:
-	     return ProcXineramaQueryScreens(client);
-    }
-    return BadRequest;
-}
-
-
 #if X_BYTE_ORDER == X_LITTLE_ENDIAN
 #define SHIFT_L(v,s) (v) << (s)
 #define SHIFT_R(v,s) (v) >> (s)
diff --git a/Xext/panoramiXSwap.c b/Xext/panoramiXSwap.c
deleted file mode 100644
index e1720c9..0000000
--- a/Xext/panoramiXSwap.c
+++ /dev/null
@@ -1,142 +0,0 @@
-/*****************************************************************
-Copyright (c) 1991, 1997 Digital Equipment Corporation, Maynard, Massachusetts.
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software.
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
-DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING,
-BUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL DAMAGES, OR OTHER LIABILITY,
-WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
-IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-Except as contained in this notice, the name of Digital Equipment Corporation
-shall not be used in advertising or otherwise to promote the sale, use or other
-dealings in this Software without prior written authorization from Digital
-Equipment Corporation.
-******************************************************************/
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include <stdio.h>
-#include <X11/X.h>
-#include <X11/Xproto.h>
-#include "misc.h"
-#include "cursor.h"
-#include "cursorstr.h"
-#include "extnsionst.h"
-#include "dixstruct.h"
-#include "gc.h"
-#include "gcstruct.h"
-#include "scrnintstr.h"
-#include "window.h"
-#include "windowstr.h"
-#include "pixmapstr.h"
-#include "panoramiX.h"
-#include <X11/extensions/panoramiXproto.h>
-#include "panoramiXsrv.h"
-#include "globals.h"
-#include "panoramiXh.h"
-
-static int
-SProcPanoramiXQueryVersion (ClientPtr client)
-{
-	REQUEST(xPanoramiXQueryVersionReq);
-	int n;
-
-	swaps(&stuff->length,n);
-	REQUEST_SIZE_MATCH (xPanoramiXQueryVersionReq);
-	return ProcPanoramiXQueryVersion(client);
-}
-
-static int
-SProcPanoramiXGetState(ClientPtr client)
-{
-	REQUEST(xPanoramiXGetStateReq);
-	int n;
-
- 	swaps (&stuff->length, n);	
-	REQUEST_SIZE_MATCH(xPanoramiXGetStateReq);
-	swapl (&stuff->window, n);
-	return ProcPanoramiXGetState(client);
-}
-
-static int 
-SProcPanoramiXGetScreenCount(ClientPtr client)
-{
-	REQUEST(xPanoramiXGetScreenCountReq);
-	int n;
-
-	swaps (&stuff->length, n);
-	REQUEST_SIZE_MATCH(xPanoramiXGetScreenCountReq);
-	swapl (&stuff->window, n);
-	return ProcPanoramiXGetScreenCount(client);
-}
-
-static int 
-SProcPanoramiXGetScreenSize(ClientPtr client)
-{
-	REQUEST(xPanoramiXGetScreenSizeReq);
-	int n;
-
-	swaps (&stuff->length, n);
-	REQUEST_SIZE_MATCH(xPanoramiXGetScreenSizeReq);
-	swapl (&stuff->window, n);
-	swapl (&stuff->screen, n);
-	return ProcPanoramiXGetScreenSize(client);
-}
-
-
-static int 
-SProcXineramaIsActive(ClientPtr client)
-{
-	REQUEST(xXineramaIsActiveReq);
-	int n;
-
-	swaps (&stuff->length, n);
-	REQUEST_SIZE_MATCH(xXineramaIsActiveReq);
-	return ProcXineramaIsActive(client);
-}
-
-
-static int 
-SProcXineramaQueryScreens(ClientPtr client)
-{
-	REQUEST(xXineramaQueryScreensReq);
-	int n;
-
-	swaps (&stuff->length, n);
-	REQUEST_SIZE_MATCH(xXineramaQueryScreensReq);
-	return ProcXineramaQueryScreens(client);
-}
-
-
-int
-SProcPanoramiXDispatch (ClientPtr client)
-{   REQUEST(xReq);
-    switch (stuff->data)
-    {
-	case X_PanoramiXQueryVersion:
-	     return SProcPanoramiXQueryVersion(client);
-	case X_PanoramiXGetState:
-	     return SProcPanoramiXGetState(client);
-	case X_PanoramiXGetScreenCount:
-	     return SProcPanoramiXGetScreenCount(client);
-	case X_PanoramiXGetScreenSize:
-	     return SProcPanoramiXGetScreenSize(client);
-	case X_XineramaIsActive:
-	     return SProcXineramaIsActive(client);
-	case X_XineramaQueryScreens:
-	     return SProcXineramaQueryScreens(client);
-    }
-    return BadRequest;
-}
diff --git a/Xext/xinerama-protocol.c b/Xext/xinerama-protocol.c
new file mode 100644
index 0000000..530aef8
--- /dev/null
+++ b/Xext/xinerama-protocol.c
@@ -0,0 +1,404 @@
+/*****************************************************************
+Copyright (c) 1991, 1997 Digital Equipment Corporation, Maynard, Massachusetts.
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING,
+BUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL DAMAGES, OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
+IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of Digital Equipment Corporation
+shall not be used in advertising or otherwise to promote the sale, use or other
+dealings in this Software without prior written authorization from Digital
+Equipment Corporation.
+******************************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+#ifdef HAVE_DMX_CONFIG_H
+#include <dmx-config.h>
+#endif
+#include <X11/X.h>
+#include <X11/Xproto.h>
+#include <X11/Xarch.h>
+#include "misc.h"
+#include "extnsionst.h"
+#include "dixstruct.h"
+#include "panoramiX.h"
+#include <X11/extensions/panoramiXproto.h>
+#include "panoramiXsrv.h"
+#include "protocol-versions.h"
+#include "xinerama-protocol.h"
+
+struct XineramaProtoRec {
+    int num_screens;
+    int ids[MAXSCREENS];
+    xXineramaScreenInfo info[MAXSCREENS];
+    Bool primary[MAXSCREENS];
+};
+
+static Bool xineramaProtoEnabled = FALSE;
+static struct XineramaProtoRec xineramaProto;
+
+static int
+ProcXineramaProtoQueryVersion (ClientPtr client)
+{
+    xPanoramiXQueryVersionReply		rep;
+    int					n;
+
+    REQUEST_SIZE_MATCH (xPanoramiXQueryVersionReq);
+
+    rep.type = X_Reply;
+    rep.length = 0;
+    rep.sequenceNumber = client->sequence;
+    rep.majorVersion = SERVER_PANORAMIX_MAJOR_VERSION;
+    rep.minorVersion = SERVER_PANORAMIX_MINOR_VERSION;
+    if (client->swapped) {
+        swaps(&rep.sequenceNumber, n);
+        swapl(&rep.length, n);
+        swaps(&rep.majorVersion, n);
+        swaps(&rep.minorVersion, n);
+    }
+    WriteToClient(client, sizeof(xPanoramiXQueryVersionReply), (char *)&rep);
+    return Success;
+}
+
+static int
+ProcXineramaProtoGetState(ClientPtr client)
+{
+    REQUEST(xPanoramiXGetStateReq);
+    WindowPtr			pWin;
+    xPanoramiXGetStateReply		rep;
+    int			n, rc;
+
+    REQUEST_SIZE_MATCH(xPanoramiXGetStateReq);
+    rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess);
+    if (rc != Success)
+	return rc;
+
+    rep.type = X_Reply;
+    rep.length = 0;
+    rep.sequenceNumber = client->sequence;
+    rep.state = xineramaProtoEnabled;
+    rep.window = stuff->window;
+    if (client->swapped) {
+	swaps (&rep.sequenceNumber, n);
+	swapl (&rep.length, n);
+	swapl (&rep.window, n);
+    }
+    WriteToClient (client, sizeof (xPanoramiXGetStateReply), (char *) &rep);
+    return Success;
+
+}
+
+static int
+ProcXineramaProtoGetScreenCount(ClientPtr client)
+{
+    REQUEST(xPanoramiXGetScreenCountReq);
+    WindowPtr                       pWin;
+    xPanoramiXGetScreenCountReply	rep;
+    int			n, rc;
+
+    REQUEST_SIZE_MATCH(xPanoramiXGetScreenCountReq);
+    rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess);
+    if (rc != Success)
+	return rc;
+
+    rep.type = X_Reply;
+    rep.length = 0;
+    rep.sequenceNumber = client->sequence;
+    rep.ScreenCount = xineramaProto.num_screens;
+    rep.window = stuff->window;
+    if (client->swapped) {
+	swaps (&rep.sequenceNumber, n);
+	swapl (&rep.length, n);
+	swapl (&rep.window, n);
+    }
+    WriteToClient (client, sizeof (xPanoramiXGetScreenCountReply), (char *) &rep);
+    return Success;
+}
+
+static int
+ProcXineramaProtoGetScreenSize(ClientPtr client)
+{
+    REQUEST(xPanoramiXGetScreenSizeReq);
+    WindowPtr			pWin;
+    xPanoramiXGetScreenSizeReply	rep;
+    int			n, rc;
+
+    if (stuff->screen > xineramaProto.num_screens)
+	return BadValue;
+
+    REQUEST_SIZE_MATCH(xPanoramiXGetScreenSizeReq);
+
+    rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess);
+    if (rc != Success)
+	return rc;
+
+    rep.type = X_Reply;
+    rep.length = 0;
+    rep.sequenceNumber = client->sequence;
+    /* screen dimensions */
+    rep.width  = xineramaProto.info[stuff->screen].width;
+    rep.height = xineramaProto.info[stuff->screen].height;
+    rep.window = stuff->window;
+    rep.screen = stuff->screen;
+    if (client->swapped) {
+	swaps (&rep.sequenceNumber, n);
+	swapl (&rep.length, n);
+	swapl (&rep.width, n);
+	swapl (&rep.height, n);
+	swapl (&rep.window, n);
+	swapl (&rep.screen, n);
+    }
+    WriteToClient (client, sizeof (xPanoramiXGetScreenSizeReply), (char *) &rep);
+    return Success;
+}
+
+static int
+ProcXineramaProtoIsActive(ClientPtr client)
+{
+    /* REQUEST(xXineramaIsActiveReq); */
+    xXineramaIsActiveReply	rep;
+
+    REQUEST_SIZE_MATCH(xXineramaIsActiveReq);
+
+    rep.type = X_Reply;
+    rep.length = 0;
+    rep.sequenceNumber = client->sequence;
+    rep.state = xineramaProtoEnabled;
+    if (client->swapped) {
+	int n;
+	swaps (&rep.sequenceNumber, n);
+	swapl (&rep.length, n);
+	swapl (&rep.state, n);
+    }
+    WriteToClient (client, sizeof (xXineramaIsActiveReply), (char *) &rep);
+    return Success;
+}
+
+static void WriteSingleInfo(ClientPtr client, xXineramaScreenInfo scratch)
+{
+    if(client->swapped) {
+	int n;
+	swaps (&scratch.x_org, n);
+	swaps (&scratch.y_org, n);
+	swaps (&scratch.width, n);
+	swaps (&scratch.height, n);
+    }
+    WriteToClient (client, sz_XineramaScreenInfo, (char *) &scratch);
+}
+
+static int
+ProcXineramaProtoQueryScreens(ClientPtr client)
+{
+    /* REQUEST(xXineramaQueryScreensReq); */
+    xXineramaQueryScreensReply	rep;
+    int num_screens;
+
+    REQUEST_SIZE_MATCH(xXineramaQueryScreensReq);
+
+    num_screens = xineramaProto.num_screens;
+
+    rep.type = X_Reply;
+    rep.sequenceNumber = client->sequence;
+    rep.number = num_screens;
+    rep.length = bytes_to_int32(rep.number * sz_XineramaScreenInfo);
+    if (client->swapped) {
+	int n;
+	swaps (&rep.sequenceNumber, n);
+	swapl (&rep.length, n);
+	swapl (&rep.number, n);
+    }
+    WriteToClient (client, sizeof (xXineramaQueryScreensReply), (char *) &rep);
+
+    if(rep.number) {
+	int i;
+
+	for(i = 0; i < num_screens; i++) {
+	    if (xineramaProto.primary[i])
+		WriteSingleInfo(client, xineramaProto.info[i]);
+	}
+	for(i = 0; i < num_screens; i++) {
+	    if (!xineramaProto.primary[i])
+		WriteSingleInfo(client, xineramaProto.info[i]);
+	}
+    }
+
+    return Success;
+}
+
+static int
+ProcXineramaProtoDispatch (ClientPtr client)
+{   REQUEST(xReq);
+    switch (stuff->data)
+    {
+	case X_PanoramiXQueryVersion:
+	     return ProcXineramaProtoQueryVersion(client);
+	case X_PanoramiXGetState:
+	     return ProcXineramaProtoGetState(client);
+	case X_PanoramiXGetScreenCount:
+	     return ProcXineramaProtoGetScreenCount(client);
+	case X_PanoramiXGetScreenSize:
+	     return ProcXineramaProtoGetScreenSize(client);
+	case X_XineramaIsActive:
+	     return ProcXineramaProtoIsActive(client);
+	case X_XineramaQueryScreens:
+	     return ProcXineramaProtoQueryScreens(client);
+    }
+    return BadRequest;
+}
+
+/* SProc */
+static int
+SProcXineramaProtoQueryVersion (ClientPtr client)
+{
+    REQUEST(xPanoramiXQueryVersionReq);
+    register int n;
+    swaps(&stuff->length,n);
+    REQUEST_SIZE_MATCH (xPanoramiXQueryVersionReq);
+    return ProcXineramaProtoQueryVersion(client);
+}
+
+static int
+SProcXineramaProtoGetState(ClientPtr client)
+{
+    REQUEST(xPanoramiXGetStateReq);
+    register int n;
+    swaps (&stuff->length, n);
+    REQUEST_SIZE_MATCH(xPanoramiXGetStateReq);
+    swapl (&stuff->window, n);
+    return ProcXineramaProtoGetState(client);
+}
+
+static int
+SProcXineramaProtoGetScreenCount(ClientPtr client)
+{
+    REQUEST(xPanoramiXGetScreenCountReq);
+    register int n;
+    swaps (&stuff->length, n);
+    REQUEST_SIZE_MATCH(xPanoramiXGetScreenCountReq);
+    swapl (&stuff->window, n);
+    return ProcXineramaProtoGetScreenCount(client);
+}
+
+static int
+SProcXineramaProtoGetScreenSize(ClientPtr client)
+{
+    REQUEST(xPanoramiXGetScreenSizeReq);
+    register int n;
+    swaps (&stuff->length, n);
+    REQUEST_SIZE_MATCH(xPanoramiXGetScreenSizeReq);
+    swapl (&stuff->window, n);
+    swapl (&stuff->screen, n);
+    return ProcXineramaProtoGetScreenSize(client);
+}
+
+static int
+SProcXineramaProtoIsActive(ClientPtr client)
+{
+    REQUEST(xXineramaIsActiveReq);
+    register int n;
+    swaps (&stuff->length, n);
+    REQUEST_SIZE_MATCH(xXineramaIsActiveReq);
+    return ProcXineramaProtoIsActive(client);
+}
+
+static int
+SProcXineramaProtoQueryScreens(ClientPtr client)
+{
+    REQUEST(xXineramaQueryScreensReq);
+    register int n;
+    swaps (&stuff->length, n);
+    REQUEST_SIZE_MATCH(xXineramaQueryScreensReq);
+    return ProcXineramaProtoQueryScreens(client);
+}
+
+static int
+SProcXineramaProtoDispatch(ClientPtr client)
+{
+    REQUEST(xReq);
+    switch (stuff->data) {
+	case X_PanoramiXQueryVersion:
+	     return SProcXineramaProtoQueryVersion(client);
+	case X_PanoramiXGetState:
+	     return SProcXineramaProtoGetState(client);
+	case X_PanoramiXGetScreenCount:
+	     return SProcXineramaProtoGetScreenCount(client);
+	case X_PanoramiXGetScreenSize:
+	     return SProcXineramaProtoGetScreenSize(client);
+	case X_XineramaIsActive:
+	     return SProcXineramaProtoIsActive(client);
+	case X_XineramaQueryScreens:
+	     return SProcXineramaProtoQueryScreens(client);
+    }
+    return BadRequest;
+}
+
+int XineramaProtoInit(void (*reset_proc)(ExtensionEntry *extEntry))
+{
+    ExtensionEntry 	*extEntry;
+
+    extEntry = AddExtension(PANORAMIX_PROTOCOL_NAME, 0, 0,
+			    ProcXineramaProtoDispatch,
+			    SProcXineramaProtoDispatch,
+			    reset_proc,
+			    StandardMinorOpcode);
+
+    if (!extEntry)
+	return -1;
+    xineramaProtoEnabled = TRUE;
+    return 0;
+}
+
+void XineramaProtoDisable(void)
+{
+    xineramaProtoEnabled = FALSE;
+}
+
+int XineramaProtoRegisterScreen(int id, xXineramaScreenInfo *info, Bool primary)
+{
+    int i, j;
+
+    if (info) {
+	for (i = 0; i < xineramaProto.num_screens; i++) {
+	    if (xineramaProto.ids[i] == id) {
+		xineramaProto.info[i] = *info;
+		xineramaProto.primary[i] = primary;
+		break;
+	    }
+	}
+	if (i == xineramaProto.num_screens) {
+	    xineramaProto.ids[i] = id;
+	    xineramaProto.info[i] = *info;
+	    xineramaProto.primary[i] = primary;
+	    xineramaProto.num_screens++;
+	}
+    } else {
+	for (i = 0; i < xineramaProto.num_screens; i++) {
+	    if (xineramaProto.ids[i] == id) {
+		break;
+	    }
+	}
+	if (i < xineramaProto.num_screens) {
+	    for (j = i; j < xineramaProto.num_screens - 1; j++) {
+		xineramaProto.ids[j] = xineramaProto.ids[j+1];
+		xineramaProto.info[j] = xineramaProto.info[j+1];
+		xineramaProto.primary[j] = xineramaProto.primary[j+1];
+	    }
+	    xineramaProto.num_screens--;
+	}
+    }
+    return 0;
+}
diff --git a/include/xinerama-protocol.h b/include/xinerama-protocol.h
new file mode 100644
index 0000000..5f06f33
--- /dev/null
+++ b/include/xinerama-protocol.h
@@ -0,0 +1,36 @@
+/*****************************************************************
+Copyright (c) 1991, 1997 Digital Equipment Corporation, Maynard, Massachusetts.
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING,
+BUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL DAMAGES, OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
+IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of Digital Equipment Corporation
+shall not be used in advertising or otherwise to promote the sale, use or other
+dealings in this Software without prior written authorization from Digital
+Equipment Corporation.
+******************************************************************/
+
+#ifndef XINERAMA_PROTOCOL_H
+#define XINERAMA_PROTOCOL_H
+
+#include <X11/extensions/panoramiXproto.h>
+
+int XineramaProtoInit(void (*reset_proc)(ExtensionEntry *extEntry));
+void XineramaProtoDisable(void);
+
+int XineramaProtoRegisterScreen(int id, xXineramaScreenInfo *info, Bool primary);
+
+#endif
diff --git a/randr/randr.c b/randr/randr.c
index 6077705..554abf8 100644
--- a/randr/randr.c
+++ b/randr/randr.c
@@ -431,8 +431,10 @@ RRTellChanged (ScreenPtr pScreen)
 	WalkTree (pScreen, TellChanged, (pointer) pScreen);
 	for (i = 0; i < pScrPriv->numOutputs; i++)
 	    pScrPriv->outputs[i]->changed = FALSE;
-	for (i = 0; i < pScrPriv->numCrtcs; i++)
+	for (i = 0; i < pScrPriv->numCrtcs; i++) {
+	    RRCrtcUpdateXinerama(pScrPriv->crtcs[i]);
 	    pScrPriv->crtcs[i]->changed = FALSE;
+	}
 	if (pScrPriv->layoutChanged)
 	{
 	    pScrPriv->layoutChanged = FALSE;
diff --git a/randr/randrstr.h b/randr/randrstr.h
index 7ea6080..2bdb31f 100644
--- a/randr/randrstr.h
+++ b/randr/randrstr.h
@@ -50,6 +50,7 @@
 #include <X11/extensions/render.h> 	/* we share subpixel order information */
 #include "picturestr.h"
 #include <X11/Xfuncproto.h>
+#include "xinerama-protocol.h"
 
 /* required for ABI compatibility for now */
 #define RANDR_10_INTERFACE 1
@@ -125,6 +126,7 @@ struct _rrCrtc {
     PictTransform   transform;
     struct pict_f_transform f_transform;
     struct pict_f_transform f_inverse;
+    xXineramaScreenInfo info;
 };
 
 struct _rrOutput {
@@ -549,7 +551,10 @@ RRCrtcNotify (RRCrtcPtr	    crtc,
 
 extern _X_EXPORT void
 RRDeliverCrtcEvent (ClientPtr client, WindowPtr pWin, RRCrtcPtr crtc);
-    
+
+/* update the Xinerama info for the CRTC */
+extern _X_EXPORT void RRCrtcUpdateXinerama(RRCrtcPtr crtc);
+
 /*
  * Request that the Crtc be reconfigured
  */
diff --git a/randr/rrcrtc.c b/randr/rrcrtc.c
index 98206a2..4f083d4 100644
--- a/randr/rrcrtc.c
+++ b/randr/rrcrtc.c
@@ -25,6 +25,47 @@
 
 RESTYPE	RRCrtcType;
 
+void RRCrtcUpdateXinerama(RRCrtcPtr crtc)
+{
+    ScreenPtr	pScreen = crtc->pScreen;
+    Bool enabled, primary = FALSE, panned = FALSE;
+    BoxRec panned_area;
+
+    rrScrPriv(pScreen);
+
+    enabled = (crtc->mode != NULL && crtc->numOutputs > 0);
+
+    if (pScrPriv) {
+	if (pScrPriv->primaryOutput && pScrPriv->primaryOutput->crtc == crtc)
+	    primary = TRUE;
+	if (pScrPriv->rrGetPanning &&
+	    pScrPriv->rrGetPanning (pScreen, crtc, &panned_area, NULL, NULL) &&
+	    (panned_area.x2 > panned_area.x1) && (panned_area.y2 > panned_area.y1)) {
+	    crtc->info.x_org = panned_area.x1;
+	    crtc->info.y_org = panned_area.y1;
+	    crtc->info.width = panned_area.x2 - panned_area.x1;
+	    crtc->info.height = panned_area.y2 - panned_area.y1;
+	    panned = TRUE;
+	}
+    }
+
+    if (!panned) {
+	crtc->info.x_org = crtc->x;
+	crtc->info.y_org = crtc->y;
+	if (crtc->mode) {
+	    crtc->info.width = crtc->mode->mode.width;
+	    crtc->info.height = crtc->mode->mode.height;
+	} else {
+	    crtc->info.width = 0;
+	    crtc->info.height = 0;
+	}
+    }
+
+    if (enabled)
+	XineramaProtoRegisterScreen(crtc->id, &crtc->info, primary);
+    else
+	XineramaProtoRegisterScreen(crtc->id, NULL, FALSE);
+}
 /*
  * Notify the CRTC of some change
  */
@@ -1095,6 +1136,9 @@ ProcRRSetPanning (ClientPtr client)
 
     pScrPriv->lastSetTime = time;
 
+    /* update the xinerama panning info */
+    RRCrtcUpdateXinerama(crtc);
+
     rep.status = RRSetConfigSuccess;
 
 sendReply:
diff --git a/randr/rrxinerama.c b/randr/rrxinerama.c
index c1bd5bb..32a7128 100644
--- a/randr/rrxinerama.c
+++ b/randr/rrxinerama.c
@@ -72,385 +72,7 @@
 #include "swaprep.h"
 #include <X11/extensions/panoramiXproto.h>
 #include "protocol-versions.h"
-
-/* Xinerama is not multi-screen capable; just report about screen 0 */
-#define RR_XINERAMA_SCREEN  0
-
-static int ProcRRXineramaQueryVersion(ClientPtr client);
-static int ProcRRXineramaGetState(ClientPtr client);
-static int ProcRRXineramaGetScreenCount(ClientPtr client);
-static int ProcRRXineramaGetScreenSize(ClientPtr client);
-static int ProcRRXineramaIsActive(ClientPtr client);
-static int ProcRRXineramaQueryScreens(ClientPtr client);
-static int SProcRRXineramaDispatch(ClientPtr client);
-
-/* Proc */
-
-int
-ProcRRXineramaQueryVersion(ClientPtr client)
-{
-    xPanoramiXQueryVersionReply	  rep;
-    register int		  n;
-
-    REQUEST_SIZE_MATCH(xPanoramiXQueryVersionReq);
-    rep.type = X_Reply;
-    rep.length = 0;
-    rep.sequenceNumber = client->sequence;
-    rep.majorVersion = SERVER_RRXINERAMA_MAJOR_VERSION;
-    rep.minorVersion = SERVER_RRXINERAMA_MINOR_VERSION;
-    if(client->swapped) {
-        swaps(&rep.sequenceNumber, n);
-        swapl(&rep.length, n);
-        swaps(&rep.majorVersion, n);
-        swaps(&rep.minorVersion, n);
-    }
-    WriteToClient(client, sizeof(xPanoramiXQueryVersionReply), (char *)&rep);
-    return Success;
-}
-
-int
-ProcRRXineramaGetState(ClientPtr client)
-{
-    REQUEST(xPanoramiXGetStateReq);
-    WindowPtr			pWin;
-    xPanoramiXGetStateReply	rep;
-    register int		n, rc;
-    ScreenPtr			pScreen;
-    rrScrPrivPtr		pScrPriv;
-    Bool			active = FALSE;
-
-    REQUEST_SIZE_MATCH(xPanoramiXGetStateReq);
-    rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess);
-    if(rc != Success)
-	return rc;
-
-    pScreen = pWin->drawable.pScreen;
-    pScrPriv = rrGetScrPriv(pScreen);
-    if (pScrPriv)
-    {
-	/* XXX do we need more than this? */
-	active = TRUE;
-    }
-
-    rep.type = X_Reply;
-    rep.length = 0;
-    rep.sequenceNumber = client->sequence;
-    rep.state = active;
-    rep.window = stuff->window;
-    if(client->swapped) {
-       swaps (&rep.sequenceNumber, n);
-       swapl (&rep.length, n);
-       swapl (&rep.window, n);
-    }
-    WriteToClient(client, sizeof(xPanoramiXGetStateReply), (char *)&rep);
-    return Success;
-}
-
-static Bool
-RRXineramaCrtcActive (RRCrtcPtr crtc)
-{
-    return crtc->mode != NULL && crtc->numOutputs > 0;
-}
-
-static int
-RRXineramaScreenCount (ScreenPtr pScreen)
-{
-    int	i, n;
-    
-    n = 0;
-    if (rrGetScrPriv (pScreen))
-    {
-	rrScrPriv(pScreen);
-	for (i = 0; i < pScrPriv->numCrtcs; i++)
-	    if (RRXineramaCrtcActive (pScrPriv->crtcs[i]))
-		n++;
-    }
-    return n;
-}
-
-static Bool
-RRXineramaScreenActive (ScreenPtr pScreen)
-{
-    return RRXineramaScreenCount (pScreen) > 0;
-}
-
-int
-ProcRRXineramaGetScreenCount(ClientPtr client)
-{
-    REQUEST(xPanoramiXGetScreenCountReq);
-    WindowPtr				pWin;
-    xPanoramiXGetScreenCountReply	rep;
-    register int			n, rc;
-
-    REQUEST_SIZE_MATCH(xPanoramiXGetScreenCountReq);
-    rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess);
-    if (rc != Success)
-	return rc;
-    
-    rep.type = X_Reply;
-    rep.length = 0;
-    rep.sequenceNumber = client->sequence;
-    rep.ScreenCount = RRXineramaScreenCount (pWin->drawable.pScreen);
-    rep.window = stuff->window;
-    if(client->swapped) {
-       swaps(&rep.sequenceNumber, n);
-       swapl(&rep.length, n);
-       swapl(&rep.window, n);
-    }
-    WriteToClient(client, sizeof(xPanoramiXGetScreenCountReply), (char *)&rep);
-    return Success;
-}
-
-int
-ProcRRXineramaGetScreenSize(ClientPtr client)
-{
-    REQUEST(xPanoramiXGetScreenSizeReq);
-    WindowPtr				pWin, pRoot;
-    ScreenPtr				pScreen;
-    xPanoramiXGetScreenSizeReply	rep;
-    register int			n, rc;
-
-    REQUEST_SIZE_MATCH(xPanoramiXGetScreenSizeReq);
-    rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess);
-    if (rc != Success)
-	return rc;
-
-    pScreen = pWin->drawable.pScreen;
-    pRoot = pScreen->root;
-    
-    rep.type = X_Reply;
-    rep.length = 0;
-    rep.sequenceNumber = client->sequence;
-    rep.width  = pRoot->drawable.width;
-    rep.height = pRoot->drawable.height;
-    rep.window = stuff->window;
-    rep.screen = stuff->screen;
-    if(client->swapped) {
-       swaps(&rep.sequenceNumber, n);
-       swapl(&rep.length, n);
-       swapl(&rep.width, n);
-       swapl(&rep.height, n);
-       swapl(&rep.window, n);
-       swapl(&rep.screen, n);
-    }
-    WriteToClient(client, sizeof(xPanoramiXGetScreenSizeReply), (char *)&rep);
-    return Success;
-}
-
-int
-ProcRRXineramaIsActive(ClientPtr client)
-{
-    xXineramaIsActiveReply	rep;
-
-    REQUEST_SIZE_MATCH(xXineramaIsActiveReq);
-
-    memset(&rep, 0, sizeof(xXineramaIsActiveReply));
-    rep.type = X_Reply;
-    rep.length = 0;
-    rep.sequenceNumber = client->sequence;
-    rep.state = RRXineramaScreenActive (screenInfo.screens[RR_XINERAMA_SCREEN]);
-    if(client->swapped) {
-	register int n;
-	swaps(&rep.sequenceNumber, n);
-	swapl(&rep.length, n);
-	swapl(&rep.state, n);
-    }
-    WriteToClient(client, sizeof(xXineramaIsActiveReply), (char *) &rep);
-    return Success;
-}
-
-static void
-RRXineramaWriteCrtc(ClientPtr client, RRCrtcPtr crtc)
-{
-    xXineramaScreenInfo scratch;
-
-    if (RRXineramaCrtcActive (crtc))
-    {
-	ScreenPtr pScreen = crtc->pScreen;
-	rrScrPrivPtr pScrPriv = rrGetScrPriv(pScreen);
-	BoxRec panned_area;
-
-	/* Check to see if crtc is panned and return the full area when applicable. */
-	if (pScrPriv && pScrPriv->rrGetPanning &&
-	    pScrPriv->rrGetPanning (pScreen, crtc, &panned_area, NULL, NULL) &&
-	    (panned_area.x2 > panned_area.x1) && (panned_area.y2 > panned_area.y1)) {
-	    scratch.x_org  = panned_area.x1;
-	    scratch.y_org  = panned_area.y1;
-	    scratch.width  = panned_area.x2  - panned_area.x1;
-	    scratch.height = panned_area.y2  - panned_area.y1;
-	} else {
-	    int width, height;
-	    RRCrtcGetScanoutSize (crtc, &width, &height);
-	    scratch.x_org  = crtc->x;
-	    scratch.y_org  = crtc->y;
-	    scratch.width  = width;
-	    scratch.height = height;
-	}
-	if(client->swapped) {
-	    register int n;
-	    swaps(&scratch.x_org, n);
-	    swaps(&scratch.y_org, n);
-	    swaps(&scratch.width, n);
-	    swaps(&scratch.height, n);
-	}
-	WriteToClient(client, sz_XineramaScreenInfo, &scratch);
-    }
-}
-
-int
-ProcRRXineramaQueryScreens(ClientPtr client)
-{
-    xXineramaQueryScreensReply	rep;
-    ScreenPtr	pScreen = screenInfo.screens[RR_XINERAMA_SCREEN];
-
-    REQUEST_SIZE_MATCH(xXineramaQueryScreensReq);
-
-    if (RRXineramaScreenActive (pScreen))
-	RRGetInfo (pScreen, FALSE);
-
-    rep.type = X_Reply;
-    rep.sequenceNumber = client->sequence;
-    rep.number = RRXineramaScreenCount (pScreen);
-    rep.length = bytes_to_int32(rep.number * sz_XineramaScreenInfo);
-    if(client->swapped) {
-	register int n;
-	swaps(&rep.sequenceNumber, n);
-	swapl(&rep.length, n);
-	swapl(&rep.number, n);
-    }
-    WriteToClient(client, sizeof(xXineramaQueryScreensReply), (char *)&rep);
-
-    if(rep.number) {
-	rrScrPriv(pScreen);
-	int i;
-	int has_primary = 0;
-
-	if (pScrPriv->primaryOutput && pScrPriv->primaryOutput->crtc) {
-	    has_primary = 1;
-	    RRXineramaWriteCrtc(client, pScrPriv->primaryOutput->crtc);
-	}
-
-	for(i = 0; i < pScrPriv->numCrtcs; i++) {
-	    if (has_primary &&
-		pScrPriv->primaryOutput->crtc == pScrPriv->crtcs[i])
-	    {
-		has_primary = 0;
-		continue;
-	    }
-	    RRXineramaWriteCrtc(client, pScrPriv->crtcs[i]);
-	}
-    }
-
-    return Success;
-}
-
-static int
-ProcRRXineramaDispatch(ClientPtr client)
-{
-    REQUEST(xReq);
-    switch (stuff->data) {
-	case X_PanoramiXQueryVersion:
-	     return ProcRRXineramaQueryVersion(client);
-	case X_PanoramiXGetState:
-	     return ProcRRXineramaGetState(client);
-	case X_PanoramiXGetScreenCount:
-	     return ProcRRXineramaGetScreenCount(client);
-	case X_PanoramiXGetScreenSize:
-	     return ProcRRXineramaGetScreenSize(client);
-	case X_XineramaIsActive:
-	     return ProcRRXineramaIsActive(client);
-	case X_XineramaQueryScreens:
-	     return ProcRRXineramaQueryScreens(client);
-    }
-    return BadRequest;
-}
-
-/* SProc */
-
-static int
-SProcRRXineramaQueryVersion (ClientPtr client)
-{
-    REQUEST(xPanoramiXQueryVersionReq);
-    register int n;
-    swaps(&stuff->length,n);
-    REQUEST_SIZE_MATCH (xPanoramiXQueryVersionReq);
-    return ProcRRXineramaQueryVersion(client);
-}
-
-static int
-SProcRRXineramaGetState(ClientPtr client)
-{
-    REQUEST(xPanoramiXGetStateReq);
-    register int n;
-    swaps (&stuff->length, n);
-    REQUEST_SIZE_MATCH(xPanoramiXGetStateReq);
-    swapl (&stuff->window, n);
-    return ProcRRXineramaGetState(client);
-}
-
-static int
-SProcRRXineramaGetScreenCount(ClientPtr client)
-{
-    REQUEST(xPanoramiXGetScreenCountReq);
-    register int n;
-    swaps (&stuff->length, n);
-    REQUEST_SIZE_MATCH(xPanoramiXGetScreenCountReq);
-    swapl (&stuff->window, n);
-    return ProcRRXineramaGetScreenCount(client);
-}
-
-static int
-SProcRRXineramaGetScreenSize(ClientPtr client)
-{
-    REQUEST(xPanoramiXGetScreenSizeReq);
-    register int n;
-    swaps (&stuff->length, n);
-    REQUEST_SIZE_MATCH(xPanoramiXGetScreenSizeReq);
-    swapl (&stuff->window, n);
-    swapl (&stuff->screen, n);
-    return ProcRRXineramaGetScreenSize(client);
-}
-
-static int
-SProcRRXineramaIsActive(ClientPtr client)
-{
-    REQUEST(xXineramaIsActiveReq);
-    register int n;
-    swaps (&stuff->length, n);
-    REQUEST_SIZE_MATCH(xXineramaIsActiveReq);
-    return ProcRRXineramaIsActive(client);
-}
-
-static int
-SProcRRXineramaQueryScreens(ClientPtr client)
-{
-    REQUEST(xXineramaQueryScreensReq);
-    register int n;
-    swaps (&stuff->length, n);
-    REQUEST_SIZE_MATCH(xXineramaQueryScreensReq);
-    return ProcRRXineramaQueryScreens(client);
-}
-
-int
-SProcRRXineramaDispatch(ClientPtr client)
-{
-    REQUEST(xReq);
-    switch (stuff->data) {
-	case X_PanoramiXQueryVersion:
-	     return SProcRRXineramaQueryVersion(client);
-	case X_PanoramiXGetState:
-	     return SProcRRXineramaGetState(client);
-	case X_PanoramiXGetScreenCount:
-	     return SProcRRXineramaGetScreenCount(client);
-	case X_PanoramiXGetScreenSize:
-	     return SProcRRXineramaGetScreenSize(client);
-	case X_XineramaIsActive:
-	     return SProcRRXineramaIsActive(client);
-	case X_XineramaQueryScreens:
-	     return SProcRRXineramaQueryScreens(client);
-    }
-    return BadRequest;
-}
+#include "xinerama-protocol.h"
 
 void
 RRXineramaExtensionInit(void)
@@ -468,9 +90,6 @@ RRXineramaExtensionInit(void)
     if (screenInfo.numScreens > 1)
 	return;
 
-    (void) AddExtension(PANORAMIX_PROTOCOL_NAME, 0,0,
-			ProcRRXineramaDispatch,
-			SProcRRXineramaDispatch,
-			NULL,
-			StandardMinorOpcode);
+    XineramaProtoInit(NULL);
 }
+
-- 
1.7.2.3



More information about the xorg-devel mailing list