[mutter/wip/carlosg/fix-issue-48: 1/2] clutter/x11: Implement missing ClutterInputDevice pad vmethods



commit 1d745a858470b29b44e5b0e308488a477c4526cb
Author: Carlos Garnacho <carlosg gnome org>
Date:   Thu Feb 22 17:48:17 2018 +0100

    clutter/x11: Implement missing ClutterInputDevice pad vmethods
    
    Use libwacom to be able to find out modes, groups and button roles on
    pad devices.
    
    https://gitlab.gnome.org/GNOME/mutter/issues/48
    
    Closes: #48

 clutter/clutter/x11/clutter-device-manager-xi2.c | 11 +++
 clutter/clutter/x11/clutter-device-manager-xi2.h |  8 ++
 clutter/clutter/x11/clutter-input-device-xi2.c   | 97 ++++++++++++++++++++++++
 clutter/clutter/x11/clutter-input-device-xi2.h   | 10 +++
 clutter/configure.ac                             | 32 +++++++-
 5 files changed, 156 insertions(+), 2 deletions(-)
---
diff --git a/clutter/clutter/x11/clutter-device-manager-xi2.c 
b/clutter/clutter/x11/clutter-device-manager-xi2.c
index d2610cc26..dee26042f 100644
--- a/clutter/clutter/x11/clutter-device-manager-xi2.c
+++ b/clutter/clutter/x11/clutter-device-manager-xi2.c
@@ -495,11 +495,18 @@ create_device (ClutterDeviceManagerXI2 *manager_xi2,
                          "device-node", node_path,
                          "n-rings", num_rings,
                          "n-strips", num_strips,
+                         "n-mode-groups", MAX (num_rings, num_strips),
                          NULL);
 
   translate_device_classes (backend_x11->xdpy, retval,
                             info->classes,
                             info->num_classes);
+
+#ifdef HAVE_LIBWACOM
+  if (source == CLUTTER_PAD_DEVICE)
+    clutter_input_device_xi2_ensure_wacom_info (retval, manager_xi2->wacom_db);
+#endif
+
   g_free (vendor_id);
   g_free (product_id);
 
@@ -2063,4 +2070,8 @@ clutter_device_manager_xi2_init (ClutterDeviceManagerXI2 *self)
                                                (GDestroyNotify) g_object_unref);
   self->tools_by_serial = g_hash_table_new_full (NULL, NULL, NULL,
                                                  (GDestroyNotify) g_object_unref);
+
+#ifdef HAVE_LIBWACOM
+  self->wacom_db = libwacom_database_new ();
+#endif
 }
diff --git a/clutter/clutter/x11/clutter-device-manager-xi2.h 
b/clutter/clutter/x11/clutter-device-manager-xi2.h
index c8e66f949..be2575975 100644
--- a/clutter/clutter/x11/clutter-device-manager-xi2.h
+++ b/clutter/clutter/x11/clutter-device-manager-xi2.h
@@ -26,6 +26,10 @@
 
 #include <clutter/clutter-device-manager.h>
 
+#ifdef HAVE_LIBWACOM
+#include <libwacom/libwacom.h>
+#endif
+
 G_BEGIN_DECLS
 
 #define CLUTTER_TYPE_DEVICE_MANAGER_XI2            (_clutter_device_manager_xi2_get_type ())
@@ -51,6 +55,10 @@ struct _ClutterDeviceManagerXI2
   GList *slave_devices;
 
   int opcode;
+
+#ifdef HAVE_LIBWACOM
+  WacomDeviceDatabase *wacom_db;
+#endif
 };
 
 struct _ClutterDeviceManagerXI2Class
diff --git a/clutter/clutter/x11/clutter-input-device-xi2.c b/clutter/clutter/x11/clutter-input-device-xi2.c
index 7fb0e05ad..2d9b6d238 100644
--- a/clutter/clutter/x11/clutter-input-device-xi2.c
+++ b/clutter/clutter/x11/clutter-input-device-xi2.c
@@ -45,6 +45,10 @@ struct _ClutterInputDeviceXI2
 
   gint device_id;
   ClutterInputDeviceTool *current_tool;
+
+#ifdef HAVE_LIBWACOM
+  WacomDevice *wacom_device;
+#endif
 };
 
 #define N_BUTTONS       5
@@ -87,6 +91,82 @@ clutter_input_device_xi2_is_grouped (ClutterInputDevice *device,
   return FALSE;
 }
 
