On Wed, Dec 21, 2011 at 9:27 PM, Peter Hutterer
<peter.hutte...@who-t.net> wrote:
> On Wed, Dec 21, 2011 at 03:28:54PM -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>
>
> Reviewed-by: Peter Hutterer <peter.hutte...@who-t.net>
>
> thank you!
>
> Cheers,
>  Peter
>
>> ---
>> Changes from v3:
>>  * Move to head of patchset
>>  * Add tests for getScrollDelta and getWheelButton
>>  * Fix bugs in getScrollDelta doc (wrap is max, not max+1)
>>  * Fix bugs in getScrollDelta implementation
>>     * log2(0) is undef; caused problems with current or old == 0
>>     * wrap now properly handled with AXIS_BITWISE
>>
>>  src/wcmCommon.c     |  177 
>> +++++++++++++++++++++++++++++++++------------------
>>  src/xf86WacomDefs.h |    2 +
>>  test/wacom-tests.c  |   84 ++++++++++++++++++++++++
>>  3 files changed, 200 insertions(+), 63 deletions(-)
>>
>> diff --git a/src/wcmCommon.c b/src/wcmCommon.c
>> index e85c6d8..e6eb958 100644
>> --- a/src/wcmCommon.c
>> +++ b/src/wcmCommon.c
>> @@ -317,73 +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     Maximum value before wraparound occurs (0 if axis does 
>> not wrap)
>> + * @param flags    Flags defining axis attributes: AXIS_INVERT and 
>> AXIS_BITWISE
>> + * @return         Relative change in axis value
>> + */
>> +static int getScrollDelta(int current, int old, int wrap, int flags)
>>  {
>> -     WacomDevicePtr priv = (WacomDevicePtr) pInfo->private;
>> -     int fakeButton = 0, value = 0;
>> +     int delta;
>>
>> -     /* emulate events for relative wheel */
>> -     if ( ds->relwheel )
>> +     if (flags & AXIS_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 << 1) | 0x01);
>> +             old = (int)log2((old << 1) | 0x01);
>> +             wrap = (int)log2((wrap << 1) | 0x01);
>>       }
>>
>> -     /* emulate events for absolute wheel when it is a touch ring (on pad) 
>> */
>> -     if ( (ds->abswheel != priv->oldWheel) && IsPad(priv) &&
>> -         (priv->oldProximity == ds->proximity))
>> +     delta = current - old;
>> +
>> +     if (flags & AXIS_INVERT)
>> +             delta = -delta;
>> +
>> +     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->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;
>> +             if (delta < 0)
>> +                     wrap_delta =  (wrap + 1) + delta;
>>               else
>> -                     wrap_delta = priv->oldWheel - ((MAX_PAD_RING + 1) + 
>> ds->abswheel);
>> +                     wrap_delta = -((wrap + 1) - delta);
>>
>> -             DBG(12, priv, "wrap detection for %d (old %d): %d (wrap %d)\n",
>> -                 ds->abswheel, priv->oldWheel, 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->wheelup : priv->wheeldn;
>> -             *fakeKey = (value > 0) ? priv->wheel_keys[2+1] : 
>> priv->wheel_keys[3+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
>> @@ -393,31 +426,49 @@ 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);
>> -
>> -     if (!fakeButton && (!fakeKey || !(*fakeKey)))
>> -             return;
>> +     /* emulate events for left strip */
>> +     delta = getScrollDelta(ds->stripx, priv->oldStripX, 0, AXIS_INVERT | 
>> AXIS_BITWISE);
>> +     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);
>> +             sendWheelStripEvent(fakeButton, fakeKey, pInfo, first_val, 
>> num_vals, valuators);
>> +     }
>>
>> -     if (!fakeKey || !(*fakeKey))
>> +     /* emulate events for right strip */
>> +     delta = getScrollDelta(ds->stripy, priv->oldStripY, 0, AXIS_INVERT | 
>> AXIS_BITWISE);
>> +     if (delta && IsPad(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, "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);
>> +     }
>>
>> -             xf86PostButtonEventP(pInfo->dev, is_absolute(pInfo), 
>> fakeButton & AC_CODE,
>> -                                  0, first_val, num_vals, VCOPY(valuators, 
>> num_vals));
>> +     /* emulate events for relative wheel */
>> +     delta = getScrollDelta(ds->relwheel, 0, 0, 0);
>> +     if (delta && IsCursor(priv) && priv->oldProximity == ds->proximity)
>> +     {
>> +             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);
>>       }
>> -     else
>> +
>> +     /* emulate events for left touch ring */
>> +     delta = getScrollDelta(ds->abswheel, priv->oldWheel, MAX_PAD_RING, 
>> AXIS_INVERT);
>> +     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, "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);
>>       }
>>  }
>>
>> diff --git a/src/xf86WacomDefs.h b/src/xf86WacomDefs.h
>> index 1cdfa1a..32b18ee 100644
>> --- a/src/xf86WacomDefs.h
>> +++ b/src/xf86WacomDefs.h
>> @@ -189,6 +189,8 @@ struct _WacomModel
>>                                        * For backward compability support,
>>                                        * tablet buttons besides the strips 
>> are
>>                                        * treated as buttons */
>> +#define AXIS_INVERT  0x01               /* Flag describing an axis which 
>> increases "downward" */
>> +#define AXIS_BITWISE 0x02               /* Flag describing an axis which 
>> changes bitwise */
>>
>>  /* get/set/property */
>>  typedef struct _PROPINFO PROPINFO;
>> diff --git a/test/wacom-tests.c b/test/wacom-tests.c
>> index d91d9c3..a22c970 100644
>> --- a/test/wacom-tests.c
>> +++ b/test/wacom-tests.c
>> @@ -29,6 +29,88 @@
>>   * change the behaviour.
>>   */
>>
>> +static void
>> +test_get_scroll_delta(void)
>> +{
>> +     int test_table[][5] = {
>> +             { 100,  25, 0, 0,  75}, { 25,  100, 0, 0, -75},
>> +             {-100, -25, 0, 0, -75}, {-25, -100, 0, 0,  75},
>> +             { 100, -25, 0, 0, 125}, {-25,  100, 0, 0,-125},
>> +             { 100, 100, 0, 0,   0}, {-25,  -25, 0, 0,   0},
>> +
>> +             {23, 0, 50, 0,  23}, {0, 23, 50, 0, -23},
>> +             {24, 0, 50, 0,  24}, {0, 24, 50, 0, -24},
>> +             {25, 0, 50, 0,  25}, {0, 25, 50, 0, -25},
>> +             {26, 0, 50, 0, -25}, {0, 26, 50, 0,  25},
>> +             {27, 0, 50, 0, -24}, {0, 27, 50, 0,  24},
>> +             {28, 0, 50, 0, -23}, {0, 28, 50, 0,  23},
>> +
>> +             {1024, 0, 0, AXIS_BITWISE, 11}, {0, 1024, 0, AXIS_BITWISE, 
>> -11},
>> +
>> +             {  0, 4, 256, AXIS_BITWISE, -3}, {4,   0, 256, AXIS_BITWISE,  
>> 3},
>> +             {  1, 4, 256, AXIS_BITWISE, -2}, {4,   1, 256, AXIS_BITWISE,  
>> 2},
>> +             {  2, 4, 256, AXIS_BITWISE, -1}, {4,   2, 256, AXIS_BITWISE,  
>> 1},
>> +             {  4, 4, 256, AXIS_BITWISE,  0}, {4,   4, 256, AXIS_BITWISE,  
>> 0},
>> +             {  8, 4, 256, AXIS_BITWISE,  1}, {4,   8, 256, AXIS_BITWISE, 
>> -1},
>> +             { 16, 4, 256, AXIS_BITWISE,  2}, {4,  16, 256, AXIS_BITWISE, 
>> -2},
>> +             { 32, 4, 256, AXIS_BITWISE,  3}, {4,  32, 256, AXIS_BITWISE, 
>> -3},
>> +             { 64, 4, 256, AXIS_BITWISE,  4}, {4,  64, 256, AXIS_BITWISE, 
>> -4},
>> +             {128, 4, 256, AXIS_BITWISE,  5}, {4, 128, 256, AXIS_BITWISE, 
>> -5},
>> +             {256, 4, 256, AXIS_BITWISE, -4}, {4, 256, 256, AXIS_BITWISE,  
>> 4}
>> +     };
>> +     int i;
>> +
>> +     for (i = 0; i < ARRAY_SIZE(test_table); i++)
>> +     {
>> +             int delta;
>> +             int current, old, wrap, flags;
>> +             current = test_table[i][0];
>> +             old     = test_table[i][1];
>> +             wrap    = test_table[i][2];
>> +             flags   = test_table[i][3];
>> +
>> +             delta = getScrollDelta(current, old, wrap, flags);
>> +             assert(delta == test_table[i][4]);
>> +
>> +             flags |= AXIS_INVERT;
>> +             delta = getScrollDelta(current, old, wrap, flags);
>> +             assert(delta == -1 * test_table[i][4]);
>> +     }
>> +}
>> +
>> +static void
>> +test_get_wheel_button(void)
>> +{
>> +     int delta;
>> +     int button_up, button_dn, action_up, action_dn;
>> +
>> +     button_up = 100;
>> +     button_dn = 200;
>> +     action_up = 300;
>> +     action_dn = 400;
>> +
>> +     for (delta = -32; delta <= 32; delta++)
>> +     {
>> +             int *action;
>> +             int result = getWheelButton(delta, button_up, button_dn, 
>> &action_up, &action_dn, &action);
>> +             if (delta < 0)
>> +             {
>> +                     assert(result == button_dn);
>> +                     assert(action == &action_dn);
>> +             }
>> +             else if (delta == 0)
>> +             {
>> +                     assert(result == 0);
>> +                     assert(action == NULL);
>> +             }
>> +             else
>> +             {
>> +                     assert(result == button_up);
>> +                     assert(action == &action_up);
>> +             }
>> +     }
>> +}
>> +
>>  /**
>>   * Test refcounting of the common struct.
>>   */
>> @@ -552,6 +634,8 @@ int main(int argc, char** argv)
>>       test_mod_buttons();
>>       test_set_type();
>>       test_flag_set();
>> +     test_get_scroll_delta();
>> +     test_get_wheel_button();
>>       return 0;
>>  }
>>
>> --
>> 1.7.7.3
>>
>>

Patchset has been merged.

Jason

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

------------------------------------------------------------------------------
Ridiculously easy VDI. With Citrix VDI-in-a-Box, you don't need a complex
infrastructure or vast IT resources to deliver seamless, secure access to
virtual desktops. With this all-in-one solution, easily deploy virtual 
desktops for less than the cost of PCs and save 60% on VDI infrastructure 
costs. Try it free! http://p.sf.net/sfu/Citrix-VDIinabox
_______________________________________________
Linuxwacom-devel mailing list
Linuxwacom-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxwacom-devel

Reply via email to