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