[gtk+/wip/wayland-tablet: 1862/1865] Wayland: Translate tilt/pressure/distance axes in motion events



commit ca654f4b28483b2679a5d64eb4dbf9596873b5d2
Author: Stephen Chandler Paul <thatslyude gmail com>
Date:   Mon Jun 22 18:02:50 2015 +0200

    Wayland: Translate tilt/pressure/distance axes in motion events
    
    On wayland, such axes are per-tool, we must update device capabilities
    on the fly as new tools enter proximity, first the slave device so
    it matches the current tool, and then the master device so it looks
    the same than the current slave device.

 gdk/wayland/gdkdevice-wayland.c |  150 ++++++++++++++++++++++++++++++++++++++-
 1 files changed, 147 insertions(+), 3 deletions(-)
---
diff --git a/gdk/wayland/gdkdevice-wayland.c b/gdk/wayland/gdkdevice-wayland.c
index 74dc00b..126bbe7 100644
--- a/gdk/wayland/gdkdevice-wayland.c
+++ b/gdk/wayland/gdkdevice-wayland.c
@@ -125,6 +125,12 @@ struct _GdkWaylandTabletData
   GdkWaylandPointerData pointer_info;
 
   GdkWaylandTabletToolData *current_tool;
+
+  gint pressure_axis_index;
+  gint xtilt_axis_index;
+  gint ytilt_axis_index;
+  gint distance_axis_index;
+  gdouble *axes;
 };
 
 struct _GdkWaylandSeat
