Merge branch 'master' into tablet-support

This commit is contained in:
Peter Hutterer 2014-06-23 10:08:18 +10:00
commit bb1dd896ac
7 changed files with 157 additions and 50 deletions

View file

@ -565,6 +565,7 @@ tp_init_buttons(struct tp_dispatch *tp,
struct tp_touch *t; struct tp_touch *t;
int width, height; int width, height;
double diagonal; double diagonal;
const struct input_absinfo *absinfo_x, *absinfo_y;
tp->buttons.is_clickpad = libevdev_has_property(device->evdev, tp->buttons.is_clickpad = libevdev_has_property(device->evdev,
INPUT_PROP_BUTTONPAD); INPUT_PROP_BUTTONPAD);
@ -580,8 +581,11 @@ tp_init_buttons(struct tp_dispatch *tp,
log_bug_kernel("non clickpad without right button?\n"); log_bug_kernel("non clickpad without right button?\n");
} }
width = abs(device->abs.max_x - device->abs.min_x); absinfo_x = device->abs.absinfo_x;
height = abs(device->abs.max_y - device->abs.min_y); absinfo_y = device->abs.absinfo_y;
width = abs(absinfo_x->maximum - absinfo_x->minimum);
height = abs(absinfo_y->maximum - absinfo_y->minimum);
diagonal = sqrt(width*width + height*height); diagonal = sqrt(width*width + height*height);
tp->buttons.motion_dist = diagonal * DEFAULT_BUTTON_MOTION_THRESHOLD; tp->buttons.motion_dist = diagonal * DEFAULT_BUTTON_MOTION_THRESHOLD;
@ -590,13 +594,15 @@ tp_init_buttons(struct tp_dispatch *tp,
tp->buttons.use_clickfinger = true; tp->buttons.use_clickfinger = true;
if (tp->buttons.is_clickpad && !tp->buttons.use_clickfinger) { if (tp->buttons.is_clickpad && !tp->buttons.use_clickfinger) {
tp->buttons.bottom_area.top_edge = height * .8 + device->abs.min_y; int xoffset = absinfo_x->minimum,
tp->buttons.bottom_area.rightbutton_left_edge = width/2 + device->abs.min_x; yoffset = absinfo_y->minimum;
tp->buttons.bottom_area.top_edge = height * .8 + yoffset;
tp->buttons.bottom_area.rightbutton_left_edge = width/2 + xoffset;
if (tp->buttons.has_topbuttons) { if (tp->buttons.has_topbuttons) {
tp->buttons.top_area.bottom_edge = height * .08 + device->abs.min_y; tp->buttons.top_area.bottom_edge = height * .08 + yoffset;
tp->buttons.top_area.rightbutton_left_edge = width * .58 + device->abs.min_x; tp->buttons.top_area.rightbutton_left_edge = width * .58 + xoffset;
tp->buttons.top_area.leftbutton_right_edge = width * .42 + device->abs.min_x; tp->buttons.top_area.leftbutton_right_edge = width * .42 + xoffset;
} else { } else {
tp->buttons.top_area.bottom_edge = INT_MIN; tp->buttons.top_area.bottom_edge = INT_MIN;
} }

View file

@ -139,7 +139,7 @@ tp_motion_history_reset(struct tp_touch *t)
static inline struct tp_touch * static inline struct tp_touch *
tp_current_touch(struct tp_dispatch *tp) tp_current_touch(struct tp_dispatch *tp)
{ {
return &tp->touches[min(tp->slot, tp->ntouches)]; return &tp->touches[min(tp->slot, tp->ntouches - 1)];
} }
static inline struct tp_touch * static inline struct tp_touch *
@ -750,8 +750,10 @@ tp_init(struct tp_dispatch *tp,
if (tp_init_slots(tp, device) != 0) if (tp_init_slots(tp, device) != 0)
return -1; return -1;
width = abs(device->abs.max_x - device->abs.min_x); width = abs(device->abs.absinfo_x->maximum -
height = abs(device->abs.max_y - device->abs.min_y); device->abs.absinfo_x->minimum);
height = abs(device->abs.absinfo_y->maximum -
device->abs.absinfo_y->minimum);
diagonal = sqrt(width*width + height*height); diagonal = sqrt(width*width + height*height);
tp->hysteresis.margin_x = tp->hysteresis.margin_x =

View file

@ -89,13 +89,19 @@ transform_absolute(struct evdev_device *device, int32_t *x, int32_t *y)
} }
} }
static inline double
scale_axis(const struct input_absinfo *absinfo, double val, double to_range)
{
return (val - absinfo->minimum) * to_range /
(absinfo->maximum - absinfo->minimum + 1);
}
double double
evdev_device_transform_x(struct evdev_device *device, evdev_device_transform_x(struct evdev_device *device,
double x, double x,
uint32_t width) uint32_t width)
{ {
return (x - device->abs.min_x) * width / return scale_axis(device->abs.absinfo_x, x, width);
(device->abs.max_x - device->abs.min_x + 1);
} }
double double
@ -103,8 +109,7 @@ evdev_device_transform_y(struct evdev_device *device,
double y, double y,
uint32_t height) uint32_t height)
{ {
return (y - device->abs.min_y) * height / return scale_axis(device->abs.absinfo_y, y, height);
(device->abs.max_y - device->abs.min_y + 1);
} }
static void static void
@ -588,6 +593,7 @@ evdev_configure_device(struct evdev_device *device)
{ {
struct libevdev *evdev = device->evdev; struct libevdev *evdev = device->evdev;
const struct input_absinfo *absinfo; const struct input_absinfo *absinfo;
struct input_absinfo fixed;
int has_abs, has_rel, has_mt; int has_abs, has_rel, has_mt;
int has_button, has_keyboard, has_touch; int has_button, has_keyboard, has_touch;
struct mt_slot *slots; struct mt_slot *slots;
@ -606,13 +612,21 @@ evdev_configure_device(struct evdev_device *device)
if (libevdev_has_event_type(evdev, EV_ABS)) { if (libevdev_has_event_type(evdev, EV_ABS)) {
if ((absinfo = libevdev_get_abs_info(evdev, ABS_X))) { if ((absinfo = libevdev_get_abs_info(evdev, ABS_X))) {
device->abs.min_x = absinfo->minimum; if (absinfo->resolution == 0) {
device->abs.max_x = absinfo->maximum; fixed = *absinfo;
fixed.resolution = 1;
libevdev_set_abs_info(evdev, ABS_X, &fixed);
}
device->abs.absinfo_x = absinfo;
has_abs = 1; has_abs = 1;
} }
if ((absinfo = libevdev_get_abs_info(evdev, ABS_Y))) { if ((absinfo = libevdev_get_abs_info(evdev, ABS_Y))) {
device->abs.min_y = absinfo->minimum; if (absinfo->resolution == 0) {
device->abs.max_y = absinfo->maximum; fixed = *absinfo;
fixed.resolution = 1;
libevdev_set_abs_info(evdev, ABS_Y, &fixed);
}
device->abs.absinfo_y = absinfo;
has_abs = 1; has_abs = 1;
} }
/* We only handle the slotted Protocol B in weston. /* We only handle the slotted Protocol B in weston.
@ -621,11 +635,23 @@ evdev_configure_device(struct evdev_device *device)
if (libevdev_has_event_code(evdev, EV_ABS, ABS_MT_POSITION_X) && if (libevdev_has_event_code(evdev, EV_ABS, ABS_MT_POSITION_X) &&
libevdev_has_event_code(evdev, EV_ABS, ABS_MT_POSITION_Y)) { libevdev_has_event_code(evdev, EV_ABS, ABS_MT_POSITION_Y)) {
absinfo = libevdev_get_abs_info(evdev, ABS_MT_POSITION_X); absinfo = libevdev_get_abs_info(evdev, ABS_MT_POSITION_X);
device->abs.min_x = absinfo->minimum; if (absinfo->resolution == 0) {
device->abs.max_x = absinfo->maximum; fixed = *absinfo;
fixed.resolution = 1;
libevdev_set_abs_info(evdev,
ABS_MT_POSITION_X,
&fixed);
}
device->abs.absinfo_x = absinfo;
absinfo = libevdev_get_abs_info(evdev, ABS_MT_POSITION_Y); absinfo = libevdev_get_abs_info(evdev, ABS_MT_POSITION_Y);
device->abs.min_y = absinfo->minimum; if (absinfo->resolution == 0) {
device->abs.max_y = absinfo->maximum; fixed = *absinfo;
fixed.resolution = 1;
libevdev_set_abs_info(evdev,
ABS_MT_POSITION_Y,
&fixed);
}
device->abs.absinfo_y = absinfo;
device->is_mt = 1; device->is_mt = 1;
has_touch = 1; has_touch = 1;
has_mt = 1; has_mt = 1;
@ -855,6 +881,25 @@ evdev_device_has_capability(struct evdev_device *device,
} }
} }
int
evdev_device_get_size(struct evdev_device *device,
double *width,
double *height)
{
const struct input_absinfo *x, *y;
x = libevdev_get_abs_info(device->evdev, ABS_X);
y = libevdev_get_abs_info(device->evdev, ABS_Y);
if (!x || !y || !x->resolution || !y->resolution)
return -1;
*width = evdev_convert_to_mm(x, x->maximum);
*height = evdev_convert_to_mm(y, y->maximum);
return 0;
}
void void
evdev_device_remove(struct evdev_device *device) evdev_device_remove(struct evdev_device *device)
{ {

View file

@ -67,7 +67,7 @@ struct evdev_device {
const char *devname; const char *devname;
int fd; int fd;
struct { struct {
int min_x, max_x, min_y, max_y; const struct input_absinfo *absinfo_x, *absinfo_y;
int32_t x, y; int32_t x, y;
int32_t seat_slot; int32_t seat_slot;
@ -152,6 +152,11 @@ int
evdev_device_has_capability(struct evdev_device *device, evdev_device_has_capability(struct evdev_device *device,
enum libinput_device_capability capability); enum libinput_device_capability capability);
int
evdev_device_get_size(struct evdev_device *device,
double *w,
double *h);
double double
evdev_device_transform_x(struct evdev_device *device, evdev_device_transform_x(struct evdev_device *device,
double x, double x,
@ -168,4 +173,11 @@ evdev_device_remove(struct evdev_device *device);
void void
evdev_device_destroy(struct evdev_device *device); evdev_device_destroy(struct evdev_device *device);
static inline double
evdev_convert_to_mm(const struct input_absinfo *absinfo, double v)
{
double value = v - absinfo->minimum;
return value/absinfo->resolution;
}
#endif /* EVDEV_H */ #endif /* EVDEV_H */

View file

@ -376,13 +376,19 @@ libinput_event_pointer_get_dy(struct libinput_event_pointer *event)
LIBINPUT_EXPORT double LIBINPUT_EXPORT double
libinput_event_pointer_get_absolute_x(struct libinput_event_pointer *event) libinput_event_pointer_get_absolute_x(struct libinput_event_pointer *event)
{ {
return event->x; struct evdev_device *device =
(struct evdev_device *) event->base.device;
return evdev_convert_to_mm(device->abs.absinfo_x, event->x);
} }
LIBINPUT_EXPORT double LIBINPUT_EXPORT double
libinput_event_pointer_get_absolute_y(struct libinput_event_pointer *event) libinput_event_pointer_get_absolute_y(struct libinput_event_pointer *event)
{ {
return event->y; struct evdev_device *device =
(struct evdev_device *) event->base.device;
return evdev_convert_to_mm(device->abs.absinfo_y, event->y);
} }
LIBINPUT_EXPORT double LIBINPUT_EXPORT double
@ -459,7 +465,10 @@ libinput_event_touch_get_seat_slot(struct libinput_event_touch *event)
LIBINPUT_EXPORT double LIBINPUT_EXPORT double
libinput_event_touch_get_x(struct libinput_event_touch *event) libinput_event_touch_get_x(struct libinput_event_touch *event)
{ {
return event->x; struct evdev_device *device =
(struct evdev_device *) event->base.device;
return evdev_convert_to_mm(device->abs.absinfo_x, event->x);
} }
LIBINPUT_EXPORT double LIBINPUT_EXPORT double
@ -485,7 +494,10 @@ libinput_event_touch_get_y_transformed(struct libinput_event_touch *event,
LIBINPUT_EXPORT double LIBINPUT_EXPORT double
libinput_event_touch_get_y(struct libinput_event_touch *event) libinput_event_touch_get_y(struct libinput_event_touch *event)
{ {
return event->y; struct evdev_device *device =
(struct evdev_device *) event->base.device;
return evdev_convert_to_mm(device->abs.absinfo_y, event->y);
} }
LIBINPUT_EXPORT int LIBINPUT_EXPORT int
@ -1429,6 +1441,16 @@ libinput_device_has_capability(struct libinput_device *device,
capability); capability);
} }
LIBINPUT_EXPORT int
libinput_device_get_size(struct libinput_device *device,
double *width,
double *height)
{
return evdev_device_get_size((struct evdev_device *)device,
width,
height);
}
LIBINPUT_EXPORT struct libinput_event * LIBINPUT_EXPORT struct libinput_event *
libinput_event_device_notify_get_base_event(struct libinput_event_device_notify *event) libinput_event_device_notify_get_base_event(struct libinput_event_device_notify *event)
{ {

View file

@ -538,11 +538,9 @@ libinput_event_pointer_get_dy(struct libinput_event_pointer *event);
/** /**
* @ingroup event_pointer * @ingroup event_pointer
* *
* Return the current absolute x coordinate of the pointer event. * Return the current absolute x coordinate of the pointer event, in mm from
* * the top left corner of the device. To get the corresponding output screen
* The coordinate is in a device specific coordinate space; to get the * coordinate, use libinput_event_pointer_get_x_transformed().
* corresponding output screen coordinate, use
* libinput_event_pointer_get_x_transformed().
* *
* For pointer events that are not of type * For pointer events that are not of type
* LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE, this function returns 0. * LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE, this function returns 0.
@ -558,11 +556,9 @@ libinput_event_pointer_get_absolute_x(struct libinput_event_pointer *event);
/** /**
* @ingroup event_pointer * @ingroup event_pointer
* *
* Return the current absolute y coordinate of the pointer event. * Return the current absolute y coordinate of the pointer event, in mm from
* * the top left corner of the device. To get the corresponding output screen
* The coordinate is in a device specific coordinate space; to get the * coordinate, use libinput_event_pointer_get_x_transformed().
* corresponding output screen coordinate, use
* libinput_event_pointer_get_y_transformed().
* *
* For pointer events that are not of type * For pointer events that are not of type
* LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE, this function returns 0. * LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE, this function returns 0.
@ -763,11 +759,9 @@ libinput_event_touch_get_seat_slot(struct libinput_event_touch *event);
/** /**
* @ingroup event_touch * @ingroup event_touch
* *
* Return the current absolute x coordinate of the touch event. * Return the current absolute x coordinate of the touch event, in mm from
* * the top left corner of the device. To get the corresponding output screen
* The coordinate is in a device specific coordinate space; to get the * coordinate, use libinput_event_touch_get_x_transformed().
* corresponding output screen coordinate, use
* libinput_event_touch_get_x_transformed().
* *
* @note this function should only be called for LIBINPUT_EVENT_TOUCH_DOWN and * @note this function should only be called for LIBINPUT_EVENT_TOUCH_DOWN and
* LIBINPUT_EVENT_TOUCH_MOTION. * LIBINPUT_EVENT_TOUCH_MOTION.
@ -781,11 +775,9 @@ libinput_event_touch_get_x(struct libinput_event_touch *event);
/** /**
* @ingroup event_touch * @ingroup event_touch
* *
* Return the current absolute y coordinate of the touch event. * Return the current absolute y coordinate of the touch event, in mm from
* * the top left corner of the device. To get the corresponding output screen
* The coordinate is in a device specific coordinate space; to get the * coordinate, use libinput_event_touch_get_y_transformed().
* corresponding output screen coordinate, use
* libinput_event_touch_get_y_transformed().
* *
* For LIBINPUT_EVENT_TOUCH_UP 0 is returned. * For LIBINPUT_EVENT_TOUCH_UP 0 is returned.
* *
@ -1604,6 +1596,25 @@ int
libinput_device_has_capability(struct libinput_device *device, libinput_device_has_capability(struct libinput_device *device,
enum libinput_device_capability capability); enum libinput_device_capability capability);
/**
* @ingroup device
*
* Get the physical size of a device in mm, where meaningful. This function
* only succeeds on devices with the required data, i.e. tablets, touchpads
* and touchscreens.
*
* If this function returns nonzero, width and height are unmodified.
*
* @param device The device
* @param width Set to the width of the device
* @param height Set to the height of the device
* @return 0 on success, or nonzero otherwise
*/
int
libinput_device_get_size(struct libinput_device *device,
double *width,
double *height);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View file

@ -243,10 +243,16 @@ print_device_notify(struct libinput_event *ev)
{ {
struct libinput_device *dev = libinput_event_get_device(ev); struct libinput_device *dev = libinput_event_get_device(ev);
struct libinput_seat *seat = libinput_device_get_seat(dev); struct libinput_seat *seat = libinput_device_get_seat(dev);
double w, h;
printf("%s %s\n", printf("%s %s",
libinput_seat_get_physical_name(seat), libinput_seat_get_physical_name(seat),
libinput_seat_get_logical_name(seat)); libinput_seat_get_logical_name(seat));
if (libinput_device_get_size(dev, &w, &h) == 0)
printf("\tsize %.2f/%.2fmm", w, h);
printf("\n");
} }
static void static void
@ -450,13 +456,16 @@ print_touch_event_with_coords(struct libinput_event *ev)
struct libinput_event_touch *t = libinput_event_get_touch_event(ev); struct libinput_event_touch *t = libinput_event_get_touch_event(ev);
double x = libinput_event_touch_get_x_transformed(t, screen_width); double x = libinput_event_touch_get_x_transformed(t, screen_width);
double y = libinput_event_touch_get_y_transformed(t, screen_height); double y = libinput_event_touch_get_y_transformed(t, screen_height);
double xmm = libinput_event_touch_get_x(t);
double ymm = libinput_event_touch_get_y(t);
print_event_time(libinput_event_touch_get_time(t)); print_event_time(libinput_event_touch_get_time(t));
printf("%d (%d) %5.2f/%5.2f\n", printf("%d (%d) %5.2f/%5.2f (%5.2f/%5.2fmm)\n",
libinput_event_touch_get_slot(t), libinput_event_touch_get_slot(t),
libinput_event_touch_get_seat_slot(t), libinput_event_touch_get_seat_slot(t),
x, y); x, y,
xmm, ymm);
} }
static int static int