[PATCH:xf86-input-mouse 4/4] Add settable properties for middle mouse button emulation

Alan Coopersmith alan.coopersmith at oracle.com
Fri Apr 27 17:43:52 PDT 2012


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 <alan.coopersmith at oracle.com>
---
 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



More information about the xorg-devel mailing list