From a64b246a03680ec5c4f3cee07058382284e5d145 Mon Sep 17 00:00:00 2001 From: Chris Salch Date: Thu, 7 Aug 2008 21:37:26 -0500 Subject: [PATCH] Adding DragLock code. --- man/evdev.man | 13 +++- src/Makefile.am | 4 +- src/draglock.c | 202 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/evdev.c | 10 +++ src/evdev.h | 10 +++ 5 files changed, 237 insertions(+), 2 deletions(-) create mode 100644 src/draglock.c diff --git a/man/evdev.man b/man/evdev.man index 0a4b71a..d853f51 100644 --- a/man/evdev.man +++ b/man/evdev.man @@ -77,7 +77,18 @@ buttons can have the same mapping. For example, a left-handed mouse with deactivated scroll-wheel would use a mapping of "3 2 1 0 0". Invalid mappings are ignored and the default mapping is used. Buttons not specified in the user's mapping use the default mapping. - +.TP 7 +.BI "Option \*qDragLockButtons\*q \*q" "L1 B2 L3 B4" \*q +Sets \*qdrag lock buttons\*q that simulate holding a button down, so +that low dexterity people do not have to hold a button down at the +same time they move a mouse cursor. Button numbers occur in pairs, +with the lock button number occurring first, followed by the button +number that is the target of the lock button. +.TP 7 +.BI "Option \*qDragLockButtons\*q \*q" "M1" \*q +Sets a \*qmaster drag lock button\*q that acts as a \*qMeta Key\*q +indicating that the next button pressed is to be +\*qdrag locked\*q. .SH AUTHORS Kristian Høgsberg. .SH "SEE ALSO" diff --git a/src/Makefile.am b/src/Makefile.am index d0b9b63..2207d7f 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -30,4 +30,6 @@ @DRIVER_NAME@_drv_la_SOURCES = @DRIVER_NAME@.c \ @DRIVER_NAME@.h \ - emuMB.c + emuMB.c \ + draglock.c + diff --git a/src/draglock.c b/src/draglock.c new file mode 100644 index 0000000..5f301a1 --- /dev/null +++ b/src/draglock.c @@ -0,0 +1,202 @@ +/* + * 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 + * + * 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. + * + */ + +/* Draglock code */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include + +#include "evdev.h" + +void EvdevDragLockLockButton(InputInfoPtr pInfo, unsigned int button); + + +/* Setup and configuration code */ +void +EvdevDragLockInit(InputInfoPtr pInfo) +{ + EvdevPtr pEvdev = (EvdevPtr)pInfo->private; + char *option_string = 0; + + option_string = xf86CheckStrOption(pInfo->options, "DragLockButtons",NULL); + + if (option_string) { + int meta_button = 0; + int lock_button = 0; + char *next_num = option_string; + char *end_str = 0; + BOOL pairs = FALSE; + + /* Loop until we hit the end of our option string */ + while (next_num != 0) { + lock_button = 0; + meta_button = 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 = 0; + } + + /* Check for a button to lock if we have a meta button */ + if (meta_button != 0 && next_num != 0 ) { + lock_button = 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 = 0; + } + } + + /* Ok, let the user know what we found on this look */ + if (meta_button != 0) { + if (lock_button == 0) { + if (!pairs) { + /* We only have a meta button */ + pEvdev->dragLock.meta = meta_button; + + xf86Msg(X_CONFIG, "%s: DragLockButtons : " + "%i as meta\n", + pInfo->name, meta_button); + } else { + xf86Msg(X_ERROR, "%s: DragLockButtons : " + "Incomplete pair specifying button pairs %s\n", + pInfo->name, option_string); + } + } else { + + /* Do bounds checking to make sure we don't crash */ + if ((meta_button <= 32) && (meta_button >= 0 ) && + (lock_button <= 32) && (lock_button >= 0)) { + + xf86Msg(X_CONFIG, "%s: DragLockButtons : %i -> %i\n", + pInfo->name, meta_button, lock_button); + + pEvdev->dragLock.lock_pair[meta_button - 1] = lock_button; + pairs=TRUE; + } else { + /* Let the user no something was wrong + with this pair of buttons */ + xf86Msg(X_CONFIG, "%s: DragLockButtons : " + "Invalid button pair %i -> %i\n", + pInfo->name, meta_button, lock_button); + } + } + } else { + xf86Msg(X_ERROR, "%s: Found DragLockButtons " + "with invalid lock button string : '%s'\n", + pInfo->name, option_string); + + /* This should be the case anyhow, just make sure */ + next_num = 0; + } + + /* Check for end of string, to avoid annoying error */ + if (next_num != 0 && *next_num == '\0') + next_num = 0; + } + } +} + +/* Clean up after ourselves */ +void +EvdevDragLockUnInit(InputInfoPtr pInfo) +{ + +} + +/* Updates DragLock button state and firest button event messges */ +void +EvdevDragLockLockButton(InputInfoPtr pInfo, unsigned int button) +{ + EvdevPtr pEvdev = (EvdevPtr)pInfo->private; + BOOL state=0; + + xf86Msg(X_INFO, "%s: Locking button %i\n", pInfo->name, button); + + /* update button state */ + state = TRUE - pEvdev->dragLock.lock_state[button - 1]; + pEvdev->dragLock.lock_state[button - 1] = state; + + xf86PostButtonEvent(pInfo->dev, 0, button, state, 0, 0); +} + +BOOL +EvdevDragLockFilterEvent(InputInfoPtr pInfo, unsigned int button, int value) +{ + EvdevPtr pEvdev = (EvdevPtr)pInfo->private; + + if (button == 0) + return FALSE; + + /* Do we have a single meta key or + several button pairings? */ + if (pEvdev->dragLock.meta != 0) { + + if (pEvdev->dragLock.meta == button) { + + /* setup up for button lock */ + if (value) + pEvdev->dragLock.meta_state = TRUE; + + return TRUE; + } else if (pEvdev->dragLock.meta_state) { /* waiting to lock */ + + pEvdev->dragLock.meta_state = FALSE; + + EvdevDragLockLockButton(pInfo, button); + + return TRUE; + } + } else if (pEvdev->dragLock.lock_pair[button - 1] && value) { + /* A meta button in a meta/lock pair was pressed */ + EvdevDragLockLockButton(pInfo, pEvdev->dragLock.lock_pair[button - 1]); + return TRUE; + } + + /* Eat events for buttons that are locked */ + if (pEvdev->dragLock.lock_state[button - 1]) + return TRUE; + + return FALSE; +} + diff --git a/src/evdev.c b/src/evdev.c index bbabb56..cdc4a86 100644 --- a/src/evdev.c +++ b/src/evdev.c @@ -217,6 +217,7 @@ EvdevReadInput(InputInfoPtr pInfo) break; } + /* Get the signed value, earlier kernels had this as unsigned */ value = ev.value; @@ -282,6 +283,11 @@ EvdevReadInput(InputInfoPtr pInfo) default: button = EvdevUtilButtonEventToButtonNumber(ev.code); + xf86Msg(X_INFO,"%s: Button Press %i\n",pInfo->name, button); + + /* Handle drage lock */ + if (EvdevDragLockFilterEvent(pInfo, button, value)) + break; if (EvdevMBEmuFilterEvent(pInfo, button, value)) break; @@ -943,7 +949,10 @@ EvdevProc(DeviceIntPtr device, int what) { xf86AddEnabledDevice(pInfo); if (pEvdev->flags & EVDEV_BUTTON_EVENTS) + { EvdevMBEmuPreInit(pInfo); + EvdevDragLockInit(pInfo); + } device->public.on = TRUE; } break; @@ -954,6 +963,7 @@ EvdevProc(DeviceIntPtr device, int what) strerror(errno)); xf86RemoveEnabledDevice(pInfo); EvdevMBEmuFinalize(pInfo); + EvdevDragLockUnInit(pInfo); device->public.on = FALSE; break; diff --git a/src/evdev.h b/src/evdev.h index 56983c2..6a5292b 100644 --- a/src/evdev.h +++ b/src/evdev.h @@ -68,6 +68,12 @@ typedef struct { Time expires; /* time of expiry */ Time timeout; } emulateMB; + struct { + int meta; /* meta key to lock any button */ + BOOL meta_state; /* meta_button state */ + unsigned int lock_pair[32]; /* specify a meta/lock pair */ + BOOL lock_state[32]; /* state of any locked buttons */ + } dragLock; unsigned char btnmap[32]; /* config-file specified button mapping */ } EvdevRec, *EvdevPtr; @@ -89,4 +95,8 @@ Atom EvdevMBEmuInitPropertyTimeout(DeviceIntPtr, char*); BOOL EvdevMBEmuSetProperty(DeviceIntPtr, Atom, XIPropertyValuePtr); #endif +/* Draglock code */ +void EvdevDragLockInit(InputInfoPtr pInfo); +void EvdevDragLockUnInit(InputInfoPtr pInfo); /* may not need this after all */ +BOOL EvdevDragLockFilterEvent(InputInfoPtr pInfo, unsigned int button, int value); #endif -- 1.5.6.3