vboxmouse_15.c revision 41f7b9cd03b9ea0b79ed9d9f81697bcf6bd08aa1
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync/** @file
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync * VirtualBox X11 Guest Additions, mouse driver for X.Org server 1.5
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync */
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync/*
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync * Copyright (C) 2006-2007 Oracle Corporation
dc0a54940789f994c84390cb4a9f03da0b492285vboxsync *
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync * available from http://www.virtualbox.org. This file is free software;
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync * you can redistribute it and/or modify it under the terms of the GNU
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync * General Public License (GPL) as published by the Free Software
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync * --------------------------------------------------------------------
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync *
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync * This code is based on evdev.c from X.Org with the following copyright
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync * and permission notice:
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync *
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync * Copyright © 2004-2008 Red Hat, Inc.
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync *
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync * Permission to use, copy, modify, distribute, and sell this software
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync * and its documentation for any purpose is hereby granted without
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync * fee, provided that the above copyright notice appear in all copies
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync * and that both that copyright notice and this permission notice
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync * appear in supporting documentation, and that the name of Red Hat
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync * not be used in advertising or publicity pertaining to distribution
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync * of the software without specific, written prior permission. Red
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync * Hat makes no representations about the suitability of this software
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync * for any purpose. It is provided "as is" without express or implied
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync * warranty.
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync *
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync * THE AUTHORS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync * NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync *
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync * Authors:
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync * Kristian Høgsberg (krh@redhat.com)
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync * Adam Jackson (ajax@redhat.com)
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync */
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync#include <VBox/VMMDev.h>
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync#include <VBox/VBoxGuestLib.h>
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync#include <iprt/err.h>
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync#include <xf86.h>
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync#include <xf86Xinput.h>
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync#include <mipointer.h>
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync#include <xf86Module.h>
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync#ifdef VBOX_GUESTR3XF86MOD
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync# define _X_EXPORT
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync#else
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync# include <errno.h>
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync# include <fcntl.h>
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync# include <unistd.h>
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync#endif
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync#include "product-generated.h"
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsyncenum
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync{
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync /** The minumum value our device can return */
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync RANGE_MIN = 0,
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync /** The maximum value our device can return */
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync RANGE_MAX = 0xFFFF
dc0a54940789f994c84390cb4a9f03da0b492285vboxsync};
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsyncstatic void
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsyncVBoxReadInput(InputInfoPtr pInfo)
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync{
dc0a54940789f994c84390cb4a9f03da0b492285vboxsync uint32_t cx, cy, fFeatures;
dc0a54940789f994c84390cb4a9f03da0b492285vboxsync
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync /* Read a byte from the device to acknowledge the event */
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync char c;
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync read(pInfo->fd, &c, 1);
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync /* The first test here is a workaround for an apparent bug in Xorg Server 1.5 */
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync if (
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) < 2
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync miPointerCurrentScreen() != NULL
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync#else
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync miPointerGetScreen(pInfo->dev) != NULL
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync#endif
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync && RT_SUCCESS(VbglR3GetMouseStatus(&fFeatures, &cx, &cy))
dc0a54940789f994c84390cb4a9f03da0b492285vboxsync && (fFeatures & VMMDEV_MOUSE_HOST_WANTS_ABSOLUTE))
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync {
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync#if ABI_XINPUT_VERSION == SET_ABI_VERSION(2, 0)
dc0a54940789f994c84390cb4a9f03da0b492285vboxsync /* Bug in the 1.4 X server series - conversion_proc was no longer
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync * called, but the server didn't yet do the conversion itself. */
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync cx = (cx * screenInfo.screens[0]->width) / 65535;
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync cy = (cy * screenInfo.screens[0]->height) / 65535;
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync#endif
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync /* send absolute movement */
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync xf86PostMotionEvent(pInfo->dev, 1, 0, 2, cx, cy);
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync }
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync}
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsyncstatic void
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsyncVBoxPtrCtrlProc(DeviceIntPtr device, PtrCtrl *ctrl)
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync{
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync /* Nothing to do, dix handles all settings */
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync}
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsyncstatic int
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsyncVBoxInit(DeviceIntPtr device)
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync{
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync CARD8 map[2] = { 0, 1 };
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync Atom axis_labels[2] = { 0, 0 };
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync Atom button_labels[2] = { 0, 0 };
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync if (!InitPointerDeviceStruct((DevicePtr)device, map, 2,
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 7
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync button_labels,
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync#endif
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) < 2
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync miPointerGetMotionEvents, VBoxPtrCtrlProc,
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync miPointerGetMotionBufferSize()
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync#elif GET_ABI_MAJOR(ABI_XINPUT_VERSION) < 3
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync GetMotionHistory, VBoxPtrCtrlProc,
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync GetMotionHistorySize(), 2 /* Number of axes */
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync#elif GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 3
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync VBoxPtrCtrlProc, GetMotionHistorySize(),
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync 2 /* Number of axes */
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync#else
dc0a54940789f994c84390cb4a9f03da0b492285vboxsync# error Unsupported version of X.Org
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync#endif
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 7
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync , axis_labels
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync#endif
dc0a54940789f994c84390cb4a9f03da0b492285vboxsync ))
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync return !Success;
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync
4e47bb772df0d04d1ded3e06354de547d52e2d06vboxsync /* Tell the server about the range of axis values we report */
4e47bb772df0d04d1ded3e06354de547d52e2d06vboxsync#if ABI_XINPUT_VERSION <= SET_ABI_VERSION(2, 0)
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync xf86InitValuatorAxisStruct(device, 0, 0, -1, 1, 0, 1);
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync xf86InitValuatorAxisStruct(device, 1, 0, -1, 1, 0, 1);
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync#else
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync xf86InitValuatorAxisStruct(device, 0,
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync# if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 7
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync axis_labels[0],
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync# endif
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync RANGE_MIN /* min X */, RANGE_MAX /* max X */,
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync 10000, 0, 10000
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync# if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 12
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync , Absolute
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync# endif
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync );
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync xf86InitValuatorAxisStruct(device, 1,
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync# if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 7
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync axis_labels[1],
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync# endif
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync RANGE_MIN /* min Y */, RANGE_MAX /* max Y */,
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync 10000, 0, 10000
dc0a54940789f994c84390cb4a9f03da0b492285vboxsync# if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 12
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync , Absolute
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync# endif
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync );
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync#endif
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync xf86InitValuatorDefaults(device, 0);
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync xf86InitValuatorDefaults(device, 1);
7f559fbdfc27f13c8448645ace787c4c1ddefd13vboxsync xf86MotionHistoryAllocate(device->public.devicePrivate);
7f559fbdfc27f13c8448645ace787c4c1ddefd13vboxsync
dc0a54940789f994c84390cb4a9f03da0b492285vboxsync return Success;
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync}
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync
dc0a54940789f994c84390cb4a9f03da0b492285vboxsyncstatic int
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsyncVBoxProc(DeviceIntPtr device, int what)
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync{
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync InputInfoPtr pInfo;
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync int rc, xrc;
c1bf14b7bd52ba68e91e056d3f054c053f944164vboxsync uint32_t fFeatures = 0;
pInfo = device->public.devicePrivate;
switch (what)
{
case DEVICE_INIT:
xrc = VBoxInit(device);
if (xrc != Success) {
VbglR3Term();
return xrc;
}
break;
case DEVICE_ON:
xf86Msg(X_INFO, "%s: On.\n", pInfo->name);
if (device->public.on)
break;
/* Tell the host that we want absolute co-ordinates */
rc = VbglR3GetMouseStatus(&fFeatures, NULL, NULL);
if (RT_SUCCESS(rc))
rc = VbglR3SetMouseStatus( fFeatures
| VMMDEV_MOUSE_GUEST_CAN_ABSOLUTE
| VMMDEV_MOUSE_NEW_PROTOCOL);
if (!RT_SUCCESS(rc)) {
xf86Msg(X_ERROR, "%s: Failed to switch guest mouse into absolute mode\n",
pInfo->name);
return !Success;
}
xf86AddEnabledDevice(pInfo);
device->public.on = TRUE;
break;
case DEVICE_OFF:
xf86Msg(X_INFO, "%s: Off.\n", pInfo->name);
rc = VbglR3GetMouseStatus(&fFeatures, NULL, NULL);
if (RT_SUCCESS(rc))
rc = VbglR3SetMouseStatus( fFeatures
& ~VMMDEV_MOUSE_GUEST_CAN_ABSOLUTE
& ~VMMDEV_MOUSE_NEW_PROTOCOL);
xf86RemoveEnabledDevice(pInfo);
device->public.on = FALSE;
break;
case DEVICE_CLOSE:
VbglR3Term();
xf86Msg(X_INFO, "%s: Close\n", pInfo->name);
break;
default:
return BadValue;
}
return Success;
}
static int
VBoxProbe(InputInfoPtr pInfo)
{
int rc = VbglR3Init();
if (!RT_SUCCESS(rc)) {
xf86Msg(X_ERROR, "%s: Failed to open the VirtualBox device (error %d)\n",
pInfo->name, rc);
return BadMatch;
}
return Success;
}
static Bool
VBoxConvert(InputInfoPtr pInfo, int first, int num, int v0, int v1, int v2,
int v3, int v4, int v5, int *x, int *y)
{
if (first == 0) {
*x = xf86ScaleAxis(v0, 0, screenInfo.screens[0]->width, 0, 65536);
*y = xf86ScaleAxis(v1, 0, screenInfo.screens[0]->height, 0, 65536);
return TRUE;
} else
return FALSE;
}
static int
VBoxPreInitInfo(InputDriverPtr drv, InputInfoPtr pInfo, int flags)
{
const char *device;
int rc;
/* Initialise the InputInfoRec. */
pInfo->device_control = VBoxProc;
pInfo->read_input = VBoxReadInput;
/* Unlike evdev, we set this unconditionally, as we don't handle keyboards. */
pInfo->type_name = XI_MOUSE;
pInfo->flags |= XI86_ALWAYS_CORE;
device = xf86SetStrOption(pInfo->options, "Device",
"/dev/vboxguest");
xf86Msg(X_CONFIG, "%s: Device: \"%s\"\n", pInfo->name, device);
do {
pInfo->fd = open(device, O_RDWR, 0);
}
while (pInfo->fd < 0 && errno == EINTR);
if (pInfo->fd < 0) {
xf86Msg(X_ERROR, "Unable to open VirtualBox device \"%s\".\n", device);
return BadMatch;
}
rc = VBoxProbe(pInfo);
if (rc != Success)
return rc;
return Success;
}
#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) < 12
static InputInfoPtr
VBoxPreInit(InputDriverPtr drv, IDevPtr dev, int flags)
{
InputInfoPtr pInfo;
const char *device;
if (!(pInfo = xf86AllocateInput(drv, 0)))
return NULL;
/* Initialise the InputInfoRec. */
pInfo->name = dev->identifier;
pInfo->conf_idev = dev;
pInfo->conversion_proc = VBoxConvert;
pInfo->flags = XI86_POINTER_CAPABLE | XI86_SEND_DRAG_EVENTS;
xf86CollectInputOptions(pInfo, NULL, NULL);
xf86ProcessCommonOptions(pInfo, pInfo->options);
if (VBoxPreInitInfo(drv, pInfo, flags) != Success) {
xf86DeleteInput(pInfo, 0);
return NULL;
}
pInfo->flags |= XI86_CONFIGURED;
return pInfo;
}
#endif
_X_EXPORT InputDriverRec VBOXMOUSE = {
1,
"vboxmouse",
NULL,
#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) < 12
VBoxPreInit,
#else
VBoxPreInitInfo,
#endif
NULL,
NULL,
0
};
static pointer
VBoxPlug(pointer module,
pointer options,
int *errmaj,
int *errmin)
{
xf86AddInputDriver(&VBOXMOUSE, module, 0);
xf86Msg(X_CONFIG, "Load address of symbol \"VBOXMOUSE\" is %p\n",
(void *)&VBOXMOUSE);
return module;
}
static XF86ModuleVersionInfo VBoxVersionRec =
{
"vboxmouse",
VBOX_VENDOR,
MODINFOSTRING1,
MODINFOSTRING2,
0, /* Missing from SDK: XORG_VERSION_CURRENT, */
1, 0, 0,
ABI_CLASS_XINPUT,
ABI_XINPUT_VERSION,
MOD_CLASS_XINPUT,
{0, 0, 0, 0}
};
_X_EXPORT XF86ModuleData vboxmouseModuleData =
{
&VBoxVersionRec,
VBoxPlug,
NULL
};