On Sun, Dec 18, 2011 at 10:06 PM, Peter Hutterer
<peter.hutte...@who-t.net> wrote:
> On Tue, Dec 13, 2011 at 01:59:02PM -0800, Jason Gerecke wrote:
>> Replaces sendWheelStripEvents and getWheelButton with several
>> small functions to reduce unnecessary code duplication.
>>
>> As a side-effect, it is now possible for the driver to handle
>> simultaneous scrolls on multiple axes. Previously, getWheelButton
>> would go through all the axes but was limited to returning a
>> single button/action.
>>
>> Signed-off-by: Jason Gerecke <killert...@gmail.com>
>
> thanks! this patch makes it messy, but at least removes the copy/paste.
It'd be nice if there were a 'tunable' diff that let you adjust how it
matches subsequences... Patience diff is usually pretty good, but even
it coughed up a mess for this particular patch. Its not that bad of a
patch when done by hand, but the algorithms get caught up matching the
wrong bits of "common" text. :(

> aside from the comments below, please reshuffle this one so it applies
> _before_ the other one in the series. short story: this way we can bisect
> down to check if this patch broke anything on its own before the new feature
> was added.
>
That's actually the reason I put it as the final patch instead of
somewhere in the middle. Though, I suppose I can put it at the
beginning of sequence as well.

> coincidentally, writing tests for these so they keep exhibiting the same
> behaviour would be great...
>
Good call -- I always seem to forget that bit when adding new
functions. I'll whip some up during the rebase.

>> ---
>>  src/wcmCommon.c |  206 
>> ++++++++++++++++++++++++++++++++-----------------------
>>  1 files changed, 121 insertions(+), 85 deletions(-)
>>
>> diff --git a/src/wcmCommon.c b/src/wcmCommon.c
>> index 0e719cf..170d1d0 100644
>> --- a/src/wcmCommon.c
>> +++ b/src/wcmCommon.c
>> @@ -317,98 +317,106 @@ static void sendAButton(InputInfoPtr pInfo, int 
>> button, int mask,
>>                  first_val, num_val, valuators);
>>  }
>>
>> -/*****************************************************************************
>> - * getWheelButton --
>> - *   Get the wheel button to be sent for the current device state.
>> - 
>> ****************************************************************************/
>> -
>> -static int getWheelButton(InputInfoPtr pInfo, const WacomDeviceState* ds,
>> -                       unsigned int **fakeKey)
>> +/**
>> + * Get the distance an axis was scrolled. This function is aware
>> + * of the different ways different scrolling axes work and strives
>> + * to produce a common representation of relative change.
>> + *
>> + * @param current  Current value of the axis
>> + * @param old      Previous value of the axis
>> + * @param wrap     Value after which wraparound occurs (0 if axis does not 
>> wrap)
>> + * @param invert   Scroll axis is inverted
>> + * @param bitwise  Scroll axis values change in a bitwise manner
>> + * @return         Relative change in axis value
>> + */
>> +static int getScrollDelta(int current, int old, int wrap, Bool invert, Bool 
>> bitwise)
>
> I'd really like either a usage of flags or enums here so that the code is
> easier to read.
>        delta = getScrollDelta(ds->stripx, priv->oldStripX, 0, TRUE, TRUE);
> is not at all obvious, getScrollDelta(..., INVERT|BITWISE) would be.
>
Flags work for me.

