Merge lp:~oif-team/geis/geis2-add-filters into lp:geis
- geis2-add-filters
- Merge into trunk
Status: | Superseded |
---|---|
Proposed branch: | lp:~oif-team/geis/geis2-add-filters |
Merge into: | lp:geis |
Diff against target: |
2455 lines (+1784/-68) 28 files modified
.bzrignore (+2/-2) ChangeLog (+150/-0) configure.ac (+1/-0) include/geis/geis.h (+69/-2) libutouch-geis/Makefile.am (+3/-1) libutouch-geis/backend/Makefile.am (+1/-1) libutouch-geis/backend/test_fixture/Makefile.am (+22/-0) libutouch-geis/backend/test_fixture/geis_backend_test_fixture.c (+45/-3) libutouch-geis/backend/test_fixture/geis_backend_test_fixture.h (+5/-3) libutouch-geis/geis.c (+133/-22) libutouch-geis/geis_attr.c (+23/-1) libutouch-geis/geis_device.c (+16/-7) libutouch-geis/geis_filter.c (+456/-0) libutouch-geis/geis_filter.h (+123/-0) libutouch-geis/geis_filter_term.c (+206/-0) libutouch-geis/geis_filter_term.h (+139/-0) libutouch-geis/geis_private.h (+16/-1) libutouch-geis/geis_subscription.c (+88/-22) libutouch-geis/geis_subscription.h (+22/-1) libutouch-geis/libutouch-geis.ver (+9/-0) testsuite/geis2/Makefile.am (+1/-0) testsuite/geis2/check_device.c (+41/-1) testsuite/geis2/check_filter.c (+41/-0) testsuite/geis2/check_geis2_api.c (+2/-0) testsuite/geis2/check_subscription.c (+66/-1) testsuite/libutouch-geis/Makefile.am (+1/-0) testsuite/libutouch-geis/check_filter.c (+101/-0) testsuite/libutouch-geis/check_geis2_internals.c (+2/-0) |
To merge this branch: | bzr merge lp:~oif-team/geis/geis2-add-filters |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Chase Douglas (community) | Approve | ||
Henrik Rydberg (community) | Needs Fixing | ||
Review via email: mp+45129@code.launchpad.net |
This proposal has been superseded by a proposal from 2011-01-06.
Commit message
Description of the change
GEIS v2.0 filter API
This series provides the public API layer of the GEIS v2.0 filter module. The implementation layer is still to come, it depends on additional back end work.
Chase Douglas (chasedouglas) wrote : | # |
Seems reasonable to me from a high-level perspective. I'm not going to go into a line-level code review, so I'm approving.
We still need to figure out continuations in this filter framework, but we'll do so next week at the rally.
- 104. By Stephen M. Webb
-
Added missing geis_attr_
value_to_ pointer function. - 105. By Stephen M. Webb
-
Fixed failure-mode return value in geis_filter_
term_bag_ new(). - 106. By Stephen M. Webb
-
Added device cacheing.
- 107. By Stephen M. Webb
-
Moved back end test fixture into a subproject.
- 108. By Stephen M. Webb
-
Marked missing geis_event_* symbols as exported.
- 109. By Stephen M. Webb
-
Added group test for back end device creation.
- 110. By Stephen M. Webb
-
Added GEIS v2.0 filter implementation (part 4, device subscription).
- 111. By Stephen M. Webb
-
Minor tweaks.
Unmerged revisions
Preview Diff
1 | === modified file '.bzrignore' |
2 | --- .bzrignore 2010-12-09 16:14:15 +0000 |
3 | +++ .bzrignore 2011-01-06 00:59:08 +0000 |
4 | @@ -1,9 +1,9 @@ |
5 | +**.la |
6 | +**.lo |
7 | |
8 | **/Makefile |
9 | *.deps |
10 | *.libs |
11 | -*/*.la |
12 | -*/*.lo |
13 | *Makefile.in |
14 | aclocal.m4 |
15 | autom4te.cache |
16 | |
17 | === modified file 'ChangeLog' |
18 | --- ChangeLog 2010-12-29 20:35:48 +0000 |
19 | +++ ChangeLog 2011-01-06 00:59:08 +0000 |
20 | @@ -1,3 +1,153 @@ |
21 | +2011-01-05 Stephen M. Webb <stephen.webb@canonical.com> |
22 | + |
23 | + Minor tweaks. |
24 | + |
25 | + * include/geis/geis.h: fixed typos in comments |
26 | + (GEIS_DEVICE_ATTRIBUTE_NAME): new constant |
27 | + * libutouch-geis/geis_device.c: used new constant instead of hard-coded string |
28 | + * testsuite/geis2/check_subscription.c: same |
29 | + |
30 | +2011-01-05 Stephen M. Webb <stephen.webb@canonical.com> |
31 | + |
32 | + Added GEIS v2.0 filter implementation (part 4, device subscription) |
33 | + |
34 | + * libutouch-geis/backend/test_fixture/geis_backend_test_fixture.c |
35 | + (_subscription): add debug output to the test fixture |
36 | + * libutouch-geis/geis_device.c: made name an attr for filtering on |
37 | + * libutouch-geis/geis_filter.h |
38 | + (geis_filter_term_by_facility_count): new function |
39 | + (geis_filter_term_by_facility): new function |
40 | + * libutouch-geis/geis_filter.c: implemented the above new functions |
41 | + * libutouch-geis/geis_subscription.h |
42 | + (geis_subscription_filter_count): new function |
43 | + (geis_subscription_filter): new function |
44 | + * libutouch-geis/geis_subscription.c: implemented the above new functions |
45 | + * testsuite/geis2/check_subscription.c (device_filter): new test case |
46 | + |
47 | +2011-01-05 Stephen M. Webb <stephen.webb@canonical.com> |
48 | + |
49 | + Added group test for back end device creation. |
50 | + |
51 | + * libutouch-geis/backend/test_fixture/geis_backend_test_fixture.c |
52 | + (_create_test_devices): new function |
53 | + (geis_backend_new_test_fixture): used it |
54 | + * libutouch-geis/backend/test_fixture/geis_backend_test_fixture.h |
55 | + (geis_backend_new_test_fixture): added track_devices parameter |
56 | + * libutouch-geis/geis.c (_set_valist): refactored to propagate init args |
57 | + * testsuite/geis2/check_device.c: new test case |
58 | + |
59 | +2011-01-05 Stephen M. Webb <stephen.webb@canonical.com> |
60 | + |
61 | + Marked missing geis_event_* symbols as exported. |
62 | + |
63 | + * libutouch-geis/libutouch-geis.ver (geis_event_attr): exported |
64 | + (geis_event_attr_by_name): exported |
65 | + (geis_event_attr_count): exported |
66 | + (geis_event_delete): exported |
67 | + (geis_event_type): exported |
68 | + |
69 | +2011-01-05 Stephen M. Webb <stephen.webb@canonical.com> |
70 | + |
71 | + Moved back end test fixture into a subproject. |
72 | + |
73 | + * libutouch-geis/backend/test_fixture: new subproject |
74 | + * libutouch-geis/backend/test_fixture/Makefile.am: new file |
75 | + * libutouch-geis/backend/test_fixture/geis_backend_test_fixture.c: renamed |
76 | + from libutouch-geis/geis_backend_test_fixture.c |
77 | + * libutouch-geis/backend/test_fixture/geis_backend_test_fixture.h: renamed |
78 | + from libutouch-geis/geis_backend_test_fixture.h |
79 | + * configure.ac (AC_OUTPUT): added libutouch-geis/backend/test_fixture/Makefile |
80 | + * libutouch-geis/Makefile.am: linked in new subproject |
81 | + * libutouch-geis/backend/Makefile.am: added new subproject |
82 | + * libutouch-geis/geis.c: changed header qualification |
83 | + |
84 | +2011-01-05 Stephen M. Webb <stephen.webb@canonical.com> |
85 | + |
86 | + Added device cacheing. |
87 | + |
88 | + * libutouch-geis/geis_private.h (geis_get_device_attr_type): new function |
89 | + * libutouch-geis/geis.c (struct _Geis): added devices field |
90 | + (_device_event_handler): new function |
91 | + (_input_event_handler): dispatched BE device events |
92 | + (geis_new_empty): initialized devices field |
93 | + (geis_new_delete): destroyed devices field |
94 | + * libutouch-geis/geis_filter.c (_get_attr_type_for_facility): implemented for |
95 | + the device facility |
96 | + |
97 | +2011-01-05 Stephen M. Webb <stephen.webb@canonical.com> |
98 | + |
99 | + Fixed failure-mode return value from geis_filter_term_bag_new |
100 | + |
101 | + * libutouch-geis/geis_filter_term.c (geis_filter_term_bag_new): returned |
102 | + NULL on failure |
103 | + |
104 | +2011-01-05 Stephen M. Webb <stephen.webb@canonical.com> |
105 | + |
106 | + Added missing geis_attr_value_to_pointer. |
107 | + |
108 | + * libutouch-geis/geis_attr.c (geis_attr_value_to_pointer): new function |
109 | + (geis_attr_value_to_string): added case to handle GEIS_ATTR_TYPE_POINTER |
110 | + |
111 | +2011-01-03 Stephen M. Webb <stephen.webb@canonical.com> |
112 | + |
113 | + Added GEIS v2.0 filter implementation (part 3, filter terms) |
114 | + |
115 | + * libutouch-geis/geis_filter_term.c: new file |
116 | + * libutouch-geis/geis_filter_term.h: new file |
117 | + * include/geis/geis.h (GeisFilterOperation): fixed typo |
118 | + * libutouch-geis/Makefile.am: added new files |
119 | + * libutouch-geis/geis_filter.c (geis_filter_add_term): implemented function |
120 | + (_facility_is_valid): new function |
121 | + (_operation_is_valid): new function |
122 | + (_get_attr_for_facility): new function |
123 | + |
124 | +2011-01-01 Stephen M. Webb <stephen.webb@canonical.com> |
125 | + |
126 | + Added GEIS v2.0 filter implementation (part 2) |
127 | + |
128 | + * libutouch-geis/geis_filter.c: fixed refcounting on bag insertion |
129 | + * libutouch-geis/geis_subscription.c |
130 | + (geis_subscription_add_filter): implemented stubbed-out function |
131 | + (geis_subscription_remove_filter): implemented stubbed-out function |
132 | + * testsuite/geis2/check_subscription.c: new test case |
133 | + |
134 | +2010-12-20 Stephen M. Webb <stephen.webb@canonical.com> |
135 | + |
136 | + Added GEIS v2.0 filter implementation (part 1) |
137 | + |
138 | + * testsuite/libutouch-geis/check_filter.c: new test suite |
139 | + * libutouch-geis/geis_filter.h (GeisFilterBag): new data structure |
140 | + (geis_filter_bag_new): new function |
141 | + (geis_filter_bag_delete): new function |
142 | + (geis_filter_bag_count): new function |
143 | + (geis_filter_bag_filter): new function |
144 | + (geis_filter_bag_insert): new function |
145 | + (geis_filter_bag_remove): new function |
146 | + (geis_filter_ref): new function |
147 | + (geis_filter_unref): new function |
148 | + * libutouch-geis/geis_filter.c: implemented new functions |
149 | + * testsuite/libutouch-geis/Makefile.am: added new test suite |
150 | + * testsuite/libutouch-geis/check_geis2_internals.c: added new test suite |
151 | + |
152 | +2010-12-29 Stephen M. Webb <stephen.webb@canonical.com> |
153 | + |
154 | + Added GEIS v2.0 filter API |
155 | + |
156 | + * libutouch-geis/geis_filter.c: new file |
157 | + * libutouch-geis/geis_filter.h: new file |
158 | + * testsuite/geis2/check_filter.c: new test suite |
159 | + * include/geis/geis.h (GeisFilter): new type |
160 | + (GeisFilterFacility): new enumeration |
161 | + (GeisFilterOperation): new enumeration |
162 | + (gei_filter_new): new function |
163 | + (geis_filter_delete): new function |
164 | + (geis_filter_name): new function |
165 | + (geis_filter_add_term): new function |
166 | + * libutouch-geis/Makefile.am: added new files |
167 | + * libutouch-geis/libutouch-geis.ver: added new symbols |
168 | + * testsuite/geis2/Makefile.am: added new test suite |
169 | + * testsuite/geis2/check_geis2_api.c: added new test suite |
170 | + |
171 | 2010-12-29 Stephen M. Webb <stephen.webb@canonical.com> |
172 | |
173 | Added backend subdirectory to libutouch-geis. |
174 | |
175 | === modified file 'configure.ac' |
176 | --- configure.ac 2010-12-29 20:35:48 +0000 |
177 | +++ configure.ac 2011-01-06 00:59:08 +0000 |
178 | @@ -88,6 +88,7 @@ |
179 | libutouch-geis-xcb/xcb_gesture.xml |
180 | libutouch-geis/Makefile |
181 | libutouch-geis/backend/Makefile |
182 | + libutouch-geis/backend/test_fixture/Makefile |
183 | testsuite/Makefile |
184 | testsuite/libutouch-geis/Makefile |
185 | testsuite/geis1/Makefile |
186 | |
187 | === modified file 'include/geis/geis.h' |
188 | --- include/geis/geis.h 2010-12-21 01:47:05 +0000 |
189 | +++ include/geis/geis.h 2011-01-06 00:59:08 +0000 |
190 | @@ -100,6 +100,7 @@ |
191 | #define GEIS_GESTURE_ATTRIBUTE_TOUCH_4_X "touch 4 x" |
192 | #define GEIS_GESTURE_ATTRIBUTE_TOUCH_4_Y "touch 4 y" |
193 | |
194 | +#define GEIS_DEVICE_ATTRIBUTE_NAME "device name" |
195 | |
196 | #define GEIS_FALSE 0 |
197 | #define GEIS_TRUE 1 |
198 | @@ -856,7 +857,7 @@ |
199 | GEIS_API void geis_device_unref(GeisDevice device); |
200 | |
201 | /** |
202 | - * Gets the name of teh input device. |
203 | + * Gets the name of the input device. |
204 | * |
205 | * @param[in] device The device. |
206 | */ |
207 | @@ -947,11 +948,77 @@ |
208 | /* @} */ |
209 | |
210 | /** |
211 | + * @defgroup geis2_filter Gesture Filter (GEIS v2.0) |
212 | + * @{ |
213 | + */ |
214 | + |
215 | +typedef struct _GeisFilter *GeisFilter; |
216 | + |
217 | +typedef enum _GeisFilterFacility |
218 | +{ |
219 | + GEIS_FILTER_DEVICE = 1000, |
220 | + GEIS_FILTER_GESTURE_TYPE = 2000, |
221 | + GEIS_FILTER_REGION = 3000 |
222 | +} GeisFilterFacility; |
223 | + |
224 | +typedef enum _GeisFilterOperation |
225 | +{ |
226 | + GEIS_FILTER_OP_EQ, |
227 | + GEIS_FILTER_OP_NE, |
228 | + GEIS_FILTER_OP_GT, |
229 | + GEIS_FILTER_OP_GE, |
230 | + GEIS_FILTER_OP_LT, |
231 | + GEIS_FILTER_OP_LE, |
232 | +} GeisFilterOperation; |
233 | + |
234 | + |
235 | +/** |
236 | + * Creates a new filter. |
237 | + * |
238 | + * @param[in] geis The GEIS API instance. |
239 | + * @param[in] name A name. |
240 | + * |
241 | + * @returns a GeisFilter object or NULL on failure. |
242 | + */ |
243 | +GEIS_API GeisFilter geis_filter_new(Geis geis, GeisString name); |
244 | + |
245 | +/** |
246 | + * Destroys a GEIS v2.0 filter object. |
247 | + * |
248 | + * @param[in] filter The filter. |
249 | + */ |
250 | +GEIS_API GeisStatus geis_filter_delete(GeisFilter filter); |
251 | + |
252 | +/** |
253 | + * Gets the name given to the filter when it was created. |
254 | + * |
255 | + * @param[in] filter The filter. |
256 | + */ |
257 | +GEIS_API GeisString geis_filter_name(GeisFilter filter); |
258 | + |
259 | +/** |
260 | + * Adds a term to a filter. |
261 | + * |
262 | + * @param[in] filter The filter. |
263 | + * @param[in] facility The term facility. |
264 | + * @param[in] ... A list of zero or more term descriptions. |
265 | + * |
266 | + * A term description is generally a (attr-name, filter-op, value) triple in |
267 | + * which the meaning of the filter-op and value depend on the type of the attr. |
268 | + * |
269 | + * The term description list must be terminated by a NULL. |
270 | + */ |
271 | +GEIS_API GeisStatus geis_filter_add_term(GeisFilter filter, |
272 | + GeisFilterFacility facility, |
273 | + ...); |
274 | + |
275 | +/* @} */ |
276 | + |
277 | +/** |
278 | * @defgroup geis2_subscription Gesture Subscription (GEIS v2.0) |
279 | * @{ |
280 | */ |
281 | |
282 | -typedef struct _GeisFilter *GeisFilter; |
283 | typedef struct _GeisSubscription *GeisSubscription; |
284 | |
285 | /** |
286 | |
287 | === modified file 'libutouch-geis/Makefile.am' |
288 | --- libutouch-geis/Makefile.am 2010-12-29 20:35:48 +0000 |
289 | +++ libutouch-geis/Makefile.am 2011-01-06 00:59:08 +0000 |
290 | @@ -31,11 +31,12 @@ |
291 | geis_backend.h geis_backend.c \ |
292 | geis_backend_protected.h \ |
293 | geis_backend_multiplexor.h geis_backend_multiplexor.c \ |
294 | - geis_backend_test_fixture.h geis_backend_test_fixture.c \ |
295 | geis_device.h geis_device.c \ |
296 | geis_error.h geis_error.c \ |
297 | geis_event.h geis_event.c \ |
298 | geis_event_queue.h geis_event_queue.c \ |
299 | + geis_filter.h geis_filter.c \ |
300 | + geis_filter_term.h geis_filter_term.c \ |
301 | geis_logging.h geis_logging.c \ |
302 | geis_region.h geis_region.c \ |
303 | geis_subscription.h geis_subscription.c \ |
304 | @@ -57,6 +58,7 @@ |
305 | -lm |
306 | |
307 | libutouch_geis_la_LIBADD = \ |
308 | + ${builddir}/backend/test_fixture/libutouch-geis-test-fixture.la \ |
309 | $(top_builddir)/libutouch-geis-xcb/libutouch-geis.la |
310 | |
311 | EXTRA_DIST = $(version_script) |
312 | |
313 | === modified file 'libutouch-geis/backend/Makefile.am' |
314 | --- libutouch-geis/backend/Makefile.am 2010-12-29 20:35:48 +0000 |
315 | +++ libutouch-geis/backend/Makefile.am 2011-01-06 00:59:08 +0000 |
316 | @@ -19,5 +19,5 @@ |
317 | # 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
318 | # |
319 | |
320 | -SUBDIRS = |
321 | +SUBDIRS = test_fixture |
322 | |
323 | |
324 | === added directory 'libutouch-geis/backend/test_fixture' |
325 | === added file 'libutouch-geis/backend/test_fixture/Makefile.am' |
326 | --- libutouch-geis/backend/test_fixture/Makefile.am 1970-01-01 00:00:00 +0000 |
327 | +++ libutouch-geis/backend/test_fixture/Makefile.am 2011-01-06 00:59:08 +0000 |
328 | @@ -0,0 +1,22 @@ |
329 | +# |
330 | +# @file libutouch-geis/backend/test_fixture/Makefile.am |
331 | +# |
332 | +# Build recipes for the test fixture back end. |
333 | +# |
334 | + |
335 | +noinst_LTLIBRARIES = libutouch-geis-test-fixture.la |
336 | + |
337 | +libutouch_geis_test_fixture_la_SOURCES = \ |
338 | + geis_backend_test_fixture.h geis_backend_test_fixture.c |
339 | + |
340 | +libutouch_geis_test_fixture_la_CPPFLAGS = \ |
341 | + -Wall -Wextra \ |
342 | + -fvisibility=hidden \ |
343 | + -I$(top_srcdir) \ |
344 | + -I$(top_srcdir)/include \ |
345 | + -I$(top_srcdir)/libutouch-geis |
346 | + |
347 | +libutouch_geis_test_fixture_la_LDFLAGS = |
348 | + |
349 | +libutouch_geis_test_fixture_la_LIBADD = |
350 | + |
351 | |
352 | === renamed file 'libutouch-geis/geis_backend_test_fixture.c' => 'libutouch-geis/backend/test_fixture/geis_backend_test_fixture.c' |
353 | --- libutouch-geis/geis_backend_test_fixture.c 2010-12-15 01:48:35 +0000 |
354 | +++ libutouch-geis/backend/test_fixture/geis_backend_test_fixture.c 2011-01-06 00:59:08 +0000 |
355 | @@ -21,13 +21,21 @@ |
356 | #include "geis_backend.h" |
357 | #include "geis_backend_protected.h" |
358 | |
359 | +#include "geis_attr.h" |
360 | +#include "geis_device.h" |
361 | +#include "geis_event.h" |
362 | +#include "geis_filter.h" |
363 | +#include "geis_filter_term.h" |
364 | #include "geis_logging.h" |
365 | +#include "geis_private.h" |
366 | +#include "geis_subscription.h" |
367 | #include <stdlib.h> |
368 | |
369 | |
370 | typedef struct _GeisBackendTestFixture |
371 | { |
372 | struct _GeisBackend tf_base; |
373 | + Geis tf_geis; |
374 | } *GeisBackendTestFixture; |
375 | |
376 | |
377 | @@ -39,11 +47,29 @@ |
378 | |
379 | |
380 | static GeisStatus |
381 | -_subscribe(GeisBackend be __attribute__((unused)), |
382 | - GeisSubscription sub __attribute__((unused))) |
383 | +_subscribe(GeisBackend be, |
384 | + GeisSubscription sub) |
385 | { |
386 | geis_debug("begins"); |
387 | GeisStatus status = GEIS_STATUS_SUCCESS; |
388 | + GeisSize i, j; |
389 | + for (i = 0; i < geis_subscription_filter_count(sub); ++i) |
390 | + { |
391 | + GeisFilter filter = geis_subscription_filter(sub, i); |
392 | + geis_debug("processing filter '%s'", geis_filter_name(filter)); |
393 | + for (j = 0; |
394 | + j < geis_filter_term_by_facility_count(filter, GEIS_FILTER_DEVICE); |
395 | + ++j) |
396 | + { |
397 | + GeisFilterTerm term = geis_filter_term_by_facility(filter, |
398 | + GEIS_FILTER_DEVICE, |
399 | + j); |
400 | + geis_debug(" DEVICE \"%s\" (%d) \"%s\"", |
401 | + geis_attr_name(geis_filter_term_attr(term)), |
402 | + geis_filter_term_operation(term), |
403 | + geis_attr_value_to_string(geis_filter_term_attr(term))); |
404 | + } |
405 | + } |
406 | geis_debug("ends"); |
407 | return status; |
408 | } |
409 | @@ -66,8 +92,18 @@ |
410 | }; |
411 | |
412 | |
413 | +static void _create_test_devices(GeisBackendTestFixture tf) |
414 | +{ |
415 | + GeisDevice device = geis_device_new("abs-test-device", 0); |
416 | + GeisEvent event = geis_event_new(GEIS_EVENT_DEVICE_AVAILABLE); |
417 | + GeisAttr attr = geis_attr_new("geis-device", GEIS_ATTR_TYPE_POINTER, device); |
418 | + geis_event_add_attr(event, attr); |
419 | + geis_post_event(tf->tf_geis, event); |
420 | +} |
421 | + |
422 | + |
423 | GeisBackend |
424 | -geis_backend_new_test_fixture(Geis geis __attribute__((unused))) |
425 | +geis_backend_new_test_fixture(Geis geis, GeisBoolean track_devices) |
426 | { |
427 | GeisBackendTestFixture tf = calloc(1, sizeof(struct _GeisBackendTestFixture)); |
428 | if (!tf) |
429 | @@ -77,6 +113,12 @@ |
430 | } |
431 | |
432 | geis_backend_init_base(&tf->tf_base, &tf_vtbl, "GEIS2 test fixture"); |
433 | + tf->tf_geis = geis; |
434 | + |
435 | + if (track_devices) |
436 | + { |
437 | + _create_test_devices(tf); |
438 | + } |
439 | |
440 | geis_debug("%s back end created", geis_backend_name(&tf->tf_base)); |
441 | |
442 | |
443 | === renamed file 'libutouch-geis/geis_backend_test_fixture.h' => 'libutouch-geis/backend/test_fixture/geis_backend_test_fixture.h' |
444 | --- libutouch-geis/geis_backend_test_fixture.h 2010-12-02 19:09:57 +0000 |
445 | +++ libutouch-geis/backend/test_fixture/geis_backend_test_fixture.h 2011-01-06 00:59:08 +0000 |
446 | @@ -2,7 +2,7 @@ |
447 | * @file geis_backend_test_fixture.h |
448 | * @brief internal GEIS test fixture back end class |
449 | * |
450 | - * Copyright 2010 Canonical Ltd. |
451 | + * Copyright 2010, 2011 Canonical Ltd. |
452 | * |
453 | * This library is free software; you can redistribute it and/or modify it under |
454 | * the terms of the GNU Lesser General Public License as published by the Free |
455 | @@ -26,10 +26,12 @@ |
456 | /** |
457 | * Constructs a new GEIS Test Fuixture back end. |
458 | * |
459 | - * @param[in] geis The API instance the back end will run in. |
460 | + * @param[in] geis The API instance the back end will run in. |
461 | + * @param[in] track_devices Indicates devices should be tracked. |
462 | * |
463 | * The Test Fixture back end is used in unit tests. |
464 | */ |
465 | -GeisBackend geis_backend_new_test_fixture(Geis geis); |
466 | +GeisBackend geis_backend_new_test_fixture(Geis geis, |
467 | + GeisBoolean track_devices); |
468 | |
469 | #endif /* GEIS_BACKEND_TEST_FIXTURE_H_ */ |
470 | |
471 | === modified file 'libutouch-geis/geis.c' |
472 | --- libutouch-geis/geis.c 2010-12-15 01:48:35 +0000 |
473 | +++ libutouch-geis/geis.c 2011-01-06 00:59:08 +0000 |
474 | @@ -2,7 +2,7 @@ |
475 | * @file libutouch-geis/geis.c |
476 | * @brief implementation of the uTouch GEIS v2.0 API instance |
477 | * |
478 | - * Copyright 2010 Canonical Ltd. |
479 | + * Copyright 2010, 2011 Canonical Ltd. |
480 | * |
481 | * This library is free software; you can redistribute it and/or modify it under |
482 | * the terms of the GNU Lesser General Public License as published by the Free |
483 | @@ -22,11 +22,14 @@ |
484 | #include "geis_private.h" |
485 | |
486 | #include <errno.h> |
487 | +#include "geis_attr.h" |
488 | #include "geis_backend.h" |
489 | -#include "geis_backend_test_fixture.h" |
490 | +#include "test_fixture/geis_backend_test_fixture.h" |
491 | #include "geis_backend_multiplexor.h" |
492 | #include "geis_error.h" |
493 | +#include "geis_event.h" |
494 | #include "geis_event_queue.h" |
495 | +#include "geis_device.h" |
496 | #include "geis_logging.h" |
497 | #include <stdarg.h> |
498 | #include <string.h> |
499 | @@ -44,6 +47,7 @@ |
500 | GeisEventQueue output_event_queue; |
501 | GeisEventCallback output_event_callback; |
502 | void *output_event_callback_context; |
503 | + GeisDeviceBag devices; |
504 | }; |
505 | |
506 | |
507 | @@ -59,6 +63,39 @@ |
508 | geis_event_queue_enqueue(geis->output_event_queue, event); |
509 | } |
510 | |
511 | + |
512 | +/* |
513 | + * Handles device events coming in from the back end. |
514 | + */ |
515 | +static GeisBoolean |
516 | +_device_event_handler(Geis geis, GeisEvent event) |
517 | +{ |
518 | + GeisBoolean handled = GEIS_FALSE; |
519 | + GeisAttr attr = geis_event_attr_by_name(event, "geis-device"); |
520 | + if (!attr) |
521 | + { |
522 | + geis_warning("invalid device event received from back end."); |
523 | + handled = GEIS_TRUE; |
524 | + goto final_exit; |
525 | + } |
526 | + |
527 | + GeisDevice device = geis_attr_value_to_pointer(attr); |
528 | + |
529 | + GeisEventType event_type = geis_event_type(event); |
530 | + if (event_type == GEIS_EVENT_DEVICE_AVAILABLE) |
531 | + { |
532 | + geis_device_bag_insert(geis->devices, device); |
533 | + } |
534 | + else if (event_type == GEIS_EVENT_DEVICE_UNAVAILABLE) |
535 | + { |
536 | + geis_device_bag_remove(geis->devices, device); |
537 | + } |
538 | + |
539 | +final_exit: |
540 | + return handled; |
541 | +} |
542 | + |
543 | + |
544 | /* |
545 | * Filters and transforms raw gesture events into cooked gesture events. |
546 | * |
547 | @@ -84,9 +121,24 @@ |
548 | event = geis_event_queue_dequeue(geis->input_event_queue); |
549 | if (event) |
550 | { |
551 | - geis->output_event_callback(geis, |
552 | - event, |
553 | - geis->output_event_callback_context); |
554 | + GeisBoolean handled = 0; |
555 | + switch (geis_event_type(event)) |
556 | + { |
557 | + case GEIS_EVENT_DEVICE_AVAILABLE: |
558 | + case GEIS_EVENT_DEVICE_UNAVAILABLE: |
559 | + handled = _device_event_handler(geis, event); |
560 | + break; |
561 | + |
562 | + default: |
563 | + break; |
564 | + } |
565 | + |
566 | + if (!handled) |
567 | + { |
568 | + geis->output_event_callback(geis, |
569 | + event, |
570 | + geis->output_event_callback_context); |
571 | + } |
572 | } |
573 | } |
574 | } |
575 | @@ -152,8 +204,18 @@ |
576 | } |
577 | geis->output_event_callback = _default_output_event_callback; |
578 | |
579 | + geis->devices = geis_device_bag_new(); |
580 | + if (!geis->output_event_queue) |
581 | + { |
582 | + geis_error_push(NULL, GEIS_STATUS_UNKNOWN_ERROR); |
583 | + geis_error("creation of geis device bag failed"); |
584 | + goto unwind_output_queue; |
585 | + } |
586 | + |
587 | goto final_exit; |
588 | |
589 | +unwind_output_queue: |
590 | + geis_event_queue_delete(geis->output_event_queue); |
591 | unwind_input_signal_pipe: |
592 | close(geis->input_event_signal_pipe[0]); |
593 | close(geis->input_event_signal_pipe[1]); |
594 | @@ -172,39 +234,55 @@ |
595 | } |
596 | |
597 | |
598 | +typedef enum _BackendType |
599 | +{ |
600 | + BACK_END_TYPE_NONE, |
601 | + BACK_END_TYPE_MOCK_ENGINE |
602 | +} BackendType; |
603 | + |
604 | /** |
605 | * Sets optional parts of a Geis API instance from a variable argument list. |
606 | */ |
607 | -static void |
608 | -geis_set_valist(Geis geis, GeisString init_arg_name, va_list varargs) |
609 | +static GeisBoolean |
610 | +_set_valist(Geis geis, GeisString init_arg_name, va_list varargs) |
611 | { |
612 | + GeisBoolean status = GEIS_TRUE; |
613 | + BackendType back_end_type = BACK_END_TYPE_NONE; |
614 | + GeisBoolean track_devices = GEIS_FALSE; |
615 | + |
616 | while (init_arg_name) |
617 | { |
618 | if (0 == strcmp(init_arg_name, GEIS_INIT_SERVICE_PROVIDER)) |
619 | { |
620 | geis_debug("initializing GEIS server"); |
621 | } |
622 | + else if (0 == strcmp(init_arg_name, GEIS_INIT_TRACK_DEVICES)) |
623 | + { |
624 | + track_devices = GEIS_TRUE; |
625 | + } |
626 | else if (0 == strcmp(init_arg_name, GEIS_INIT_UTOUCH_MOCK_ENGINE)) |
627 | { |
628 | - if (NULL != geis->backend) |
629 | - { |
630 | - geis_error("multiple back ends requested, only using %s",\ |
631 | - geis_backend_name(geis->backend)); |
632 | - } |
633 | - else |
634 | - { |
635 | - geis_debug("initializing GEIS test fixture"); |
636 | - geis->backend = geis_backend_new_test_fixture(geis); |
637 | - } |
638 | + if (back_end_type != BACK_END_TYPE_NONE) |
639 | + { |
640 | + geis_error("multiple back ends requested, only using last request"); |
641 | + } |
642 | + back_end_type = BACK_END_TYPE_MOCK_ENGINE; |
643 | } |
644 | |
645 | init_arg_name = va_arg(varargs, GeisString); |
646 | } |
647 | |
648 | - if (NULL == geis->backend) |
649 | - { |
650 | - geis_debug("initializing default GEIS back end"); |
651 | - } |
652 | + if (back_end_type ==BACK_END_TYPE_MOCK_ENGINE) |
653 | + { |
654 | + geis->backend = geis_backend_new_test_fixture(geis, track_devices); |
655 | + } |
656 | + else |
657 | + { |
658 | + geis_error_push(NULL, GEIS_STATUS_UNKNOWN_ERROR); |
659 | + geis_error("back end required but not specified"); |
660 | + status = GEIS_FALSE; |
661 | + } |
662 | + return status; |
663 | } |
664 | |
665 | |
666 | @@ -214,15 +292,23 @@ |
667 | Geis |
668 | geis_new(GeisString init_arg_name, ...) |
669 | { |
670 | + GeisBoolean success = GEIS_FALSE; |
671 | Geis geis = geis_new_empty(); |
672 | if (geis) |
673 | { |
674 | va_list varargs; |
675 | va_start(varargs, init_arg_name); |
676 | - geis_set_valist(geis, init_arg_name, varargs); |
677 | + success = _set_valist(geis, init_arg_name, varargs); |
678 | va_end(varargs); |
679 | } |
680 | |
681 | + if (!success) |
682 | + { |
683 | + geis_error_push(NULL, GEIS_STATUS_UNKNOWN_ERROR); |
684 | + geis_error("can not initialize GEIS API"); |
685 | + geis_delete(geis); |
686 | + geis = NULL; |
687 | + } |
688 | return geis; |
689 | } |
690 | |
691 | @@ -238,6 +324,11 @@ |
692 | return GEIS_STATUS_BAD_ARGUMENT; |
693 | } |
694 | |
695 | + geis_device_bag_delete(geis->devices); |
696 | + geis_event_queue_delete(geis->output_event_queue); |
697 | + close(geis->input_event_signal_pipe[0]); |
698 | + close(geis->input_event_signal_pipe[1]); |
699 | + geis_event_queue_delete(geis->input_event_queue); |
700 | if (geis->backend) |
701 | geis_backend_delete(geis->backend); |
702 | geis_backend_multiplexor_delete(geis->backend_multiplexor); |
703 | @@ -420,3 +511,23 @@ |
704 | } |
705 | |
706 | |
707 | +GeisAttrType |
708 | +geis_get_device_attr_type(Geis geis, GeisString attr_name) |
709 | +{ |
710 | + GeisSize i = 0; |
711 | + for (; i < geis_device_bag_count(geis->devices); ++i) |
712 | + { |
713 | + GeisDevice device = geis_device_bag_device(geis->devices, i); |
714 | + GeisSize j = 0; |
715 | + for (; j < geis_device_attr_count(device); ++j) |
716 | + { |
717 | + GeisAttr attr = geis_device_attr(device, j); |
718 | + if (0 == strcmp(geis_attr_name(attr), attr_name)) |
719 | + { |
720 | + return geis_attr_type(attr); |
721 | + } |
722 | + } |
723 | + } |
724 | + return GEIS_ATTR_TYPE_UNKNOWN; |
725 | +} |
726 | + |
727 | |
728 | === modified file 'libutouch-geis/geis_attr.c' |
729 | --- libutouch-geis/geis_attr.c 2010-12-14 15:24:58 +0000 |
730 | +++ libutouch-geis/geis_attr.c 2011-01-06 00:59:08 +0000 |
731 | @@ -2,7 +2,7 @@ |
732 | * @file geis_attr.c |
733 | * @brief internal uTouch GeisAttr facilities |
734 | * |
735 | - * Copyright 2010 Canonical Ltd. |
736 | + * Copyright 2010, 2011 Canonical Ltd. |
737 | * |
738 | * This library is free software; you can redistribute it and/or modify it under |
739 | * the terms of the GNU Lesser General Public License as published by the Free |
740 | @@ -304,6 +304,23 @@ |
741 | } |
742 | |
743 | |
744 | +GeisPointer |
745 | +geis_attr_value_to_pointer(GeisAttr attr) |
746 | +{ |
747 | + GeisPointer p_value = NULL; |
748 | + switch (attr->attr_type) |
749 | + { |
750 | + case GEIS_ATTR_TYPE_POINTER: |
751 | + p_value = attr->v_value; |
752 | + break; |
753 | + |
754 | + default: |
755 | + break; |
756 | + } |
757 | + return p_value; |
758 | +} |
759 | + |
760 | + |
761 | GeisString |
762 | geis_attr_value_to_string(GeisAttr attr) |
763 | { |
764 | @@ -326,6 +343,11 @@ |
765 | s_value = buf; |
766 | break; |
767 | |
768 | + case GEIS_ATTR_TYPE_POINTER: |
769 | + sprintf(buf, "%p", attr->v_value); |
770 | + s_value = buf; |
771 | + break; |
772 | + |
773 | case GEIS_ATTR_TYPE_STRING: |
774 | s_value = attr->s_value; |
775 | break; |
776 | |
777 | === modified file 'libutouch-geis/geis_device.c' |
778 | --- libutouch-geis/geis_device.c 2010-12-21 13:59:31 +0000 |
779 | +++ libutouch-geis/geis_device.c 2011-01-06 00:59:08 +0000 |
780 | @@ -2,7 +2,7 @@ |
781 | * @file libutouch-geis/geis_region.c |
782 | * @brief implementation of the uTouch GEIS v2.0 API Input Device module |
783 | * |
784 | - * Copyright 2010 Canonical Ltd. |
785 | + * Copyright 2010, 2010 Canonical Ltd. |
786 | * |
787 | * This library is free software; you can redistribute it and/or modify it under |
788 | * the terms of the GNU Lesser General Public License as published by the Free |
789 | @@ -30,7 +30,6 @@ |
790 | struct _GeisDevice |
791 | { |
792 | GeisSize ref_count; |
793 | - GeisString name; |
794 | GeisInteger id; |
795 | GeisAttrBag attr_bag; |
796 | }; |
797 | @@ -177,12 +176,15 @@ |
798 | goto unwind_device; |
799 | } |
800 | |
801 | - device->name = strdup(name); |
802 | - if (!device->name) |
803 | + GeisAttr name_attr = geis_attr_new(GEIS_DEVICE_ATTRIBUTE_NAME, |
804 | + GEIS_ATTR_TYPE_STRING, |
805 | + (void *)name); |
806 | + if (!name_attr) |
807 | { |
808 | geis_debug("error allocating device name"); |
809 | goto unwind_attrs; |
810 | } |
811 | + geis_attr_bag_insert(device->attr_bag, name_attr); |
812 | |
813 | device->id = id; |
814 | geis_device_ref(device); |
815 | @@ -204,7 +206,7 @@ |
816 | static void |
817 | _device_delete(GeisDevice device) |
818 | { |
819 | - free((char *)device->name); |
820 | + geis_attr_bag_delete(device->attr_bag); |
821 | free(device); |
822 | } |
823 | |
824 | @@ -233,12 +235,19 @@ |
825 | |
826 | |
827 | /* |
828 | - * Gets the name of teh input device. |
829 | + * Gets the name of the input device. |
830 | */ |
831 | GeisString |
832 | geis_device_name(GeisDevice device) |
833 | { |
834 | - return device->name; |
835 | + GeisString device_name = NULL; |
836 | + GeisAttr name_attr = geis_attr_bag_find(device->attr_bag, |
837 | + GEIS_DEVICE_ATTRIBUTE_NAME); |
838 | + if (name_attr) |
839 | + { |
840 | + device_name = geis_attr_value_to_string(name_attr); |
841 | + } |
842 | + return device_name; |
843 | } |
844 | |
845 | |
846 | |
847 | === added file 'libutouch-geis/geis_filter.c' |
848 | --- libutouch-geis/geis_filter.c 1970-01-01 00:00:00 +0000 |
849 | +++ libutouch-geis/geis_filter.c 2011-01-06 00:59:08 +0000 |
850 | @@ -0,0 +1,456 @@ |
851 | +/** |
852 | + * @file libutouch-geis/geis_filter.c |
853 | + * @brief implementation of the uTouch GEIS v2.0 API filter module |
854 | + * |
855 | + * Copyright 2010, 2011 Canonical Ltd. |
856 | + * |
857 | + * This library is free software; you can redistribute it and/or modify it under |
858 | + * the terms of the GNU Lesser General Public License as published by the Free |
859 | + * Software Foundation; either version 3 of the License, or (at your option) any |
860 | + * later version. |
861 | + * |
862 | + * This library is distributed in the hope that it will be useful, but WITHOUT |
863 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
864 | + * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more |
865 | + * details. |
866 | + * |
867 | + * You should have received a copy of the GNU Lesser General Public License |
868 | + * along with this program; if not, write to the Free Software Foundation, Inc., |
869 | + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
870 | + */ |
871 | +#include "geis_config.h" |
872 | +#include "geis_filter.h" |
873 | + |
874 | +#include "geis_attr.h" |
875 | +#include "geis_error.h" |
876 | +#include "geis_filter_term.h" |
877 | +#include "geis_logging.h" |
878 | +#include "geis_private.h" |
879 | +#include <stdarg.h> |
880 | +#include <stdlib.h> |
881 | +#include <string.h> |
882 | + |
883 | + |
884 | +struct _GeisFilter |
885 | +{ |
886 | + GeisSize ref_count; |
887 | + GeisString name; |
888 | + Geis geis; |
889 | + GeisFilterTermBag terms; |
890 | +}; |
891 | + |
892 | +struct _GeisFilterBag |
893 | +{ |
894 | + GeisFilter *filter_store; |
895 | + GeisSize filter_store_size; |
896 | + GeisSize filter_count; |
897 | +}; |
898 | + |
899 | +static const int filter_bag_growth_constant = 2; |
900 | + |
901 | + |
902 | +/* |
903 | + * Creates a new filter bag, |
904 | + */ |
905 | +GeisFilterBag |
906 | +geis_filter_bag_new() |
907 | +{ |
908 | + GeisFilterBag bag = calloc(1, sizeof(struct _GeisFilterBag)); |
909 | + if (!bag) |
910 | + { |
911 | + geis_error("failed to allocate filter bag"); |
912 | + goto final_exit; |
913 | + } |
914 | + |
915 | + bag->filter_store_size = 3; |
916 | + bag->filter_count = 0; |
917 | + bag->filter_store = calloc(bag->filter_store_size, sizeof(GeisFilter)); |
918 | + if (!bag->filter_store) |
919 | + { |
920 | + geis_error("failed to allocate filter bag store"); |
921 | + goto unwind_bag; |
922 | + } |
923 | + goto final_exit; |
924 | + |
925 | +unwind_bag: |
926 | + free(bag); |
927 | +final_exit: |
928 | + return bag; |
929 | +} |
930 | + |
931 | + |
932 | +/* |
933 | + * Destroys a filter bag. |
934 | + */ |
935 | +void |
936 | +geis_filter_bag_delete(GeisFilterBag bag) |
937 | +{ |
938 | + GeisSize i; |
939 | + for (i = bag->filter_count; i > 0; --i) |
940 | + { |
941 | + geis_filter_delete(bag->filter_store[i-1]); |
942 | + } |
943 | + free(bag); |
944 | +} |
945 | + |
946 | + |
947 | +/* |
948 | + * Gets the number of filters in the bag. |
949 | + */ |
950 | +GeisSize |
951 | +geis_filter_bag_count(GeisFilterBag bag) |
952 | +{ |
953 | + return bag->filter_count; |
954 | +} |
955 | + |
956 | + |
957 | +/* |
958 | + * Gets an indicated filter from a bag. |
959 | + */ |
960 | +GeisFilter |
961 | +geis_filter_bag_filter(GeisFilterBag bag, GeisSize index) |
962 | +{ |
963 | + GeisFilter filter = NULL; |
964 | + if (index < bag->filter_count) |
965 | + { |
966 | + filter = bag->filter_store[index]; |
967 | + } |
968 | + return filter; |
969 | +} |
970 | + |
971 | + |
972 | +/* |
973 | + * Inserts a filter in the bag. |
974 | + */ |
975 | +GeisStatus |
976 | +geis_filter_bag_insert(GeisFilterBag bag, GeisFilter filter) |
977 | +{ |
978 | + GeisStatus status = GEIS_STATUS_UNKNOWN_ERROR; |
979 | + geis_filter_ref(filter); |
980 | + if (bag->filter_count >= bag->filter_store_size) |
981 | + { |
982 | + GeisSize new_store_size = bag->filter_store_size * filter_bag_growth_constant; |
983 | + GeisFilter *new_store = realloc(bag->filter_store, |
984 | + new_store_size * sizeof(struct _GeisFilter)); |
985 | + if (!new_store) |
986 | + { |
987 | + geis_error("failed to reallocate filter bag"); |
988 | + goto error_exit; |
989 | + } |
990 | + bag->filter_store = new_store; |
991 | + bag->filter_store_size = new_store_size; |
992 | + } |
993 | + bag->filter_store[bag->filter_count++] = filter; |
994 | + status = GEIS_STATUS_SUCCESS; |
995 | + goto final_exit; |
996 | + |
997 | +error_exit: |
998 | + geis_filter_unref(filter); |
999 | +final_exit: |
1000 | + return status; |
1001 | +} |
1002 | + |
1003 | + |
1004 | +/* |
1005 | + * Remoes a filter from the bag. |
1006 | + */ |
1007 | +GeisStatus |
1008 | +geis_filter_bag_remove(GeisFilterBag bag, GeisFilter filter) |
1009 | +{ |
1010 | + GeisSize i; |
1011 | + GeisStatus status = GEIS_STATUS_SUCCESS; |
1012 | + for (i = 0; i < bag->filter_count; ++i) |
1013 | + { |
1014 | + if (bag->filter_store[i] == filter) |
1015 | + { |
1016 | + GeisSize j; |
1017 | + geis_filter_delete(bag->filter_store[i]); |
1018 | + --bag->filter_count; |
1019 | + for (j = i; j < bag->filter_count; ++j) |
1020 | + { |
1021 | + bag->filter_store[j] = bag->filter_store[j+1]; |
1022 | + } |
1023 | + break; |
1024 | + } |
1025 | + } |
1026 | + return status; |
1027 | +} |
1028 | + |
1029 | + |
1030 | +/* |
1031 | + * Creates a GEIS v2.0 filter object. |
1032 | + */ |
1033 | +GeisFilter |
1034 | +geis_filter_new(Geis geis, GeisString name) |
1035 | +{ |
1036 | + GeisFilter filter = calloc(1, sizeof(struct _GeisFilter)); |
1037 | + if (!filter) |
1038 | + { |
1039 | + geis_error_push(geis, GEIS_STATUS_UNKNOWN_ERROR); |
1040 | + geis_error("error allocating filter"); |
1041 | + goto final_exit; |
1042 | + } |
1043 | + |
1044 | + if (name) |
1045 | + { |
1046 | + filter->name = strdup(name); |
1047 | + } |
1048 | + else |
1049 | + { |
1050 | + filter->name = strdup(""); |
1051 | + } |
1052 | + if (!filter->name) |
1053 | + { |
1054 | + geis_error_push(geis, GEIS_STATUS_UNKNOWN_ERROR); |
1055 | + geis_error("error allocating filter name"); |
1056 | + goto unwind_filter; |
1057 | + } |
1058 | + |
1059 | + filter->terms = geis_filter_term_bag_new(); |
1060 | + if (!filter->terms) |
1061 | + { |
1062 | + geis_error_push(geis, GEIS_STATUS_UNKNOWN_ERROR); |
1063 | + geis_error("error allocating filter terms"); |
1064 | + goto unwind_name; |
1065 | + } |
1066 | + |
1067 | + filter->geis = geis; |
1068 | + geis_filter_ref(filter); |
1069 | + goto final_exit; |
1070 | + |
1071 | +unwind_name: |
1072 | + free((char *)filter->name); |
1073 | +unwind_filter: |
1074 | + free(filter); |
1075 | + filter = NULL; |
1076 | +final_exit: |
1077 | + return filter; |
1078 | +} |
1079 | + |
1080 | + |
1081 | +/* |
1082 | + * Destroys a GEIS v2.0 filter object. |
1083 | + */ |
1084 | +GeisStatus |
1085 | +geis_filter_delete(GeisFilter filter) |
1086 | +{ |
1087 | + GeisStatus status = GEIS_STATUS_SUCCESS; |
1088 | + if (geis_filter_unref(filter) == 0) |
1089 | + { |
1090 | + geis_filter_term_bag_delete(filter->terms); |
1091 | + free((char *)filter->name); |
1092 | + free(filter); |
1093 | + } |
1094 | + return status; |
1095 | +} |
1096 | + |
1097 | + |
1098 | +/* |
1099 | + * Gets the name given to the filter when it was created. |
1100 | + */ |
1101 | +GeisString |
1102 | +geis_filter_name(GeisFilter filter) |
1103 | +{ |
1104 | + return filter->name; |
1105 | +} |
1106 | + |
1107 | + |
1108 | +/* |
1109 | + * Indicates if the facility is valid. |
1110 | + */ |
1111 | +static GeisBoolean |
1112 | +_facility_is_valid(GeisFilterFacility facility) |
1113 | +{ |
1114 | + return facility == GEIS_FILTER_DEVICE |
1115 | + || facility == GEIS_FILTER_GESTURE_TYPE |
1116 | + || facility == GEIS_FILTER_REGION; |
1117 | +} |
1118 | + |
1119 | + |
1120 | +/* |
1121 | + * Indicates if the operation is valid. |
1122 | + */ |
1123 | +static GeisBoolean |
1124 | +_operation_is_valid(GeisFilterOperation op) |
1125 | +{ |
1126 | + return op == GEIS_FILTER_OP_EQ |
1127 | + || op == GEIS_FILTER_OP_NE |
1128 | + || op == GEIS_FILTER_OP_GT |
1129 | + || op == GEIS_FILTER_OP_GE |
1130 | + || op == GEIS_FILTER_OP_LT |
1131 | + || op == GEIS_FILTER_OP_LE; |
1132 | +} |
1133 | + |
1134 | + |
1135 | +/* |
1136 | + * Gets the attr description by name. |
1137 | + * @todo implement this function |
1138 | + */ |
1139 | +static GeisAttrType |
1140 | +_get_attr_type_for_facility(Geis geis, |
1141 | + GeisFilterFacility facility, |
1142 | + GeisString attr_name) |
1143 | +{ |
1144 | + GeisAttrType type = GEIS_ATTR_TYPE_UNKNOWN; |
1145 | + switch (facility) |
1146 | + { |
1147 | + case GEIS_FILTER_DEVICE: |
1148 | + type = geis_get_device_attr_type(geis, attr_name); |
1149 | + break; |
1150 | + default: |
1151 | + break; |
1152 | + } |
1153 | + return type; |
1154 | +} |
1155 | + |
1156 | + |
1157 | +/* |
1158 | + * Adds a term to a filter. |
1159 | + */ |
1160 | +GeisStatus |
1161 | +geis_filter_add_term(GeisFilter filter, |
1162 | + GeisFilterFacility facility, |
1163 | + ...) |
1164 | +{ |
1165 | + GeisStatus status = GEIS_STATUS_UNKNOWN_ERROR; |
1166 | + va_list varargs; |
1167 | + GeisString attr_name; |
1168 | + |
1169 | + if (!_facility_is_valid(facility)) |
1170 | + { |
1171 | + status = GEIS_STATUS_BAD_ARGUMENT; |
1172 | + geis_error_push(filter->geis, status); |
1173 | + geis_error("invalid filter facility"); |
1174 | + goto final_exit; |
1175 | + } |
1176 | + |
1177 | + va_start(varargs, facility); |
1178 | + for (attr_name = va_arg(varargs, GeisString); |
1179 | + attr_name; |
1180 | + attr_name = va_arg(varargs, GeisString)) |
1181 | + { |
1182 | + GeisAttrType attr_type = _get_attr_type_for_facility(filter->geis, |
1183 | + facility, |
1184 | + attr_name); |
1185 | + if (attr_type == GEIS_ATTR_TYPE_UNKNOWN) |
1186 | + { |
1187 | + status = GEIS_STATUS_BAD_ARGUMENT; |
1188 | + geis_error_push(filter->geis, status); |
1189 | + geis_error("invalid attr name for facility"); |
1190 | + goto final_exit; |
1191 | + } |
1192 | + |
1193 | + GeisFilterOperation op = va_arg(varargs, GeisFilterOperation); |
1194 | + if (!_operation_is_valid(op)) |
1195 | + { |
1196 | + status = GEIS_STATUS_BAD_ARGUMENT; |
1197 | + geis_error_push(filter->geis, status); |
1198 | + geis_error("invalid filter operation"); |
1199 | + goto final_exit; |
1200 | + } |
1201 | + |
1202 | + switch (attr_type) |
1203 | + { |
1204 | + case GEIS_ATTR_TYPE_BOOLEAN: |
1205 | + { |
1206 | + GeisBoolean value = va_arg(varargs, GeisBoolean); |
1207 | + GeisAttr attr = geis_attr_new(attr_name, GEIS_ATTR_TYPE_BOOLEAN, &value); |
1208 | + GeisFilterTerm term = geis_filter_term_new(facility, op, attr); |
1209 | + geis_filter_term_bag_insert(filter->terms, term); |
1210 | + } |
1211 | + break; |
1212 | + |
1213 | + case GEIS_ATTR_TYPE_FLOAT: |
1214 | + { |
1215 | + GeisFloat value = va_arg(varargs, double); |
1216 | + GeisAttr attr = geis_attr_new(attr_name, GEIS_ATTR_TYPE_FLOAT, &value); |
1217 | + GeisFilterTerm term = geis_filter_term_new(facility, op, attr); |
1218 | + geis_filter_term_bag_insert(filter->terms, term); |
1219 | + } |
1220 | + break; |
1221 | + |
1222 | + case GEIS_ATTR_TYPE_INTEGER: |
1223 | + { |
1224 | + GeisInteger value = va_arg(varargs, GeisInteger); |
1225 | + GeisAttr attr = geis_attr_new(attr_name, GEIS_ATTR_TYPE_INTEGER, &value); |
1226 | + GeisFilterTerm term = geis_filter_term_new(facility, op, attr); |
1227 | + geis_filter_term_bag_insert(filter->terms, term); |
1228 | + } |
1229 | + break; |
1230 | + |
1231 | + case GEIS_ATTR_TYPE_POINTER: |
1232 | + { |
1233 | + GeisPointer value = va_arg(varargs, GeisPointer); |
1234 | + GeisAttr attr = geis_attr_new(attr_name, GEIS_ATTR_TYPE_POINTER, value); |
1235 | + GeisFilterTerm term = geis_filter_term_new(facility, op, attr); |
1236 | + geis_filter_term_bag_insert(filter->terms, term); |
1237 | + } |
1238 | + break; |
1239 | + |
1240 | + case GEIS_ATTR_TYPE_STRING: |
1241 | + { |
1242 | + GeisString value = va_arg(varargs, GeisString); |
1243 | + GeisAttr attr = geis_attr_new(attr_name, GEIS_ATTR_TYPE_STRING, (void *)value); |
1244 | + GeisFilterTerm term = geis_filter_term_new(facility, op, attr); |
1245 | + geis_filter_term_bag_insert(filter->terms, term); |
1246 | + } |
1247 | + break; |
1248 | + |
1249 | + default: |
1250 | + status = GEIS_STATUS_BAD_ARGUMENT; |
1251 | + geis_error_push(filter->geis, status); |
1252 | + geis_error("invalid filter argument"); |
1253 | + goto final_exit; |
1254 | + break; |
1255 | + } |
1256 | + } |
1257 | + va_end(varargs); |
1258 | + status = GEIS_STATUS_SUCCESS; |
1259 | + |
1260 | +final_exit: |
1261 | + return status; |
1262 | +} |
1263 | + |
1264 | + |
1265 | +/* |
1266 | + * Atomically increments filter refcount. |
1267 | + */ |
1268 | +void |
1269 | +geis_filter_ref(GeisFilter filter) |
1270 | +{ |
1271 | + __sync_add_and_fetch(&filter->ref_count, 1); |
1272 | +} |
1273 | + |
1274 | + |
1275 | +/* |
1276 | + * Atomically decrements and returns filter refcount. |
1277 | + */ |
1278 | +GeisSize |
1279 | +geis_filter_unref(GeisFilter filter) |
1280 | +{ |
1281 | + return __sync_sub_and_fetch(&filter->ref_count, 1); |
1282 | +} |
1283 | + |
1284 | +/* |
1285 | + * Gets the number of terms in the filter grouped by facility. |
1286 | + */ |
1287 | +GeisSize |
1288 | +geis_filter_term_by_facility_count(GeisFilter filter, |
1289 | + GeisFilterFacility facility) |
1290 | +{ |
1291 | + return geis_filter_term_bag_count(filter->terms, facility); |
1292 | +} |
1293 | + |
1294 | + |
1295 | +/* |
1296 | + * Gets the indicated term in the filter by facility. |
1297 | + */ |
1298 | +GeisFilterTerm |
1299 | +geis_filter_term_by_facility(GeisFilter filter, |
1300 | + GeisFilterFacility facility, |
1301 | + GeisSize index) |
1302 | +{ |
1303 | + return geis_filter_term_bag_filter(filter->terms, facility, index); |
1304 | +} |
1305 | + |
1306 | + |
1307 | |
1308 | === added file 'libutouch-geis/geis_filter.h' |
1309 | --- libutouch-geis/geis_filter.h 1970-01-01 00:00:00 +0000 |
1310 | +++ libutouch-geis/geis_filter.h 2011-01-06 00:59:08 +0000 |
1311 | @@ -0,0 +1,123 @@ |
1312 | +/** |
1313 | + * @file geis_filter.h |
1314 | + * @brief internal uTouch Geis filter module private interface |
1315 | + * |
1316 | + * Copyright 2010 Canonical Ltd. |
1317 | + * |
1318 | + * This library is free software; you can redistribute it and/or modify it under |
1319 | + * the terms of the GNU Lesser General Public License as published by the Free |
1320 | + * Software Foundation; either version 3 of the License, or (at your option) any |
1321 | + * later version. |
1322 | + * |
1323 | + * This library is distributed in the hope that it will be useful, but WITHOUT |
1324 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
1325 | + * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more |
1326 | + * details. |
1327 | + * |
1328 | + * You should have received a copy of the GNU Lesser General Public License |
1329 | + * along with this program; if not, write to the Free Software Foundation, Inc., |
1330 | + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
1331 | + */ |
1332 | +#ifndef GEIS_FILTER_H_ |
1333 | +#define GEIS_FILTER_H_ |
1334 | + |
1335 | +#include "geis/geis.h" |
1336 | +#include "geis_filter_term.h" |
1337 | + |
1338 | +/** |
1339 | + * @defgroup utouch_geis_filter_container A Filter Container |
1340 | + * @{ |
1341 | + */ |
1342 | + |
1343 | +/** |
1344 | + * An unsorted container for holding filters. |
1345 | + */ |
1346 | +typedef struct _GeisFilterBag *GeisFilterBag; |
1347 | + |
1348 | +/** |
1349 | + * Creates a new filter bag, |
1350 | + */ |
1351 | +GeisFilterBag geis_filter_bag_new(); |
1352 | + |
1353 | +/** |
1354 | + * Destroys a filter bag. |
1355 | + * |
1356 | + * @param[in] bag The filter bag, |
1357 | + */ |
1358 | +void geis_filter_bag_delete(GeisFilterBag bag); |
1359 | + |
1360 | +/** |
1361 | + * Gets the number of filters in the bag. |
1362 | + * |
1363 | + * @param[in] bag The filter bag, |
1364 | + */ |
1365 | +GeisSize geis_filter_bag_count(GeisFilterBag bag); |
1366 | + |
1367 | +/**t |
1368 | + * Gets an indicated filter from a bag. |
1369 | + * |
1370 | + * @param[in] bag The filter bag. |
1371 | + * @param[in] index The index. |
1372 | + */ |
1373 | +GeisFilter geis_filter_bag_filter(GeisFilterBag bag, GeisSize index); |
1374 | + |
1375 | +/** |
1376 | + * Inserts a filter in the bag. |
1377 | + * |
1378 | + * @param[in] bag The filter bag. |
1379 | + * @param[in] filter The filter to insert. |
1380 | + */ |
1381 | +GeisStatus geis_filter_bag_insert(GeisFilterBag bag, GeisFilter filter); |
1382 | + |
1383 | +/** |
1384 | + * Remoes a filter from the bag. |
1385 | + * |
1386 | + * @param[in] bag The filter bag. |
1387 | + * @param[in] filter The filter to remove. |
1388 | + */ |
1389 | +GeisStatus geis_filter_bag_remove(GeisFilterBag bag, GeisFilter filter); |
1390 | + |
1391 | +/** @} */ |
1392 | + |
1393 | +/** |
1394 | + * @defgroup utouch_geis_filter_internals Filter Internals |
1395 | + * @{ |
1396 | + */ |
1397 | + |
1398 | +/** |
1399 | + * Increments the reference count on a filter. |
1400 | + * |
1401 | + * @param[in] filter The filter. |
1402 | + */ |
1403 | +void geis_filter_ref(GeisFilter filter); |
1404 | + |
1405 | +/** |
1406 | + * Decrements and returns the referemce count on a filter. |
1407 | + * |
1408 | + * @param[in] filter The filter. |
1409 | + */ |
1410 | +GeisSize geis_filter_unref(GeisFilter filter); |
1411 | + |
1412 | +/** |
1413 | + * Gets the number of terms in the filter grouped by facility. |
1414 | + * |
1415 | + * @param[in] filter The filter. |
1416 | + * @param[in] facility The facility. |
1417 | + */ |
1418 | +GeisSize geis_filter_term_by_facility_count(GeisFilter filter, |
1419 | + GeisFilterFacility facility); |
1420 | + |
1421 | +/** |
1422 | + * Gets the indicated term in the filter by facility. |
1423 | + * |
1424 | + * @param[in] filter The filter. |
1425 | + * @param[in] facility The facility. |
1426 | + * @param[in] index Indicates which term. |
1427 | + */ |
1428 | +GeisFilterTerm geis_filter_term_by_facility(GeisFilter filter, |
1429 | + GeisFilterFacility facility, |
1430 | + GeisSize index); |
1431 | + |
1432 | +/** @} */ |
1433 | + |
1434 | +#endif /* GEIS_FILTER_H_ */ |
1435 | |
1436 | === added file 'libutouch-geis/geis_filter_term.c' |
1437 | --- libutouch-geis/geis_filter_term.c 1970-01-01 00:00:00 +0000 |
1438 | +++ libutouch-geis/geis_filter_term.c 2011-01-06 00:59:08 +0000 |
1439 | @@ -0,0 +1,206 @@ |
1440 | +/** |
1441 | + * @file libutouch-geis/geis_filter_term.c |
1442 | + * @brief implementation of the uTouch GEIS v2.0 API filter term module |
1443 | + * |
1444 | + * Copyright 2011 Canonical Ltd. |
1445 | + * |
1446 | + * This library is free software; you can redistribute it and/or modify it under |
1447 | + * the terms of the GNU Lesser General Public License as published by the Free |
1448 | + * Software Foundation; either version 3 of the License, or (at your option) any |
1449 | + * later version. |
1450 | + * |
1451 | + * This library is distributed in the hope that it will be useful, but WITHOUT |
1452 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
1453 | + * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more |
1454 | + * details. |
1455 | + * |
1456 | + * You should have received a copy of the GNU Lesser General Public License |
1457 | + * along with this program; if not, write to the Free Software Foundation, Inc., |
1458 | + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
1459 | + */ |
1460 | +#include "geis_config.h" |
1461 | +#include "geis_filter_term.h" |
1462 | + |
1463 | +#include "geis_attr.h" |
1464 | +#include "geis_error.h" |
1465 | +#include "geis_logging.h" |
1466 | +#include <stdlib.h> |
1467 | + |
1468 | + |
1469 | +/* |
1470 | + * One of the terms of a filter. |
1471 | + */ |
1472 | +struct _GeisFilterTerm |
1473 | +{ |
1474 | + GeisFilterFacility facility; |
1475 | + GeisFilterOperation op; |
1476 | + GeisAttr attr; |
1477 | +}; |
1478 | + |
1479 | + |
1480 | +/* |
1481 | + * All of the terms of a filter. |
1482 | + */ |
1483 | +struct _GeisFilterTermBag |
1484 | +{ |
1485 | + GeisFilterTerm *store; |
1486 | + GeisSize store_size; |
1487 | + GeisSize count; |
1488 | +}; |
1489 | + |
1490 | +static const GeisSize term_bag_growth_constant = 2; |
1491 | + |
1492 | + |
1493 | +GeisFilterTermBag |
1494 | +geis_filter_term_bag_new() |
1495 | +{ |
1496 | + GeisFilterTermBag bag = calloc(1, sizeof(struct _GeisFilterTermBag)); |
1497 | + if (!bag) |
1498 | + { |
1499 | + geis_error("failed to allocate filter termbag"); |
1500 | + goto final_exit; |
1501 | + } |
1502 | + |
1503 | + bag->store_size = 3; |
1504 | + bag->count = 0; |
1505 | + bag->store = calloc(bag->store_size, sizeof(GeisFilterTerm)); |
1506 | + if (!bag->store) |
1507 | + { |
1508 | + geis_error("failed to allocate filter bag store"); |
1509 | + goto unwind_bag; |
1510 | + } |
1511 | + goto final_exit; |
1512 | + |
1513 | +unwind_bag: |
1514 | + free(bag); |
1515 | + bag = NULL; |
1516 | +final_exit: |
1517 | + return bag; |
1518 | +} |
1519 | + |
1520 | + |
1521 | +void |
1522 | +geis_filter_term_bag_delete(GeisFilterTermBag bag) |
1523 | +{ |
1524 | + free(bag); |
1525 | +} |
1526 | + |
1527 | + |
1528 | +GeisSize |
1529 | +geis_filter_term_bag_count(GeisFilterTermBag bag, GeisFilterFacility facility) |
1530 | +{ |
1531 | + GeisSize count = 0; |
1532 | + GeisSize i = 0; |
1533 | + while (i < bag->count) |
1534 | + { |
1535 | + if (bag->store[i]->facility == facility) |
1536 | + ++count; |
1537 | + ++i; |
1538 | + } |
1539 | + return count; |
1540 | +} |
1541 | + |
1542 | + |
1543 | +GeisFilterTerm |
1544 | +geis_filter_term_bag_filter(GeisFilterTermBag bag, |
1545 | + GeisFilterFacility facility, |
1546 | + GeisSize index) |
1547 | +{ |
1548 | + GeisFilterTerm term = NULL; |
1549 | + GeisSize count = 0; |
1550 | + GeisSize i = 0; |
1551 | + while (i < bag->count) |
1552 | + { |
1553 | + if (bag->store[i]->facility == facility) |
1554 | + { |
1555 | + if (count == index) |
1556 | + { |
1557 | + term = bag->store[i]; |
1558 | + break; |
1559 | + } |
1560 | + ++count; |
1561 | + } |
1562 | + ++i; |
1563 | + } |
1564 | + return term; |
1565 | +} |
1566 | + |
1567 | + |
1568 | +GeisStatus |
1569 | +geis_filter_term_bag_insert(GeisFilterTermBag bag, |
1570 | + GeisFilterTerm term) |
1571 | +{ |
1572 | + GeisStatus status = GEIS_STATUS_UNKNOWN_ERROR; |
1573 | + if (bag->count >= bag->store_size) |
1574 | + { |
1575 | + GeisSize new_store_size = bag->store_size * term_bag_growth_constant; |
1576 | + GeisFilterTerm *new_store = realloc(bag->store, |
1577 | + new_store_size * sizeof(struct _GeisFilterTerm)); |
1578 | + if (!new_store) |
1579 | + { |
1580 | + geis_error("failed to reallocate filter term bag"); |
1581 | + goto error_exit; |
1582 | + } |
1583 | + bag->store = new_store; |
1584 | + bag->store_size = new_store_size; |
1585 | + } |
1586 | + bag->store[bag->count++] = term; |
1587 | + status = GEIS_STATUS_SUCCESS; |
1588 | + goto final_exit; |
1589 | + |
1590 | +error_exit: |
1591 | +final_exit: |
1592 | + return status; |
1593 | +} |
1594 | + |
1595 | + |
1596 | +GeisFilterTerm |
1597 | +geis_filter_term_new(GeisFilterFacility facility, |
1598 | + GeisFilterOperation operation, |
1599 | + GeisAttr attr) |
1600 | +{ |
1601 | + GeisFilterTerm term = calloc(1, sizeof(struct _GeisFilterTerm)); |
1602 | + if (!term) |
1603 | + { |
1604 | + geis_error("failed to allocate filter termbag"); |
1605 | + goto final_exit; |
1606 | + } |
1607 | + term->facility = facility; |
1608 | + term->op = operation; |
1609 | + term->attr = attr; |
1610 | + |
1611 | +final_exit: |
1612 | + return term; |
1613 | +} |
1614 | + |
1615 | + |
1616 | +void |
1617 | +geis_filter_term_delete(GeisFilterTerm term) |
1618 | +{ |
1619 | + geis_attr_delete(term->attr); |
1620 | + free(term); |
1621 | +} |
1622 | + |
1623 | + |
1624 | +GeisFilterFacility |
1625 | +geis_filter_term_facility(GeisFilterTerm term) |
1626 | +{ |
1627 | + return term->facility; |
1628 | +} |
1629 | + |
1630 | + |
1631 | +GeisFilterOperation |
1632 | +geis_filter_term_operation(GeisFilterTerm term) |
1633 | +{ |
1634 | + return term->op; |
1635 | +} |
1636 | + |
1637 | + |
1638 | +GeisAttr |
1639 | +geis_filter_term_attr(GeisFilterTerm term) |
1640 | +{ |
1641 | + return term->attr; |
1642 | +} |
1643 | + |
1644 | + |
1645 | + |
1646 | |
1647 | === added file 'libutouch-geis/geis_filter_term.h' |
1648 | --- libutouch-geis/geis_filter_term.h 1970-01-01 00:00:00 +0000 |
1649 | +++ libutouch-geis/geis_filter_term.h 2011-01-06 00:59:08 +0000 |
1650 | @@ -0,0 +1,139 @@ |
1651 | +/** |
1652 | + * @file geis_filter_term.h |
1653 | + * @brief internal uTouch Geis filter term module private interface |
1654 | + * |
1655 | + * Copyright 2011 Canonical Ltd. |
1656 | + * |
1657 | + * This library is free software; you can redistribute it and/or modify it under |
1658 | + * the terms of the GNU Lesser General Public License as published by the Free |
1659 | + * Software Foundation; either version 3 of the License, or (at your option) any |
1660 | + * later version. |
1661 | + * |
1662 | + * This library is distributed in the hope that it will be useful, but WITHOUT |
1663 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
1664 | + * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more |
1665 | + * details. |
1666 | + * |
1667 | + * You should have received a copy of the GNU Lesser General Public License |
1668 | + * along with this program; if not, write to the Free Software Foundation, Inc., |
1669 | + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
1670 | + */ |
1671 | +#ifndef GEIS_FILTER_TERM_H_ |
1672 | +#define GEIS_FILTER_TERM_H_ |
1673 | + |
1674 | +#include "geis/geis.h" |
1675 | + |
1676 | +/** |
1677 | + * @defgroup utouch_geis_filter_term Filter Terms. |
1678 | + * @{ |
1679 | + */ |
1680 | + |
1681 | +/** |
1682 | + * One of the terms of a filter. |
1683 | + * |
1684 | + * A term belong to a facility (eg. device, gesture type, region) and is used to |
1685 | + * compare (using an operation) a named attribute with a given value. |
1686 | + */ |
1687 | +typedef struct _GeisFilterTerm *GeisFilterTerm; |
1688 | + |
1689 | +/** |
1690 | + * Creates a new filter term. |
1691 | + * |
1692 | + * @param[in] facility The term's facility. |
1693 | + * @param[in] operation The term's operation. |
1694 | + * @param[in] attr The term's attr name, type, and value |
1695 | + */ |
1696 | +GeisFilterTerm geis_filter_term_new(GeisFilterFacility facility, |
1697 | + GeisFilterOperation operation, |
1698 | + GeisAttr attr); |
1699 | + |
1700 | +/** |
1701 | + * Destroys a filter term. |
1702 | + * |
1703 | + * @param[in] term The filter term. |
1704 | + */ |
1705 | +void geis_filter_term_delete(GeisFilterTerm term); |
1706 | + |
1707 | +/** |
1708 | + * Gets a filter term's facility. |
1709 | + * |
1710 | + * @param[in] term The filter term. |
1711 | + */ |
1712 | +GeisFilterFacility geis_filter_term_facility(GeisFilterTerm term); |
1713 | + |
1714 | +/** |
1715 | + * Gets a filter term's operation. |
1716 | + * |
1717 | + * @param[in] term The filter term. |
1718 | + */ |
1719 | +GeisFilterOperation geis_filter_term_operation(GeisFilterTerm term); |
1720 | + |
1721 | +/** |
1722 | + * Gets a filter term's attributes. |
1723 | + * |
1724 | + * @param[in] term The filter term. |
1725 | + */ |
1726 | +GeisAttr geis_filter_term_attr(GeisFilterTerm term); |
1727 | + |
1728 | +/** @} */ |
1729 | + |
1730 | +/** |
1731 | + * @defgroup utouch_geis_filter_term_container A Filter Term Container |
1732 | + * @{ |
1733 | + */ |
1734 | + |
1735 | +/** |
1736 | + * An unsorted container for holding filter terms. |
1737 | + * |
1738 | + * This implementation is physically unsorted, but terms are logically grouped |
1739 | + * by facility. |
1740 | + * |
1741 | + * This is a purely internal structure, as is the filter term. The bag "owns" |
1742 | + * the term. |
1743 | + */ |
1744 | +typedef struct _GeisFilterTermBag *GeisFilterTermBag; |
1745 | + |
1746 | +/** |
1747 | + * Creates a new filter term bag, |
1748 | + */ |
1749 | +GeisFilterTermBag geis_filter_term_bag_new(); |
1750 | + |
1751 | +/** |
1752 | + * Destroys a filter term bag. |
1753 | + * |
1754 | + * @param[in] bag The filter term bag. |
1755 | + */ |
1756 | +void geis_filter_term_bag_delete(GeisFilterTermBag bag); |
1757 | + |
1758 | +/** |
1759 | + * Gets the number of filter terms in the bag for a given facility. |
1760 | + * |
1761 | + * @param[in] bag The filter term bag. |
1762 | + * @param[in] facility The facility. |
1763 | + */ |
1764 | +GeisSize geis_filter_term_bag_count(GeisFilterTermBag bag, |
1765 | + GeisFilterFacility facility); |
1766 | + |
1767 | +/** |
1768 | + * Gets an indicated filter term from a bag. |
1769 | + * |
1770 | + * @param[in] bag The filter bag. |
1771 | + * @param[in] facility The facility. |
1772 | + * @param[in] index The index. |
1773 | + */ |
1774 | +GeisFilterTerm geis_filter_term_bag_filter(GeisFilterTermBag bag, |
1775 | + GeisFilterFacility facility, |
1776 | + GeisSize index); |
1777 | + |
1778 | +/** |
1779 | + * Inserts a filter in the bag. |
1780 | + * |
1781 | + * @param[in] bag The filter bag. |
1782 | + * @param[in] term The filter to insert. |
1783 | + */ |
1784 | +GeisStatus geis_filter_term_bag_insert(GeisFilterTermBag bag, |
1785 | + GeisFilterTerm term); |
1786 | + |
1787 | +/** @} */ |
1788 | + |
1789 | +#endif /* GEIS_FILTER_TERM_H_ */ |
1790 | |
1791 | === modified file 'libutouch-geis/geis_private.h' |
1792 | --- libutouch-geis/geis_private.h 2010-12-15 01:48:35 +0000 |
1793 | +++ libutouch-geis/geis_private.h 2011-01-06 00:59:08 +0000 |
1794 | @@ -5,7 +5,7 @@ |
1795 | * This file is the internal interface to the GEIS API object. It provides the |
1796 | * implementation hooks for back ends to pass information through the API. |
1797 | * |
1798 | - * Copyright 2010 Canonical Ltd. |
1799 | + * Copyright 2010, 2011 Canonical Ltd. |
1800 | * |
1801 | * This library is free software; you can redistribute it and/or modify it under |
1802 | * the terms of the GNU Lesser General Public License as published by the Free |
1803 | @@ -90,4 +90,19 @@ |
1804 | */ |
1805 | GeisStatus geis_deactivate_subscription(Geis geis, GeisSubscription sub); |
1806 | |
1807 | +/** |
1808 | + * Gets the type of a named device attr. |
1809 | + * |
1810 | + * @param[in] geis The API instance. |
1811 | + * @param[in] attr_name The name of the device attr. |
1812 | + * |
1813 | + * Gets the type of a device attr by name, assuming the attr is known. |
1814 | + * |
1815 | + * There is a basic assumption that all device attrs of the same name are of the |
1816 | + * same type. |
1817 | + * |
1818 | + * @returns the type of the attr, GEIS_ATTR_TYPE_UNKNOWN if the attr is unknown. |
1819 | + */ |
1820 | +GeisAttrType geis_get_device_attr_type(Geis geis, GeisString attr_name); |
1821 | + |
1822 | #endif /* GEIS_PRIVATE_H_ */ |
1823 | |
1824 | === modified file 'libutouch-geis/geis_subscription.c' |
1825 | --- libutouch-geis/geis_subscription.c 2010-12-15 01:48:35 +0000 |
1826 | +++ libutouch-geis/geis_subscription.c 2011-01-06 00:59:08 +0000 |
1827 | @@ -2,7 +2,7 @@ |
1828 | * @file libutouch-geis/geis_subscription.c |
1829 | * @brief implementation of the uTouch GEIS v2.0 API subscription module |
1830 | * |
1831 | - * Copyright 2010 Canonical Ltd. |
1832 | + * Copyright 2010, 2011 Canonical Ltd. |
1833 | * |
1834 | * This library is free software; you can redistribute it and/or modify it under |
1835 | * the terms of the GNU Lesser General Public License as published by the Free |
1836 | @@ -22,8 +22,9 @@ |
1837 | #include "geis_subscription.h" |
1838 | |
1839 | #include "geis/geis.h" |
1840 | +#include "geis_filter.h" |
1841 | +#include "geis_logging.h" |
1842 | #include "geis_private.h" |
1843 | -#include "geis_logging.h" |
1844 | #include <math.h> |
1845 | #include <stdlib.h> |
1846 | #include <string.h> |
1847 | @@ -35,6 +36,7 @@ |
1848 | GeisInteger sub_id; |
1849 | GeisString sub_name; |
1850 | GeisSubscriptionFlags sub_flags; |
1851 | + GeisFilterBag sub_filters; |
1852 | }; |
1853 | |
1854 | struct _GeisSubBag |
1855 | @@ -126,12 +128,12 @@ |
1856 | } |
1857 | |
1858 | GeisSize new_store_size = ceilf(bag->sub_store_size * sub_bag_growth_constant); |
1859 | - geis_debug(". new_store_size=%ld", new_store_size); |
1860 | GeisSubscription *new_store = realloc(bag->sub_store, |
1861 | new_store_size * sizeof(struct _GeisSubBag)); |
1862 | if (!new_store) |
1863 | { |
1864 | geis_error("failed to reallocate sub bag"); |
1865 | + index = -1; |
1866 | goto final_exit; |
1867 | } |
1868 | index = bag->sub_store_size; |
1869 | @@ -208,26 +210,54 @@ |
1870 | if (!sub) |
1871 | { |
1872 | geis_error_push(geis, GEIS_STATUS_UNKNOWN_ERROR); |
1873 | - geis_error("calloc failed"); |
1874 | - goto error_exit; |
1875 | + geis_error("error allocating subscription"); |
1876 | + goto final_exit; |
1877 | + } |
1878 | + |
1879 | + if (sub_name) |
1880 | + { |
1881 | + sub->sub_name = strdup(sub_name); |
1882 | } |
1883 | else |
1884 | { |
1885 | - if (sub_name) |
1886 | - { |
1887 | - sub->sub_name = strdup(sub_name); |
1888 | - } |
1889 | - else |
1890 | - { |
1891 | - sub->sub_name = strdup(""); |
1892 | - } |
1893 | - sub->sub_geis = geis; |
1894 | - sub->sub_id = geis_subscription_bag_insert(geis_subscription_bag(geis), sub); |
1895 | - sub->sub_flags = sub_flags; |
1896 | - geis_debug("created subscription \"%s\" id %d", sub->sub_name, sub->sub_id); |
1897 | - } |
1898 | - |
1899 | -error_exit: |
1900 | + sub->sub_name = strdup(""); |
1901 | + } |
1902 | + if (!sub->sub_name) |
1903 | + { |
1904 | + geis_error_push(geis, GEIS_STATUS_UNKNOWN_ERROR); |
1905 | + geis_error("error allocating subscription name"); |
1906 | + goto unwind_sub; |
1907 | + } |
1908 | + |
1909 | + sub->sub_filters = geis_filter_bag_new(); |
1910 | + if (!sub->sub_filters) |
1911 | + { |
1912 | + geis_error_push(geis, GEIS_STATUS_UNKNOWN_ERROR); |
1913 | + geis_error("error allocating subscription filters"); |
1914 | + goto unwind_name; |
1915 | + } |
1916 | + |
1917 | + sub->sub_id = geis_subscription_bag_insert(geis_subscription_bag(geis), sub); |
1918 | + if (sub->sub_id < 0) |
1919 | + { |
1920 | + geis_error_push(geis, GEIS_STATUS_UNKNOWN_ERROR); |
1921 | + geis_error("error storing subscription"); |
1922 | + goto unwind_filters; |
1923 | + } |
1924 | + |
1925 | + sub->sub_geis = geis; |
1926 | + sub->sub_flags = sub_flags; |
1927 | + geis_debug("created subscription \"%s\" id %d", sub->sub_name, sub->sub_id); |
1928 | + goto final_exit; |
1929 | + |
1930 | +unwind_filters: |
1931 | + geis_filter_bag_delete(sub->sub_filters); |
1932 | +unwind_name: |
1933 | + free((char *)sub->sub_name); |
1934 | +unwind_sub: |
1935 | + free(sub); |
1936 | + sub = NULL; |
1937 | +final_exit: |
1938 | return sub; |
1939 | } |
1940 | |
1941 | @@ -289,7 +319,7 @@ |
1942 | */ |
1943 | GeisStatus |
1944 | geis_subscription_add_filter(GeisSubscription sub, |
1945 | - GeisFilter filter __attribute__((unused))) |
1946 | + GeisFilter filter) |
1947 | { |
1948 | GeisStatus status = GEIS_STATUS_UNKNOWN_ERROR; |
1949 | if (!sub) |
1950 | @@ -298,6 +328,14 @@ |
1951 | goto error_exit; |
1952 | } |
1953 | |
1954 | + status = geis_filter_bag_insert(sub->sub_filters, filter); |
1955 | + if (status != GEIS_STATUS_SUCCESS) |
1956 | + { |
1957 | + geis_error_push(sub->sub_geis, GEIS_STATUS_UNKNOWN_ERROR); |
1958 | + geis_error("error adding filter to subscription"); |
1959 | + goto error_exit; |
1960 | + } |
1961 | + |
1962 | error_exit: |
1963 | return status; |
1964 | } |
1965 | @@ -310,7 +348,7 @@ |
1966 | */ |
1967 | GeisStatus |
1968 | geis_subscription_remove_filter(GeisSubscription sub, |
1969 | - GeisFilter filter __attribute__((unused))) |
1970 | + GeisFilter filter) |
1971 | { |
1972 | GeisStatus status = GEIS_STATUS_UNKNOWN_ERROR; |
1973 | if (!sub) |
1974 | @@ -319,8 +357,36 @@ |
1975 | goto error_exit; |
1976 | } |
1977 | |
1978 | + status = geis_filter_bag_remove(sub->sub_filters, filter); |
1979 | + if (status != GEIS_STATUS_SUCCESS) |
1980 | + { |
1981 | + geis_error_push(sub->sub_geis, GEIS_STATUS_UNKNOWN_ERROR); |
1982 | + geis_error("error removing filter from subscription"); |
1983 | + goto error_exit; |
1984 | + } |
1985 | + |
1986 | error_exit: |
1987 | return status; |
1988 | } |
1989 | |
1990 | |
1991 | +/* |
1992 | + * Gets the numvber of filters in a subscirption. |
1993 | + */ |
1994 | +GeisSize |
1995 | +geis_subscription_filter_count(GeisSubscription sub) |
1996 | +{ |
1997 | + return geis_filter_bag_count(sub->sub_filters); |
1998 | +} |
1999 | + |
2000 | + |
2001 | +/* |
2002 | + * Gets an indicated filter from a subscription. |
2003 | + */ |
2004 | +GeisFilter |
2005 | +geis_subscription_filter(GeisSubscription sub, GeisSize index) |
2006 | +{ |
2007 | + return geis_filter_bag_filter(sub->sub_filters, index); |
2008 | +} |
2009 | + |
2010 | + |
2011 | |
2012 | === modified file 'libutouch-geis/geis_subscription.h' |
2013 | --- libutouch-geis/geis_subscription.h 2010-12-15 01:48:35 +0000 |
2014 | +++ libutouch-geis/geis_subscription.h 2011-01-06 00:59:08 +0000 |
2015 | @@ -2,7 +2,7 @@ |
2016 | * @file geis_subscription.h |
2017 | * @brief internal uTouch Geis subscription modul private interface |
2018 | * |
2019 | - * Copyright 2010 Canonical Ltd. |
2020 | + * Copyright 2010, 2011 Canonical Ltd. |
2021 | * |
2022 | * This library is free software; you can redistribute it and/or modify it under |
2023 | * the terms of the GNU Lesser General Public License as published by the Free |
2024 | @@ -25,6 +25,11 @@ |
2025 | |
2026 | |
2027 | /** |
2028 | + * @defgroup utouch_geis_sub_container A Subscription Container |
2029 | + * @{ |
2030 | + */ |
2031 | + |
2032 | +/** |
2033 | * A container for subscriptions. |
2034 | */ |
2035 | typedef struct _GeisSubBag *GeisSubBag; |
2036 | @@ -79,5 +84,21 @@ |
2037 | */ |
2038 | GeisSubscription geis_subscription_bag_find(GeisSubBag bag, GeisInteger sub_id); |
2039 | |
2040 | +/* @} */ |
2041 | + |
2042 | +/** |
2043 | + * Gets the numvber of filters in a subscirption. |
2044 | + * |
2045 | + * @param[in] sub The subscription. |
2046 | + */ |
2047 | +GeisSize geis_subscription_filter_count(GeisSubscription sub); |
2048 | + |
2049 | +/** |
2050 | + * Gets an indicated filter from a subscription. |
2051 | + * |
2052 | + * @param[in] sub The subscription. |
2053 | + * @param[in] index Indicates which filter to retrieve. |
2054 | + */ |
2055 | +GeisFilter geis_subscription_filter(GeisSubscription sub, GeisSize index); |
2056 | |
2057 | #endif /* GEIS_SUBSCRIPTION_H_ */ |
2058 | |
2059 | === modified file 'libutouch-geis/libutouch-geis.ver' |
2060 | --- libutouch-geis/libutouch-geis.ver 2010-12-21 01:47:05 +0000 |
2061 | +++ libutouch-geis/libutouch-geis.ver 2011-01-06 00:59:08 +0000 |
2062 | @@ -31,6 +31,15 @@ |
2063 | geis_error_code; |
2064 | geis_error_count; |
2065 | geis_error_message; |
2066 | + geis_event_attr; |
2067 | + geis_event_attr_by_name; |
2068 | + geis_event_attr_count; |
2069 | + geis_event_delete; |
2070 | + geis_event_type; |
2071 | + geis_filter_add_term; |
2072 | + geis_filter_delete; |
2073 | + geis_filter_name; |
2074 | + geis_filter_new; |
2075 | geis_get_configuration; |
2076 | geis_new; |
2077 | geis_next_event; |
2078 | |
2079 | === modified file 'testsuite/geis2/Makefile.am' |
2080 | --- testsuite/geis2/Makefile.am 2010-12-29 20:23:01 +0000 |
2081 | +++ testsuite/geis2/Makefile.am 2011-01-06 00:59:08 +0000 |
2082 | @@ -19,6 +19,7 @@ |
2083 | check_device.c \ |
2084 | check_error_codes.c \ |
2085 | check_event.c \ |
2086 | + check_filter.c \ |
2087 | check_geis_new.c \ |
2088 | check_general_types.c \ |
2089 | check_region.c \ |
2090 | |
2091 | === modified file 'testsuite/geis2/check_device.c' |
2092 | --- testsuite/geis2/check_device.c 2010-12-21 01:47:05 +0000 |
2093 | +++ testsuite/geis2/check_device.c 2011-01-06 00:59:08 +0000 |
2094 | @@ -5,6 +5,24 @@ |
2095 | |
2096 | #include <geis/geis.h> |
2097 | |
2098 | +/* fixtures */ |
2099 | +static Geis g_geis; |
2100 | + |
2101 | +/* fixture setup */ |
2102 | +static void |
2103 | +construct_geis() |
2104 | +{ |
2105 | + g_geis = geis_new(GEIS_INIT_UTOUCH_MOCK_ENGINE, GEIS_INIT_TRACK_DEVICES, NULL); |
2106 | +} |
2107 | + |
2108 | +/* fixture teardown */ |
2109 | +static void |
2110 | +destroy_geis() |
2111 | +{ |
2112 | + geis_delete(g_geis); |
2113 | +} |
2114 | + |
2115 | + |
2116 | /* Compile-time test to ensure types are defined */ |
2117 | START_TEST(geis_device_types) |
2118 | { |
2119 | @@ -29,6 +47,23 @@ |
2120 | } |
2121 | END_TEST |
2122 | |
2123 | +START_TEST(receive_events) |
2124 | +{ |
2125 | + GeisStatus status; |
2126 | + GeisEvent event_out; |
2127 | + |
2128 | + status = geis_dispatch_events(g_geis); |
2129 | + fail_unless(status == GEIS_STATUS_SUCCESS, |
2130 | + "unexpected status from geis_dispatch_events"); |
2131 | + status = geis_next_event(g_geis, &event_out); |
2132 | + fail_unless(status == GEIS_STATUS_SUCCESS, |
2133 | + "unexpected status from geis_dispatch_events"); |
2134 | + fail_unless(geis_event_type(event_out) == GEIS_EVENT_DEVICE_AVAILABLE, |
2135 | + "unexpected event type received"); |
2136 | + |
2137 | +} |
2138 | +END_TEST |
2139 | + |
2140 | |
2141 | /* boilerplate */ |
2142 | Suite * |
2143 | @@ -36,10 +71,15 @@ |
2144 | { |
2145 | Suite *s = suite_create("geis2_device"); |
2146 | |
2147 | - TCase *device = tcase_create("geis2_device"); |
2148 | + TCase *device = tcase_create("device-api"); |
2149 | tcase_add_test(device, geis_device_types); |
2150 | suite_add_tcase(s, device); |
2151 | |
2152 | + TCase *usage = tcase_create("device-usage"); |
2153 | + tcase_add_checked_fixture(usage, construct_geis, destroy_geis); |
2154 | + tcase_add_test(usage, receive_events); |
2155 | + suite_add_tcase(s, usage); |
2156 | + |
2157 | return s; |
2158 | } |
2159 | |
2160 | |
2161 | === added file 'testsuite/geis2/check_filter.c' |
2162 | --- testsuite/geis2/check_filter.c 1970-01-01 00:00:00 +0000 |
2163 | +++ testsuite/geis2/check_filter.c 2011-01-06 00:59:08 +0000 |
2164 | @@ -0,0 +1,41 @@ |
2165 | +/** |
2166 | + * Unit tests for GEIS v2.0 Filter Module. |
2167 | + */ |
2168 | +#include <check.h> |
2169 | + |
2170 | +#include <geis/geis.h> |
2171 | + |
2172 | +/* Compile-time test to ensure types are defined */ |
2173 | +START_TEST(geis_filter_types) |
2174 | +{ |
2175 | + GeisFilter type; |
2176 | +} |
2177 | +END_TEST |
2178 | + |
2179 | +/* Compile-and-link-time test to verify required functions exist */ |
2180 | +START_TEST(geis_filter_functions) |
2181 | +{ |
2182 | + Geis geis; |
2183 | + GeisFilter filter = geis_filter_new(geis, "filter"); |
2184 | + GeisString name = geis_filter_name(filter); |
2185 | + GeisStatus status = geis_filter_add_term(filter, GEIS_FILTER_GESTURE_TYPE, |
2186 | + GEIS_GESTURE_ATTRIBUTE_TOUCHES, GEIS_FILTER_OP_GT, 1, |
2187 | + NULL); |
2188 | + geis_filter_delete(filter); |
2189 | +} |
2190 | +END_TEST |
2191 | + |
2192 | + |
2193 | +/* boilerplate */ |
2194 | +Suite * |
2195 | +geis2_filter_suite_new() |
2196 | +{ |
2197 | + Suite *s = suite_create("geis2_filter"); |
2198 | + |
2199 | + TCase *filter = tcase_create("geis2_filter"); |
2200 | + tcase_add_test(filter, geis_filter_types); |
2201 | + suite_add_tcase(s, filter); |
2202 | + |
2203 | + return s; |
2204 | +} |
2205 | + |
2206 | |
2207 | === modified file 'testsuite/geis2/check_geis2_api.c' |
2208 | --- testsuite/geis2/check_geis2_api.c 2010-12-21 01:47:05 +0000 |
2209 | +++ testsuite/geis2/check_geis2_api.c 2011-01-06 00:59:08 +0000 |
2210 | @@ -12,6 +12,7 @@ |
2211 | extern Suite *geis2_config_suite_new(); |
2212 | extern Suite *geis2_attr_suite_new(); |
2213 | extern Suite *geis2_region_suite_new(); |
2214 | +extern Suite *geis2_filter_suite_new(); |
2215 | extern Suite *geis2_subscription_suite_new(); |
2216 | extern Suite *geis2_event_suite_new(); |
2217 | |
2218 | @@ -31,6 +32,7 @@ |
2219 | srunner_add_suite(sr, geis2_attr_suite_new()); |
2220 | srunner_add_suite(sr, geis2_region_suite_new()); |
2221 | srunner_add_suite(sr, geis2_device_suite_new()); |
2222 | + srunner_add_suite(sr, geis2_filter_suite_new()); |
2223 | srunner_add_suite(sr, geis2_subscription_suite_new()); |
2224 | srunner_add_suite(sr, geis2_event_suite_new()); |
2225 | |
2226 | |
2227 | === modified file 'testsuite/geis2/check_subscription.c' |
2228 | --- testsuite/geis2/check_subscription.c 2010-12-15 01:48:35 +0000 |
2229 | +++ testsuite/geis2/check_subscription.c 2011-01-06 00:59:08 +0000 |
2230 | @@ -14,7 +14,7 @@ |
2231 | static void |
2232 | construct_geis() |
2233 | { |
2234 | - g_geis = geis_new(GEIS_INIT_UTOUCH_MOCK_ENGINE, NULL); |
2235 | + g_geis = geis_new(GEIS_INIT_UTOUCH_MOCK_ENGINE, GEIS_INIT_TRACK_DEVICES, NULL); |
2236 | } |
2237 | |
2238 | /* fixture teardown */ |
2239 | @@ -51,6 +51,69 @@ |
2240 | } |
2241 | END_TEST |
2242 | |
2243 | + |
2244 | +START_TEST(filter) |
2245 | +{ |
2246 | + GeisFilter filter = geis_filter_new(g_geis, "filter"); |
2247 | + GeisSubscription sub = geis_subscription_new(g_geis, |
2248 | + "name", |
2249 | + GEIS_SUBSCRIPTION_NONE); |
2250 | + fail_unless(GEIS_STATUS_SUCCESS == geis_subscription_add_filter(sub, filter)); |
2251 | + fail_unless(GEIS_STATUS_SUCCESS == geis_subscription_remove_filter(sub, filter)); |
2252 | +} |
2253 | +END_TEST |
2254 | + |
2255 | + |
2256 | +START_TEST(device_filter) |
2257 | +{ |
2258 | + GeisStatus status; |
2259 | + GeisEvent event; |
2260 | + |
2261 | + GeisSubscription sub = geis_subscription_new(g_geis, |
2262 | + "devices", |
2263 | + GEIS_SUBSCRIPTION_NONE); |
2264 | + |
2265 | + while (geis_dispatch_events(g_geis) == GEIS_STATUS_CONTINUE) |
2266 | + ; |
2267 | + status = geis_next_event(g_geis, &event); |
2268 | + while (status == GEIS_STATUS_SUCCESS || status == GEIS_STATUS_CONTINUE) |
2269 | + { |
2270 | + if (geis_event_type(event) == GEIS_EVENT_DEVICE_AVAILABLE) |
2271 | + { |
2272 | + GeisAttr attr = geis_event_attr_by_name(event, "geis-device"); |
2273 | + fail_if (!attr, "geis-device attr not found in device event"); |
2274 | + |
2275 | + GeisDevice device = geis_attr_value_to_pointer(attr); |
2276 | + fail_if (!device, "geis device not found in device event"); |
2277 | + |
2278 | + GeisFilter filter = geis_filter_new(g_geis, "device filter"); |
2279 | + fail_if(!filter, "can not create filter"); |
2280 | + |
2281 | + GeisStatus fs = geis_filter_add_term(filter, GEIS_FILTER_DEVICE, |
2282 | + GEIS_DEVICE_ATTRIBUTE_NAME, GEIS_FILTER_OP_NE, geis_device_name(device), |
2283 | + NULL); |
2284 | + fail_if(fs != GEIS_STATUS_SUCCESS, "can not add device to filter"); |
2285 | + |
2286 | + fs = geis_subscription_add_filter(sub, filter); |
2287 | + fail_if(fs != GEIS_STATUS_SUCCESS, "can not subscribe filter"); |
2288 | + |
2289 | + if (status == GEIS_STATUS_CONTINUE) |
2290 | + { |
2291 | + status = geis_next_event(g_geis, &event); |
2292 | + } |
2293 | + else |
2294 | + { |
2295 | + break; |
2296 | + } |
2297 | + } |
2298 | + } |
2299 | + |
2300 | + fail_unless(GEIS_STATUS_SUCCESS == geis_subscription_activate(sub), |
2301 | + "unable to activate subscription"); |
2302 | +} |
2303 | +END_TEST |
2304 | + |
2305 | + |
2306 | /* boilerplate */ |
2307 | Suite * |
2308 | geis2_subscription_suite_new() |
2309 | @@ -64,6 +127,8 @@ |
2310 | TCase *usage = tcase_create("subscription-usage"); |
2311 | tcase_add_checked_fixture(usage, construct_geis, destroy_geis); |
2312 | tcase_add_test(usage, construction); |
2313 | + tcase_add_test(usage, filter); |
2314 | + tcase_add_test(usage, device_filter); |
2315 | suite_add_tcase(s, usage); |
2316 | |
2317 | return s; |
2318 | |
2319 | === modified file 'testsuite/libutouch-geis/Makefile.am' |
2320 | --- testsuite/libutouch-geis/Makefile.am 2010-12-29 20:23:01 +0000 |
2321 | +++ testsuite/libutouch-geis/Makefile.am 2011-01-06 00:59:08 +0000 |
2322 | @@ -36,6 +36,7 @@ |
2323 | check_device.c \ |
2324 | check_error_reporting.c \ |
2325 | check_event_queue.c \ |
2326 | + check_filter.c \ |
2327 | check_geis_private.c \ |
2328 | check_region.c \ |
2329 | check_subscription.c \ |
2330 | |
2331 | === added file 'testsuite/libutouch-geis/check_filter.c' |
2332 | --- testsuite/libutouch-geis/check_filter.c 1970-01-01 00:00:00 +0000 |
2333 | +++ testsuite/libutouch-geis/check_filter.c 2011-01-06 00:59:08 +0000 |
2334 | @@ -0,0 +1,101 @@ |
2335 | +/** |
2336 | + * unit tests for the geis filter module |
2337 | + */ |
2338 | +#include <check.h> |
2339 | + |
2340 | +#include "libutouch-geis/geis_filter.h" |
2341 | + |
2342 | + |
2343 | +/* fixtures */ |
2344 | +static Geis g_geis; |
2345 | +static GeisFilterBag g_filter_bag; |
2346 | +static GeisString g_filter_name = "filter"; |
2347 | + |
2348 | +/* fixture setup */ |
2349 | +static void |
2350 | +construct_bag() |
2351 | +{ |
2352 | + g_geis = geis_new(GEIS_INIT_UTOUCH_MOCK_ENGINE, NULL); |
2353 | + g_filter_bag = geis_filter_bag_new(); |
2354 | +} |
2355 | + |
2356 | +/* fixture teardown */ |
2357 | +static void |
2358 | +destroy_bag() |
2359 | +{ |
2360 | + geis_filter_bag_delete(g_filter_bag); |
2361 | + geis_delete(g_geis); |
2362 | +} |
2363 | + |
2364 | +/* verify bag construction/destruction */ |
2365 | +START_TEST(construct) |
2366 | +{ |
2367 | + GeisFilterBag bag = geis_filter_bag_new(); |
2368 | + fail_unless(bag != NULL, "failed to create filter bag"); |
2369 | + geis_filter_bag_delete(bag); |
2370 | +} |
2371 | +END_TEST |
2372 | + |
2373 | +/* verify bag insertion */ |
2374 | +START_TEST(insert) |
2375 | +{ |
2376 | + GeisFilter filter = geis_filter_new(g_geis, g_filter_name); |
2377 | + geis_filter_bag_insert(g_filter_bag, filter); |
2378 | + fail_unless(geis_filter_bag_count(g_filter_bag) == 1, |
2379 | + "unexpected bag size after insertion"); |
2380 | +} |
2381 | +END_TEST |
2382 | + |
2383 | +/* verify bag removal */ |
2384 | +START_TEST(remove) |
2385 | +{ |
2386 | + GeisFilter filter = geis_filter_new(g_geis, g_filter_name); |
2387 | + geis_filter_bag_insert(g_filter_bag, filter); |
2388 | + fail_unless(geis_filter_bag_count(g_filter_bag) == 1, |
2389 | + "unexpected bag size after insertion"); |
2390 | + geis_filter_bag_remove(g_filter_bag, filter); |
2391 | + fail_unless(geis_filter_bag_count(g_filter_bag) == 0, |
2392 | + "unexpected bag size after removal"); |
2393 | +} |
2394 | +END_TEST |
2395 | + |
2396 | +START_TEST(expand) |
2397 | +{ |
2398 | + int i; |
2399 | + for (i = 0; i < 24; ++i) |
2400 | + { |
2401 | + GeisSize count; |
2402 | + char name[32]; |
2403 | + sprintf(name, "%04d", i); |
2404 | + GeisFilter filter = geis_filter_new(g_geis, name); |
2405 | + geis_filter_bag_insert(g_filter_bag, filter); |
2406 | + count = geis_filter_bag_count(g_filter_bag); |
2407 | + fail_unless(count == (i+1), |
2408 | + "unexpected bag size %ld after insertion, expected %d", |
2409 | + count, i+1); |
2410 | + } |
2411 | +} |
2412 | +END_TEST |
2413 | + |
2414 | + |
2415 | + |
2416 | +/* boilerplate */ |
2417 | +Suite * |
2418 | +make_filter_suite() |
2419 | +{ |
2420 | + Suite *s = suite_create("utouch-geis2-filter"); |
2421 | + |
2422 | + TCase *create = tcase_create("filter-bag-creation"); |
2423 | + tcase_add_test(create, construct); |
2424 | + suite_add_tcase(s, create); |
2425 | + |
2426 | + TCase *usage = tcase_create("filter-bag-usage"); |
2427 | + tcase_add_checked_fixture(usage, construct_bag, destroy_bag); |
2428 | + tcase_add_test(usage, insert); |
2429 | + tcase_add_test(usage, remove); |
2430 | + tcase_add_test(usage, expand); |
2431 | + suite_add_tcase(s, usage); |
2432 | + |
2433 | + return s; |
2434 | +} |
2435 | + |
2436 | |
2437 | === modified file 'testsuite/libutouch-geis/check_geis2_internals.c' |
2438 | --- testsuite/libutouch-geis/check_geis2_internals.c 2010-12-21 13:59:31 +0000 |
2439 | +++ testsuite/libutouch-geis/check_geis2_internals.c 2011-01-06 00:59:08 +0000 |
2440 | @@ -11,6 +11,7 @@ |
2441 | extern Suite *make_device_suite(); |
2442 | extern Suite *make_error_reporting_suite(); |
2443 | extern Suite *make_event_queue_suite(); |
2444 | +extern Suite *make_filter_suite(); |
2445 | extern Suite *make_region_suite(); |
2446 | extern Suite *make_subscription_suite(); |
2447 | |
2448 | @@ -30,6 +31,7 @@ |
2449 | srunner_add_suite(sr, make_backend_event_posting_suite()); |
2450 | srunner_add_suite(sr, make_device_suite()); |
2451 | srunner_add_suite(sr, make_region_suite()); |
2452 | + srunner_add_suite(sr, make_filter_suite()); |
2453 | srunner_add_suite(sr, make_subscription_suite()); |
2454 | |
2455 | srunner_set_log(sr, LOGFILE_PREFIX".log"); |
At geis.h:132, there is a "teh".
In geis_filter_ term_bag_ new(), there is an error path that returns non-null.
That's about what I could find. Perhaps also adding _get_attr_ for_factility( ) before respinning this patch would be good.