Edit

IABSD.fr/xenocara/driver/xf86-video-vmware/src/vmwarectrl.c

Branch :

  • Show log

    Commit

  • Author : matthieu
    Date : 2006-11-26 20:20:56
    Hash : a8df3806
    Message : Importing xf86-video-vmware 10.14.0

  • driver/xf86-video-vmware/src/vmwarectrl.c
  • /*
     * 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).
     */
    
    /*
     * vmwarectrl.c --
     *
     *      The implementation of the VMWARE_CTRL protocol extension that
     *      allows X clients to communicate with the driver.
     */
    
    
    #ifdef HAVE_CONFIG_H
    #include "config.h"
    #endif
    
    #define NEED_REPLIES
    #define NEED_EVENTS
    #include "dixstruct.h"
    #include "extnsionst.h"
    #include <X11/X.h>
    #include <X11/extensions/panoramiXproto.h>
    
    #include "vmware.h"
    #include "vmwarectrlproto.h"
    
    
    /*
     *----------------------------------------------------------------------------
     *
     * VMwareCtrlQueryVersion --
     *
     *      Implementation of QueryVersion command handler. Initialises and
     *      sends a reply.
     *
     * Results:
     *      Standard response codes.
     *
     * Side effects:
     *      Writes reply to client
     *
     *----------------------------------------------------------------------------
     */
    
    static int
    VMwareCtrlQueryVersion(ClientPtr client)
    {
       xVMwareCtrlQueryVersionReply rep = { 0, };
       register int n;
    
       REQUEST_SIZE_MATCH(xVMwareCtrlQueryVersionReq);
    
       rep.type = X_Reply;
       rep.length = 0;
       rep.sequenceNumber = client->sequence;
       rep.majorVersion = VMWARE_CTRL_MAJOR_VERSION;
       rep.minorVersion = VMWARE_CTRL_MINOR_VERSION;
       if (client->swapped) {
          swaps(&rep.sequenceNumber, n);
          swapl(&rep.length, n);
          swapl(&rep.majorVersion, n);
          swapl(&rep.minorVersion, n);
       }
       WriteToClient(client, sizeof(xVMwareCtrlQueryVersionReply), (char *)&rep);
    
       return client->noClientException;
    }
    
    
    /*
     *----------------------------------------------------------------------------
     *
     * VMwareCtrlDoSetRes --
     *
     *      Set the custom resolution into the mode list.
     *
     *      This is done by alternately updating one of two dynamic modes. It is
     *      done this way because the server gets upset if you try to switch
     *      to a new resolution that has the same index as the current one.
     *
     * Results:
     *      TRUE on success, FALSE otherwise.
     *
     * Side effects:
     *      One dynamic mode will be updated if successful.
     *
     *----------------------------------------------------------------------------
     */
    
    static Bool
    VMwareCtrlDoSetRes(ScrnInfoPtr pScrn,
                       CARD32 x,
                       CARD32 y)
    {
       DisplayModePtr mode;
       VMWAREPtr pVMWARE = VMWAREPTR(pScrn);
      
       if (pScrn && pScrn->modes) {
          /* 
           * Don't resize larger than possible but don't
           * return an X Error either.
           */
          if (x > pVMWARE->initialMode->HDisplay ||
              y > pVMWARE->initialMode->VDisplay) {
             return TRUE;
          }
    
          /*
           * Switch the dynamic modes so that we alternate
           * which one gets updated on each call.
           */
          mode = pVMWARE->dynMode1;
          pVMWARE->dynMode1 = pVMWARE->dynMode2;
          pVMWARE->dynMode2 = mode;
    
          /*
           * Initialise the dynamic mode if it hasn't been used before.
           */
          if (!pVMWARE->dynMode1) {
             pVMWARE->dynMode1 = VMWAREAddDisplayMode(pScrn, "DynMode", 1, 1);
          }
          mode = pVMWARE->dynMode1;
    
          mode->HDisplay = x;
          mode->VDisplay = y;
    
          return TRUE;
       } else {
          return FALSE;
       }
    }
    
    
    /*
     *----------------------------------------------------------------------------
     *
     * VMwareCtrlSetRes --
     *
     *      Implementation of SetRes command handler. Initialises and sends a
     *      reply.
     *
     * Results:
     *      Standard response codes.
     *
     * Side effects:
     *      Writes reply to client
     *
     *----------------------------------------------------------------------------
     */
    
    static int
    VMwareCtrlSetRes(ClientPtr client)
    {
       REQUEST(xVMwareCtrlSetResReq);
       xVMwareCtrlSetResReply rep = { 0, };
       ScrnInfoPtr pScrn;
       ExtensionEntry *ext;
       register int n;
    
       REQUEST_SIZE_MATCH(xVMwareCtrlSetResReq);
    
       if (!(ext = CheckExtension(VMWARE_CTRL_PROTOCOL_NAME))) {
          return BadMatch;
       }
    
       pScrn = ext->extPrivate;
       if (pScrn->scrnIndex != stuff->screen) {
          return BadMatch;
       }
    
       if (!VMwareCtrlDoSetRes(pScrn, stuff->x, stuff->y)) {
          return BadValue;
       }
    
       rep.type = X_Reply;
       rep.length = (sizeof(xVMwareCtrlSetResReply) - sizeof(xGenericReply)) >> 2;
       rep.sequenceNumber = client->sequence;
       rep.screen = stuff->screen;
       rep.x = stuff->x;
       rep.y = stuff->y;
       if (client->swapped) {
          swaps(&rep.sequenceNumber, n);
          swapl(&rep.length, n);
          swapl(&rep.screen, n);
          swapl(&rep.x, n);
          swapl(&rep.y, n);
       }
       WriteToClient(client, sizeof(xVMwareCtrlSetResReply), (char *)&rep);
    
       return client->noClientException;
    }
    
    
    /*
     *----------------------------------------------------------------------------
     *
     * 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
     *      each command type.
     *
     * Results:
     *      Standard response codes.
     *
     * Side effects:
     *      Side effects of individual command handlers.
     *
     *----------------------------------------------------------------------------
     */
    
    static int
    VMwareCtrlDispatch(ClientPtr client)
    {
       REQUEST(xReq);
    
       switch(stuff->data) {
       case X_VMwareCtrlQueryVersion:
          return VMwareCtrlQueryVersion(client);
       case X_VMwareCtrlSetRes:
          return VMwareCtrlSetRes(client);
       case X_VMwareCtrlSetTopology:
          return VMwareCtrlSetTopology(client);
       }
       return BadRequest;
    }
    
    
    /*
     *----------------------------------------------------------------------------
     *
     * SVMwareCtrlQueryVersion --
     *
     *      Wrapper for QueryVersion handler that handles input from other-endian
     *      clients.
     *
     * Results:
     *      Standard response codes.
     *
     * Side effects:
     *      Side effects of unswapped implementation.
     *
     *----------------------------------------------------------------------------
     */
    
    static int
    SVMwareCtrlQueryVersion(ClientPtr client)
    {
       register int n;
    
       REQUEST(xVMwareCtrlQueryVersionReq);
       REQUEST_SIZE_MATCH(xVMwareCtrlQueryVersionReq);
    
       swaps(&stuff->length, n);
    
       return VMwareCtrlQueryVersion(client);
    }
    
    
    /*
     *----------------------------------------------------------------------------
     *
     * SVMwareCtrlSetRes --
     *
     *      Wrapper for SetRes handler that handles input from other-endian
     *      clients.
     *
     * Results:
     *      Standard response codes.
     *
     * Side effects:
     *      Side effects of unswapped implementation.
     *
     *----------------------------------------------------------------------------
     */
    
    static int
    SVMwareCtrlSetRes(ClientPtr client)
    {
       register int n;
    
       REQUEST(xVMwareCtrlSetResReq);
       REQUEST_SIZE_MATCH(xVMwareCtrlSetResReq);
    
       swaps(&stuff->length, n);
       swapl(&stuff->screen, n);
       swapl(&stuff->x, n);
       swapl(&stuff->y, n);
    
       return VMwareCtrlSetRes(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.
     *
     * Results:
     *      Standard response codes.
     *
     * Side effects:
     *      Side effects of individual command handlers.
     *
     *----------------------------------------------------------------------------
     */
    
    static int
    SVMwareCtrlDispatch(ClientPtr client)
    {
       REQUEST(xReq);
    
       switch(stuff->data) {
       case X_VMwareCtrlQueryVersion:
          return SVMwareCtrlQueryVersion(client);
       case X_VMwareCtrlSetRes:
          return SVMwareCtrlSetRes(client);
       case X_VMwareCtrlSetTopology:
          return SVMwareCtrlSetTopology(client);
       }
       return BadRequest;
    }
    
    
    /*
     *----------------------------------------------------------------------------
     *
     * VMwareCtrlResetProc --
     *
     *      Cleanup handler called when the extension is removed.
     *
     * Results:
     *      None
     *
     * Side effects:
     *      None
     *
     *----------------------------------------------------------------------------
     */
    
    static void
    VMwareCtrlResetProc(ExtensionEntry* extEntry)
    {
       /* Currently, no cleanup is necessary. */
    }
    
    
    /*
     *----------------------------------------------------------------------------
     *
     * VMwareCtrl_ExitInit --
     *
     *      Initialiser for the VMWARE_CTRL protocol extension.
     *
     * Results:
     *      None.
     *
     * Side effects:
     *      Protocol extension will be registered if successful.
     *
     *----------------------------------------------------------------------------
     */
    
    void
    VMwareCtrl_ExtInit(ScrnInfoPtr pScrn)
    {
       ExtensionEntry *myext;
    
       if (!(myext = CheckExtension(VMWARE_CTRL_PROTOCOL_NAME))) {
          if (!(myext = AddExtension(VMWARE_CTRL_PROTOCOL_NAME, 0, 0,
                                     VMwareCtrlDispatch,
                                     SVMwareCtrlDispatch,
                                     VMwareCtrlResetProc,
                                     StandardMinorOpcode))) {
             xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
                        "Failed to add VMWARE_CTRL extension\n");
    	 return;
          }
    
          /*
           * For now, only support one screen as that's all the virtual
           * hardware supports.
           */
          myext->extPrivate = pScrn;
    
          xf86DrvMsg(pScrn->scrnIndex, X_INFO,
                     "Initialized VMWARE_CTRL extension version %d.%d\n",
                     VMWARE_CTRL_MAJOR_VERSION, VMWARE_CTRL_MINOR_VERSION);
       }
    }