Merge lp:~oif-team/geis/geis2_add_regions into lp:geis

Proposed by Stephen M. Webb
Status: Merged
Merged at revision: 96
Proposed branch: lp:~oif-team/geis/geis2_add_regions
Merge into: lp:geis
Diff against target: 778 lines (+660/-0)
12 files modified
ChangeLog (+21/-0)
include/geis/geis.h (+58/-0)
libutouch-geis/Makefile.am (+1/-0)
libutouch-geis/geis_region.c (+291/-0)
libutouch-geis/geis_region.h (+103/-0)
libutouch-geis/libutouch-geis.ver (+3/-0)
testsuite/geis2/Makefile.am (+1/-0)
testsuite/geis2/check_geis2_api.c (+2/-0)
testsuite/geis2/check_region.c (+65/-0)
testsuite/libutouch-geis/Makefile.am (+1/-0)
testsuite/libutouch-geis/check_geis2_internals.c (+2/-0)
testsuite/libutouch-geis/check_region.c (+112/-0)
To merge this branch: bzr merge lp:~oif-team/geis/geis2_add_regions
Reviewer Review Type Date Requested Status
Henrik Rydberg (community) Approve
Review via email: mp+43901@code.launchpad.net

Description of the change

Added GEIS v2.0 region module with accompanying unit test suites.

To post a comment you must log in.
Revision history for this message
Henrik Rydberg (rydberg) wrote :

//GeisRegion geis_region_new()
+ geis_error("error allocaring region");