>>  {
>> -     WacomDevicePtr priv = (WacomDevicePtr) pInfo->private;
>> -     int fakeButton = 0, value = 0;
>> +     int delta;
>>
>> -     /* emulate events for relative wheel */
>> -     if ( ds->relwheel )
>> +     if (bitwise)
>>       {
>> -             value = ds->relwheel;
>> -             fakeButton = (value > 0) ? priv->relup : priv->reldn;
>> -             *fakeKey = (value > 0) ? priv->wheel_keys[0+1] : 
>> priv->wheel_keys[1+1];
>> +             current = (int)log2(current);
>> +             old = (int)log2(old);
>>       }
>>
>> -     /* emulate events for absolute wheel when it is a touch ring (on pad) 
>> */
>> -     if ( (ds->abswheel != priv->oldWheel) && IsPad(priv) &&
>> -         (priv->oldProximity == ds->proximity))
>> -     {
>> -             int wrap_delta;
>> -             value = priv->oldWheel - ds->abswheel;
>> -
>> -             /* Wraparound detection. If the distance oldvalue..value is
>> -              * larger than the oldvalue..value considering the
>> -              * wraparound, assume wraparound and readjust */
>> -             if (value < 0)
>> -                     wrap_delta = ((MAX_PAD_RING + 1) + priv->oldWheel) - 
>> ds->abswheel;
>> -             else
>> -                     wrap_delta = priv->oldWheel - ((MAX_PAD_RING + 1) + 
>> ds->abswheel);
>> +     delta = current - old;
>>
>> -             DBG(12, priv, "wrap detection for %d (old %d): %d (wrap %d)\n",
>> -                 ds->abswheel, priv->oldWheel, value, wrap_delta);
>> +     if (invert)
>> +             delta = -delta;
>>
>> -             if (abs(wrap_delta) < abs(value))
>> -                     value = wrap_delta;
>> -
>> -             fakeButton = (value > 0) ? priv->wheelup : priv->wheeldn;
>> -             *fakeKey = (value > 0) ? priv->wheel_keys[2+1] : 
>> priv->wheel_keys[3+1];
>> -     }
>> -
>> -     /* emulate events for 2nd absolute wheel when it is a touch ring (on 
>> pad) */
>> -     if ( (ds->abswheel2 != priv->oldWheel2) && IsPad(priv) &&
>> -         (priv->oldProximity == ds->proximity))
>> +     if (wrap != 0)
>>       {
>> +             /* Wraparound detection. If the distance old..current
>> +              * is larger than the old..current considering the
>> +              * wraparound, assume wraparound and readjust */
>>               int wrap_delta;
>> -             value = priv->oldWheel2 - ds->abswheel2;
>>
>> -             /* Wraparound detection. If the distance oldvalue..value is
>> -              * larger than the oldvalue..value considering the
>> -              * wraparound, assume wraparound and readjust */
>> -             if (value < 0)
>> -                     wrap_delta = ((MAX_PAD_RING + 1) + priv->oldWheel2) - 
>> ds->abswheel2;
>> +             if (delta < 0)
>> +                     wrap_delta = (wrap + 1) + delta;
>>               else
>> -                     wrap_delta = priv->oldWheel2 - ((MAX_PAD_RING + 1) + 
>> ds->abswheel2);
>> +                     wrap_delta = -((wrap + 1) - delta);
>>
>> -             DBG(12, priv, "wrap detection for %d (old %d): %d (wrap %d)\n",
>> -                 ds->abswheel2, priv->oldWheel2, value, wrap_delta);
>> +             if (abs(wrap_delta) < abs(delta))
>> +                     delta = wrap_delta;
>> +     }
>>
>> -             if (abs(wrap_delta) < abs(value))
>> -                     value = wrap_delta;
>> +     return delta;
>> +}
>>
>> -             fakeButton = (value > 0) ? priv->wheel2up : priv->wheel2dn;
>> -             *fakeKey = (value > 0) ? priv->wheel_keys[4+1] : 
>> priv->wheel_keys[5+1];
>> -     }
>> +/**
>> + * Get the scroll button/action to send given the delta of
>> + * the scrolling axis and the possible events that can be
>> + * sent.
>> + *
>> + * @param delta        Amount of change in the scrolling axis
>> + * @param button_up    Button event to send on scroll up
>> + * @param button_dn    Button event to send on scroll down
>> + * @param action_up    Action to send on scroll up
>> + * @param action_dn    Action to send on scroll down
>> + * @param[out] action  Action that should be performed
>> + * @return             Button that should be pressed
>> + */
>> +static int getWheelButton(int delta, int button_up, int button_dn,
>> +                          unsigned int *action_up, unsigned int *action_dn,
>> +                          unsigned int **action)
>> +{
>> +     int button = 0;
>> +     *action = NULL;
>>
>> -     /* emulate events for left strip */
>> -     if ( ds->stripx != priv->oldStripX )
>> +     if (delta)
>>       {
>> -             value = ds->stripx - priv->oldStripX;
>> -
>> -             fakeButton = (value < 0) ? priv->striplup : priv->stripldn;
>> -             *fakeKey = (value < 0) ? priv->strip_keys[0+1] : 
>> priv->strip_keys[1+1];
>> +             button  = delta > 0 ? button_up : button_dn;
>> +             *action = delta > 0 ? action_up : action_dn;
>>       }
>>
>> -     /* emulate events for right strip */
>> -     if ( ds->stripy != priv->oldStripY )
>> -     {
>> -             value = ds->stripy - priv->oldStripY;
>> +     return button;
>> +}
>>
>> -             fakeButton = (value < 0) ? priv->striprup : priv->striprdn;
>> -             *fakeKey = (value < 0) ? priv->strip_keys[2+1] : 
>> priv->strip_keys[3+1];
>> -     }
>> +/**
>> + * Send button or actions for a scrolling axis.
>> + *
>> + * @param button     X button number to send if no action is defined
>> + * @param action     Action to send
>> + * @param pInfo
>> + * @param first_val
>> + * @param num_vals
>> + * @param valuators
>> + */
>> +static void sendWheelStripEvent(int button, unsigned int *action, 
>> InputInfoPtr pInfo,
>> +                                 int first_val, int num_vals, int 
>> *valuators)
>> +{
>> +     WacomDevicePtr priv = (WacomDevicePtr) pInfo->private;
>>
>> -     DBG(10, priv, "send fakeButton %x with value = %d \n",
>> -             fakeButton, value);
>> +     unsigned int button_action[1] = {button | AC_BUTTON | AC_KEYBTNPRESS};
>> +     if (!action || !(*action)) {
>> +             DBG(10, priv, "No wheel/strip action set; sending button %d 
>> (action %d).\n", button, button_action[0]);
>> +             action = &button_action[0];
>> +     }
>>
>> -     return fakeButton;
>> +     sendAction(pInfo, 1, action, ARRAY_SIZE(action), first_val, num_vals, 
>> valuators);
>> +     sendAction(pInfo, 0, action, ARRAY_SIZE(action), first_val, num_vals, 
>> valuators);
>>  }
>> +
>>  /*****************************************************************************
>>   * sendWheelStripEvents --
>>   *   Send events defined for relative/absolute wheels or strips
>> @@ -418,31 +426,59 @@ static void sendWheelStripEvents(InputInfoPtr pInfo, 
>> const WacomDeviceState* ds,
>>                                int first_val, int num_vals, int *valuators)
>>  {
>>       WacomDevicePtr priv = (WacomDevicePtr) pInfo->private;
>> -     int fakeButton = 0;
>> +     int fakeButton = 0, delta = 0;
>>       unsigned int *fakeKey = NULL;
>>
>>       DBG(10, priv, "\n");
>>
>> -     fakeButton = getWheelButton(pInfo, ds, &fakeKey);
>> +     /* emulate events for left strip */
>> +     delta = getScrollDelta(ds->stripx, priv->oldStripX, 0, TRUE, TRUE);
>> +     if (delta && IsPad(priv) && priv->oldProximity == ds->proximity)
>> +     {
>> +             DBG(10, priv, "Left touch strip scroll delta = %d\n", delta);
>> +             fakeButton = getWheelButton(delta, priv->striplup, 
>> priv->stripldn,
>> +                                         priv->strip_keys[0+1], 
>> priv->strip_keys[1+1], &fakeKey);
>
> urgh, named defines for the indices please. which would prevent...
>
>> +             sendWheelStripEvent(fakeButton, fakeKey, pInfo, first_val, 
>> num_vals, valuators);
>> +     }
>>
>> -     if (!fakeButton && (!fakeKey || !(*fakeKey)))
>> -             return;
>> +     /* emulate events for right strip */
>> +     delta = getScrollDelta(ds->stripy, priv->oldStripY, 0, TRUE, TRUE);
>> +     if (delta && IsPad(priv) && priv->oldProximity == ds->proximity)
>> +     {
>> +             DBG(10, priv, "Right touch strip scroll delta = %d\n", delta);
>> +             fakeButton = getWheelButton(delta, priv->striprup, 
>> priv->striprdn,
>> +                                         priv->strip_keys[2+1], 
>> priv->strip_keys[3+1], &fakeKey);
>> +             sendWheelStripEvent(fakeButton, fakeKey, pInfo, first_val, 
>> num_vals, valuators);
>> +     }
>>
>> -     if (!fakeKey || !(*fakeKey))
>> +     /* emulate events for relative wheel */
>> +     delta = getScrollDelta(ds->relwheel, 0, 0, FALSE, FALSE);
>> +     if (delta && IsCursor(priv) && priv->oldProximity == ds->proximity)
>>       {
>> -             /* send both button on/off in the same event for pad */
>> -             xf86PostButtonEventP(pInfo->dev, is_absolute(pInfo), 
>> fakeButton & AC_CODE,
>> -                                  1, first_val, num_vals, VCOPY(valuators, 
>> num_vals));
>> +             DBG(10, priv, "Relative wheel scroll delta = %d\n", delta);
>> +             fakeButton = getWheelButton(delta, priv->relup, priv->reldn,
>> +                                         priv->wheel_keys[0+1], 
>> priv->wheel_keys[1+1], &fakeKey);
>> +             sendWheelStripEvent(fakeButton, fakeKey, pInfo, first_val, 
>> num_vals, valuators);
>> +     }
>
> confusion here, the relwheel has the same index as the lstrip? and the lring
> the same as the rstrip?
>
> the diff is virtually so this may be correct, but having named defines with
> comments would help greatly here.
>
If you're confused by two different arrays (strip_keys and wheel_keys)
having different data at the same indicies, I think that's a sign of a
more fundamental problem. Personally, I never understood the need for
a distinction between strip_keys and wheel_keys. A single
"scroll_keys" (or, as I'd rather name it, "scroll_actions") array that
houses all the scroll events would make things a *lot* less confusing.
Throw named indicies on top of that, and things get better still.

If you don't mind, I'd like to move this work to a separate patch
which does unification and named indicies.

> Cheers,
>  Peter
>
>>
>> -             xf86PostButtonEventP(pInfo->dev, is_absolute(pInfo), 
>> fakeButton & AC_CODE,
>> -                                  0, first_val, num_vals, VCOPY(valuators, 
>> num_vals));
>> +     /* emulate events for left touch ring */
>> +     delta = getScrollDelta(ds->abswheel, priv->oldWheel, MAX_PAD_RING, 
>> TRUE, FALSE);
>> +     if (delta && IsPad(priv) && priv->oldProximity == ds->proximity)
>> +     {
>> +             DBG(10, priv, "Left touch wheel scroll delta = %d\n", delta);
>> +             fakeButton = getWheelButton(delta, priv->wheelup, 
>> priv->wheeldn,
>> +                                         priv->wheel_keys[2+1], 
>> priv->wheel_keys[3+1], &fakeKey);
>
>> +             sendWheelStripEvent(fakeButton, fakeKey, pInfo, first_val, 
>> num_vals, valuators);
>>       }
>> -     else
>> +
>> +     /* emulate events for right touch ring */
>> +     delta = getScrollDelta(ds->abswheel2, priv->oldWheel2, MAX_PAD_RING, 
>> TRUE, FALSE);
>> +     if (delta && IsPad(priv) && priv->oldProximity == ds->proximity)
>>       {
>> -             sendAction(pInfo, 1, fakeKey, ARRAY_SIZE(priv->wheel_keys[0]),
>> -                        first_val, num_vals, valuators);
>> -             sendAction(pInfo, 0, fakeKey, ARRAY_SIZE(priv->wheel_keys[0]),
>> -                        first_val, num_vals, valuators);
>> +             DBG(10, priv, "Right touch wheel scroll delta = %d\n", delta);
>> +             fakeButton = getWheelButton(delta, priv->wheel2up, 
>> priv->wheel2dn,
>> +                                         priv->wheel_keys[4+1], 
>> priv->wheel_keys[5+1], &fakeKey);
>> +             sendWheelStripEvent(fakeButton, fakeKey, pInfo, first_val, 
>> num_vals, valuators);
>>       }
>>  }
>>
>> --
>> 1.7.7.3

Jason

---
Day xee-nee-svsh duu-'ushtlh-ts'it;
nuu-wee-ya' duu-xan' 'vm-nvshtlh-ts'it.
Huu-chan xuu naa~-gha.

------------------------------------------------------------------------------
Learn Windows Azure Live!  Tuesday, Dec 13, 2011
Microsoft is holding a special Learn Windows Azure training event for 
developers. It will provide a great way to learn Windows Azure and what it 
provides. You can attend the event by watching it streamed LIVE online.  
Learn more at http://p.sf.net/sfu/ms-windowsazure
_______________________________________________
Linuxwacom-devel mailing list
Linuxwacom-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxwacom-devel

Reply via email to