Skip to content

Commit

Permalink
tools: add stylus button support
Browse files Browse the repository at this point in the history
For the evdev events only a few hand-selected ones, all other ones are ignored
for now.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
  • Loading branch information
whot committed Nov 18, 2019
1 parent 733eb07 commit c9e9ea3
Showing 1 changed file with 86 additions and 13 deletions.
99 changes: 86 additions & 13 deletions tools/libinput-debug-tablet.c
Expand Up @@ -61,6 +61,8 @@ struct context {
double tx, ty;
double dist, pressure;
double rotation, slider;
unsigned int buttons_down[32];
unsigned int evdev_buttons_down[32];

/* libevdev device state */
struct {
Expand All @@ -86,6 +88,24 @@ print_line(const char *format, ...)
printf("%.*s\n", width - n, empty);
}

static void
print_buttons(struct context *ctx, unsigned int *buttons, size_t sz)
{
char buf[256] = {0};
size_t len = 0;

for (size_t i = 0; i < sz; i++) {
const char *name;

if (buttons[i] == 0)
continue;

name = libevdev_event_code_get_name(EV_KEY, buttons[i]);
len += snprintf(&buf[len], sizeof(buf) - len, "%s ", name);
}
print_line(" buttons: %s", buf);
}

static void
print_bar(const char *header, double value, double normalized)
{
Expand Down Expand Up @@ -197,7 +217,10 @@ print_state(struct context *ctx)
print_bar("pressure:", ctx->pressure, ctx->pressure);
print_bar("rotation:", ctx->rotation, ctx->rotation/360.0);
print_bar("slider:", ctx->slider, (ctx->slider + 1.0)/2.0);
lines_printed += 9;
print_buttons(ctx,
ctx->buttons_down,
ARRAY_LENGTH(ctx->buttons_down));
lines_printed += 10;

printf("evdev:\n");
print_bar("ABS_X:", ctx->abs.x, normalize(ctx->evdev, ABS_X, ctx->abs.x));
Expand All @@ -207,7 +230,10 @@ print_state(struct context *ctx)
print_bar("ABS_TILT_Y:", ctx->abs.tilt_y, normalize(ctx->evdev, ABS_TILT_Y, ctx->abs.tilt_y));
print_bar("ABS_DISTANCE:", ctx->abs.distance, normalize(ctx->evdev, ABS_DISTANCE, ctx->abs.distance));
print_bar("ABS_PRESSURE:", ctx->abs.pressure, normalize(ctx->evdev, ABS_PRESSURE, ctx->abs.pressure));
lines_printed += 8;
print_buttons(ctx,
ctx->evdev_buttons_down,
ARRAY_LENGTH(ctx->evdev_buttons_down));
lines_printed += 9;

return lines_printed;
}
Expand Down Expand Up @@ -274,6 +300,28 @@ update_tablet_axes(struct context *ctx, struct libinput_event_tablet_tool *t)
ctx->slider = libinput_event_tablet_tool_get_slider_position(t);
}

static void
handle_tablet_button_event(struct context *ctx, struct libinput_event *ev)
{
struct libinput_event_tablet_tool *t = libinput_event_get_tablet_tool_event(ev);
unsigned int button = libinput_event_tablet_tool_get_button(t);
enum libinput_button_state state = libinput_event_tablet_tool_get_button_state(t);

for (size_t i = 0; i < ARRAY_LENGTH(ctx->buttons_down); i++) {
if (state == LIBINPUT_BUTTON_STATE_PRESSED) {
if (ctx->buttons_down[i] == 0) {
ctx->buttons_down[i] = button;
break;
}
} else {
if (ctx->buttons_down[i] == button) {
ctx->buttons_down[i] = 0;
break;
}
}
}
}

static void
handle_tablet_axis_event(struct context *ctx, struct libinput_event *ev)
{
Expand Down Expand Up @@ -325,6 +373,9 @@ handle_libinput_events(struct context *ctx)
case LIBINPUT_EVENT_DEVICE_REMOVED:
handle_device_removed(ctx, ev);
break;
case LIBINPUT_EVENT_TABLET_TOOL_BUTTON:
handle_tablet_button_event(ctx, ev);
break;
case LIBINPUT_EVENT_TABLET_TOOL_AXIS:
handle_tablet_axis_event(ctx, ev);
break;
Expand All @@ -349,35 +400,57 @@ handle_libevdev_events(struct context *ctx)
struct libevdev *evdev = ctx->evdev;
struct input_event event;

#define evbit(_t, _c) (((_t) << 16) | (_c))

if (!evdev)
return;

while (libevdev_next_event(evdev, LIBEVDEV_READ_FLAG_NORMAL, &event)
== LIBEVDEV_READ_STATUS_SUCCESS)
{
if (event.type != EV_ABS)
continue;

switch (event.code) {
case ABS_X:
switch(evbit(event.type, event.code)) {
case evbit(EV_KEY, BTN_TOOL_PEN):
case evbit(EV_KEY, BTN_TOOL_RUBBER):
case evbit(EV_KEY, BTN_TOOL_BRUSH):
case evbit(EV_KEY, BTN_TOOL_PENCIL):
case evbit(EV_KEY, BTN_TOOL_AIRBRUSH):
case evbit(EV_KEY, BTN_TOOL_MOUSE):
case evbit(EV_KEY, BTN_TOOL_LENS):
ctx->evdev_buttons_down[event.code - BTN_TOOL_PEN] = event.value ? event.code : 0;
break;
/* above tools should be mutually exclusive but let's leave
* enough space */
case evbit(EV_KEY, BTN_TOUCH):
ctx->evdev_buttons_down[7] = event.value ? event.code : 0;
break;
case evbit(EV_KEY, BTN_STYLUS):
ctx->evdev_buttons_down[8] = event.value ? event.code : 0;
break;
case evbit(EV_KEY, BTN_STYLUS2):
ctx->evdev_buttons_down[9] = event.value ? event.code : 0;
break;
case evbit(EV_KEY, BTN_STYLUS3):
ctx->evdev_buttons_down[10] = event.value ? event.code : 0;
break;
case evbit(EV_ABS, ABS_X):
ctx->abs.x = event.value;
break;
case ABS_Y:
case evbit(EV_ABS, ABS_Y):
ctx->abs.y = event.value;
break;
case ABS_Z:
case evbit(EV_ABS, ABS_Z):
ctx->abs.z = event.value;
break;
case ABS_PRESSURE:
case evbit(EV_ABS, ABS_PRESSURE):
ctx->abs.pressure = event.value;
break;
case ABS_TILT_X:
case evbit(EV_ABS, ABS_TILT_X):
ctx->abs.tilt_x = event.value;
break;
case ABS_TILT_Y:
case evbit(EV_ABS, ABS_TILT_Y):
ctx->abs.tilt_y = event.value;
break;
case ABS_DISTANCE:
case evbit(EV_ABS, ABS_DISTANCE):
ctx->abs.distance = event.value;
break;
}
Expand Down

0 comments on commit c9e9ea3

Please sign in to comment.