Merge lp:~bregma/geis/geis-windows into lp:geis

Proposed by Stephen M. Webb
Status: Superseded
Proposed branch: lp:~bregma/geis/geis-windows
Merge into: lp:geis
Prerequisite: lp:~bregma/geis/geis-diagnostics
Diff against target: 1403 lines (+765/-201)
13 files modified
ChangeLog (+45/-0)
configure.ac (+5/-0)
doc/geistest.1 (+20/-4)
geis/geis.h (+1/-1)
libutouch-geis-xcb/Makefile.am (+10/-5)
libutouch-geis-xcb/geis.c (+20/-5)
libutouch-geis-xcb/geis_instance.c (+36/-22)
libutouch-geis-xcb/geis_instance.h (+14/-11)
libutouch-geis-xcb/geis_instance_table.c (+127/-0)
libutouch-geis-xcb/geis_instance_table.h (+41/-0)
libutouch-geis-xcb/geis_xcb.c (+201/-90)
libutouch-geis-xcb/geis_xcb.h (+23/-18)
testsuite/geistest/geistest.c (+222/-45)
To merge this branch: bzr merge lp:~bregma/geis/geis-windows
Reviewer Review Type Date Requested Status
Chase Douglas (community) Needs Fixing
Review via email: mp+34126@code.launchpad.net

This proposal has been superseded by a proposal from 2010-08-30.

Commit message

Fixed gesture subscriptions on multiple windows simultaneously.

Description of the change

Fixed the implementation to allow for gesture subscriptions on multiple windows simultaneously.

To post a comment you must log in.
lp:~bregma/geis/geis-windows updated
77. By Stephen M. Webb

removed debug code

78. By Stephen M. Webb

Removed input device enumeration handling until later.

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

1. There's a typo in the geistest man page in line 97 of the big merge diff below. Another typo in line 107.

2. "#if 0" and "#ifdef REVERT_XCB_CHANGES" code should be removed:
  a. geis_instance_input_devices should be removed if it doesn't work.
  b. xcb connection stuff should be removed since we need Xlib for XI2. That won't change anytime soon.
  c. geis_xcb_input_devices should either be removed, or the printf's should be changed to the new diagnostics framework

3. Why does _GeisXcb include a win_info? On cursory glance I would think it should just contain the xcb connection information. As a side note, having GeisWinInfo contain a field called "win_info" makes grepping through the source hard. Perhaps the internal field should be called win_info_impl, or something along those lines?