+static void
+clutter_input_device_xi2_finalize (GObject *object)
+{
+#ifdef HAVE_LIBWACOM
+  ClutterInputDeviceXI2 *device_xi2 = CLUTTER_INPUT_DEVICE_XI2 (object);
+
+  if (device_xi2->wacom_device)
+    libwacom_destroy (device_xi2->wacom_device);
+#endif
+
+  G_OBJECT_CLASS (clutter_input_device_xi2_parent_class)->finalize (object);
+}
+
+static gint
+clutter_input_device_xi2_get_group_n_modes (ClutterInputDevice *device,
+                                            gint                group)
+{
+#ifdef HAVE_LIBWACOM
+  ClutterInputDeviceXI2 *device_xi2 = CLUTTER_INPUT_DEVICE_XI2 (device);
+
+  if (device_xi2->wacom_device)
+    {
+      if (group == 0)
+        {
+          if (libwacom_has_ring (device_xi2->wacom_device))
+            return libwacom_get_ring_num_modes (device_xi2->wacom_device);
+          else if (libwacom_get_num_strips (device_xi2->wacom_device) >= 1)
+            return libwacom_get_strips_num_modes (device_xi2->wacom_device);
+        }
+      else if (group == 1)
+        {
+          if (libwacom_has_ring2 (device_xi2->wacom_device))
+            return libwacom_get_ring2_num_modes (device_xi2->wacom_device);
+          else if (libwacom_get_num_strips (device_xi2->wacom_device) >= 2)
+            return libwacom_get_strips_num_modes (device_xi2->wacom_device);
+        }
+    }
+#endif
+
+  return -1;
+}
+
+#ifdef HAVE_LIBWACOM
+static int
+clutter_input_device_xi2_get_button_group (ClutterInputDevice *device,
+                                           guint               button)
+{
+  ClutterInputDeviceXI2 *device_xi2 = CLUTTER_INPUT_DEVICE_XI2 (device);
+
+  if (device_xi2->wacom_device)
+    {
+      if (button >= libwacom_get_num_buttons (device_xi2->wacom_device))
+        return -1;
+
+      return libwacom_get_button_led_group (device_xi2->wacom_device,
+                                            'A' + button);
+    }
+  else
+    return -1;
+}
+#endif
+
+static gboolean
+clutter_input_device_xi2_is_mode_switch_button (ClutterInputDevice *device,
+                                                guint               group,
+                                                guint               button)
+{
+  int button_group = -1;
+
+#ifdef HAVE_LIBWACOM
+  button_group = clutter_input_device_xi2_get_button_group (device, button);
+#endif
+
+  return button_group == (int) group;
+}
+
 static void
 clutter_input_device_xi2_class_init (ClutterInputDeviceXI2Class *klass)
 {
@@ -94,9 +174,12 @@ clutter_input_device_xi2_class_init (ClutterInputDeviceXI2Class *klass)
   ClutterInputDeviceClass *device_class = CLUTTER_INPUT_DEVICE_CLASS (klass);
 
   gobject_class->constructed = clutter_input_device_xi2_constructed;
+  gobject_class->finalize = clutter_input_device_xi2_finalize;
 
   device_class->keycode_to_evdev = clutter_input_device_xi2_keycode_to_evdev;
   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;
 }
 
 static void
@@ -196,3 +279,17 @@ clutter_input_device_xi2_get_current_tool (ClutterInputDevice *device)
   ClutterInputDeviceXI2 *device_xi2 = CLUTTER_INPUT_DEVICE_XI2 (device);
   return device_xi2->current_tool;
 }
+
+#ifdef HAVE_LIBWACOM
+void
+clutter_input_device_xi2_ensure_wacom_info (ClutterInputDevice  *device,
+                                            WacomDeviceDatabase *wacom_db)
+{
+  ClutterInputDeviceXI2 *device_xi2 = CLUTTER_INPUT_DEVICE_XI2 (device);
+  const gchar *node_path;
+
+  node_path = clutter_input_device_get_device_node (device);
+  device_xi2->wacom_device = libwacom_new_from_path (wacom_db, node_path,
+                                                     WFALLBACK_NONE, NULL);
+}
+#endif
diff --git a/clutter/clutter/x11/clutter-input-device-xi2.h b/clutter/clutter/x11/clutter-input-device-xi2.h
index b93684f71..e30fb4d18 100644
--- a/clutter/clutter/x11/clutter-input-device-xi2.h
+++ b/clutter/clutter/x11/clutter-input-device-xi2.h
@@ -27,6 +27,10 @@
 #include <clutter/clutter-input-device.h>
 #include <X11/extensions/XInput2.h>
 
+#ifdef HAVE_LIBWACOM
+#include <libwacom/libwacom.h>
+#endif
+
 G_BEGIN_DECLS
 
 #define CLUTTER_TYPE_INPUT_DEVICE_XI2           (_clutter_input_device_xi2_get_type ())
