vmmouse.c revision c4f7863a
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
35d075918cSmrg *
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.
39d075918cSmrg *
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#include <X11/X.h>
529bd41f2cSmrg#include <X11/Xproto.h>
539bd41f2cSmrg
549bd41f2cSmrg#include "xf86.h"
559bd41f2cSmrg
569bd41f2cSmrg#ifdef XINPUT
579bd41f2cSmrg#include <X11/extensions/XI.h>
589bd41f2cSmrg#include <X11/extensions/XIproto.h>
599bd41f2cSmrg#include "extnsionst.h"
609bd41f2cSmrg#include "extinit.h"
619bd41f2cSmrg#else
629bd41f2cSmrg#include "inputstr.h"
639bd41f2cSmrg#endif
649bd41f2cSmrg
659bd41f2cSmrg#include "xf86Xinput.h"
669bd41f2cSmrg#include "xf86_OSproc.h"
679bd41f2cSmrg#include "xf86OSmouse.h"
689bd41f2cSmrg#include "compiler.h"
699bd41f2cSmrg
70b15a006bSmrg#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 7
71b15a006bSmrg#include <xserver-properties.h>
72ea0de359Smrg#include "exevents.h"
73b15a006bSmrg#endif
74b15a006bSmrg
759bd41f2cSmrg#include "xisb.h"
769bd41f2cSmrg#include "mipointer.h"
779bd41f2cSmrg
78c4f7863aSmrg#ifndef HAVE_XORG_SERVER_1_5_0
79c4f7863aSmrg#include <xf86_ansic.h>
80c4f7863aSmrg#include <xf86_libc.h>
81c4f7863aSmrg#endif
82c4f7863aSmrg
839bd41f2cSmrg/*****************************************************************************
849bd41f2cSmrg *	Local Headers
859bd41f2cSmrg ****************************************************************************/
869bd41f2cSmrg#include "vmmouse_client.h"
879bd41f2cSmrg
889bd41f2cSmrg/*
899bd41f2cSmrg * This is the only way I know to turn a #define of an integer constant into
909bd41f2cSmrg * a constant string.
919bd41f2cSmrg */
929bd41f2cSmrg#define VMW_INNERSTRINGIFY(s) #s
939bd41f2cSmrg#define VMW_STRING(str) VMW_INNERSTRINGIFY(str)
949bd41f2cSmrg
959bd41f2cSmrg/*
969bd41f2cSmrg * So that the file compiles unmodified when dropped into an xfree source tree.
979bd41f2cSmrg */
989bd41f2cSmrg#ifndef XORG_VERSION_CURRENT
999bd41f2cSmrg#define XORG_VERSION_CURRENT XF86_VERSION_CURRENT
1009bd41f2cSmrg#endif
1019bd41f2cSmrg
1029bd41f2cSmrg/*
1039bd41f2cSmrg * Version constants
1049bd41f2cSmrg */
1059bd41f2cSmrg#define VMMOUSE_DRIVER_VERSION \
1069418810dSmrg   (PACKAGE_VERSION_MAJOR * 65536 + PACKAGE_VERSION_MINOR * 256 + PACKAGE_VERSION_PATCHLEVEL)
1079bd41f2cSmrg#define VMMOUSE_DRIVER_VERSION_STRING \
1089418810dSmrg    VMW_STRING(PACKAGE_VERSION_MAJOR) "." VMW_STRING(PACKAGE_VERSION_MINOR) \
1099418810dSmrg    "." VMW_STRING(PACKAGE_VERSION_PATCHLEVEL)
1109bd41f2cSmrg
1119bd41f2cSmrg/*
1129bd41f2cSmrg * Standard four digit version string expected by VMware Tools installer.
113c4f7863aSmrg * As the driver's version is only  {major, minor, patchlevel},
114c4f7863aSmrg * The fourth digit may describe the commit number relative to the
115c4f7863aSmrg * last version tag as output from `git describe`
1169bd41f2cSmrg */
1179bd41f2cSmrg#ifdef __GNUC__
118c4f7863aSmrg#ifdef VMW_SUBPATCH
119c4f7863aSmrgconst char vm_mouse_version[] __attribute__((section(".modinfo"),unused)) =
120c4f7863aSmrg    "version=" VMMOUSE_DRIVER_VERSION_STRING "." VMW_STRING(VMW_SUBPATCH);
121c4f7863aSmrg#else
1229bd41f2cSmrgconst char vm_mouse_version[] __attribute__((section(".modinfo"),unused)) =
1239bd41f2cSmrg    "version=" VMMOUSE_DRIVER_VERSION_STRING ".0";
124c4f7863aSmrg#endif /*VMW_SUBPATCH*/
1259bd41f2cSmrg#endif
1269bd41f2cSmrg
1279bd41f2cSmrg
1289bd41f2cSmrg/*****************************************************************************
1299bd41f2cSmrg *	static function header
1309bd41f2cSmrg ****************************************************************************/
131c4f7863aSmrg#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 12
132c4f7863aSmrgstatic int VMMousePreInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags);
133c4f7863aSmrg#else
1349bd41f2cSmrgstatic InputInfoPtr VMMousePreInit(InputDriverPtr drv, IDevPtr dev, int flags);
135c4f7863aSmrgstatic void VMMouseCloseProc(InputInfoPtr pInfo);
136c4f7863aSmrgstatic Bool VMMouseConvertProc(InputInfoPtr pInfo, int first, int num, int v0, int v1, int v2,
137c4f7863aSmrg			       int v3, int v4, int v5, int *x, int *y);
138c4f7863aSmrg#endif
1399bd41f2cSmrgstatic void VMMouseUnInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags);
1409bd41f2cSmrgstatic void MouseCommonOptions(InputInfoPtr pInfo);
1419bd41f2cSmrgstatic void GetVMMouseMotionEvent(InputInfoPtr pInfo);
1429bd41f2cSmrgstatic void VMMousePostEvent(InputInfoPtr pInfo, int buttons, int dx, int dy, int dz, int dw);
1439bd41f2cSmrgstatic void VMMouseDoPostEvent(InputInfoPtr pInfo, int buttons, int dx, int dy);
1449bd41f2cSmrgstatic Bool VMMouseDeviceControl(DeviceIntPtr device, int mode);
145c4f7863aSmrgstatic int  VMMouseControlProc(InputInfoPtr pInfo, xDeviceCtl * control);
1469bd41f2cSmrgstatic void VMMouseReadInput(InputInfoPtr pInfo);
1479bd41f2cSmrgstatic int  VMMouseSwitchMode(ClientPtr client, DeviceIntPtr dev, int mode);
1489bd41f2cSmrgstatic void MouseCtrl(DeviceIntPtr device, PtrCtrl *ctrl);
1499bd41f2cSmrg
1509bd41f2cSmrg/******************************************************************************
1519bd41f2cSmrg *		Definitions
1529bd41f2cSmrg *****************************************************************************/
1539bd41f2cSmrgtypedef struct {
154d075918cSmrg   int                 screenNum;
155d075918cSmrg   Bool                vmmouseAvailable;
156d075918cSmrg   VMMOUSE_INPUT_DATA  vmmousePrevInput;
157d075918cSmrg   Bool                isCurrRelative;
158d075918cSmrg   Bool                absoluteRequested;
1599bd41f2cSmrg} VMMousePrivRec, *VMMousePrivPtr;
1609bd41f2cSmrg
1619418810dSmrg#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) < 7
1629bd41f2cSmrgstatic const char *reqSymbols[] = {
1639bd41f2cSmrg   "InitPointerDeviceStruct",
1649bd41f2cSmrg   "LoaderSymbol",
1659bd41f2cSmrg   "LoadSubModule",
1669bd41f2cSmrg   "miPointerGetMotionBufferSize",
1679bd41f2cSmrg   "miPointerGetMotionEvents",
1689bd41f2cSmrg   "screenInfo",
1699bd41f2cSmrg   "Xcalloc",
1709bd41f2cSmrg   "xf86AddEnabledDevice",
1719bd41f2cSmrg   "xf86AddInputDriver",
1729bd41f2cSmrg   "xf86AddModuleInfo",
1739bd41f2cSmrg   "xf86AllocateInput",
1749bd41f2cSmrg   "xf86BlockSIGIO",
1759bd41f2cSmrg   "xf86CloseSerial",
1769bd41f2cSmrg   "xf86CollectInputOptions",
1779bd41f2cSmrg   "xf86ffs",
1789bd41f2cSmrg   "xf86FlushInput",
1799bd41f2cSmrg   "xf86GetAllowMouseOpenFail",
1809bd41f2cSmrg   "xf86GetMotionEvents",
1819bd41f2cSmrg   "xf86InitValuatorAxisStruct",
1829bd41f2cSmrg   "xf86InitValuatorDefaults",
1839bd41f2cSmrg   "xf86LoaderCheckSymbol",
1849bd41f2cSmrg   "xf86MotionHistoryAllocate",
1859bd41f2cSmrg   "xf86Msg",
1869bd41f2cSmrg   "xf86NameCmp",
1879bd41f2cSmrg   "xf86OpenSerial",
1889bd41f2cSmrg   "xf86OSMouseInit",
1899bd41f2cSmrg   "xf86PostButtonEvent",
1909bd41f2cSmrg   "xf86PostMotionEvent",
1919bd41f2cSmrg   "xf86ProcessCommonOptions",
1929bd41f2cSmrg   "xf86RemoveEnabledDevice",
1939bd41f2cSmrg   "xf86SetIntOption",
1949bd41f2cSmrg   "xf86SetStrOption",
1959bd41f2cSmrg   "xf86sprintf",
1969bd41f2cSmrg   "xf86sscanf",
1979bd41f2cSmrg   "xf86UnblockSIGIO",
1989bd41f2cSmrg   "xf86usleep",
1999bd41f2cSmrg   "xf86XInputSetScreen",
2009bd41f2cSmrg   "Xfree",
2019bd41f2cSmrg   "XisbBlockDuration",
2029bd41f2cSmrg   "XisbFree",
2039bd41f2cSmrg   "XisbNew",
2049bd41f2cSmrg   "XisbRead",
2059bd41f2cSmrg   "Xstrdup",
2069bd41f2cSmrg   NULL
2079bd41f2cSmrg};
2089418810dSmrg#endif
2099bd41f2cSmrg
2109bd41f2cSmrgInputDriverRec VMMOUSE = {
2119bd41f2cSmrg   1,
2129bd41f2cSmrg   "vmmouse",
2139bd41f2cSmrg   NULL,
2149bd41f2cSmrg   VMMousePreInit,
215d075918cSmrg   VMMouseUnInit,
216c4f7863aSmrg   NULL
217c4f7863aSmrg#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) < 11
218c4f7863aSmrg       ,
2199bd41f2cSmrg   0
220c4f7863aSmrg#endif
2219bd41f2cSmrg};
2229bd41f2cSmrg
2239bd41f2cSmrgstatic char reverseMap[32] = { 0,  4,  2,  6,  1,  5,  3,  7,
2249bd41f2cSmrg			       8, 12, 10, 14,  9, 13, 11, 15,
2259bd41f2cSmrg			      16, 20, 18, 22, 17, 21, 19, 23,
2269bd41f2cSmrg			      24, 28, 26, 30, 25, 29, 27, 31};
2279bd41f2cSmrg
2289bd41f2cSmrg#define reverseBits(map, b)	(((b) & ~0x0f) | map[(b) & 0x0f])
2299bd41f2cSmrg
230c4f7863aSmrg#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 12
231c4f7863aSmrgstatic int
232c4f7863aSmrgVMMouseInitPassthru(InputDriverPtr drv, InputInfoPtr pInfo, int flags)
233c4f7863aSmrg{
234c4f7863aSmrg   InputAttributes *attrs = NULL;
235c4f7863aSmrg   InputOption *input_options = NULL, *tmp, *opts;
236c4f7863aSmrg   pointer options;
237c4f7863aSmrg   DeviceIntPtr dev;
238c4f7863aSmrg   int rc;
239c4f7863aSmrg
240c4f7863aSmrg   options = xf86OptionListDuplicate(pInfo->options);
241c4f7863aSmrg   options = xf86ReplaceStrOption(options, "Driver", "mouse");
242c4f7863aSmrg
243c4f7863aSmrg   while(options) {
244c4f7863aSmrg      tmp = calloc(1, sizeof(InputOption));
245c4f7863aSmrg      tmp->key = xf86OptionName(options);
246c4f7863aSmrg      tmp->value = xf86OptionValue(options);
247c4f7863aSmrg      tmp->next = input_options;
248c4f7863aSmrg      input_options = tmp;
249c4f7863aSmrg      options = xf86NextOption(options);
250c4f7863aSmrg   }
251c4f7863aSmrg
252c4f7863aSmrg   rc = NewInputDeviceRequest(input_options, attrs, &dev);
253c4f7863aSmrg
254c4f7863aSmrg   opts = input_options;
255c4f7863aSmrg   tmp = opts;
256c4f7863aSmrg   while(opts) {
257c4f7863aSmrg      tmp = opts->next;
258c4f7863aSmrg      free(opts->key);
259c4f7863aSmrg      free(opts->value);
260c4f7863aSmrg      free(opts);
261c4f7863aSmrg      opts = tmp;
262c4f7863aSmrg   }
263c4f7863aSmrg
264c4f7863aSmrg   return rc;
265c4f7863aSmrg}
266c4f7863aSmrg
267c4f7863aSmrg#else /* if ABI_XINPUT_VERSION < 12 */
268c4f7863aSmrgstatic InputInfoPtr
269c4f7863aSmrgVMMouseInitPassthru(InputDriverPtr drv, IDevPtr dev, int flags)
270c4f7863aSmrg{
271c4f7863aSmrg   InputDriverRec *passthruMouse;
272c4f7863aSmrg   passthruMouse = (InputDriverRec *)LoaderSymbol("MOUSE");
273c4f7863aSmrg   if(passthruMouse != NULL) {
274c4f7863aSmrg      return (passthruMouse->PreInit)(drv, dev, flags);
275c4f7863aSmrg   } else {
276c4f7863aSmrg      return NULL;
277c4f7863aSmrg   }
278c4f7863aSmrg}
279c4f7863aSmrg#endif
2809bd41f2cSmrg
2819bd41f2cSmrg/*
2829bd41f2cSmrg *----------------------------------------------------------------------
2839bd41f2cSmrg *
2849bd41f2cSmrg * VMMousePreInit --
2859bd41f2cSmrg *	This function collect all the information that is necessary to
2869bd41f2cSmrg *	determine the configuration of the hardware and to prepare the
2879bd41f2cSmrg *	device for being used
288d075918cSmrg *
2899bd41f2cSmrg * Results:
2909bd41f2cSmrg * 	An InputInfoPtr object which points to vmmouse's information,
2919bd41f2cSmrg *	if the absolute pointing device available
2929bd41f2cSmrg *	Otherwise, an InputInfoPtr of regular mouse
293d075918cSmrg *
2949bd41f2cSmrg * Side effects:
2959bd41f2cSmrg * 	VMMouse was initialized with necessary information
2969bd41f2cSmrg *
2979bd41f2cSmrg *----------------------------------------------------------------------
2989bd41f2cSmrg */
2999bd41f2cSmrg
300c4f7863aSmrg#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) < 12
301c4f7863aSmrgstatic int
302c4f7863aSmrgVMMouseNewPreInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags);
303c4f7863aSmrg
3049bd41f2cSmrgstatic InputInfoPtr
3059bd41f2cSmrgVMMousePreInit(InputDriverPtr drv, IDevPtr dev, int flags)
306d075918cSmrg{
3079bd41f2cSmrg   InputInfoPtr pInfo;
308b15a006bSmrg
309b15a006bSmrg#ifndef NO_MOUSE_MODULE
310b15a006bSmrg{
3119bd41f2cSmrg   OSMouseInfoPtr osInfo = NULL;
3129bd41f2cSmrg
3139bd41f2cSmrg   /*
3149bd41f2cSmrg    * let Xserver init the mouse first
315d075918cSmrg    */
3169bd41f2cSmrg   osInfo = xf86OSMouseInit(0);
3179bd41f2cSmrg   if (!osInfo)
3189bd41f2cSmrg      return FALSE;
319b15a006bSmrg}
320b15a006bSmrg#endif
321d075918cSmrg
3229bd41f2cSmrg   /*
3239bd41f2cSmrg    * try to enable vmmouse here
3249bd41f2cSmrg    */
3259bd41f2cSmrg   if (!VMMouseClient_Enable()) {
3269bd41f2cSmrg      /*
3279bd41f2cSmrg       * vmmouse failed
3289bd41f2cSmrg       * Fall back to normal mouse module
3299bd41f2cSmrg       */
3309bd41f2cSmrg      xf86Msg(X_ERROR, "VMWARE(0): vmmouse enable failed\n");
331c4f7863aSmrg      return VMMouseInitPassthru(drv, dev, flags);
3329bd41f2cSmrg   } else {
3339bd41f2cSmrg      /*
3349bd41f2cSmrg       * vmmouse is available
3359bd41f2cSmrg       */
3369bd41f2cSmrg      xf86Msg(X_INFO, "VMWARE(0): vmmouse is available\n");
3379bd41f2cSmrg      /*
3389bd41f2cSmrg       * Disable the absolute pointing device for now
3399bd41f2cSmrg       * It will be enabled during DEVICE_ON phase
3409bd41f2cSmrg       */
341d075918cSmrg      VMMouseClient_Disable();
3429bd41f2cSmrg   }
343d075918cSmrg
3449bd41f2cSmrg   if (!(pInfo = xf86AllocateInput(drv, 0))) {
3459bd41f2cSmrg      return NULL;
346d075918cSmrg   }
3479bd41f2cSmrg
348d075918cSmrg   pInfo->name = dev->identifier;
3499bd41f2cSmrg#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) == 0
3509bd41f2cSmrg   pInfo->motion_history_proc = xf86GetMotionEvents;
3519bd41f2cSmrg#endif
3529bd41f2cSmrg   pInfo->close_proc = VMMouseCloseProc;
3539bd41f2cSmrg   pInfo->conversion_proc = VMMouseConvertProc;
3549bd41f2cSmrg   pInfo->reverse_conversion_proc = NULL;
3559bd41f2cSmrg   pInfo->fd = -1;
3569bd41f2cSmrg   pInfo->dev = NULL;
3579bd41f2cSmrg   pInfo->private_flags = 0;
3589bd41f2cSmrg   pInfo->always_core_feedback = 0;
3599bd41f2cSmrg   pInfo->conf_idev = dev;
360c4f7863aSmrg   pInfo->flags = XI86_POINTER_CAPABLE | XI86_SEND_DRAG_EVENTS;
361c4f7863aSmrg
362c4f7863aSmrg   /* Collect the options, and process the common options. */
363c4f7863aSmrg   xf86CollectInputOptions(pInfo, NULL, NULL);
364c4f7863aSmrg   xf86ProcessCommonOptions(pInfo, pInfo->options);
365c4f7863aSmrg
366c4f7863aSmrg   if (VMMouseNewPreInit(drv, pInfo, flags) == Success)
367c4f7863aSmrg       pInfo->flags |= XI86_CONFIGURED;
368c4f7863aSmrg
369c4f7863aSmrg   return pInfo;
370c4f7863aSmrg}
371c4f7863aSmrg
372c4f7863aSmrgstatic int
373c4f7863aSmrgVMMouseNewPreInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags)
374c4f7863aSmrg#else /* if ABI_XINPUT_VERSION >= 12 */
375c4f7863aSmrgstatic int
376c4f7863aSmrgVMMousePreInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags)
377c4f7863aSmrg#endif
378c4f7863aSmrg{
379c4f7863aSmrg   MouseDevPtr pMse = NULL;
380c4f7863aSmrg   VMMousePrivPtr mPriv = NULL;
381c4f7863aSmrg   int rc = Success;
382c4f7863aSmrg
383c4f7863aSmrg#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 12
384c4f7863aSmrg   /* For ABI < 12, we need to return the wrapped driver's pInfo (see
385c4f7863aSmrg    * above). ABI 12, we call NIDR and are done */
386c4f7863aSmrg   if (!VMMouseClient_Enable()) {
387c4f7863aSmrg      xf86Msg(X_ERROR, "VMWARE(0): vmmouse enable failed\n");
388c4f7863aSmrg      return VMMouseInitPassthru(drv, pInfo, flags);
389c4f7863aSmrg   } else {
390c4f7863aSmrg      xf86Msg(X_INFO, "VMWARE(0): vmmouse is available\n");
391c4f7863aSmrg      VMMouseClient_Disable();
392c4f7863aSmrg   }
393c4f7863aSmrg#endif
394c4f7863aSmrg
395c4f7863aSmrg   mPriv = calloc (1, sizeof (VMMousePrivRec));
396c4f7863aSmrg
397c4f7863aSmrg   if (!mPriv) {
398c4f7863aSmrg      rc = BadAlloc;
399c4f7863aSmrg      goto error;
400c4f7863aSmrg   }
401c4f7863aSmrg
402c4f7863aSmrg   mPriv->absoluteRequested = FALSE;
403c4f7863aSmrg   mPriv->vmmouseAvailable = TRUE;
404c4f7863aSmrg
405c4f7863aSmrg   /* Settup the pInfo */
406c4f7863aSmrg   pInfo->type_name = XI_MOUSE;
407c4f7863aSmrg   pInfo->device_control = VMMouseDeviceControl;
408c4f7863aSmrg   pInfo->read_input = VMMouseReadInput;
409c4f7863aSmrg   pInfo->control_proc = VMMouseControlProc;
410c4f7863aSmrg   pInfo->switch_mode = VMMouseSwitchMode;
4119bd41f2cSmrg
4129bd41f2cSmrg   /* Allocate the MouseDevRec and initialise it. */
413c4f7863aSmrg   if (!(pMse = calloc(sizeof(MouseDevRec), 1))) {
414c4f7863aSmrg      rc = BadAlloc;
415c4f7863aSmrg      goto error;
4169bd41f2cSmrg   }
4179bd41f2cSmrg
4189bd41f2cSmrg   pInfo->private = pMse;
4199bd41f2cSmrg   pMse->Ctrl = MouseCtrl;
4209bd41f2cSmrg   pMse->PostEvent = VMMousePostEvent;
4219bd41f2cSmrg   pMse->CommonOptions = MouseCommonOptions;
4229bd41f2cSmrg   pMse->mousePriv = mPriv;
423d075918cSmrg
4249bd41f2cSmrg
4259bd41f2cSmrg   /* Check if the device can be opened. */
4269bd41f2cSmrg   pInfo->fd = xf86OpenSerial(pInfo->options);
4279bd41f2cSmrg   if (pInfo->fd == -1) {
4289bd41f2cSmrg      if (xf86GetAllowMouseOpenFail())
4299bd41f2cSmrg	 xf86Msg(X_WARNING, "%s: cannot open input device\n", pInfo->name);
4309bd41f2cSmrg      else {
4319bd41f2cSmrg	 xf86Msg(X_ERROR, "%s: cannot open input device\n", pInfo->name);
432c4f7863aSmrg	 rc = BadValue;
433c4f7863aSmrg	 goto error;
4349bd41f2cSmrg      }
4359bd41f2cSmrg   }
4369bd41f2cSmrg   xf86CloseSerial(pInfo->fd);
4379bd41f2cSmrg   pInfo->fd = -1;
438d075918cSmrg
4399bd41f2cSmrg   /* Process the options */
4409bd41f2cSmrg   pMse->CommonOptions(pInfo);
441d075918cSmrg
4429bd41f2cSmrg   /* set up the current screen num */
4439bd41f2cSmrg   mPriv->screenNum = xf86SetIntOption(pInfo->options, "ScreenNumber", 0);
444d075918cSmrg
445c4f7863aSmrg   return Success;
446c4f7863aSmrg
447c4f7863aSmrgerror:
448c4f7863aSmrg   pInfo->private = NULL;
449c4f7863aSmrg   if (mPriv)
450c4f7863aSmrg      free(mPriv);
451c4f7863aSmrg   if (pMse)
452c4f7863aSmrg      free(pMse);
453c4f7863aSmrg
454c4f7863aSmrg   return rc;
4559bd41f2cSmrg}
4569bd41f2cSmrg
4579bd41f2cSmrg
4589bd41f2cSmrg/*
4599bd41f2cSmrg *----------------------------------------------------------------------
4609bd41f2cSmrg *
4619bd41f2cSmrg * MouseCtrl --
462d075918cSmrg *     Alter the control paramters for the mouse.
463d075918cSmrg *
4649bd41f2cSmrg * Results:
465d075918cSmrg * 	None
466d075918cSmrg *
4679bd41f2cSmrg * Side effects:
4689bd41f2cSmrg * 	None
4699bd41f2cSmrg *
4709bd41f2cSmrg *----------------------------------------------------------------------
4719bd41f2cSmrg */
4729bd41f2cSmrg
4739bd41f2cSmrgstatic void
4749bd41f2cSmrgMouseCtrl(DeviceIntPtr device, PtrCtrl *ctrl)
4759bd41f2cSmrg{
4769bd41f2cSmrg    InputInfoPtr pInfo;
4779bd41f2cSmrg    MouseDevPtr pMse;
4789bd41f2cSmrg
4799bd41f2cSmrg    pInfo = device->public.devicePrivate;
4809bd41f2cSmrg    pMse = pInfo->private;
4819bd41f2cSmrg
4829bd41f2cSmrg#ifdef EXTMOUSEDEBUG
4839bd41f2cSmrg    xf86Msg(X_INFO, "VMMOUSE(0): MouseCtrl pMse=%p\n", pMse);
4849bd41f2cSmrg#endif
485d075918cSmrg
4869bd41f2cSmrg    pMse->num       = ctrl->num;
4879bd41f2cSmrg    pMse->den       = ctrl->den;
4889bd41f2cSmrg    pMse->threshold = ctrl->threshold;
4899bd41f2cSmrg}
4909bd41f2cSmrg
4919bd41f2cSmrg
4929bd41f2cSmrg/*
4939bd41f2cSmrg *----------------------------------------------------------------------
4949bd41f2cSmrg *
4959bd41f2cSmrg * VMMouseDoPostEvent --
4969bd41f2cSmrg *	Post the mouse button event and mouse motion event to Xserver
497d075918cSmrg *
4989bd41f2cSmrg * Results:
4999bd41f2cSmrg * 	None
500d075918cSmrg *
5019bd41f2cSmrg * Side effects:
5029bd41f2cSmrg * 	Mouse location and button status was updated
5039bd41f2cSmrg *
5049bd41f2cSmrg *----------------------------------------------------------------------
5059bd41f2cSmrg */
5069bd41f2cSmrg
5079bd41f2cSmrgstatic void
5089bd41f2cSmrgVMMouseDoPostEvent(InputInfoPtr pInfo, int buttons, int dx, int dy)
5099bd41f2cSmrg{
5109bd41f2cSmrg    MouseDevPtr pMse;
5119bd41f2cSmrg    VMMousePrivPtr mPriv;
5129bd41f2cSmrg    int truebuttons;
5139bd41f2cSmrg    int id, change;
514d075918cSmrg    Bool mouseMoved = FALSE;
515d075918cSmrg
5169bd41f2cSmrg    pMse = pInfo->private;
5179bd41f2cSmrg    mPriv = (VMMousePrivPtr)pMse->mousePriv;
5189bd41f2cSmrg
5199bd41f2cSmrg    /*
5209bd41f2cSmrg     * The following truebuttons/reverseBits and lastButtons are
5219bd41f2cSmrg     * used to compare the current buttons and the previous buttons
5229bd41f2cSmrg     * to find the button changes during two mouse events
523d075918cSmrg     */
5249bd41f2cSmrg    truebuttons = buttons;
5259bd41f2cSmrg
5269bd41f2cSmrg    buttons = reverseBits(reverseMap, buttons);
5279bd41f2cSmrg
528d075918cSmrg    if (mPriv->isCurrRelative) {
529d075918cSmrg       mouseMoved = dx || dy;
530d075918cSmrg    } else {
531d075918cSmrg       mouseMoved = (dx != mPriv->vmmousePrevInput.X) ||
532d075918cSmrg                    (dy != mPriv->vmmousePrevInput.Y) ||
533d075918cSmrg                    (mPriv->vmmousePrevInput.Flags & VMMOUSE_MOVE_RELATIVE);
534d075918cSmrg    }
535d075918cSmrg    if (mouseMoved) {
5369bd41f2cSmrg
537d075918cSmrg#ifdef CALL_CONVERSION_PROC
5389bd41f2cSmrg        /*
539d075918cSmrg         * Xservers between 1.3.99.0 - 1.4.0.90 do not call conversion_proc, so
540d075918cSmrg         * we need to do the conversion from device to screen space.
5419bd41f2cSmrg         */
5429bd41f2cSmrg        VMMouseConvertProc(pInfo, 0, 2, dx, dy, 0, 0, 0, 0, &dx, &dy);
543d075918cSmrg#endif
544d075918cSmrg        xf86PostMotionEvent(pInfo->dev, !mPriv->isCurrRelative, 0, 2, dx, dy);
5459bd41f2cSmrg    }
546d075918cSmrg
5479bd41f2cSmrg    if (truebuttons != pMse->lastButtons) {
5489bd41f2cSmrg       change = buttons ^ reverseBits(reverseMap, pMse->lastButtons);
5499bd41f2cSmrg       while (change) {
5509bd41f2cSmrg	  id = ffs(change);
5519bd41f2cSmrg	  change &= ~(1 << (id - 1));
5529bd41f2cSmrg	  xf86PostButtonEvent(pInfo->dev, 0, id,
5539bd41f2cSmrg			      (buttons & (1 << (id - 1))), 0, 0);
5549bd41f2cSmrg       }
5559bd41f2cSmrg       pMse->lastButtons = truebuttons;
5569bd41f2cSmrg    }
5579bd41f2cSmrg}
5589bd41f2cSmrg
5599bd41f2cSmrg
5609bd41f2cSmrg/*
5619bd41f2cSmrg *----------------------------------------------------------------------
5629bd41f2cSmrg *
5639bd41f2cSmrg * VMMousePostEvent --
5649bd41f2cSmrg *	Prepare the mouse status according to the Z axis mapping
5659bd41f2cSmrg *	before we post the event to Xserver
566d075918cSmrg *
5679bd41f2cSmrg * Results:
5689bd41f2cSmrg * 	None
569d075918cSmrg *
5709bd41f2cSmrg * Side effects:
5719bd41f2cSmrg * 	Buttons was updated according to Z axis mapping
5729bd41f2cSmrg *
5739bd41f2cSmrg *----------------------------------------------------------------------
5749bd41f2cSmrg */
5759bd41f2cSmrg
5769bd41f2cSmrgstatic void
5779bd41f2cSmrgVMMousePostEvent(InputInfoPtr pInfo, int buttons, int dx, int dy, int dz, int dw)
5789bd41f2cSmrg{
5799bd41f2cSmrg    MouseDevPtr pMse;
5809bd41f2cSmrg    int zbutton = 0;
5819bd41f2cSmrg    VMMousePrivPtr mPriv;
582d075918cSmrg
5839bd41f2cSmrg    pMse = pInfo->private;
5849bd41f2cSmrg    mPriv = (VMMousePrivPtr)pMse->mousePriv;
5859bd41f2cSmrg    /* Map the Z axis movement. */
5869bd41f2cSmrg    /* XXX Could this go in the conversion_proc? */
5879bd41f2cSmrg    switch (pMse->negativeZ) {
5889bd41f2cSmrg    case MSE_NOZMAP:	/* do nothing */
5899bd41f2cSmrg	break;
5909bd41f2cSmrg    case MSE_MAPTOX:
5919bd41f2cSmrg	if (dz != 0) {
592d075918cSmrg	   if(mPriv->isCurrRelative)
5939bd41f2cSmrg	      dx = dz;
5949bd41f2cSmrg	   else
595d075918cSmrg	      dx += dz;
5969bd41f2cSmrg	    dz = 0;
5979bd41f2cSmrg	}
5989bd41f2cSmrg	break;
5999bd41f2cSmrg    case MSE_MAPTOY:
6009bd41f2cSmrg	if (dz != 0) {
601d075918cSmrg	   if(mPriv->isCurrRelative)
6029bd41f2cSmrg	      dy = dz;
6039bd41f2cSmrg	   else
604d075918cSmrg	      dy += dz;
6059bd41f2cSmrg	    dz = 0;
6069bd41f2cSmrg	}
6079bd41f2cSmrg	break;
6089bd41f2cSmrg    default:	/* buttons */
6099bd41f2cSmrg	buttons &= ~(pMse->negativeZ | pMse->positiveZ
6109bd41f2cSmrg		   | pMse->negativeW | pMse->positiveW);
6119bd41f2cSmrg	if (dw < 0 || dz < -1) {
6129bd41f2cSmrg	    zbutton = pMse->negativeW;
6139bd41f2cSmrg	}
6149bd41f2cSmrg	else if (dz < 0) {
6159bd41f2cSmrg	    zbutton = pMse->negativeZ;
6169bd41f2cSmrg	}
6179bd41f2cSmrg	else if (dw > 0 || dz > 1) {
6189bd41f2cSmrg	    zbutton = pMse->positiveW;
6199bd41f2cSmrg	}
6209bd41f2cSmrg	else if (dz > 0) {
6219bd41f2cSmrg	    zbutton = pMse->positiveZ;
6229bd41f2cSmrg	}
6239bd41f2cSmrg	buttons |= zbutton;
6249bd41f2cSmrg	dz = 0;
6259bd41f2cSmrg	break;
6269bd41f2cSmrg    }
6279bd41f2cSmrg
6289bd41f2cSmrg    VMMouseDoPostEvent(pInfo, buttons, dx, dy);
6299bd41f2cSmrg
6309bd41f2cSmrg    /*
6319bd41f2cSmrg     * If dz has been mapped to a button `down' event, we need to cook up
6329bd41f2cSmrg     * a corresponding button `up' event.
6339bd41f2cSmrg     */
6349bd41f2cSmrg    if (zbutton) {
6359bd41f2cSmrg	buttons &= ~zbutton;
636d075918cSmrg	if(mPriv->isCurrRelative)
6379bd41f2cSmrg	   VMMouseDoPostEvent(pInfo, buttons, 0, 0);
6389bd41f2cSmrg	else
6399bd41f2cSmrg	   VMMouseDoPostEvent(pInfo, buttons, dx, dy);
6409bd41f2cSmrg    }
6419bd41f2cSmrg}
6429bd41f2cSmrg
6439bd41f2cSmrg
6449bd41f2cSmrg/*
6459bd41f2cSmrg *----------------------------------------------------------------------
6469bd41f2cSmrg *
6479bd41f2cSmrg * FlushButtons --
6489bd41f2cSmrg *
649d075918cSmrg * 	FlushButtons -- reset button states.
6509bd41f2cSmrg *
6519bd41f2cSmrg * Results:
6529bd41f2cSmrg * 	None
653d075918cSmrg *
6549bd41f2cSmrg * Side effects:
6559bd41f2cSmrg * 	None
6569bd41f2cSmrg *
6579bd41f2cSmrg *----------------------------------------------------------------------
6589bd41f2cSmrg */
6599bd41f2cSmrg
6609bd41f2cSmrgstatic void
6619bd41f2cSmrgFlushButtons(MouseDevPtr pMse)
6629bd41f2cSmrg{
6639bd41f2cSmrg    pMse->lastButtons = 0;
6649bd41f2cSmrg}
6659bd41f2cSmrg
6669bd41f2cSmrg
6679bd41f2cSmrg/*
6689bd41f2cSmrg *----------------------------------------------------------------------
6699bd41f2cSmrg *
6709bd41f2cSmrg * MouseCommonOptions --
6719bd41f2cSmrg *	Process acceptable mouse options. Currently we only process
6729bd41f2cSmrg *	"Buttons" and "ZAxisMapping" options.
673d075918cSmrg *	More options can be added later on
6749bd41f2cSmrg *
6759bd41f2cSmrg * Results:
6769bd41f2cSmrg * 	None
677d075918cSmrg *
6789bd41f2cSmrg * Side effects:
6799bd41f2cSmrg * 	The buttons was setup according to the options
6809bd41f2cSmrg *
6819bd41f2cSmrg *----------------------------------------------------------------------
6829bd41f2cSmrg */
6839bd41f2cSmrg
6849bd41f2cSmrgstatic void
6859bd41f2cSmrgMouseCommonOptions(InputInfoPtr pInfo)
6869bd41f2cSmrg{
6879bd41f2cSmrg   MouseDevPtr pMse;
6889bd41f2cSmrg   MessageType from = X_DEFAULT;
6899bd41f2cSmrg   char *s;
6909bd41f2cSmrg   int origButtons;
6919bd41f2cSmrg
6929bd41f2cSmrg   pMse = pInfo->private;
6939bd41f2cSmrg
6949bd41f2cSmrg   pMse->buttons = xf86SetIntOption(pInfo->options, "Buttons", 0);
6959bd41f2cSmrg   from = X_CONFIG;
6969bd41f2cSmrg   if (!pMse->buttons) {
6979bd41f2cSmrg      pMse->buttons = MSE_DFLTBUTTONS;
6989bd41f2cSmrg      from = X_DEFAULT;
6999bd41f2cSmrg   }
7009bd41f2cSmrg   origButtons = pMse->buttons;
7019bd41f2cSmrg
7029bd41f2cSmrg   /*
7039bd41f2cSmrg    * "emulate3Buttons" and "Drag Lock" is not supported
7049bd41f2cSmrg    */
7059bd41f2cSmrg
7069bd41f2cSmrg   /*
7079bd41f2cSmrg    * Process option for ZAxisMapping
7089bd41f2cSmrg    */
709d075918cSmrg   s = xf86SetStrOption(pInfo->options, "ZAxisMapping", "4 5");
7109bd41f2cSmrg   if (s) {
7119bd41f2cSmrg      int b1 = 0, b2 = 0, b3 = 0, b4 = 0;
7129bd41f2cSmrg      char *msg = NULL;
7139bd41f2cSmrg
7149bd41f2cSmrg      if (!xf86NameCmp(s, "x")) {
7159bd41f2cSmrg	 pMse->negativeZ = pMse->positiveZ = MSE_MAPTOX;
7169bd41f2cSmrg	 pMse->negativeW = pMse->positiveW = MSE_MAPTOX;
7179bd41f2cSmrg	 msg = xstrdup("X axis");
7189bd41f2cSmrg      } else if (!xf86NameCmp(s, "y")) {
7199bd41f2cSmrg	 pMse->negativeZ = pMse->positiveZ = MSE_MAPTOY;
7209bd41f2cSmrg	 pMse->negativeW = pMse->positiveW = MSE_MAPTOY;
7219bd41f2cSmrg	 msg = xstrdup("Y axis");
7229bd41f2cSmrg      } else if (sscanf(s, "%d %d %d %d", &b1, &b2, &b3, &b4) >= 2 &&
7239bd41f2cSmrg		 b1 > 0 && b1 <= MSE_MAXBUTTONS &&
7249bd41f2cSmrg		 b2 > 0 && b2 <= MSE_MAXBUTTONS) {
7259bd41f2cSmrg	 msg = xstrdup("buttons XX and YY");
7269bd41f2cSmrg	 if (msg)
7279bd41f2cSmrg	    sprintf(msg, "buttons %d and %d", b1, b2);
7289bd41f2cSmrg	 pMse->negativeZ = pMse->negativeW = 1 << (b1-1);
7299bd41f2cSmrg	 pMse->positiveZ = pMse->positiveW = 1 << (b2-1);
7309bd41f2cSmrg	 if (b1 > pMse->buttons) pMse->buttons = b1;
7319bd41f2cSmrg	 if (b2 > pMse->buttons) pMse->buttons = b2;
732d075918cSmrg
7339bd41f2cSmrg	 /*
734d075918cSmrg	  * Option "ZAxisMapping" "N1 N2 N3 N4" not supported
7359bd41f2cSmrg	  */
7369bd41f2cSmrg	 pMse->negativeW = pMse->positiveW = MSE_NOZMAP;
7379bd41f2cSmrg      } else {
7389bd41f2cSmrg	 pMse->negativeZ = pMse->positiveZ = MSE_NOZMAP;
7399bd41f2cSmrg	 pMse->negativeW = pMse->positiveW = MSE_NOZMAP;
7409bd41f2cSmrg      }
7419bd41f2cSmrg      if (msg) {
7429bd41f2cSmrg	 xf86Msg(X_CONFIG, "%s: ZAxisMapping: %s\n", pInfo->name, msg);
743c4f7863aSmrg	 free(msg);
7449bd41f2cSmrg      } else {
7459bd41f2cSmrg	 xf86Msg(X_WARNING, "%s: Invalid ZAxisMapping value: \"%s\"\n",
7469bd41f2cSmrg		 pInfo->name, s);
7479bd41f2cSmrg      }
7489bd41f2cSmrg   }
7499bd41f2cSmrg
7509bd41f2cSmrg   /*
7519bd41f2cSmrg    * Emulatewheel is not supported
7529bd41f2cSmrg    */
7539bd41f2cSmrg   if (origButtons != pMse->buttons)
7549bd41f2cSmrg      from = X_CONFIG;
755d075918cSmrg
7569bd41f2cSmrg}
7579bd41f2cSmrg
7589bd41f2cSmrg
7599bd41f2cSmrg/*
7609bd41f2cSmrg *----------------------------------------------------------------------
7619bd41f2cSmrg *
7629bd41f2cSmrg * VMMouseUnInit --
7639bd41f2cSmrg * 	This function was supposed to be called by Xserver to do Un-Init.
7649bd41f2cSmrg *	But it was unused now
7659bd41f2cSmrg *
7669bd41f2cSmrg * Results:
7679bd41f2cSmrg * 	None
768d075918cSmrg *
7699bd41f2cSmrg * Side effects:
7709bd41f2cSmrg * 	None
7719bd41f2cSmrg *
7729bd41f2cSmrg *----------------------------------------------------------------------
7739bd41f2cSmrg */
7749bd41f2cSmrg
775d075918cSmrgstatic void
776c4f7863aSmrgVMMouseUnInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags)
7779bd41f2cSmrg{
7789bd41f2cSmrg   xf86Msg(X_INFO, "VMWARE(0): VMMouseUnInit\n");
7799bd41f2cSmrg}
7809bd41f2cSmrg
7819bd41f2cSmrg
7829bd41f2cSmrg/*
7839bd41f2cSmrg *----------------------------------------------------------------------
7849bd41f2cSmrg *
7859bd41f2cSmrg * VMMouseDeviceControl --
7869bd41f2cSmrg * 	This function was called by Xserver during DEVICE_INIT, DEVICE_ON,
787d075918cSmrg *	DEVICE_OFF and DEVICE_CLOSE phase
788d075918cSmrg *
7899bd41f2cSmrg * Results:
7909bd41f2cSmrg * 	TRUE, if sucessful
7919bd41f2cSmrg *	FALSE, if failed
792d075918cSmrg *
7939bd41f2cSmrg * Side effects:
7949bd41f2cSmrg * 	Absolute pointing device is enabled during DEVICE_ON
7959bd41f2cSmrg *	Absolute pointing device is disabled during DEVICE_OFF
7969bd41f2cSmrg *	and DEVICE_CLOSE
7979bd41f2cSmrg *
7989bd41f2cSmrg *----------------------------------------------------------------------
7999bd41f2cSmrg */
8009bd41f2cSmrg
8019bd41f2cSmrgstatic Bool
8029bd41f2cSmrgVMMouseDeviceControl(DeviceIntPtr device, int mode)
8039bd41f2cSmrg{
8049bd41f2cSmrg   InputInfoPtr pInfo;
8059bd41f2cSmrg   MouseDevPtr pMse;
8069bd41f2cSmrg   VMMousePrivPtr mPriv;
8079bd41f2cSmrg   unsigned char map[MSE_MAXBUTTONS + 1];
8089bd41f2cSmrg   int i;
809b15a006bSmrg#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 7
810b15a006bSmrg   Atom btn_labels[MSE_MAXBUTTONS] = {0};
811b15a006bSmrg   Atom axes_labels[2] = { 0, 0 };
812b15a006bSmrg#endif
813d075918cSmrg
8149bd41f2cSmrg   pInfo = device->public.devicePrivate;
8159bd41f2cSmrg   pMse = pInfo->private;
8169bd41f2cSmrg   pMse->device = device;
817d075918cSmrg   mPriv = (VMMousePrivPtr)pMse->mousePriv;
8189bd41f2cSmrg
8199bd41f2cSmrg   switch (mode){
8209bd41f2cSmrg   case DEVICE_INIT:
8219bd41f2cSmrg      device->public.on = FALSE;
8229bd41f2cSmrg      /*
8239bd41f2cSmrg       * [KAZU-241097] We don't know exactly how many buttons the
8249bd41f2cSmrg       * device has, so setup the map with the maximum number.
8259bd41f2cSmrg       */
8269bd41f2cSmrg      for (i = 0; i < MSE_MAXBUTTONS; i++)
8279bd41f2cSmrg	 map[i + 1] = i + 1;
828b15a006bSmrg#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 7
829b15a006bSmrg      btn_labels[0] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_LEFT);
830b15a006bSmrg      btn_labels[1] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_MIDDLE);
831b15a006bSmrg      btn_labels[2] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_RIGHT);
832b15a006bSmrg      btn_labels[4] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_UP);
833b15a006bSmrg      btn_labels[5] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_DOWN);
834b15a006bSmrg      btn_labels[6] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_HWHEEL_LEFT);
835b15a006bSmrg      btn_labels[7] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_HWHEEL_RIGHT);
836b15a006bSmrg      /* other buttons are unknown */
837b15a006bSmrg
838b15a006bSmrg#ifdef ABS_VALUATOR_AXES
839b15a006bSmrg      axes_labels[0] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_X);
840b15a006bSmrg      axes_labels[1] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_Y);
841b15a006bSmrg#else
842b15a006bSmrg      axes_labels[0] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_X);
843b15a006bSmrg      axes_labels[1] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_Y);
844b15a006bSmrg#endif /* ABS_VALUATOR_AXES */
845b15a006bSmrg#endif
8469bd41f2cSmrg
8479bd41f2cSmrg      InitPointerDeviceStruct((DevicePtr)device, map,
8489bd41f2cSmrg			      min(pMse->buttons, MSE_MAXBUTTONS),
849b15a006bSmrg#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 7
850b15a006bSmrg				btn_labels,
851b15a006bSmrg#endif
8529bd41f2cSmrg#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) == 0
8539bd41f2cSmrg				miPointerGetMotionEvents,
854d075918cSmrg#elif GET_ABI_MAJOR(ABI_XINPUT_VERSION) < 3
8559bd41f2cSmrg                                GetMotionHistory,
8569bd41f2cSmrg#endif
8579bd41f2cSmrg                                pMse->Ctrl,
8589bd41f2cSmrg#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) == 0
8599bd41f2cSmrg				miPointerGetMotionBufferSize()
8609bd41f2cSmrg#else
8619bd41f2cSmrg                                GetMotionHistorySize(), 2
862b15a006bSmrg#endif
863b15a006bSmrg#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 7
864b15a006bSmrg				, axes_labels
8659bd41f2cSmrg#endif
8669bd41f2cSmrg                                );
8679bd41f2cSmrg
8689bd41f2cSmrg      /* X valuator */
869d075918cSmrg#ifdef ABS_VALUATOR_AXES
870b15a006bSmrg      xf86InitValuatorAxisStruct(device, 0,
871b15a006bSmrg#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 7
872b15a006bSmrg				axes_labels[0],
873b15a006bSmrg#endif
874c4f7863aSmrg				0, 65535, 10000, 0, 10000
875c4f7863aSmrg#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 12
876c4f7863aSmrg                                , Absolute
877c4f7863aSmrg#endif
878c4f7863aSmrg                                );
879d075918cSmrg#else
880b15a006bSmrg      xf86InitValuatorAxisStruct(device, 0,
881b15a006bSmrg#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 7
882b15a006bSmrg				axes_labels[0],
883b15a006bSmrg#endif
884c4f7863aSmrg				0, -1, 1, 0, 1
885c4f7863aSmrg#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 12
886c4f7863aSmrg                                , Relative
887c4f7863aSmrg#endif
888c4f7863aSmrg                                );
889d075918cSmrg#endif
8909bd41f2cSmrg      xf86InitValuatorDefaults(device, 0);
8919bd41f2cSmrg      /* Y valuator */
892d075918cSmrg#ifdef ABS_VALUATOR_AXES
893b15a006bSmrg      xf86InitValuatorAxisStruct(device, 1,
894b15a006bSmrg#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 7
895b15a006bSmrg				axes_labels[1],
896b15a006bSmrg#endif
897c4f7863aSmrg				0, 65535, 10000, 0, 10000
898c4f7863aSmrg#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 12
899c4f7863aSmrg                                , Absolute
900c4f7863aSmrg#endif
901c4f7863aSmrg                                );
902d075918cSmrg#else
903b15a006bSmrg      xf86InitValuatorAxisStruct(device, 1,
904b15a006bSmrg#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 7
905b15a006bSmrg				axes_labels[1],
906b15a006bSmrg#endif
907c4f7863aSmrg				0, -1, 1, 0, 1
908c4f7863aSmrg#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 12
909c4f7863aSmrg                                , Relative
910c4f7863aSmrg#endif
911c4f7863aSmrg                                );
912d075918cSmrg#endif
9139bd41f2cSmrg      xf86InitValuatorDefaults(device, 1);
9149bd41f2cSmrg#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) == 0
9159bd41f2cSmrg      xf86MotionHistoryAllocate(pInfo);
9169bd41f2cSmrg#endif
9179bd41f2cSmrg
9189bd41f2cSmrg      xf86Msg(X_INFO, "VMWARE(0): VMMOUSE DEVICE_INIT\n");
9199bd41f2cSmrg#ifdef EXTMOUSEDEBUG
9209bd41f2cSmrg      xf86Msg(X_INFO, "assigning %p atom=%d name=%s\n", device, pInfo->atom,
9219bd41f2cSmrg	     pInfo->name);
9229bd41f2cSmrg#endif
9239bd41f2cSmrg      break;
9249bd41f2cSmrg
9259bd41f2cSmrg   case DEVICE_ON:
9269bd41f2cSmrg      xf86Msg(X_INFO, "VMWARE(0): VMMOUSE DEVICE_ON\n");
9279bd41f2cSmrg      pInfo->fd = xf86OpenSerial(pInfo->options);
9289bd41f2cSmrg      if (pInfo->fd == -1)
9299bd41f2cSmrg	 xf86Msg(X_WARNING, "%s: cannot open input device\n", pInfo->name);
9309bd41f2cSmrg      else {
9319bd41f2cSmrg	 pMse->buffer = XisbNew(pInfo->fd, 64);
9329bd41f2cSmrg	 if (!pMse->buffer) {
9339bd41f2cSmrg	    xf86CloseSerial(pInfo->fd);
9349bd41f2cSmrg	    pInfo->fd = -1;
9359bd41f2cSmrg	 } else {
9369bd41f2cSmrg	    VMMousePrivPtr mPriv = (VMMousePrivPtr)pMse->mousePriv;
9379bd41f2cSmrg	    if (mPriv != NULL) {
9389bd41f2cSmrg	       /*
9399bd41f2cSmrg		* enable absolute pointing device here
9409bd41f2cSmrg		*/
941d075918cSmrg	       if (!VMMouseClient_Enable()) {
9429bd41f2cSmrg		  xf86Msg(X_ERROR, "VMWARE(0): vmmouse enable failed\n");
9439bd41f2cSmrg		  mPriv->vmmouseAvailable = FALSE;
9449bd41f2cSmrg		  device->public.on = FALSE;
9459bd41f2cSmrg		  return FALSE;
9469bd41f2cSmrg	       } else {
947d075918cSmrg		  mPriv->vmmouseAvailable = TRUE;
9489bd41f2cSmrg		  xf86Msg(X_INFO, "VMWARE(0): vmmouse enabled\n");
949d075918cSmrg	       }
9509bd41f2cSmrg	    }
9519bd41f2cSmrg	    xf86FlushInput(pInfo->fd);
9529bd41f2cSmrg	    xf86AddEnabledDevice(pInfo);
9539bd41f2cSmrg	 }
9549bd41f2cSmrg      }
9559bd41f2cSmrg      pMse->lastButtons = 0;
9569bd41f2cSmrg      device->public.on = TRUE;
9579bd41f2cSmrg      FlushButtons(pMse);
958d075918cSmrg      break;
9599bd41f2cSmrg   case DEVICE_OFF:
9609bd41f2cSmrg   case DEVICE_CLOSE:
9619bd41f2cSmrg      xf86Msg(X_INFO, "VMWARE(0): VMMOUSE DEVICE_OFF/CLOSE\n");
9629bd41f2cSmrg
9639bd41f2cSmrg      if (pInfo->fd != -1) {
9649bd41f2cSmrg	 VMMousePrivPtr mPriv = (VMMousePrivPtr)pMse->mousePriv;
9659bd41f2cSmrg	 if( mPriv->vmmouseAvailable ) {
9669bd41f2cSmrg	    VMMouseClient_Disable();
967d075918cSmrg            mPriv->vmmouseAvailable = FALSE;
968d075918cSmrg            mPriv->absoluteRequested = FALSE;
9699bd41f2cSmrg	 }
970d075918cSmrg
9719bd41f2cSmrg	 xf86RemoveEnabledDevice(pInfo);
9729bd41f2cSmrg	 if (pMse->buffer) {
9739bd41f2cSmrg	    XisbFree(pMse->buffer);
9749bd41f2cSmrg	    pMse->buffer = NULL;
9759bd41f2cSmrg	 }
9769bd41f2cSmrg	 xf86CloseSerial(pInfo->fd);
9779bd41f2cSmrg	 pInfo->fd = -1;
9789bd41f2cSmrg      }
9799bd41f2cSmrg      device->public.on = FALSE;
9809bd41f2cSmrg      usleep(300000);
9819bd41f2cSmrg      break;
9829bd41f2cSmrg
9839bd41f2cSmrg   }
9849bd41f2cSmrg
9859bd41f2cSmrg   return Success;
9869bd41f2cSmrg}
9879bd41f2cSmrg
9889bd41f2cSmrg
9899bd41f2cSmrg/*
9909bd41f2cSmrg *----------------------------------------------------------------------
9919bd41f2cSmrg *
9929bd41f2cSmrg * VMMouseReadInput --
9939bd41f2cSmrg * 	This function was called by Xserver when there is data available
9949bd41f2cSmrg *	in the input device
995d075918cSmrg *
9969bd41f2cSmrg * Results:
9979bd41f2cSmrg * 	None
998d075918cSmrg *
9999bd41f2cSmrg * Side effects:
10009bd41f2cSmrg * 	Input data in regular PS/2 fd was cleared
10019bd41f2cSmrg *	Real mouse data was read from the absolute pointing device
10029bd41f2cSmrg *	and posted to Xserver
1003d075918cSmrg *
10049bd41f2cSmrg *----------------------------------------------------------------------
10059bd41f2cSmrg */
10069bd41f2cSmrg
10079bd41f2cSmrgstatic void
10089bd41f2cSmrgVMMouseReadInput(InputInfoPtr pInfo)
10099bd41f2cSmrg{
10109bd41f2cSmrg   MouseDevPtr pMse;
1011d075918cSmrg   VMMousePrivPtr mPriv;
10129bd41f2cSmrg   int c;
1013d075918cSmrg   int len = 0;
10149bd41f2cSmrg
10159bd41f2cSmrg   pMse = pInfo->private;
10169bd41f2cSmrg   mPriv = pMse->mousePriv;
1017d075918cSmrg
1018d075918cSmrg   if (!mPriv->absoluteRequested) {
1019d075918cSmrg      /*
1020d075918cSmrg       * We can request for absolute mode, but it depends on
1021d075918cSmrg       * host whether it will send us absolute or relative
1022d075918cSmrg       * position.
1023d075918cSmrg       */
1024d075918cSmrg      VMMouseClient_RequestAbsolute();
1025d075918cSmrg      mPriv->absoluteRequested = TRUE;
1026d075918cSmrg      xf86Msg(X_INFO, "VMWARE(0): vmmouse enable absolute mode\n");
1027d075918cSmrg   }
1028d075918cSmrg
10299bd41f2cSmrg   /*
10309bd41f2cSmrg    * First read the bytes in input device to clear the regular PS/2 fd so
1031d075918cSmrg    * we don't get called again.
10329bd41f2cSmrg    */
10339bd41f2cSmrg   /*
10349bd41f2cSmrg    * Set blocking to -1 on the first call because we know there is data to
10359bd41f2cSmrg    * read. Xisb automatically clears it after one successful read so that
10369bd41f2cSmrg    * succeeding reads are preceeded by a select with a 0 timeout to prevent
10379bd41f2cSmrg    * read from blocking indefinitely.
10389bd41f2cSmrg    */
10399bd41f2cSmrg   XisbBlockDuration(pMse->buffer, -1);
10409bd41f2cSmrg   while ((c = XisbRead(pMse->buffer)) >= 0) {
10419bd41f2cSmrg      len++;
10429bd41f2cSmrg      /*
10439bd41f2cSmrg       * regular PS packet consists of 3 bytes
1044d075918cSmrg       * We read 3 bytes to drain the PS/2 packet
10459bd41f2cSmrg       */
10469bd41f2cSmrg      if(len < 3) continue;
1047d075918cSmrg      len = 0;
10489bd41f2cSmrg      /*
10499bd41f2cSmrg       * Now get the real data from absolute pointing device
10509bd41f2cSmrg       */
10519bd41f2cSmrg      GetVMMouseMotionEvent(pInfo);
10529bd41f2cSmrg   }
10539bd41f2cSmrg   /*
10549bd41f2cSmrg    * There maybe still vmmouse data available
10559bd41f2cSmrg    */
10569bd41f2cSmrg   GetVMMouseMotionEvent(pInfo);
10579bd41f2cSmrg}
10589bd41f2cSmrg
10599bd41f2cSmrg
10609bd41f2cSmrg/*
10619bd41f2cSmrg *----------------------------------------------------------------------
10629bd41f2cSmrg *
10639bd41f2cSmrg * GetVMMouseMotionEvent --
10649bd41f2cSmrg * 	Read all the mouse data available from the absolute
10659bd41f2cSmrg * 	pointing device	and post it to the Xserver
1066d075918cSmrg *
10679bd41f2cSmrg * Results:
10689bd41f2cSmrg * 	None
1069d075918cSmrg *
10709bd41f2cSmrg * Side effects:
10719bd41f2cSmrg *	Real mouse data was read from the absolute pointing
10729bd41f2cSmrg *	device and posted to Xserver
1073d075918cSmrg *
10749bd41f2cSmrg *----------------------------------------------------------------------
10759bd41f2cSmrg */
10769bd41f2cSmrg
10779bd41f2cSmrgstatic void
10789bd41f2cSmrgGetVMMouseMotionEvent(InputInfoPtr pInfo){
10799bd41f2cSmrg   MouseDevPtr pMse;
1080d075918cSmrg   VMMousePrivPtr mPriv;
10819bd41f2cSmrg   int buttons, dx, dy, dz, dw;
10829bd41f2cSmrg   VMMOUSE_INPUT_DATA  vmmouseInput;
10839bd41f2cSmrg   int ps2Buttons = 0;
10849bd41f2cSmrg   int numPackets;
10859bd41f2cSmrg
1086d075918cSmrg   pMse = pInfo->private;
1087d075918cSmrg   mPriv = (VMMousePrivPtr)pMse->mousePriv;
10889bd41f2cSmrg   while((numPackets = VMMouseClient_GetInput(&vmmouseInput))){
10899bd41f2cSmrg      if (numPackets == VMMOUSE_ERROR) {
10909bd41f2cSmrg         VMMouseClient_Disable();
10919bd41f2cSmrg         VMMouseClient_Enable();
10929bd41f2cSmrg         VMMouseClient_RequestAbsolute();
10939bd41f2cSmrg         xf86Msg(X_INFO, "VMWARE(0): re-requesting absolute mode after reset\n");
10949bd41f2cSmrg         break;
10959bd41f2cSmrg      }
10969bd41f2cSmrg
10979bd41f2cSmrg      if(vmmouseInput.Buttons & VMMOUSE_MIDDLE_BUTTON)
10989bd41f2cSmrg	 ps2Buttons |= 0x04; 			/* Middle*/
10999bd41f2cSmrg      if(vmmouseInput.Buttons & VMMOUSE_RIGHT_BUTTON)
11009bd41f2cSmrg	 ps2Buttons |= 0x02; 			/* Right*/
11019bd41f2cSmrg      if(vmmouseInput.Buttons & VMMOUSE_LEFT_BUTTON)
11029bd41f2cSmrg	 ps2Buttons |= 0x01; 			/* Left*/
1103d075918cSmrg
11049bd41f2cSmrg      buttons = (ps2Buttons & 0x04) >> 1 |	/* Middle */
11059bd41f2cSmrg	 (ps2Buttons & 0x02) >> 1 |       	/* Right */
11069bd41f2cSmrg	 (ps2Buttons & 0x01) << 2;       	/* Left */
1107d075918cSmrg
11089bd41f2cSmrg      dx = vmmouseInput.X;
1109d075918cSmrg      dy = vmmouseInput.Y;
11109bd41f2cSmrg      dz = (char)vmmouseInput.Z;
11119bd41f2cSmrg      dw = 0;
1112d075918cSmrg      /*
1113d075918cSmrg       * Get the per package relative or absolute information.
1114d075918cSmrg       */
1115d075918cSmrg      mPriv->isCurrRelative = vmmouseInput.Flags & VMMOUSE_MOVE_RELATIVE;
11169bd41f2cSmrg      /* post an event */
11179bd41f2cSmrg      pMse->PostEvent(pInfo, buttons, dx, dy, dz, dw);
1118d075918cSmrg      mPriv->vmmousePrevInput = vmmouseInput;
11199bd41f2cSmrg   }
11209bd41f2cSmrg}
11219bd41f2cSmrg
11229bd41f2cSmrg
11239bd41f2cSmrg/*
11249bd41f2cSmrg *----------------------------------------------------------------------
11259bd41f2cSmrg *
11269bd41f2cSmrg * VMMouseControlProc --
1127d075918cSmrg *	This function is unused
11289bd41f2cSmrg *
11299bd41f2cSmrg * Results:
11309bd41f2cSmrg * 	None
1131d075918cSmrg *
11329bd41f2cSmrg * Side effects:
11339bd41f2cSmrg * 	None
11349bd41f2cSmrg *
11359bd41f2cSmrg *----------------------------------------------------------------------
11369bd41f2cSmrg */
11379bd41f2cSmrg
11389bd41f2cSmrgstatic int
1139c4f7863aSmrgVMMouseControlProc(InputInfoPtr pInfo, xDeviceCtl * control)
11409bd41f2cSmrg{
11419bd41f2cSmrg   xf86Msg(X_INFO, "VMWARE(0): VMMouseControlProc\n");
11429bd41f2cSmrg   return (Success);
11439bd41f2cSmrg}
11449bd41f2cSmrg
11459bd41f2cSmrg
11469bd41f2cSmrg/*
11479bd41f2cSmrg *----------------------------------------------------------------------
11489bd41f2cSmrg *
11499bd41f2cSmrg *  VMMouseCloseProc --
1150d075918cSmrg *	This function is unused
11519bd41f2cSmrg *
11529bd41f2cSmrg * Results:
11539bd41f2cSmrg * 	None
1154d075918cSmrg *
11559bd41f2cSmrg * Side effects:
11569bd41f2cSmrg * 	None
11579bd41f2cSmrg *
11589bd41f2cSmrg *----------------------------------------------------------------------
11599bd41f2cSmrg */
11609bd41f2cSmrg
1161c4f7863aSmrg#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) < 12
11629bd41f2cSmrgstatic void
1163c4f7863aSmrgVMMouseCloseProc(InputInfoPtr pInfo)
11649bd41f2cSmrg{
11659bd41f2cSmrg   xf86Msg(X_INFO, "VMWARE(0): VMMouseCloseProc\n");
11669bd41f2cSmrg}
1167c4f7863aSmrg#endif
11689bd41f2cSmrg
11699bd41f2cSmrg
11709bd41f2cSmrg/*
11719bd41f2cSmrg *----------------------------------------------------------------------
11729bd41f2cSmrg *
11739bd41f2cSmrg *  VMMouseSwitchProc --
1174d075918cSmrg *	This function is unused
11759bd41f2cSmrg *
11769bd41f2cSmrg * Results:
11779bd41f2cSmrg * 	None
1178d075918cSmrg *
11799bd41f2cSmrg * Side effects:
11809bd41f2cSmrg * 	None
11819bd41f2cSmrg *
11829bd41f2cSmrg *----------------------------------------------------------------------
11839bd41f2cSmrg */
11849bd41f2cSmrg
11859bd41f2cSmrgstatic int
11869bd41f2cSmrgVMMouseSwitchMode(ClientPtr client, DeviceIntPtr dev, int mode)
11879bd41f2cSmrg{
11889bd41f2cSmrg   xf86Msg(X_INFO, "VMWARE(0): VMMouseSwitchMode\n");
11899bd41f2cSmrg   return (Success);
11909bd41f2cSmrg}
11919bd41f2cSmrg
11929bd41f2cSmrg
11939bd41f2cSmrg/*
11949bd41f2cSmrg *----------------------------------------------------------------------
11959bd41f2cSmrg *
11969bd41f2cSmrg * VMMouseConvertProc  --
11979bd41f2cSmrg * 	This function was called by Xserver to convert valuators to X and Y
1198d075918cSmrg *
11999bd41f2cSmrg * Results:
12009bd41f2cSmrg * 	TRUE
1201d075918cSmrg *
12029bd41f2cSmrg * Side effects:
12039bd41f2cSmrg * 	X and Y was converted according to current Screen dimension
1204d075918cSmrg *
12059bd41f2cSmrg *----------------------------------------------------------------------
12069bd41f2cSmrg */
12079bd41f2cSmrg
1208c4f7863aSmrg#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) < 12
12099bd41f2cSmrgstatic Bool
12109bd41f2cSmrgVMMouseConvertProc(InputInfoPtr pInfo, int first, int num, int v0, int v1, int v2,
12119bd41f2cSmrg	     int v3, int v4, int v5, int *x, int *y)
12129bd41f2cSmrg{
12139bd41f2cSmrg   MouseDevPtr pMse;
12149bd41f2cSmrg   VMMousePrivPtr mPriv;
12159bd41f2cSmrg   double factorX, factorY;
12169bd41f2cSmrg
12179bd41f2cSmrg   pMse = pInfo->private;
12189bd41f2cSmrg   mPriv = pMse->mousePriv;
12199bd41f2cSmrg
12209bd41f2cSmrg   if (first != 0 || num != 2)
12219bd41f2cSmrg      return FALSE;
1222d075918cSmrg
1223d075918cSmrg   if(mPriv->isCurrRelative) {
12249bd41f2cSmrg      *x = v0;
12259bd41f2cSmrg      *y = v1;
12269bd41f2cSmrg   } else {
12279bd41f2cSmrg      factorX = ((double) screenInfo.screens[mPriv->screenNum]->width) / (double) 65535;
12289bd41f2cSmrg      factorY = ((double) screenInfo.screens[mPriv->screenNum]->height) / (double) 65535;
1229d075918cSmrg
12309bd41f2cSmrg      *x = v0 * factorX + 0.5;
12319bd41f2cSmrg      *y = v1 * factorY + 0.5;
1232d075918cSmrg
12339bd41f2cSmrg      if (mPriv->screenNum != -1) {
12349bd41f2cSmrg	 xf86XInputSetScreen(pInfo, mPriv->screenNum, *x, *y);
12359bd41f2cSmrg      }
12369bd41f2cSmrg   }
12379bd41f2cSmrg   return TRUE;
12389bd41f2cSmrg}
1239c4f7863aSmrg#endif
12409bd41f2cSmrg
12419bd41f2cSmrg
12429bd41f2cSmrg#ifdef XFree86LOADER
12439bd41f2cSmrg
12449bd41f2cSmrg/*
12459bd41f2cSmrg *----------------------------------------------------------------------
12469bd41f2cSmrg *
12479bd41f2cSmrg * VMMouseUnplug  --
12489bd41f2cSmrg * 	This function was called by Xserver when unplug
1249d075918cSmrg *
12509bd41f2cSmrg * Results:
12519bd41f2cSmrg * 	None
1252d075918cSmrg *
12539bd41f2cSmrg * Side effects:
12549bd41f2cSmrg * 	None
1255d075918cSmrg *
12569bd41f2cSmrg *----------------------------------------------------------------------
12579bd41f2cSmrg */
12589bd41f2cSmrg
12599bd41f2cSmrgstatic void
12609bd41f2cSmrgVMMouseUnplug(pointer p)
12619bd41f2cSmrg{
12629bd41f2cSmrg   xf86Msg(X_INFO, "VMWARE(0): VMMouseUnplug\n");
12639bd41f2cSmrg}
12649bd41f2cSmrg
12659bd41f2cSmrg
12669bd41f2cSmrg/*
12679bd41f2cSmrg *----------------------------------------------------------------------
12689bd41f2cSmrg *
12699bd41f2cSmrg * VMMousePlug  --
12709bd41f2cSmrg * 	This function was called when Xserver load vmmouse module. It will
1271d075918cSmrg * 	integrate the  module infto the XFree86 loader architecutre.
1272d075918cSmrg *
12739bd41f2cSmrg * Results:
12749bd41f2cSmrg * 	TRUE
1275d075918cSmrg *
12769bd41f2cSmrg * Side effects:
1277d075918cSmrg * 	Regular mouse module was loaded as a submodule. In case
12789bd41f2cSmrg * 	absolute pointing device is not available, we can always fall back
12799bd41f2cSmrg *	to the regular mouse module
1280d075918cSmrg *
12819bd41f2cSmrg *----------------------------------------------------------------------
12829bd41f2cSmrg */
12839bd41f2cSmrg
12849bd41f2cSmrgstatic pointer
12859bd41f2cSmrgVMMousePlug(pointer	module,
12869bd41f2cSmrg	    pointer	options,
12879bd41f2cSmrg	    int		*errmaj,
12889bd41f2cSmrg	    int		*errmin)
12899bd41f2cSmrg{
12909bd41f2cSmrg   static Bool Initialised = FALSE;
12919bd41f2cSmrg
12929418810dSmrg#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) < 7
12939bd41f2cSmrg   xf86LoaderReqSymLists(reqSymbols, NULL);
12949418810dSmrg#endif
1295d075918cSmrg
1296d075918cSmrg   if (!Initialised)
12979bd41f2cSmrg      Initialised = TRUE;
12989bd41f2cSmrg
12999bd41f2cSmrg   xf86Msg(X_INFO, "VMWARE(0): VMMOUSE module was loaded\n");
13009bd41f2cSmrg   xf86AddInputDriver(&VMMOUSE, module, 0);
13019bd41f2cSmrg
1302b15a006bSmrg#ifndef NO_MOUSE_MODULE
1303b15a006bSmrg{
1304b15a006bSmrg   char *name;
13059bd41f2cSmrg   /*
13069bd41f2cSmrg    * Load the normal mouse module as submodule
13079bd41f2cSmrg    * If we fail in PreInit later, this allows us to fall back to normal mouse module
13089bd41f2cSmrg    */
13099bd41f2cSmrg#ifndef NORMALISE_MODULE_NAME
13109bd41f2cSmrg   name = xstrdup("mouse");
13119bd41f2cSmrg#else
13129bd41f2cSmrg   /* Normalise the module name */
13139bd41f2cSmrg   name = xf86NormalizeName("mouse");
13149bd41f2cSmrg#endif
13159bd41f2cSmrg
13169bd41f2cSmrg   if (!LoadSubModule(module, name, NULL, NULL, NULL, NULL, errmaj, errmin)) {
13179bd41f2cSmrg      LoaderErrorMsg(NULL, name, *errmaj, *errmin);
13189bd41f2cSmrg   }
1319c4f7863aSmrg   free(name);
1320b15a006bSmrg}
1321b15a006bSmrg#endif
1322d075918cSmrg
13239bd41f2cSmrg   return module;
13249bd41f2cSmrg}
13259bd41f2cSmrg
13269bd41f2cSmrgstatic XF86ModuleVersionInfo VMMouseVersionRec = {
13279bd41f2cSmrg   "vmmouse",
13289bd41f2cSmrg   MODULEVENDORSTRING,
13299bd41f2cSmrg   MODINFOSTRING1,
13309bd41f2cSmrg   MODINFOSTRING2,
13319bd41f2cSmrg   XORG_VERSION_CURRENT,
13329418810dSmrg   PACKAGE_VERSION_MAJOR, PACKAGE_VERSION_MINOR, PACKAGE_VERSION_PATCHLEVEL,
13339bd41f2cSmrg   ABI_CLASS_XINPUT,
13349bd41f2cSmrg   ABI_XINPUT_VERSION,
13359bd41f2cSmrg   MOD_CLASS_XINPUT,
13369bd41f2cSmrg   {0, 0, 0, 0}		/* signature, to be patched into the file by a tool */
13379bd41f2cSmrg};
13389bd41f2cSmrg
13399bd41f2cSmrg/*
13409bd41f2cSmrg * The variable contains the necessary information to load and initialize the module
13419bd41f2cSmrg */
1342b15a006bSmrg_X_EXPORT XF86ModuleData vmmouseModuleData = {
13439bd41f2cSmrg   &VMMouseVersionRec,
13449bd41f2cSmrg   VMMousePlug,
13459bd41f2cSmrg   VMMouseUnplug
13469bd41f2cSmrg};
13479bd41f2cSmrg#endif /* XFree86LOADER */
1348