Merge lp:~kevin-wells/libgrip/touch-points into lp:libgrip

Proposed by Kevin Wells
Status: Rejected
Rejected by: Stephen M. Webb
Proposed branch: lp:~kevin-wells/libgrip/touch-points
Merge into: lp:libgrip
Diff against target: 197 lines (+128/-0)
2 files modified
src/gripgesturemanager.c (+122/-0)
src/gripgesturemanager.h (+6/-0)
To merge this branch: bzr merge lp:~kevin-wells/libgrip/touch-points
Reviewer Review Type Date Requested Status
Henrik Rydberg (community) Disapprove
Stephen M. Webb (community) Approve
Review via email: mp+54441@code.launchpad.net

Description of the change

For demonstration purposes I needed to display the actual touch points used in the gestures exposed by libgrip, but that information was not in the event structures (although those points are contained in the geis attributes).

Also, the information passed in the libgrip event structures is not enough to recreate how the object being transformed should react to the gesture. As an example, I am using the pinch, drag, and rotate gestures to apply transformations to a map with the goal that the points on the map that are pressed stay under the touch points as the touch points move around the screen. I realize this could only work with 2 touch points, but my netbook only supports 2 touch points. The problem is that the only notion of position of the event is focus_x and focus_y. In the case of a pinch event, only knowing the focus_x and focus_y and radius_delta will only allow the map to be tracked accurately if both points have moved towards or away from the focus an equal amount (radius_delta / 2). If one point is kept stationary and the second is moved toward or away from the focus, tracking on the map becomes inaccurate.

While this is ultimately an issue with the gesture recognition library, geis provides finger positions, and with that additional information, this issue can be avoided. This branch adds finger_x and finger_y arrays of size fingers to the pinch, drag, and rotate event structures and populates them with point information from geis.

If this is something that is deemed useful, I can update the rectangle-mover example to show touch points and demonstrate the issue I mentioned.

To post a comment you must log in.
Revision history for this message
Stephen M. Webb (bregma) wrote :

I don't have a problem with propagating the touch points in general, but be aware that the significance of the touch points depends on the type of device. For example, a number of touchpads report only the bounding box, which will give focus and radius but not information about which individual points are in motion. The actual coordinates of a touchpad (an indirect device) may also not correspond to points on the screen in the same way as touchscreen touches do.

In short, I approve this patch as it is as a way to propagate the touch information through the libgrip structures, but also note it is insufficient for the purpose stated since that also requires the device information to be propagated. That information can come in a separate patch.

I also note the indentation appears to be a little messed up in a couple of places, particularly the parameters lists.

I'll wait and see what others have to say.

review: Approve
lp:~kevin-wells/libgrip/touch-points updated
40. By Kevin Wells

Fix indentation

Revision history for this message
Henrik Rydberg (rydberg) wrote :

You may be interested in this branch: lp:~utouch-team/utouch-grail/grail2, which contains an example code, grail-transform, that does what you describe.

Revision history for this message
Chase Douglas (chasedouglas) wrote :

Hi Kevin,

I'm not opposed to adding the touches, but I don't think they are actually necessary for what you want to do.

First, I'd like to define the meaning of the focus coordinates. These are the central coordinates of the touches when the gesture begins. They are used for event propagation to the correct X window and then to the correct toolkit widget. The values of the focus coordinates do not change during the gesture lifetime.

Also, all values are in screen coordinates. One unit of a value from the uTouch stack is equal to one pixel on screen.

When you receive gesture events, you can think of them as transformations upon a point on screen. Thus, a drag event moves this point by the delta_{x,y} amount. A pinch event does not move the point, but the object being interacted with may be shrunk or expanded.

The key here is that the gesture event transformations are not about the focus coordinates. They are about the current transformation position. Unfortunately, this is where we begin to see a problem with libgrip as it currently exists. The transformation position isn't provided in the libgrip gesture events. If you run geistest (from the utouch-geis-tools package), you'll see "position x" and "position y" attributes. These are the current transformation coordinates about which pinch to zoom or rotations should be applied.

My thoughts are that we should do the following:

1. Immediately add the transformation position coordinates to libgrip and push to natty.
2. Hold off on merging this change until device types are added to libgrip (as Stephen wrote, the device type is necessary for correct interpretation of touch coordinates)

Revision history for this message
Henrik Rydberg (rydberg) wrote :

