Merge lp:~oif-team/geis/event-control-functions into lp:geis

Proposed by Stephen M. Webb
Status: Superseded
Proposed branch: lp:~oif-team/geis/event-control-functions
Merge into: lp:geis
Prerequisite: lp:geis/2.x
Diff against target: 1294 lines (+1020/-24)
18 files modified
.bzrignore (+7/-7)
ChangeLog (+55/-0)
include/geis/geis.h (+161/-1)
libutouch-geis/Makefile.am (+3/-1)
libutouch-geis/geis.c (+165/-10)
libutouch-geis/geis_attr.c (+16/-0)
libutouch-geis/geis_attr.h (+5/-0)
libutouch-geis/geis_event.c (+124/-0)
libutouch-geis/geis_event.h (+41/-0)
libutouch-geis/geis_event_queue.c (+154/-0)
libutouch-geis/geis_event_queue.h (+74/-0)
libutouch-geis/geis_private.h (+14/-1)
libutouch-geis/libutouch-geis.ver (+3/-0)
testsuite/libutouch-geis/Makefile.am (+2/-0)
testsuite/libutouch-geis/check_attr.c (+27/-0)
testsuite/libutouch-geis/check_backend_event_posting.c (+70/-0)
testsuite/libutouch-geis/check_event_queue.c (+88/-0)
testsuite/libutouch-geis/check_geis2_internals.c (+11/-4)
To merge this branch: bzr merge lp:~oif-team/geis/event-control-functions
Reviewer Review Type Date Requested Status
Chase Douglas (community) Needs Fixing
Review via email: mp+42791@code.launchpad.net

This proposal has been superseded by a proposal from 2010-12-10.

Description of the change

Adds the event control functions.

To post a comment you must log in.
Revision history for this message
Chase Douglas (chasedouglas) wrote :

1. I would remove the geis_event_delete calls until it's implemented. I don't like seeing "#if 0" :). If you want to note something that should be changed in the future, I think a "FIXME: <blah>" is better. It gives context as to what is needed.

2. geis_event_queue_push allocates a GeisEvent on the stack and copies the event passed in. Then, the event is copied once more into the GeisEventQueueNode. The stack allocation and copying of the GeisEvent into the function is unnecessary. A pointer should be passed instead.

3. The event queue is a queue, not a stack. Queue semantics should be used, such as enqueue and dequeue. Using push and pop confuses me until I remember that it's a queue :).

4. geis_event_queue_front copies data into a geis event. Why not just return a pointer to the event? This would cut down on extra allocating and copying.

5. Imo, a cleaner interface is a dequeue function that returns the event if available and removes it from the queue. This requires one function call instead of two to retrieve the event and remove it.

review: Needs Fixing
114. By Stephen M. Webb

Added geis_attr_bag_attr() function.

115. By Stephen M. Webb

Added event control and queueing.

116. By Stephen M. Webb

Renamed event queue functions.

