vmmouse.c revision 9bd41f2c
19bd41f2cSmrg/*
29bd41f2cSmrg * Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany.
39bd41f2cSmrg * Copyright 1993 by David Dawes <dawes@xfree86.org>
49bd41f2cSmrg * Copyright 2002 by SuSE Linux AG, Author: Egbert Eich
59bd41f2cSmrg * Copyright 1994-2002 by The XFree86 Project, Inc.
69bd41f2cSmrg * Copyright 2002 by Paul Elliott
79bd41f2cSmrg * Copyright 2002-2006 by VMware, Inc.
89bd41f2cSmrg *
99bd41f2cSmrg * Permission to use, copy, modify, distribute, and sell this software and its
109bd41f2cSmrg * documentation for any purpose is hereby granted without fee, provided that
119bd41f2cSmrg * the above copyright notice appear in all copies and that both that
129bd41f2cSmrg * copyright notice and this permission notice appear in supporting
139bd41f2cSmrg * documentation, and that the names of copyright holders not be
149bd41f2cSmrg * used in advertising or publicity pertaining to distribution of the
159bd41f2cSmrg * software without specific, written prior permission.  The copyright holders
169bd41f2cSmrg * make no representations about the suitability of this
179bd41f2cSmrg * software for any purpose.  It is provided "as is" without express or
189bd41f2cSmrg * implied warranty.
199bd41f2cSmrg *
209bd41f2cSmrg * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
219bd41f2cSmrg * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
229bd41f2cSmrg * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
239bd41f2cSmrg * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
249bd41f2cSmrg * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
259bd41f2cSmrg * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
269bd41f2cSmrg * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
279bd41f2cSmrg *
289bd41f2cSmrg */
299bd41f2cSmrg
309bd41f2cSmrg/*
319bd41f2cSmrg * vmmouse.c --
329bd41f2cSmrg *
339bd41f2cSmrg * 	This is a modified version of the mouse input driver
349bd41f2cSmrg * 	provided in Xserver/hw/xfree86/input/mouse/mouse.c
359bd41f2cSmrg *
369bd41f2cSmrg *      Although all data is read using the vmmouse protocol, notification
379bd41f2cSmrg *      is still done through the PS/2 port, so all the basic code for
389bd41f2cSmrg *      interacting with the port is retained.
399bd41f2cSmrg *
409bd41f2cSmrg */
419bd41f2cSmrg
429bd41f2cSmrg
439bd41f2cSmrg/*****************************************************************************
449bd41f2cSmrg *	Standard Headers
459bd41f2cSmrg ****************************************************************************/
469bd41f2cSmrg#ifdef HAVE_CONFIG_H
479bd41f2cSmrg#include "config.h"
489bd41f2cSmrg#endif
499bd41f2cSmrg
509bd41f2cSmrg#include <stdio.h>
519bd41f2cSmrg#define NEED_EVENTS
529bd41f2cSmrg#include <X11/X.h>
539bd41f2cSmrg#include <X11/Xproto.h>
549bd41f2cSmrg
559bd41f2cSmrg#include "xf86.h"
569bd41f2cSmrg
579bd41f2cSmrg#ifdef XINPUT
589bd41f2cSmrg#include <X11/extensions/XI.h>
599bd41f2cSmrg#include <X11/extensions/XIproto.h>
609bd41f2cSmrg#include "extnsionst.h"
619bd41f2cSmrg#include "extinit.h"
629bd41f2cSmrg#else
639bd41f2cSmrg#include "inputstr.h"
649bd41f2cSmrg#endif
659bd41f2cSmrg
669bd41f2cSmrg#include "xf86Xinput.h"
679bd41f2cSmrg#include "xf86_OSproc.h"
689bd41f2cSmrg#include "xf86OSmouse.h"
699bd41f2cSmrg#include "compiler.h"
709bd41f2cSmrg
719bd41f2cSmrg#include "xisb.h"
729bd41f2cSmrg#include "mipointer.h"
739bd41f2cSmrg
749bd41f2cSmrg/*****************************************************************************
759bd41f2cSmrg *	Local Headers
769bd41f2cSmrg ****************************************************************************/
779bd41f2cSmrg#include "vmmouse_client.h"
789bd41f2cSmrg
799bd41f2cSmrg/*
809bd41f2cSmrg * This is the only way I know to turn a #define of an integer constant into
819bd41f2cSmrg * a constant string.
829bd41f2cSmrg */
839bd41f2cSmrg#define VMW_INNERSTRINGIFY(s) #s
849bd41f2cSmrg#define VMW_STRING(str) VMW_INNERSTRINGIFY(str)
859bd41f2cSmrg
869bd41f2cSmrg/*
879bd41f2cSmrg * So that the file compiles unmodified when dropped into an xfree source tree.
889bd41f2cSmrg */
899bd41f2cSmrg#ifndef XORG_VERSION_CURRENT
909bd41f2cSmrg#define XORG_VERSION_CURRENT XF86_VERSION_CURRENT
919bd41f2cSmrg#endif
929bd41f2cSmrg
939bd41f2cSmrg/*
949bd41f2cSmrg * Version constants
959bd41f2cSmrg */
969bd41f2cSmrg#define VMMOUSE_MAJOR_VERSION 12
979bd41f2cSmrg#define VMMOUSE_MINOR_VERSION 4
989bd41f2cSmrg#define VMMOUSE_PATCHLEVEL 3
999bd41f2cSmrg#define VMMOUSE_DRIVER_VERSION \
1009bd41f2cSmrg   (VMMOUSE_MAJOR_VERSION * 65536 + VMMOUSE_MINOR_VERSION * 256 + VMMOUSE_PATCHLEVEL)
1019bd41f2cSmrg#define VMMOUSE_DRIVER_VERSION_STRING \
1029bd41f2cSmrg    VMW_STRING(VMMOUSE_MAJOR_VERSION) "." VMW_STRING(VMMOUSE_MINOR_VERSION) \
1039bd41f2cSmrg    "." VMW_STRING(VMMOUSE_PATCHLEVEL)
1049bd41f2cSmrg
1059bd41f2cSmrg/*
1069bd41f2cSmrg * Standard four digit version string expected by VMware Tools installer.
1079bd41f2cSmrg * As the driver's version is only  {major, minor, patchlevel}, simply append an
1089bd41f2cSmrg * extra zero for the fourth digit.
1099bd41f2cSmrg */
1109bd41f2cSmrg#ifdef __GNUC__
1119bd41f2cSmrgconst char vm_mouse_version[] __attribute__((section(".modinfo"),unused)) =
1129bd41f2cSmrg    "version=" VMMOUSE_DRIVER_VERSION_STRING ".0";
1139bd41f2cSmrg#endif
1149bd41f2cSmrg
1159bd41f2cSmrg
1169bd41f2cSmrg/*****************************************************************************
1179bd41f2cSmrg *	static function header
1189bd41f2cSmrg ****************************************************************************/
1199bd41f2cSmrg#ifdef XFree86LOADER
1209bd41f2cSmrgstatic const OptionInfoRec *VMMouseAvailableOptions(void *unused);
1219bd41f2cSmrg#endif
1229bd41f2cSmrgstatic InputInfoPtr VMMousePreInit(InputDriverPtr drv, IDevPtr dev, int flags);
1239bd41f2cSmrgstatic void VMMouseUnInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags);
1249bd41f2cSmrgstatic void MouseCommonOptions(InputInfoPtr pInfo);
1259bd41f2cSmrgstatic void GetVMMouseMotionEvent(InputInfoPtr pInfo);
1269bd41f2cSmrgstatic void VMMousePostEvent(InputInfoPtr pInfo, int buttons, int dx, int dy, int dz, int dw);
1279bd41f2cSmrgstatic void VMMouseDoPostEvent(InputInfoPtr pInfo, int buttons, int dx, int dy);
1289bd41f2cSmrgstatic Bool VMMouseDeviceControl(DeviceIntPtr device, int mode);
1299bd41f2cSmrgstatic void VMMouseCloseProc(LocalDevicePtr local);
1309bd41f2cSmrgstatic int  VMMouseControlProc(LocalDevicePtr local, xDeviceCtl * control);
1319bd41f2cSmrgstatic void VMMouseReadInput(InputInfoPtr pInfo);
1329bd41f2cSmrgstatic int  VMMouseSwitchMode(ClientPtr client, DeviceIntPtr dev, int mode);
1339bd41f2cSmrgstatic Bool VMMouseConvertProc(InputInfoPtr pInfo, int first, int num, int v0, int v1, int v2,
1349bd41f2cSmrg			       int v3, int v4, int v5, int *x, int *y);
1359bd41f2cSmrgstatic void MouseCtrl(DeviceIntPtr device, PtrCtrl *ctrl);
1369bd41f2cSmrg
1379bd41f2cSmrg/******************************************************************************
1389bd41f2cSmrg *		Definitions
1399bd41f2cSmrg *****************************************************************************/
1409bd41f2cSmrgtypedef struct {
1419bd41f2cSmrg   int 		screenNum;
1429bd41f2cSmrg   Bool 	vmmouseAvailable;
1439bd41f2cSmrg   Bool		relative;
1449bd41f2cSmrg} VMMousePrivRec, *VMMousePrivPtr;
1459bd41f2cSmrg
1469bd41f2cSmrgstatic const char *reqSymbols[] = {
1479bd41f2cSmrg   "InitPointerDeviceStruct",
1489bd41f2cSmrg   "LoaderSymbol",
1499bd41f2cSmrg   "LoadSubModule",
1509bd41f2cSmrg   "miPointerGetMotionBufferSize",
1519bd41f2cSmrg   "miPointerGetMotionEvents",
1529bd41f2cSmrg   "screenInfo",
1539bd41f2cSmrg   "Xcalloc",
1549bd41f2cSmrg   "xf86AddEnabledDevice",
1559bd41f2cSmrg   "xf86AddInputDriver",
1569bd41f2cSmrg   "xf86AddModuleInfo",
1579bd41f2cSmrg   "xf86AllocateInput",
1589bd41f2cSmrg   "xf86BlockSIGIO",
1599bd41f2cSmrg   "xf86CloseSerial",
1609bd41f2cSmrg   "xf86CollectInputOptions",
1619bd41f2cSmrg   "xf86ffs",
1629bd41f2cSmrg   "xf86FlushInput",
1639bd41f2cSmrg   "xf86GetAllowMouseOpenFail",
1649bd41f2cSmrg   "xf86GetMotionEvents",
1659bd41f2cSmrg   "xf86InitValuatorAxisStruct",
1669bd41f2cSmrg   "xf86InitValuatorDefaults",
1679bd41f2cSmrg   "xf86LoaderCheckSymbol",
1689bd41f2cSmrg   "xf86MotionHistoryAllocate",
1699bd41f2cSmrg   "xf86Msg",
1709bd41f2cSmrg   "xf86NameCmp",
1719bd41f2cSmrg   "xf86OpenSerial",
1729bd41f2cSmrg   "xf86OSMouseInit",
1739bd41f2cSmrg   "xf86PostButtonEvent",
1749bd41f2cSmrg   "xf86PostMotionEvent",
1759bd41f2cSmrg   "xf86ProcessCommonOptions",
1769bd41f2cSmrg   "xf86RemoveEnabledDevice",
1779bd41f2cSmrg   "xf86SetIntOption",
1789bd41f2cSmrg   "xf86SetStrOption",
1799bd41f2cSmrg   "xf86sprintf",
1809bd41f2cSmrg   "xf86sscanf",
1819bd41f2cSmrg   "xf86UnblockSIGIO",
1829bd41f2cSmrg   "xf86usleep",
1839bd41f2cSmrg   "xf86XInputSetScreen",
1849bd41f2cSmrg   "Xfree",
1859bd41f2cSmrg   "XisbBlockDuration",
1869bd41f2cSmrg   "XisbFree",
1879bd41f2cSmrg   "XisbNew",
1889bd41f2cSmrg   "XisbRead",
1899bd41f2cSmrg   "Xstrdup",
1909bd41f2cSmrg   NULL
1919bd41f2cSmrg};
1929bd41f2cSmrg
1939bd41f2cSmrgInputDriverRec VMMOUSE = {
1949bd41f2cSmrg   1,
1959bd41f2cSmrg   "vmmouse",
1969bd41f2cSmrg   NULL,
1979bd41f2cSmrg   VMMousePreInit,
1989bd41f2cSmrg   VMMouseUnInit,
1999bd41f2cSmrg   NULL,
2009bd41f2cSmrg   0
2019bd41f2cSmrg};
2029bd41f2cSmrg
2039bd41f2cSmrgtypedef enum {
2049bd41f2cSmrg    OPTION_ALWAYS_CORE,
2059bd41f2cSmrg    OPTION_SEND_CORE_EVENTS,
2069bd41f2cSmrg    OPTION_CORE_POINTER,
2079bd41f2cSmrg    OPTION_SEND_DRAG_EVENTS,
2089bd41f2cSmrg    OPTION_HISTORY_SIZE,
2099bd41f2cSmrg    OPTION_DEVICE,
2109bd41f2cSmrg    OPTION_PROTOCOL,
2119bd41f2cSmrg    OPTION_BUTTONS,
2129bd41f2cSmrg    OPTION_EMULATE_3_BUTTONS,
2139bd41f2cSmrg    OPTION_EMULATE_3_TIMEOUT,
2149bd41f2cSmrg    OPTION_CHORD_MIDDLE,
2159bd41f2cSmrg    OPTION_FLIP_XY,
2169bd41f2cSmrg    OPTION_INV_X,
2179bd41f2cSmrg    OPTION_INV_Y,
2189bd41f2cSmrg    OPTION_ANGLE_OFFSET,
2199bd41f2cSmrg    OPTION_Z_AXIS_MAPPING,
2209bd41f2cSmrg    OPTION_SAMPLE_RATE,
2219bd41f2cSmrg    OPTION_RESOLUTION,
2229bd41f2cSmrg    OPTION_EMULATE_WHEEL,
2239bd41f2cSmrg    OPTION_EMU_WHEEL_BUTTON,
2249bd41f2cSmrg    OPTION_EMU_WHEEL_INERTIA,
2259bd41f2cSmrg    OPTION_X_AXIS_MAPPING,
2269bd41f2cSmrg    OPTION_Y_AXIS_MAPPING,
2279bd41f2cSmrg    OPTION_AUTO_SOFT,
2289bd41f2cSmrg    OPTION_DRAGLOCKBUTTONS
2299bd41f2cSmrg} MouseOpts;
2309bd41f2cSmrg
2319bd41f2cSmrg/*
2329bd41f2cSmrg * Define the acceptable mouse options
2339bd41f2cSmrg * Currently not all of those options are supported
2349bd41f2cSmrg *
2359bd41f2cSmrg */
2369bd41f2cSmrgstatic const OptionInfoRec mouseOptions[] = {
2379bd41f2cSmrg    { OPTION_ALWAYS_CORE,	"AlwaysCore",	  OPTV_BOOLEAN,	{0}, FALSE },
2389bd41f2cSmrg    { OPTION_SEND_CORE_EVENTS,	"SendCoreEvents", OPTV_BOOLEAN,	{0}, FALSE },
2399bd41f2cSmrg    { OPTION_CORE_POINTER,	"CorePointer",	  OPTV_BOOLEAN,	{0}, FALSE },
2409bd41f2cSmrg    { OPTION_SEND_DRAG_EVENTS,	"SendDragEvents", OPTV_BOOLEAN,	{0}, FALSE },
2419bd41f2cSmrg    { OPTION_HISTORY_SIZE,	"HistorySize",	  OPTV_INTEGER,	{0}, FALSE },
2429bd41f2cSmrg    { OPTION_DEVICE,		"Device",	  OPTV_STRING,	{0}, FALSE },
2439bd41f2cSmrg    { OPTION_PROTOCOL,		"Protocol",	  OPTV_STRING,	{0}, FALSE },
2449bd41f2cSmrg    { OPTION_BUTTONS,		"Buttons",	  OPTV_INTEGER,	{0}, FALSE },
2459bd41f2cSmrg    { OPTION_EMULATE_3_BUTTONS,	"Emulate3Buttons",OPTV_BOOLEAN,	{0}, FALSE },
2469bd41f2cSmrg    { OPTION_EMULATE_3_TIMEOUT,	"Emulate3Timeout",OPTV_INTEGER,	{0}, FALSE },
2479bd41f2cSmrg    { OPTION_CHORD_MIDDLE,	"ChordMiddle",	  OPTV_BOOLEAN,	{0}, FALSE },
2489bd41f2cSmrg    { OPTION_FLIP_XY,		"FlipXY",	  OPTV_BOOLEAN,	{0}, FALSE },
2499bd41f2cSmrg    { OPTION_INV_X,		"InvX",		  OPTV_BOOLEAN,	{0}, FALSE },
2509bd41f2cSmrg    { OPTION_INV_Y,		"InvY",		  OPTV_BOOLEAN,	{0}, FALSE },
2519bd41f2cSmrg    { OPTION_ANGLE_OFFSET,	"AngleOffset",	  OPTV_INTEGER,	{0}, FALSE },
2529bd41f2cSmrg    { OPTION_Z_AXIS_MAPPING,	"ZAxisMapping",	  OPTV_STRING,	{0}, FALSE },
2539bd41f2cSmrg    { OPTION_SAMPLE_RATE,	"SampleRate",	  OPTV_INTEGER,	{0}, FALSE },
2549bd41f2cSmrg    { OPTION_RESOLUTION,	"Resolution",	  OPTV_INTEGER,	{0}, FALSE },
2559bd41f2cSmrg    { OPTION_EMULATE_WHEEL,	"EmulateWheel",	  OPTV_BOOLEAN, {0}, FALSE },
2569bd41f2cSmrg    { OPTION_EMU_WHEEL_BUTTON,	"EmulateWheelButton", OPTV_INTEGER, {0}, FALSE },
2579bd41f2cSmrg    { OPTION_EMU_WHEEL_INERTIA,	"EmulateWheelInertia", OPTV_INTEGER, {0}, FALSE },
2589bd41f2cSmrg    { OPTION_X_AXIS_MAPPING,	"XAxisMapping",	  OPTV_STRING,	{0}, FALSE },
2599bd41f2cSmrg    { OPTION_Y_AXIS_MAPPING,	"YAxisMapping",	  OPTV_STRING,	{0}, FALSE },
2609bd41f2cSmrg    { OPTION_AUTO_SOFT,		"AutoSoft",	  OPTV_BOOLEAN, {0}, FALSE },
2619bd41f2cSmrg    { OPTION_DRAGLOCKBUTTONS,	"DragLockButtons",OPTV_STRING,	{0}, FALSE },
2629bd41f2cSmrg    { -1,			NULL,		  OPTV_NONE,	{0}, FALSE }
2639bd41f2cSmrg};
2649bd41f2cSmrg
2659bd41f2cSmrgstatic char reverseMap[32] = { 0,  4,  2,  6,  1,  5,  3,  7,
2669bd41f2cSmrg			       8, 12, 10, 14,  9, 13, 11, 15,
2679bd41f2cSmrg			      16, 20, 18, 22, 17, 21, 19, 23,
2689bd41f2cSmrg			      24, 28, 26, 30, 25, 29, 27, 31};
2699bd41f2cSmrg
2709bd41f2cSmrg#define reverseBits(map, b)	(((b) & ~0x0f) | map[(b) & 0x0f])
2719bd41f2cSmrg
2729bd41f2cSmrg
2739bd41f2cSmrg/*
2749bd41f2cSmrg *----------------------------------------------------------------------
2759bd41f2cSmrg *
2769bd41f2cSmrg * VMMousePreInit --
2779bd41f2cSmrg *	This function collect all the information that is necessary to
2789bd41f2cSmrg *	determine the configuration of the hardware and to prepare the
2799bd41f2cSmrg *	device for being used
2809bd41f2cSmrg *
2819bd41f2cSmrg * Results:
2829bd41f2cSmrg * 	An InputInfoPtr object which points to vmmouse's information,
2839bd41f2cSmrg *	if the absolute pointing device available
2849bd41f2cSmrg *	Otherwise, an InputInfoPtr of regular mouse
2859bd41f2cSmrg *
2869bd41f2cSmrg * Side effects:
2879bd41f2cSmrg * 	VMMouse was initialized with necessary information
2889bd41f2cSmrg *
2899bd41f2cSmrg *----------------------------------------------------------------------
2909bd41f2cSmrg */
2919bd41f2cSmrg
2929bd41f2cSmrgstatic InputInfoPtr
2939bd41f2cSmrgVMMousePreInit(InputDriverPtr drv, IDevPtr dev, int flags)
2949bd41f2cSmrg{
2959bd41f2cSmrg   InputInfoPtr pInfo;
2969bd41f2cSmrg   MouseDevPtr pMse;
2979bd41f2cSmrg   VMMousePrivPtr mPriv;
2989bd41f2cSmrg   OSMouseInfoPtr osInfo = NULL;
2999bd41f2cSmrg
3009bd41f2cSmrg   /*
3019bd41f2cSmrg    * let Xserver init the mouse first
3029bd41f2cSmrg    */
3039bd41f2cSmrg   osInfo = xf86OSMouseInit(0);
3049bd41f2cSmrg   if (!osInfo)
3059bd41f2cSmrg      return FALSE;
3069bd41f2cSmrg
3079bd41f2cSmrg   mPriv = xcalloc (1, sizeof (VMMousePrivRec));
3089bd41f2cSmrg
3099bd41f2cSmrg
3109bd41f2cSmrg   if (!mPriv) {
3119bd41f2cSmrg      return NULL;
3129bd41f2cSmrg   }
3139bd41f2cSmrg   /*
3149bd41f2cSmrg    * try to enable vmmouse here
3159bd41f2cSmrg    */
3169bd41f2cSmrg   if (!VMMouseClient_Enable()) {
3179bd41f2cSmrg      /*
3189bd41f2cSmrg       * vmmouse failed
3199bd41f2cSmrg       * Fall back to normal mouse module
3209bd41f2cSmrg       */
3219bd41f2cSmrg      InputDriverRec *passthruMouse;
3229bd41f2cSmrg      xf86Msg(X_ERROR, "VMWARE(0): vmmouse enable failed\n");
3239bd41f2cSmrg      mPriv->vmmouseAvailable = FALSE;
3249bd41f2cSmrg      passthruMouse = (InputDriverRec *)LoaderSymbol("MOUSE");
3259bd41f2cSmrg      xfree(mPriv);
3269bd41f2cSmrg      if(passthruMouse != NULL){
3279bd41f2cSmrg	 return (passthruMouse->PreInit)(drv, dev, flags);
3289bd41f2cSmrg      } else {
3299bd41f2cSmrg	 return NULL;
3309bd41f2cSmrg      }
3319bd41f2cSmrg
3329bd41f2cSmrg   } else {
3339bd41f2cSmrg      /*
3349bd41f2cSmrg       * vmmouse is available
3359bd41f2cSmrg       */
3369bd41f2cSmrg      mPriv->vmmouseAvailable = TRUE;
3379bd41f2cSmrg      xf86Msg(X_INFO, "VMWARE(0): vmmouse is available\n");
3389bd41f2cSmrg      /*
3399bd41f2cSmrg       * Disable the absolute pointing device for now
3409bd41f2cSmrg       * It will be enabled during DEVICE_ON phase
3419bd41f2cSmrg       */
3429bd41f2cSmrg      VMMouseClient_Disable();
3439bd41f2cSmrg   }
3449bd41f2cSmrg
3459bd41f2cSmrg   if (!(pInfo = xf86AllocateInput(drv, 0))) {
3469bd41f2cSmrg      xfree(mPriv);
3479bd41f2cSmrg      return NULL;
3489bd41f2cSmrg   }
3499bd41f2cSmrg
3509bd41f2cSmrg   /* Settup the pInfo */
3519bd41f2cSmrg   pInfo->name = dev->identifier;
3529bd41f2cSmrg   pInfo->type_name = XI_MOUSE;
3539bd41f2cSmrg   pInfo->flags = XI86_POINTER_CAPABLE | XI86_SEND_DRAG_EVENTS;
3549bd41f2cSmrg   pInfo->device_control = VMMouseDeviceControl;
3559bd41f2cSmrg   pInfo->read_input = VMMouseReadInput;
3569bd41f2cSmrg#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) == 0
3579bd41f2cSmrg   pInfo->motion_history_proc = xf86GetMotionEvents;
3589bd41f2cSmrg#endif
3599bd41f2cSmrg   pInfo->control_proc = VMMouseControlProc;
3609bd41f2cSmrg   pInfo->close_proc = VMMouseCloseProc;
3619bd41f2cSmrg   pInfo->switch_mode = VMMouseSwitchMode;
3629bd41f2cSmrg   pInfo->conversion_proc = VMMouseConvertProc;
3639bd41f2cSmrg   pInfo->reverse_conversion_proc = NULL;
3649bd41f2cSmrg   pInfo->fd = -1;
3659bd41f2cSmrg   pInfo->dev = NULL;
3669bd41f2cSmrg   pInfo->private_flags = 0;
3679bd41f2cSmrg   pInfo->always_core_feedback = 0;
3689bd41f2cSmrg   pInfo->conf_idev = dev;
3699bd41f2cSmrg
3709bd41f2cSmrg   /* Allocate the MouseDevRec and initialise it. */
3719bd41f2cSmrg   if (!(pMse = xcalloc(sizeof(MouseDevRec), 1))) {
3729bd41f2cSmrg      xfree(mPriv);
3739bd41f2cSmrg      return pInfo;
3749bd41f2cSmrg   }
3759bd41f2cSmrg
3769bd41f2cSmrg   pInfo->private = pMse;
3779bd41f2cSmrg   pMse->Ctrl = MouseCtrl;
3789bd41f2cSmrg   pMse->PostEvent = VMMousePostEvent;
3799bd41f2cSmrg   pMse->CommonOptions = MouseCommonOptions;
3809bd41f2cSmrg   pMse->mousePriv = mPriv;
3819bd41f2cSmrg
3829bd41f2cSmrg
3839bd41f2cSmrg   /* Collect the options, and process the common options. */
3849bd41f2cSmrg   xf86CollectInputOptions(pInfo, NULL, NULL);
3859bd41f2cSmrg   xf86ProcessCommonOptions(pInfo, pInfo->options);
3869bd41f2cSmrg
3879bd41f2cSmrg   /* Check if the device can be opened. */
3889bd41f2cSmrg   pInfo->fd = xf86OpenSerial(pInfo->options);
3899bd41f2cSmrg   if (pInfo->fd == -1) {
3909bd41f2cSmrg      if (xf86GetAllowMouseOpenFail())
3919bd41f2cSmrg	 xf86Msg(X_WARNING, "%s: cannot open input device\n", pInfo->name);
3929bd41f2cSmrg      else {
3939bd41f2cSmrg	 xf86Msg(X_ERROR, "%s: cannot open input device\n", pInfo->name);
3949bd41f2cSmrg	 if (pMse->mousePriv)
3959bd41f2cSmrg	    xfree(pMse->mousePriv);
3969bd41f2cSmrg	 xfree(pMse);
3979bd41f2cSmrg	 pInfo->private = NULL;
3989bd41f2cSmrg	 return pInfo;
3999bd41f2cSmrg      }
4009bd41f2cSmrg   }
4019bd41f2cSmrg   xf86CloseSerial(pInfo->fd);
4029bd41f2cSmrg   pInfo->fd = -1;
4039bd41f2cSmrg
4049bd41f2cSmrg   /* Process the options */
4059bd41f2cSmrg   pMse->CommonOptions(pInfo);
4069bd41f2cSmrg
4079bd41f2cSmrg   /* set up the current screen num */
4089bd41f2cSmrg   mPriv->screenNum = xf86SetIntOption(pInfo->options, "ScreenNumber", 0);
4099bd41f2cSmrg
4109bd41f2cSmrg   pInfo->flags |= XI86_CONFIGURED;
4119bd41f2cSmrg   return pInfo;
4129bd41f2cSmrg}
4139bd41f2cSmrg
4149bd41f2cSmrg#ifdef XFree86LOADER
4159bd41f2cSmrgstatic const OptionInfoRec *
4169bd41f2cSmrgVMMouseAvailableOptions(void *unused)
4179bd41f2cSmrg{
4189bd41f2cSmrg    return (mouseOptions);
4199bd41f2cSmrg}
4209bd41f2cSmrg#endif
4219bd41f2cSmrg
4229bd41f2cSmrg
4239bd41f2cSmrg/*
4249bd41f2cSmrg *----------------------------------------------------------------------
4259bd41f2cSmrg *
4269bd41f2cSmrg * MouseCtrl --
4279bd41f2cSmrg *     Alter the control paramters for the mouse.
4289bd41f2cSmrg *
4299bd41f2cSmrg * Results:
4309bd41f2cSmrg * 	None
4319bd41f2cSmrg *
4329bd41f2cSmrg * Side effects:
4339bd41f2cSmrg * 	None
4349bd41f2cSmrg *
4359bd41f2cSmrg *----------------------------------------------------------------------
4369bd41f2cSmrg */
4379bd41f2cSmrg
4389bd41f2cSmrgstatic void
4399bd41f2cSmrgMouseCtrl(DeviceIntPtr device, PtrCtrl *ctrl)
4409bd41f2cSmrg{
4419bd41f2cSmrg    InputInfoPtr pInfo;
4429bd41f2cSmrg    MouseDevPtr pMse;
4439bd41f2cSmrg
4449bd41f2cSmrg    pInfo = device->public.devicePrivate;
4459bd41f2cSmrg    pMse = pInfo->private;
4469bd41f2cSmrg
4479bd41f2cSmrg#ifdef EXTMOUSEDEBUG
4489bd41f2cSmrg    xf86Msg(X_INFO, "VMMOUSE(0): MouseCtrl pMse=%p\n", pMse);
4499bd41f2cSmrg#endif
4509bd41f2cSmrg
4519bd41f2cSmrg    pMse->num       = ctrl->num;
4529bd41f2cSmrg    pMse->den       = ctrl->den;
4539bd41f2cSmrg    pMse->threshold = ctrl->threshold;
4549bd41f2cSmrg}
4559bd41f2cSmrg
4569bd41f2cSmrg
4579bd41f2cSmrg/*
4589bd41f2cSmrg *----------------------------------------------------------------------
4599bd41f2cSmrg *
4609bd41f2cSmrg * VMMouseDoPostEvent --
4619bd41f2cSmrg *	Post the mouse button event and mouse motion event to Xserver
4629bd41f2cSmrg *
4639bd41f2cSmrg * Results:
4649bd41f2cSmrg * 	None
4659bd41f2cSmrg *
4669bd41f2cSmrg * Side effects:
4679bd41f2cSmrg * 	Mouse location and button status was updated
4689bd41f2cSmrg *
4699bd41f2cSmrg *----------------------------------------------------------------------
4709bd41f2cSmrg */
4719bd41f2cSmrg
4729bd41f2cSmrgstatic void
4739bd41f2cSmrgVMMouseDoPostEvent(InputInfoPtr pInfo, int buttons, int dx, int dy)
4749bd41f2cSmrg{
4759bd41f2cSmrg    MouseDevPtr pMse;
4769bd41f2cSmrg    VMMousePrivPtr mPriv;
4779bd41f2cSmrg    int truebuttons;
4789bd41f2cSmrg    int id, change;
4799bd41f2cSmrg
4809bd41f2cSmrg    pMse = pInfo->private;
4819bd41f2cSmrg    mPriv = (VMMousePrivPtr)pMse->mousePriv;
4829bd41f2cSmrg
4839bd41f2cSmrg    /*
4849bd41f2cSmrg     * The following truebuttons/reverseBits and lastButtons are
4859bd41f2cSmrg     * used to compare the current buttons and the previous buttons
4869bd41f2cSmrg     * to find the button changes during two mouse events
4879bd41f2cSmrg     */
4889bd41f2cSmrg    truebuttons = buttons;
4899bd41f2cSmrg
4909bd41f2cSmrg    buttons = reverseBits(reverseMap, buttons);
4919bd41f2cSmrg
4929bd41f2cSmrg    if (dx || dy) {
4939bd41f2cSmrg
4949bd41f2cSmrg        /*
4959bd41f2cSmrg         * The Xserver no longer calls an input device's conversion_proc
4969bd41f2cSmrg         * to convert x and y coordinates from device to screen space.
4979bd41f2cSmrg         */
4989bd41f2cSmrg        VMMouseConvertProc(pInfo, 0, 2, dx, dy, 0, 0, 0, 0, &dx, &dy);
4999bd41f2cSmrg        xf86PostMotionEvent(pInfo->dev, !mPriv->relative, 0, 2, dx, dy);
5009bd41f2cSmrg    }
5019bd41f2cSmrg
5029bd41f2cSmrg    if (truebuttons != pMse->lastButtons) {
5039bd41f2cSmrg       change = buttons ^ reverseBits(reverseMap, pMse->lastButtons);
5049bd41f2cSmrg       while (change) {
5059bd41f2cSmrg	  id = ffs(change);
5069bd41f2cSmrg	  change &= ~(1 << (id - 1));
5079bd41f2cSmrg	  xf86PostButtonEvent(pInfo->dev, 0, id,
5089bd41f2cSmrg			      (buttons & (1 << (id - 1))), 0, 0);
5099bd41f2cSmrg       }
5109bd41f2cSmrg       pMse->lastButtons = truebuttons;
5119bd41f2cSmrg    }
5129bd41f2cSmrg}
5139bd41f2cSmrg
5149bd41f2cSmrg
5159bd41f2cSmrg/*
5169bd41f2cSmrg *----------------------------------------------------------------------
5179bd41f2cSmrg *
5189bd41f2cSmrg * VMMousePostEvent --
5199bd41f2cSmrg *	Prepare the mouse status according to the Z axis mapping
5209bd41f2cSmrg *	before we post the event to Xserver
5219bd41f2cSmrg *
5229bd41f2cSmrg * Results:
5239bd41f2cSmrg * 	None
5249bd41f2cSmrg *
5259bd41f2cSmrg * Side effects:
5269bd41f2cSmrg * 	Buttons was updated according to Z axis mapping
5279bd41f2cSmrg *
5289bd41f2cSmrg *----------------------------------------------------------------------
5299bd41f2cSmrg */
5309bd41f2cSmrg
5319bd41f2cSmrgstatic void
5329bd41f2cSmrgVMMousePostEvent(InputInfoPtr pInfo, int buttons, int dx, int dy, int dz, int dw)
5339bd41f2cSmrg{
5349bd41f2cSmrg    MouseDevPtr pMse;
5359bd41f2cSmrg    int zbutton = 0;
5369bd41f2cSmrg    VMMousePrivPtr mPriv;
5379bd41f2cSmrg
5389bd41f2cSmrg    pMse = pInfo->private;
5399bd41f2cSmrg    mPriv = (VMMousePrivPtr)pMse->mousePriv;
5409bd41f2cSmrg    /* Map the Z axis movement. */
5419bd41f2cSmrg    /* XXX Could this go in the conversion_proc? */
5429bd41f2cSmrg    switch (pMse->negativeZ) {
5439bd41f2cSmrg    case MSE_NOZMAP:	/* do nothing */
5449bd41f2cSmrg	break;
5459bd41f2cSmrg    case MSE_MAPTOX:
5469bd41f2cSmrg	if (dz != 0) {
5479bd41f2cSmrg	   if(mPriv->relative)
5489bd41f2cSmrg	      dx = dz;
5499bd41f2cSmrg	   else
5509bd41f2cSmrg	      dx += dz;
5519bd41f2cSmrg	    dz = 0;
5529bd41f2cSmrg	}
5539bd41f2cSmrg	break;
5549bd41f2cSmrg    case MSE_MAPTOY:
5559bd41f2cSmrg	if (dz != 0) {
5569bd41f2cSmrg	   if(mPriv->relative)
5579bd41f2cSmrg	      dy = dz;
5589bd41f2cSmrg	   else
5599bd41f2cSmrg	      dy += dz;
5609bd41f2cSmrg	    dz = 0;
5619bd41f2cSmrg	}
5629bd41f2cSmrg	break;
5639bd41f2cSmrg    default:	/* buttons */
5649bd41f2cSmrg	buttons &= ~(pMse->negativeZ | pMse->positiveZ
5659bd41f2cSmrg		   | pMse->negativeW | pMse->positiveW);
5669bd41f2cSmrg	if (dw < 0 || dz < -1) {
5679bd41f2cSmrg	    zbutton = pMse->negativeW;
5689bd41f2cSmrg	}
5699bd41f2cSmrg	else if (dz < 0) {
5709bd41f2cSmrg	    zbutton = pMse->negativeZ;
5719bd41f2cSmrg	}
5729bd41f2cSmrg	else if (dw > 0 || dz > 1) {
5739bd41f2cSmrg	    zbutton = pMse->positiveW;
5749bd41f2cSmrg	}
5759bd41f2cSmrg	else if (dz > 0) {
5769bd41f2cSmrg	    zbutton = pMse->positiveZ;
5779bd41f2cSmrg	}
5789bd41f2cSmrg	buttons |= zbutton;
5799bd41f2cSmrg	dz = 0;
5809bd41f2cSmrg	break;
5819bd41f2cSmrg    }
5829bd41f2cSmrg
5839bd41f2cSmrg    VMMouseDoPostEvent(pInfo, buttons, dx, dy);
5849bd41f2cSmrg
5859bd41f2cSmrg    /*
5869bd41f2cSmrg     * If dz has been mapped to a button `down' event, we need to cook up
5879bd41f2cSmrg     * a corresponding button `up' event.
5889bd41f2cSmrg     */
5899bd41f2cSmrg    if (zbutton) {
5909bd41f2cSmrg	buttons &= ~zbutton;
5919bd41f2cSmrg	if(mPriv->relative)
5929bd41f2cSmrg	   VMMouseDoPostEvent(pInfo, buttons, 0, 0);
5939bd41f2cSmrg	else
5949bd41f2cSmrg	   VMMouseDoPostEvent(pInfo, buttons, dx, dy);
5959bd41f2cSmrg    }
5969bd41f2cSmrg}
5979bd41f2cSmrg
5989bd41f2cSmrg
5999bd41f2cSmrg/*
6009bd41f2cSmrg *----------------------------------------------------------------------
6019bd41f2cSmrg *
6029bd41f2cSmrg * FlushButtons --
6039bd41f2cSmrg *
6049bd41f2cSmrg * 	FlushButtons -- send button up events for sanity. It is called
6059bd41f2cSmrg *	during DEVICE_ON in VMMouseDeviceControl
6069bd41f2cSmrg *
6079bd41f2cSmrg * Results:
6089bd41f2cSmrg * 	None
6099bd41f2cSmrg *
6109bd41f2cSmrg * Side effects:
6119bd41f2cSmrg * 	None
6129bd41f2cSmrg *
6139bd41f2cSmrg *----------------------------------------------------------------------
6149bd41f2cSmrg */
6159bd41f2cSmrg
6169bd41f2cSmrgstatic void
6179bd41f2cSmrgFlushButtons(MouseDevPtr pMse)
6189bd41f2cSmrg{
6199bd41f2cSmrg
6209bd41f2cSmrg    /* If no button down is pending xf86PostButtonEvent()
6219bd41f2cSmrg     * will discard them. So we are on the safe side. */
6229bd41f2cSmrg
6239bd41f2cSmrg    int i, blocked;
6249bd41f2cSmrg
6259bd41f2cSmrg    pMse->lastButtons = 0;
6269bd41f2cSmrg
6279bd41f2cSmrg    blocked = xf86BlockSIGIO ();
6289bd41f2cSmrg    for (i = 1; i <= 5; i++)
6299bd41f2cSmrg	xf86PostButtonEvent(pMse->device,0,i,0,0,0);
6309bd41f2cSmrg    xf86UnblockSIGIO (blocked);
6319bd41f2cSmrg}
6329bd41f2cSmrg
6339bd41f2cSmrg
6349bd41f2cSmrg/*
6359bd41f2cSmrg *----------------------------------------------------------------------
6369bd41f2cSmrg *
6379bd41f2cSmrg * MouseCommonOptions --
6389bd41f2cSmrg *	Process acceptable mouse options. Currently we only process
6399bd41f2cSmrg *	"Buttons" and "ZAxisMapping" options.
6409bd41f2cSmrg *	More options can be added later on
6419bd41f2cSmrg *
6429bd41f2cSmrg * Results:
6439bd41f2cSmrg * 	None
6449bd41f2cSmrg *
6459bd41f2cSmrg * Side effects:
6469bd41f2cSmrg * 	The buttons was setup according to the options
6479bd41f2cSmrg *
6489bd41f2cSmrg *----------------------------------------------------------------------
6499bd41f2cSmrg */
6509bd41f2cSmrg
6519bd41f2cSmrgstatic void
6529bd41f2cSmrgMouseCommonOptions(InputInfoPtr pInfo)
6539bd41f2cSmrg{
6549bd41f2cSmrg   MouseDevPtr pMse;
6559bd41f2cSmrg   MessageType from = X_DEFAULT;
6569bd41f2cSmrg   char *s;
6579bd41f2cSmrg   int origButtons;
6589bd41f2cSmrg
6599bd41f2cSmrg   pMse = pInfo->private;
6609bd41f2cSmrg
6619bd41f2cSmrg   pMse->buttons = xf86SetIntOption(pInfo->options, "Buttons", 0);
6629bd41f2cSmrg   from = X_CONFIG;
6639bd41f2cSmrg   if (!pMse->buttons) {
6649bd41f2cSmrg      pMse->buttons = MSE_DFLTBUTTONS;
6659bd41f2cSmrg      from = X_DEFAULT;
6669bd41f2cSmrg   }
6679bd41f2cSmrg   origButtons = pMse->buttons;
6689bd41f2cSmrg
6699bd41f2cSmrg   /*
6709bd41f2cSmrg    * "emulate3Buttons" and "Drag Lock" is not supported
6719bd41f2cSmrg    */
6729bd41f2cSmrg
6739bd41f2cSmrg   /*
6749bd41f2cSmrg    * Process option for ZAxisMapping
6759bd41f2cSmrg    */
6769bd41f2cSmrg   s = xf86SetStrOption(pInfo->options, "ZAxisMapping", NULL);
6779bd41f2cSmrg   if (s) {
6789bd41f2cSmrg      int b1 = 0, b2 = 0, b3 = 0, b4 = 0;
6799bd41f2cSmrg      char *msg = NULL;
6809bd41f2cSmrg
6819bd41f2cSmrg      if (!xf86NameCmp(s, "x")) {
6829bd41f2cSmrg	 pMse->negativeZ = pMse->positiveZ = MSE_MAPTOX;
6839bd41f2cSmrg	 pMse->negativeW = pMse->positiveW = MSE_MAPTOX;
6849bd41f2cSmrg	 msg = xstrdup("X axis");
6859bd41f2cSmrg      } else if (!xf86NameCmp(s, "y")) {
6869bd41f2cSmrg	 pMse->negativeZ = pMse->positiveZ = MSE_MAPTOY;
6879bd41f2cSmrg	 pMse->negativeW = pMse->positiveW = MSE_MAPTOY;
6889bd41f2cSmrg	 msg = xstrdup("Y axis");
6899bd41f2cSmrg      } else if (sscanf(s, "%d %d %d %d", &b1, &b2, &b3, &b4) >= 2 &&
6909bd41f2cSmrg		 b1 > 0 && b1 <= MSE_MAXBUTTONS &&
6919bd41f2cSmrg		 b2 > 0 && b2 <= MSE_MAXBUTTONS) {
6929bd41f2cSmrg	 msg = xstrdup("buttons XX and YY");
6939bd41f2cSmrg	 if (msg)
6949bd41f2cSmrg	    sprintf(msg, "buttons %d and %d", b1, b2);
6959bd41f2cSmrg	 pMse->negativeZ = pMse->negativeW = 1 << (b1-1);
6969bd41f2cSmrg	 pMse->positiveZ = pMse->positiveW = 1 << (b2-1);
6979bd41f2cSmrg	 if (b1 > pMse->buttons) pMse->buttons = b1;
6989bd41f2cSmrg	 if (b2 > pMse->buttons) pMse->buttons = b2;
6999bd41f2cSmrg
7009bd41f2cSmrg	 /*
7019bd41f2cSmrg	  * Option "ZAxisMapping" "N1 N2 N3 N4" not supported
7029bd41f2cSmrg	  */
7039bd41f2cSmrg	 pMse->negativeW = pMse->positiveW = MSE_NOZMAP;
7049bd41f2cSmrg      } else {
7059bd41f2cSmrg	 pMse->negativeZ = pMse->positiveZ = MSE_NOZMAP;
7069bd41f2cSmrg	 pMse->negativeW = pMse->positiveW = MSE_NOZMAP;
7079bd41f2cSmrg      }
7089bd41f2cSmrg      if (msg) {
7099bd41f2cSmrg	 xf86Msg(X_CONFIG, "%s: ZAxisMapping: %s\n", pInfo->name, msg);
7109bd41f2cSmrg	 xfree(msg);
7119bd41f2cSmrg      } else {
7129bd41f2cSmrg	 xf86Msg(X_WARNING, "%s: Invalid ZAxisMapping value: \"%s\"\n",
7139bd41f2cSmrg		 pInfo->name, s);
7149bd41f2cSmrg      }
7159bd41f2cSmrg   }
7169bd41f2cSmrg
7179bd41f2cSmrg   /*
7189bd41f2cSmrg    * Emulatewheel is not supported
7199bd41f2cSmrg    */
7209bd41f2cSmrg   if (origButtons != pMse->buttons)
7219bd41f2cSmrg      from = X_CONFIG;
7229bd41f2cSmrg
7239bd41f2cSmrg}
7249bd41f2cSmrg
7259bd41f2cSmrg
7269bd41f2cSmrg/*
7279bd41f2cSmrg *----------------------------------------------------------------------
7289bd41f2cSmrg *
7299bd41f2cSmrg * VMMouseUnInit --
7309bd41f2cSmrg * 	This function was supposed to be called by Xserver to do Un-Init.
7319bd41f2cSmrg *	But it was unused now
7329bd41f2cSmrg *
7339bd41f2cSmrg * Results:
7349bd41f2cSmrg * 	None
7359bd41f2cSmrg *
7369bd41f2cSmrg * Side effects:
7379bd41f2cSmrg * 	None
7389bd41f2cSmrg *
7399bd41f2cSmrg *----------------------------------------------------------------------
7409bd41f2cSmrg */
7419bd41f2cSmrg
7429bd41f2cSmrgstatic void
7439bd41f2cSmrgVMMouseUnInit(InputDriverPtr drv, LocalDevicePtr local, int flags)
7449bd41f2cSmrg{
7459bd41f2cSmrg   xf86Msg(X_INFO, "VMWARE(0): VMMouseUnInit\n");
7469bd41f2cSmrg}
7479bd41f2cSmrg
7489bd41f2cSmrg
7499bd41f2cSmrg/*
7509bd41f2cSmrg *----------------------------------------------------------------------
7519bd41f2cSmrg *
7529bd41f2cSmrg * VMMouseDeviceControl --
7539bd41f2cSmrg * 	This function was called by Xserver during DEVICE_INIT, DEVICE_ON,
7549bd41f2cSmrg *	DEVICE_OFF and DEVICE_CLOSE phase
7559bd41f2cSmrg *
7569bd41f2cSmrg * Results:
7579bd41f2cSmrg * 	TRUE, if sucessful
7589bd41f2cSmrg *	FALSE, if failed
7599bd41f2cSmrg *
7609bd41f2cSmrg * Side effects:
7619bd41f2cSmrg * 	Absolute pointing device is enabled during DEVICE_ON
7629bd41f2cSmrg *	Absolute pointing device is disabled during DEVICE_OFF
7639bd41f2cSmrg *	and DEVICE_CLOSE
7649bd41f2cSmrg *
7659bd41f2cSmrg *----------------------------------------------------------------------
7669bd41f2cSmrg */
7679bd41f2cSmrg
7689bd41f2cSmrgstatic Bool
7699bd41f2cSmrgVMMouseDeviceControl(DeviceIntPtr device, int mode)
7709bd41f2cSmrg{
7719bd41f2cSmrg   InputInfoPtr pInfo;
7729bd41f2cSmrg   MouseDevPtr pMse;
7739bd41f2cSmrg   VMMousePrivPtr mPriv;
7749bd41f2cSmrg   unsigned char map[MSE_MAXBUTTONS + 1];
7759bd41f2cSmrg   int i;
7769bd41f2cSmrg
7779bd41f2cSmrg   pInfo = device->public.devicePrivate;
7789bd41f2cSmrg   pMse = pInfo->private;
7799bd41f2cSmrg   pMse->device = device;
7809bd41f2cSmrg   mPriv = (VMMousePrivPtr)pMse->mousePriv;
7819bd41f2cSmrg
7829bd41f2cSmrg   switch (mode){
7839bd41f2cSmrg   case DEVICE_INIT:
7849bd41f2cSmrg      device->public.on = FALSE;
7859bd41f2cSmrg      /*
7869bd41f2cSmrg       * [KAZU-241097] We don't know exactly how many buttons the
7879bd41f2cSmrg       * device has, so setup the map with the maximum number.
7889bd41f2cSmrg       */
7899bd41f2cSmrg      for (i = 0; i < MSE_MAXBUTTONS; i++)
7909bd41f2cSmrg	 map[i + 1] = i + 1;
7919bd41f2cSmrg
7929bd41f2cSmrg      InitPointerDeviceStruct((DevicePtr)device, map,
7939bd41f2cSmrg			      min(pMse->buttons, MSE_MAXBUTTONS),
7949bd41f2cSmrg#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) == 0
7959bd41f2cSmrg				miPointerGetMotionEvents,
7969bd41f2cSmrg#else
7979bd41f2cSmrg                                GetMotionHistory,
7989bd41f2cSmrg#endif
7999bd41f2cSmrg                                pMse->Ctrl,
8009bd41f2cSmrg#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) == 0
8019bd41f2cSmrg				miPointerGetMotionBufferSize()
8029bd41f2cSmrg#else
8039bd41f2cSmrg                                GetMotionHistorySize(), 2
8049bd41f2cSmrg#endif
8059bd41f2cSmrg                                );
8069bd41f2cSmrg
8079bd41f2cSmrg      /* X valuator */
8089bd41f2cSmrg      xf86InitValuatorAxisStruct(device, 0, 0, -1, 1, 0, 1);
8099bd41f2cSmrg      xf86InitValuatorDefaults(device, 0);
8109bd41f2cSmrg      /* Y valuator */
8119bd41f2cSmrg      xf86InitValuatorAxisStruct(device, 1, 0, -1, 1, 0, 1);
8129bd41f2cSmrg      xf86InitValuatorDefaults(device, 1);
8139bd41f2cSmrg#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) == 0
8149bd41f2cSmrg      xf86MotionHistoryAllocate(pInfo);
8159bd41f2cSmrg#endif
8169bd41f2cSmrg
8179bd41f2cSmrg      xf86Msg(X_INFO, "VMWARE(0): VMMOUSE DEVICE_INIT\n");
8189bd41f2cSmrg#ifdef EXTMOUSEDEBUG
8199bd41f2cSmrg      xf86Msg(X_INFO, "assigning %p atom=%d name=%s\n", device, pInfo->atom,
8209bd41f2cSmrg	     pInfo->name);
8219bd41f2cSmrg#endif
8229bd41f2cSmrg      break;
8239bd41f2cSmrg
8249bd41f2cSmrg   case DEVICE_ON:
8259bd41f2cSmrg      xf86Msg(X_INFO, "VMWARE(0): VMMOUSE DEVICE_ON\n");
8269bd41f2cSmrg      pInfo->fd = xf86OpenSerial(pInfo->options);
8279bd41f2cSmrg      if (pInfo->fd == -1)
8289bd41f2cSmrg	 xf86Msg(X_WARNING, "%s: cannot open input device\n", pInfo->name);
8299bd41f2cSmrg      else {
8309bd41f2cSmrg	 pMse->buffer = XisbNew(pInfo->fd, 64);
8319bd41f2cSmrg	 if (!pMse->buffer) {
8329bd41f2cSmrg	    xf86CloseSerial(pInfo->fd);
8339bd41f2cSmrg	    pInfo->fd = -1;
8349bd41f2cSmrg	 } else {
8359bd41f2cSmrg	    VMMousePrivPtr mPriv = (VMMousePrivPtr)pMse->mousePriv;
8369bd41f2cSmrg	    if (mPriv != NULL) {
8379bd41f2cSmrg	       /*
8389bd41f2cSmrg		* enable absolute pointing device here
8399bd41f2cSmrg		*/
8409bd41f2cSmrg	       if (!VMMouseClient_Enable()) {
8419bd41f2cSmrg		  xf86Msg(X_ERROR, "VMWARE(0): vmmouse enable failed\n");
8429bd41f2cSmrg		  mPriv->vmmouseAvailable = FALSE;
8439bd41f2cSmrg		  device->public.on = FALSE;
8449bd41f2cSmrg		  return FALSE;
8459bd41f2cSmrg	       } else {
8469bd41f2cSmrg		  mPriv->vmmouseAvailable = TRUE;
8479bd41f2cSmrg		  VMMouseClient_RequestAbsolute();
8489bd41f2cSmrg		  mPriv->relative = FALSE;
8499bd41f2cSmrg		  xf86Msg(X_INFO, "VMWARE(0): vmmouse enabled\n");
8509bd41f2cSmrg	       }
8519bd41f2cSmrg	    }
8529bd41f2cSmrg	    xf86FlushInput(pInfo->fd);
8539bd41f2cSmrg	    xf86AddEnabledDevice(pInfo);
8549bd41f2cSmrg	 }
8559bd41f2cSmrg      }
8569bd41f2cSmrg      pMse->lastButtons = 0;
8579bd41f2cSmrg      device->public.on = TRUE;
8589bd41f2cSmrg      FlushButtons(pMse);
8599bd41f2cSmrg      break;
8609bd41f2cSmrg   case DEVICE_OFF:
8619bd41f2cSmrg   case DEVICE_CLOSE:
8629bd41f2cSmrg      xf86Msg(X_INFO, "VMWARE(0): VMMOUSE DEVICE_OFF/CLOSE\n");
8639bd41f2cSmrg
8649bd41f2cSmrg      if (pInfo->fd != -1) {
8659bd41f2cSmrg	 VMMousePrivPtr mPriv = (VMMousePrivPtr)pMse->mousePriv;
8669bd41f2cSmrg	 if( mPriv->vmmouseAvailable ) {
8679bd41f2cSmrg	    VMMouseClient_Disable();
8689bd41f2cSmrg	    mPriv->vmmouseAvailable = FALSE;
8699bd41f2cSmrg	 }
8709bd41f2cSmrg
8719bd41f2cSmrg	 xf86RemoveEnabledDevice(pInfo);
8729bd41f2cSmrg	 if (pMse->buffer) {
8739bd41f2cSmrg	    XisbFree(pMse->buffer);
8749bd41f2cSmrg	    pMse->buffer = NULL;
8759bd41f2cSmrg	 }
8769bd41f2cSmrg	 xf86CloseSerial(pInfo->fd);
8779bd41f2cSmrg	 pInfo->fd = -1;
8789bd41f2cSmrg      }
8799bd41f2cSmrg      device->public.on = FALSE;
8809bd41f2cSmrg      usleep(300000);
8819bd41f2cSmrg      break;
8829bd41f2cSmrg
8839bd41f2cSmrg   }
8849bd41f2cSmrg
8859bd41f2cSmrg   return Success;
8869bd41f2cSmrg}
8879bd41f2cSmrg
8889bd41f2cSmrg
8899bd41f2cSmrg/*
8909bd41f2cSmrg *----------------------------------------------------------------------
8919bd41f2cSmrg *
8929bd41f2cSmrg * VMMouseReadInput --
8939bd41f2cSmrg * 	This function was called by Xserver when there is data available
8949bd41f2cSmrg *	in the input device
8959bd41f2cSmrg *
8969bd41f2cSmrg * Results:
8979bd41f2cSmrg * 	None
8989bd41f2cSmrg *
8999bd41f2cSmrg * Side effects:
9009bd41f2cSmrg * 	Input data in regular PS/2 fd was cleared
9019bd41f2cSmrg *	Real mouse data was read from the absolute pointing device
9029bd41f2cSmrg *	and posted to Xserver
9039bd41f2cSmrg *
9049bd41f2cSmrg *----------------------------------------------------------------------
9059bd41f2cSmrg */
9069bd41f2cSmrg
9079bd41f2cSmrgstatic void
9089bd41f2cSmrgVMMouseReadInput(InputInfoPtr pInfo)
9099bd41f2cSmrg{
9109bd41f2cSmrg   MouseDevPtr pMse;
9119bd41f2cSmrg   VMMousePrivPtr mPriv;
9129bd41f2cSmrg   int c;
9139bd41f2cSmrg   int len = 0;
9149bd41f2cSmrg
9159bd41f2cSmrg   pMse = pInfo->private;
9169bd41f2cSmrg   mPriv = pMse->mousePriv;
9179bd41f2cSmrg
9189bd41f2cSmrg   /*
9199bd41f2cSmrg    * First read the bytes in input device to clear the regular PS/2 fd so
9209bd41f2cSmrg    * we don't get called again.
9219bd41f2cSmrg    */
9229bd41f2cSmrg   /*
9239bd41f2cSmrg    * Set blocking to -1 on the first call because we know there is data to
9249bd41f2cSmrg    * read. Xisb automatically clears it after one successful read so that
9259bd41f2cSmrg    * succeeding reads are preceeded by a select with a 0 timeout to prevent
9269bd41f2cSmrg    * read from blocking indefinitely.
9279bd41f2cSmrg    */
9289bd41f2cSmrg   XisbBlockDuration(pMse->buffer, -1);
9299bd41f2cSmrg   while ((c = XisbRead(pMse->buffer)) >= 0) {
9309bd41f2cSmrg      len++;
9319bd41f2cSmrg      /*
9329bd41f2cSmrg       * regular PS packet consists of 3 bytes
9339bd41f2cSmrg       * We read 3 bytes to drain the PS/2 packet
9349bd41f2cSmrg       */
9359bd41f2cSmrg      if(len < 3) continue;
9369bd41f2cSmrg      len = 0;
9379bd41f2cSmrg      /*
9389bd41f2cSmrg       * Now get the real data from absolute pointing device
9399bd41f2cSmrg       */
9409bd41f2cSmrg      GetVMMouseMotionEvent(pInfo);
9419bd41f2cSmrg   }
9429bd41f2cSmrg   /*
9439bd41f2cSmrg    * There maybe still vmmouse data available
9449bd41f2cSmrg    */
9459bd41f2cSmrg   GetVMMouseMotionEvent(pInfo);
9469bd41f2cSmrg}
9479bd41f2cSmrg
9489bd41f2cSmrg
9499bd41f2cSmrg/*
9509bd41f2cSmrg *----------------------------------------------------------------------
9519bd41f2cSmrg *
9529bd41f2cSmrg * GetVMMouseMotionEvent --
9539bd41f2cSmrg * 	Read all the mouse data available from the absolute
9549bd41f2cSmrg * 	pointing device	and post it to the Xserver
9559bd41f2cSmrg *
9569bd41f2cSmrg * Results:
9579bd41f2cSmrg * 	None
9589bd41f2cSmrg *
9599bd41f2cSmrg * Side effects:
9609bd41f2cSmrg *	Real mouse data was read from the absolute pointing
9619bd41f2cSmrg *	device and posted to Xserver
9629bd41f2cSmrg *
9639bd41f2cSmrg *----------------------------------------------------------------------
9649bd41f2cSmrg */
9659bd41f2cSmrg
9669bd41f2cSmrgstatic void
9679bd41f2cSmrgGetVMMouseMotionEvent(InputInfoPtr pInfo){
9689bd41f2cSmrg   MouseDevPtr pMse;
9699bd41f2cSmrg   int buttons, dx, dy, dz, dw;
9709bd41f2cSmrg   VMMOUSE_INPUT_DATA  vmmouseInput;
9719bd41f2cSmrg   int ps2Buttons = 0;
9729bd41f2cSmrg   int numPackets;
9739bd41f2cSmrg
9749bd41f2cSmrg   pMse = pInfo->private;
9759bd41f2cSmrg   while((numPackets = VMMouseClient_GetInput(&vmmouseInput))){
9769bd41f2cSmrg      if (numPackets == VMMOUSE_ERROR) {
9779bd41f2cSmrg         VMMouseClient_Disable();
9789bd41f2cSmrg         VMMouseClient_Enable();
9799bd41f2cSmrg         VMMouseClient_RequestAbsolute();
9809bd41f2cSmrg         xf86Msg(X_INFO, "VMWARE(0): re-requesting absolute mode after reset\n");
9819bd41f2cSmrg         break;
9829bd41f2cSmrg      }
9839bd41f2cSmrg
9849bd41f2cSmrg      if(vmmouseInput.Buttons & VMMOUSE_MIDDLE_BUTTON)
9859bd41f2cSmrg	 ps2Buttons |= 0x04; 			/* Middle*/
9869bd41f2cSmrg      if(vmmouseInput.Buttons & VMMOUSE_RIGHT_BUTTON)
9879bd41f2cSmrg	 ps2Buttons |= 0x02; 			/* Right*/
9889bd41f2cSmrg      if(vmmouseInput.Buttons & VMMOUSE_LEFT_BUTTON)
9899bd41f2cSmrg	 ps2Buttons |= 0x01; 			/* Left*/
9909bd41f2cSmrg
9919bd41f2cSmrg      buttons = (ps2Buttons & 0x04) >> 1 |	/* Middle */
9929bd41f2cSmrg	 (ps2Buttons & 0x02) >> 1 |       	/* Right */
9939bd41f2cSmrg	 (ps2Buttons & 0x01) << 2;       	/* Left */
9949bd41f2cSmrg
9959bd41f2cSmrg      dx = vmmouseInput.X;
9969bd41f2cSmrg      dy = vmmouseInput.Y;
9979bd41f2cSmrg      dz = (char)vmmouseInput.Z;
9989bd41f2cSmrg      dw = 0;
9999bd41f2cSmrg      /* post an event */
10009bd41f2cSmrg      pMse->PostEvent(pInfo, buttons, dx, dy, dz, dw);
10019bd41f2cSmrg   }
10029bd41f2cSmrg}
10039bd41f2cSmrg
10049bd41f2cSmrg
10059bd41f2cSmrg/*
10069bd41f2cSmrg *----------------------------------------------------------------------
10079bd41f2cSmrg *
10089bd41f2cSmrg * VMMouseControlProc --
10099bd41f2cSmrg *	This function is unused
10109bd41f2cSmrg *
10119bd41f2cSmrg * Results:
10129bd41f2cSmrg * 	None
10139bd41f2cSmrg *
10149bd41f2cSmrg * Side effects:
10159bd41f2cSmrg * 	None
10169bd41f2cSmrg *
10179bd41f2cSmrg *----------------------------------------------------------------------
10189bd41f2cSmrg */
10199bd41f2cSmrg
10209bd41f2cSmrgstatic int
10219bd41f2cSmrgVMMouseControlProc(LocalDevicePtr local, xDeviceCtl * control)
10229bd41f2cSmrg{
10239bd41f2cSmrg   xf86Msg(X_INFO, "VMWARE(0): VMMouseControlProc\n");
10249bd41f2cSmrg   return (Success);
10259bd41f2cSmrg}
10269bd41f2cSmrg
10279bd41f2cSmrg
10289bd41f2cSmrg/*
10299bd41f2cSmrg *----------------------------------------------------------------------
10309bd41f2cSmrg *
10319bd41f2cSmrg *  VMMouseCloseProc --
10329bd41f2cSmrg *	This function is unused
10339bd41f2cSmrg *
10349bd41f2cSmrg * Results:
10359bd41f2cSmrg * 	None
10369bd41f2cSmrg *
10379bd41f2cSmrg * Side effects:
10389bd41f2cSmrg * 	None
10399bd41f2cSmrg *
10409bd41f2cSmrg *----------------------------------------------------------------------
10419bd41f2cSmrg */
10429bd41f2cSmrg
10439bd41f2cSmrgstatic void
10449bd41f2cSmrgVMMouseCloseProc(LocalDevicePtr local)
10459bd41f2cSmrg{
10469bd41f2cSmrg   xf86Msg(X_INFO, "VMWARE(0): VMMouseCloseProc\n");
10479bd41f2cSmrg}
10489bd41f2cSmrg
10499bd41f2cSmrg
10509bd41f2cSmrg/*
10519bd41f2cSmrg *----------------------------------------------------------------------
10529bd41f2cSmrg *
10539bd41f2cSmrg *  VMMouseSwitchProc --
10549bd41f2cSmrg *	This function is unused
10559bd41f2cSmrg *
10569bd41f2cSmrg * Results:
10579bd41f2cSmrg * 	None
10589bd41f2cSmrg *
10599bd41f2cSmrg * Side effects:
10609bd41f2cSmrg * 	None
10619bd41f2cSmrg *
10629bd41f2cSmrg *----------------------------------------------------------------------
10639bd41f2cSmrg */
10649bd41f2cSmrg
10659bd41f2cSmrgstatic int
10669bd41f2cSmrgVMMouseSwitchMode(ClientPtr client, DeviceIntPtr dev, int mode)
10679bd41f2cSmrg{
10689bd41f2cSmrg   xf86Msg(X_INFO, "VMWARE(0): VMMouseSwitchMode\n");
10699bd41f2cSmrg   return (Success);
10709bd41f2cSmrg}
10719bd41f2cSmrg
10729bd41f2cSmrg
10739bd41f2cSmrg/*
10749bd41f2cSmrg *----------------------------------------------------------------------
10759bd41f2cSmrg *
10769bd41f2cSmrg * VMMouseConvertProc  --
10779bd41f2cSmrg * 	This function was called by Xserver to convert valuators to X and Y
10789bd41f2cSmrg *
10799bd41f2cSmrg * Results:
10809bd41f2cSmrg * 	TRUE
10819bd41f2cSmrg *
10829bd41f2cSmrg * Side effects:
10839bd41f2cSmrg * 	X and Y was converted according to current Screen dimension
10849bd41f2cSmrg *
10859bd41f2cSmrg *----------------------------------------------------------------------
10869bd41f2cSmrg */
10879bd41f2cSmrg
10889bd41f2cSmrgstatic Bool
10899bd41f2cSmrgVMMouseConvertProc(InputInfoPtr pInfo, int first, int num, int v0, int v1, int v2,
10909bd41f2cSmrg	     int v3, int v4, int v5, int *x, int *y)
10919bd41f2cSmrg{
10929bd41f2cSmrg   MouseDevPtr pMse;
10939bd41f2cSmrg   VMMousePrivPtr mPriv;
10949bd41f2cSmrg   double factorX, factorY;
10959bd41f2cSmrg
10969bd41f2cSmrg   pMse = pInfo->private;
10979bd41f2cSmrg   mPriv = pMse->mousePriv;
10989bd41f2cSmrg
10999bd41f2cSmrg   if (first != 0 || num != 2)
11009bd41f2cSmrg      return FALSE;
11019bd41f2cSmrg
11029bd41f2cSmrg   if(mPriv->relative) {
11039bd41f2cSmrg      *x = v0;
11049bd41f2cSmrg      *y = v1;
11059bd41f2cSmrg   } else {
11069bd41f2cSmrg      factorX = ((double) screenInfo.screens[mPriv->screenNum]->width) / (double) 65535;
11079bd41f2cSmrg      factorY = ((double) screenInfo.screens[mPriv->screenNum]->height) / (double) 65535;
11089bd41f2cSmrg
11099bd41f2cSmrg      *x = v0 * factorX + 0.5;
11109bd41f2cSmrg      *y = v1 * factorY + 0.5;
11119bd41f2cSmrg
11129bd41f2cSmrg      if (mPriv->screenNum != -1) {
11139bd41f2cSmrg	 xf86XInputSetScreen(pInfo, mPriv->screenNum, *x, *y);
11149bd41f2cSmrg      }
11159bd41f2cSmrg   }
11169bd41f2cSmrg   return TRUE;
11179bd41f2cSmrg}
11189bd41f2cSmrg
11199bd41f2cSmrg
11209bd41f2cSmrg#ifdef XFree86LOADER
11219bd41f2cSmrgModuleInfoRec VMMouseInfo = {
11229bd41f2cSmrg    1,
11239bd41f2cSmrg    "VMMOUSE",
11249bd41f2cSmrg    NULL,
11259bd41f2cSmrg    0,
11269bd41f2cSmrg    VMMouseAvailableOptions,
11279bd41f2cSmrg};
11289bd41f2cSmrg
11299bd41f2cSmrg
11309bd41f2cSmrg/*
11319bd41f2cSmrg *----------------------------------------------------------------------
11329bd41f2cSmrg *
11339bd41f2cSmrg * VMMouseUnplug  --
11349bd41f2cSmrg * 	This function was called by Xserver when unplug
11359bd41f2cSmrg *
11369bd41f2cSmrg * Results:
11379bd41f2cSmrg * 	None
11389bd41f2cSmrg *
11399bd41f2cSmrg * Side effects:
11409bd41f2cSmrg * 	None
11419bd41f2cSmrg *
11429bd41f2cSmrg *----------------------------------------------------------------------
11439bd41f2cSmrg */
11449bd41f2cSmrg
11459bd41f2cSmrgstatic void
11469bd41f2cSmrgVMMouseUnplug(pointer p)
11479bd41f2cSmrg{
11489bd41f2cSmrg   xf86Msg(X_INFO, "VMWARE(0): VMMouseUnplug\n");
11499bd41f2cSmrg}
11509bd41f2cSmrg
11519bd41f2cSmrg
11529bd41f2cSmrg/*
11539bd41f2cSmrg *----------------------------------------------------------------------
11549bd41f2cSmrg *
11559bd41f2cSmrg * VMMousePlug  --
11569bd41f2cSmrg * 	This function was called when Xserver load vmmouse module. It will
11579bd41f2cSmrg * 	integrate the  module infto the XFree86 loader architecutre.
11589bd41f2cSmrg *
11599bd41f2cSmrg * Results:
11609bd41f2cSmrg * 	TRUE
11619bd41f2cSmrg *
11629bd41f2cSmrg * Side effects:
11639bd41f2cSmrg * 	Regular mouse module was loaded as a submodule. In case
11649bd41f2cSmrg * 	absolute pointing device is not available, we can always fall back
11659bd41f2cSmrg *	to the regular mouse module
11669bd41f2cSmrg *
11679bd41f2cSmrg *----------------------------------------------------------------------
11689bd41f2cSmrg */
11699bd41f2cSmrg
11709bd41f2cSmrgstatic pointer
11719bd41f2cSmrgVMMousePlug(pointer	module,
11729bd41f2cSmrg	    pointer	options,
11739bd41f2cSmrg	    int		*errmaj,
11749bd41f2cSmrg	    int		*errmin)
11759bd41f2cSmrg{
11769bd41f2cSmrg   static Bool Initialised = FALSE;
11779bd41f2cSmrg   char *name;
11789bd41f2cSmrg
11799bd41f2cSmrg   xf86LoaderReqSymLists(reqSymbols, NULL);
11809bd41f2cSmrg
11819bd41f2cSmrg   if (!Initialised) {
11829bd41f2cSmrg      Initialised = TRUE;
11839bd41f2cSmrg#ifndef REMOVE_LOADER_CHECK_MODULE_INFO
11849bd41f2cSmrg      if (xf86LoaderCheckSymbol("xf86AddModuleInfo"))
11859bd41f2cSmrg#endif
11869bd41f2cSmrg	 xf86AddModuleInfo(&VMMouseInfo, module);
11879bd41f2cSmrg   }
11889bd41f2cSmrg
11899bd41f2cSmrg   xf86Msg(X_INFO, "VMWARE(0): VMMOUSE module was loaded\n");
11909bd41f2cSmrg   xf86AddInputDriver(&VMMOUSE, module, 0);
11919bd41f2cSmrg
11929bd41f2cSmrg   /*
11939bd41f2cSmrg    * Load the normal mouse module as submodule
11949bd41f2cSmrg    * If we fail in PreInit later, this allows us to fall back to normal mouse module
11959bd41f2cSmrg    */
11969bd41f2cSmrg#ifndef NORMALISE_MODULE_NAME
11979bd41f2cSmrg   name = xstrdup("mouse");
11989bd41f2cSmrg#else
11999bd41f2cSmrg   /* Normalise the module name */
12009bd41f2cSmrg   name = xf86NormalizeName("mouse");
12019bd41f2cSmrg#endif
12029bd41f2cSmrg
12039bd41f2cSmrg   if (!LoadSubModule(module, name, NULL, NULL, NULL, NULL, errmaj, errmin)) {
12049bd41f2cSmrg      LoaderErrorMsg(NULL, name, *errmaj, *errmin);
12059bd41f2cSmrg   }
12069bd41f2cSmrg   xfree(name);
12079bd41f2cSmrg
12089bd41f2cSmrg   return module;
12099bd41f2cSmrg}
12109bd41f2cSmrg
12119bd41f2cSmrgstatic XF86ModuleVersionInfo VMMouseVersionRec = {
12129bd41f2cSmrg   "vmmouse",
12139bd41f2cSmrg   MODULEVENDORSTRING,
12149bd41f2cSmrg   MODINFOSTRING1,
12159bd41f2cSmrg   MODINFOSTRING2,
12169bd41f2cSmrg   XORG_VERSION_CURRENT,
12179bd41f2cSmrg   VMMOUSE_MAJOR_VERSION, VMMOUSE_MINOR_VERSION, VMMOUSE_PATCHLEVEL,
12189bd41f2cSmrg   ABI_CLASS_XINPUT,
12199bd41f2cSmrg   ABI_XINPUT_VERSION,
12209bd41f2cSmrg   MOD_CLASS_XINPUT,
12219bd41f2cSmrg   {0, 0, 0, 0}		/* signature, to be patched into the file by a tool */
12229bd41f2cSmrg};
12239bd41f2cSmrg
12249bd41f2cSmrg/*
12259bd41f2cSmrg * The variable contains the necessary information to load and initialize the module
12269bd41f2cSmrg */
12279bd41f2cSmrgXF86ModuleData vmmouseModuleData = {
12289bd41f2cSmrg   &VMMouseVersionRec,
12299bd41f2cSmrg   VMMousePlug,
12309bd41f2cSmrg   VMMouseUnplug
12319bd41f2cSmrg};
12329bd41f2cSmrg#endif /* XFree86LOADER */
1233