Merge lp:~dandrader/geis/lp984069 into lp:geis
- lp984069
- Merge into trunk
Status: | Merged |
---|---|
Merged at revision: | 258 |
Proposed branch: | lp:~dandrader/geis/lp984069 |
Merge into: | lp:geis |
Diff against target: |
1242 lines (+1068/-27) 14 files modified
.bzrignore (+1/-0) configure.ac (+5/-0) include/geis/geis.h (+5/-0) libutouch-geis/backend/grail/geis_grail_backend.c (+18/-8) m4/gtest.m4 (+51/-0) testsuite/Makefile.am (+1/-1) testsuite/geis2/Makefile.am (+39/-9) testsuite/geis2/gtest_gbe_direct_touch_coords.cpp (+295/-0) testsuite/geis2/gtest_grail_backend.cpp (+134/-0) testsuite/geis2/gtest_grail_backend.h (+52/-0) testsuite/gtest/Makefile.am (+14/-9) testsuite/x11_mocks/Makefile.am (+13/-0) testsuite/x11_mocks/x11_mocks.c (+406/-0) testsuite/x11_mocks/x11_mocks.h (+34/-0) |
To merge this branch: | bzr merge lp:~dandrader/geis/lp984069 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Chase Douglas (community) | Approve | ||
Stephen M. Webb (community) | Needs Fixing | ||
Review via email: mp+102337@code.launchpad.net |
Commit message
Description of the change
GeisTouches from direct devices should be in window coordinates. Have this also documented in geis.h
The fix for bug #978378 in Unity depends on it.
This should be tested by someone with a touchscreen device along with the fix for bug #978378 (lp:~dandrader/unity/direct_device) to verify that those modifications indeed get bug #978378 fixed.
Stephen M. Webb (bregma) wrote : | # |
Chase Douglas (chasedouglas) wrote : | # |
I tested the branch and everything seems to work appropriately. In the unity branch, the unity bug #978378 seems to be fixed.
We just need tests in geis now.
- 253. By Stephen M. Webb
-
Added an API for setting and getting grail tuning properties.
- 254. By Stephen M. Webb
-
Added a compile-time sentinel check to variadic calls in the API.
Daniel d'Andrada (dandrader) wrote : | # |
It now has a unit test.
Daniel d'Andrada (dandrader) wrote : | # |
I would make it use Google Test istead of Check Framework but in utouch-geis GTest is quite entangled with xorg-gtest and integration tests (ENABLE_
Chase Douglas (chasedouglas) wrote : | # |
As far as I understand, the gtest issue is merely that we need to make the autotools stuff know about gtest for unit testing. I would prefer to fix that issue now and continue to use gtest.
Otherwise, I'm ok with this for now. I think we may want to split the mock out into a separate project in the future, maybe using a mock framework like google-mock to make things easier.
- 255. By Chase Douglas
-
Merge fixes for radius and position delta calculations
- 256. By Chase Douglas
-
Merge fix for GeisSubscriptio
nFlags usage when compiling with g++
Daniel d'Andrada (dandrader) wrote : | # |
Took libgtest.a out of libgtest_geis.a and made the regression test of this bug GTest based instead of Check based.
Ready for a new review.
Chase Douglas (chasedouglas) wrote : | # |
* xorg-gtest.m4 shouldn't be modified. It comes from upstream xorg-gtest and may be replaced by a newer version from an updated xorg-gtest automatically by aclocal --install. IIRC, I think it may also be always replaced by our packaging since it uses aclocal --install --force.
Since _CHECK_GTEST is meant to be an internal implementation detail of xorg-gtest.m4, I suggest copying it to a new file m4/gtest.m4 and removing the leading underscore.
* libgtest_
* libgtest_
* libgtest doesn't need to be built with --std=c++0x. xorg-gtest doesn't need to built with it either. I also don't know why TEST_ROOT_DIR is defined for both gtest libs. I think it was a copy/paste error.
* PRINT_FAILURE_
* I like the idea of MOCK_PRINT. I think it duplicates the geis logging, though. Why not use geis_debug()? I know this means you can't enable mock printouts without geis debug printouts, but I think that's ok. If you're debugging at this level you might be setting GEIS_DEBUG=3 anyway. If you have a standard format where something like "XMOCK: " is prepended to the message, it will be easy to grep or grep -v on it.
Stephen M. Webb (bregma) wrote : | # |
(1) m4/xorg-gtest.m4 is actually a convenience copy of a source file belonging to another package and will likely be overwritten at build time. I would suggest the CHECK_GTEST macro be hoisted into its own .m4 file so it doesn't get trampled: it's already renamed so there shouldn't be a conflict.
(2) Not sure why you did all the fancy wrangling in testsuite/
(3) Why reorganize testsuite/
(4) If you're changing testsuite libraries around anyway, would it be possible to consolidate all support libraries used in the testsuite (gtest, mocks) into a single subdirectory? It would simplify the Makefile.ams used in the various test suites. Feel free to argue this.
Stephen M. Webb (bregma) wrote : | # |
* I like the idea of MOCK_PRINT. I think it duplicates the geis logging, though. Why not use geis_debug()? I know this means you can't enable mock printouts without geis debug printouts, but I think that's ok. If you're debugging at this level you might be setting GEIS_DEBUG=3 anyway. If you have a standard format where something like "XMOCK: " is prepended to the message, it will be easy to grep or grep -v on it.
geis_debug() is not a public symbol exported from libutouch-geis.so. It is not available for any part of the testsuite except the libutouch tests (which are internal unit tests).
Chase Douglas (chasedouglas) wrote : | # |
On 04/23/2012 02:17 PM, Stephen M. Webb wrote:
> * I like the idea of MOCK_PRINT. I think it duplicates the geis logging, though. Why not use geis_debug()? I know this means you can't enable mock printouts without geis debug printouts, but I think that's ok. If you're debugging at this level you might be setting GEIS_DEBUG=3 anyway. If you have a standard format where something like "XMOCK: " is prepended to the message, it will be easy to grep or grep -v on it.
>
> geis_debug() is not a public symbol exported from libutouch-geis.so. It is not available for any part of the testsuite except the libutouch tests (which are internal unit tests).
Ok. What about printing if an env var is set, like MOCK_DEBUG? I'm not a
big fan of preprocessor macros enabling optional functionality. It's not
easy to figure out whether something has been compiled with the
functionality or not.
Stephen M. Webb (bregma) wrote : | # |
> Ok. What about printing if an env var is set, like MOCK_DEBUG? I'm not a
> big fan of preprocessor macros enabling optional functionality. It's not
> easy to figure out whether something has been compiled with the
> functionality or not.
+1
Daniel d'Andrada (dandrader) wrote : | # |
> On 04/23/2012 02:17 PM, Stephen M. Webb wrote:
> > * I like the idea of MOCK_PRINT. I think it duplicates the geis logging,
> though. Why not use geis_debug()? I know this means you can't enable mock
> printouts without geis debug printouts, but I think that's ok. If you're
> debugging at this level you might be setting GEIS_DEBUG=3 anyway. If you have
> a standard format where something like "XMOCK: " is prepended to the message,
> it will be easy to grep or grep -v on it.
> >
> > geis_debug() is not a public symbol exported from libutouch-geis.so. It is
> not available for any part of the testsuite except the libutouch tests (which
> are internal unit tests).
>
> Ok. What about printing if an env var is set, like MOCK_DEBUG? I'm not a
> big fan of preprocessor macros enabling optional functionality. It's not
> easy to figure out whether something has been compiled with the
> functionality or not.
Me neither, but that was the easiest way and I didn't think it was worth to invest time into making a fully fledged solution.
Daniel d'Andrada (dandrader) wrote : | # |
> (3) Why reorganize testsuite/
> targets go at the top (eg. *_PROGRAMS) and the detailed rules for building
> them come later, rather than the other way around. Granted, that tradition
> started because automake required it, but following convention makes it easier
> from someone who sees a lot of Makefile.ams to follow unfamiliar code. Could
> you make your reasoning for this explicit?
I like when all code regarding a library/program is together in a single block instead of intertwined with code for other libraries/programs. I find that arrangement easier to read and maintain. But as with coding style, it's mostly a matter of personal taste.
Daniel d'Andrada (dandrader) wrote : | # |
> (2) Not sure why you did all the fancy wrangling in
> testsuite/
> including the xorg-gtest sources conditionally on ENABLE_
> Could you make your reasoning explicit?
That's another way of doing it. But I prefer the separation method since "That way we can have tests that depend on gtest but not on xorg-gtest" and therefore tests can link against only what they are going to use. Tests that use xmock will use gtest but never xorg-gtest, evemu or the fixtures included in libgtest_geis.
Daniel d'Andrada (dandrader) wrote : | # |
> (4) If you're changing testsuite libraries around anyway, would it be possible
> to consolidate all support libraries used in the testsuite (gtest, mocks) into
> a single subdirectory? It would simplify the Makefile.ams used in the various
> test suites. Feel free to argue this.
I personally find it a bit messy to have the sources of several separate, independent, binaries (programs of libraries) living together in the same directory. It can easily result in a cluttered directory listing and Makefile.am.
Stephen M. Webb (bregma) wrote : | # |
On 04/24/2012 09:52 AM, Daniel d'Andrada wrote:
>> (2) Not sure why you did all the fancy wrangling in
>> testsuite/
>> including the xorg-gtest sources conditionally on ENABLE_
>> Could you make your reasoning explicit?
>
> That's another way of doing it. But I prefer the separation method since "That way we can have tests that depend on gtest but not on xorg-gtest" and therefore tests can link against only what they are going to use. Tests that use xmock will use gtest but never xorg-gtest, evemu or the fixtures included in libgtest_geis.
But you know that for the last 40 years or so linkers only pull objects out of archives if they're used, so the only
difference between using a single library and using multiple libraries is one of increased maintenance cost and
confusion about which library to use?
Daniel d'Andrada (dandrader) wrote : | # |
> On 04/24/2012 09:52 AM, Daniel d'Andrada wrote:
> >> (2) Not sure why you did all the fancy wrangling in
> >> testsuite/
> >> including the xorg-gtest sources conditionally on ENABLE_
> >> Could you make your reasoning explicit?
> >
> > That's another way of doing it. But I prefer the separation method since
> "That way we can have tests that depend on gtest but not on xorg-gtest" and
> therefore tests can link against only what they are going to use. Tests that
> use xmock will use gtest but never xorg-gtest, evemu or the fixtures included
> in libgtest_geis.
>
> But you know that for the last 40 years or so linkers only pull objects out of
> archives if they're used, so the only
> difference between using a single library and using multiple libraries is one
> of increased maintenance cost and
> confusion about which library to use?
I can do single library approach, no problem.
Daniel d'Andrada (dandrader) wrote : | # |
Updated according to comments.
Ready for a new review round.
- 257. By Daniel d'Andrada
-
GeisTouches from direct devices should be in window coordinates
GeisTouches provided by gesture events (GEIS_EVENT_
GESTURE_ BEGIN,
GEIS_EVENT_GESTURE_ UPDATE and GEIS_EVENT_ GESTURE_ END) should be in window
coordinates if they come from a direct device (e.g. touchscreens) and in
input device coordinates when from indirect devices (e.g. touchpads/trackpads) . Have this also documented in geis.h
They were coming always in device coordinates.
- 258. By Daniel d'Andrada
-
Make it possible to have gtest without integration tests and xorg-gtest
That way we can have unit and functional tests using gtest independently
of whether integration tests will be built or whether xorg-gtest is present. - 259. By Daniel d'Andrada
-
Adding X11 mockups
- 260. By Daniel d'Andrada
-
Organize the Makefile a bit
Bring together the code for each binary in blocks instead of having them intertwined
- 261. By Daniel d'Andrada
-
Regression test for lp984069
Chase Douglas (chasedouglas) wrote : | # |
* The --std=c++0x flags are still used.
* PRINT_FAILURE_
I think everything else I commented on has been addressed.
Daniel d'Andrada (dandrader) wrote : | # |
> * The --std=c++0x flags are still used.
>
> * PRINT_FAILURE_
>
> I think everything else I commented on has been addressed.
Ah, yeah, I forgot those. Sorry for that.
- 262. By Daniel d'Andrada
-
GTest doesn't need --std=c++0x
- 263. By Daniel d'Andrada
-
ADD_FAILURE() already prints the current file name and line number
- 264. By Daniel d'Andrada
-
Stop immediately if subscription creation fails
Daniel d'Andrada (dandrader) wrote : | # |
Updated.
ADD_FAILURE() does print the file name and line number but it does *not* return. Therefore a wrapping macro is still needed. So I removed the printf() command and renamed the macro.
I've removed the --std=c++0x flag from gtest
Chase Douglas (chasedouglas) wrote : | # |
On 04/24/2012 11:59 AM, Daniel d'Andrada wrote:
> ADD_FAILURE() does print the file name and line number but it does *not* return. Therefore a wrapping macro is still needed. So I removed the printf() command and renamed the macro.
Ahh, I remembered wrong. You want FAIL() << [message]; It's just like
ADD_FAILURE() except that it causes the function to return. It's
analogous to ASSERT_*() vs EXPECT_*().
http://
> I've removed the --std=c++0x flag from gtest
gtest_geis2_
Stephen M. Webb (bregma) wrote : | # |
"make distcheck" fails (there should be no nodist_ prefix on the SOURCES variable in testsuite/
Daniel d'Andrada (dandrader) wrote : | # |
> On 04/24/2012 11:59 AM, Daniel d'Andrada wrote:
> > ADD_FAILURE() does print the file name and line number but it does *not*
> return. Therefore a wrapping macro is still needed. So I removed the printf()
> command and renamed the macro.
>
> Ahh, I remembered wrong. You want FAIL() << [message]; It's just like
> ADD_FAILURE() except that it causes the function to return. It's
> analogous to ASSERT_*() vs EXPECT_*().
>
> http://
FAIL(), like ASSERT_*(), can only be used from within functions that return void. That's why I have to stick with ADD_FAILURE().
>
> > I've removed the --std=c++0x flag from gtest
>
> gtest_geis2_
I needs --std=c++0x because it uses c++0x stuff (like nullptr and range-based for loops)
Daniel d'Andrada (dandrader) wrote : | # |
> "make distcheck" fails (there should be no nodist_ prefix on the SOURCES
> variable in testsuite/
Fixed.
- 265. By Daniel d'Andrada
-
sources of x11_mocks are distributed
Chase Douglas (chasedouglas) : | # |
Chase Douglas (chasedouglas) wrote : | # |
On 04/24/2012 12:31 PM, Daniel d'Andrada wrote:
>> On 04/24/2012 11:59 AM, Daniel d'Andrada wrote:
>>> ADD_FAILURE() does print the file name and line number but it does *not*
>> return. Therefore a wrapping macro is still needed. So I removed the printf()
>> command and renamed the macro.
>>
>> Ahh, I remembered wrong. You want FAIL() << [message]; It's just like
>> ADD_FAILURE() except that it causes the function to return. It's
>> analogous to ASSERT_*() vs EXPECT_*().
>>
>> http://
>
> FAIL(), like ASSERT_*(), can only be used from within functions that return void. That's why I have to stick with ADD_FAILURE().
Ahh, yes, that would be an issue.
This is a bit bike-shedding, but I would prefer to unroll the macro
since it's two simple lines. I think it would make the code easier to
read. However, I'm ok with it as is.
>>
>>> I've removed the --std=c++0x flag from gtest
>>
>> gtest_geis2_
>
> I needs --std=c++0x because it uses c++0x stuff (like nullptr and range-based for loops)
Ok, I didn't realize that.
- 266. By Daniel d'Andrada
-
We don't need a macro anymore. Wrapped code is too simple
Preview Diff
1 | === modified file '.bzrignore' |
2 | --- .bzrignore 2012-04-11 16:18:03 +0000 |
3 | +++ .bzrignore 2012-04-24 19:38:21 +0000 |
4 | @@ -48,4 +48,5 @@ |
5 | TAGS |
6 | testsuite/geistest/geistest |
7 | testsuite/libutouch-geis/*.xml |
8 | +testsuite/geis2/gtest_geis2_grail_backend |
9 | tools/geis-server/geis-server |
10 | |
11 | === modified file 'configure.ac' |
12 | --- configure.ac 2012-04-12 17:13:41 +0000 |
13 | +++ configure.ac 2012-04-24 19:38:21 +0000 |
14 | @@ -97,6 +97,10 @@ |
15 | [enable_integration_tests=$enableval], |
16 | [enable_integration_tests=auto]) |
17 | |
18 | +# Check for Google C++ Testing Framework |
19 | +CHECK_GTEST() |
20 | +AM_CONDITIONAL([HAVE_GTEST], [test "x$have_gtest" = xyes]) |
21 | + |
22 | have_xorg_gtest=no |
23 | AS_IF([test "x$enable_integration_tests" != xno], |
24 | [CHECK_XORG_GTEST( |
25 | @@ -132,6 +136,7 @@ |
26 | testsuite/geis2/Makefile |
27 | testsuite/geis1/Makefile |
28 | testsuite/geistest/Makefile |
29 | + testsuite/x11_mocks/Makefile |
30 | examples/Makefile |
31 | python/Makefile |
32 | tools/Makefile |
33 | |
34 | === modified file 'include/geis/geis.h' |
35 | --- include/geis/geis.h 2012-04-20 19:14:59 +0000 |
36 | +++ include/geis/geis.h 2012-04-24 19:38:21 +0000 |
37 | @@ -2061,6 +2061,11 @@ |
38 | * is capable of reporting differing sets of touch attributes, so there is no |
39 | * guarantee that any or all of the defined touch attributes will bre present. |
40 | * |
41 | + * If the touch comes from a direct device (see |
42 | + * GEIS_DEVICE_ATTRIBUTE_DIRECT_TOUCH) its position (x and y attributes) will |
43 | + * be in window coordinates, otherwise it will be in the input device's own |
44 | + * coordinate system. |
45 | + * |
46 | * @{ |
47 | * |
48 | * @def GEIS_TOUCH_ATTRIBUTE_ID |
49 | |
50 | === modified file 'libutouch-geis/backend/grail/geis_grail_backend.c' |
51 | --- libutouch-geis/backend/grail/geis_grail_backend.c 2012-04-20 15:00:21 +0000 |
52 | +++ libutouch-geis/backend/grail/geis_grail_backend.c 2012-04-24 19:38:21 +0000 |
53 | @@ -635,19 +635,29 @@ |
54 | focus_y = frame_touch_get_window_y(uftouch); |
55 | } |
56 | |
57 | - GeisFloat fval = frame_touch_get_device_x(uftouch); |
58 | - bboxMinX = fmin(bboxMinX, fval); |
59 | - bboxMaxX = fmax(bboxMaxX, fval); |
60 | + GeisFloat touch_x, touch_y; |
61 | + if (is_touchscreen) |
62 | + { |
63 | + touch_x = frame_touch_get_window_x(uftouch); |
64 | + touch_y = frame_touch_get_window_y(uftouch); |
65 | + } |
66 | + else |
67 | + { |
68 | + touch_x = frame_touch_get_device_x(uftouch); |
69 | + touch_y = frame_touch_get_device_y(uftouch); |
70 | + } |
71 | + |
72 | + bboxMinX = fmin(bboxMinX, touch_x); |
73 | + bboxMaxX = fmax(bboxMaxX, touch_x); |
74 | geis_touch_add_attr(touch, geis_attr_new(GEIS_TOUCH_ATTRIBUTE_X, |
75 | GEIS_ATTR_TYPE_FLOAT, |
76 | - &fval)); |
77 | + &touch_x)); |
78 | |
79 | - fval = frame_touch_get_device_y(uftouch); |
80 | - bboxMinY = fmin(bboxMinY, fval); |
81 | - bboxMaxY = fmax(bboxMaxY, fval); |
82 | + bboxMinY = fmin(bboxMinY, touch_y); |
83 | + bboxMaxY = fmax(bboxMaxY, touch_y); |
84 | geis_touch_add_attr(touch, geis_attr_new(GEIS_TOUCH_ATTRIBUTE_Y, |
85 | GEIS_ATTR_TYPE_FLOAT, |
86 | - &fval)); |
87 | + &touch_y)); |
88 | |
89 | geis_touchset_insert(touchset, touch); |
90 | geis_frame_add_touchid(frame, geis_touch_id(touch)); |
91 | |
92 | === added file 'm4/gtest.m4' |
93 | --- m4/gtest.m4 1970-01-01 00:00:00 +0000 |
94 | +++ m4/gtest.m4 2012-04-24 19:38:21 +0000 |
95 | @@ -0,0 +1,51 @@ |
96 | +# serial 1 |
97 | + |
98 | +# Copyright (C) 2012 Canonical, Ltd. |
99 | +# |
100 | +# Permission is hereby granted, free of charge, to any person obtaining a copy |
101 | +# of this software and associated documentation files (the "Software"), to deal |
102 | +# in the Software without restriction, including without limitation the rights |
103 | +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
104 | +# copies of the Software, and to permit persons to whom the Software is |
105 | +# furnished to do so, subject to the following conditions: |
106 | +# |
107 | +# The above copyright notice and this permission notice (including the next |
108 | +# paragraph) shall be included in all copies or substantial portions of the |
109 | +# Software. |
110 | +# |
111 | +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
112 | +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
113 | +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
114 | +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
115 | +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
116 | +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
117 | +# SOFTWARE. |
118 | + |
119 | +# Checks whether the gtest source is available on the system. Allows for |
120 | +# adjusting the include and source path. Sets have_gtest=yes if the source is |
121 | +# present. Sets GTEST_CPPFLAGS and GTEST_SOURCE to the preprocessor flags and |
122 | +# source location respectively. |
123 | +AC_DEFUN([CHECK_GTEST], |
124 | +[ |
125 | + AC_ARG_WITH([gtest-include-path], |
126 | + [AS_HELP_STRING([--with-gtest-include-path], |
127 | + [location of the Google test headers])], |
128 | + [GTEST_CPPFLAGS="-I$withval"]) |
129 | + |
130 | + AC_ARG_WITH([gtest-source-path], |
131 | + [AS_HELP_STRING([--with-gtest-source-path], |
132 | + [location of the Google test sources, defaults to /usr/src/gtest])], |
133 | + [GTEST_SOURCE="$withval"], |
134 | + [GTEST_SOURCE="/usr/src/gtest"]) |
135 | + |
136 | + GTEST_CPPFLAGS="$GTEST_CPPFLAGS -I$GTEST_SOURCE" |
137 | + |
138 | + AC_CHECK_FILES([$GTEST_SOURCE/src/gtest-all.cc] |
139 | + [$GTEST_SOURCE/src/gtest_main.cc], |
140 | + [have_gtest=yes], |
141 | + [have_gtest=no]) |
142 | + |
143 | + AS_IF([test "x$have_gtest_source" = xyes], |
144 | + [AC_SUBST(GTEST_CPPFLAGS)] |
145 | + [AC_SUBST(GTEST_SOURCE)]) |
146 | +]) # CHECK_GTEST |
147 | |
148 | === modified file 'testsuite/Makefile.am' |
149 | --- testsuite/Makefile.am 2012-03-28 16:54:23 +0000 |
150 | +++ testsuite/Makefile.am 2012-04-24 19:38:21 +0000 |
151 | @@ -20,6 +20,6 @@ |
152 | # 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
153 | # |
154 | |
155 | -SUBDIRS = gtest geis-util libutouch-geis geis2 geis1 geistest |
156 | +SUBDIRS = gtest x11_mocks geis-util libutouch-geis geis2 geis1 geistest |
157 | |
158 | EXTRA_DIST = recordings |
159 | |
160 | === modified file 'testsuite/geis2/Makefile.am' |
161 | --- testsuite/geis2/Makefile.am 2012-04-16 19:12:46 +0000 |
162 | +++ testsuite/geis2/Makefile.am 2012-04-24 19:38:21 +0000 |
163 | @@ -1,19 +1,15 @@ |
164 | # |
165 | -# @file testsuite/geis1/Makefile.am |
166 | -# @brief automake recipe for the geis v1.0 testsuite unit testing directory |
167 | +# @file testsuite/geis2/Makefile.am |
168 | +# @brief automake recipe for the geis v2.0 testsuite testing directory |
169 | # |
170 | |
171 | test_targets = |
172 | + |
173 | +##### check_geis2_api - Tests using Check C testing framework ##### |
174 | + |
175 | if HAVE_CHECK |
176 | test_targets += check_geis2_api |
177 | endif |
178 | -if ENABLE_INTEGRATION_TESTS |
179 | - test_targets += gtest_geis2_api |
180 | -endif |
181 | - |
182 | -TESTS = $(test_targets) |
183 | - |
184 | -check_PROGRAMS = $(test_targets) |
185 | |
186 | check_geis2_api_SOURCES = \ |
187 | check_attr.c \ |
188 | @@ -42,6 +38,38 @@ |
189 | $(top_builddir)/libutouch-geis/libutouch-geis.la \ |
190 | $(CHECK_LIBS) |
191 | |
192 | +#### gtest_geis2_grail_backend - Test for the GRAIL backend of Geis v2 API ##### |
193 | +#### using gtest ##### |
194 | + |
195 | +if HAVE_GTEST |
196 | + test_targets += gtest_geis2_grail_backend |
197 | +endif |
198 | + |
199 | +gtest_geis2_grail_backend_SOURCES = \ |
200 | + gtest_grail_backend.cpp \ |
201 | + gtest_gbe_direct_touch_coords.cpp |
202 | + |
203 | +gtest_geis2_grail_backend_CPPFLAGS = \ |
204 | + --std=c++0x \ |
205 | + -I$(top_srcdir) \ |
206 | + -I$(top_srcdir)/include \ |
207 | + -I$(top_srcdir)/libutouch-geis \ |
208 | + -I$(top_srcdir)/testsuite/gtest \ |
209 | + -I$(top_srcdir)/testsuite/x11_mocks \ |
210 | + -DTEST_ROOT_DIR=\"$(abs_top_srcdir)/testsuite/\" |
211 | + $(GTEST_CFLAGS) |
212 | + |
213 | +gtest_geis2_grail_backend_LDADD = \ |
214 | + $(top_builddir)/testsuite/gtest/libgtest_geis.a \ |
215 | + $(top_builddir)/testsuite/x11_mocks/libx11_mocks.a \ |
216 | + $(top_builddir)/libutouch-geis/libutouch-geis.la |
217 | + |
218 | +#### gtest_geis2_api - Integration tests using xorg-gest and evemu ##### |
219 | + |
220 | +if ENABLE_INTEGRATION_TESTS |
221 | + test_targets += gtest_geis2_api |
222 | +endif |
223 | + |
224 | gtest_geis2_api_SOURCES = \ |
225 | gtest_attrs.cpp \ |
226 | gtest_config.cpp \ |
227 | @@ -73,3 +101,5 @@ |
228 | geis2_api.log \ |
229 | geis2_api.xml |
230 | |
231 | +TESTS = $(test_targets) |
232 | +check_PROGRAMS = $(test_targets) |
233 | |
234 | === added file 'testsuite/geis2/gtest_gbe_direct_touch_coords.cpp' |
235 | --- testsuite/geis2/gtest_gbe_direct_touch_coords.cpp 1970-01-01 00:00:00 +0000 |
236 | +++ testsuite/geis2/gtest_gbe_direct_touch_coords.cpp 2012-04-24 19:38:21 +0000 |
237 | @@ -0,0 +1,295 @@ |
238 | +#include "gtest_grail_backend.h" |
239 | +#include "x11_mocks.h" |
240 | + |
241 | +/* |
242 | + Check that when a direct device (e.g. a touchscreen) is being used, the |
243 | + position of a GeisTouch will be in window coordinates instead of input |
244 | + device coordinates. |
245 | + |
246 | + This means that the x an y values of a GeisTouch should come from |
247 | + XIDeviceEvent::event_x and XIDeviceEvent::event_y and not from |
248 | + XIDeviceEvent::valuators.values[0] and XIDeviceEvent::valuators.values[1], |
249 | + like it's the case for indirect devices (such as trackpads). |
250 | + |
251 | + Regression test for https://bugs.launchpad.net/bugs/984069 |
252 | + */ |
253 | + |
254 | +class Geis2GrailBackend : public Geis2GrailBackendBase |
255 | +{ |
256 | + protected: |
257 | + Geis2GrailBackend() : _subscription(nullptr) {} |
258 | + |
259 | + void CreateXMockDevices(); |
260 | + void DestroyXMockDevices(); |
261 | + void SendXInput2Events(); |
262 | + |
263 | + virtual void OnEventInitComplete(GeisEvent event); |
264 | + virtual void OnEventGestureBegin(GeisEvent event); |
265 | + |
266 | + GeisSubscription _subscription; |
267 | +}; |
268 | + |
269 | +void Geis2GrailBackend::CreateXMockDevices() |
270 | +{ |
271 | + xmock_devices_count = 1; |
272 | + xmock_devices = (XIDeviceInfo*) calloc(xmock_devices_count, |
273 | + sizeof(XIDeviceInfo)); |
274 | + |
275 | + XITouchClassInfo *touch_info = (XITouchClassInfo*) malloc(sizeof(XITouchClassInfo)); |
276 | + touch_info->type = XITouchClass; |
277 | + touch_info->sourceid = 0; |
278 | + touch_info->mode = XIDirectTouch; |
279 | + touch_info->num_touches = 5; |
280 | + |
281 | + XIValuatorClassInfo *x_axis_info = (XIValuatorClassInfo*) malloc(sizeof(XIValuatorClassInfo)); |
282 | + x_axis_info->type = XIValuatorClass; |
283 | + x_axis_info->sourceid = 0; |
284 | + x_axis_info->number = 0; /* identifies it as being the X axis */ |
285 | + x_axis_info->min = -500.0; |
286 | + x_axis_info->max = 500.0; |
287 | + x_axis_info->resolution = 3000; /* counts/meter */ |
288 | + |
289 | + XIValuatorClassInfo *y_axis_info = (XIValuatorClassInfo*) malloc(sizeof(XIValuatorClassInfo)); |
290 | + y_axis_info->type = XIValuatorClass; |
291 | + y_axis_info->sourceid = 0; |
292 | + y_axis_info->number = 1; /* identifies it as being the Y axis */ |
293 | + y_axis_info->min = -500.0; |
294 | + y_axis_info->max = 500.0; |
295 | + y_axis_info->resolution = 3000; |
296 | + |
297 | + XIAnyClassInfo **classes = (XIAnyClassInfo**) malloc(sizeof(XIAnyClassInfo*)*3); |
298 | + classes[0] = (XIAnyClassInfo*) touch_info; |
299 | + classes[1] = (XIAnyClassInfo*) x_axis_info; |
300 | + classes[2] = (XIAnyClassInfo*) y_axis_info; |
301 | + |
302 | + xmock_devices[0].deviceid = 0; |
303 | + xmock_devices[0].name = const_cast<char *>("Fake Touch Screen"); |
304 | + xmock_devices[0].use = XISlavePointer; |
305 | + xmock_devices[0].attachment = 1; |
306 | + xmock_devices[0].enabled = True; |
307 | + xmock_devices[0].num_classes = 3; |
308 | + xmock_devices[0].classes = classes; |
309 | +} |
310 | + |
311 | +void Geis2GrailBackend::DestroyXMockDevices() |
312 | +{ |
313 | + for (int i = 0; i < xmock_devices_count; ++i) |
314 | + { |
315 | + for (int j = 0; j < xmock_devices[i].num_classes; ++j) |
316 | + free(xmock_devices[i].classes[j]); |
317 | + free(xmock_devices[i].classes); |
318 | + } |
319 | + free(xmock_devices); |
320 | +} |
321 | + |
322 | +void Geis2GrailBackend::SendXInput2Events() |
323 | +{ |
324 | + XEvent event; |
325 | + XGenericEventCookie *xcookie = 0; |
326 | + XIDeviceEvent *device_event = 0; |
327 | + XITouchOwnershipEvent *ownership_event = 0; |
328 | + int serial = 0; |
329 | + |
330 | + event.type = GenericEvent; |
331 | + device_event = (XIDeviceEvent*)calloc(1, sizeof(XIDeviceEvent)); |
332 | + device_event->serial = serial++; |
333 | + device_event->display = xmock_display; |
334 | + device_event->extension = xmock_xi2_opcode; |
335 | + device_event->evtype = XI_TouchBegin; |
336 | + device_event->time = xmock_server_time; |
337 | + device_event->deviceid = 0; |
338 | + /* The source device that originally generated the event. */ |
339 | + device_event->sourceid = device_event->deviceid; |
340 | + device_event->detail = 0; /* touch id */ |
341 | + device_event->root = DefaultRootWindow(xmock_display); |
342 | + device_event->event = DefaultRootWindow(xmock_display); |
343 | + device_event->child = 0; |
344 | + device_event->root_x = 123.0f; |
345 | + device_event->root_y = 456.0f; |
346 | + device_event->event_x = device_event->root_x; |
347 | + device_event->event_y = device_event->root_y; |
348 | + device_event->valuators.mask_len = 2; /* two bytes */ |
349 | + device_event->valuators.mask = (unsigned char*) malloc(2); |
350 | + XISetMask(device_event->valuators.mask, 0); /* X axis is present */ |
351 | + XISetMask(device_event->valuators.mask, 1); /* Y axis is present */ |
352 | + device_event->valuators.values = (double*) malloc(sizeof(double)*2); |
353 | + device_event->valuators.values[0] = -200.0; |
354 | + device_event->valuators.values[1] = -100.0; |
355 | + xcookie = &event.xcookie; |
356 | + xcookie->extension = xmock_xi2_opcode; |
357 | + xcookie->evtype = XI_TouchBegin; |
358 | + xcookie->data = device_event; |
359 | + xmock_add_to_event_queue(&event); |
360 | + |
361 | + event.type = GenericEvent; |
362 | + device_event = (XIDeviceEvent*)calloc(1, sizeof(XIDeviceEvent)); |
363 | + device_event->serial = serial++; |
364 | + device_event->display = xmock_display; |
365 | + device_event->extension = xmock_xi2_opcode; |
366 | + device_event->evtype = XI_TouchBegin; |
367 | + device_event->time = xmock_server_time; |
368 | + device_event->deviceid = 0; |
369 | + device_event->sourceid = device_event->deviceid; |
370 | + device_event->detail = 1; /* touch id */ |
371 | + device_event->root = DefaultRootWindow(xmock_display); |
372 | + device_event->event = DefaultRootWindow(xmock_display); |
373 | + device_event->child = 0; |
374 | + device_event->root_x = 222.0f; |
375 | + device_event->root_y = 456.0f; |
376 | + device_event->event_x = device_event->root_x; |
377 | + device_event->event_y = device_event->root_y; |
378 | + device_event->valuators.mask_len = 2; |
379 | + device_event->valuators.mask = (unsigned char*) malloc(2); |
380 | + XISetMask(device_event->valuators.mask, 0); |
381 | + XISetMask(device_event->valuators.mask, 1); |
382 | + device_event->valuators.values = (double*) malloc(sizeof(double)*2); |
383 | + device_event->valuators.values[0] = -150.0; |
384 | + device_event->valuators.values[1] = -100.0; |
385 | + xcookie = &event.xcookie; |
386 | + xcookie->extension = xmock_xi2_opcode; |
387 | + xcookie->evtype = XI_TouchBegin; |
388 | + xcookie->data = device_event; |
389 | + xmock_add_to_event_queue(&event); |
390 | + |
391 | + xmock_server_time += 5; |
392 | + |
393 | + event.type = GenericEvent; |
394 | + ownership_event = (XITouchOwnershipEvent*)calloc(1, sizeof(XITouchOwnershipEvent)); |
395 | + ownership_event->type = GenericEvent; |
396 | + ownership_event->serial = serial++; |
397 | + ownership_event->display = xmock_display; |
398 | + ownership_event->extension = xmock_xi2_opcode; |
399 | + ownership_event->evtype = XI_TouchOwnership; |
400 | + ownership_event->time = xmock_server_time; |
401 | + ownership_event->deviceid = 0; |
402 | + ownership_event->sourceid = ownership_event->deviceid; |
403 | + ownership_event->touchid = 0; |
404 | + ownership_event->root = DefaultRootWindow(xmock_display); |
405 | + ownership_event->event = DefaultRootWindow(xmock_display); |
406 | + ownership_event->child = 0; |
407 | + xcookie = &event.xcookie; |
408 | + xcookie->extension = xmock_xi2_opcode; |
409 | + xcookie->evtype = XI_TouchOwnership; |
410 | + xcookie->data = ownership_event; |
411 | + xmock_add_to_event_queue(&event); |
412 | + |
413 | + event.type = GenericEvent; |
414 | + ownership_event = (XITouchOwnershipEvent*)calloc(1, sizeof(XITouchOwnershipEvent)); |
415 | + ownership_event->type = GenericEvent; |
416 | + ownership_event->serial = serial++; |
417 | + ownership_event->display = xmock_display; |
418 | + ownership_event->extension = xmock_xi2_opcode; |
419 | + ownership_event->evtype = XI_TouchOwnership; |
420 | + ownership_event->time = xmock_server_time; |
421 | + ownership_event->deviceid = 0; |
422 | + ownership_event->sourceid = ownership_event->deviceid; |
423 | + ownership_event->touchid = 1; |
424 | + ownership_event->root = DefaultRootWindow(xmock_display); |
425 | + ownership_event->event = DefaultRootWindow(xmock_display); |
426 | + ownership_event->child = 0; |
427 | + xcookie = &event.xcookie; |
428 | + xcookie->extension = xmock_xi2_opcode; |
429 | + xcookie->evtype = XI_TouchOwnership; |
430 | + xcookie->data = ownership_event; |
431 | + xmock_add_to_event_queue(&event); |
432 | + |
433 | + event.type = GenericEvent; |
434 | + device_event = (XIDeviceEvent*)calloc(1, sizeof(XIDeviceEvent)); |
435 | + device_event->serial = serial++; |
436 | + device_event->display = xmock_display; |
437 | + device_event->extension = xmock_xi2_opcode; |
438 | + device_event->evtype = XI_TouchUpdate; |
439 | + device_event->time = xmock_server_time; |
440 | + device_event->deviceid = 0; |
441 | + device_event->sourceid = device_event->deviceid; |
442 | + device_event->detail = 0; |
443 | + device_event->root = DefaultRootWindow(xmock_display); |
444 | + device_event->event = DefaultRootWindow(xmock_display); |
445 | + device_event->child = 0; |
446 | + device_event->root_x = 123.0f; |
447 | + device_event->root_y = 466.0f; |
448 | + device_event->event_x = device_event->root_x; |
449 | + device_event->event_y = device_event->root_y; |
450 | + device_event->valuators.mask_len = 2; /* two bytes */ |
451 | + device_event->valuators.mask = (unsigned char*) malloc(2); |
452 | + XISetMask(device_event->valuators.mask, 0); |
453 | + XISetMask(device_event->valuators.mask, 1); |
454 | + device_event->valuators.values = (double*) malloc(sizeof(double)*2); |
455 | + device_event->valuators.values[0] = -200.0; |
456 | + device_event->valuators.values[1] = -90.0; |
457 | + xcookie = &event.xcookie; |
458 | + xcookie->extension = xmock_xi2_opcode; |
459 | + xcookie->evtype = XI_TouchUpdate; |
460 | + xcookie->data = device_event; |
461 | + xmock_add_to_event_queue(&event); |
462 | + |
463 | + event.type = GenericEvent; |
464 | + device_event = (XIDeviceEvent*)calloc(1, sizeof(XIDeviceEvent)); |
465 | + device_event->serial = serial++; |
466 | + device_event->display = xmock_display; |
467 | + device_event->extension = xmock_xi2_opcode; |
468 | + device_event->evtype = XI_TouchUpdate; |
469 | + device_event->time = xmock_server_time; |
470 | + device_event->deviceid = 0; |
471 | + device_event->sourceid = device_event->deviceid; |
472 | + device_event->detail = 1; /* touch id */ |
473 | + device_event->root = DefaultRootWindow(xmock_display); |
474 | + device_event->event = DefaultRootWindow(xmock_display); |
475 | + device_event->child = 0; |
476 | + device_event->root_x = 222.0f; |
477 | + device_event->root_y = 466.0f; |
478 | + device_event->event_x = device_event->root_x; |
479 | + device_event->event_y = device_event->root_y; |
480 | + device_event->valuators.mask_len = 2; |
481 | + device_event->valuators.mask = (unsigned char*) malloc(2); |
482 | + XISetMask(device_event->valuators.mask, 0); |
483 | + XISetMask(device_event->valuators.mask, 1); |
484 | + device_event->valuators.values = (double*) malloc(sizeof(double)*2); |
485 | + device_event->valuators.values[0] = -150.0; |
486 | + device_event->valuators.values[1] = -90.0; |
487 | + xcookie = &event.xcookie; |
488 | + xcookie->extension = xmock_xi2_opcode; |
489 | + xcookie->evtype = XI_TouchUpdate; |
490 | + xcookie->data = device_event; |
491 | + xmock_add_to_event_queue(&event); |
492 | +} |
493 | + |
494 | +void Geis2GrailBackend::OnEventInitComplete(GeisEvent event) |
495 | +{ |
496 | + _subscription = CreateFilteredSubscription( |
497 | + "My 2-touches Touch", 2, GEIS_GESTURE_TOUCH); |
498 | + ASSERT_NE(nullptr, _subscription); |
499 | + |
500 | + SendXInput2Events(); |
501 | +} |
502 | + |
503 | +void Geis2GrailBackend::OnEventGestureBegin(GeisEvent event) |
504 | +{ |
505 | + GeisAttr attr = geis_event_attr_by_name(event, GEIS_EVENT_ATTRIBUTE_TOUCHSET); |
506 | + GeisTouchSet geis_touch_set = (GeisTouchSet) geis_attr_value_to_pointer(attr); |
507 | + |
508 | + TouchSet touch_set(geis_touch_set); |
509 | + |
510 | + /* check that there are two touch points and that they are in window coordinates |
511 | + (instead of input device coordinates) */ |
512 | + ASSERT_EQ(2, touch_set.size()); |
513 | + ASSERT_TRUE(touch_set.contains(123.0f, 456.0f)); |
514 | + ASSERT_TRUE(touch_set.contains(222.0f, 456.0f)); |
515 | +} |
516 | + |
517 | +TEST_F(Geis2GrailBackend, DirectDeviceTouchCoords) |
518 | +{ |
519 | + CreateXMockDevices(); |
520 | + |
521 | + Geis geis = geis_new(GEIS_INIT_UTOUCH_GRAIL_BACKEND, |
522 | + nullptr); |
523 | + ASSERT_NE(nullptr, geis); |
524 | + |
525 | + Run(geis); |
526 | + |
527 | + if (_subscription) |
528 | + geis_subscription_delete(_subscription); |
529 | + geis_delete(geis); |
530 | + |
531 | + DestroyXMockDevices(); |
532 | +} |
533 | |
534 | === added file 'testsuite/geis2/gtest_grail_backend.cpp' |
535 | --- testsuite/geis2/gtest_grail_backend.cpp 1970-01-01 00:00:00 +0000 |
536 | +++ testsuite/geis2/gtest_grail_backend.cpp 2012-04-24 19:38:21 +0000 |
537 | @@ -0,0 +1,134 @@ |
538 | +#include "gtest_grail_backend.h" |
539 | +#include "x11_mocks.h" |
540 | +#include <iostream> |
541 | + |
542 | +#define ADD_FAILURE_AND_RETURN(ret) \ |
543 | + {\ |
544 | + ADD_FAILURE();\ |
545 | + return ret;\ |
546 | + }\ |
547 | + |
548 | +Touch::Touch(GeisTouch geis_touch) |
549 | +{ |
550 | + GeisAttr attr = geis_touch_attr_by_name(geis_touch, GEIS_TOUCH_ATTRIBUTE_X); |
551 | + x = geis_attr_value_to_float(attr); |
552 | + |
553 | + attr = geis_touch_attr_by_name(geis_touch, GEIS_TOUCH_ATTRIBUTE_Y); |
554 | + y = geis_attr_value_to_float(attr); |
555 | + |
556 | + attr = geis_touch_attr_by_name(geis_touch, GEIS_TOUCH_ATTRIBUTE_ID); |
557 | + id = geis_attr_value_to_integer(attr); |
558 | +} |
559 | + |
560 | +TouchSet::TouchSet(GeisTouchSet geis_touch_set) |
561 | +{ |
562 | + int count = geis_touchset_touch_count(geis_touch_set); |
563 | + for (int i = 0; i < count; ++i) |
564 | + push_back(Touch(geis_touchset_touch(geis_touch_set, i))); |
565 | +} |
566 | + |
567 | +bool TouchSet::contains(float x, float y) |
568 | +{ |
569 | + for (auto touch : *this) |
570 | + { |
571 | + if (touch.x == x && touch.y == y) |
572 | + return true; |
573 | + } |
574 | + return false; |
575 | +} |
576 | + |
577 | +GeisSubscription Geis2GrailBackendBase::CreateFilteredSubscription( |
578 | + GeisString name, GeisSize num_touches, GeisString gesture_class) |
579 | +{ |
580 | + GeisStatus status = GEIS_STATUS_UNKNOWN_ERROR; |
581 | + GeisFilter filter = nullptr; |
582 | + GeisSubscription sub = nullptr; |
583 | + |
584 | + sub = geis_subscription_new(_geis, name, GEIS_SUBSCRIPTION_NONE); |
585 | + |
586 | + filter = geis_filter_new(_geis, "filter"); |
587 | + if (filter == nullptr) ADD_FAILURE_AND_RETURN(nullptr); |
588 | + |
589 | + status = geis_filter_add_term(filter, |
590 | + GEIS_FILTER_CLASS, |
591 | + GEIS_CLASS_ATTRIBUTE_NAME, GEIS_FILTER_OP_EQ, gesture_class, |
592 | + GEIS_GESTURE_ATTRIBUTE_TOUCHES, GEIS_FILTER_OP_EQ, num_touches, |
593 | + nullptr); |
594 | + if (status != GEIS_STATUS_SUCCESS) ADD_FAILURE_AND_RETURN(nullptr); |
595 | + |
596 | + status = geis_filter_add_term(filter, |
597 | + GEIS_FILTER_REGION, |
598 | + GEIS_REGION_ATTRIBUTE_WINDOWID, GEIS_FILTER_OP_EQ, |
599 | + DefaultRootWindow(xmock_display), |
600 | + nullptr); |
601 | + if (status != GEIS_STATUS_SUCCESS) ADD_FAILURE_AND_RETURN(nullptr); |
602 | + |
603 | + status = geis_subscription_add_filter(sub, filter); |
604 | + if (status != GEIS_STATUS_SUCCESS) ADD_FAILURE_AND_RETURN(nullptr); |
605 | + |
606 | + status = geis_subscription_activate(sub); |
607 | + if (status != GEIS_STATUS_SUCCESS) ADD_FAILURE_AND_RETURN(nullptr); |
608 | + |
609 | + return sub; |
610 | +} |
611 | + |
612 | +bool Geis2GrailBackendBase::DispatchAndProcessEvents() |
613 | +{ |
614 | + bool got_events = false; |
615 | + GeisEvent event; |
616 | + GeisStatus status; |
617 | + |
618 | + status = geis_dispatch_events(_geis); |
619 | + if (status != GEIS_STATUS_SUCCESS) ADD_FAILURE_AND_RETURN(false); |
620 | + |
621 | + status = geis_next_event(_geis, &event); |
622 | + if (status != GEIS_STATUS_SUCCESS |
623 | + && status != GEIS_STATUS_CONTINUE |
624 | + && status != GEIS_STATUS_EMPTY) |
625 | + ADD_FAILURE_AND_RETURN(false); |
626 | + |
627 | + if (status == GEIS_STATUS_SUCCESS || status == GEIS_STATUS_CONTINUE) |
628 | + got_events = true; |
629 | + |
630 | + while (status == GEIS_STATUS_CONTINUE || status == GEIS_STATUS_SUCCESS) |
631 | + { |
632 | + switch (geis_event_type(event)) |
633 | + { |
634 | + case GEIS_EVENT_INIT_COMPLETE: |
635 | + OnEventInitComplete(event); |
636 | + break; |
637 | + case GEIS_EVENT_GESTURE_BEGIN: |
638 | + OnEventGestureBegin(event); |
639 | + break; |
640 | + case GEIS_EVENT_GESTURE_UPDATE: |
641 | + OnEventGestureUpdate(event); |
642 | + break; |
643 | + case GEIS_EVENT_GESTURE_END: |
644 | + OnEventGestureEnd(event); |
645 | + break; |
646 | + default: |
647 | + break; |
648 | + } |
649 | + geis_event_delete(event); |
650 | + status = geis_next_event(_geis, &event); |
651 | + } |
652 | + |
653 | + return got_events; |
654 | +} |
655 | + |
656 | +void Geis2GrailBackendBase::Run(Geis geis) |
657 | +{ |
658 | + _geis = geis; |
659 | + |
660 | + bool got_events; |
661 | + do |
662 | + { |
663 | + got_events = DispatchAndProcessEvents(); |
664 | + } while (got_events); |
665 | +} |
666 | + |
667 | +int main(int argc, char **argv) |
668 | +{ |
669 | + testing::InitGoogleTest(&argc, argv); |
670 | + return RUN_ALL_TESTS(); |
671 | +} |
672 | |
673 | === added file 'testsuite/geis2/gtest_grail_backend.h' |
674 | --- testsuite/geis2/gtest_grail_backend.h 1970-01-01 00:00:00 +0000 |
675 | +++ testsuite/geis2/gtest_grail_backend.h 2012-04-24 19:38:21 +0000 |
676 | @@ -0,0 +1,52 @@ |
677 | +#ifndef GTEST_GRAIL_BACKEND_H |
678 | +#define GTEST_GRAIL_BACKEND_H |
679 | + |
680 | +#include <gtest/gtest.h> |
681 | +#include <geis/geis.h> |
682 | +#include <vector> |
683 | + |
684 | +class Touch |
685 | +{ |
686 | + public: |
687 | + Touch(GeisTouch geis_touch); |
688 | + |
689 | + int id; |
690 | + float x; |
691 | + float y; |
692 | +}; |
693 | + |
694 | +class TouchSet : public std::vector<Touch> |
695 | +{ |
696 | + public: |
697 | + TouchSet(GeisTouchSet geis_touch_set); |
698 | + bool contains(float x, float y); |
699 | +}; |
700 | + |
701 | +class Geis2GrailBackendBase : public ::testing::Test |
702 | +{ |
703 | + protected: |
704 | + Geis2GrailBackendBase() : _geis(nullptr) {} |
705 | + virtual ~Geis2GrailBackendBase() {} |
706 | + |
707 | + /* Dispatch and process Geis events in a loop until there are no more |
708 | + events. */ |
709 | + void Run(Geis geis); |
710 | + |
711 | + |
712 | + /* Creates (and activates) a GeisSubscription with the given name |
713 | + and with filters for the given number of touches and gesture class. */ |
714 | + GeisSubscription CreateFilteredSubscription(GeisString name, |
715 | + GeisSize num_touches, |
716 | + GeisString gesture_class); |
717 | + |
718 | + virtual void OnEventInitComplete(GeisEvent event) {} |
719 | + virtual void OnEventGestureBegin(GeisEvent event) {} |
720 | + virtual void OnEventGestureUpdate(GeisEvent event) {} |
721 | + virtual void OnEventGestureEnd(GeisEvent event) {} |
722 | + |
723 | + private: |
724 | + Geis _geis; |
725 | + bool DispatchAndProcessEvents(); |
726 | +}; |
727 | + |
728 | +#endif // GTEST_GRAIL_BACKEND_H |
729 | |
730 | === modified file 'testsuite/gtest/Makefile.am' |
731 | --- testsuite/gtest/Makefile.am 2012-03-30 11:51:09 +0000 |
732 | +++ testsuite/gtest/Makefile.am 2012-04-24 19:38:21 +0000 |
733 | @@ -3,26 +3,31 @@ |
734 | # @brief automake recipe for the geis gtest testsuite harness directory |
735 | # |
736 | |
737 | -if ENABLE_INTEGRATION_TESTS |
738 | +if HAVE_GTEST |
739 | check_LIBRARIES = libgtest_geis.a |
740 | endif |
741 | |
742 | -libgtest_geis_a_SOURCES = \ |
743 | - gtest_evemu_device.h gtest_evemu_device.cpp \ |
744 | - gtest_geis_fixture.h gtest_geis_fixture.cpp \ |
745 | - gtest_geis1_fixture.h gtest_geis1_fixture.cpp |
746 | - |
747 | nodist_libgtest_geis_a_SOURCES = \ |
748 | - $(XORG_GTEST_SOURCE)/src/xorg-gtest-all.cpp \ |
749 | $(GTEST_SOURCE)/src/gtest-all.cc |
750 | |
751 | libgtest_geis_a_CPPFLAGS = \ |
752 | - --std=c++0x \ |
753 | -I$(top_srcdir) \ |
754 | -I$(top_srcdir)/include \ |
755 | -I$(top_srcdir)/libutouch-geis \ |
756 | -DTEST_ROOT_DIR=\"$(abs_top_srcdir)/testsuite/\" \ |
757 | + $(GTEST_CPPFLAGS) |
758 | + |
759 | +if ENABLE_INTEGRATION_TESTS |
760 | +libgtest_geis_a_SOURCES = \ |
761 | + gtest_evemu_device.h gtest_evemu_device.cpp \ |
762 | + gtest_geis_fixture.h gtest_geis_fixture.cpp \ |
763 | + gtest_geis1_fixture.h gtest_geis1_fixture.cpp |
764 | + |
765 | +nodist_libgtest_geis_a_SOURCES += \ |
766 | + $(XORG_GTEST_SOURCE)/src/xorg-gtest-all.cpp |
767 | + |
768 | +libgtest_geis_a_CPPFLAGS += \ |
769 | $(XORG_GTEST_CPPFLAGS) \ |
770 | - $(GTEST_CPPFLAGS) \ |
771 | $(EVEMU_CFLAGS) \ |
772 | $(XORG_GTEST_CFLAGS) |
773 | +endif |
774 | |
775 | === added directory 'testsuite/x11_mocks' |
776 | === added file 'testsuite/x11_mocks/Makefile.am' |
777 | --- testsuite/x11_mocks/Makefile.am 1970-01-01 00:00:00 +0000 |
778 | +++ testsuite/x11_mocks/Makefile.am 2012-04-24 19:38:21 +0000 |
779 | @@ -0,0 +1,13 @@ |
780 | +# |
781 | +# @file testsuite/x11_mocks/Makefile.am |
782 | +# @brief automake recipe for the X11 mockups |
783 | +# |
784 | + |
785 | +check_LIBRARIES = libx11_mocks.a |
786 | + |
787 | +libx11_mocks_a_SOURCES = \ |
788 | + x11_mocks.c |
789 | + |
790 | +libx11_mocks_a_CFLAGS = \ |
791 | + --std=c99 |
792 | + |
793 | |
794 | === added file 'testsuite/x11_mocks/x11_mocks.c' |
795 | --- testsuite/x11_mocks/x11_mocks.c 1970-01-01 00:00:00 +0000 |
796 | +++ testsuite/x11_mocks/x11_mocks.c 2012-04-24 19:38:21 +0000 |
797 | @@ -0,0 +1,406 @@ |
798 | +/* needed to break into 'Display' struct internals. */ |
799 | +#define XLIB_ILLEGAL_ACCESS |
800 | +#include <X11/Xlib.h> |
801 | + |
802 | +#include <geis/geis.h> |
803 | + |
804 | +#include "x11_mocks.h" |
805 | + |
806 | +#include <sys/eventfd.h> |
807 | +#include <stdio.h> |
808 | +#include <unistd.h> |
809 | + |
810 | +int xmock_xi2_opcode = 42; |
811 | +int xmock_xi2_event_base = 40000; |
812 | +int xmock_xi2_error_base = 40000; |
813 | +int xmock_xsync_event_base = 50000; |
814 | +int xmock_xsync_error_base = 50000; |
815 | +Display *xmock_display = NULL; |
816 | +uint64_t xmock_server_time = 0; |
817 | + |
818 | +XIDeviceInfo *xmock_devices = NULL; |
819 | +int xmock_devices_count = 0; |
820 | + |
821 | +/* id to be used for the next alarm that gets created */ |
822 | +XSyncAlarm _xmock_next_alarm = 1; |
823 | + |
824 | +struct EventQueueItem |
825 | +{ |
826 | + XEvent event; |
827 | + struct EventQueueItem *next; |
828 | +} *xmock_event_queue = NULL; |
829 | + |
830 | +#define XMOCK_PRINT_FUNCTION _xmock_print_function(__func__) |
831 | +void _xmock_print_function(const char *function) |
832 | +{ |
833 | + static int debug_enabled = -1; |
834 | + if (debug_enabled == -1) |
835 | + { |
836 | + if (getenv("XMOCK_DEBUG")) |
837 | + debug_enabled = 1; |
838 | + else |
839 | + debug_enabled = 0; |
840 | + } |
841 | + |
842 | + if (debug_enabled) |
843 | + printf("XMOCK: %s mock called.\n", function); |
844 | +} |
845 | + |
846 | +void xmock_add_to_event_queue(const XEvent *event) |
847 | +{ |
848 | + struct EventQueueItem *new_item = malloc(sizeof(struct EventQueueItem)); |
849 | + new_item->event = *event; |
850 | + new_item->next = NULL; |
851 | + |
852 | + if (!xmock_event_queue) |
853 | + { |
854 | + xmock_event_queue = new_item; |
855 | + } |
856 | + else |
857 | + { |
858 | + struct EventQueueItem *last_item = xmock_event_queue; |
859 | + while (last_item->next) |
860 | + { |
861 | + last_item = last_item->next; |
862 | + } |
863 | + last_item->next = new_item; |
864 | + } |
865 | + |
866 | + static const uint64_t num = 1; |
867 | + if (write(xmock_display->fd, &num, sizeof(num)) != sizeof(num)) |
868 | + { |
869 | + fprintf(stderr, "ERROR: failed to update eventfd instance,\n"); |
870 | + exit(1); |
871 | + } |
872 | +} |
873 | + |
874 | +Display *XOpenDisplay(_Xconst char *display_name) |
875 | +{ |
876 | + XMOCK_PRINT_FUNCTION; |
877 | + (void)display_name; |
878 | + |
879 | + Display *display = (Display*)calloc(1, sizeof(Display)); |
880 | + display->fd = eventfd(0, EFD_NONBLOCK); |
881 | + display->default_screen = 0; |
882 | + display->nscreens = 1; |
883 | + display->screens = (Screen*)calloc(1, sizeof(Screen)); |
884 | + display->screens[0].root = 1; |
885 | + |
886 | + xmock_display = display; |
887 | + |
888 | + return display; |
889 | +} |
890 | + |
891 | +int XCloseDisplay(Display *display) |
892 | +{ |
893 | + XMOCK_PRINT_FUNCTION; |
894 | + |
895 | + close(display->fd); |
896 | + free(display->screens); |
897 | + free(display); |
898 | + |
899 | + xmock_display = NULL; |
900 | + |
901 | + return 0; |
902 | +} |
903 | + |
904 | +int XSync(Display *display, Bool discard) |
905 | +{ |
906 | + (void)display; |
907 | + (void)discard; |
908 | + return 0; |
909 | +} |
910 | + |
911 | +int XFlush(Display *display) |
912 | +{ |
913 | + (void)display; |
914 | + return 0; |
915 | +} |
916 | + |
917 | +Bool XQueryExtension(Display *display, const char *name, |
918 | + int *major_opcode_return, int *first_event_return, int *first_error_return) |
919 | +{ |
920 | + XMOCK_PRINT_FUNCTION; |
921 | + (void)display; |
922 | + (void)name; /* assuming name == "XInputExtension" */ |
923 | + |
924 | + *major_opcode_return = xmock_xi2_opcode; |
925 | + *first_event_return = xmock_xi2_event_base; |
926 | + *first_error_return = xmock_xi2_error_base; |
927 | + |
928 | + return True; |
929 | +} |
930 | + |
931 | +int XPending(Display *display) |
932 | +{ |
933 | + XMOCK_PRINT_FUNCTION; |
934 | + (void)display; |
935 | + |
936 | + int pending_events_count = 0; |
937 | + struct EventQueueItem *item = xmock_event_queue; |
938 | + while (item != NULL) |
939 | + { |
940 | + ++pending_events_count; |
941 | + item = item->next; |
942 | + } |
943 | + return pending_events_count; |
944 | +} |
945 | + |
946 | +int XNextEvent(Display *display, XEvent *event_return) |
947 | +{ |
948 | + XMOCK_PRINT_FUNCTION; |
949 | + (void)display; |
950 | + |
951 | + |
952 | + if (xmock_event_queue) |
953 | + { |
954 | + uint64_t num = 1; |
955 | + ssize_t bytes_read = read(xmock_display->fd, &num, sizeof(num)); |
956 | + (void)bytes_read; |
957 | + |
958 | + *event_return = xmock_event_queue->event; |
959 | + |
960 | + struct EventQueueItem *removed_item = xmock_event_queue; |
961 | + xmock_event_queue = xmock_event_queue->next; |
962 | + free(removed_item); |
963 | + } |
964 | + else |
965 | + { |
966 | + /* not going to block... */ |
967 | + } |
968 | + |
969 | + return 0; |
970 | +} |
971 | + |
972 | +Bool XGetEventData(Display *display, XGenericEventCookie *cookie) |
973 | +{ |
974 | + XMOCK_PRINT_FUNCTION; |
975 | + (void)display; |
976 | + (void)cookie; |
977 | + return True; |
978 | +} |
979 | + |
980 | +void XFreeEventData(Display *display, XGenericEventCookie *cookie) |
981 | +{ |
982 | + XMOCK_PRINT_FUNCTION; |
983 | + (void)display; |
984 | + |
985 | + if (cookie->data && cookie->extension == xmock_xi2_opcode) |
986 | + { |
987 | + if (cookie->evtype == XI_TouchBegin |
988 | + || cookie->evtype == XI_TouchUpdate |
989 | + || cookie->evtype == XI_TouchEnd) |
990 | + { |
991 | + XIDeviceEvent *device_event = (XIDeviceEvent*) cookie->data; |
992 | + free(device_event->valuators.mask); |
993 | + free(device_event->valuators.values); |
994 | + } |
995 | + free(cookie->data); |
996 | + } |
997 | +} |
998 | + |
999 | +XIDeviceInfo* XIQueryDevice(Display * display, |
1000 | + int deviceid, |
1001 | + int * ndevices_return) |
1002 | +{ |
1003 | + XMOCK_PRINT_FUNCTION; |
1004 | + (void)display; |
1005 | + (void)deviceid; /* assuming XIAllDevices */ |
1006 | + |
1007 | + XIDeviceInfo *devices; |
1008 | + |
1009 | + devices = calloc(xmock_devices_count, sizeof(XIDeviceInfo)); |
1010 | + |
1011 | + for (int i = 0; i < xmock_devices_count; ++i) { |
1012 | + devices[i] = xmock_devices[i]; |
1013 | + } |
1014 | + |
1015 | + *ndevices_return = xmock_devices_count; |
1016 | + |
1017 | + return devices; |
1018 | +} |
1019 | + |
1020 | +void XIFreeDeviceInfo(XIDeviceInfo *info) |
1021 | +{ |
1022 | + XMOCK_PRINT_FUNCTION; |
1023 | + free(info); |
1024 | +} |
1025 | + |
1026 | +Status XIQueryVersion(Display *display, |
1027 | + int *major_version_inout, |
1028 | + int *minor_version_inout) |
1029 | +{ |
1030 | + XMOCK_PRINT_FUNCTION; |
1031 | + (void)display; |
1032 | + *major_version_inout = 2; |
1033 | + *minor_version_inout = 2; |
1034 | + return Success; |
1035 | +} |
1036 | + |
1037 | +Status XISelectEvents(Display *display, |
1038 | + Window win, |
1039 | + XIEventMask *masks, |
1040 | + int num_masks) |
1041 | +{ |
1042 | + XMOCK_PRINT_FUNCTION; |
1043 | + (void)display; |
1044 | + (void)win; |
1045 | + (void)masks; |
1046 | + (void)num_masks; |
1047 | + return Success; |
1048 | +} |
1049 | + |
1050 | +int XIGrabTouchBegin( |
1051 | + Display* display, |
1052 | + int deviceid, |
1053 | + Window grab_window, |
1054 | + int owner_events, |
1055 | + XIEventMask *mask, |
1056 | + int num_modifiers, |
1057 | + XIGrabModifiers *modifiers_inout) |
1058 | +{ |
1059 | + XMOCK_PRINT_FUNCTION; |
1060 | + (void)display; |
1061 | + (void)deviceid; |
1062 | + (void)grab_window; |
1063 | + (void)owner_events; |
1064 | + (void)mask; |
1065 | + |
1066 | + for (int i = 0; i < num_modifiers; ++i) |
1067 | + { |
1068 | + modifiers_inout[i].status = XIGrabSuccess; |
1069 | + } |
1070 | + |
1071 | + return 0; |
1072 | +} |
1073 | + |
1074 | +Status XIUngrabTouchBegin( |
1075 | + Display* display, |
1076 | + int deviceid, |
1077 | + Window grab_window, |
1078 | + int num_modifiers, |
1079 | + XIGrabModifiers *modifiers) |
1080 | +{ |
1081 | + XMOCK_PRINT_FUNCTION; |
1082 | + (void)display; |
1083 | + (void)deviceid; |
1084 | + (void)grab_window; |
1085 | + (void)num_modifiers; |
1086 | + (void)modifiers; |
1087 | + return Success; |
1088 | +} |
1089 | + |
1090 | +Status XIAllowTouchEvents( |
1091 | + Display* display, |
1092 | + int deviceid, |
1093 | + unsigned int touchid, |
1094 | + Window grab_window, |
1095 | + int event_mode) |
1096 | +{ |
1097 | + XMOCK_PRINT_FUNCTION; |
1098 | + (void)display; |
1099 | + (void)deviceid; |
1100 | + (void)touchid; |
1101 | + (void)grab_window; |
1102 | + (void)event_mode; |
1103 | + return Success; |
1104 | +} |
1105 | + |
1106 | +Status XSyncQueryExtension( |
1107 | + Display* dpy, |
1108 | + int* event_base_return, |
1109 | + int* error_base_return) |
1110 | +{ |
1111 | + XMOCK_PRINT_FUNCTION; |
1112 | + (void)dpy; |
1113 | + *event_base_return = xmock_xsync_event_base; |
1114 | + *error_base_return = xmock_xsync_error_base; |
1115 | + return True; |
1116 | +} |
1117 | + |
1118 | +Status XSyncInitialize( |
1119 | + Display* dpy, |
1120 | + int* major_version_return, |
1121 | + int* minor_version_return) |
1122 | +{ |
1123 | + XMOCK_PRINT_FUNCTION; |
1124 | + (void)dpy; |
1125 | + *major_version_return = 1; |
1126 | + *minor_version_return = 0; |
1127 | + return True; |
1128 | +} |
1129 | + |
1130 | +XSyncSystemCounter *XSyncListSystemCounters( |
1131 | + Display* dpy, |
1132 | + int* n_counters_return) |
1133 | +{ |
1134 | + XMOCK_PRINT_FUNCTION; |
1135 | + (void)dpy; |
1136 | + *n_counters_return = 1; |
1137 | + |
1138 | + XSyncSystemCounter *sys_counter = malloc(sizeof(XSyncSystemCounter)); |
1139 | + sys_counter->name = "SERVERTIME"; |
1140 | + sys_counter->counter = 1; |
1141 | + sys_counter->resolution.hi = 1; |
1142 | + sys_counter->resolution.lo = 0; |
1143 | + return sys_counter; |
1144 | +} |
1145 | + |
1146 | +void XSyncFreeSystemCounterList(XSyncSystemCounter* list) |
1147 | +{ |
1148 | + XMOCK_PRINT_FUNCTION; |
1149 | + free(list); |
1150 | +} |
1151 | + |
1152 | +XSyncAlarm XSyncCreateAlarm( |
1153 | + Display* dpy, |
1154 | + unsigned long values_mask, |
1155 | + XSyncAlarmAttributes* values) |
1156 | +{ |
1157 | + XMOCK_PRINT_FUNCTION; |
1158 | + (void)dpy; |
1159 | + |
1160 | + XSyncAlarmNotifyEvent alarm_notify; |
1161 | + alarm_notify.type = xmock_xsync_event_base + XSyncAlarmNotify; |
1162 | + alarm_notify.alarm = _xmock_next_alarm; |
1163 | + alarm_notify.counter_value = values->trigger.wait_value; |
1164 | + xmock_add_to_event_queue((XEvent*)&alarm_notify); |
1165 | + |
1166 | + XSyncValue time = values->trigger.wait_value; |
1167 | + uint64_t timeout = (uint64_t)XSyncValueHigh32(time) << 32 |
1168 | + | (uint64_t)XSyncValueLow32(time); |
1169 | + xmock_server_time = timeout + 1; |
1170 | + |
1171 | + return _xmock_next_alarm++; |
1172 | +} |
1173 | + |
1174 | +Status XSyncDestroyAlarm( |
1175 | + Display* dpy, |
1176 | + XSyncAlarm alarm) |
1177 | +{ |
1178 | + XMOCK_PRINT_FUNCTION; |
1179 | + (void)dpy; |
1180 | + (void)alarm; |
1181 | +} |
1182 | + |
1183 | +void XSyncIntsToValue( |
1184 | + XSyncValue* pv, |
1185 | + unsigned int l, |
1186 | + int h) |
1187 | +{ |
1188 | + XMOCK_PRINT_FUNCTION; |
1189 | + pv->hi = h; |
1190 | + pv->lo = l; |
1191 | +} |
1192 | + |
1193 | +int XSyncValueHigh32(XSyncValue v) |
1194 | +{ |
1195 | + XMOCK_PRINT_FUNCTION; |
1196 | + return v.hi; |
1197 | +} |
1198 | + |
1199 | +unsigned int XSyncValueLow32(XSyncValue v) |
1200 | +{ |
1201 | + XMOCK_PRINT_FUNCTION; |
1202 | + return v.lo; |
1203 | +} |
1204 | |
1205 | === added file 'testsuite/x11_mocks/x11_mocks.h' |
1206 | --- testsuite/x11_mocks/x11_mocks.h 1970-01-01 00:00:00 +0000 |
1207 | +++ testsuite/x11_mocks/x11_mocks.h 2012-04-24 19:38:21 +0000 |
1208 | @@ -0,0 +1,34 @@ |
1209 | +#ifndef X11_MOCKS_H |
1210 | +#define X11_MOCKS_H |
1211 | + |
1212 | +#include <X11/Xlib.h> |
1213 | +#include <X11/extensions/XInput2.h> |
1214 | +#include <X11/extensions/sync.h> |
1215 | + |
1216 | +#ifdef __cplusplus |
1217 | +extern "C" { |
1218 | +#endif |
1219 | + |
1220 | +extern int xmock_xi2_opcode; |
1221 | +extern int xmock_xi2_event_base; |
1222 | +extern int xmock_xi2_error_base; |
1223 | +extern int xmock_xsync_event_base; |
1224 | +extern int xmock_xsync_error_base; |
1225 | +extern Display *xmock_display; |
1226 | +extern uint64_t xmock_server_time; |
1227 | + |
1228 | +/* to be filled by user. A copy of it will be returned by each |
1229 | + XIQueryDevice call */ |
1230 | +extern XIDeviceInfo *xmock_devices; |
1231 | +extern int xmock_devices_count; |
1232 | + |
1233 | +/* Adds the given XEvent to the xmock event queue. |
1234 | + The Diplay connection will signal that there are |
1235 | + pending events */ |
1236 | +extern void xmock_add_to_event_queue(const XEvent* event); |
1237 | + |
1238 | +#ifdef __cplusplus |
1239 | +} |
1240 | +#endif |
1241 | + |
1242 | +#endif |
The code change looks OK. I built and tested with a touchscreen, and nothing appears to be broken, but I don't think that's really a valid test of this change. Is there a better interactive test?