summaryrefslogtreecommitdiffstats
path: root/src/VBox/Additions/x11/vboxmouse
diff options
context:
space:
mode:
Diffstat (limited to 'src/VBox/Additions/x11/vboxmouse')
-rw-r--r--src/VBox/Additions/x11/vboxmouse/Makefile.kmk296
-rw-r--r--src/VBox/Additions/x11/vboxmouse/vboxmouse.c374
2 files changed, 670 insertions, 0 deletions
diff --git a/src/VBox/Additions/x11/vboxmouse/Makefile.kmk b/src/VBox/Additions/x11/vboxmouse/Makefile.kmk
new file mode 100644
index 00000000..bebc3234
--- /dev/null
+++ b/src/VBox/Additions/x11/vboxmouse/Makefile.kmk
@@ -0,0 +1,296 @@
+# $Id: Makefile.kmk $
+## @file
+# Sub-Makefile for the VBox Additions XFree86 and X.org mouse drivers.
+#
+
+#
+# Copyright (C) 2006-2023 Oracle and/or its affiliates.
+#
+# This file is part of VirtualBox base platform packages, as
+# available from https://www.virtualbox.org.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation, in version 3 of the
+# License.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, see <https://www.gnu.org/licenses>.
+#
+# SPDX-License-Identifier: GPL-3.0-only
+#
+
+SUB_DEPTH = ../../../../..
+include $(KBUILD_PATH)/subheader.kmk
+
+vboxmouse_xorg_INCS = \
+ $(VBOX_PATH_X11_ROOT)/inputproto-1.9.99.902 \
+ $(VBOX_PATH_X11_ROOT)/libpciaccess-0.10.8 \
+ $(VBOX_PATH_X11_ROOT)/pixman-0.40.0 \
+ $(VBOX_PATH_X11_ROOT)/xextproto-7.1.1 \
+ $(VBOX_PATH_X11_ROOT)/xproto-7.0.31
+
+#
+# vboxmouse_drv
+#
+if1of ($(KBUILD_TARGET), linux)
+ SYSMODS += vboxmouse_drv
+ vboxmouse_drv_TEMPLATE = VBoxGuestR3XFree86Mod
+ vboxmouse_drv_DEFS.linux = linux
+ vboxmouse_drv_DEFS.x86 += __i386__
+ # This one has to be defined when building server code on systems where
+ # unsigned long is 64bits
+ vboxmouse_drv_DEFS.amd64 += _XSERVER64
+ vboxmouse_drv_DEFS += \
+ _POSIX_C_SOURCE=199309L _POSIX_SOURCE _XOPEN_SOURCE _DEFAULT_SOURCE \
+ _BSD_SOURCE _SVID_SOURCE _GNU_SOURCE SHAPE XINPUT XKB LBX XAPPGROUP \
+ XCSECURITY TOGCUP XF86BIGFONT DPMSExtension PIXPRIV PANORAMIX RENDER \
+ GCCUSESGAS AVOID_GLYPHBLT PIXPRIV SINGLEDEPTH XFreeXDGA XvExtension \
+ XFree86LOADER XFree86Server XF86VIDMODE XvMCExtension SMART_SCHEDULE \
+ BUILDDEBUG X_BYTE_ORDER=X_LITTLE_ENDIAN DNDEBUG FUNCPROTO=15 NARROWPROTO \
+ IN_MODULE XFree86Module PNP_MOUSE IN_XF86_MODULE
+ vboxmouse_drv_INCS := \
+ $(VBOX_PATH_X11_ROOT)/XFree86-4.3 \
+ $(VBOX_PATH_X11_ROOT)/XFree86-4.3/X11 \
+ $(VBOX_PATH_X11_ROOT)/XFree86-4.3/X11/extensions \
+ $(VBOX_PATH_X11_ROOT)/XFree86-4.3/Xserver \
+ $(PATH_SUB_CURRENT)
+ vboxmouse_drv_SOURCES = \
+ vboxmouse.c
+ # Any global symbols in the driver object files will be added to XFree86's
+ # symbol table, which can cause problems if we e.g. define a symbol in two
+ # modules.
+ vboxmouse_drv_POST_CMDS = \
+ objcopy --keep-global-symbol vboxmouseModuleData $(out) $(out)-objcopy$$(NLTAB) \
+ $(MV) -f $(out)-objcopy $(out)
+endif
+
+
+#
+# vboxmouse_drv_70
+#
+DLLS += vboxmouse_drv_70
+vboxmouse_drv_70_TEMPLATE = VBoxGuestR3XOrgMod
+vboxmouse_drv_70_DEFS = \
+ XFree86Server IN_MODULE XFree86Module XFree86LOADER XINPUT XORG_7X IN_XF86_MODULE DONT_DEFINE_WRAPPERS NO_ANSIC
+vboxmouse_drv_70_INCS := \
+ $(vboxmouse_xorg_INCS) \
+ $(VBOX_PATH_X11_ROOT)/xorg-server-1.0.1 \
+ $(PATH_SUB_CURRENT)
+vboxmouse_drv_70_SOURCES = \
+ vboxmouse.c
+
+
+#
+# vboxmouse_drv_71
+#
+DLLS += vboxmouse_drv_71
+vboxmouse_drv_71_TEMPLATE = VBoxGuestR3XOrgMod
+vboxmouse_drv_71_DEFS := $(vboxmouse_drv_70_DEFS) NO_ANSIC
+vboxmouse_drv_71_INCS := \
+ $(vboxmouse_xorg_INCS) \
+ $(VBOX_PATH_X11_ROOT)/xorg-server-1.1.0 \
+ $(PATH_SUB_CURRENT)
+vboxmouse_drv_71_SOURCES = \
+ vboxmouse.c
+
+
+#
+# vboxmouse_drv_13
+#
+DLLS += vboxmouse_drv_13
+vboxmouse_drv_13_TEMPLATE = VBoxGuestR3XOrgMod
+vboxmouse_drv_13_DEFS := $(vboxmouse_drv_70_DEFS) NO_ANSIC
+vboxmouse_drv_13_INCS := \
+ $(vboxmouse_xorg_INCS) \
+ $(VBOX_PATH_X11_ROOT)/xorg-server-1.3.0.0 \
+ $(PATH_SUB_CURRENT)
+vboxmouse_drv_13_SOURCES = \
+ vboxmouse.c
+
+
+#
+# vboxmouse_drv_14
+#
+DLLS += vboxmouse_drv_14
+vboxmouse_drv_14_TEMPLATE = VBoxGuestR3XOrgMod
+vboxmouse_drv_14_DEFS := $(vboxmouse_drv_70_DEFS) NO_ANSIC
+vboxmouse_drv_14_INCS := \
+ $(vboxmouse_xorg_INCS) \
+ $(VBOX_PATH_X11_ROOT)/xorg-server-1.4.2 \
+ $(PATH_SUB_CURRENT)
+vboxmouse_drv_14_SOURCES = \
+ vboxmouse.c
+
+
+#
+# vboxmouse_drv_15
+#
+DLLS += vboxmouse_drv_15
+vboxmouse_drv_15_TEMPLATE = VBoxGuestR3XOrgMod
+vboxmouse_drv_15_DEFS := $(vboxmouse_drv_70_DEFS) NO_ANSIC
+vboxmouse_drv_15_INCS := \
+ $(vboxmouse_xorg_INCS) \
+ $(VBOX_PATH_X11_ROOT)/xorg-server-1.5.3 \
+ $(PATH_SUB_CURRENT)
+vboxmouse_drv_15_SOURCES = \
+ vboxmouse.c
+
+
+#
+# vboxmouse_drv_16
+#
+DLLS += vboxmouse_drv_16
+vboxmouse_drv_16_TEMPLATE = VBoxGuestR3XOrgMod
+vboxmouse_drv_16_DEFS := $(vboxmouse_drv_70_DEFS) NO_ANSIC
+vboxmouse_drv_16_INCS := \
+ $(vboxmouse_xorg_INCS) \
+ $(VBOX_PATH_X11_ROOT)/xorg-server-1.6.5 \
+ $(PATH_SUB_CURRENT)
+vboxmouse_drv_16_SOURCES = \
+ vboxmouse.c
+
+
+ifneq ($(KBUILD_TARGET),linux)
+
+ #
+ # vboxmouse_drv_17
+ #
+ DLLS += vboxmouse_drv_17
+ vboxmouse_drv_17_TEMPLATE = VBoxGuestR3XOrgMod
+ vboxmouse_drv_17_DEFS := $(vboxmouse_drv_70_DEFS) NO_ANSIC
+ vboxmouse_drv_17_INCS := \
+ $(vboxmouse_xorg_INCS) \
+ $(VBOX_PATH_X11_ROOT)/xorg-server-1.7.7 \
+ $(PATH_SUB_CURRENT)
+ vboxmouse_drv_17_SOURCES = \
+ vboxmouse.c
+
+
+ #
+ # vboxmouse_drv_18
+ #
+ DLLS += vboxmouse_drv_18
+ vboxmouse_drv_18_TEMPLATE = VBoxGuestR3XOrgMod
+ vboxmouse_drv_18_DEFS := $(vboxmouse_drv_70_DEFS) NO_ANSIC
+ vboxmouse_drv_18_INCS := \
+ $(vboxmouse_xorg_INCS) \
+ $(VBOX_PATH_X11_ROOT)/xorg-server-1.8.0 \
+ $(PATH_SUB_CURRENT)
+ vboxmouse_drv_18_SOURCES = \
+ vboxmouse.c
+
+
+ #
+ # vboxmouse_drv_19
+ #
+ DLLS += vboxmouse_drv_19
+ vboxmouse_drv_19_TEMPLATE = VBoxGuestR3XOrgMod
+ vboxmouse_drv_19_DEFS := $(vboxmouse_drv_70_DEFS) NO_ANSIC
+ vboxmouse_drv_19_INCS := \
+ $(vboxmouse_xorg_INCS) \
+ $(VBOX_PATH_X11_ROOT)/xorg-server-1.9.0 \
+ $(PATH_SUB_CURRENT)
+ vboxmouse_drv_19_SOURCES = \
+ vboxmouse.c
+
+
+ #
+ # vboxmouse_drv_110
+ #
+ DLLS += vboxmouse_drv_110
+ vboxmouse_drv_110_TEMPLATE = VBoxGuestR3XOrgMod
+ vboxmouse_drv_110_DEFS := $(vboxmouse_drv_70_DEFS) NO_ANSIC
+ vboxmouse_drv_110_INCS := \
+ $(vboxmouse_xorg_INCS) \
+ $(VBOX_PATH_X11_ROOT)/xorg-server-1.10.0 \
+ $(PATH_SUB_CURRENT)
+ vboxmouse_drv_110_SOURCES = \
+ vboxmouse.c
+
+ DLLS += vboxmouse_drv_111
+ vboxmouse_drv_111_TEMPLATE = VBoxGuestR3XOrgMod
+ vboxmouse_drv_111_DEFS := $(vboxmouse_drv_70_DEFS) NO_ANSIC
+ vboxmouse_drv_111_INCS := \
+ $(vboxmouse_xorg_INCS) \
+ $(VBOX_PATH_X11_ROOT)/xorg-server-1.11.0 \
+ $(PATH_SUB_CURRENT)
+ vboxmouse_drv_111_SOURCES = \
+ vboxmouse.c
+
+ DLLS += vboxmouse_drv_112
+ vboxmouse_drv_112_TEMPLATE = VBoxGuestR3XOrgMod
+ vboxmouse_drv_112_DEFS := $(vboxmouse_drv_70_DEFS) NO_ANSIC
+ vboxmouse_drv_112_INCS := \
+ $(vboxmouse_xorg_INCS) \
+ $(VBOX_PATH_X11_ROOT)/xorg-server-1.12.0 \
+ $(PATH_SUB_CURRENT)
+ vboxmouse_drv_112_SOURCES = \
+ vboxmouse.c
+
+endif # neq ($(KBUILD_TARGET),linux)
+
+
+ifdef VBOX_USE_SYSTEM_XORG_HEADERS
+ # As vboxmouse_drv is not needed at all for X.Org Server 1.7 and later do not
+ # build it in this case.
+ DLLS := $(filter-out vboxmouse_drv_%,$(DLLS))
+ SYSMODS := $(filter-out vboxmouse_drv%,$(SYSMODS))
+endif
+
+
+# Check the undefined symbols in the X.Org modules against lists of allowed
+# symbols. Not very elegant, but it will catch problems early.
+
+ifdef VBOX_WITH_TESTCASES
+ # ifndef VBOX_ONLY_ADDITIONS
+ ifndef VBOX_USE_SYSTEM_XORG_HEADERS
+ ifeq ($(KBUILD_TARGET),linux)
+ ifeq ($(KBUILD_HOST_ARCH),$(KBUILD_TARGET_ARCH))
+ ifndef VBOX_ONLY_SDK
+ VBOXMOUSE_SRC_PATH := $(PATH_SUB_CURRENT)
+
+ ifeq ($(KBUILD_TARGET),linux)
+ TESTING += $(vboxmouse_drv_0_OUTDIR)/tstvboxmouse68.run
+ OTHERS += $(vboxmouse_drv_0_OUTDIR)/tstvboxmouse68.run
+ $$(vboxmouse_drv_0_OUTDIR)/tstvboxmouse68.run: $$(vboxmouse_drv_1_STAGE_TARGET)
+ $(QUIET)$(call MSG_L1,Checking for unresolved symbols in $<)
+ $(QUIET)/bin/sh $(PATH_ROOT)/src/bldprogs/checkUndefined.sh $(KBUILD_HOST) \
+ "$(vboxmouse_drv_1_STAGE_TARGET)" --static "$(VBOXMOUSE_SRC_PATH)/../undefined_xfree86" "$(VBOXMOUSE_SRC_PATH)/../undefined_xfree86_modules"
+ $(QUIET)$(APPEND) -t "$@" "done"
+ endif
+
+ ##
+ # Using the extra expansion to replace $(ver) before eval, thus everything
+ # else needs escaped dollars.
+ define def_vboxmouse_test
+ TESTING += $$(vboxmouse_drv$(ver)_0_OUTDIR)/tstvboxmouse$(ver).run
+ OTHERS += $$(vboxmouse_drv$(ver)_0_OUTDIR)/tstvboxmouse$(ver).run
+ $$$$(vboxmouse_drv$(ver)_0_OUTDIR)/tstvboxmouse$(ver).run: $$$$(vboxmouse_drv$(ver)_1_STAGE_TARGET)
+ $$(QUIET)$$(call MSG_L1,Checking for unresolved symbols in $$<)
+ $$(QUIET)$$(ASH) $$(PATH_ROOT)/src/bldprogs/checkUndefined.sh $$(KBUILD_HOST) \
+ $$(vboxmouse_drv$(ver)_1_STAGE_TARGET) $$(VBOXMOUSE_SRC_PATH)/../undefined_xfree86 $(VBOXMOUSE_SRC_PATH)/../undefined_xfree86_modules $$(VBOXMOUSE_SRC_PATH)/../undefined_xorg
+ $$(QUIET)$$(APPEND) -t "$$@" "done"
+ endef
+
+ $(foreach ver, _70 _71 _13 _14 _15 _16, $(eval $(def_vboxmouse_test)))
+
+ ifneq ($(KBUILD_TARGET),linux)
+ $(foreach ver, _17 _18 _19 _110 _111 _112 _113, $(eval $(def_vboxmouse_test)))
+
+ endif # neq ($(KBUILD_TARGET),linux)
+
+ endif # ! VBOX_ONLY_SDK
+ endif # eq ($(KBUILD_HOST_ARCH),$(KBUILD_TARGET_ARCH))
+ endif # eq ($(KBUILD_TARGET),linux)
+ endif # ! VBOX_USE_SYSTEM_XORG_HEADERS
+ # endif # ! VBOX_ONLY_ADDITIONS
+endif # VBOX_WITH_TESTCASES
+
+include $(FILE_KBUILD_SUB_FOOTER)
+
diff --git a/src/VBox/Additions/x11/vboxmouse/vboxmouse.c b/src/VBox/Additions/x11/vboxmouse/vboxmouse.c
new file mode 100644
index 00000000..dfdc4f31
--- /dev/null
+++ b/src/VBox/Additions/x11/vboxmouse/vboxmouse.c
@@ -0,0 +1,374 @@
+/* $Id: vboxmouse.c $ */
+/** @file
+ * VirtualBox X11 Guest Additions, mouse driver for X.Org server 1.5
+ */
+
+/*
+ * Copyright (C) 2006-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ * --------------------------------------------------------------------
+ *
+ * This code is based on evdev.c from X.Org with the following copyright
+ * and permission notice:
+ *
+ * Copyright © 2004-2008 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of Red Hat
+ * not be used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission. Red
+ * Hat makes no representations about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied
+ * warranty.
+ *
+ * THE AUTHORS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
+ * NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
+ * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors:
+ * Kristian Høgsberg (krh@redhat.com)
+ * Adam Jackson (ajax@redhat.com)
+ */
+
+#include <VBox/VMMDev.h> /* for VMMDEV_MOUSE_XXX */
+#include <VBox/VBoxGuestLib.h>
+#include <iprt/errcore.h>
+#include <xf86.h>
+#include <xf86Xinput.h>
+#include <mipointer.h>
+
+#include <xf86Module.h>
+
+#ifdef VBOX_GUESTR3XF86MOD
+# define _X_EXPORT
+#else
+# include <errno.h>
+# include <fcntl.h>
+# include <unistd.h>
+#endif
+
+#include "product-generated.h"
+
+static void
+VBoxReadInput(InputInfoPtr pInfo)
+{
+ uint32_t cx, cy, fFeatures;
+
+ /* Read a byte from the device to acknowledge the event */
+ char c;
+ int res = read(pInfo->fd, &c, 1);
+ NOREF(res);
+ /* The first test here is a workaround for an apparent bug in Xorg Server 1.5 */
+ if (
+#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) < 2
+ miPointerCurrentScreen() != NULL
+#else
+ miPointerGetScreen(pInfo->dev) != NULL
+#endif
+ && RT_SUCCESS(VbglR3GetMouseStatus(&fFeatures, &cx, &cy))
+ && (fFeatures & VMMDEV_MOUSE_HOST_WANTS_ABSOLUTE))
+ {
+#if ABI_XINPUT_VERSION == SET_ABI_VERSION(2, 0)
+ /* Bug in the 1.4 X server series - conversion_proc was no longer
+ * called, but the server didn't yet do the conversion itself. */
+ cx = (cx * screenInfo.screens[0]->width) / 65535;
+ cy = (cy * screenInfo.screens[0]->height) / 65535;
+#endif
+ /* send absolute movement */
+ xf86PostMotionEvent(pInfo->dev, 1, 0, 2, cx, cy);
+ }
+}
+
+static void
+VBoxPtrCtrlProc(DeviceIntPtr device, PtrCtrl *ctrl)
+{
+ /* Nothing to do, dix handles all settings */
+ RT_NOREF(device, ctrl);
+}
+
+static int
+VBoxInit(DeviceIntPtr device)
+{
+ CARD8 map[2] = { 0, 1 };
+#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 7
+ Atom axis_labels[2] = { 0, 0 };
+ Atom button_labels[2] = { 0, 0 };
+#endif
+ if (!InitPointerDeviceStruct((DevicePtr)device, map, 2,
+#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 7
+ button_labels,
+#endif
+#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) < 2
+ miPointerGetMotionEvents, VBoxPtrCtrlProc,
+ miPointerGetMotionBufferSize()
+#elif GET_ABI_MAJOR(ABI_XINPUT_VERSION) < 3
+ GetMotionHistory, VBoxPtrCtrlProc,
+ GetMotionHistorySize(), 2 /* Number of axes */
+
+#elif GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 3
+ VBoxPtrCtrlProc, GetMotionHistorySize(),
+ 2 /* Number of axes */
+#else
+# error Unsupported version of X.Org
+#endif
+#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 7
+ , axis_labels
+#endif
+ ))
+ return !Success;
+
+ /* Tell the server about the range of axis values we report */
+#if ABI_XINPUT_VERSION <= SET_ABI_VERSION(2, 0)
+ xf86InitValuatorAxisStruct(device, 0, 0, -1, 1, 0, 1);
+ xf86InitValuatorAxisStruct(device, 1, 0, -1, 1, 0, 1);
+#else
+ xf86InitValuatorAxisStruct(device, 0,
+# if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 7
+ axis_labels[0],
+# endif
+ VMMDEV_MOUSE_RANGE_MIN /* min X */, VMMDEV_MOUSE_RANGE_MAX /* max X */,
+ 10000, 0, 10000
+# if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 12
+ , Absolute
+# endif
+ );
+
+ xf86InitValuatorAxisStruct(device, 1,
+# if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 7
+ axis_labels[1],
+# endif
+ VMMDEV_MOUSE_RANGE_MIN /* min Y */, VMMDEV_MOUSE_RANGE_MAX /* max Y */,
+ 10000, 0, 10000
+# if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 12
+ , Absolute
+# endif
+ );
+#endif
+ xf86InitValuatorDefaults(device, 0);
+ xf86InitValuatorDefaults(device, 1);
+ xf86MotionHistoryAllocate(device->public.devicePrivate);
+
+ return Success;
+}
+
+static int
+VBoxProc(DeviceIntPtr device, int what)
+{
+ InputInfoPtr pInfo;
+ int rc, xrc;
+ 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);
+ fFeatures &= VMMDEV_MOUSE_GUEST_NEEDS_HOST_CURSOR;
+ 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);
+ fFeatures &= VMMDEV_MOUSE_GUEST_NEEDS_HOST_CURSOR;
+ 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)
+{
+ RT_NOREF(pInfo, num, v2, v3, v4, v5);
+
+ 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;
+ }
+ return FALSE;
+}
+
+static int
+VBoxPreInitInfo(InputDriverPtr drv, InputInfoPtr pInfo, int flags)
+{
+ const char *device;
+ int rc;
+ RT_NOREF(drv, flags);
+
+ /* 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 = xf86AllocateInput(drv, 0);
+ if (!pInfo)
+ 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)
+{
+ RT_NOREF(options, errmaj, 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
+};