On Mon, Jan 19, 2015 at 09:44:08PM -0500, Stephen Chandler Paul wrote:
> On the majority of Wacom tablets, the buttons are on the left side, opposite 
> of
> the side where the palm is meant to rest. Because of this, it's impossible to
> use the tablet with your left hand (comfortably, anyway) unless you flip it
> over, in which case the coordinates need to be inverted for it to match up 
> with
> the screen properly. This is where left handed mode comes in. When enabled, it
> reverses all the coordinates so that the tablet may be rotated, and the palm
> rest on the tablet moved over to the left side.
> 
> Signed-off-by: Stephen Chandler Paul <[email protected]>
> ---
>  src/evdev-tablet.c | 16 +++++++++-
>  test/tablet.c      | 85 
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 100 insertions(+), 1 deletion(-)
> 
> This probably should have been sent with the last patch instead of as a 
> separate
> patch, oops!
> 
> diff --git a/src/evdev-tablet.c b/src/evdev-tablet.c
> index f80d642..10f8697 100644
> --- a/src/evdev-tablet.c
> +++ b/src/evdev-tablet.c
> @@ -86,6 +86,12 @@ tablet_mark_all_axes_changed(struct tablet_dispatch 
> *tablet,
>  }
>  
>  static void
> +tablet_change_to_left_handed(struct evdev_device *device)
> +{
> +     device->left_handed.enabled = device->left_handed.want_enabled;
> +}
> +
> +static void
>  tablet_update_tool(struct tablet_dispatch *tablet,
>                  struct evdev_device *device,
>                  enum libinput_tool_type tool,
> @@ -142,7 +148,11 @@ tablet_check_notify_axes(struct tablet_dispatch *tablet,
>               switch (a) {
>               case LIBINPUT_TABLET_AXIS_X:
>               case LIBINPUT_TABLET_AXIS_Y:
> -                     tablet->axes[a] = absinfo->value;
> +                     if (device->left_handed.enabled)
> +                             tablet->axes[a] =
> +                                     absinfo->maximum - absinfo->value;

this won't work if you have a non-zero absinfo->minimum. The formula is 
   max - (value - min)
Please add a helper function for inverting an axis, not the last time
we'll get this wrong :)

> +                     else
> +                             tablet->axes[a] = absinfo->value;
>                       break;
>               case LIBINPUT_TABLET_AXIS_DISTANCE:
>               case LIBINPUT_TABLET_AXIS_PRESSURE:
> @@ -486,6 +496,8 @@ tablet_flush(struct tablet_dispatch *tablet,
>                                           tablet->axes);
>               tablet_set_status(tablet, TABLET_TOOL_OUT_OF_PROXIMITY);
>               tablet_unset_status(tablet, TABLET_TOOL_LEAVING_PROXIMITY);
> +
> +             tablet_change_to_left_handed(device);
>       }
>  
>       /* Update state */
> @@ -588,5 +600,7 @@ evdev_tablet_create(struct evdev_device *device)
>               return NULL;
>       }
>  
> +     evdev_init_left_handed(device, tablet_change_to_left_handed);
> +
>       return &tablet->base;
>  }
> diff --git a/test/tablet.c b/test/tablet.c
> index 367c4db..cfc7cde 100644
> --- a/test/tablet.c
> +++ b/test/tablet.c
> @@ -239,6 +239,90 @@ START_TEST(motion)
>  }
>  END_TEST
>  
> +START_TEST(left_handed)
> +{
> +     struct litest_device *dev = litest_current_device();
> +     struct libinput *li = dev->libinput;
> +     struct libinput_event *event;
> +     struct libinput_event_tablet *tablet_event;
> +     double right_hand_x, right_hand_y;
> +     double left_hand_x, left_hand_y;
> +     struct axis_replacement axes[] = {
> +             { ABS_DISTANCE, 10 },
> +             { -1, -1 }
> +     };
> +
> +     
> ck_assert(libinput_device_config_left_handed_is_available(dev->libinput_device));
> +
> +     litest_drain_events(li);
> +
> +     /* Test that left-handed mode doesn't go into effect until the tool has
> +      * left proximity of the tablet */
> +     litest_tablet_proximity_in(dev, 20, 20, axes);

fwiw, always use uneven coordinates for tests like these, otherwise you may
not spot an accidental bug in the form of x = y.

> +     libinput_dispatch(li);

use litest_wait_for_event_of_type() here, makes the flow a bit easier.

> +
> +     while ((event = libinput_get_event(li))) {
> +             if (libinput_event_get_type(event) == 
> LIBINPUT_EVENT_TABLET_AXIS) {
> +                     tablet_event = libinput_event_get_tablet_event(event);
> +
> +                     right_hand_x = libinput_event_tablet_get_axis_value(
> +                         tablet_event, LIBINPUT_TABLET_AXIS_X);
> +                     right_hand_y = libinput_event_tablet_get_axis_value(
> +                         tablet_event, LIBINPUT_TABLET_AXIS_Y);
> +             }
> +
> +             libinput_event_destroy(event);
> +     }
> +
> +     libinput_device_config_left_handed_set(dev->libinput_device, 1);
> +     litest_event(dev, EV_ABS, ABS_X, 10);
> +     litest_event(dev, EV_ABS, ABS_Y, 10);
> +     libinput_dispatch(li);
> +
> +     while ((event = libinput_get_event(li))) {
> +             if (libinput_event_get_type(event) == 
> LIBINPUT_EVENT_TABLET_AXIS) {
> +                     double x, y;
> +
> +                     tablet_event = libinput_event_get_tablet_event(event);
> +
> +                     x = libinput_event_tablet_get_axis_value(
> +                         tablet_event, LIBINPUT_TABLET_AXIS_X);
> +                     y = libinput_event_tablet_get_axis_value(
> +                         tablet_event, LIBINPUT_TABLET_AXIS_Y);
> +
> +                     litest_assert_double_lt(x, right_hand_x);
> +                     litest_assert_double_lt(y, right_hand_y);
> +             }
> +
> +             libinput_event_destroy(event);
> +     }
> +
> +     /* In left handed mode, since the formula inverts the values of the
> +      * coordinates, using the same coordinates as test values should always
> +      * result in the left handed coordinates being larger then the right
> +      * handed ones */

you have access to the libevdev device, I think it's best to get the min/max
and make sure that it's actually inverted for both axes.

> +     litest_tablet_proximity_out(dev);
> +     litest_tablet_proximity_in(dev, 20, 20, axes);
> +     libinput_dispatch(li);
> +
> +     while ((event = libinput_get_event(li))) {
> +             if (libinput_event_get_type(event) == 
> LIBINPUT_EVENT_TABLET_AXIS) {

litest_wait_for_event_of_type as well here.

Cheers,
   Peter

> +                     tablet_event = libinput_event_get_tablet_event(event);
> +
> +                     left_hand_x = libinput_event_tablet_get_axis_value(
> +                         tablet_event, LIBINPUT_TABLET_AXIS_X);
> +                     left_hand_y = libinput_event_tablet_get_axis_value(
> +                         tablet_event, LIBINPUT_TABLET_AXIS_Y);
> +
> +                     litest_assert_double_gt(left_hand_x, right_hand_x);
> +                     litest_assert_double_gt(left_hand_y, right_hand_y);
> +             }
> +
> +             libinput_event_destroy(event);
> +     }
> +}
> +END_TEST
> +
>  START_TEST(motion_event_state)
>  {
>       struct litest_device *dev = litest_current_device();
> @@ -869,6 +953,7 @@ main(int argc, char **argv)
>       litest_add("tablet:proximity", bad_distance_events, LITEST_TABLET | 
> LITEST_DISTANCE, LITEST_ANY);
>       litest_add("tablet:motion", motion, LITEST_TABLET, LITEST_ANY);
>       litest_add("tablet:motion", motion_event_state, LITEST_TABLET, 
> LITEST_ANY);
> +     litest_add("tablet:left_handed", left_handed, LITEST_TABLET, 
> LITEST_ANY);
>       litest_add("tablet:normalization", normalization, LITEST_TABLET, 
> LITEST_ANY);
>       litest_add("tablet:pad", pad_buttons_ignored, LITEST_TABLET, 
> LITEST_ANY);
>  
> -- 
> 2.0.5
> 
_______________________________________________
wayland-devel mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/wayland-devel

Reply via email to