From: Dave Airlie <airl...@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

_______________________________________________
xorg-devel@lists.x.org: X.Org development
Archives: http://lists.x.org/archives/xorg-devel
Info: http://lists.x.org/mailman/listinfo/xorg-devel

Reply via email to