vmwarectrl.c revision 2e8abef9
16df26cacSmrg/* 26df26cacSmrg * Copyright 2006 by VMware, Inc. 36df26cacSmrg * 46df26cacSmrg * Permission is hereby granted, free of charge, to any person obtaining a 56df26cacSmrg * copy of this software and associated documentation files (the "Software"), 66df26cacSmrg * to deal in the Software without restriction, including without limitation 76df26cacSmrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 86df26cacSmrg * and/or sell copies of the Software, and to permit persons to whom the 96df26cacSmrg * Software is furnished to do so, subject to the following conditions: 106df26cacSmrg * 116df26cacSmrg * The above copyright notice and this permission notice shall be included in 126df26cacSmrg * all copies or substantial portions of the Software. 136df26cacSmrg * 146df26cacSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 156df26cacSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 166df26cacSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 176df26cacSmrg * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 186df26cacSmrg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 196df26cacSmrg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 206df26cacSmrg * OTHER DEALINGS IN THE SOFTWARE. 216df26cacSmrg * 226df26cacSmrg * Except as contained in this notice, the name of the copyright holder(s) 236df26cacSmrg * and author(s) shall not be used in advertising or otherwise to promote 246df26cacSmrg * the sale, use or other dealings in this Software without prior written 256df26cacSmrg * authorization from the copyright holder(s) and author(s). 266df26cacSmrg */ 276df26cacSmrg 286df26cacSmrg/* 296df26cacSmrg * vmwarectrl.c -- 306df26cacSmrg * 316df26cacSmrg * The implementation of the VMWARE_CTRL protocol extension that 326df26cacSmrg * allows X clients to communicate with the driver. 336df26cacSmrg */ 346df26cacSmrg 356df26cacSmrg 366df26cacSmrg#ifdef HAVE_CONFIG_H 376df26cacSmrg#include "config.h" 386df26cacSmrg#endif 396df26cacSmrg 406df26cacSmrg#define NEED_REPLIES 416df26cacSmrg#define NEED_EVENTS 426df26cacSmrg#include "dixstruct.h" 436df26cacSmrg#include "extnsionst.h" 446df26cacSmrg#include <X11/X.h> 456df26cacSmrg#include <X11/extensions/panoramiXproto.h> 466df26cacSmrg 476df26cacSmrg#include "vmware.h" 486df26cacSmrg#include "vmwarectrlproto.h" 496df26cacSmrg 506df26cacSmrg 516df26cacSmrg/* 526df26cacSmrg *---------------------------------------------------------------------------- 536df26cacSmrg * 546df26cacSmrg * VMwareCtrlQueryVersion -- 556df26cacSmrg * 566df26cacSmrg * Implementation of QueryVersion command handler. Initialises and 576df26cacSmrg * sends a reply. 586df26cacSmrg * 596df26cacSmrg * Results: 606df26cacSmrg * Standard response codes. 616df26cacSmrg * 626df26cacSmrg * Side effects: 636df26cacSmrg * Writes reply to client 646df26cacSmrg * 656df26cacSmrg *---------------------------------------------------------------------------- 666df26cacSmrg */ 676df26cacSmrg 686df26cacSmrgstatic int 696df26cacSmrgVMwareCtrlQueryVersion(ClientPtr client) 706df26cacSmrg{ 716df26cacSmrg xVMwareCtrlQueryVersionReply rep = { 0, }; 726df26cacSmrg register int n; 736df26cacSmrg 746df26cacSmrg REQUEST_SIZE_MATCH(xVMwareCtrlQueryVersionReq); 756df26cacSmrg 766df26cacSmrg rep.type = X_Reply; 776df26cacSmrg rep.length = 0; 786df26cacSmrg rep.sequenceNumber = client->sequence; 796df26cacSmrg rep.majorVersion = VMWARE_CTRL_MAJOR_VERSION; 806df26cacSmrg rep.minorVersion = VMWARE_CTRL_MINOR_VERSION; 816df26cacSmrg if (client->swapped) { 826df26cacSmrg swaps(&rep.sequenceNumber, n); 836df26cacSmrg swapl(&rep.length, n); 846df26cacSmrg swapl(&rep.majorVersion, n); 856df26cacSmrg swapl(&rep.minorVersion, n); 866df26cacSmrg } 876df26cacSmrg WriteToClient(client, sizeof(xVMwareCtrlQueryVersionReply), (char *)&rep); 886df26cacSmrg 896df26cacSmrg return client->noClientException; 906df26cacSmrg} 916df26cacSmrg 926df26cacSmrg 936df26cacSmrg/* 946df26cacSmrg *---------------------------------------------------------------------------- 956df26cacSmrg * 966df26cacSmrg * VMwareCtrlDoSetRes -- 976df26cacSmrg * 986df26cacSmrg * Set the custom resolution into the mode list. 996df26cacSmrg * 1006df26cacSmrg * This is done by alternately updating one of two dynamic modes. It is 1016df26cacSmrg * done this way because the server gets upset if you try to switch 1026df26cacSmrg * to a new resolution that has the same index as the current one. 1036df26cacSmrg * 1046df26cacSmrg * Results: 1056df26cacSmrg * TRUE on success, FALSE otherwise. 1066df26cacSmrg * 1076df26cacSmrg * Side effects: 1086df26cacSmrg * One dynamic mode will be updated if successful. 1096df26cacSmrg * 1106df26cacSmrg *---------------------------------------------------------------------------- 1116df26cacSmrg */ 1126df26cacSmrg 1136df26cacSmrgstatic Bool 1146df26cacSmrgVMwareCtrlDoSetRes(ScrnInfoPtr pScrn, 1156df26cacSmrg CARD32 x, 1166df26cacSmrg CARD32 y, 1176df26cacSmrg Bool resetXinerama) 1186df26cacSmrg{ 11916fd1166Smrg int modeIndex; 1206df26cacSmrg DisplayModePtr mode; 1216df26cacSmrg VMWAREPtr pVMWARE = VMWAREPTR(pScrn); 1226df26cacSmrg 1236df26cacSmrg if (pScrn && pScrn->modes) { 1246df26cacSmrg VmwareLog(("DoSetRes: %d %d\n", x, y)); 12516fd1166Smrg 1266df26cacSmrg if (resetXinerama) { 1276df26cacSmrg xfree(pVMWARE->xineramaNextState); 1286df26cacSmrg pVMWARE->xineramaNextState = NULL; 1296df26cacSmrg pVMWARE->xineramaNextNumOutputs = 0; 1306df26cacSmrg } 1316df26cacSmrg 13216fd1166Smrg /* 1336df26cacSmrg * Don't resize larger than possible but don't 1346df26cacSmrg * return an X Error either. 1356df26cacSmrg */ 1366df26cacSmrg if (x > pVMWARE->maxWidth || 1376df26cacSmrg y > pVMWARE->maxHeight) { 1386df26cacSmrg return TRUE; 1396df26cacSmrg } 1406df26cacSmrg 1416df26cacSmrg /* 14216fd1166Smrg * Find an dynamic mode which isn't current, and replace it with 14316fd1166Smrg * the requested mode. Normally this will cause us to alternate 14416fd1166Smrg * between two dynamic mode slots, but there are some important 14516fd1166Smrg * corner cases to consider. For example, adding the same mode 14616fd1166Smrg * multiple times, adding a mode that we never switch to, or 14716fd1166Smrg * adding a mode which is a duplicate of a built-in mode. The 14816fd1166Smrg * best way to handle all of these cases is to directly test the 14916fd1166Smrg * dynamic mode against the current mode pointer for this 15016fd1166Smrg * screen. 1516df26cacSmrg */ 1526df26cacSmrg 15316fd1166Smrg for (modeIndex = 0; modeIndex < NUM_DYN_MODES; modeIndex++) { 15416fd1166Smrg /* 15516fd1166Smrg * Initialise the dynamic mode if it hasn't been used before. 15616fd1166Smrg */ 15716fd1166Smrg if (!pVMWARE->dynModes[modeIndex]) { 15816fd1166Smrg pVMWARE->dynModes[modeIndex] = VMWAREAddDisplayMode(pScrn, "DynMode", 1, 1); 15916fd1166Smrg } 16016fd1166Smrg 16116fd1166Smrg mode = pVMWARE->dynModes[modeIndex]; 16216fd1166Smrg if (mode != pScrn->currentMode) { 16316fd1166Smrg break; 16416fd1166Smrg } 1656df26cacSmrg } 1666df26cacSmrg 1676df26cacSmrg mode->HDisplay = x; 1686df26cacSmrg mode->VDisplay = y; 1696df26cacSmrg 1706df26cacSmrg return TRUE; 1716df26cacSmrg } else { 1726df26cacSmrg return FALSE; 1736df26cacSmrg } 1746df26cacSmrg} 1756df26cacSmrg 1766df26cacSmrg 1776df26cacSmrg/* 1786df26cacSmrg *---------------------------------------------------------------------------- 1796df26cacSmrg * 1806df26cacSmrg * VMwareCtrlSetRes -- 1816df26cacSmrg * 1826df26cacSmrg * Implementation of SetRes command handler. Initialises and sends a 1836df26cacSmrg * reply. 1846df26cacSmrg * 1856df26cacSmrg * Results: 1866df26cacSmrg * Standard response codes. 1876df26cacSmrg * 1886df26cacSmrg * Side effects: 1896df26cacSmrg * Writes reply to client 1906df26cacSmrg * 1916df26cacSmrg *---------------------------------------------------------------------------- 1926df26cacSmrg */ 1936df26cacSmrg 1946df26cacSmrgstatic int 1956df26cacSmrgVMwareCtrlSetRes(ClientPtr client) 1966df26cacSmrg{ 1976df26cacSmrg REQUEST(xVMwareCtrlSetResReq); 1986df26cacSmrg xVMwareCtrlSetResReply rep = { 0, }; 1996df26cacSmrg ScrnInfoPtr pScrn; 2006df26cacSmrg ExtensionEntry *ext; 2016df26cacSmrg register int n; 2026df26cacSmrg 2036df26cacSmrg REQUEST_SIZE_MATCH(xVMwareCtrlSetResReq); 2046df26cacSmrg 2056df26cacSmrg if (!(ext = CheckExtension(VMWARE_CTRL_PROTOCOL_NAME))) { 2066df26cacSmrg return BadMatch; 2076df26cacSmrg } 2086df26cacSmrg 2096df26cacSmrg pScrn = ext->extPrivate; 2106df26cacSmrg if (pScrn->scrnIndex != stuff->screen) { 2116df26cacSmrg return BadMatch; 2126df26cacSmrg } 2136df26cacSmrg 2146df26cacSmrg if (!VMwareCtrlDoSetRes(pScrn, stuff->x, stuff->y, TRUE)) { 2156df26cacSmrg return BadValue; 2166df26cacSmrg } 2176df26cacSmrg 2186df26cacSmrg rep.type = X_Reply; 2196df26cacSmrg rep.length = (sizeof(xVMwareCtrlSetResReply) - sizeof(xGenericReply)) >> 2; 2206df26cacSmrg rep.sequenceNumber = client->sequence; 2216df26cacSmrg rep.screen = stuff->screen; 2226df26cacSmrg rep.x = stuff->x; 2236df26cacSmrg rep.y = stuff->y; 2246df26cacSmrg if (client->swapped) { 2256df26cacSmrg swaps(&rep.sequenceNumber, n); 2266df26cacSmrg swapl(&rep.length, n); 2276df26cacSmrg swapl(&rep.screen, n); 2286df26cacSmrg swapl(&rep.x, n); 2296df26cacSmrg swapl(&rep.y, n); 2306df26cacSmrg } 2316df26cacSmrg WriteToClient(client, sizeof(xVMwareCtrlSetResReply), (char *)&rep); 2326df26cacSmrg 2336df26cacSmrg return client->noClientException; 2346df26cacSmrg} 2356df26cacSmrg 2366df26cacSmrg 2376df26cacSmrg/* 2386df26cacSmrg *---------------------------------------------------------------------------- 2396df26cacSmrg * 2406df26cacSmrg * VMwareCtrlDoSetTopology -- 2416df26cacSmrg * 2426df26cacSmrg * Set the custom topology and set a dynamic mode to the bounding box 2436df26cacSmrg * of the passed topology. If a topology is already pending, then do 2446df26cacSmrg * nothing but do not return failure. 2456df26cacSmrg * 2466df26cacSmrg * Results: 2476df26cacSmrg * TRUE on success, FALSE otherwise. 2486df26cacSmrg * 2496df26cacSmrg * Side effects: 2506df26cacSmrg * One dynamic mode and the pending xinerama state will be updated if 2516df26cacSmrg * successful. 2526df26cacSmrg * 2536df26cacSmrg *---------------------------------------------------------------------------- 2546df26cacSmrg */ 2556df26cacSmrg 2566df26cacSmrgstatic Bool 2576df26cacSmrgVMwareCtrlDoSetTopology(ScrnInfoPtr pScrn, 2586df26cacSmrg xXineramaScreenInfo *extents, 2596df26cacSmrg unsigned long number) 2606df26cacSmrg{ 2616df26cacSmrg VMWAREPtr pVMWARE = VMWAREPTR(pScrn); 2626df26cacSmrg 2636df26cacSmrg if (pVMWARE && pVMWARE->xinerama) { 2646df26cacSmrg VMWAREXineramaPtr xineramaState; 2656df26cacSmrg short maxX = 0; 2666df26cacSmrg short maxY = 0; 2676df26cacSmrg size_t i; 2686df26cacSmrg 2696df26cacSmrg if (pVMWARE->xineramaNextState) { 2706df26cacSmrg VmwareLog(("DoSetTopology: Aborting due to existing pending state\n")); 2716df26cacSmrg return TRUE; 2726df26cacSmrg } 2736df26cacSmrg 2746df26cacSmrg for (i = 0; i < number; i++) { 2756df26cacSmrg maxX = MAX(maxX, extents[i].x_org + extents[i].width); 2766df26cacSmrg maxY = MAX(maxY, extents[i].y_org + extents[i].height); 2776df26cacSmrg } 2786df26cacSmrg 2796df26cacSmrg VmwareLog(("DoSetTopology: %d %d\n", maxX, maxY)); 2806df26cacSmrg 2816df26cacSmrg xineramaState = (VMWAREXineramaPtr)xcalloc(number, sizeof(VMWAREXineramaRec)); 2826df26cacSmrg if (xineramaState) { 2836df26cacSmrg memcpy(xineramaState, extents, number * sizeof (VMWAREXineramaRec)); 2846df26cacSmrg 2852e8abef9Smrg /* 2862e8abef9Smrg * Make this the new pending Xinerama state. Normally we'll 2872e8abef9Smrg * wait until the next mode switch in order to synchronously 2882e8abef9Smrg * push this state out to X clients and the virtual hardware. 2892e8abef9Smrg * 2902e8abef9Smrg * However, if we're already in the right video mode, there 2912e8abef9Smrg * will be no mode change. In this case, push it out 2922e8abef9Smrg * immediately. 2932e8abef9Smrg */ 2946df26cacSmrg xfree(pVMWARE->xineramaNextState); 2956df26cacSmrg pVMWARE->xineramaNextState = xineramaState; 2966df26cacSmrg pVMWARE->xineramaNextNumOutputs = number; 2976df26cacSmrg 2982e8abef9Smrg if (maxX == pVMWARE->ModeReg.svga_reg_width && 2992e8abef9Smrg maxY == pVMWARE->ModeReg.svga_reg_height) { 3002e8abef9Smrg 3012e8abef9Smrg /* 3022e8abef9Smrg * XXX: 3032e8abef9Smrg * 3042e8abef9Smrg * There are problems with trying to set a Xinerama state 3052e8abef9Smrg * without a mode switch. The biggest one is that 3062e8abef9Smrg * applications typically won't notice a topology change 3072e8abef9Smrg * that occurs without a mode switch. If you run "xdpyinfo 3082e8abef9Smrg * -ext XINERAMA" after one such topology change, it will 3092e8abef9Smrg * report the new data, but apps (like the GNOME Panel) 3102e8abef9Smrg * will not notice until the next mode change. 3112e8abef9Smrg * 3122e8abef9Smrg * I don't think there's any good solution to this... as 3132e8abef9Smrg * far as I know, even on a non-virtualized machine 3142e8abef9Smrg * there's no way for an app to find out if the Xinerama 3152e8abef9Smrg * opology changes without a resolution change also 3162e8abef9Smrg * occurring. There might be some cheats we can take, like 3172e8abef9Smrg * swithcing to a new mode with the same resolution and a 3182e8abef9Smrg * different (fake) refresh rate, or temporarily switching 3192e8abef9Smrg * to an intermediate mode. Ick. 3202e8abef9Smrg * 3212e8abef9Smrg * The other annoyance here is that when we reprogram the 3222e8abef9Smrg * SVGA device's monitor topology registers, it may 3232e8abef9Smrg * rearrange those monitors on the host's screen, but they 3242e8abef9Smrg * will still have the old contents. This might be 3252e8abef9Smrg * correct, but it isn't guaranteed to match what's on X's 3262e8abef9Smrg * framebuffer at the moment. So we'll send a 3272e8abef9Smrg * full-framebuffer update rect afterwards. 3282e8abef9Smrg */ 3292e8abef9Smrg 3302e8abef9Smrg vmwareNextXineramaState(pVMWARE); 3312e8abef9Smrg vmwareSendSVGACmdUpdateFullScreen(pVMWARE); 3322e8abef9Smrg 3332e8abef9Smrg return TRUE; 3342e8abef9Smrg } else { 3352e8abef9Smrg return VMwareCtrlDoSetRes(pScrn, maxX, maxY, FALSE); 3362e8abef9Smrg } 3372e8abef9Smrg 3386df26cacSmrg } else { 3396df26cacSmrg return FALSE; 3406df26cacSmrg } 3416df26cacSmrg } else { 3426df26cacSmrg return FALSE; 3436df26cacSmrg } 3446df26cacSmrg} 3456df26cacSmrg 3466df26cacSmrg 3476df26cacSmrg/* 3486df26cacSmrg *---------------------------------------------------------------------------- 3496df26cacSmrg * 3506df26cacSmrg * VMwareCtrlSetTopology -- 3516df26cacSmrg * 3526df26cacSmrg * Implementation of SetTopology command handler. Initialises and sends a 3536df26cacSmrg * reply. 3546df26cacSmrg * 3556df26cacSmrg * Results: 3566df26cacSmrg * Standard response codes. 3576df26cacSmrg * 3586df26cacSmrg * Side effects: 3596df26cacSmrg * Writes reply to client 3606df26cacSmrg * 3616df26cacSmrg *---------------------------------------------------------------------------- 3626df26cacSmrg */ 3636df26cacSmrg 3646df26cacSmrgstatic int 3656df26cacSmrgVMwareCtrlSetTopology(ClientPtr client) 3666df26cacSmrg{ 3676df26cacSmrg REQUEST(xVMwareCtrlSetTopologyReq); 3686df26cacSmrg xVMwareCtrlSetTopologyReply rep = { 0, }; 3696df26cacSmrg ScrnInfoPtr pScrn; 3706df26cacSmrg ExtensionEntry *ext; 3716df26cacSmrg register int n; 3726df26cacSmrg xXineramaScreenInfo *extents; 3736df26cacSmrg 3746df26cacSmrg REQUEST_AT_LEAST_SIZE(xVMwareCtrlSetTopologyReq); 3756df26cacSmrg 3766df26cacSmrg if (!(ext = CheckExtension(VMWARE_CTRL_PROTOCOL_NAME))) { 3776df26cacSmrg return BadMatch; 3786df26cacSmrg } 3796df26cacSmrg 3806df26cacSmrg pScrn = ext->extPrivate; 3816df26cacSmrg if (pScrn->scrnIndex != stuff->screen) { 3826df26cacSmrg return BadMatch; 3836df26cacSmrg } 3846df26cacSmrg 3856df26cacSmrg extents = (xXineramaScreenInfo *)(stuff + 1); 3866df26cacSmrg if (!VMwareCtrlDoSetTopology(pScrn, extents, stuff->number)) { 3876df26cacSmrg return BadValue; 3886df26cacSmrg } 3896df26cacSmrg 3906df26cacSmrg rep.type = X_Reply; 3916df26cacSmrg rep.length = (sizeof(xVMwareCtrlSetTopologyReply) - sizeof(xGenericReply)) >> 2; 3926df26cacSmrg rep.sequenceNumber = client->sequence; 3936df26cacSmrg rep.screen = stuff->screen; 3946df26cacSmrg if (client->swapped) { 3956df26cacSmrg swaps(&rep.sequenceNumber, n); 3966df26cacSmrg swapl(&rep.length, n); 3976df26cacSmrg swapl(&rep.screen, n); 3986df26cacSmrg } 3996df26cacSmrg WriteToClient(client, sizeof(xVMwareCtrlSetTopologyReply), (char *)&rep); 4006df26cacSmrg 4016df26cacSmrg return client->noClientException; 4026df26cacSmrg} 4036df26cacSmrg 4046df26cacSmrg 4056df26cacSmrg/* 4066df26cacSmrg *---------------------------------------------------------------------------- 4076df26cacSmrg * 4086df26cacSmrg * VMwareCtrlDispatch -- 4096df26cacSmrg * 4106df26cacSmrg * Dispatcher for VMWARE_CTRL commands. Calls the correct handler for 4116df26cacSmrg * each command type. 4126df26cacSmrg * 4136df26cacSmrg * Results: 4146df26cacSmrg * Standard response codes. 4156df26cacSmrg * 4166df26cacSmrg * Side effects: 4176df26cacSmrg * Side effects of individual command handlers. 4186df26cacSmrg * 4196df26cacSmrg *---------------------------------------------------------------------------- 4206df26cacSmrg */ 4216df26cacSmrg 4226df26cacSmrgstatic int 4236df26cacSmrgVMwareCtrlDispatch(ClientPtr client) 4246df26cacSmrg{ 4256df26cacSmrg REQUEST(xReq); 4266df26cacSmrg 4276df26cacSmrg switch(stuff->data) { 4286df26cacSmrg case X_VMwareCtrlQueryVersion: 4296df26cacSmrg return VMwareCtrlQueryVersion(client); 4306df26cacSmrg case X_VMwareCtrlSetRes: 4316df26cacSmrg return VMwareCtrlSetRes(client); 4326df26cacSmrg case X_VMwareCtrlSetTopology: 4336df26cacSmrg return VMwareCtrlSetTopology(client); 4346df26cacSmrg } 4356df26cacSmrg return BadRequest; 4366df26cacSmrg} 4376df26cacSmrg 4386df26cacSmrg 4396df26cacSmrg/* 4406df26cacSmrg *---------------------------------------------------------------------------- 4416df26cacSmrg * 4426df26cacSmrg * SVMwareCtrlQueryVersion -- 4436df26cacSmrg * 4446df26cacSmrg * Wrapper for QueryVersion handler that handles input from other-endian 4456df26cacSmrg * clients. 4466df26cacSmrg * 4476df26cacSmrg * Results: 4486df26cacSmrg * Standard response codes. 4496df26cacSmrg * 4506df26cacSmrg * Side effects: 4516df26cacSmrg * Side effects of unswapped implementation. 4526df26cacSmrg * 4536df26cacSmrg *---------------------------------------------------------------------------- 4546df26cacSmrg */ 4556df26cacSmrg 4566df26cacSmrgstatic int 4576df26cacSmrgSVMwareCtrlQueryVersion(ClientPtr client) 4586df26cacSmrg{ 4596df26cacSmrg register int n; 4606df26cacSmrg 4616df26cacSmrg REQUEST(xVMwareCtrlQueryVersionReq); 4626df26cacSmrg REQUEST_SIZE_MATCH(xVMwareCtrlQueryVersionReq); 4636df26cacSmrg 4646df26cacSmrg swaps(&stuff->length, n); 4656df26cacSmrg 4666df26cacSmrg return VMwareCtrlQueryVersion(client); 4676df26cacSmrg} 4686df26cacSmrg 4696df26cacSmrg 4706df26cacSmrg/* 4716df26cacSmrg *---------------------------------------------------------------------------- 4726df26cacSmrg * 4736df26cacSmrg * SVMwareCtrlSetRes -- 4746df26cacSmrg * 4756df26cacSmrg * Wrapper for SetRes handler that handles input from other-endian 4766df26cacSmrg * clients. 4776df26cacSmrg * 4786df26cacSmrg * Results: 4796df26cacSmrg * Standard response codes. 4806df26cacSmrg * 4816df26cacSmrg * Side effects: 4826df26cacSmrg * Side effects of unswapped implementation. 4836df26cacSmrg * 4846df26cacSmrg *---------------------------------------------------------------------------- 4856df26cacSmrg */ 4866df26cacSmrg 4876df26cacSmrgstatic int 4886df26cacSmrgSVMwareCtrlSetRes(ClientPtr client) 4896df26cacSmrg{ 4906df26cacSmrg register int n; 4916df26cacSmrg 4926df26cacSmrg REQUEST(xVMwareCtrlSetResReq); 4936df26cacSmrg REQUEST_SIZE_MATCH(xVMwareCtrlSetResReq); 4946df26cacSmrg 4956df26cacSmrg swaps(&stuff->length, n); 4966df26cacSmrg swapl(&stuff->screen, n); 4976df26cacSmrg swapl(&stuff->x, n); 4986df26cacSmrg swapl(&stuff->y, n); 4996df26cacSmrg 5006df26cacSmrg return VMwareCtrlSetRes(client); 5016df26cacSmrg} 5026df26cacSmrg 5036df26cacSmrg 5046df26cacSmrg/* 5056df26cacSmrg *---------------------------------------------------------------------------- 5066df26cacSmrg * 5076df26cacSmrg * SVMwareCtrlSetTopology -- 5086df26cacSmrg * 5096df26cacSmrg * Wrapper for SetTopology handler that handles input from other-endian 5106df26cacSmrg * clients. 5116df26cacSmrg * 5126df26cacSmrg * Results: 5136df26cacSmrg * Standard response codes. 5146df26cacSmrg * 5156df26cacSmrg * Side effects: 5166df26cacSmrg * Side effects of unswapped implementation. 5176df26cacSmrg * 5186df26cacSmrg *---------------------------------------------------------------------------- 5196df26cacSmrg */ 5206df26cacSmrg 5216df26cacSmrgstatic int 5226df26cacSmrgSVMwareCtrlSetTopology(ClientPtr client) 5236df26cacSmrg{ 5246df26cacSmrg register int n; 5256df26cacSmrg 5266df26cacSmrg REQUEST(xVMwareCtrlSetTopologyReq); 5276df26cacSmrg REQUEST_SIZE_MATCH(xVMwareCtrlSetTopologyReq); 5286df26cacSmrg 5296df26cacSmrg swaps(&stuff->length, n); 5306df26cacSmrg swapl(&stuff->screen, n); 5316df26cacSmrg swapl(&stuff->number, n); 5326df26cacSmrg /* Each extent is a struct of shorts. */ 5336df26cacSmrg SwapRestS(stuff); 5346df26cacSmrg 5356df26cacSmrg return VMwareCtrlSetTopology(client); 5366df26cacSmrg} 5376df26cacSmrg 5386df26cacSmrg 5396df26cacSmrg/* 5406df26cacSmrg *---------------------------------------------------------------------------- 5416df26cacSmrg * 5426df26cacSmrg * SVMwareCtrlDispatch -- 5436df26cacSmrg * 5446df26cacSmrg * Wrapper for dispatcher that handles input from other-endian clients. 5456df26cacSmrg * 5466df26cacSmrg * Results: 5476df26cacSmrg * Standard response codes. 5486df26cacSmrg * 5496df26cacSmrg * Side effects: 5506df26cacSmrg * Side effects of individual command handlers. 5516df26cacSmrg * 5526df26cacSmrg *---------------------------------------------------------------------------- 5536df26cacSmrg */ 5546df26cacSmrg 5556df26cacSmrgstatic int 5566df26cacSmrgSVMwareCtrlDispatch(ClientPtr client) 5576df26cacSmrg{ 5586df26cacSmrg REQUEST(xReq); 5596df26cacSmrg 5606df26cacSmrg switch(stuff->data) { 5616df26cacSmrg case X_VMwareCtrlQueryVersion: 5626df26cacSmrg return SVMwareCtrlQueryVersion(client); 5636df26cacSmrg case X_VMwareCtrlSetRes: 5646df26cacSmrg return SVMwareCtrlSetRes(client); 5656df26cacSmrg case X_VMwareCtrlSetTopology: 5666df26cacSmrg return SVMwareCtrlSetTopology(client); 5676df26cacSmrg } 5686df26cacSmrg return BadRequest; 5696df26cacSmrg} 5706df26cacSmrg 5716df26cacSmrg 5726df26cacSmrg/* 5736df26cacSmrg *---------------------------------------------------------------------------- 5746df26cacSmrg * 5756df26cacSmrg * VMwareCtrlResetProc -- 5766df26cacSmrg * 5776df26cacSmrg * Cleanup handler called when the extension is removed. 5786df26cacSmrg * 5796df26cacSmrg * Results: 5806df26cacSmrg * None 5816df26cacSmrg * 5826df26cacSmrg * Side effects: 5836df26cacSmrg * None 5846df26cacSmrg * 5856df26cacSmrg *---------------------------------------------------------------------------- 5866df26cacSmrg */ 5876df26cacSmrg 5886df26cacSmrgstatic void 5896df26cacSmrgVMwareCtrlResetProc(ExtensionEntry* extEntry) 5906df26cacSmrg{ 5916df26cacSmrg /* Currently, no cleanup is necessary. */ 5926df26cacSmrg} 5936df26cacSmrg 5946df26cacSmrg 5956df26cacSmrg/* 5966df26cacSmrg *---------------------------------------------------------------------------- 5976df26cacSmrg * 5986df26cacSmrg * VMwareCtrl_ExitInit -- 5996df26cacSmrg * 6006df26cacSmrg * Initialiser for the VMWARE_CTRL protocol extension. 6016df26cacSmrg * 6026df26cacSmrg * Results: 6036df26cacSmrg * None. 6046df26cacSmrg * 6056df26cacSmrg * Side effects: 6066df26cacSmrg * Protocol extension will be registered if successful. 6076df26cacSmrg * 6086df26cacSmrg *---------------------------------------------------------------------------- 6096df26cacSmrg */ 6106df26cacSmrg 6116df26cacSmrgvoid 6126df26cacSmrgVMwareCtrl_ExtInit(ScrnInfoPtr pScrn) 6136df26cacSmrg{ 6146df26cacSmrg ExtensionEntry *myext; 6156df26cacSmrg 6166df26cacSmrg if (!(myext = CheckExtension(VMWARE_CTRL_PROTOCOL_NAME))) { 6176df26cacSmrg if (!(myext = AddExtension(VMWARE_CTRL_PROTOCOL_NAME, 0, 0, 6186df26cacSmrg VMwareCtrlDispatch, 6196df26cacSmrg SVMwareCtrlDispatch, 6206df26cacSmrg VMwareCtrlResetProc, 6216df26cacSmrg StandardMinorOpcode))) { 6226df26cacSmrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 6236df26cacSmrg "Failed to add VMWARE_CTRL extension\n"); 6246df26cacSmrg return; 6256df26cacSmrg } 6266df26cacSmrg 6276df26cacSmrg /* 6286df26cacSmrg * For now, only support one screen as that's all the virtual 6296df26cacSmrg * hardware supports. 6306df26cacSmrg */ 6316df26cacSmrg myext->extPrivate = pScrn; 6326df26cacSmrg 6336df26cacSmrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 6346df26cacSmrg "Initialized VMWARE_CTRL extension version %d.%d\n", 6356df26cacSmrg VMWARE_CTRL_MAJOR_VERSION, VMWARE_CTRL_MINOR_VERSION); 6366df26cacSmrg } 6376df26cacSmrg} 638