summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Gerecke <jason.gerecke@wacom.com>2019-09-09 14:43:45 -0700
committerGitHub <noreply@github.com>2019-09-09 14:43:45 -0700
commitef943197cc912f782412dcbe02aac92a8fb4d61f (patch)
tree577948e9c90b55b271ee6e69fb7dbf9337320114
parent0ac49a26d25279b7777239066aff8e1f5f23bd4b (diff)
parenta38074dcfb2350c0253ae4ac3c3745c4977596e5 (diff)
downloadxf86-input-wacom-ef943197cc912f782412dcbe02aac92a8fb4d61f.tar.gz
Merge pull request #77 from jigpu/issue-43
Improve gesture recognition and usability Reviewed-by: Aaron Armstrong Skomra <aaron.skomra@wacom.com>
-rw-r--r--src/wcmTouchFilter.c109
-rw-r--r--src/wcmValidateDevice.c22
-rw-r--r--src/xf86WacomDefs.h1
3 files changed, 65 insertions, 67 deletions
diff --git a/src/wcmTouchFilter.c b/src/wcmTouchFilter.c
index 423a893..41baa12 100644
--- a/src/wcmTouchFilter.c
+++ b/src/wcmTouchFilter.c
@@ -189,6 +189,22 @@ static double touchDistance(WacomDeviceState ds0, WacomDeviceState ds1)
return distance;
}
+static Bool vectorsSameDirection(WacomCommonPtr common, WacomDeviceState ds00,
+ WacomDeviceState ds01, WacomDeviceState ds10, WacomDeviceState ds11)
+{
+ float dx0 = ds01.x - ds00.x;
+ float dy0 = ds01.y - ds00.y;
+ float m0 = sqrt(dx0*dx0 + dy0*dy0);
+ float dx1 = ds11.x - ds10.x;
+ float dy1 = ds11.y - ds10.y;
+ float m1 = sqrt(dx1*dx1 + dy1*dy1);
+
+ float dot = (dx0/m0 * dx1/m1) + (dy0/m0 * dy1/m1);
+ float angle = acos(dot);
+
+ return angle < (3.141592f / 2);
+}
+
static Bool pointsInLine(WacomCommonPtr common, WacomDeviceState ds0,
WacomDeviceState ds1)
{
@@ -199,18 +215,18 @@ static Bool pointsInLine(WacomCommonPtr common, WacomDeviceState ds0,
WACOM_HORIZ_ALLOWED : WACOM_VERT_ALLOWED;
int vertical_rotated = (rotated) ?
WACOM_VERT_ALLOWED : WACOM_HORIZ_ALLOWED;
- int max_spread = common->wcmGestureParameters.wcmMaxScrollFingerSpread;
+ int scroll_threshold = common->wcmGestureParameters.wcmScrollDistance;
if (!common->wcmGestureParameters.wcmScrollDirection)
{
- if ((abs(ds0.x - ds1.x) < max_spread) &&
- (abs(ds0.y - ds1.y) > max_spread))
+ if ((abs(ds0.x - ds1.x) < scroll_threshold) &&
+ (abs(ds0.y - ds1.y) > scroll_threshold))
{
common->wcmGestureParameters.wcmScrollDirection = horizon_rotated;
ret = TRUE;
}
- if ((abs(ds0.y - ds1.y) < max_spread) &&
- (abs(ds0.x - ds1.x) > max_spread))
+ if ((abs(ds0.y - ds1.y) < scroll_threshold) &&
+ (abs(ds0.x - ds1.x) > scroll_threshold))
{
common->wcmGestureParameters.wcmScrollDirection = vertical_rotated;
ret = TRUE;
@@ -218,12 +234,12 @@ static Bool pointsInLine(WacomCommonPtr common, WacomDeviceState ds0,
}
else if (common->wcmGestureParameters.wcmScrollDirection == vertical_rotated)
{
- if (abs(ds0.y - ds1.y) < max_spread)
+ if (abs(ds0.y - ds1.y) < scroll_threshold)
ret = TRUE;
}
else if (common->wcmGestureParameters.wcmScrollDirection == horizon_rotated)
{
- if (abs(ds0.x - ds1.x) < max_spread)
+ if (abs(ds0.x - ds1.x) < scroll_threshold)
ret = TRUE;
}
return ret;
@@ -435,6 +451,14 @@ void wcmGestureFilter(WacomDevicePtr priv, int touch_id)
if (common->wcmGestureMode == GESTURE_NONE_MODE)
common->wcmGestureMode = GESTURE_LAG_MODE;
}
+ /* If we're in a multitouch mode but two fingers aren't in proximity
+ * we should directly head to CANCEL mode and wait for both fingers
+ * to leave the screen.
+ */
+ else if (common->wcmGestureMode & (GESTURE_SCROLL_MODE | GESTURE_ZOOM_MODE))
+ {
+ common->wcmGestureMode = GESTURE_CANCEL_MODE;
+ }
/* When only 1 finger is in proximity, it can be in either LAG mode,
* NONE mode or DRAG mode.
* 1 finger LAG mode is a very short time period mainly to debounce
@@ -517,7 +541,7 @@ void wcmGestureFilter(WacomDevicePtr priv, int touch_id)
goto ret;
}
- if (!(common->wcmGestureMode & (GESTURE_SCROLL_MODE | GESTURE_ZOOM_MODE)) && touch_id == 1)
+ if ((common->wcmGestureMode & GESTURE_LAG_MODE) && touch_id == 1)
wcmFingerTapToClick(priv);
/* Change mode happens only when both fingers are out */
@@ -528,23 +552,18 @@ void wcmGestureFilter(WacomDevicePtr priv, int touch_id)
if (!dsLast[0].proximity || !dsLast[1].proximity)
goto ret;
- /* was in zoom mode no time check needed */
+ /* continue zooming if already in zoom mode */
if ((common->wcmGestureMode & GESTURE_ZOOM_MODE) &&
ds[0].proximity && ds[1].proximity)
wcmFingerZoom(priv);
- /* was in scroll mode no time check needed */
+ /* continue scrollling if already in scroll mode */
else if (common->wcmGestureMode & GESTURE_SCROLL_MODE)
wcmFingerScroll(priv);
/* process complex two finger gestures */
else {
- CARD32 ms = GetTimeInMillis();
- int taptime = common->wcmGestureParameters.wcmTapTime;
-
- if (ds[0].proximity && ds[1].proximity &&
- (taptime < (ms - ds[0].sample)) &&
- (taptime < (ms - ds[1].sample)))
+ if (ds[0].proximity && ds[1].proximity)
{
/* scroll should be considered first since it requires
* a finger distance check */
@@ -586,7 +605,7 @@ static void wcmSendScrollEvent(WacomDevicePtr priv, int dist,
int button = (dist > 0) ? buttonUp : buttonDn;
WacomCommonPtr common = priv->common;
int count = (int)((1.0 * abs(dist)/
- common->wcmGestureParameters.wcmScrollDistance) + 0.5);
+ common->wcmGestureParameters.wcmScrollDistance));
WacomDeviceState ds[2] = {};
getStateHistory(common, ds, ARRAY_SIZE(ds), 0);
@@ -614,12 +633,13 @@ static void wcmFingerScroll(WacomDevicePtr priv)
{
WacomCommonPtr common = priv->common;
WacomDeviceState ds[2] = {};
+ WacomDeviceState *start = common->wcmGestureState;
int midPoint_new = 0;
int midPoint_old = 0;
int i = 0, dist = 0;
WacomFilterState filterd; /* borrow this struct */
- int max_spread = common->wcmGestureParameters.wcmMaxScrollFingerSpread;
- int gestureStart = 0;
+ int max_spread = common->wcmGestureParameters.wcmZoomDistance;
+ int spread;
if (!common->wcmGesture)
return;
@@ -628,23 +648,23 @@ static void wcmFingerScroll(WacomDevicePtr priv)
DBG(10, priv, "\n");
+ spread = fabs(touchDistance(ds[0], ds[1]) - touchDistance(start[0], start[1]));
+
if (common->wcmGestureMode != GESTURE_SCROLL_MODE)
{
- if (fabs(touchDistance(ds[0], ds[1]) -
- touchDistance(common->wcmGestureState[0],
- common->wcmGestureState[1])) < max_spread)
+ if (spread < max_spread)
{
/* two fingers stay close to each other all the time and
* move in vertical or horizontal direction together
*/
- if (pointsInLine(common, ds[0], common->wcmGestureState[0])
- && pointsInLine(common, ds[1], common->wcmGestureState[1])
- && common->wcmGestureParameters.wcmScrollDirection)
+ if (pointsInLine(common, ds[0], start[0])
+ && pointsInLine(common, ds[1], start[1])
+ && common->wcmGestureParameters.wcmScrollDirection
+ && vectorsSameDirection(common, ds[0], start[0], ds[1], start[1]))
{
/* left button might be down. Send it up first */
wcmSendButtonClick(priv, 1, 0);
common->wcmGestureMode = GESTURE_SCROLL_MODE;
- gestureStart = 1;
}
}
}
@@ -653,13 +673,6 @@ static void wcmFingerScroll(WacomDevicePtr priv)
if (common->wcmGestureMode != GESTURE_SCROLL_MODE)
return;
- /* forget history leading up to the beginning of the gesture */
- if (gestureStart)
- {
- common->wcmGestureState[0] = ds[0];
- common->wcmGestureState[1] = ds[1];
- }
-
/* initialize the points so we can rotate them */
filterd.x[0] = ds[0].x;
filterd.y[0] = ds[0].y;
@@ -724,10 +737,12 @@ static void wcmFingerZoom(WacomDevicePtr priv)
{
WacomCommonPtr common = priv->common;
WacomDeviceState ds[2] = {};
+ WacomDeviceState *start = common->wcmGestureState;
int count, button;
- int dist;
- int max_spread = common->wcmGestureParameters.wcmMaxScrollFingerSpread;
- int gestureStart = 0;
+ int dist = touchDistance(common->wcmGestureState[0],
+ common->wcmGestureState[1]);
+ int max_spread = common->wcmGestureParameters.wcmZoomDistance;
+ int spread;
if (!common->wcmGesture)
return;
@@ -736,36 +751,24 @@ static void wcmFingerZoom(WacomDevicePtr priv)
DBG(10, priv, "\n");
+ spread = fabs(touchDistance(ds[0], ds[1]) - touchDistance(start[0], start[1]));
+
if (common->wcmGestureMode != GESTURE_ZOOM_MODE)
{
/* two fingers moved apart from each other */
- if (fabs(touchDistance(ds[0], ds[1]) -
- touchDistance(common->wcmGestureState[0],
- common->wcmGestureState[1])) >
- (3 * max_spread))
+ if (spread > max_spread)
{
/* left button might be down, send it up first */
wcmSendButtonClick(priv, 1, 0);
-
- /* fingers moved apart more than 3 times
- * wcmMaxScrollFingerSpread, zoom mode is entered */
common->wcmGestureMode = GESTURE_ZOOM_MODE;
- gestureStart = 1;
}
}
if (common->wcmGestureMode != GESTURE_ZOOM_MODE)
return;
- /* forget history leading up to the beginning of the gesture */
- if (gestureStart)
- {
- common->wcmGestureState[0] = ds[0];
- common->wcmGestureState[1] = ds[1];
- }
-
- dist = touchDistance(ds[0], ds[1]) - touchDistance(common->wcmGestureState[0], common->wcmGestureState[1]);
- count = (int)((1.0 * abs(dist)/common->wcmGestureParameters.wcmZoomDistance) + 0.5);
+ dist = touchDistance(ds[0], ds[1]) - dist;
+ count = (int)((1.0 * abs(dist)/common->wcmGestureParameters.wcmZoomDistance));
/* user might have changed from left to right or vice versa */
if (count < common->wcmGestureParameters.wcmGestureUsed)
diff --git a/src/wcmValidateDevice.c b/src/wcmValidateDevice.c
index dda2fff..a389c81 100644
--- a/src/wcmValidateDevice.c
+++ b/src/wcmValidateDevice.c
@@ -1064,11 +1064,11 @@ error:
return FALSE;
}
-/* The values were based on trail and error. */
-#define WCM_BAMBOO3_MAXX 4096.0
-#define WCM_BAMBOO3_ZOOM_DISTANCE 180.0
-#define WCM_BAMBOO3_SCROLL_DISTANCE 80.0
-#define WCM_BAMBOO3_SCROLL_SPREAD_DISTANCE 350.0
+/* The values were based on trial and error with a 3rd-gen Bamboo */
+#define WCM_DEFAULT_MM_XRES (27.8 * 1000)
+#define WCM_DEFAULT_MM_YRES (44.5 * 1000)
+#define WCM_ZOOM_DISTANCE_MM 6.5
+#define WCM_SCROLL_DISTANCE_MM 1.8
/**
* Parse post-init options for this device. Useful for overriding HW
@@ -1095,10 +1095,10 @@ Bool wcmPostInitParseOptions(InputInfoPtr pInfo, Bool is_primary,
/* 2FG touch device */
if (TabletHasFeature(common, WCM_2FGT) && IsTouch(priv))
{
- int zoom_distance = common->wcmMaxTouchX *
- (WCM_BAMBOO3_ZOOM_DISTANCE / WCM_BAMBOO3_MAXX);
- int scroll_distance = common->wcmMaxTouchX *
- (WCM_BAMBOO3_SCROLL_DISTANCE / WCM_BAMBOO3_MAXX);
+ int x_res = common->wcmTouchResolX ? common->wcmTouchResolX : WCM_DEFAULT_MM_XRES;
+ int y_res = common->wcmTouchResolY ? common->wcmTouchResolY : WCM_DEFAULT_MM_YRES;
+ int zoom_distance = WCM_ZOOM_DISTANCE_MM * x_res / 1000;
+ int scroll_distance = WCM_SCROLL_DISTANCE_MM * y_res / 1000;
common->wcmGestureParameters.wcmZoomDistance =
xf86SetIntOption(pInfo->options, "ZoomDistance",
@@ -1107,10 +1107,6 @@ Bool wcmPostInitParseOptions(InputInfoPtr pInfo, Bool is_primary,
common->wcmGestureParameters.wcmScrollDistance =
xf86SetIntOption(pInfo->options, "ScrollDistance",
scroll_distance);
-
- common->wcmGestureParameters.wcmMaxScrollFingerSpread =
- common->wcmMaxTouchX *
- (WCM_BAMBOO3_SCROLL_SPREAD_DISTANCE / WCM_BAMBOO3_MAXX);
}
diff --git a/src/xf86WacomDefs.h b/src/xf86WacomDefs.h
index cab3abf..566211e 100644
--- a/src/xf86WacomDefs.h
+++ b/src/xf86WacomDefs.h
@@ -375,7 +375,6 @@ typedef struct {
int wcmZoomDistance; /* minimum distance for a zoom touch gesture */
int wcmScrollDistance; /* minimum motion before sending a scroll gesture */
int wcmScrollDirection; /* store the vertical or horizontal bit in use */
- int wcmMaxScrollFingerSpread; /* maximum distance between fingers for scroll gesture */
int wcmGestureUsed; /* retain used gesture count within one in-prox event */
int wcmTapTime; /* minimum time between taps for a right click */
} WacomGesturesParameters;