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&#174; 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

Reply via email to