Based on evdev's similar properties, including using the name "middle" button, to avoid confusion with evdev's 3rd button emulation for emulating the right button on a single button mouse.
Allows manual enable & disable at runtime. Exports new xf86-mouse.pc & xf86-mouse-properties.h for property name definitions. Signed-off-by: Alan Coopersmith <[email protected]> --- Makefile.am | 5 ++- configure.ac | 12 +++++ include/Makefile.am | 1 + include/xf86-mouse-properties.h | 33 ++++++++++++++ man/mousedrv.man | 4 +- src/Makefile.am | 2 +- src/mouse.c | 94 ++++++++++++++++++++++++++++++++++++--- xf86-mouse.pc.in | 6 +++ 8 files changed, 146 insertions(+), 11 deletions(-) create mode 100644 include/Makefile.am create mode 100644 include/xf86-mouse-properties.h create mode 100644 xf86-mouse.pc.in diff --git a/Makefile.am b/Makefile.am index f73a7ce..01da486 100644 --- a/Makefile.am +++ b/Makefile.am @@ -18,7 +18,7 @@ # IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -SUBDIRS = src man +SUBDIRS = include src man MAINTAINERCLEANFILES = ChangeLog INSTALL .PHONY: ChangeLog INSTALL @@ -31,6 +31,9 @@ ChangeLog: dist-hook: ChangeLog INSTALL +# Provide an sdk location that is writable by this module +DISTCHECK_CONFIGURE_FLAGS = --with-sdkdir='$${includedir}/xorg' + if LINT # Check source code with tools like lint & sparse lint: diff --git a/configure.ac b/configure.ac index 8ad7f65..ba55829 100644 --- a/configure.ac +++ b/configure.ac @@ -57,6 +57,16 @@ AC_ARG_WITH(xorg-module-dir, inputdir=${moduledir}/input AC_SUBST(inputdir) +# X Server SDK location is required to install xf86-mouse-properties.h +# This location is also relayed in the xorg-mouse.pc file +sdkdir=`$PKG_CONFIG --variable=sdkdir xorg-server` + +# Workaround overriding sdkdir to be able to create a tarball when user has no +# write permission in sdkdir. See DISTCHECK_CONFIGURE_FLAGS in Makefile.am +AC_ARG_WITH([sdkdir], [], [sdkdir="$withval"]) +AC_SUBST([sdkdir]) + + # Work out which OS mouse driver we need to build case $host_os in linux*) @@ -78,6 +88,8 @@ DRIVER_NAME=mouse AC_SUBST([DRIVER_NAME]) AC_CONFIG_FILES([Makefile + xf86-mouse.pc + include/Makefile src/Makefile man/Makefile]) AC_OUTPUT diff --git a/include/Makefile.am b/include/Makefile.am new file mode 100644 index 0000000..27ce0fb --- /dev/null +++ b/include/Makefile.am @@ -0,0 +1 @@ +sdk_HEADERS = xf86-mouse-properties.h diff --git a/include/xf86-mouse-properties.h b/include/xf86-mouse-properties.h new file mode 100644 index 0000000..fab5ddb --- /dev/null +++ b/include/xf86-mouse-properties.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef _XF86_MOUSE_PROPERTIES_H_ +#define _XF86_MOUSE_PROPERTIES_H_ + +/* Middle mouse button emulation */ +/* BOOL */ +#define MOUSE_PROP_MIDBUTTON "Mouse Middle Button Emulation" +/* CARD32 */ +#define MOUSE_PROP_MIDBUTTON_TIMEOUT "Mouse Middle Button Timeout" + +#endif /* _XF86_MOUSE_PROPERTIES_H_ */ diff --git a/man/mousedrv.man b/man/mousedrv.man index c9c2744..aedbd4d 100644 --- a/man/mousedrv.man +++ b/man/mousedrv.man @@ -125,12 +125,12 @@ cannot be auto-detected, the default value is 3. The maximum number is 24. Enable/disable the emulation of the third (middle) mouse button for mice which only have two physical buttons. The third button is emulated by pressing both buttons simultaneously. Default: on, until a press of a -physical button 3 is detected. +physical button 3 is detected. Property: "Mouse Middle Button Emulation" .TP 7 .BI "Option \*qEmulate3Timeout\*q \*q" integer \*q Sets the timeout (in milliseconds) that the driver waits before deciding if two buttons where pressed "simultaneously" when 3 button emulation is -enabled. Default: 50. +enabled. Default: 50. Property: "Mouse Middle Button Timeout" .TP 7 .BI "Option \*qChordMiddle\*q \*q" boolean \*q Enable/disable handling of mice that send left+right events when the middle diff --git a/src/Makefile.am b/src/Makefile.am index 927d530..0d65131 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -19,7 +19,7 @@ # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. AM_CFLAGS = $(CWARNFLAGS) -AM_CPPFLAGS = $(XORG_CFLAGS) +AM_CPPFLAGS = -I../include $(XORG_CFLAGS) # this is obnoxious: # -module lets us name the module exactly how we want diff --git a/src/mouse.c b/src/mouse.c index 308d356..3e820a7 100644 --- a/src/mouse.c +++ b/src/mouse.c @@ -65,6 +65,7 @@ #include "exevents.h" #include <X11/Xatom.h> #include "xserver-properties.h" +#include "xf86-mouse-properties.h" #include "compiler.h" @@ -140,6 +141,7 @@ static void ps2WakeupHandler(pointer data, int i, pointer LastSelectMask); static void ps2BlockHandler(pointer data, struct timeval **waitTime, pointer LastSelectMask); #endif +static void Emulate3ButtonsSetEnabled(InputInfoPtr pInfo, Bool enable); /* mouse autoprobe stuff */ static const char *autoOSProtocol(InputInfoPtr pInfo, int *protoPara); @@ -161,6 +163,10 @@ _X_EXPORT InputDriverRec MOUSE = { #define RETRY_COUNT 4 +/* Properties that can be set at runtime via xinput */ +static Atom prop_mbemu = 0; /* Middle button emulation on/off property */ +static Atom prop_mbtimeout = 0; /* Middle button timeout property */ + /* * Microsoft (all serial models), Logitech MouseMan, First Mouse, etc, * ALPS GlidePoint, Thinking Mouse. @@ -1041,10 +1047,38 @@ static void MouseInitButtonLabels(Atom *btn_labels) btn_labels[i] = unknown_btn; } +static int +MouseSetProperty(DeviceIntPtr device, Atom atom, + XIPropertyValuePtr val, BOOL checkonly) +{ + InputInfoPtr pInfo = device->public.devicePrivate; + MouseDevPtr pMse = pInfo->private; + + if (atom == prop_mbemu) + { + if (val->format != 8 || val->size != 1 || val->type != XA_INTEGER) + return BadMatch; + + if (!checkonly) + Emulate3ButtonsSetEnabled(pInfo, *((BOOL*)val->data)); + } + else if (atom == prop_mbtimeout) + { + if (val->format != 32 || val->size != 1 || val->type != XA_INTEGER) + return BadMatch; + + if (!checkonly) + pMse->emulate3Timeout = *((CARD32*)val->data); + } + + return Success; +} + static void MouseInitProperties(DeviceIntPtr device) { InputInfoPtr pInfo = device->public.devicePrivate; MouseDevPtr pMse = pInfo->private; + int rc; #ifdef XI_PROP_DEVICE_NODE const char *device_node = @@ -1076,6 +1110,32 @@ static void MouseInitProperties(DeviceIntPtr device) XISetDevicePropertyDeletable(device, prop_btn_label, FALSE); } } + + /* Middle button emulation - which this driver calls 3rd button emulation, + * but evdev's properties considers that to be simulating right button + * clicks from a one button mouse, which this driver does not currently + * support, so we use this name for better consistency. + */ + prop_mbemu = MakeAtom(MOUSE_PROP_MIDBUTTON, strlen(MOUSE_PROP_MIDBUTTON), + TRUE); + rc = XIChangeDeviceProperty(device, prop_mbemu, XA_INTEGER, 8, + PropModeReplace, 1, + &pMse->emulate3Buttons, FALSE); + if (rc != Success) + return; + XISetDevicePropertyDeletable(device, prop_mbemu, FALSE); + + prop_mbtimeout = MakeAtom(MOUSE_PROP_MIDBUTTON_TIMEOUT, + strlen(MOUSE_PROP_MIDBUTTON_TIMEOUT), TRUE); + rc = XIChangeDeviceProperty(device, prop_mbtimeout, XA_INTEGER, 32, + PropModeReplace, 1, + &pMse->emulate3Timeout, FALSE); + + if (rc != Success) + return; + XISetDevicePropertyDeletable(device, prop_mbtimeout, FALSE); + + XIRegisterPropertyHandler(device, MouseSetProperty, NULL, NULL); } static void @@ -1965,6 +2025,32 @@ buttonTimer(InputInfoPtr pInfo) return 0; } +static void +Emulate3ButtonsSetEnabled(InputInfoPtr pInfo, Bool enable) +{ + MouseDevPtr pMse = pInfo->private; + + if (pMse->emulate3Buttons == enable) + return; + + pMse->emulate3Buttons = enable; + + if (enable) { + pMse->emulateState = 0; + pMse->emulate3Pending = FALSE; + pMse->emulate3ButtonsSoft = FALSE; /* specifically requested now */ + + RegisterBlockAndWakeupHandlers (MouseBlockHandler, MouseWakeupHandler, + (pointer) pInfo); + } else { + if (pMse->emulate3Pending) + buttonTimer(pInfo); + + RemoveBlockAndWakeupHandlers (MouseBlockHandler, MouseWakeupHandler, + (pointer) pInfo); + } +} + static Bool Emulate3ButtonsSoft(InputInfoPtr pInfo) { @@ -1973,15 +2059,9 @@ Emulate3ButtonsSoft(InputInfoPtr pInfo) if (!pMse->emulate3ButtonsSoft) return TRUE; - pMse->emulate3Buttons = FALSE; - - if (pMse->emulate3Pending) - buttonTimer(pInfo); - xf86Msg(X_INFO,"3rd Button detected: disabling emulate3Button\n"); - RemoveBlockAndWakeupHandlers (MouseBlockHandler, MouseWakeupHandler, - (pointer) pInfo); + Emulate3ButtonsSetEnabled(pInfo, FALSE); return FALSE; } diff --git a/xf86-mouse.pc.in b/xf86-mouse.pc.in new file mode 100644 index 0000000..561aa66 --- /dev/null +++ b/xf86-mouse.pc.in @@ -0,0 +1,6 @@ +sdkdir=@sdkdir@ + +Name: xf86-mouse +Description: X.Org mouse input driver for non-evdev OS'es +Version: @PACKAGE_VERSION@ +Cflags: -I${sdkdir} -- 1.7.9.2 _______________________________________________ [email protected]: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
