Merge lp:~dandrader/geis/lp984069 into lp:geis

Proposed by Daniel d'Andrada
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
Reviewer Review Type Date Requested Status
Chase Douglas (community) Approve
Stephen M. Webb (community) Needs Fixing
Review via email: mp+102337@code.launchpad.net

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.

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

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?

Revision history for this message
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.

review: Needs Fixing
lp:~dandrader/geis/lp984069 updated
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.

Revision history for this message
Daniel d'Andrada (dandrader) wrote :

It now has a unit test.

Revision history for this message
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_INTEGRATION_TESTS).

Revision history for this message
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.

review: Needs Fixing
lp:~dandrader/geis/lp984069 updated
255. By Chase Douglas

Merge fixes for radius and position delta calculations

256. By Chase Douglas

Merge fix for GeisSubscriptionFlags usage when compiling with g++

Revision history for this message
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.

Revision history for this message
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_geis_a_CPPFLAGS still needs $(GTEST_CPPFLAGS). If the gtest headers are installed somewhere other than a standard location, GTEST_CPPFLAGS will have the -I<header path> option. This will be needed for building xorg-gtest too. Likewise for gtest_geis2_grail_backend_CPPFLAGS.

* libgtest_geis_a_LIBADD should add the libgtest.a file instead of an intermediate object file. I don't know if that will work, but the .o file is sort of an autotools implementation detail. This may also remove the need for libgtest_geis_a_DEPENDENCIES.

* 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_AND_RETURN isn't necessary. All you need is ADD_FAILURE() << [message]; The file and line will be printed automatically, and the function return automatically.

* 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.

review: Needs Fixing
Revision history for this message
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/gtest/Makefile.am to provide multiple libraries instead of just including the xorg-gtest sources conditionally on ENABLE_INTEGRATION_TESTS. Could you make your reasoning explicit?

(3) Why reorganize testsuite/geis2/Makefile.am? Traditionally all the build 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?

(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.

review: Needs Fixing
Revision history for this message
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).

Revision history for this message
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.

Revision history for this message
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

Revision history for this message
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.

Revision history for this message
Daniel d'Andrada (dandrader) wrote :

> (3) Why reorganize testsuite/geis2/Makefile.am? Traditionally all the build
> 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.

Revision history for this message
Daniel d'Andrada (dandrader) wrote :

> (2) Not sure why you did all the fancy wrangling in
> testsuite/gtest/Makefile.am to provide multiple libraries instead of just
> including the xorg-gtest sources conditionally on ENABLE_INTEGRATION_TESTS.
> 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.

Revision history for this message
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.

Revision history for this message
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/gtest/Makefile.am to provide multiple libraries instead of just
>> including the xorg-gtest sources conditionally on ENABLE_INTEGRATION_TESTS.
>> 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?

Revision history for this message
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/gtest/Makefile.am to provide multiple libraries instead of just
> >> including the xorg-gtest sources conditionally on ENABLE_INTEGRATION_TESTS.
> >> 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.

Revision history for this message
Daniel d'Andrada (dandrader) wrote :

Updated according to comments.

Ready for a new review round.

lp:~dandrader/geis/lp984069 updated
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

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

* The --std=c++0x flags are still used.

* PRINT_FAILURE_AND_RETURN is still there.

I think everything else I commented on has been addressed.

review: Needs Fixing
Revision history for this message
Daniel d'Andrada (dandrader) wrote :

> * The --std=c++0x flags are still used.
>
> * PRINT_FAILURE_AND_RETURN is still there.
>
> I think everything else I commented on has been addressed.

Ah, yeah, I forgot those. Sorry for that.

lp:~dandrader/geis/lp984069 updated
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

Revision history for this message
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

Revision history for this message
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://code.google.com/p/googletest/wiki/AdvancedGuide#Explicit_Success_and_Failure

> I've removed the --std=c++0x flag from gtest

gtest_geis2_grail_backend_CPPFLAGS still has --std=c++0x.

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

"make distcheck" fails (there should be no nodist_ prefix on the SOURCES variable in testsuite/x11_mocks/Makefile.am).

review: Needs Fixing
Revision history for this message
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://code.google.com/p/googletest/wiki/AdvancedGuide#Explicit_Success_and_Failure

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_grail_backend_CPPFLAGS still has --std=c++0x.

I needs --std=c++0x because it uses c++0x stuff (like nullptr and range-based for loops)

Revision history for this message
Daniel d'Andrada (dandrader) wrote :

> "make distcheck" fails (there should be no nodist_ prefix on the SOURCES
> variable in testsuite/x11_mocks/Makefile.am).

Fixed.

lp:~dandrader/geis/lp984069 updated
265. By Daniel d'Andrada

sources of x11_mocks are distributed

Revision history for this message
Chase Douglas (chasedouglas) :
review: Approve
Revision history for this message
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://code.google.com/p/googletest/wiki/AdvancedGuide#Explicit_Success_and_Failure
>
> 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_grail_backend_CPPFLAGS still has --std=c++0x.
>
> I needs --std=c++0x because it uses c++0x stuff (like nullptr and range-based for loops)

Ok, I didn't realize that.

lp:~dandrader/geis/lp984069 updated
266. By Daniel d'Andrada