Unmerged revisions

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file '.bzrignore'
--- .bzrignore 2010-11-24 16:59:34 +0000
+++ .bzrignore 2010-12-09 23:44:08 +0000
@@ -1,9 +1,9 @@
1**.pdf1**.pdf
2**/Makefile
2*.deps3*.deps
3*.libs4*.libs
4*/*.la5*/*.la
5*/*.lo6*/*.lo
6*/Makefile
7*Makefile.in7*Makefile.in
8aclocal.m48aclocal.m4
9autom4te.cache9autom4te.cache
@@ -23,16 +23,16 @@
23doc/docbook-xsl.css23doc/docbook-xsl.css
24doc/geisspec-1.0.html24doc/geisspec-1.0.html
25geis_config.*25geis_config.*
26libtool
26libutouch-geis-xcb/xcb_gesture.xml27libutouch-geis-xcb/xcb_gesture.xml
27libutouch-geis-xcb/xcb_gesture.[ch]28libutouch-geis-xcb/xcb_gesture.[ch]
28libutouch-geis.pc29libutouch-geis.pc
29libtool
30Makefile
31stamp-*30stamp-*
32testsuite/libutouch-geis/check_geis2_internals31testsuite/geis1/*.log
33testsuite/libutouch-geis/*.log
34testsuite/geis1/check_geis_internals32testsuite/geis1/check_geis_internals
35testsuite/geis1/*.log33testsuite/geis2/*.log
36testsuite/geis2/check_geis2_api34testsuite/geis2/check_geis2_api
37testsuite/geis2/*.log
38testsuite/geistest/geistest35testsuite/geistest/geistest
36testsuite/libutouch-geis/*.log
37testsuite/libutouch-geis/*.xml
38testsuite/libutouch-geis/check_geis2_internals
3939
=== modified file 'ChangeLog'
--- ChangeLog 2010-12-02 19:09:57 +0000
+++ ChangeLog 2010-12-09 23:44:08 +0000
@@ -1,3 +1,58 @@
12010-12-08 Stephen M. Webb <stephen.webb@canonical.com>
2
3 Refactored event queue style.
4
5 * libutouch-geis/geis_event_queue.h (geis_event_queue_enqueue): renamed from
6 geis_event_queue_push
7 (geis_event_queue_dequeue): renamed from geis_event_queue_pop
8 changed event output parameter to return value
9 * libutouch-geis/geis_event_queue.c: refactored for above
10 * libutouch-geis/geis.c: refactored for above
11 * testsuite/libutouch-geis/check_event_queue.c: refactored for above
12
13
142010-12-08 Stephen M. Webb <stephen.webb@canonical.com>
15
16 Added an event queue.
17
18 * libutouch-geis/geis_event.c: new file
19 * libutouch-geis/geis_event.h: new file
20 * libutouch-geis/geis_event_queue.c: new file
21 * libutouch-geis/geis_event_queue.h: new file
22 * testsuite/libutouch-geis/check_backend_event_posting.c: new test case
23 * testsuite/libutouch-geis/check_event_queue.c: new test case
24 * include/geis/geis.h (GeisEventType): new enum type
25 (geis_event_delete): new function
26 (geis_event_type): new function
27 (geis_event_attr_count): new function
28 (geis_event_attr): new function
29 (geis_event_attr_by_name): new function
30 * libutouch-geis/Makefile.am: added new files
31 * libutouch-geis/geis.c (struct _Geis): added input_event_queue,
32 output_event_queue, and input_signal_pipe members
33 (_default_output_event_callback): new function
34 (_input_event_handler): new function
35 (geis_new_empty): initialized new members
36 (geis_register_event_callback): used _default_output_event_callback
37 (geis_next_event): implemented stubbed-out function
38 * testsuite/libutouch-geis/Makefile.am: added new test cases
39 * testsuite/libutouch-geis/check_geis2_internals.c: added new test cases
40
41
422010-12-02 Stephen M. Webb <stephen.webb@canonical.com>
43
44 Added GEIS v2.0 event control functions.
45
46 * include/geis/geis.h (GeisEvent): new type
47 (GeisEventCallback): new type
48 (GEIS_DEFAULT_EVENT_CALLBACK): new constant
49 (geis_register_event_callback): new function
50 (geis_dispatch_events): new function
51 (geis_next_event): new function
52 * libutouch-geis/geis_private.h (geis_post_event): new function
53 * libutouch-geis/geis.c: implemented new functions
54 * libutouch-geis/libutouch-geis.ver: added new symbols
55
12010-12-02 Stephen M. Webb <stephen.webb@canonical.com>562010-12-02 Stephen M. Webb <stephen.webb@canonical.com>
257
3 Added a back end base and test fixture.58 Added a back end base and test fixture.
459
=== modified file 'include/geis/geis.h'
--- include/geis/geis.h 2010-12-02 19:09:57 +0000
+++ include/geis/geis.h 2010-12-09 23:44:08 +0000
@@ -299,7 +299,7 @@
299/* @} */299/* @} */
300300
301/**301/**
302 * @defgroup geis_config Configuration and Control (GEIS v1.0)302 * @defgroup geis1_config Configuration and Control (GEIS v1.0)
303 * @{303 * @{
304 */304 */
305305
@@ -717,6 +717,166 @@
717717
718/* @} */718/* @} */
719719
720/**
721 * @defgroup geis2_event_control Event Control (GEIS v2.0)
722 *
723 * These functions are used to dispatch events generated from the various other
724 * GEIS components.
725 *
726 * Applications must invoke geis_dispatch_events() from time to time to generate
727 * input device, gesture type, and gesture events. The GEIS events are then
728 * retrieved either from the internal event queue using the geis_next_event()
729 * call or through an application-supplied callback set through the
730 * geis_register_event_callback() call.
731 *
732 * @{
733 */
734
735typedef enum _GeisEventType
736{
737 GEIS_EVENT_TYPE_DEVICE_AVAILABLE = 1000,
738 GEIS_EVENT_TYPE_DEVICE_UNAVAILABLE = 1010,
739 GEIS_EVENT_TYPE_GESTURE_TYPE_AVAILABLE = 2000,
740 GEIS_EVENT_TYPE_GESTURE_TYPE_UNAVAILABLE = 2010,
741 GEIS_EVENT_TYPE_GESTURE_BEGIN = 3000,
742 GEIS_EVENT_TYPE_GESTURE_UPDATE = 3010,
743 GEIS_EVENT_TYPE_GESTURE_END = 3020,
744 GEIS_EVENT_TYPE_ERROR = 5000,
745 GEIS_EVENT_TYPE_UNKNOWN = 9999
746} GeisEventType;
747
748/**
749 * Opaque pointer to a generic GEIS event.
750 *
751 * Applications must determine the type of the actual event and convert the
752 * opaque pointer to a concrete event pointer, if required.
753 *
754 * Events are created by the GEIS API but must be destroyed by the application.
755 */
756typedef struct _GeisEvent *GeisEvent;
757
758/**
759 * Destroys a GeisEvent.
760 *
761 * @param[in] geis The GeisEvent to destroy.
762 */
763GEIS_API void geis_event_delete(GeisEvent event);
764
765/**
766 * Gets the type of the event.
767 *
768 * @param[in] geis The GeisEvent to destroy.
769 */
770GEIS_API GeisEventType geis_event_type(GeisEvent event);
771
772/**
773 * Gets the number of attributes in the event.
774 *
775 * @param[in] geis The GeisEvent.
776 */
777GEIS_API GeisSize geis_event_attr_count(GeisEvent event);
778
779/**
780 * Gets an indicated attribute from the event.
781 *
782 * @param[in] geis The GeisEvent.
783 * @param[in] index Indicates the attribute to retrieve.
784 */
785GEIS_API GeisAttr geis_event_attr(GeisEvent event, GeisSize index);
786
787/**
788 * Gets a named attribute from the event.
789 *
790 * @param[in] geis The GeisEvent.
791 * @param[in] attr_name The name of the attribute to retrieve.
792 */
793GEIS_API GeisAttr geis_event_attr_by_name(GeisEvent event, GeisString attr_name);
794
795/**
796 * The application callback type for the event dispatcher.
797 *
798 * @param[in] geis the GEIS API instance
799 * @param[in] event the opaque event pointer
800 * @param[in] context the application-supplied context value
801 */
802typedef void (*GeisEventCallback)(Geis geis, GeisEvent event, void *context);
803
804/**
805 * A special constant indicating the use of the default event callback.
806 */
807#define GEIS_DEFAULT_EVENT_CALLBACK ((GeisEventCallback)0)
808
809/**
810 * Registers an event-handler callback.
811 *
812 * @param[in] geis the GEIS API instance
813 * @param[in] event_callback the callback to register
814 * @param[in] context the caller context
815 *
816 * This function registers the callback to be executed whenever a new GeisEvent
817 * is generated. The default function pushes the GeisEvent onto an internal
818 * queue to be picked up by a call to geis_next_event().
819 *
820 * Calling geis_register_event_callback() with a callback of
821 * GEIS_DEFAULT_EVENT_CALLBACK replaces any registered function wit hthe default
822 * function.
823 *
824 * The callback is executed in the same thread context as the one
825 * geis_dispatch_events() is called from.
826 */
827GEIS_API void geis_register_event_callback(Geis geis,
828 GeisEventCallback event_callback,
829 void *context);
830
831/**
832 * Pumps the GEIS event loop.
833 *
834 * @param[in] geis The GEIS API instance.
835 * @param[out] event An opeaque event object.
836 *
837 * Processes input events until there are no more input events to process and
838 * generates zero or more gesture events, reporting them via the user-supplied
839 * callback or pushing them on the internal event queue for retrieval via the
840 * geis_next_event() call.
841 *
842 * @retval GEIS_STATUS_SUCCESS The event loop was successfully pumped and
843 * no further events remain to be processed at
844 * this time.
845 *
846 * @retval GEIS_STATUS_CONTINUE The event loop was successfully pumped but
847 * the system detected there are events
848 * still remaining to be processed.
849 *
850 * @retval GEIS_STATUS_UNKNOWN_ERROR Some error occurred
851 */
852GEIS_API GeisStatus geis_dispatch_events(Geis geis);
853
854/**
855 * Retrieves the next queued GEIS event.
856 *
857 * @param[in] geis The GEIS API instance.
858 * @param[out] event The GeisEvent retrieved, if any.
859 *
860 * Pulls the next available GeisEvent from the internal event queue, if any, and
861 * indicates whether there are more events left.
862 *
863 * @retval GEIS_STATUS_SUCCESS An event was successfully pulled from the
864 * queue and the queue is now empty.
865 *
866 * @retval GEIS_STATUS_CONTINUE An event was successfully pulled from the
867 * queue and one or more events remain in the
868 * queue.
869 *
870 * @retval GEIS_STATUS_EMPTY No event was pulled from the queue because
871 * it is empty. The value of *event remains
872 * unchanged.
873 *
874 * @retval GEIS_STATUS_UNKNOWN_ERROR Some error occurred
875 */
876GEIS_API GeisStatus geis_next_event(Geis geis, GeisEvent *event);
877
878/* @} */
879
720#ifdef __cplusplus880#ifdef __cplusplus
721} // extern "C"881} // extern "C"
722#endif882#endif
723883
=== modified file 'libutouch-geis/Makefile.am'
--- libutouch-geis/Makefile.am 2010-12-02 19:09:57 +0000
+++ libutouch-geis/Makefile.am 2010-12-09 23:44:08 +0000
@@ -26,9 +26,11 @@
26 geis_attr.h geis_attr.c \26 geis_attr.h geis_attr.c \
27 geis_backend.h geis_backend.c \27 geis_backend.h geis_backend.c \
28 geis_backend_protected.h \28 geis_backend_protected.h \
29 geis_backend_multiplexor.h geis_backend_multiplexor.c \
29 geis_backend_test_fixture.h geis_backend_test_fixture.c \30 geis_backend_test_fixture.h geis_backend_test_fixture.c \
30 geis_backend_multiplexor.h geis_backend_multiplexor.c \
31 geis_error.h geis_error.c \31 geis_error.h geis_error.c \
32 geis_event.h geis_event.c \
33 geis_event_queue.h geis_event_queue.c \
32 geis_logging.h geis_logging.c \34 geis_logging.h geis_logging.c \
33 geis_subscription.h geis_subscription.c \35 geis_subscription.h geis_subscription.c \
34 geis_private.h geis.c36 geis_private.h geis.c
3537
=== modified file 'libutouch-geis/geis.c'
--- libutouch-geis/geis.c 2010-12-02 19:09:57 +0000
+++ libutouch-geis/geis.c 2010-12-09 23:44:08 +0000
@@ -21,24 +21,76 @@
21#include "geis_config.h"21#include "geis_config.h"
22#include "geis_private.h"22#include "geis_private.h"
2323
24#include <errno.h>
24#include "geis_backend.h"25#include "geis_backend.h"
25#include "geis_backend_test_fixture.h"26#include "geis_backend_test_fixture.h"
26#include "geis_backend_multiplexor.h"27#include "geis_backend_multiplexor.h"
27#include "geis_error.h"28#include "geis_error.h"
29#include "geis_event_queue.h"
28#include "geis_logging.h"30#include "geis_logging.h"
29#include <stdarg.h>31#include <stdarg.h>
30#include <string.h>32#include <string.h>
33#include <unistd.h>
3134
3235
33struct _Geis36struct _Geis
34{37{
35 GeisErrorStack error_stack;38 GeisErrorStack error_stack;
36 GeisSubBag subscription_bag;39 GeisSubBag subscription_bag;
37 GeisBackendMultiplexor backend_multiplexor;40 GeisBackendMultiplexor backend_multiplexor;
38 GeisBackend backend;41 GeisBackend backend;
42 GeisEventQueue input_event_queue;
43 int input_event_signal_pipe[2];
44 GeisEventQueue output_event_queue;
45 GeisEventCallback output_event_callback;
46 void *output_event_callback_context;
39};47};
4048
4149
50/*
51 * The default event callback -- just pushes events on the internal queue
52 */
53static void
54_default_output_event_callback(Geis geis,
55 GeisEvent event,
56 void *context __attribute__((unused)))
57{
58 geis_debug("posting output event");
59 geis_event_queue_enqueue(geis->output_event_queue, event);
60}
61
62/*
63 * Filters and transforms raw gesture events into cooked gesture events.
64 *
65 * For now, does nothing except copy from the input queueu to the output queue.
66 */
67static void
68_input_event_handler(int fd, GeisBackendMultiplexorEvent mux_ev, void *context)
69{
70 Geis geis = (Geis)context;
71
72 if (mux_ev == GEIS_BE_MX_READ_AVAILABLE)
73 {
74 GeisEvent event;
75
76 /* clear the input event signal */
77 char buf[2];
78 if (read(fd, buf, 1) != 1)
79 {
80 geis_warning("unexpected number of bytes read from signal pipe");
81 }
82
83 geis_debug("input event available");
84 event = geis_event_queue_dequeue(geis->input_event_queue);
85 if (event)
86 {
87 geis->output_event_callback(geis,
88 event,
89 geis->output_event_callback_context);
90 }
91 }
92}
93
42/**94/**
43 * Creates a new empty Geis API instance.95 * Creates a new empty Geis API instance.
44 */96 */
@@ -71,14 +123,49 @@
71 geis_error("creation of back end multiplexor failed");123 geis_error("creation of back end multiplexor failed");
72 goto unwind_subscription_bag;124 goto unwind_subscription_bag;
73 }125 }
126
127 geis->input_event_queue = geis_event_queue_new();
128 if (!geis->input_event_queue)
129 {
130 geis_error_push(NULL, GEIS_STATUS_UNKNOWN_ERROR);
131 geis_error("creation of input event queue failed");
132 goto unwind_backend_mux;
133 }
134 if (pipe(geis->input_event_signal_pipe) < 0)
135 {
136 geis_error_push(NULL, GEIS_STATUS_UNKNOWN_ERROR);
137 geis_error("error %d creating input event signal pipe: %s",
138 errno, strerror(errno));
139 goto unwind_input_queue;
140 }
141 geis_backend_multiplexor_add_fd(geis->backend_multiplexor,
142 geis->input_event_signal_pipe[0],
143 _input_event_handler,
144 geis);
145
146 geis->output_event_queue = geis_event_queue_new();
147 if (!geis->output_event_queue)
148 {
149 geis_error_push(NULL, GEIS_STATUS_UNKNOWN_ERROR);
150 geis_error("creation of output event queue failed");
151 goto unwind_input_signal_pipe;
152 }
153 geis->output_event_callback = _default_output_event_callback;
154
74 goto final_exit;155 goto final_exit;
75156
157unwind_input_signal_pipe:
158 close(geis->input_event_signal_pipe[0]);
159 close(geis->input_event_signal_pipe[1]);
160unwind_input_queue:
161 geis_event_queue_delete(geis->input_event_queue);
162unwind_backend_mux:
163 geis_backend_multiplexor_delete(geis->backend_multiplexor);
76unwind_subscription_bag:164unwind_subscription_bag:
77 geis_subscription_bag_delete(geis->subscription_bag);165 geis_subscription_bag_delete(geis->subscription_bag);
78
79unwind_geis:166unwind_geis:
80 free(geis);167 free(geis);
81 geis = NULL;168 geis = NULL;
82169
83final_exit:170final_exit:
84 return geis;171 return geis;
@@ -187,7 +274,7 @@
187}274}
188275
189276
190/**277/*
191 * Sets a named configuration item.278 * Sets a named configuration item.
192 */279 */
193GeisStatus280GeisStatus
@@ -208,7 +295,75 @@
208}295}
209296
210297
211GeisErrorStack *geis_error_stack(Geis geis)298/*
299 * Registers an application-supplied event callback.
300 */
301void
302geis_register_event_callback(Geis geis,
303 GeisEventCallback output_event_callback,
304 void *context)
305{
306 if (output_event_callback == GEIS_DEFAULT_EVENT_CALLBACK)
307 {
308 geis->output_event_callback = _default_output_event_callback;
309 }
310 else
311 {
312 geis->output_event_callback = output_event_callback;
313 }
314 geis->output_event_callback_context = context;
315}
316
317
318/*
319 * Pumps the GEIS v2 event loop.
320 */
321GeisStatus
322geis_dispatch_events(Geis geis)
323{
324 GeisStatus status = geis_backend_multiplexor_pump(geis->backend_multiplexor);
325 return status;
326}
327
328
329/*
330 * Posts an event through the API.
331 *
332 * Pushes the new event onto the input event queue and signals that a new event
333 * has arrived.
334 */
335void
336geis_post_event(Geis geis, GeisEvent event)
337{
338 geis_event_queue_enqueue(geis->input_event_queue, event);
339 if (write(geis->input_event_signal_pipe[1], "1", 1) != 1)
340 {
341 geis_error("error %d writing input event signal: %s", errno, strerror(errno));
342 }
343}
344
345
346/*
347 * Pulls the next event off the queue.
348 */
349GeisStatus
350geis_next_event(Geis geis, GeisEvent *event)
351{
352 GeisStatus status = GEIS_STATUS_EMPTY;
353 *event = geis_event_queue_dequeue(geis->output_event_queue);
354 if (*event)
355 {
356 status = geis_event_queue_is_empty(geis->output_event_queue)
357 ? GEIS_STATUS_SUCCESS
358 : GEIS_STATUS_CONTINUE;
359 }
360
361 return status;
362}
363
364
365GeisErrorStack *
366geis_error_stack(Geis geis)
212{367{
213 return &geis->error_stack;368 return &geis->error_stack;
214}369}
215370
=== modified file 'libutouch-geis/geis_attr.c'
--- libutouch-geis/geis_attr.c 2010-11-26 18:22:53 +0000
+++ libutouch-geis/geis_attr.c 2010-12-09 23:44:08 +0000
@@ -123,6 +123,22 @@
123123
124124
125GeisAttr125GeisAttr
126geis_attr_bag_attr(GeisAttrBag bag, GeisSize index)
127{
128 GeisAttr attr = NULL;
129 if (index >= bag->attr_count)
130 {
131 geis_error("index out of range");
132 }
133 else
134 {
135 return bag->attr_store[index];
136 }
137 return attr;
138}
139
140
141GeisAttr
126geis_attr_bag_find(GeisAttrBag bag, GeisString attr_name)142geis_attr_bag_find(GeisAttrBag bag, GeisString attr_name)
127{143{
128 GeisAttr attr = NULL;144 GeisAttr attr = NULL;
129145
=== modified file 'libutouch-geis/geis_attr.h'
--- libutouch-geis/geis_attr.h 2010-11-26 18:22:53 +0000
+++ libutouch-geis/geis_attr.h 2010-12-09 23:44:08 +0000
@@ -43,6 +43,11 @@
43GeisSize geis_attr_bag_count(GeisAttrBag bag);43GeisSize geis_attr_bag_count(GeisAttrBag bag);
4444
45/**45/**
46 * Pulls an indicated attr out of a bag.
47 */
48GeisAttr geis_attr_bag_attr(GeisAttrBag bag, GeisSize index);
49
50/**
46 * Inserts an attribute in an attribute container.51 * Inserts an attribute in an attribute container.
47 */52 */
48GeisStatus geis_attr_bag_insert(GeisAttrBag bag, GeisAttr attr);53GeisStatus geis_attr_bag_insert(GeisAttrBag bag, GeisAttr attr);
4954
=== added file 'libutouch-geis/geis_event.c'
--- libutouch-geis/geis_event.c 1970-01-01 00:00:00 +0000
+++ libutouch-geis/geis_event.c 2010-12-09 23:44:08 +0000
@@ -0,0 +1,124 @@
1/**
2 * @file geis_event.c
3 * @brief uTouch GeisEvent module implementation
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
22#include "geis/geis.h"
23#include "geis_attr.h"
24#include "geis_logging.h"
25#include <stdlib.h>
26
27
28struct _GeisEvent
29{
30 GeisEventType ev_type;
31 GeisAttrBag ev_attr_bag;
32};
33
34
35/*
36 * Creates a new event.
37 */
38GeisEvent
39geis_event_new(GeisEventType ev_type)
40{
41 GeisEvent event = calloc(1, sizeof(struct _GeisEvent));
42 if (!event)
43 {
44 geis_error("unable to allocate GeisEvent");
45 goto final_exit;
46 }
47
48 event->ev_type = ev_type;
49 event->ev_attr_bag = geis_attr_bag_new(4);
50 if (!event->ev_attr_bag)
51 {
52 geis_error("unable to allocate GeisEvent attribute bag");
53 goto unwind_event;
54 }
55 goto final_exit;
56
57unwind_event:
58 free(event);
59final_exit:
60 return event;
61}
62
63
64/*
65 * Destroys an event.
66 */
67void
68geis_event_delete(GeisEvent event)
69{
70 geis_attr_bag_delete(event->ev_attr_bag);
71 free(event);
72}
73
74
75/*
76 * Gets the type of the event.
77 */
78GeisEventType
79geis_event_type(GeisEvent event)
80{
81 return event->ev_type;
82}
83
84
85/*
86 * Gets how many attrs are in the event.
87 */
88GeisSize
89geis_event_attr_count(GeisEvent event)
90{
91 return geis_attr_bag_count(event->ev_attr_bag);
92}
93
94
95/*
96 * Gets an indicated attr.
97 */
98GeisAttr
99geis_event_attr(GeisEvent event, GeisSize index)
100{
101 return geis_attr_bag_attr(event->ev_attr_bag, index);
102}
103
104
105/*
106 * Gets a named attr.
107 */
108GeisAttr
109geis_event_attr_by_name(GeisEvent event, GeisString attr_name)
110{
111 return geis_attr_bag_find(event->ev_attr_bag, attr_name);
112}
113
114
115/*
116 * Adds an attr.
117 */
118GeisStatus
119geis_event_add_attr(GeisEvent event, GeisAttr attr)
120{
121 return geis_attr_bag_insert(event->ev_attr_bag, attr);
122}
123
124
0125
=== added file 'libutouch-geis/geis_event.h'
--- libutouch-geis/geis_event.h 1970-01-01 00:00:00 +0000
+++ libutouch-geis/geis_event.h 2010-12-09 23:44:08 +0000
@@ -0,0 +1,41 @@
1/**
2 * @file geis_event.c
3 * @brief Internal interface of the uTouch GeisEvent 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#ifndef GEIS_EVENT_H_
22#define GEIS_EVENT_H_
23
24#include "geis/geis.h"
25
26/**
27 * Creates a new, empty event of type @p type.
28 *
29 * @param[in] type The type of the event.
30 */
31GeisEvent geis_event_new(GeisEventType type);
32
33/**
34 * Adds an attr to an event.
35 *
36 * @param[in] event The event.
37 * @param[in] attr The attr.
38 */
39GeisStatus geis_event_add_attr(GeisEvent event, GeisAttr attr);
40
41#endif /* GEIS_EVENT_H_ */
042
=== added file 'libutouch-geis/geis_event_queue.c'
--- libutouch-geis/geis_event_queue.c 1970-01-01 00:00:00 +0000
+++ libutouch-geis/geis_event_queue.c 2010-12-09 23:44:08 +0000
@@ -0,0 +1,154 @@
1/**
2 * @file geis_event_queue.c
3 * @brief internal uTouch Geis event queue implementation
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_event_queue.h"
22
23#include "geis_logging.h"
24#include <stdlib.h>
25
26
27typedef struct _GeisEventQueueNode *GeisEventQueueNode;
28
29struct _GeisEventQueueNode
30{
31 GeisEventQueueNode eq_next;
32 GeisEvent eq_event;
33};
34
35struct _GeisEventQueue
36{
37 GeisEventQueueNode eq_front;
38 GeisEventQueueNode eq_back;
39 GeisEventQueueNode eq_pool;
40};
41
42
43/*
44 * Creates a new Geis Event queue.
45 */
46GeisEventQueue
47geis_event_queue_new()
48{
49 GeisEventQueue queue = calloc(1, sizeof(struct _GeisEventQueue));
50 if (!queue)
51 {
52 geis_error("can not allocate event queue");
53 }
54 return queue;
55}
56
57
58/*
59 * Destroys a Geis Event queue.
60 */
61void
62geis_event_queue_delete(GeisEventQueue queue)
63{
64 GeisEventQueueNode node = queue->eq_pool;
65 while (node)
66 {
67 GeisEventQueueNode eq_next = node->eq_next;
68 free(node);
69 node = eq_next;
70 }
71
72 node = queue->eq_front;
73 while (node)
74 {
75 GeisEventQueueNode eq_next = node->eq_next;
76 geis_event_delete(node->eq_event);
77 free(node);
78 node = eq_next;
79 }
80
81 free(queue);
82}
83
84
85/*
86 * Pushes a new event onto the back of the event queue.
87 */
88GeisStatus
89geis_event_queue_enqueue(GeisEventQueue queue, GeisEvent event)
90{
91 GeisStatus status = GEIS_STATUS_UNKNOWN_ERROR;
92 GeisEventQueueNode node;
93
94 if (queue->eq_pool)
95 {
96 node = queue->eq_pool;
97 queue->eq_pool = node->eq_next;
98 }
99 else
100 {
101 node = calloc(1, sizeof(struct _GeisEventQueueNode));
102 if (!node)
103 {
104 geis_error("can not allocate event queue node");
105 goto error_exit;
106 }
107 }
108
109 node->eq_event = event;
110 if (!queue->eq_front)
111 {
112 queue->eq_front = node;
113 }
114 if (queue->eq_back)
115 {
116 queue->eq_back->eq_next = node;
117 }
118 queue->eq_back = node;
119 status = GEIS_STATUS_SUCCESS;
120
121error_exit:
122 return status;
123}
124
125
126/*
127 * Indicates if the event queue is empty.
128 */
129GeisBoolean
130geis_event_queue_is_empty(GeisEventQueue queue)
131{
132 return queue->eq_front == NULL;
133}
134
135
136/*
137 * Pops the event off the front of the event queue.
138 */
139GeisEvent
140geis_event_queue_dequeue(GeisEventQueue queue)
141{
142 GeisEvent event = NULL;
143 if (queue->eq_front)
144 {
145 event = queue->eq_front->eq_event;
146
147 GeisEventQueueNode node = queue->eq_front;
148 queue->eq_front = node->eq_next;
149 node->eq_next = queue->eq_pool;
150 queue->eq_pool = node;
151 }
152 return event;
153}
154
0155
=== added file 'libutouch-geis/geis_event_queue.h'
--- libutouch-geis/geis_event_queue.h 1970-01-01 00:00:00 +0000
+++ libutouch-geis/geis_event_queue.h 2010-12-09 23:44:08 +0000
@@ -0,0 +1,74 @@
1/**
2 * @file geis_event_queue.h
3 * @brief internal uTouch Geis event queue public 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_EVENT_QUEUE_H_
22#define GEIS_EVENT_QUEUE_H_
23
24#include <geis/geis.h>
25
26
27/**
28 * A container for event_queues.
29 */
30typedef struct _GeisEventQueue *GeisEventQueue;
31
32
33/**
34 * Creates a new Geis Event queue.
35 */
36GeisEventQueue geis_event_queue_new();
37
38/**
39 * Destroys a Geis Event queue.
40 *
41 * @param[in] queue The event queue.
42 */
43void geis_event_queue_delete(GeisEventQueue queue);
44
45/**
46 * Pushes a new event onto the back of the event queue.
47 *
48 * @param[in] queue The event queue.
49 *
50 * @retval GEIS_STATUS_SUCCESS Normal successful completion.
51 *
52 * @retval GEIS_STATUS_UNKNOWN_ERROR Something bad happened.
53 */
54GeisStatus geis_event_queue_enqueue(GeisEventQueue queue, GeisEvent event);
55
56/**
57 * Indicates if an event queue is empty.
58 *
59 * @param[in] queue The event queue.
60 *
61 * @returns GEIS_TRUE if the queue contains no events, GEIS_FALSE otherwise.
62 */
63GeisBoolean geis_event_queue_is_empty(GeisEventQueue queue);
64
65/**
66 * Pops the event off the front of the queue.
67 *
68 * @param[in] queue The event queue.
69 *
70 * @returns the next GeisEvent or NULL of the queue is empty.
71 */
72GeisEvent geis_event_queue_dequeue(GeisEventQueue queue);
73
74#endif /* GEIS_EVENT_QUEUE_H_ */
075
=== modified file 'libutouch-geis/geis_private.h'
--- libutouch-geis/geis_private.h 2010-11-29 19:22:34 +0000
+++ libutouch-geis/geis_private.h 2010-12-09 23:44:08 +0000
@@ -28,14 +28,27 @@
2828
2929
30/**30/**
31 * Gets the error stack drom the geis object.31 * Gets the error stack from the geis object.
32 *
33 * @param[in] geis The API instance.
32 */34 */
33GeisErrorStack *geis_error_stack(Geis geis);35GeisErrorStack *geis_error_stack(Geis geis);
3436
35/**37/**
36 * Gets the subscription container from the geis object.38 * Gets the subscription container from the geis object.
39 *
40 * @param[in] geis The API instance.
37 */41 */
38GeisSubBag geis_subscription_bag(Geis geis);42GeisSubBag geis_subscription_bag(Geis geis);
3943
4044
45/**
46 * Posts a new event through the API.
47 *
48 * @param[in] geis The API instance.
49 * @param[in] event The GEIS event.
50 */
51void geis_post_event(Geis geis, GeisEvent event);
52
53
41#endif /* GEIS_PRIVATE_H_ */54#endif /* GEIS_PRIVATE_H_ */
4255
=== modified file 'libutouch-geis/libutouch-geis.ver'
--- libutouch-geis/libutouch-geis.ver 2010-11-29 02:16:02 +0000
+++ libutouch-geis/libutouch-geis.ver 2010-12-09 23:44:08 +0000
@@ -20,11 +20,14 @@
20 geis_attr_value_to_integer;20 geis_attr_value_to_integer;
21 geis_attr_value_to_string;21 geis_attr_value_to_string;
22 geis_delete;22 geis_delete;
23 geis_dispatch_events;
23 geis_error_code;24 geis_error_code;
24 geis_error_count;25 geis_error_count;
25 geis_error_message;26 geis_error_message;
26 geis_get_configuration;27 geis_get_configuration;
27 geis_new;28 geis_new;
29 geis_next_event;
30 geis_register_event_callback;
28 geis_set_configuration;31 geis_set_configuration;
29 geis_subscription_add_filter;32 geis_subscription_add_filter;
30 geis_subscription_delete;33 geis_subscription_delete;
3134
=== modified file 'testsuite/libutouch-geis/Makefile.am'
--- testsuite/libutouch-geis/Makefile.am 2010-12-02 16:54:02 +0000
+++ testsuite/libutouch-geis/Makefile.am 2010-12-09 23:44:08 +0000
@@ -32,8 +32,10 @@
3232
33check_geis2_internals_SOURCES = \33check_geis2_internals_SOURCES = \
34 check_attr.c \34 check_attr.c \
35 check_backend_event_posting.c \
35 check_backend_multiplexor.c \36 check_backend_multiplexor.c \
36 check_error_reporting.c \37 check_error_reporting.c \
38 check_event_queue.c \
37 check_subscription.c \39 check_subscription.c \
38 check_geis2_internals.c40 check_geis2_internals.c
3941
4042
=== modified file 'testsuite/libutouch-geis/check_attr.c'
--- testsuite/libutouch-geis/check_attr.c 2010-11-26 18:22:53 +0000
+++ testsuite/libutouch-geis/check_attr.c 2010-12-09 23:44:08 +0000
@@ -48,6 +48,31 @@
48END_TEST48END_TEST
4949
5050
51/* verify bag get operation (positive results) */
52START_TEST(get_success)
53{
54 GeisAttr dst_attr;
55 GeisAttr src_attr = geis_attr_new("test-attr",
56 GEIS_ATTR_TYPE_STRING,
57 (void*)test_attr_string);
58 geis_attr_bag_insert(g_attr_bag, src_attr);
59 dst_attr = geis_attr_bag_attr(g_attr_bag, 0);
60 fail_if(dst_attr == NULL, "expected instance not found");
61 fail_unless(0 == strcmp(geis_attr_value_to_string(dst_attr), test_attr_string),
62 "unexpected attribute value returned");
63}
64END_TEST
65
66
67/* verify bag get operation (negative results) */
68START_TEST(get_fail)
69{
70 GeisAttr attr = geis_attr_bag_attr(g_attr_bag, 5);
71 fail_unless(attr == NULL, "unexpected instance indexed");
72}
73END_TEST
74
75
51/* verify bag find operation (positive results) */76/* verify bag find operation (positive results) */
52START_TEST(find_success)77START_TEST(find_success)
53{78{
@@ -86,6 +111,8 @@
86 TCase *usage = tcase_create("attr-bag-usage");111 TCase *usage = tcase_create("attr-bag-usage");
87 tcase_add_checked_fixture(usage, construct_bag, destroy_bag);112 tcase_add_checked_fixture(usage, construct_bag, destroy_bag);
88 tcase_add_test(usage, insertion);113 tcase_add_test(usage, insertion);
114 tcase_add_test(usage, get_success);
115 tcase_add_test(usage, get_fail);
89 tcase_add_test(usage, find_success);116 tcase_add_test(usage, find_success);
90 tcase_add_test(usage, find_fail);117 tcase_add_test(usage, find_fail);
91 suite_add_tcase(s, usage);118 suite_add_tcase(s, usage);
92119
=== added file 'testsuite/libutouch-geis/check_backend_event_posting.c'
--- testsuite/libutouch-geis/check_backend_event_posting.c 1970-01-01 00:00:00 +0000
+++ testsuite/libutouch-geis/check_backend_event_posting.c 2010-12-09 23:44:08 +0000
@@ -0,0 +1,70 @@
1/**
2 * internal unit test for the back end event posting interface
3 */
4#include <check.h>
5
6#include "geis/geis.h"
7#include "libutouch-geis/geis_event.h"
8#include "libutouch-geis/geis_private.h"
9
10/* fixtures */
11Geis g_geis;
12
13static void
14construct_geis()
15{
16 g_geis = geis_new(GEIS_INIT_UTOUCH_MOCK_ENGINE, NULL);
17}
18
19static void
20destroy_geis()
21{
22 geis_delete(g_geis);
23}
24
25START_TEST(backend_post)
26{
27 GeisStatus status;
28 GeisEvent event_in = geis_event_new(GEIS_EVENT_TYPE_GESTURE_END);
29 GeisEvent event_out;
30
31 geis_post_event(g_geis, event_in);
32 status = geis_dispatch_events(g_geis);
33 fail_unless(status == GEIS_STATUS_SUCCESS,
34 "unexpected status from geis_dispatch_events");
35 status = geis_next_event(g_geis, &event_out);
36 fail_unless(status == GEIS_STATUS_SUCCESS,
37 "unexpected status from geis_next_event");
38 fail_unless(geis_event_type(event_in) == geis_event_type(event_out),
39 "event in and event out types do not match");
40
41 geis_post_event(g_geis, event_in);
42 geis_post_event(g_geis, event_in);
43 status = geis_dispatch_events(g_geis);
44 fail_unless(status == GEIS_STATUS_SUCCESS,
45 "unexpected status from geis_dispatch_events");
46 status = geis_next_event(g_geis, &event_out);
47 fail_unless(status == GEIS_STATUS_CONTINUE,
48 "expected CONTINUE status from geis_next_event");
49 status = geis_next_event(g_geis, &event_out);
50 fail_unless(status == GEIS_STATUS_SUCCESS,
51 "expected SUCCESS status from geis_next_event");
52
53 geis_event_delete(event_in);
54}
55END_TEST
56
57/* boilerplate */
58Suite *
59make_backend_event_posting_suite()
60{
61 Suite *s = suite_create("utouch-geis2-backend-event-posting");
62
63 TCase *usage = tcase_create("backend-event-posting-usage");
64 tcase_add_checked_fixture(usage, construct_geis, destroy_geis);
65 tcase_add_test(usage, backend_post);
66 suite_add_tcase(s, usage);
67
68 return s;
69}
70
071
=== added file 'testsuite/libutouch-geis/check_event_queue.c'
--- testsuite/libutouch-geis/check_event_queue.c 1970-01-01 00:00:00 +0000
+++ testsuite/libutouch-geis/check_event_queue.c 2010-12-09 23:44:08 +0000
@@ -0,0 +1,88 @@
1/**
2 * unit tests for the geis_event_queue module
3 */
4#include <check.h>
5
6#include "geis/geis.h"
7#include "libutouch-geis/geis_event.h"
8#include "libutouch-geis/geis_event_queue.h"
9
10
11/* fixtures */
12static GeisEventQueue g_queue;
13
14/* fixture setup */
15static void
16construct_event_queue()
17{
18 g_queue = geis_event_queue_new();
19}
20
21/* fixture teardown */
22static void
23destroy_event_queue()
24{
25 geis_event_queue_delete(g_queue);
26}
27
28
29/* verify event queue construction/destruction */
30START_TEST(construction)
31{
32 construct_event_queue();
33 fail_unless(g_queue != NULL, "failed to create the event queue");
34 fail_unless(geis_event_queue_is_empty(g_queue), "queue is not empty");
35 destroy_event_queue();
36}
37END_TEST
38
39
40/* verify event_queue insertion */
41START_TEST(enqueue_dequeue)
42{
43 GeisStatus status = GEIS_STATUS_UNKNOWN_ERROR;
44 GeisEvent event1 = geis_event_new(GEIS_EVENT_TYPE_GESTURE_BEGIN);
45 GeisEvent event2 = geis_event_new(GEIS_EVENT_TYPE_GESTURE_END);
46 GeisEvent ev;
47
48 ev = geis_event_queue_dequeue(g_queue);
49 fail_unless(ev == NULL, "unexpected failure at pop(0)");
50
51 status = geis_event_queue_enqueue(g_queue, event1);
52 fail_unless(status == GEIS_STATUS_SUCCESS, "failure at enqueue(event1)");
53 fail_unless(!geis_event_queue_is_empty(g_queue), "queue is unexpectedly empty");
54 status = geis_event_queue_enqueue(g_queue, event2);
55 fail_unless(status == GEIS_STATUS_SUCCESS, "failure at enqueue(event2)");
56
57 ev = geis_event_queue_dequeue(g_queue);
58 fail_unless(ev != NULL, "failure at dequeue(1)");
59 fail_unless(ev == event1, "unexpected value returned from front(1)");
60
61 ev = geis_event_queue_dequeue(g_queue);
62 fail_unless(ev != NULL, "failure at dequeue(2)");
63 fail_unless(ev == event2, "unexpected value returned from front(2)");
64
65 ev = geis_event_queue_dequeue(g_queue);
66 fail_unless(ev == NULL, "failure at dequeue(3)");
67 fail_unless(geis_event_queue_is_empty(g_queue), "queue is not empty");
68}
69END_TEST
70
71/* boilerplate */
72Suite *
73make_event_queue_suite()
74{
75 Suite *s = suite_create("utouch-geis2-event-queue");
76
77 TCase *create = tcase_create("event-queue-creation");
78 tcase_add_test(create, construction);
79 suite_add_tcase(s, create);
80
81 TCase *usage = tcase_create("event-queue-operation");
82 tcase_add_checked_fixture(usage, construct_event_queue, destroy_event_queue);
83 tcase_add_test(usage, enqueue_dequeue);
84 suite_add_tcase(s, usage);
85
86 return s;
87}
88
089
=== modified file 'testsuite/libutouch-geis/check_geis2_internals.c'
--- testsuite/libutouch-geis/check_geis2_internals.c 2010-12-02 16:54:02 +0000
+++ testsuite/libutouch-geis/check_geis2_internals.c 2010-12-09 23:44:08 +0000
@@ -3,10 +3,14 @@
3 */3 */
4#include <check.h>4#include <check.h>
55
6#define LOGFILE_PREFIX "geis2_internals"
7
8extern Suite *make_attr_suite();
9extern Suite *make_backend_event_posting_suite();
10extern Suite *make_backend_multiplexor_suite();
6extern Suite *make_error_reporting_suite();11extern Suite *make_error_reporting_suite();
7extern Suite *make_attr_suite();12extern Suite *make_event_queue_suite();
8extern Suite *make_subscription_suite();13extern Suite *make_subscription_suite();
9extern Suite *make_backend_multiplexor_suite();
1014
1115
12int16int
@@ -19,10 +23,13 @@
19 SRunner *sr = srunner_create(s);23 SRunner *sr = srunner_create(s);
20 srunner_add_suite(sr, make_error_reporting_suite());24 srunner_add_suite(sr, make_error_reporting_suite());
21 srunner_add_suite(sr, make_attr_suite());25 srunner_add_suite(sr, make_attr_suite());
26 srunner_add_suite(sr, make_event_queue_suite());
27 srunner_add_suite(sr, make_backend_multiplexor_suite());
28 srunner_add_suite(sr, make_backend_event_posting_suite());
22 srunner_add_suite(sr, make_subscription_suite());29 srunner_add_suite(sr, make_subscription_suite());
23 srunner_add_suite(sr, make_backend_multiplexor_suite());
2430
25 srunner_set_log(sr, "geis2_internals.log");31 srunner_set_log(sr, LOGFILE_PREFIX".log");
32 srunner_set_xml(sr, LOGFILE_PREFIX".xml");
26 srunner_run_all(sr, CK_NORMAL);33 srunner_run_all(sr, CK_NORMAL);
27 num_failed = srunner_ntests_failed(sr);34 num_failed = srunner_ntests_failed(sr);
2835

Subscribers

People subscribed via source and target branches

to all changes: