Blob Blame History Raw
From 0e4f7168edfb86c2749b51109d6cc08bced5c2b0 Mon Sep 17 00:00:00 2001
From: Fabio Valentini <decathorpe@gmail.com>
Date: Tue, 16 Jul 2019 10:25:48 +0200
Subject: [PATCH 23/28] clutter: Add API to retrieve the physical size of
 absolute devices

---
 .../clutter/clutter-device-manager-private.h  |  4 ++
 clutter/clutter/clutter-input-device.c        | 12 +++++
 clutter/clutter/clutter-input-device.h        |  5 ++
 .../evdev/clutter-input-device-evdev.c        | 13 +++++
 .../clutter/x11/clutter-input-device-xi2.c    | 51 +++++++++++++++++++
 5 files changed, 85 insertions(+)

diff --git a/clutter/clutter/clutter-device-manager-private.h b/clutter/clutter/clutter-device-manager-private.h
index 2364fd27c..60cb99d55 100644
--- a/clutter/clutter/clutter-device-manager-private.h
+++ b/clutter/clutter/clutter-device-manager-private.h
@@ -167,6 +167,10 @@ struct _ClutterInputDeviceClass
   gboolean (* is_grouped) (ClutterInputDevice *device,
                            ClutterInputDevice *other_device);
 
+  gboolean (* get_physical_size) (ClutterInputDevice *device,
+                                  gdouble            *width,
+                                  gdouble            *height);
+
   /* Keyboard accessbility */
   void (* process_kbd_a11y_event) (ClutterEvent               *event,
                                    ClutterInputDevice         *device,
diff --git a/clutter/clutter/clutter-input-device.c b/clutter/clutter/clutter-input-device.c
index f084d3a7a..482e000aa 100644
--- a/clutter/clutter/clutter-input-device.c
+++ b/clutter/clutter/clutter-input-device.c
@@ -2286,3 +2286,15 @@ clutter_input_device_is_grouped (ClutterInputDevice *device,
 
   return CLUTTER_INPUT_DEVICE_GET_CLASS (device)->is_grouped (device, other_device);
 }
+
+gboolean
+clutter_input_device_get_physical_size (ClutterInputDevice *device,
+                                        gdouble            *width,
+                                        gdouble            *height)
+{
+  g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (device), FALSE);
+
+  return CLUTTER_INPUT_DEVICE_GET_CLASS (device)->get_physical_size (device,
+                                                                     width,
+                                                                     height);
+}
diff --git a/clutter/clutter/clutter-input-device.h b/clutter/clutter/clutter-input-device.h
index 3961b5027..873af2697 100644
--- a/clutter/clutter/clutter-input-device.h
+++ b/clutter/clutter/clutter-input-device.h
@@ -172,6 +172,11 @@ CLUTTER_AVAILABLE_IN_ALL
 gboolean                  clutter_input_device_is_grouped       (ClutterInputDevice *device,
                                                                  ClutterInputDevice *other_device);
 
+CLUTTER_AVAILABLE_IN_ALL
+gboolean                  clutter_input_device_get_physical_size (ClutterInputDevice *device,
+                                                                  gdouble            *width,
+                                                                  gdouble            *height);
+
 G_END_DECLS
 
 #endif /* __CLUTTER_INPUT_DEVICE_H__ */
diff --git a/clutter/clutter/evdev/clutter-input-device-evdev.c b/clutter/clutter/evdev/clutter-input-device-evdev.c
index 51c7e942c..ad511405c 100644
--- a/clutter/clutter/evdev/clutter-input-device-evdev.c
+++ b/clutter/clutter/evdev/clutter-input-device-evdev.c
@@ -1268,6 +1268,18 @@ clutter_input_device_evdev_release_touch_state (ClutterInputDeviceEvdev *device,
                        GINT_TO_POINTER (touch_state->device_slot));
 }
 
