{
struct libinput_event_pointer *p = libinput_event_get_pointer_event(ev);
double v = 0, h = 0;
+ int dv = 0, dh = 0;
const char *have_vert = "",
*have_horiz = "";
const char *source = "invalid";
LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL)) {
v = libinput_event_pointer_get_axis_value(p,
LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL);
+ dv = libinput_event_pointer_get_axis_value_discrete(p,
+ LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL);
have_vert = "*";
}
if (libinput_event_pointer_has_axis(p,
LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL)) {
h = libinput_event_pointer_get_axis_value(p,
LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL);
+ dh = libinput_event_pointer_get_axis_value_discrete(p,
+ LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL);
have_horiz = "*";
}
print_event_time(libinput_event_pointer_get_time(p));
- printq("vert %.2f%s horiz %.2f%s (%s)\n",
- v, have_vert, h, have_horiz, source);
+ printq("vert %.2f/%d%s horiz %.2f/%d%s (%s)\n",
+ v, dv, have_vert, h, dh, have_horiz, source);
}
static void
double x, y;
};
+struct device_user_data {
+ struct point scroll_accumulated;
+};
+
struct evdev_device {
struct list node;
struct libevdev *evdev;
struct {
double vx, vy;
double hx, hy;
+
+ double vx_discrete, vy_discrete;
+ double hx_discrete, hy_discrete;
} scroll;
/* touch positions */
draw_scrollbars(struct window *w, cairo_t *cr)
{
+ /* normal scrollbars */
cairo_save(cr);
cairo_set_source_rgb(cr, .4, .8, 0);
cairo_rectangle(cr, w->scroll.vx - 10, w->scroll.vy - 20, 20, 40);
cairo_rectangle(cr, w->scroll.hx - 20, w->scroll.hy - 10, 40, 20);
cairo_fill(cr);
+
+ /* discrete scrollbars */
+ cairo_set_source_rgb(cr, .8, .4, 0);
+ cairo_rectangle(cr, w->scroll.vx_discrete - 5, w->scroll.vy_discrete - 10, 10, 20);
+ cairo_rectangle(cr, w->scroll.hx_discrete - 10, w->scroll.hy_discrete - 5, 20, 10);
+ cairo_fill(cr);
+
cairo_restore(cr);
}
w->scroll.vy = w->height/2;
w->scroll.hx = w->width/2;
w->scroll.hy = w->height/2;
+ w->scroll.vx_discrete = w->width/2;
+ w->scroll.vy_discrete = w->height/2;
+ w->scroll.hx_discrete = w->width/2;
+ w->scroll.hy_discrete = w->height/2;
w->swipe.x = w->width/2;
w->swipe.y = w->height/2;
const char *device_node;
int fd;
struct evdev_device *d;
+ struct device_user_data *data;
ud = libinput_device_get_udev_device(dev);
device_node = udev_device_get_devnode(ud);
d->evdev = evdev;
d->libinput_device =libinput_device_ref(dev);
+ data = zalloc(sizeof *data);
+ libinput_device_set_user_data(dev, data);
+
c = g_io_channel_unix_new(fd);
g_io_channel_set_encoding(c, NULL, NULL);
d->source_id = g_io_add_watch(c, G_IO_IN,
list_remove(&d->node);
g_source_remove(d->source_id);
+ free(libinput_device_get_user_data(d->libinput_device));
libinput_device_unref(d->libinput_device);
libevdev_free(d->evdev);
close(d->fd);
handle_event_axis(struct libinput_event *ev, struct window *w)
{
struct libinput_event_pointer *p = libinput_event_get_pointer_event(ev);
+ struct libinput_device *dev = libinput_event_get_device(ev);
+ struct device_user_data *data = libinput_device_get_user_data(dev);
double value;
+ int discrete;
+
+ assert(data);
if (libinput_event_pointer_has_axis(p,
LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL)) {
LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL);
w->scroll.vy += value;
w->scroll.vy = clip(w->scroll.vy, 0, w->height);
+ data->scroll_accumulated.y += value;
+
+ discrete = libinput_event_pointer_get_axis_value_discrete(p,
+ LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL);
+ if (discrete) {
+ w->scroll.vy_discrete += data->scroll_accumulated.y;
+ w->scroll.vy_discrete = clip(w->scroll.vy_discrete, 0, w->height);
+ data->scroll_accumulated.y = 0;
+ }
}
if (libinput_event_pointer_has_axis(p,
LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL);
w->scroll.hx += value;
w->scroll.hx = clip(w->scroll.hx, 0, w->width);
+ data->scroll_accumulated.x += value;
+
+ discrete = libinput_event_pointer_get_axis_value_discrete(p,
+ LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL);
+ if (discrete) {
+ w->scroll.hx_discrete += data->scroll_accumulated.x;
+ w->scroll.hx_discrete = clip(w->scroll.hx_discrete, 0, w->width);
+ data->scroll_accumulated.x = 0;
+ }
}
}