+ while (init_arg_name)
+ {
+ if (0 == strcmp(init_arg_name, GEIS_REGION_X11_ROOT))
+ {
+ region->type = strdup(init_arg_name);
+ geis_debug("using X11 root");

a break here would make it more apparent that type is normally assigned once

+ }
+ else if (0 == strcmp(init_arg_name, GEIS_REGION_X11_WINDOWID))
+ {
+ region->type = strdup(init_arg_name);
+ region->data.windowid = va_arg(varargs, int);
+ geis_debug("using X11 windowid 0x%08x", region->data.windowid);

ditto

+ }

//GeisStatus geis_region_delete(GeisRegion region)
+{
+ --region->ref_count;
+ if (0 == region->ref_count)

With this construct, we will have to be careful when using threads operating under mutexes against a single geis instance. If two threads happen to queue for the same code path... boom.

Reading on, I see you already warn about this in the text.

A way around this is to split the ref counting from the actual freeing, and keep old regions around for recycling.

+ {
+ if (region->name)
+ free((char *)region->name);
+ free((char *)region->type);
+ free(region);
+ }
+ return GEIS_STATUS_SUCCESS;
+}

Thanks!

review: Needs Fixing
lp:~oif-team/geis/geis2_add_regions updated
96. By Stephen M. Webb

Added GEIS v2.0 region module.

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

Fixed the comment typo, added the missing duplicate checks, and made the refcounting atomic to avoid threading issues. The container is still not threadsafe, that can come later.

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

Very nice! The "if (region->name)" is redundant, but never mind.

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

I know this has been merged, but I would like to see geis_region_delete() renamed to something like geis_region_deref() or geis_region_release(). Delete implies that the object will be freed immediately, which is not what happens here if a reference is held elsewhere.

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

On Tue, 2010-12-21 at 18:28 +0000, Chase Douglas wrote:
> I know this has been merged, but I would like to see geis_region_delete() renamed to something
> like geis_region_deref() or geis_region_release(). Delete implies that the object will be freed
> immediately, which is not what happens here if a reference is held elsewhere.

That would be awfully confusing for the library user, considering there
is no geis_region_ref() anywhere in sight. In fact, the library user
has no idea this is a reference counted object. As far as they are
concerned, when they call geis_region_delete(), the object is deleted
and is no longer valid.

The refcounting is an internal feature of this particular object to
ensure persistence event though lifetime control is in the user's hands.
The refcounting is explicit on other objects because they are created by
the API rather than the user.

The rest of the library uses _new() and _delete() as the construction
and destruction calls where object lifetime is under the control of the
user. Consistency in an API is a good thing.

I'm less worried about what has to go on under the hood to make things
easier for the library user, since I'm assuming anyone who is
maintaining the library is capable of figuring things out by reading the
code. The typical library user should not have to read the code.

--
Stephen M. Webb <email address hidden>
Canonical Ltd.

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

Ahh, I thought the _ref() function was public. I'm fine with it as is then.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'ChangeLog'
--- ChangeLog 2010-12-15 01:48:35 +0000
+++ ChangeLog 2010-12-17 02:59:09 +0000
@@ -1,3 +1,24 @@
12010-12-15 Stephen M. Webb <stephen.webb@canonical.com>
2
3 Added GEIS v2.0 region module.
4
5 * libutouch-geis/geis_region.c: new file
6 * libutouch-geis/geis_region.h: new file
7 * testsuite/geis2/check_region.c: new test suite
8 * testsuite/libutouch-geis/check_region.c: new test suite
9 * include/geis/geis.h (GeisRegion): new typedef
10 (GEIS_REGION_X11_ROOT): new region initialization constant
11 (GEIS_REGION_X11_WINDOWID): new region initialization constant
12 (geis_region_new): new function
13 (geis_region_delete): new function
14 (geis_region_name): new function
15 * libutouch-geis/Makefile.am: added new files
16 * libutouch-geis/libutouch-geis.ver: added new symbols
17 * testsuite/geis2/Makefile.am: added new test suite files
18 * testsuite/geis2/check_geis2_api.c: added new test suite
19 * testsuite/libutouch-geis/Makefile.am: added new test suite files
20 * testsuite/libutouch-geis/check_geis2_internals.c: added new test suite
21
12010-12-12 Stephen M. Webb <stephen.webb@canonical.com>222010-12-12 Stephen M. Webb <stephen.webb@canonical.com>
223
3 Fixed some container expansion errors.24 Fixed some container expansion errors.
425
=== modified file 'include/geis/geis.h'
--- include/geis/geis.h 2010-12-15 01:48:35 +0000
+++ include/geis/geis.h 2010-12-17 02:59:09 +0000
@@ -636,6 +636,64 @@
636/* @} */636/* @} */
637637
638/**638/**
639 * @defgroup geis2_region Gesture Regions (GEIS v2.0)
640 * @{
641 */
642
643typedef struct _GeisRegion *GeisRegion;
644
645/**
646 * @defgroup geis2_region_init_args Gesture Region Initialization Arguments
647 *
648 * Gesture regions are created to describe a particular display/feedback region.
649 * The type of the region can not be changed after creation (just create a new
650 * region for that). The types of regions are platform specific and each type
651 * may require addition arguments.
652 *
653 * The following region initialization argument names are required by the
654 * GEIS v2.0 specification.
655 *
656 * @{
657 */
658#define GEIS_REGION_X11_ROOT "org.libgeis.region.x11.root"
659#define GEIS_REGION_X11_WINDOWID "org.libgeis.region.x11.windowid"
660
661/* @} */
662
663/**
664 * Creates a new GEIS v2.0 region.
665 *
666 * @param[in] geis The GEIS API instance.
667 * @param[in] name A name. Used for diagnostics.
668 * @param[in] init_arg_name The name of the first initialization argument.
669 *
670 * The initialization argument list must be terminated by a NULL.
671 *
672 * @returns a newly created region, or NULL on failure.
673 */
674GEIS_API GeisRegion geis_region_new(Geis geis,
675 GeisString name,
676 GeisString init_arg_name, ...);
677
678/**
679 * Destroys a GEIS v2.0 region.
680 *
681 * @param[in] region The region.
682 */
683GEIS_API GeisStatus geis_region_delete(GeisRegion region);
684
685/**
686 * Gets the name of a GEIS v2.0 region.
687 *
688 * @param[in] region The region.
689 *
690 * Returns the @p name value used when creating the region.
691 */
692GEIS_API GeisString geis_region_name(GeisRegion region);
693
694/* @} */
695
696/**
639 * @defgroup geis2_subscription Gesture Subscription (GEIS v2.0)697 * @defgroup geis2_subscription Gesture Subscription (GEIS v2.0)
640 * @{698 * @{
641 */699 */
642700
=== modified file 'libutouch-geis/Makefile.am'
--- libutouch-geis/Makefile.am 2010-12-09 16:14:15 +0000
+++ libutouch-geis/Makefile.am 2010-12-17 02:59:09 +0000
@@ -32,6 +32,7 @@
32 geis_event.h geis_event.c \32 geis_event.h geis_event.c \
33 geis_event_queue.h geis_event_queue.c \33 geis_event_queue.h geis_event_queue.c \
34 geis_logging.h geis_logging.c \34 geis_logging.h geis_logging.c \
35 geis_region.h geis_region.c \
35 geis_subscription.h geis_subscription.c \36 geis_subscription.h geis_subscription.c \
36 geis_private.h geis.c37 geis_private.h geis.c
3738
3839
=== added file 'libutouch-geis/geis_region.c'
--- libutouch-geis/geis_region.c 1970-01-01 00:00:00 +0000
+++ libutouch-geis/geis_region.c 2010-12-17 02:59:09 +0000
@@ -0,0 +1,291 @@
1/**
2 * @file libutouch-geis/geis_region.c
3 * @brief implementation of the uTouch GEIS v2.0 API region module
4 *
5 * Copyright 2010 Canonical Ltd.
6 *
7 * This library is free software; you can redistribute it and/or modify it under
8 * the terms of the GNU Lesser General Public License as published by the Free
9 * Software Foundation; either version 3 of the License, or (at your option) any
10 * later version.
11 *
12 * This library is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
15 * details.
16 *
17 * You should have received a copy of the GNU Lesser General Public License
18 * along with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21#include "geis_config.h"
22#include "geis_region.h"
23
24#include "geis_error.h"
25#include "geis_logging.h"
26#include <string.h>
27#include <stdarg.h>
28#include <stdlib.h>
29
30
31struct _GeisRegion
32{
33 int ref_count;
34 GeisString type;
35 GeisString name;
36 union {
37 int windowid;
38 } data;
39};
40
41struct _GeisRegionBag
42{
43 GeisRegion *region_store;
44 GeisSize region_store_size;
45 GeisSize region_count;
46};
47
48static const int region_bag_growth_constant = 2;
49
50
51/*
52 * Constructs a region bag.
53 */
54GeisRegionBag
55geis_region_bag_new()
56{
57 GeisRegionBag bag = calloc(1, sizeof(struct _GeisRegionBag));
58 if (!bag)
59 {
60 geis_error("failed to allocate region bag");
61 goto final_exit;
62 }
63
64 bag->region_store_size = 3;
65 bag->region_count = 0;
66 bag->region_store = calloc(bag->region_store_size, sizeof(GeisRegion));
67 if (!bag->region_store)
68 {
69 geis_error("failed to allocate region bag store");
70 goto unwind_bag;
71 }
72 goto final_exit;
73
74unwind_bag:
75 free(bag);
76final_exit:
77 return bag;
78}
79
80
81/*
82 * Destroys a region bag.
83 */
84void
85geis_region_bag_delete(GeisRegionBag bag)
86{
87 GeisSize i;
88 for (i = bag->region_count; i > 0; --i)
89 {
90 geis_region_delete(bag->region_store[i-1]);
91 }
92 free(bag);
93}
94
95
96/*
97 * Gets the number of regions held in a bag.
98 */
99GeisSize
100geis_region_bag_count(GeisRegionBag bag)
101{
102 return bag->region_count;
103}
104
105
106/*
107 * Gets an indicated region from a bag.
108 */
109GeisRegion
110geis_region_bag_region(GeisRegionBag bag, GeisSize index)
111{
112 GeisRegion region = NULL;
113 if (index < bag->region_count)
114 {
115 region = bag->region_store[index];
116 }
117 return region;
118}
119
120
121/*
122 * Puts a region into a bag.
123 */
124GeisStatus
125geis_region_bag_insert(GeisRegionBag bag, GeisRegion region)
126{
127 GeisStatus status = GEIS_STATUS_UNKNOWN_ERROR;
128 if (bag->region_count >= bag->region_store_size)
129 {
130 GeisSize new_store_size = bag->region_store_size * region_bag_growth_constant;
131 GeisRegion *new_store = realloc(bag->region_store,
132 new_store_size * sizeof(struct _GeisRegion));
133 if (!new_store)
134 {
135 geis_error("failed to reallocate region bag");
136 goto error_exit;
137 }
138 bag->region_store = new_store;
139 bag->region_store_size = new_store_size;
140 }
141 bag->region_store[bag->region_count++] = region;
142 status = GEIS_STATUS_SUCCESS;
143
144error_exit:
145 return status;
146}
147
148
149/**
150 * Takes a region out of a bag.
151 */
152GeisStatus
153geis_region_bag_remove(GeisRegionBag bag, GeisRegion region)
154{
155 GeisSize i;
156 GeisStatus status = GEIS_STATUS_SUCCESS;
157 for (i = 0; i < bag->region_count; ++i)
158 {
159 if (bag->region_store[i] == region)
160 {
161 GeisSize j;
162 geis_region_delete(bag->region_store[i]);
163 --bag->region_count;
164 for (j = i; j < bag->region_count; ++j)
165 {
166 bag->region_store[j] = bag->region_store[j+1];
167 }
168 break;
169 }
170 }
171 return status;
172}
173
174
175/*
176 * Constructs a region.
177 */
178GeisRegion
179geis_region_new(Geis geis,
180 GeisString name,
181 GeisString init_arg_name, ...)
182{
183 GeisRegion region = NULL;
184 va_list varargs;
185
186 region = calloc(1, sizeof(struct _GeisRegion));
187 if (!region)
188 {
189 geis_error_push(geis, GEIS_STATUS_UNKNOWN_ERROR);
190 geis_error("error allocating region");
191 goto final_exit;
192 }
193
194 va_start(varargs, init_arg_name);
195 while (init_arg_name)
196 {
197 if (0 == strcmp(init_arg_name, GEIS_REGION_X11_ROOT))
198 {
199 if (region->type)
200 {
201 geis_warning("multiple region types requested, only using the first");
202 break;
203 }
204 region->type = strdup(init_arg_name);
205 geis_debug("using X11 root");
206 }
207 else if (0 == strcmp(init_arg_name, GEIS_REGION_X11_WINDOWID))
208 {
209 if (region->type)
210 {
211 geis_warning("multiple region types requested, only using the first");
212 break;
213 }
214 region->type = strdup(init_arg_name);
215 region->data.windowid = va_arg(varargs, int);
216 geis_debug("using X11 windowid 0x%08x", region->data.windowid);
217 }
218
219 init_arg_name = va_arg(varargs, GeisString);
220 }
221 va_end(varargs);
222
223 ++region->ref_count;
224 region->name = strdup(name);
225
226final_exit:
227 return region;
228}
229
230
231/*
232 * Destroys a GEIS v2.0 region.
233 */
234GeisStatus
235geis_region_delete(GeisRegion region)
236{
237 if (0 == __sync_sub_and_fetch(&region->ref_count, 1))
238 {
239 if (region->name)
240 free((char *)region->name);
241 free((char *)region->type);
242 free(region);
243 }
244 return GEIS_STATUS_SUCCESS;
245}
246
247
248/**
249 * Gets the name of a GEIS v2.0 region.
250 *
251 * @param[in] region The region.
252 *
253 * Returns the @p name value used when creating the region.
254 */
255GeisString
256geis_region_name(GeisRegion region)
257{
258 return region->name;
259}
260
261
262/*
263 * Adds a reference to a region.
264 */
265void
266geis_region_ref(GeisRegion region)
267{
268 __sync_add_and_fetch(&region->ref_count, 1);
269}
270
271
272/*
273 * Gets the type of the region.
274 */
275GeisString
276geis_region_type(GeisRegion region)
277{
278 return region->type;
279}
280
281
282/*
283 * Gets the data (if any) associated with the region type.
284 */
285void *
286geis_region_data(GeisRegion region)
287{
288 return &region->data;
289}
290
291
0292
=== added file 'libutouch-geis/geis_region.h'
--- libutouch-geis/geis_region.h 1970-01-01 00:00:00 +0000
+++ libutouch-geis/geis_region.h 2010-12-17 02:59:09 +0000
@@ -0,0 +1,103 @@
1/**
2 * @file geis_region.h
3 * @brief internal uTouch Geis region module private interface
4 *
5 * Copyright 2010 Canonical Ltd.
6 *
7 * This library is free software; you can redistribute it and/or modify it under
8 * the terms of the GNU Lesser General Public License as published by the Free
9 * Software Foundation; either version 3 of the License, or (at your option) any
10 * later version.
11 *
12 * This library is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
15 * details.
16 *
17 * You should have received a copy of the GNU Lesser General Public License
18 * along with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21#ifndef GEIS_REGION_H_
22#define GEIS_REGION_H_
23
24#include "geis/geis.h"
25
26/**
27 * @struct _GeisRegion
28 *
29 * This is a refcounted object: using the internal function geis_region_ref()
30 * will increment the reference count on the object, and geis_region_delete()
31 * will decrement the reference count and destroy the object when the reference
32 * count is set to zero.
33 *
34 * If you are handed a GeisRegion and want to keep it around, you need to ref it
35 * and then delete it when you're done, otherwise it could disappear out from
36 * under you.
37 *
38 * Because GeisRegion lifetime is affected explicitly by application action
39 * (new and delete calls are under application control), the refcount mechanism
40 * has been made threadsafe.
41 */
42
43/**
44 * Contains regions in no particular order, with no duplicate checking.
45 *
46 * @note This container is not threadsafe.
47 */
48typedef struct _GeisRegionBag *GeisRegionBag;
49
50/**
51 * Creates a new region bag.
52 */
53GeisRegionBag geis_region_bag_new();
54
55/**
56 * Destroys a region bag.
57 *
58 * @param[in] bag The region bag.
59 */
60void geis_region_bag_delete(GeisRegionBag bag);
61
62/**
63 * Gets the number of regions held in a bag.
64 */
65GeisSize geis_region_bag_count(GeisRegionBag bag);
66
67/**
68 * Gets an indicated region from a bag.
69 */
70GeisRegion geis_region_bag_region(GeisRegionBag bag, GeisSize index);
71
72/**
73 * Puts a region into a bag.
74 */
75GeisStatus geis_region_bag_insert(GeisRegionBag bag, GeisRegion region);
76
77/**
78 * Takes a region out of a bag.
79 */
80GeisStatus geis_region_bag_remove(GeisRegionBag bag, GeisRegion region);
81
82/**
83 * Adds a reference to a region.
84 *
85 * @param[in] region A region.
86 */
87void geis_region_ref(GeisRegion);
88
89/**
90 * Gets the type of the region.
91 *
92 * @param[in] region A region.
93 */
94GeisString geis_region_type(GeisRegion region);
95
96/**
97 * Gets the data (if any) associated with the region type.
98 *
99 * @param[in] region A region.
100 */
101void *geis_region_data(GeisRegion region);
102
103#endif /* GEIS_REGION_H_ */
0104
=== modified file 'libutouch-geis/libutouch-geis.ver'
--- libutouch-geis/libutouch-geis.ver 2010-12-15 01:48:35 +0000
+++ libutouch-geis/libutouch-geis.ver 2010-12-17 02:59:09 +0000
@@ -27,6 +27,9 @@
27 geis_get_configuration;27 geis_get_configuration;
28 geis_new;28 geis_new;
29 geis_next_event;29 geis_next_event;
30 geis_region_delete;
31 geis_region_name;
32 geis_region_new;
30 geis_register_event_callback;33 geis_register_event_callback;
31 geis_set_configuration;34 geis_set_configuration;
32 geis_subscription_activate;35 geis_subscription_activate;
3336
=== modified file 'testsuite/geis2/Makefile.am'
--- testsuite/geis2/Makefile.am 2010-11-29 02:16:02 +0000
+++ testsuite/geis2/Makefile.am 2010-12-17 02:59:09 +0000
@@ -18,6 +18,7 @@
18 check_error_codes.c \18 check_error_codes.c \
19 check_geis_new.c \19 check_geis_new.c \
20 check_general_types.c \20 check_general_types.c \
21 check_region.c \
21 check_subscription.c \22 check_subscription.c \
22 check_version_macro.c \23 check_version_macro.c \
23 check_geis2_api.c24 check_geis2_api.c
2425
=== modified file 'testsuite/geis2/check_geis2_api.c'
--- testsuite/geis2/check_geis2_api.c 2010-11-29 02:16:02 +0000
+++ testsuite/geis2/check_geis2_api.c 2010-12-17 02:59:09 +0000
@@ -9,6 +9,7 @@
9extern Suite *geis2_error_codes_suite_new();9extern Suite *geis2_error_codes_suite_new();
10extern Suite *geis2_geis_new_suite_new();10extern Suite *geis2_geis_new_suite_new();
11extern Suite *geis2_config_suite_new();11extern Suite *geis2_config_suite_new();
12extern Suite *geis2_region_suite_new();
12extern Suite *geis2_subscription_suite_new();13extern Suite *geis2_subscription_suite_new();
1314
14int15int
@@ -24,6 +25,7 @@
24 srunner_add_suite(sr, geis2_error_codes_suite_new());25 srunner_add_suite(sr, geis2_error_codes_suite_new());
25 srunner_add_suite(sr, geis2_geis_new_suite_new());26 srunner_add_suite(sr, geis2_geis_new_suite_new());
26 srunner_add_suite(sr, geis2_config_suite_new());27 srunner_add_suite(sr, geis2_config_suite_new());
28 srunner_add_suite(sr, geis2_region_suite_new());
27 srunner_add_suite(sr, geis2_subscription_suite_new()); 29 srunner_add_suite(sr, geis2_subscription_suite_new());
2830
29 srunner_set_log(sr, "geis2_api.log");31 srunner_set_log(sr, "geis2_api.log");
3032
=== added file 'testsuite/geis2/check_region.c'
--- testsuite/geis2/check_region.c 1970-01-01 00:00:00 +0000
+++ testsuite/geis2/check_region.c 2010-12-17 02:59:09 +0000
@@ -0,0 +1,65 @@
1/**
2 * Unit tests for GEIS v2.0 region module
3 */
4#include <check.h>
5
6#include <geis/geis.h>
7#include <string.h>
8
9
10/* fixtures */
11static Geis g_geis;
12
13/* fixture setup */
14static void
15construct_geis()
16{
17 g_geis = geis_new(GEIS_INIT_UTOUCH_MOCK_ENGINE, NULL);
18}
19
20/* fixture teardown */
21static void
22destroy_geis()
23{
24 geis_delete(g_geis);
25}
26
27
28/* compile-time test to ensure required types are defined */
29START_TEST(region_constants)
30{
31 GeisString ini;
32 ini = GEIS_REGION_X11_ROOT;
33 ini = GEIS_REGION_X11_WINDOWID;
34}
35END_TEST
36
37START_TEST(construction)
38{
39 GeisRegion sub = geis_region_new(g_geis, "name", GEIS_REGION_X11_ROOT, NULL);
40 fail_unless(sub != NULL,
41 "failed to create region");
42 fail_unless(0 == strcmp(geis_region_name(sub), "name"),
43 "unexpected region name returned");
44 geis_region_delete(sub);
45}
46END_TEST
47
48/* boilerplate */
49Suite *
50geis2_region_suite_new()
51{
52 Suite *s = suite_create("geis2_region");
53
54 TCase *create = tcase_create("region-constants");
55 tcase_add_test(create, region_constants);
56 suite_add_tcase(s, create);
57
58 TCase *usage = tcase_create("region-usage");
59 tcase_add_checked_fixture(usage, construct_geis, destroy_geis);
60 tcase_add_test(usage, construction);
61 suite_add_tcase(s, usage);
62
63 return s;
64}
65
066
=== modified file 'testsuite/libutouch-geis/Makefile.am'
--- testsuite/libutouch-geis/Makefile.am 2010-12-13 03:53:15 +0000
+++ testsuite/libutouch-geis/Makefile.am 2010-12-17 02:59:09 +0000
@@ -36,6 +36,7 @@
36 check_backend_multiplexor.c \36 check_backend_multiplexor.c \
37 check_error_reporting.c \37 check_error_reporting.c \
38 check_event_queue.c \38 check_event_queue.c \
39 check_region.c \
39 check_subscription.c \40 check_subscription.c \
40 check_geis2_internals.c41 check_geis2_internals.c
4142
4243
=== modified file 'testsuite/libutouch-geis/check_geis2_internals.c'
--- testsuite/libutouch-geis/check_geis2_internals.c 2010-12-09 16:14:15 +0000
+++ testsuite/libutouch-geis/check_geis2_internals.c 2010-12-17 02:59:09 +0000
@@ -10,6 +10,7 @@
10extern Suite *make_backend_multiplexor_suite();10extern Suite *make_backend_multiplexor_suite();
11extern Suite *make_error_reporting_suite();11extern Suite *make_error_reporting_suite();
12extern Suite *make_event_queue_suite();12extern Suite *make_event_queue_suite();
13extern Suite *make_region_suite();
13extern Suite *make_subscription_suite();14extern Suite *make_subscription_suite();
1415
1516
@@ -26,6 +27,7 @@
26 srunner_add_suite(sr, make_event_queue_suite());27 srunner_add_suite(sr, make_event_queue_suite());
27 srunner_add_suite(sr, make_backend_multiplexor_suite());28 srunner_add_suite(sr, make_backend_multiplexor_suite());
28 srunner_add_suite(sr, make_backend_event_posting_suite());29 srunner_add_suite(sr, make_backend_event_posting_suite());
30 srunner_add_suite(sr, make_region_suite());
29 srunner_add_suite(sr, make_subscription_suite());31 srunner_add_suite(sr, make_subscription_suite());
3032
31 srunner_set_log(sr, LOGFILE_PREFIX".log");33 srunner_set_log(sr, LOGFILE_PREFIX".log");
3234
=== added file 'testsuite/libutouch-geis/check_region.c'
--- testsuite/libutouch-geis/check_region.c 1970-01-01 00:00:00 +0000
+++ testsuite/libutouch-geis/check_region.c 2010-12-17 02:59:09 +0000
@@ -0,0 +1,112 @@
1/**
2 * internal unit tests for the uTouch GEIS v2.0 region module
3 *
4 * Note the public API is checked through the geis2 testsuite.
5 */
6#include <check.h>
7
8#include "geis/geis.h"
9#include "libutouch-geis/geis_region.h"
10#include <stdio.h>
11
12
13/* fixtures */
14static Geis g_geis;
15static GeisRegionBag g_region_bag;
16static uint16_t g_sample_windowid = 0x11;
17
18/* fixture setup */
19static void
20construct_bag()
21{
22 g_geis = geis_new(GEIS_INIT_UTOUCH_MOCK_ENGINE, NULL);
23 g_region_bag = geis_region_bag_new(1);
24}
25
26/* fixture teardown */
27static void
28destroy_bag()
29{
30 geis_region_bag_delete(g_region_bag);
31 geis_delete(g_geis);
32}
33
34
35START_TEST(region_access)
36{
37 GeisRegion region;
38 region = geis_region_new(g_geis, "test01",
39 GEIS_REGION_X11_WINDOWID, g_sample_windowid,
40 NULL);
41 fail_unless(0 == strcmp(geis_region_type(region), GEIS_REGION_X11_WINDOWID),
42 "bad region type");
43 fail_unless(g_sample_windowid == *(int *)geis_region_data(region),
44 "bad region data");
45}
46END_TEST
47
48/* verify bag construction/destruction */
49START_TEST(bag_construction)
50{
51 GeisRegionBag bag = geis_region_bag_new();
52 fail_unless(bag != NULL,
53 "failed to create region bag");
54 fail_unless(geis_region_bag_count(bag) == 0,
55 "unexpected size");
56 geis_region_bag_delete(bag);
57}
58END_TEST
59
60
61/* verify bag insertion */
62START_TEST(bag_insertion)
63{
64 GeisRegion region;
65 region = geis_region_new(g_geis, "test02", GEIS_REGION_X11_ROOT, NULL);
66 geis_region_bag_insert(g_region_bag, region);
67 fail_unless(geis_region_bag_count(g_region_bag) == 1,
68 "unexpected bag size after insertion");
69}
70END_TEST
71
72
73START_TEST(bag_expansion)
74{
75 int i;
76 GeisRegion region;
77 for (i = 0; i < 24; ++i)
78 {
79 char name[32];
80 sprintf(name, "%04d", i);
81 region = geis_region_new(g_geis, name, GEIS_REGION_X11_ROOT, NULL);
82 geis_region_bag_insert(g_region_bag, region);
83 int size = geis_region_bag_count(g_region_bag);
84 fail_if((size - 1) != i, "expected region bag size %d, got %d", i, size);
85 }
86}
87END_TEST
88
89
90/* boilerplate */
91Suite *
92make_region_suite()
93{
94 Suite *s = suite_create("utouch-geis2-region");
95
96 TCase *create = tcase_create("region-access");
97 tcase_add_test(create, region_access);
98 suite_add_tcase(s, create);
99
100 TCase *bag_create = tcase_create("region-bag-creation");
101 tcase_add_test(bag_create, bag_construction);
102 suite_add_tcase(s, bag_create);
103
104 TCase *bag_usage = tcase_create("region-bag-usage");
105 tcase_add_checked_fixture(bag_usage, construct_bag, destroy_bag);
106 tcase_add_test(bag_usage, bag_insertion);
107 tcase_add_test(bag_usage, bag_expansion);
108 suite_add_tcase(s, bag_usage);
109
110 return s;
111}
112

Subscribers

People subscribed via source and target branches

to all changes: