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#include "dixstruct.h" 416df26cacSmrg#include "extnsionst.h" 423bfa90b6Smrg#include "randrstr.h" 436df26cacSmrg#include <X11/X.h> 446df26cacSmrg#include <X11/extensions/panoramiXproto.h> 456df26cacSmrg 466df26cacSmrg#include "vmware.h" 476df26cacSmrg#include "vmwarectrlproto.h" 486df26cacSmrg 49a241306cSmrg#ifndef HAVE_XORG_SERVER_1_5_0 50a241306cSmrg#include <xf86_ansic.h> 51a241306cSmrg#include <xf86_libc.h> 52a241306cSmrg#endif 536df26cacSmrg 546df26cacSmrg/* 556df26cacSmrg *---------------------------------------------------------------------------- 566df26cacSmrg * 576df26cacSmrg * VMwareCtrlQueryVersion -- 586df26cacSmrg * 596df26cacSmrg * Implementation of QueryVersion command handler. Initialises and 606df26cacSmrg * sends a reply. 616df26cacSmrg * 626df26cacSmrg * Results: 636df26cacSmrg * Standard response codes. 646df26cacSmrg * 656df26cacSmrg * Side effects: 666df26cacSmrg * Writes reply to client 676df26cacSmrg * 686df26cacSmrg *---------------------------------------------------------------------------- 696df26cacSmrg */ 706df26cacSmrg 716df26cacSmrgstatic int 726df26cacSmrgVMwareCtrlQueryVersion(ClientPtr client) 736df26cacSmrg{ 746df26cacSmrg xVMwareCtrlQueryVersionReply rep = { 0, }; 756df26cacSmrg register int n; 766df26cacSmrg 776df26cacSmrg REQUEST_SIZE_MATCH(xVMwareCtrlQueryVersionReq); 786df26cacSmrg 796df26cacSmrg rep.type = X_Reply; 806df26cacSmrg rep.length = 0; 816df26cacSmrg rep.sequenceNumber = client->sequence; 826df26cacSmrg rep.majorVersion = VMWARE_CTRL_MAJOR_VERSION; 836df26cacSmrg rep.minorVersion = VMWARE_CTRL_MINOR_VERSION; 846df26cacSmrg if (client->swapped) { 853bfa90b6Smrg _swaps(&rep.sequenceNumber, n); 863bfa90b6Smrg _swapl(&rep.length, n); 873bfa90b6Smrg _swapl(&rep.majorVersion, n); 883bfa90b6Smrg _swapl(&rep.minorVersion, n); 896df26cacSmrg } 906df26cacSmrg WriteToClient(client, sizeof(xVMwareCtrlQueryVersionReply), (char *)&rep); 916df26cacSmrg 926df26cacSmrg return client->noClientException; 936df26cacSmrg} 946df26cacSmrg 956df26cacSmrg 966df26cacSmrg/* 976df26cacSmrg *---------------------------------------------------------------------------- 986df26cacSmrg * 996df26cacSmrg * VMwareCtrlDoSetRes -- 1006df26cacSmrg * 1016df26cacSmrg * Set the custom resolution into the mode list. 1026df26cacSmrg * 1036df26cacSmrg * This is done by alternately updating one of two dynamic modes. It is 1046df26cacSmrg * done this way because the server gets upset if you try to switch 1056df26cacSmrg * to a new resolution that has the same index as the current one. 1066df26cacSmrg * 1076df26cacSmrg * Results: 1086df26cacSmrg * TRUE on success, FALSE otherwise. 1096df26cacSmrg * 1106df26cacSmrg * Side effects: 1116df26cacSmrg * One dynamic mode will be updated if successful. 1126df26cacSmrg * 1136df26cacSmrg *---------------------------------------------------------------------------- 1146df26cacSmrg */ 1156df26cacSmrg 1166df26cacSmrgstatic Bool 1176df26cacSmrgVMwareCtrlDoSetRes(ScrnInfoPtr pScrn, 1186df26cacSmrg CARD32 x, 1196df26cacSmrg CARD32 y, 1206df26cacSmrg Bool resetXinerama) 1216df26cacSmrg{ 12216fd1166Smrg int modeIndex; 1236df26cacSmrg DisplayModePtr mode; 1246df26cacSmrg VMWAREPtr pVMWARE = VMWAREPTR(pScrn); 1256df26cacSmrg 1266df26cacSmrg if (pScrn && pScrn->modes) { 1276df26cacSmrg VmwareLog(("DoSetRes: %d %d\n", x, y)); 12816fd1166Smrg 1296df26cacSmrg if (resetXinerama) { 130a241306cSmrg free(pVMWARE->xineramaNextState); 1316df26cacSmrg pVMWARE->xineramaNextState = NULL; 1326df26cacSmrg pVMWARE->xineramaNextNumOutputs = 0; 1336df26cacSmrg } 1346df26cacSmrg 13516fd1166Smrg /* 1366df26cacSmrg * Don't resize larger than possible but don't 1376df26cacSmrg * return an X Error either. 1386df26cacSmrg */ 1396df26cacSmrg if (x > pVMWARE->maxWidth || 1406df26cacSmrg y > pVMWARE->maxHeight) { 1416df26cacSmrg return TRUE; 1426df26cacSmrg } 1436df26cacSmrg 1446df26cacSmrg /* 14516fd1166Smrg * Find an dynamic mode which isn't current, and replace it with 14616fd1166Smrg * the requested mode. Normally this will cause us to alternate 14716fd1166Smrg * between two dynamic mode slots, but there are some important 14816fd1166Smrg * corner cases to consider. For example, adding the same mode 14916fd1166Smrg * multiple times, adding a mode that we never switch to, or 15016fd1166Smrg * adding a mode which is a duplicate of a built-in mode. The 15116fd1166Smrg * best way to handle all of these cases is to directly test the 15216fd1166Smrg * dynamic mode against the current mode pointer for this 15316fd1166Smrg * screen. 1546df26cacSmrg */ 1556df26cacSmrg 15616fd1166Smrg for (modeIndex = 0; modeIndex < NUM_DYN_MODES; modeIndex++) { 15716fd1166Smrg /* 15816fd1166Smrg * Initialise the dynamic mode if it hasn't been used before. 15916fd1166Smrg */ 16016fd1166Smrg if (!pVMWARE->dynModes[modeIndex]) { 16116fd1166Smrg pVMWARE->dynModes[modeIndex] = VMWAREAddDisplayMode(pScrn, "DynMode", 1, 1); 16216fd1166Smrg } 16316fd1166Smrg 16416fd1166Smrg mode = pVMWARE->dynModes[modeIndex]; 16516fd1166Smrg if (mode != pScrn->currentMode) { 16616fd1166Smrg break; 16716fd1166Smrg } 1686df26cacSmrg } 1696df26cacSmrg 1706df26cacSmrg mode->HDisplay = x; 1716df26cacSmrg mode->VDisplay = y; 1726df26cacSmrg 1736df26cacSmrg return TRUE; 1746df26cacSmrg } else { 1756df26cacSmrg return FALSE; 1766df26cacSmrg } 1776df26cacSmrg} 1786df26cacSmrg 1796df26cacSmrg 1806df26cacSmrg/* 1816df26cacSmrg *---------------------------------------------------------------------------- 1826df26cacSmrg * 1836df26cacSmrg * VMwareCtrlSetRes -- 1846df26cacSmrg * 1856df26cacSmrg * Implementation of SetRes command handler. Initialises and sends a 1866df26cacSmrg * reply. 1876df26cacSmrg * 1886df26cacSmrg * Results: 1896df26cacSmrg * Standard response codes. 1906df26cacSmrg * 1916df26cacSmrg * Side effects: 1926df26cacSmrg * Writes reply to client 1936df26cacSmrg * 1946df26cacSmrg *---------------------------------------------------------------------------- 1956df26cacSmrg */ 1966df26cacSmrg 1976df26cacSmrgstatic int 1986df26cacSmrgVMwareCtrlSetRes(ClientPtr client) 1996df26cacSmrg{ 2006df26cacSmrg REQUEST(xVMwareCtrlSetResReq); 2016df26cacSmrg xVMwareCtrlSetResReply rep = { 0, }; 2026df26cacSmrg ScrnInfoPtr pScrn; 2036df26cacSmrg ExtensionEntry *ext; 2046df26cacSmrg register int n; 2056df26cacSmrg 2066df26cacSmrg REQUEST_SIZE_MATCH(xVMwareCtrlSetResReq); 2076df26cacSmrg 2086df26cacSmrg if (!(ext = CheckExtension(VMWARE_CTRL_PROTOCOL_NAME))) { 2096df26cacSmrg return BadMatch; 2106df26cacSmrg } 2116df26cacSmrg 2126df26cacSmrg pScrn = ext->extPrivate; 2136df26cacSmrg if (pScrn->scrnIndex != stuff->screen) { 2146df26cacSmrg return BadMatch; 2156df26cacSmrg } 2166df26cacSmrg 2176df26cacSmrg if (!VMwareCtrlDoSetRes(pScrn, stuff->x, stuff->y, TRUE)) { 2186df26cacSmrg return BadValue; 2196df26cacSmrg } 2206df26cacSmrg 2216df26cacSmrg rep.type = X_Reply; 2226df26cacSmrg rep.length = (sizeof(xVMwareCtrlSetResReply) - sizeof(xGenericReply)) >> 2; 2236df26cacSmrg rep.sequenceNumber = client->sequence; 2246df26cacSmrg rep.screen = stuff->screen; 2256df26cacSmrg rep.x = stuff->x; 2266df26cacSmrg rep.y = stuff->y; 2276df26cacSmrg if (client->swapped) { 2283bfa90b6Smrg _swaps(&rep.sequenceNumber, n); 2293bfa90b6Smrg _swapl(&rep.length, n); 2303bfa90b6Smrg _swapl(&rep.screen, n); 2313bfa90b6Smrg _swapl(&rep.x, n); 2323bfa90b6Smrg _swapl(&rep.y, n); 2336df26cacSmrg } 2346df26cacSmrg WriteToClient(client, sizeof(xVMwareCtrlSetResReply), (char *)&rep); 2356df26cacSmrg 2366df26cacSmrg return client->noClientException; 2376df26cacSmrg} 2386df26cacSmrg 2396df26cacSmrg 2406df26cacSmrg/* 2416df26cacSmrg *---------------------------------------------------------------------------- 2426df26cacSmrg * 2436df26cacSmrg * VMwareCtrlDoSetTopology -- 2446df26cacSmrg * 2456df26cacSmrg * Set the custom topology and set a dynamic mode to the bounding box 2466df26cacSmrg * of the passed topology. If a topology is already pending, then do 2476df26cacSmrg * nothing but do not return failure. 2486df26cacSmrg * 2496df26cacSmrg * Results: 2506df26cacSmrg * TRUE on success, FALSE otherwise. 2516df26cacSmrg * 2526df26cacSmrg * Side effects: 2536df26cacSmrg * One dynamic mode and the pending xinerama state will be updated if 2546df26cacSmrg * successful. 2556df26cacSmrg * 2566df26cacSmrg *---------------------------------------------------------------------------- 2576df26cacSmrg */ 2586df26cacSmrg 2596df26cacSmrgstatic Bool 2606df26cacSmrgVMwareCtrlDoSetTopology(ScrnInfoPtr pScrn, 2616df26cacSmrg xXineramaScreenInfo *extents, 2626df26cacSmrg unsigned long number) 2636df26cacSmrg{ 2646df26cacSmrg VMWAREPtr pVMWARE = VMWAREPTR(pScrn); 2656df26cacSmrg 2666df26cacSmrg if (pVMWARE && pVMWARE->xinerama) { 2676df26cacSmrg VMWAREXineramaPtr xineramaState; 2686df26cacSmrg short maxX = 0; 2696df26cacSmrg short maxY = 0; 2706df26cacSmrg size_t i; 2716df26cacSmrg 2726df26cacSmrg if (pVMWARE->xineramaNextState) { 2736df26cacSmrg VmwareLog(("DoSetTopology: Aborting due to existing pending state\n")); 2746df26cacSmrg return TRUE; 2756df26cacSmrg } 2766df26cacSmrg 2776df26cacSmrg for (i = 0; i < number; i++) { 2786df26cacSmrg maxX = MAX(maxX, extents[i].x_org + extents[i].width); 2796df26cacSmrg maxY = MAX(maxY, extents[i].y_org + extents[i].height); 2806df26cacSmrg } 2816df26cacSmrg 2826df26cacSmrg VmwareLog(("DoSetTopology: %d %d\n", maxX, maxY)); 2836df26cacSmrg 284a241306cSmrg xineramaState = (VMWAREXineramaPtr)calloc(number, sizeof(VMWAREXineramaRec)); 2856df26cacSmrg if (xineramaState) { 2866df26cacSmrg memcpy(xineramaState, extents, number * sizeof (VMWAREXineramaRec)); 2876df26cacSmrg 2882e8abef9Smrg /* 2892e8abef9Smrg * Make this the new pending Xinerama state. Normally we'll 2902e8abef9Smrg * wait until the next mode switch in order to synchronously 2912e8abef9Smrg * push this state out to X clients and the virtual hardware. 2922e8abef9Smrg * 2932e8abef9Smrg * However, if we're already in the right video mode, there 2942e8abef9Smrg * will be no mode change. In this case, push it out 2952e8abef9Smrg * immediately. 2962e8abef9Smrg */ 297a241306cSmrg free(pVMWARE->xineramaNextState); 2986df26cacSmrg pVMWARE->xineramaNextState = xineramaState; 2996df26cacSmrg pVMWARE->xineramaNextNumOutputs = number; 3006df26cacSmrg 3012e8abef9Smrg if (maxX == pVMWARE->ModeReg.svga_reg_width && 3022e8abef9Smrg maxY == pVMWARE->ModeReg.svga_reg_height) { 3032e8abef9Smrg 3043bfa90b6Smrg /* 3053bfa90b6Smrg * The annoyance here is that when we reprogram the 3063bfa90b6Smrg * SVGA device's monitor topology registers, it may 3073bfa90b6Smrg * rearrange those monitors on the host's screen, but they 3083bfa90b6Smrg * will still have the old contents. This might be 3093bfa90b6Smrg * correct, but it isn't guaranteed to match what's on X's 3103bfa90b6Smrg * framebuffer at the moment. So we'll send a 3113bfa90b6Smrg * full-framebuffer update rect afterwards. 3123bfa90b6Smrg */ 3132e8abef9Smrg 3142e8abef9Smrg vmwareNextXineramaState(pVMWARE); 3153bfa90b6Smrg#ifdef HAVE_XORG_SERVER_1_2_0 3163bfa90b6Smrg RRSendConfigNotify(pScrn->pScreen); 3173bfa90b6Smrg#endif 3182e8abef9Smrg vmwareSendSVGACmdUpdateFullScreen(pVMWARE); 3192e8abef9Smrg 3202e8abef9Smrg return TRUE; 3212e8abef9Smrg } else { 3222e8abef9Smrg return VMwareCtrlDoSetRes(pScrn, maxX, maxY, FALSE); 3232e8abef9Smrg } 3242e8abef9Smrg 3256df26cacSmrg } else { 3266df26cacSmrg return FALSE; 3276df26cacSmrg } 3286df26cacSmrg } else { 3296df26cacSmrg return FALSE; 3306df26cacSmrg } 3316df26cacSmrg} 3326df26cacSmrg 3336df26cacSmrg 3346df26cacSmrg/* 3356df26cacSmrg *---------------------------------------------------------------------------- 3366df26cacSmrg * 3376df26cacSmrg * VMwareCtrlSetTopology -- 3386df26cacSmrg * 3396df26cacSmrg * Implementation of SetTopology command handler. Initialises and sends a 3406df26cacSmrg * reply. 3416df26cacSmrg * 3426df26cacSmrg * Results: 3436df26cacSmrg * Standard response codes. 3446df26cacSmrg * 3456df26cacSmrg * Side effects: 3466df26cacSmrg * Writes reply to client 3476df26cacSmrg * 3486df26cacSmrg *---------------------------------------------------------------------------- 3496df26cacSmrg */ 3506df26cacSmrg 3516df26cacSmrgstatic int 3526df26cacSmrgVMwareCtrlSetTopology(ClientPtr client) 3536df26cacSmrg{ 3546df26cacSmrg REQUEST(xVMwareCtrlSetTopologyReq); 3556df26cacSmrg xVMwareCtrlSetTopologyReply rep = { 0, }; 3566df26cacSmrg ScrnInfoPtr pScrn; 3576df26cacSmrg ExtensionEntry *ext; 3586df26cacSmrg register int n; 3596df26cacSmrg xXineramaScreenInfo *extents; 3606df26cacSmrg 3616df26cacSmrg REQUEST_AT_LEAST_SIZE(xVMwareCtrlSetTopologyReq); 3626df26cacSmrg 3636df26cacSmrg if (!(ext = CheckExtension(VMWARE_CTRL_PROTOCOL_NAME))) { 3646df26cacSmrg return BadMatch; 3656df26cacSmrg } 3666df26cacSmrg 3676df26cacSmrg pScrn = ext->extPrivate; 3686df26cacSmrg if (pScrn->scrnIndex != stuff->screen) { 3696df26cacSmrg return BadMatch; 3706df26cacSmrg } 3716df26cacSmrg 3726df26cacSmrg extents = (xXineramaScreenInfo *)(stuff + 1); 3736df26cacSmrg if (!VMwareCtrlDoSetTopology(pScrn, extents, stuff->number)) { 3746df26cacSmrg return BadValue; 3756df26cacSmrg } 3766df26cacSmrg 3776df26cacSmrg rep.type = X_Reply; 3786df26cacSmrg rep.length = (sizeof(xVMwareCtrlSetTopologyReply) - sizeof(xGenericReply)) >> 2; 3796df26cacSmrg rep.sequenceNumber = client->sequence; 3806df26cacSmrg rep.screen = stuff->screen; 3816df26cacSmrg if (client->swapped) { 3823bfa90b6Smrg _swaps(&rep.sequenceNumber, n); 3833bfa90b6Smrg _swapl(&rep.length, n); 3843bfa90b6Smrg _swapl(&rep.screen, n); 3856df26cacSmrg } 3866df26cacSmrg WriteToClient(client, sizeof(xVMwareCtrlSetTopologyReply), (char *)&rep); 3876df26cacSmrg 3886df26cacSmrg return client->noClientException; 3896df26cacSmrg} 3906df26cacSmrg 3916df26cacSmrg 3926df26cacSmrg/* 3936df26cacSmrg *---------------------------------------------------------------------------- 3946df26cacSmrg * 3956df26cacSmrg * VMwareCtrlDispatch -- 3966df26cacSmrg * 3976df26cacSmrg * Dispatcher for VMWARE_CTRL commands. Calls the correct handler for 3986df26cacSmrg * each command type. 3996df26cacSmrg * 4006df26cacSmrg * Results: 4016df26cacSmrg * Standard response codes. 4026df26cacSmrg * 4036df26cacSmrg * Side effects: 4046df26cacSmrg * Side effects of individual command handlers. 4056df26cacSmrg * 4066df26cacSmrg *---------------------------------------------------------------------------- 4076df26cacSmrg */ 4086df26cacSmrg 4096df26cacSmrgstatic int 4106df26cacSmrgVMwareCtrlDispatch(ClientPtr client) 4116df26cacSmrg{ 4126df26cacSmrg REQUEST(xReq); 4136df26cacSmrg 4146df26cacSmrg switch(stuff->data) { 4156df26cacSmrg case X_VMwareCtrlQueryVersion: 4166df26cacSmrg return VMwareCtrlQueryVersion(client); 4176df26cacSmrg case X_VMwareCtrlSetRes: 4186df26cacSmrg return VMwareCtrlSetRes(client); 4196df26cacSmrg case X_VMwareCtrlSetTopology: 4206df26cacSmrg return VMwareCtrlSetTopology(client); 4216df26cacSmrg } 4226df26cacSmrg return BadRequest; 4236df26cacSmrg} 4246df26cacSmrg 4256df26cacSmrg 4266df26cacSmrg/* 4276df26cacSmrg *---------------------------------------------------------------------------- 4286df26cacSmrg * 4296df26cacSmrg * SVMwareCtrlQueryVersion -- 4306df26cacSmrg * 4316df26cacSmrg * Wrapper for QueryVersion handler that handles input from other-endian 4326df26cacSmrg * clients. 4336df26cacSmrg * 4346df26cacSmrg * Results: 4356df26cacSmrg * Standard response codes. 4366df26cacSmrg * 4376df26cacSmrg * Side effects: 4386df26cacSmrg * Side effects of unswapped implementation. 4396df26cacSmrg * 4406df26cacSmrg *---------------------------------------------------------------------------- 4416df26cacSmrg */ 4426df26cacSmrg 4436df26cacSmrgstatic int 4446df26cacSmrgSVMwareCtrlQueryVersion(ClientPtr client) 4456df26cacSmrg{ 4466df26cacSmrg register int n; 4476df26cacSmrg 4486df26cacSmrg REQUEST(xVMwareCtrlQueryVersionReq); 4496df26cacSmrg REQUEST_SIZE_MATCH(xVMwareCtrlQueryVersionReq); 4506df26cacSmrg 4513bfa90b6Smrg _swaps(&stuff->length, n); 4526df26cacSmrg 4536df26cacSmrg return VMwareCtrlQueryVersion(client); 4546df26cacSmrg} 4556df26cacSmrg 4566df26cacSmrg 4576df26cacSmrg/* 4586df26cacSmrg *---------------------------------------------------------------------------- 4596df26cacSmrg * 4606df26cacSmrg * SVMwareCtrlSetRes -- 4616df26cacSmrg * 4626df26cacSmrg * Wrapper for SetRes handler that handles input from other-endian 4636df26cacSmrg * clients. 4646df26cacSmrg * 4656df26cacSmrg * Results: 4666df26cacSmrg * Standard response codes. 4676df26cacSmrg * 4686df26cacSmrg * Side effects: 4696df26cacSmrg * Side effects of unswapped implementation. 4706df26cacSmrg * 4716df26cacSmrg *---------------------------------------------------------------------------- 4726df26cacSmrg */ 4736df26cacSmrg 4746df26cacSmrgstatic int 4756df26cacSmrgSVMwareCtrlSetRes(ClientPtr client) 4766df26cacSmrg{ 4776df26cacSmrg register int n; 4786df26cacSmrg 4796df26cacSmrg REQUEST(xVMwareCtrlSetResReq); 4806df26cacSmrg REQUEST_SIZE_MATCH(xVMwareCtrlSetResReq); 4816df26cacSmrg 4823bfa90b6Smrg _swaps(&stuff->length, n); 4833bfa90b6Smrg _swapl(&stuff->screen, n); 4843bfa90b6Smrg _swapl(&stuff->x, n); 4853bfa90b6Smrg _swapl(&stuff->y, n); 4866df26cacSmrg 4876df26cacSmrg return VMwareCtrlSetRes(client); 4886df26cacSmrg} 4896df26cacSmrg 4906df26cacSmrg 4916df26cacSmrg/* 4926df26cacSmrg *---------------------------------------------------------------------------- 4936df26cacSmrg * 4946df26cacSmrg * SVMwareCtrlSetTopology -- 4956df26cacSmrg * 4966df26cacSmrg * Wrapper for SetTopology handler that handles input from other-endian 4976df26cacSmrg * clients. 4986df26cacSmrg * 4996df26cacSmrg * Results: 5006df26cacSmrg * Standard response codes. 5016df26cacSmrg * 5026df26cacSmrg * Side effects: 5036df26cacSmrg * Side effects of unswapped implementation. 5046df26cacSmrg * 5056df26cacSmrg *---------------------------------------------------------------------------- 5066df26cacSmrg */ 5076df26cacSmrg 5086df26cacSmrgstatic int 5096df26cacSmrgSVMwareCtrlSetTopology(ClientPtr client) 5106df26cacSmrg{ 5116df26cacSmrg register int n; 5126df26cacSmrg 5136df26cacSmrg REQUEST(xVMwareCtrlSetTopologyReq); 5146df26cacSmrg REQUEST_SIZE_MATCH(xVMwareCtrlSetTopologyReq); 5156df26cacSmrg 5163bfa90b6Smrg _swaps(&stuff->length, n); 5173bfa90b6Smrg _swapl(&stuff->screen, n); 5183bfa90b6Smrg _swapl(&stuff->number, n); 5196df26cacSmrg /* Each extent is a struct of shorts. */ 5206df26cacSmrg SwapRestS(stuff); 5216df26cacSmrg 5226df26cacSmrg return VMwareCtrlSetTopology(client); 5236df26cacSmrg} 5246df26cacSmrg 5256df26cacSmrg 5266df26cacSmrg/* 5276df26cacSmrg *---------------------------------------------------------------------------- 5286df26cacSmrg * 5296df26cacSmrg * SVMwareCtrlDispatch -- 5306df26cacSmrg * 5316df26cacSmrg * Wrapper for dispatcher that handles input from other-endian clients. 5326df26cacSmrg * 5336df26cacSmrg * Results: 5346df26cacSmrg * Standard response codes. 5356df26cacSmrg * 5366df26cacSmrg * Side effects: 5376df26cacSmrg * Side effects of individual command handlers. 5386df26cacSmrg * 5396df26cacSmrg *---------------------------------------------------------------------------- 5406df26cacSmrg */ 5416df26cacSmrg 5426df26cacSmrgstatic int 5436df26cacSmrgSVMwareCtrlDispatch(ClientPtr client) 5446df26cacSmrg{ 5456df26cacSmrg REQUEST(xReq); 5466df26cacSmrg 5476df26cacSmrg switch(stuff->data) { 5486df26cacSmrg case X_VMwareCtrlQueryVersion: 5496df26cacSmrg return SVMwareCtrlQueryVersion(client); 5506df26cacSmrg case X_VMwareCtrlSetRes: 5516df26cacSmrg return SVMwareCtrlSetRes(client); 5526df26cacSmrg case X_VMwareCtrlSetTopology: 5536df26cacSmrg return SVMwareCtrlSetTopology(client); 5546df26cacSmrg } 5556df26cacSmrg return BadRequest; 5566df26cacSmrg} 5576df26cacSmrg 5586df26cacSmrg 5596df26cacSmrg/* 5606df26cacSmrg *---------------------------------------------------------------------------- 5616df26cacSmrg * 5626df26cacSmrg * VMwareCtrlResetProc -- 5636df26cacSmrg * 5646df26cacSmrg * Cleanup handler called when the extension is removed. 5656df26cacSmrg * 5666df26cacSmrg * Results: 5676df26cacSmrg * None 5686df26cacSmrg * 5696df26cacSmrg * Side effects: 5706df26cacSmrg * None 5716df26cacSmrg * 5726df26cacSmrg *---------------------------------------------------------------------------- 5736df26cacSmrg */ 5746df26cacSmrg 5756df26cacSmrgstatic void 5766df26cacSmrgVMwareCtrlResetProc(ExtensionEntry* extEntry) 5776df26cacSmrg{ 5786df26cacSmrg /* Currently, no cleanup is necessary. */ 5796df26cacSmrg} 5806df26cacSmrg 5816df26cacSmrg 5826df26cacSmrg/* 5836df26cacSmrg *---------------------------------------------------------------------------- 5846df26cacSmrg * 5856df26cacSmrg * VMwareCtrl_ExitInit -- 5866df26cacSmrg * 5876df26cacSmrg * Initialiser for the VMWARE_CTRL protocol extension. 5886df26cacSmrg * 5896df26cacSmrg * Results: 5906df26cacSmrg * None. 5916df26cacSmrg * 5926df26cacSmrg * Side effects: 5936df26cacSmrg * Protocol extension will be registered if successful. 5946df26cacSmrg * 5956df26cacSmrg *---------------------------------------------------------------------------- 5966df26cacSmrg */ 5976df26cacSmrg 5986df26cacSmrgvoid 5996df26cacSmrgVMwareCtrl_ExtInit(ScrnInfoPtr pScrn) 6006df26cacSmrg{ 6016df26cacSmrg ExtensionEntry *myext; 6026df26cacSmrg 6036df26cacSmrg if (!(myext = CheckExtension(VMWARE_CTRL_PROTOCOL_NAME))) { 6046df26cacSmrg if (!(myext = AddExtension(VMWARE_CTRL_PROTOCOL_NAME, 0, 0, 6056df26cacSmrg VMwareCtrlDispatch, 6066df26cacSmrg SVMwareCtrlDispatch, 6076df26cacSmrg VMwareCtrlResetProc, 6086df26cacSmrg StandardMinorOpcode))) { 6096df26cacSmrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 6106df26cacSmrg "Failed to add VMWARE_CTRL extension\n"); 6116df26cacSmrg return; 6126df26cacSmrg } 6136df26cacSmrg 6146df26cacSmrg /* 6156df26cacSmrg * For now, only support one screen as that's all the virtual 6166df26cacSmrg * hardware supports. 6176df26cacSmrg */ 6186df26cacSmrg myext->extPrivate = pScrn; 6196df26cacSmrg 6206df26cacSmrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 6216df26cacSmrg "Initialized VMWARE_CTRL extension version %d.%d\n", 6226df26cacSmrg VMWARE_CTRL_MAJOR_VERSION, VMWARE_CTRL_MINOR_VERSION); 6236df26cacSmrg } 6246df26cacSmrg} 625