Add a patch for support extra touch events. 88/56388/2 accepted/tizen/mobile/20160115.010533 accepted/tizen/tv/20160115.010554 accepted/tizen/wearable/20160115.010614 submit/tizen/20160114.100050
authorJengHyun Kang <jhyuni.kang@samsung.com>
Thu, 7 Jan 2016 08:23:24 +0000 (17:23 +0900)
committerJengHyun Kang <jhyuni.kang@samsung.com>
Wed, 13 Jan 2016 06:15:05 +0000 (15:15 +0900)
  - libinput commit name: add orientation and size of touch point and pressure to the API

Change-Id: Icfd09c132b51bf15837f11bdd662181e666960b5

packaging/libinput.spec [changed mode: 0755->0644]
src/evdev.c
src/evdev.h
src/libinput-private.h
src/libinput-util.h
src/libinput.c
src/libinput.h
src/libinput.sym

old mode 100755 (executable)
new mode 100644 (file)
index cf21d2e2771e595f63e7fad04a605c5dc389eb3d..9e23867366cd6af78b8518d8f90ac9d6edf0a740 100644 (file)
 #include "evdev.h"
 #include "filter.h"
 #include "libinput-private.h"
+#include "stdio.h"
 
 #define DEFAULT_WHEEL_CLICK_ANGLE 15
 #define DEFAULT_MIDDLE_BUTTON_SCROLL_TIMEOUT 200
