I have finished the rewrite of gestures and attached patch. Its also
been pushed to bamboo branch of xf86-input-wacom. Comments welcome.
Also, I need to debug Zoom gestures to figure out what about
emitKeysym is crashing my Fedora Xorg 1.7 server. And I also need to
bring the variables back out to xsetwacom again.
Below is text from commit message:
1 and 2 finger gesture have a lot of overlapping and
interacting logic so combine into single function.
Most decisions on gesture types are not made at a time window
defined by wcmGestureTapTime instead of based on distance alone.
Added a new Tap gesture to click left/right button on touchpads.
Comment out Zoom calls to emitKeysym because its crashing my
X server.
Split scroll speed control into horizontal/vertical values to
align with xf86-input-synaptics user interface. Also speed
is now based on exact distance traveled instead of distance of
midpoints.
Chris
On Sat, Jan 30, 2010 at 7:28 PM, Chris Bagwell <[email protected]> wrote:
> Hi all,
>
> I wanted to let you know the status of Bamboo P&T and
> xf86-input-wacom; especially related to making use of patches that
> Jason Child has produced.
>
> I've ported most all the patch set except for a part related to
> reconnecting the tablet and setting some new variables using
> xsetwacom. They have been uploaded to sourceforge. You can play with
> them using:
>
> git clone
> git://linuxwacom.git.sourceforge.net/gitroot/linuxwacom/xf86-input-wacom
> git checkout -b bamboo remotes/origin/bamboo
>
> To get full use of this, you'll need to use latest kernel driver from
> linuxwacom-0.8.5-9 and also apply all the kernel patches to it from
> Jason Childs' latest patchset on mailing list.
>
> With this combination of software, I can get single finger touch and
> single finger double tap gestures working. I can also get two finger
> scrolling gestures working. There are a few issues/bugs I can tell
> but quite usable overall.
>
> Chris
>
From 202b9c7ab30ea355468ec00e21376fb75880481f Mon Sep 17 00:00:00 2001
From: Chris Bagwell <[email protected]>
Date: Thu, 4 Feb 2010 23:22:36 -0600
Subject: [PATCH] Rewrite gestures by combining 1 and 2 finger logic
1 and 2 finger gesture have a lot of overlapping and
interacting logic so combine into single function.
Most decisions on gesture types are not made at a time window
defined by wcmGestureTapTime instead of based on distance alone.
Added a new Tap gesture to left/right click mouse on touchpads.
Comment out Zoom calls to emitKeysym because its crashing my
X server.
Split scroll speed control into horizontal/vertical values to
align with xf86-input-synaptics user interface. Also speed
is now based on exact distance traveled instead of distance of
midpoints.
Signed-off-by: Chris Bagwell <[email protected]>
---
src/wcmCommon.c | 110 +-------------
src/wcmConfig.c | 10 +-
src/wcmTouchFilter.c | 385 ++++++++++++++++++++++++++++++++---------------
src/wcmValidateDevice.c | 36 +----
src/xf86WacomDefs.h | 12 +-
5 files changed, 285 insertions(+), 268 deletions(-)
diff --git a/src/wcmCommon.c b/src/wcmCommon.c
index 37c88a1..febb34a 100644
--- a/src/wcmCommon.c
+++ b/src/wcmCommon.c
@@ -35,7 +35,7 @@ extern void xf86WcmInitialCoordinates(LocalDevicePtr local, int axes);
extern void xf86WcmVirtualTabletSize(LocalDevicePtr local);
extern void xf86WcmVirtualTabletPadding(LocalDevicePtr local);
extern void wcmTilt2R(WacomDeviceStatePtr ds);
-extern void xf86WcmFingerTapToClick(WacomCommonPtr common, WacomDevicePtr priv);
+extern int xf86WcmTouchFilter(WacomCommonPtr common, WacomDevicePtr priv, unsigned int channel);
/*****************************************************************************
* Static functions
@@ -1218,108 +1218,14 @@ void wcmEvent(WacomCommonPtr common, unsigned int channel,
}
}
- /* process second finger data if exists
- * and both touch and geature are enabled */
- if ((ds.device_type == TOUCH_ID) &&
- common->wcmTouch && common->wcmGesture)
- {
- WacomChannelPtr pOtherChannel;
- WacomDeviceState dsOther;
-
- /* Get the other channel state */
- if (channel)
- pOtherChannel = common->wcmChannel;
- else
- pOtherChannel = common->wcmChannel + 1;
- dsOther = pOtherChannel->valid.state;
-
- /* Exit gesture mode when both fingers are out. */
- if (!ds.proximity && !dsOther.proximity)
- {
- common->wcmGestureMode = 0;
-
- /* send a touch out-prox event here
- * in case the FF was out before the SF */
- channel = 0;
- }
- else
- {
- /* don't move the cursor if in gesture mode
- * wait for second finger data to process gestures */
- if (!channel && common->wcmGestureMode)
- goto ret;
-
- /* process gesture */
- if (channel)
- {
- xf86WcmFingerTapToClick(common, priv);
- goto ret;
- }
- }
- }
-
- /* process single finger events
- * if touch is in Relative mode then allow single click
- * to work regardless of gesture on/off state.
- * Also ensure that we don't try to process single clicks
- * when in an active gesture mode.
- */
- if (ds.device_type == TOUCH_ID && common->wcmTouch &&
- (common->wcmCapacityDefault && !(priv->flags & ABSOLUTE_FLAG) && !common->wcmGestureMode))
- {
- WacomDeviceState* pds = &common->wcmTouchpadState;
-
- if (ds.proximity)
- {
- switch (common->wcmTouchpadMode)
- {
- case 0:
- common->wcmTouchpadMode = 1;
- common->wcmTouchpadState = ds;
- common->wcmTouchpadState.sample = (int)GetTimeInMillis();
- break;
- case 1:
- if (GetTimeInMillis() - pds->sample <= 200) {
- int xd = ds.x - pds->x;
- int yd = ds.y - pds->y;
-
- if (xd*xd + yd*yd > 10*10)
- common->wcmTouchpadMode = 2;
- } else {
- /* left button down */
- xf86PostButtonEvent(priv->local->dev,FALSE,1,TRUE,0,0);
- common->wcmTouchpadMode = 3;
- }
- break;
- }
- } else {
- switch (common->wcmTouchpadMode)
- {
- case 1:
- if (GetTimeInMillis() - pds->sample <= 200)
- {
- /* left button down */
- xf86PostButtonEvent(priv->local->dev,FALSE,1,TRUE,0,0);
- /* left button up */
- xf86PostButtonEvent(priv->local->dev,FALSE,1,FALSE,0,0);
- }
- break;
- case 3:
- /* left button up */
- xf86PostButtonEvent(priv->local->dev,FALSE,1,FALSE,0,0);
- }
- common->wcmTouchpadMode = 0;
- }
- if (common->wcmTouchpadMode == 1 || common->wcmTouchpadMode == 2)
- ds.buttons &= ~1;
- }
+ if (ds.device_type == TOUCH_ID && common->wcmTouch &&
+ common->wcmGesture)
+ /* Consume gesture if requested */
+ if (xf86WcmTouchFilter(common, priv, channel))
+ goto ret;
- /* everything else falls here,
- * dispatch unless this is destined for a touch device
- * and touch is disabled.
- */
- if (ds.device_type != TOUCH_ID || common->wcmTouch)
- commonDispatchDevice(common,channel,pChannel, suppress);
+ /* everything else falls here */
+ commonDispatchDevice(common,channel,pChannel,suppress);
ret:
resetSampleCounter(pChannel);
}
diff --git a/src/wcmConfig.c b/src/wcmConfig.c
index 8358f46..7beaf3f 100644
--- a/src/wcmConfig.c
+++ b/src/wcmConfig.c
@@ -134,11 +134,11 @@ static int xf86WcmAllocate(LocalDevicePtr local, char* type_name, int flag)
common->wcmDevCls = &gWacomUSBDevice; /* device-specific functions */
common->wcmTPCButton =
common->wcmTPCButtonDefault; /* set Tablet PC button on/off */
- common->wcmRightClickDistance = 300; /* max finger spacing */
- common->wcmZoomPinchDistance = 350; /* max to start gesture */
- common->wcmActivateDistance = 50; /* min to start any gesture */
- common->wcmScrollActivateDistance = 50; /* min to start scroll */
- common->wcmGestureTapTime = 150; /* min time to start gesture */
+ common->wcmGestureTapDistance = 50;/* max distance to start gesture */
+ common->wcmGestureTapTime = 200; /* min time to start gesture */
+ common->wcmGestureVertDelta = 50; /* Vert scroll event distance */
+ common->wcmGestureHorzDelta = 50; /* Horz scroll event distance */
+ common->wcmGestureZoomDelta = 20; /* Pinch Zoom event distance */
common->wcmCapacity = -1; /* Capacity is disabled */
common->wcmCapacityDefault = -1; /* default to -1 when capacity isn't supported */
/* 3 when capacity is supported */
diff --git a/src/wcmTouchFilter.c b/src/wcmTouchFilter.c
index d3a253b..12fa95b 100644
--- a/src/wcmTouchFilter.c
+++ b/src/wcmTouchFilter.c
@@ -24,21 +24,23 @@
#include <math.h>
/* Defines for 2FC Gesture */
-#define WACOM_DOWN_TIME_IN_MS 800
-#define WACOM_TIME_BETWEEN_IN_MS 400
#define WACOM_HORIZ_ALLOWED 1
#define WACOM_VERT_ALLOWED 2
-#define GESTURE_TAP_MODE 1
-#define GESTURE_SCROLL_MODE 2
-#define GESTURE_ZOOM_MODE 4
+#define GESTURE_NO_MODE 0
+#define GESTURE_DETECT_MODE 1
+#define GESTURE_PASSTHRU_MODE 3
+#define GESTURE_SCROLL_HORZ_MODE 7
+#define GESTURE_SCROLL_VERT_MODE 8
+#define GESTURE_ZOOM_MODE 9
#define WCM_SCROLL_UP 5 /* vertical up */
#define WCM_SCROLL_DOWN 4 /* vertical down */
#define WCM_SCROLL_LEFT 6 /* horizontal left */
#define WCM_SCROLL_RIGHT 7 /* horizontal right */
-void xf86WcmFingerTapToClick(WacomCommonPtr common, WacomDevicePtr priv);
+int xf86WcmTouchFilter(WacomCommonPtr common, WacomDevicePtr priv,
+ unsigned int channel);
extern void wcmRotateCoordinates(LocalDevicePtr local, int* x, int* y);
extern void emitKeysym (DeviceIntPtr keydev, int keysym, int state);
@@ -54,6 +56,11 @@ static double touchDistance(WacomDeviceState ds0, WacomDeviceState ds1)
return distance;
}
+/* When in auto-detect mode, find when fingers are moving in a line
+ * that is of width wcmGestureTapDistance and return its direction.
+ * When a direction is specified, return TRUE only when moving
+ * in line of wcmGestureTapDistance width.
+ */
static Bool pointsInLine(WacomCommonPtr common, WacomDeviceState ds0,
WacomDeviceState ds1, int *direction)
{
@@ -61,12 +68,12 @@ static Bool pointsInLine(WacomCommonPtr common, WacomDeviceState ds0,
if (*direction == 0)
{
- if (abs(ds0.x - ds1.x) < common->wcmScrollActivateDistance)
+ if (abs(ds0.x - ds1.x) < common->wcmGestureTapDistance)
{
*direction = WACOM_VERT_ALLOWED;
ret = TRUE;
}
- else if (abs(ds0.y - ds1.y) < common->wcmScrollActivateDistance)
+ else if (abs(ds0.y - ds1.y) < common->wcmGestureTapDistance)
{
*direction = WACOM_HORIZ_ALLOWED;
ret = TRUE;
@@ -74,12 +81,12 @@ static Bool pointsInLine(WacomCommonPtr common, WacomDeviceState ds0,
}
else if (*direction == WACOM_HORIZ_ALLOWED)
{
- if (abs(ds0.y - ds1.y) < common->wcmScrollActivateDistance)
+ if (abs(ds0.y - ds1.y) < common->wcmGestureTapDistance)
ret = TRUE;
}
else if (*direction == WACOM_VERT_ALLOWED)
{
- if (abs(ds0.x - ds1.x) < common->wcmScrollActivateDistance)
+ if (abs(ds0.x - ds1.x) < common->wcmGestureTapDistance)
ret = TRUE;
}
return ret;
@@ -89,133 +96,256 @@ static Bool pointsInLineAfter(WacomCommonPtr common, int p1, int p2)
{
Bool ret = FALSE;
- if (abs(p1 - p2) < common->wcmScrollActivateDistance)
+ if (abs(p1 - p2) < common->wcmGestureTapDistance)
ret = TRUE;
return ret;
}
-static void xf86WcmSwitchLeftClick(WacomDevicePtr priv)
-{
- WacomCommonPtr common = priv->common;
-
- if (common->wcmGestureMode)
- {
- /* send button one up */
- xf86PostButtonEvent(priv->local->dev,FALSE,1,FALSE,0,0);
- priv->oldButtons = 0;
- }
-}
-
-/*****************************************************************************
- * translate second finger tap to right click
- ****************************************************************************/
-
-void xf86WcmFingerTapToClick(WacomCommonPtr common, WacomDevicePtr priv)
+/* Filters out events related to following gestures and replaces with
+ * specified action:
+ *
+ * Single and Double Finger Taps - Left and Right button click
+ * Double Finger Scroll - Scroll Button Events
+ * Double Finger Pinch Zoom - Zoom Finger Events
+ * Single and Double Finger Touches - Left and Right Button Clicks
+ *
+ * In addition, Touch gestures let standard X/Y data to be processed
+ * as normal.
+ */
+int xf86WcmTouchFilter(WacomCommonPtr common, WacomDevicePtr priv,
+ unsigned int channel)
{
WacomChannelPtr firstChannel = common->wcmChannel;
WacomChannelPtr secondChannel = common->wcmChannel + 1;
- WacomDeviceState ds[2] = { firstChannel->valid.states[0],
- secondChannel->valid.states[0] };
+ WacomDeviceState ds[2] = { firstChannel->valid.state,
+ secondChannel->valid.state };
WacomDeviceState dsLast[2] = { firstChannel->valid.states[1],
- secondChannel->valid.states[1] };
- int direction = 0;
-
- DBG(10, priv, "mode = %d, "
- "ds[0].x = %d, ds[0].y = %d, ds[1].x = %d, ds[1].y = %d, "
- "ds[0].sample = %d, ds[1].sample = %d, "
- "dsLast[0].sample = %d, dsLast[1].sample = %d, "
- "ds[1].proximity = %s, dsLast[1].proximity = %s\n",
- common->wcmGestureMode,
- ds[0].x, ds[0].y, ds[1].x, ds[1].y,
- ds[0].sample, ds[1].sample,
- dsLast[0].sample, dsLast[1].sample,
- ds[1].proximity ? "true" : "false",
- dsLast[1].proximity ? "true" : "false");
-
- /* skip initial second finger event */
- if (!dsLast[1].proximity)
- goto skipGesture;
+ secondChannel->valid.states[1] };
if (!IsTouch(priv))
{
/* this should never happen */
xf86Msg(X_ERROR, "WACOM: No touch device found for %s \n", common->wcmDevice);
- goto skipGesture;
+ return TRUE;
}
- /* process second finger tap if matched */
- if ((dsLast[0].sample < dsLast[1].sample) &&
- ((GetTimeInMillis() - dsLast[1].sample) <= common->wcmGestureTapTime))
+ DBG(10, priv, "channel = %d, mode = %d, "
+ "ds[0].x = %d, ds[0].y = %d, ds[1].x = %d, ds[1].y = %d, "
+ "ds[0].sample = %d, ds[1].sample = %d, "
+ "wcmGestureState[0].sample = %d, wcmGestureState[1].sample = %d, "
+ "wcmGestureFingers = %d ds[0].proximity = %s, ds[1].proximity = %s\n",
+ channel,
+ common->wcmGestureMode,
+ ds[0].x, ds[0].y, ds[1].x, ds[1].y,
+ ds[0].sample, ds[1].sample,
+ common->wcmGestureState[0].sample,
+ common->wcmGestureState[1].sample,
+ common->wcmGestureFingers,
+ ds[0].proximity ? "true" : "false",
+ ds[1].proximity ? "true" : "false");
+
+ /* Detect when both fingers are removed */
+ if (!ds[0].proximity && !ds[1].proximity)
{
- /* send right click when second finger taps within WACOM_TAP_TIMEms
- * and both fingers stay within WACOM_DIST */
- if (!ds[1].proximity && dsLast[1].proximity)
+ if (common->wcmGestureMode == GESTURE_DETECT_MODE)
{
- if (touchDistance(ds[0], dsLast[1]) <= common->wcmRightClickDistance)
+ /* In relative mode, we met condition
+ * to send button down. */
+ if (!(priv->flags & ABSOLUTE_FLAG))
{
- /* send left up before sending right down */
- if (!common->wcmGestureMode)
- {
- common->wcmGestureMode = GESTURE_TAP_MODE;
- xf86WcmSwitchLeftClick(priv);
- }
-
- /* right button down */
- xf86PostButtonEvent(priv->local->dev,FALSE,3,TRUE,0,0);
- /* right button up */
- xf86PostButtonEvent(priv->local->dev,FALSE,3,FALSE,0,0);
- } else if (common->wcmGestureMode == GESTURE_TAP_MODE) {
- common->wcmGestureMode = 0;
+ /* left for single finger
+ * right for double finger
+ */
+ if (common->wcmGestureFingers == 1)
+ common->wcmGestureButtonDown = 1;
+ else
+ common->wcmGestureButtonDown = 3;
+
+ xf86PostButtonEvent(priv->local->dev,
+ priv->flags&ABSOLUTE_FLAG,
+ common->wcmGestureButtonDown,
+ 1,0,0);
+ xf86PostButtonEvent(priv->local->dev,
+ priv->flags&ABSOLUTE_FLAG,
+ common->wcmGestureButtonDown,
+ 0,0,0);
+ common->wcmGestureButtonDown = 0;
}
+ common->wcmGestureMode = 0;
+ return TRUE;
}
- }
- /* process complex two finger gestures */
- if ((common->wcmGestureTapTime >
- (GetTimeInMillis() - dsLast[0].sample)) &&
- (common->wcmGestureTapTime >
- (GetTimeInMillis() - dsLast[1].sample)))
- {
-
- /* FIXME: Crashes X when emitting Ctrl-Up/Ctrl-Down */
- if (0 && touchDistance(ds[0], ds[1]) >= common->wcmZoomPinchDistance &&
- common->wcmGestureMode != GESTURE_TAP_MODE &&
- common->wcmGestureMode != GESTURE_SCROLL_MODE)
+ else if (common->wcmGestureMode == GESTURE_PASSTHRU_MODE)
{
- /* fingers moved apart more than WACOM_APART_IN_POINT
- * zoom mode is entered */
- if (!common->wcmGestureMode)
+ if (common->wcmGestureButtonDown)
{
- common->wcmGestureMode = GESTURE_ZOOM_MODE;
- xf86WcmSwitchLeftClick(priv);
+ xf86PostButtonEvent(priv->local->dev,
+ priv->flags&ABSOLUTE_FLAG,
+ common->wcmGestureButtonDown,
+ 0,0,0);
+ common->wcmGestureButtonDown = 0;
}
- xf86WcmFingerZoom(priv);
+ common->wcmGestureMode = 0;
+ return channel;
}
-
- if ( pointsInLine(common, ds[0], dsLast[0], &direction) &&
- pointsInLine(common, ds[1], dsLast[1], &direction) &&
- common->wcmGestureMode != GESTURE_ZOOM_MODE &&
- common->wcmGestureMode != GESTURE_TAP_MODE)
+ else
{
- /* send scroll event when both fingers move in
- * the same direction */
- if (!common->wcmGestureMode)
- {
- common->wcmGestureMode = GESTURE_SCROLL_MODE;
- xf86WcmSwitchLeftClick(priv);
- }
- xf86WcmFingerScroll(priv);
+ common->wcmGestureMode = 0;
+ return TRUE;
}
}
-skipGesture:
- /* keep the initial states for both fingers */
- if ( !(common->wcmGestureMode && (GESTURE_SCROLL_MODE | GESTURE_ZOOM_MODE))
- && ds[0].proximity && ds[1].proximity)
+ /* Process one and two finger gestures at same time.
+ * Commit to gesture at wcmGestureTapTime time.
+ */
+ switch (common->wcmGestureMode)
{
- common->wcmGestureState[0] = ds[0];
- common->wcmGestureState[1] = ds[1];
+ case GESTURE_NO_MODE:
+ /* Transition into single finger gesture
+ * mode and store its related state.
+ */
+ common->wcmGestureMode = GESTURE_DETECT_MODE;
+ common->wcmGestureState[0] = ds[0];
+ /* Consume and return because we always need
+ * at least two samples to do next step.
+ */
+ return TRUE;
+ case GESTURE_DETECT_MODE:
+ {
+ int dist = touchDistance(ds[0], common->wcmGestureState[0]);
+
+ if (ds[1].proximity)
+ common->wcmGestureFingers = 2;
+ else
+ common->wcmGestureFingers = 1;
+
+ /* As long as less then 200ms and didn't
+ * move to much, then consume
+ * until we know enough to determine tap
+ * vs. touch.
+ */
+ if ((GetTimeInMillis() - common->wcmGestureState[0].sample) <= common->wcmGestureTapTime &&
+ (dist <= common->wcmGestureTapDistance))
+ return TRUE;
+
+ /* Process no movement case first. */
+ if (dist <= common->wcmGestureTapDistance)
+ {
+
+ common->wcmGestureMode = GESTURE_PASSTHRU_MODE;
+
+ /* For touchscreens, perform a left
+ * button press.
+ */
+ /* FIXME: If we are going to
+ * support Touchscreen button
+ * presses right here then it
+ * looks like duplicate of
+ * (CapacityDefault >= 0)
+ * logic in commonDispatchDevice.
+ * I do not know that code
+ * good enough yet to know were
+ * logic needs to live.
+ */
+ if (priv->flags & ABSOLUTE_FLAG)
+ {
+ if (common->wcmGestureFingers == 1)
+ common->wcmGestureButtonDown = 1;
+ else
+ common->wcmGestureButtonDown = 3;
+
+ /* left button down */
+ xf86PostButtonEvent(priv->local->dev,
+ priv->flags&ABSOLUTE_FLAG,
+ common->wcmGestureButtonDown,
+ 1,0,0);
+ return TRUE;
+ }
+ }
+ else if (common->wcmGestureFingers == 2)
+ {
+ int direction = 0;
+
+ /* Detect if first finger is moving
+ * in a line and then verify
+ * finger two is following same
+ * line.
+ */
+ if (pointsInLine(common, ds[0],
+ dsLast[0],
+ &direction) &&
+ pointsInLine(common, ds[1],
+ dsLast[1],
+ &direction))
+ {
+ if (direction == WACOM_HORIZ_ALLOWED)
+ common->wcmGestureMode = GESTURE_SCROLL_HORZ_MODE;
+ else
+ common->wcmGestureMode = GESTURE_SCROLL_VERT_MODE;
+ xf86WcmFingerScroll(priv);
+ return TRUE;
+ }
+ else if (abs(touchDistance(common->wcmGestureState[0], common->wcmGestureState[1]) - touchDistance(ds[0], ds[1])) > common->wcmGestureZoomDelta)
+ {
+ common->wcmGestureMode = GESTURE_ZOOM_MODE;
+ xf86WcmFingerZoom(priv);
+ }
+ else
+ common->wcmGestureMode = GESTURE_PASSTHRU_MODE;
+ }
+ else
+ common->wcmGestureMode = GESTURE_PASSTHRU_MODE;
+ }
+ break;
+ case GESTURE_PASSTHRU_MODE:
+ /* Only let channel 0 events processed normally. */
+ return channel;
+
+ case GESTURE_SCROLL_HORZ_MODE:
+ case GESTURE_SCROLL_VERT_MODE:
+ {
+ int direction = 0;
+
+ /* Since both fingers will be moving with
+ * this gesture, only process first finger
+ * data to prevent double-sends of
+ * scroll events.
+ * Go ahead and look for invalid range
+ * and abort gesture in that case.
+ */
+ if (channel)
+ {
+ if (!(pointsInLine(common, ds[1], dsLast[1],
+ &direction)))
+ /* Come out of scroll mode */
+ common->wcmGestureMode = GESTURE_PASSTHRU_MODE;
+ return TRUE;
+ }
+
+ /* Since second figure was validated in
+ * its own context, just check validity
+ * first figure now.
+ */
+ if (pointsInLine(common, ds[0], dsLast[0],
+ &direction))
+ xf86WcmFingerScroll(priv);
+ else
+ /* Come out of scroll mode */
+ common->wcmGestureMode = GESTURE_PASSTHRU_MODE;
+ return TRUE;
+ }
+ break;
+ case GESTURE_ZOOM_MODE:
+ xf86WcmFingerZoom(priv);
+
+ return TRUE;
+
+ default:
+ /* Should not happen */
+ common->wcmGestureMode = GESTURE_NO_MODE;
+ return TRUE;
}
+ return FALSE;
}
static void xf86WcmSendScrollEvent(WacomDevicePtr priv, int dist,
@@ -224,6 +354,12 @@ static void xf86WcmSendScrollEvent(WacomDevicePtr priv, int dist,
WacomCommonPtr common = priv->common;
int i = 0;
int button = (dist > 0) ? up :dn;
+ int dist_threshold;
+
+ if (common->wcmGestureMode == GESTURE_SCROLL_VERT_MODE)
+ dist_threshold = common->wcmGestureVertDelta;
+ else
+ dist_threshold = common->wcmGestureHorzDelta;
/* Make sure at least one event happens even if
* distances is negligible.
@@ -231,11 +367,13 @@ static void xf86WcmSendScrollEvent(WacomDevicePtr priv, int dist,
do {
/* button down */
- xf86PostButtonEvent(priv->local->dev, FALSE, button, TRUE, 0, 0);
+ xf86PostButtonEvent(priv->local->dev, priv->flags&ABSOLUTE_FLAG,
+ button, 1, 0, 0);
/* button up */
- xf86PostButtonEvent(priv->local->dev, FALSE, button, FALSE, 0, 0);
+ xf86PostButtonEvent(priv->local->dev, priv->flags&ABSOLUTE_FLAG,
+ button, 0, 0, 0);
i++;
- } while (i < (int)(((double)abs(dist)/(double)common->wcmActivateDistance) + 0.5));
+ } while (i < (int)(((double)abs(dist)/(double)dist_threshold) + 0.5));
}
static void xf86WcmFingerScroll(WacomDevicePtr priv)
@@ -278,11 +416,9 @@ static void xf86WcmFingerScroll(WacomDevicePtr priv)
midPoint_new = (((double)filterd.x[0] + (double)filterd.x[1]) / 2.);
if (pointsInLineAfter(common, midPoint_old, midPoint_new))
{
- midPoint_old = (((double)filterd.y[2] + (double)filterd.y[3]) / 2.);
- midPoint_new = (((double)filterd.y[0] + (double)filterd.y[1]) / 2.);
- dist = midPoint_old - midPoint_new;
+ dist = filterd.y[2] - filterd.y[0];
- if (abs(dist) > common->wcmScrollActivateDistance)
+ if (abs(dist) > common->wcmGestureVertDelta)
{
gesture = 1;
xf86WcmSendScrollEvent(priv, dist,
@@ -296,11 +432,9 @@ static void xf86WcmFingerScroll(WacomDevicePtr priv)
midPoint_new = (((double)filterd.y[0] + (double)filterd.y[1]) / 2.);
if (pointsInLineAfter(common, midPoint_old, midPoint_new))
{
- midPoint_old = (((double)filterd.x[2] + (double)filterd.x[3]) / 2.);
- midPoint_new = (((double)filterd.x[0] + (double)filterd.x[1]) / 2.);
- dist = midPoint_old - midPoint_new;
+ dist = filterd.x[2] - filterd.x[0];
- if (abs(dist) > common->wcmScrollActivateDistance)
+ if (abs(dist) > common->wcmGestureHorzDelta)
{
gesture = 1;
xf86WcmSendScrollEvent(priv, dist,
@@ -322,8 +456,8 @@ static void xf86WcmFingerZoom(WacomDevicePtr priv)
WacomCommonPtr common = priv->common;
WacomChannelPtr firstChannel = common->wcmChannel;
WacomChannelPtr secondChannel = common->wcmChannel + 1;
- WacomDeviceState ds[2] = { firstChannel->valid.states[0],
- secondChannel->valid.states[0] };
+ WacomDeviceState ds[2] = { firstChannel->valid.state,
+ secondChannel->valid.state };
int i = 0;
int direction;
int dist = touchDistance(common->wcmGestureState[0],
@@ -332,18 +466,21 @@ static void xf86WcmFingerZoom(WacomDevicePtr priv)
DBG(10, priv, "\n");
dist = touchDistance(ds[0], ds[1]) - dist;
- direction = (dist > 0) ? XK_plus : XK_minus;
/* zooming? */
- if (abs(dist) > common->wcmActivateDistance)
+ if (abs(dist) > common->wcmGestureZoomDelta)
{
- for (i=0; i<(int)(((double)abs(dist)/
- (double)common->wcmActivateDistance) + 0.5); i++)
+ direction = (dist > 0) ? XK_plus : XK_minus;
+
+ for (i=0; i<=(int)(((double)abs(dist)/
+ (double)common->wcmGestureZoomDelta) + 0.5); i++)
{
+ /*
emitKeysym (priv->local->dev, XK_Control_L, TRUE);
emitKeysym (priv->local->dev, direction, TRUE);
- emitKeysym (priv->local->dev, direction, FALSE);
+ emitKeysym (priv->local->dev, direction, FALSE);
emitKeysym (priv->local->dev, XK_Control_L, FALSE);
+ */
}
/* reset initial states */
diff --git a/src/wcmValidateDevice.c b/src/wcmValidateDevice.c
index ca13b46..18d2a66 100644
--- a/src/wcmValidateDevice.c
+++ b/src/wcmValidateDevice.c
@@ -642,38 +642,12 @@ int wcmParseOptions(LocalDevicePtr local, unsigned long* keys)
common->wcmGestureDefault = 1;
}
- /* Set Bamboo P&T Defaults for gesture size and timeouts.
- * Other hardware uses initialized defaults.
- */
- if (common->tablet_id >= 0xd0 && common->tablet_id <= 0xd3) {
- common->wcmRightClickDistance = 100;
- common->wcmZoomPinchDistance = 350;
- common->wcmActivateDistance = 20;
- common->wcmScrollActivateDistance = 20;
- common->wcmGestureTapTime = 150;
- }
-
- /* Set maximum distance allowed for right click touch gesture */
- common->wcmRightClickDistance =
- xf86SetIntOption(local->options, "RightClickDistance",
- common->wcmRightClickDistance);
-
- /* Set minimum distance allowed for zoom touch gesture */
- common->wcmZoomPinchDistance =
- xf86SetIntOption(local->options, "ZoomPinchDistance",
- common->wcmZoomPinchDistance);
-
- /* Set minimum motion required before sending on a scroll gesture */
- common->wcmActivateDistance =
- xf86SetIntOption(local->options, "ActivateDistance",
- common->wcmActivateDistance);
-
- /* Set min parallel motion required before entering scroll gesture */
- common->wcmScrollActivateDistance =
- xf86SetIntOption(local->options, "ScrollActivateDistance",
- common->wcmScrollActivateDistance);
+ /* Set maximum distance to start a tap gesture */
+ common->wcmGestureTapDistance =
+ xf86SetIntOption(local->options, "GestureTapDistance",
+ common->wcmGestureTapDistance);
- /* Set minimum time between events required to start a gesture */
+ /* Set maximum time allowed to start a gesture */
common->wcmGestureTapTime =
xf86SetIntOption(local->options, "GestureTapTime",
common->wcmGestureTapTime);
diff --git a/src/xf86WacomDefs.h b/src/xf86WacomDefs.h
index 21458db..509c32b 100644
--- a/src/xf86WacomDefs.h
+++ b/src/xf86WacomDefs.h
@@ -427,17 +427,17 @@ struct _WacomCommonRec
int wcmTouch; /* disable/enable touch event */
int wcmTPCButtonDefault; /* Tablet PC button default */
int wcmTouchDefault; /* default to disable when not supported */
- int wcmTouchpadMode; /* in touchpad mdoe? */
- WacomDeviceState wcmTouchpadState; /* initial state in touchpad mode */
int wcmGesture; /* disable/enable touch gesture */
int wcmGestureDefault; /* default touch gesture to disable when not supported */
int wcmGestureMode; /* data is in Gesture Mode? */
WacomDeviceState wcmGestureState[MAX_FINGERS]; /* inital state when in gesture mode */
- int wcmRightClickDistance; /* maximum finger spacing for gesture */
- int wcmZoomPinchDistance; /* minimum to start zoom guesture */
- int wcmActivateDistance; /* minimum motion to start any gestures */
- int wcmScrollActivateDistance; /* minimum to start scroll gesture */
+ int wcmGestureTapDistance; /* maximum distance to start gesture */
int wcmGestureTapTime; /* minimum time to start a gesture */
+ int wcmGestureButtonDown; /* button down from last gesture */
+ int wcmGestureFingers; /* Fingers in proximity at gesture start */
+ int wcmGestureVertDelta; /* Vertical scroll event distance */
+ int wcmGestureHorzDelta; /* Horizonatl scroll event distance */
+ int wcmGestureZoomDelta; /* Pinch Zoom event distance */
int wcmCapacity; /* disable/enable capacity */
int wcmCapacityDefault; /* default to -1 when capacity isn't supported/disabled */
/* 3 when capacity is supported */
--
1.6.6
------------------------------------------------------------------------------
The Planet: dedicated and managed hosting, cloud storage, colocation
Stay online with enterprise data centers and the best network in the business
Choose flexible plans and management services without long-term contracts
Personal 24x7 support from experience hosting pros just a phone call away.
http://p.sf.net/sfu/theplanet-com
_______________________________________________
Linuxwacom-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/linuxwacom-devel