[gtk+/multitouch: 92/121] gdk: Add gdk_event_get_touch_area()
- From: Carlos Garnacho <carlosg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/multitouch: 92/121] gdk: Add gdk_event_get_touch_area()
- Date: Thu, 12 Jan 2012 03:13:18 +0000 (UTC)
commit 101cc9eb42d5ba966cd395d3649d52fe8fa3490e
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]