[mutter] clutter/evdev: Add ClutterInputDeviceEvdev::device-matrix property



commit cc838ead8bb38786c18e426e613df8de9c8cae33
Author: Carlos Garnacho <carlosg gnome org>
Date:   Tue Nov 8 13:00:15 2016 +0100

    clutter/evdev: Add ClutterInputDeviceEvdev::device-matrix property
    
    And transform absolute events using this matrix. This property is
    akin to the "Coordinate Transformation Matrix" property in X11,
    and will be used to map tablets/touchscreens to outputs, favoured
    over the libinput matrix which is meant for calibration.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=774115

 .../clutter/evdev/clutter-device-manager-evdev.c   |    7 ++
 clutter/clutter/evdev/clutter-input-device-evdev.c |   88 ++++++++++++++++++++
 clutter/clutter/evdev/clutter-input-device-evdev.h |    7 ++
 3 files changed, 102 insertions(+), 0 deletions(-)
---
diff --git a/clutter/clutter/evdev/clutter-device-manager-evdev.c 
b/clutter/clutter/evdev/clutter-device-manager-evdev.c
index 2a3c768..23c43ad 100644
--- a/clutter/clutter/evdev/clutter-device-manager-evdev.c
+++ b/clutter/clutter/evdev/clutter-device-manager-evdev.c
@@ -312,6 +312,9 @@ new_absolute_motion_event (ClutterInputDevice *input_device,
   _clutter_xkb_translate_state (event, seat->xkb, seat->button_state);
   event->motion.x = x;
   event->motion.y = y;
+  clutter_input_device_evdev_translate_coordinates (input_device, stage,
+                                                    &event->motion.x,
+                                                    &event->motion.y);
   event->motion.axes = axes;
   clutter_event_set_source_device (event, input_device);
 
@@ -510,6 +513,10 @@ notify_touch_event (ClutterInputDevice *input_device,
   event->touch.device = seat->core_pointer;
   event->touch.x = x;
   event->touch.y = y;
+  clutter_input_device_evdev_translate_coordinates (input_device, stage,
+                                                    &event->touch.x,
+                                                    &event->touch.y);
+
   /* "NULL" sequences are special cased in clutter */
   event->touch.sequence = GINT_TO_POINTER (slot + 1);
   _clutter_xkb_translate_state (event, seat->xkb, seat->button_state);
diff --git a/clutter/clutter/evdev/clutter-input-device-evdev.c 
b/clutter/clutter/evdev/clutter-input-device-evdev.c
index c6f515f..c321d41 100644
--- a/clutter/clutter/evdev/clutter-input-device-evdev.c
+++ b/clutter/clutter/evdev/clutter-input-device-evdev.c
@@ -35,6 +35,8 @@
 #include "clutter-input-device-evdev.h"
 #include "clutter-device-manager-evdev.h"
 
+#include "cairo-gobject.h"
+
 typedef struct _ClutterInputDeviceClass        ClutterInputDeviceEvdevClass;
 
 #define clutter_input_device_evdev_get_type _clutter_input_device_evdev_get_type
@@ -43,6 +45,14 @@ G_DEFINE_TYPE (ClutterInputDeviceEvdev,
                clutter_input_device_evdev,
                CLUTTER_TYPE_INPUT_DEVICE)
 
+enum {
+  PROP_0,
+  PROP_DEVICE_MATRIX,
+  N_PROPS
+};
+
+static GParamSpec *obj_props[N_PROPS] = { 0 };
+
 static void
 clutter_input_device_evdev_finalize (GObject *object)
 {
@@ -59,6 +69,47 @@ clutter_input_device_evdev_finalize (GObject *object)
   G_OBJECT_CLASS (clutter_input_device_evdev_parent_class)->finalize (object);
 }
 
+static void
+clutter_input_device_evdev_set_property (GObject      *object,
+                                         guint         prop_id,
+                                         const GValue *value,
+                                         GParamSpec   *pspec)
+{
+  ClutterInputDeviceEvdev *device = CLUTTER_INPUT_DEVICE_EVDEV (object);
+
+  switch (prop_id)
+    {
+    case PROP_DEVICE_MATRIX:
+      {
+        const cairo_matrix_t *matrix = g_value_get_boxed (value);
+        cairo_matrix_init_identity (&device->device_matrix);
+        cairo_matrix_multiply (&device->device_matrix,
+                               &device->device_matrix, matrix);
+        break;
+      }
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+    }
+}
+
+static void
+clutter_input_device_evdev_get_property (GObject    *object,
+                                         guint       prop_id,
+                                         GValue     *value,
+                                         GParamSpec *pspec)
+{
+  ClutterInputDeviceEvdev *device = CLUTTER_INPUT_DEVICE_EVDEV (object);
+
+  switch (prop_id)
+    {
+    case PROP_DEVICE_MATRIX:
+      g_value_set_boxed (value, &device->device_matrix);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+    }
+}
+
 static gboolean
 clutter_input_device_evdev_keycode_to_evdev (ClutterInputDevice *device,
                                              guint hardware_keycode,
@@ -114,13 +165,26 @@ clutter_input_device_evdev_class_init (ClutterInputDeviceEvdevClass *klass)
   GObjectClass *object_class = G_OBJECT_CLASS (klass);
 
   object_class->finalize = clutter_input_device_evdev_finalize;
+  object_class->set_property = clutter_input_device_evdev_set_property;
+  object_class->get_property = clutter_input_device_evdev_get_property;
+
   klass->keycode_to_evdev = clutter_input_device_evdev_keycode_to_evdev;
   klass->update_from_tool = clutter_input_device_evdev_update_from_tool;
+
+  obj_props[PROP_DEVICE_MATRIX] =
+    g_param_spec_boxed ("device-matrix",
+                       P_("Device input matrix"),
+                       P_("Device input matrix"),
+                       CAIRO_GOBJECT_TYPE_MATRIX,
+                       CLUTTER_PARAM_READWRITE);
+
+  g_object_class_install_properties (object_class, N_PROPS, obj_props);
 }
 
 static void
 clutter_input_device_evdev_init (ClutterInputDeviceEvdev *self)
 {
+  cairo_matrix_init_identity (&self->device_matrix);
 }
 
 /*
@@ -313,3 +377,27 @@ clutter_evdev_event_sequence_get_slot (const ClutterEventSequence *sequence)
 
   return GPOINTER_TO_INT (sequence) - 1;
 }
+
+void
+clutter_input_device_evdev_translate_coordinates (ClutterInputDevice *device,
+                                                  ClutterStage       *stage,
+                                                  gfloat             *x,
+                                                  gfloat             *y)
+{
+  ClutterInputDeviceEvdev *device_evdev = CLUTTER_INPUT_DEVICE_EVDEV (device);
+  double min_x = 0, min_y = 0, max_x = 1, max_y = 1;
+  gdouble stage_width, stage_height;
+  double x_d, y_d;
+
+  stage_width = clutter_actor_get_width (CLUTTER_ACTOR (stage));
+  stage_height = clutter_actor_get_height (CLUTTER_ACTOR (stage));
+  x_d = *x / stage_width;
+  y_d = *y / stage_height;
+
+  cairo_matrix_transform_point (&device_evdev->device_matrix, &min_x, &min_y);
+  cairo_matrix_transform_point (&device_evdev->device_matrix, &max_x, &max_y);
+  cairo_matrix_transform_point (&device_evdev->device_matrix, &x_d, &y_d);
+
+  *x = CLAMP (x_d, MIN (min_x, max_x), MAX (min_x, max_x)) * stage_width;
+  *y = CLAMP (y_d, MIN (min_y, max_y), MAX (min_y, max_y)) * stage_height;
+}
diff --git a/clutter/clutter/evdev/clutter-input-device-evdev.h 
b/clutter/clutter/evdev/clutter-input-device-evdev.h
index be2c7ef..b462f0a 100644
--- a/clutter/clutter/evdev/clutter-input-device-evdev.h
+++ b/clutter/clutter/evdev/clutter-input-device-evdev.h
@@ -66,6 +66,8 @@ struct _ClutterInputDeviceEvdev
   struct libinput_device *libinput_device;
   ClutterSeatEvdev *seat;
   ClutterInputDeviceTool *last_tool;
+
+  cairo_matrix_t device_matrix;
 };
 
 GType                     _clutter_input_device_evdev_get_type        (void) G_GNUC_CONST;
@@ -102,6 +104,11 @@ void                         _clutter_evdev_event_set_relative_motion (ClutterEvent 
*event,
                                                                    double        dx_unaccel,
                                                                    double        dy_unaccel);
 
+void                      clutter_input_device_evdev_translate_coordinates (ClutterInputDevice *device,
+                                                                            ClutterStage       *stage,
+                                                                            gfloat             *x,
+                                                                            gfloat             *y);
+
 G_END_DECLS
 
 #endif /* __CLUTTER_INPUT_DEVICE_EVDEV_H__ */


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]