I think the problem is clear to everyone, these things were originally scheduled to be fixed in natty, but we had to push some things to oneiric, hence there is still a bit of confusion.

First thing - yes, using coordinates makes perfect sense for some applications, I think the question is how these coordinates should be presented. In grail2 (see link above), we have started exposing the touch frames through the grail2 interface, which gives you access to all touch information, not only coordinates. The touch frames are supposed to also be visible through geis, as abstracted touch frames. The implementation further exposing these in libgrip should ideally be using those, although this can of course change later, as they become available.

Second thing - the information needed for accurate transforms is only partly present, and it is not only a question of clear definitions, but also about backwards compatibility. The transformation needs the pivot (position of scale and rotate), the scale, the angle, and the drag. These values can be used to construct the 3x3 transformation matrix, as seen in the grail_element. Note that the drag is different from the center movement, by a factor (called moveness in grail2) which depends on the difference between the center point and the pivot point. Since the center movement is also important, in particular for applications not using rotation, both the center movement and the drag (or at least the moveness factor) needs to be present in the events. Hence, the current geis events will not be quite enough either.

Since the event properties in the current geis/grail implementation carries certain semantics, perfectly reasonable for the simpler rigid case implemented so far, we might even have to consider adding new properties for all parts of the new transformations.

To conclude, I think your patches make perfect sense, and they point at the current deficiencies very well. However, I think we may need to take this opportunity to add all of the missing pieces in libgrip, based on the considerations so outlined.

Revision history for this message
Stephen M. Webb (bregma) wrote :

I think this discussion has moved beyond the scope if this particular merge request and should be continued in another forum.

This particular merge request was simply to propagate some additional information the original proposer found useful. I agree it is missing data and it should not hurt to add it. There may well be additional data that should also be added: let them be proposed in additional merge requests.

New functionality not yet available in GEIS or qhich require a rewrite of libgrip to use GEIS v2 are also not in scope.

Please give an approve/disapprove for the proposed merge request.

Revision history for this message
Henrik Rydberg (rydberg) wrote :

I would like to commend the idea and the initiative, but await the notion of touch frames through libgrip.

review: Disapprove
Revision history for this message
Kevin Wells (kevin-wells) wrote :

> Hi Kevin,
>
> I'm not opposed to adding the touches, but I don't think they are actually
> necessary for what you want to do.
>
> First, I'd like to define the meaning of the focus coordinates. These are the
> central coordinates of the touches when the gesture begins. They are used for
> event propagation to the correct X window and then to the correct toolkit
> widget. The values of the focus coordinates do not change during the gesture
> lifetime.
>
> Also, all values are in screen coordinates. One unit of a value from the
> uTouch stack is equal to one pixel on screen.
>
> When you receive gesture events, you can think of them as transformations upon
> a point on screen. Thus, a drag event moves this point by the delta_{x,y}
> amount. A pinch event does not move the point, but the object being interacted
> with may be shrunk or expanded.
>
> The key here is that the gesture event transformations are not about the focus
> coordinates. They are about the current transformation position.
> Unfortunately, this is where we begin to see a problem with libgrip as it
> currently exists. The transformation position isn't provided in the libgrip
> gesture events. If you run geistest (from the utouch-geis-tools package),
> you'll see "position x" and "position y" attributes. These are the current
> transformation coordinates about which pinch to zoom or rotations should be
> applied.
>
> My thoughts are that we should do the following:
>
> 1. Immediately add the transformation position coordinates to libgrip and push
> to natty.
> 2. Hold off on merging this change until device types are added to libgrip (as
> Stephen wrote, the device type is necessary for correct interpretation of
> touch coordinates)

I have been using focus_{x,y} as the transformation position, but did discover that it was in screen coordinates and needed to be converted. When I run geistest, it seems that focus_{x,y} is equal to position_{x,y} for drag events (position is not present in pinch or rotate), but this also means that focus_{x,y} is changing throughout the lifetime of the gesture. I am running Maverick, so I am not sure if this is something that has changed recently.

I didn't know that different devices report point touch coordinates differently (I only have one device multitouch capable), and I agree that device information would be useful when considering using touch points.

Revision history for this message
Stephen M. Webb (bregma) wrote :

Given the disapprovals and the bitrot, I'm rejecting this proposal.

Unmerged revisions

40. By Kevin Wells

Fix indentation

39. By Kevin Wells

Use slice allocators instead of g_new for finger points

38. By Kevin Wells