@@ -45,6 +49,12 @@ void  clutter_input_device_xi2_update_tool      (ClutterInputDevice     *device,
                                                  ClutterInputDeviceTool *tool);
 ClutterInputDeviceTool * clutter_input_device_xi2_get_current_tool (ClutterInputDevice *device);
 
+#ifdef HAVE_LIBWACOM
+void clutter_input_device_xi2_ensure_wacom_info (ClutterInputDevice  *device,
+                                                 WacomDeviceDatabase *wacom_db);
+
+#endif
+
 G_END_DECLS
 
 #endif /* __CLUTTER_INPUT_DEVICE_XI2_H__ */
diff --git a/clutter/configure.ac b/clutter/configure.ac
index 3c3d0c558..5474fa093 100644
--- a/clutter/configure.ac
+++ b/clutter/configure.ac
@@ -121,6 +121,7 @@ m4_define([xcomposite_req_version],     [0.4])
 m4_define([gdk_req_version],            [3.3.18])
 m4_define([libinput_req_version],       [1.4.0])
 m4_define([libudev_req_version],        [136])
+m4_define([libwacom_req_version],       [0.13])
 
 AC_SUBST([GLIB_REQ_VERSION],       [glib_req_version])
 AC_SUBST([COGL_REQ_VERSION],       [cogl_req_version])
@@ -133,6 +134,7 @@ AC_SUBST([XCOMPOSITE_REQ_VERSION], [xcomposite_req_version])
 AC_SUBST([GDK_REQ_VERSION],        [gdk_req_version])
 AC_SUBST([LIBINPUT_REQ_VERSION],   [libinput_req_version])
 AC_SUBST([LIBUDEV_REQ_VERSION],    [libudev_req_version])
+AC_SUBST([LIBWACOM_REQ_VERSION],   [libwacom_req_version])
 
 # Checks for typedefs, structures, and compiler characteristics.
 AM_PATH_GLIB_2_0([glib_req_version],
@@ -508,6 +510,32 @@ X11_EXTS=${X11_EXTS#* }
 
 AC_CACHE_SAVE
 
+dnl === Libwacom support for X11 ===============================================
+AC_ARG_WITH(libwacom,
+  AC_HELP_STRING([--without-libwacom],
+                 [disable the use of libwacom for advanced tablet management]),,
+  with_libwacom=auto)
+
+have_libwacom=no
+AC_MSG_CHECKING([libwacom])
+if test x$with_libwacom = xno ; then
+  AC_MSG_RESULT([disabled])
+else
+  if $PKG_CONFIG --exists libwacom '>=' $LIBWACOM_REQ_VERSION; then
+    have_libwacom=yes
+    AC_MSG_RESULT(yes)
+    PKG_CHECK_MODULES([LIBWACOM], [libwacom])
+    AC_SUBST(LIBWACOM_CFLAGS)
+    AC_SUBST(LIBWACOM_LIBS)
+    AC_DEFINE([HAVE_LIBWACOM], 1, [Building with libwacom for advanced tablet management])
+  else
+    AC_MSG_RESULT(no)
+    if test x$with_libwacom = xyes ; then
+      AC_MSG_ERROR([libwacom forced but not found])
+    fi
+  fi
+fi
+
 dnl === Enable GDK-Pixbuf in tests ============================================
 
 m4_define([pixbuf_default], [yes])
@@ -679,8 +707,8 @@ AS_IF([test "x$CLUTTER_BASE_PC_FILES_PRIVATE" = "x" && test "x$BACKEND_PC_FILES_
 AC_SUBST(CLUTTER_REQUIRES)
 AC_SUBST(CLUTTER_REQUIRES_PRIVATE)
 
-CLUTTER_CFLAGS="$FLAVOUR_CFLAGS $CLUTTER_DEPS_CFLAGS $CLUTTER_DEPS_PRIVATE_CFLAGS $GLIB_CFLAGS"
-CLUTTER_LIBS="$FLAVOUR_LIBS $CLUTTER_DEPS_LIBS $CLUTTER_DEPS_PRIVATE_LIBS $GLIB_LIBS"
+CLUTTER_CFLAGS="$FLAVOUR_CFLAGS $CLUTTER_DEPS_CFLAGS $CLUTTER_DEPS_PRIVATE_CFLAGS $GLIB_CFLAGS 
$LIBWACOM_CFLAGS"
+CLUTTER_LIBS="$FLAVOUR_LIBS $CLUTTER_DEPS_LIBS $CLUTTER_DEPS_PRIVATE_LIBS $GLIB_LIBS $LIBWACOM_LIBS"
 AC_SUBST(CLUTTER_CFLAGS)
 AC_SUBST(CLUTTER_LIBS)
 


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