Currently when enabling XI 1.2 multitouch events the Wacom driver does a strange mix of emulating a mouse (when there is only touch) and switches suddenly switches to be a touchscreen when 2 fingers are down.
Change this to only send touch events when using multitouch mode, such that the touchscreen works the same as other touchscreens. This enables applications to properly respond to one finger touches (e.g. panning in GTK+). The X server core will still send emulated input events to applications not supporting multitouch, so there shouldn't be a regression for those applications. Signed-off-by: Sjoerd Simons <sjo...@greynoise.nl> --- src/wcmCommon.c | 8 +++++++- src/wcmTouchFilter.c | 51 +++++++++++++------------------------------------- 2 files changed, 20 insertions(+), 39 deletions(-) diff --git a/src/wcmCommon.c b/src/wcmCommon.c index 1ab2490..5a5921c 100644 --- a/src/wcmCommon.c +++ b/src/wcmCommon.c @@ -970,8 +970,14 @@ void wcmEvent(WacomCommonPtr common, unsigned int channel, if (pChannel->nSamples < common->wcmRawSample) ++pChannel->nSamples; if ((ds.device_type == TOUCH_ID) && common->wcmTouch) + { wcmGestureFilter(priv, ds.serial_num - 1); - +#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 16 + /* When using XI 1.2 multitouch events don't do common dispatching */ + if (!common->wcmGesture) + return; +#endif + } /* For touch, only first finger moves the cursor */ if ((common->wcmTouch && ds.device_type == TOUCH_ID && ds.serial_num == 1) || (ds.device_type != TOUCH_ID)) diff --git a/src/wcmTouchFilter.c b/src/wcmTouchFilter.c index 5e0d349..1720a76 100644 --- a/src/wcmTouchFilter.c +++ b/src/wcmTouchFilter.c @@ -37,7 +37,6 @@ #define GESTURE_LAG_MODE 8 #define GESTURE_PREDRAG_MODE 16 #define GESTURE_DRAG_MODE 32 -#define GESTURE_MULTITOUCH_MODE 64 #define WCM_SCROLL_UP 5 /* vertical up */ #define WCM_SCROLL_DOWN 4 /* vertical down */ @@ -103,12 +102,9 @@ static void getStateHistory(WacomCommonPtr common, WacomDeviceState states[], in * * @param[in] priv * @param[in] channel Channel to send a touch event for - * @param[in] no_update If 'true', TouchUpdate events will not be created. - * This should be used when entering multitouch mode to ensure TouchBegin - * events are sent for already-in-prox contacts. */ static void -wcmSendTouchEvent(WacomDevicePtr priv, WacomChannelPtr channel, Bool no_update) +wcmSendTouchEvent(WacomDevicePtr priv, WacomChannelPtr channel) { #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 16 ValuatorMask *mask = priv->common->touch_mask; @@ -123,7 +119,7 @@ wcmSendTouchEvent(WacomDevicePtr priv, WacomChannelPtr channel, Bool no_update) DBG(6, priv->common, "This is a touch end event\n"); type = XI_TouchEnd; } - else if (!oldstate.proximity || no_update) { + else if (!oldstate.proximity) { DBG(6, priv->common, "This is a touch begin event\n"); type = XI_TouchBegin; } @@ -147,35 +143,18 @@ wcmSendTouchEvent(WacomDevicePtr priv, WacomChannelPtr channel, Bool no_update) */ static void wcmFingerMultitouch(WacomDevicePtr priv, int contact_id) { - Bool lag_mode = priv->common->wcmGestureMode == GESTURE_LAG_MODE; - Bool prox = FALSE; int i; - if (lag_mode && TabletHasFeature(priv->common, WCM_LCD)) { - /* wcmSingleFingerPress triggers a button press as - * soon as a single finger appears. ensure we release - * that button before getting too far along - */ - wcmSendButtonClick(priv, 1, 0); - } - for (i = 0; i < MAX_CHANNELS; i++) { WacomChannelPtr channel = priv->common->wcmChannel+i; WacomDeviceState state = channel->valid.state; if (state.device_type != TOUCH_ID) continue; - if (lag_mode || state.serial_num == contact_id + 1) { - wcmSendTouchEvent(priv, channel, lag_mode); + if (state.serial_num == contact_id + 1) { + wcmSendTouchEvent(priv, channel); } - - prox |= state.proximity; } - - if (!prox) - priv->common->wcmGestureMode = GESTURE_NONE_MODE; - else if (lag_mode) - priv->common->wcmGestureMode = GESTURE_MULTITOUCH_MODE; } static double touchDistance(WacomDeviceState ds0, WacomDeviceState ds1) @@ -373,6 +352,15 @@ void wcmGestureFilter(WacomDevicePtr priv, int touch_id) WacomCommonPtr common = priv->common; WacomDeviceState ds[2] = {{0}}, dsLast[2] = {{0}}; +#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 16 + /* Send multitouch data to X if appropriate */ + if (!common->wcmGesture) + { + wcmFingerMultitouch(priv, touch_id); + return; + } +#endif + getStateHistory(common, ds, ARRAY_SIZE(ds), 0); getStateHistory(common, dsLast, ARRAY_SIZE(dsLast), 1); @@ -386,9 +374,6 @@ void wcmGestureFilter(WacomDevicePtr priv, int touch_id) return; } - if (common->wcmGestureMode == GESTURE_MULTITOUCH_MODE) - goto ret; - /* When 2 fingers are in proximity, it must always be in one of * the valid 2 fingers modes: LAG, SCROLL, or ZOOM. * LAG mode is used while deciding between SCROLL and ZOOM and @@ -521,16 +506,6 @@ void wcmGestureFilter(WacomDevicePtr priv, int touch_id) } ret: -#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 16 - /* Send multitouch data to X if appropriate */ - if (!common->wcmGesture && ds[1].proximity && common->wcmGestureMode == GESTURE_NONE_MODE) - common->wcmGestureMode = GESTURE_LAG_MODE; - if (!common->wcmGesture && (common->wcmGestureMode == GESTURE_LAG_MODE || - common->wcmGestureMode == GESTURE_MULTITOUCH_MODE)) { - wcmFingerMultitouch(priv, touch_id); - } -#endif - if ((common->wcmGestureMode == GESTURE_NONE_MODE || common->wcmGestureMode == GESTURE_DRAG_MODE) && touch_id == 0) { -- 1.7.10.4 ------------------------------------------------------------------------------ Try New Relic Now & We'll Send You this Cool Shirt New Relic is the only SaaS-based application performance monitoring service that delivers powerful full stack analytics. Optimize and monitor your browser, app, & servers with just a few lines of code. Try New Relic and get this awesome Nerd Life shirt! http://p.sf.net/sfu/newrelic_d2d_may _______________________________________________ Linuxwacom-devel mailing list Linuxwacom-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linuxwacom-devel