We don't need a macro anymore. Wrapped code is too simple

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file '.bzrignore'
--- .bzrignore 2012-04-11 16:18:03 +0000
+++ .bzrignore 2012-04-24 19:38:21 +0000
@@ -48,4 +48,5 @@
48TAGS48TAGS
49testsuite/geistest/geistest49testsuite/geistest/geistest
50testsuite/libutouch-geis/*.xml50testsuite/libutouch-geis/*.xml
51testsuite/geis2/gtest_geis2_grail_backend
51tools/geis-server/geis-server52tools/geis-server/geis-server
5253
=== modified file 'configure.ac'
--- configure.ac 2012-04-12 17:13:41 +0000
+++ configure.ac 2012-04-24 19:38:21 +0000
@@ -97,6 +97,10 @@
97 [enable_integration_tests=$enableval],97 [enable_integration_tests=$enableval],
98 [enable_integration_tests=auto])98 [enable_integration_tests=auto])
9999
100# Check for Google C++ Testing Framework
101CHECK_GTEST()
102AM_CONDITIONAL([HAVE_GTEST], [test "x$have_gtest" = xyes])
103
100have_xorg_gtest=no104have_xorg_gtest=no
101AS_IF([test "x$enable_integration_tests" != xno],105AS_IF([test "x$enable_integration_tests" != xno],
102 [CHECK_XORG_GTEST(106 [CHECK_XORG_GTEST(
@@ -132,6 +136,7 @@
132 testsuite/geis2/Makefile136 testsuite/geis2/Makefile
133 testsuite/geis1/Makefile137 testsuite/geis1/Makefile
134 testsuite/geistest/Makefile138 testsuite/geistest/Makefile
139 testsuite/x11_mocks/Makefile
135 examples/Makefile140 examples/Makefile
136 python/Makefile141 python/Makefile
137 tools/Makefile142 tools/Makefile
138143
=== modified file 'include/geis/geis.h'
--- include/geis/geis.h 2012-04-20 19:14:59 +0000
+++ include/geis/geis.h 2012-04-24 19:38:21 +0000
@@ -2061,6 +2061,11 @@
2061 * is capable of reporting differing sets of touch attributes, so there is no2061 * is capable of reporting differing sets of touch attributes, so there is no
2062 * guarantee that any or all of the defined touch attributes will bre present.2062 * guarantee that any or all of the defined touch attributes will bre present.
2063 *2063 *
2064 * If the touch comes from a direct device (see
2065 * GEIS_DEVICE_ATTRIBUTE_DIRECT_TOUCH) its position (x and y attributes) will
2066 * be in window coordinates, otherwise it will be in the input device's own
2067 * coordinate system.
2068 *
2064 * @{2069 * @{
2065 *2070 *
2066 * @def GEIS_TOUCH_ATTRIBUTE_ID2071 * @def GEIS_TOUCH_ATTRIBUTE_ID
20672072
=== modified file 'libutouch-geis/backend/grail/geis_grail_backend.c'
--- libutouch-geis/backend/grail/geis_grail_backend.c 2012-04-20 15:00:21 +0000
+++ libutouch-geis/backend/grail/geis_grail_backend.c 2012-04-24 19:38:21 +0000
@@ -635,19 +635,29 @@
635 focus_y = frame_touch_get_window_y(uftouch);635 focus_y = frame_touch_get_window_y(uftouch);
636 }636 }
637637
638 GeisFloat fval = frame_touch_get_device_x(uftouch);638 GeisFloat touch_x, touch_y;
639 bboxMinX = fmin(bboxMinX, fval);639 if (is_touchscreen)
640 bboxMaxX = fmax(bboxMaxX, fval);640 {
641 touch_x = frame_touch_get_window_x(uftouch);
642 touch_y = frame_touch_get_window_y(uftouch);
643 }
644 else
645 {
646 touch_x = frame_touch_get_device_x(uftouch);
647 touch_y = frame_touch_get_device_y(uftouch);
648 }
649
650 bboxMinX = fmin(bboxMinX, touch_x);
651 bboxMaxX = fmax(bboxMaxX, touch_x);
641 geis_touch_add_attr(touch, geis_attr_new(GEIS_TOUCH_ATTRIBUTE_X,652 geis_touch_add_attr(touch, geis_attr_new(GEIS_TOUCH_ATTRIBUTE_X,
642 GEIS_ATTR_TYPE_FLOAT,653 GEIS_ATTR_TYPE_FLOAT,
643 &fval));654 &touch_x));
644655
645 fval = frame_touch_get_device_y(uftouch);656 bboxMinY = fmin(bboxMinY, touch_y);
646 bboxMinY = fmin(bboxMinY, fval);657 bboxMaxY = fmax(bboxMaxY, touch_y);
647 bboxMaxY = fmax(bboxMaxY, fval);
648 geis_touch_add_attr(touch, geis_attr_new(GEIS_TOUCH_ATTRIBUTE_Y,658 geis_touch_add_attr(touch, geis_attr_new(GEIS_TOUCH_ATTRIBUTE_Y,
649 GEIS_ATTR_TYPE_FLOAT,659 GEIS_ATTR_TYPE_FLOAT,
650 &fval));660 &touch_y));
651661
652 geis_touchset_insert(touchset, touch);662 geis_touchset_insert(touchset, touch);
653 geis_frame_add_touchid(frame, geis_touch_id(touch));663 geis_frame_add_touchid(frame, geis_touch_id(touch));
654664
=== added file 'm4/gtest.m4'
--- m4/gtest.m4 1970-01-01 00:00:00 +0000
+++ m4/gtest.m4 2012-04-24 19:38:21 +0000
@@ -0,0 +1,51 @@
1# serial 1
2
3# Copyright (C) 2012 Canonical, Ltd.
4#
5# Permission is hereby granted, free of charge, to any person obtaining a copy
6# of this software and associated documentation files (the "Software"), to deal
7# in the Software without restriction, including without limitation the rights
8# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9# copies of the Software, and to permit persons to whom the Software is
10# furnished to do so, subject to the following conditions:
11#
12# The above copyright notice and this permission notice (including the next
13# paragraph) shall be included in all copies or substantial portions of the
14# Software.
15#
16# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22# SOFTWARE.
23
24# Checks whether the gtest source is available on the system. Allows for
25# adjusting the include and source path. Sets have_gtest=yes if the source is
26# present. Sets GTEST_CPPFLAGS and GTEST_SOURCE to the preprocessor flags and
27# source location respectively.
28AC_DEFUN([CHECK_GTEST],
29[
30 AC_ARG_WITH([gtest-include-path],
31 [AS_HELP_STRING([--with-gtest-include-path],
32 [location of the Google test headers])],
33 [GTEST_CPPFLAGS="-I$withval"])
34
35 AC_ARG_WITH([gtest-source-path],
36 [AS_HELP_STRING([--with-gtest-source-path],
37 [location of the Google test sources, defaults to /usr/src/gtest])],
38 [GTEST_SOURCE="$withval"],
39 [GTEST_SOURCE="/usr/src/gtest"])
40
41 GTEST_CPPFLAGS="$GTEST_CPPFLAGS -I$GTEST_SOURCE"
42
43 AC_CHECK_FILES([$GTEST_SOURCE/src/gtest-all.cc]
44 [$GTEST_SOURCE/src/gtest_main.cc],
45 [have_gtest=yes],
46 [have_gtest=no])
47
48 AS_IF([test "x$have_gtest_source" = xyes],
49 [AC_SUBST(GTEST_CPPFLAGS)]
50 [AC_SUBST(GTEST_SOURCE)])
51]) # CHECK_GTEST
052
=== modified file 'testsuite/Makefile.am'
--- testsuite/Makefile.am 2012-03-28 16:54:23 +0000
+++ testsuite/Makefile.am 2012-04-24 19:38:21 +0000
@@ -20,6 +20,6 @@
20# 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA20# 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21#21#
2222
23SUBDIRS = gtest geis-util libutouch-geis geis2 geis1 geistest23SUBDIRS = gtest x11_mocks geis-util libutouch-geis geis2 geis1 geistest
2424
25EXTRA_DIST = recordings25EXTRA_DIST = recordings
2626
=== modified file 'testsuite/geis2/Makefile.am'
--- testsuite/geis2/Makefile.am 2012-04-16 19:12:46 +0000
+++ testsuite/geis2/Makefile.am 2012-04-24 19:38:21 +0000
@@ -1,19 +1,15 @@
1#1#
2# @file testsuite/geis1/Makefile.am 2# @file testsuite/geis2/Makefile.am
3# @brief automake recipe for the geis v1.0 testsuite unit testing directory3# @brief automake recipe for the geis v2.0 testsuite testing directory
4#4#
55
6test_targets = 6test_targets =
7
8##### check_geis2_api - Tests using Check C testing framework #####
9
7if HAVE_CHECK10if HAVE_CHECK
8 test_targets += check_geis2_api11 test_targets += check_geis2_api
9endif12endif
10if ENABLE_INTEGRATION_TESTS
11 test_targets += gtest_geis2_api
12endif
13
14TESTS = $(test_targets)
15
16check_PROGRAMS = $(test_targets)
1713
18check_geis2_api_SOURCES = \14check_geis2_api_SOURCES = \
19 check_attr.c \15 check_attr.c \
@@ -42,6 +38,38 @@
42 $(top_builddir)/libutouch-geis/libutouch-geis.la \38 $(top_builddir)/libutouch-geis/libutouch-geis.la \
43 $(CHECK_LIBS)39 $(CHECK_LIBS)
4440
41#### gtest_geis2_grail_backend - Test for the GRAIL backend of Geis v2 API #####
42#### using gtest #####
43
44if HAVE_GTEST
45 test_targets += gtest_geis2_grail_backend
46endif
47
48gtest_geis2_grail_backend_SOURCES = \
49 gtest_grail_backend.cpp \
50 gtest_gbe_direct_touch_coords.cpp
51
52gtest_geis2_grail_backend_CPPFLAGS = \
53 --std=c++0x \
54 -I$(top_srcdir) \
55 -I$(top_srcdir)/include \
56 -I$(top_srcdir)/libutouch-geis \
57 -I$(top_srcdir)/testsuite/gtest \
58 -I$(top_srcdir)/testsuite/x11_mocks \
59 -DTEST_ROOT_DIR=\"$(abs_top_srcdir)/testsuite/\"
60 $(GTEST_CFLAGS)
61
62gtest_geis2_grail_backend_LDADD = \
63 $(top_builddir)/testsuite/gtest/libgtest_geis.a \
64 $(top_builddir)/testsuite/x11_mocks/libx11_mocks.a \
65 $(top_builddir)/libutouch-geis/libutouch-geis.la
66
67#### gtest_geis2_api - Integration tests using xorg-gest and evemu #####
68
69if ENABLE_INTEGRATION_TESTS
70 test_targets += gtest_geis2_api
71endif
72
45gtest_geis2_api_SOURCES = \73gtest_geis2_api_SOURCES = \
46 gtest_attrs.cpp \74 gtest_attrs.cpp \
47 gtest_config.cpp \75 gtest_config.cpp \
@@ -73,3 +101,5 @@
73 geis2_api.log \101 geis2_api.log \
74 geis2_api.xml102 geis2_api.xml
75103
104TESTS = $(test_targets)
105check_PROGRAMS = $(test_targets)
76106
=== added file 'testsuite/geis2/gtest_gbe_direct_touch_coords.cpp'
--- testsuite/geis2/gtest_gbe_direct_touch_coords.cpp 1970-01-01 00:00:00 +0000
+++ testsuite/geis2/gtest_gbe_direct_touch_coords.cpp 2012-04-24 19:38:21 +0000
@@ -0,0 +1,295 @@
1#include "gtest_grail_backend.h"
2#include "x11_mocks.h"
3
4/*
5 Check that when a direct device (e.g. a touchscreen) is being used, the
6 position of a GeisTouch will be in window coordinates instead of input
7 device coordinates.
8
9 This means that the x an y values of a GeisTouch should come from
10 XIDeviceEvent::event_x and XIDeviceEvent::event_y and not from
11 XIDeviceEvent::valuators.values[0] and XIDeviceEvent::valuators.values[1],
12 like it's the case for indirect devices (such as trackpads).
13
14 Regression test for https://bugs.launchpad.net/bugs/984069
15 */
16
17class Geis2GrailBackend : public Geis2GrailBackendBase
18{
19 protected:
20 Geis2GrailBackend() : _subscription(nullptr) {}
21
22 void CreateXMockDevices();
23 void DestroyXMockDevices();
24 void SendXInput2Events();
25
26 virtual void OnEventInitComplete(GeisEvent event);
27 virtual void OnEventGestureBegin(GeisEvent event);
28
29 GeisSubscription _subscription;
30};
31
32void Geis2GrailBackend::CreateXMockDevices()
33{
34 xmock_devices_count = 1;
35 xmock_devices = (XIDeviceInfo*) calloc(xmock_devices_count,
36 sizeof(XIDeviceInfo));
37
38 XITouchClassInfo *touch_info = (XITouchClassInfo*) malloc(sizeof(XITouchClassInfo));
39 touch_info->type = XITouchClass;
40 touch_info->sourceid = 0;
41 touch_info->mode = XIDirectTouch;
42 touch_info->num_touches = 5;
43
44 XIValuatorClassInfo *x_axis_info = (XIValuatorClassInfo*) malloc(sizeof(XIValuatorClassInfo));
45 x_axis_info->type = XIValuatorClass;
46 x_axis_info->sourceid = 0;
47 x_axis_info->number = 0; /* identifies it as being the X axis */
48 x_axis_info->min = -500.0;
49 x_axis_info->max = 500.0;
50 x_axis_info->resolution = 3000; /* counts/meter */
51
52 XIValuatorClassInfo *y_axis_info = (XIValuatorClassInfo*) malloc(sizeof(XIValuatorClassInfo));
53 y_axis_info->type = XIValuatorClass;
54 y_axis_info->sourceid = 0;
55 y_axis_info->number = 1; /* identifies it as being the Y axis */
56 y_axis_info->min = -500.0;
57 y_axis_info->max = 500.0;
58 y_axis_info->resolution = 3000;
59
60 XIAnyClassInfo **classes = (XIAnyClassInfo**) malloc(sizeof(XIAnyClassInfo*)*3);
61 classes[0] = (XIAnyClassInfo*) touch_info;
62 classes[1] = (XIAnyClassInfo*) x_axis_info;
63 classes[2] = (XIAnyClassInfo*) y_axis_info;
64
65 xmock_devices[0].deviceid = 0;
66 xmock_devices[0].name = const_cast<char *>("Fake Touch Screen");
67 xmock_devices[0].use = XISlavePointer;
68 xmock_devices[0].attachment = 1;
69 xmock_devices[0].enabled = True;
70 xmock_devices[0].num_classes = 3;
71 xmock_devices[0].classes = classes;
72}
73
74void Geis2GrailBackend::DestroyXMockDevices()
75{
76 for (int i = 0; i < xmock_devices_count; ++i)
77 {
78 for (int j = 0; j < xmock_devices[i].num_classes; ++j)
79 free(xmock_devices[i].classes[j]);
80 free(xmock_devices[i].classes);
81 }
82 free(xmock_devices);
83}
84
85void Geis2GrailBackend::SendXInput2Events()
86{
87 XEvent event;
88 XGenericEventCookie *xcookie = 0;
89 XIDeviceEvent *device_event = 0;
90 XITouchOwnershipEvent *ownership_event = 0;
91 int serial = 0;
92
93 event.type = GenericEvent;
94 device_event = (XIDeviceEvent*)calloc(1, sizeof(XIDeviceEvent));
95 device_event->serial = serial++;
96 device_event->display = xmock_display;
97 device_event->extension = xmock_xi2_opcode;
98 device_event->evtype = XI_TouchBegin;
99 device_event->time = xmock_server_time;
100 device_event->deviceid = 0;
101 /* The source device that originally generated the event. */
102 device_event->sourceid = device_event->deviceid;
103 device_event->detail = 0; /* touch id */
104 device_event->root = DefaultRootWindow(xmock_display);
105 device_event->event = DefaultRootWindow(xmock_display);
106 device_event->child = 0;
107 device_event->root_x = 123.0f;
108 device_event->root_y = 456.0f;
109 device_event->event_x = device_event->root_x;
110 device_event->event_y = device_event->root_y;
111 device_event->valuators.mask_len = 2; /* two bytes */
112 device_event->valuators.mask = (unsigned char*) malloc(2);
113 XISetMask(device_event->valuators.mask, 0); /* X axis is present */
114 XISetMask(device_event->valuators.mask, 1); /* Y axis is present */
115 device_event->valuators.values = (double*) malloc(sizeof(double)*2);
116 device_event->valuators.values[0] = -200.0;
117 device_event->valuators.values[1] = -100.0;
118 xcookie = &event.xcookie;
119 xcookie->extension = xmock_xi2_opcode;
120 xcookie->evtype = XI_TouchBegin;
121 xcookie->data = device_event;
122 xmock_add_to_event_queue(&event);
123
124 event.type = GenericEvent;
125 device_event = (XIDeviceEvent*)calloc(1, sizeof(XIDeviceEvent));
126 device_event->serial = serial++;
127 device_event->display = xmock_display;
128 device_event->extension = xmock_xi2_opcode;
129 device_event->evtype = XI_TouchBegin;
130 device_event->time = xmock_server_time;
131 device_event->deviceid = 0;
132 device_event->sourceid = device_event->deviceid;
133 device_event->detail = 1; /* touch id */
134 device_event->root = DefaultRootWindow(xmock_display);
135 device_event->event = DefaultRootWindow(xmock_display);
136 device_event->child = 0;
137 device_event->root_x = 222.0f;
138 device_event->root_y = 456.0f;
139 device_event->event_x = device_event->root_x;
140 device_event->event_y = device_event->root_y;
141 device_event->valuators.mask_len = 2;
142 device_event->valuators.mask = (unsigned char*) malloc(2);
143 XISetMask(device_event->valuators.mask, 0);
144 XISetMask(device_event->valuators.mask, 1);
145 device_event->valuators.values = (double*) malloc(sizeof(double)*2);
146 device_event->valuators.values[0] = -150.0;
147 device_event->valuators.values[1] = -100.0;
148 xcookie = &event.xcookie;
149 xcookie->extension = xmock_xi2_opcode;
150 xcookie->evtype = XI_TouchBegin;
151 xcookie->data = device_event;
152 xmock_add_to_event_queue(&event);
153
154 xmock_server_time += 5;
155
156 event.type = GenericEvent;
157 ownership_event = (XITouchOwnershipEvent*)calloc(1, sizeof(XITouchOwnershipEvent));
158 ownership_event->type = GenericEvent;
159 ownership_event->serial = serial++;
160 ownership_event->display = xmock_display;
161 ownership_event->extension = xmock_xi2_opcode;
162 ownership_event->evtype = XI_TouchOwnership;
163 ownership_event->time = xmock_server_time;
164 ownership_event->deviceid = 0;
165 ownership_event->sourceid = ownership_event->deviceid;
166 ownership_event->touchid = 0;
167 ownership_event->root = DefaultRootWindow(xmock_display);
168 ownership_event->event = DefaultRootWindow(xmock_display);
169 ownership_event->child = 0;
170 xcookie = &event.xcookie;
171 xcookie->extension = xmock_xi2_opcode;
172 xcookie->evtype = XI_TouchOwnership;
173 xcookie->data = ownership_event;
174 xmock_add_to_event_queue(&event);
175
176 event.type = GenericEvent;
177 ownership_event = (XITouchOwnershipEvent*)calloc(1, sizeof(XITouchOwnershipEvent));
178 ownership_event->type = GenericEvent;
179 ownership_event->serial = serial++;
180 ownership_event->display = xmock_display;
181 ownership_event->extension = xmock_xi2_opcode;
182 ownership_event->evtype = XI_TouchOwnership;
183 ownership_event->time = xmock_server_time;
184 ownership_event->deviceid = 0;
185 ownership_event->sourceid = ownership_event->deviceid;
186 ownership_event->touchid = 1;
187 ownership_event->root = DefaultRootWindow(xmock_display);
188 ownership_event->event = DefaultRootWindow(xmock_display);
189 ownership_event->child = 0;
190 xcookie = &event.xcookie;
191 xcookie->extension = xmock_xi2_opcode;
192 xcookie->evtype = XI_TouchOwnership;
193 xcookie->data = ownership_event;
194 xmock_add_to_event_queue(&event);
195
196 event.type = GenericEvent;
197 device_event = (XIDeviceEvent*)calloc(1, sizeof(XIDeviceEvent));
198 device_event->serial = serial++;
199 device_event->display = xmock_display;
200 device_event->extension = xmock_xi2_opcode;
201 device_event->evtype = XI_TouchUpdate;
202 device_event->time = xmock_server_time;
203 device_event->deviceid = 0;
204 device_event->sourceid = device_event->deviceid;
205 device_event->detail = 0;
206 device_event->root = DefaultRootWindow(xmock_display);
207 device_event->event = DefaultRootWindow(xmock_display);
208 device_event->child = 0;
209 device_event->root_x = 123.0f;
210 device_event->root_y = 466.0f;
211 device_event->event_x = device_event->root_x;
212 device_event->event_y = device_event->root_y;
213 device_event->valuators.mask_len = 2; /* two bytes */
214 device_event->valuators.mask = (unsigned char*) malloc(2);
215 XISetMask(device_event->valuators.mask, 0);
216 XISetMask(device_event->valuators.mask, 1);
217 device_event->valuators.values = (double*) malloc(sizeof(double)*2);
218 device_event->valuators.values[0] = -200.0;
219 device_event->valuators.values[1] = -90.0;
220 xcookie = &event.xcookie;
221 xcookie->extension = xmock_xi2_opcode;
222 xcookie->evtype = XI_TouchUpdate;
223 xcookie->data = device_event;
224 xmock_add_to_event_queue(&event);
225
226 event.type = GenericEvent;
227 device_event = (XIDeviceEvent*)calloc(1, sizeof(XIDeviceEvent));
228 device_event->serial = serial++;
229 device_event->display = xmock_display;
230 device_event->extension = xmock_xi2_opcode;
231 device_event->evtype = XI_TouchUpdate;
232 device_event->time = xmock_server_time;
233 device_event->deviceid = 0;
234 device_event->sourceid = device_event->deviceid;
235 device_event->detail = 1; /* touch id */
236 device_event->root = DefaultRootWindow(xmock_display);
237 device_event->event = DefaultRootWindow(xmock_display);
238 device_event->child = 0;
239 device_event->root_x = 222.0f;
240 device_event->root_y = 466.0f;
241 device_event->event_x = device_event->root_x;
242 device_event->event_y = device_event->root_y;
243 device_event->valuators.mask_len = 2;
244 device_event->valuators.mask = (unsigned char*) malloc(2);
245 XISetMask(device_event->valuators.mask, 0);
246 XISetMask(device_event->valuators.mask, 1);
247 device_event->valuators.values = (double*) malloc(sizeof(double)*2);
248 device_event->valuators.values[0] = -150.0;
249 device_event->valuators.values[1] = -90.0;
250 xcookie = &event.xcookie;
251 xcookie->extension = xmock_xi2_opcode;
252 xcookie->evtype = XI_TouchUpdate;
253 xcookie->data = device_event;
254 xmock_add_to_event_queue(&event);
255}
256
257void Geis2GrailBackend::OnEventInitComplete(GeisEvent event)
258{
259 _subscription = CreateFilteredSubscription(
260 "My 2-touches Touch", 2, GEIS_GESTURE_TOUCH);
261 ASSERT_NE(nullptr, _subscription);
262
263 SendXInput2Events();
264}
265
266void Geis2GrailBackend::OnEventGestureBegin(GeisEvent event)
267{
268 GeisAttr attr = geis_event_attr_by_name(event, GEIS_EVENT_ATTRIBUTE_TOUCHSET);
269 GeisTouchSet geis_touch_set = (GeisTouchSet) geis_attr_value_to_pointer(attr);
270
271 TouchSet touch_set(geis_touch_set);
272
273 /* check that there are two touch points and that they are in window coordinates
274 (instead of input device coordinates) */
275 ASSERT_EQ(2, touch_set.size());
276 ASSERT_TRUE(touch_set.contains(123.0f, 456.0f));
277 ASSERT_TRUE(touch_set.contains(222.0f, 456.0f));
278}
279
280TEST_F(Geis2GrailBackend, DirectDeviceTouchCoords)
281{
282 CreateXMockDevices();
283
284 Geis geis = geis_new(GEIS_INIT_UTOUCH_GRAIL_BACKEND,
285 nullptr);
286 ASSERT_NE(nullptr, geis);
287
288 Run(geis);
289
290 if (_subscription)
291 geis_subscription_delete(_subscription);
292 geis_delete(geis);
293
294 DestroyXMockDevices();
295}
0296
=== added file 'testsuite/geis2/gtest_grail_backend.cpp'
--- testsuite/geis2/gtest_grail_backend.cpp 1970-01-01 00:00:00 +0000
+++ testsuite/geis2/gtest_grail_backend.cpp 2012-04-24 19:38:21 +0000
@@ -0,0 +1,134 @@
1#include "gtest_grail_backend.h"
2#include "x11_mocks.h"
3#include <iostream>
4
5#define ADD_FAILURE_AND_RETURN(ret) \
6 {\
7 ADD_FAILURE();\
8 return ret;\
9 }\
10
11Touch::Touch(GeisTouch geis_touch)
12{
13 GeisAttr attr = geis_touch_attr_by_name(geis_touch, GEIS_TOUCH_ATTRIBUTE_X);
14 x = geis_attr_value_to_float(attr);
15
16 attr = geis_touch_attr_by_name(geis_touch, GEIS_TOUCH_ATTRIBUTE_Y);
17 y = geis_attr_value_to_float(attr);
18
19 attr = geis_touch_attr_by_name(geis_touch, GEIS_TOUCH_ATTRIBUTE_ID);
20 id = geis_attr_value_to_integer(attr);
21}
22
23TouchSet::TouchSet(GeisTouchSet geis_touch_set)
24{
25 int count = geis_touchset_touch_count(geis_touch_set);
26 for (int i = 0; i < count; ++i)
27 push_back(Touch(geis_touchset_touch(geis_touch_set, i)));
28}
29
30bool TouchSet::contains(float x, float y)
31{
32 for (auto touch : *this)
33 {
34 if (touch.x == x && touch.y == y)
35 return true;
36 }
37 return false;
38}
39
40GeisSubscription Geis2GrailBackendBase::CreateFilteredSubscription(
41 GeisString name, GeisSize num_touches, GeisString gesture_class)
42{
43 GeisStatus status = GEIS_STATUS_UNKNOWN_ERROR;
44 GeisFilter filter = nullptr;
45 GeisSubscription sub = nullptr;
46
47 sub = geis_subscription_new(_geis, name, GEIS_SUBSCRIPTION_NONE);
48
49 filter = geis_filter_new(_geis, "filter");
50 if (filter == nullptr) ADD_FAILURE_AND_RETURN(nullptr);
51
52 status = geis_filter_add_term(filter,
53 GEIS_FILTER_CLASS,
54 GEIS_CLASS_ATTRIBUTE_NAME, GEIS_FILTER_OP_EQ, gesture_class,
55 GEIS_GESTURE_ATTRIBUTE_TOUCHES, GEIS_FILTER_OP_EQ, num_touches,
56 nullptr);
57 if (status != GEIS_STATUS_SUCCESS) ADD_FAILURE_AND_RETURN(nullptr);
58
59 status = geis_filter_add_term(filter,
60 GEIS_FILTER_REGION,
61 GEIS_REGION_ATTRIBUTE_WINDOWID, GEIS_FILTER_OP_EQ,
62 DefaultRootWindow(xmock_display),
63 nullptr);
64 if (status != GEIS_STATUS_SUCCESS) ADD_FAILURE_AND_RETURN(nullptr);
65
66 status = geis_subscription_add_filter(sub, filter);
67 if (status != GEIS_STATUS_SUCCESS) ADD_FAILURE_AND_RETURN(nullptr);
68
69 status = geis_subscription_activate(sub);
70 if (status != GEIS_STATUS_SUCCESS) ADD_FAILURE_AND_RETURN(nullptr);
71
72 return sub;
73}
74
75bool Geis2GrailBackendBase::DispatchAndProcessEvents()
76{
77 bool got_events = false;
78 GeisEvent event;
79 GeisStatus status;
80
81 status = geis_dispatch_events(_geis);
82 if (status != GEIS_STATUS_SUCCESS) ADD_FAILURE_AND_RETURN(false);
83
84 status = geis_next_event(_geis, &event);
85 if (status != GEIS_STATUS_SUCCESS
86 && status != GEIS_STATUS_CONTINUE
87 && status != GEIS_STATUS_EMPTY)
88 ADD_FAILURE_AND_RETURN(false);
89
90 if (status == GEIS_STATUS_SUCCESS || status == GEIS_STATUS_CONTINUE)
91 got_events = true;
92
93 while (status == GEIS_STATUS_CONTINUE || status == GEIS_STATUS_SUCCESS)
94 {
95 switch (geis_event_type(event))
96 {
97 case GEIS_EVENT_INIT_COMPLETE:
98 OnEventInitComplete(event);
99 break;
100 case GEIS_EVENT_GESTURE_BEGIN:
101 OnEventGestureBegin(event);
102 break;
103 case GEIS_EVENT_GESTURE_UPDATE:
104 OnEventGestureUpdate(event);
105 break;
106 case GEIS_EVENT_GESTURE_END:
107 OnEventGestureEnd(event);
108 break;
109 default:
110 break;
111 }
112 geis_event_delete(event);
113 status = geis_next_event(_geis, &event);
114 }
115
116 return got_events;
117}
118
119void Geis2GrailBackendBase::Run(Geis geis)
120{
121 _geis = geis;
122
123 bool got_events;
124 do
125 {
126 got_events = DispatchAndProcessEvents();
127 } while (got_events);
128}
129
130int main(int argc, char **argv)
131{
132 testing::InitGoogleTest(&argc, argv);
133 return RUN_ALL_TESTS();
134}
0135
=== added file 'testsuite/geis2/gtest_grail_backend.h'
--- testsuite/geis2/gtest_grail_backend.h 1970-01-01 00:00:00 +0000
+++ testsuite/geis2/gtest_grail_backend.h 2012-04-24 19:38:21 +0000
@@ -0,0 +1,52 @@
1#ifndef GTEST_GRAIL_BACKEND_H
2#define GTEST_GRAIL_BACKEND_H
3
4#include <gtest/gtest.h>
5#include <geis/geis.h>
6#include <vector>
7
8class Touch
9{
10 public:
11 Touch(GeisTouch geis_touch);
12
13 int id;
14 float x;
15 float y;
16};
17
18class TouchSet : public std::vector<Touch>
19{
20 public:
21 TouchSet(GeisTouchSet geis_touch_set);
22 bool contains(float x, float y);
23};
24
25class Geis2GrailBackendBase : public ::testing::Test
26{
27 protected:
28 Geis2GrailBackendBase() : _geis(nullptr) {}
29 virtual ~Geis2GrailBackendBase() {}
30
31 /* Dispatch and process Geis events in a loop until there are no more
32 events. */
33 void Run(Geis geis);
34
35
36 /* Creates (and activates) a GeisSubscription with the given name
37 and with filters for the given number of touches and gesture class. */
38 GeisSubscription CreateFilteredSubscription(GeisString name,
39 GeisSize num_touches,
40 GeisString gesture_class);
41
42 virtual void OnEventInitComplete(GeisEvent event) {}
43 virtual void OnEventGestureBegin(GeisEvent event) {}
44 virtual void OnEventGestureUpdate(GeisEvent event) {}
45 virtual void OnEventGestureEnd(GeisEvent event) {}
46
47 private:
48 Geis _geis;
49 bool DispatchAndProcessEvents();
50};
51
52#endif // GTEST_GRAIL_BACKEND_H
053
=== modified file 'testsuite/gtest/Makefile.am'
--- testsuite/gtest/Makefile.am 2012-03-30 11:51:09 +0000
+++ testsuite/gtest/Makefile.am 2012-04-24 19:38:21 +0000
@@ -3,26 +3,31 @@
3# @brief automake recipe for the geis gtest testsuite harness directory3# @brief automake recipe for the geis gtest testsuite harness directory
4#4#
55
6if ENABLE_INTEGRATION_TESTS6if HAVE_GTEST
7 check_LIBRARIES = libgtest_geis.a7 check_LIBRARIES = libgtest_geis.a
8endif8endif
99
10libgtest_geis_a_SOURCES = \
11 gtest_evemu_device.h gtest_evemu_device.cpp \
12 gtest_geis_fixture.h gtest_geis_fixture.cpp \
13 gtest_geis1_fixture.h gtest_geis1_fixture.cpp
14
15nodist_libgtest_geis_a_SOURCES = \10nodist_libgtest_geis_a_SOURCES = \
16 $(XORG_GTEST_SOURCE)/src/xorg-gtest-all.cpp \
17 $(GTEST_SOURCE)/src/gtest-all.cc11 $(GTEST_SOURCE)/src/gtest-all.cc
1812
19libgtest_geis_a_CPPFLAGS = \13libgtest_geis_a_CPPFLAGS = \
20 --std=c++0x \
21 -I$(top_srcdir) \14 -I$(top_srcdir) \
22 -I$(top_srcdir)/include \15 -I$(top_srcdir)/include \
23 -I$(top_srcdir)/libutouch-geis \16 -I$(top_srcdir)/libutouch-geis \
24 -DTEST_ROOT_DIR=\"$(abs_top_srcdir)/testsuite/\" \17 -DTEST_ROOT_DIR=\"$(abs_top_srcdir)/testsuite/\" \
18 $(GTEST_CPPFLAGS)
19
20if ENABLE_INTEGRATION_TESTS
21libgtest_geis_a_SOURCES = \
22 gtest_evemu_device.h gtest_evemu_device.cpp \
23 gtest_geis_fixture.h gtest_geis_fixture.cpp \
24 gtest_geis1_fixture.h gtest_geis1_fixture.cpp
25
26nodist_libgtest_geis_a_SOURCES += \
27 $(XORG_GTEST_SOURCE)/src/xorg-gtest-all.cpp
28
29libgtest_geis_a_CPPFLAGS += \
25 $(XORG_GTEST_CPPFLAGS) \30 $(XORG_GTEST_CPPFLAGS) \
26 $(GTEST_CPPFLAGS) \
27 $(EVEMU_CFLAGS) \31 $(EVEMU_CFLAGS) \
28 $(XORG_GTEST_CFLAGS)32 $(XORG_GTEST_CFLAGS)
33endif
2934
=== added directory 'testsuite/x11_mocks'
=== added file 'testsuite/x11_mocks/Makefile.am'
--- testsuite/x11_mocks/Makefile.am 1970-01-01 00:00:00 +0000
+++ testsuite/x11_mocks/Makefile.am 2012-04-24 19:38:21 +0000
@@ -0,0 +1,13 @@
1#
2# @file testsuite/x11_mocks/Makefile.am
3# @brief automake recipe for the X11 mockups
4#
5
6check_LIBRARIES = libx11_mocks.a
7
8libx11_mocks_a_SOURCES = \
9 x11_mocks.c
10
11libx11_mocks_a_CFLAGS = \
12 --std=c99
13
014
=== added file 'testsuite/x11_mocks/x11_mocks.c'
--- testsuite/x11_mocks/x11_mocks.c 1970-01-01 00:00:00 +0000
+++ testsuite/x11_mocks/x11_mocks.c 2012-04-24 19:38:21 +0000
@@ -0,0 +1,406 @@
1/* needed to break into 'Display' struct internals. */
2#define XLIB_ILLEGAL_ACCESS
3#include <X11/Xlib.h>
4
5#include <geis/geis.h>
6
7#include "x11_mocks.h"
8
9#include <sys/eventfd.h>
10#include <stdio.h>
11#include <unistd.h>
12
13int xmock_xi2_opcode = 42;
14int xmock_xi2_event_base = 40000;
15int xmock_xi2_error_base = 40000;
16int xmock_xsync_event_base = 50000;
17int xmock_xsync_error_base = 50000;
18Display *xmock_display = NULL;
19uint64_t xmock_server_time = 0;
20
21XIDeviceInfo *xmock_devices = NULL;
22int xmock_devices_count = 0;
23
24/* id to be used for the next alarm that gets created */
25XSyncAlarm _xmock_next_alarm = 1;
26
27struct EventQueueItem
28{
29 XEvent event;
30 struct EventQueueItem *next;
31} *xmock_event_queue = NULL;
32
33#define XMOCK_PRINT_FUNCTION _xmock_print_function(__func__)
34void _xmock_print_function(const char *function)
35{
36 static int debug_enabled = -1;
37 if (debug_enabled == -1)
38 {
39 if (getenv("XMOCK_DEBUG"))
40 debug_enabled = 1;
41 else
42 debug_enabled = 0;
43 }
44
45 if (debug_enabled)
46 printf("XMOCK: %s mock called.\n", function);
47}
48
49void xmock_add_to_event_queue(const XEvent *event)
50{
51 struct EventQueueItem *new_item = malloc(sizeof(struct EventQueueItem));
52 new_item->event = *event;
53 new_item->next = NULL;
54
55 if (!xmock_event_queue)
56 {
57 xmock_event_queue = new_item;
58 }
59 else
60 {
61 struct EventQueueItem *last_item = xmock_event_queue;
62 while (last_item->next)
63 {
64 last_item = last_item->next;
65 }
66 last_item->next = new_item;
67 }
68
69 static const uint64_t num = 1;
70 if (write(xmock_display->fd, &num, sizeof(num)) != sizeof(num))
71 {
72 fprintf(stderr, "ERROR: failed to update eventfd instance,\n");
73 exit(1);
74 }
75}
76
77Display *XOpenDisplay(_Xconst char *display_name)
78{
79 XMOCK_PRINT_FUNCTION;
80 (void)display_name;
81
82 Display *display = (Display*)calloc(1, sizeof(Display));
83 display->fd = eventfd(0, EFD_NONBLOCK);
84 display->default_screen = 0;
85 display->nscreens = 1;
86 display->screens = (Screen*)calloc(1, sizeof(Screen));
87 display->screens[0].root = 1;
88
89 xmock_display = display;
90
91 return display;
92}
93
94int XCloseDisplay(Display *display)
95{
96 XMOCK_PRINT_FUNCTION;
97
98 close(display->fd);
99 free(display->screens);
100 free(display);
101
102 xmock_display = NULL;
103
104 return 0;
105}
106
107int XSync(Display *display, Bool discard)
108{
109 (void)display;
110 (void)discard;
111 return 0;
112}
113
114int XFlush(Display *display)
115{
116 (void)display;
117 return 0;
118}
119
120Bool XQueryExtension(Display *display, const char *name,
121 int *major_opcode_return, int *first_event_return, int *first_error_return)
122{
123 XMOCK_PRINT_FUNCTION;
124 (void)display;
125 (void)name; /* assuming name == "XInputExtension" */
126
127 *major_opcode_return = xmock_xi2_opcode;
128 *first_event_return = xmock_xi2_event_base;
129 *first_error_return = xmock_xi2_error_base;
130
131 return True;
132}
133
134int XPending(Display *display)
135{
136 XMOCK_PRINT_FUNCTION;
137 (void)display;
138
139 int pending_events_count = 0;
140 struct EventQueueItem *item = xmock_event_queue;
141 while (item != NULL)
142 {
143 ++pending_events_count;
144 item = item->next;
145 }
146 return pending_events_count;
147}
148
149int XNextEvent(Display *display, XEvent *event_return)
150{
151 XMOCK_PRINT_FUNCTION;
152 (void)display;
153
154
155 if (xmock_event_queue)
156 {
157 uint64_t num = 1;
158 ssize_t bytes_read = read(xmock_display->fd, &num, sizeof(num));
159 (void)bytes_read;
160
161 *event_return = xmock_event_queue->event;
162
163 struct EventQueueItem *removed_item = xmock_event_queue;
164 xmock_event_queue = xmock_event_queue->next;
165 free(removed_item);
166 }
167 else
168 {
169 /* not going to block... */
170 }
171
172 return 0;
173}
174
175Bool XGetEventData(Display *display, XGenericEventCookie *cookie)
176{
177 XMOCK_PRINT_FUNCTION;
178 (void)display;
179 (void)cookie;
180 return True;
181}
182
183void XFreeEventData(Display *display, XGenericEventCookie *cookie)
184{
185 XMOCK_PRINT_FUNCTION;
186 (void)display;
187
188 if (cookie->data && cookie->extension == xmock_xi2_opcode)
189 {
190 if (cookie->evtype == XI_TouchBegin
191 || cookie->evtype == XI_TouchUpdate
192 || cookie->evtype == XI_TouchEnd)
193 {
194 XIDeviceEvent *device_event = (XIDeviceEvent*) cookie->data;
195 free(device_event->valuators.mask);
196 free(device_event->valuators.values);
197 }
198 free(cookie->data);
199 }
200}
201
202XIDeviceInfo* XIQueryDevice(Display * display,
203 int deviceid,
204 int * ndevices_return)
205{
206 XMOCK_PRINT_FUNCTION;
207 (void)display;
208 (void)deviceid; /* assuming XIAllDevices */
209
210 XIDeviceInfo *devices;
211
212 devices = calloc(xmock_devices_count, sizeof(XIDeviceInfo));
213
214 for (int i = 0; i < xmock_devices_count; ++i) {
215 devices[i] = xmock_devices[i];
216 }
217
218 *ndevices_return = xmock_devices_count;
219
220 return devices;
221}
222
223void XIFreeDeviceInfo(XIDeviceInfo *info)
224{
225 XMOCK_PRINT_FUNCTION;
226 free(info);
227}
228
229Status XIQueryVersion(Display *display,
230 int *major_version_inout,
231 int *minor_version_inout)
232{
233 XMOCK_PRINT_FUNCTION;
234 (void)display;
235 *major_version_inout = 2;
236 *minor_version_inout = 2;
237 return Success;
238}
239
240Status XISelectEvents(Display *display,
241 Window win,
242 XIEventMask *masks,
243 int num_masks)
244{
245 XMOCK_PRINT_FUNCTION;
246 (void)display;
247 (void)win;
248 (void)masks;
249 (void)num_masks;
250 return Success;
251}
252
253int XIGrabTouchBegin(
254 Display* display,
255 int deviceid,
256 Window grab_window,
257 int owner_events,
258 XIEventMask *mask,
259 int num_modifiers,
260 XIGrabModifiers *modifiers_inout)
261{
262 XMOCK_PRINT_FUNCTION;
263 (void)display;
264 (void)deviceid;
265 (void)grab_window;
266 (void)owner_events;
267 (void)mask;
268
269 for (int i = 0; i < num_modifiers; ++i)
270 {
271 modifiers_inout[i].status = XIGrabSuccess;
272 }
273
274 return 0;
275}
276
277Status XIUngrabTouchBegin(
278 Display* display,
279 int deviceid,
280 Window grab_window,
281 int num_modifiers,
282 XIGrabModifiers *modifiers)
283{
284 XMOCK_PRINT_FUNCTION;
285 (void)display;
286 (void)deviceid;
287 (void)grab_window;
288 (void)num_modifiers;
289 (void)modifiers;
290 return Success;
291}
292
293Status XIAllowTouchEvents(
294 Display* display,
295 int deviceid,
296 unsigned int touchid,
297 Window grab_window,
298 int event_mode)
299{
300 XMOCK_PRINT_FUNCTION;
301 (void)display;
302 (void)deviceid;
303 (void)touchid;
304 (void)grab_window;
305 (void)event_mode;
306 return Success;
307}
308
309Status XSyncQueryExtension(
310 Display* dpy,
311 int* event_base_return,
312 int* error_base_return)
313{
314 XMOCK_PRINT_FUNCTION;
315 (void)dpy;
316 *event_base_return = xmock_xsync_event_base;
317 *error_base_return = xmock_xsync_error_base;
318 return True;
319}
320
321Status XSyncInitialize(
322 Display* dpy,
323 int* major_version_return,
324 int* minor_version_return)
325{
326 XMOCK_PRINT_FUNCTION;
327 (void)dpy;
328 *major_version_return = 1;
329 *minor_version_return = 0;
330 return True;
331}
332
333XSyncSystemCounter *XSyncListSystemCounters(
334 Display* dpy,
335 int* n_counters_return)
336{
337 XMOCK_PRINT_FUNCTION;
338 (void)dpy;
339 *n_counters_return = 1;
340
341 XSyncSystemCounter *sys_counter = malloc(sizeof(XSyncSystemCounter));
342 sys_counter->name = "SERVERTIME";
343 sys_counter->counter = 1;
344 sys_counter->resolution.hi = 1;
345 sys_counter->resolution.lo = 0;
346 return sys_counter;
347}
348
349void XSyncFreeSystemCounterList(XSyncSystemCounter* list)
350{
351 XMOCK_PRINT_FUNCTION;
352 free(list);
353}
354
355XSyncAlarm XSyncCreateAlarm(
356 Display* dpy,
357 unsigned long values_mask,
358 XSyncAlarmAttributes* values)
359{
360 XMOCK_PRINT_FUNCTION;
361 (void)dpy;
362
363 XSyncAlarmNotifyEvent alarm_notify;
364 alarm_notify.type = xmock_xsync_event_base + XSyncAlarmNotify;
365 alarm_notify.alarm = _xmock_next_alarm;
366 alarm_notify.counter_value = values->trigger.wait_value;
367 xmock_add_to_event_queue((XEvent*)&alarm_notify);
368
369 XSyncValue time = values->trigger.wait_value;
370 uint64_t timeout = (uint64_t)XSyncValueHigh32(time) << 32
371 | (uint64_t)XSyncValueLow32(time);
372 xmock_server_time = timeout + 1;
373
374 return _xmock_next_alarm++;
375}
376
377Status XSyncDestroyAlarm(
378 Display* dpy,
379 XSyncAlarm alarm)
380{
381 XMOCK_PRINT_FUNCTION;
382 (void)dpy;
383 (void)alarm;
384}
385
386void XSyncIntsToValue(
387 XSyncValue* pv,
388 unsigned int l,
389 int h)
390{
391 XMOCK_PRINT_FUNCTION;
392 pv->hi = h;
393 pv->lo = l;
394}
395
396int XSyncValueHigh32(XSyncValue v)
397{
398 XMOCK_PRINT_FUNCTION;
399 return v.hi;
400}
401
402unsigned int XSyncValueLow32(XSyncValue v)
403{
404 XMOCK_PRINT_FUNCTION;
405 return v.lo;
406}
0407
=== added file 'testsuite/x11_mocks/x11_mocks.h'
--- testsuite/x11_mocks/x11_mocks.h 1970-01-01 00:00:00 +0000
+++ testsuite/x11_mocks/x11_mocks.h 2012-04-24 19:38:21 +0000
@@ -0,0 +1,34 @@
1#ifndef X11_MOCKS_H
2#define X11_MOCKS_H
3
4#include <X11/Xlib.h>
5#include <X11/extensions/XInput2.h>
6#include <X11/extensions/sync.h>
7
8#ifdef __cplusplus
9extern "C" {
10#endif
11
12extern int xmock_xi2_opcode;
13extern int xmock_xi2_event_base;
14extern int xmock_xi2_error_base;
15extern int xmock_xsync_event_base;
16extern int xmock_xsync_error_base;
17extern Display *xmock_display;
18extern uint64_t xmock_server_time;
19
20/* to be filled by user. A copy of it will be returned by each
21 XIQueryDevice call */
22extern XIDeviceInfo *xmock_devices;
23extern int xmock_devices_count;
24
25/* Adds the given XEvent to the xmock event queue.
26 The Diplay connection will signal that there are
27 pending events */
28extern void xmock_add_to_event_queue(const XEvent* event);
29
30#ifdef __cplusplus
31}
32#endif
33
34#endif

Subscribers

People subscribed via source and target branches