Merge lp:~chasedouglas/grail/rework into lp:grail

Proposed by Chase Douglas on 2012-01-25
Status: Merged
Merged at revision: 174
Proposed branch: lp:~chasedouglas/grail/rework
Merge into: lp:grail
Diff against target: 15435 lines (+11164/-3707)
92 files modified
Makefile.am (+30/-0)
configure.ac (+33/-9)
include/utouch/grail.h (+685/-0)
m4/gcov.m4 (+83/-0)
m4/gtest.m4 (+24/-0)
src/Makefile.am (+48/-24)
src/evbuf.h (+0/-57)
src/gebuf.h (+0/-68)
src/gestures-drag.c (+0/-135)
src/gestures-pinch.c (+0/-131)
src/gestures-rotate.c (+0/-130)
src/gestures-tapping.c (+0/-100)
src/gestures-touch.c (+0/-98)
src/grail-api.c (+0/-328)
src/grail-bits.c (+0/-93)
src/grail-event.c (+0/-118)
src/grail-frame.c (+0/-410)
src/grail-gestures.c (+0/-219)
src/grail-gestures.h (+0/-115)
src/grail-impl.h (+0/-88)
src/grail-init.c (+0/-236)
src/grail-inserter.c (+0/-304)
src/grail-inserter.h (+0/-93)
src/grail-legacy.c (+0/-64)
src/grail-recognizer.c (+0/-58)
src/grail-recognizer.h (+0/-44)
src/grailbuf.h (+0/-59)
src/v2/evbuf.h (+57/-0)
src/v2/gebuf.h (+68/-0)
src/v2/gestures-drag.c (+135/-0)
src/v2/gestures-pinch.c (+131/-0)
src/v2/gestures-rotate.c (+130/-0)
src/v2/gestures-tapping.c (+100/-0)
src/v2/gestures-touch.c (+98/-0)
src/v2/grail-api.c (+328/-0)
src/v2/grail-bits.c (+93/-0)
src/v2/grail-event.c (+118/-0)
src/v2/grail-frame.c (+410/-0)
src/v2/grail-gestures.c (+223/-0)
src/v2/grail-gestures.h (+115/-0)
src/v2/grail-impl.h (+88/-0)
src/v2/grail-init.c (+236/-0)
src/v2/grail-inserter.c (+304/-0)
src/v2/grail-inserter.h (+93/-0)
src/v2/grail-legacy.c (+64/-0)
src/v2/grail-recognizer.c (+58/-0)
src/v2/grail-recognizer.h (+44/-0)
src/v2/grailbuf.h (+59/-0)
src/v3/event.cpp (+102/-0)
src/v3/event.h (+57/-0)
src/v3/forward.h (+57/-0)
src/v3/gesture.cpp (+350/-0)
src/v3/gesture.h (+85/-0)
src/v3/handle.cpp (+329/-0)
src/v3/handle.h (+74/-0)
src/v3/log.cpp (+63/-0)
src/v3/log.h (+59/-0)
src/v3/recognizer.cpp (+933/-0)
src/v3/recognizer.h (+95/-0)
src/v3/slice.cpp (+710/-0)
src/v3/slice.h (+99/-0)
src/v3/subscription.cpp (+271/-0)
src/v3/subscription.h (+81/-0)
test/Makefile.am (+29/-11)
test/check-grail.c (+0/-25)
test/check-mapping.cpp (+96/-124)
test/check-transform.cpp (+112/-133)
test/device.cpp (+64/-0)
test/device.h (+49/-0)
test/events.h (+57/-0)
test/grail.cpp (+65/-0)
test/recording.cpp (+41/-0)
test/recording.h (+53/-0)
test/recordings/ntrig-2-drag.event (+598/-0)
test/recordings/ntrig-dell-xt2.prop (+32/-0)
test/subscription.cpp (+257/-0)
test/x11/fixture.cpp (+191/-0)
test/x11/fixture.h (+65/-0)
test/x11/twodrag.cpp (+341/-0)
tools/Makefile.am (+37/-1)
tools/common/device.c (+188/-0)
tools/common/device.h (+28/-0)
tools/common/servertime.c (+91/-0)
tools/common/servertime.h (+30/-0)
tools/common/slice.c (+94/-0)
tools/common/slice.h (+24/-0)
tools/grail-eventprinter.c (+1/-1)
tools/grail-test-3-1.c (+348/-0)
tools/grail-test-atomic.c (+361/-0)
tools/grail-test-edge.c (+362/-0)
tools/grail-test-propagation.c (+330/-0)
tools/grail-transform.c (+0/-431)
To merge this branch: bzr merge lp:~chasedouglas/grail/rework
Reviewer Review Type Date Requested Status
Stephen M. Webb (community) 2012-01-25 Approve on 2012-01-25
Review via email: mp+90032@code.launchpad.net

Description of the change

The new grail implementation is ready! I don't feel like recapping the changes, you should be familiar with the general idea by now :). There are unit tests for the subscription object, and an integration test for a two-touch drag. Unfortunately, if you run the two-touch drag test under valgrind it is slowed down enough that timeouts occur that would not under normal operation. I'm still pondering how to handle this, but for now we must ignore failure under valgrind.

To post a comment you must log in.
lp:~chasedouglas/grail/rework updated on 2012-01-25
291. By Chase Douglas on 2012-01-25

Merge from trunk

Stephen M. Webb (bregma) wrote :

I've been using this branch for geis development and testing, so I give it a general approval except for the following.

(1) The test suite gets built with a 'make all' target, which is not usual procedure. The Makefile.am in the test subdirectory should use a check_PROGRAMS target and not a noinst_PROGRAMS target.

(2) There is no way to disable building the test suite if xorg-gtest is installed on your system, and the test suite fails to build if the --with-xi argument is not given to ./configure.

(3) The TwoDrag test fails throwing a "Failed to open device file" exception. It looks like the test data is missing from the repo.

review: Needs Fixing
lp:~chasedouglas/grail/rework updated on 2012-01-25
292. By Chase Douglas on 2012-01-25

Add recordings needed for testing

293. By Chase Douglas on 2012-01-25

Build testsuite at "make check" time

294. By Chase Douglas on 2012-01-25

Fix build for HAVE_XI conditional

Chase Douglas (chasedouglas) wrote :

> I've been using this branch for geis development and testing, so I give it a
> general approval except for the following.
>
> (1) The test suite gets built with a 'make all' target, which is not usual
> procedure. The Makefile.am in the test subdirectory should use a
> check_PROGRAMS target and not a noinst_PROGRAMS target.

Fixed

> (2) There is no way to disable building the test suite if xorg-gtest is
> installed on your system, and the test suite fails to build if the --with-xi
> argument is not given to ./configure.

The entire build system was broken, so I fixed it all up.

> (3) The TwoDrag test fails throwing a "Failed to open device file" exception.
> It looks like the test data is missing from the repo.

Yep, I forgot to bzr add the recordings directory. It should work now.

Stephen M. Webb (bregma) wrote :