Add finger_x and finger_y to drag and rotate events.

37. By Kevin Wells

Add finger locations to Pinch gestures

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/gripgesturemanager.c'
2--- src/gripgesturemanager.c 2011-01-24 20:04:47 +0000
3+++ src/gripgesturemanager.c 2011-03-22 23:57:27 +0000
4@@ -221,6 +221,72 @@
5 gobject_class->finalize = grip_gesture_manager_finalize;
6 }
7
8+static void
9+gesture_handle_finger_properties (gint fingers,
10+ gdouble **finger_x,
11+ gdouble **finger_y,
12+ GeisSize attr_count,
13+ GeisGestureAttr *attrs)
14+{
15+ *finger_x = g_slice_alloc0 (sizeof (gdouble) * fingers);
16+ *finger_y = g_slice_alloc0 (sizeof (gdouble) * fingers);
17+
18+ int i;
19+ for (i = 0; i < attr_count; ++i)
20+ {
21+ if (g_strcmp0 (attrs[i].name, GEIS_GESTURE_ATTRIBUTE_TOUCH_0_X) == 0 &&
22+ attrs[i].type == GEIS_ATTR_TYPE_FLOAT)
23+ {
24+ (*finger_x)[0] = attrs[i].float_val;
25+ }
26+ else if (g_strcmp0 (attrs[i].name, GEIS_GESTURE_ATTRIBUTE_TOUCH_0_Y) == 0 &&
27+ attrs[i].type == GEIS_ATTR_TYPE_FLOAT)
28+ {
29+ (*finger_y)[0] = attrs[i].float_val;
30+ }
31+ else if (g_strcmp0 (attrs[i].name, GEIS_GESTURE_ATTRIBUTE_TOUCH_1_X) == 0 &&
32+ attrs[i].type == GEIS_ATTR_TYPE_FLOAT)
33+ {
34+ (*finger_x)[1] = attrs[i].float_val;
35+ }
36+ else if (g_strcmp0 (attrs[i].name, GEIS_GESTURE_ATTRIBUTE_TOUCH_1_Y) == 0 &&
37+ attrs[i].type == GEIS_ATTR_TYPE_FLOAT)
38+ {
39+ (*finger_y)[1] = attrs[i].float_val;
40+ }
41+ else if (g_strcmp0 (attrs[i].name, GEIS_GESTURE_ATTRIBUTE_TOUCH_2_X) == 0 &&
42+ attrs[i].type == GEIS_ATTR_TYPE_FLOAT)
43+ {
44+ (*finger_x)[2] = attrs[i].float_val;
45+ }
46+ else if (g_strcmp0 (attrs[i].name, GEIS_GESTURE_ATTRIBUTE_TOUCH_2_Y) == 0 &&
47+ attrs[i].type == GEIS_ATTR_TYPE_FLOAT)
48+ {
49+ (*finger_y)[2] = attrs[i].float_val;
50+ }
51+ else if (g_strcmp0 (attrs[i].name, GEIS_GESTURE_ATTRIBUTE_TOUCH_3_X) == 0 &&
52+ attrs[i].type == GEIS_ATTR_TYPE_FLOAT)
53+ {
54+ (*finger_x)[3] = attrs[i].float_val;
55+ }
56+ else if (g_strcmp0 (attrs[i].name, GEIS_GESTURE_ATTRIBUTE_TOUCH_3_Y) == 0 &&
57+ attrs[i].type == GEIS_ATTR_TYPE_FLOAT)
58+ {
59+ (*finger_y)[3] = attrs[i].float_val;
60+ }
61+ else if (g_strcmp0 (attrs[i].name, GEIS_GESTURE_ATTRIBUTE_TOUCH_4_X) == 0 &&
62+ attrs[i].type == GEIS_ATTR_TYPE_FLOAT)
63+ {
64+ (*finger_x)[4] = attrs[i].float_val;
65+ }
66+ else if (g_strcmp0 (attrs[i].name, GEIS_GESTURE_ATTRIBUTE_TOUCH_4_Y) == 0 &&
67+ attrs[i].type == GEIS_ATTR_TYPE_FLOAT)
68+ {
69+ (*finger_y)[4] = attrs[i].float_val;
70+ }
71+ }
72+}
73+
74 static gint
75 pinch_gesture_handle_properties (GripEventGesturePinch *event,
76 GeisSize attr_count,
77@@ -268,6 +334,12 @@
78 }
79 }
80
81+ gesture_handle_finger_properties (touches,
82+ &event->finger_x,
83+ &event->finger_y,
84+ attr_count,
85+ attrs);
86+
87 return touches;
88 }
89
90@@ -333,6 +405,12 @@
91 }
92 }
93
94+ gesture_handle_finger_properties (touches,
95+ &event->finger_x,
96+ &event->finger_y,
97+ attr_count,
98+ attrs);
99+
100 return touches;
101 }
102
103@@ -382,6 +460,12 @@
104 event->angle = attrs[i].float_val;
105 }
106 }
107+
108+ gesture_handle_finger_properties (touches,
109+ &event->finger_x,
110+ &event->finger_y,
111+ attr_count,
112+ attrs);
113
114 return touches;
115 }
116@@ -1260,6 +1344,28 @@
117 new_event = grip_gesture_event_new (event->type);
118 *new_event = *event;
119
120+ if (event->type == GRIP_GESTURE_DRAG)
121+ {
122+ new_event->drag.finger_x = g_slice_copy (sizeof (gdouble) * event->drag.fingers,
123+ event->drag.finger_x);
124+ new_event->drag.finger_y = g_slice_copy (sizeof (gdouble) * event->drag.fingers,
125+ event->drag.finger_y);
126+ }
127+ else if (event->type == GRIP_GESTURE_PINCH)
128+ {
129+ new_event->pinch.finger_x = g_slice_copy (sizeof (gdouble) * event->pinch.fingers,
130+ event->pinch.finger_x);
131+ new_event->pinch.finger_y = g_slice_copy (sizeof (gdouble) * event->pinch.fingers,
132+ event->pinch.finger_y);
133+ }
134+ else if (event->type == GRIP_GESTURE_ROTATE)
135+ {
136+ new_event->rotate.finger_x = g_slice_copy (sizeof (gdouble) * event->rotate.fingers,
137+ event->rotate.finger_x);
138+ new_event->rotate.finger_y = g_slice_copy (sizeof (gdouble) * event->rotate.fingers,
139+ event->rotate.finger_y);
140+ }
141+
142 return new_event;
143 }
144
145@@ -1268,5 +1374,21 @@
146 {
147 g_return_if_fail (event != NULL);
148
149+ if (event->type == GRIP_GESTURE_DRAG)
150+ {
151+ g_slice_free1 (sizeof (gdouble) * event->drag.fingers, event->drag.finger_x);
152+ g_slice_free1 (sizeof (gdouble) * event->drag.fingers, event->drag.finger_y);
153+ }
154+ else if (event->type == GRIP_GESTURE_PINCH)
155+ {
156+ g_slice_free1 (sizeof (gdouble) * event->pinch.fingers, event->pinch.finger_x);
157+ g_slice_free1 (sizeof (gdouble) * event->pinch.fingers, event->pinch.finger_y);
158+ }
159+ else if (event->type == GRIP_GESTURE_ROTATE)
160+ {
161+ g_slice_free1 (sizeof (gdouble) * event->rotate.fingers, event->rotate.finger_x);
162+ g_slice_free1 (sizeof (gdouble) * event->rotate.fingers, event->rotate.finger_y);
163+ }
164+
165 g_slice_free (GripGestureEvent, event);
166 }
167
168=== modified file 'src/gripgesturemanager.h'
169--- src/gripgesturemanager.h 2011-01-21 17:19:26 +0000
170+++ src/gripgesturemanager.h 2011-03-22 23:57:27 +0000
171@@ -78,6 +78,8 @@
172 gint fingers;
173 gdouble focus_x;
174 gdouble focus_y;
175+ gdouble *finger_x;
176+ gdouble *finger_y;
177 gint delta_x;
178 gint delta_y;
179 gdouble velocity_x;
180@@ -97,6 +99,8 @@
181 guint fingers;
182 gdouble focus_x;
183 gdouble focus_y;
184+ gdouble *finger_x;
185+ gdouble *finger_y;
186 gdouble radius_delta;
187 gdouble radial_velocity;
188 gdouble radius;
189@@ -113,6 +117,8 @@
190 guint fingers;
191 gdouble focus_x;
192 gdouble focus_y;
193+ gdouble *finger_x;
194+ gdouble *finger_y;
195 gdouble angle_delta;
196 gdouble angular_velocity;
197 gdouble angle;

Subscribers

People subscribed via source and target branches