From 34e7264e99ceab5e9e2e022ed9a56531845b0b17 Mon Sep 17 00:00:00 2001 From: Philip Langdale Date: Wed, 11 Oct 2006 10:57:57 -0700 Subject: [PATCH] Add xinerama support to the vmware video driver. (Better late than never). With this change, the VMWARE_CTRL extension is updated so that it can receive topology updates at runtime. I will add some sample client code separately. I also intend to add support for a static initial topology defined in xorg.conf but I haven't got around to it yet due to hating to write string parsing code. --- configure.ac | 2 +- src/Makefile.am | 3 +- src/vmware.c | 74 +++++- src/vmware.h | 20 +- src/vmwarectrl.c | 155 ++++++++++- src/vmwarectrl.h | 3 +- src/vmwarectrlproto.h | 33 ++- src/vmwarexinerama.c | 691 ++++++++++++++++++++++++++++++++++++++++++++++++++ 8 files changed, 969 insertions(+), 12 deletions(-) create mode 100644 src/vmwarexinerama.c diff --git a/configure.ac b/configure.ac index 99b996f..37273cd 100644 --- a/configure.ac +++ b/configure.ac @@ -22,7 +22,7 @@ AC_PREREQ(2.57) AC_INIT([xf86-video-vmware], - 10.13.0, + 10.13.99, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], xf86-video-vmware) diff --git a/src/Makefile.am b/src/Makefile.am index f940770..b7857b9 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -46,4 +46,5 @@ vmware_drv_la_SOURCES = \ vmwarexaa.c \ vmwarectrl.c \ vmwarectrl.h \ - vmwarectrlproto.h + vmwarectrlproto.h \ + vmwarexinerama.c diff --git a/src/vmware.c b/src/vmware.c index e08bc38..7f93120 100644 --- a/src/vmware.c +++ b/src/vmware.c @@ -82,7 +82,7 @@ char rcsId_vmware[] = #define VMWARE_DRIVER_NAME "vmware" #define VMWARE_MAJOR_VERSION 10 #define VMWARE_MINOR_VERSION 13 -#define VMWARE_PATCHLEVEL 0 +#define VMWARE_PATCHLEVEL 99 #define VMWARE_DRIVER_VERSION \ (VMWARE_MAJOR_VERSION * 65536 + VMWARE_MINOR_VERSION * 256 + VMWARE_PATCHLEVEL) @@ -164,12 +164,16 @@ static XF86ModuleVersionInfo vmwareVersRec = { typedef enum { OPTION_HW_CURSOR, - OPTION_NOACCEL + OPTION_NOACCEL, + OPTION_XINERAMA, + OPTION_STATIC_XINERAMA, } VMWAREOpts; static const OptionInfoRec VMWAREOptions[] = { { OPTION_HW_CURSOR, "HWcursor", OPTV_BOOLEAN, {0}, FALSE }, { OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_XINERAMA, "Xinerama", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_STATIC_XINERAMA, "StaticXinerama", OPTV_BOOLEAN, {0}, FALSE }, { -1, NULL, OPTV_NONE, {0}, FALSE } }; @@ -431,6 +435,7 @@ VMWAREPreInit(ScrnInfoPtr pScrn, int flags) int i; ClockRange* clockRanges; IOADDRESS domainIOBase = 0; + Bool useXinerama = TRUE; #ifndef BUILD_FOR_420 domainIOBase = pScrn->domainIOBase; @@ -743,6 +748,18 @@ VMWAREPreInit(ScrnInfoPtr pScrn, int flags) } pScrn->videoRam = pVMWARE->videoRam / 1024; pScrn->memPhysBase = pVMWARE->memPhysBase; + + /* + * Init xinerama preferences. + */ + useXinerama = xf86ReturnOptValBool(options, OPTION_XINERAMA, TRUE); + if (useXinerama && !(pVMWARE->vmwareCapability & SVGA_CAP_MULTIMON)) { + useXinerama = FALSE; + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Xinerama is not not supported by " + "the current virtual hardware\n"); + } + pVMWARE->xineramaStatic = xf86ReturnOptValBool(options, OPTION_STATIC_XINERAMA, FALSE); + xfree(options); { @@ -815,6 +832,30 @@ VMWAREPreInit(ScrnInfoPtr pScrn, int flags) xf86LoaderReqSymLists(vmwareXaaSymbols, NULL); } + /* Initialise VMWARE_CTRL extension. */ + VMwareCtrl_ExtInit(pScrn); + + /* Initialise Xinerama extension. */ + if (useXinerama) { + VMwareXinerama_ExtInit(pScrn); + } + + if (pVMWARE->xinerama && pVMWARE->xineramaStatic) { +#if 0 + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Setting up static Xinerama topology.\n"); + pVMWARE->xineramaState = (VMWAREXineramaPtr)xcalloc(pVMWARE->xineramaNumOutputs, + sizeof (VMWAREXineramaRec)); + if (!pVMWARE->xineramaState) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Failed to initialize VMware Xinerama state.\n"); + } else { + /* XXX: Apply static xinerama topology from config file. */ + } +#else + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "\"StaticXinerama\" is not supported yet.\n"); +#endif + } + return TRUE; } @@ -989,6 +1030,33 @@ VMWAREModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode) } } + /* + * Update Xinerama info appropriately. + */ + if (pVMWARE->xinerama && !pVMWARE->xineramaStatic) { + if (pVMWARE->xineramaNextState) { + Xfree(pVMWARE->xineramaState); + pVMWARE->xineramaState = pVMWARE->xineramaNextState; + pVMWARE->xineramaNumOutputs = pVMWARE->xineramaNextNumOutputs; + + pVMWARE->xineramaNextState = NULL; + pVMWARE->xineramaNextNumOutputs = 0; + } else { + VMWAREXineramaPtr basicState = + (VMWAREXineramaPtr)xcalloc(1, sizeof (VMWAREXineramaRec)); + if (basicState) { + basicState->x_org = 0; + basicState->y_org = 0; + basicState->width = vmwareReg->svga_reg_width; + basicState->height = vmwareReg->svga_reg_height; + + Xfree(pVMWARE->xineramaState); + pVMWARE->xineramaState = basicState; + pVMWARE->xineramaNumOutputs = 1; + } + } + } + return TRUE; } @@ -1427,8 +1495,6 @@ VMWAREScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) */ pVMWARE->dynMode1 = NULL; pVMWARE->dynMode2 = NULL; - - VMwareCtrl_ExtInit(pScrn); #if VMWARE_DRIVER_FUNC pScrn->DriverFunc = VMWareDriverFunc; diff --git a/src/vmware.h b/src/vmware.h index 4b98ebb..7f138a6 100644 --- a/src/vmware.h +++ b/src/vmware.h @@ -14,6 +14,8 @@ #include "xf86_OSproc.h" #include "xf86Resources.h" +#include + #include "compiler.h" /* inb/outb */ #include "xf86PciInfo.h" /* pci vendor id */ @@ -52,6 +54,8 @@ typedef struct { CARD32 svga_reg_id; } VMWARERegRec, *VMWARERegPtr; +typedef xXineramaScreenInfo VMWAREXineramaRec, *VMWAREXineramaPtr; + typedef struct { EntityInfoPtr pEnt; pciVideoPtr PciInfo; @@ -138,6 +142,18 @@ typedef struct { SVGASurface* curPict; int op; + /* + * Xinerama state + */ + Bool xinerama; + Bool xineramaStatic; + + VMWAREXineramaPtr xineramaState; + unsigned int xineramaNumOutputs; + + VMWAREXineramaPtr xineramaNextState; + unsigned int xineramaNextNumOutputs; + } VMWARERec, *VMWAREPtr; #define VMWAREPTR(p) ((VMWAREPtr)((p)->driverPrivate)) @@ -254,8 +270,10 @@ void vmwareXAACloseScreen( ScreenPtr pScreen ); -/* vmware_ctl.c */ +/* vmwarectrl.c */ void VMwareCtrl_ExtInit(ScrnInfoPtr pScrn); +/* vmwarexinerama.c */ +void VMwareXinerama_ExtInit(ScrnInfoPtr pScrn); #endif diff --git a/src/vmwarectrl.c b/src/vmwarectrl.c index 7d3e564..413e673 100644 --- a/src/vmwarectrl.c +++ b/src/vmwarectrl.c @@ -39,9 +39,10 @@ #define NEED_REPLIES #define NEED_EVENTS -#include #include "dixstruct.h" #include "extnsionst.h" +#include +#include #include "vmware.h" #include "vmwarectrlproto.h" @@ -216,6 +217,119 @@ VMwareCtrlSetRes(ClientPtr client) /* *---------------------------------------------------------------------------- * + * VMwareCtrlDoSetTopology -- + * + * Set the custom topology and set a dynamic mode to the bounding box + * of the passed topology. + * + * Results: + * TRUE on success, FALSE otherwise. + * + * Side effects: + * One dynamic mode and the pending xinerama state will be updated if + * successful. + * + *---------------------------------------------------------------------------- + */ + +static Bool +VMwareCtrlDoSetTopology(ScrnInfoPtr pScrn, + xXineramaScreenInfo *extents, + unsigned long number) +{ + VMWAREPtr pVMWARE = VMWAREPTR(pScrn); + + if (pVMWARE && pVMWARE->xinerama) { + VMWAREXineramaPtr xineramaState; + short maxX = 0; + short maxY = 0; + size_t i; + + for (i = 0; i < number; i++) { + maxX = MAX(maxX, extents[i].x_org + extents[i].width); + maxY = MAX(maxY, extents[i].y_org + extents[i].height); + } + + xineramaState = (VMWAREXineramaPtr)xcalloc(number, sizeof(VMWAREXineramaRec)); + if (xineramaState) { + memcpy(xineramaState, extents, number * sizeof (VMWAREXineramaRec)); + + Xfree(pVMWARE->xineramaNextState); + pVMWARE->xineramaNextState = xineramaState; + pVMWARE->xineramaNextNumOutputs = number; + + return VMwareCtrlDoSetRes(pScrn, maxX, maxY); + } else { + return FALSE; + } + } else { + return FALSE; + } +} + + +/* + *---------------------------------------------------------------------------- + * + * VMwareCtrlSetTopology -- + * + * Implementation of SetTopology command handler. Initialises and sends a + * reply. + * + * Results: + * Standard response codes. + * + * Side effects: + * Writes reply to client + * + *---------------------------------------------------------------------------- + */ + +static int +VMwareCtrlSetTopology(ClientPtr client) +{ + REQUEST(xVMwareCtrlSetTopologyReq); + xVMwareCtrlSetTopologyReply rep = { 0, }; + ScrnInfoPtr pScrn; + ExtensionEntry *ext; + register int n; + xXineramaScreenInfo *extents; + size_t i; + + REQUEST_AT_LEAST_SIZE(xVMwareCtrlSetTopologyReq); + + if (!(ext = CheckExtension(VMWARE_CTRL_PROTOCOL_NAME))) { + return BadMatch; + } + + pScrn = ext->extPrivate; + if (pScrn->scrnIndex != stuff->screen) { + return BadMatch; + } + + extents = (xXineramaScreenInfo *)(stuff + 1); + if (!VMwareCtrlDoSetTopology(pScrn, extents, stuff->number)) { + return BadValue; + } + + rep.type = X_Reply; + rep.length = (sizeof(xVMwareCtrlSetTopologyReply) - sizeof(xGenericReply)) >> 2; + rep.sequenceNumber = client->sequence; + rep.screen = stuff->screen; + if (client->swapped) { + swaps(&rep.sequenceNumber, n); + swapl(&rep.length, n); + swapl(&rep.screen, n); + } + WriteToClient(client, sizeof(xVMwareCtrlSetTopologyReply), (char *)&rep); + + return client->noClientException; +} + + +/* + *---------------------------------------------------------------------------- + * * VMwareCtrlDispatch -- * * Dispatcher for VMWARE_CTRL commands. Calls the correct handler for @@ -240,6 +354,8 @@ VMwareCtrlDispatch(ClientPtr client) return VMwareCtrlQueryVersion(client); case X_VMwareCtrlSetRes: return VMwareCtrlSetRes(client); + case X_VMwareCtrlSetTopology: + return VMwareCtrlSetTopology(client); } return BadRequest; } @@ -313,6 +429,41 @@ SVMwareCtrlSetRes(ClientPtr client) /* *---------------------------------------------------------------------------- * + * SVMwareCtrlSetTopology -- + * + * Wrapper for SetTopology handler that handles input from other-endian + * clients. + * + * Results: + * Standard response codes. + * + * Side effects: + * Side effects of unswapped implementation. + * + *---------------------------------------------------------------------------- + */ + +static int +SVMwareCtrlSetTopology(ClientPtr client) +{ + register int n; + + REQUEST(xVMwareCtrlSetTopologyReq); + REQUEST_SIZE_MATCH(xVMwareCtrlSetTopologyReq); + + swaps(&stuff->length, n); + swapl(&stuff->screen, n); + swapl(&stuff->number, n); + /* Each extent is a struct of shorts. */ + SwapRestS(stuff); + + return VMwareCtrlSetTopology(client); +} + + +/* + *---------------------------------------------------------------------------- + * * SVMwareCtrlDispatch -- * * Wrapper for dispatcher that handles input from other-endian clients. @@ -336,6 +487,8 @@ SVMwareCtrlDispatch(ClientPtr client) return SVMwareCtrlQueryVersion(client); case X_VMwareCtrlSetRes: return SVMwareCtrlSetRes(client); + case X_VMwareCtrlSetTopology: + return SVMwareCtrlSetTopology(client); } return BadRequest; } diff --git a/src/vmwarectrl.h b/src/vmwarectrl.h index f264494..a671ae1 100644 --- a/src/vmwarectrl.h +++ b/src/vmwarectrl.h @@ -39,9 +39,10 @@ #define VMWARE_CTRL_PROTOCOL_NAME "VMWARE_CTRL" #define VMWARE_CTRL_MAJOR_VERSION 0 -#define VMWARE_CTRL_MINOR_VERSION 1 +#define VMWARE_CTRL_MINOR_VERSION 2 #define X_VMwareCtrlQueryVersion 0 #define X_VMwareCtrlSetRes 1 +#define X_VMwareCtrlSetTopology 2 #endif /* _VMWARE_CTRL_H_ */ diff --git a/src/vmwarectrlproto.h b/src/vmwarectrlproto.h index ecff744..76f157f 100644 --- a/src/vmwarectrlproto.h +++ b/src/vmwarectrlproto.h @@ -44,6 +44,8 @@ * Requests and Replies */ +/* Version 0.1 definitions. */ + typedef struct { CARD8 reqType; /* always X_VMwareCtrlReqCode */ CARD8 VMwareCtrlReqType; /* always X_VMwareCtrlQueryVersion */ @@ -85,11 +87,36 @@ typedef struct { CARD32 screen B32; CARD32 x B32; CARD32 y B32; - CARD32 pad2 B32; - CARD32 pad3 B32; - CARD32 pad4 B32; + CARD32 pad2 B32; + CARD32 pad3 B32; + CARD32 pad4 B32; } xVMwareCtrlSetResReply; #define sz_xVMwareCtrlSetResReply 32 +/* Version 0.2 definitions. */ + +typedef struct { + CARD8 reqType; /* always X_VMwareCtrlReqCode */ + CARD8 VMwareCtrlReqType; /* always X_VMwareCtrlSetTopology */ + CARD16 length B16; + CARD32 screen B32; + CARD32 number B32; + CARD32 pad1 B32; +} xVMwareCtrlSetTopologyReq; +#define sz_xVMwareCtrlSetTopologyReq 16 + +typedef struct { + BYTE type; /* X_Reply */ + BYTE pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 screen B32; + CARD32 pad2 B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; +} xVMwareCtrlSetTopologyReply; +#define sz_xVMwareCtrlSetTopologyReply 32 #endif /* _VMWARE_CTRL_PROTO_H_ */ diff --git a/src/vmwarexinerama.c b/src/vmwarexinerama.c new file mode 100644 index 0000000..fe137ad --- /dev/null +++ b/src/vmwarexinerama.c @@ -0,0 +1,691 @@ +/* + * Copyright 2006 by VMware, Inc. + * + * 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, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * 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 + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, 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 the copyright holder(s) + * and author(s) shall not be used in advertising or otherwise to promote + * the sale, use or other dealings in this Software without prior written + * authorization from the copyright holder(s) and author(s). + */ + +/* + * vmwarexinerama.c -- + * + * The implementation of the Xinerama protocol extension. + */ + + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#define NEED_REPLIES +#define NEED_EVENTS +#include "dixstruct.h" +#include "extnsionst.h" +#include +#include + +#include "vmware.h" + + +/* + *---------------------------------------------------------------------------- + * + * VMwareXineramaQueryVersion -- + * + * Implementation of QueryVersion command handler. Initialises and + * sends a reply. + * + * Results: + * Standard response codes. + * + * Side effects: + * Writes reply to client. + * + *---------------------------------------------------------------------------- + */ + +static int +VMwareXineramaQueryVersion(ClientPtr client) +{ + xPanoramiXQueryVersionReply rep; + register int n; + + REQUEST_SIZE_MATCH(xPanoramiXQueryVersionReq); + rep.type = X_Reply; + rep.length = 0; + rep.sequenceNumber = client->sequence; + rep.majorVersion = 1; + rep.minorVersion = 0; + 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 (client->noClientException); +} + + +/* + *---------------------------------------------------------------------------- + * + * VMwareXineramaGetState -- + * + * Implementation of GetState command handler. Initialises and + * sends a reply. + * + * Results: + * Standard response codes. + * + * Side effects: + * Writes reply to client. + * + *---------------------------------------------------------------------------- + */ + +static int +VMwareXineramaGetState(ClientPtr client) +{ + REQUEST(xPanoramiXGetStateReq); + WindowPtr pWin; + xPanoramiXGetStateReply rep; + register int n; + ExtensionEntry *ext; + ScrnInfoPtr pScrn; + VMWAREPtr pVMWARE; + + REQUEST_SIZE_MATCH(xPanoramiXGetStateReq); + pWin = LookupWindow(stuff->window, client); + if(!pWin) return BadWindow; + + if (!(ext = CheckExtension(PANORAMIX_PROTOCOL_NAME))) { + return BadMatch; + } + pScrn = ext->extPrivate; + pVMWARE = VMWAREPTR(pScrn); + + rep.type = X_Reply; + rep.length = 0; + rep.sequenceNumber = client->sequence; + rep.state = pVMWARE->xinerama; + if(client->swapped) { + swaps (&rep.sequenceNumber, n); + swapl (&rep.length, n); + swaps (&rep.state, n); + } + WriteToClient(client, sizeof(xPanoramiXGetStateReply), (char *)&rep); + return client->noClientException; +} + + +/* + *---------------------------------------------------------------------------- + * + * VMwareXineramaGetScreenCount -- + * + * Implementation of GetScreenCount command handler. Initialises and + * sends a reply. + * + * Results: + * Standard response codes. + * + * Side effects: + * Writes reply to client. + * + *---------------------------------------------------------------------------- + */ + +static int +VMwareXineramaGetScreenCount(ClientPtr client) +{ + REQUEST(xPanoramiXGetScreenCountReq); + WindowPtr pWin; + xPanoramiXGetScreenCountReply rep; + register int n; + ExtensionEntry *ext; + ScrnInfoPtr pScrn; + VMWAREPtr pVMWARE; + + REQUEST_SIZE_MATCH(xPanoramiXGetScreenCountReq); + pWin = LookupWindow(stuff->window, client); + if(!pWin) return BadWindow; + + if (!(ext = CheckExtension(PANORAMIX_PROTOCOL_NAME))) { + return BadMatch; + } + pScrn = ext->extPrivate; + pVMWARE = VMWAREPTR(pScrn); + + rep.type = X_Reply; + rep.length = 0; + rep.sequenceNumber = client->sequence; + rep.ScreenCount = pVMWARE->xineramaNumOutputs; + if(client->swapped) { + swaps(&rep.sequenceNumber, n); + swapl(&rep.length, n); + swaps(&rep.ScreenCount, n); + } + WriteToClient(client, sizeof(xPanoramiXGetScreenCountReply), (char *)&rep); + return client->noClientException; +} + + +/* + *---------------------------------------------------------------------------- + * + * VMwareXineramaGetScreenSize -- + * + * Implementation of GetScreenSize command handler. Initialises and + * sends a reply. + * + * Results: + * Standard response codes. + * + * Side effects: + * Writes reply to client. + * + *---------------------------------------------------------------------------- + */ + +static int +VMwareXineramaGetScreenSize(ClientPtr client) +{ + REQUEST(xPanoramiXGetScreenSizeReq); + WindowPtr pWin; + xPanoramiXGetScreenSizeReply rep; + register int n; + ExtensionEntry *ext; + ScrnInfoPtr pScrn; + VMWAREPtr pVMWARE; + + REQUEST_SIZE_MATCH(xPanoramiXGetScreenSizeReq); + pWin = LookupWindow (stuff->window, client); + if(!pWin) return BadWindow; + + if (!(ext = CheckExtension(PANORAMIX_PROTOCOL_NAME))) { + return BadMatch; + } + pScrn = ext->extPrivate; + pVMWARE = VMWAREPTR(pScrn); + + rep.type = X_Reply; + rep.length = 0; + rep.sequenceNumber = client->sequence; + rep.width = pVMWARE->xineramaState[stuff->screen].width; + rep.height = pVMWARE->xineramaState[stuff->screen].height; + if(client->swapped) { + swaps(&rep.sequenceNumber, n); + swapl(&rep.length, n); + swaps(&rep.width, n); + swaps(&rep.height, n); + } + WriteToClient(client, sizeof(xPanoramiXGetScreenSizeReply), (char *)&rep); + return client->noClientException; +} + + +/* + *---------------------------------------------------------------------------- + * + * VMwareXineramaIsActive -- + * + * Implementation of IsActive command handler. Initialises and + * sends a reply. + * + * Results: + * Standard response codes. + * + * Side effects: + * Writes reply to client. + * + *---------------------------------------------------------------------------- + */ + +static int +VMwareXineramaIsActive(ClientPtr client) +{ + xXineramaIsActiveReply rep; + ExtensionEntry *ext; + ScrnInfoPtr pScrn; + VMWAREPtr pVMWARE; + + REQUEST_SIZE_MATCH(xXineramaIsActiveReq); + + if (!(ext = CheckExtension(PANORAMIX_PROTOCOL_NAME))) { + return BadMatch; + } + pScrn = ext->extPrivate; + pVMWARE = VMWAREPTR(pScrn); + + rep.type = X_Reply; + rep.length = 0; + rep.sequenceNumber = client->sequence; + rep.state = pVMWARE->xinerama; + 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 client->noClientException; +} + + +/* + *---------------------------------------------------------------------------- + * + * VMwareXineramaQueryScreens -- + * + * Implementation of QueryScreens command handler. Initialises and + * sends a reply. + * + * Results: + * Standard response codes. + * + * Side effects: + * Writes reply to client. + * + *---------------------------------------------------------------------------- + */ + +static int +VMwareXineramaQueryScreens(ClientPtr client) +{ + xXineramaQueryScreensReply rep; + ExtensionEntry *ext; + ScrnInfoPtr pScrn; + VMWAREPtr pVMWARE; + + REQUEST_SIZE_MATCH(xXineramaQueryScreensReq); + + if (!(ext = CheckExtension(PANORAMIX_PROTOCOL_NAME))) { + return BadMatch; + } + pScrn = ext->extPrivate; + pVMWARE = VMWAREPTR(pScrn); + + rep.type = X_Reply; + rep.sequenceNumber = client->sequence; + rep.number = pVMWARE->xinerama ? pVMWARE->xineramaNumOutputs : 0; + rep.length = rep.number * sz_XineramaScreenInfo >> 2; + 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(pVMWARE->xinerama) { + xXineramaScreenInfo scratch; + int i; + + for(i = 0; i < pVMWARE->xineramaNumOutputs; i++) { + scratch.x_org = pVMWARE->xineramaState[i].x_org; + scratch.y_org = pVMWARE->xineramaState[i].y_org; + scratch.width = pVMWARE->xineramaState[i].width; + scratch.height = pVMWARE->xineramaState[i].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, (char *)&scratch); + } + } + + return client->noClientException; +} + + +/* + *---------------------------------------------------------------------------- + * + * VMwareXineramaDispatch -- + * + * Dispatcher for Xinerama commands. Calls the correct handler for + * each command type. + * + * Results: + * Standard response codes. + * + * Side effects: + * Side effects of individual command handlers. + * + *---------------------------------------------------------------------------- + */ + +static int +VMwareXineramaDispatch(ClientPtr client) +{ + REQUEST(xReq); + switch (stuff->data) { + case X_PanoramiXQueryVersion: + return VMwareXineramaQueryVersion(client); + case X_PanoramiXGetState: + return VMwareXineramaGetState(client); + case X_PanoramiXGetScreenCount: + return VMwareXineramaGetScreenCount(client); + case X_PanoramiXGetScreenSize: + return VMwareXineramaGetScreenSize(client); + case X_XineramaIsActive: + return VMwareXineramaIsActive(client); + case X_XineramaQueryScreens: + return VMwareXineramaQueryScreens(client); + } + return BadRequest; +} + + +/* + *---------------------------------------------------------------------------- + * + * SVMwareXineramaQueryVersion -- + * + * Wrapper for QueryVersion handler that handles input from other-endian + * clients. + * + * Results: + * Standard response codes. + * + * Side effects: + * Side effects of unswapped implementation. + * + *---------------------------------------------------------------------------- + */ + +static int +SVMwareXineramaQueryVersion (ClientPtr client) +{ + REQUEST(xPanoramiXQueryVersionReq); + register int n; + swaps(&stuff->length,n); + REQUEST_SIZE_MATCH (xPanoramiXQueryVersionReq); + return VMwareXineramaQueryVersion(client); +} + + +/* + *---------------------------------------------------------------------------- + * + * SVMwareXineramaGetState -- + * + * Wrapper for GetState handler that handles input from other-endian + * clients. + * + * Results: + * Standard response codes. + * + * Side effects: + * Side effects of unswapped implementation. + * + *---------------------------------------------------------------------------- + */ + +static int +SVMwareXineramaGetState(ClientPtr client) +{ + REQUEST(xPanoramiXGetStateReq); + register int n; + swaps (&stuff->length, n); + REQUEST_SIZE_MATCH(xPanoramiXGetStateReq); + return VMwareXineramaGetState(client); +} + + +/* + *---------------------------------------------------------------------------- + * + * SVMwareXineramaGetScreenCount -- + * + * Wrapper for GetScreenCount handler that handles input from other-endian + * clients. + * + * Results: + * Standard response codes. + * + * Side effects: + * Side effects of unswapped implementation. + * + *---------------------------------------------------------------------------- + */ + +static int +SVMwareXineramaGetScreenCount(ClientPtr client) +{ + REQUEST(xPanoramiXGetScreenCountReq); + register int n; + swaps (&stuff->length, n); + REQUEST_SIZE_MATCH(xPanoramiXGetScreenCountReq); + return VMwareXineramaGetScreenCount(client); +} + + +/* + *---------------------------------------------------------------------------- + * + * SVMwareXineramaGetScreenSize -- + * + * Wrapper for GetScreenSize handler that handles input from other-endian + * clients. + * + * Results: + * Standard response codes. + * + * Side effects: + * Side effects of unswapped implementation. + * + *---------------------------------------------------------------------------- + */ + +static int +SVMwareXineramaGetScreenSize(ClientPtr client) +{ + REQUEST(xPanoramiXGetScreenSizeReq); + register int n; + swaps (&stuff->length, n); + REQUEST_SIZE_MATCH(xPanoramiXGetScreenSizeReq); + return VMwareXineramaGetScreenSize(client); +} + + +/* + *---------------------------------------------------------------------------- + * + * SVMwareXineramaIsActive -- + * + * Wrapper for IsActive handler that handles input from other-endian + * clients. + * + * Results: + * Standard response codes. + * + * Side effects: + * Side effects of unswapped implementation. + * + *---------------------------------------------------------------------------- + */ + +static int +SVMwareXineramaIsActive(ClientPtr client) +{ + REQUEST(xXineramaIsActiveReq); + register int n; + swaps (&stuff->length, n); + REQUEST_SIZE_MATCH(xXineramaIsActiveReq); + return VMwareXineramaIsActive(client); +} + + +/* + *---------------------------------------------------------------------------- + * + * SVMwareXineramaQueryScreens -- + * + * Wrapper for QueryScreens handler that handles input from other-endian + * clients. + * + * Results: + * Standard response codes. + * + * Side effects: + * Side effects of unswapped implementation. + * + *---------------------------------------------------------------------------- + */ + +static int +SVMwareXineramaQueryScreens(ClientPtr client) +{ + REQUEST(xXineramaQueryScreensReq); + register int n; + swaps (&stuff->length, n); + REQUEST_SIZE_MATCH(xXineramaQueryScreensReq); + return VMwareXineramaQueryScreens(client); +} + + +/* + *---------------------------------------------------------------------------- + * + * SVMwareXineramaDispatch -- + * + * Wrapper for dispatcher that handles input from other-endian clients. + * + * Results: + * Standard response codes. + * + * Side effects: + * Side effects of individual command handlers. + * + *---------------------------------------------------------------------------- + */ + +static int +SVMwareXineramaDispatch(ClientPtr client) +{ + REQUEST(xReq); + switch (stuff->data) { + case X_PanoramiXQueryVersion: + return SVMwareXineramaQueryVersion(client); + case X_PanoramiXGetState: + return SVMwareXineramaGetState(client); + case X_PanoramiXGetScreenCount: + return SVMwareXineramaGetScreenCount(client); + case X_PanoramiXGetScreenSize: + return SVMwareXineramaGetScreenSize(client); + case X_XineramaIsActive: + return SVMwareXineramaIsActive(client); + case X_XineramaQueryScreens: + return SVMwareXineramaQueryScreens(client); + } + return BadRequest; +} + + +/* + *---------------------------------------------------------------------------- + * + * VMwareXineramaResetProc -- + * + * Cleanup handler called when the extension is removed. + * + * Results: + * None + * + * Side effects: + * None + * + *---------------------------------------------------------------------------- + */ + +static void +VMwareXineramaResetProc(ExtensionEntry* extEntry) +{ + /* Called by CloseDownExtensions() */ + + ScrnInfoPtr pScrn = extEntry->extPrivate; + VMWAREPtr pVMWARE = VMWAREPTR(pScrn); + + if (pVMWARE->xineramaState) { + Xfree(pVMWARE->xineramaState); + pVMWARE->xineramaState = NULL; + pVMWARE->xineramaNumOutputs = 0; + pVMWARE->xinerama = FALSE; + } +} + + +/* + *---------------------------------------------------------------------------- + * + * VMwareCtrl_ExitInit -- + * + * Initialiser for the Xinerama protocol extension. + * + * Results: + * None. + * + * Side effects: + * Protocol extension will be registered if successful. + * + *---------------------------------------------------------------------------- + */ + +void +VMwareXinerama_ExtInit(ScrnInfoPtr pScrn) +{ + ExtensionEntry *myext; + VMWAREPtr pVMWARE = VMWAREPTR(pScrn); + +#ifdef PANORAMIX + if(!noPanoramiXExtension) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Built-in Xinerama active, not initializing VMware Xinerama\n"); + pVMWARE->xinerama = FALSE; + return; + } +#endif + + if (!(myext = CheckExtension(PANORAMIX_PROTOCOL_NAME))) { + if (!(myext = AddExtension(PANORAMIX_PROTOCOL_NAME, 0, 0, + VMwareXineramaDispatch, + SVMwareXineramaDispatch, + VMwareXineramaResetProc, + StandardMinorOpcode))) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Failed to add VMware Xinerama extension.\n"); + return; + } + + pVMWARE->xinerama = TRUE; + + myext->extPrivate = pScrn; + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Initialized VMware Xinerama extension.\n"); + } +} -- 2.7.4