diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-06 03:01:46 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-06 03:01:46 +0000 |
commit | f8fe689a81f906d1b91bb3220acde2a4ecb14c5b (patch) | |
tree | 26484e9d7e2c67806c2d1760196ff01aaa858e8c /src/VBox/Additions/x11/vboxmouse | |
parent | Initial commit. (diff) | |
download | virtualbox-f8fe689a81f906d1b91bb3220acde2a4ecb14c5b.tar.xz virtualbox-f8fe689a81f906d1b91bb3220acde2a4ecb14c5b.zip |
Adding upstream version 6.0.4-dfsg.upstream/6.0.4-dfsgupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r-- | src/VBox/Additions/x11/vboxmouse/Makefile.kmk | 286 | ||||
-rw-r--r-- | src/VBox/Additions/x11/vboxmouse/vboxmouse.c | 364 |
2 files changed, 650 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..8bc81b30 --- /dev/null +++ b/src/VBox/Additions/x11/vboxmouse/Makefile.kmk @@ -0,0 +1,286 @@ +# $Id: Makefile.kmk $ +## @file +# Sub-Makefile for the VBox Additions XFree86 and X.org mouse drivers. +# + +# +# Copyright (C) 2006-2019 Oracle Corporation +# +# This file is part of VirtualBox Open Source Edition (OSE), as +# available from http://www.virtualbox.org. This file is free software; +# you can redistribute it and/or modify it under the terms of the GNU +# General Public License (GPL) as published by the Free Software +# Foundation, in version 2 as it comes in the "COPYING" file of the +# VirtualBox OSE distribution. VirtualBox OSE is distributed in the +# hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. +# + +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.16.0 \ + $(VBOX_PATH_X11_ROOT)/xextproto-7.1.1 \ + $(VBOX_PATH_X11_ROOT)/xproto-7.0.18 + +# +# vboxmouse_drv +# +if1of ($(KBUILD_TARGET), linux) + SYSMODS += vboxmouse_drv + vboxmouse_drv_TEMPLATE = VBOXGUESTR3XF86MOD + 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..774a9059 --- /dev/null +++ b/src/VBox/Additions/x11/vboxmouse/vboxmouse.c @@ -0,0 +1,364 @@ +/* $Id: vboxmouse.c $ */ +/** @file + * VirtualBox X11 Guest Additions, mouse driver for X.Org server 1.5 + */ + +/* + * Copyright (C) 2006-2019 Oracle Corporation + * + * This file is part of VirtualBox Open Source Edition (OSE), as + * available from http://www.virtualbox.org. This file is free software; + * you can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) as published by the Free Software + * Foundation, in version 2 as it comes in the "COPYING" file of the + * VirtualBox OSE distribution. VirtualBox OSE is distributed in the + * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. + * -------------------------------------------------------------------- + * + * 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 +}; |