Hi Chris,
Thank you for sharing your thoughts. I see the beauty of your state
machine. I am still in -11, which I would like to push out first.
Ping
On Wed, Mar 3, 2010 at 6:38 PM, Chris Bagwell <ch...@cnpbagwell.com> wrote:
>
> /* 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 wcmTouchFilter(WacomCommonPtr common, WacomDevicePtr priv,
> unsigned int channel)
> {
> WacomChannelPtr firstChannel = common->wcmChannel;
> WacomChannelPtr secondChannel = common->wcmChannel + 1;
> WacomDeviceState ds[2] = { firstChannel->valid.state,
> secondChannel->valid.state };
> WacomDeviceState dsLast[2] = { firstChannel->valid.states[1],
> secondChannel->valid.states[1] };
>
> if (!IsTouch(priv))
> {
> /* this should never happen */
> xf86Msg(X_ERROR, "WACOM: No touch device found for %s \n",
> common->wcmDevice);
> return TRUE;
> }
>
> 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)
> {
> if (common->wcmGestureMode == GESTURE_DETECT_MODE)
> {
> /* In relative mode, we met condition
> * to send button down. */
> if (!(priv->flags & ABSOLUTE_FLAG))
> {
> /* 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;
> }
> else if (common->wcmGestureMode == GESTURE_PASSTHRU_MODE)
> {
> if (common->wcmGestureButtonDown)
> {
> xf86PostButtonEvent(priv->local->dev,
>
> priv->flags&ABSOLUTE_FLAG,
>
> common->wcmGestureButtonDown,
> 0,0,0);
> common->wcmGestureButtonDown = 0;
> }
> common->wcmGestureMode = 0;
> return channel;
> }
> else
> common->wcmGestureMode = 0;
> return TRUE;
> }
>
> /* Process one and two finger gestures at same time.
> * Commit to gesture at wcmGestureTapTime time.
> */
> switch (common->wcmGestureMode)
> {
> 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.
> */
> case GESTURE_DETECT_MODE:
> {
> int dist = touchDistance(ds[0],
> common->wcmGestureState[0]);
>
> if (ds[1].proximity)
> common->wcmGestureFingers = 2;
> else
> common->wcmGestureFingers = 1;
>
> /* Store initial second finger state */
> if (ds[1].proximity && !dsLast[1].proximity)
> common->wcmGestureState[1] = ds[1];
>
> /* As long as less then 200ms and didn't
> * move to much, then consume event
> * 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);
> }
> }
> else if (common->wcmGestureFingers == 2)
> {
> int direction = 0;
>
> /* Detect if first finger is moving
> * in a line and then verify
> * finger two is following the same
> * line.
> */
> if (pointsInLine(common, ds[0],
>
> common->wcmGestureState[0],
> &direction) &&
> pointsInLine(common, ds[1],
>
> common->wcmGestureState[1],
> &direction))
> {
> if (direction ==
> WACOM_HORIZ_POS || direction == WACOM_HORIZ_NEG)
>
> common->wcmGestureMode = GESTURE_SCROLL_HORZ_MODE;
> else
>
> common->wcmGestureMode = GESTURE_SCROLL_VERT_MODE;
> wcmFingerScroll(priv);
> }
> else if
> (abs(touchDistance(common->wcmGestureState[0],
> common->wcmGestureState[1]) - touchDistance(ds[0], ds[1])) >
> common->wcmGestureZoomDelta)
> {
> common->wcmGestureMode =
> GESTURE_ZOOM_MODE;
> wcmFingerZoom(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],
> common->wcmGestureState[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],
> common->wcmGestureState[0],
> &direction))
> wcmFingerScroll(priv);
> else
> /* Come out of scroll mode */
> common->wcmGestureMode =
> GESTURE_PASSTHRU_MODE;
> }
> break;
> case GESTURE_ZOOM_MODE:
> wcmFingerZoom(priv);
> break;
>
> default:
> /* Should not happen */
> common->wcmGestureMode = GESTURE_NO_MODE;
> break;
> }
> return TRUE;
> }
>
------------------------------------------------------------------------------
Download Intel® Parallel Studio Eval
Try the new software tools for yourself. Speed compiling, find bugs
proactively, and fine-tune applications for parallel performance.
See why Intel Parallel Studio got high marks during beta.
http://p.sf.net/sfu/intel-sw-dev
_______________________________________________
Linuxwacom-devel mailing list
Linuxwacom-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxwacom-devel