+#define DEFAULT_TOUCH_PRESSURE 1.0
+#define DEFAULT_TOUCH_ORIENTATION 0.0
+#define DEFAULT_TOUCH_MAJOR 0.0
+#define DEFAULT_TOUCH_MINOR 0.0
 
 enum evdev_key_type {
        EVDEV_KEY_TYPE_NONE,
@@ -222,6 +227,100 @@ evdev_device_transform_y(struct evdev_device *device,
        return scale_axis(device->abs.absinfo_y, y, height);
 }
 
+double
+evdev_device_transform_ellipse_diameter_to_mm(struct evdev_device *device,
+                                             int diameter,
+                                             double axis_angle)
+{
+       double x_res = device->abs.absinfo_x->resolution;
+       double y_res = device->abs.absinfo_y->resolution;
+
+       if (x_res == y_res)
+               return diameter / (x_res ? x_res : 1);
+
+       /* resolution differs but no orientation available
+        * -> estimate resolution using the average */
+       if (device->abs.absinfo_orientation == NULL) {
+               return diameter * 2.0 / (x_res + y_res);
+       } else {
+               /* Why scale x using sine of angle?
+                * axis_angle = 0 indicates that the given diameter
+                * is aligned with the y-axis. */
+               double x_scaling_ratio = fabs(sin(deg2rad(axis_angle)));
+               double y_scaling_ratio = fabs(cos(deg2rad(axis_angle)));
+
+               return diameter / hypotf(y_res * y_scaling_ratio,
+                                        x_res * x_scaling_ratio);
+       }
+}
+
+double
+evdev_device_transform_ellipse_diameter(struct evdev_device *device,
+                                       int diameter,
+                                       double axis_angle,
+                                       uint32_t width,
+                                       uint32_t height)
+{
+       double x_res = device->abs.absinfo_x->resolution;
+       double y_res = device->abs.absinfo_y->resolution;
+       double x_scale = width / (device->abs.x + 1.0);
+       double y_scale = height / (device->abs.y + 1.0);
+
+       if (x_res == y_res)
+               return diameter * x_scale;
+
+       /* no orientation available -> estimate resolution using the
+        * average */
+       if (device->abs.absinfo_orientation == NULL) {
+               return diameter * (x_scale + y_scale) / 2.0;
+       } else {
+               /* Why scale x using sine of angle?
+                * axis_angle = 0 indicates that the given diameter
+                * is aligned with the y-axis. */
+               double x_scaling_ratio = fabs(sin(deg2rad(axis_angle)));
+               double y_scaling_ratio = fabs(cos(deg2rad(axis_angle)));
+
+               return diameter * (y_scale * y_scaling_ratio +
+                                  x_scale * x_scaling_ratio);
+       }
+}
+
+double
+evdev_device_transform_orientation(struct evdev_device *device,
+                                  int32_t orientation)
+{
+       const struct input_absinfo *orientation_info =
+                                       device->abs.absinfo_orientation;
+
+       double angle = DEFAULT_TOUCH_ORIENTATION;
+
+       /* ABS_MT_ORIENTATION is defined as a clockwise rotation - zero
+        * (instead of minimum) is mapped to the y-axis, and maximum is
+        * mapped to the x-axis. So minimum is likely to be negative but
+        * plays no role in scaling the value to degrees.*/
+       if (orientation_info)
+               angle = (90.0 * orientation) / orientation_info->maximum;
+
+       return fmod(360.0 + angle, 360.0);
+}
+
+double
+evdev_device_transform_pressure(struct evdev_device *device,
+                               int32_t pressure)
+{
+       const struct input_absinfo *pressure_info =
+                                       device->abs.absinfo_pressure;
+
+       if (pressure_info) {
+               double max_pressure = pressure_info->maximum;
+               double min_pressure = pressure_info->minimum;
+               return (pressure - min_pressure) /
+                                       (max_pressure - min_pressure);
+       } else {
+               return DEFAULT_TOUCH_PRESSURE;
+       }
+}
+
 static void
 evdev_flush_pending_event(struct evdev_device *device, uint64_t time)
 {
@@ -234,8 +333,15 @@ evdev_flush_pending_event(struct evdev_device *device, uint64_t time)
        int seat_slot;
        struct libinput_device *base = &device->base;
        struct libinput_seat *seat = base->seat;
+       struct mt_slot *slot_data;
+       struct ellipse default_touch = {
+               .major = DEFAULT_TOUCH_MAJOR,
+               .minor = DEFAULT_TOUCH_MINOR,
+               .orientation = DEFAULT_TOUCH_ORIENTATION
+       };
 
        slot = device->mt.slot;
+       slot_data = &device->mt.slots[slot];
 
        switch (device->pending_event) {
        case EVDEV_NONE:
@@ -276,7 +382,7 @@ evdev_flush_pending_event(struct evdev_device *device, uint64_t time)
                if (!(device->seat_caps & EVDEV_DEVICE_TOUCH))
                        break;
 
-               if (device->mt.slots[slot].seat_slot != -1) {
+               if (slot_data->seat_slot != -1) {
                        log_bug_kernel(libinput,
                                       "%s: Driver sent multiple touch down for the "
                                       "same slot",
@@ -285,23 +391,23 @@ evdev_flush_pending_event(struct evdev_device *device, uint64_t time)
                }
 
                seat_slot = ffs(~seat->slot_map) - 1;
-               device->mt.slots[slot].seat_slot = seat_slot;
+               slot_data->seat_slot = seat_slot;
 
                if (seat_slot == -1)
                        break;
 
                seat->slot_map |= 1 << seat_slot;
-               x = device->mt.slots[slot].x;
-               y = device->mt.slots[slot].y;
+               x = slot_data->x;
+               y = slot_data->y;
                transform_absolute(device, &x, &y);
 
-               touch_notify_touch_down(base, time, slot, seat_slot, x, y);
+               touch_notify_touch_down(base, time, slot, seat_slot, x, y, &slot_data->area, slot_data->pressure);
                break;
        case EVDEV_ABSOLUTE_MT_MOTION:
                if (!(device->seat_caps & EVDEV_DEVICE_TOUCH))
                        break;
 
-               seat_slot = device->mt.slots[slot].seat_slot;
+               seat_slot = slot_data->seat_slot;
                x = device->mt.slots[slot].x;
                y = device->mt.slots[slot].y;
 
@@ -309,14 +415,14 @@ evdev_flush_pending_event(struct evdev_device *device, uint64_t time)
                        break;
 
                transform_absolute(device, &x, &y);
-               touch_notify_touch_motion(base, time, slot, seat_slot, x, y);
+               touch_notify_touch_motion(base, time, slot, seat_slot, x, y, &slot_data->area, slot_data->pressure);
                break;
        case EVDEV_ABSOLUTE_MT_UP:
                if (!(device->seat_caps & EVDEV_DEVICE_TOUCH))
                        break;
 
-               seat_slot = device->mt.slots[slot].seat_slot;
-               device->mt.slots[slot].seat_slot = -1;
+               seat_slot = slot_data->seat_slot;
+               slot_data->seat_slot = -1;
 
                if (seat_slot == -1)
                        break;
@@ -349,7 +455,7 @@ evdev_flush_pending_event(struct evdev_device *device, uint64_t time)
                cy = device->abs.y;
                transform_absolute(device, &cx, &cy);
 
-               touch_notify_touch_down(base, time, -1, seat_slot, cx, cy);
+               touch_notify_touch_down(base, time, -1, seat_slot, cx, cy, &default_touch, DEFAULT_TOUCH_PRESSURE);
                break;
        case EVDEV_ABSOLUTE_MOTION:
                cx = device->abs.x;
@@ -364,7 +470,7 @@ evdev_flush_pending_event(struct evdev_device *device, uint64_t time)
                        if (seat_slot == -1)
                                break;
 
-                       touch_notify_touch_motion(base, time, -1, seat_slot, x, y);
+                       touch_notify_touch_motion(base, time, -1, seat_slot, x, y, &default_touch, DEFAULT_TOUCH_PRESSURE);
                } else if (device->seat_caps & EVDEV_DEVICE_POINTER) {
                        pointer_notify_motion_absolute(base, time, x, y);
                }
@@ -522,12 +628,12 @@ evdev_process_touch(struct evdev_device *device,
                    struct input_event *e,
                    uint64_t time)
 {
-       switch (e->code) {
-       case ABS_MT_SLOT:
+       struct mt_slot *current_slot = &device->mt.slots[device->mt.slot];
+
+       if (e->code == ABS_MT_SLOT) {
                evdev_flush_pending_event(device, time);
                device->mt.slot = e->value;
-               break;
-       case ABS_MT_TRACKING_ID:
+       } else if(e->code == ABS_MT_TRACKING_ID) {
                if (device->pending_event != EVDEV_NONE &&
                    device->pending_event != EVDEV_ABSOLUTE_MT_MOTION)
                        evdev_flush_pending_event(device, time);
@@ -535,17 +641,31 @@ evdev_process_touch(struct evdev_device *device,
                        device->pending_event = EVDEV_ABSOLUTE_MT_DOWN;
                else
                        device->pending_event = EVDEV_ABSOLUTE_MT_UP;
-               break;
-       case ABS_MT_POSITION_X:
-               device->mt.slots[device->mt.slot].x = e->value;
-               if (device->pending_event == EVDEV_NONE)
-                       device->pending_event = EVDEV_ABSOLUTE_MT_MOTION;
-               break;
-       case ABS_MT_POSITION_Y:
-               device->mt.slots[device->mt.slot].y = e->value;
-               if (device->pending_event == EVDEV_NONE)
+       } else {
+               bool needs_wake = true;
+
+               switch (e->code) {
+               case ABS_MT_POSITION_X:
+                       current_slot->x = e->value;
+                       break;
+               case ABS_MT_POSITION_Y:
+                       current_slot->y = e->value;
+                       break;
+               case ABS_MT_TOUCH_MAJOR:
+                       current_slot->area.major = e->value;
+                       break;
+               case ABS_MT_TOUCH_MINOR:
+                       current_slot->area.minor = e->value;
+                       break;
+               case ABS_MT_ORIENTATION:
+                       current_slot->area.orientation = e->value;
+                       break;
+               default:
+                       needs_wake = false;
+                       break;
+               }
+               if (needs_wake && device->pending_event == EVDEV_NONE)
                        device->pending_event = EVDEV_ABSOLUTE_MT_MOTION;
-               break;
        }
 }
 
@@ -1419,8 +1539,12 @@ evdev_configure_device(struct evdev_device *device)
                return -1;
        }
 
-       if (libevdev_has_event_type(evdev, EV_ABS)) {
+       device->abs.absinfo_orientation = libevdev_get_abs_info(evdev, ABS_MT_ORIENTATION);
+       device->abs.absinfo_pressure = libevdev_get_abs_info(evdev, ABS_MT_PRESSURE);
+       device->abs.absinfo_major = libevdev_get_abs_info(evdev, ABS_MT_TOUCH_MAJOR);
+       device->abs.absinfo_minor = libevdev_get_abs_info(evdev, ABS_MT_TOUCH_MINOR);
 
+       if (libevdev_has_event_type(evdev, EV_ABS)) {
                if ((absinfo = libevdev_get_abs_info(evdev, ABS_X))) {
                        if (evdev_fix_abs_resolution(evdev,
                                                     ABS_X,
@@ -1483,8 +1607,12 @@ evdev_configure_device(struct evdev_device *device)
 
                        for (slot = 0; slot < num_slots; ++slot) {
                                slots[slot].seat_slot = -1;
-                               slots[slot].x = 0;
-                               slots[slot].y = 0;
+                               slots[slot].x = libevdev_get_slot_value(evdev, slot, ABS_MT_POSITION_X);
+                               slots[slot].y = libevdev_get_slot_value(evdev, slot, ABS_MT_POSITION_Y);
+                               slots[slot].area.major = libevdev_get_slot_value(evdev, slot, ABS_MT_TOUCH_MAJOR);
+                               slots[slot].area.minor = libevdev_get_slot_value(evdev, slot, ABS_MT_TOUCH_MINOR);
+                               slots[slot].area.orientation = libevdev_get_slot_value(evdev, slot, ABS_MT_ORIENTATION);
+                               slots[slot].pressure = libevdev_get_slot_value(evdev, slot, ABS_MT_PRESSURE);
                        }
                        device->mt.slots = slots;
                        device->mt.slots_len = num_slots;
index 72082e5aaade15f251e7125ee2aa4c42bd2464a4..a1feabde164a6b46080f05231e2bf1578edc11dd 100644 (file)
@@ -60,6 +60,8 @@ enum evdev_device_tags {
 struct mt_slot {
        int32_t seat_slot;
        int32_t x, y;
+       struct ellipse area;
+       int32_t pressure;
 };
 
 struct evdev_device {
@@ -76,6 +78,7 @@ struct evdev_device {
        int fd;
        struct {
                const struct input_absinfo *absinfo_x, *absinfo_y;
+               const struct input_absinfo *absinfo_major, *absinfo_minor, *absinfo_pressure, *absinfo_orientation;
                int fake_resolution;
 
                int32_t x, y;
@@ -272,6 +275,27 @@ double
 evdev_device_transform_y(struct evdev_device *device,
                         double y,
                         uint32_t height);
+
+double
+evdev_device_transform_ellipse_diameter_to_mm(struct evdev_device *device,
+                                             int32_t diameter,
+                                             double axis_angle);
+
+double
+evdev_device_transform_ellipse_diameter(struct evdev_device *device,
+                                       int32_t diameter,
+                                       double axis_angle,
+                                       uint32_t width,
+                                       uint32_t height);
+
+double
+evdev_device_transform_orientation(struct evdev_device *device,
+                                  int32_t orientation);
+
+double
+evdev_device_transform_pressure(struct evdev_device *device,
+                               int32_t pressure);
+
 int
 evdev_device_suspend(struct evdev_device *device);
 
index dbe15586493eb2e7ced16732e8d46d084ec9fb21..0b216f4188ab60075916cd566b14d4b5e2c30881 100644 (file)
 
 struct libinput_source;
 
+/* Ellipse parameters in device coordinates */
+struct ellipse {
+       int major, minor, orientation;
+};
+
 struct libinput_interface_backend {
        int (*resume)(struct libinput *libinput);
        void (*suspend)(struct libinput *libinput);
@@ -313,7 +318,9 @@ touch_notify_touch_down(struct libinput_device *device,
                        int32_t slot,
                        int32_t seat_slot,
                        double x,
-                       double y);
+                       double y,
+                       const struct ellipse *area,
+                       int32_t pressure);
 
 void
 touch_notify_touch_motion(struct libinput_device *device,
@@ -321,7 +328,9 @@ touch_notify_touch_motion(struct libinput_device *device,
                          int32_t slot,
                          int32_t seat_slot,
                          double x,
-                         double y);
+                         double y,
+                         const struct ellipse *area,
+                         int32_t pressure);
 
 void
 touch_notify_touch_up(struct libinput_device *device,
index f76439f110cdb02c326be84d87ecf08ec186e83a..88aff93c3c463f03ae47dd17454507a21abc6566 100644 (file)
@@ -98,6 +98,12 @@ msleep(unsigned int ms)
        usleep(ms * 1000);
 }
 
+static inline double
+deg2rad(double angle)
+{
+       return angle * M_PI/180.0;
+}
+
 enum directions {
        N  = 1 << 0,
        NE = 1 << 1,
index c1e68eb15a9de963e77efd1d8960fbc2a7b0c834..7a1055ca178f3aaff13c13817cf82d292ea50fe4 100644 (file)
 #include "evdev.h"
 #include "timer.h"
 
+#define require_event_type(li_, type_, retval_, ...)   \
+       if (type_ == LIBINPUT_EVENT_NONE) abort(); \
+       if (!check_event_type(li_, __func__, type_, __VA_ARGS__, -1)) \
+               return retval_; \
+
+static inline bool
+check_event_type(struct libinput *libinput,
+                const char *function_name,
+                enum libinput_event_type type_in,
+                ...)
+{
+       bool rc = false;
+       va_list args;
+       unsigned int type_permitted;
+
+       va_start(args, type_in);
+       type_permitted = va_arg(args, unsigned int);
+
+       while (type_permitted != (unsigned int)-1) {
+               if (type_permitted == type_in) {
+                       rc = true;
+                       break;
+               }
+               type_permitted = va_arg(args, unsigned int);
+       }
+
+       va_end(args);
+
+       if (!rc)
+               log_bug_client(libinput,
+                                  "Invalid event type %d passed to %s()\n",
+                                  type_in, function_name);
+
+       return rc;
+}
+
 struct libinput_source {
        libinput_source_dispatch_t dispatch;
        void *user_data;
@@ -77,6 +113,8 @@ struct libinput_event_touch {
        int32_t seat_slot;
        double x;
        double y;
+       struct ellipse area;
+       int32_t pressure;
 };
 
 static void
@@ -501,6 +539,227 @@ libinput_event_touch_get_y(struct libinput_event_touch *event)
        return evdev_convert_to_mm(device->abs.absinfo_y, event->y);
 }
 
+LIBINPUT_EXPORT double
+libinput_event_touch_get_major(struct libinput_event_touch *event)
+{
+#if 0
+       struct evdev_device *device =
+               (struct evdev_device *) event->base.device;
+       double angle;
+#endif
+       require_event_type(libinput_event_get_context(&event->base),
+                          event->base.type,
+                          0,
+                          LIBINPUT_EVENT_TOUCH_DOWN,
+                          LIBINPUT_EVENT_TOUCH_MOTION);
+
+       /* return touch major value directly.
+           Currently transfrom touch major value is not needed */
+       return event->area.major;
+#if 0
+       angle = evdev_device_transform_orientation(device,
+                                                  event->area.orientation);
+
+       return evdev_device_transform_ellipse_diameter_to_mm(device,
+                                                            event->area.major,
+                                                            angle);
+#endif
+}
+
+LIBINPUT_EXPORT double
+libinput_event_touch_get_major_transformed(struct libinput_event_touch *event,
+                                          uint32_t width,
+                                          uint32_t height)
+{
+#if 0
+       struct evdev_device *device =
+               (struct evdev_device *) event->base.device;
+       double angle;
+#endif
+       require_event_type(libinput_event_get_context(&event->base),
+                          event->base.type,
+                          0,
+                          LIBINPUT_EVENT_TOUCH_DOWN,
+                          LIBINPUT_EVENT_TOUCH_MOTION);
+
+       /* return touch major value directly.
+           Currently transfrom touch major value is not needed */
+       return event->area.major;
+#if 0
+       angle = evdev_device_transform_orientation(device,
+                                                  event->area.orientation);
+
+       return evdev_device_transform_ellipse_diameter(device,
+                                                      event->area.major,
+                                                      angle,
+                                                      width,
+                                                      height);
+#endif
+}
+
+LIBINPUT_EXPORT int
+libinput_event_touch_has_major(struct libinput_event_touch *event)
+{
+       struct evdev_device *device =
+               (struct evdev_device *) event->base.device;
+
+       require_event_type(libinput_event_get_context(&event->base),
+                          event->base.type,
+                          0,
+                          LIBINPUT_EVENT_TOUCH_DOWN,
+                          LIBINPUT_EVENT_TOUCH_MOTION);
+
+       return device->abs.absinfo_major != 0;
+}
+
+LIBINPUT_EXPORT double
+libinput_event_touch_get_minor(struct libinput_event_touch *event)
+{
+#if 0
+       struct evdev_device *device =
+               (struct evdev_device *) event->base.device;
+       double angle;
+#endif
+       require_event_type(libinput_event_get_context(&event->base),
+                          event->base.type,
+                          0,
+                          LIBINPUT_EVENT_TOUCH_DOWN,
+                          LIBINPUT_EVENT_TOUCH_MOTION);
+
+       /* return touch minor value directly.
+           Currently transfrom touch minor value is not needed */
+       return event->area.minor;
+#if 0
+       angle = evdev_device_transform_orientation(device,
+                                                  event->area.orientation);
+
+       /* angle + 90 since the minor diameter is perpendicular to the
+        * major axis */
+       return evdev_device_transform_ellipse_diameter_to_mm(device,
+                                                            event->area.minor,
+                                                            angle + 90.0);
+#endif
+}
+
+LIBINPUT_EXPORT double
+libinput_event_touch_get_minor_transformed(struct libinput_event_touch *event,
+                                          uint32_t width,
+                                          uint32_t height)
+{
+#if 0
+       struct evdev_device *device =
+               (struct evdev_device *) event->base.device;
+       double angle;
+       int diameter;
+#endif
+       require_event_type(libinput_event_get_context(&event->base),
+                          event->base.type,
+                          0,
+                          LIBINPUT_EVENT_TOUCH_DOWN,
+                          LIBINPUT_EVENT_TOUCH_MOTION);
+
+       /* return touch minor value directly.
+           Currently transfrom touch minor value is not needed */
+       return event->area.minor;
+#if 0
+       angle = evdev_device_transform_orientation(device,
+                                                  event->area.orientation);
+
+       /* use major diameter if minor is not available, but if it is
+        * add 90 since the minor diameter is perpendicular to the
+        * major axis */
+       if (device->abs.absinfo_minor) {
+               diameter = event->area.minor,
+               angle += 90.0;
+       } else {
+               diameter = event->area.major;
+       }
+
+       return evdev_device_transform_ellipse_diameter(device,
+                                                      diameter,
+                                                      angle,
+                                                      width,
+                                                      height);
+#endif
+}
+
+LIBINPUT_EXPORT int
+libinput_event_touch_has_minor(struct libinput_event_touch *event)
+{
+       struct evdev_device *device =
+               (struct evdev_device *) event->base.device;
+
+       require_event_type(libinput_event_get_context(&event->base),
+                          event->base.type,
+                          0,
+                          LIBINPUT_EVENT_TOUCH_DOWN,
+                          LIBINPUT_EVENT_TOUCH_MOTION);
+
+       return device->abs.absinfo_minor != 0;
+}
+
+LIBINPUT_EXPORT double
+libinput_event_touch_get_orientation(struct libinput_event_touch *event)
+{
+       struct evdev_device *device =
+               (struct evdev_device *) event->base.device;
+
+       require_event_type(libinput_event_get_context(&event->base),
+                          event->base.type,
+                          0,
+                          LIBINPUT_EVENT_TOUCH_DOWN,
+                          LIBINPUT_EVENT_TOUCH_MOTION);
+
+       return evdev_device_transform_orientation(device,
+                                                 event->area.orientation);
+}
+
+LIBINPUT_EXPORT int
+libinput_event_touch_has_orientation(struct libinput_event_touch *event)
+{
+       struct evdev_device *device =
+               (struct evdev_device *) event->base.device;
+
+       require_event_type(libinput_event_get_context(&event->base),
+                          event->base.type,
+                          0,
+                          LIBINPUT_EVENT_TOUCH_DOWN,
+                          LIBINPUT_EVENT_TOUCH_MOTION);
+
+       return device->abs.absinfo_orientation != 0;
+}
+
+LIBINPUT_EXPORT double
+libinput_event_touch_get_pressure(struct libinput_event_touch *event)
+{
+       struct evdev_device *device =
+               (struct evdev_device *) event->base.device;
+
+       require_event_type(libinput_event_get_context(&event->base),
+                          event->base.type,
+                          0,
+                          LIBINPUT_EVENT_TOUCH_DOWN,
+                          LIBINPUT_EVENT_TOUCH_MOTION);
+
+       return evdev_device_transform_pressure(device,
+                                              event->pressure);
+}
+
+LIBINPUT_EXPORT int
+libinput_event_touch_has_pressure(struct libinput_event_touch *event)
+{
+       struct evdev_device *device =
+               (struct evdev_device *) event->base.device;
+
+       require_event_type(libinput_event_get_context(&event->base),
+                          event->base.type,
+                          0,
+                          LIBINPUT_EVENT_TOUCH_DOWN,
+                          LIBINPUT_EVENT_TOUCH_MOTION);
+
+       return device->abs.absinfo_pressure != 0;
+}
+
 struct libinput_source *
 libinput_add_fd(struct libinput *libinput,
                int fd,
@@ -1072,7 +1331,9 @@ touch_notify_touch_down(struct libinput_device *device,
                        int32_t slot,
                        int32_t seat_slot,
                        double x,
-                       double y)
+                       double y,
+                       const struct ellipse *area,
+                       int32_t pressure)
 {
        struct libinput_event_touch *touch_event;
 
@@ -1086,6 +1347,8 @@ touch_notify_touch_down(struct libinput_device *device,
                .seat_slot = seat_slot,
                .x = x,
                .y = y,
+               .area = *area,
+               .pressure = pressure,
        };
 
        post_device_event(device, time,
@@ -1099,7 +1362,9 @@ touch_notify_touch_motion(struct libinput_device *device,
                          int32_t slot,
                          int32_t seat_slot,
                          double x,
-                         double y)
+                         double y,
+                         const struct ellipse *area,
+                         int32_t pressure)
 {
        struct libinput_event_touch *touch_event;
 
@@ -1113,6 +1378,8 @@ touch_notify_touch_motion(struct libinput_device *device,
                .seat_slot = seat_slot,
                .x = x,
                .y = y,
+               .area = *area,
+               .pressure = pressure,
        };
 
        post_device_event(device, time,
index 56c3ca13cac7aa38275314225bd9e005a9980c9e..08deb47a5ff598e4e8970d0ba502135bdb853d50 100644 (file)
@@ -884,6 +884,228 @@ double
 libinput_event_touch_get_y_transformed(struct libinput_event_touch *event,
                                       uint32_t height);
 
+/**
+ * @ingroup event_touch
+ *
+ * Return the diameter of the major axis of the touch ellipse in mm.
+ * This value might not be provided by the device, in that case the value
+ * 0.0 is returned.
+ *
+ * A more detailed explanation can be found in @ref touch_event_properties.
+ *
+ * For events not of type @ref LIBINPUT_EVENT_TOUCH_DOWN, @ref
+ * LIBINPUT_EVENT_TOUCH_MOTION, this function returns 0.
+ *
+ * @note It is an application bug to call this function for events of type
+ * other than @ref LIBINPUT_EVENT_TOUCH_DOWN or @ref
+ * LIBINPUT_EVENT_TOUCH_MOTION.
+ *
+ * @param event The libinput touch event
+ * @return The current major axis diameter
+ */
+double
+libinput_event_touch_get_major(struct libinput_event_touch *event);
+
+/**
+ * @ingroup event_touch
+ *
+ * Return the diameter of the major axis of the touch ellipse in screen
+ * space. This value might not be provided by the device, in that case the
+ * value 0.0 is returned.
+ *
+ * A more detailed explanation can be found in @ref touch_event_properties.
+ *
+ * For events not of type @ref LIBINPUT_EVENT_TOUCH_DOWN or @ref
+ * LIBINPUT_EVENT_TOUCH_MOTION this function returns 0.
+ *
+ * @note It is an application bug to call this function for events of type
+ * other than @ref LIBINPUT_EVENT_TOUCH_DOWN or @ref
+ * LIBINPUT_EVENT_TOUCH_MOTION.
+ *
+ * @param event The libinput touch event
+ * @param width The current output screen width
+ * @param height The current output screen height
+ * @return The current major axis diameter
+ */
+double
+libinput_event_touch_get_major_transformed(struct libinput_event_touch *event,
+                                          uint32_t width,
+                                          uint32_t height);
+
+/**
+ * @ingroup event_touch
+ *
+ * Return whether the event contains a major axis value of the touch ellipse.
+ *
+ * A more detailed explanation can be found in @ref touch_event_properties.
+ *
+ * For events not of type @ref LIBINPUT_EVENT_TOUCH_DOWN, @ref
+ * LIBINPUT_EVENT_TOUCH_MOTION, this function returns 0.
+ *
+ * @note It is an application bug to call this function for events of type
+ * other than @ref LIBINPUT_EVENT_TOUCH_DOWN or @ref
+ * LIBINPUT_EVENT_TOUCH_MOTION.
+ *
+ * @param event The libinput touch event
+ * @return Non-zero when a major diameter is available
+ */
+int
+libinput_event_touch_has_major(struct libinput_event_touch *event);
+
+/**
+ * @ingroup event_touch
+ *
+ * Return the diameter of the minor axis of the touch ellipse in mm.
+ * This value might not be provided by the device, in this case the value
+ * 0.0 is returned.
+ *
+ * A more detailed explanation can be found in @ref touch_event_properties.
+ *
+ * For events not of type @ref LIBINPUT_EVENT_TOUCH_DOWN or @ref
+ * LIBINPUT_EVENT_TOUCH_MOTION this function returns 0.
+ *
+ * @note It is an application bug to call this function for events of type
+ * other than @ref LIBINPUT_EVENT_TOUCH_DOWN or @ref
+ * LIBINPUT_EVENT_TOUCH_MOTION.
+ *
+ * @param event The libinput touch event
+ * @return The current minor diameter
+ */
+double
+libinput_event_touch_get_minor(struct libinput_event_touch *event);
+
+/**
+ * @ingroup event_touch
+ *
+ * Return the diameter of the minor axis of the touch ellipse in screen
+ * space. This value might not be provided by the device, in this case
+ * the value 0.0 is returned.
+ *
+ * A more detailed explanation can be found in @ref touch_event_properties.
+ *
+ * For events not of type @ref LIBINPUT_EVENT_TOUCH_DOWN or @ref
+ * LIBINPUT_EVENT_TOUCH_MOTION this function returns 0.
+ *
+ * @note It is an application bug to call this function for events of type
+ * other than @ref LIBINPUT_EVENT_TOUCH_DOWN or @ref
+ * LIBINPUT_EVENT_TOUCH_MOTION.
+ *
+ * @param event The libinput touch event
+ * @param width The current output screen width
+ * @param height The current output screen height
+ * @return The current minor diameter
+ */
+double
+libinput_event_touch_get_minor_transformed(struct libinput_event_touch *event,
+                                          uint32_t width,
+                                          uint32_t height);
+/**
+ * @ingroup event_touch
+ *
+ * Return whether the event contains a minor axis value of the touch ellipse.
+ *
+ * A more detailed explanation can be found in @ref touch_event_properties.
+ *
+ * For events not of type @ref LIBINPUT_EVENT_TOUCH_DOWN, @ref
+ * LIBINPUT_EVENT_TOUCH_MOTION, this function returns 0.
+ *
+ * @note It is an application bug to call this function for events of type
+ * other than @ref LIBINPUT_EVENT_TOUCH_DOWN or @ref
+ * LIBINPUT_EVENT_TOUCH_MOTION.
+ *
+ * @param event The libinput touch event
+ * @return Non-zero when a minor diameter is available
+ */
+int
+libinput_event_touch_has_minor(struct libinput_event_touch *event);
+
+/**
+ * @ingroup event_touch
+ *
+ * Return the pressure value applied to the touch contact normalized to the
+ * range [0, 1]. If this value is not available the function returns the maximum
+ * value 1.0.
+ *
+ * A more detailed explanation can be found in @ref touch_event_properties.
+ *
+ * For events not of type @ref LIBINPUT_EVENT_TOUCH_DOWN or @ref
+ * LIBINPUT_EVENT_TOUCH_MOTION this function returns 0.
+ *
+ * @note It is an application bug to call this function for events of type
+ * other than @ref LIBINPUT_EVENT_TOUCH_DOWN or @ref
+ * LIBINPUT_EVENT_TOUCH_MOTION.
+ *
+ * @param event The libinput touch event
+ * @return The current pressure value
+ */
+double
+libinput_event_touch_get_pressure(struct libinput_event_touch *event);
+
+/**
+ * @ingroup event_touch
+ *
+ * Return whether the event contains a pressure value for the touch contact.
+ *
+ * A more detailed explanation can be found in @ref touch_event_properties.
+ *
+ * For events not of type @ref LIBINPUT_EVENT_TOUCH_DOWN, @ref
+ * LIBINPUT_EVENT_TOUCH_MOTION, this function returns 0.
+ *
+ * @note It is an application bug to call this function for events of type
+ * other than @ref LIBINPUT_EVENT_TOUCH_DOWN or @ref
+ * LIBINPUT_EVENT_TOUCH_MOTION.
+ *
+ * @param event The libinput touch event
+ * @return Non-zero when a pressure value is available
+ */
+int
+libinput_event_touch_has_pressure(struct libinput_event_touch *event);
+
+/**
+ * @ingroup event_touch
+ *
+ * Return the major axis rotation in degrees, clockwise from the logical north
+ * of the touch screen.
+ *
+ * @note Even when the orientation is measured by the device, it might be only
+ * available in coarse steps (e.g only indicating alignment with either of the
+ * axes).
+ *
+ * A more detailed explanation can be found in @ref touch_event_properties.
+ *
+ * For events not of type @ref LIBINPUT_EVENT_TOUCH_DOWN, @ref
+ * LIBINPUT_EVENT_TOUCH_MOTION, this function returns 0.
+ *
+ * @note It is an application bug to call this function for events of type
+ * other than @ref LIBINPUT_EVENT_TOUCH_DOWN or @ref
+ * LIBINPUT_EVENT_TOUCH_MOTION.
+ *
+ * @param event The libinput touch event
+ * @return The current orientation value
+ */
+double
+libinput_event_touch_get_orientation(struct libinput_event_touch *event);
+
+/**
+ * @ingroup event_touch
+ *
+ * Return whether the event contains a orientation value for the touch contact.
+ *
+ * A more detailed explanation can be found in @ref touch_event_properties.
+ *
+ * For events not of type @ref LIBINPUT_EVENT_TOUCH_DOWN, @ref
+ * LIBINPUT_EVENT_TOUCH_MOTION, this function returns 0.
+ *
+ * @note It is an application bug to call this function for events of type
+ * other than @ref LIBINPUT_EVENT_TOUCH_DOWN or @ref
+ * LIBINPUT_EVENT_TOUCH_MOTION.
+ *
+ * @param event The libinput touch event
+ * @return Non-zero when an orientation value is available
+ */
+int
+libinput_event_touch_has_orientation(struct libinput_event_touch *event);
+
 /**
  * @ingroup event_touch
  *
index 644e910551c8515737c976b44643d92aa12e4500..e96c9ec45dcd8b4973b0fa27839a86c8a1da5ed3 100644 (file)
@@ -136,3 +136,16 @@ LIBINPUT_0.11.0 {
 
        libinput_device_pointer_has_button;
 } LIBINPUT_0.9.0;
+
+LIBINPUT_1.1_unreleased {
+       libinput_event_touch_get_major;
+       libinput_event_touch_get_major_transformed;
+       libinput_event_touch_get_minor;
+       libinput_event_touch_get_minor_transformed;
+       libinput_event_touch_get_orientation;
+       libinput_event_touch_get_pressure;
+       libinput_event_touch_has_major;
+       libinput_event_touch_has_minor;
+       libinput_event_touch_has_orientation;
+       libinput_event_touch_has_pressure;
+} LIBINPUT_0.9.0;