[gtk+/multitouch: 92/123] gdk: Add gdk_event_get_touch_area()



commit f090ce33a690108bb65fd8aeef431a75184bc650
Author: Carlos Garnacho <carlosg gnome org>
Date:   Sun Nov 6 11:45:42 2011 +0100

    gdk: Add gdk_event_get_touch_area()
    
    If given an event coming from a touch devices,
    this functions will read the MT major/minor/orientation
    axes and return a cairo_region_t with the touch shape.

 gdk/gdkevents.c |   89 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 gdk/gdkevents.h |    1 +
 2 files changed, 90 insertions(+), 0 deletions(-)
---
diff --git a/gdk/gdkevents.c b/gdk/gdkevents.c
index 978323b..cc12fbc 100644
--- a/gdk/gdkevents.c
+++ b/gdk/gdkevents.c
@@ -1812,6 +1812,95 @@ gdk_event_get_touch_id (const GdkEvent *event,
 }
 
 /**
+ * gdk_event_get_touch_area:
+ * @event: a #GdkEvent 
+ *
+ * This function takes a #GdkEvent coming from a touch device
+ * (eg. gdk_event_get_source_device() returns a device of type
+ * %GDK_SOURCE_TOUCH), and returns the area covered by the touch
+ * as a #cairo_region_t. or %NULL if the device doesn't provide
+ * this information, or the touch area information couldn't be
+ * extracted from the event.
+ *
+ * <note><warning>Not all touch capable devices provide this
+ * information, so provide fallbacks to this function returning
+ * %NULL, even if the window receiving events is only meant
+ * to react to touch events.</warning></note>
+ *
+ * Returns: (transfer full): the touch region, or %NULL if unavailable
+ **/
+cairo_region_t *
+gdk_event_get_touch_area (GdkEvent *event)
+{
+  gdouble *axes, minor_axis, major_axis, orientation_axis;
+  GdkAtom major, minor, orientation;
+  GdkDevice *device;
+
+  g_return_val_if_fail (event != NULL, NULL);
+
+  device = gdk_event_get_source_device (event);
+
+  if (!device)
+    return NULL;
+
+  if (event->type == GDK_MOTION_NOTIFY ||
+      event->type == GDK_TOUCH_MOTION)
+    axes = event->motion.axes;
+  else if (event->type == GDK_BUTTON_PRESS ||
+           event->type == GDK_2BUTTON_PRESS ||
+           event->type == GDK_3BUTTON_PRESS ||
+           event->type == GDK_BUTTON_RELEASE)
+    axes = event->button.axes;
+  else
+    return NULL;
+
+  major = gdk_atom_intern_static_string ("Abs MT Touch Major");
+  minor = gdk_atom_intern_static_string ("Abs MT Touch Minor");
+  orientation = gdk_atom_intern_static_string ("Abs MT Orientation");
+
+  if (gdk_device_get_axis_value (device, axes, major, &major_axis) &&
+      gdk_device_get_axis_value (device, axes, minor, &minor_axis) &&
+      gdk_device_get_axis_value (device, axes, orientation, &orientation_axis))
+    {
+      cairo_rectangle_int_t rect;
+      GdkScreen *screen;
+      gdouble x, y;
+
+      /* FIXME: We're assuming the device is mapped to a single screen,
+       * could lead to stretched/shrinked shapes in multimonitor, although
+       * that'd be an unusual setup for touchscreens.
+       */
+      screen = gdk_window_get_screen (event->any.window);
+      gdk_event_get_coords (event, &x, &y);
+
+      if (orientation_axis == 0)
+        {
+          /* Orientation is horizontal */
+          rect.width = (gint) gdk_screen_get_width (screen) * major_axis;
+          rect.height = (gint) gdk_screen_get_height (screen) * minor_axis;
+        }
+      else
+        {
+          /* Orientation is vertical */
+          rect.height = (gint) gdk_screen_get_height (screen) * major_axis;
+          rect.width = (gint) gdk_screen_get_width (screen) * minor_axis;
+        }
+
+      /* Something is wrong here */
+      if (rect.width == 0 ||
+          rect.height == 0)
+        return NULL;
+
+      rect.x = x - rect.width / 2;
+      rect.y = y - rect.height / 2;
+
+      return cairo_region_create_rectangle (&rect);
+    }
+
+  return NULL;
+}
+
+/**
  * gdk_set_show_events:
  * @show_events:  %TRUE to output event debugging information.
  * 
diff --git a/gdk/gdkevents.h b/gdk/gdkevents.h
index fe885ee..dcd2e7a 100644
--- a/gdk/gdkevents.h
+++ b/gdk/gdkevents.h
@@ -1202,6 +1202,7 @@ GdkScreen *gdk_event_get_screen         (const GdkEvent  *event);
 
 gboolean   gdk_event_get_touch_id       (const GdkEvent  *event,
                                          guint           *touch_id);
+cairo_region_t * gdk_event_get_touch_area (GdkEvent      *event);
 
 void	  gdk_set_show_events		(gboolean	 show_events);
 gboolean  gdk_get_show_events		(void);



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