I got through to line 309 of the merge diff below, but I have to stop now to leave :(. I will pick up my review later.

review: Needs Fixing

Unmerged revisions

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'ChangeLog'
2--- ChangeLog 2010-08-30 20:28:40 +0000
3+++ ChangeLog 2010-08-30 20:28:40 +0000
4@@ -1,5 +1,50 @@
5 2010-08-30 Stephen M. Webb <stephen.webb@canonical.com>
6
7+ Removed some debug code and fixed pasto.
8+
9+ * libutouch-geis-xcb/geis_instance.c: fixed a pasto
10+ * testsuite/geistest/geistest.c: removed debug code
11+
12+2010-08-30 Stephen M. Webb <stephen.webb@canonical.com>
13+
14+ Fixed so multiple windows will work.
15+
16+ Altered geistest to work with a single window or all windows, had to fix geis
17+ implementation so this was possible.
18+
19+ * libutouch-geis-xcb/geis_instance_table.c: new file
20+ * libutouch-geis-xcb/geis_instance_table.h: new file
21+ * configure.ac: added package checks for x11-xcb and xi
22+ * doc/geistest.1: documented new CLI switches
23+ * geis/geis.h (geis_input_devices): fixed argument type
24+ * libutouch-geis-xcb/Makefile.am (libutouch_geis_la_SOURCES): added new files
25+ (libutouch_geis_la_CFLAGS): aded X11XCB_CFLAGS and XI2_CFLAGS
26+ (libutouch_geis_la_LIBADD): aded X11XCB_LIBS and XI2LIBS_
27+ * libutouch-geis-xcb/geis.c (s_geis_xcb): new static global
28+ (geis_init): used it
29+ * libutouch-geis-xcb/geis_instance.h (_GeisInstance): added window_id
30+ (geis_instance_new): renamed from geis_instance_get
31+ (geis_instance_input_devices): new function
32+ (geis_instance_subscribe): added GeisXcb parameter
33+ (geis_instance_get_window_id): new function
34+ (geis_instance_fd): removed function
35+ (geis_instance_event_dispatch): removed function
36+ * libutouch-geis-xcb/geis_instance.c: implemented new functions
37+ * libutouch-geis-xcb/geis_xcb.h (geis_xcb_new): renamed from geis_xcb_get
38+ (geis_xcb_create_instance): new function
39+ (geis_xcb_input_devices): new function
40+ (geis_xcb_subscribe): added GeisInstance parameter
41+ (geis_xcb_dispatch): changed parameter type to GeisXcb
42+ * libutouch-geis-xcb/geis_xcb.c: Implemeneted new functions
43+ * testsuite/geistest/geistest.c (parse_opts): added -w switch
44+ (subscribe_window): new function
45+ (subscribe_windows_preorder): new function
46+ (subscribe_all_windows): new function
47+ (main): used the new functions
48+
49+
50+2010-08-30 Stephen M. Webb <stephen.webb@canonical.com>
51+
52 Added runtime diagnostic facility.
53
54 * libutouch-geis-xcb/geis_debug.h: replaced with
55
56=== modified file 'configure.ac'
57--- configure.ac 2010-08-25 20:41:17 +0000
58+++ configure.ac 2010-08-30 20:28:40 +0000
59@@ -24,6 +24,11 @@
60 AC_MSG_ERROR([Grail development libraries not found]))
61 PKG_CHECK_MODULES([XCB], [xcb >= 1.6], ,
62 AC_MSG_ERROR([XCB development libraries not found]))
63+PKG_CHECK_MODULES([X11XCB], [x11-xcb >= 1.3.3], ,
64+ AC_MSG_ERROR([X11-XCB development libraries not found]))
65+PKG_CHECK_MODULES([XI2], [xi >= 1.3], ,
66+ AC_MSG_ERROR([XI2 development libraries not found]))
67+
68 # XCB code generation configuration
69 AC_MSG_CHECKING(XCBPROTO_XCBINCLUDEDIR)
70 XCBPROTO_XCBINCLUDEDIR=`$PKG_CONFIG --variable=xcbincludedir xcb-proto`
71
72=== modified file 'doc/geistest.1'
73--- doc/geistest.1 2010-08-16 16:25:17 +0000
74+++ doc/geistest.1 2010-08-30 20:28:40 +0000
75@@ -4,7 +4,10 @@
76 geistest \- test operatoin of the GEIS API
77
78 .SH SYNOPSIS
79-.B geistest windowid
80+.B geistest [
81+.B -w
82+.I windowid
83+.B ]
84 .br
85
86 .SH DESCRIPTION
87@@ -12,8 +15,21 @@
88 .B geistest
89 program. This program is a test driver for verifying the recognition and propagation of gestures through the GEIS API.
90
91-
92-.SH EXAMPLE
93+.SH OPTIONS
94+.IP -w
95+Specifies the
96+.I windowId
97+of a specific windo to associate with gestures.
98+Particularly useful with touchscreens.
99+
100+The
101+.I windowId
102+can be determined using the program
103+.BR xwininfo .
104+
105+.SH ENVIRONMENT
106+.IP GEIS_DEBUG
107+Enables GEIS libraru diagnostic messages on stderr.
108
109 .SH "SEE ALSO"
110-gesturetest(1)
111\ No newline at end of file
112+gesturetest(1)
113
114=== modified file 'geis/geis.h'
115--- geis/geis.h 2010-08-24 17:59:37 +0000
116+++ geis/geis.h 2010-08-30 20:28:40 +0000
117@@ -293,7 +293,7 @@
118 * @retval GEIS_STATUS_SUCCESS normal successful completion
119 */
120 GEIS_API GeisStatus geis_input_devices(GeisInstance geis_instance,
121- GeisInputFuncs func,
122+ GeisInputFuncs *func,
123 void *cookie);
124
125 /* @} */
126
127=== modified file 'libutouch-geis-xcb/Makefile.am'
128--- libutouch-geis-xcb/Makefile.am 2010-08-30 20:28:40 +0000
129+++ libutouch-geis-xcb/Makefile.am 2010-08-30 20:28:40 +0000
130@@ -16,9 +16,10 @@
131
132 libutouch_geis_la_SOURCES = \
133 geis.c \
134- geis_logging.h geis_logging.c \
135- geis_xcb.h geis_xcb.c \
136- geis_instance.h geis_instance.c
137+ geis_logging.h geis_logging.c \
138+ geis_instance.h geis_instance.c \
139+ geis_instance_table.h geis_instance_table.c \
140+ geis_xcb.h geis_xcb.c
141
142 dist_libutouch_geis_la_SOURCES = \
143 xcb_gesture.h xcb_gesture.c
144@@ -29,7 +30,9 @@
145 -DGEIS_BUILDING_DSO=1 \
146 -I$(top_srcdir) \
147 $(GRAIL_CFLAGS) \
148- $(XCB_CFLAGS)
149+ $(X11XCB_CFLAGS) \
150+ $(XCB_CFLAGS) \
151+ $(XI2_CFLAGS)
152
153 libutouch_geis_la_LDFLAGS = \
154 -Wl,-z,defs -Wl,--as-needed \
155@@ -37,7 +40,9 @@
156 -Wl,--version-script=$(version_script)
157
158 libutouch_geis_la_LIBADD = \
159- $(XCB_LIBS)
160+ $(X11XCB_LIBS) \
161+ $(XCB_LIBS) \
162+ $(XI2_LIBS)
163
164 BUILT_SOURCES = $(dist_libutouch_geis_la_SOURCES)
165 CLEANFILES = $(dist_libutouch_geis_la_SOURCES)
166
167=== modified file 'libutouch-geis-xcb/geis.c'
168--- libutouch-geis-xcb/geis.c 2010-08-11 13:54:54 +0000
169+++ libutouch-geis-xcb/geis.c 2010-08-30 20:28:40 +0000
170@@ -20,9 +20,13 @@
171 #include <geis/geis.h>
172
173 #include "geis_instance.h"
174+#include "geis_xcb.h"
175 #include <stdlib.h>
176
177
178+static GeisXcb s_geis_xcb = NULL;
179+
180+
181 /**
182 * @param[in] win_info
183 * @param[out] geis_instance
184@@ -34,13 +38,19 @@
185 geis_init(GeisWinInfo *win_info, GeisInstance *geis_instance)
186 {
187 *geis_instance = NULL;
188+ GeisXcbWinInfo *xcb_win_info = (GeisXcbWinInfo*)win_info->win_info;
189
190 if (win_info->win_type != GEIS_XCB_FULL_WINDOW)
191 {
192 return GEIS_BAD_ARGUMENT;
193 }
194
195- *geis_instance = geis_instance_get((GeisXcbWinInfo*)win_info->win_info);
196+ if (!s_geis_xcb)
197+ {
198+ s_geis_xcb = geis_xcb_new(xcb_win_info);
199+ }
200+
201+ *geis_instance = geis_xcb_create_instance(s_geis_xcb, xcb_win_info->window_id);
202 return GEIS_STATUS_SUCCESS;
203 }
204
205@@ -109,7 +119,7 @@
206 switch (configuration_item)
207 {
208 case GEIS_CONFIG_UNIX_FD:
209- *(int *)value = geis_instance_fd(geis_instance);
210+ *(int *)value = geis_xcb_fd(s_geis_xcb);
211 status = GEIS_STATUS_SUCCESS;
212 break;
213 }
214@@ -147,7 +157,7 @@
215 return GEIS_BAD_ARGUMENT;
216 }
217
218- geis_instance_event_dispatch(geis_instance);
219+ geis_xcb_dispatch(s_geis_xcb);
220 return GEIS_STATUS_SUCCESS;
221 }
222
223@@ -159,7 +169,7 @@
224 */
225 GeisStatus
226 geis_input_devices(GeisInstance geis_instance,
227- GeisInputFuncs funcs,
228+ GeisInputFuncs *funcs,
229 void *cookie)
230 {
231 if (!geis_instance_is_valid(geis_instance))
232@@ -167,7 +177,11 @@
233 return GEIS_BAD_ARGUMENT;
234 }
235
236- return GEIS_UNKNOWN_ERROR;
237+#if 0
238+ return geis_instance_input_devices(geis_instance, funcs, cookie);
239+#else
240+ return geis_xcb_input_devices(s_geis_xcb);
241+#endif
242 }
243
244
245@@ -191,6 +205,7 @@
246 }
247
248 return geis_instance_subscribe(geis_instance,
249+ s_geis_xcb,
250 input_list,
251 gesture_list,
252 funcs,
253
254=== modified file 'libutouch-geis-xcb/geis_instance.c'
255--- libutouch-geis-xcb/geis_instance.c 2010-08-27 17:05:55 +0000
256+++ libutouch-geis-xcb/geis_instance.c 2010-08-30 20:28:40 +0000
257@@ -19,17 +19,27 @@
258 */
259 #include "geis_instance.h"
260
261+#include "geis_logging.h"
262 #include <stdlib.h>
263
264
265+/**
266+ * Creates a new GeisInstance for an X11 windowId.
267+ *
268+ * @param[in] An X11 windowId.
269+ *
270+ * @returns a new GeisInstance or NULL on failure.
271+ */
272 GeisInstance
273-geis_instance_get(GeisXcbWinInfo* win_info)
274+geis_instance_new(uint32_t window_id)
275 {
276 GeisInstance instance = calloc(1, sizeof(struct _GeisInstance));
277- if (instance)
278+ if (!instance)
279 {
280- instance->xcb = geis_xcb_get(win_info);
281+ geis_error("allocating GeisInstance");
282+ return NULL;
283 }
284+ instance->window_id = window_id;
285 return instance;
286 }
287
288@@ -44,12 +54,26 @@
289 int
290 geis_instance_is_valid(GeisInstance instance)
291 {
292- return (instance != 0 && instance->xcb != 0);
293-}
294+ return (instance != 0 && instance->window_id != 0);
295+}
296+
297+
298+#ifdef REVERT_XCB_CHANGES
299+GeisStatus
300+geis_instance_input_devices(GeisInstance instance,
301+ GeisInputFuncs *funcs,
302+ void *cookie)
303+{
304+ instance->input_funcs = funcs;
305+ instance->input_cookie = cookie;
306+ return geis_xcb_input_devices(instance);
307+}
308+#endif
309
310
311 GeisStatus
312 geis_instance_subscribe(GeisInstance instance,
313+ GeisXcb xcb,
314 GeisInputDeviceId *input_list,
315 const char* *gesture_list,
316 GeisGestureFuncs *funcs,
317@@ -60,14 +84,14 @@
318 instance->gesture_cookie = cookie;
319 if (input_list == GEIS_ALL_INPUT_DEVICES)
320 {
321- result = geis_xcb_subscribe(instance, 0, gesture_list);
322+ result = geis_xcb_subscribe(xcb, instance, 0, gesture_list);
323 }
324 else
325 {
326 GeisInputDeviceId *device_id = input_list;
327 for (; *device_id; ++device_id)
328 {
329- GeisStatus a_result = geis_xcb_subscribe(instance,
330+ GeisStatus a_result = geis_xcb_subscribe(xcb, instance,
331 (uint16_t)*device_id,
332 gesture_list);
333 if (a_result == GEIS_STATUS_SUCCESS)
334@@ -80,25 +104,15 @@
335 }
336
337
338-int
339-geis_instance_fd(GeisInstance instance)
340-{
341- if (instance == NULL)
342- return -1;
343-
344- return geis_xcb_fd(instance->xcb);
345-}
346-
347-
348-void
349-geis_instance_event_dispatch(GeisInstance instance)
350-{
351- geis_xcb_dispatch(instance);
352+uint32_t
353+geis_instance_get_window_id(GeisInstance instance)
354+{
355+ return instance->window_id;
356 }
357
358
359 void
360 geis_instance_free(GeisInstance instance)
361 {
362- geis_xcb_free(instance->xcb);
363+ free(instance);
364 }
365
366=== modified file 'libutouch-geis-xcb/geis_instance.h'
367--- libutouch-geis-xcb/geis_instance.h 2010-08-22 16:53:46 +0000
368+++ libutouch-geis-xcb/geis_instance.h 2010-08-30 20:28:40 +0000
369@@ -26,31 +26,34 @@
370
371 struct _GeisInstance
372 {
373- GeisXcb *xcb;
374- GeisInputCallback input_callback;
375- void *input_cookie;
376- GeisGestureFuncs *gesture_funcs;
377- void *gesture_cookie;
378+ uint32_t window_id;
379+ GeisInputFuncs *input_funcs;
380+ void *input_cookie;
381+ GeisGestureFuncs *gesture_funcs;
382+ void *gesture_cookie;
383 };
384
385 /** @brief Constructs a GeisInstance. */
386-GeisInstance geis_instance_get(GeisXcbWinInfo* win_info);
387+GeisInstance geis_instance_new(uint32_t win_info);
388+
389
390 /** @brief Indicates if the GeisInstance is valid. */
391 int geis_instance_is_valid(GeisInstance instance);
392
393+/** @brief Subscribe to input devices. */
394+GeisStatus geis_instance_input_devices(GeisInstance instance,
395+ GeisInputFuncs *funcs,
396+ void *cookie);
397+
398 /** @brief Subscribe to gestures. */
399 GeisStatus geis_instance_subscribe(GeisInstance instance,
400+ GeisXcb xcb,
401 GeisInputDeviceId *input_list,
402 const char* *gesture_list,
403 GeisGestureFuncs *funcs,
404 void *cookie);
405
406-/** @brief Gets the event file descriptor. */
407-int geis_instance_fd(GeisInstance instance);
408-
409-/** @brief Dispatches events. */
410-void geis_instance_event_dispatch(GeisInstance instance);
411+uint32_t geis_instance_get_window_id(GeisInstance instance);
412
413 /** @brief Tears down the GeisInstance. */
414 void geis_instance_free(GeisInstance instance);
415
416=== added file 'libutouch-geis-xcb/geis_instance_table.c'
417--- libutouch-geis-xcb/geis_instance_table.c 1970-01-01 00:00:00 +0000
418+++ libutouch-geis-xcb/geis_instance_table.c 2010-08-30 20:28:40 +0000
419@@ -0,0 +1,127 @@
420+/**
421+ * geis_instance_table.h
422+ *
423+ * Copyright 2010 Canonical Ltd.
424+ *
425+ * This library is free software; you can redistribute it and/or modify it under
426+ * the terms of the GNU Lesser General Public License as published by the Free
427+ * Software Foundation; either version 3 of the License, or (at your option) any
428+ * later version.
429+ *
430+ * This library is distributed in the hope that it will be useful, but WITHOUT
431+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
432+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
433+ * more details.
434+ *
435+ * You should have received a copy of the GNU General Public License along with
436+ * this program; if not, write to the Free Software Foundation, Inc., 51
437+ * Franklin St, Fifth Floor, Boston, MA 02110-1301 US
438+ */
439+#include "geis_instance_table.h"
440+
441+#include "geis_instance.h"
442+#include <stdlib.h>
443+
444+#define GROWTH_FACTOR 2
445+
446+
447+typedef struct _GeisInstanceTableEntry
448+{
449+ uint32_t id;
450+ GeisInstance type;
451+} *GeisInstanceTableEntry;
452+
453+struct _GeisInstanceTable
454+{
455+ size_t capacity;
456+ size_t size;
457+ GeisInstanceTableEntry data;
458+};
459+
460+
461+GeisInstanceTable
462+geis_instance_table_new(int size_hint)
463+{
464+ GeisInstanceTable table = malloc(sizeof(struct _GeisInstanceTable));
465+ if (!table)
466+ {
467+ /* TODO: report error */
468+ }
469+
470+ table->capacity = size_hint;
471+ table->size = 0;
472+ table->data = calloc(table->capacity,
473+ size_hint * sizeof(struct _GeisInstanceTableEntry));
474+ if (!table->data)
475+ {
476+ /* TODO: report error */
477+ }
478+
479+ return table;
480+}
481+
482+
483+/**
484+ * Adds (or replaces) a gesture type in the table.
485+ */
486+void
487+geis_instance_table_add(GeisInstanceTable table,
488+ GeisInstance instance)
489+{
490+ size_t i;
491+ uint32_t window_id = geis_instance_get_window_id(instance);
492+
493+ /* If the ID is already present, just replace the gesture type */
494+ for (i = 0; i < table->size; ++i)
495+ {
496+ if (table->data[i].id == window_id)
497+ {
498+ table->data[i].type = instance;
499+ return;
500+ }
501+ }
502+
503+ /* If there is no space to insert, grow the table. */
504+ if (table->size >= table->capacity)
505+ {
506+ size_t new_capacity = table->capacity * GROWTH_FACTOR;
507+ GeisInstanceTableEntry new_data = realloc(table->data,
508+ new_capacity * sizeof(struct _GeisInstanceTableEntry));
509+ if (!new_data)
510+ {
511+ /* TODO: report error */
512+ }
513+
514+ table->capacity = new_capacity;
515+ table->data = new_data;
516+ }
517+
518+ table->data[table->size].id = window_id;
519+ table->data[table->size].type = instance;
520+ ++table->size;
521+}
522+
523+
524+GeisInstance
525+geis_instance_table_get(GeisInstanceTable table,
526+ uint32_t window_id)
527+{
528+ size_t i;
529+ for (i = 0; i < table->size; ++i)
530+ {
531+ if (table->data[i].id == window_id)
532+ {
533+ return table->data[i].type;
534+ }
535+ }
536+ return NULL;
537+}
538+
539+
540+void
541+geis_instance_table_free(GeisInstanceTable table)
542+{
543+ free(table->data);
544+ free(table);
545+}
546+
547
548=== added file 'libutouch-geis-xcb/geis_instance_table.h'
549--- libutouch-geis-xcb/geis_instance_table.h 1970-01-01 00:00:00 +0000
550+++ libutouch-geis-xcb/geis_instance_table.h 2010-08-30 20:28:40 +0000
551@@ -0,0 +1,41 @@
552+/**
553+ * geis_instance_table.h
554+ *
555+ * Copyright 2010 Canonical Ltd.
556+ *
557+ * This library is free software; you can redistribute it and/or modify it under
558+ * the terms of the GNU Lesser General Public License as published by the Free
559+ * Software Foundation; either version 3 of the License, or (at your option) any
560+ * later version.
561+ *
562+ * This library is distributed in the hope that it will be useful, but WITHOUT
563+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
564+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
565+ * more details.
566+ *
567+ * You should have received a copy of the GNU General Public License along with
568+ * this program; if not, write to the Free Software Foundation, Inc., 51
569+ * Franklin St, Fifth Floor, Boston, MA 02110-1301 US
570+ */
571+#ifndef GEIS_INSTANCE_TABLE_H_
572+#define GEIS_INSTANCE_TABLE_H_
573+
574+#include "geis_config.h"
575+#include <geis/geis.h>
576+
577+/**
578+ * A map from XCB window IDs to geisInstances.
579+ */
580+typedef struct _GeisInstanceTable *GeisInstanceTable;
581+
582+GeisInstanceTable geis_instance_table_new(int size_hint);
583+
584+void geis_instance_table_add(GeisInstanceTable type_table,
585+ GeisInstance instance);
586+
587+GeisInstance geis_instance_table_get(GeisInstanceTable type_table,
588+ uint32_t window_id);
589+
590+void geis_instance_table_free(GeisInstanceTable type_table);
591+
592+#endif /* GEIS_INSTANCE_TABLE_H_ */
593
594=== modified file 'libutouch-geis-xcb/geis_xcb.c'
595--- libutouch-geis-xcb/geis_xcb.c 2010-08-30 20:28:40 +0000
596+++ libutouch-geis-xcb/geis_xcb.c 2010-08-30 20:28:40 +0000
597@@ -20,27 +20,25 @@
598 #include "geis_xcb.h"
599
600 #include "geis_instance.h"
601+#include "geis_instance_table.h"
602 #include "geis_logging.h"
603 #include <grail.h>
604 #include <grail-types.h>
605 #include <stdlib.h>
606 #include <string.h>
607+#include <X11/extensions/XInput2.h>
608 #include <X11/X.h>
609+#include <X11/Xlib-xcb.h>
610 #include "xcb_gesture.h"
611 #include <xcb/xcb.h>
612
613 struct _GeisXcb
614 {
615 GeisXcbWinInfo *win_info;
616+ Display *display;
617 xcb_connection_t *connection;
618 int fd;
619-};
620-
621-static GeisXcb s_geis_xcb =
622-{
623- NULL,
624- NULL,
625- -1
626+ GeisInstanceTable instance_table;
627 };
628
629 typedef struct _GrailAttrMap
630@@ -625,79 +623,136 @@
631 /**
632 * @param[in] win_info
633 */
634-GeisXcb *
635-geis_xcb_get(GeisXcbWinInfo *win_info)
636-{
637- if (!s_geis_xcb.connection)
638- {
639- s_geis_xcb.win_info = win_info;
640- s_geis_xcb.connection = xcb_connect(win_info->display_name,
641- win_info->screenp);
642- if (!s_geis_xcb.connection)
643- {
644- geis_error("error connecting to X server.");
645- return NULL;
646- }
647-
648-#if 0
649- {
650- char buffer[128];
651- xcb_input_get_extension_version_cookie_t input_version_cookie;
652-
653- input_version_cookie = xcb_input_get_extension_version(s_geis_xcb.connection,
654- 127,
655- buffer);
656- }
657-#endif
658-
659- {
660- xcb_generic_error_t *error;
661- xcb_gesture_query_version_cookie_t version_cookie;
662- xcb_gesture_query_version_reply_t *version_reply = NULL;
663-
664- version_cookie = xcb_gesture_query_version(s_geis_xcb.connection,
665- XCB_GESTURE_MAJOR_VERSION,
666- XCB_GESTURE_MINOR_VERSION);
667- version_reply = xcb_gesture_query_version_reply(s_geis_xcb.connection,
668- version_cookie,
669- &error);
670- if (!version_reply)
671- {
672- geis_error("failed to receive gesture version reply\n");
673- return NULL;
674- }
675-
676- if (version_reply->major_version != XCB_GESTURE_MAJOR_VERSION
677- && version_reply->minor_version != XCB_GESTURE_MINOR_VERSION)
678- {
679- geis_error("server supports unrecognized version: %d.%d\n",
680- version_reply->major_version, version_reply->minor_version);
681- free(version_reply);
682- return NULL;
683- }
684-
685- free(version_reply);
686- }
687-
688-
689- s_geis_xcb.fd = xcb_get_file_descriptor(s_geis_xcb.connection);
690- }
691-
692- return &s_geis_xcb;
693-}
694-
695-
696+GeisXcb
697+geis_xcb_new(GeisXcbWinInfo *win_info)
698+{
699+ GeisXcb xcb = calloc(1, sizeof(struct _GeisXcb));
700+ if (!xcb)
701+ {
702+ /** @todo: report error */
703+ }
704+
705+ xcb->win_info = win_info;
706+#if 0
707+ xcb->connection = xcb_connect(win_info->display_name,
708+ win_info->screenp);
709+#else
710+ xcb->display = XOpenDisplay(win_info->display_name);
711+ if (!xcb->display)
712+ {
713+ geis_error("error opening X server.");
714+ return NULL;
715+ }
716+
717+ xcb->connection = XGetXCBConnection(xcb->display);
718+#endif
719+ if (!xcb->connection)
720+ {
721+ geis_error("error connecting to X server.");
722+ return NULL;
723+ }
724+
725+ {
726+#if 0
727+ char buffer[128];
728+ xcb_input_get_extension_version_cookie_t input_version_cookie;
729+
730+ input_version_cookie = xcb_input_get_extension_version(xcb->connection,
731+ 127,
732+ buffer);
733+#else
734+ /* XInput Extension available? */
735+ int opcode, event, error;
736+ if (!XQueryExtension(xcb->display, "XInputExtension",
737+ &opcode, &event, &error))
738+ {
739+ geis_error("X Input extension not available.\n");
740+ return NULL;
741+ }
742+
743+ /* Which version of XI2? We support 2.0 */
744+ int major = 2, minor = 0;
745+ if (XIQueryVersion(xcb->display, &major, &minor) == BadRequest)
746+ {
747+ geis_error("XI2 not available. Server supports %d.%d\n", major, minor);
748+ return NULL;
749+ }
750+#endif
751+ }
752+
753+ {
754+ xcb_gesture_query_version_cookie_t version_cookie;
755+ xcb_gesture_query_version_reply_t *version_reply = NULL;
756+ xcb_generic_error_t *error = NULL;
757+
758+ version_cookie = xcb_gesture_query_version(xcb->connection,
759+ XCB_GESTURE_MAJOR_VERSION,
760+ XCB_GESTURE_MINOR_VERSION);
761+ version_reply = xcb_gesture_query_version_reply(xcb->connection,
762+ version_cookie,
763+ &error);
764+ if (!version_reply)
765+ {
766+ geis_error("failed to receive gesture version reply\n");
767+ return NULL;
768+ }
769+
770+ if (version_reply->major_version != XCB_GESTURE_MAJOR_VERSION
771+ && version_reply->minor_version != XCB_GESTURE_MINOR_VERSION)
772+ {
773+ geis_error("server supports unrecognized version: %d.%d\n",
774+ version_reply->major_version, version_reply->minor_version);
775+ return NULL;
776+ }
777+
778+ free(version_reply);
779+ }
780+
781+
782+ xcb->fd = xcb_get_file_descriptor(xcb->connection);
783+ xcb->instance_table = geis_instance_table_new(1);
784+
785+ return xcb;
786+}
787+
788+
789+/**
790+ * Create a new GeisInstance for a windowId.
791+ *
792+ * @param[in] An X11 windowId.
793+ */
794+GeisInstance
795+geis_xcb_create_instance(GeisXcb xcb, uint32_t window_id)
796+{
797+ GeisInstance instance = geis_instance_new(window_id);
798+ if (!instance)
799+ {
800+ geis_error("failure to create GeisInstance");
801+ }
802+ else
803+ {
804+ geis_instance_table_add(xcb->instance_table, instance);
805+ }
806+ return instance;
807+}
808+
809+
810+/**
811+ * Gets the file description on which events will appear.
812+ */
813 int
814-geis_xcb_fd(GeisXcb *xcb)
815+geis_xcb_fd(GeisXcb xcb)
816 {
817 return xcb->fd;
818 }
819
820
821+/**
822+ * Dispatches events.
823+ */
824 void
825-geis_xcb_dispatch(GeisInstance instance)
826+geis_xcb_dispatch(GeisXcb xcb)
827 {
828- GeisXcb *xcb = instance->xcb;
829 if (xcb->connection)
830 {
831 const xcb_query_extension_reply_t *extension_info;
832@@ -708,7 +763,7 @@
833 {
834 xcb_gesture_notify_event_t *gesture_event = NULL;
835 if (event->response_type != GenericEvent) {
836- geis_warning("warning: Received non-generic event type: %d\n",
837+ geis_warning("received non-generic event type: %d\n",
838 event->response_type);
839 continue;
840 }
841@@ -716,19 +771,29 @@
842 gesture_event = (xcb_gesture_notify_event_t*)event;
843 if (gesture_event->extension != extension_info->major_opcode)
844 {
845- geis_warning("warning: Received non-gesture extension event: %d\n",
846+ geis_warning("received non-gesture extension event: %d\n",
847 gesture_event->extension);
848 continue;
849 }
850
851 if (gesture_event->event_type != XCB_GESTURE_NOTIFY)
852 {
853- geis_warning("warning: Received unrecognized gesture event type: %d\n",
854+ geis_warning("received unrecognized gesture event type: %d\n",
855 gesture_event->event_type);
856 continue;
857 }
858
859- geis_xcb_dispatch_gesture(instance, gesture_event);
860+ GeisInstance instance = geis_instance_table_get(xcb->instance_table,
861+ gesture_event->event);
862+ if (!instance)
863+ {
864+ geis_error("no instance found for window_id 0x%08.8x\n",
865+ gesture_event->event);
866+ }
867+ else
868+ {
869+ geis_xcb_dispatch_gesture(instance, gesture_event);
870+ }
871
872 event = xcb_poll_for_event(xcb->connection);
873 }
874@@ -737,9 +802,10 @@
875
876
877 void
878-geis_xcb_free(GeisXcb* xcb)
879+geis_xcb_free(GeisXcb xcb)
880 {
881 xcb_disconnect(xcb->connection);
882+ XCloseDisplay(xcb->display);
883 }
884
885
886@@ -782,7 +848,8 @@
887
888
889 static GeisStatus
890-geis_xcb_verify_event_selection(GeisXcb *xcb,
891+geis_xcb_verify_event_selection(GeisXcb xcb,
892+ uint32_t window_id,
893 uint16_t device_id,
894 uint32_t mask_len,
895 uint32_t *mask)
896@@ -792,13 +859,12 @@
897 xcb_gesture_get_selected_events_cookie_t events_cookie;
898 xcb_gesture_get_selected_events_reply_t *events_reply = NULL;
899 xcb_gesture_event_mask_iterator_t event_mask_it;
900- uint32_t masks_len_reply = 0;
901 uint32_t mask_len_reply = 0;
902 uint32_t *mask_reply = NULL;
903 int device_is_found = 0;
904
905 events_cookie = xcb_gesture_get_selected_events(xcb->connection,
906- xcb->win_info->window_id);
907+ window_id);
908 events_reply = xcb_gesture_get_selected_events_reply(xcb->connection,
909 events_cookie,
910 &error);
911@@ -849,17 +915,31 @@
912
913
914 GeisStatus
915-geis_xcb_subscribe(GeisInstance instance,
916+geis_xcb_subscribe(GeisXcb xcb,
917+ GeisInstance instance,
918 uint16_t device_id,
919 const char **gesture_list)
920 {
921- GeisStatus result = GEIS_UNKNOWN_ERROR;
922- uint32_t mask_len = 1;
923- uint32_t *mask = 0;
924+ GeisStatus result = GEIS_UNKNOWN_ERROR;
925+ uint32_t mask_len = 1;
926+ uint32_t *mask = 0;
927+ const char **g;
928+ xcb_generic_error_t *error;
929+ xcb_void_cookie_t select_cookie;
930+ xcb_window_t window_id = geis_instance_get_window_id(instance);
931
932- xcb_generic_error_t *error;
933- xcb_void_cookie_t select_cookie;
934- GeisXcb *xcb = instance->xcb;
935+ if (gesture_list == GEIS_ALL_GESTURES)
936+ {
937+ geis_debug("subscribing device %d for the all gestures\n", device_id);
938+ }
939+ else
940+ {
941+ geis_debug("subscribing device %d for the following gestures:\n", device_id);
942+ for (g = gesture_list; *g; ++g)
943+ {
944+ geis_debug("\t\"%s\"\n", *g);
945+ }
946+ }
947
948 geis_xcb_map_gestures_to_mask(gesture_list, &mask, &mask_len);
949 if (!mask)
950@@ -869,18 +949,18 @@
951 }
952
953 select_cookie = xcb_gesture_select_events_checked(xcb->connection,
954- xcb->win_info->window_id,
955+ window_id,
956 device_id,
957 mask_len,
958 mask);
959 error = xcb_request_check(xcb->connection, select_cookie);
960 if (error)
961 {
962- geis_error("failed to select events\n");
963+ geis_error("failed to select events for window 0x%08x\n", window_id);
964 goto done;
965 }
966
967- result = geis_xcb_verify_event_selection(xcb, device_id, mask_len, mask);
968+ result = geis_xcb_verify_event_selection(xcb, window_id, device_id, mask_len, mask);
969 if (result == GEIS_STATUS_SUCCESS)
970 {
971 geis_xcb_dispatch_gesture_type(instance, gesture_list);
972@@ -891,3 +971,34 @@
973 really_done:
974 return result;
975 }
976+
977+
978+GeisStatus
979+geis_xcb_input_devices(GeisXcb xcb)
980+{
981+ int i;
982+ int ndevices;
983+ XIDeviceInfo *devices;
984+ XIDeviceInfo *device;
985+
986+ devices = XIQueryDevice(xcb->display, XIAllDevices, &ndevices);
987+ for (i = 0; i < ndevices; i++)
988+ {
989+ device = &devices[i];
990+#if 0
991+ switch(device->use)
992+ {
993+ case XIMasterPointer: printf("master pointer\n"); break;
994+ case XIMasterKeyboard: printf("master keyboard\n"); break;
995+ case XISlavePointer: printf("slave pointer\n"); break;
996+ case XISlaveKeyboard: printf("slave keyboard\n"); break;
997+ case XIFloatingSlave: printf("floating slave\n"); break;
998+ }
999+#endif
1000+ }
1001+ XIFreeDeviceInfo(devices);
1002+
1003+ return GEIS_STATUS_SUCCESS;
1004+}
1005+
1006+
1007
1008=== modified file 'libutouch-geis-xcb/geis_xcb.h'
1009--- libutouch-geis-xcb/geis_xcb.h 2010-08-24 17:08:41 +0000
1010+++ libutouch-geis-xcb/geis_xcb.h 2010-08-30 20:28:40 +0000
1011@@ -4,18 +4,18 @@
1012 * Copyright 2010 Canonical Ltd.
1013 *
1014 * This library is free software; you can redistribute it and/or modify it under
1015- * the terms of the GNU Lesser General Public License as published by the Free Software
1016- * Foundation; either version 3 of the License, or (at your option) any later
1017- * version.
1018+ * the terms of the GNU Lesser General Public License as published by the Free
1019+ * Software Foundation; either version 3 of the License, or (at your option) any
1020+ * later version.
1021 *
1022 * This library is distributed in the hope that it will be useful, but WITHOUT
1023 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
1024- * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
1025- * more details.
1026+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
1027+ * details.
1028 *
1029 * You should have received a copy of the GNU Lesser General Public License
1030- * along with this program; if not, write to the Free Software
1031- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1032+ * along with this program; if not, write to the Free Software Foundation, Inc.,
1033+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1034 */
1035 #ifndef GEIS_XCB_H_
1036 #define GEIS_XCB_H_
1037@@ -23,18 +23,23 @@
1038 #include "geis_config.h"
1039 #include <geis/geis.h>
1040
1041-typedef struct _GeisXcb GeisXcb;
1042-
1043-GeisXcb *geis_xcb_get(GeisXcbWinInfo *win_info);
1044-
1045-GeisStatus geis_xcb_subscribe(GeisInstance instance,
1046- uint16_t device_id,
1047+typedef struct _GeisXcb *GeisXcb;
1048+
1049+GeisXcb geis_xcb_new(GeisXcbWinInfo *win_info);
1050+
1051+GeisInstance geis_xcb_create_instance(GeisXcb xcb, uint32_t window_id);
1052+
1053+GeisStatus geis_xcb_input_devices(GeisXcb xcb);
1054+
1055+GeisStatus geis_xcb_subscribe(GeisXcb xcb,
1056+ GeisInstance instance,
1057+ uint16_t device_id,
1058 const char **gesture_list);
1059
1060-int geis_xcb_fd(GeisXcb* xcb);
1061-
1062-void geis_xcb_dispatch(GeisInstance instance);
1063-
1064-void geis_xcb_free(GeisXcb *xcb);
1065+int geis_xcb_fd(GeisXcb xcb);
1066+
1067+void geis_xcb_dispatch(GeisXcb xcb);
1068+
1069+void geis_xcb_free(GeisXcb xcb);
1070
1071 #endif /* GEIS_XCB_H_ */
1072
1073=== modified file 'testsuite/geistest/geistest.c'
1074--- testsuite/geistest/geistest.c 2010-08-24 17:59:37 +0000
1075+++ testsuite/geistest/geistest.c 2010-08-30 20:28:40 +0000
1076@@ -23,6 +23,8 @@
1077 #include <stdlib.h>
1078 #include <string.h>
1079 #include <sys/select.h>
1080+#include <unistd.h>
1081+#include <xcb/xcb.h>
1082
1083
1084 static void
1085@@ -51,6 +53,24 @@
1086
1087
1088 static void
1089+input_device_added(void *cookie, GeisInputDeviceId device_id, void *attrs)
1090+{
1091+}
1092+
1093+
1094+static void
1095+input_device_changed(void *cookie, GeisInputDeviceId device_id, void *attrs)
1096+{
1097+}
1098+
1099+
1100+static void
1101+input_device_removed(void *cookie, GeisInputDeviceId device_id, void *attrs)
1102+{
1103+}
1104+
1105+
1106+static void
1107 gesture_added(void *cookie,
1108 GeisGestureType gesture_type,
1109 GeisGestureId gesture_id,
1110@@ -116,6 +136,12 @@
1111 }
1112
1113
1114+GeisInputFuncs input_funcs = {
1115+ input_device_added,
1116+ input_device_changed,
1117+ input_device_removed
1118+};
1119+
1120 GeisGestureFuncs gesture_funcs = {
1121 gesture_added,
1122 gesture_removed,
1123@@ -128,22 +154,33 @@
1124 int
1125 parse_opts(int argc, char* argv[], uint32_t *window_id)
1126 {
1127- if (argc != 2)
1128- return 0;
1129-
1130- *window_id = strtol(argv[1], NULL, 0);
1131+ int opt;
1132+
1133+ while ((opt = getopt(argc, argv, "w:")) != -1)
1134+ {
1135+ switch (opt)
1136+ {
1137+ case 'w':
1138+ *window_id = strtol(optarg, NULL, 0);
1139+ break;
1140+
1141+ default:
1142+ return 0;
1143+ }
1144+ }
1145+
1146 return 1;
1147 }
1148
1149
1150-int
1151-main(int argc, char* argv[])
1152+static GeisInstance
1153+subscribe_window(uint32_t window_id)
1154 {
1155 GeisStatus status = GEIS_UNKNOWN_ERROR;
1156 GeisXcbWinInfo xcb_win_info = {
1157 .display_name = NULL,
1158 .screenp = NULL,
1159- .window_id = 0x296
1160+ .window_id = window_id
1161 };
1162 GeisWinInfo win_info = {
1163 GEIS_XCB_FULL_WINDOW,
1164@@ -151,51 +188,177 @@
1165 };
1166 GeisInstance instance;
1167
1168- if (!parse_opts(argc, argv, &xcb_win_info.window_id))
1169- {
1170- fprintf(stderr, "usage: %s windowid\n", argv[0]);
1171- return -1;
1172- }
1173-
1174 status = geis_init(&win_info, &instance);
1175 if (status != GEIS_STATUS_SUCCESS)
1176 {
1177 fprintf(stderr, "error in geis_init\n");
1178- return 1;
1179- }
1180-
1181- status = geis_configuration_supported(instance, GEIS_CONFIG_UNIX_FD);
1182- if (status != GEIS_STATUS_SUCCESS)
1183- {
1184- fprintf(stderr, "GEIS does not support Unix fd\n");
1185- return 1;
1186- }
1187-
1188- int fd = -1;
1189- status = geis_configuration_get_value(instance, GEIS_CONFIG_UNIX_FD, &fd);
1190- if (status != GEIS_STATUS_SUCCESS)
1191- {
1192- fprintf(stderr, "error retrieving GEIS fd\n");
1193- return 1;
1194- }
1195-
1196- const char *gestures[] =
1197- {
1198- GEIS_GESTURE_TYPE_ROTATE2,
1199- GEIS_GESTURE_TYPE_DRAG3,
1200- GEIS_GESTURE_TYPE_ROTATE3,
1201- 0
1202- };
1203+ return NULL;
1204+ }
1205+
1206+ status = geis_input_devices(instance, &input_funcs, NULL);
1207+ if (status != GEIS_STATUS_SUCCESS)
1208+ {
1209+ fprintf(stderr, "error subscribing to input devices\n");
1210+ return NULL;
1211+ }
1212
1213 status = geis_subscribe(instance,
1214 GEIS_ALL_INPUT_DEVICES,
1215- gestures,
1216+ GEIS_ALL_GESTURES,
1217 &gesture_funcs,
1218 NULL);
1219 if (status != GEIS_STATUS_SUCCESS)
1220 {
1221 fprintf(stderr, "error subscribing to gestures\n");
1222- return 1;
1223+ return NULL;
1224+ }
1225+
1226+ return instance;
1227+}
1228+
1229+
1230+static size_t
1231+subscribe_windows_preorder(xcb_connection_t *xcb,
1232+ xcb_window_t window,
1233+ size_t instance_table_size,
1234+ GeisInstance **instance_table)
1235+{
1236+ ++instance_table_size;
1237+ GeisInstance *new_instance_table;
1238+ new_instance_table = realloc(*instance_table,
1239+ instance_table_size * sizeof(GeisInstance));
1240+ new_instance_table[instance_table_size-1] = subscribe_window(window);
1241+ if (!new_instance_table[instance_table_size-1])
1242+ {
1243+ fprintf(stderr, "error creating geis instance for window 0x%08x\n", window);
1244+ free(new_instance_table);
1245+ instance_table_size = 0;
1246+ goto error_exit;
1247+ }
1248+
1249+ xcb_generic_error_t *error;
1250+ xcb_query_tree_cookie_t tree_cookie = xcb_query_tree(xcb, window);
1251+ xcb_query_tree_reply_t *tree_reply = xcb_query_tree_reply(xcb,
1252+ tree_cookie,
1253+ &error);
1254+ if (!tree_reply)
1255+ {
1256+ fprintf(stderr, "failed to query tree for window 0x%x\n", window);
1257+ goto error_exit;
1258+ }
1259+
1260+ int num_children = xcb_query_tree_children_length(tree_reply);
1261+ if (num_children <= 0)
1262+ goto tree_exit;
1263+
1264+ xcb_window_t *children = xcb_query_tree_children(tree_reply);
1265+ if (!children)
1266+ {
1267+ fprintf(stderr, "failed to retrieve children of window 0x%x\n", window);
1268+ goto tree_exit;
1269+ }
1270+
1271+ int i;
1272+ for (i = 0; i < num_children; i++)
1273+ {
1274+ instance_table_size = subscribe_windows_preorder(xcb,
1275+ children[i],
1276+ instance_table_size,
1277+ &new_instance_table);
1278+ if (instance_table_size == 0)
1279+ break;
1280+ }
1281+
1282+tree_exit:
1283+ free(tree_reply);
1284+error_exit:
1285+ *instance_table = new_instance_table;
1286+ return instance_table_size;
1287+}
1288+
1289+
1290+static size_t
1291+subscribe_all_windows(GeisInstance **instance_table)
1292+{
1293+ int instance_table_size = 0;
1294+
1295+ xcb_connection_t *xcb = xcb_connect(NULL, NULL);
1296+ if (!xcb) {
1297+ fprintf(stderr, "error connecting to X server\n");
1298+ return -1;
1299+ }
1300+
1301+ const xcb_setup_t *setup = xcb_get_setup(xcb);
1302+ if (!setup)
1303+ {
1304+ fprintf(stderr, "error getting xcb setup\n");
1305+ return -1;
1306+ }
1307+
1308+ xcb_screen_iterator_t screen = xcb_setup_roots_iterator(setup);
1309+ while (screen.rem)
1310+ {
1311+ instance_table_size = subscribe_windows_preorder(xcb,
1312+ screen.data->root,
1313+ instance_table_size,
1314+ instance_table);
1315+
1316+ xcb_screen_next(&screen);
1317+ }
1318+
1319+ xcb_disconnect(xcb);
1320+ return instance_table_size;
1321+}
1322+
1323+int
1324+main(int argc, char* argv[])
1325+{
1326+ int result = -1;
1327+ uint32_t window_id = 0;
1328+ int fd = -1;
1329+ GeisStatus status = GEIS_UNKNOWN_ERROR;
1330+ GeisInstance *instance_table = NULL;
1331+ size_t instance_table_size = 0;
1332+
1333+ if (!parse_opts(argc, argv, &window_id))
1334+ {
1335+ fprintf(stderr, "usage: %s windowid\n", argv[0]);
1336+ return -1;
1337+ }
1338+
1339+ if (window_id != 0)
1340+ {
1341+ instance_table_size = 1;
1342+ instance_table = calloc(instance_table_size, sizeof(GeisInstance));
1343+ instance_table[0] = subscribe_window(window_id);
1344+ if (!instance_table[0])
1345+ {
1346+ fprintf(stderr, "can not continue, exiting....\n");
1347+ goto error_exit;
1348+ }
1349+ }
1350+ else
1351+ {
1352+ instance_table_size = subscribe_all_windows(&instance_table);
1353+ if (instance_table_size == 0)
1354+ {
1355+ fprintf(stderr, "can not continue, exiting....\n");
1356+ goto error_exit;
1357+ }
1358+ }
1359+
1360+ status = geis_configuration_supported(instance_table[0], GEIS_CONFIG_UNIX_FD);
1361+ if (status != GEIS_STATUS_SUCCESS)
1362+ {
1363+ fprintf(stderr, "GEIS does not support Unix fd\n");
1364+ goto fail_exit;
1365+ }
1366+
1367+ status = geis_configuration_get_value(instance_table[0], GEIS_CONFIG_UNIX_FD, &fd);
1368+ if (status != GEIS_STATUS_SUCCESS)
1369+ {
1370+ fprintf(stderr, "error retrieving GEIS fd\n");
1371+ goto fail_exit;
1372 }
1373
1374 while(1)
1375@@ -212,10 +375,24 @@
1376
1377 if (FD_ISSET(fd, &read_fds))
1378 {
1379- geis_event_dispatch(instance);
1380- }
1381- }
1382-
1383- geis_finish(instance);
1384+ geis_event_dispatch(instance_table[0]);
1385+ }
1386+ }
1387+
1388+fail_exit:
1389+ {
1390+ int i;
1391+ for (i = 0; i < instance_table_size; ++i)
1392+ {
1393+ geis_finish(instance_table[i]);
1394+ }
1395+ }
1396+
1397+error_exit:
1398+ if (instance_table_size > 0)
1399+ {
1400+ free(instance_table);
1401+ }
1402+ return result;
1403 }
1404

Subscribers

People subscribed via source and target branches