diff -urN xserver-xorg-input-evdev-2.5.99.901.packaged/include/evdev-properties.h xserver-xorg-input-evdev-2.5.99.901/include/evdev-properties.h --- xserver-xorg-input-evdev-2.5.99.901.packaged/include/evdev-properties.h 2010-06-30 23:14:52.000000000 +0100 +++ xserver-xorg-input-evdev-2.5.99.901/include/evdev-properties.h 2010-12-07 21:22:06.444751926 +0000 @@ -66,4 +66,8 @@ /* BOOL */ #define EVDEV_PROP_SWAP_AXES "Evdev Axes Swap" +/* Auto-release */ +/* CARD32, 1 value, bitmap, bit N set = button (N+1) is auto-released */ +#define EVDEV_PROP_AUTORELEASE "Evdev Auto-Release Buttons" + #endif diff -urN xserver-xorg-input-evdev-2.5.99.901.packaged/src/Makefile.am xserver-xorg-input-evdev-2.5.99.901/src/Makefile.am --- xserver-xorg-input-evdev-2.5.99.901.packaged/src/Makefile.am 2010-08-06 03:26:24.000000000 +0100 +++ xserver-xorg-input-evdev-2.5.99.901/src/Makefile.am 2010-12-07 21:22:30.123579868 +0000 @@ -36,5 +36,6 @@ @DRIVER_NAME@.h \ emuMB.c \ emuWheel.c \ + autorelease.c \ draglock.c diff -urN xserver-xorg-input-evdev-2.5.99.901.packaged/src/Makefile.in xserver-xorg-input-evdev-2.5.99.901/src/Makefile.in diff -urN xserver-xorg-input-evdev-2.5.99.901.packaged/src/autorelease.c xserver-xorg-input-evdev-2.5.99.901/src/autorelease.c --- xserver-xorg-input-evdev-2.5.99.901.packaged/src/autorelease.c 1970-01-01 01:00:00.000000000 +0100 +++ xserver-xorg-input-evdev-2.5.99.901/src/autorelease.c 2010-12-07 21:53:17.036161117 +0000 @@ -0,0 +1,203 @@ +/* + * Copyright 2010 Darren Salt + * Structure taken from draglock.c + * Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany. + * Copyright 1993 by David Dawes + * Copyright 2002 by SuSE Linux AG, Author: Egbert Eich + * Copyright 1994-2002 by The XFree86 Project, Inc. + * Copyright 2002 by Paul Elliott + * (Ported from xf86-input-mouse, above copyrights taken from there) + * Copyright © 2008 University of South Australia + * Copyright 2008 by Chris Salch + * Copyright 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 the authors not be used in + * advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. The authors make 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. + * + */ + +/* Mouse button auto-release code */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif +#include "evdev.h" + +#include +#include +#include +#include + +#include + +#ifdef HAVE_PROPERTIES +static Atom prop_autorelease = 0; +#endif + +void EvdevAutoReleaseButton(InputInfoPtr pInfo, unsigned int button); + + +/* Setup and configuration code */ +void +EvdevAutoReleasePreInit(InputInfoPtr pInfo) +{ + EvdevPtr pEvdev = (EvdevPtr)pInfo->private; + char *option_string = NULL; + CARD32 release = 0; + char *next_num = NULL; + char *end_str = NULL; + + option_string = xf86CheckStrOption(pInfo->options, "AutoReleaseButtons",NULL); + + if (!option_string) + return; + + next_num = option_string; + + /* Loop until we hit the end of our option string */ + while (next_num != NULL) { + release = strtol(next_num, &end_str, 10); + + /* check to see if we found anything */ + if (next_num != end_str) { + /* setup for the next number */ + next_num = end_str; + } else { + /* we have nothing more to parse, drop out of the loop */ + next_num = NULL; + } + + /* Ok, let the user know what we found on this look */ + if (release > 0 && release <= EVDEV_MAXBUTTONS) { + pEvdev->releaseButtons |= 1U << (release - 1); + } else { + xf86Msg(X_ERROR, "%s: Found AutoReleaseButtons " + "with invalid button string : '%s'\n", + pInfo->name, option_string); + + /* This should be the case anyhow; just make sure */ + next_num = NULL; + } + + /* Check for end of string (to avoid annoying error) */ + if (next_num != NULL && *next_num == '\0') + next_num = NULL; + } + + free(option_string); +} + +/* Fires button event messges */ +void +EvdevAutoReleaseButton(InputInfoPtr pInfo, unsigned int button) +{ + EvdevQueueButtonEvent(pInfo, button, TRUE); + EvdevQueueButtonEvent(pInfo, button, FALSE); +} + +/* Filter button presses looking for either a meta button or the + * control of a button pair. + * + * @param button button number (1 for left, 3 for right) + * @param value TRUE if button press, FALSE if release + * + * @return TRUE if the event was swallowed here, FALSE otherwise. + */ +BOOL +EvdevAutoReleaseFilterEvent(InputInfoPtr pInfo, unsigned int button, int value) +{ + EvdevPtr pEvdev = (EvdevPtr)pInfo->private; + + if (button == 0) + return FALSE; + + if (pEvdev->releaseButtons & (1U << (button - 1))) { + /* Instant release if the button is marked such + and this is a press event*/ + if (value) { + EvdevAutoReleaseButton(pInfo, button); + } + /* Eat the release event */ + return TRUE; + } + + return FALSE; +} + +#ifdef HAVE_PROPERTIES +/** + * Set the auto-release property. + * This is a bitmap, with bit N for button (N+1). + */ +static int +EvdevAutoReleaseSetProperty(DeviceIntPtr dev, Atom atom, XIPropertyValuePtr val, + BOOL checkonly) +{ + InputInfoPtr pInfo = dev->public.devicePrivate; + EvdevPtr pEvdev = pInfo->private; + + if (atom == prop_autorelease) + { + CARD32 release; + + if (val->format != 32 || val->type != XA_INTEGER) + return BadMatch; + + if (val->size != 1) + return BadMatch; + + release = *((CARD32*)val->data); + + if (release & ~((1UL << EVDEV_MAXBUTTONS) - 1)) { + return BadValue; + } + + if (!checkonly) { + pEvdev->releaseButtons = release; + } + } + + return Success; +} + +/** + * Initialise property for drag lock buttons setting. + */ +void +EvdevAutoReleaseInitProperty(DeviceIntPtr dev) +{ + InputInfoPtr pInfo = dev->public.devicePrivate; + EvdevPtr pEvdev = pInfo->private; + + if (!dev->button) /* don't init prop for keyboards */ + return; + + prop_autorelease = MakeAtom(EVDEV_PROP_AUTORELEASE, + strlen(EVDEV_PROP_AUTORELEASE), TRUE); + + XIChangeDeviceProperty(dev, prop_autorelease, XA_INTEGER, 32, + PropModeReplace, 1, &pEvdev->releaseButtons, + FALSE); + + XISetDevicePropertyDeletable(dev, prop_autorelease, FALSE); + + XIRegisterPropertyHandler(dev, EvdevAutoReleaseSetProperty, NULL, NULL); +} + +#endif diff -urN xserver-xorg-input-evdev-2.5.99.901.packaged/src/evdev.c xserver-xorg-input-evdev-2.5.99.901/src/evdev.c --- xserver-xorg-input-evdev-2.5.99.901.packaged/src/evdev.c 2010-11-18 03:10:57.000000000 +0000 +++ xserver-xorg-input-evdev-2.5.99.901/src/evdev.c 2010-12-07 21:58:22.117060181 +0000 @@ -564,6 +564,9 @@ if (EvdevDragLockFilterEvent(pInfo, button, value)) return; + if (EvdevAutoReleaseFilterEvent(pInfo, button, value)) + return; + if (EvdevWheelEmuFilterButton(pInfo, button, value)) return; @@ -1662,6 +1665,7 @@ EvdevMBEmuInitProperty(device); EvdevWheelEmuInitProperty(device); EvdevDragLockInitProperty(device); + EvdevAutoReleaseInitProperty(device); #endif return Success; @@ -2283,6 +2287,7 @@ EvdevMBEmuPreInit(pInfo); EvdevWheelEmuPreInit(pInfo); EvdevDragLockPreInit(pInfo); + EvdevAutoReleasePreInit(pInfo); } return Success; diff -urN xserver-xorg-input-evdev-2.5.99.901.packaged/src/evdev.h xserver-xorg-input-evdev-2.5.99.901/src/evdev.h --- xserver-xorg-input-evdev-2.5.99.901.packaged/src/evdev.h 2010-10-28 04:05:18.000000000 +0100 +++ xserver-xorg-input-evdev-2.5.99.901/src/evdev.h 2010-12-07 21:35:49.496012414 +0000 @@ -173,6 +173,7 @@ int min_y; int max_y; } calibration; + CARD32 releaseButtons; unsigned char btnmap[32]; /* config-file specified button mapping */ @@ -227,9 +228,14 @@ void EvdevDragLockPreInit(InputInfoPtr pInfo); BOOL EvdevDragLockFilterEvent(InputInfoPtr pInfo, unsigned int button, int value); +/* Auto-release code */ +void EvdevAutoReleasePreInit(InputInfoPtr pInfo); +BOOL EvdevAutoReleaseFilterEvent(InputInfoPtr pInfo, unsigned int button, int value); + #ifdef HAVE_PROPERTIES void EvdevMBEmuInitProperty(DeviceIntPtr); void EvdevWheelEmuInitProperty(DeviceIntPtr); void EvdevDragLockInitProperty(DeviceIntPtr); +void EvdevAutoReleaseInitProperty(DeviceIntPtr); #endif #endif