@@ -2375,6 +2381,9 @@ _gdk_wayland_seat_remove_tablet (GdkWaylandSeat       *seat,
   if (tablet->pointer_info.focus)
     g_object_unref (tablet->pointer_info.focus);
 
+  if (tablet->axes)
+    g_free (tablet->axes);
+
   wl_surface_destroy (tablet->pointer_info.pointer_surface);
   g_object_unref (tablet->master);
   g_object_unref (tablet->stylus_device);
@@ -2849,10 +2858,18 @@ gdk_wayland_tablet_flush_frame_event (GdkWaylandTabletData *tablet,
     {
     case GDK_MOTION_NOTIFY:
       event->motion.time = time;
+      event->motion.axes =
+        g_memdup (tablet->axes,
+                  sizeof (gdouble) *
+                  gdk_device_get_n_axes (tablet->current_device));
       break;
     case GDK_BUTTON_PRESS:
     case GDK_BUTTON_RELEASE:
       event->button.time = time;
+      event->button.axes =
+        g_memdup (tablet->axes,
+                  sizeof (gdouble) *
+                  gdk_device_get_n_axes (tablet->current_device));
       break;
     case GDK_PROXIMITY_IN:
     case GDK_PROXIMITY_OUT:
@@ -2889,6 +2906,75 @@ gdk_wayland_tablet_get_frame_event (GdkWaylandTabletData *tablet,
 }
 
 static void
+gdk_wayland_device_tablet_clone_tool_axes (GdkWaylandTabletData *tablet,
+                                           GdkDeviceTool        *tool)
+{
+  gint axis_pos;
+
+  g_object_freeze_notify (G_OBJECT (tablet->current_device));
+  _gdk_device_reset_axes (tablet->current_device);
+
+  _gdk_device_add_axis (tablet->current_device, GDK_NONE, GDK_AXIS_X, 0, 0, 0);
+  _gdk_device_add_axis (tablet->current_device, GDK_NONE, GDK_AXIS_Y, 0, 0, 0);
+
+  if (tool->tool_axes & (GDK_AXIS_FLAG_XTILT | GDK_AXIS_FLAG_YTILT))
+    {
+      axis_pos = _gdk_device_add_axis (tablet->current_device, GDK_NONE,
+                                       GDK_AXIS_XTILT, -65535, 65535, 0);
+      tablet->xtilt_axis_index = axis_pos;
+
+      axis_pos = _gdk_device_add_axis (tablet->current_device, GDK_NONE,
+                                       GDK_AXIS_YTILT, -65535, 65535, 0);
+      tablet->ytilt_axis_index = axis_pos;
+    }
+  if (tool->tool_axes & GDK_AXIS_FLAG_DISTANCE)
+    {
+      axis_pos = _gdk_device_add_axis (tablet->current_device, GDK_NONE,
+                                       GDK_AXIS_DISTANCE, 0, 65535, 0);
+      tablet->distance_axis_index = axis_pos;
+    }
+  if (tool->tool_axes & GDK_AXIS_FLAG_PRESSURE)
+    {
+      axis_pos = _gdk_device_add_axis (tablet->current_device, GDK_NONE,
+                                       GDK_AXIS_PRESSURE, 0, 65535, 0);
+      tablet->pressure_axis_index = axis_pos;
+    }
+
+  if (tablet->axes)
+    g_free(tablet->axes);
+
+  tablet->axes =
+    g_new0 (gdouble, gdk_device_get_n_axes (tablet->current_device));
+
+  g_object_thaw_notify (G_OBJECT (tablet->current_device));
+}
+
+static void
+gdk_wayland_mimic_device_axes (GdkDevice *master,
+                               GdkDevice *slave)
+{
+  gdouble axis_min, axis_max, axis_resolution;
+  GdkAtom axis_label;
+  GdkAxisUse axis_use;
+  gint axis_count;
+  gint i;
+
+  g_object_freeze_notify (G_OBJECT (master));
+  _gdk_device_reset_axes (master);
+  axis_count = gdk_device_get_n_axes (slave);
+
+  for (i = 0; i < axis_count; i++)
+    {
+      _gdk_device_get_axis_info (slave, i, &axis_label, &axis_use, &axis_min,
+                                 &axis_max, &axis_resolution);
+      _gdk_device_add_axis (master, axis_label, axis_use, axis_min,
+                            axis_max, axis_resolution);
+    }
+
+  g_object_thaw_notify (G_OBJECT (master));
+}
+
+static void
 tablet_tool_handle_proximity_in (void                      *data,
                                  struct zwp_tablet_tool_v1 *wp_tablet_tool,
                                  uint32_t                   serial,
@@ -2923,6 +3009,8 @@ tablet_tool_handle_proximity_in (void                      *data,
     gdk_device_add_tool (tablet->current_device, tool->tool);
 
   gdk_device_update_tool (tablet->current_device, tool->tool);
+  gdk_wayland_device_tablet_clone_tool_axes (tablet, tool->tool);
+  gdk_wayland_mimic_device_axes (tablet->master, tablet->current_device);
 
   event = gdk_wayland_tablet_get_frame_event (tablet, GDK_PROXIMITY_IN);
   event->proximity.window = g_object_ref (tablet->pointer_info.focus);
@@ -2997,6 +3085,62 @@ tablet_tool_handle_motion (void                      *data,
 }
 
 static void
+tablet_tool_handle_pressure (void                      *data,
+                             struct zwp_tablet_tool_v1 *wp_tablet_tool,
+                             uint32_t                   pressure)
+{
+  GdkWaylandTabletToolData *tool = data;
+  GdkWaylandTabletData *tablet = tool->current_tablet;
+  gint axis_index = tablet->pressure_axis_index;
+
+  _gdk_device_translate_axis (tablet->current_device, axis_index,
+                              pressure, &tablet->axes[axis_index]);
+
+  GDK_NOTE (EVENTS,
+            g_message ("tablet tool %d pressure %d",
+                       gdk_device_tool_get_tool_type (tool->tool), pressure));
+}
+
+static void
+tablet_tool_handle_distance (void                      *data,
+                             struct zwp_tablet_tool_v1 *wp_tablet_tool,
+                             uint32_t                   distance)
+{
+  GdkWaylandTabletToolData *tool = data;
+  GdkWaylandTabletData *tablet = tool->current_tablet;
+  gint axis_index = tablet->distance_axis_index;
+
+  _gdk_device_translate_axis (tablet->current_device, axis_index,
+                              distance, &tablet->axes[axis_index]);
+
+  GDK_NOTE (EVENTS,
+            g_message ("tablet tool %d distance %d",
+                       gdk_device_tool_get_tool_type (tool->tool), distance));
+}
+
+static void
+tablet_tool_handle_tilt (void                      *data,
+                         struct zwp_tablet_tool_v1 *wp_tablet_tool,
+                         int32_t                    xtilt,
+                         int32_t                    ytilt)
+{
+  GdkWaylandTabletToolData *tool = data;
+  GdkWaylandTabletData *tablet = tool->current_tablet;
+  gint xtilt_axis_index = tablet->xtilt_axis_index;
+  gint ytilt_axis_index = tablet->ytilt_axis_index;
+
+  _gdk_device_translate_axis (tablet->current_device, xtilt_axis_index,
+                              xtilt, &tablet->axes[xtilt_axis_index]);
+  _gdk_device_translate_axis (tablet->current_device, ytilt_axis_index,
+                              ytilt, &tablet->axes[ytilt_axis_index]);
+
+  GDK_NOTE (EVENTS,
+            g_message ("tablet tool %d tilt %d/%d",
+                       gdk_device_tool_get_tool_type (tool->tool),
+                       xtilt, ytilt));
+}
+
+static void
 tablet_tool_handle_frame (void                      *data,
                           struct zwp_tablet_tool_v1 *wl_tablet_tool,
                           uint32_t                   time)
@@ -3037,9 +3181,9 @@ static const struct zwp_tablet_tool_v1_listener tablet_tool_listener = {
   tablet_handler_placeholder, /* down */
   tablet_handler_placeholder, /* up */
   tablet_tool_handle_motion,
-  tablet_handler_placeholder, /* pressure */
-  tablet_handler_placeholder, /* distance */
-  tablet_handler_placeholder, /* tilt */
+  tablet_tool_handle_pressure,
+  tablet_tool_handle_distance,
+  tablet_tool_handle_tilt,
   tablet_handler_placeholder, /* button_state */
   tablet_tool_handle_frame,
 };


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