+static gboolean
+clutter_input_device_evdev_get_physical_size (ClutterInputDevice *device,
+                                              gdouble            *width,
+                                              gdouble            *height)
+{
+  struct libinput_device *libinput_device;
+
+  libinput_device = clutter_evdev_input_device_get_libinput_device (device);
+
+  return libinput_device_get_size (libinput_device, width, height) == 0;
+}
+
 static void
 clutter_input_device_evdev_class_init (ClutterInputDeviceEvdevClass *klass)
 {
@@ -1283,6 +1295,7 @@ clutter_input_device_evdev_class_init (ClutterInputDeviceEvdevClass *klass)
   klass->get_group_n_modes = clutter_input_device_evdev_get_group_n_modes;
   klass->is_grouped = clutter_input_device_evdev_is_grouped;
   klass->process_kbd_a11y_event = clutter_input_device_evdev_process_kbd_a11y_event;
+  klass->get_physical_size = clutter_input_device_evdev_get_physical_size;
 
   obj_props[PROP_DEVICE_MATRIX] =
     g_param_spec_boxed ("device-matrix",
diff --git a/clutter/clutter/x11/clutter-input-device-xi2.c b/clutter/clutter/x11/clutter-input-device-xi2.c
index f62ba85dc..48ca04cd1 100644
--- a/clutter/clutter/x11/clutter-input-device-xi2.c
+++ b/clutter/clutter/x11/clutter-input-device-xi2.c
@@ -179,6 +179,56 @@ clutter_input_device_xi2_is_mode_switch_button (ClutterInputDevice *device,
   return button_group == (int) group;
 }
 
+static gboolean
+clutter_input_device_xi2_get_physical_size (ClutterInputDevice *device,
+                                            gdouble            *width,
+                                            gdouble            *height)
+{
+  Display *xdisplay;
+  XIDeviceInfo *dev_info;
+  gdouble w = 0, h = 0;
+  int i, n_info, device_id;
+
+  xdisplay = clutter_x11_get_default_display ();
+  device_id = clutter_input_device_get_device_id (device);
+
+  clutter_x11_trap_x_errors ();
+  dev_info = XIQueryDevice (xdisplay, device_id, &n_info);
+  if (clutter_x11_untrap_x_errors ())
+    return FALSE;
+
+  if (!dev_info)
+    return FALSE;
+
+  for (i = 0; i < dev_info->num_classes; i++)
+    {
+      XIValuatorClassInfo *valuator;
+      gdouble *value;
+
+      if (dev_info->classes[i]->type != XIValuatorClass)
+        continue;
+
+      valuator = (XIValuatorClassInfo *) dev_info->classes[i];
+
+      if (valuator->label == XInternAtom (xdisplay, "Abs X", True) ||
+          valuator->label == XInternAtom (xdisplay, "Abs MT Position X", True))
+        value = &w;
+      else if (valuator->label == XInternAtom (xdisplay, "Abs Y", True) ||
+               valuator->label == XInternAtom (xdisplay, "Abs MT Position Y", True))
+        value = &h;
+      else
+        continue;
+
+      *value = (valuator->max - valuator->min) * 1000 / valuator->resolution;
+    }
+
+  XIFreeDeviceInfo (dev_info);
+  *width = w;
+  *height = h;
+
+  return (w > 0 && h > 0);
+}
+
 static void
 clutter_input_device_xi2_class_init (ClutterInputDeviceXI2Class *klass)
 {
@@ -192,6 +242,7 @@ clutter_input_device_xi2_class_init (ClutterInputDeviceXI2Class *klass)
   device_class->is_grouped = clutter_input_device_xi2_is_grouped;
   device_class->get_group_n_modes = clutter_input_device_xi2_get_group_n_modes;
   device_class->is_mode_switch_button = clutter_input_device_xi2_is_mode_switch_button;
+  device_class->get_physical_size = clutter_input_device_xi2_get_physical_size;
 }
 
 static void
-- 
2.21.0