vmmouse.c revision 0da4cdcc
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"
680da4cdccSmrg#include "xf86Priv.h"
699bd41f2cSmrg#include "compiler.h"
709bd41f2cSmrg
71b15a006bSmrg#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 7
72b15a006bSmrg#include <xserver-properties.h>
73ea0de359Smrg#include "exevents.h"
74b15a006bSmrg#endif
75b15a006bSmrg
760da4cdccSmrg#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) < 18
770da4cdccSmrg#define LogMessageVerbSigSafe xf86MsgVerb
780da4cdccSmrg#endif
790da4cdccSmrg
809bd41f2cSmrg#include "xisb.h"
819bd41f2cSmrg#include "mipointer.h"
829bd41f2cSmrg
83c4f7863aSmrg#ifndef HAVE_XORG_SERVER_1_5_0
84c4f7863aSmrg#include <xf86_ansic.h>
85c4f7863aSmrg#include <xf86_libc.h>
86c4f7863aSmrg#endif
87c4f7863aSmrg
889bd41f2cSmrg/*****************************************************************************
899bd41f2cSmrg *	Local Headers
909bd41f2cSmrg ****************************************************************************/
919bd41f2cSmrg#include "vmmouse_client.h"
929bd41f2cSmrg
939bd41f2cSmrg/*
949bd41f2cSmrg * This is the only way I know to turn a #define of an integer constant into
959bd41f2cSmrg * a constant string.
969bd41f2cSmrg */
979bd41f2cSmrg#define VMW_INNERSTRINGIFY(s) #s
989bd41f2cSmrg#define VMW_STRING(str) VMW_INNERSTRINGIFY(str)
999bd41f2cSmrg
1009bd41f2cSmrg/*
1019bd41f2cSmrg * So that the file compiles unmodified when dropped into an xfree source tree.
1029bd41f2cSmrg */
1039bd41f2cSmrg#ifndef XORG_VERSION_CURRENT
1049bd41f2cSmrg#define XORG_VERSION_CURRENT XF86_VERSION_CURRENT
1059bd41f2cSmrg#endif
1069bd41f2cSmrg
1079bd41f2cSmrg/*
1089bd41f2cSmrg * Version constants
1099bd41f2cSmrg */
1109bd41f2cSmrg#define VMMOUSE_DRIVER_VERSION \
1119418810dSmrg   (PACKAGE_VERSION_MAJOR * 65536 + PACKAGE_VERSION_MINOR * 256 + PACKAGE_VERSION_PATCHLEVEL)
1129bd41f2cSmrg#define VMMOUSE_DRIVER_VERSION_STRING \
1139418810dSmrg    VMW_STRING(PACKAGE_VERSION_MAJOR) "." VMW_STRING(PACKAGE_VERSION_MINOR) \
1149418810dSmrg    "." VMW_STRING(PACKAGE_VERSION_PATCHLEVEL)
1159bd41f2cSmrg
1169bd41f2cSmrg/*
1179bd41f2cSmrg * Standard four digit version string expected by VMware Tools installer.
118c4f7863aSmrg * As the driver's version is only  {major, minor, patchlevel},
119c4f7863aSmrg * The fourth digit may describe the commit number relative to the
120c4f7863aSmrg * last version tag as output from `git describe`
1219bd41f2cSmrg */
1229bd41f2cSmrg#ifdef __GNUC__
123c4f7863aSmrg#ifdef VMW_SUBPATCH
124c4f7863aSmrgconst char vm_mouse_version[] __attribute__((section(".modinfo"),unused)) =
125c4f7863aSmrg    "version=" VMMOUSE_DRIVER_VERSION_STRING "." VMW_STRING(VMW_SUBPATCH);
126c4f7863aSmrg#else
1279bd41f2cSmrgconst char vm_mouse_version[] __attribute__((section(".modinfo"),unused)) =
1289bd41f2cSmrg    "version=" VMMOUSE_DRIVER_VERSION_STRING ".0";
129c4f7863aSmrg#endif /*VMW_SUBPATCH*/
1309bd41f2cSmrg#endif
1319bd41f2cSmrg
1329bd41f2cSmrg
1339bd41f2cSmrg/*****************************************************************************
1349bd41f2cSmrg *	static function header
1359bd41f2cSmrg ****************************************************************************/
136c4f7863aSmrg#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 12
137c4f7863aSmrgstatic int VMMousePreInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags);
138c4f7863aSmrg#else
1399bd41f2cSmrgstatic InputInfoPtr VMMousePreInit(InputDriverPtr drv, IDevPtr dev, int flags);
140c4f7863aSmrgstatic void VMMouseCloseProc(InputInfoPtr pInfo);
141c4f7863aSmrgstatic Bool VMMouseConvertProc(InputInfoPtr pInfo, int first, int num, int v0, int v1, int v2,
142c4f7863aSmrg			       int v3, int v4, int v5, int *x, int *y);
143c4f7863aSmrg#endif
1449bd41f2cSmrgstatic void VMMouseUnInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags);
1459bd41f2cSmrgstatic void MouseCommonOptions(InputInfoPtr pInfo);
1469bd41f2cSmrgstatic void GetVMMouseMotionEvent(InputInfoPtr pInfo);
1479bd41f2cSmrgstatic void VMMousePostEvent(InputInfoPtr pInfo, int buttons, int dx, int dy, int dz, int dw);
1489bd41f2cSmrgstatic void VMMouseDoPostEvent(InputInfoPtr pInfo, int buttons, int dx, int dy);
1499bd41f2cSmrgstatic Bool VMMouseDeviceControl(DeviceIntPtr device, int mode);
150c4f7863aSmrgstatic int  VMMouseControlProc(InputInfoPtr pInfo, xDeviceCtl * control);
1519bd41f2cSmrgstatic void VMMouseReadInput(InputInfoPtr pInfo);
1529bd41f2cSmrgstatic int  VMMouseSwitchMode(ClientPtr client, DeviceIntPtr dev, int mode);
1539bd41f2cSmrgstatic void MouseCtrl(DeviceIntPtr device, PtrCtrl *ctrl);
1549bd41f2cSmrg
1559bd41f2cSmrg/******************************************************************************
1569bd41f2cSmrg *		Definitions
1579bd41f2cSmrg *****************************************************************************/
1589bd41f2cSmrgtypedef struct {
159d075918cSmrg   int                 screenNum;
160d075918cSmrg   Bool                vmmouseAvailable;
161d075918cSmrg   VMMOUSE_INPUT_DATA  vmmousePrevInput;
162d075918cSmrg   Bool                isCurrRelative;
163d075918cSmrg   Bool                absoluteRequested;
1649bd41f2cSmrg} VMMousePrivRec, *VMMousePrivPtr;
1659bd41f2cSmrg
1669418810dSmrg#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) < 7
1679bd41f2cSmrgstatic const char *reqSymbols[] = {
1689bd41f2cSmrg   "InitPointerDeviceStruct",
1699bd41f2cSmrg   "LoaderSymbol",
1709bd41f2cSmrg   "LoadSubModule",
1719bd41f2cSmrg   "miPointerGetMotionBufferSize",
1729bd41f2cSmrg   "miPointerGetMotionEvents",
1739bd41f2cSmrg   "screenInfo",
1749bd41f2cSmrg   "Xcalloc",
1759bd41f2cSmrg   "xf86AddEnabledDevice",
1769bd41f2cSmrg   "xf86AddInputDriver",
1779bd41f2cSmrg   "xf86AddModuleInfo",
1789bd41f2cSmrg   "xf86AllocateInput",
1799bd41f2cSmrg   "xf86BlockSIGIO",
1809bd41f2cSmrg   "xf86CloseSerial",
1819bd41f2cSmrg   "xf86CollectInputOptions",
1829bd41f2cSmrg   "xf86ffs",
1839bd41f2cSmrg   "xf86FlushInput",
1849bd41f2cSmrg   "xf86GetAllowMouseOpenFail",
1859bd41f2cSmrg   "xf86GetMotionEvents",
1869bd41f2cSmrg   "xf86InitValuatorAxisStruct",
1879bd41f2cSmrg   "xf86InitValuatorDefaults",
1889bd41f2cSmrg   "xf86LoaderCheckSymbol",
1899bd41f2cSmrg   "xf86MotionHistoryAllocate",
1909bd41f2cSmrg   "xf86Msg",
1919bd41f2cSmrg   "xf86NameCmp",
1929bd41f2cSmrg   "xf86OpenSerial",
1939bd41f2cSmrg   "xf86OSMouseInit",
1949bd41f2cSmrg   "xf86PostButtonEvent",
1959bd41f2cSmrg   "xf86PostMotionEvent",
1969bd41f2cSmrg   "xf86ProcessCommonOptions",
1979bd41f2cSmrg   "xf86RemoveEnabledDevice",
1989bd41f2cSmrg   "xf86SetIntOption",
1999bd41f2cSmrg   "xf86SetStrOption",
2009bd41f2cSmrg   "xf86sprintf",
2019bd41f2cSmrg   "xf86sscanf",
2029bd41f2cSmrg   "xf86UnblockSIGIO",
2039bd41f2cSmrg   "xf86usleep",
2049bd41f2cSmrg   "xf86XInputSetScreen",
2059bd41f2cSmrg   "Xfree",
2069bd41f2cSmrg   "XisbBlockDuration",
2079bd41f2cSmrg   "XisbFree",
2089bd41f2cSmrg   "XisbNew",
2099bd41f2cSmrg   "XisbRead",
2109bd41f2cSmrg   "Xstrdup",
2119bd41f2cSmrg   NULL
2129bd41f2cSmrg};
2139418810dSmrg#endif
2149bd41f2cSmrg
2159bd41f2cSmrgInputDriverRec VMMOUSE = {
2169bd41f2cSmrg   1,
2179bd41f2cSmrg   "vmmouse",
2189bd41f2cSmrg   NULL,
2199bd41f2cSmrg   VMMousePreInit,
220d075918cSmrg   VMMouseUnInit,
221c4f7863aSmrg   NULL
222c4f7863aSmrg#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) < 11
223c4f7863aSmrg       ,
2249bd41f2cSmrg   0
225c4f7863aSmrg#endif
2269bd41f2cSmrg};
2279bd41f2cSmrg
2289bd41f2cSmrgstatic char reverseMap[32] = { 0,  4,  2,  6,  1,  5,  3,  7,
2299bd41f2cSmrg			       8, 12, 10, 14,  9, 13, 11, 15,
2309bd41f2cSmrg			      16, 20, 18, 22, 17, 21, 19, 23,
2319bd41f2cSmrg			      24, 28, 26, 30, 25, 29, 27, 31};
2329bd41f2cSmrg
2339bd41f2cSmrg#define reverseBits(map, b)	(((b) & ~0x0f) | map[(b) & 0x0f])
2349bd41f2cSmrg
235c4f7863aSmrg#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 12
2360da4cdccSmrg#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) < 14
2370da4cdccSmrg
2380da4cdccSmrgstatic InputOption*
2390da4cdccSmrginput_option_new(InputOption *list, char *key, char *value)
2400da4cdccSmrg{
2410da4cdccSmrg   InputOption *new;
2420da4cdccSmrg
2430da4cdccSmrg   new = calloc(1, sizeof(InputOption));
2440da4cdccSmrg   new->key = key;
2450da4cdccSmrg   new->value = value;
2460da4cdccSmrg   new->next = list;
2470da4cdccSmrg   return new;
2480da4cdccSmrg}
2490da4cdccSmrg
2500da4cdccSmrgstatic void
2510da4cdccSmrginput_option_free_list(InputOption **opts)
2520da4cdccSmrg{
2530da4cdccSmrg   InputOption *tmp = *opts;
2540da4cdccSmrg   while(*opts)
2550da4cdccSmrg   {
2560da4cdccSmrg      tmp = (*opts)->next;
2570da4cdccSmrg      free((*opts)->key);
2580da4cdccSmrg      free((*opts)->value);
2590da4cdccSmrg      free((*opts));
2600da4cdccSmrg      *opts = tmp;
2610da4cdccSmrg   }
2620da4cdccSmrg}
2630da4cdccSmrg#endif
2640da4cdccSmrg
265c4f7863aSmrgstatic int
266c4f7863aSmrgVMMouseInitPassthru(InputDriverPtr drv, InputInfoPtr pInfo, int flags)
267c4f7863aSmrg{
268c4f7863aSmrg   InputAttributes *attrs = NULL;
2690da4cdccSmrg   InputOption *input_options = NULL;
270c4f7863aSmrg   pointer options;
271c4f7863aSmrg   DeviceIntPtr dev;
272c4f7863aSmrg   int rc;
273c4f7863aSmrg
274c4f7863aSmrg   options = xf86OptionListDuplicate(pInfo->options);
275c4f7863aSmrg   options = xf86ReplaceStrOption(options, "Driver", "mouse");
276c4f7863aSmrg
277c4f7863aSmrg   while(options) {
2780da4cdccSmrg      input_options = input_option_new(input_options,
2790da4cdccSmrg                                       xf86OptionName(options),
2800da4cdccSmrg                                       xf86OptionValue(options));
281c4f7863aSmrg      options = xf86NextOption(options);
282c4f7863aSmrg   }
283c4f7863aSmrg
284c4f7863aSmrg   rc = NewInputDeviceRequest(input_options, attrs, &dev);
285c4f7863aSmrg
2860da4cdccSmrg   input_option_free_list(&input_options);
287c4f7863aSmrg
288c4f7863aSmrg   return rc;
289c4f7863aSmrg}
290c4f7863aSmrg
291c4f7863aSmrg#else /* if ABI_XINPUT_VERSION < 12 */
292c4f7863aSmrgstatic InputInfoPtr
293c4f7863aSmrgVMMouseInitPassthru(InputDriverPtr drv, IDevPtr dev, int flags)
294c4f7863aSmrg{
295c4f7863aSmrg   InputDriverRec *passthruMouse;
296c4f7863aSmrg   passthruMouse = (InputDriverRec *)LoaderSymbol("MOUSE");
297c4f7863aSmrg   if(passthruMouse != NULL) {
298c4f7863aSmrg      return (passthruMouse->PreInit)(drv, dev, flags);
299c4f7863aSmrg   } else {
300c4f7863aSmrg      return NULL;
301c4f7863aSmrg   }
302c4f7863aSmrg}
303c4f7863aSmrg#endif
3049bd41f2cSmrg
3059bd41f2cSmrg/*
3069bd41f2cSmrg *----------------------------------------------------------------------
3079bd41f2cSmrg *
3089bd41f2cSmrg * VMMousePreInit --
3099bd41f2cSmrg *	This function collect all the information that is necessary to
3109bd41f2cSmrg *	determine the configuration of the hardware and to prepare the
3119bd41f2cSmrg *	device for being used
312d075918cSmrg *
3139bd41f2cSmrg * Results:
3149bd41f2cSmrg * 	An InputInfoPtr object which points to vmmouse's information,
3159bd41f2cSmrg *	if the absolute pointing device available
3169bd41f2cSmrg *	Otherwise, an InputInfoPtr of regular mouse
317d075918cSmrg *
3189bd41f2cSmrg * Side effects:
3199bd41f2cSmrg * 	VMMouse was initialized with necessary information
3209bd41f2cSmrg *
3219bd41f2cSmrg *----------------------------------------------------------------------
3229bd41f2cSmrg */
3239bd41f2cSmrg
324c4f7863aSmrg#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) < 12
325c4f7863aSmrgstatic int
326c4f7863aSmrgVMMouseNewPreInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags);
327c4f7863aSmrg
3289bd41f2cSmrgstatic InputInfoPtr
3299bd41f2cSmrgVMMousePreInit(InputDriverPtr drv, IDevPtr dev, int flags)
330d075918cSmrg{
3319bd41f2cSmrg   InputInfoPtr pInfo;
332b15a006bSmrg
333b15a006bSmrg#ifndef NO_MOUSE_MODULE
334b15a006bSmrg{
3359bd41f2cSmrg   OSMouseInfoPtr osInfo = NULL;
3369bd41f2cSmrg
3379bd41f2cSmrg   /*
3389bd41f2cSmrg    * let Xserver init the mouse first
339d075918cSmrg    */
3409bd41f2cSmrg   osInfo = xf86OSMouseInit(0);
3419bd41f2cSmrg   if (!osInfo)
3429bd41f2cSmrg      return FALSE;
343b15a006bSmrg}
344b15a006bSmrg#endif
345d075918cSmrg
3460da4cdccSmrg   /*
3470da4cdccSmrg    * enable hardware access
3480da4cdccSmrg    */
3490da4cdccSmrg   if (!xorgHWAccess) {
3500da4cdccSmrg      if (xf86EnableIO())
3510da4cdccSmrg          xorgHWAccess = TRUE;
3520da4cdccSmrg      else
3530da4cdccSmrg          return NULL;
3540da4cdccSmrg   }
3550da4cdccSmrg
3569bd41f2cSmrg   /*
3579bd41f2cSmrg    * try to enable vmmouse here
3589bd41f2cSmrg    */
3599bd41f2cSmrg   if (!VMMouseClient_Enable()) {
3609bd41f2cSmrg      /*
3619bd41f2cSmrg       * vmmouse failed
3629bd41f2cSmrg       * Fall back to normal mouse module
3639bd41f2cSmrg       */
3649bd41f2cSmrg      xf86Msg(X_ERROR, "VMWARE(0): vmmouse enable failed\n");
365c4f7863aSmrg      return VMMouseInitPassthru(drv, dev, flags);
3669bd41f2cSmrg   } else {
3679bd41f2cSmrg      /*
3689bd41f2cSmrg       * vmmouse is available
3699bd41f2cSmrg       */
3709bd41f2cSmrg      xf86Msg(X_INFO, "VMWARE(0): vmmouse is available\n");
3719bd41f2cSmrg      /*
3729bd41f2cSmrg       * Disable the absolute pointing device for now
3739bd41f2cSmrg       * It will be enabled during DEVICE_ON phase
3749bd41f2cSmrg       */
375d075918cSmrg      VMMouseClient_Disable();
3769bd41f2cSmrg   }
377d075918cSmrg
3789bd41f2cSmrg   if (!(pInfo = xf86AllocateInput(drv, 0))) {
3799bd41f2cSmrg      return NULL;
380d075918cSmrg   }
3819bd41f2cSmrg
382d075918cSmrg   pInfo->name = dev->identifier;
3839bd41f2cSmrg#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) == 0
3849bd41f2cSmrg   pInfo->motion_history_proc = xf86GetMotionEvents;
3859bd41f2cSmrg#endif
3869bd41f2cSmrg   pInfo->close_proc = VMMouseCloseProc;
3879bd41f2cSmrg   pInfo->conversion_proc = VMMouseConvertProc;
3889bd41f2cSmrg   pInfo->reverse_conversion_proc = NULL;
3899bd41f2cSmrg   pInfo->fd = -1;
3909bd41f2cSmrg   pInfo->dev = NULL;
3919bd41f2cSmrg   pInfo->private_flags = 0;
3929bd41f2cSmrg   pInfo->always_core_feedback = 0;
3939bd41f2cSmrg   pInfo->conf_idev = dev;
394c4f7863aSmrg   pInfo->flags = XI86_POINTER_CAPABLE | XI86_SEND_DRAG_EVENTS;
395c4f7863aSmrg
396c4f7863aSmrg   /* Collect the options, and process the common options. */
397c4f7863aSmrg   xf86CollectInputOptions(pInfo, NULL, NULL);
398c4f7863aSmrg   xf86ProcessCommonOptions(pInfo, pInfo->options);
399c4f7863aSmrg
400c4f7863aSmrg   if (VMMouseNewPreInit(drv, pInfo, flags) == Success)
401c4f7863aSmrg       pInfo->flags |= XI86_CONFIGURED;
402c4f7863aSmrg
403c4f7863aSmrg   return pInfo;
404c4f7863aSmrg}
405c4f7863aSmrg
406c4f7863aSmrgstatic int
407c4f7863aSmrgVMMouseNewPreInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags)
408c4f7863aSmrg#else /* if ABI_XINPUT_VERSION >= 12 */
409c4f7863aSmrgstatic int
410c4f7863aSmrgVMMousePreInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags)
411c4f7863aSmrg#endif
412c4f7863aSmrg{
413c4f7863aSmrg   MouseDevPtr pMse = NULL;
414c4f7863aSmrg   VMMousePrivPtr mPriv = NULL;
415c4f7863aSmrg   int rc = Success;
416c4f7863aSmrg
4170da4cdccSmrg   /* Enable hardware access. */
4180da4cdccSmrg   if (!xorgHWAccess) {
4190da4cdccSmrg      if (xf86EnableIO())
4200da4cdccSmrg          xorgHWAccess = TRUE;
4210da4cdccSmrg      else {
4220da4cdccSmrg          rc = BadValue;
4230da4cdccSmrg          goto error;
4240da4cdccSmrg      }
4250da4cdccSmrg   }
4260da4cdccSmrg
427c4f7863aSmrg#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 12
428c4f7863aSmrg   /* For ABI < 12, we need to return the wrapped driver's pInfo (see
429c4f7863aSmrg    * above). ABI 12, we call NIDR and are done */
430c4f7863aSmrg   if (!VMMouseClient_Enable()) {
431c4f7863aSmrg      xf86Msg(X_ERROR, "VMWARE(0): vmmouse enable failed\n");
432c4f7863aSmrg      return VMMouseInitPassthru(drv, pInfo, flags);
433c4f7863aSmrg   } else {
434c4f7863aSmrg      xf86Msg(X_INFO, "VMWARE(0): vmmouse is available\n");
435c4f7863aSmrg      VMMouseClient_Disable();
436c4f7863aSmrg   }
437c4f7863aSmrg#endif
438c4f7863aSmrg
439c4f7863aSmrg   mPriv = calloc (1, sizeof (VMMousePrivRec));
440c4f7863aSmrg
441c4f7863aSmrg   if (!mPriv) {
442c4f7863aSmrg      rc = BadAlloc;
443c4f7863aSmrg      goto error;
444c4f7863aSmrg   }
445c4f7863aSmrg
446c4f7863aSmrg   mPriv->absoluteRequested = FALSE;
447c4f7863aSmrg   mPriv->vmmouseAvailable = TRUE;
448c4f7863aSmrg
449c4f7863aSmrg   /* Settup the pInfo */
450c4f7863aSmrg   pInfo->type_name = XI_MOUSE;
451c4f7863aSmrg   pInfo->device_control = VMMouseDeviceControl;
452c4f7863aSmrg   pInfo->read_input = VMMouseReadInput;
453c4f7863aSmrg   pInfo->control_proc = VMMouseControlProc;
454c4f7863aSmrg   pInfo->switch_mode = VMMouseSwitchMode;
4559bd41f2cSmrg
4569bd41f2cSmrg   /* Allocate the MouseDevRec and initialise it. */
457c4f7863aSmrg   if (!(pMse = calloc(sizeof(MouseDevRec), 1))) {
458c4f7863aSmrg      rc = BadAlloc;
459c4f7863aSmrg      goto error;
4609bd41f2cSmrg   }
4619bd41f2cSmrg
4629bd41f2cSmrg   pInfo->private = pMse;
4639bd41f2cSmrg   pMse->Ctrl = MouseCtrl;
4649bd41f2cSmrg   pMse->PostEvent = VMMousePostEvent;
4659bd41f2cSmrg   pMse->CommonOptions = MouseCommonOptions;
4669bd41f2cSmrg   pMse->mousePriv = mPriv;
467d075918cSmrg
4689bd41f2cSmrg
4699bd41f2cSmrg   /* Check if the device can be opened. */
4709bd41f2cSmrg   pInfo->fd = xf86OpenSerial(pInfo->options);
4719bd41f2cSmrg   if (pInfo->fd == -1) {
4729bd41f2cSmrg      if (xf86GetAllowMouseOpenFail())
4739bd41f2cSmrg	 xf86Msg(X_WARNING, "%s: cannot open input device\n", pInfo->name);
4749bd41f2cSmrg      else {
4759bd41f2cSmrg	 xf86Msg(X_ERROR, "%s: cannot open input device\n", pInfo->name);
476c4f7863aSmrg	 rc = BadValue;
477c4f7863aSmrg	 goto error;
4789bd41f2cSmrg      }
4799bd41f2cSmrg   }
4809bd41f2cSmrg   xf86CloseSerial(pInfo->fd);
4819bd41f2cSmrg   pInfo->fd = -1;
482d075918cSmrg
4839bd41f2cSmrg   /* Process the options */
4849bd41f2cSmrg   pMse->CommonOptions(pInfo);
485d075918cSmrg
4869bd41f2cSmrg   /* set up the current screen num */
4879bd41f2cSmrg   mPriv->screenNum = xf86SetIntOption(pInfo->options, "ScreenNumber", 0);
488d075918cSmrg
489c4f7863aSmrg   return Success;
490c4f7863aSmrg
491c4f7863aSmrgerror:
492c4f7863aSmrg   pInfo->private = NULL;
493c4f7863aSmrg   if (mPriv)
494c4f7863aSmrg      free(mPriv);
495c4f7863aSmrg   if (pMse)
496c4f7863aSmrg      free(pMse);
497c4f7863aSmrg
498c4f7863aSmrg   return rc;
4999bd41f2cSmrg}
5009bd41f2cSmrg
5019bd41f2cSmrg
5029bd41f2cSmrg/*
5039bd41f2cSmrg *----------------------------------------------------------------------
5049bd41f2cSmrg *
5059bd41f2cSmrg * MouseCtrl --
506d075918cSmrg *     Alter the control paramters for the mouse.
507d075918cSmrg *
5089bd41f2cSmrg * Results:
509d075918cSmrg * 	None
510d075918cSmrg *
5119bd41f2cSmrg * Side effects:
5129bd41f2cSmrg * 	None
5139bd41f2cSmrg *
5149bd41f2cSmrg *----------------------------------------------------------------------
5159bd41f2cSmrg */
5169bd41f2cSmrg
5179bd41f2cSmrgstatic void
5189bd41f2cSmrgMouseCtrl(DeviceIntPtr device, PtrCtrl *ctrl)
5199bd41f2cSmrg{
5209bd41f2cSmrg    InputInfoPtr pInfo;
5219bd41f2cSmrg    MouseDevPtr pMse;
5229bd41f2cSmrg
5239bd41f2cSmrg    pInfo = device->public.devicePrivate;
5249bd41f2cSmrg    pMse = pInfo->private;
5259bd41f2cSmrg
5269bd41f2cSmrg#ifdef EXTMOUSEDEBUG
5279bd41f2cSmrg    xf86Msg(X_INFO, "VMMOUSE(0): MouseCtrl pMse=%p\n", pMse);
5289bd41f2cSmrg#endif
529d075918cSmrg
5309bd41f2cSmrg    pMse->num       = ctrl->num;
5319bd41f2cSmrg    pMse->den       = ctrl->den;
5329bd41f2cSmrg    pMse->threshold = ctrl->threshold;
5339bd41f2cSmrg}
5349bd41f2cSmrg
5359bd41f2cSmrg
5369bd41f2cSmrg/*
5379bd41f2cSmrg *----------------------------------------------------------------------
5389bd41f2cSmrg *
5399bd41f2cSmrg * VMMouseDoPostEvent --
5409bd41f2cSmrg *	Post the mouse button event and mouse motion event to Xserver
541d075918cSmrg *
5429bd41f2cSmrg * Results:
5439bd41f2cSmrg * 	None
544d075918cSmrg *
5459bd41f2cSmrg * Side effects:
5469bd41f2cSmrg * 	Mouse location and button status was updated
5479bd41f2cSmrg *
5489bd41f2cSmrg *----------------------------------------------------------------------
5499bd41f2cSmrg */
5509bd41f2cSmrg
5519bd41f2cSmrgstatic void
5529bd41f2cSmrgVMMouseDoPostEvent(InputInfoPtr pInfo, int buttons, int dx, int dy)
5539bd41f2cSmrg{
5549bd41f2cSmrg    MouseDevPtr pMse;
5559bd41f2cSmrg    VMMousePrivPtr mPriv;
5569bd41f2cSmrg    int truebuttons;
5579bd41f2cSmrg    int id, change;
558d075918cSmrg    Bool mouseMoved = FALSE;
559d075918cSmrg
5609bd41f2cSmrg    pMse = pInfo->private;
5619bd41f2cSmrg    mPriv = (VMMousePrivPtr)pMse->mousePriv;
5629bd41f2cSmrg
5639bd41f2cSmrg    /*
5649bd41f2cSmrg     * The following truebuttons/reverseBits and lastButtons are
5659bd41f2cSmrg     * used to compare the current buttons and the previous buttons
5669bd41f2cSmrg     * to find the button changes during two mouse events
567d075918cSmrg     */
5689bd41f2cSmrg    truebuttons = buttons;
5699bd41f2cSmrg
5709bd41f2cSmrg    buttons = reverseBits(reverseMap, buttons);
5719bd41f2cSmrg
572d075918cSmrg    if (mPriv->isCurrRelative) {
573d075918cSmrg       mouseMoved = dx || dy;
574d075918cSmrg    } else {
575d075918cSmrg       mouseMoved = (dx != mPriv->vmmousePrevInput.X) ||
576d075918cSmrg                    (dy != mPriv->vmmousePrevInput.Y) ||
577d075918cSmrg                    (mPriv->vmmousePrevInput.Flags & VMMOUSE_MOVE_RELATIVE);
578d075918cSmrg    }
579d075918cSmrg    if (mouseMoved) {
5809bd41f2cSmrg
581d075918cSmrg#ifdef CALL_CONVERSION_PROC
5829bd41f2cSmrg        /*
583d075918cSmrg         * Xservers between 1.3.99.0 - 1.4.0.90 do not call conversion_proc, so
584d075918cSmrg         * we need to do the conversion from device to screen space.
5859bd41f2cSmrg         */
5869bd41f2cSmrg        VMMouseConvertProc(pInfo, 0, 2, dx, dy, 0, 0, 0, 0, &dx, &dy);
587d075918cSmrg#endif
588d075918cSmrg        xf86PostMotionEvent(pInfo->dev, !mPriv->isCurrRelative, 0, 2, dx, dy);
5899bd41f2cSmrg    }
590d075918cSmrg
5919bd41f2cSmrg    if (truebuttons != pMse->lastButtons) {
5929bd41f2cSmrg       change = buttons ^ reverseBits(reverseMap, pMse->lastButtons);
5939bd41f2cSmrg       while (change) {
5949bd41f2cSmrg	  id = ffs(change);
5959bd41f2cSmrg	  change &= ~(1 << (id - 1));
5969bd41f2cSmrg	  xf86PostButtonEvent(pInfo->dev, 0, id,
5979bd41f2cSmrg			      (buttons & (1 << (id - 1))), 0, 0);
5989bd41f2cSmrg       }
5999bd41f2cSmrg       pMse->lastButtons = truebuttons;
6009bd41f2cSmrg    }
6019bd41f2cSmrg}
6029bd41f2cSmrg
6039bd41f2cSmrg
6049bd41f2cSmrg/*
6059bd41f2cSmrg *----------------------------------------------------------------------
6069bd41f2cSmrg *
6079bd41f2cSmrg * VMMousePostEvent --
6089bd41f2cSmrg *	Prepare the mouse status according to the Z axis mapping
6099bd41f2cSmrg *	before we post the event to Xserver
610d075918cSmrg *
6119bd41f2cSmrg * Results:
6129bd41f2cSmrg * 	None
613d075918cSmrg *
6149bd41f2cSmrg * Side effects:
6159bd41f2cSmrg * 	Buttons was updated according to Z axis mapping
6169bd41f2cSmrg *
6179bd41f2cSmrg *----------------------------------------------------------------------
6189bd41f2cSmrg */
6199bd41f2cSmrg
6209bd41f2cSmrgstatic void
6219bd41f2cSmrgVMMousePostEvent(InputInfoPtr pInfo, int buttons, int dx, int dy, int dz, int dw)
6229bd41f2cSmrg{
6239bd41f2cSmrg    MouseDevPtr pMse;
6249bd41f2cSmrg    int zbutton = 0;
6259bd41f2cSmrg    VMMousePrivPtr mPriv;
626d075918cSmrg
6279bd41f2cSmrg    pMse = pInfo->private;
6289bd41f2cSmrg    mPriv = (VMMousePrivPtr)pMse->mousePriv;
6299bd41f2cSmrg    /* Map the Z axis movement. */
6309bd41f2cSmrg    /* XXX Could this go in the conversion_proc? */
6319bd41f2cSmrg    switch (pMse->negativeZ) {
6329bd41f2cSmrg    case MSE_NOZMAP:	/* do nothing */
6339bd41f2cSmrg	break;
6349bd41f2cSmrg    case MSE_MAPTOX:
6359bd41f2cSmrg	if (dz != 0) {
636d075918cSmrg	   if(mPriv->isCurrRelative)
6379bd41f2cSmrg	      dx = dz;
6389bd41f2cSmrg	   else
639d075918cSmrg	      dx += dz;
6409bd41f2cSmrg	    dz = 0;
6419bd41f2cSmrg	}
6429bd41f2cSmrg	break;
6439bd41f2cSmrg    case MSE_MAPTOY:
6449bd41f2cSmrg	if (dz != 0) {
645d075918cSmrg	   if(mPriv->isCurrRelative)
6469bd41f2cSmrg	      dy = dz;
6479bd41f2cSmrg	   else
648d075918cSmrg	      dy += dz;
6499bd41f2cSmrg	    dz = 0;
6509bd41f2cSmrg	}
6519bd41f2cSmrg	break;
6529bd41f2cSmrg    default:	/* buttons */
6539bd41f2cSmrg	buttons &= ~(pMse->negativeZ | pMse->positiveZ
6549bd41f2cSmrg		   | pMse->negativeW | pMse->positiveW);
6559bd41f2cSmrg	if (dw < 0 || dz < -1) {
6569bd41f2cSmrg	    zbutton = pMse->negativeW;
6579bd41f2cSmrg	}
6589bd41f2cSmrg	else if (dz < 0) {
6599bd41f2cSmrg	    zbutton = pMse->negativeZ;
6609bd41f2cSmrg	}
6619bd41f2cSmrg	else if (dw > 0 || dz > 1) {
6629bd41f2cSmrg	    zbutton = pMse->positiveW;
6639bd41f2cSmrg	}
6649bd41f2cSmrg	else if (dz > 0) {
6659bd41f2cSmrg	    zbutton = pMse->positiveZ;
6669bd41f2cSmrg	}
6679bd41f2cSmrg	buttons |= zbutton;
6689bd41f2cSmrg	dz = 0;
6699bd41f2cSmrg	break;
6709bd41f2cSmrg    }
6719bd41f2cSmrg
6729bd41f2cSmrg    VMMouseDoPostEvent(pInfo, buttons, dx, dy);
6739bd41f2cSmrg
6749bd41f2cSmrg    /*
6759bd41f2cSmrg     * If dz has been mapped to a button `down' event, we need to cook up
6769bd41f2cSmrg     * a corresponding button `up' event.
6779bd41f2cSmrg     */
6789bd41f2cSmrg    if (zbutton) {
6799bd41f2cSmrg	buttons &= ~zbutton;
680d075918cSmrg	if(mPriv->isCurrRelative)
6819bd41f2cSmrg	   VMMouseDoPostEvent(pInfo, buttons, 0, 0);
6829bd41f2cSmrg	else
6839bd41f2cSmrg	   VMMouseDoPostEvent(pInfo, buttons, dx, dy);
6849bd41f2cSmrg    }
6859bd41f2cSmrg}
6869bd41f2cSmrg
6879bd41f2cSmrg
6889bd41f2cSmrg/*
6899bd41f2cSmrg *----------------------------------------------------------------------
6909bd41f2cSmrg *
6919bd41f2cSmrg * FlushButtons --
6929bd41f2cSmrg *
693d075918cSmrg * 	FlushButtons -- reset button states.
6949bd41f2cSmrg *
6959bd41f2cSmrg * Results:
6969bd41f2cSmrg * 	None
697d075918cSmrg *
6989bd41f2cSmrg * Side effects:
6999bd41f2cSmrg * 	None
7009bd41f2cSmrg *
7019bd41f2cSmrg *----------------------------------------------------------------------
7029bd41f2cSmrg */
7039bd41f2cSmrg
7049bd41f2cSmrgstatic void
7059bd41f2cSmrgFlushButtons(MouseDevPtr pMse)
7069bd41f2cSmrg{
7079bd41f2cSmrg    pMse->lastButtons = 0;
7089bd41f2cSmrg}
7099bd41f2cSmrg
7109bd41f2cSmrg
7119bd41f2cSmrg/*
7129bd41f2cSmrg *----------------------------------------------------------------------
7139bd41f2cSmrg *
7149bd41f2cSmrg * MouseCommonOptions --
7159bd41f2cSmrg *	Process acceptable mouse options. Currently we only process
7169bd41f2cSmrg *	"Buttons" and "ZAxisMapping" options.
717d075918cSmrg *	More options can be added later on
7189bd41f2cSmrg *
7199bd41f2cSmrg * Results:
7209bd41f2cSmrg * 	None
721d075918cSmrg *
7229bd41f2cSmrg * Side effects:
7239bd41f2cSmrg * 	The buttons was setup according to the options
7249bd41f2cSmrg *
7259bd41f2cSmrg *----------------------------------------------------------------------
7269bd41f2cSmrg */
7279bd41f2cSmrg
7289bd41f2cSmrgstatic void
7299bd41f2cSmrgMouseCommonOptions(InputInfoPtr pInfo)
7309bd41f2cSmrg{
7319bd41f2cSmrg   MouseDevPtr pMse;
7329bd41f2cSmrg   char *s;
7339bd41f2cSmrg
7349bd41f2cSmrg   pMse = pInfo->private;
7359bd41f2cSmrg
7369bd41f2cSmrg   pMse->buttons = xf86SetIntOption(pInfo->options, "Buttons", 0);
7379bd41f2cSmrg   if (!pMse->buttons) {
7389bd41f2cSmrg      pMse->buttons = MSE_DFLTBUTTONS;
7399bd41f2cSmrg   }
7409bd41f2cSmrg
7419bd41f2cSmrg   /*
7429bd41f2cSmrg    * "emulate3Buttons" and "Drag Lock" is not supported
7439bd41f2cSmrg    */
7449bd41f2cSmrg
7459bd41f2cSmrg   /*
7469bd41f2cSmrg    * Process option for ZAxisMapping
7479bd41f2cSmrg    */
748d075918cSmrg   s = xf86SetStrOption(pInfo->options, "ZAxisMapping", "4 5");
7499bd41f2cSmrg   if (s) {
7509bd41f2cSmrg      int b1 = 0, b2 = 0, b3 = 0, b4 = 0;
7519bd41f2cSmrg      char *msg = NULL;
7529bd41f2cSmrg
7539bd41f2cSmrg      if (!xf86NameCmp(s, "x")) {
7549bd41f2cSmrg	 pMse->negativeZ = pMse->positiveZ = MSE_MAPTOX;
7559bd41f2cSmrg	 pMse->negativeW = pMse->positiveW = MSE_MAPTOX;
7569bd41f2cSmrg	 msg = xstrdup("X axis");
7579bd41f2cSmrg      } else if (!xf86NameCmp(s, "y")) {
7589bd41f2cSmrg	 pMse->negativeZ = pMse->positiveZ = MSE_MAPTOY;
7599bd41f2cSmrg	 pMse->negativeW = pMse->positiveW = MSE_MAPTOY;
7609bd41f2cSmrg	 msg = xstrdup("Y axis");
7619bd41f2cSmrg      } else if (sscanf(s, "%d %d %d %d", &b1, &b2, &b3, &b4) >= 2 &&
7629bd41f2cSmrg		 b1 > 0 && b1 <= MSE_MAXBUTTONS &&
7639bd41f2cSmrg		 b2 > 0 && b2 <= MSE_MAXBUTTONS) {
7649bd41f2cSmrg	 msg = xstrdup("buttons XX and YY");
7659bd41f2cSmrg	 if (msg)
7669bd41f2cSmrg	    sprintf(msg, "buttons %d and %d", b1, b2);
7679bd41f2cSmrg	 pMse->negativeZ = pMse->negativeW = 1 << (b1-1);
7689bd41f2cSmrg	 pMse->positiveZ = pMse->positiveW = 1 << (b2-1);
7699bd41f2cSmrg	 if (b1 > pMse->buttons) pMse->buttons = b1;
7709bd41f2cSmrg	 if (b2 > pMse->buttons) pMse->buttons = b2;
771d075918cSmrg
7729bd41f2cSmrg	 /*
773d075918cSmrg	  * Option "ZAxisMapping" "N1 N2 N3 N4" not supported
7749bd41f2cSmrg	  */
7759bd41f2cSmrg	 pMse->negativeW = pMse->positiveW = MSE_NOZMAP;
7769bd41f2cSmrg      } else {
7779bd41f2cSmrg	 pMse->negativeZ = pMse->positiveZ = MSE_NOZMAP;
7789bd41f2cSmrg	 pMse->negativeW = pMse->positiveW = MSE_NOZMAP;
7799bd41f2cSmrg      }
7809bd41f2cSmrg      if (msg) {
7819bd41f2cSmrg	 xf86Msg(X_CONFIG, "%s: ZAxisMapping: %s\n", pInfo->name, msg);
782c4f7863aSmrg	 free(msg);
7839bd41f2cSmrg      } else {
7849bd41f2cSmrg	 xf86Msg(X_WARNING, "%s: Invalid ZAxisMapping value: \"%s\"\n",
7859bd41f2cSmrg		 pInfo->name, s);
7869bd41f2cSmrg      }
7879bd41f2cSmrg   }
7889bd41f2cSmrg}
7899bd41f2cSmrg
7909bd41f2cSmrg
7919bd41f2cSmrg/*
7929bd41f2cSmrg *----------------------------------------------------------------------
7939bd41f2cSmrg *
7949bd41f2cSmrg * VMMouseUnInit --
7959bd41f2cSmrg * 	This function was supposed to be called by Xserver to do Un-Init.
7969bd41f2cSmrg *	But it was unused now
7979bd41f2cSmrg *
7989bd41f2cSmrg * Results:
7999bd41f2cSmrg * 	None
800d075918cSmrg *
8019bd41f2cSmrg * Side effects:
8029bd41f2cSmrg * 	None
8039bd41f2cSmrg *
8049bd41f2cSmrg *----------------------------------------------------------------------
8059bd41f2cSmrg */
8069bd41f2cSmrg
807d075918cSmrgstatic void
808c4f7863aSmrgVMMouseUnInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags)
8099bd41f2cSmrg{
8109bd41f2cSmrg   xf86Msg(X_INFO, "VMWARE(0): VMMouseUnInit\n");
8119bd41f2cSmrg}
8129bd41f2cSmrg
8139bd41f2cSmrg
8149bd41f2cSmrg/*
8159bd41f2cSmrg *----------------------------------------------------------------------
8169bd41f2cSmrg *
8179bd41f2cSmrg * VMMouseDeviceControl --
8189bd41f2cSmrg * 	This function was called by Xserver during DEVICE_INIT, DEVICE_ON,
819d075918cSmrg *	DEVICE_OFF and DEVICE_CLOSE phase
820d075918cSmrg *
8219bd41f2cSmrg * Results:
8229bd41f2cSmrg * 	TRUE, if sucessful
8239bd41f2cSmrg *	FALSE, if failed
824d075918cSmrg *
8259bd41f2cSmrg * Side effects:
8269bd41f2cSmrg * 	Absolute pointing device is enabled during DEVICE_ON
8279bd41f2cSmrg *	Absolute pointing device is disabled during DEVICE_OFF
8289bd41f2cSmrg *	and DEVICE_CLOSE
8299bd41f2cSmrg *
8309bd41f2cSmrg *----------------------------------------------------------------------
8319bd41f2cSmrg */
8329bd41f2cSmrg
8339bd41f2cSmrgstatic Bool
8349bd41f2cSmrgVMMouseDeviceControl(DeviceIntPtr device, int mode)
8359bd41f2cSmrg{
8369bd41f2cSmrg   InputInfoPtr pInfo;
8379bd41f2cSmrg   MouseDevPtr pMse;
8389bd41f2cSmrg   unsigned char map[MSE_MAXBUTTONS + 1];
8399bd41f2cSmrg   int i;
840b15a006bSmrg#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 7
841b15a006bSmrg   Atom btn_labels[MSE_MAXBUTTONS] = {0};
842b15a006bSmrg   Atom axes_labels[2] = { 0, 0 };
843b15a006bSmrg#endif
844d075918cSmrg
8459bd41f2cSmrg   pInfo = device->public.devicePrivate;
8469bd41f2cSmrg   pMse = pInfo->private;
8479bd41f2cSmrg   pMse->device = device;
8489bd41f2cSmrg
8499bd41f2cSmrg   switch (mode){
8509bd41f2cSmrg   case DEVICE_INIT:
8519bd41f2cSmrg      device->public.on = FALSE;
8529bd41f2cSmrg      /*
8539bd41f2cSmrg       * [KAZU-241097] We don't know exactly how many buttons the
8549bd41f2cSmrg       * device has, so setup the map with the maximum number.
8559bd41f2cSmrg       */
8569bd41f2cSmrg      for (i = 0; i < MSE_MAXBUTTONS; i++)
8579bd41f2cSmrg	 map[i + 1] = i + 1;
858b15a006bSmrg#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 7
859b15a006bSmrg      btn_labels[0] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_LEFT);
860b15a006bSmrg      btn_labels[1] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_MIDDLE);
861b15a006bSmrg      btn_labels[2] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_RIGHT);
862b15a006bSmrg      btn_labels[4] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_UP);
863b15a006bSmrg      btn_labels[5] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_DOWN);
864b15a006bSmrg      btn_labels[6] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_HWHEEL_LEFT);
865b15a006bSmrg      btn_labels[7] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_HWHEEL_RIGHT);
866b15a006bSmrg      /* other buttons are unknown */
867b15a006bSmrg
868b15a006bSmrg#ifdef ABS_VALUATOR_AXES
869b15a006bSmrg      axes_labels[0] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_X);
870b15a006bSmrg      axes_labels[1] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_Y);
871b15a006bSmrg#else
872b15a006bSmrg      axes_labels[0] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_X);
873b15a006bSmrg      axes_labels[1] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_Y);
874b15a006bSmrg#endif /* ABS_VALUATOR_AXES */
875b15a006bSmrg#endif
8769bd41f2cSmrg
8779bd41f2cSmrg      InitPointerDeviceStruct((DevicePtr)device, map,
8789bd41f2cSmrg			      min(pMse->buttons, MSE_MAXBUTTONS),
879b15a006bSmrg#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 7
880b15a006bSmrg				btn_labels,
881b15a006bSmrg#endif
8829bd41f2cSmrg#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) == 0
8839bd41f2cSmrg				miPointerGetMotionEvents,
884d075918cSmrg#elif GET_ABI_MAJOR(ABI_XINPUT_VERSION) < 3
8859bd41f2cSmrg                                GetMotionHistory,
8869bd41f2cSmrg#endif
8879bd41f2cSmrg                                pMse->Ctrl,
8889bd41f2cSmrg#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) == 0
8899bd41f2cSmrg				miPointerGetMotionBufferSize()
8909bd41f2cSmrg#else
8919bd41f2cSmrg                                GetMotionHistorySize(), 2
892b15a006bSmrg#endif
893b15a006bSmrg#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 7
894b15a006bSmrg				, axes_labels
8959bd41f2cSmrg#endif
8969bd41f2cSmrg                                );
8979bd41f2cSmrg
8989bd41f2cSmrg      /* X valuator */
899d075918cSmrg#ifdef ABS_VALUATOR_AXES
900b15a006bSmrg      xf86InitValuatorAxisStruct(device, 0,
901b15a006bSmrg#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 7
902b15a006bSmrg				axes_labels[0],
903b15a006bSmrg#endif
904c4f7863aSmrg				0, 65535, 10000, 0, 10000
905c4f7863aSmrg#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 12
906c4f7863aSmrg                                , Absolute
907c4f7863aSmrg#endif
908c4f7863aSmrg                                );
909d075918cSmrg#else
910b15a006bSmrg      xf86InitValuatorAxisStruct(device, 0,
911b15a006bSmrg#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 7
912b15a006bSmrg				axes_labels[0],
913b15a006bSmrg#endif
914c4f7863aSmrg				0, -1, 1, 0, 1
915c4f7863aSmrg#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 12
916c4f7863aSmrg                                , Relative
917c4f7863aSmrg#endif
918c4f7863aSmrg                                );
919d075918cSmrg#endif
9209bd41f2cSmrg      xf86InitValuatorDefaults(device, 0);
9219bd41f2cSmrg      /* Y valuator */
922d075918cSmrg#ifdef ABS_VALUATOR_AXES
923b15a006bSmrg      xf86InitValuatorAxisStruct(device, 1,
924b15a006bSmrg#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 7
925b15a006bSmrg				axes_labels[1],
926b15a006bSmrg#endif
927c4f7863aSmrg				0, 65535, 10000, 0, 10000
928c4f7863aSmrg#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 12
929c4f7863aSmrg                                , Absolute
930c4f7863aSmrg#endif
931c4f7863aSmrg                                );
932d075918cSmrg#else
933b15a006bSmrg      xf86InitValuatorAxisStruct(device, 1,
934b15a006bSmrg#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 7
935b15a006bSmrg				axes_labels[1],
936b15a006bSmrg#endif
937c4f7863aSmrg				0, -1, 1, 0, 1
938c4f7863aSmrg#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 12
939c4f7863aSmrg                                , Relative
940c4f7863aSmrg#endif
941c4f7863aSmrg                                );
942d075918cSmrg#endif
9439bd41f2cSmrg      xf86InitValuatorDefaults(device, 1);
9449bd41f2cSmrg#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) == 0
9459bd41f2cSmrg      xf86MotionHistoryAllocate(pInfo);
9469bd41f2cSmrg#endif
9479bd41f2cSmrg
9489bd41f2cSmrg      xf86Msg(X_INFO, "VMWARE(0): VMMOUSE DEVICE_INIT\n");
9499bd41f2cSmrg#ifdef EXTMOUSEDEBUG
9509bd41f2cSmrg      xf86Msg(X_INFO, "assigning %p atom=%d name=%s\n", device, pInfo->atom,
9519bd41f2cSmrg	     pInfo->name);
9529bd41f2cSmrg#endif
9539bd41f2cSmrg      break;
9549bd41f2cSmrg
9559bd41f2cSmrg   case DEVICE_ON:
9569bd41f2cSmrg      xf86Msg(X_INFO, "VMWARE(0): VMMOUSE DEVICE_ON\n");
9579bd41f2cSmrg      pInfo->fd = xf86OpenSerial(pInfo->options);
9589bd41f2cSmrg      if (pInfo->fd == -1)
9599bd41f2cSmrg	 xf86Msg(X_WARNING, "%s: cannot open input device\n", pInfo->name);
9609bd41f2cSmrg      else {
9619bd41f2cSmrg	 pMse->buffer = XisbNew(pInfo->fd, 64);
9629bd41f2cSmrg	 if (!pMse->buffer) {
9639bd41f2cSmrg	    xf86CloseSerial(pInfo->fd);
9649bd41f2cSmrg	    pInfo->fd = -1;
9659bd41f2cSmrg	 } else {
9669bd41f2cSmrg	    VMMousePrivPtr mPriv = (VMMousePrivPtr)pMse->mousePriv;
9679bd41f2cSmrg	    if (mPriv != NULL) {
9689bd41f2cSmrg	       /*
9699bd41f2cSmrg		* enable absolute pointing device here
9709bd41f2cSmrg		*/
971d075918cSmrg	       if (!VMMouseClient_Enable()) {
9729bd41f2cSmrg		  xf86Msg(X_ERROR, "VMWARE(0): vmmouse enable failed\n");
9739bd41f2cSmrg		  mPriv->vmmouseAvailable = FALSE;
9749bd41f2cSmrg		  device->public.on = FALSE;
9759bd41f2cSmrg		  return FALSE;
9769bd41f2cSmrg	       } else {
977d075918cSmrg		  mPriv->vmmouseAvailable = TRUE;
9789bd41f2cSmrg		  xf86Msg(X_INFO, "VMWARE(0): vmmouse enabled\n");
979d075918cSmrg	       }
9809bd41f2cSmrg	    }
9819bd41f2cSmrg	    xf86FlushInput(pInfo->fd);
9829bd41f2cSmrg	    xf86AddEnabledDevice(pInfo);
9839bd41f2cSmrg	 }
9849bd41f2cSmrg      }
9859bd41f2cSmrg      pMse->lastButtons = 0;
9869bd41f2cSmrg      device->public.on = TRUE;
9879bd41f2cSmrg      FlushButtons(pMse);
988d075918cSmrg      break;
9899bd41f2cSmrg   case DEVICE_OFF:
9909bd41f2cSmrg   case DEVICE_CLOSE:
9919bd41f2cSmrg      xf86Msg(X_INFO, "VMWARE(0): VMMOUSE DEVICE_OFF/CLOSE\n");
9929bd41f2cSmrg
9939bd41f2cSmrg      if (pInfo->fd != -1) {
9949bd41f2cSmrg	 VMMousePrivPtr mPriv = (VMMousePrivPtr)pMse->mousePriv;
9959bd41f2cSmrg	 if( mPriv->vmmouseAvailable ) {
9969bd41f2cSmrg	    VMMouseClient_Disable();
997d075918cSmrg            mPriv->vmmouseAvailable = FALSE;
998d075918cSmrg            mPriv->absoluteRequested = FALSE;
9999bd41f2cSmrg	 }
1000d075918cSmrg
10019bd41f2cSmrg	 xf86RemoveEnabledDevice(pInfo);
10029bd41f2cSmrg	 if (pMse->buffer) {
10039bd41f2cSmrg	    XisbFree(pMse->buffer);
10049bd41f2cSmrg	    pMse->buffer = NULL;
10059bd41f2cSmrg	 }
10069bd41f2cSmrg	 xf86CloseSerial(pInfo->fd);
10079bd41f2cSmrg	 pInfo->fd = -1;
10089bd41f2cSmrg      }
10099bd41f2cSmrg      device->public.on = FALSE;
10109bd41f2cSmrg      usleep(300000);
10119bd41f2cSmrg      break;
10129bd41f2cSmrg
10139bd41f2cSmrg   }
10149bd41f2cSmrg
10159bd41f2cSmrg   return Success;
10169bd41f2cSmrg}
10179bd41f2cSmrg
10189bd41f2cSmrg
10199bd41f2cSmrg/*
10209bd41f2cSmrg *----------------------------------------------------------------------
10219bd41f2cSmrg *
10229bd41f2cSmrg * VMMouseReadInput --
10239bd41f2cSmrg * 	This function was called by Xserver when there is data available
10249bd41f2cSmrg *	in the input device
1025d075918cSmrg *
10269bd41f2cSmrg * Results:
10279bd41f2cSmrg * 	None
1028d075918cSmrg *
10299bd41f2cSmrg * Side effects:
10309bd41f2cSmrg * 	Input data in regular PS/2 fd was cleared
10319bd41f2cSmrg *	Real mouse data was read from the absolute pointing device
10329bd41f2cSmrg *	and posted to Xserver
1033d075918cSmrg *
10349bd41f2cSmrg *----------------------------------------------------------------------
10359bd41f2cSmrg */
10369bd41f2cSmrg
10379bd41f2cSmrgstatic void
10389bd41f2cSmrgVMMouseReadInput(InputInfoPtr pInfo)
10399bd41f2cSmrg{
10409bd41f2cSmrg   MouseDevPtr pMse;
1041d075918cSmrg   VMMousePrivPtr mPriv;
10429bd41f2cSmrg   int c;
1043d075918cSmrg   int len = 0;
10449bd41f2cSmrg
10459bd41f2cSmrg   pMse = pInfo->private;
10469bd41f2cSmrg   mPriv = pMse->mousePriv;
1047d075918cSmrg
1048d075918cSmrg   if (!mPriv->absoluteRequested) {
1049d075918cSmrg      /*
1050d075918cSmrg       * We can request for absolute mode, but it depends on
1051d075918cSmrg       * host whether it will send us absolute or relative
1052d075918cSmrg       * position.
1053d075918cSmrg       */
1054d075918cSmrg      VMMouseClient_RequestAbsolute();
1055d075918cSmrg      mPriv->absoluteRequested = TRUE;
10560da4cdccSmrg      LogMessageVerbSigSafe(X_INFO, -1, "VMWARE(0): vmmouse enable absolute mode\n");
1057d075918cSmrg   }
1058d075918cSmrg
10599bd41f2cSmrg   /*
10609bd41f2cSmrg    * First read the bytes in input device to clear the regular PS/2 fd so
1061d075918cSmrg    * we don't get called again.
10629bd41f2cSmrg    */
10639bd41f2cSmrg   /*
10649bd41f2cSmrg    * Set blocking to -1 on the first call because we know there is data to
10659bd41f2cSmrg    * read. Xisb automatically clears it after one successful read so that
10669bd41f2cSmrg    * succeeding reads are preceeded by a select with a 0 timeout to prevent
10679bd41f2cSmrg    * read from blocking indefinitely.
10689bd41f2cSmrg    */
10699bd41f2cSmrg   XisbBlockDuration(pMse->buffer, -1);
10709bd41f2cSmrg   while ((c = XisbRead(pMse->buffer)) >= 0) {
10719bd41f2cSmrg      len++;
10729bd41f2cSmrg      /*
10739bd41f2cSmrg       * regular PS packet consists of 3 bytes
1074d075918cSmrg       * We read 3 bytes to drain the PS/2 packet
10759bd41f2cSmrg       */
10769bd41f2cSmrg      if(len < 3) continue;
1077d075918cSmrg      len = 0;
10789bd41f2cSmrg      /*
10799bd41f2cSmrg       * Now get the real data from absolute pointing device
10809bd41f2cSmrg       */
10819bd41f2cSmrg      GetVMMouseMotionEvent(pInfo);
10829bd41f2cSmrg   }
10839bd41f2cSmrg   /*
10849bd41f2cSmrg    * There maybe still vmmouse data available
10859bd41f2cSmrg    */
10869bd41f2cSmrg   GetVMMouseMotionEvent(pInfo);
10879bd41f2cSmrg}
10889bd41f2cSmrg
10899bd41f2cSmrg
10909bd41f2cSmrg/*
10919bd41f2cSmrg *----------------------------------------------------------------------
10929bd41f2cSmrg *
10939bd41f2cSmrg * GetVMMouseMotionEvent --
10949bd41f2cSmrg * 	Read all the mouse data available from the absolute
10959bd41f2cSmrg * 	pointing device	and post it to the Xserver
1096d075918cSmrg *
10979bd41f2cSmrg * Results:
10989bd41f2cSmrg * 	None
1099d075918cSmrg *
11009bd41f2cSmrg * Side effects:
11019bd41f2cSmrg *	Real mouse data was read from the absolute pointing
11029bd41f2cSmrg *	device and posted to Xserver
1103d075918cSmrg *
11049bd41f2cSmrg *----------------------------------------------------------------------
11059bd41f2cSmrg */
11069bd41f2cSmrg
11079bd41f2cSmrgstatic void
11089bd41f2cSmrgGetVMMouseMotionEvent(InputInfoPtr pInfo){
11099bd41f2cSmrg   MouseDevPtr pMse;
1110d075918cSmrg   VMMousePrivPtr mPriv;
11119bd41f2cSmrg   int buttons, dx, dy, dz, dw;
11129bd41f2cSmrg   VMMOUSE_INPUT_DATA  vmmouseInput;
11139bd41f2cSmrg   int numPackets;
11149bd41f2cSmrg
1115d075918cSmrg   pMse = pInfo->private;
1116d075918cSmrg   mPriv = (VMMousePrivPtr)pMse->mousePriv;
11179bd41f2cSmrg   while((numPackets = VMMouseClient_GetInput(&vmmouseInput))){
11180da4cdccSmrg      int ps2Buttons = 0;
11199bd41f2cSmrg      if (numPackets == VMMOUSE_ERROR) {
11209bd41f2cSmrg         VMMouseClient_Disable();
11219bd41f2cSmrg         VMMouseClient_Enable();
11229bd41f2cSmrg         VMMouseClient_RequestAbsolute();
11230da4cdccSmrg         LogMessageVerbSigSafe(X_INFO, -1, "VMWARE(0): re-requesting absolute mode after reset\n");
11249bd41f2cSmrg         break;
11259bd41f2cSmrg      }
11269bd41f2cSmrg
11279bd41f2cSmrg      if(vmmouseInput.Buttons & VMMOUSE_MIDDLE_BUTTON)
11289bd41f2cSmrg	 ps2Buttons |= 0x04; 			/* Middle*/
11299bd41f2cSmrg      if(vmmouseInput.Buttons & VMMOUSE_RIGHT_BUTTON)
11309bd41f2cSmrg	 ps2Buttons |= 0x02; 			/* Right*/
11319bd41f2cSmrg      if(vmmouseInput.Buttons & VMMOUSE_LEFT_BUTTON)
11329bd41f2cSmrg	 ps2Buttons |= 0x01; 			/* Left*/
1133d075918cSmrg
11349bd41f2cSmrg      buttons = (ps2Buttons & 0x04) >> 1 |	/* Middle */
11359bd41f2cSmrg	 (ps2Buttons & 0x02) >> 1 |       	/* Right */
11369bd41f2cSmrg	 (ps2Buttons & 0x01) << 2;       	/* Left */
1137d075918cSmrg
11389bd41f2cSmrg      dx = vmmouseInput.X;
1139d075918cSmrg      dy = vmmouseInput.Y;
11409bd41f2cSmrg      dz = (char)vmmouseInput.Z;
11419bd41f2cSmrg      dw = 0;
1142d075918cSmrg      /*
1143d075918cSmrg       * Get the per package relative or absolute information.
1144d075918cSmrg       */
1145d075918cSmrg      mPriv->isCurrRelative = vmmouseInput.Flags & VMMOUSE_MOVE_RELATIVE;
11469bd41f2cSmrg      /* post an event */
11479bd41f2cSmrg      pMse->PostEvent(pInfo, buttons, dx, dy, dz, dw);
1148d075918cSmrg      mPriv->vmmousePrevInput = vmmouseInput;
11499bd41f2cSmrg   }
11509bd41f2cSmrg}
11519bd41f2cSmrg
11529bd41f2cSmrg
11539bd41f2cSmrg/*
11549bd41f2cSmrg *----------------------------------------------------------------------
11559bd41f2cSmrg *
11569bd41f2cSmrg * VMMouseControlProc --
1157d075918cSmrg *	This function is unused
11589bd41f2cSmrg *
11599bd41f2cSmrg * Results:
11609bd41f2cSmrg * 	None
1161d075918cSmrg *
11629bd41f2cSmrg * Side effects:
11639bd41f2cSmrg * 	None
11649bd41f2cSmrg *
11659bd41f2cSmrg *----------------------------------------------------------------------
11669bd41f2cSmrg */
11679bd41f2cSmrg
11689bd41f2cSmrgstatic int
1169c4f7863aSmrgVMMouseControlProc(InputInfoPtr pInfo, xDeviceCtl * control)
11709bd41f2cSmrg{
11719bd41f2cSmrg   xf86Msg(X_INFO, "VMWARE(0): VMMouseControlProc\n");
11729bd41f2cSmrg   return (Success);
11739bd41f2cSmrg}
11749bd41f2cSmrg
11759bd41f2cSmrg
11769bd41f2cSmrg/*
11779bd41f2cSmrg *----------------------------------------------------------------------
11789bd41f2cSmrg *
11799bd41f2cSmrg *  VMMouseCloseProc --
1180d075918cSmrg *	This function is unused
11819bd41f2cSmrg *
11829bd41f2cSmrg * Results:
11839bd41f2cSmrg * 	None
1184d075918cSmrg *
11859bd41f2cSmrg * Side effects:
11869bd41f2cSmrg * 	None
11879bd41f2cSmrg *
11889bd41f2cSmrg *----------------------------------------------------------------------
11899bd41f2cSmrg */
11909bd41f2cSmrg
1191c4f7863aSmrg#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) < 12
11929bd41f2cSmrgstatic void
1193c4f7863aSmrgVMMouseCloseProc(InputInfoPtr pInfo)
11949bd41f2cSmrg{
11959bd41f2cSmrg   xf86Msg(X_INFO, "VMWARE(0): VMMouseCloseProc\n");
11969bd41f2cSmrg}
1197c4f7863aSmrg#endif
11989bd41f2cSmrg
11999bd41f2cSmrg
12009bd41f2cSmrg/*
12019bd41f2cSmrg *----------------------------------------------------------------------
12029bd41f2cSmrg *
12039bd41f2cSmrg *  VMMouseSwitchProc --
1204d075918cSmrg *	This function is unused
12059bd41f2cSmrg *
12069bd41f2cSmrg * Results:
12079bd41f2cSmrg * 	None
1208d075918cSmrg *
12099bd41f2cSmrg * Side effects:
12109bd41f2cSmrg * 	None
12119bd41f2cSmrg *
12129bd41f2cSmrg *----------------------------------------------------------------------
12139bd41f2cSmrg */
12149bd41f2cSmrg
12159bd41f2cSmrgstatic int
12169bd41f2cSmrgVMMouseSwitchMode(ClientPtr client, DeviceIntPtr dev, int mode)
12179bd41f2cSmrg{
12189bd41f2cSmrg   xf86Msg(X_INFO, "VMWARE(0): VMMouseSwitchMode\n");
12199bd41f2cSmrg   return (Success);
12209bd41f2cSmrg}
12219bd41f2cSmrg
12229bd41f2cSmrg
12239bd41f2cSmrg/*
12249bd41f2cSmrg *----------------------------------------------------------------------
12259bd41f2cSmrg *
12269bd41f2cSmrg * VMMouseConvertProc  --
12279bd41f2cSmrg * 	This function was called by Xserver to convert valuators to X and Y
1228d075918cSmrg *
12299bd41f2cSmrg * Results:
12309bd41f2cSmrg * 	TRUE
1231d075918cSmrg *
12329bd41f2cSmrg * Side effects:
12339bd41f2cSmrg * 	X and Y was converted according to current Screen dimension
1234d075918cSmrg *
12359bd41f2cSmrg *----------------------------------------------------------------------
12369bd41f2cSmrg */
12379bd41f2cSmrg
1238c4f7863aSmrg#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) < 12
12399bd41f2cSmrgstatic Bool
12409bd41f2cSmrgVMMouseConvertProc(InputInfoPtr pInfo, int first, int num, int v0, int v1, int v2,
12419bd41f2cSmrg	     int v3, int v4, int v5, int *x, int *y)
12429bd41f2cSmrg{
12439bd41f2cSmrg   MouseDevPtr pMse;
12449bd41f2cSmrg   VMMousePrivPtr mPriv;
12459bd41f2cSmrg   double factorX, factorY;
12469bd41f2cSmrg
12479bd41f2cSmrg   pMse = pInfo->private;
12489bd41f2cSmrg   mPriv = pMse->mousePriv;
12499bd41f2cSmrg
12509bd41f2cSmrg   if (first != 0 || num != 2)
12519bd41f2cSmrg      return FALSE;
1252d075918cSmrg
1253d075918cSmrg   if(mPriv->isCurrRelative) {
12549bd41f2cSmrg      *x = v0;
12559bd41f2cSmrg      *y = v1;
12569bd41f2cSmrg   } else {
12579bd41f2cSmrg      factorX = ((double) screenInfo.screens[mPriv->screenNum]->width) / (double) 65535;
12589bd41f2cSmrg      factorY = ((double) screenInfo.screens[mPriv->screenNum]->height) / (double) 65535;
1259d075918cSmrg
12609bd41f2cSmrg      *x = v0 * factorX + 0.5;
12619bd41f2cSmrg      *y = v1 * factorY + 0.5;
1262d075918cSmrg
12639bd41f2cSmrg      if (mPriv->screenNum != -1) {
12649bd41f2cSmrg	 xf86XInputSetScreen(pInfo, mPriv->screenNum, *x, *y);
12659bd41f2cSmrg      }
12669bd41f2cSmrg   }
12679bd41f2cSmrg   return TRUE;
12689bd41f2cSmrg}
1269c4f7863aSmrg#endif
12709bd41f2cSmrg
12719bd41f2cSmrg
12729bd41f2cSmrg#ifdef XFree86LOADER
12739bd41f2cSmrg
12749bd41f2cSmrg/*
12759bd41f2cSmrg *----------------------------------------------------------------------
12769bd41f2cSmrg *
12779bd41f2cSmrg * VMMouseUnplug  --
12789bd41f2cSmrg * 	This function was called by Xserver when unplug
1279d075918cSmrg *
12809bd41f2cSmrg * Results:
12819bd41f2cSmrg * 	None
1282d075918cSmrg *
12839bd41f2cSmrg * Side effects:
12849bd41f2cSmrg * 	None
1285d075918cSmrg *
12869bd41f2cSmrg *----------------------------------------------------------------------
12879bd41f2cSmrg */
12889bd41f2cSmrg
12899bd41f2cSmrgstatic void
12909bd41f2cSmrgVMMouseUnplug(pointer p)
12919bd41f2cSmrg{
12929bd41f2cSmrg   xf86Msg(X_INFO, "VMWARE(0): VMMouseUnplug\n");
12939bd41f2cSmrg}
12949bd41f2cSmrg
12959bd41f2cSmrg
12969bd41f2cSmrg/*
12979bd41f2cSmrg *----------------------------------------------------------------------
12989bd41f2cSmrg *
12999bd41f2cSmrg * VMMousePlug  --
13009bd41f2cSmrg * 	This function was called when Xserver load vmmouse module. It will
1301d075918cSmrg * 	integrate the  module infto the XFree86 loader architecutre.
1302d075918cSmrg *
13039bd41f2cSmrg * Results:
13049bd41f2cSmrg * 	TRUE
1305d075918cSmrg *
13069bd41f2cSmrg * Side effects:
1307d075918cSmrg * 	Regular mouse module was loaded as a submodule. In case
13089bd41f2cSmrg * 	absolute pointing device is not available, we can always fall back
13099bd41f2cSmrg *	to the regular mouse module
1310d075918cSmrg *
13119bd41f2cSmrg *----------------------------------------------------------------------
13129bd41f2cSmrg */
13139bd41f2cSmrg
13149bd41f2cSmrgstatic pointer
13159bd41f2cSmrgVMMousePlug(pointer	module,
13169bd41f2cSmrg	    pointer	options,
13179bd41f2cSmrg	    int		*errmaj,
13189bd41f2cSmrg	    int		*errmin)
13199bd41f2cSmrg{
13209bd41f2cSmrg   static Bool Initialised = FALSE;
13219bd41f2cSmrg
13229418810dSmrg#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) < 7
13239bd41f2cSmrg   xf86LoaderReqSymLists(reqSymbols, NULL);
13249418810dSmrg#endif
1325d075918cSmrg
1326d075918cSmrg   if (!Initialised)
13279bd41f2cSmrg      Initialised = TRUE;
13289bd41f2cSmrg
13299bd41f2cSmrg   xf86Msg(X_INFO, "VMWARE(0): VMMOUSE module was loaded\n");
13309bd41f2cSmrg   xf86AddInputDriver(&VMMOUSE, module, 0);
13319bd41f2cSmrg
1332b15a006bSmrg#ifndef NO_MOUSE_MODULE
1333b15a006bSmrg{
1334b15a006bSmrg   char *name;
13359bd41f2cSmrg   /*
13369bd41f2cSmrg    * Load the normal mouse module as submodule
13379bd41f2cSmrg    * If we fail in PreInit later, this allows us to fall back to normal mouse module
13389bd41f2cSmrg    */
13399bd41f2cSmrg#ifndef NORMALISE_MODULE_NAME
13409bd41f2cSmrg   name = xstrdup("mouse");
13419bd41f2cSmrg#else
13429bd41f2cSmrg   /* Normalise the module name */
13439bd41f2cSmrg   name = xf86NormalizeName("mouse");
13449bd41f2cSmrg#endif
13459bd41f2cSmrg
13469bd41f2cSmrg   if (!LoadSubModule(module, name, NULL, NULL, NULL, NULL, errmaj, errmin)) {
13479bd41f2cSmrg      LoaderErrorMsg(NULL, name, *errmaj, *errmin);
13489bd41f2cSmrg   }
1349c4f7863aSmrg   free(name);
1350b15a006bSmrg}
1351b15a006bSmrg#endif
1352d075918cSmrg
13539bd41f2cSmrg   return module;
13549bd41f2cSmrg}
13559bd41f2cSmrg
13569bd41f2cSmrgstatic XF86ModuleVersionInfo VMMouseVersionRec = {
13579bd41f2cSmrg   "vmmouse",
13589bd41f2cSmrg   MODULEVENDORSTRING,
13599bd41f2cSmrg   MODINFOSTRING1,
13609bd41f2cSmrg   MODINFOSTRING2,
13619bd41f2cSmrg   XORG_VERSION_CURRENT,
13629418810dSmrg   PACKAGE_VERSION_MAJOR, PACKAGE_VERSION_MINOR, PACKAGE_VERSION_PATCHLEVEL,
13639bd41f2cSmrg   ABI_CLASS_XINPUT,
13649bd41f2cSmrg   ABI_XINPUT_VERSION,
13659bd41f2cSmrg   MOD_CLASS_XINPUT,
13669bd41f2cSmrg   {0, 0, 0, 0}		/* signature, to be patched into the file by a tool */
13679bd41f2cSmrg};
13689bd41f2cSmrg
13699bd41f2cSmrg/*
13709bd41f2cSmrg * The variable contains the necessary information to load and initialize the module
13719bd41f2cSmrg */
1372b15a006bSmrg_X_EXPORT XF86ModuleData vmmouseModuleData = {
13739bd41f2cSmrg   &VMMouseVersionRec,
13749bd41f2cSmrg   VMMousePlug,
13759bd41f2cSmrg   VMMouseUnplug
13769bd41f2cSmrg};
13779bd41f2cSmrg#endif /* XFree86LOADER */
1378