Yep. Good to go.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'Makefile.am'
2--- Makefile.am 2011-01-02 12:06:04 +0000
3+++ Makefile.am 2012-01-25 15:53:29 +0000
4@@ -5,6 +5,36 @@
5
6 INCLUDES = $(top_srcdir)/include/
7
8+if HAVE_GCOV
9+ .PHONY: coverage-html generate-coverage-html coverage-html-clean
10+ coverage-html:
11+ -$(MAKE) $(AM_MAKEFLAGS) -k check
12+ $(MAKE) $(AM_MAKEFLAGS) generate-coverage-html
13+
14+ generate-coverage-html:
15+ @echo Collecting coverage data
16+ $(LCOV) --directory $(top_builddir) --base-directory src --capture --output-file coverage.info --no-checksum --compat-libtool
17+ LANG=C $(GENHTML) --prefix $(top_builddir) --output-directory coveragereport --title "Code Coverage" --legend --show-details coverage.info
18+
19+ clean-coverage-html:
20+ -$(LCOV) --directory $(top_builddir) -z
21+ -rm -rf coverage.info coveragereport
22+ -find $(top_builddir) -name '*.gcda' -print | xargs rm
23+
24+ .PHONY: coverage-xml generate-coverage-xml coverage-xml-clean
25+ coverage-xml:
26+ -$(MAKE) $(AM_MAKEFLAGS) -k check
27+ $(MAKE) $(AM_MAKEFLAGS) generate-coverage-xml
28+
29+ generate-coverage-xml:
30+ @echo Generating coverage XML report
31+ $(MAKE) $(AM_MAKEFLAGS) clean-coverage-xml
32+ $(GCOVR) -x -r $(top_builddir) -o $(top_builddir)/coverage.xml --object-directory=$(abs_builddir)/.libs
33+
34+ clean-coverage-xml:
35+ -rm -rf $(top_builddir)/coverage.xml
36+endif # HAVE_GCOV
37+
38 .PHONY: ChangeLog INSTALL
39 INSTALL:
40 $(INSTALL_CMD)
41
42=== modified file 'configure.ac'
43--- configure.ac 2011-08-31 17:20:48 +0000
44+++ configure.ac 2012-01-25 15:53:29 +0000
45@@ -1,16 +1,21 @@
46 # Initialize Autoconf
47 AC_PREREQ([2.60])
48 AC_INIT([Gesture Recognition And Instantiation Library],
49- [2.1.0],
50+ [2.99.1],
51 [],
52 [utouch-grail])
53 AC_CONFIG_SRCDIR([Makefile.am])
54 AC_CONFIG_HEADERS([config.h])
55 AC_CONFIG_AUX_DIR([config-aux])
56+AC_CONFIG_MACRO_DIR([m4])
57+
58+m4_include([m4/gcov.m4])
59+m4_include([m4/gtest.m4])
60
61 # Initialize Automake
62 AM_INIT_AUTOMAKE([foreign dist-bzip2])
63-AM_MAINTAINER_MODE
64+AM_SILENT_RULES([yes])
65+AM_MAINTAINER_MODE([enable])
66
67 LIB_VERSION=3:0:2
68 AC_SUBST([LIB_VERSION])
69@@ -20,11 +25,12 @@
70
71 # Checks for programs.
72 AC_PROG_CC
73+AC_PROG_CXX
74 AC_PROG_INSTALL
75
76 PKG_CHECK_MODULES([MTDEV], [mtdev >= 1.1])
77 PKG_CHECK_MODULES([EVEMU], [utouch-evemu >= 1.0.5])
78-PKG_CHECK_MODULES([FRAME], [utouch-frame >= 1.2])
79+PKG_CHECK_MODULES([FRAME], [utouch-frame >= 1.9.0])
80
81 AC_ARG_WITH([xi], AS_HELP_STRING([--with-xi], [Build with XI2.1 support]))
82 AM_CONDITIONAL([HAVE_XI], [test "x$with_xi" != "x"])
83@@ -33,19 +39,37 @@
84 PKG_CHECK_MODULES(XINPUT, x11 xext [xi >= 1.4.1.99.1] [inputproto >= 2.0.99.1])
85 AC_DEFINE([HAVE_XI], [1], [XI2.1 support])
86 ])
87+
88 # Check for TDD tools
89-PKG_CHECK_MODULES([CHECK], [check >= 0.9.8],
90- [have_check=yes],
91- AC_MSG_WARN([package 'check' not found: tests disabled]))
92-AM_CONDITIONAL([HAVE_CHECK],[test "x$have_check" = xyes])
93-
94+AC_CHECK_GTEST
95+
96+AS_IF([test "x$have_gtest" = xyes],
97+ [PKG_CHECK_MODULES(XORG_GTEST, xorg-gtest,
98+ [have_xorg_gtest="yes"],
99+ [AC_MSG_WARN([xorg-gtest not installed, tests will not be built])])],
100+ [AC_MSG_WARN([gtest not installed, tests will not be build])]
101+)
102+
103+AM_CONDITIONAL([HAVE_GTEST], [test "x$have_xorg_gtest" = xyes])
104+
105+AC_SUBST([GTEST_LDFLAGS])
106+AC_SUBST([GTEST_CXXFLAGS])
107+
108+# Enable coverage reports using gcov
109+AC_TDD_GCOV
110+
111+AM_CONDITIONAL([HAVE_GCOV],[test "x$ac_cv_check_gcov" = xyes])
112+
113 AC_CONFIG_FILES([Makefile
114 src/Makefile
115 tools/Makefile
116 test/Makefile
117 utouch-grail.pc])
118
119-AC_SUBST(AM_CPPFLAGS, "-Wall -Werror")
120+AC_SUBST(AM_CPPFLAGS, "-DBUILDING_GRAIL $GTEST_CPPFLAGS")
121+AC_SUBST(AM_CFLAGS, "-fvisibility=hidden -Wall -Werror $COVERAGE_CFLAGS")
122+AC_SUBST(AM_CXXFLAGS, "-std=c++0x $COVERAGE_CXXFLAGS $GTEST_CXXFLAGS")
123+AC_SUBST(AM_LDFLAGS, "$COVERAGE_LDFLAGS $GTEST_LDFLAGS")
124
125 AC_OUTPUT
126
127
128=== added directory 'include/utouch'
129=== added file 'include/utouch/grail.h'
130--- include/utouch/grail.h 1970-01-01 00:00:00 +0000
131+++ include/utouch/grail.h 2012-01-25 15:53:29 +0000
132@@ -0,0 +1,685 @@
133+/*****************************************************************************
134+ *
135+ * utouch-grail - Multitouch Gesture Recognition Library
136+ *
137+ * Copyright (C) 2010-2011 Canonical Ltd.
138+ *
139+ * This program is free software: you can redistribute it and/or modify it
140+ * under the terms of the GNU General Public License as published by the
141+ * Free Software Foundation, either version 3 of the License, or (at your
142+ * option) any later version.
143+ *
144+ * This program is distributed in the hope that it will be useful, but
145+ * WITHOUT ANY WARRANTY; without even the implied warranty of
146+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
147+ * General Public License for more details.
148+ *
149+ * You should have received a copy of the GNU General Public License along
150+ * with this program. If not, see <http://www.gnu.org/licenses/>.
151+ *
152+ ****************************************************************************/
153+
154+/**
155+ * @file utouch/grail.h
156+ * Definitions of the main and platform-generic API
157+ */
158+
159+#ifndef UTOUCH_GRAIL_UTOUCH_GRAIL_H_
160+#define UTOUCH_GRAIL_UTOUCH_GRAIL_H_
161+
162+#include <stdint.h>
163+
164+#include <utouch/frame.h>
165+
166+#ifdef __cplusplus
167+extern "C" {
168+#endif
169+
170+/**
171+ * @defgroup v3 uTouch-Grail 3.x
172+ * @{
173+ */
174+
175+/** An object for the context of the uTouch Frame instance */
176+typedef struct UGHandle_* UGHandle;
177+/** An object for a gesture subscription */
178+typedef struct UGSubscription_* UGSubscription;
179+/** An object for an event */
180+typedef struct UGEvent_* UGEvent;
181+/** An object for a gesture state in time */
182+typedef const struct UGSlice_* UGSlice;
183+
184+/** The status code denoting the result of a function call */
185+typedef enum UGStatus {
186+ UGStatusSuccess = 0, /**< The call was successful */
187+ UGStatusErrorGeneric, /**< A platform-dependent error occurred */
188+ UGStatusErrorResources, /**< An error occurred due to insufficient resources */
189+ UGStatusErrorNoEvent, /**< No events were available to get */
190+ UGStatusErrorUnknownProperty, /**< The requested property value was not set */
191+ UGStatusErrorInvalidValue, /**< The property value passed in is invalid */
192+ UGStatusErrorInvalidDevice, /**< The requested device does not exist */
193+ UGStatusErrorInvalidSubscription, /**< The subscription is invalid */
194+ UGStatusErrorInvalidGesture, /**< The requested gesture does not exist */
195+ UGStatusErrorInvalidIndex, /**< The requested touch index is invalid */
196+ UGStatusErrorAtomicity, /**< The subscription has a different value for
197+ UGSubscriptionPropertyAtomicGestures than other
198+ subscriptions active on the window */
199+} UGStatus;
200+
201+/** Subscription properties */
202+typedef enum UGSubscriptionProperty {
203+ /**
204+ * Device to subscribe to gesture events for
205+ *
206+ * Value type: UFDevice
207+ */
208+ UGSubscriptionPropertyDevice,
209+ /**
210+ * Window to subscribe to gesture events for
211+ *
212+ * Value type: UFWindowId
213+ */
214+ UGSubscriptionPropertyWindow,
215+ /**
216+ * Gesture types to subscribe for
217+ *
218+ * Value type: UGGestureTypeMask
219+ */
220+ UGSubscriptionPropertyMask,
221+ /**
222+ * Number of touches required to begin gesture
223+ *
224+ * Value type: unsigned int
225+ */
226+ UGSubscriptionPropertyTouchesStart,
227+ /**
228+ * Minimum number of touches for gesture
229+ *
230+ * Value type: unsigned int
231+ */
232+ UGSubscriptionPropertyTouchesMinimum,
233+ /**
234+ * Maximum number of touches for gesture
235+ *
236+ * Value type: unsigned int
237+ */
238+ UGSubscriptionPropertyTouchesMaximum,
239+ /**
240+ * Timeout for recognizing a drag gesture
241+ *
242+ * Value type: 64-bit unsigned integer
243+ */
244+ UGSubscriptionPropertyDragTimeout,
245+ /**
246+ * Threshold value for recognizing a drag gesture
247+ *
248+ * Value type: float
249+ */
250+ UGSubscriptionPropertyDragThreshold,
251+ /**
252+ * Timeout for recognizing a pinch gesture
253+ *
254+ * Value type: 64-bit unsigned integer
255+ */
256+ UGSubscriptionPropertyPinchTimeout,
257+ /**
258+ * Threshold value for recognizing a pinch gesture
259+ *
260+ * Value type: float
261+ */
262+ UGSubscriptionPropertyPinchThreshold,
263+ /**
264+ * Timeout for recognizing a rotate gesture
265+ *
266+ * Value type: 64-bit unsigned integer
267+ */
268+ UGSubscriptionPropertyRotateTimeout,
269+ /**
270+ * Threshold value for recognizing a rotate gesture
271+ *
272+ * Value type: float
273+ */
274+ UGSubscriptionPropertyRotateThreshold,
275+ /**
276+ * Timeout for recognizing a tap gesture
277+ *
278+ * Value type: 64-bit unsigned integer
279+ */
280+ UGSubscriptionPropertyTapTimeout,
281+ /**
282+ * Threshold value for recognizing a tap gesture
283+ *
284+ * Value type: float
285+ */
286+ UGSubscriptionPropertyTapThreshold,
287+ /**
288+ * Only support one gesture at a time
289+ *
290+ * Value type: int with boolean semantics
291+ *
292+ * The first version of uTouch-Grail supported only one gesture at a time.
293+ * When this property is true, uTouch-Grail will mimic this behavior. This
294+ * results in the following:
295+ *
296+ * - The uTouch-Grail client must not attempt to accept or reject a gesture
297+ * - If a gesture is active for a maximum of N touches, the addition of
298+ * another touch will end the gesture. A new gesture is begun if another
299+ * subscription's TouchesStart property equals the new number of touches.
300+ * - All subscriptions for a window must have the same value for this
301+ * property. If a client attempts to activate a subscription with a
302+ * different value for this property than the already activated
303+ * subscriptions for the window, UGStatusErrorAtomicity will be returned.
304+ *
305+ * There is one key difference between uTouch-Grail v1 behavior and the use of
306+ * this option. The v1 behavior only supported one gesture per device. The use
307+ * of this option only supports one gesture per device per window. The
308+ * beginning of a gesture in a window does not inhibit gestures in other
309+ * windows. It also does not guarantee that there are no active touches
310+ * outside the window.
311+ */
312+ UGSubscriptionPropertyAtomicGestures,
313+} UGSubscriptionProperty;
314+
315+/** Event type */
316+typedef enum UGEventType {
317+ UGEventTypeSlice = 0, /**< A new gesture slice */
318+} UGEventType;
319+
320+/** Event properties */
321+typedef enum UGEventProperty {
322+ /**
323+ * Type of event
324+ *
325+ * Value type: UGEventType
326+ */
327+ UGEventPropertyType = 0,
328+ /**
329+ * Slice of a gesture
330+ *
331+ * Value type: UGSlice
332+ */
333+ UGEventPropertySlice,
334+ /**
335+ * Event time
336+ *
337+ * Value type: 64-bit unsigned int
338+ *
339+ * This property holds the time the event occurred in display server
340+ * timespace. The time is provided in milliseconds (ms).
341+ */
342+ UGEventPropertyTime,
343+} UGEventProperty;
344+
345+/** Gesture type bit indices */
346+typedef enum UGGestureType {
347+ UGGestureTypeDrag = 0x1, /**< Drag gesture */
348+ UGGestureTypePinch = 0x2, /**< Pinch gesture */
349+ UGGestureTypeRotate = 0x4, /**< Rotate gesture */
350+ UGGestureTypeTap = 0x8, /**< Tap gesture */
351+ UGGestureTypeTouch = 0x10, /**< Touch gesture */
352+} UGGestureType;
353+
354+/** Bit-mask of gesture types */
355+typedef uint32_t UGGestureTypeMask;
356+
357+/** 2D affine transformation */
358+typedef const float UGTransform[3][3];
359+
360+/** Gesture slice state */
361+typedef enum UGGestureState {
362+ UGGestureStateBegin = 0, /**< Gesture slice begin */
363+ UGGestureStateUpdate, /**< Gesture slice update */
364+ UGGestureStateEnd, /**< Gesture slice end */
365+} UGGestureState;
366+
367+/** Gesture slice properties */
368+typedef enum UGSliceProperty {
369+ /**
370+ * Gesture ID
371+ *
372+ * Value type: unsigned int
373+ */
374+ UGSlicePropertyId = 0,
375+ /**
376+ * Gesture set state
377+ *
378+ * Value type: UGGestureState
379+ */
380+ UGSlicePropertyState,
381+ /**
382+ * Gesture subscription
383+ *
384+ * Value type: UGSubscription
385+ */
386+ UGSlicePropertySubscription,
387+ /**
388+ * Recognized gestures
389+ *
390+ * Value type: UGGestureTypeMask
391+ */
392+ UGSlicePropertyRecognized,
393+ /**
394+ * Number of touches
395+ *
396+ * Value type: unsigned int
397+ */
398+ UGSlicePropertyNumTouches,
399+ /**
400+ * Touch frame
401+ *
402+ * Value type: UFFrame
403+ */
404+ UGSlicePropertyFrame,
405+ /**
406+ * Original gesture center along the X axis
407+ *
408+ * Value type: float
409+ *
410+ * This value represents the original geometric center of the touches.
411+ */
412+ UGSlicePropertyOriginalCenterX,
413+ /**
414+ * Original gesture center along the Y axis
415+ *
416+ * Value type: float
417+ *
418+ * This value represents the original geometric center of the touches.
419+ */
420+ UGSlicePropertyOriginalCenterY,
421+ /**
422+ * Original radius of touches
423+ *
424+ * Value type: float
425+ *
426+ * This value represents the average of the square of the euclidean distance
427+ * from the geometric center of the original touches to each touch.
428+ */
429+ UGSlicePropertyOriginalRadius,
430+ /**
431+ * Best-fit 2D affine transformation of previous to current touch locations
432+ *
433+ * Value type: pointer to UGTransform
434+ *
435+ * The transformation is relative to the previous geometric center of the
436+ * touches.
437+ */
438+ UGSlicePropertyTransform,
439+ /**
440+ * Best-fit 2D affine transformation of original to current touch locations
441+ *
442+ * Value type: pointer to UGTransform
443+ *
444+ * The transformation is relative to the original geometric center of the
445+ * touches.
446+ */
447+ UGSlicePropertyCumulativeTransform,
448+ /**
449+ * Best-fit instant center of rotation along the X axis
450+ *
451+ * Value type: float
452+ */
453+ UGSlicePropertyCenterOfRotationX,
454+ /**
455+ * Best-fit instant center of rotation along the Y axis
456+ *
457+ * Value type: float
458+ */
459+ UGSlicePropertyCenterOfRotationY,
460+ /**
461+ * Whether the construction of all gestures containing the same touches is
462+ * finished
463+ *
464+ * Value type: int with boolean semantics
465+ *
466+ * Grail events are serial. This property allows the client to determine if
467+ * all the possible gestures from the set of touches in this gesture have been
468+ * sent. When this value is true, the client will have received all the
469+ * information needed to make a gesture accept and reject decision based on
470+ * potentially overlapping gestures. An example is when both one and two touch
471+ * gestures are subscribed on the same window with the same gesture types and
472+ * thresholds. When this property is true for one touch gesture events, the
473+ * client can be sure there are no other touches unless a two touch gesture
474+ * event has already been sent.
475+ */
476+ UGSlicePropertyConstructionFinished,
477+} UGSliceProperty;
478+
479+/**
480+ * Create a new grail context
481+ *
482+ * @param [in] frame_handle The uTouch frame context object
483+ * @param [out] handle The new uTouch grail context object
484+ * @return UGStatusSuccess or UGStatusErrorResources
485+ */
486+UGStatus grail_new(UFHandle frame_handle, UGHandle *handle);
487+
488+/**
489+ * Delete a grail context
490+ *
491+ * @param [in] handle The uTouch Grail context object
492+ */
493+void grail_delete_v3(UGHandle handle);
494+
495+/**
496+ * Get the event file descriptor for the uTouch Frame context
497+ *
498+ * @param [in] handle The uTouch Grail context object
499+ * @return A file descriptor for the context
500+ *
501+ * When events are available for processing, the file descriptor will be
502+ * readable. Perform an 8-byte read from the file descriptor to clear the state.
503+ * Refer to the EVENTFD(2) man page for more details.
504+ */
505+int grail_get_fd(UGHandle handle);
506+
507+/**
508+ * Create a new subscription object
509+ *
510+ * @param [out] subscription The new subscription object
511+ * @return UGStatusSuccess or UGStatusErrorResources
512+ */
513+UGStatus grail_subscription_new(UGSubscription* subscription);
514+
515+/**
516+ * Delete a subscription object
517+ *
518+ * @param [in] subscription The subscription object
519+ */
520+void grail_subscription_delete(UGSubscription subscription);
521+
522+/**
523+ * Set a subscription property
524+ *
525+ * @param [in] subscription The subscription object
526+ * @param [in] property The subscription property
527+ * @param [in] value The new value of the property
528+ * @return UGStatusSuccess or UGStatusInvalidProperty
529+ */
530+UGStatus grail_subscription_set_property(UGSubscription subscription,
531+ UGSubscriptionProperty property,
532+ const void* value);
533+
534+/**
535+ * Get a subscription property
536+ *
537+ * @param [in] subscription The subscription object
538+ * @param [in] property The subscription property
539+ * @param [out] value The value of the property
540+ * @return UGStatusSuccess or UGStatusInvalidProperty
541+ */
542+UGStatus grail_subscription_get_property(UGSubscription subscription,
543+ UGSubscriptionProperty property,
544+ void* value);
545+
546+/**
547+ * Activate a subscription
548+ *
549+ * @param [in] handle The context object
550+ * @param [in] subscription The subscription object
551+ * @return UGStatusSuccess or UGStatusErrorInvalidDevice
552+ */
553+UGStatus grail_subscription_activate(UGHandle handle, UGSubscription subscription);
554+
555+/**
556+ * Deactivate a subscription
557+ *
558+ * @param [in] handle The context object
559+ * @param [in] subscription The subscription object
560+ */
561+void grail_subscription_deactivate(UGHandle handle,
562+ UGSubscription subscription);
563+
564+/**
565+ * Process a uTouch Frame event
566+ *
567+ * @param [in] handle The context object
568+ * @param [in] event The uTouch Frame event
569+ */
570+void grail_process_frame_event(UGHandle handle, const UFEvent event);
571+
572+/**
573+ * Get an event from the uTouch Grail context
574+ *
575+ * @param [in] handle The context object
576+ * @param [out] event The retrieved event
577+ * @return UGStatusSuccess or UGStatusErrorNoEvent
578+ */
579+UGStatus grail_get_event(UGHandle handle, UGEvent *event);
580+
581+/**
582+ * Update the grail state for the given server time
583+ *
584+ * @param [in] handle The context object
585+ * @param [in] time The current server time
586+ *
587+ * The recognizer uses timeouts for deciding whether to accept or reject
588+ * touches. Calling this function will perform any pending decisions based on
589+ * the current server time.
590+ */
591+void grail_update_time(UGHandle handle, uint64_t time);
592+
593+/**
594+ * Get the next timeout at which to update the grail state
595+ *
596+ * @param [in] handle The context object
597+ * @return The next server time at which the grail state should be updated
598+ *
599+ * To update the grail state, call grail_update_time().
600+ */
601+uint64_t grail_next_timeout(UGHandle handle);
602+
603+/**
604+ * Increment the reference count of an event
605+ *
606+ * @param [in] event The event object
607+ */
608+void grail_event_ref(UGEvent event);
609+
610+/**
611+ * Decrement the reference count of an event
612+ *
613+ * @param [in] event The event object
614+ *
615+ * When the reference count reaches zero, the event is freed.
616+ */
617+void grail_event_unref(UGEvent event);
618+
619+/**
620+ * Get the value of a property of an event
621+ *
622+ * @param [in] event The event object
623+ * @param [in] property The property to retrieve a value for
624+ * @param [out] value The value retrieved
625+ * @return UGStatusSuccess or UGStatusErrorUnknownProperty
626+ */
627+UGStatus grail_event_get_property(const UGEvent event, UGEventProperty property,
628+ void *value);
629+
630+/**
631+ * Get the touch ID of a touch in a slice
632+ *
633+ * @param [in] slice The gesture slcie object
634+ * @param [in] index The index of the touch in the slice
635+ * @param [out] touch_id The touch ID of the touch
636+ */
637+UGStatus grail_slice_get_touch_id(const UGSlice slice, unsigned int index,
638+ UFTouchId *touch_id);
639+
640+/**
641+ * Get the value of a property of a gesture slice
642+ *
643+ * @param [in] slice The gesture slice object
644+ * @param [in] property The property to retrieve a value for
645+ * @param [out] value The value retrieved
646+ * @return UGStatusSuccess or UGStatusErrorUnknownProperty
647+ */
648+UGStatus grail_slice_get_property(const UGSlice slice, UGSliceProperty property,
649+ void *value);
650+
651+/**
652+ * Accept gesture associated with gesture slice
653+ *
654+ * @param [in] handle The context object
655+ * @param [in] id The ID of the gesture to accept
656+ * @return UGStatusSuccess or UGStatusErrorInvalidGesture
657+ */
658+UGStatus grail_accept_gesture(UGHandle handle, unsigned int id);
659+
660+/**
661+ * Reject gesture associated with gesture slice
662+ *
663+ * @param [in] handle The context object
664+ * @param [in] id The ID of the gesture to reject
665+ * @return UGStatusSuccess or UGStatusErrorInvalidGesture
666+ */
667+UGStatus grail_reject_gesture(UGHandle handle, unsigned int id);
668+
669+/**
670+ * @defgroup v3-helpers Helper Functions
671+ * These helper functions may be used in place of the generic property getters.
672+ * They are limited to properties that are guaranteed to exist in all instances
673+ * of the objects.
674+ * @{
675+ */
676+
677+/**
678+ * Get the type of an event
679+ *
680+ * @param [in] event The event object
681+ * @return The type of the event
682+ */
683+UGEventType grail_event_get_type(const UGEvent event);
684+
685+/**
686+ * Get the time of an event
687+ *
688+ * @param [in] event The event object
689+ * @return The time of the event
690+ */
691+uint64_t grail_event_get_time(const UGEvent event);
692+
693+/**
694+ * Get the ID of a gesture from a slice
695+ *
696+ * @param [in] slice The gesture slice object
697+ * @return The ID of the gesture
698+ */
699+unsigned int grail_slice_get_id(const UGSlice slice);
700+
701+/**
702+ * Get the state of a gesture in a slice
703+ *
704+ * @param [in] slice The gesture slice object
705+ * @return The state of the gesture in the slice
706+ */
707+UGGestureState grail_slice_get_state(const UGSlice slice);
708+
709+/**
710+ * Get the subscription for the gesture from the slice
711+ *
712+ * @param [in] slice The gesture slice object
713+ * @return The subscription
714+ */
715+UGSubscription grail_slice_get_subscription(const UGSlice slice);
716+
717+/**
718+ * Get the gestures recognized through the slice
719+ *
720+ * @param [in] slice The gesture slice object
721+ * @return The recognized gestures
722+ */
723+UGGestureTypeMask grail_slice_get_recognized(const UGSlice slice);
724+
725+/**
726+ * Get the current number of touches in the slice
727+ *
728+ * @param [in] slice The gesture slice object
729+ * @return The number of touches
730+ */
731+unsigned int grail_slice_get_num_touches(const UGSlice slice);
732+
733+/**
734+ * Get the original centroid position of the gesture along the X axis
735+ *
736+ * @param [in] slice The gesture slice object
737+ * @return The position
738+ */
739+float grail_slice_get_original_center_x(const UGSlice slice);
740+
741+/**
742+ * Get the original centroid position of the gesture along the Y axis
743+ *
744+ * @param [in] slice The gesture slice object
745+ * @return The position
746+ */
747+float grail_slice_get_original_center_y(const UGSlice slice);
748+
749+/**
750+ * Get the original radius of the gesture
751+ *
752+ * @param [in] slice The gesture slice object
753+ * @return The position
754+ */
755+float grail_slice_get_original_radius(const UGSlice slice);
756+
757+/**
758+ * Get the instantaneous center of rotation of the gesture along the X axis
759+ *
760+ * @param [in] slice The gesture slice object
761+ * @return The position
762+ */
763+float grail_slice_get_center_of_rotation_x(const UGSlice slice);
764+
765+/**
766+ * Get the instantaneous center of rotation of the gesture along the Y axis
767+ *
768+ * @param [in] slice The gesture slice object
769+ * @return The position
770+ */
771+float grail_slice_get_center_of_rotation_y(const UGSlice slice);
772+
773+/**
774+ * Get the best-fit instantaneous 2D affine transformation for the gesture slice
775+ *
776+ * @param [in] slice The gesture slice object
777+ * @return the transformation
778+ *
779+ * The returned transformation is owned by the gesture slice.
780+ */
781+const UGTransform *grail_slice_get_transform(const UGSlice slice);
782+
783+/**
784+ * Get the best-fit cumulative 2D affine transformation for the gesture slice
785+ *
786+ * @param [in] slice The gesture slice object
787+ * @return the transformation
788+ *
789+ * The returned transformation is owned by the gesture slice.
790+ */
791+const UGTransform *grail_slice_get_cumulative_transform(const UGSlice slice);
792+
793+/**
794+ * Get the uTouch-Frame frame for the slice
795+ *
796+ * @param [in] slice The gesture slice object
797+ * @return the frame
798+ */
799+const UFFrame grail_slice_get_frame(const UGSlice slice);
800+
801+/**
802+ * Get whether construction has finished for all touches in the gesture
803+ *
804+ * @param [in] slice The gesture slice object
805+ * @return whether construction has finished
806+ */
807+int grail_slice_get_construction_finished(const UGSlice slice);
808+
809+/** @} */
810+
811+/** @} */
812+
813+#ifdef __cplusplus
814+}
815+#endif
816+
817+#endif // UTOUCH_GRAIL_UTOUCH_GRAIL_H_
818
819=== added directory 'm4'
820=== added file 'm4/gcov.m4'
821--- m4/gcov.m4 1970-01-01 00:00:00 +0000
822+++ m4/gcov.m4 2012-01-25 15:53:29 +0000
823@@ -0,0 +1,83 @@
824+# Checks for existence of coverage tools:
825+# * gcov
826+# * lcov
827+# * genhtml
828+# * gcovr
829+#
830+# Sets ac_cv_check_gcov to yes if tooling is present
831+# and reports the executables to the variables LCOV, GCOVR and GENHTML.
832+AC_DEFUN([AC_TDD_GCOV],
833+[
834+ AC_ARG_ENABLE(gcov,
835+ AS_HELP_STRING([--enable-gcov],
836+ [enable coverage testing with gcov]),
837+ [use_gcov=$enableval], [use_gcov=no])
838+
839+ if test "x$use_gcov" = "xyes"; then
840+ # we need gcc:
841+ if test "$GCC" != "yes"; then
842+ AC_MSG_ERROR([GCC is required for --enable-gcov])
843+ fi
844+
845+ # Check if ccache is being used
846+ AC_CHECK_PROG(SHTOOL, shtool, shtool)
847+ case `$SHTOOL path $CC` in
848+ *ccache*[)] gcc_ccache=yes;;
849+ *[)] gcc_ccache=no;;
850+ esac
851+
852+ if test "$gcc_ccache" = "yes" && (test -z "$CCACHE_DISABLE" || test "$CCACHE_DISABLE" != "1"); then
853+ AC_MSG_ERROR([ccache must be disabled when --enable-gcov option is used. You can disable ccache by setting environment variable CCACHE_DISABLE=1.])
854+ fi
855+
856+ lcov_version_list="1.6 1.7 1.8 1.9"
857+ AC_CHECK_PROG(LCOV, lcov, lcov)
858+ AC_CHECK_PROG(GENHTML, genhtml, genhtml)
859+ AC_CHECK_PROG(GCOVR, gcovr, gcovr)
860+
861+ if test "$LCOV"; then
862+ AC_CACHE_CHECK([for lcov version], glib_cv_lcov_version, [
863+ glib_cv_lcov_version=invalid
864+ lcov_version=`$LCOV -v 2>/dev/null | $SED -e 's/^.* //'`
865+ for lcov_check_version in $lcov_version_list; do
866+ if test "$lcov_version" = "$lcov_check_version"; then
867+ glib_cv_lcov_version="$lcov_check_version (ok)"
868+ fi
869+ done
870+ ])
871+ else
872+ lcov_msg="To enable code coverage reporting you must have one of the following lcov versions installed: $lcov_version_list"
873+ AC_MSG_ERROR([$lcov_msg])
874+ fi
875+
876+ case $glib_cv_lcov_version in
877+ ""|invalid[)]
878+ lcov_msg="You must have one of the following versions of lcov: $lcov_version_list (found: $lcov_version)."
879+ AC_MSG_ERROR([$lcov_msg])
880+ LCOV="exit 0;"
881+ ;;
882+ esac
883+
884+ if test -z "$GENHTML"; then
885+ AC_MSG_ERROR([Could not find genhtml from the lcov package])
886+ fi
887+
888+ if test -z "$GCOVR"; then
889+ AC_MSG_ERROR([Could not find gcovr; easy_install (or pip) gcovr])
890+ fi
891+
892+ ac_cv_check_gcov=yes
893+
894+ # Remove all optimization flags from CFLAGS
895+ changequote({,})
896+ CFLAGS=`echo "$CFLAGS" | $SED -e 's/-O[0-9]*//g'`
897+ changequote([,])
898+
899+ # Add the special gcc flags
900+ COVERAGE_CFLAGS="-O0 -fprofile-arcs -ftest-coverage"
901+ COVERAGE_CXXFLAGS="-O0 -fprofile-arcs -ftest-coverage"
902+ COVERAGE_LDFLAGS="-lgcov"
903+
904+fi
905+]) # AC_TDD_GCOV
906+
907
908=== added file 'm4/gtest.m4'
909--- m4/gtest.m4 1970-01-01 00:00:00 +0000
910+++ m4/gtest.m4 2012-01-25 15:53:29 +0000
911@@ -0,0 +1,24 @@
912+# Checks whether the gtest library is available on the system
913+# Allows for adjusting the include and library path.
914+# Sets have_gtest=yes if the library is present and
915+# reports the compiler and linker flags in
916+# GTEST_CXXFLAGS AND GTEST_LDFLAGS, respectively.
917+AC_DEFUN([AC_CHECK_GTEST],
918+[
919+ AC_ARG_WITH([gtest-include-path],
920+ [AS_HELP_STRING([--with-gtest-include-path],
921+ [location of the Google test headers, defaults to /usr/include])],
922+ [GTEST_CXXFLAGS="-I$withval"],
923+ [GTEST_CXXFLAGS='-I/usr/include'])
924+
925+ AC_ARG_WITH([gtest-lib-path],
926+ [AS_HELP_STRING([--with-gtest-lib-path], [location of the Google test libraries])],
927+ [GTEST_LDFLAGS="-L$withval -lpthread"],
928+ [GTEST_LDFLAGS='-lgtest -lpthread'])
929+
930+ AC_HAVE_LIBRARY( [gtest],
931+ [have_gtest=yes],
932+ AC_MSG_WARN([package 'gtest' not found: tests disabled]))
933+
934+]) # AC_CHECK_GTEST
935+
936
937=== modified file 'src/Makefile.am'
938--- src/Makefile.am 2011-04-28 16:53:41 +0000
939+++ src/Makefile.am 2012-01-25 15:53:29 +0000
940@@ -1,3 +1,5 @@
941+AUTOMAKE_OPTIONS = subdir-objects
942+
943 lib_LTLIBRARIES = libutouch-grail.la
944
945 libutouch_grail_la_LDFLAGS = \
946@@ -7,32 +9,48 @@
947 $(EVEMU_LIBS) \
948 $(FRAME_LIBS)
949
950+v2dir = v2
951 libutouch_grail_la_SOURCES = \
952- evbuf.h \
953- gebuf.h \
954- grailbuf.h \
955- grail-bits.c \
956- grail-inserter.c \
957- grail-inserter.h \
958- grail-gestures.c \
959- grail-gestures.h \
960- gestures-touch.c \
961- gestures-drag.c \
962- gestures-pinch.c \
963- gestures-rotate.c \
964- gestures-tapping.c \
965- grail-recognizer.c \
966- grail-recognizer.h \
967- grail-event.c \
968- grail-impl.h \
969- grail-api.c \
970- grail-legacy.c \
971- grail-init.c \
972- grail-frame.c
973+ v2/evbuf.h \
974+ v2/gebuf.h \
975+ v2/grailbuf.h \
976+ v2/grail-bits.c \
977+ v2/grail-inserter.c \
978+ v2/grail-inserter.h \
979+ v2/grail-gestures.c \
980+ v2/grail-gestures.h \
981+ v2/gestures-touch.c \
982+ v2/gestures-drag.c \
983+ v2/gestures-pinch.c \
984+ v2/gestures-rotate.c \
985+ v2/gestures-tapping.c \
986+ v2/grail-recognizer.c \
987+ v2/grail-recognizer.h \
988+ v2/grail-event.c \
989+ v2/grail-impl.h \
990+ v2/grail-api.c \
991+ v2/grail-legacy.c \
992+ v2/grail-init.c \
993+ v2/grail-frame.c
994
995-# These are flags required to properly set up
996-# the build. -fvisibility requires GCC > 4 (or clang)
997-AM_CFLAGS = $(CWARNFLAGS) -DBUILDING_GRAIL -fvisibility=hidden
998+if HAVE_XI
999+v3dir = v3
1000+libutouch_grail_la_SOURCES += \
1001+ v3/event.cpp \
1002+ v3/event.h \
1003+ v3/gesture.cpp \
1004+ v3/gesture.h \
1005+ v3/handle.cpp \
1006+ v3/handle.h \
1007+ v3/log.cpp \
1008+ v3/log.h \
1009+ v3/recognizer.cpp \
1010+ v3/recognizer.h \
1011+ v3/slice.cpp \
1012+ v3/slice.h \
1013+ v3/subscription.cpp \
1014+ v3/subscription.h
1015+endif
1016
1017 INCLUDES = -I$(top_srcdir)/include/
1018
1019@@ -41,3 +59,9 @@
1020 $(top_srcdir)/include/grail-bits.h \
1021 $(top_srcdir)/include/grail-types.h \
1022 $(top_srcdir)/include/grail.h
1023+
1024+if HAVE_XI
1025+libutouch_grail_v3includedir = $(includedir)/utouch
1026+libutouch_grail_v3include_HEADERS = \
1027+ $(top_srcdir)/include/utouch/grail.h
1028+endif
1029
1030=== removed file 'src/evbuf.h'
1031--- src/evbuf.h 2011-04-28 16:53:57 +0000
1032+++ src/evbuf.h 1970-01-01 00:00:00 +0000
1033@@ -1,57 +0,0 @@
1034-/*****************************************************************************
1035- *
1036- * grail - Gesture Recognition And Instantiation Library
1037- *
1038- * Copyright (C) 2010-2011 Canonical Ltd.
1039- *
1040- * This program is free software: you can redistribute it and/or modify it
1041- * under the terms of the GNU General Public License as published by the
1042- * Free Software Foundation, either version 3 of the License, or (at your
1043- * option) any later version.
1044- *
1045- * This program is distributed in the hope that it will be useful, but
1046- * WITHOUT ANY WARRANTY; without even the implied warranty of
1047- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1048- * General Public License for more details.
1049- *
1050- * You should have received a copy of the GNU General Public License along
1051- * with this program. If not, see <http://www.gnu.org/licenses/>.
1052- *
1053- ****************************************************************************/
1054-
1055-#ifndef GRAIL_EVBUF_H
1056-#define GRAIL_EVBUF_H
1057-
1058-#define DIM_EVENTS 4096
1059-
1060-struct evbuf {
1061- int head;
1062- int tail;
1063- struct input_event buffer[DIM_EVENTS];
1064-};
1065-
1066-static inline void evbuf_clear(struct evbuf *evbuf)
1067-{
1068- evbuf->head = evbuf->tail = 0;
1069-}
1070-
1071-static inline int evbuf_empty(const struct evbuf *evbuf)
1072-{
1073- return evbuf->head == evbuf->tail;
1074-}
1075-
1076-static inline void evbuf_put(struct evbuf *evbuf,
1077- const struct input_event *ev)
1078-{
1079- evbuf->buffer[evbuf->head++] = *ev;
1080- evbuf->head &= DIM_EVENTS - 1;
1081-}
1082-
1083-static inline void evbuf_get(struct evbuf *evbuf,
1084- struct input_event *ev)
1085-{
1086- *ev = evbuf->buffer[evbuf->tail++];
1087- evbuf->tail &= DIM_EVENTS - 1;
1088-}
1089-
1090-#endif
1091
1092=== removed file 'src/gebuf.h'
1093--- src/gebuf.h 2011-05-17 14:15:22 +0000
1094+++ src/gebuf.h 1970-01-01 00:00:00 +0000
1095@@ -1,68 +0,0 @@
1096-/*****************************************************************************
1097- *
1098- * grail - Gesture Recognition And Instantiation Library
1099- *
1100- * Copyright (C) 2010-2011 Canonical Ltd.
1101- *
1102- * This program is free software: you can redistribute it and/or modify it
1103- * under the terms of the GNU General Public License as published by the
1104- * Free Software Foundation, either version 3 of the License, or (at your
1105- * option) any later version.
1106- *
1107- * This program is distributed in the hope that it will be useful, but
1108- * WITHOUT ANY WARRANTY; without even the implied warranty of
1109- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1110- * General Public License for more details.
1111- *
1112- * You should have received a copy of the GNU General Public License along
1113- * with this program. If not, see <http://www.gnu.org/licenses/>.
1114- *
1115- ****************************************************************************/
1116-
1117-#ifndef GRAIL_GESTURE_BUFFER_H
1118-#define GRAIL_GESTURE_BUFFER_H
1119-
1120-#include "grail-impl.h"
1121-
1122-#define DIM_GESTURE_EVENTS 512
1123-
1124-struct gesture_event {
1125- int status;
1126- int ntouch;
1127- int nprop;
1128- utouch_frame_time_t time;
1129- struct grail_coord pos;
1130- grail_prop_t prop[DIM_GRAIL_PROP];
1131-};
1132-
1133-struct gebuf {
1134- int head;
1135- int tail;
1136- struct gesture_event buffer[DIM_GESTURE_EVENTS];
1137-};
1138-
1139-static inline void gebuf_clear(struct gebuf *gebuf)
1140-{
1141- gebuf->head = gebuf->tail = 0;
1142-}
1143-
1144-static inline int gebuf_empty(const struct gebuf *gebuf)
1145-{
1146- return gebuf->head == gebuf->tail;
1147-}
1148-
1149-static inline void gebuf_put(struct gebuf *gebuf,
1150- const struct gesture_event *ev)
1151-{
1152- gebuf->buffer[gebuf->head++] = *ev;
1153- gebuf->head &= DIM_GESTURE_EVENTS - 1;
1154-}
1155-
1156-static inline void gebuf_get(struct gebuf *gebuf,
1157- struct gesture_event *ev)
1158-{
1159- *ev = gebuf->buffer[gebuf->tail++];
1160- gebuf->tail &= DIM_GESTURE_EVENTS - 1;
1161-}
1162-
1163-#endif
1164
1165=== removed file 'src/gestures-drag.c'
1166--- src/gestures-drag.c 2011-04-28 16:53:57 +0000
1167+++ src/gestures-drag.c 1970-01-01 00:00:00 +0000
1168@@ -1,135 +0,0 @@
1169-/*****************************************************************************
1170- *
1171- * grail - Gesture Recognition And Instantiation Library
1172- *
1173- * Copyright (C) 2010-2011 Canonical Ltd.
1174- *
1175- * This program is free software: you can redistribute it and/or modify it
1176- * under the terms of the GNU General Public License as published by the
1177- * Free Software Foundation, either version 3 of the License, or (at your
1178- * option) any later version.
1179- *
1180- * This program is distributed in the hope that it will be useful, but
1181- * WITHOUT ANY WARRANTY; without even the implied warranty of
1182- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1183- * General Public License for more details.
1184- *
1185- * You should have received a copy of the GNU General Public License along
1186- * with this program. If not, see <http://www.gnu.org/licenses/>.
1187- *
1188- ****************************************************************************/
1189-
1190-#include "grail-recognizer.h"
1191-#include <math.h>
1192-#include <stdio.h>
1193-
1194-static const int getype[DIM_TOUCH + 1] = {
1195- -1,
1196- GRAIL_TYPE_DRAG1,
1197- GRAIL_TYPE_DRAG2,
1198- GRAIL_TYPE_DRAG3,
1199- GRAIL_TYPE_DRAG4,
1200- GRAIL_TYPE_DRAG5,
1201-};
1202-
1203-static void set_props(const struct gesture_inserter *gin,
1204- struct combo_model *s, const struct move_model *m,
1205- const struct utouch_frame *frame)
1206-{
1207- if (m->single) {
1208- s->prop[GRAIL_PROP_DRAG_DX] = m->fm[FM_X].raw_delta;
1209- s->prop[GRAIL_PROP_DRAG_DY] = m->fm[FM_Y].raw_delta;
1210- } else {
1211- s->prop[GRAIL_PROP_DRAG_DX] = m->fm[FM_X].action_delta;
1212- s->prop[GRAIL_PROP_DRAG_DY] = m->fm[FM_Y].action_delta;
1213- }
1214- s->prop[GRAIL_PROP_DRAG_VX] = m->fm[FM_X].velocity;
1215- s->prop[GRAIL_PROP_DRAG_VY] = m->fm[FM_Y].velocity;
1216- s->prop[GRAIL_PROP_DRAG_X] = m->fm[FM_X].value;
1217- s->prop[GRAIL_PROP_DRAG_Y] = m->fm[FM_Y].value;
1218- s->nprop = 6;
1219- s->nprop += gin_add_contact_props(gin, s->prop + s->nprop, frame);
1220-}
1221-
1222-static const int fm_mask = 0x03;
1223-
1224-int gru_drag(struct grail *ge,
1225- const struct utouch_frame *frame)
1226-{
1227- struct gesture_recognizer *gru = ge->gru;
1228- struct combo_model *state = &gru->drag;
1229- struct move_model *move = &gru->move;
1230- int mask = state->active ? (move->active & fm_mask) : fm_mask;
1231- if (!move->multi && !move->single) {
1232- if (state->active) {
1233- gru_end(ge, state->gid, move,
1234- state->prop, state->nprop);
1235- state->active = 0;
1236- }
1237- }
1238- if ((move->timeout & fm_mask) == fm_mask) {
1239- if (state->active) {
1240- gin_gid_timeout(ge, state->gid);
1241- }
1242- }
1243- if (!state->active) {
1244- int type = getype[move->ntouch];
1245- if (type < 0)
1246- return 0;
1247- state->gid = gin_gid_begin(ge, type, PRIO_GESTURE, frame);
1248- state->active = 1;
1249- }
1250- if (!(move->tickle & mask))
1251- return 0;
1252- if (!(move->active & fm_mask))
1253- return 0;
1254- set_props(ge->gin, state, move, frame);
1255- gru_event(ge, state->gid, move, state->prop, state->nprop);
1256- return 1;
1257-}
1258-
1259-int gru_windrag(struct grail *ge,
1260- const struct utouch_frame *frame)
1261-{
1262- struct gesture_recognizer *gru = ge->gru;
1263- struct combo_model *state = &gru->windrag;
1264- struct move_model *move = &gru->move;
1265- int mask = state->active ? (move->active & fm_mask) : fm_mask;
1266- if (!move->multi && !move->single) {
1267- if (state->active && out_of_bounds(state, move)) {
1268- gru_end(ge, state->gid, move,
1269- state->prop, state->nprop);
1270- state->active = 0;
1271- }
1272- }
1273- if ((move->timeout & fm_mask) == fm_mask) {
1274- if (state->active) {
1275- gin_gid_timeout(ge, state->gid);
1276- }
1277- }
1278- if (!state->active) {
1279- if (move->ntouch == 4) {
1280- state->gid = gin_gid_begin(ge, GRAIL_TYPE_MDRAG,
1281- PRIO_META, frame);
1282- state->mintouch = 1;
1283- state->maxtouch = 4;
1284- state->active = 1;
1285- } else if (move->ntouch == 3) {
1286- state->gid = gin_gid_begin(ge, GRAIL_TYPE_EDRAG,
1287- PRIO_ENV, frame);
1288- state->mintouch = 1;
1289- state->maxtouch = 3;
1290- state->active = 1;
1291- } else {
1292- return 0;
1293- }
1294- }
1295- if (!(move->tickle & mask))
1296- return 0;
1297- if (!(move->active & fm_mask))
1298- return 0;
1299- set_props(ge->gin, state, move, frame);
1300- gru_event(ge, state->gid, move, state->prop, state->nprop);
1301- return 1;
1302-}
1303-
1304
1305=== removed file 'src/gestures-pinch.c'
1306--- src/gestures-pinch.c 2011-06-06 14:42:39 +0000
1307+++ src/gestures-pinch.c 1970-01-01 00:00:00 +0000
1308@@ -1,131 +0,0 @@
1309-/*****************************************************************************
1310- *
1311- * grail - Gesture Recognition And Instantiation Library
1312- *
1313- * Copyright (C) 2010-2011 Canonical Ltd.
1314- *
1315- * This program is free software: you can redistribute it and/or modify it
1316- * under the terms of the GNU General Public License as published by the
1317- * Free Software Foundation, either version 3 of the License, or (at your
1318- * option) any later version.
1319- *
1320- * This program is distributed in the hope that it will be useful, but
1321- * WITHOUT ANY WARRANTY; without even the implied warranty of
1322- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1323- * General Public License for more details.
1324- *
1325- * You should have received a copy of the GNU General Public License along
1326- * with this program. If not, see <http://www.gnu.org/licenses/>.
1327- *
1328- ****************************************************************************/
1329-
1330-#include "grail-recognizer.h"
1331-#include <math.h>
1332-#include <stdio.h>
1333-
1334-static const int getype[DIM_TOUCH + 1] = {
1335- 0,
1336- 0,
1337- GRAIL_TYPE_PINCH2,
1338- GRAIL_TYPE_PINCH3,
1339- GRAIL_TYPE_PINCH4,
1340- GRAIL_TYPE_PINCH5,
1341-};
1342-
1343-static const int fm_mask = 0x04;
1344-
1345-static void set_props(const struct gesture_inserter *gin,
1346- struct combo_model *s,
1347- const struct move_model *m,
1348- const struct utouch_frame *frame)
1349-{
1350- s->prop[GRAIL_PROP_PINCH_DR] = m->fm[FM_R].action_delta;
1351- s->prop[GRAIL_PROP_PINCH_VR] = m->fm[FM_R].velocity;
1352- s->prop[GRAIL_PROP_PINCH_R] = m->fm[FM_R].value;
1353- s->prop[GRAIL_PROP_PINCH_X] = m->fm[FM_X].value;
1354- s->prop[GRAIL_PROP_PINCH_Y] = m->fm[FM_Y].value;
1355- s->nprop = 5;
1356- s->nprop += gin_add_contact_props(gin, s->prop + s->nprop, frame);
1357-}
1358-
1359-int gru_pinch(struct grail *ge,
1360- const struct utouch_frame *frame)
1361-{
1362- struct gesture_recognizer *gru = ge->gru;
1363- struct combo_model *state = &gru->pinch;
1364- struct move_model *move = &gru->move;
1365- int mask = state->active ? (move->active & fm_mask) : fm_mask;
1366- if (!move->multi && !move->single) {
1367- if (state->active) {
1368- gru_end(ge, state->gid, move,
1369- state->prop, state->nprop);
1370- state->active = 0;
1371- }
1372- return 0;
1373- }
1374- if ((move->timeout & fm_mask) == fm_mask) {
1375- if (state->active) {
1376- gin_gid_timeout(ge, state->gid);
1377- }
1378- }
1379- if (!(move->tickle & mask))
1380- return 0;
1381- if (!state->active) {
1382- int type = getype[move->ntouch];
1383- if (!type)
1384- return 0;
1385- state->gid = gin_gid_begin(ge, type, PRIO_GESTURE, frame);
1386- state->active = 1;
1387- }
1388- if (!(move->active & fm_mask))
1389- return 0;
1390- set_props(ge->gin, state, move, frame);
1391- gru_event(ge, state->gid, move, state->prop, state->nprop);
1392- return 1;
1393-}
1394-
1395-int gru_winpinch(struct grail *ge,
1396- const struct utouch_frame *frame)
1397-{
1398- struct gesture_recognizer *gru = ge->gru;
1399- struct combo_model *state = &gru->winpinch;
1400- struct move_model *move = &gru->move;
1401- int mask = state->active ? (move->active & fm_mask) : fm_mask;
1402- if (!move->multi) {
1403- if (state->active && out_of_bounds(state, move)) {
1404- gru_end(ge, state->gid, move,
1405- state->prop, state->nprop);
1406- state->active = 0;
1407- }
1408- return 0;
1409- }
1410- if ((move->timeout & fm_mask) == fm_mask) {
1411- if (state->active) {
1412- gin_gid_timeout(ge, state->gid);
1413- }
1414- }
1415- if (!(move->tickle & mask))
1416- return 0;
1417- if (!state->active) {
1418- if (move->ntouch == 4) {
1419- state->gid = gin_gid_begin(ge, GRAIL_TYPE_MPINCH,
1420- PRIO_META, frame);
1421- state->mintouch = 2;
1422- state->maxtouch = 4;
1423- state->active = 1;
1424- } else if (move->ntouch == 3) {
1425- state->gid = gin_gid_begin(ge, GRAIL_TYPE_EPINCH,
1426- PRIO_ENV, frame);
1427- state->mintouch = 2;
1428- state->maxtouch = 3;
1429- state->active = 1;
1430- } else {
1431- return 0;
1432- }
1433- }
1434- if (!(move->active & fm_mask))
1435- return 0;
1436- set_props(ge->gin, state, move, frame);
1437- gru_event(ge, state->gid, move, state->prop, state->nprop);
1438- return 1;
1439-}
1440
1441=== removed file 'src/gestures-rotate.c'
1442--- src/gestures-rotate.c 2011-06-03 12:54:23 +0000
1443+++ src/gestures-rotate.c 1970-01-01 00:00:00 +0000
1444@@ -1,130 +0,0 @@
1445-/*****************************************************************************
1446- *
1447- * grail - Gesture Recognition And Instantiation Library
1448- *
1449- * Copyright (C) 2010-2011 Canonical Ltd.
1450- *
1451- * This program is free software: you can redistribute it and/or modify it
1452- * under the terms of the GNU General Public License as published by the
1453- * Free Software Foundation, either version 3 of the License, or (at your
1454- * option) any later version.
1455- *
1456- * This program is distributed in the hope that it will be useful, but
1457- * WITHOUT ANY WARRANTY; without even the implied warranty of
1458- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1459- * General Public License for more details.
1460- *
1461- * You should have received a copy of the GNU General Public License along
1462- * with this program. If not, see <http://www.gnu.org/licenses/>.
1463- *
1464- ****************************************************************************/
1465-
1466-#include "grail-recognizer.h"
1467-#include <math.h>
1468-#include <stdio.h>
1469-
1470-static const int getype[DIM_TOUCH + 1] = {
1471- 0,
1472- 0,
1473- GRAIL_TYPE_ROTATE2,
1474- GRAIL_TYPE_ROTATE3,
1475- GRAIL_TYPE_ROTATE4,
1476- GRAIL_TYPE_ROTATE5,
1477-};
1478-
1479-static const int fm_mask = 0x08;
1480-
1481-static void set_props(const struct gesture_inserter *gin,
1482- struct combo_model *s, const struct move_model *m,
1483- const struct utouch_frame *frame)
1484-{
1485- s->prop[GRAIL_PROP_ROTATE_DA] = m->fm[FM_A].action_delta;
1486- s->prop[GRAIL_PROP_ROTATE_VA] = m->fm[FM_A].velocity;
1487- s->prop[GRAIL_PROP_ROTATE_A] = m->fm[FM_A].value;
1488- s->prop[GRAIL_PROP_ROTATE_X] = m->fm[FM_X].value;
1489- s->prop[GRAIL_PROP_ROTATE_Y] = m->fm[FM_Y].value;
1490- s->nprop = 5;
1491- s->nprop += gin_add_contact_props(gin, s->prop + s->nprop, frame);
1492-}
1493-
1494-int gru_rotate(struct grail *ge,
1495- const struct utouch_frame *frame)
1496-{
1497- struct gesture_recognizer *gru = ge->gru;
1498- struct combo_model *state = &gru->rotate;
1499- struct move_model *move = &gru->move;
1500- int mask = state->active ? (move->active & fm_mask) : fm_mask;
1501- if (!move->multi && !move->single) {
1502- if (state->active) {
1503- gru_end(ge, state->gid, move,
1504- state->prop, state->nprop);
1505- state->active = 0;
1506- }
1507- return 0;
1508- }
1509- if ((move->timeout & fm_mask) == fm_mask) {
1510- if (state->active) {
1511- gin_gid_timeout(ge, state->gid);
1512- }
1513- }
1514- if (!(move->tickle & mask))
1515- return 0;
1516- if (!state->active) {
1517- int type = getype[move->ntouch];
1518- if (!type)
1519- return 0;
1520- state->gid = gin_gid_begin(ge, type, PRIO_GESTURE, frame);
1521- state->active = 1;
1522- }
1523- if (!(move->active & fm_mask))
1524- return 0;
1525- set_props(ge->gin, state, move, frame);
1526- gru_event(ge, state->gid, move, state->prop, state->nprop);
1527- return 1;
1528-}
1529-
1530-int gru_winrotate(struct grail *ge,
1531- const struct utouch_frame *frame)
1532-{
1533- struct gesture_recognizer *gru = ge->gru;
1534- struct combo_model *state = &gru->winrotate;
1535- struct move_model *move = &gru->move;
1536- int mask = state->active ? (move->active & fm_mask) : fm_mask;
1537- if (!move->multi) {
1538- if (state->active && out_of_bounds(state, move)) {
1539- gru_end(ge, state->gid, move,
1540- state->prop, state->nprop);
1541- state->active = 0;
1542- }
1543- return 0;
1544- }
1545- if ((move->timeout & fm_mask) == fm_mask) {
1546- if (state->active) {
1547- gin_gid_timeout(ge, state->gid);
1548- }
1549- }
1550- if (!(move->tickle & mask))
1551- return 0;
1552- if (!state->active) {
1553- if (move->ntouch == 4) {
1554- state->gid = gin_gid_begin(ge, GRAIL_TYPE_MROTATE,
1555- PRIO_META, frame);
1556- state->mintouch = 2;
1557- state->maxtouch = 4;
1558- state->active = 1;
1559- } else if (move->ntouch == 3) {
1560- state->gid = gin_gid_begin(ge, GRAIL_TYPE_EROTATE,
1561- PRIO_ENV, frame);
1562- state->mintouch = 2;
1563- state->maxtouch = 3;
1564- state->active = 1;
1565- } else {
1566- return 0;
1567- }
1568- }
1569- if (!(move->active & fm_mask))
1570- return 0;
1571- set_props(ge->gin, state, move, frame);
1572- gru_event(ge, state->gid, move, state->prop, state->nprop);
1573- return 1;
1574-}
1575
1576=== removed file 'src/gestures-tapping.c'
1577--- src/gestures-tapping.c 2011-04-28 16:53:57 +0000
1578+++ src/gestures-tapping.c 1970-01-01 00:00:00 +0000
1579@@ -1,100 +0,0 @@
1580-/*****************************************************************************
1581- *
1582- * grail - Gesture Recognition And Instantiation Library
1583- *
1584- * Copyright (C) 2010-2011 Canonical Ltd.
1585- *
1586- * This program is free software: you can redistribute it and/or modify it
1587- * under the terms of the GNU General Public License as published by the
1588- * Free Software Foundation, either version 3 of the License, or (at your
1589- * option) any later version.
1590- *
1591- * This program is distributed in the hope that it will be useful, but
1592- * WITHOUT ANY WARRANTY; without even the implied warranty of
1593- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1594- * General Public License for more details.
1595- *
1596- * You should have received a copy of the GNU General Public License along
1597- * with this program. If not, see <http://www.gnu.org/licenses/>.
1598- *
1599- ****************************************************************************/
1600-
1601-#include "grail-recognizer.h"
1602-#include <math.h>
1603-
1604-static const int fm_mask = 0x07;
1605-
1606-static void set_props(const struct gesture_inserter *gin,
1607- struct tapping_model *s, const struct move_model *m,
1608- const struct utouch_frame *frame)
1609-{
1610- s->prop[GRAIL_PROP_TAP_DT] = m->time - s->start;
1611- s->prop[GRAIL_PROP_TAP_X] = m->fm[FM_X].value;
1612- s->prop[GRAIL_PROP_TAP_Y] = m->fm[FM_Y].value;
1613- s->nprop = 3;
1614- s->nprop += gin_add_contact_props(gin, s->prop + s->nprop, frame);
1615-}
1616-
1617-int gru_tapping(struct grail *ge,
1618- const struct utouch_frame *frame)
1619-{
1620- struct gesture_recognizer *gru = ge->gru;
1621- struct tapping_model *state = &gru->tapping;
1622- struct move_model *move = &gru->move;
1623- state->tap = 0;
1624- if (frame->num_active && !frame->prev->num_active) {
1625- state->mintouch = 0;
1626- state->maxtouch = 0;
1627- }
1628- if (move->ntouch > state->maxtouch) {
1629- if (state->active) {
1630- gin_gid_discard(ge, state->gid);
1631- state->active = 0;
1632- }
1633- state->start = move->time;
1634- state->maxtouch = move->ntouch;
1635- set_props(ge->gin, state, move, frame);
1636- if (state->maxtouch <= 5) {
1637- int type = GRAIL_TYPE_TAP1 + state->maxtouch - 1;
1638- state->gid = gin_gid_begin(ge, type, PRIO_TAP, frame);
1639- state->active = 1;
1640- }
1641- return 0;
1642- }
1643- if (!state->active) {
1644- state->mintouch = move->ntouch;
1645- state->maxtouch = move->ntouch;
1646- return 0;
1647- }
1648- if (move->ntouch <= state->mintouch) {
1649- int x = state->prop[GRAIL_PROP_TAP_X];
1650- int y = state->prop[GRAIL_PROP_TAP_Y];
1651- int t = move->time - state->start;
1652- if (t > move->fm[FM_X].bar_ms) {
1653- gin_gid_discard(ge, state->gid);
1654- state->mintouch = move->ntouch;
1655- state->maxtouch = move->ntouch;
1656- state->active = 0;
1657- return 0;
1658- }
1659- state->tap = state->maxtouch;
1660- state->prop[GRAIL_PROP_TAP_DT] = t;
1661- gin_gid_event(ge, state->gid, x, y, state->maxtouch,
1662- state->prop, state->nprop, 1);
1663- state->mintouch = move->ntouch;
1664- state->maxtouch = move->ntouch;
1665- state->active = 0;
1666- return 1;
1667- }
1668- if (!move->ntouch)
1669- return 0;
1670- state->prop[GRAIL_PROP_TAP_DT] = move->time - state->start;
1671- if ((move->active & fm_mask) ||
1672- move->time - state->start > move->fm[FM_X].bar_ms) {
1673- gin_gid_discard(ge, state->gid);
1674- state->mintouch = move->ntouch;
1675- state->maxtouch = move->ntouch;
1676- state->active = 0;
1677- }
1678- return 0;
1679-}
1680
1681=== removed file 'src/gestures-touch.c'
1682--- src/gestures-touch.c 2011-04-04 17:27:38 +0000
1683+++ src/gestures-touch.c 1970-01-01 00:00:00 +0000
1684@@ -1,98 +0,0 @@
1685-/*****************************************************************************
1686- *
1687- * grail - Gesture Recognition And Instantiation Library
1688- *
1689- * Copyright (C) 2010 Canonical Ltd.
1690- * Copyright (C) 2010 Henrik Rydberg <rydberg@bitmath.org>
1691- *
1692- * This program is free software: you can redistribute it and/or modify it
1693- * under the terms of the GNU General Public License as published by the
1694- * Free Software Foundation, either version 3 of the License, or (at your
1695- * option) any later version.
1696- *
1697- * This program is distributed in the hope that it will be useful, but
1698- * WITHOUT ANY WARRANTY; without even the implied warranty of
1699- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1700- * General Public License for more details.
1701- *
1702- * You should have received a copy of the GNU General Public License along
1703- * with this program. If not, see <http://www.gnu.org/licenses/>.
1704- *
1705- ****************************************************************************/
1706-
1707-#include "grail-recognizer.h"
1708-#include <math.h>
1709-#include <stdio.h>
1710-
1711-static const int getype[DIM_TOUCH + 1] = {
1712- -1,
1713- GRAIL_TYPE_TOUCH1,
1714- GRAIL_TYPE_TOUCH2,
1715- GRAIL_TYPE_TOUCH3,
1716- GRAIL_TYPE_TOUCH4,
1717- GRAIL_TYPE_TOUCH5,
1718-};
1719-
1720-int gru_touch(struct grail *ge,
1721- const struct utouch_frame *frame)
1722-{
1723- struct gesture_recognizer *gru = ge->gru;
1724- struct combo_model *state = &gru->touch;
1725- struct move_model *move = &gru->move;
1726- if (frame->slot_revision != frame->prev->slot_revision) {
1727- if (state->active) {
1728- gru_end(ge, state->gid, move,
1729- state->prop, state->nprop);
1730- state->active = 0;
1731- }
1732- }
1733- if (!state->active) {
1734- int type = getype[move->ntouch];
1735- if (type <= 0)
1736- return 0;
1737- state->gid = gin_gid_begin(ge, type, -PRIO_GESTURE, frame);
1738- state->active = 1;
1739- }
1740- if (move->time - move->fm[FM_X].original_ms <= move->fm[FM_X].hold_ms)
1741- return 0;
1742- state->nprop = gin_add_contact_props(ge->gin, state->prop, frame);
1743- gru_event(ge, state->gid, move, state->prop, state->nprop);
1744- return 1;
1745-}
1746-
1747-int gru_wintouch(struct grail *ge,
1748- const struct utouch_frame *frame)
1749-{
1750- struct gesture_recognizer *gru = ge->gru;
1751- struct combo_model *state = &gru->wintouch;
1752- struct move_model *move = &gru->move;
1753- if (frame->slot_revision != frame->prev->slot_revision) {
1754- if (state->active && out_of_bounds(state, move)) {
1755- gru_end(ge, state->gid, move,
1756- state->prop, state->nprop);
1757- state->active = 0;
1758- }
1759- }
1760- if (!state->active) {
1761- if (move->ntouch == 4) {
1762- state->gid = gin_gid_begin(ge, GRAIL_TYPE_MTOUCH,
1763- -PRIO_META, frame);
1764- state->mintouch = 1;
1765- state->maxtouch = 4;
1766- state->active = 1;
1767- } else if (move->ntouch == 3) {
1768- state->gid = gin_gid_begin(ge, GRAIL_TYPE_ETOUCH,
1769- -PRIO_ENV, frame);
1770- state->mintouch = 1;
1771- state->maxtouch = 3;
1772- state->active = 1;
1773- } else {
1774- return 0;
1775- }
1776- }
1777- if (move->time - move->fm[FM_X].original_ms <= move->fm[FM_X].hold_ms)
1778- return 0;
1779- state->nprop = gin_add_contact_props(ge->gin, state->prop, frame);
1780- gru_event(ge, state->gid, move, state->prop, state->nprop);
1781- return 1;
1782-}
1783
1784=== removed file 'src/grail-api.c'
1785--- src/grail-api.c 2011-08-31 17:20:48 +0000
1786+++ src/grail-api.c 1970-01-01 00:00:00 +0000
1787@@ -1,328 +0,0 @@
1788-/*****************************************************************************
1789- *
1790- * grail - Gesture Recognition And Instantiation Library
1791- *
1792- * Copyright (C) 2010-2011 Canonical Ltd.
1793- *
1794- * This program is free software: you can redistribute it and/or modify it
1795- * under the terms of the GNU General Public License as published by the
1796- * Free Software Foundation, either version 3 of the License, or (at your
1797- * option) any later version.
1798- *
1799- * This program is distributed in the hope that it will be useful, but
1800- * WITHOUT ANY WARRANTY; without even the implied warranty of
1801- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1802- * General Public License for more details.
1803- *
1804- * You should have received a copy of the GNU General Public License along
1805- * with this program. If not, see <http://www.gnu.org/licenses/>.
1806- *
1807- ****************************************************************************/
1808-
1809-#include "grail-impl.h"
1810-#include "grail-inserter.h"
1811-#include "grail-recognizer.h"
1812-#include <string.h>
1813-#include <stdio.h>
1814-#include <unistd.h>
1815-#include <fcntl.h>
1816-#include <malloc.h>
1817-#include <errno.h>
1818-#include <stdlib.h>
1819-#include <sys/stat.h>
1820-
1821-#define DIM_FRAMES 100
1822-#define FRAME_RATE 100
1823-
1824-unsigned int GRAIL_PUBLIC grail_get_version(void)
1825-{
1826- return GRAIL_VERSION;
1827-}
1828-
1829-int GRAIL_PUBLIC grail_open(struct grail *ge, int fd)
1830-{
1831- struct grail_impl *x;
1832- struct stat fs;
1833- int ret;
1834-
1835- ret = fstat(fd, &fs);
1836- if (ret)
1837- return ret;
1838-
1839- x = calloc(1, sizeof(*x));
1840- if (!x)
1841- return -ENOMEM;
1842-
1843- if (!fs.st_rdev)
1844- x->fptest = fdopen(fd, "r");
1845-
1846- x->evemu = evemu_new(x->fptest ? "fptest" : 0);
1847- if (!x->evemu) {
1848- ret = -ENOMEM;
1849- goto freemem;
1850- }
1851- if (x->fptest)
1852- ret = evemu_read(x->evemu, x->fptest) <= 0;
1853- else
1854- ret = evemu_extract(x->evemu, fd);
1855- if (ret)
1856- goto freemem;
1857- if (!utouch_frame_is_supported_mtdev(x->evemu)) {
1858- ret = -ENODEV;
1859- goto freemem;
1860- }
1861-
1862- if (!x->fptest) {
1863- x->mtdev = mtdev_new_open(fd);
1864- if (!x->mtdev) {
1865- ret = -ENOMEM;
1866- goto freemem;
1867- }
1868- }
1869- x->fh = utouch_frame_new_engine(DIM_FRAMES, DIM_TOUCH, FRAME_RATE);
1870- if (!x->fh) {
1871- ret = -ENOMEM;
1872- goto freedev;
1873- }
1874- ret = utouch_frame_init_mtdev(x->fh, x->evemu);
1875- if (ret)
1876- goto freeframe;
1877-
1878- ge->impl = x;
1879-
1880- ret = gin_init(ge);
1881- if (ret)
1882- goto freeframe;
1883-
1884- ret = gru_init(ge);
1885- if (ret)
1886- goto freegin;
1887-
1888- return 0;
1889- freegin:
1890- gin_destroy(ge);
1891- freeframe:
1892- utouch_frame_delete_engine(x->fh);
1893- freedev:
1894- if (x->mtdev)
1895- mtdev_close_delete(x->mtdev);
1896- freemem:
1897- evemu_delete(x->evemu);
1898- if (x->fptest)
1899- fclose(x->fptest);
1900- free(x);
1901- ge->impl = 0;
1902- return ret;
1903-}
1904-
1905-void GRAIL_PUBLIC grail_close(struct grail *ge, int fd)
1906-{
1907- struct grail_impl *x = ge->impl;
1908- gru_destroy(ge);
1909- gin_destroy(ge);
1910- utouch_frame_delete_engine(x->fh);
1911- if (x->mtdev)
1912- mtdev_close_delete(x->mtdev);
1913- evemu_delete(x->evemu);
1914- if (x->fptest)
1915- fclose(x->fptest);
1916- free(x);
1917- ge->impl = 0;
1918-}
1919-
1920-int GRAIL_PUBLIC grail_idle(struct grail *ge, int fd, int ms)
1921-{
1922- struct grail_impl *x = ge->impl;
1923- if (x->fptest)
1924- return 0;
1925- if (x->mtdev)
1926- return mtdev_idle(x->mtdev, fd, ms);
1927- return 1;
1928-}
1929-
1930-void GRAIL_PUBLIC grail_get_units(const struct grail *ge,
1931- struct grail_coord *min, struct grail_coord *max)
1932-{
1933- struct utouch_surface *s = utouch_frame_get_surface(ge->impl->fh);
1934- min->x = s->min_x;
1935- min->y = s->min_y;
1936- max->x = s->max_x;
1937- max->y = s->max_y;
1938-}
1939-
1940-const struct utouch_frame GRAIL_PUBLIC *
1941-grail_get_contact_frame(const struct grail *ge)
1942-{
1943- return ge->impl->touch;
1944-}
1945-
1946-static void flush_events(struct grail *ge)
1947-{
1948- struct grail_impl *impl = ge->impl;
1949- struct input_event iev;
1950-
1951- grailbuf_clear(&impl->gbuf);
1952- while (!evbuf_empty(&impl->evbuf)) {
1953- evbuf_get(&impl->evbuf, &iev);
1954- if (ge->event)
1955- ge->event(ge, &iev);
1956- }
1957-}
1958-
1959-static int skip_event(const struct input_event *ev, int count)
1960-{
1961- switch (ev->type) {
1962- case EV_ABS:
1963- return 1;
1964- case EV_KEY:
1965- return ev->code >= BTN_DIGI && ev->code < BTN_WHEEL;
1966- case EV_SYN:
1967- switch (ev->code) {
1968- case SYN_MT_REPORT:
1969- return 1;
1970- case SYN_REPORT:
1971- return count == 0;
1972- default:
1973- return 0;
1974- }
1975- default:
1976- return 0;
1977- }
1978-}
1979-
1980-static void flush_gestures(struct grail *ge)
1981-{
1982- struct grail_impl *impl = ge->impl;
1983- struct input_event iev;
1984- struct grail_event gev;
1985- int count = 0;
1986-
1987- while (!evbuf_empty(&impl->evbuf)) {
1988- evbuf_get(&impl->evbuf, &iev);
1989- if (skip_event(&iev, count))
1990- continue;
1991- if (ge->event)
1992- ge->event(ge, &iev);
1993- if (iev.type == EV_SYN && iev.code == SYN_REPORT)
1994- count = 0;
1995- else
1996- count++;
1997- }
1998- while (!grailbuf_empty(&impl->gbuf)) {
1999- grailbuf_get(&impl->gbuf, &gev);
2000- if (ge->gesture)
2001- ge->gesture(ge, &gev);
2002- }
2003-}
2004-
2005-static int gesture_timeout(struct grail *ge, const struct utouch_frame *frame)
2006-{
2007- struct gesture_recognizer *gru = ge->gru;
2008- struct gesture_inserter *gin = ge->gin;
2009-
2010- return grail_mask_count(gin->used, sizeof(gin->used)) == 0 &&
2011- frame->time - frame->mod_time > gru->move.fm[FM_X].hold_ms;
2012-}
2013-
2014-static void report_frame(struct grail *ge,
2015- const struct utouch_frame *touch,
2016- const struct input_event *syn)
2017-{
2018- struct grail_impl *impl = ge->impl;
2019-
2020- impl->touch = touch;
2021-
2022- if (touch->num_active && !touch->prev->num_active) {
2023- impl->ongoing = 1;
2024- impl->gesture = 0;
2025- }
2026-
2027- if (!impl->ongoing)
2028- return;
2029-
2030- gin_frame_begin(ge, touch);
2031- gru_recognize(ge, touch);
2032- gin_frame_end(ge, touch);
2033-
2034- if (!grailbuf_empty(&impl->gbuf))
2035- impl->gesture = 1;
2036-
2037- if (touch->num_active == 0 || gesture_timeout(ge, touch))
2038- impl->ongoing &= impl->gesture;
2039-}
2040-
2041-static void grail_pump_mtdev(struct grail *ge, const struct input_event *ev)
2042-{
2043- struct grail_impl *impl = ge->impl;
2044- const struct utouch_frame *frame;
2045-
2046- evbuf_put(&impl->evbuf, ev);
2047-
2048- if (ev->type == EV_SYN || ev->type == EV_ABS || ev->type == EV_KEY) {
2049- frame = utouch_frame_pump_mtdev(impl->fh, ev);
2050- if (frame)
2051- report_frame(ge, frame, ev);
2052- }
2053-
2054- if (ev->type == EV_SYN) {
2055- if (!impl->ongoing)
2056- flush_events(ge);
2057- if (impl->gesture)
2058- flush_gestures(ge);
2059- }
2060-}
2061-
2062-/**
2063- * Read an event from the given file. If fast_fileread is true,
2064- * return immediately. If it is false, delay between events
2065- * so it looks like they are coming in real time.
2066- */
2067-static int grail_read_evemu_event(FILE *fp, struct input_event *ev,
2068- struct timeval *evtime, int fast_fileread) {
2069- if (fast_fileread)
2070- return evemu_read_event(fp, ev);
2071- return evemu_read_event_realtime(fp, ev, evtime);
2072-}
2073-
2074-
2075-static int grail_pull_fstest(struct grail *ge, int fd)
2076-{
2077- struct grail_impl *impl = ge->impl;
2078- struct input_event ev;
2079- struct timeval evtime;
2080- int count = 0;
2081-
2082- memset(&evtime, 0, sizeof(evtime));
2083- while (grail_read_evemu_event(impl->fptest, &ev, &evtime, impl->fast_fileread) > 0) {
2084- grail_pump_mtdev(ge, &ev);
2085- count++;
2086- }
2087-
2088- fclose(impl->fptest);
2089- impl->fptest = 0;
2090-
2091- return count > 0 ? count : -1;
2092-}
2093-
2094-int GRAIL_PUBLIC grail_pull(struct grail *ge, int fd)
2095-{
2096- struct grail_impl *impl = ge->impl;
2097- struct input_event ev;
2098- int ret, count = 0;
2099-
2100- if (impl->fptest)
2101- return grail_pull_fstest(ge, fd);
2102-
2103- while ((ret = mtdev_get(impl->mtdev, fd, &ev, 1)) > 0) {
2104- grail_pump_mtdev(ge, &ev);
2105- count++;
2106- }
2107-
2108- return count > 0 ? count : ret;
2109-}
2110-
2111-void GRAIL_PUBLIC grail_set_coordinate_transform_callback(struct grail *ge,
2112- utouch_coordinate_transform_cb callback,
2113- void *user_data) {
2114- utouch_frame_set_coordinate_transform_callback(ge->impl->fh, callback, user_data);
2115-}
2116
2117=== removed file 'src/grail-bits.c'
2118--- src/grail-bits.c 2011-04-28 16:53:57 +0000
2119+++ src/grail-bits.c 1970-01-01 00:00:00 +0000
2120@@ -1,93 +0,0 @@
2121-/*****************************************************************************
2122- *
2123- * grail - Gesture Recognition And Instantiation Library
2124- *
2125- * Copyright (C) 2010-2011 Canonical Ltd.
2126- *
2127- * This program is free software: you can redistribute it and/or modify it
2128- * under the terms of the GNU General Public License as published by the
2129- * Free Software Foundation, either version 3 of the License, or (at your
2130- * option) any later version.
2131- *
2132- * This program is distributed in the hope that it will be useful, but
2133- * WITHOUT ANY WARRANTY; without even the implied warranty of
2134- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2135- * General Public License for more details.
2136- *
2137- * You should have received a copy of the GNU General Public License along
2138- * with this program. If not, see <http://www.gnu.org/licenses/>.
2139- *
2140- ****************************************************************************/
2141-
2142-#include "grail-bits.h"
2143-
2144-static const int grail_bits_in_byte[256] =
2145-{
2146- 0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4,1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,
2147- 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
2148- 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
2149- 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
2150- 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
2151- 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
2152- 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
2153- 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,
2154-};
2155-
2156-static const int grail_first_set_bit[256] =
2157-{
2158- -1,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
2159- 5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
2160- 6,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
2161- 5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
2162- 7,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
2163- 5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
2164- 6,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
2165- 5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
2166-};
2167-
2168-void GRAIL_PUBLIC grail_mask_set_mask(grail_mask_t *a, const grail_mask_t *b,
2169- int bytes)
2170-{
2171- while (bytes--)
2172- *a++ |= *b++;
2173-}
2174-
2175-void GRAIL_PUBLIC grail_mask_clear_mask(grail_mask_t *a, const grail_mask_t *b,
2176- int bytes)
2177-{
2178- while (bytes--)
2179- *a++ &= ~*b++;
2180-}
2181-
2182-int GRAIL_PUBLIC grail_mask_count(const grail_mask_t *mask, int bytes)
2183-{
2184- int count = 0;
2185- while (bytes--)
2186- count += grail_bits_in_byte[*mask++];
2187- return count;
2188-}
2189-
2190-int GRAIL_PUBLIC grail_mask_get_first(const grail_mask_t *mask, int bytes)
2191-{
2192- int k;
2193- for (k = 0; k < bytes; k++)
2194- if (mask[k])
2195- return (k << 3) | grail_first_set_bit[mask[k]];
2196- return -1;
2197-}
2198-
2199-int GRAIL_PUBLIC grail_mask_get_next(int i, const grail_mask_t *mask, int bytes)
2200-{
2201- int k = ++i >> 3;
2202- if (k < bytes) {
2203- i = grail_first_set_bit[mask[k] & (~0 << (i & 7))];
2204- if (i >= 0)
2205- return (k << 3) | i;
2206- while (++k < bytes) {
2207- i = grail_first_set_bit[mask[k]];
2208- if (i >= 0)
2209- return (k << 3) | i;
2210- }
2211- }
2212- return -1;
2213-}
2214
2215=== removed file 'src/grail-event.c'
2216--- src/grail-event.c 2011-08-31 17:45:31 +0000
2217+++ src/grail-event.c 1970-01-01 00:00:00 +0000
2218@@ -1,118 +0,0 @@
2219-/*****************************************************************************
2220- *
2221- * grail - Gesture Recognition And Instantiation Library
2222- *
2223- * Copyright (C) 2010-2011 Canonical Ltd.
2224- *
2225- * This program is free software: you can redistribute it and/or modify it
2226- * under the terms of the GNU General Public License as published by the
2227- * Free Software Foundation, either version 3 of the License, or (at your
2228- * option) any later version.
2229- *
2230- * This program is distributed in the hope that it will be useful, but
2231- * WITHOUT ANY WARRANTY; without even the implied warranty of
2232- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2233- * General Public License for more details.
2234- *
2235- * You should have received a copy of the GNU General Public License along
2236- * with this program. If not, see <http://www.gnu.org/licenses/>.
2237- *
2238- ****************************************************************************/
2239-
2240-#include "grail-inserter.h"
2241-#include "grail-impl.h"
2242-#include <malloc.h>
2243-#include <string.h>
2244-#include <errno.h>
2245-#include <math.h>
2246-
2247-static void compute_bbox(struct grail_coord *min, struct grail_coord *max,
2248- const struct utouch_frame *frame)
2249-{
2250- float x, y;
2251- int i;
2252- if (frame->num_active < 1)
2253- return;
2254- x = frame->active[0]->x;
2255- y = frame->active[0]->y;
2256- min->x = max->x = x;
2257- min->y = max->y = y;
2258- for (i = 1; i < frame->num_active; i++) {
2259- x = frame->active[i]->x;
2260- y = frame->active[i]->y;
2261- if (x < min->x)
2262- min->x = x;
2263- if (y < min->y)
2264- min->y = y;
2265- if (x > max->x)
2266- max->x = x;
2267- if (y > max->y)
2268- max->y = y;
2269- }
2270-}
2271-
2272-int gin_add_contact_props(const struct gesture_inserter *gin,
2273- grail_prop_t *prop, const struct utouch_frame *frame)
2274-{
2275- struct grail_coord min = { 0, 0 };
2276- struct grail_coord max = { 0, 0 };
2277- int i, n = 0, ntouch = frame->num_active;
2278- if (!ntouch)
2279- return n;
2280- if (ntouch > 5)
2281- ntouch = 5;
2282- compute_bbox(&min, &max, frame);
2283- prop[n++] = min.x;
2284- prop[n++] = min.y;
2285- prop[n++] = max.x;
2286- prop[n++] = max.y;
2287- for (i = 0; i < ntouch; i++) {
2288- const struct utouch_contact *ct = frame->active[i];
2289- prop[n++] = ct->id;
2290- prop[n++] = ct->x;
2291- prop[n++] = ct->y;
2292- }
2293- return n;
2294-}
2295-
2296-int gin_get_clients(struct grail *ge,
2297- struct grail_client_info *info, int maxinfo,
2298- const grail_mask_t* types, int btypes,
2299- const grail_mask_t* span, int bspan,
2300- const struct utouch_frame *frame)
2301-{
2302- struct grail_coord pos[DIM_TOUCH];
2303- int i, npos = 0;
2304- if (!ge->get_clients)
2305- return 0;
2306- grail_mask_foreach(i, span, bspan) {
2307- pos[npos].x = frame->slots[i]->x;
2308- pos[npos].y = frame->slots[i]->y;
2309- npos++;
2310- }
2311- return ge->get_clients(ge, info, maxinfo, pos, npos, types, btypes);
2312-}
2313-
2314-void gin_send_event(struct grail *ge, struct slot_state *s,
2315- const struct gesture_event *ev,
2316- const struct utouch_frame *frame)
2317-{
2318- struct grail_impl *impl = ge->impl;
2319- struct grail_event gev;
2320- int i;
2321- if (!ge->gesture)
2322- return;
2323- gev.type = s->type;
2324- gev.id = s->id;
2325- gev.status = ev->status;
2326- gev.ntouch = ev->ntouch;
2327- gev.nprop = ev->nprop;
2328- gev.time = ev->time;
2329- gev.pos.x = ev->pos.x;
2330- gev.pos.y = ev->pos.y;
2331- memcpy(gev.prop, ev->prop, ev->nprop * sizeof(grail_prop_t));
2332- for (i = 0; i < s->nclient; i++) {
2333- gev.client_id = s->client_id[i];
2334- grailbuf_put(&impl->gbuf, &gev);
2335- }
2336-}
2337
2338=== removed file 'src/grail-frame.c'
2339--- src/grail-frame.c 2011-08-31 17:20:48 +0000
2340+++ src/grail-frame.c 1970-01-01 00:00:00 +0000
2341@@ -1,410 +0,0 @@
2342-/*****************************************************************************
2343- *
2344- * grail - Gesture Recognition And Instantiation Library
2345- *
2346- * Copyright (C) 2010-2011 Canonical Ltd.
2347- *
2348- * This program is free software: you can redistribute it and/or modify it
2349- * under the terms of the GNU General Public License as published by the
2350- * Free Software Foundation, either version 3 of the License, or (at your
2351- * option) any later version.
2352- *
2353- * This program is distributed in the hope that it will be useful, but
2354- * WITHOUT ANY WARRANTY; without even the implied warranty of
2355- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2356- * General Public License for more details.
2357- *
2358- * You should have received a copy of the GNU General Public License along
2359- * with this program. If not, see <http://www.gnu.org/licenses/>.
2360- *
2361- ****************************************************************************/
2362-
2363-#include "grail-impl.h"
2364-#include <stdlib.h>
2365-#include <string.h>
2366-#include <math.h>
2367-
2368-static void set_center_velocity_and_radius(struct grail_impl *impl,
2369- struct grail_element *slot)
2370-{
2371- const struct utouch_contact **tc = slot->touches;
2372- double x, y, vx, vy, r2, dx, dy;
2373- int i;
2374-
2375- switch (slot->num_touches) {
2376- case 1:
2377- x = tc[0]->x;
2378- y = tc[0]->y;
2379- vx = tc[0]->vx;
2380- vy = tc[0]->vy;
2381- r2 = 0;
2382- break;
2383- case 2:
2384- dx = 0.5 * (tc[1]->x - tc[0]->x);
2385- dy = 0.5 * (tc[1]->y - tc[0]->y);
2386- x = tc[0]->x + dx;
2387- y = tc[0]->y + dy;
2388- vx = 0.5 * (tc[0]->vx + tc[1]->vx);
2389- vy = 0.5 * (tc[0]->vy + tc[1]->vy);
2390- r2 = dx * dx + dy * dy;
2391- break;
2392- default:
2393- x = y = vx = vy = r2 = 0;
2394- for (i = 0; i < slot->num_touches; i++) {
2395- x += tc[i]->x;
2396- y += tc[i]->y;
2397- vx += tc[i]->vx;
2398- vy += tc[i]->vy;
2399- }
2400- x /= slot->num_touches;
2401- y /= slot->num_touches;
2402- vx /= slot->num_touches;
2403- vy /= slot->num_touches;
2404- for (i = 0; i < slot->num_touches; i++) {
2405- dx = tc[i]->x - x;
2406- dy = tc[i]->y - y;
2407- r2 += dx * dx + dy * dy;
2408- }
2409- r2 /= slot->num_touches;
2410- break;
2411- }
2412-
2413- slot->center.x = x;
2414- slot->center.y = y;
2415- slot->velocity.x = 1000 * vx;
2416- slot->velocity.y = 1000 * vy;
2417- slot->radius2 = r2;
2418-}
2419-
2420-static void set_transform(struct grail_impl *impl, struct grail_element *slot,
2421- double ds, double dc)
2422-{
2423- const struct grail_element *pslot = slot->prev;
2424- double dx = slot->center.x - pslot->center.x;
2425- double dy = slot->center.y - pslot->center.y;
2426- float *T = slot->transform;
2427-
2428- T[0] = dc;
2429- T[1] = ds;
2430- T[2] = dx;
2431- T[3] = -ds;
2432- T[4] = dc;
2433- T[5] = dy;
2434-
2435- slot->drag.x = pslot->drag.x + dx;
2436- slot->drag.y = pslot->drag.y + dy;
2437-}
2438-
2439-static void start_slot(struct grail_impl *impl,
2440- struct grail_element *slot,
2441- const struct utouch_frame *touch)
2442-{
2443- float *T = slot->transform;
2444-
2445- slot->id = impl->seqid++ & GRAIL_ID_MAX;
2446- slot->expect_mask = GRAIL_EXPECT_MASK;
2447- slot->active_mask = 0;
2448- slot->start_time = touch->time;
2449- set_center_velocity_and_radius(impl, slot);
2450- T[0] = T[4] = 1;
2451- T[1] = T[2] = T[3] = T[5] = 0;
2452- slot->drag.x = 0;
2453- slot->drag.y = 0;
2454- slot->scale2 = 1;
2455- slot->angle = 0;
2456-}
2457-
2458-static void update_slot(struct grail_impl *impl,
2459- struct grail_element *slot,
2460- double ds, double dc)
2461-{
2462- const struct grail_element *pslot = slot->prev;
2463-
2464- slot->id = pslot->id;
2465- slot->start_time = pslot->start_time;
2466- slot->expect_mask = pslot->expect_mask;
2467- slot->active_mask = pslot->active_mask;
2468-
2469- set_center_velocity_and_radius(impl, slot);
2470- set_transform(impl, slot, ds, dc);
2471-
2472- slot->scale2 = pslot->scale2 * (ds * ds + dc * dc);
2473- slot->angle = pslot->angle + ds / dc; /* atan2(ds, dc) */
2474-}
2475-
2476-static void stop_slot(struct grail_impl *impl,
2477- struct grail_element *slot)
2478-{
2479- const struct grail_element *pslot = slot->prev;
2480- float *T = slot->transform;
2481-
2482- slot->id = -1;
2483- slot->num_touches = 0;
2484- slot->start_time = pslot->start_time;
2485- slot->expect_mask = 0;
2486- slot->active_mask = pslot->active_mask;
2487- slot->center = pslot->center;
2488- slot->velocity = pslot->velocity;
2489- slot->radius2 = pslot->radius2;
2490- T[0] = T[4] = 1;
2491- T[1] = T[2] = T[3] = T[5] = 0;
2492- slot->drag = pslot->drag;
2493- slot->scale2 = pslot->scale2;
2494- slot->angle = pslot->angle;
2495-}
2496-
2497-static void set_slot_one(struct grail_impl *impl,
2498- struct grail_element *slot,
2499- const struct utouch_frame *touch,
2500- const struct utouch_contact *t1)
2501-{
2502- const struct grail_element *pslot = slot->prev;
2503- const struct utouch_contact *p1 = pslot->touches[0];
2504-
2505- if (!t1->active) {
2506- stop_slot(impl, slot);
2507- return;
2508- }
2509-
2510- slot->touches[0] = t1;
2511- slot->num_touches = 1;
2512-
2513- if (pslot->num_touches != slot->num_touches || t1->id != p1->id) {
2514- start_slot(impl, slot, touch);
2515- return;
2516- }
2517-
2518- update_slot(impl, slot, 0, 1);
2519-}
2520-
2521-static void set_slot_two(struct grail_impl *impl,
2522- struct grail_element *slot,
2523- const struct utouch_frame *touch,
2524- const struct utouch_contact *t1,
2525- const struct utouch_contact *t2)
2526-{
2527- const struct grail_element *pslot = slot->prev;
2528- const struct utouch_contact *p1 = pslot->touches[0];
2529- const struct utouch_contact *p2 = pslot->touches[1];
2530- double tx, ty, px, py, d2;
2531-
2532- if (!t1->active || !t2->active) {
2533- stop_slot(impl, slot);
2534- return;
2535- }
2536-
2537- slot->touches[0] = t1;
2538- slot->touches[1] = t2;
2539- slot->num_touches = 2;
2540-
2541- if (pslot->num_touches != slot->num_touches ||
2542- t1->id != p1->id || t2->id != p2->id) {
2543- start_slot(impl, slot, touch);
2544- return;
2545- }
2546-
2547- tx = t2->x - t1->x;
2548- ty = t2->y - t1->y;
2549- px = p2->x - p1->x;
2550- py = p2->y - p1->y;
2551-
2552- d2 = px * px + py * py;
2553- if (d2 > 0) {
2554- px /= d2;
2555- py /= d2;
2556- }
2557-
2558- update_slot(impl, slot, tx * py - ty * px, tx * px + ty * py);
2559-}
2560-
2561-static void set_slot_multi(struct grail_impl *impl,
2562- struct grail_element *slot,
2563- struct grail_frame *frame,
2564- const struct utouch_frame *touch)
2565-{
2566- const struct grail_element *pslot = slot->prev;
2567- struct grail_element **slots = frame->slots;
2568- int i, j, n = impl->num_touches;
2569- struct grail_element *best = 0;
2570-
2571- if (touch->num_active < 3) {
2572- stop_slot(impl, slot);
2573- return;
2574- }
2575-
2576- memcpy(slot->touches, touch->active,
2577- touch->num_active * sizeof(slot->touches[0]));
2578- slot->num_touches = touch->num_active;
2579-
2580- if (pslot->num_touches != slot->num_touches) {
2581- start_slot(impl, slot, touch);
2582- return;
2583- }
2584-
2585- for (i = 0; i < slot->num_touches; i++) {
2586- if (slot->touches[i]->id != pslot->touches[i]->id) {
2587- start_slot(impl, slot, touch);
2588- return;
2589- }
2590- }
2591-
2592- for (i = 0; i < impl->num_touches; i++) {
2593- for (j = i + 1; j < impl->num_touches; j++) {
2594- struct grail_element *s = slots[n++];
2595- if (!s->num_touches)
2596- continue;
2597- if (!best || s->radius2 > best->radius2)
2598- best = s;
2599- }
2600- }
2601-
2602- update_slot(impl, slot, best->transform[1], best->transform[0]);
2603-}
2604-
2605-/**
2606- * Determine the center of rotation point.
2607- *
2608- * For any given point q that is transformed by a 2D affine transformation
2609- * matrix T about anchor point P the new point q' may be determined by the
2610- * following equation:
2611- *
2612- * q' = T * (q - P) + P
2613- *
2614- * T and P are dependent, so we can modify one and find a new value for the
2615- * other. We will label the original T and P as T0 and P0, and the new values
2616- * will be labeled T1 and P1. We can find new values by solving the following
2617- * equation:
2618- *
2619- * q' = T0 * (q - P0) + P0 = T1 * (q - P1) + P1
2620- *
2621- * In the calculations below, we use variables for the scalar values
2622- * that make up T0, P0, T1, and P1:
2623- *
2624- * T0: [ a -b c ] P0: [ x0 ] T1: [ a -b 0 ] P1: [ x1 ]
2625- * [ b a d ] [ y0 ] [ b a 0 ] [ y1 ]
2626- * [ 0 0 1 ] [ 0 ] [ 0 0 1 ] [ 0 ]
2627- *
2628- * Note that rotation and scaling are independent of the anchor point, so a and
2629- * b are equivalent between the transformation matrices.
2630- *
2631- * Since we know all the values of T0, P0, and T1, we can calculate the values
2632- * x1 and y1 in P1.
2633- */
2634-static inline int set_center_of_rotation(struct grail_element *e)
2635-{
2636- float a = e->transform[0];
2637- float b = e->transform[3];
2638- float c = e->transform[2];
2639- float d = e->transform[5];
2640- float x0 = e->center.x;
2641- float y0 = e->center.y;
2642- float x1;
2643- float y1;
2644-
2645- float div = a*a - 2*a + b*b + 1;
2646-
2647- if (fabsf(div) < 1e-5)
2648- return 0;
2649-
2650- x1 = (a*a*x0 - a*(2*x0+c) + b*b*x0 - b*d + c + x0) / div;
2651- y1 = (a*a*y0 - a*(2*y0+d) + b*b*y0 + b*c + d + y0) / div;
2652-
2653- e->rotation_center.x = x1;
2654- e->rotation_center.y = y1;
2655-
2656- return 1;
2657-}
2658-
2659-static void set_slots(struct grail_impl *impl,
2660- struct grail_frame *frame,
2661- const struct utouch_frame *touch)
2662-{
2663- struct grail_element **slots = frame->slots;
2664- struct utouch_contact *const *tc = touch->slots;
2665- int i, j, n = 0;
2666-
2667- for (i = 0; i < impl->num_touches; i++)
2668- set_slot_one(impl, slots[n++], touch, tc[i]);
2669-
2670- for (i = 0; i < impl->num_touches; i++)
2671- for (j = i + 1; j < impl->num_touches; j++)
2672- set_slot_two(impl, slots[n++], touch, tc[i], tc[j]);
2673-
2674- set_slot_multi(impl, slots[n++], frame, touch);
2675-}
2676-
2677-static void collect_transforms(struct grail_impl *impl,
2678- struct grail_frame *frame,
2679- const struct utouch_frame *touch)
2680-{
2681- const struct utouch_surface *s = utouch_frame_get_surface(impl->fh);
2682- const struct grail_control *ctl = impl->ctl;
2683- float d_x = ctl->bar_drag_x * (s->mapped_max_x - s->mapped_min_x);
2684- float d_y = ctl->bar_drag_y * (s->mapped_max_y - s->mapped_min_y);
2685- float ds2 = ctl->bar_scale * ctl->bar_scale;
2686- float dt;
2687- int i;
2688-
2689- for (i = 0; i < impl->num_slots; i++) {
2690- struct grail_element *s = frame->slots[i];
2691-
2692- if (!s->num_touches)
2693- continue;
2694-
2695- set_center_of_rotation(s);
2696-
2697- dt = touch->time - s->start_time;
2698- if (dt > ctl->glue_ms) {
2699- unsigned int mask = s->active_mask;
2700-
2701- if (fabs(s->drag.x) > d_x)
2702- mask |= GRAIL_EXPECT_DRAG_X;
2703- if (fabs(s->drag.y) > d_y)
2704- mask |= GRAIL_EXPECT_DRAG_Y;
2705- if (fabs(s->scale2 - 1) > ds2)
2706- mask |= GRAIL_EXPECT_SCALE;
2707- if (fabs(s->angle) > ctl->bar_angle)
2708- mask |= GRAIL_EXPECT_ANGLE;
2709-
2710- s->active_mask = mask;
2711-
2712- if (dt < ctl->drop_x_ms)
2713- mask |= GRAIL_EXPECT_DRAG_X;
2714- if (dt < ctl->drop_y_ms)
2715- mask |= GRAIL_EXPECT_DRAG_Y;
2716- if (dt < ctl->drop_scale_ms)
2717- mask |= GRAIL_EXPECT_SCALE;
2718- if (dt < ctl->drop_angle_ms)
2719- mask |= GRAIL_EXPECT_ANGLE;
2720-
2721- s->expect_mask &= mask;
2722- }
2723-
2724- frame->ongoing[frame->num_ongoing++] = s;
2725- }
2726-}
2727-
2728-const struct grail_frame GRAIL_PUBLIC *
2729-grail_pump_frame(grail_handle ge, const struct utouch_frame *touch)
2730-{
2731- struct grail_impl *impl = ge->impl;
2732- struct grail_frame *frame = impl->frames[impl->nextframe];
2733- const struct grail_frame *prev = frame->prev;
2734- int i;
2735-
2736- if (touch->slot_revision == touch->prev->slot_revision &&
2737- !prev->num_ongoing)
2738- return 0;
2739-
2740- frame->touch = touch;
2741- frame->num_ongoing = 0;
2742- for (i = 0; i < impl->num_slots; i++)
2743- frame->slots[i]->prev = prev->slots[i];
2744-
2745- set_slots(impl, frame, touch);
2746- collect_transforms(impl, frame, touch);
2747-
2748- impl->nextframe = (impl->nextframe + 1) % impl->num_frames;
2749-
2750- return frame;
2751-}
2752
2753=== removed file 'src/grail-gestures.c'
2754--- src/grail-gestures.c 2011-10-03 11:14:32 +0000
2755+++ src/grail-gestures.c 1970-01-01 00:00:00 +0000
2756@@ -1,219 +0,0 @@
2757-/*****************************************************************************
2758- *
2759- * grail - Gesture Recognition And Instantiation Library
2760- *
2761- * Copyright (C) 2010-2011 Canonical Ltd.
2762- *
2763- * This program is free software: you can redistribute it and/or modify it
2764- * under the terms of the GNU General Public License as published by the
2765- * Free Software Foundation, either version 3 of the License, or (at your
2766- * option) any later version.
2767- *
2768- * This program is distributed in the hope that it will be useful, but
2769- * WITHOUT ANY WARRANTY; without even the implied warranty of
2770- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2771- * General Public License for more details.
2772- *
2773- * You should have received a copy of the GNU General Public License along
2774- * with this program. If not, see <http://www.gnu.org/licenses/>.
2775- *
2776- ****************************************************************************/
2777-
2778-#include "grail-recognizer.h"
2779-#include "grail-impl.h"
2780-#include <math.h>
2781-
2782-/* Units of mm or radians */
2783-static const float FM_SN[DIM_FM] = { 0.13, 0.13, 0.26, 2 * M_PI / 1000 };
2784-static const float FM_BAR[DIM_FM] = { 2.6, 2.6, 5.2, 2 * M_PI / 50 };
2785-
2786-/* Units of ms */
2787-static const grail_time_t FM_HOLD_MS[DIM_FM] = { 60, 60, 60, 60 };
2788-static const grail_time_t FM_BAR_MS[DIM_FM] = { 300, 300, 500, 500 };
2789-static const grail_time_t SAMPLE_MS = 10;
2790-
2791-static const float EPS = 1e-3;
2792-
2793-static void compute_position(float *x, float *y,
2794- const struct utouch_frame *frame)
2795-{
2796- int i, n = frame->num_active;
2797- *x = 0;
2798- *y = 0;
2799- if (n < 1)
2800- return;
2801- for (i = 0; i < n; i++) {
2802- const struct utouch_contact *t = frame->active[i];
2803- *x += t->x;
2804- *y += t->y;
2805- }
2806- *x /= n;
2807- *y /= n;
2808-}
2809-
2810-static float compute_radius(float x, float y,
2811- const struct utouch_frame *frame)
2812-{
2813- int i, n = frame->num_active;
2814- float r = 0, r2 = 0;
2815- if (n < 2)
2816- return r;
2817- for (i = 0; i < n; i++) {
2818- const struct utouch_contact *t = frame->active[i];
2819- float dx = t->x - x;
2820- float dy = t->y - y;
2821- r2 += dx * dx + dy * dy;
2822- }
2823- r2 /= n;
2824- r = sqrt(r2);
2825- return r;
2826-}
2827-
2828-static float compute_rotation(float x, float y, float r,
2829- const struct utouch_frame *frame)
2830-{
2831- int i, n = frame->num_active;
2832- float da = 0, darc2 = 0;
2833- if (n < 2)
2834- return da;
2835- for (i = 0; i < n; i++) {
2836- const struct utouch_contact *t = frame->active[i];
2837- const struct utouch_contact *ot = t->prev;
2838- float dx = t->x - x;
2839- float dy = t->y - y;
2840- float mx = t->x - ot->x;
2841- float my = t->y - ot->y;
2842- darc2 += dx * my - dy * mx;
2843- }
2844- darc2 /= n;
2845- da = darc2 / (r * r);
2846- return da;
2847-}
2848-
2849-static void move_reset(struct move_model *m, int i, float x, grail_time_t t)
2850-{
2851- struct filter_model *fm = &m->fm[i];
2852- fm->raw_delta = 0;
2853- fm->action_delta = 0;
2854- fm->velocity = 0;
2855- fm->value = x;
2856- fm->original = x;
2857- fm->original_ms = t;
2858- fm->sample = x;
2859- fm->sample_ms = t;
2860- m->tickle &= ~(1 << i);
2861- m->active &= ~(1 << i);
2862- m->timeout &= ~(1 << i);
2863-}
2864-
2865-static void move_update(struct move_model *m, int i, float x, grail_time_t t)
2866-{
2867- struct filter_model *fm = &m->fm[i];
2868- float dt = t - fm->sample_ms;
2869- fm->raw_delta = x - fm->value;
2870- fm->action_delta = fm->raw_delta;
2871- fm->value = x;
2872- if (dt > SAMPLE_MS) {
2873- fm->velocity = (x - fm->sample) / dt;
2874- fm->sample = x;
2875- fm->sample_ms = t;
2876- }
2877- if (fabs(fm->raw_delta) > EPS)
2878- m->tickle |= (1 << i);
2879- else
2880- m->tickle &= ~(1 << i);
2881- if (m->active & (1 << i))
2882- return;
2883- fm->action_delta = 0;
2884- if (fabs(x - fm->original) > fm->bar) {
2885- if (t - fm->original_ms > fm->hold_ms) {
2886- m->active |= (1 << i);
2887- fm->action_delta = x - fm->original;
2888- }
2889- } else if (t - fm->original_ms > fm->bar_ms) {
2890- m->timeout |= (1 << i);
2891- }
2892-}
2893-
2894-void gru_init_motion(struct grail *ge)
2895-{
2896- struct utouch_surface *s = utouch_frame_get_surface(ge->impl->fh);
2897- struct gesture_recognizer *gru = ge->gru;
2898- struct move_model *m = &gru->move;
2899- float U[DIM_FM]; /* Device unit dimensions */
2900- float P[DIM_FM]; /* Device physical dimensions */
2901- int i;
2902- U[FM_X] = s->mapped_max_x - s->mapped_min_x;
2903- U[FM_Y] = s->mapped_max_y - s->mapped_min_y;
2904- U[FM_R] = sqrt(U[FM_X] * U[FM_X] + U[FM_Y] * U[FM_Y]);
2905- U[FM_A] = 2 * M_PI;
2906- P[FM_X] = s->phys_width;
2907- P[FM_Y] = s->phys_height;
2908- P[FM_R] = sqrt(P[FM_X] * P[FM_X] + P[FM_Y] * P[FM_Y]);
2909- P[FM_A] = 2 * M_PI;
2910- for (i = 0; i < DIM_FM; i++) {
2911- m->fm[i].fuzz = U[i] * FM_SN[i] / P[i];
2912- m->fm[i].bar = U[i] * FM_BAR[i] / P[i];
2913- m->fm[i].hold_ms = FM_HOLD_MS[i];
2914- m->fm[i].bar_ms = FM_BAR_MS[i];
2915- }
2916-}
2917-
2918-void gru_motion(struct grail *ge,
2919- const struct utouch_frame *frame)
2920-{
2921- const struct utouch_surface *s = utouch_frame_get_surface(ge->impl->fh);
2922- struct gesture_recognizer *gru = ge->gru;
2923- struct move_model *m = &gru->move;
2924- grail_time_t t = frame->time;
2925- float x, y, r, a;
2926-
2927- compute_position(&x, &y, frame);
2928- if (frame->prev->revision != frame->revision) {
2929- r = compute_radius(x, y, frame);
2930- a = 0;
2931- move_reset(m, FM_X, x, t);
2932- move_reset(m, FM_Y, y, t);
2933- move_reset(m, FM_R, r, t);
2934- move_reset(m, FM_A, a, t);
2935- m->single = 0;
2936- m->multi = 0;
2937- } else if (frame->num_active < 2) {
2938- r = 0;
2939- a = 0;
2940- move_update(m, FM_X, x, t);
2941- move_update(m, FM_Y, y, t);
2942- move_reset(m, FM_R, r, t);
2943- move_reset(m, FM_A, a, t);
2944- m->single = 1;
2945- m->multi = 0;
2946- } else {
2947- r = compute_radius(x, y, frame);
2948- a = m->fm[FM_A].value;
2949- if (!s->is_semi_mt)
2950- a += compute_rotation(x, y, r, frame);
2951- move_update(m, FM_X, x, t);
2952- move_update(m, FM_Y, y, t);
2953- move_update(m, FM_R, r, t);
2954- move_update(m, FM_A, a, t);
2955- m->single = 0;
2956- m->multi = 1;
2957- }
2958- m->ntouch = frame->num_active;
2959- m->time = t;
2960-}
2961-
2962-void gru_event(struct grail *ge, int gid,
2963- const struct move_model *m,
2964- const grail_prop_t *prop, int nprop)
2965-{
2966- gin_gid_event(ge, gid, m->fm[FM_X].value, m->fm[FM_Y].value, m->ntouch,
2967- prop, nprop, 0);
2968-}
2969-
2970-void gru_end(struct grail *ge, int gid, const struct move_model *m,
2971- const grail_prop_t *prop, int nprop)
2972-{
2973- gin_gid_end(ge, gid, m->fm[FM_X].value, m->fm[FM_Y].value, m->ntouch,
2974- prop, nprop);
2975-}
2976
2977=== removed file 'src/grail-gestures.h'
2978--- src/grail-gestures.h 2011-05-17 14:15:22 +0000
2979+++ src/grail-gestures.h 1970-01-01 00:00:00 +0000
2980@@ -1,115 +0,0 @@
2981-/*****************************************************************************
2982- *
2983- * grail - Gesture Recognition And Instantiation Library
2984- *
2985- * Copyright (C) 2010-2011 Canonical Ltd.
2986- *
2987- * This program is free software: you can redistribute it and/or modify it
2988- * under the terms of the GNU General Public License as published by the
2989- * Free Software Foundation, either version 3 of the License, or (at your
2990- * option) any later version.
2991- *
2992- * This program is distributed in the hope that it will be useful, but
2993- * WITHOUT ANY WARRANTY; without even the implied warranty of
2994- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2995- * General Public License for more details.
2996- *
2997- * You should have received a copy of the GNU General Public License along
2998- * with this program. If not, see <http://www.gnu.org/licenses/>.
2999- *
3000- ****************************************************************************/
3001-
3002-#ifndef GRAIL_GESTURES_H
3003-#define GRAIL_GESTURES_H
3004-
3005-#include "grail-inserter.h"
3006-
3007-#define PRIO_POINTER 1
3008-#define PRIO_GESTURE 2
3009-#define PRIO_ENV 3
3010-#define PRIO_META 4
3011-#define PRIO_TAP 5
3012-
3013-#define DIM_FM 4
3014-
3015-#define FM_X 0
3016-#define FM_Y 1
3017-#define FM_R 2
3018-#define FM_A 3
3019-
3020-struct filter_model {
3021- float raw_delta;
3022- float action_delta;
3023- float velocity;
3024- float value;
3025- float original;
3026- float sample;
3027- float fuzz;
3028- float bar;
3029- grail_time_t original_ms;
3030- grail_time_t sample_ms;
3031- grail_time_t hold_ms;
3032- grail_time_t bar_ms;
3033-};
3034-
3035-struct move_model {
3036- struct filter_model fm[DIM_FM];
3037- int tickle, active, timeout;
3038- int single, multi, ntouch;
3039- grail_time_t time;
3040-};
3041-
3042-void gru_init_motion(struct grail *ge);
3043-void gru_motion(struct grail *ge,
3044- const struct utouch_frame *frame);
3045-void gru_event(struct grail *ge, int gid,
3046- const struct move_model *move,
3047- const grail_prop_t *prop, int nprop);
3048-void gru_end(struct grail *ge, int gid,
3049- const struct move_model *move,
3050- const grail_prop_t *prop, int nprop);
3051-
3052-struct combo_model {
3053- int active, gid;
3054- int mintouch, maxtouch;
3055- int nprop;
3056- grail_prop_t prop[DIM_GRAIL_PROP];
3057-};
3058-
3059-int gru_touch(struct grail *ge,
3060- const struct utouch_frame *frame);
3061-int gru_drag(struct grail *ge,
3062- const struct utouch_frame *frame);
3063-int gru_pinch(struct grail *ge,
3064- const struct utouch_frame *frame);
3065-int gru_rotate(struct grail *ge,
3066- const struct utouch_frame *frame);
3067-
3068-static inline int out_of_bounds(const struct combo_model *s,
3069- const struct move_model *m)
3070-{
3071- return m->ntouch < s->mintouch || m->ntouch > s->maxtouch;
3072-}
3073-
3074-int gru_wintouch(struct grail *ge,
3075- const struct utouch_frame *frame);
3076-int gru_windrag(struct grail *ge,
3077- const struct utouch_frame *frame);
3078-int gru_winpinch(struct grail *ge,
3079- const struct utouch_frame *frame);
3080-int gru_winrotate(struct grail *ge,
3081- const struct utouch_frame *frame);
3082-
3083-struct tapping_model {
3084- grail_time_t start;
3085- int mintouch, maxtouch;
3086- int active, gid, tap;
3087- int nprop;
3088- grail_prop_t prop[DIM_GRAIL_PROP];
3089-};
3090-
3091-int gru_tapping(struct grail *ge,
3092- const struct utouch_frame *frame);
3093-
3094-#endif
3095-
3096
3097=== removed file 'src/grail-impl.h'
3098--- src/grail-impl.h 2011-08-30 15:10:16 +0000
3099+++ src/grail-impl.h 1970-01-01 00:00:00 +0000
3100@@ -1,88 +0,0 @@
3101-/*****************************************************************************
3102- *
3103- * grail - Gesture Recognition And Instantiation Library
3104- *
3105- * Copyright (C) 2010-2011 Canonical Ltd.
3106- *
3107- * This program is free software: you can redistribute it and/or modify it
3108- * under the terms of the GNU General Public License as published by the
3109- * Free Software Foundation, either version 3 of the License, or (at your
3110- * option) any later version.
3111- *
3112- * This program is distributed in the hope that it will be useful, but
3113- * WITHOUT ANY WARRANTY; without even the implied warranty of
3114- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
3115- * General Public License for more details.
3116- *
3117- * You should have received a copy of the GNU General Public License along
3118- * with this program. If not, see <http://www.gnu.org/licenses/>.
3119- *
3120- ****************************************************************************/
3121-
3122-#ifndef GRAIL_IMPL_H
3123-#define GRAIL_IMPL_H
3124-
3125-#define MTDEV_NO_LEGACY_API
3126-#define GRAIL_NO_LEGACY_API
3127-
3128-#include <grail.h>
3129-#include <utouch/frame-mtdev.h>
3130-#include "evbuf.h"
3131-#include "grailbuf.h"
3132-
3133-#define DIM_TOUCH 32
3134-#define DIM_TOUCH_BYTES ((DIM_TOUCH + 7) >> 3)
3135-#define GRAIL_ID_MAX 0xffff
3136-
3137-#define MIN(a, b) ((a) < (b) ? (a) : (b))
3138-#define MAX(a, b) ((a) > (b) ? (a) : (b))
3139-
3140-typedef void *grail_select_callback;
3141-
3142-/*
3143- * In this implementation, there can be N one-gestures, N (N - 1) / 2
3144- * two-gestures, and one global gesture.
3145- */
3146-static inline int get_slot_count(int n)
3147-{
3148- return n + n * (n - 1) / 2 + 1;
3149-}
3150-
3151-int create_grail2(struct grail_impl *x,
3152- utouch_frame_handle fh,
3153- unsigned int num_frames,
3154- void *select,
3155- unsigned int version,
3156- unsigned int control_size,
3157- unsigned int frame_size,
3158- unsigned int slot_size);
3159-
3160-void destroy_grail2(struct grail_impl *x);
3161-
3162-struct grail_impl {
3163- struct evemu_device *evemu;
3164- struct mtdev *mtdev;
3165- utouch_frame_handle fh;
3166- const struct utouch_frame *touch;
3167- struct evbuf evbuf;
3168- struct grailbuf gbuf;
3169- int filter_abs;
3170- int ongoing;
3171- int gesture;
3172- FILE *fptest;
3173- int fast_fileread;
3174- /* new stuff below */
3175- struct grail_control *ctl;
3176- grail_select_callback select;
3177- int num_frames;
3178- int num_slots;
3179- int num_touches;
3180- int nextframe;
3181- int seqid;
3182- unsigned int control_size;
3183- unsigned int frame_size;
3184- unsigned int slot_size;
3185- struct grail_frame **frames;
3186-};
3187-
3188-#endif
3189
3190=== removed file 'src/grail-init.c'
3191--- src/grail-init.c 2011-08-31 17:20:48 +0000
3192+++ src/grail-init.c 1970-01-01 00:00:00 +0000
3193@@ -1,236 +0,0 @@
3194-/*****************************************************************************
3195- *
3196- * grail - Gesture Recognition And Instantiation Library
3197- *
3198- * Copyright (C) 2010-2011 Canonical Ltd.
3199- *
3200- * This program is free software: you can redistribute it and/or modify it
3201- * under the terms of the GNU General Public License as published by the
3202- * Free Software Foundation, either version 3 of the License, or (at your
3203- * option) any later version.
3204- *
3205- * This program is distributed in the hope that it will be useful, but
3206- * WITHOUT ANY WARRANTY; without even the implied warranty of
3207- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
3208- * General Public License for more details.
3209- *
3210- * You should have received a copy of the GNU General Public License along
3211- * with this program. If not, see <http://www.gnu.org/licenses/>.
3212- *
3213- ****************************************************************************/
3214-
3215-#include "grail-impl.h"
3216-#include <stdlib.h>
3217-#include <string.h>
3218-#include <math.h>
3219-
3220-static struct grail_control *create_control(int size)
3221-{
3222- struct grail_control *c = calloc(1, size);
3223-
3224- if (!c)
3225- return 0;
3226-
3227- c->glue_ms = 60;
3228- c->bar_drag_x = 0.03;
3229- c->bar_drag_y = 0.03;
3230- c->bar_scale = 0.3;
3231- c->bar_angle = 0.1;
3232- c->drop_x_ms = 300;
3233- c->drop_y_ms = 300;
3234- c->drop_scale_ms = 300;
3235- c->drop_angle_ms = 300;
3236-
3237- return c;
3238-}
3239-
3240-static void destroy_slots(struct grail_element **slots, int nslot)
3241-{
3242- int i;
3243-
3244- if (slots) {
3245- for (i = nslot - 1; i >= 0; i--)
3246- free(slots[i]);
3247- free(slots);
3248- }
3249-}
3250-
3251-static void destroy_frame(struct grail_frame *frame, int nslot)
3252-{
3253- if (frame) {
3254- destroy_slots(frame->slots, nslot);
3255- free(frame->ongoing);
3256- free(frame);
3257- }
3258-}
3259-
3260-static void destroy_frames(struct grail_frame **frames, int nframe, int nslot)
3261-{
3262- int i;
3263-
3264- if (frames) {
3265- for (i = nframe - 1; i >= 0; i--)
3266- destroy_frame(frames[i], nslot);
3267- free(frames);
3268- }
3269-}
3270-
3271-static struct grail_element **create_slots(int nslot, int ntouch, int size)
3272-{
3273- struct grail_element **slots;
3274- struct grail_element *s;
3275- int i;
3276-
3277- slots = calloc(nslot, sizeof(slots[0]));
3278- if (!slots)
3279- return 0;
3280-
3281- for (i = 0; i < nslot; i++) {
3282- s = calloc(1, size + ntouch * sizeof(void *));
3283- if (!s)
3284- goto out;
3285- s->slot = i;
3286- s->id = -1;
3287- s->touches = (void *)((char *)s + size);
3288- slots[i] = s;
3289- }
3290-
3291- return slots;
3292- out:
3293- destroy_slots(slots, nslot);
3294- return 0;
3295-}
3296-
3297-static struct grail_frame *create_frame(int nslot, int ntouch,
3298- int frame_size, int slot_size)
3299-{
3300- struct grail_frame *frame;
3301-
3302- frame = calloc(1, frame_size);
3303- if (!frame)
3304- return 0;
3305-
3306- frame->ongoing = calloc(nslot, sizeof(frame->ongoing[0]));
3307- frame->slots = create_slots(nslot, ntouch, slot_size);
3308- if (!frame->ongoing || !frame->slots)
3309- goto out;
3310-
3311- return frame;
3312- out:
3313- destroy_frame(frame, nslot);
3314- return 0;
3315-}
3316-
3317-static struct grail_frame **create_frames(int nframe, int nslot, int ntouch,
3318- int frame_size, int slot_size)
3319-{
3320- struct grail_frame **frames;
3321- struct grail_frame *f;
3322- int i;
3323-
3324- frames = calloc(nframe, sizeof(frames[0]));
3325- if (!frames)
3326- return 0;
3327-
3328- for (i = 0; i < nframe; i++) {
3329- f = create_frame(nslot, ntouch, frame_size, slot_size);
3330- if (!f)
3331- goto out;
3332- frames[i] = f;
3333- }
3334-
3335- return frames;
3336- out:
3337- destroy_frames(frames, nframe, nslot);
3338- return 0;
3339-}
3340-
3341-int create_grail2(struct grail_impl *x,
3342- utouch_frame_handle fh,
3343- unsigned int num_frames,
3344- grail_select_callback select,
3345- unsigned int version,
3346- unsigned int control_size,
3347- unsigned int frame_size,
3348- unsigned int slot_size)
3349-{
3350- unsigned int ntouch = utouch_frame_get_num_slots(fh);
3351- unsigned int nslot = get_slot_count(ntouch);
3352- int i;
3353-
3354- x->select = select;
3355- x->control_size = MAX(control_size, sizeof(struct grail_control));
3356- x->frame_size = MAX(frame_size, sizeof(struct grail_frame));
3357- x->slot_size = MAX(slot_size, sizeof(struct grail_element));
3358-
3359- x->num_frames = num_frames;
3360- x->num_slots = nslot;
3361- x->num_touches = ntouch;
3362-
3363- x->ctl = create_control(x->control_size);
3364- if (!x->ctl)
3365- goto freemem;
3366-
3367- x->frames = create_frames(num_frames, nslot, ntouch,
3368- x->frame_size, x->slot_size);
3369- if (!x->frames)
3370- goto freemem;
3371-
3372- for (i = 0; i < num_frames; i++)
3373- x->frames[(i + 1) % num_frames]->prev = x->frames[i];
3374-
3375- return 0;
3376-
3377- freemem:
3378- destroy_grail2(x);
3379- return -ENOMEM;
3380-}
3381-
3382-void destroy_grail2(struct grail_impl *x)
3383-{
3384- destroy_frames(x->frames, x->num_frames, x->num_slots);
3385- free(x->ctl);
3386-}
3387-
3388-grail_handle GRAIL_PUBLIC grail_new_raw(utouch_frame_handle fh,
3389- unsigned int num_frames,
3390- grail_select_callback select,
3391- unsigned int version,
3392- unsigned int control_size,
3393- unsigned int frame_size,
3394- unsigned int slot_size)
3395-{
3396- struct grail *ge;
3397- struct grail_impl *x;
3398-
3399- ge = calloc(1, sizeof(*ge));
3400- if (!ge)
3401- return 0;
3402- x = calloc(1, sizeof(*x));
3403- if (!x)
3404- goto out;
3405- x->fh = fh;
3406- if (create_grail2(x, fh, num_frames, select,
3407- version, control_size, frame_size, slot_size))
3408- goto out;
3409-
3410- ge->impl = x;
3411- return ge;
3412-
3413- out:
3414- free(x);
3415- free(ge);
3416- return 0;
3417-}
3418-
3419-void GRAIL_PUBLIC grail_delete(grail_handle ge)
3420-{
3421- destroy_grail2(ge->impl);
3422- free(ge->impl);
3423- free(ge);
3424-}
3425-
3426-struct grail_control GRAIL_PUBLIC *grail_get_control(grail_handle ge)
3427-{
3428- return ge->impl->ctl;
3429-}
3430
3431=== removed file 'src/grail-inserter.c'
3432--- src/grail-inserter.c 2011-08-31 17:20:48 +0000
3433+++ src/grail-inserter.c 1970-01-01 00:00:00 +0000
3434@@ -1,304 +0,0 @@
3435-/*****************************************************************************
3436- *
3437- * grail - Gesture Recognition And Instantiation Library
3438- *
3439- * Copyright (C) 2010-2011 Canonical Ltd.
3440- *
3441- * This program is free software: you can redistribute it and/or modify it
3442- * under the terms of the GNU General Public License as published by the
3443- * Free Software Foundation, either version 3 of the License, or (at your
3444- * option) any later version.
3445- *
3446- * This program is distributed in the hope that it will be useful, but
3447- * WITHOUT ANY WARRANTY; without even the implied warranty of
3448- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
3449- * General Public License for more details.
3450- *
3451- * You should have received a copy of the GNU General Public License along
3452- * with this program. If not, see <http://www.gnu.org/licenses/>.
3453- *
3454- ****************************************************************************/
3455-
3456-#include "grail-gestures.h"
3457-#include "grail-inserter.h"
3458-#include "grail-impl.h"
3459-#include <malloc.h>
3460-#include <string.h>
3461-#include <errno.h>
3462-#include <math.h>
3463-
3464-static const int MAX_GESTURE_ID = 0xfff;
3465-
3466-static int find_gslot(const struct gesture_inserter *gin, int gid)
3467-{
3468- int i;
3469- grail_mask_foreach(i, gin->used, sizeof(gin->used))
3470- if (gin->state[i].id == gid)
3471- return i;
3472- return -1;
3473-}
3474-
3475-static int mask_overlap(const grail_mask_t *a, const grail_mask_t *b,
3476- int bytes)
3477-{
3478- int i;
3479-
3480- for (i = 0; i < bytes; i++)
3481- if (a[i] & b[i])
3482- return 1;
3483-
3484- return 0;
3485-}
3486-
3487-// todo: spanning tree for multi-user case
3488-static void setup_new_gestures(struct grail *ge,
3489- const struct utouch_frame *frame)
3490-{
3491- struct gesture_inserter *gin = ge->gin;
3492- grail_mask_t types[DIM_GRAIL_TYPE_BYTES];
3493- grail_mask_t span[DIM_TOUCH_BYTES];
3494- struct grail_client_info info[DIM_CLIENT];
3495- int i, j, nclient = 0;
3496- int nfresh = grail_mask_count(gin->fresh, sizeof(gin->fresh));
3497- if (!nfresh)
3498- return;
3499-
3500- memset(types, 0, sizeof(types));
3501- memset(span, 0, sizeof(span));
3502-
3503- grail_mask_foreach(i, gin->fresh, sizeof(gin->fresh)) {
3504- struct slot_state *s = &gin->state[i];
3505- grail_mask_set(types, s->type);
3506- grail_mask_set_mask(span, s->span, sizeof(span));
3507- }
3508-
3509- nclient = gin_get_clients(ge, info, DIM_CLIENT, types, sizeof(types),
3510- span, sizeof(span), frame);
3511-
3512- grail_mask_foreach(i, gin->fresh, sizeof(gin->fresh)) {
3513- struct slot_state *s = &gin->state[i];
3514- s->nclient = 0;
3515- for (j = 0; j < nclient; j++) {
3516- if (!grail_mask_get(info[j].mask, s->type))
3517- continue;
3518- if (gin->grab_active &&
3519- info[j].id.client != gin->grab_client)
3520- continue;
3521- if (grail_mask_get(info[j].mask, GRAIL_TYPE_SYSFLAG1)) {
3522- gin->grab_active = 1;
3523- gin->grab_client = info[j].id.client;
3524- }
3525- s->client_id[s->nclient++] = info[j].id;
3526- }
3527- }
3528-
3529- memset(gin->fresh, 0, sizeof(gin->fresh));
3530-}
3531-
3532-int gin_init(struct grail *ge)
3533-{
3534- struct gesture_inserter *gin;
3535- int i;
3536- gin = calloc(1, sizeof(*gin));
3537- if (!gin)
3538- return -ENOMEM;
3539- for (i = 0; i < DIM_INSTANCE; i++)
3540- grail_mask_set(gin->unused, i);
3541- ge->gin = gin;
3542- return 0;
3543-}
3544-
3545-void gin_destroy(struct grail *ge)
3546-{
3547- free(ge->gin);
3548- ge->gin = NULL;
3549-}
3550-
3551-void gin_frame_begin(struct grail *ge, const struct utouch_frame *frame)
3552-{
3553- struct gesture_inserter *gin = ge->gin;
3554- memset(gin->types, 0, sizeof(gin->types));
3555- gin->time = frame->time;
3556- if (frame->num_active && !frame->prev->num_active)
3557- gin->grab_active = 0;
3558-}
3559-
3560-void gin_frame_end(struct grail *ge, const struct utouch_frame *frame)
3561-{
3562- struct gesture_inserter *gin = ge->gin;
3563- grail_mask_t keep[DIM_TOUCH_BYTES];
3564- int i, hold[2] = { 0, 0 }, discard[2] = { 0, 0 };
3565-
3566- memset(keep, 0, sizeof(keep));
3567- setup_new_gestures(ge, frame);
3568-
3569- grail_mask_foreach(i, gin->used, sizeof(gin->used)) {
3570- struct slot_state *s = &gin->state[i];
3571- if (!s->nclient)
3572- continue;
3573- if (s->priority > hold[s->slice])
3574- hold[s->slice] = s->priority;
3575- if (s->status != GRAIL_STATUS_UPDATE)
3576- continue;
3577- if (s->priority > discard[s->slice])
3578- discard[s->slice] = s->priority;
3579- }
3580-
3581- grail_mask_foreach(i, gin->used, sizeof(gin->used)) {
3582- struct slot_state *s = &gin->state[i];
3583- if (!s->nclient || (s->priority < discard[s->slice] && !s->sent))
3584- gin_gid_discard(ge, s->id);
3585- }
3586-
3587- grail_mask_foreach(i, gin->used, sizeof(gin->used)) {
3588- struct slot_state *s = &gin->state[i];
3589- if (s->slice == 1)
3590- grail_mask_set_mask(keep, s->span, sizeof(keep));
3591- }
3592-
3593- grail_mask_foreach(i, gin->used, sizeof(gin->used)) {
3594- struct slot_state *s = &gin->state[i];
3595- if (!s->timeout)
3596- continue;
3597- if (mask_overlap(keep, s->span, sizeof(keep)))
3598- continue;
3599- gin_gid_discard(ge, s->id);
3600- }
3601-
3602- grail_mask_foreach(i, gin->used, sizeof(gin->used)) {
3603- struct slot_state *s = &gin->state[i];
3604- struct gesture_event ev;
3605- grail_mask_set(gin->types, s->type);
3606- if (s->priority < hold[s->slice] && !s->sent)
3607- continue;
3608- while (!gebuf_empty(&s->buf)) {
3609- gebuf_get(&s->buf, &ev);
3610- gin_send_event(ge, s, &ev, frame);
3611- }
3612- s->sent = 1;
3613- }
3614-
3615- grail_mask_foreach(i, gin->used, sizeof(gin->used)) {
3616- struct slot_state *s = &gin->state[i];
3617- if (s->status == GRAIL_STATUS_END)
3618- gin_gid_discard(ge, s->id);
3619- }
3620-}
3621-
3622-int gin_gid_begin(struct grail *ge, int type, int priority,
3623- const struct utouch_frame *frame)
3624-{
3625- struct gesture_inserter *gin = ge->gin;
3626- struct slot_state *s;
3627- int slot;
3628- int i = grail_mask_get_first(gin->unused, sizeof(gin->unused));
3629- if (i < 0)
3630- return -1;
3631- s = &gin->state[i];
3632- s->type = type;
3633- if (priority < 0) {
3634- s->priority = -priority;
3635- s->slice = 1;
3636- } else {
3637- s->priority = priority;
3638- s->slice = 0;
3639- }
3640- s->timeout = 0;
3641- s->sent = 0;
3642- s->id = gin->gestureid++ & MAX_GESTURE_ID;
3643- s->status = GRAIL_STATUS_BEGIN;
3644- s->nclient = 0;
3645- for (slot = 0; slot < DIM_TOUCH; slot++)
3646- grail_mask_modify(s->span, slot, frame->slots[slot]->active);
3647- gebuf_clear(&s->buf);
3648- grail_mask_clear(gin->unused, i);
3649- grail_mask_set(gin->fresh, i);
3650- grail_mask_set(gin->used, i);
3651- return s->id;
3652-}
3653-
3654-void gin_gid_discard(struct grail *ge, int gid)
3655-{
3656- struct gesture_inserter *gin = ge->gin;
3657- struct slot_state *s;
3658- int i = find_gslot(gin, gid);
3659- if (i < 0)
3660- return;
3661- s = &gin->state[i];
3662- gebuf_clear(&s->buf);
3663- s->status = GRAIL_STATUS_END;
3664- grail_mask_clear(gin->used, i);
3665- grail_mask_set(gin->unused, i);
3666-}
3667-
3668-void gin_gid_timeout(struct grail *ge, int gid)
3669-{
3670- int i = find_gslot(ge->gin, gid);
3671- if (i >= 0)
3672- ge->gin->state[i].timeout = 1;
3673-}
3674-
3675-void gin_gid_event(struct grail *ge, int gid,
3676- float x, float y, int ntouch,
3677- const grail_prop_t *prop, int nprop,
3678- int transient)
3679-{
3680- struct gesture_inserter *gin = ge->gin;
3681- struct gesture_event ev;
3682- struct slot_state *s;
3683- int i = find_gslot(gin, gid);
3684- if (i < 0)
3685- return;
3686- s = &gin->state[i];
3687- ev.status = transient ? GRAIL_STATUS_UPDATE : s->status;
3688- ev.ntouch = ntouch;
3689- ev.nprop = nprop;
3690- ev.time = gin->time;
3691- ev.pos.x = x;
3692- ev.pos.y = y;
3693- memcpy(ev.prop, prop, nprop * sizeof(grail_prop_t));
3694- gebuf_put(&s->buf, &ev);
3695- if (transient)
3696- s->status = GRAIL_STATUS_END;
3697- else if (s->status == GRAIL_STATUS_BEGIN)
3698- s->status = GRAIL_STATUS_UPDATE;
3699-}
3700-
3701-void gin_gid_end(struct grail *ge, int gid,
3702- float x, float y, int ntouch,
3703- const grail_prop_t *prop, int nprop)
3704-{
3705- struct gesture_inserter *gin = ge->gin;
3706- struct gesture_event ev;
3707- struct slot_state *s;
3708- int i = find_gslot(gin, gid);
3709- if (i < 0)
3710- return;
3711- s = &gin->state[i];
3712- if (s->status != GRAIL_STATUS_BEGIN) {
3713- ev.status = GRAIL_STATUS_END;
3714- ev.ntouch = ntouch;
3715- ev.nprop = nprop;
3716- ev.time = gin->time;
3717- ev.pos.x = x;
3718- ev.pos.y = y;
3719- memcpy(ev.prop, prop, nprop * sizeof(grail_prop_t));
3720- gebuf_put(&s->buf, &ev);
3721- }
3722- s->status = GRAIL_STATUS_END;
3723-}
3724-
3725-void GRAIL_PUBLIC grail_set_bbox(struct grail *ge,
3726- const struct grail_coord *tmin,
3727- const struct grail_coord *tmax)
3728-{
3729- struct utouch_surface *s = utouch_frame_get_surface(ge->impl->fh);
3730-
3731- s->mapped_min_x = tmin->x;
3732- s->mapped_min_y = tmin->y;
3733- s->mapped_max_x = tmax->x;
3734- s->mapped_max_y = tmax->y;
3735-
3736- if (ge->gru)
3737- gru_init_motion(ge);
3738-}
3739
3740=== removed file 'src/grail-inserter.h'
3741--- src/grail-inserter.h 2011-05-17 14:15:22 +0000
3742+++ src/grail-inserter.h 1970-01-01 00:00:00 +0000
3743@@ -1,93 +0,0 @@
3744-/*****************************************************************************
3745- *
3746- * grail - Gesture Recognition And Instantiation Library
3747- *
3748- * Copyright (C) 2010-2011 Canonical Ltd.
3749- *
3750- * This program is free software: you can redistribute it and/or modify it
3751- * under the terms of the GNU General Public License as published by the
3752- * Free Software Foundation, either version 3 of the License, or (at your
3753- * option) any later version.
3754- *
3755- * This program is distributed in the hope that it will be useful, but
3756- * WITHOUT ANY WARRANTY; without even the implied warranty of
3757- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
3758- * General Public License for more details.
3759- *
3760- * You should have received a copy of the GNU General Public License along
3761- * with this program. If not, see <http://www.gnu.org/licenses/>.
3762- *
3763- ****************************************************************************/
3764-
3765-#ifndef GRAIL_INSERTER_H
3766-#define GRAIL_INSERTER_H
3767-
3768-#include "grail-impl.h"
3769-#include "gebuf.h"
3770-
3771-#define DIM_EV_TYPE EV_CNT
3772-#define DIM_EV_TYPE_BYTES ((DIM_EV_TYPE + 7) >> 3)
3773-
3774-#define DIM_INSTANCE 32
3775-#define DIM_INSTANCE_BYTES ((DIM_INSTANCE + 7) >> 3)
3776-
3777-#define DIM_CLIENT 32
3778-
3779-struct slot_state {
3780- int type;
3781- int priority;
3782- int slice;
3783- int timeout;
3784- int sent;
3785- int id;
3786- int status;
3787- int nclient;
3788- struct grail_client_id client_id[DIM_CLIENT];
3789- grail_mask_t span[DIM_TOUCH_BYTES];
3790- struct gebuf buf;
3791-};
3792-
3793-struct gesture_inserter {
3794- struct slot_state state[DIM_INSTANCE];
3795- grail_mask_t types[DIM_GRAIL_TYPE_BYTES];
3796- grail_mask_t unused[DIM_INSTANCE_BYTES];
3797- grail_mask_t fresh[DIM_INSTANCE_BYTES];
3798- grail_mask_t used[DIM_INSTANCE_BYTES];
3799- grail_time_t time;
3800- int gestureid;
3801- int grab_active;
3802- int grab_client;
3803-};
3804-
3805-int gin_add_contact_props(const struct gesture_inserter *gin,
3806- grail_prop_t *prop, const struct utouch_frame *frame);
3807-
3808-int gin_get_clients(struct grail *ge,
3809- struct grail_client_info *info, int maxinfo,
3810- const grail_mask_t* types, int btypes,
3811- const grail_mask_t* span, int bspan,
3812- const struct utouch_frame *frame);
3813-void gin_send_event(struct grail *ge, struct slot_state *s,
3814- const struct gesture_event *ev,
3815- const struct utouch_frame *frame);
3816-
3817-int gin_init(struct grail *ge);
3818-void gin_destroy(struct grail *ge);
3819-
3820-void gin_frame_begin(struct grail *ge, const struct utouch_frame *frame);
3821-void gin_frame_end(struct grail *ge, const struct utouch_frame *frame);
3822-
3823-int gin_gid_begin(struct grail *ge, int type, int priority,
3824- const struct utouch_frame *frame);
3825-void gin_gid_discard(struct grail *ge, int gid);
3826-void gin_gid_timeout(struct grail *ge, int gid);
3827-
3828-void gin_gid_event(struct grail *ge, int gid,
3829- float x, float y, int ntouch,
3830- const grail_prop_t *prop, int nprop,
3831- int transient);
3832-void gin_gid_end(struct grail *ge, int gid,
3833- float x, float y, int ntouch,
3834- const grail_prop_t *prop, int nprop);
3835-
3836-#endif
3837
3838=== removed file 'src/grail-legacy.c'
3839--- src/grail-legacy.c 2011-08-31 17:20:48 +0000
3840+++ src/grail-legacy.c 1970-01-01 00:00:00 +0000
3841@@ -1,64 +0,0 @@
3842-/*****************************************************************************
3843- *
3844- * grail - Gesture Recognition And Instantiation Library
3845- *
3846- * Copyright (C) 2010-2011 Canonical Ltd.
3847- *
3848- * This program is free software: you can redistribute it and/or modify it
3849- * under the terms of the GNU General Public License as published by the
3850- * Free Software Foundation, either version 3 of the License, or (at your
3851- * option) any later version.
3852- *
3853- * This program is distributed in the hope that it will be useful, but
3854- * WITHOUT ANY WARRANTY; without even the implied warranty of
3855- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
3856- * General Public License for more details.
3857- *
3858- * You should have received a copy of the GNU General Public License along
3859- * with this program. If not, see <http://www.gnu.org/licenses/>.
3860- *
3861- ****************************************************************************/
3862-
3863-#include <grail.h>
3864-#include "grail-inserter.h"
3865-#include <string.h>
3866-#include <stdio.h>
3867-#include <unistd.h>
3868-#include <fcntl.h>
3869-#include <malloc.h>
3870-#include <errno.h>
3871-#include <stdlib.h>
3872-
3873-#ifndef GRAIL_NO_LEGACY_ABI
3874-
3875-void GRAIL_PUBLIC grail_filter_abs_events(struct grail *ge, int usage)
3876-{
3877- struct grail_impl *x = ge->impl;
3878- x->filter_abs = usage;
3879-}
3880-
3881-int GRAIL_PUBLIC grail_get_contacts(const struct grail *ge,
3882- struct grail_contact *touch, int max_touch)
3883-{
3884- const struct utouch_frame *frame = ge->impl->touch;
3885- int i;
3886- if (frame->num_active < max_touch)
3887- max_touch = frame->num_active;
3888- for (i = 0; i < max_touch; i++) {
3889- struct grail_contact *t = &touch[i];
3890- const struct utouch_contact *ct = frame->active[i];
3891- t->id = ct->id;
3892- t->tool_type = ct->tool_type;
3893- t->pos.x = ct->x;
3894- t->pos.y = ct->y;
3895- t->touch_major = ct->touch_major;
3896- t->touch_minor = ct->touch_minor;
3897- t->width_major = ct->width_major;
3898- t->width_minor = ct->width_minor;
3899- t->angle = ct->orientation;
3900- t->pressure = ct->pressure;
3901- }
3902- return max_touch;
3903-}
3904-
3905-#endif
3906
3907=== removed file 'src/grail-recognizer.c'
3908--- src/grail-recognizer.c 2011-04-28 16:53:57 +0000
3909+++ src/grail-recognizer.c 1970-01-01 00:00:00 +0000
3910@@ -1,58 +0,0 @@
3911-/*****************************************************************************
3912- *
3913- * grail - Gesture Recognition And Instantiation Library
3914- *
3915- * Copyright (C) 2010-2011 Canonical Ltd.
3916- *
3917- * This program is free software: you can redistribute it and/or modify it
3918- * under the terms of the GNU General Public License as published by the
3919- * Free Software Foundation, either version 3 of the License, or (at your
3920- * option) any later version.
3921- *
3922- * This program is distributed in the hope that it will be useful, but
3923- * WITHOUT ANY WARRANTY; without even the implied warranty of
3924- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
3925- * General Public License for more details.
3926- *
3927- * You should have received a copy of the GNU General Public License along
3928- * with this program. If not, see <http://www.gnu.org/licenses/>.
3929- *
3930- ****************************************************************************/
3931-
3932-#include "grail-recognizer.h"
3933-#include <string.h>
3934-#include <malloc.h>
3935-#include <errno.h>
3936-
3937-int gru_init(struct grail *ge)
3938-{
3939- struct gesture_recognizer *gru;
3940- gru = calloc(1, sizeof(struct gesture_recognizer));
3941- if (!gru)
3942- return -ENOMEM;
3943- ge->gru = gru;
3944- gru_init_motion(ge);
3945- return 0;
3946-}
3947-
3948-void gru_destroy(struct grail *ge)
3949-{
3950- free(ge->gru);
3951- ge->gru = NULL;
3952-}
3953-
3954-void gru_recognize(struct grail *ge, const struct utouch_frame *frame)
3955-{
3956- if (!ge->gin || !ge->gru)
3957- return;
3958- gru_motion(ge, frame);
3959- gru_touch(ge, frame);
3960- gru_drag(ge, frame);
3961- gru_pinch(ge, frame);
3962- gru_rotate(ge, frame);
3963- gru_wintouch(ge, frame);
3964- gru_windrag(ge, frame);
3965- gru_winpinch(ge, frame);
3966- gru_winrotate(ge, frame);
3967- gru_tapping(ge, frame);
3968-}
3969
3970=== removed file 'src/grail-recognizer.h'
3971--- src/grail-recognizer.h 2011-05-17 14:15:22 +0000
3972+++ src/grail-recognizer.h 1970-01-01 00:00:00 +0000
3973@@ -1,44 +0,0 @@
3974-/*****************************************************************************
3975- *
3976- * grail - Gesture Recognition And Instantiation Library
3977- *
3978- * Copyright (C) 2010-2011 Canonical Ltd.
3979- *
3980- * This program is free software: you can redistribute it and/or modify it
3981- * under the terms of the GNU General Public License as published by the
3982- * Free Software Foundation, either version 3 of the License, or (at your
3983- * option) any later version.
3984- *
3985- * This program is distributed in the hope that it will be useful, but
3986- * WITHOUT ANY WARRANTY; without even the implied warranty of
3987- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
3988- * General Public License for more details.
3989- *
3990- * You should have received a copy of the GNU General Public License along
3991- * with this program. If not, see <http://www.gnu.org/licenses/>.
3992- *
3993- ****************************************************************************/
3994-
3995-#ifndef GRAIL_RECOGNIZER_H
3996-#define GRAIL_RECOGNIZER_H
3997-
3998-#include "grail-gestures.h"
3999-
4000-struct gesture_recognizer {
4001- struct move_model move;
4002- struct combo_model touch;
4003- struct combo_model drag;
4004- struct combo_model pinch;
4005- struct combo_model rotate;
4006- struct combo_model wintouch;
4007- struct combo_model windrag;
4008- struct combo_model winpinch;
4009- struct combo_model winrotate;
4010- struct tapping_model tapping;
4011-};
4012-
4013-int gru_init(struct grail *ge);
4014-void gru_recognize(struct grail *ge, const struct utouch_frame *frame);
4015-void gru_destroy(struct grail *ge);
4016-
4017-#endif
4018
4019=== removed file 'src/grailbuf.h'
4020--- src/grailbuf.h 2011-05-17 14:15:22 +0000
4021+++ src/grailbuf.h 1970-01-01 00:00:00 +0000
4022@@ -1,59 +0,0 @@
4023-/*****************************************************************************
4024- *
4025- * grail - Gesture Recognition And Instantiation Library
4026- *
4027- * Copyright (C) 2010-2011 Canonical Ltd.
4028- *
4029- * This program is free software: you can redistribute it and/or modify it
4030- * under the terms of the GNU General Public License as published by the
4031- * Free Software Foundation, either version 3 of the License, or (at your
4032- * option) any later version.
4033- *
4034- * This program is distributed in the hope that it will be useful, but
4035- * WITHOUT ANY WARRANTY; without even the implied warranty of
4036- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
4037- * General Public License for more details.
4038- *
4039- * You should have received a copy of the GNU General Public License along
4040- * with this program. If not, see <http://www.gnu.org/licenses/>.
4041- *
4042- ****************************************************************************/
4043-
4044-#ifndef GRAIL_BUFFER_H
4045-#define GRAIL_BUFFER_H
4046-
4047-#include <grail.h>
4048-
4049-#define DIM_GRAIL_EVENTS 512
4050-
4051-struct grailbuf {
4052- int head;
4053- int tail;
4054- struct grail_event buffer[DIM_GRAIL_EVENTS];
4055-};
4056-
4057-static inline void grailbuf_clear(struct grailbuf *buf)
4058-{
4059- buf->head = buf->tail = 0;
4060-}
4061-
4062-static inline int grailbuf_empty(const struct grailbuf *buf)
4063-{
4064- return buf->head == buf->tail;
4065-}
4066-
4067-static inline void grailbuf_put(struct grailbuf *buf,
4068- const struct grail_event *ev)
4069-{
4070- buf->buffer[buf->head++] = *ev;
4071- buf->head &= DIM_GRAIL_EVENTS - 1;
4072-}
4073-
4074-static inline void grailbuf_get(struct grailbuf *buf,
4075- struct grail_event *ev)
4076-{
4077- *ev = buf->buffer[buf->tail++];
4078- buf->tail &= DIM_GRAIL_EVENTS - 1;
4079-}
4080-
4081-#endif
4082
4083=== added directory 'src/v2'
4084=== added file 'src/v2/evbuf.h'
4085--- src/v2/evbuf.h 1970-01-01 00:00:00 +0000
4086+++ src/v2/evbuf.h 2012-01-25 15:53:29 +0000
4087@@ -0,0 +1,57 @@
4088+/*****************************************************************************
4089+ *
4090+ * grail - Gesture Recognition And Instantiation Library
4091+ *
4092+ * Copyright (C) 2010-2011 Canonical Ltd.
4093+ *
4094+ * This program is free software: you can redistribute it and/or modify it
4095+ * under the terms of the GNU General Public License as published by the
4096+ * Free Software Foundation, either version 3 of the License, or (at your
4097+ * option) any later version.
4098+ *
4099+ * This program is distributed in the hope that it will be useful, but
4100+ * WITHOUT ANY WARRANTY; without even the implied warranty of
4101+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
4102+ * General Public License for more details.
4103+ *
4104+ * You should have received a copy of the GNU General Public License along
4105+ * with this program. If not, see <http://www.gnu.org/licenses/>.
4106+ *
4107+ ****************************************************************************/
4108+
4109+#ifndef GRAIL_EVBUF_H
4110+#define GRAIL_EVBUF_H
4111+
4112+#define DIM_EVENTS 4096
4113+
4114+struct evbuf {
4115+ int head;
4116+ int tail;
4117+ struct input_event buffer[DIM_EVENTS];
4118+};
4119+
4120+static inline void evbuf_clear(struct evbuf *evbuf)
4121+{
4122+ evbuf->head = evbuf->tail = 0;
4123+}
4124+
4125+static inline int evbuf_empty(const struct evbuf *evbuf)
4126+{
4127+ return evbuf->head == evbuf->tail;
4128+}
4129+
4130+static inline void evbuf_put(struct evbuf *evbuf,
4131+ const struct input_event *ev)
4132+{
4133+ evbuf->buffer[evbuf->head++] = *ev;
4134+ evbuf->head &= DIM_EVENTS - 1;
4135+}
4136+
4137+static inline void evbuf_get(struct evbuf *evbuf,
4138+ struct input_event *ev)
4139+{
4140+ *ev = evbuf->buffer[evbuf->tail++];
4141+ evbuf->tail &= DIM_EVENTS - 1;
4142+}
4143+
4144+#endif
4145
4146=== added file 'src/v2/gebuf.h'
4147--- src/v2/gebuf.h 1970-01-01 00:00:00 +0000
4148+++ src/v2/gebuf.h 2012-01-25 15:53:29 +0000
4149@@ -0,0 +1,68 @@
4150+/*****************************************************************************
4151+ *
4152+ * grail - Gesture Recognition And Instantiation Library
4153+ *
4154+ * Copyright (C) 2010-2011 Canonical Ltd.
4155+ *
4156+ * This program is free software: you can redistribute it and/or modify it
4157+ * under the terms of the GNU General Public License as published by the
4158+ * Free Software Foundation, either version 3 of the License, or (at your
4159+ * option) any later version.
4160+ *
4161+ * This program is distributed in the hope that it will be useful, but
4162+ * WITHOUT ANY WARRANTY; without even the implied warranty of
4163+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
4164+ * General Public License for more details.
4165+ *
4166+ * You should have received a copy of the GNU General Public License along
4167+ * with this program. If not, see <http://www.gnu.org/licenses/>.
4168+ *
4169+ ****************************************************************************/
4170+
4171+#ifndef GRAIL_GESTURE_BUFFER_H
4172+#define GRAIL_GESTURE_BUFFER_H
4173+
4174+#include "grail-impl.h"
4175+
4176+#define DIM_GESTURE_EVENTS 512
4177+
4178+struct gesture_event {
4179+ int status;
4180+ int ntouch;
4181+ int nprop;
4182+ utouch_frame_time_t time;
4183+ struct grail_coord pos;
4184+ grail_prop_t prop[DIM_GRAIL_PROP];
4185+};
4186+
4187+struct gebuf {
4188+ int head;
4189+ int tail;
4190+ struct gesture_event buffer[DIM_GESTURE_EVENTS];
4191+};
4192+
4193+static inline void gebuf_clear(struct gebuf *gebuf)
4194+{
4195+ gebuf->head = gebuf->tail = 0;
4196+}
4197+
4198+static inline int gebuf_empty(const struct gebuf *gebuf)
4199+{
4200+ return gebuf->head == gebuf->tail;
4201+}
4202+
4203+static inline void gebuf_put(struct gebuf *gebuf,
4204+ const struct gesture_event *ev)
4205+{
4206+ gebuf->buffer[gebuf->head++] = *ev;
4207+ gebuf->head &= DIM_GESTURE_EVENTS - 1;
4208+}
4209+
4210+static inline void gebuf_get(struct gebuf *gebuf,
4211+ struct gesture_event *ev)
4212+{
4213+ *ev = gebuf->buffer[gebuf->tail++];
4214+ gebuf->tail &= DIM_GESTURE_EVENTS - 1;
4215+}
4216+
4217+#endif
4218
4219=== added file 'src/v2/gestures-drag.c'
4220--- src/v2/gestures-drag.c 1970-01-01 00:00:00 +0000
4221+++ src/v2/gestures-drag.c 2012-01-25 15:53:29 +0000
4222@@ -0,0 +1,135 @@
4223+/*****************************************************************************
4224+ *
4225+ * grail - Gesture Recognition And Instantiation Library
4226+ *
4227+ * Copyright (C) 2010-2011 Canonical Ltd.
4228+ *
4229+ * This program is free software: you can redistribute it and/or modify it
4230+ * under the terms of the GNU General Public License as published by the
4231+ * Free Software Foundation, either version 3 of the License, or (at your
4232+ * option) any later version.
4233+ *
4234+ * This program is distributed in the hope that it will be useful, but
4235+ * WITHOUT ANY WARRANTY; without even the implied warranty of
4236+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
4237+ * General Public License for more details.
4238+ *
4239+ * You should have received a copy of the GNU General Public License along
4240+ * with this program. If not, see <http://www.gnu.org/licenses/>.
4241+ *
4242+ ****************************************************************************/
4243+
4244+#include "grail-recognizer.h"
4245+#include <math.h>
4246+#include <stdio.h>
4247+
4248+static const int getype[DIM_TOUCH + 1] = {
4249+ -1,
4250+ GRAIL_TYPE_DRAG1,
4251+ GRAIL_TYPE_DRAG2,
4252+ GRAIL_TYPE_DRAG3,
4253+ GRAIL_TYPE_DRAG4,
4254+ GRAIL_TYPE_DRAG5,
4255+};
4256+
4257+static void set_props(const struct gesture_inserter *gin,
4258+ struct combo_model *s, const struct move_model *m,
4259+ const struct utouch_frame *frame)
4260+{
4261+ if (m->single) {
4262+ s->prop[GRAIL_PROP_DRAG_DX] = m->fm[FM_X].raw_delta;
4263+ s->prop[GRAIL_PROP_DRAG_DY] = m->fm[FM_Y].raw_delta;
4264+ } else {
4265+ s->prop[GRAIL_PROP_DRAG_DX] = m->fm[FM_X].action_delta;
4266+ s->prop[GRAIL_PROP_DRAG_DY] = m->fm[FM_Y].action_delta;
4267+ }
4268+ s->prop[GRAIL_PROP_DRAG_VX] = m->fm[FM_X].velocity;
4269+ s->prop[GRAIL_PROP_DRAG_VY] = m->fm[FM_Y].velocity;
4270+ s->prop[GRAIL_PROP_DRAG_X] = m->fm[FM_X].value;
4271+ s->prop[GRAIL_PROP_DRAG_Y] = m->fm[FM_Y].value;
4272+ s->nprop = 6;
4273+ s->nprop += gin_add_contact_props(gin, s->prop + s->nprop, frame);
4274+}
4275+
4276+static const int fm_mask = 0x03;
4277+
4278+int gru_drag(struct grail *ge,
4279+ const struct utouch_frame *frame)
4280+{
4281+ struct gesture_recognizer *gru = ge->gru;
4282+ struct combo_model *state = &gru->drag;
4283+ struct move_model *move = &gru->move;
4284+ int mask = state->active ? (move->active & fm_mask) : fm_mask;
4285+ if (!move->multi && !move->single) {
4286+ if (state->active) {
4287+ gru_end(ge, state->gid, move,
4288+ state->prop, state->nprop);
4289+ state->active = 0;
4290+ }
4291+ }
4292+ if ((move->timeout & fm_mask) == fm_mask) {
4293+ if (state->active) {
4294+ gin_gid_timeout(ge, state->gid);
4295+ }
4296+ }
4297+ if (!state->active) {
4298+ int type = getype[move->ntouch];
4299+ if (type < 0)
4300+ return 0;
4301+ state->gid = gin_gid_begin(ge, type, PRIO_GESTURE, frame);
4302+ state->active = 1;
4303+ }
4304+ if (!(move->tickle & mask))
4305+ return 0;
4306+ if (!(move->active & fm_mask))
4307+ return 0;
4308+ set_props(ge->gin, state, move, frame);
4309+ gru_event(ge, state->gid, move, state->prop, state->nprop);
4310+ return 1;
4311+}
4312+
4313+int gru_windrag(struct grail *ge,
4314+ const struct utouch_frame *frame)
4315+{
4316+ struct gesture_recognizer *gru = ge->gru;
4317+ struct combo_model *state = &gru->windrag;
4318+ struct move_model *move = &gru->move;
4319+ int mask = state->active ? (move->active & fm_mask) : fm_mask;
4320+ if (!move->multi && !move->single) {
4321+ if (state->active && out_of_bounds(state, move)) {
4322+ gru_end(ge, state->gid, move,
4323+ state->prop, state->nprop);
4324+ state->active = 0;
4325+ }
4326+ }
4327+ if ((move->timeout & fm_mask) == fm_mask) {
4328+ if (state->active) {
4329+ gin_gid_timeout(ge, state->gid);
4330+ }
4331+ }
4332+ if (!state->active) {
4333+ if (move->ntouch == 4) {
4334+ state->gid = gin_gid_begin(ge, GRAIL_TYPE_MDRAG,
4335+ PRIO_META, frame);
4336+ state->mintouch = 1;
4337+ state->maxtouch = 4;
4338+ state->active = 1;
4339+ } else if (move->ntouch == 3) {
4340+ state->gid = gin_gid_begin(ge, GRAIL_TYPE_EDRAG,
4341+ PRIO_ENV, frame);
4342+ state->mintouch = 1;
4343+ state->maxtouch = 3;
4344+ state->active = 1;
4345+ } else {
4346+ return 0;
4347+ }
4348+ }
4349+ if (!(move->tickle & mask))
4350+ return 0;
4351+ if (!(move->active & fm_mask))
4352+ return 0;
4353+ set_props(ge->gin, state, move, frame);
4354+ gru_event(ge, state->gid, move, state->prop, state->nprop);
4355+ return 1;
4356+}
4357+
4358
4359=== added file 'src/v2/gestures-pinch.c'
4360--- src/v2/gestures-pinch.c 1970-01-01 00:00:00 +0000
4361+++ src/v2/gestures-pinch.c 2012-01-25 15:53:29 +0000
4362@@ -0,0 +1,131 @@
4363+/*****************************************************************************
4364+ *
4365+ * grail - Gesture Recognition And Instantiation Library
4366+ *
4367+ * Copyright (C) 2010-2011 Canonical Ltd.
4368+ *
4369+ * This program is free software: you can redistribute it and/or modify it
4370+ * under the terms of the GNU General Public License as published by the
4371+ * Free Software Foundation, either version 3 of the License, or (at your
4372+ * option) any later version.
4373+ *
4374+ * This program is distributed in the hope that it will be useful, but
4375+ * WITHOUT ANY WARRANTY; without even the implied warranty of
4376+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
4377+ * General Public License for more details.
4378+ *
4379+ * You should have received a copy of the GNU General Public License along
4380+ * with this program. If not, see <http://www.gnu.org/licenses/>.
4381+ *
4382+ ****************************************************************************/
4383+
4384+#include "grail-recognizer.h"
4385+#include <math.h>
4386+#include <stdio.h>
4387+
4388+static const int getype[DIM_TOUCH + 1] = {
4389+ 0,
4390+ 0,
4391+ GRAIL_TYPE_PINCH2,
4392+ GRAIL_TYPE_PINCH3,
4393+ GRAIL_TYPE_PINCH4,
4394+ GRAIL_TYPE_PINCH5,
4395+};
4396+
4397+static const int fm_mask = 0x04;
4398+
4399+static void set_props(const struct gesture_inserter *gin,
4400+ struct combo_model *s,
4401+ const struct move_model *m,
4402+ const struct utouch_frame *frame)
4403+{
4404+ s->prop[GRAIL_PROP_PINCH_DR] = m->fm[FM_R].action_delta;
4405+ s->prop[GRAIL_PROP_PINCH_VR] = m->fm[FM_R].velocity;
4406+ s->prop[GRAIL_PROP_PINCH_R] = m->fm[FM_R].value;
4407+ s->prop[GRAIL_PROP_PINCH_X] = m->fm[FM_X].value;
4408+ s->prop[GRAIL_PROP_PINCH_Y] = m->fm[FM_Y].value;
4409+ s->nprop = 5;
4410+ s->nprop += gin_add_contact_props(gin, s->prop + s->nprop, frame);
4411+}
4412+
4413+int gru_pinch(struct grail *ge,
4414+ const struct utouch_frame *frame)
4415+{
4416+ struct gesture_recognizer *gru = ge->gru;
4417+ struct combo_model *state = &gru->pinch;
4418+ struct move_model *move = &gru->move;
4419+ int mask = state->active ? (move->active & fm_mask) : fm_mask;
4420+ if (!move->multi && !move->single) {
4421+ if (state->active) {
4422+ gru_end(ge, state->gid, move,
4423+ state->prop, state->nprop);
4424+ state->active = 0;
4425+ }
4426+ return 0;
4427+ }
4428+ if ((move->timeout & fm_mask) == fm_mask) {
4429+ if (state->active) {
4430+ gin_gid_timeout(ge, state->gid);
4431+ }
4432+ }
4433+ if (!(move->tickle & mask))
4434+ return 0;
4435+ if (!state->active) {
4436+ int type = getype[move->ntouch];
4437+ if (!type)
4438+ return 0;
4439+ state->gid = gin_gid_begin(ge, type, PRIO_GESTURE, frame);
4440+ state->active = 1;
4441+ }
4442+ if (!(move->active & fm_mask))
4443+ return 0;
4444+ set_props(ge->gin, state, move, frame);
4445+ gru_event(ge, state->gid, move, state->prop, state->nprop);
4446+ return 1;
4447+}
4448+
4449+int gru_winpinch(struct grail *ge,
4450+ const struct utouch_frame *frame)
4451+{
4452+ struct gesture_recognizer *gru = ge->gru;
4453+ struct combo_model *state = &gru->winpinch;
4454+ struct move_model *move = &gru->move;
4455+ int mask = state->active ? (move->active & fm_mask) : fm_mask;
4456+ if (!move->multi) {
4457+ if (state->active && out_of_bounds(state, move)) {
4458+ gru_end(ge, state->gid, move,
4459+ state->prop, state->nprop);
4460+ state->active = 0;
4461+ }
4462+ return 0;
4463+ }
4464+ if ((move->timeout & fm_mask) == fm_mask) {
4465+ if (state->active) {
4466+ gin_gid_timeout(ge, state->gid);
4467+ }
4468+ }
4469+ if (!(move->tickle & mask))
4470+ return 0;
4471+ if (!state->active) {
4472+ if (move->ntouch == 4) {
4473+ state->gid = gin_gid_begin(ge, GRAIL_TYPE_MPINCH,
4474+ PRIO_META, frame);
4475+ state->mintouch = 2;
4476+ state->maxtouch = 4;
4477+ state->active = 1;
4478+ } else if (move->ntouch == 3) {
4479+ state->gid = gin_gid_begin(ge, GRAIL_TYPE_EPINCH,
4480+ PRIO_ENV, frame);
4481+ state->mintouch = 2;
4482+ state->maxtouch = 3;
4483+ state->active = 1;
4484+ } else {
4485+ return 0;
4486+ }
4487+ }
4488+ if (!(move->active & fm_mask))
4489+ return 0;
4490+ set_props(ge->gin, state, move, frame);
4491+ gru_event(ge, state->gid, move, state->prop, state->nprop);
4492+ return 1;
4493+}
4494
4495=== added file 'src/v2/gestures-rotate.c'
4496--- src/v2/gestures-rotate.c 1970-01-01 00:00:00 +0000
4497+++ src/v2/gestures-rotate.c 2012-01-25 15:53:29 +0000
4498@@ -0,0 +1,130 @@
4499+/*****************************************************************************
4500+ *
4501+ * grail - Gesture Recognition And Instantiation Library
4502+ *
4503+ * Copyright (C) 2010-2011 Canonical Ltd.
4504+ *
4505+ * This program is free software: you can redistribute it and/or modify it
4506+ * under the terms of the GNU General Public License as published by the
4507+ * Free Software Foundation, either version 3 of the License, or (at your
4508+ * option) any later version.
4509+ *
4510+ * This program is distributed in the hope that it will be useful, but
4511+ * WITHOUT ANY WARRANTY; without even the implied warranty of
4512+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
4513+ * General Public License for more details.
4514+ *
4515+ * You should have received a copy of the GNU General Public License along
4516+ * with this program. If not, see <http://www.gnu.org/licenses/>.
4517+ *
4518+ ****************************************************************************/
4519+
4520+#include "grail-recognizer.h"
4521+#include <math.h>
4522+#include <stdio.h>
4523+
4524+static const int getype[DIM_TOUCH + 1] = {
4525+ 0,
4526+ 0,
4527+ GRAIL_TYPE_ROTATE2,
4528+ GRAIL_TYPE_ROTATE3,
4529+ GRAIL_TYPE_ROTATE4,
4530+ GRAIL_TYPE_ROTATE5,
4531+};
4532+
4533+static const int fm_mask = 0x08;
4534+
4535+static void set_props(const struct gesture_inserter *gin,
4536+ struct combo_model *s, const struct move_model *m,
4537+ const struct utouch_frame *frame)
4538+{
4539+ s->prop[GRAIL_PROP_ROTATE_DA] = m->fm[FM_A].action_delta;
4540+ s->prop[GRAIL_PROP_ROTATE_VA] = m->fm[FM_A].velocity;
4541+ s->prop[GRAIL_PROP_ROTATE_A] = m->fm[FM_A].value;
4542+ s->prop[GRAIL_PROP_ROTATE_X] = m->fm[FM_X].value;
4543+ s->prop[GRAIL_PROP_ROTATE_Y] = m->fm[FM_Y].value;
4544+ s->nprop = 5;
4545+ s->nprop += gin_add_contact_props(gin, s->prop + s->nprop, frame);
4546+}
4547+
4548+int gru_rotate(struct grail *ge,
4549+ const struct utouch_frame *frame)
4550+{
4551+ struct gesture_recognizer *gru = ge->gru;
4552+ struct combo_model *state = &gru->rotate;
4553+ struct move_model *move = &gru->move;
4554+ int mask = state->active ? (move->active & fm_mask) : fm_mask;
4555+ if (!move->multi && !move->single) {
4556+ if (state->active) {
4557+ gru_end(ge, state->gid, move,
4558+ state->prop, state->nprop);
4559+ state->active = 0;
4560+ }
4561+ return 0;
4562+ }
4563+ if ((move->timeout & fm_mask) == fm_mask) {
4564+ if (state->active) {
4565+ gin_gid_timeout(ge, state->gid);
4566+ }
4567+ }
4568+ if (!(move->tickle & mask))
4569+ return 0;
4570+ if (!state->active) {
4571+ int type = getype[move->ntouch];
4572+ if (!type)
4573+ return 0;
4574+ state->gid = gin_gid_begin(ge, type, PRIO_GESTURE, frame);
4575+ state->active = 1;
4576+ }
4577+ if (!(move->active & fm_mask))
4578+ return 0;
4579+ set_props(ge->gin, state, move, frame);
4580+ gru_event(ge, state->gid, move, state->prop, state->nprop);
4581+ return 1;
4582+}
4583+
4584+int gru_winrotate(struct grail *ge,
4585+ const struct utouch_frame *frame)
4586+{
4587+ struct gesture_recognizer *gru = ge->gru;
4588+ struct combo_model *state = &gru->winrotate;
4589+ struct move_model *move = &gru->move;
4590+ int mask = state->active ? (move->active & fm_mask) : fm_mask;
4591+ if (!move->multi) {
4592+ if (state->active && out_of_bounds(state, move)) {
4593+ gru_end(ge, state->gid, move,
4594+ state->prop, state->nprop);
4595+ state->active = 0;
4596+ }
4597+ return 0;
4598+ }
4599+ if ((move->timeout & fm_mask) == fm_mask) {
4600+ if (state->active) {
4601+ gin_gid_timeout(ge, state->gid);
4602+ }
4603+ }
4604+ if (!(move->tickle & mask))
4605+ return 0;
4606+ if (!state->active) {
4607+ if (move->ntouch == 4) {
4608+ state->gid = gin_gid_begin(ge, GRAIL_TYPE_MROTATE,
4609+ PRIO_META, frame);
4610+ state->mintouch = 2;
4611+ state->maxtouch = 4;
4612+ state->active = 1;
4613+ } else if (move->ntouch == 3) {
4614+ state->gid = gin_gid_begin(ge, GRAIL_TYPE_EROTATE,
4615+ PRIO_ENV, frame);
4616+ state->mintouch = 2;
4617+ state->maxtouch = 3;
4618+ state->active = 1;
4619+ } else {
4620+ return 0;
4621+ }
4622+ }
4623+ if (!(move->active & fm_mask))
4624+ return 0;
4625+ set_props(ge->gin, state, move, frame);
4626+ gru_event(ge, state->gid, move, state->prop, state->nprop);
4627+ return 1;
4628+}
4629
4630=== added file 'src/v2/gestures-tapping.c'
4631--- src/v2/gestures-tapping.c 1970-01-01 00:00:00 +0000
4632+++ src/v2/gestures-tapping.c 2012-01-25 15:53:29 +0000
4633@@ -0,0 +1,100 @@
4634+/*****************************************************************************
4635+ *
4636+ * grail - Gesture Recognition And Instantiation Library
4637+ *
4638+ * Copyright (C) 2010-2011 Canonical Ltd.
4639+ *
4640+ * This program is free software: you can redistribute it and/or modify it
4641+ * under the terms of the GNU General Public License as published by the
4642+ * Free Software Foundation, either version 3 of the License, or (at your
4643+ * option) any later version.
4644+ *
4645+ * This program is distributed in the hope that it will be useful, but
4646+ * WITHOUT ANY WARRANTY; without even the implied warranty of
4647+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
4648+ * General Public License for more details.
4649+ *
4650+ * You should have received a copy of the GNU General Public License along
4651+ * with this program. If not, see <http://www.gnu.org/licenses/>.
4652+ *
4653+ ****************************************************************************/
4654+
4655+#include "grail-recognizer.h"
4656+#include <math.h>
4657+
4658+static const int fm_mask = 0x07;
4659+
4660+static void set_props(const struct gesture_inserter *gin,
4661+ struct tapping_model *s, const struct move_model *m,
4662+ const struct utouch_frame *frame)
4663+{
4664+ s->prop[GRAIL_PROP_TAP_DT] = m->time - s->start;
4665+ s->prop[GRAIL_PROP_TAP_X] = m->fm[FM_X].value;
4666+ s->prop[GRAIL_PROP_TAP_Y] = m->fm[FM_Y].value;
4667+ s->nprop = 3;
4668+ s->nprop += gin_add_contact_props(gin, s->prop + s->nprop, frame);
4669+}
4670+
4671+int gru_tapping(struct grail *ge,
4672+ const struct utouch_frame *frame)
4673+{
4674+ struct gesture_recognizer *gru = ge->gru;
4675+ struct tapping_model *state = &gru->tapping;
4676+ struct move_model *move = &gru->move;
4677+ state->tap = 0;
4678+ if (frame->num_active && !frame->prev->num_active) {
4679+ state->mintouch = 0;
4680+ state->maxtouch = 0;
4681+ }
4682+ if (move->ntouch > state->maxtouch) {
4683+ if (state->active) {
4684+ gin_gid_discard(ge, state->gid);
4685+ state->active = 0;
4686+ }
4687+ state->start = move->time;
4688+ state->maxtouch = move->ntouch;
4689+ set_props(ge->gin, state, move, frame);
4690+ if (state->maxtouch <= 5) {
4691+ int type = GRAIL_TYPE_TAP1 + state->maxtouch - 1;
4692+ state->gid = gin_gid_begin(ge, type, PRIO_TAP, frame);
4693+ state->active = 1;
4694+ }
4695+ return 0;
4696+ }
4697+ if (!state->active) {
4698+ state->mintouch = move->ntouch;
4699+ state->maxtouch = move->ntouch;
4700+ return 0;
4701+ }
4702+ if (move->ntouch <= state->mintouch) {
4703+ int x = state->prop[GRAIL_PROP_TAP_X];
4704+ int y = state->prop[GRAIL_PROP_TAP_Y];
4705+ int t = move->time - state->start;
4706+ if (t > move->fm[FM_X].bar_ms) {
4707+ gin_gid_discard(ge, state->gid);
4708+ state->mintouch = move->ntouch;
4709+ state->maxtouch = move->ntouch;
4710+ state->active = 0;
4711+ return 0;
4712+ }
4713+ state->tap = state->maxtouch;
4714+ state->prop[GRAIL_PROP_TAP_DT] = t;
4715+ gin_gid_event(ge, state->gid, x, y, state->maxtouch,
4716+ state->prop, state->nprop, 1);
4717+ state->mintouch = move->ntouch;
4718+ state->maxtouch = move->ntouch;
4719+ state->active = 0;
4720+ return 1;
4721+ }
4722+ if (!move->ntouch)
4723+ return 0;
4724+ state->prop[GRAIL_PROP_TAP_DT] = move->time - state->start;
4725+ if ((move->active & fm_mask) ||
4726+ move->time - state->start > move->fm[FM_X].bar_ms) {
4727+ gin_gid_discard(ge, state->gid);
4728+ state->mintouch = move->ntouch;
4729+ state->maxtouch = move->ntouch;
4730+ state->active = 0;
4731+ }
4732+ return 0;
4733+}
4734
4735=== added file 'src/v2/gestures-touch.c'
4736--- src/v2/gestures-touch.c 1970-01-01 00:00:00 +0000
4737+++ src/v2/gestures-touch.c 2012-01-25 15:53:29 +0000
4738@@ -0,0 +1,98 @@
4739+/*****************************************************************************
4740+ *
4741+ * grail - Gesture Recognition And Instantiation Library
4742+ *
4743+ * Copyright (C) 2010 Canonical Ltd.
4744+ * Copyright (C) 2010 Henrik Rydberg <rydberg@bitmath.org>
4745+ *
4746+ * This program is free software: you can redistribute it and/or modify it
4747+ * under the terms of the GNU General Public License as published by the
4748+ * Free Software Foundation, either version 3 of the License, or (at your
4749+ * option) any later version.
4750+ *
4751+ * This program is distributed in the hope that it will be useful, but
4752+ * WITHOUT ANY WARRANTY; without even the implied warranty of
4753+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
4754+ * General Public License for more details.
4755+ *
4756+ * You should have received a copy of the GNU General Public License along
4757+ * with this program. If not, see <http://www.gnu.org/licenses/>.
4758+ *
4759+ ****************************************************************************/
4760+
4761+#include "grail-recognizer.h"
4762+#include <math.h>
4763+#include <stdio.h>
4764+
4765+static const int getype[DIM_TOUCH + 1] = {
4766+ -1,
4767+ GRAIL_TYPE_TOUCH1,
4768+ GRAIL_TYPE_TOUCH2,
4769+ GRAIL_TYPE_TOUCH3,
4770+ GRAIL_TYPE_TOUCH4,
4771+ GRAIL_TYPE_TOUCH5,
4772+};
4773+
4774+int gru_touch(struct grail *ge,
4775+ const struct utouch_frame *frame)
4776+{
4777+ struct gesture_recognizer *gru = ge->gru;
4778+ struct combo_model *state = &gru->touch;
4779+ struct move_model *move = &gru->move;
4780+ if (frame->slot_revision != frame->prev->slot_revision) {
4781+ if (state->active) {
4782+ gru_end(ge, state->gid, move,
4783+ state->prop, state->nprop);
4784+ state->active = 0;
4785+ }
4786+ }
4787+ if (!state->active) {
4788+ int type = getype[move->ntouch];
4789+ if (type <= 0)
4790+ return 0;
4791+ state->gid = gin_gid_begin(ge, type, -PRIO_GESTURE, frame);
4792+ state->active = 1;
4793+ }
4794+ if (move->time - move->fm[FM_X].original_ms <= move->fm[FM_X].hold_ms)
4795+ return 0;
4796+ state->nprop = gin_add_contact_props(ge->gin, state->prop, frame);
4797+ gru_event(ge, state->gid, move, state->prop, state->nprop);
4798+ return 1;
4799+}
4800+
4801+int gru_wintouch(struct grail *ge,
4802+ const struct utouch_frame *frame)
4803+{
4804+ struct gesture_recognizer *gru = ge->gru;
4805+ struct combo_model *state = &gru->wintouch;
4806+ struct move_model *move = &gru->move;
4807+ if (frame->slot_revision != frame->prev->slot_revision) {
4808+ if (state->active && out_of_bounds(state, move)) {
4809+ gru_end(ge, state->gid, move,
4810+ state->prop, state->nprop);
4811+ state->active = 0;
4812+ }
4813+ }
4814+ if (!state->active) {
4815+ if (move->ntouch == 4) {
4816+ state->gid = gin_gid_begin(ge, GRAIL_TYPE_MTOUCH,
4817+ -PRIO_META, frame);
4818+ state->mintouch = 1;
4819+ state->maxtouch = 4;
4820+ state->active = 1;
4821+ } else if (move->ntouch == 3) {
4822+ state->gid = gin_gid_begin(ge, GRAIL_TYPE_ETOUCH,
4823+ -PRIO_ENV, frame);
4824+ state->mintouch = 1;
4825+ state->maxtouch = 3;
4826+ state->active = 1;
4827+ } else {
4828+ return 0;
4829+ }
4830+ }
4831+ if (move->time - move->fm[FM_X].original_ms <= move->fm[FM_X].hold_ms)
4832+ return 0;
4833+ state->nprop = gin_add_contact_props(ge->gin, state->prop, frame);
4834+ gru_event(ge, state->gid, move, state->prop, state->nprop);
4835+ return 1;
4836+}
4837
4838=== added file 'src/v2/grail-api.c'
4839--- src/v2/grail-api.c 1970-01-01 00:00:00 +0000
4840+++ src/v2/grail-api.c 2012-01-25 15:53:29 +0000
4841@@ -0,0 +1,328 @@
4842+/*****************************************************************************
4843+ *
4844+ * grail - Gesture Recognition And Instantiation Library
4845+ *
4846+ * Copyright (C) 2010-2011 Canonical Ltd.
4847+ *
4848+ * This program is free software: you can redistribute it and/or modify it
4849+ * under the terms of the GNU General Public License as published by the
4850+ * Free Software Foundation, either version 3 of the License, or (at your
4851+ * option) any later version.
4852+ *
4853+ * This program is distributed in the hope that it will be useful, but
4854+ * WITHOUT ANY WARRANTY; without even the implied warranty of
4855+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
4856+ * General Public License for more details.
4857+ *
4858+ * You should have received a copy of the GNU General Public License along
4859+ * with this program. If not, see <http://www.gnu.org/licenses/>.
4860+ *
4861+ ****************************************************************************/
4862+
4863+#include "grail-impl.h"
4864+#include "grail-inserter.h"
4865+#include "grail-recognizer.h"
4866+#include <string.h>
4867+#include <stdio.h>
4868+#include <unistd.h>
4869+#include <fcntl.h>
4870+#include <malloc.h>
4871+#include <errno.h>
4872+#include <stdlib.h>
4873+#include <sys/stat.h>
4874+
4875+#define DIM_FRAMES 100
4876+#define FRAME_RATE 100
4877+
4878+unsigned int GRAIL_PUBLIC grail_get_version(void)
4879+{
4880+ return GRAIL_VERSION;
4881+}
4882+
4883+int GRAIL_PUBLIC grail_open(struct grail *ge, int fd)
4884+{
4885+ struct grail_impl *x;
4886+ struct stat fs;
4887+ int ret;
4888+
4889+ ret = fstat(fd, &fs);
4890+ if (ret)
4891+ return ret;
4892+
4893+ x = calloc(1, sizeof(*x));
4894+ if (!x)
4895+ return -ENOMEM;
4896+
4897+ if (!fs.st_rdev)
4898+ x->fptest = fdopen(fd, "r");
4899+
4900+ x->evemu = evemu_new(x->fptest ? "fptest" : 0);
4901+ if (!x->evemu) {
4902+ ret = -ENOMEM;
4903+ goto freemem;
4904+ }
4905+ if (x->fptest)
4906+ ret = evemu_read(x->evemu, x->fptest) <= 0;
4907+ else
4908+ ret = evemu_extract(x->evemu, fd);
4909+ if (ret)
4910+ goto freemem;
4911+ if (!utouch_frame_is_supported_mtdev(x->evemu)) {
4912+ ret = -ENODEV;
4913+ goto freemem;
4914+ }
4915+
4916+ if (!x->fptest) {
4917+ x->mtdev = mtdev_new_open(fd);
4918+ if (!x->mtdev) {
4919+ ret = -ENOMEM;
4920+ goto freemem;
4921+ }
4922+ }
4923+ x->fh = utouch_frame_new_engine(DIM_FRAMES, DIM_TOUCH, FRAME_RATE);
4924+ if (!x->fh) {
4925+ ret = -ENOMEM;
4926+ goto freedev;
4927+ }
4928+ ret = utouch_frame_init_mtdev(x->fh, x->evemu);
4929+ if (ret)
4930+ goto freeframe;
4931+
4932+ ge->impl = x;
4933+
4934+ ret = gin_init(ge);
4935+ if (ret)
4936+ goto freeframe;
4937+
4938+ ret = gru_init(ge);
4939+ if (ret)
4940+ goto freegin;
4941+
4942+ return 0;
4943+ freegin:
4944+ gin_destroy(ge);
4945+ freeframe:
4946+ utouch_frame_delete_engine(x->fh);
4947+ freedev:
4948+ if (x->mtdev)
4949+ mtdev_close_delete(x->mtdev);
4950+ freemem:
4951+ evemu_delete(x->evemu);
4952+ if (x->fptest)
4953+ fclose(x->fptest);
4954+ free(x);
4955+ ge->impl = 0;
4956+ return ret;
4957+}
4958+
4959+void GRAIL_PUBLIC grail_close(struct grail *ge, int fd)
4960+{
4961+ struct grail_impl *x = ge->impl;
4962+ gru_destroy(ge);
4963+ gin_destroy(ge);
4964+ utouch_frame_delete_engine(x->fh);
4965+ if (x->mtdev)
4966+ mtdev_close_delete(x->mtdev);
4967+ evemu_delete(x->evemu);
4968+ if (x->fptest)
4969+ fclose(x->fptest);
4970+ free(x);
4971+ ge->impl = 0;
4972+}
4973+
4974+int GRAIL_PUBLIC grail_idle(struct grail *ge, int fd, int ms)
4975+{
4976+ struct grail_impl *x = ge->impl;
4977+ if (x->fptest)
4978+ return 0;
4979+ if (x->mtdev)
4980+ return mtdev_idle(x->mtdev, fd, ms);
4981+ return 1;
4982+}
4983+
4984+void GRAIL_PUBLIC grail_get_units(const struct grail *ge,
4985+ struct grail_coord *min, struct grail_coord *max)
4986+{
4987+ struct utouch_surface *s = utouch_frame_get_surface(ge->impl->fh);
4988+ min->x = s->min_x;
4989+ min->y = s->min_y;
4990+ max->x = s->max_x;
4991+ max->y = s->max_y;
4992+}
4993+
4994+const struct utouch_frame GRAIL_PUBLIC *
4995+grail_get_contact_frame(const struct grail *ge)
4996+{
4997+ return ge->impl->touch;
4998+}
4999+
5000+static void flush_events(struct grail *ge)
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches