Merge lp:geis/client-arch into lp:geis

Proposed by Stephen M. Webb
Status: Superseded
Proposed branch: lp:geis/client-arch
Merge into: lp:geis
Diff against target: 9682 lines (+7292/-647)
88 files modified
.bzrignore (+7/-1)
Makefile.am (+1/-0)
configure.ac (+4/-1)
include/geis/geis.h (+11/-8)
libs/Makefile.am (+1/-1)
libs/geis-dbus/Makefile.am (+41/-0)
libs/geis-dbus/geis_dbus.h (+37/-8)
libs/geis-dbus/geis_dbus_attr.c (+178/-0)
libs/geis-dbus/geis_dbus_attr.h (+57/-0)
libs/geis-dbus/geis_dbus_class.c (+126/-0)
libs/geis-dbus/geis_dbus_class.h (+45/-0)
libs/geis-dbus/geis_dbus_device.c (+152/-0)
libs/geis-dbus/geis_dbus_device.h (+61/-0)
libs/geis-dbus/geis_dbus_dispatcher.c (+486/-0)
libs/geis-dbus/geis_dbus_dispatcher.h (+116/-0)
libs/geis-dbus/geis_dbus_gesture_event.c (+516/-0)
libs/geis-dbus/geis_dbus_gesture_event.h (+55/-0)
libs/geis-dbus/geis_dbus_region.c (+91/-0)
libs/geis-dbus/geis_dbus_region.h (+47/-0)
libs/geis-dbus/geis_dbus_subscription.c (+506/-0)
libs/geis-dbus/geis_dbus_subscription.h (+206/-0)
libutouch-geis/Makefile.am (+5/-0)
libutouch-geis/backend/Makefile.am (+1/-1)
libutouch-geis/backend/dbus/Makefile.am (+34/-0)
libutouch-geis/backend/dbus/geis_dbus_backend.c (+248/-0)
libutouch-geis/backend/dbus/geis_dbus_client.c (+685/-0)
libutouch-geis/backend/dbus/geis_dbus_client.h (+97/-0)
libutouch-geis/backend/dbus/geis_dbus_locator.c (+268/-0)
libutouch-geis/backend/dbus/geis_dbus_locator.h (+62/-0)
libutouch-geis/backend/test_fixture/geis_backend_test_fixture.c (+7/-5)
libutouch-geis/backend/xcb/geis_xcb_backend.c (+10/-8)
libutouch-geis/backend/xcb/geis_xcb_backend_token.c (+4/-4)
libutouch-geis/backend/xcb/grail_gestures.c (+1/-1)
libutouch-geis/geis.c (+166/-158)
libutouch-geis/geis_attr.c (+143/-0)
libutouch-geis/geis_attr.h (+16/-0)
libutouch-geis/geis_backend.c (+2/-0)
libutouch-geis/geis_backend_multiplexor.c (+183/-74)
libutouch-geis/geis_backend_multiplexor.h (+51/-15)
libutouch-geis/geis_backend_protected.h (+2/-2)
libutouch-geis/geis_backend_token.c (+6/-4)
libutouch-geis/geis_backend_token.h (+32/-9)
libutouch-geis/geis_class.c (+2/-2)
libutouch-geis/geis_class.h (+1/-1)
libutouch-geis/geis_device.h (+1/-1)
libutouch-geis/geis_filter.c (+83/-0)
libutouch-geis/geis_filter.h (+51/-0)
libutouch-geis/geis_filter_term.c (+120/-0)
libutouch-geis/geis_filter_term.h (+8/-0)
libutouch-geis/geis_filterable.c (+151/-0)
libutouch-geis/geis_filterable.h (+116/-0)
libutouch-geis/geis_gesture_flick.c (+1/-1)
libutouch-geis/geis_private.h (+65/-59)
libutouch-geis/geis_subscription.c (+73/-10)
libutouch-geis/geis_subscription.h (+53/-0)
libutouch-geis/geis_timer.c (+5/-4)
libutouch-geis/geis_v1.c (+104/-45)
libutouch-geis/server/Makefile.am (+5/-2)
libutouch-geis/server/geis_dbus_announcer.c (+233/-0)
libutouch-geis/server/geis_dbus_announcer.h (+54/-0)
libutouch-geis/server/geis_dbus_client_proxy.c (+486/-0)
libutouch-geis/server/geis_dbus_client_proxy.h (+60/-0)
libutouch-geis/server/geis_dbus_proxy_box.c (+199/-0)
libutouch-geis/server/geis_dbus_proxy_box.h (+115/-0)
libutouch-geis/server/geis_dbus_server.c (+278/-154)
libutouch-geis/server/geis_dbus_server.h (+70/-30)
python/_geis_bindings/_geis_bindings.c (+3/-2)
python/geis/__init__.py (+6/-4)
testsuite/geis2/check_class.c (+1/-1)
testsuite/geis2/check_config.c (+1/-1)
testsuite/geis2/check_device.c (+1/-1)
testsuite/geis2/check_filter.c (+1/-1)
testsuite/geis2/check_frame.c (+1/-1)
testsuite/geis2/check_geis_new.c (+1/-1)
testsuite/geis2/check_region.c (+1/-1)
testsuite/geis2/check_subscription.c (+1/-1)
testsuite/libutouch-geis/Makefile.am (+1/-0)
testsuite/libutouch-geis/check_backend_multiplexor.c (+6/-2)
testsuite/libutouch-geis/check_backend_token.c (+1/-1)
testsuite/libutouch-geis/check_filter.c (+1/-1)
testsuite/libutouch-geis/check_geis_private.c (+4/-3)
testsuite/libutouch-geis/check_region.c (+1/-1)
testsuite/libutouch-geis/check_subscription.c (+1/-1)
testsuite/libutouch-geis/check_timer.c (+1/-1)
tools/Makefile.am (+1/-1)
tools/geis-server/Makefile.am (+33/-0)
tools/geis-server/geis-server.c (+85/-0)
tools/geisview/geisview (+39/-13)
To merge this branch: bzr merge lp:geis/client-arch
Reviewer Review Type Date Requested Status
Chase Douglas (community) Needs Information
Review via email: mp+79329@code.launchpad.net

This proposal has been superseded by a proposal from 2011-10-17.

Description of the change

Adds selectable client-server architecture using a private DBus.

I think at this point (most) functionality is there. May need some polish over the next cycle.

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

Added a trunk synch to resolve some merge conflicts.

lp:geis/client-arch updated
196. By Stephen M. Webb

Synched to lp:utouch-geis.

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

A ton of code that looks very clean. I really like the changes from an aesthetic point of view. It's obvious that you put a lot of thought into how things should be structured!

Here's what I'm looking for in reviewing this code:

1. Are there any "black box" changes?
2. Does the code look clean? Does it appear to do what is stated in the merge request?
3. Does it work?
4. Are there any issues highlighted by the merge proposal description?

Note that I'm not doing a line by line review. There's too much code to review for that level of detail, and you're a trusted member of the development team.

For item 1, there are no changes in include/. Since there are no api changes, and it's assumed there are no abi changes, this criteria is fulfilled.

For item 2, the code is definitely clean. It does appear to do what is stated in the merge request in whole.

However, I don't see any change in the default backend choice, and I don't see any change in geisview that would cause it to use the new client-server backend. Am I missing something, or was this lost in a merge or rebase? I would prefer to see the default backend change to the client-server backend with a fallback to the xcb backend.

The geis server is under tools/. Is this implementation merely an example, or is it the defacto server that should be used? If it's the latter, I would prefer to move it to the top level. I feel putting it in tools/ gives the wrong impression that it is not an essential part of the project.

For item 3, I'm not ready to give an answer yet since I don't know that geisview is using the new architecture. (On IRC, Stephen explained how to test: tools/geis-server/geis-server and then tools/geisview/geisview).

For item 4, I would like to know what is left out by the statement in the merge proposal: "I think at this point (most) functionality is there." Please detail which functionality is missing?

Overall, I'm extremely happy with the changes, assuming the testing shows it works :). I look forward to merging the branch once these issues are resolved!

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

On 10/13/2011 04:53 PM, Chase Douglas wrote:
> For item 1, there are no changes in include/. Since there are no api changes, and it's assumed there are no abi changes, this criteria is fulfilled.

There is a backwards-compatible API change in include/geis/geis.h with
the addition of the GEIS_INIT_UTOUCH_DBUS_BACKEND defined constant.

> For item 2, the code is definitely clean. It does appear to do what is stated in the merge request in whole.
>
> However, I don't see any change in the default backend choice, and I don't see any change in geisview that would cause it to use the new client-server backend. Am I missing something, or was this lost in a merge or rebase? I would prefer to see the default backend change to the client-server backend with a fallback to the xcb backend.

This was apparently clobbered by a last-minute merge from trunk with
manual conflict resolution. I will re-add the back end selection to the
geisview tool and make it command-line configurable, and resubmit.

Changing the default back end to the dbus-client is a little premature
until a proper daemon is set up complete with launch scripts (dbus
service?). This should wait until after the round of plugin
refactoring. Changing the default back-end is a one-line change.

> The geis server is under tools/. Is this implementation merely an example, or is it the defacto server that should be used? If it's the latter, I would prefer to move it to the top level. I feel putting it in tools/ gives the wrong impression that it is not an essential part of the project.

The program under tools is a test driver tool. Writing a proper daemon
application with attendant start and stop scripts, logging, and control
options should be a separate task not a part of the internal library
changes designed to enable that task.

All of the changes made under this merge request were made under the
original assumption that the geis server would run as a compiz plugin.
None of them are incompatible with running a standalone server and
neither do they require it.

We should consider making a "utouchd" daemon a separate project from the
utouch-geis library.

> For item 3, I'm not ready to give an answer yet since I don't know that geisview is using the new architecture. (On IRC, Stephen explained how to test: tools/geis-server/geis-server and then tools/geisview/geisview).

I will provide better instructions with the above-mentioned changes to
geisview.

> For item 4, I would like to know what is left out by the statement in the merge proposal: "I think at this point (most) functionality is there." Please detail which functionality is missing?

Yes, quite. The only known functional deficit is proper reconnection
from the client when the server has disconnected and then reconnected
again. After verbal discussions we decided to defer this functionality
to later in the interest of getting the client-server merge completed.

Revision history for this message
Chase Douglas (chasedouglas) wrote :
Download full text (3.5 KiB)

> On 10/13/2011 04:53 PM, Chase Douglas wrote:
> > For item 1, there are no changes in include/. Since there are no api
> changes, and it's assumed there are no abi changes, this criteria is
> fulfilled.
>
> There is a backwards-compatible API change in include/geis/geis.h with
> the addition of the GEIS_INIT_UTOUCH_DBUS_BACKEND defined constant.

Argh... I see now that although the unmerged revisions list below starts at commit 187, the client-arch commits really start at commit 159. I will need to re-review to include those commits as well.

> > For item 2, the code is definitely clean. It does appear to do what is
> stated in the merge request in whole.
> >
> > However, I don't see any change in the default backend choice, and I don't
> see any change in geisview that would cause it to use the new client-server
> backend. Am I missing something, or was this lost in a merge or rebase? I
> would prefer to see the default backend change to the client-server backend
> with a fallback to the xcb backend.
>
> This was apparently clobbered by a last-minute merge from trunk with
> manual conflict resolution. I will re-add the back end selection to the
> geisview tool and make it command-line configurable, and resubmit.
>
> Changing the default back end to the dbus-client is a little premature
> until a proper daemon is set up complete with launch scripts (dbus
> service?). This should wait until after the round of plugin
> refactoring. Changing the default back-end is a one-line change.

I'm not sure it's premature. The client-arch won't be used unless you have a server running, in which case we can probably assume the user knows what they are doing. The main reason I would like to switch the default is so we can test current clients of geis without having to recompile them. And, it would be switchable merely by running or killing the geis server. I will probably run the tools/ server by default in my installs just so we have some good testing.

> > The geis server is under tools/. Is this implementation merely an example,
> or is it the defacto server that should be used? If it's the latter, I would
> prefer to move it to the top level. I feel putting it in tools/ gives the
> wrong impression that it is not an essential part of the project.
>
> The program under tools is a test driver tool. Writing a proper daemon
> application with attendant start and stop scripts, logging, and control
> options should be a separate task not a part of the internal library
> changes designed to enable that task.
>
> All of the changes made under this merge request were made under the
> original assumption that the geis server would run as a compiz plugin.
> None of them are incompatible with running a standalone server and
> neither do they require it.
>
> We should consider making a "utouchd" daemon a separate project from the
> utouch-geis library.

Ok, that sounds reasonable.

> > For item 4, I would like to know what is left out by the statement in the
> merge proposal: "I think at this point (most) functionality is there." Please
> detail which functionality is missing?
>
> Yes, quite. The only known functional deficit is proper reconnection
> fr...

Read more...

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

On 10/13/2011 09:03 PM, Chase Douglas wrote:
>
> Argh... I see now that although the unmerged revisions list below starts at commit 187, the client-arch commits really start at commit 159. I will need to re-review to include those commits as well.

Yeah, it was a big set of changes with a number of synchs with trunk
along the way.

> I'm not sure it's premature. The client-arch won't be used unless you have a server running, in which case we can probably assume the user knows what they are doing. The main reason I would like to switch the default is so we can test current clients of geis without having to recompile them. And, it would be switchable merely by running or killing the geis server. I will probably run the tools/ server by default in my installs just so we have some good testing.

So you're suggesting autodiscovery with fallback. OK, I can do that.
Would like that as part of this merge or should we open a bug to track
that work?

Note that clients would not need any kind of recompile regardless.

>> The only known functional deficit is proper reconnection
>> from the client when the server has disconnected and then reconnected
>> again. After verbal discussions we decided to defer this functionality
>> to later in the interest of getting the client-server merge completed.
>
> Ok, that's reasonable for now. If we merge the branch like this, we should open a bug to track this missing functionality.

Absolutely.

lp:geis/client-arch updated
197. By Stephen M. Webb

Added a command-line switch to select a back end in geisview.

198. By Stephen M. Webb

Added back-end autodiscovery and failover.

The default back end is now DBus, with a fallback to XCB if the DBus server is not detected.

199. By Stephen M. Webb

Added full support for filtering by gesture class name with DBus server back end.

200. By Stephen M. Webb

Fixed a couple of invalid deallocations on exit.

Unmerged revisions

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file '.bzrignore'
--- .bzrignore 2011-04-18 13:48:35 +0000
+++ .bzrignore 2011-10-17 21:56:23 +0000
@@ -6,13 +6,13 @@
6**/xcb_gesture.[ch]6**/xcb_gesture.[ch]
7*.deps7*.deps
8*.libs8*.libs
9*.log
9*Makefile.in10*Makefile.in
10aclocal.m411aclocal.m4
11autom4te.cache12autom4te.cache
12config.*13config.*
13configure14configure
14debian/*.debhelper15debian/*.debhelper
15debian/*.log
16debian/*.substvars16debian/*.substvars
17debian/files17debian/files
18debian/libutouch-geis-dev18debian/libutouch-geis-dev
@@ -28,8 +28,13 @@
28examples/geis228examples/geis2
29geis_config.*29geis_config.*
30libtool30libtool
31libtool.m4
31libutouch-geis.pc32libutouch-geis.pc
33ltoptions.m4
34ltversion.m4
35lt~obsolete.m4
32stamp-*36stamp-*
37TAGS
33testsuite/geis1/*.log38testsuite/geis1/*.log
34testsuite/geis1/check_geis1_api39testsuite/geis1/check_geis1_api
35testsuite/geis2/*.log40testsuite/geis2/*.log
@@ -38,3 +43,4 @@
38testsuite/libutouch-geis/*.log43testsuite/libutouch-geis/*.log
39testsuite/libutouch-geis/*.xml44testsuite/libutouch-geis/*.xml
40testsuite/libutouch-geis/check_geis2_internals45testsuite/libutouch-geis/check_geis2_internals
46tools/geis-server/geis-server
4147
=== modified file 'Makefile.am'
--- Makefile.am 2011-04-18 13:47:57 +0000
+++ Makefile.am 2011-10-17 21:56:23 +0000
@@ -20,6 +20,7 @@
2020
2121
22ACLOCAL_MFLAGS = -I m422ACLOCAL_MFLAGS = -I m4
23AM_MAKEFLAGS = --no-print-directory
2324
24SUBDIRS = include libs libutouch-geis testsuite python tools examples doc25SUBDIRS = include libs libutouch-geis testsuite python tools examples doc
2526
2627
=== modified file 'configure.ac'
--- configure.ac 2011-08-31 19:53:52 +0000
+++ configure.ac 2011-10-17 21:56:23 +0000
@@ -95,12 +95,14 @@
95 doc/Makefile95 doc/Makefile
96 include/Makefile96 include/Makefile
97 libs/Makefile97 libs/Makefile
98 libs/geis-dbus/Makefile
98 libs/xcb/Makefile99 libs/xcb/Makefile
99 libs/xcb/xcb_gesture.xml100 libs/xcb/xcb_gesture.xml
100 libutouch-geis/Makefile101 libutouch-geis/Makefile
101 libutouch-geis/backend/Makefile102 libutouch-geis/backend/Makefile
102 libutouch-geis/backend/test_fixture/Makefile103 libutouch-geis/backend/test_fixture/Makefile
103 libutouch-geis/backend/xcb/Makefile104 libutouch-geis/backend/xcb/Makefile
105 libutouch-geis/backend/dbus/Makefile
104 libutouch-geis/server/Makefile106 libutouch-geis/server/Makefile
105 testsuite/Makefile107 testsuite/Makefile
106 testsuite/libutouch-geis/Makefile108 testsuite/libutouch-geis/Makefile
@@ -110,5 +112,6 @@
110 examples/Makefile112 examples/Makefile
111 python/Makefile113 python/Makefile
112 tools/Makefile114 tools/Makefile
113 tools/geisview/Makefile])115 tools/geisview/Makefile
116 tools/geis-server/Makefile])
114AC_OUTPUT117AC_OUTPUT
115118
=== modified file 'include/geis/geis.h'
--- include/geis/geis.h 2011-08-17 04:26:54 +0000
+++ include/geis/geis.h 2011-10-17 21:56:23 +0000
@@ -459,18 +459,21 @@
459 * @name Vendor-defined Initialization Arguments459 * @name Vendor-defined Initialization Arguments
460 *460 *
461 * @par461 * @par
462 * These initialization arguments are not a part of te GEIS specification and462 * These initialization arguments are not a part of the GEIS specification and
463 * may change.463 * may change.
464 *464 *
465 * @{465 * @{
466 *466 *
467 * @def GEIS_INIT_UTOUCH_MOCK_ENGINE467 * @def GEIS_INIT_UTOUCH_MOCK_BACKEND
468 *468 *
469 * @def GEIS_INIT_UTOUCH_XCB469 * @def GEIS_INIT_UTOUCH_DBUS_BACKEND
470 *
471 * @def GEIS_INIT_UTOUCH_XCB_BACKEND
470 */472 */
471473
472#define GEIS_INIT_UTOUCH_MOCK_ENGINE "com.canonical.utouch.mock.engine"474#define GEIS_INIT_UTOUCH_MOCK_BACKEND "com.canonical.utouch.backend.mock"
473#define GEIS_INIT_UTOUCH_XCB "com.canonical.utouch.xcb"475#define GEIS_INIT_UTOUCH_DBUS_BACKEND "com.canonical.utouch.backend.dbus"
476#define GEIS_INIT_UTOUCH_XCB_BACKEND "com.canonical.utouch.backend.xcb"
474477
475/* @} */478/* @} */
476479
@@ -1302,7 +1305,7 @@
1302 *1305 *
1303 * @param[in] gesture_class The gesture class object.1306 * @param[in] gesture_class The gesture class object.
1304 *1307 *
1305 * The reference count of teh object is decremented and, if it reaches zero, the1308 * The reference count of the object is decremented and, if it reaches zero, the
1306 * object is destroyed.1309 * object is destroyed.
1307 */1310 */
1308GEIS_API void geis_gesture_class_unref(GeisGestureClass gesture_class);1311GEIS_API void geis_gesture_class_unref(GeisGestureClass gesture_class);
@@ -1332,7 +1335,7 @@
1332GEIS_API GeisSize geis_gesture_class_attr_count(GeisGestureClass gesture_class);1335GEIS_API GeisSize geis_gesture_class_attr_count(GeisGestureClass gesture_class);
13331336
1334/**1337/**
1335 * Gets the indicated attribute of teh gesture class.1338 * Gets the indicated attribute of the gesture class.
1336 * @memberof GeisGestureClass1339 * @memberof GeisGestureClass
1337 *1340 *
1338 * @param[in] gesture_class The gesture class object.1341 * @param[in] gesture_class The gesture class object.
13391342
=== modified file 'libs/Makefile.am'
--- libs/Makefile.am 2011-01-17 15:03:18 +0000
+++ libs/Makefile.am 2011-10-17 21:56:23 +0000
@@ -19,5 +19,5 @@
19# 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA19# 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20#20#
2121
22SUBDIRS = xcb22SUBDIRS = xcb geis-dbus
2323
2424
=== added directory 'libs/geis-dbus'
=== added file 'libs/geis-dbus/Makefile.am'
--- libs/geis-dbus/Makefile.am 1970-01-01 00:00:00 +0000
+++ libs/geis-dbus/Makefile.am 2011-10-17 21:56:23 +0000
@@ -0,0 +1,41 @@
1#
2# @file libs/geis-dbus/Makefile.am
3# @brief automake recipe for the uTouch GEIS v2.0 DBus helper library
4#
5# Copyright 2011 Canonical, Ltd.
6#
7# This file is part of the utouch-geis library. This library is free software;
8# you can redistribute it and/or modify it under the terms of the GNU Lesser
9# General Public License as published by the Free Software Foundation; either
10# version 3 of the License, or (at your option) any 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
22noinst_LTLIBRARIES = libgeis-dbus.la
23
24dist_libgeis_dbus_la_SOURCES = \
25 geis_dbus.h \
26 geis_dbus_attr.h geis_dbus_attr.c \
27 geis_dbus_class.h geis_dbus_class.c \
28 geis_dbus_device.h geis_dbus_device.c \
29 geis_dbus_dispatcher.h geis_dbus_dispatcher.c \
30 geis_dbus_gesture_event.h geis_dbus_gesture_event.c \
31 geis_dbus_region.h geis_dbus_region.c \
32 geis_dbus_subscription.h geis_dbus_subscription.c
33
34libgeis_dbus_la_CPPFLAGS = \
35 -I$(top_srcdir)/libutouch-geis \
36 $(DBUS_CFLAGS)
37
38libgeis_dbus_la_LIBADD = \
39 $(DBUS_LIBS)
40
41
042
=== renamed file 'libutouch-geis/server/geis_dbus.h' => 'libs/geis-dbus/geis_dbus.h'
--- libutouch-geis/server/geis_dbus.h 2011-01-31 12:25:35 +0000
+++ libs/geis-dbus/geis_dbus.h 2011-10-17 21:56:23 +0000
@@ -1,4 +1,9 @@
1/**1/**
2 * @file geis_dbus.h
3 * @brief Common definitions for the GEIS DBus module(s).
4 */
5
6/*
2 * Copyright 2011 Canonical Ltd.7 * Copyright 2011 Canonical Ltd.
3 *8 *
4 * This library is free software; you can redistribute it and/or modify it under9 * This library is free software; you can redistribute it and/or modify it under
@@ -11,12 +16,36 @@
11 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more16 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
12 * details.17 * details.
13 *18 *
14 * You should have received a copy of the GNU Lesser General Public License19 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software Foundation, Inc.,20 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 */21 */
1822#ifndef GEIS_DBUS_H_
1923#define GEIS_DBUS_H_
20#define GEIS_DBUS_BUS_NAME "com.canonical.utouch"24
21#define GEIS_REMOTE_FUNCTION "getAddress"25#define GEIS_DBUS_SERVICE_PATH "/com/canonical/utouch/Geis"
2226#define GEIS_DBUS_SERVICE_INTERFACE "com.canonical.utouch.Geis"
27
28#define GEIS_DBUS_GET_SERVER_ADDRESS "GetServerAddress"
29
30#define GEIS_DBUS_INIT_COMPLETE "InitComplete"
31
32#define GEIS_DBUS_DEVICE_AVAILABLE "DeviceAvailable"
33#define GEIS_DBUS_DEVICE_UNAVAILABLE "DeviceUnavailable"
34
35#define GEIS_DBUS_CLASS_AVAILABLE "ClassAvailable"
36#define GEIS_DBUS_CLASS_UNAVAILABLE "ClassUnavailable"
37
38#define GEIS_DBUS_REGION_AVAILABLE "RegionAvailable"
39#define GEIS_DBUS_REGION_UNAVAILABLE "RegionUnavailable"
40
41#define GEIS_DBUS_SUBSCRIPTION_CREATE "SubscriptionCreate"
42#define GEIS_DBUS_SUBSCRIPTION_ACTIVATE "SubscriptionActivate"
43#define GEIS_DBUS_SUBSCRIPTION_DEACTIVATE "SubscriptionDeactivate"
44#define GEIS_DBUS_SUBSCRIPTION_DESTROY "SubscriptionDestroy"
45
46#define GEIS_DBUS_GESTURE_EVENT "GestureEvent"
47
48#define GEIS_DBUS_ERROR_SUBSCRIPTION_FAIL GEIS_DBUS_SERVICE_INTERFACE \
49 ".SubscriptionFail"
50
51#endif /* GEIS_DBUS_H_ */
2352
=== added file 'libs/geis-dbus/geis_dbus_attr.c'
--- libs/geis-dbus/geis_dbus_attr.c 1970-01-01 00:00:00 +0000
+++ libs/geis-dbus/geis_dbus_attr.c 2011-10-17 21:56:23 +0000
@@ -0,0 +1,178 @@
1/**
2 * @file geis_dbus_attr.c
3 * @brief Implementation of the GEIS DBus attr transport.
4 */
5
6/*
7 * Copyright 2011 Canonical Ltd.
8 *
9 * This library is free software; you can redistribute it and/or modify it under
10 * the terms of the GNU Lesser General Public License as published by the Free
11 * Software Foundation; either version 3 of the License, or (at your option) any
12 * later version.
13 *
14 * This library is distributed in the hope that it will be useful, but WITHOUT
15 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
17 * details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21 */
22#include "geis_config.h"
23#include "geis_dbus_attr.h"
24
25#include "geis_attr.h"
26#include "geis_logging.h"
27
28
29/*
30 * Marshalls a single GEIS attr to an open DBus message container iterator.
31 */
32void
33geis_dbus_attr_marshall(GeisAttr attr, DBusMessageIter *iter)
34{
35 DBusMessageIter dict_iter;
36 GeisString attr_name = geis_attr_name(attr);
37
38 dbus_message_iter_open_container(iter,
39 DBUS_TYPE_STRUCT,
40 NULL,
41 &dict_iter);
42 dbus_message_iter_append_basic(&dict_iter, DBUS_TYPE_STRING, &attr_name);
43 switch (geis_attr_type(attr))
44 {
45 case GEIS_ATTR_TYPE_BOOLEAN:
46 {
47 DBusMessageIter variant_iter;
48 dbus_bool_t val = geis_attr_value_to_boolean(attr);
49 dbus_message_iter_open_container(&dict_iter,
50 DBUS_TYPE_VARIANT,
51 DBUS_TYPE_BOOLEAN_AS_STRING,
52 &variant_iter);
53 dbus_message_iter_append_basic(&variant_iter, DBUS_TYPE_BOOLEAN, &val);
54 dbus_message_iter_close_container(&dict_iter, &variant_iter);
55 break;
56 }
57
58 case GEIS_ATTR_TYPE_FLOAT:
59 {
60 DBusMessageIter variant_iter;
61 double val = geis_attr_value_to_float(attr);
62 dbus_message_iter_open_container(&dict_iter,
63 DBUS_TYPE_VARIANT,
64 DBUS_TYPE_DOUBLE_AS_STRING,
65 &variant_iter);
66 dbus_message_iter_append_basic(&variant_iter, DBUS_TYPE_DOUBLE, &val);
67 dbus_message_iter_close_container(&dict_iter, &variant_iter);
68 break;
69 }
70
71 case GEIS_ATTR_TYPE_INTEGER:
72 {
73 DBusMessageIter variant_iter;
74 dbus_int32_t val = geis_attr_value_to_integer(attr);
75 dbus_message_iter_open_container(&dict_iter,
76 DBUS_TYPE_VARIANT,
77 DBUS_TYPE_INT32_AS_STRING,
78 &variant_iter);
79 dbus_message_iter_append_basic(&variant_iter, DBUS_TYPE_INT32, &val);
80 dbus_message_iter_close_container(&dict_iter, &variant_iter);
81 break;
82 }
83
84 case GEIS_ATTR_TYPE_STRING:
85 {
86 DBusMessageIter variant_iter;
87 GeisString val = geis_attr_value_to_string(attr);
88 dbus_message_iter_open_container(&dict_iter,
89 DBUS_TYPE_VARIANT,
90 DBUS_TYPE_STRING_AS_STRING,
91 &variant_iter);
92 dbus_message_iter_append_basic(&variant_iter, DBUS_TYPE_STRING, &val);
93 dbus_message_iter_close_container(&dict_iter, &variant_iter);
94 break;
95 }
96
97 default:
98 geis_error("invalid attribute type for DBus");
99 }
100 dbus_message_iter_close_container(iter, &dict_iter);
101}
102
103
104/*
105 * Unmarshalls a single GEIS attr from a DBus message iterator.
106 */
107GeisAttr
108geis_dbus_attr_unmarshall(DBusMessageIter *iter)
109{
110 GeisAttr attr = NULL;
111 DBusMessageIter dict_iter;
112
113 dbus_message_iter_recurse(iter, &dict_iter);
114 int dtype = dbus_message_iter_get_arg_type(&dict_iter);
115 if (dtype != DBUS_TYPE_STRING)
116 {
117 geis_error("error getting attr name from DBus message");
118 goto final_exit;
119 }
120
121 char *attr_name;
122 dbus_message_iter_get_basic(&dict_iter, &attr_name);
123
124 dbus_message_iter_next(&dict_iter);
125 dtype = dbus_message_iter_get_arg_type(&dict_iter);
126 if (dtype != DBUS_TYPE_VARIANT)
127 {
128 geis_error("error getting attr variant from DBus message");
129 goto final_exit;
130 }
131
132 DBusMessageIter variant_iter;
133 dbus_message_iter_recurse(&dict_iter, &variant_iter);
134 int vtype = dbus_message_iter_get_arg_type(&variant_iter);
135 switch (vtype)
136 {
137 case DBUS_TYPE_BOOLEAN:
138 {
139 dbus_bool_t val;
140 dbus_message_iter_get_basic(&variant_iter, &val);
141 attr = geis_attr_new(attr_name, GEIS_ATTR_TYPE_BOOLEAN, &val);
142 break;
143 }
144
145 case DBUS_TYPE_DOUBLE:
146 {
147 double dval;
148 dbus_message_iter_get_basic(&variant_iter, &dval);
149 float fval = dval;
150 attr = geis_attr_new(attr_name, GEIS_ATTR_TYPE_FLOAT, &fval);
151 break;
152 }
153
154 case DBUS_TYPE_INT32:
155 {
156 dbus_int32_t val;
157 dbus_message_iter_get_basic(&variant_iter, &val);
158 attr = geis_attr_new(attr_name, GEIS_ATTR_TYPE_INTEGER, &val);
159 break;
160 }
161
162 case DBUS_TYPE_STRING:
163 {
164 GeisString val;
165 dbus_message_iter_get_basic(&variant_iter, &val);
166 attr = geis_attr_new(attr_name, GEIS_ATTR_TYPE_STRING, (void *)val);
167 break;
168 }
169
170 default:
171 geis_error("unexpected attr data type from DBus");
172 break;
173 }
174
175final_exit:
176 return attr;
177}
178
0179
=== added file 'libs/geis-dbus/geis_dbus_attr.h'
--- libs/geis-dbus/geis_dbus_attr.h 1970-01-01 00:00:00 +0000
+++ libs/geis-dbus/geis_dbus_attr.h 2011-10-17 21:56:23 +0000
@@ -0,0 +1,57 @@
1/**
2 * @file geis_dbus_attr.h
3 * @brief Interface for the GEIS DBus attr transport.
4 */
5
6/*
7 * Copyright 2011 Canonical Ltd.
8 *
9 * This library is free software; you can redistribute it and/or modify it under
10 * the terms of the GNU Lesser General Public License as published by the Free
11 * Software Foundation; either version 3 of the License, or (at your option) any
12 * later version.
13 *
14 * This library is distributed in the hope that it will be useful, but WITHOUT
15 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
17 * details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21 */
22#ifndef GEIS_DBUS_ATTR_H_
23#define GEIS_DBUS_ATTR_H_
24
25#include <dbus/dbus.h>
26#include "geis/geis.h"
27
28
29/**
30 * The DBus type signature for a GEIS attrlist entry.
31 */
32#define GEIS_DBUS_TYPE_SIGNATURE_ATTR \
33 DBUS_STRUCT_BEGIN_CHAR_AS_STRING \
34 DBUS_TYPE_STRING_AS_STRING \
35 DBUS_TYPE_VARIANT_AS_STRING \
36 DBUS_STRUCT_END_CHAR_AS_STRING
37
38/**
39 * Marshalls a single GEIS attr to an open DBus message container iterator.
40 *
41 * @param[in] attr The GEIS attr.
42 * @param[in] iter The DBus message iterator.
43 */
44void
45geis_dbus_attr_marshall(GeisAttr attr, DBusMessageIter *iter);
46
47/**
48 * Unmarshalls a single GEIS attr from a DBus message iterator.
49 *
50 * @param[in] iter The DBus message iterator.
51 *
52 * @returns a GEIS attribute or NULL on error.
53 */
54GeisAttr
55geis_dbus_attr_unmarshall(DBusMessageIter *iter);
56
57#endif /* GEIS_DBUS_ATTR_H_ */
058
=== added file 'libs/geis-dbus/geis_dbus_class.c'
--- libs/geis-dbus/geis_dbus_class.c 1970-01-01 00:00:00 +0000
+++ libs/geis-dbus/geis_dbus_class.c 2011-10-17 21:56:23 +0000
@@ -0,0 +1,126 @@
1/**
2 * @file geis_dbus_gesture_class.c
3 * @brief Implementations of the GEIS DBus gesture_class transport.
4 */
5
6/*
7 * Copyright 2011 Canonical Ltd.
8 *
9 * This library is free software; you can redistribute it and/or modify it under
10 * the terms of the GNU Lesser General Public License as published by the Free
11 * Software Foundation; either version 3 of the License, or (at your option) any
12 * later version.
13 *
14 * This library is distributed in the hope that it will be useful, but WITHOUT
15 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
17 * details.
18 *
19 * You should have received a copy of the GNU Lesser General Public License
20 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21 */
22#include "geis_config.h"
23#include "geis_dbus_class.h"
24
25#include "geis_dbus.h"
26#include "geis_dbus_attr.h"
27#include "geis_class.h"
28#include "geis_logging.h"
29
30
31/*
32 * Creates a Dbus "gesture_class available" message from a GEIS gesture_class.
33 *
34 * The Wire protocol for this message is class_id and class_name followed by
35 * the list of class attributes.
36 */
37DBusMessage *
38geis_dbus_class_available_message_from_class(GeisGestureClass gesture_class)
39{
40 DBusMessage *message = dbus_message_new_signal(GEIS_DBUS_SERVICE_PATH,
41 GEIS_DBUS_SERVICE_INTERFACE,
42 GEIS_DBUS_CLASS_AVAILABLE);
43 DBusMessageIter iter;
44 dbus_message_iter_init_append(message, &iter);
45
46 dbus_int32_t gesture_class_id = geis_gesture_class_id(gesture_class);
47 dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &gesture_class_id);
48
49 const char *gesture_class_name = geis_gesture_class_name(gesture_class);
50 dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &gesture_class_name);
51
52 DBusMessageIter array_iter;
53 dbus_message_iter_open_container(&iter,
54 DBUS_TYPE_ARRAY,
55 GEIS_DBUS_TYPE_SIGNATURE_ATTR,
56 &array_iter);
57 GeisSize attr_count = geis_gesture_class_attr_count(gesture_class);
58 for (GeisSize i = 0; i < attr_count; ++i)
59 {
60 geis_dbus_attr_marshall(geis_gesture_class_attr(gesture_class, i),
61 &array_iter);
62 }
63 dbus_message_iter_close_container(&iter, &array_iter);
64 return message;
65}
66
67
68/*
69 * Creates GEIS gesture_class from a DBus "gesture_class available" message.
70 */
71GeisGestureClass
72geis_dbus_class_class_from_available_message(DBusMessage *message)
73{
74 GeisGestureClass gesture_class = NULL;
75 DBusMessageIter iter;
76 dbus_message_iter_init(message, &iter);
77
78 int type = dbus_message_iter_get_arg_type(&iter);
79 if (type != DBUS_TYPE_INT32)
80 {
81 geis_error("error getting gesture_class ID from DBus message.");
82 goto final_exit;
83 }
84 dbus_int32_t gesture_class_id;
85 dbus_message_iter_get_basic(&iter, &gesture_class_id);
86
87 dbus_message_iter_next(&iter);
88 type = dbus_message_iter_get_arg_type(&iter);
89 if (type != DBUS_TYPE_STRING)
90 {
91 geis_error("error getting gesture_class name from DBus message.");
92 goto final_exit;
93 }
94
95 char *gesture_class_name;
96 dbus_message_iter_get_basic(&iter, &gesture_class_name);
97 gesture_class = geis_gesture_class_new(gesture_class_name, gesture_class_id);
98
99 dbus_message_iter_next(&iter);
100 type = dbus_message_iter_get_arg_type(&iter);
101 if (type != DBUS_TYPE_ARRAY)
102 {
103 geis_error("error getting gesture_class attr list from DBus message.");
104 goto final_exit;
105 }
106
107 DBusMessageIter array_iter;
108 dbus_message_iter_recurse(&iter, &array_iter);
109 int atype = dbus_message_iter_get_arg_type(&array_iter);
110 while (atype == DBUS_TYPE_DICT_ENTRY)
111 {
112 GeisAttr attr = geis_dbus_attr_unmarshall(&array_iter);
113 if (attr)
114 {
115 geis_gesture_class_add_attr(gesture_class, attr);
116 }
117
118 dbus_message_iter_next(&array_iter);
119 atype = dbus_message_iter_get_arg_type(&array_iter);
120 }
121
122final_exit:
123 return gesture_class;
124}
125
126
0127
=== added file 'libs/geis-dbus/geis_dbus_class.h'
--- libs/geis-dbus/geis_dbus_class.h 1970-01-01 00:00:00 +0000
+++ libs/geis-dbus/geis_dbus_class.h 2011-10-17 21:56:23 +0000
@@ -0,0 +1,45 @@
1/**
2 * @file geis_dbus_class.h
3 * @brief Interface for the GEIS DBus gesture class transport.
4 */
5
6/*
7 * Copyright 2011 Canonical Ltd.
8 *
9 * This library is free software; you can redistribute it and/or modify it under
10 * the terms of the GNU Lesser General Public License as published by the Free
11 * Software Foundation; either version 3 of the License, or (at your option) any
12 * later version.
13 *
14 * This library is distributed in the hope that it will be useful, but WITHOUT
15 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
17 * details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21 */
22#ifndef GEIS_DBUS_GESTURE_CLASS_H_
23#define GEIS_DBUS_GESTURE_CLASS_H_
24
25#include <dbus/dbus.h>
26#include "geis/geis.h"
27
28
29/**
30 * Creates a Dbus "class available" message from a GEIS class.
31 *
32 * @param[in] class A GEIS gesture class.
33 */
34DBusMessage *
35geis_dbus_class_available_message_from_class(GeisGestureClass gesture_class);
36
37/**
38 * Creates GEIS class from a DBus "class available" message.
39 *
40 * @param[in] message A DBus message.
41 */
42GeisGestureClass
43geis_dbus_class_class_from_available_message(DBusMessage *message);
44
45#endif /* GEIS_DBUS_GESTURE_CLASS_H_ */
046
=== added file 'libs/geis-dbus/geis_dbus_device.c'
--- libs/geis-dbus/geis_dbus_device.c 1970-01-01 00:00:00 +0000
+++ libs/geis-dbus/geis_dbus_device.c 2011-10-17 21:56:23 +0000
@@ -0,0 +1,152 @@
1/**
2 * @file geis_dbus_device.c
3 * @brief Implementations of the GEIS DBus device transport.
4 */
5
6/*
7 * Copyright 2011 Canonical Ltd.
8 *
9 * This library is free software; you can redistribute it and/or modify it under
10 * the terms of the GNU Lesser General Public License as published by the Free
11 * Software Foundation; either version 3 of the License, or (at your option) any
12 * later version.
13 *
14 * This library is distributed in the hope that it will be useful, but WITHOUT
15 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
17 * details.
18 *
19 * You should have received a copy of the GNU Lesser General Public License
20 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21 */
22#include "geis_config.h"
23#include "geis_dbus_device.h"
24
25#include "geis_dbus.h"
26#include "geis_dbus_attr.h"
27#include "geis_device.h"
28#include "geis_logging.h"
29
30
31/*
32 * Creates a Dbus "device available" message from a GEIS device.
33 *
34 * The Wire protocol for this message is device_id and device_name followed by
35 * the list of device attributes.
36 */
37DBusMessage *
38geis_dbus_device_available_message_from_device(GeisDevice device)
39{
40 DBusMessage *message = dbus_message_new_signal(GEIS_DBUS_SERVICE_PATH,
41 GEIS_DBUS_SERVICE_INTERFACE,
42 GEIS_DBUS_DEVICE_AVAILABLE);
43 DBusMessageIter iter;
44 dbus_message_iter_init_append(message, &iter);
45
46 dbus_int32_t device_id = geis_device_id(device);
47 dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &device_id);
48
49 const char *device_name = geis_device_name(device);
50 dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &device_name);
51
52 DBusMessageIter array_iter;
53 dbus_message_iter_open_container(&iter,
54 DBUS_TYPE_ARRAY,
55 GEIS_DBUS_TYPE_SIGNATURE_ATTR,
56 &array_iter);
57 GeisSize attr_count = geis_device_attr_count(device);
58 for (GeisSize i = 0; i < attr_count; ++i)
59 {
60 geis_dbus_attr_marshall(geis_device_attr(device, i), &array_iter);
61 }
62 dbus_message_iter_close_container(&iter, &array_iter);
63 return message;
64}
65
66
67/*
68 * Creates GEIS device from a DBus "device available" message.
69 */
70GeisDevice
71geis_dbus_device_device_from_available_message(DBusMessage *message)
72{
73 geis_debug("begins");
74 GeisDevice device = NULL;
75 DBusMessageIter iter;
76 dbus_message_iter_init(message, &iter);
77
78 int type = dbus_message_iter_get_arg_type(&iter);
79 if (type != DBUS_TYPE_INT32)
80 {
81 geis_error("error getting device ID from DBus message.");
82 goto final_exit;
83 }
84 dbus_int32_t device_id;
85 dbus_message_iter_get_basic(&iter, &device_id);
86
87 dbus_message_iter_next(&iter);
88 type = dbus_message_iter_get_arg_type(&iter);
89 if (type != DBUS_TYPE_STRING)
90 {
91 geis_error("error getting device name from DBus message.");
92 goto final_exit;
93 }
94
95 char *device_name;
96 dbus_message_iter_get_basic(&iter, &device_name);
97 device = geis_device_new(device_name, device_id);
98
99 dbus_message_iter_next(&iter);
100 type = dbus_message_iter_get_arg_type(&iter);
101 if (type != DBUS_TYPE_ARRAY)
102 {
103 geis_error("error getting device attr list from DBus message.");
104 goto final_exit;
105 }
106
107 DBusMessageIter array_iter;
108 dbus_message_iter_recurse(&iter, &array_iter);
109 int atype = dbus_message_iter_get_arg_type(&array_iter);
110 while (atype == DBUS_TYPE_DICT_ENTRY)
111 {
112 GeisAttr attr = geis_dbus_attr_unmarshall(&array_iter);
113 if (attr)
114 {
115 geis_device_add_attr(device, attr);
116 }
117
118 dbus_message_iter_next(&array_iter);
119 atype = dbus_message_iter_get_arg_type(&array_iter);
120 }
121
122final_exit:
123 geis_debug("ends");
124 return device;
125}
126
127
128/*
129 * Creates a Dbus "device unavailable" message from a GEIS device.
130 */
131DBusMessage *
132geis_dbus_device_unavailable_message_from_device(GeisDevice device GEIS_UNUSED)
133{
134 geis_debug("begins");
135 DBusMessage *message = NULL;
136 geis_debug("ends");
137 return message;
138}
139
140
141/*
142 * Creates GEIS device from a DBus "device unavailable" message.
143 */
144GeisDevice
145geis_dbus_device_device_from_unavailable_message(DBusMessage *message GEIS_UNUSED)
146{
147 geis_debug("begins");
148 GeisDevice device = NULL;
149 geis_debug("ends");
150 return device;
151}
152
0153
=== added file 'libs/geis-dbus/geis_dbus_device.h'
--- libs/geis-dbus/geis_dbus_device.h 1970-01-01 00:00:00 +0000
+++ libs/geis-dbus/geis_dbus_device.h 2011-10-17 21:56:23 +0000
@@ -0,0 +1,61 @@
1/**
2 * @file geis_dbus_device.h
3 * @brief Interface for the GEIS DBus device transport.
4 */
5
6/*
7 * Copyright 2011 Canonical Ltd.
8 *
9 * This library is free software; you can redistribute it and/or modify it under
10 * the terms of the GNU Lesser General Public License as published by the Free
11 * Software Foundation; either version 3 of the License, or (at your option) any
12 * later version.
13 *
14 * This library is distributed in the hope that it will be useful, but WITHOUT
15 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
17 * details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21 */
22#ifndef GEIS_DBUS_DEVICE_H_
23#define GEIS_DBUS_DEVICE_H_
24
25#include <dbus/dbus.h>
26#include "geis/geis.h"
27
28
29/**
30 * Creates a Dbus "device available" message from a GEIS device.
31 *
32 * @param[in] device A GEIS device.
33 */
34DBusMessage *
35geis_dbus_device_available_message_from_device(GeisDevice device);
36
37/**
38 * Creates GEIS device from a DBus "device available" message.
39 *
40 * @param[in] message A DBus message.
41 */
42GeisDevice
43geis_dbus_device_device_from_available_message(DBusMessage *message);
44
45/**
46 * Creates a Dbus "device unavailable" message from a GEIS device.
47 *
48 * @param[in] device A GEIS device.
49 */
50DBusMessage *
51geis_dbus_device_unavailable_message_from_device(GeisDevice device);
52
53/**
54 * Creates GEIS device from a DBus "device unavailable" message.
55 *
56 * @param[in] message A DBus message.
57 */
58GeisDevice
59geis_dbus_device_device_from_unavailable_message(DBusMessage *message);
60
61#endif /* GEIS_DBUS_DEVICE_H_ */
062
=== added file 'libs/geis-dbus/geis_dbus_dispatcher.c'
--- libs/geis-dbus/geis_dbus_dispatcher.c 1970-01-01 00:00:00 +0000
+++ libs/geis-dbus/geis_dbus_dispatcher.c 2011-10-17 21:56:23 +0000
@@ -0,0 +1,486 @@
1/**
2 * @file geis_dbus_dispatcher.c
3 * @brief Implementation of the GEIS DBus dispatcher.
4 */
5
6/*
7 * Copyright 2011 Canonical Ltd.
8 *
9 * This library is free software; you can redistribute it and/or modify it under
10 * the terms of the GNU Lesser General Public License as published by the Free
11 * Software Foundation; either version 3 of the License, or (at your option) any
12 * later version.
13 *
14 * This library is distributed in the hope that it will be useful, but WITHOUT
15 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
17 * details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21 */
22#include "geis_config.h"
23#include "geis_dbus_dispatcher.h"
24
25#include "geis_logging.h"
26#include "geis_private.h"
27#include <stdio.h>
28#include <stdlib.h>
29
30
31typedef struct GeisDBusWatch *GeisDBusWatch;
32typedef struct GeisDBusWatchBag *GeisDBusWatchBag;
33
34/*
35 * Connects a DBusWatch back to a DBusConnection.
36 *
37 * This is an intrusive linked list node. See GeisDBusWatchBag.
38 */
39struct GeisDBusWatch
40{
41 DBusConnection *connection;
42 DBusWatch *watch;
43 GeisDBusWatch next;
44};
45
46
47/*
48 * Maps file descriptors to watches and connections.
49 *
50 * A DBusWatch is assciated with a single file descriptor, but each file
51 * descriptor may be associated with more than one DBusWatch.
52 *
53 * Each DBusConnection has one or more DBusWatch. The DBusWatches are passed
54 * around without reference to the connection itself, but we often need the
55 * connection when all we have is the watch.
56 *
57 * To make things more complex, the DBusServer does not have a connection
58 * associated with its watches.
59 *
60 * This is a linked list with a free pool.
61 */
62struct GeisDBusWatchBag
63{
64 GeisDBusWatch front;
65 GeisDBusWatch back;
66 GeisDBusWatch pool;
67};
68
69static const int _geis_dbus_watch_bag_initial_size = 4;
70
71
72struct GeisDBusDispatcher
73{
74 Geis geis;
75 GeisDBusWatchBag watches;
76};
77
78
79/*
80 * Creates a new empty collection of watches.
81 *
82 * The pool is primed with a few empty watches to save time later, on the
83 * assumption that if you're creating a bag you're going to use it.
84 */
85static GeisDBusWatchBag
86_geis_dbus_watch_bag_new()
87{
88 GeisDBusWatchBag bag = calloc(1, sizeof(struct GeisDBusWatchBag));
89 if (!bag)
90 {
91 geis_error("error allocating GeisDBusWatchBag");
92 goto final_exit;
93 }
94
95 /* Prime the free pool. */
96 for (int i = 0; i < _geis_dbus_watch_bag_initial_size; ++i)
97 {
98 GeisDBusWatch gdbw = calloc(1, sizeof(struct GeisDBusWatch));
99 if (!gdbw)
100 {
101 geis_error("error allocating GeisDBusWatchBag");
102 goto unwind_pool;
103 }
104 gdbw->next = bag->pool;
105 bag->pool = gdbw;
106 }
107 goto final_exit;
108
109unwind_pool:
110final_exit:
111 return bag;
112}
113
114
115/*
116 * Destroys a collection of watches.
117 *
118 * @param[in] bag A collection of %GeisDBusWatches.
119 *
120 * There should be no need to unref any of the contents of the bag, they can
121 * just be freed without consequence.
122 */
123static void
124_geis_dbus_watch_bag_delete(GeisDBusWatchBag bag)
125{
126 /* Free the pool. */
127 GeisDBusWatch gdbw = bag->pool;
128 while (gdbw)
129 {
130 GeisDBusWatch next = gdbw->next;
131 free(gdbw);
132 gdbw = next;
133 }
134
135 /* Free the in-use watches. */
136 gdbw = bag->front;
137 while (gdbw)
138 {
139 GeisDBusWatch next = gdbw->next;
140 free(gdbw);
141 gdbw = next;
142 }
143
144 free(bag);
145}
146
147
148/*
149 * Gets an allocated watch from the bag.
150 *
151 * @param[in] bag A collection of %GeisDBusWatches.
152 * @param[in] connection A DBusConnection.
153 * @param[in] watch A DBusWatch.
154 *
155 * A factory function to create a new watch in the collection and return a
156 * pointer to it.
157 */
158static GeisDBusWatch
159_geis_dbus_watch_bag_alloc_watch(GeisDBusWatchBag bag,
160 DBusConnection *connection,
161 DBusWatch *watch)
162{
163 GeisDBusWatch gdbw = NULL;
164
165 /* Either pull a free watch off the pool or allocate a new one. */
166 if (bag->pool)
167 {
168 gdbw = bag->pool;
169 bag->pool = bag->pool->next;
170 }
171 else
172 {
173 gdbw = calloc(1, sizeof(struct GeisDBusWatch));
174 if (!gdbw)
175 {
176 geis_error("error allocating GeisDBusWatchBag");
177 goto final_exit;
178 }
179 }
180
181 /* Fill in the data bits. */
182 gdbw->connection = connection;
183 gdbw->watch = watch;
184 gdbw->next = NULL;
185
186 /* Add it to the in-use list. */
187 if (!bag->front)
188 {
189 bag->front = gdbw;
190 }
191 if (bag->back)
192 {
193 bag->back->next = gdbw;
194 }
195 bag->back = gdbw;
196
197final_exit:
198 return gdbw;
199}
200
201
202/*
203 * Removes a watch from a collection of such beasts.
204 *
205 * @param[in] bag A collection of %GeisDBusWatches.
206 * @param[in] watch The watch to remove.
207 */
208static void
209_geis_dbus_watch_bag_remove_watch(GeisDBusWatchBag bag,
210 DBusWatch *watch)
211{
212 for (GeisDBusWatch gdbw = bag->front, prev = NULL; gdbw; gdbw = gdbw->next)
213 {
214 if (gdbw->watch == watch)
215 {
216 if (gdbw == bag->front)
217 {
218 bag->front = gdbw->next;
219 }
220 else
221 {
222 prev->next = gdbw->next;
223 }
224 if (gdbw == bag->back)
225 {
226 bag->back = prev;
227 }
228
229 gdbw->next = bag->pool;
230 bag->pool = gdbw;
231
232 break;
233 }
234 prev = gdbw;
235 }
236}
237
238
239/*
240 * Indicates if a file descriptor is already held in the watch bag.
241 *
242 * @param[in] bag A collection of %GeisDBusWatches.
243 * @param[in] fd A file descriptor.
244 * @param[out] flags The DBus watch flags for any enabled watches found.
245 *
246 * @returns zero if the file descriptor is not in the bag, non-zero otherwise.
247 */
248static int
249_geis_dbus_watch_bag_has_fd(GeisDBusWatchBag bag, int fd, unsigned int *flags)
250{
251 int has_fd = 0;
252 for (GeisDBusWatch gdbw = bag->front; gdbw; gdbw = gdbw->next)
253 {
254 if (dbus_watch_get_unix_fd(gdbw->watch) == fd)
255 {
256 has_fd |= ~0;
257 if (dbus_watch_get_enabled(gdbw->watch))
258 {
259 *flags |= dbus_watch_get_flags(gdbw->watch);
260 }
261 }
262 }
263 return has_fd;
264}
265
266
267/*
268 * Finds a DBusWatch in the bag that matches the fd and current activity.
269 *
270 * @param[in] bag A collection of %GeisDBusWatches.
271 * @param[in] fd The file descriptor on which an activity has been detected.
272 * @param[in] activity The bitmask of currently detected activity on the fd.
273 *
274 * A DBusWatch will match if it has the same file descriptor and is watching for
275 * (one of) the activity(ies) that has just occurred.
276 *
277 * Note that writers are implicitly looking for hangups or errors but the DBus
278 * library goes into an infinite loop when a hangup has occurred no a write
279 * watch, so defer that to a read watch.
280 *
281 * @returns a GeisDBusWatch or NULL if no matching watch was found.
282 */
283static GeisDBusWatch
284_geis_dbus_watch_bag_find_fd_activity(GeisDBusWatchBag bag,
285 int fd,
286 GeisBackendMultiplexorActivity activity)
287{
288 GeisDBusWatch gdbw = NULL;
289 for (gdbw = bag->front; gdbw; gdbw = gdbw->next)
290 {
291 if (dbus_watch_get_unix_fd(gdbw->watch) == fd)
292 {
293 unsigned int flags = dbus_watch_get_flags(gdbw->watch);
294 if ((activity & GEIS_BE_MX_READ_AVAILABLE && flags & DBUS_WATCH_READABLE)
295 || (activity & GEIS_BE_MX_WRITE_AVAILABLE && flags & DBUS_WATCH_WRITABLE)
296 || (activity & GEIS_BE_MX_HANGUP_DETECTED && flags & DBUS_WATCH_READABLE)
297 || (activity & GEIS_BE_MX_ERROR_DETECTED))
298 {
299 break;
300 }
301 }
302 }
303 return gdbw;
304}
305
306
307/*
308 * A callback function passed to the Geis multiplexor.
309 *
310 * @param[in] fd The file descriptor on which an activity has been detected.
311 * @param[in] activity The bitmask of currently detected activity on the fd.
312 * @param[in] context The %GeisDBusDispatcher passed through the multiplexor.
313 *
314 * This callback gets invoked whenever a requested activity is detected on a
315 * regostered DBusWatch file descriptor. It translates the GEIS Multiplexor
316 * activity to DBus activity.
317 */
318static void
319_geis_dbus_dispatcher_callback(int fd,
320 GeisBackendMultiplexorActivity activity,
321 void *context)
322{
323 GeisDBusDispatcher dispatcher = (GeisDBusDispatcher)context;
324 GeisDBusWatch gdb = _geis_dbus_watch_bag_find_fd_activity(dispatcher->watches,
325 fd,
326 activity);
327 if (gdb)
328 {
329 /* Translate GEIS multiplexor activity to DBus watch flags. */
330 unsigned int flags = 0;
331 if (activity & GEIS_BE_MX_READ_AVAILABLE) flags |= DBUS_WATCH_READABLE;
332 if (activity & GEIS_BE_MX_WRITE_AVAILABLE) flags |= DBUS_WATCH_WRITABLE;
333 if (activity & GEIS_BE_MX_HANGUP_DETECTED) flags |= DBUS_WATCH_HANGUP;
334 if (activity & GEIS_BE_MX_ERROR_DETECTED) flags |= DBUS_WATCH_ERROR;
335 dbus_watch_handle(gdb->watch, flags);
336
337 if (gdb->connection)
338 {
339 if (activity & GEIS_BE_MX_HANGUP_DETECTED)
340 {
341 dbus_connection_close(gdb->connection);
342 }
343 else
344 {
345 DBusDispatchStatus s;
346 s = dbus_connection_get_dispatch_status(gdb->connection);
347 while (DBUS_DISPATCH_DATA_REMAINS == s)
348 {
349 s = dbus_connection_dispatch(gdb->connection);
350 }
351 }
352 }
353 }
354}
355
356
357/*
358 * Creates a new GEIS DBus dispatcher.
359 */
360GeisDBusDispatcher
361geis_dbus_dispatcher_new(Geis geis)
362{
363 GeisDBusDispatcher dispatcher = calloc(1, sizeof(struct GeisDBusDispatcher));
364 if (!dispatcher)
365 {
366 geis_error("error allocating GEIS DBus dispatcher.");
367 goto final_exit;
368 }
369
370 dispatcher->geis = geis;
371 dispatcher->watches = _geis_dbus_watch_bag_new();
372 if (!dispatcher->watches)
373 {
374 geis_error("error creating GEIS DBus dispatcher watches.");
375 goto unwind_dispatcher;
376 }
377
378 goto final_exit;
379
380unwind_dispatcher:
381 free(dispatcher);
382final_exit:
383 return dispatcher;
384}
385
386
387/*
388 * Destroys an existing %GeisDBusDispatcher object.
389 */
390void
391geis_dbus_dispatcher_delete(GeisDBusDispatcher dispatcher)
392{
393 _geis_dbus_watch_bag_delete(dispatcher->watches);
394 free(dispatcher);
395 }
396
397
398/*
399 * Registers a new DBusWatch with a %GeisDBusDispatcher object.
400 */
401void
402geis_dbus_dispatcher_register(GeisDBusDispatcher dispatcher,
403 DBusConnection *connection,
404 DBusWatch *watch)
405{
406 int watch_fd = dbus_watch_get_unix_fd(watch);
407
408 /* Calculate all the enabled flags on the fd for all watches. */
409 unsigned int flags = 0;
410 int has_fd = _geis_dbus_watch_bag_has_fd(dispatcher->watches, watch_fd, &flags);
411 _geis_dbus_watch_bag_alloc_watch(dispatcher->watches, connection, watch);
412 if (dbus_watch_get_enabled(watch))
413 {
414 flags |= dbus_watch_get_flags(watch);
415 }
416
417 /* Convert the watch flags to multiplexor activities. */
418 GeisBackendMultiplexorActivity activity = 0;
419 if (flags & DBUS_WATCH_READABLE) activity |= GEIS_BE_MX_READ_AVAILABLE;
420 if (flags & DBUS_WATCH_WRITABLE) activity |= GEIS_BE_MX_WRITE_AVAILABLE;
421
422 /* Set or adjust the multiplexor seubscription. */
423 if (has_fd)
424 {
425 geis_remultiplex_fd(dispatcher->geis, watch_fd, activity);
426 }
427 else
428 {
429 geis_multiplex_fd(dispatcher->geis,
430 watch_fd,
431 activity,
432 _geis_dbus_dispatcher_callback,
433 dispatcher);
434 }
435}
436
437
438/*
439 * Unregisters a DBusWatch for events.
440 */
441void
442geis_dbus_dispatcher_unregister(GeisDBusDispatcher dispatcher,
443 DBusWatch *watch)
444{
445 int watch_fd = dbus_watch_get_unix_fd(watch);
446 unsigned int flags = 0;
447 _geis_dbus_watch_bag_remove_watch(dispatcher->watches, watch);
448 if (!_geis_dbus_watch_bag_has_fd(dispatcher->watches, watch_fd, &flags))
449 {
450 geis_demultiplex_fd(dispatcher->geis, watch_fd);
451 }
452}
453
454
455/*
456 * Marks a DBusWatch as active, maybe.
457 */
458void
459geis_dbus_dispatcher_toggle_watch(GeisDBusDispatcher dispatcher,
460 DBusWatch *watch)
461{
462 int watch_fd = dbus_watch_get_unix_fd(watch);
463
464 /* Calculate all the enabled flags on the fd for all watches. */
465 unsigned int flags = 0;
466 _geis_dbus_watch_bag_has_fd(dispatcher->watches, watch_fd, &flags);
467 if (dbus_watch_get_enabled(watch))
468 {
469 flags |= dbus_watch_get_flags(watch);
470 }
471 else
472 {
473 flags &= ~dbus_watch_get_flags(watch);
474 }
475
476 /* Convert the watch flags to multiplexor activities. */
477 GeisBackendMultiplexorActivity activity = 0;
478 if (flags & DBUS_WATCH_READABLE) activity |= GEIS_BE_MX_READ_AVAILABLE;
479 if (flags & DBUS_WATCH_WRITABLE) activity |= GEIS_BE_MX_WRITE_AVAILABLE;
480
481 /* Set or adjust the multiplexor seubscription. */
482 geis_remultiplex_fd(dispatcher->geis, watch_fd, activity);
483
484}
485
486
0487
=== added file 'libs/geis-dbus/geis_dbus_dispatcher.h'
--- libs/geis-dbus/geis_dbus_dispatcher.h 1970-01-01 00:00:00 +0000
+++ libs/geis-dbus/geis_dbus_dispatcher.h 2011-10-17 21:56:23 +0000
@@ -0,0 +1,116 @@
1/**
2 * @file geis_dbus_dispatcher.h
3 * @brief Interface for the GEIS DBus dispatcher.
4 *
5 * The GEIS DBus dispatcher provides a central dispatch point for all DBus
6 * events used internally by GEIS.
7 *
8 * This header is for internal GEIS use only and contains no client
9 * (externally-visible) symbols.
10 */
11
12/*
13 * Copyright 2011 Canonical Ltd.
14 *
15 * This library is free software; you can redistribute it and/or modify it under
16 * the terms of the GNU Lesser General Public License as published by the Free
17 * Software Foundation; either version 3 of the License, or (at your option) any
18 * later version.
19 *
20 * This library is distributed in the hope that it will be useful, but WITHOUT
21 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
22 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
23 * details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program. If not, see <http://www.gnu.org/licenses/>.
27 */
28#ifndef GEIS_DBUS_DISPATCHER_H_
29#define GEIS_DBUS_DISPATCHER_H_
30
31#include <dbus/dbus.h>
32#include "geis/geis.h"
33
34
35/**
36 * The %GeisDBusDispatcher centralizes all dispatch for all DBus events used
37 * internally by the GEIS client-server mechanism.
38 *
39 * Geis implements single-threaded ansynchronous dispatch for DBus events, in
40 * case a single-threaded client is making use of GEIS. This also simplifies a
41 * lot of the internal design of the GEIS DBus service, since no locking or
42 * other forms of synchronization are required.
43 */
44typedef struct GeisDBusDispatcher *GeisDBusDispatcher;
45
46/**
47 * A callback type for the handler function dispatched on DBus events.
48 *
49 * @todo the parameters of the GeisDispatchCallback must be defined.
50 */
51typedef void (*GeisDispatchCallback)(void *context);
52
53
54/**
55 * Creates a new GEIS DBus dispatcher.
56 *
57 * @param[in] geis A GEIS instance.
58 *
59 * Creates a new %GeisDBusDispatcher and registers it with the GEIS API instance
60 * so it will be multiplexed and receive event notification.
61 *
62 * @returns a new %GeisDBusDispatcher object or NULL on failure.
63 */
64GeisDBusDispatcher
65geis_dbus_dispatcher_new(Geis geis);
66
67/**
68 * Destroys an existing %GeisDBusDispatcher object.
69 *
70 * @param[in] dispatcher A %GeisDBusDispatcher object.
71 */
72void
73geis_dbus_dispatcher_delete(GeisDBusDispatcher dispatcher);
74
75/**
76 * Registers a new DBusWatch with a %GeisDBusDispatcher object.
77 *
78 * @param[in] dispatcher A %GeisDBusDispatcher object.
79 * @param[in] connection A DBus connection.
80 * @param[in] watch A DBusWatch om the connection.
81 *
82 * The @p watch will be registered with the @p dispatcher for future DBus
83 * events. The @p watch may or may not be activated, depending on its @a
84 * enabled state at the time of registration.
85 */
86void
87geis_dbus_dispatcher_register(GeisDBusDispatcher dispatcher,
88 DBusConnection *connection,
89 DBusWatch *watch);
90
91/**
92 * Unregisters a DBusWatch for events.
93 *
94 * @param[in] dispatcher A %GeisDBusDispatcher object.
95 * @param[in] watch A DBusWatch.
96 */
97void
98geis_dbus_dispatcher_unregister(GeisDBusDispatcher dispatcher,
99 DBusWatch *watch);
100
101/**
102 * Marks a DBusWatch as active or not, depending on its state.
103 *
104 * @param[in] dispatcher A %GeisDBusDispatcher object.
105 * @param[in] watch A pointer to a DBusWatch object.
106 *
107 * The @p dispatcher will listen for events on the @p watch if its @a is_enabled
108 * state is true or not.
109 */
110void
111geis_dbus_dispatcher_toggle_watch(GeisDBusDispatcher dispatcher,
112 DBusWatch *watch);
113
114
115
116#endif /* GEIS_DBUS_DISPATCHER_H_ */
0117
=== added file 'libs/geis-dbus/geis_dbus_gesture_event.c'
--- libs/geis-dbus/geis_dbus_gesture_event.c 1970-01-01 00:00:00 +0000
+++ libs/geis-dbus/geis_dbus_gesture_event.c 2011-10-17 21:56:23 +0000
@@ -0,0 +1,516 @@
1/**
2 * @file geis_dbus_gesture_event.c
3 * @brief Implementation of the GEIS DBus gesture event transport.
4 */
5
6/*
7 * Copyright 2011 Canonical Ltd.
8 *
9 * This library is free software; you can redistribute it and/or modify it under
10 * the terms of the GNU Lesser General Public License as published by the Free
11 * Software Foundation; either version 3 of the License, or (at your option) any
12 * later version.
13 *
14 * This library is distributed in the hope that it will be useful, but WITHOUT
15 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
17 * details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21 */
22#include "geis_config.h"
23#include "geis_dbus_gesture_event.h"
24
25#include "geis_attr.h"
26#include "geis_dbus.h"
27#include "geis_dbus_attr.h"
28#include "geis_event.h"
29#include "geis_group.h"
30#include "geis_logging.h"
31#include "geis_touch.h"
32
33/**
34 * A frame is marshalled as a dict entry of
35 * {id: [array of attrs, array of touch ids]}, which is {i(a(sv)ai))} in
36 * DBus terminaology.
37 */
38#define GEIS_DBUS_TYPE_SIGNATURE_FRAME \
39 DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING \
40 DBUS_TYPE_INT32_AS_STRING \
41 DBUS_STRUCT_BEGIN_CHAR_AS_STRING \
42 DBUS_TYPE_ARRAY_AS_STRING \
43 GEIS_DBUS_TYPE_SIGNATURE_ATTR \
44 DBUS_TYPE_ARRAY_AS_STRING \
45 DBUS_TYPE_INT32_AS_STRING \
46 DBUS_STRUCT_END_CHAR_AS_STRING \
47 DBUS_DICT_ENTRY_END_CHAR_AS_STRING \
48
49#define GEIS_DBUS_TYPE_SIGNATURE_FRAMESET \
50 DBUS_TYPE_ARRAY_AS_STRING \
51 GEIS_DBUS_TYPE_SIGNATURE_FRAME
52
53
54static void
55_marshall_touchset(GeisTouchSet touchset, DBusMessageIter *iter)
56{
57 DBusMessageIter touchset_iter;
58 dbus_message_iter_open_container(iter,
59 DBUS_TYPE_ARRAY,
60 DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
61 DBUS_TYPE_INT32_AS_STRING
62 DBUS_TYPE_ARRAY_AS_STRING
63 GEIS_DBUS_TYPE_SIGNATURE_ATTR
64 DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
65 &touchset_iter);
66 for (GeisSize t = 0; t < geis_touchset_touch_count(touchset); ++t)
67 {
68 DBusMessageIter touch_iter;
69 dbus_message_iter_open_container(&touchset_iter,
70 DBUS_TYPE_DICT_ENTRY,
71 NULL,
72 &touch_iter);
73 GeisTouch touch = geis_touchset_touch(touchset, t);
74 dbus_int32_t touch_id = geis_touch_id(touch);
75
76 dbus_message_iter_append_basic(&touch_iter, DBUS_TYPE_INT32, &touch_id);
77 DBusMessageIter attr_iter;
78 dbus_message_iter_open_container(&touch_iter,
79 DBUS_TYPE_ARRAY,
80 GEIS_DBUS_TYPE_SIGNATURE_ATTR,
81 &attr_iter);
82 for (GeisSize a = 0; a < geis_touch_attr_count(touch); ++a)
83 {
84 geis_dbus_attr_marshall(geis_touch_attr(touch, a), &attr_iter);
85 }
86 dbus_message_iter_close_container(&touch_iter, &attr_iter);
87 dbus_message_iter_close_container(&touchset_iter, &touch_iter);
88 }
89 dbus_message_iter_close_container(iter, &touchset_iter);
90}
91
92
93static void
94_unmarshall_touchset(DBusMessageIter *iter, GeisTouchSet touchset)
95{
96 int dtype = dbus_message_iter_get_arg_type(iter);
97 if (dtype != DBUS_TYPE_ARRAY)
98 {
99 geis_error("malformed GeisEvent touchset");
100 }
101
102 DBusMessageIter touch_iter;
103 dbus_message_iter_recurse(iter, &touch_iter);
104 for (dtype = dbus_message_iter_get_arg_type(&touch_iter);
105 dtype != DBUS_TYPE_INVALID;
106 dbus_message_iter_next(&touch_iter),
107 dtype = dbus_message_iter_get_arg_type(&touch_iter))
108 {
109 DBusMessageIter dict_iter;
110 dbus_message_iter_recurse(&touch_iter, &dict_iter);
111 int type = dbus_message_iter_get_arg_type(&dict_iter);
112 if (type != DBUS_TYPE_INT32)
113 {
114 geis_error("malformed GeisEvent touchset");
115 continue;
116 }
117 dbus_int32_t touch_id;
118 dbus_message_iter_get_basic(&dict_iter, &touch_id);
119 dbus_message_iter_next(&dict_iter);
120 GeisTouch touch = geis_touch_new(touch_id);
121
122 type = dbus_message_iter_get_arg_type(&dict_iter);
123 if (type != DBUS_TYPE_ARRAY)
124 {
125 geis_error("malformed GeisEvent touchset");
126 continue;
127 }
128
129 DBusMessageIter attr_iter;
130 dbus_message_iter_recurse(&dict_iter, &attr_iter);
131 for (int type = dbus_message_iter_get_arg_type(&attr_iter);
132 type != DBUS_TYPE_INVALID;
133 dbus_message_iter_next(&attr_iter),
134 type = dbus_message_iter_get_arg_type(&attr_iter))
135 {
136 GeisAttr attr = geis_dbus_attr_unmarshall(&attr_iter);
137 geis_touch_add_attr(touch, attr);
138 }
139 geis_touchset_insert(touchset, touch);
140 }
141}
142
143
144/**
145 * Marshalls a GEIS frame to a DBus message via a message iterator.
146 * @param[in] frame The GEIS frame to marshall.
147 * @param[in] iter The DBus message iterator.
148 *
149 * @todo The class set and matrix need to be added.
150 */
151static void
152_marshall_frame(GeisFrame frame, DBusMessageIter *frame_iter)
153{
154 DBusMessageIter dict_iter;
155 dbus_message_iter_open_container(frame_iter,
156 DBUS_TYPE_DICT_ENTRY,
157 NULL,
158 &dict_iter);
159
160 dbus_int32_t frame_id = geis_frame_id(frame);
161 dbus_message_iter_append_basic(&dict_iter, DBUS_TYPE_INT32, &frame_id);
162
163 {
164 DBusMessageIter struct_iter;
165 dbus_message_iter_open_container(&dict_iter,
166 DBUS_TYPE_STRUCT,
167 NULL,
168 &struct_iter);
169 {
170 DBusMessageIter attr_iter;
171 dbus_message_iter_open_container(&struct_iter,
172 DBUS_TYPE_ARRAY,
173 GEIS_DBUS_TYPE_SIGNATURE_ATTR,
174 &attr_iter);
175 for (GeisSize a = 0; a < geis_frame_attr_count(frame); ++a)
176 {
177 geis_dbus_attr_marshall(geis_frame_attr(frame, a), &attr_iter);
178 }
179 dbus_message_iter_close_container(&struct_iter, &attr_iter);
180 }
181 {
182 DBusMessageIter touch_iter;
183 dbus_message_iter_open_container(&struct_iter,
184 DBUS_TYPE_ARRAY,
185 DBUS_TYPE_INT32_AS_STRING,
186 &touch_iter);
187 for (GeisSize t = 0; t < geis_frame_touchid_count(frame); ++t)
188 {
189 dbus_int32_t touch_id = geis_frame_touchid(frame, t);
190 dbus_message_iter_append_basic(&touch_iter, DBUS_TYPE_INT32, &touch_id);
191 }
192 dbus_message_iter_close_container(&struct_iter, &touch_iter);
193 }
194 dbus_message_iter_close_container(&dict_iter, &struct_iter);
195 }
196 dbus_message_iter_close_container(frame_iter, &dict_iter);
197}
198
199
200/**
201 * Unmarshalls a GEIS frame from a DBus message via a message iterator.
202 * @param[in] frame_iter The DBus message iterator.
203 * @param[in] group The group the unmarshalled frame will belong to.
204 */
205static void
206_unmarshall_frame(DBusMessageIter *frame_iter, GeisGroup group)
207{
208 int type = dbus_message_iter_get_arg_type(frame_iter);
209 if (type != DBUS_TYPE_DICT_ENTRY)
210 {
211 geis_error("malformed GeisEvent frame: expected %c, received %c",
212 DBUS_TYPE_DICT_ENTRY, type);
213 goto final_exit;
214 }
215 DBusMessageIter dict_iter;
216 dbus_message_iter_recurse(frame_iter, &dict_iter);
217
218 type = dbus_message_iter_get_arg_type(&dict_iter);
219 if (type != DBUS_TYPE_INT32)
220 {
221 geis_error("malformed GeisEvent frame: expected %c, received %c",
222 DBUS_TYPE_INT32, type);
223 goto final_exit;
224 }
225 dbus_int32_t frame_id;
226 dbus_message_iter_get_basic(&dict_iter, &frame_id);
227 GeisFrame frame = geis_frame_new(frame_id);
228 geis_group_insert_frame(group, frame);
229
230 dbus_message_iter_next(&dict_iter);
231 type = dbus_message_iter_get_arg_type(&dict_iter);
232 if (type != DBUS_TYPE_STRUCT)
233 {
234 geis_error("malformed GeisEvent frame: expected %c, received %c",
235 DBUS_TYPE_STRUCT, type);
236 }
237 else
238 {
239 DBusMessageIter struct_iter;
240 dbus_message_iter_recurse(&dict_iter, &struct_iter);
241
242 type = dbus_message_iter_get_arg_type(&struct_iter);
243 if (type != DBUS_TYPE_ARRAY)
244 {
245 geis_error("malformed GeisEvent frame: expected %c, received %c",
246 DBUS_TYPE_ARRAY, type);
247 }
248 else
249 {
250 DBusMessageIter attr_iter;
251 dbus_message_iter_recurse(&struct_iter, &attr_iter);
252 for (int type = dbus_message_iter_get_arg_type(&attr_iter);
253 type != DBUS_TYPE_INVALID;
254 dbus_message_iter_next(&attr_iter),
255 type = dbus_message_iter_get_arg_type(&attr_iter))
256 {
257 GeisAttr attr = geis_dbus_attr_unmarshall(&attr_iter);
258 geis_frame_add_attr(frame, attr);
259 }
260 }
261
262 dbus_message_iter_next(&struct_iter),
263 type = dbus_message_iter_get_arg_type(&struct_iter);
264 if (type != DBUS_TYPE_ARRAY)
265 {
266 geis_error("malformed GeisEvent frame: expected %c, received %c",
267 DBUS_TYPE_ARRAY, type);
268 }
269 else
270 {
271 DBusMessageIter touch_iter;
272 dbus_message_iter_recurse(&struct_iter, &touch_iter);
273 for (int type = dbus_message_iter_get_arg_type(&touch_iter);
274 type != DBUS_TYPE_INVALID;
275 dbus_message_iter_next(&touch_iter),
276 type = dbus_message_iter_get_arg_type(&touch_iter))
277 {
278 type = dbus_message_iter_get_arg_type(&touch_iter);
279 if (type != DBUS_TYPE_INT32)
280 {
281 geis_error("malformed GeisEvent frame: expected %c, received %c",
282 DBUS_TYPE_INT32, type);
283 break;
284 }
285
286 dbus_int32_t touch_id;
287 dbus_message_iter_get_basic(&touch_iter, &touch_id);
288 geis_frame_add_touchid(frame, touch_id);
289 }
290 }
291 }
292
293final_exit:
294 return;
295}
296
297
298/**
299 * Marshalls a GEIS groupset to a DBus message via a message iterator.
300 * @param[in] groupset The GEIS groupset.
301 * @param[in] iter A DBus message iterator.
302 */
303static void
304_marshall_groupset(GeisGroupSet groupset, DBusMessageIter *iter)
305{
306 DBusMessageIter groupset_iter;
307 dbus_message_iter_open_container(iter,
308 DBUS_TYPE_ARRAY,
309 DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
310 DBUS_TYPE_INT32_AS_STRING
311 GEIS_DBUS_TYPE_SIGNATURE_FRAMESET
312 DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
313 &groupset_iter);
314 for (GeisSize i = 0; i < geis_groupset_group_count(groupset); ++i)
315 {
316 GeisGroup group = geis_groupset_group(groupset, i);
317 if (!group)
318 {
319 geis_warning("can not extract group %zu from groupset", i);
320 goto final_exit;
321 }
322 DBusMessageIter group_iter;
323 dbus_message_iter_open_container(&groupset_iter,
324 DBUS_TYPE_DICT_ENTRY,
325 NULL,
326 &group_iter);
327 dbus_int32_t group_id = geis_group_id(group);
328 dbus_message_iter_append_basic(&group_iter, DBUS_TYPE_INT32, &group_id);
329 DBusMessageIter frameset_iter;
330 dbus_message_iter_open_container(&group_iter,
331 DBUS_TYPE_ARRAY,
332 GEIS_DBUS_TYPE_SIGNATURE_FRAME,
333 &frameset_iter);
334 for (GeisSize j = 0; j < geis_group_frame_count(group); ++j)
335 {
336 GeisFrame frame = geis_group_frame(group, j);
337 if (!frame)
338 {
339 geis_warning("can not extract frame %zu from group", j);
340 goto final_exit;
341 }
342 _marshall_frame(frame, &frameset_iter);
343 }
344 dbus_message_iter_close_container(&group_iter, &frameset_iter);
345 dbus_message_iter_close_container(&groupset_iter, &group_iter);
346 }
347 dbus_message_iter_close_container(iter, &groupset_iter);
348
349final_exit:
350 return;
351}
352
353
354static void
355_unmarshall_groupset(DBusMessageIter *iter, GeisGroupSet groupset)
356{
357 int dtype = dbus_message_iter_get_arg_type(iter);
358 if (dtype != DBUS_TYPE_ARRAY)
359 {
360 geis_error("malformed GeisEvent groupset");
361 }
362
363 DBusMessageIter groupset_iter;
364 dbus_message_iter_recurse(iter, &groupset_iter);
365 for (dtype = dbus_message_iter_get_arg_type(&groupset_iter);
366 dtype != DBUS_TYPE_INVALID;
367 dbus_message_iter_next(&groupset_iter),
368 dtype = dbus_message_iter_get_arg_type(&groupset_iter))
369 {
370 DBusMessageIter group_iter;
371 dbus_message_iter_recurse(&groupset_iter, &group_iter);
372
373 int type = dbus_message_iter_get_arg_type(&group_iter);
374 if (type != DBUS_TYPE_INT32)
375 {
376 geis_error("malformed GeisEvent group");
377 continue;
378 }
379 dbus_int32_t group_id;
380 dbus_message_iter_get_basic(&group_iter, &group_id);
381 GeisGroup group = geis_group_new(group_id);
382 geis_groupset_insert(groupset, group);
383 dbus_message_iter_next(&group_iter);
384
385 DBusMessageIter frameset_iter;
386 dbus_message_iter_recurse(&group_iter, &frameset_iter);
387 for (int ftype = dbus_message_iter_get_arg_type(&frameset_iter);
388 ftype != DBUS_TYPE_INVALID;
389 dbus_message_iter_next(&frameset_iter),
390 ftype = dbus_message_iter_get_arg_type(&frameset_iter))
391 {
392 _unmarshall_frame(&frameset_iter, group);
393 }
394 }
395}
396
397
398/*
399 * Creates a Dbus "gesture event" message from a GEIS gesture event.
400 *
401 * A gesture event has the following structure.
402 * - a numeric event type (begin/update/end)
403 * - a set of one or more touches, where each touch has
404 * - a touch ID
405 * - a set of one or more attrs
406 * - a set of one or more gesture groups, where is group has
407 * - a group ID
408 * - a set of one or more gesture frames, where each frame has
409 * - a set of one or more gesture classes
410 * - a set of one or more gesture attrs
411 * - a zet of one or more touch indexes
412 *
413 * @todo add the gesture classes
414 */
415DBusMessage *
416geis_dbus_gesture_event_message_from_geis_event(GeisEvent event)
417{
418 DBusMessage *message = dbus_message_new_signal(GEIS_DBUS_SERVICE_PATH,
419 GEIS_DBUS_SERVICE_INTERFACE,
420 GEIS_DBUS_GESTURE_EVENT);
421 DBusMessageIter iter;
422 dbus_message_iter_init_append(message, &iter);
423
424 dbus_uint32_t event_type = geis_event_type(event);
425 dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &event_type);
426
427 GeisAttr attr = geis_event_attr_by_name(event, GEIS_EVENT_ATTRIBUTE_TOUCHSET);
428 if (!attr)
429 {
430 geis_error("no touchset for gesture event");
431 goto final_exit;
432 }
433
434 GeisTouchSet touchset = geis_attr_value_to_pointer(attr);
435 if (!touchset)
436 {
437 geis_warning("can not convert attr to touchset");
438 goto final_exit;
439 }
440
441 _marshall_touchset(touchset, &iter);
442
443 attr = geis_event_attr_by_name(event, GEIS_EVENT_ATTRIBUTE_GROUPSET);
444 if (!attr)
445 {
446 geis_error("no groupset for gesture event");
447 goto final_exit;
448 }
449
450 GeisGroupSet groupset = geis_attr_value_to_pointer(attr);
451 if (!groupset)
452 {
453 geis_warning("can not convert attr to groupset");
454 goto final_exit;
455 }
456
457 _marshall_groupset(groupset, &iter);
458
459final_exit:
460 return message;
461}
462
463
464/*
465 * Indicates if a DBus message is a "gesture event" message.
466 */
467GeisBoolean
468geis_dbus_message_is_gesture_event(DBusMessage *message)
469{
470 GeisBoolean is_gesture_event_message = GEIS_FALSE;
471 if (dbus_message_is_signal(message,
472 GEIS_DBUS_SERVICE_INTERFACE,
473 GEIS_DBUS_GESTURE_EVENT))
474 {
475 is_gesture_event_message = GEIS_TRUE;
476 }
477
478 return is_gesture_event_message;
479}
480
481
482/*
483 * Creates GEIS event from a DBus "gesture_event" message.
484 */
485GeisEvent
486geis_dbus_gesture_event_from_message(DBusMessage *message)
487{
488 DBusMessageIter iter;
489 dbus_message_iter_init(message, &iter);
490
491 dbus_uint32_t event_type;
492 dbus_message_iter_get_basic(&iter, &event_type);
493 GeisEvent event = geis_event_new(event_type);
494
495 dbus_message_iter_next(&iter);
496 GeisTouchSet touchset = geis_touchset_new();
497 _unmarshall_touchset(&iter, touchset);
498 GeisAttr touch_attr = geis_attr_new(GEIS_EVENT_ATTRIBUTE_TOUCHSET,
499 GEIS_ATTR_TYPE_POINTER,
500 touchset);
501 geis_attr_set_destructor(touch_attr, (GeisAttrDestructor)geis_touchset_delete);
502 geis_event_add_attr(event, touch_attr);
503
504 dbus_message_iter_next(&iter);
505 GeisGroupSet groupset = geis_groupset_new();
506 _unmarshall_groupset(&iter, groupset);
507 GeisAttr group_attr = geis_attr_new(GEIS_EVENT_ATTRIBUTE_GROUPSET,
508 GEIS_ATTR_TYPE_POINTER,
509 groupset);
510 geis_attr_set_destructor(group_attr, (GeisAttrDestructor)geis_groupset_delete);
511 geis_event_add_attr(event, group_attr);
512
513 return event;
514}
515
516
0517
=== added file 'libs/geis-dbus/geis_dbus_gesture_event.h'
--- libs/geis-dbus/geis_dbus_gesture_event.h 1970-01-01 00:00:00 +0000
+++ libs/geis-dbus/geis_dbus_gesture_event.h 2011-10-17 21:56:23 +0000
@@ -0,0 +1,55 @@
1/**
2 * @file geis_dbus_gesture_event.h
3 * @brief Interface for the GEIS DBus gesture event transport.
4 */
5
6/*
7 * Copyright 2011 Canonical Ltd.
8 *
9 * This library is free software; you can redistribute it and/or modify it under
10 * the terms of the GNU Lesser General Public License as published by the Free
11 * Software Foundation; either version 3 of the License, or (at your option) any
12 * later version.
13 *
14 * This library is distributed in the hope that it will be useful, but WITHOUT
15 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
17 * details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21 */
22#ifndef GEIS_DBUS_GESTURE_EVENT_H_
23#define GEIS_DBUS_GESTURE_EVENT_H_
24
25#include <dbus/dbus.h>
26#include "geis/geis.h"
27
28
29/**
30 * Creates a Dbus "gesture event" message from a GEIS gesture event.
31 *
32 * @param[in] event A GEIS event.
33 */
34DBusMessage *
35geis_dbus_gesture_event_message_from_geis_event(GeisEvent event);
36
37/**
38 * Indicates if a DBus message is a "gesture event" message.
39 *
40 * @param[in] message A DBus message.
41 */
42GeisBoolean
43geis_dbus_message_is_gesture_event(DBusMessage *message);
44
45/**
46 * Creates GEIS event from a DBus "gesture_event" message.
47 *
48 * @param[in] message A DBus message.
49 */
50GeisEvent
51geis_dbus_gesture_event_from_message(DBusMessage *message);
52
53
54#endif /* GEIS_DBUS_GESTURE_EVENT_H_ */
55
056
=== added file 'libs/geis-dbus/geis_dbus_region.c'
--- libs/geis-dbus/geis_dbus_region.c 1970-01-01 00:00:00 +0000
+++ libs/geis-dbus/geis_dbus_region.c 2011-10-17 21:56:23 +0000
@@ -0,0 +1,91 @@
1/**
2 * @file geis_dbus_region.c
3 * @brief Implementations of the GEIS DBus region transport.
4 */
5
6/*
7 * Copyright 2011 Canonical Ltd.
8 *
9 * This library is free software; you can redistribute it and/or modify it under
10 * the terms of the GNU Lesser General Public License as published by the Free
11 * Software Foundation; either version 3 of the License, or (at your option) any
12 * later version.
13 *
14 * This library is distributed in the hope that it will be useful, but WITHOUT
15 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
17 * details.
18 *
19 * You should have received a copy of the GNU Lesser General Public License
20 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21 */
22#include "geis_config.h"
23#include "geis_dbus_region.h"
24
25#include "geis_dbus.h"
26#include "geis_logging.h"
27
28
29/*
30 * Creates a Dbus "region available" message from a GEIS region.
31 */
32DBusMessage *
33geis_dbus_region_available_message_from_region(GeisFilterableAttribute fa)
34{
35 DBusMessage *message = dbus_message_new_signal(GEIS_DBUS_SERVICE_PATH,
36 GEIS_DBUS_SERVICE_INTERFACE,
37 GEIS_DBUS_REGION_AVAILABLE);
38 DBusMessageIter iter;
39 dbus_message_iter_init_append(message, &iter);
40
41 const char *attr_name = fa->name;
42 dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &attr_name);
43
44 dbus_int32_t attr_type = fa->type;
45 dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &attr_type);
46
47
48 return message;
49}
50
51
52/*
53 * Creates GEIS region filterable attribute from a DBus "region available"
54 * message.
55 */
56GeisFilterableAttribute
57geis_dbus_region_from_region_available_message(DBusMessage *message)
58{
59 geis_debug("begins");
60 static struct GeisFilterableAttribute attr;
61 DBusMessageIter iter;
62 dbus_message_iter_init(message, &iter);
63
64 int type = dbus_message_iter_get_arg_type(&iter);
65 if (type != DBUS_TYPE_STRING)
66 {
67 geis_error("error getting attr name name from DBus message.");
68 goto final_exit;
69 }
70 char *attr_name;
71 dbus_message_iter_get_basic(&iter, &attr_name);
72 dbus_message_iter_next(&iter);
73
74 type = dbus_message_iter_get_arg_type(&iter);
75 if (type != DBUS_TYPE_INT32)
76 {
77 geis_error("error getting attr type from DBus message.");
78 goto final_exit;
79 }
80 dbus_int32_t attr_type;
81 dbus_message_iter_get_basic(&iter, &attr_type);
82
83 attr.name = attr_name;
84 attr.type = attr_type;
85
86final_exit:
87 geis_debug("ends");
88 return &attr;
89}
90
91
092
=== added file 'libs/geis-dbus/geis_dbus_region.h'
--- libs/geis-dbus/geis_dbus_region.h 1970-01-01 00:00:00 +0000
+++ libs/geis-dbus/geis_dbus_region.h 2011-10-17 21:56:23 +0000
@@ -0,0 +1,47 @@
1/**
2 * @file geis_dbus_region.h
3 * @brief Interface for the GEIS DBus region transport.
4 */
5
6/*
7 * Copyright 2011 Canonical Ltd.
8 *
9 * This library is free software; you can redistribute it and/or modify it under
10 * the terms of the GNU Lesser General Public License as published by the Free
11 * Software Foundation; either version 3 of the License, or (at your option) any
12 * later version.
13 *
14 * This library is distributed in the hope that it will be useful, but WITHOUT
15 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
17 * details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21 */
22#ifndef GEIS_DBUS_REGION_H_
23#define GEIS_DBUS_REGION_H_
24
25#include <dbus/dbus.h>
26#include "geis/geis.h"
27#include "geis_filterable.h"
28
29
30/**
31 * Creates a Dbus "region available" message from a GEIS region.
32 *
33 * @param[in] fa A GEIS region filterable attribute.
34 */
35DBusMessage *
36geis_dbus_region_available_message_from_region(GeisFilterableAttribute fa);
37
38/**
39 * Creates GEIS region filterable attribute from a DBus "region available"
40 * message.
41 *
42 * @param[in] message A DBus message.
43 */
44GeisFilterableAttribute
45geis_dbus_region_from_region_available_message(DBusMessage *message);
46
47#endif /* GEIS_DBUS_REGION_H_ */
048
=== added file 'libs/geis-dbus/geis_dbus_subscription.c'
--- libs/geis-dbus/geis_dbus_subscription.c 1970-01-01 00:00:00 +0000
+++ libs/geis-dbus/geis_dbus_subscription.c 2011-10-17 21:56:23 +0000
@@ -0,0 +1,506 @@
1/**
2 * @file geis_dbus_subscription.c
3 * @brief Implementation of the GEIS DBus subscription transport.
4 */
5
6/*
7 * Copyright 2011 Canonical Ltd.
8 *
9 * This library is free software; you can redistribute it and/or modify it under
10 * the terms of the GNU Lesser General Public License as published by the Free
11 * Software Foundation; either version 3 of the License, or (at your option) any
12 * later version.
13 *
14 * This library is distributed in the hope that it will be useful, but WITHOUT
15 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
17 * details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21 */
22#include "geis_config.h"
23#include "geis_dbus_subscription.h"
24
25#include "geis_dbus.h"
26#include "geis_dbus_attr.h"
27#include "geis_filter_term.h"
28#include "geis_logging.h"
29#include "geis_subscription.h"
30#include <stdint.h>
31
32
33/*
34 * A filter term is marshalled as a (facility, operation, value) tuple.
35 * That would be a (ii(sv)) in DBusspeak.
36 */
37#define GEIS_DBUS_TYPE_SIGNATURE_TERM \
38 DBUS_STRUCT_BEGIN_CHAR_AS_STRING \
39 DBUS_TYPE_INT32_AS_STRING \
40 DBUS_TYPE_INT32_AS_STRING \
41 GEIS_DBUS_TYPE_SIGNATURE_ATTR \
42 DBUS_STRUCT_END_CHAR_AS_STRING
43
44/*
45 * A term list is an array of terms, as in a(ii(sv)).
46 */
47#define GEIS_DBUS_TYPE_SIGNATURE_TERM_LIST \
48 DBUS_TYPE_ARRAY_AS_STRING \
49 GEIS_DBUS_TYPE_SIGNATURE_TERM
50
51/*
52 * A filter is a named array of filter terms.
53 * That's a {sa(ii(sv))} in the DBus tongue.
54 */
55#define GEIS_DBUS_TYPE_SIGNATURE_FILTER \
56 DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING \
57 DBUS_TYPE_STRING_AS_STRING \
58 GEIS_DBUS_TYPE_SIGNATURE_TERM_LIST \
59 DBUS_DICT_ENTRY_END_CHAR_AS_STRING
60
61
62/**
63 * Adds filter terms to a DBus message.
64 *
65 * @param[in] filter The filter for which terms will be marshalled.
66 * @param[in] filter_iter A DBus message output iterator.
67 */
68static void
69_geis_dbus_marshall_subscription_filter_terms(GeisFilter filter,
70 DBusMessageIter *filter_iter)
71{
72 DBusMessageIter term_list_iter;
73 dbus_message_iter_open_container(filter_iter,
74 DBUS_TYPE_ARRAY,
75 GEIS_DBUS_TYPE_SIGNATURE_TERM,
76 &term_list_iter);
77 for (GeisSize i = 0; i < geis_filter_term_count(filter); ++i)
78 {
79 GeisFilterTerm term = geis_filter_term(filter, i);
80 dbus_int32_t facility = geis_filter_term_facility(term);
81 dbus_int32_t operation = geis_filter_term_operation(term);
82 GeisAttr attr = geis_filter_term_attr(term);
83
84 DBusMessageIter term_iter;
85 dbus_message_iter_open_container(&term_list_iter,
86 DBUS_TYPE_STRUCT,
87 NULL,
88 &term_iter);
89 dbus_message_iter_append_basic(&term_iter, DBUS_TYPE_INT32, &facility);
90 dbus_message_iter_append_basic(&term_iter, DBUS_TYPE_INT32, &operation);
91 geis_dbus_attr_marshall(attr, &term_iter);
92 dbus_message_iter_close_container(&term_list_iter, &term_iter);
93 }
94 dbus_message_iter_close_container(filter_iter, &term_list_iter);
95}
96
97
98/**
99 * Squeezes the filters on a subscription into the DBus wire protocol.
100 *
101 * @param[in] sub A %GeisSubscription
102 * @param[in] msg_iter The open output iterator for a DBus message.
103 *
104 * The filters are marshalled as an array of DBus dict entries.
105 */
106static void
107_geis_dbus_marshall_subscription_filters(GeisSubscription subscription,
108 DBusMessageIter *msg_iter)
109{
110 DBusMessageIter filter_list_iter;
111
112 dbus_message_iter_open_container(msg_iter,
113 DBUS_TYPE_ARRAY,
114 GEIS_DBUS_TYPE_SIGNATURE_FILTER,
115 &filter_list_iter);
116
117 for (GeisFilterIterator it = geis_subscription_filter_begin(subscription);
118 it != geis_subscription_filter_end(subscription);
119 it = geis_subscription_filter_next(subscription, it))
120 {
121 const char *filter_name = geis_filter_name(*it);
122
123 DBusMessageIter filter_iter;
124 dbus_message_iter_open_container(&filter_list_iter,
125 DBUS_TYPE_DICT_ENTRY,
126 NULL,
127 &filter_iter);
128 dbus_message_iter_append_basic(&filter_iter, DBUS_TYPE_STRING, &filter_name);
129 _geis_dbus_marshall_subscription_filter_terms(*it, &filter_iter);
130 dbus_message_iter_close_container(&filter_list_iter, &filter_iter);
131 }
132 dbus_message_iter_close_container(msg_iter, &filter_list_iter);
133}
134
135
136static void
137_geis_dbus_unmarshall_filter_terms(GeisFilter filter,
138 DBusMessageIter *filter_iter)
139{
140 DBusMessageIter term_list_iter;
141 dbus_message_iter_recurse(filter_iter, &term_list_iter);
142 for (int dtype = dbus_message_iter_get_arg_type(&term_list_iter);
143 dtype != DBUS_TYPE_INVALID;
144 dbus_message_iter_next(&term_list_iter),
145 dtype = dbus_message_iter_get_arg_type(&term_list_iter))
146 {
147 int ttype = dbus_message_iter_get_arg_type(&term_list_iter);
148 if (ttype != DBUS_TYPE_STRUCT)
149 {
150 geis_error("malformed GeisSubscription term");
151 goto final_exit;
152 }
153
154 DBusMessageIter term_iter;
155 dbus_message_iter_recurse(&term_list_iter, &term_iter);
156
157 dbus_int32_t facility;
158 dbus_message_iter_get_basic(&term_iter, &facility);
159 dbus_message_iter_next(&term_iter);
160
161 dbus_int32_t operation;
162 dbus_message_iter_get_basic(&term_iter, &operation);
163 dbus_message_iter_next(&term_iter);
164
165 GeisAttr attr = geis_dbus_attr_unmarshall(&term_iter);
166 GeisFilterTerm term = geis_filter_term_new(facility, operation, attr);
167 geis_filter_add_term_internal(filter, term);
168 }
169
170final_exit:
171 return;
172}
173
174
175/**
176 * Unmarshalls a filter from a DBus message.
177 *
178 * @param[in] geis A GEIS instance.
179 * @param[in] filter_iter A DBus message iterator pointing to the filter.
180 */
181static GeisFilter
182_geis_dbus_unmarshall_filter(Geis geis, DBusMessageIter *filter_iter)
183{
184 GeisFilter filter = NULL;
185
186 int ftype = dbus_message_iter_get_arg_type(filter_iter);
187 if (ftype != DBUS_TYPE_DICT_ENTRY)
188 {
189 geis_error("malformed GeisSubscription filter");
190 goto final_exit;
191 }
192
193 DBusMessageIter dict_iter;
194 dbus_message_iter_recurse(filter_iter, &dict_iter);
195
196 ftype = dbus_message_iter_get_arg_type(&dict_iter);
197 if (ftype != DBUS_TYPE_STRING)
198 {
199 geis_error("malformed GeisSubscription filter");
200 goto final_exit;
201 }
202 GeisString filter_name;
203 dbus_message_iter_get_basic(&dict_iter, &filter_name);
204 dbus_message_iter_next(&dict_iter);
205
206 filter = geis_filter_new(geis, filter_name);
207
208 ftype = dbus_message_iter_get_arg_type(&dict_iter);
209 if (ftype != DBUS_TYPE_ARRAY)
210 {
211 geis_error("malformed GeisSubscription filter");
212 goto final_exit;
213 }
214 _geis_dbus_unmarshall_filter_terms(filter, &dict_iter);
215
216final_exit:
217 return filter;
218}
219
220
221/**
222 * Unmarshalls a list of filters from a DBus message.
223 *
224 * @param[in] geis A GEIS instance.
225 * @param[in] subscription_iter A DBus message iterator for the subscription.
226 * @param[in] subscription A GEIS subsccription.
227 *
228 * This function unmarshalls filters from a GEIS DBus subscription message and
229 * adds them to a existing GEIS subscription.
230 */
231static void
232_geis_dbus_unmarshall_subscription_filters(Geis geis,
233 DBusMessageIter *subscription_iter,
234 GeisSubscription subscription)
235{
236 DBusMessageIter filter_list_iter;
237 dbus_message_iter_recurse(subscription_iter, &filter_list_iter);
238 for (int dtype = dbus_message_iter_get_arg_type(&filter_list_iter);
239 dtype != DBUS_TYPE_INVALID;
240 dbus_message_iter_next(&filter_list_iter),
241 dtype = dbus_message_iter_get_arg_type(&filter_list_iter))
242 {
243 GeisFilter filter = _geis_dbus_unmarshall_filter(geis, &filter_list_iter);
244 if (filter)
245 {
246 geis_subscription_add_filter(subscription, filter);
247 }
248 }
249}
250
251
252/*
253 * Indicates if a DBus message is a GEIS_DBUS_SUBSCRIPTION_CREATE method call.
254 */
255GeisBoolean
256geis_dbus_message_is_subscription_create_call(DBusMessage *message)
257{
258 return dbus_message_is_method_call(message,
259 GEIS_DBUS_SERVICE_INTERFACE,
260 GEIS_DBUS_SUBSCRIPTION_CREATE);
261}
262
263
264/*
265 * Creates a GEIS_DBUS_SUBSCRIPTION_CREATE method call message.
266 */
267DBusMessage *
268geis_dbus_subscription_create_call_message(GeisSubscription subscription)
269{
270 DBusMessage *message = NULL;
271 GeisString sub_name = "dummy";
272 dbus_int32_t sub_id = -1;
273 dbus_uint32_t sub_flags = 0;
274 DBusMessageIter iter;
275
276 message = dbus_message_new_method_call(GEIS_DBUS_SERVICE_INTERFACE,
277 GEIS_DBUS_SERVICE_PATH,
278 GEIS_DBUS_SERVICE_INTERFACE,
279 GEIS_DBUS_SUBSCRIPTION_CREATE);
280
281 if (subscription)
282 {
283 sub_name = geis_subscription_name(subscription);
284 sub_id = geis_subscription_id(subscription);
285 sub_flags = geis_subscription_flags(subscription);
286 }
287 dbus_message_iter_init_append(message, &iter);
288
289 dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &sub_name);
290 dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &sub_id);
291 dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &sub_flags);
292 _geis_dbus_marshall_subscription_filters(subscription, &iter);
293
294 return message;
295}
296
297
298/*
299 * Creates a %GeisSubscription from a method call message.
300 */
301GeisSubscription
302geis_dbus_subscription_from_create_call_message(Geis geis, DBusMessage *message)
303{
304 DBusMessageIter message_iter;
305 dbus_message_iter_init(message, &message_iter);
306
307 GeisString client_sub_name;
308 dbus_message_iter_get_basic(&message_iter, &client_sub_name);
309 dbus_message_iter_next(&message_iter);
310
311 dbus_int32_t client_sub_id;
312 dbus_message_iter_get_basic(&message_iter, &client_sub_id);
313 dbus_message_iter_next(&message_iter);
314
315 dbus_uint32_t client_sub_flags;
316 dbus_message_iter_get_basic(&message_iter, &client_sub_flags);
317 dbus_message_iter_next(&message_iter);
318
319 GeisSubscription subscription = NULL;
320 subscription = geis_subscription_new(geis, client_sub_name, client_sub_flags);
321 if (!subscription)
322 {
323 geis_error("error creating proxy subscription");
324 goto final_exit;
325 }
326 intptr_t fudge = client_sub_id;
327 geis_subscription_set_pdata(subscription, (GeisPointer)fudge);
328
329 int dtype = dbus_message_iter_get_arg_type(&message_iter);
330 if (dtype != DBUS_TYPE_ARRAY)
331 {
332 geis_error("malformed GeisSubscription message"
333 " (expected type %c, received type %c)",
334 DBUS_TYPE_ARRAY, dtype);
335 goto final_exit;
336 }
337
338 _geis_dbus_unmarshall_subscription_filters(geis, &message_iter, subscription);
339
340final_exit:
341 return subscription;
342}
343
344
345/*
346 * Creates a GEIS_DBUS_SUBSCRIPTION_CREATE method return message.
347 */
348DBusMessage *
349geis_dbus_subscription_create_return_message(DBusMessage *message,
350 GeisSubscription subscription)
351{
352 DBusMessage *reply = dbus_message_new_method_return(message);
353 intptr_t fudge = (intptr_t)geis_subscription_pdata(subscription);
354 dbus_int32_t client_sub_id = fudge;
355 dbus_int32_t server_sub_id = geis_subscription_id(subscription);
356 dbus_message_append_args(reply,
357 DBUS_TYPE_INT32, &client_sub_id,
358 DBUS_TYPE_INT32, &server_sub_id,
359 DBUS_TYPE_INVALID);
360
361 return reply;
362}
363
364
365/*
366 * Indicates if a DBus message is a GEIS_DBUS_SUBSCRIPTION_ACTIVATE message.
367 */
368GeisBoolean
369geis_dbus_message_is_subscription_activate_call(DBusMessage *message)
370{
371 return dbus_message_is_method_call(message,
372 GEIS_DBUS_SERVICE_INTERFACE,
373 GEIS_DBUS_SUBSCRIPTION_ACTIVATE);
374}
375
376
377/*
378 * Creates a GEIS_DBUS_SUBSCRIPTION_ACTIVATE method call message.
379 */
380DBusMessage *
381geis_dbus_subscription_activate_call_message(GeisSubscription subscription)
382{
383 DBusMessage *message = NULL;
384 DBusMessageIter iter;
385
386 message = dbus_message_new_method_call(GEIS_DBUS_SERVICE_INTERFACE,
387 GEIS_DBUS_SERVICE_PATH,
388 GEIS_DBUS_SERVICE_INTERFACE,
389 GEIS_DBUS_SUBSCRIPTION_ACTIVATE);
390 dbus_message_iter_init_append(message, &iter);
391
392 dbus_int32_t subscription_id = geis_subscription_id(subscription);
393 dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &subscription_id);
394 _geis_dbus_marshall_subscription_filters(subscription, &iter);
395 return message;
396}
397
398
399/*
400 * Creates a GEIS_DBUS_SUBSCRIPTION_ACTIVATE method return message.
401 */
402DBusMessage *
403geis_dbus_subscription_activate_return_message(DBusMessage *message,
404 GeisSubscription subscription)
405{
406 DBusMessage *reply = NULL;
407 reply = dbus_message_new_method_return(message);
408 dbus_int32_t subscription_id = -1;
409
410 if (subscription)
411 {
412 subscription_id = geis_subscription_id(subscription);
413 }
414 dbus_message_append_args(reply,
415 DBUS_TYPE_INT32, &subscription_id,
416 DBUS_TYPE_INVALID);
417 return reply;
418}
419
420
421/*
422 * Indicates if a DBus message is a GEIS_DBUS_SUBSCRIPTION_DEACTIVATE message.
423 */
424GeisBoolean
425geis_dbus_message_is_subscription_deactivate_call(DBusMessage *message)
426{
427 return dbus_message_is_method_call(message,
428 GEIS_DBUS_SERVICE_INTERFACE,
429 GEIS_DBUS_SUBSCRIPTION_DEACTIVATE);
430}
431
432
433/*
434 * Creates a GEIS_DBUS_SUBSCRIPTION_DEACTIVATE method call message.
435 */
436DBusMessage *
437geis_dbus_subscription_deactivate_call_message(GeisSubscription subscription GEIS_UNUSED)
438{
439 DBusMessage *message = NULL;
440 message = dbus_message_new_method_call(GEIS_DBUS_SERVICE_INTERFACE,
441 GEIS_DBUS_SERVICE_PATH,
442 GEIS_DBUS_SERVICE_INTERFACE,
443 GEIS_DBUS_SUBSCRIPTION_DEACTIVATE);
444 return message;
445}
446
447
448/**
449 */
450DBusMessage *
451geis_dbus_subscription_deactivate_return_message(DBusMessage *message,
452 GeisSubscription subscription)
453{
454 DBusMessage *reply = NULL;
455 reply = dbus_message_new_method_return(message);
456 dbus_int32_t subscription_id = geis_subscription_id(subscription);
457 dbus_message_append_args(reply,
458 DBUS_TYPE_INT32, &subscription_id,
459 DBUS_TYPE_INVALID);
460 return reply;
461}
462
463
464/*
465 * Indicates if a DBus message is a GEIS_DBUS_SUBSCRIPTION_DESTROY message.
466 */
467GeisBoolean
468geis_dbus_message_is_subscription_destroy_call(DBusMessage *message)
469{
470 return dbus_message_is_method_call(message,
471 GEIS_DBUS_SERVICE_INTERFACE,
472 GEIS_DBUS_SUBSCRIPTION_DESTROY);
473}
474
475
476/*
477 * Creates a GEIS_DBUS_SUBSCRIPTION_DESTROY method call message.
478 */
479DBusMessage *
480geis_dbus_subscription_destroy_call_message(GeisSubscription subscription)
481{
482 DBusMessage *message = NULL;
483 message = dbus_message_new_method_call(GEIS_DBUS_SERVICE_INTERFACE,
484 GEIS_DBUS_SERVICE_PATH,
485 GEIS_DBUS_SERVICE_INTERFACE,
486 GEIS_DBUS_SUBSCRIPTION_DESTROY);
487
488 dbus_int32_t server_sub_id = (intptr_t)geis_subscription_pdata(subscription);
489 dbus_message_append_args(message,
490 DBUS_TYPE_INT32, &server_sub_id,
491 DBUS_TYPE_INVALID);
492
493 return message;
494}
495
496
497/*
498 * Creates a GEIS_DBUS_SUBSCRIPTION_DESTROY method return message.
499 */
500DBusMessage *
501geis_dbus_subscription_destroy_return_message(DBusMessage *message)
502{
503 return dbus_message_new_method_return(message);
504}
505
506
0507
=== added file 'libs/geis-dbus/geis_dbus_subscription.h'
--- libs/geis-dbus/geis_dbus_subscription.h 1970-01-01 00:00:00 +0000
+++ libs/geis-dbus/geis_dbus_subscription.h 2011-10-17 21:56:23 +0000
@@ -0,0 +1,206 @@
1/**
2 * @file geis_dbus_subscription.h
3 * @brief Interface for the GEIS DBus subscription transport.
4 */
5
6/*
7 * Copyright 2011 Canonical Ltd.
8 *
9 * This library is free software; you can redistribute it and/or modify it under
10 * the terms of the GNU Lesser General Public License as published by the Free
11 * Software Foundation; either version 3 of the License, or (at your option) any
12 * later version.
13 *
14 * This library is distributed in the hope that it will be useful, but WITHOUT
15 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
17 * details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21 */
22#ifndef GEIS_DBUS_SUBSCRIPTION_H_
23#define GEIS_DBUS_SUBSCRIPTION_H_
24
25#include <dbus/dbus.h>
26#include "geis/geis.h"
27
28
29/**
30 * Indicates if a DBus message is a GEIS_DBUS_SUBSCRIPTION_CREATE method call.
31 *
32 * @param[in] message A DBus message.
33 *
34 * This function is used on the server side to identify if a received message is
35 * a GEIS_DBUS_SUBSCRIPTION_CREATE method call.
36 *
37 * @returns GEIS_TRUE if the message is GEIS_DBUS_SUBSCRIPTION_CREATE,
38 * GEIS_FALSE otherwise.
39 */
40GeisBoolean
41geis_dbus_message_is_subscription_create_call(DBusMessage *message);
42
43/**
44 * Creates a GEIS_DBUS_SUBSCRIPTION_CREATE method call message.
45 *
46 * @param[in] subscription A GEIS subscription.
47 *
48 * This function is used on the client side to create a
49 * GEIS_DBUS_SUBSCRIPTION_CREATE method call message from a local
50 * %GeisSubscription object.
51 *
52 * @returns A DBus message object.
53 */
54DBusMessage *
55geis_dbus_subscription_create_call_message(GeisSubscription subscription);
56
57/**
58 * Creates a %GeisSubscription from a GEIS_DBUS_SUBSCRIPTION_CREATE method call
59 * message.
60 *
61 * @param[in] geis A %Geis instance.
62 * @param[in] message A DBus message.
63 *
64 * This function is used on the server side to create a subscription object to
65 * proxy the client-side subscription object.
66 *
67 * @returns a %GeisSubscription or NULL on failure.
68 */
69GeisSubscription
70geis_dbus_subscription_from_create_call_message(Geis geis, DBusMessage *message);
71
72/**
73 * Creates a GEIS_DBUS_SUBSCRIPTION_CREATE method return message.
74 *
75 * @param[in] message The DBUs method_call message to reply to.
76 * @param[in] subscription A GEIS subscription.
77 *
78 * This function is used on the server side to create a response to a received
79 * GEIS_DBUS_SUBSCRIPTION_CREATE method call message.
80 *
81 * @returns A DBus message object.
82 */
83DBusMessage *
84geis_dbus_subscription_create_return_message(DBusMessage *message,
85 GeisSubscription subscription);
86
87/**
88 * Indicates if a DBus message is a GEIS_DBUS_SUBSCRIPTION_ACTIVATE message.
89 *
90 * @param[in] message A DBus message.
91 *
92 * @returns GEIS_TRUE if the message is GEIS_DBUS_SUBSCRIPTION_ACTIVATE,
93 * GEIS_FALSE otherwise.
94 */
95GeisBoolean
96geis_dbus_message_is_subscription_activate_call(DBusMessage *message);
97
98/**
99 * Creates a GEIS_DBUS_SUBSCRIPTION_ACTIVATE method call message.
100 *
101 * @param[in] subscription A GEIS subscription.
102 *
103 * This function is used on the client side to create a
104 * GEIS_DBUS_SUBSCRIPTION_ACTIVATE method call message from a local
105 * %GeisSubscription object.
106 *
107 * @returns A DBus message object.
108 */
109DBusMessage *
110geis_dbus_subscription_activate_call_message(GeisSubscription subscription);
111
112/**
113 * Creates a GEIS_DBUS_SUBSCRIPTION_ACTIVATE method return message.
114 *
115 * @param[in] message The DBUs method_call message to reply to.
116 * @param[in] subscription A GEIS subscription.
117 *
118 * This function is used on the server side to create a response to a received
119 * GEIS_DBUS_SUBSCRIPTION_ACTIVATE method call message.
120 *
121 * @returns A DBus message object.
122 */
123DBusMessage *
124geis_dbus_subscription_activate_return_message(DBusMessage *message,
125 GeisSubscription subscription);
126
127/**
128 * Indicates if a DBus message is a GEIS_DBUS_SUBSCRIPTION_DEACTIVATE message.
129 *
130 * @param[in] message A DBus message.
131 *
132 * @returns GEIS_TRUE if the message is GEIS_DBUS_SUBSCRIPTION_DEACTIVATE,
133 * GEIS_FALSE otherwise.
134 */
135GeisBoolean
136geis_dbus_message_is_subscription_deactivate_call(DBusMessage *message);
137
138/**
139 * Creates a GEIS_DBUS_SUBSCRIPTION_DEACTIVATE method return message.
140 *
141 * @param[in] message The DBUs method_call message to reply to.
142 * @param[in] subscription A GEIS subscription.
143 *
144 * This function is used on the server side to create a response to a received
145 * GEIS_DBUS_SUBSCRIPTION_DEACTIVATE method call message.
146 *
147 * @returns A DBus message object.
148 */
149DBusMessage *
150geis_dbus_subscription_deactivate_return_message(DBusMessage *message,
151 GeisSubscription subscription);
152
153/**
154 * Creates a GEIS_DBUS_SUBSCRIPTION_DEACTIVATE method call message.
155 *
156 * @param[in] subscription A GEIS subscription.
157 *
158 * This function is used on the client side to create a
159 * GEIS_DBUS_SUBSCRIPTION_DEACTIVATE method call message from a local
160 * %GeisSubscription object.
161 *
162 * @returns A DBus message object.
163 */
164DBusMessage *
165geis_dbus_subscription_deactivate_call_message(GeisSubscription subscription);
166
167/**
168 * Indicates if a DBus message is a GEIS_DBUS_SUBSCRIPTION_DESTROY message.
169 *
170 * @param[in] message A DBus message.
171 *
172 * @returns GEIS_TRUE if the message is GEIS_DBUS_SUBSCRIPTION_DESTROY,
173 * GEIS_FALSE otherwise.
174 */
175GeisBoolean
176geis_dbus_message_is_subscription_destroy_call(DBusMessage *message);
177
178/**
179 * Creates a GEIS_DBUS_SUBSCRIPTION_DESTROY method call message.
180 *
181 * @param[in] subscription A GEIS subscription.
182 *
183 * This function is used on the client side to create a
184 * GEIS_DBUS_SUBSCRIPTION_DESTROY method call message from a local
185 * %GeisSubscription object.
186 *
187 * @returns A DBus message object.
188 */
189DBusMessage *
190geis_dbus_subscription_destroy_call_message(GeisSubscription subscription);
191
192/**
193 * Creates a GEIS_DBUS_SUBSCRIPTION_DESTROY method return message.
194 *
195 * @param[in] message The DBUs method_call message to reply to.
196 *
197 * This function is used on the server side to create a response to a received
198 * GEIS_DBUS_SUBSCRIPTION_DESTROY method call message.
199 *
200 * @returns A DBus message object.
201 */
202DBusMessage *
203geis_dbus_subscription_destroy_return_message(DBusMessage *message);
204
205
206#endif /* GEIS_DBUS_SUBSCRIPTION_H_ */
0207
=== modified file 'libutouch-geis/Makefile.am'
--- libutouch-geis/Makefile.am 2011-08-17 15:48:51 +0000
+++ libutouch-geis/Makefile.am 2011-10-17 21:56:23 +0000
@@ -39,6 +39,7 @@
39 geis_event.h geis_event.c \39 geis_event.h geis_event.c \
40 geis_event_queue.h geis_event_queue.c \40 geis_event_queue.h geis_event_queue.c \
41 geis_filter.h geis_filter.c \41 geis_filter.h geis_filter.c \
42 geis_filterable.h geis_filterable.c \
42 geis_filter_term.h geis_filter_term.c \43 geis_filter_term.h geis_filter_term.c \
43 geis_frame.h geis_frame.c \44 geis_frame.h geis_frame.c \
44 geis_gesture_flick.h geis_gesture_flick.c \45 geis_gesture_flick.h geis_gesture_flick.c \
@@ -56,6 +57,8 @@
56 -I$(top_srcdir) \57 -I$(top_srcdir) \
57 -I$(top_srcdir)/include \58 -I$(top_srcdir)/include \
58 -I$(srcdir)/backend \59 -I$(srcdir)/backend \
60 -I$(top_srcdir)/libs/geis-dbus \
61 $(DBUS_CFLAGS) \
59 $(GRAIL_CFLAGS) 62 $(GRAIL_CFLAGS)
6063
61libutouch_geis_la_LDFLAGS = \64libutouch_geis_la_LDFLAGS = \
@@ -66,8 +69,10 @@
6669
67libutouch_geis_la_LIBADD = \70libutouch_geis_la_LIBADD = \
68 ${builddir}/backend/test_fixture/libutouch-geis-test-fixture.la \71 ${builddir}/backend/test_fixture/libutouch-geis-test-fixture.la \
72 ${builddir}/backend/dbus/libutouch-geis-dbus-backend.la \
69 ${builddir}/backend/xcb/libutouch-geis-xcb-backend.la \73 ${builddir}/backend/xcb/libutouch-geis-xcb-backend.la \
70 ${builddir}/server/libutouch-geis-dbus-server.la \74 ${builddir}/server/libutouch-geis-dbus-server.la \
75 $(top_builddir)/libs/geis-dbus/libgeis-dbus.la \
71 $(top_builddir)/libs/xcb/libxcb-gesture.la 76 $(top_builddir)/libs/xcb/libxcb-gesture.la
7277
73EXTRA_DIST = $(version_script)78EXTRA_DIST = $(version_script)
7479
=== modified file 'libutouch-geis/backend/Makefile.am'
--- libutouch-geis/backend/Makefile.am 2011-01-17 14:58:27 +0000
+++ libutouch-geis/backend/Makefile.am 2011-10-17 21:56:23 +0000
@@ -19,5 +19,5 @@
19# 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA19# 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20#20#
2121
22SUBDIRS = test_fixture xcb22SUBDIRS = test_fixture xcb dbus
2323
2424
=== added directory 'libutouch-geis/backend/dbus'
=== added file 'libutouch-geis/backend/dbus/Makefile.am'
--- libutouch-geis/backend/dbus/Makefile.am 1970-01-01 00:00:00 +0000
+++ libutouch-geis/backend/dbus/Makefile.am 2011-10-17 21:56:23 +0000
@@ -0,0 +1,34 @@
1#
2# @file libutouch-geis/backend/xcb/Makefile.am
3# @brief automake recipe for the uTouch GEIS v2.0 XCB back end
4#
5# Copyright 2011 Canonical, Ltd.
6#
7# This file is part of the utouch-geis library. This library is free software;
8# you can redistribute it and/or modify it under the terms of the GNU Lesser
9# General Public License as published by the Free Software Foundation; either
10# version 3 of the License, or (at your option) any 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 General Public License
18# along with this program. If not, see <http://www.gnu.org/licenses/
19#
20
21noinst_LTLIBRARIES = libutouch-geis-dbus-backend.la
22
23libutouch_geis_dbus_backend_la_SOURCES = \
24 geis_dbus_backend.c \
25 geis_dbus_client.h geis_dbus_client.c \
26 geis_dbus_locator.h geis_dbus_locator.c
27
28libutouch_geis_dbus_backend_la_CPPFLAGS = \
29 -I$(top_srcdir) \
30 -I$(top_srcdir)/libs/geis-dbus \
31 -I$(top_srcdir)/include \
32 -I$(top_srcdir)/libutouch-geis \
33 $(DBUS_CFLAGS)
34
035
=== added file 'libutouch-geis/backend/dbus/geis_dbus_backend.c'
--- libutouch-geis/backend/dbus/geis_dbus_backend.c 1970-01-01 00:00:00 +0000
+++ libutouch-geis/backend/dbus/geis_dbus_backend.c 2011-10-17 21:56:23 +0000
@@ -0,0 +1,248 @@
1/**
2 * @file geis_dbus_backend.c
3 * @brief GEIS DBus client back end
4 */
5
6/*
7 * Copyright 2011 Canonical Ltd.
8 *
9 * This library is free software; you can redistribute it and/or modify it under
10 * the terms of the GNU Lesser General Public License as published by the Free
11 * Software Foundation; either version 3 of the License, or (at your option) any
12 * later version.
13 *
14 * This library is distributed in the hope that it will be useful, but WITHOUT
15 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
17 * details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21 */
22#include "geis_config.h"
23#include "geis_backend.h"
24#include "geis_backend_protected.h"
25
26#include "geis_dbus_client.h"
27#include "geis_event.h"
28#include "geis_logging.h"
29#include "geis_private.h"
30
31
32/**
33 * @addtogroup geis_backend_dbus GEIS DBus Back End
34 * @ingroup geis_backends
35 *
36 * A GEIS Back End that is a DBus client, for connecting to a single central
37 * GEIS service offering data over the DBus.
38 *
39 * @{
40 */
41
42/** The opaque DBus Back End type. */
43typedef struct GeisDBusBackend *GeisDBusBackend;
44
45/** The less opaque DBus Back End structure. */
46struct GeisDBusBackend
47{
48 Geis geis;
49 GeisDBusClient dbus_client;
50};
51
52/** The DBus Back End token type */
53typedef struct GeisDBusToken
54{
55 struct GeisBackendToken base;
56 GeisDBusBackend be;
57} *GeisDBusToken;
58
59
60/**
61 * Converts from a GeisBackendToken to an XcbBackendToken.
62 */
63static inline GeisDBusToken
64_geis_dbus_token_from_geis_token(GeisBackendToken gbt)
65{
66 return (GeisDBusToken)gbt;
67}
68
69
70/**
71 * Allocates memory for a token from a pool.
72 */
73static GeisDBusToken
74_geis_dbus_token_allocate(void)
75{
76 return calloc(1, sizeof(struct GeisDBusToken));
77}
78
79
80/**
81 * Returns memory for a token to a pool.
82 */
83static void
84_geis_dbus_token_deallocate(GeisDBusToken gdt)
85{
86 free(gdt);
87}
88
89
90/**
91 * Deep-copy-constructs a token.
92 */
93static GeisBackendToken
94_geis_dbus_token_clone(GeisBackendToken original)
95{
96 return original;
97}
98
99
100/**
101 * Releases resources for a token.
102 *
103 * @param[in] token A %GeisDBusToken.
104 */
105static void
106_geis_dbus_token_finalize(GeisBackendToken token GEIS_UNUSED)
107{
108}
109
110
111/**
112 * Composes one token onto another.
113 *
114 * @param[in,out] lhs
115 * @param[in] rhs
116 */
117static void
118_geis_dbus_token_compose(GeisBackendToken lhs GEIS_UNUSED,
119 GeisBackendToken rhs GEIS_UNUSED)
120{
121}
122
123
124/**
125 * Activates a DBus back end token.
126 *
127 * @param[in] token A %GeisDBusToken.
128 * @param[in] subscription The subscrition the token will be activated on.
129 *
130 * Sends a request to the server to activate a subscription with the tokenized
131 * content.
132 *
133 * @returns GEIS_STATUS_SUCCESS.
134 */
135static GeisStatus
136_geis_dbus_token_activate(GeisBackendToken token, GeisSubscription subscription)
137{
138 GeisDBusToken gdt = _geis_dbus_token_from_geis_token(token);
139 geis_dbus_client_subscribe(gdt->be->dbus_client, subscription);
140 return GEIS_STATUS_SUCCESS;
141}
142
143
144/**
145 * Deactivates a DBus back end token.
146 *
147 * @param[in] token A %GeisDBusToken.
148 */
149static GeisStatus
150_geis_dbus_token_deactivate(GeisBackendToken token, GeisSubscription subscription)
151{
152 GeisDBusToken gdt = _geis_dbus_token_from_geis_token(token);
153 geis_dbus_client_unsubscribe(gdt->be->dbus_client, subscription);
154 _geis_dbus_token_deallocate(gdt);
155 return GEIS_STATUS_UNKNOWN_ERROR;
156}
157
158
159static struct GeisBackendTokenVtable _token_vtbl = {
160 _geis_dbus_token_clone,
161 _geis_dbus_token_finalize,
162 _geis_dbus_token_compose,
163 _geis_dbus_token_activate,
164 _geis_dbus_token_deactivate,
165};
166
167
168/**
169 * Constructs a DBus back end.
170 *
171 * @param[in] mem
172 * @param[in] geis
173 */
174static void
175_geis_dbus_backend_construct(void *mem, Geis geis)
176{
177 GeisDBusBackend gdb = (GeisDBusBackend)mem;
178 gdb->geis = geis;
179
180 gdb->dbus_client = geis_dbus_client_new(geis);
181 if (!gdb->dbus_client)
182 {
183 geis_error("error creating GEIS DBus client");
184 goto final_exit;
185 }
186
187final_exit:
188 return;
189}
190
191
192/**
193 * Deconstructs a DBus back end.
194 *
195 * @param[in] be A %GeisDBusBackend.
196 */
197static void
198_geis_dbus_backend_finalize(GeisBackend be)
199{
200 GeisDBusBackend gdb = (GeisDBusBackend)be;
201 geis_dbus_client_delete(gdb->dbus_client);
202}
203
204
205/**
206 * Creates DBus-back-end-specific back end token.
207 */
208static GeisBackendToken
209_geis_dbus_backend_create_token(GeisBackend be,
210 GeisBackendTokenInitState init_state GEIS_UNUSED)
211{
212 GeisDBusBackend gdb = (GeisDBusBackend)be;
213 GeisDBusToken token = _geis_dbus_token_allocate();
214 if (token)
215 {
216 token->base.vtbl = &_token_vtbl;
217 token->be = gdb;
218 }
219 return (GeisBackendToken)token;
220}
221
222
223static struct GeisBackendVtable gdb_vtbl = {
224 _geis_dbus_backend_construct,
225 _geis_dbus_backend_finalize,
226 _geis_dbus_backend_create_token,
227};
228
229
230/**
231 * Registers the back end with the GEIS back end registry.
232 */
233static void __attribute__((constructor))
234_register_dbus_backend(void)
235{
236 geis_register_backend(GEIS_INIT_UTOUCH_DBUS_BACKEND,
237 sizeof(struct GeisDBusBackend),
238 &gdb_vtbl);
239}
240
241
242/** A dummy routine to force linkage of this module without dlopening it */
243void
244geis_include_dbus_backend(void)
245{
246}
247
248/** @} */
0249
=== added file 'libutouch-geis/backend/dbus/geis_dbus_client.c'
--- libutouch-geis/backend/dbus/geis_dbus_client.c 1970-01-01 00:00:00 +0000
+++ libutouch-geis/backend/dbus/geis_dbus_client.c 2011-10-17 21:56:23 +0000
@@ -0,0 +1,685 @@
1/**
2 * @file geis_dbus_client.c
3 * @brief Implementations of the GEIS DBus client.
4 */
5
6/*
7 * Copyright 2011 Canonical Ltd.
8 *
9 * This library is free software; you can redistribute it and/or modify it under
10 * the terms of the GNU Lesser General Public License as published by the Free
11 * Software Foundation; either version 3 of the License, or (at your option) any
12 * later version.
13 *
14 * This library is distributed in the hope that it will be useful, but WITHOUT
15 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
17 * details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21 */
22#include "geis_config.h"
23#include "geis_dbus_client.h"
24
25#include "geis_dbus.h"
26#include "geis_dbus_class.h"
27#include "geis_dbus_device.h"
28#include "geis_dbus_gesture_event.h"
29#include "geis_dbus_locator.h"
30#include "geis_dbus_region.h"
31#include "geis_dbus_subscription.h"
32#include "geis_event.h"
33#include "geis_logging.h"
34#include "geis_private.h"
35#include <stdio.h>
36#include <stdlib.h>
37
38
39typedef enum GeisDBusClientState
40{
41 GEIS_DBUS_CLIENT_DISCONNECTED, /* no server available */
42 GEIS_DBUS_CLIENT_INITIALIZING, /* server connected, client initializing */
43 GEIS_DBUS_CLIENT_CONNECTING, /* server connected, not initialized */
44 GEIS_DBUS_CLIENT_CONNECTED /* server connected, all systems go */
45} GeisDBusClientState;
46
47
48struct GeisDBusClient
49{
50 Geis geis;
51 GeisDBusDispatcher dispatcher;
52 GeisDBusLocator locator;
53 GeisDBusClientState state;
54 DBusConnection *connection;
55 GeisSubBag subscription_bag;
56};
57
58
59/**
60 * Handles a device-available message from the server.
61 *
62 * @param[in] client A %GeisDBusClient.
63 * @param[in] message The %DBusMessage.
64 */
65static void
66_client_device_available(GeisDBusClient client, DBusMessage *message)
67{
68 GeisDevice device = geis_dbus_device_device_from_available_message(message);
69 if (device)
70 {
71 geis_register_device(client->geis, device, 0, NULL);
72 }
73 else
74 {
75 geis_error("no device received from remote back end");
76 }
77}
78
79
80/**
81 * Handles a device-unavailable message from the server.
82 *
83 * @param[in] client A %GeisDBusClient.
84 * @param[in] message The %DBusMessage.
85 */
86static void
87_client_device_unavailable(GeisDBusClient client, DBusMessage *message)
88{
89 GeisDevice device = geis_dbus_device_device_from_unavailable_message(message);
90 if (device)
91 {
92 geis_unregister_device(client->geis, device);
93 }
94 else
95 {
96 geis_error("no device received from remote back end");
97 }
98}
99
100
101/**
102 * Handles a class-available message from the server.
103 *
104 * @param[in] client A %GeisDBusClient.
105 * @param[in] message The %DBusMessage.
106 */
107static void
108_client_class_available(GeisDBusClient client, DBusMessage *message)
109{
110 GeisGestureClass gesture_class;
111
112 gesture_class = geis_dbus_class_class_from_available_message(message);
113 if (gesture_class)
114 {
115 geis_register_gesture_class(client->geis, gesture_class, 0, NULL);
116 }
117 else
118 {
119 geis_error("no gesture class received from remote back end");
120 }
121}
122
123
124/**
125 * Handles a region-available message from the server.
126 *
127 * @param[in] client A %GeisDBusClient.
128 * @param[in] message The %DBusMessage.
129 */
130static void
131_client_region_available(GeisDBusClient client, DBusMessage *message)
132{
133 GeisFilterableAttribute attr;
134
135 attr = geis_dbus_region_from_region_available_message(message);
136 if (attr)
137 {
138 attr->add_term_callback = 0;
139 attr->add_term_context = 0;
140 geis_register_region(client->geis, NULL, 1, attr);
141 }
142 else
143 {
144 geis_error("no region attr received from remote back end");
145 }
146}
147
148
149/**
150 * Handles a class-unavailable message from the server.
151 *
152 * @param[in] client A %GeisDBusClient.
153 * @param[in] message The %DBusMessage.
154 */
155static void
156_client_gesture_event(GeisDBusClient client, DBusMessage *message)
157{
158 GeisEvent event = geis_dbus_gesture_event_from_message(message);
159 if (!event)
160 {
161 geis_error("no gesture event received from remote back end");
162 }
163 else
164 {
165 geis_post_event(client->geis, event);
166 }
167}
168
169
170/**
171 * Processes an subscription-activate reply from the server.
172 *
173 * @param[in] pending A DBusPendingCall object.
174 * @param[in] user_data The %GeisDBusClient object.
175 */
176static void
177_geis_dbus_client_activate_reply(DBusPendingCall *pending, void *user_data)
178{
179 GeisDBusClient client GEIS_UNUSED = (GeisDBusClient)user_data;
180 DBusMessage *reply = dbus_pending_call_steal_reply(pending);
181
182 if (DBUS_MESSAGE_TYPE_ERROR == dbus_message_get_type(reply))
183 {
184 const char *s = NULL;
185 dbus_message_get_args(reply, NULL, DBUS_TYPE_STRING, &s, DBUS_TYPE_INVALID);
186 geis_error("error %s: %s", dbus_message_get_error_name(reply), s);
187 }
188}
189
190
191/**
192 * Processes a subscription-create reply from the server.
193 *
194 * @param[in] pending A DBusPendingCall object.
195 * @param[in] user_data The %GeisDBusClient object.
196 */
197static void
198_geis_dbus_client_subscribe_reply(DBusPendingCall *pending, void *user_data)
199{
200 GeisDBusClient client = (GeisDBusClient)user_data;
201 DBusMessage *reply = dbus_pending_call_steal_reply(pending);
202
203 if (DBUS_MESSAGE_TYPE_ERROR == dbus_message_get_type(reply))
204 {
205 const char *s = NULL;
206 dbus_message_get_args(reply, NULL, DBUS_TYPE_STRING, &s, DBUS_TYPE_INVALID);
207 geis_error("error %s: %s", dbus_message_get_error_name(reply), s);
208 }
209 else
210 {
211 DBusMessage *msg;
212 DBusPendingCall *pending;
213 DBusError error = DBUS_ERROR_INIT;
214 dbus_int32_t client_sub_id;
215 dbus_int32_t server_sub_id;
216 GeisSubscription subscription;
217
218 dbus_message_get_args(reply,
219 &error,
220 DBUS_TYPE_INT32, &client_sub_id,
221 DBUS_TYPE_INT32, &server_sub_id,
222 DBUS_TYPE_INVALID);
223 if (dbus_error_is_set(&error))
224 {
225 geis_error("error %s: %s", error.name, error.message);
226 dbus_error_free(&error);
227 }
228
229 subscription = geis_subscription_bag_find(client->subscription_bag,
230 client_sub_id);
231 if (!subscription)
232 {
233 geis_error("invalid client subcription id %d returned from server",
234 client_sub_id);
235 }
236 else
237 {
238 geis_subscription_set_pdata(subscription, (GeisPointer)(intptr_t)server_sub_id);
239
240 msg = geis_dbus_subscription_activate_call_message(subscription);
241 dbus_connection_send_with_reply(client->connection, msg, &pending, -1);
242 dbus_message_unref(msg);
243 if (!pending)
244 {
245 geis_error("error sending DBus CreateSubscription method call");
246 }
247 else
248 {
249 dbus_pending_call_set_notify(pending,
250 _geis_dbus_client_activate_reply,
251 client, 0);
252 }
253 }
254 }
255
256 dbus_message_unref(reply);
257 dbus_pending_call_unref(pending);
258}
259
260
261/**
262 * Processes a deactivate-subscription reply from the server.
263 *
264 * @param[in] pending A DBusPendingCall object.
265 * @param[in] user_data The %GeisDBusClient object.
266 */
267static void
268_geis_dbus_client_unsubscribe_reply(DBusPendingCall *pending, void *user_data)
269{
270 GeisDBusClient client GEIS_UNUSED = (GeisDBusClient)user_data;
271 DBusMessage *reply = dbus_pending_call_steal_reply(pending);
272
273 if (DBUS_MESSAGE_TYPE_ERROR == dbus_message_get_type(reply))
274 {
275 const char *s = NULL;
276 dbus_message_get_args(reply, NULL, DBUS_TYPE_STRING, &s, DBUS_TYPE_INVALID);
277 geis_error("error %s: %s", dbus_message_get_error_name(reply), s);
278 }
279 else
280 {
281 geis_warning("signature=\"%s\"", dbus_message_get_signature(reply));
282 geis_warning("path=\"%s\"", dbus_message_get_path(reply));
283 geis_warning("interface=\"%s\"", dbus_message_get_interface(reply));
284 geis_warning("member=\"%s\"", dbus_message_get_member(reply));
285 }
286
287 dbus_message_unref(reply);
288 dbus_pending_call_unref(pending);
289}
290
291
292/**
293 * Creates a remote subscription.
294 */
295void
296_dbus_client_subscribe(GeisDBusClient client,
297 GeisSubscription subscription)
298{
299 DBusPendingCall *pending_return;
300
301 GeisSubscription sub = geis_subscription_bag_find(client->subscription_bag,
302 geis_subscription_id(subscription));
303 if (sub && geis_subscription_pdata(sub))
304 {
305 geis_warning("subscription already activated!");
306 }
307 else
308 {
309 DBusMessage *msg = geis_dbus_subscription_create_call_message(subscription);
310 dbus_connection_send_with_reply(client->connection, msg, &pending_return, -1);
311 dbus_message_unref(msg);
312 if (!pending_return)
313 {
314 geis_error("error sending DBus CreateSubscription method call");
315 }
316 else
317 {
318 dbus_pending_call_set_notify(pending_return,
319 _geis_dbus_client_subscribe_reply,
320 client, 0);
321 }
322 }
323}
324
325
326/**
327 * Re-subscribes all existing sibscriptions when the server appears or
328 * reappears.
329 */
330void
331_dbus_client_resubscribe_all(GeisDBusClient client)
332{
333 GeisSubBagIterator it;
334 for (it = geis_subscription_bag_begin(client->subscription_bag);
335 it != geis_subscription_bag_end(client->subscription_bag);
336 it = geis_subscription_bag_iterator_next(client->subscription_bag, it))
337 {
338 geis_subscription_set_pdata(*it, 0);
339 _dbus_client_subscribe(client, *it);
340 }
341}
342
343
344/**
345 * The DBus message dispatch function for the GEIS DBus client.
346 *
347 * @param[in] connection The %GeisDBusClient DBus connection.
348 * @param[in] message The DBus message received.
349 * @param[in] user_data The %GeisDBusClient.
350 */
351static DBusHandlerResult
352_geis_dbus_client_message_handler(DBusConnection *connection GEIS_UNUSED,
353 DBusMessage *message,
354 void *user_data)
355{
356 DBusHandlerResult result = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
357 GeisDBusClient client = (GeisDBusClient)user_data;
358 int type = dbus_message_get_type(message);
359
360 if (dbus_message_is_signal(message,
361 DBUS_INTERFACE_LOCAL,
362 "Disconnected"))
363 {
364 geis_warning("server disconnected?");
365 result = DBUS_HANDLER_RESULT_HANDLED;
366 }
367 else if (dbus_message_is_signal(message,
368 GEIS_DBUS_SERVICE_INTERFACE,
369 GEIS_DBUS_DEVICE_AVAILABLE))
370 {
371 _client_device_available(client, message);
372 result = DBUS_HANDLER_RESULT_HANDLED;
373 }
374 else if (dbus_message_is_signal(message,
375 GEIS_DBUS_SERVICE_INTERFACE,
376 GEIS_DBUS_DEVICE_UNAVAILABLE))
377
378 {
379 _client_device_unavailable(client, message);
380 result = DBUS_HANDLER_RESULT_HANDLED;
381 }
382 else if (dbus_message_is_signal(message,
383 GEIS_DBUS_SERVICE_INTERFACE,
384 GEIS_DBUS_CLASS_AVAILABLE))
385 {
386 _client_class_available(client, message);
387 result = DBUS_HANDLER_RESULT_HANDLED;
388 }
389 else if (dbus_message_is_signal(message,
390 GEIS_DBUS_SERVICE_INTERFACE,
391 GEIS_DBUS_REGION_AVAILABLE))
392 {
393 _client_region_available(client, message);
394 result = DBUS_HANDLER_RESULT_HANDLED;
395 }
396 else if (dbus_message_is_signal(message,
397 GEIS_DBUS_SERVICE_INTERFACE,
398 GEIS_DBUS_INIT_COMPLETE))
399 {
400 if (client->state == GEIS_DBUS_CLIENT_INITIALIZING)
401 {
402 geis_post_event(client->geis, geis_event_new(GEIS_EVENT_INIT_COMPLETE));
403 }
404 client->state = GEIS_DBUS_CLIENT_CONNECTED;
405 _dbus_client_resubscribe_all(client);
406 result = DBUS_HANDLER_RESULT_HANDLED;
407 }
408 else if (geis_dbus_message_is_gesture_event(message))
409 {
410 _client_gesture_event(client, message);
411 result = DBUS_HANDLER_RESULT_HANDLED;
412 }
413 else if (type == DBUS_MESSAGE_TYPE_ERROR)
414 {
415 const char *str = NULL;
416 dbus_message_get_args(message, NULL,
417 DBUS_TYPE_STRING, &str,
418 DBUS_TYPE_INVALID);
419 geis_warning("error %s: %s", dbus_message_get_error_name(message), str);
420 }
421 else
422 {
423 geis_warning("unhandled DBus %s received:",
424 dbus_message_type_to_string(dbus_message_get_type(message)));
425 geis_warning(" signature=\"%s\"", dbus_message_get_signature(message));
426 geis_warning(" sender=\"%s\"", dbus_message_get_sender(message));
427 geis_warning(" path=\"%s\"",
428 dbus_message_get_path(message) ?
429 dbus_message_get_path(message) :
430 "(no path)");
431 geis_warning(" interface=\"%s\"",
432 dbus_message_get_interface(message) ?
433 dbus_message_get_interface(message) :
434 "(no interface)");
435 geis_warning(" member=\"%s\"",
436 dbus_message_get_member(message) ?
437 dbus_message_get_member(message) :
438 "(no member)");
439 }
440 return result;
441}
442
443
444/**
445 * Adds the client watches to the dispatcher watch list.
446 *
447 * @param[in] watch A %DBusWatch.
448 * @param[in] data The %GeisDBusClientProxy.
449 */
450static dbus_bool_t
451_client_add_watch(DBusWatch *watch, void *data)
452{
453 dbus_bool_t status = TRUE;
454 GeisDBusClient client = (GeisDBusClient)data;
455
456 geis_dbus_dispatcher_register(client->dispatcher, client->connection, watch);
457 return status;
458}
459
460
461/**
462 * Toggles the enabled/disabled status of the client watches.
463 *
464 * @param[in] watch A %DBusWatch.
465 * @param[in] data The %GeisDBusClientProxy.
466 */
467static void
468_client_toggle_watch(DBusWatch *watch, void *data)
469{
470 GeisDBusClient client = (GeisDBusClient)data;
471
472 geis_dbus_dispatcher_toggle_watch(client->dispatcher, watch);
473}
474
475
476/**
477 * Removes the client watches from the dispatcher watch list.
478 *
479 * @param[in] watch A %DBusWatch.
480 * @param[in] data The %GeisDBusClientProxy.
481 */
482static void
483_client_remove_watch(DBusWatch *watch, void *data)
484{
485 GeisDBusClient client = (GeisDBusClient)data;
486
487 geis_dbus_dispatcher_unregister(client->dispatcher, watch);
488}
489
490
491/**
492 * Connects to the GEIS server once an address is located.
493 *
494 * @param[in] client A %GeisDBusClient object.
495 * @param[in] address The address of the server.
496 */
497static void
498_client_connect(GeisDBusClient client, const char *address)
499{
500 geis_debug("server address=\"%s\"", address);
501 DBusError error = DBUS_ERROR_INIT;
502 client->connection = dbus_connection_open(address, &error);
503 if (!client->connection || dbus_error_is_set(&error))
504 {
505 char msg[512];
506 snprintf(msg, sizeof(msg), "error %s connecting to server at address %s: %s",
507 error.name, address, error.message);
508 geis_error("%s", msg);
509 dbus_error_free(&error);
510 goto final_exit;
511 }
512
513 /* Integrate with the app event loop via the GEIS multiplexor. */
514 dbus_connection_set_watch_functions(client->connection,
515 _client_add_watch,
516 _client_remove_watch,
517 _client_toggle_watch,
518 client, 0);
519
520 /* Install a handler for any and all messages. */
521 dbus_connection_add_filter(client->connection,
522 _geis_dbus_client_message_handler,
523 client, 0);
524 if (client->state != GEIS_DBUS_CLIENT_INITIALIZING)
525 {
526 client->state = GEIS_DBUS_CLIENT_CONNECTING;
527 }
528
529final_exit:
530 return;
531}
532
533
534/*
535 * Creates a new GeisDBusClient.
536 */
537GeisDBusClient
538geis_dbus_client_new(Geis geis)
539{
540 GeisDBusClient client = calloc(1, sizeof(struct GeisDBusClient));
541 if (!client)
542 {
543 goto final_exit;
544 }
545
546 client->geis = geis;
547 client->state = GEIS_DBUS_CLIENT_INITIALIZING;
548
549 client->dispatcher = geis_dbus_dispatcher_new(geis);
550 if (!client->dispatcher)
551 {
552 goto unwind_client;
553 }
554
555 client->locator = geis_dbus_locator_new(client);
556 if (!client->locator)
557 {
558 goto unwind_dispatcher;
559 }
560
561 client->subscription_bag = geis_subscription_bag_new(1);
562 if (!client->subscription_bag)
563 {
564 goto unwind_locator;
565 }
566
567 goto final_exit;
568
569unwind_locator:
570 geis_dbus_locator_delete(client->locator);
571unwind_dispatcher:
572 geis_dbus_dispatcher_delete(client->dispatcher);
573unwind_client:
574 free(client);
575 client = NULL;
576final_exit:
577 return client;
578}
579
580
581/*
582 * Destroys a GeisDBusClient.
583 */
584void
585geis_dbus_client_delete(GeisDBusClient client)
586{
587 geis_subscription_bag_delete(client->subscription_bag);
588 geis_dbus_locator_delete(client->locator);
589 if (client->connection)
590 {
591 dbus_connection_unref(client->connection);
592 }
593 geis_dbus_dispatcher_delete(client->dispatcher);
594 free(client);
595}
596
597
598/*
599 * Gets the client dispatcher.
600 */
601GeisDBusDispatcher
602geis_dbus_client_dispatcher(GeisDBusClient client)
603{
604 return client->dispatcher;
605}
606
607
608/*
609 * Signals the client the server has been located.
610 */
611void
612geis_dbus_client_server_located(GeisDBusClient client)
613{
614 _client_connect(client, geis_dbus_locator_server_address(client->locator));
615}
616
617
618/*
619 * Signals the client the server has been dislocated.
620 */
621void
622geis_dbus_client_server_dislocated(GeisDBusClient client)
623{
624 GeisEvent event = geis_event_new(GEIS_EVENT_ERROR);
625 client->state = GEIS_DBUS_CLIENT_DISCONNECTED;
626 geis_post_event(client->geis, event);
627}
628
629
630/*
631 * Requests a subscription on the remote end.
632 */
633GeisStatus
634geis_dbus_client_subscribe(GeisDBusClient client,
635 GeisSubscription subscription)
636{
637 GeisStatus status = GEIS_STATUS_SUCCESS;
638
639 if (client->state == GEIS_DBUS_CLIENT_CONNECTED)
640 {
641 _dbus_client_subscribe(client, subscription);
642 }
643 geis_subscription_bag_insert(client->subscription_bag, subscription);
644
645 return status;
646}
647
648
649/*
650 * Destroys a subscription on the remote end.
651 */
652GeisStatus
653geis_dbus_client_unsubscribe(GeisDBusClient client,
654 GeisSubscription subscription)
655{
656 GeisStatus status = GEIS_STATUS_UNKNOWN_ERROR;
657 if (geis_subscription_bag_find(client->subscription_bag,
658 geis_subscription_id(subscription)))
659 {
660 DBusMessage *msg;
661 DBusPendingCall *pending_return;
662
663 msg = geis_dbus_subscription_destroy_call_message(subscription);
664 dbus_connection_send_with_reply(client->connection, msg, &pending_return, -1);
665 dbus_message_unref(msg);
666 if (!pending_return)
667 {
668 geis_error("error sending DBus CreateSubscription method call");
669 goto final_exit;
670 }
671
672 dbus_pending_call_set_notify(pending_return,
673 _geis_dbus_client_unsubscribe_reply,
674 client, 0);
675 geis_subscription_bag_remove(client->subscription_bag, subscription);
676 status = GEIS_STATUS_SUCCESS;
677 }
678
679final_exit:
680 return status;
681}
682
683
684
685
0686
=== added file 'libutouch-geis/backend/dbus/geis_dbus_client.h'
--- libutouch-geis/backend/dbus/geis_dbus_client.h 1970-01-01 00:00:00 +0000
+++ libutouch-geis/backend/dbus/geis_dbus_client.h 2011-10-17 21:56:23 +0000
@@ -0,0 +1,97 @@
1/**
2 * @file geis_dbus_client.h
3 * @brief Interface for the GEIS DBus client.
4 *
5 * The GEIS DBus client offers remote GEIS functionality over a managed
6 * DBus connection.
7 *
8 * This header is for internal GEIS use only and contains no client
9 * (externally-visible) symbols.
10 */
11
12/*
13 * Copyright 2011 Canonical Ltd.
14 *
15 * This library is free software; you can redistribute it and/or modify it under
16 * the terms of the GNU Lesser General Public License as published by the Free
17 * Software Foundation; either version 3 of the License, or (at your option) any
18 * later version.
19 *
20 * This library is distributed in the hope that it will be useful, but WITHOUT
21 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
22 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
23 * details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program. If not, see <http://www.gnu.org/licenses/>.
27 */
28#ifndef GEIS_DBUS_CLIENT_H_
29#define GEIS_DBUS_CLIENT_H_
30
31#include "geis/geis.h"
32#include "geis_dbus_dispatcher.h"
33
34
35typedef struct GeisDBusClient *GeisDBusClient;
36
37
38/**
39 * Creates a new %GeisDBusClient object.
40 */
41GeisDBusClient
42geis_dbus_client_new(Geis geis);
43
44/**
45 * Destroys a %GeisDBusClient.
46 *
47 * @param[in] client A GeisDBusClient.
48 */
49void
50geis_dbus_client_delete(GeisDBusClient client);
51
52/**
53 * Gets the client dispatcher.
54 *
55 * @param[in] client A GeisDBusClient.
56 */
57GeisDBusDispatcher
58geis_dbus_client_dispatcher(GeisDBusClient client);
59
60/**
61 * Signals the client the server has been located.
62 *
63 * @param[in] client A GeisDBusClient.
64 */
65void
66geis_dbus_client_server_located(GeisDBusClient client);
67
68/**
69 * Signals the client the server has been dislocated.
70 *
71 * @param[in] client A GeisDBusClient.
72 */
73void
74geis_dbus_client_server_dislocated(GeisDBusClient client);
75
76/**
77 * Cerates a subscription on the remote end.
78 *
79 * @param[in] client The client-side of the DBus connection.
80 * @param[in] subscription The local subscription object.
81 */
82GeisStatus
83geis_dbus_client_subscribe(GeisDBusClient client,
84 GeisSubscription subscription);
85
86/**
87 * Deactivates a subscription on the remote end.
88 *
89 * @param[in] client The client-side of the DBus connection.
90 * @param[in] subscription The local subscription object.
91 */
92GeisStatus
93geis_dbus_client_unsubscribe(GeisDBusClient client,
94 GeisSubscription subscription);
95
96
97#endif /* GEIS_DBUS_CLIENT_H_ */
098
=== added file 'libutouch-geis/backend/dbus/geis_dbus_locator.c'
--- libutouch-geis/backend/dbus/geis_dbus_locator.c 1970-01-01 00:00:00 +0000
+++ libutouch-geis/backend/dbus/geis_dbus_locator.c 2011-10-17 21:56:23 +0000
@@ -0,0 +1,268 @@
1/**
2 * @file geis_dbus_locator.c
3 * @brief Implementation of the GEIS DBus locator.
4 */
5
6/*
7 * Copyright 2011 Canonical Ltd.
8 *
9 * This library is free software; you can redistribute it and/or modify it under
10 * the terms of the GNU Lesser General Public License as published by the Free
11 * Software Foundation; either version 3 of the License, or (at your option) any
12 * later version.
13 *
14 * This library is distributed in the hope that it will be useful, but WITHOUT
15 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
17 * details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21 */
22#include "geis_config.h"
23#include "geis_dbus_locator.h"
24
25#include <dbus/dbus.h>
26#include "geis_dbus.h"
27#include "geis_logging.h"
28#include <stdio.h>
29#include <stdlib.h>
30#include <string.h>
31
32
33typedef enum GeisDBusLocatorState
34{
35 GEIS_DBUS_LOCATOR_STATE_INITIALIZING,
36 GEIS_DBUS_LOCATOR_STATE_LOCATING,
37 GEIS_DBUS_LOCATOR_STATE_WAITING,
38 GEIS_DBUS_LOCATOR_STATE_FINALIZING
39} GeisDBusLocatorState;
40
41
42struct GeisDBusLocator
43{
44 GeisDBusClient client;
45 GeisDBusLocatorState state;
46 DBusConnection *session_bus;
47 char *server_address;
48 dbus_uint32_t serial;
49};
50
51
52/*
53 * Performs the act of actually locating the server.
54 */
55static void
56_locator_find_server(GeisDBusLocator locator)
57{
58 locator->state = GEIS_DBUS_LOCATOR_STATE_LOCATING;
59 DBusMessage *msg = dbus_message_new_method_call(GEIS_DBUS_SERVICE_INTERFACE,
60 GEIS_DBUS_SERVICE_PATH,
61 GEIS_DBUS_SERVICE_INTERFACE,
62 GEIS_DBUS_GET_SERVER_ADDRESS);
63 dbus_connection_send(locator->session_bus, msg, &locator->serial);
64 dbus_message_unref(msg);
65}
66
67
68/*
69 * A generic message handler function.
70 */
71static DBusHandlerResult
72_locator_message_handler(DBusConnection *connection GEIS_UNUSED,
73 DBusMessage *message,
74 void *user_data)
75{
76 DBusHandlerResult result = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
77 GeisDBusLocator locator = (GeisDBusLocator)user_data;
78 int type = dbus_message_get_type(message);
79
80 if (dbus_message_is_signal(message, DBUS_INTERFACE_DBUS, "NameOwnerChanged"))
81 {
82 char *name;
83 char *old_owner;
84 char *new_owner;
85 dbus_message_get_args(message, NULL,
86 DBUS_TYPE_STRING, &name,
87 DBUS_TYPE_STRING, &old_owner,
88 DBUS_TYPE_STRING, &new_owner,
89 DBUS_TYPE_INVALID);
90 if (strlen(old_owner))
91 {
92 geis_debug("%s has gone away", name);
93 geis_dbus_client_server_dislocated(locator->client);
94 result = DBUS_HANDLER_RESULT_HANDLED;
95 }
96 else if (strlen(new_owner))
97 {
98 geis_debug("%s has appeared", name);
99 _locator_find_server(locator);
100 result = DBUS_HANDLER_RESULT_HANDLED;
101 }
102 }
103 else if (type == DBUS_MESSAGE_TYPE_METHOD_RETURN)
104 {
105 if (locator->serial == dbus_message_get_reply_serial(message))
106 {
107 dbus_message_get_args(message, NULL,
108 DBUS_TYPE_STRING, &locator->server_address,
109 DBUS_TYPE_INVALID);
110 geis_dbus_client_server_located(locator->client);
111 result = DBUS_HANDLER_RESULT_HANDLED;
112 }
113 }
114 else if (type == DBUS_MESSAGE_TYPE_ERROR)
115 {
116 if (dbus_message_is_error(message, DBUS_ERROR_SERVICE_UNKNOWN))
117 {
118 geis_warning("server not found!");
119 geis_dbus_client_server_dislocated(locator->client);
120 result = DBUS_HANDLER_RESULT_HANDLED;
121 }
122 else
123 {
124 const char *str = NULL;
125 dbus_message_get_args(message, NULL,
126 DBUS_TYPE_STRING, &str,
127 DBUS_TYPE_INVALID);
128 geis_warning("error %s: %s", dbus_message_get_error_name(message), str);
129 }
130 }
131
132 return result;
133}
134
135
136/*
137 * Adds the locator watches to the dispatcher watch list.
138 */
139static dbus_bool_t
140_locator_add_watch(DBusWatch *watch, void *data)
141{
142 dbus_bool_t status = TRUE;
143 GeisDBusLocator locator = (GeisDBusLocator)data;
144 GeisDBusDispatcher dispatcher = geis_dbus_client_dispatcher(locator->client);
145
146 geis_dbus_dispatcher_register(dispatcher, locator->session_bus, watch);
147 return status;
148}
149
150
151/*
152 * Toggles the enabled/disabled status of the locator watches.
153 */
154static void
155_locator_toggle_watch(DBusWatch *watch, void *data)
156{
157 GeisDBusLocator locator = (GeisDBusLocator)data;
158 GeisDBusDispatcher dispatcher = geis_dbus_client_dispatcher(locator->client);
159
160 geis_dbus_dispatcher_toggle_watch(dispatcher, watch);
161}
162
163
164/*
165 * Removes the locator watches from the dispatcher watch list.
166 */
167static void
168_locator_remove_watch(DBusWatch *watch, void *data)
169{
170 GeisDBusLocator locator = (GeisDBusLocator)data;
171 GeisDBusDispatcher dispatcher = geis_dbus_client_dispatcher(locator->client);
172
173 geis_dbus_dispatcher_unregister(dispatcher, watch);
174}
175
176
177/*
178 * Creates a new GeisDBusLocator object.
179 */
180GeisDBusLocator
181geis_dbus_locator_new(GeisDBusClient client)
182{
183 GeisDBusLocator locator = calloc(1, sizeof(struct GeisDBusLocator));
184 if (!locator)
185 {
186 goto final_exit;
187 }
188
189 locator->client = client;
190 locator->state = GEIS_DBUS_LOCATOR_STATE_INITIALIZING;
191
192 /* Connect to the DBus session bus. */
193 DBusError error = DBUS_ERROR_INIT;
194 locator->session_bus = dbus_bus_get(DBUS_BUS_SESSION, &error);
195 if (!locator->session_bus || dbus_error_is_set(&error))
196 {
197 char msg[512];
198 snprintf(msg, sizeof(msg), "error %s connecting to session bus: %s",
199 error.name, error.message);
200 geis_error("%s", msg);
201 goto unwind_error;
202 }
203
204 /* Integrate with the app event loop via the GEIS multiplexor. */
205 dbus_connection_set_watch_functions(locator->session_bus,
206 _locator_add_watch,
207 _locator_remove_watch,
208 _locator_toggle_watch,
209 locator, 0);
210
211 /* Look for server-connect and server-disconnect messages. */
212 dbus_bus_add_match(locator->session_bus,
213 "type='signal',sender='" DBUS_SERVICE_DBUS "'," \
214 "interface='" DBUS_INTERFACE_DBUS "'," \
215 "member='NameOwnerChanged'," \
216 "arg0='" GEIS_DBUS_SERVICE_INTERFACE "'",
217 &error);
218 if (dbus_error_is_set(&error))
219 {
220 char msg[512];
221 snprintf(msg, sizeof(msg), "error %s adding match to session bus: %s",
222 error.name, error.message);
223 geis_error("%s", msg);
224 goto unwind_error;
225 }
226
227 /* Install a handler for any and all messages. */
228 dbus_connection_add_filter(locator->session_bus,
229 _locator_message_handler,
230 locator, 0);
231
232 /* OK, go eh? */
233 _locator_find_server(locator);
234
235unwind_error:
236 dbus_error_free(&error);
237final_exit:
238 return locator;
239}
240
241
242/*
243 * Destroys a %GeisDBusLocator object.
244 */
245void
246geis_dbus_locator_delete(GeisDBusLocator locator)
247{
248 if (locator)
249 {
250 if (locator->server_address)
251 {
252 free(locator->server_address);
253 }
254 if (locator->session_bus)
255 {
256 dbus_connection_unref(locator->session_bus);
257 }
258 free(locator);
259 }
260}
261
262
263char *
264geis_dbus_locator_server_address(GeisDBusLocator locator)
265{
266 return locator->server_address;
267}
268
0269
=== added file 'libutouch-geis/backend/dbus/geis_dbus_locator.h'
--- libutouch-geis/backend/dbus/geis_dbus_locator.h 1970-01-01 00:00:00 +0000
+++ libutouch-geis/backend/dbus/geis_dbus_locator.h 2011-10-17 21:56:23 +0000
@@ -0,0 +1,62 @@
1/**
2 * @file geis_dbus_locator.h
3 * @brief Interface for the GEIS DBus locator.
4 *
5 * The GEIS DBus locator makes the location of the GEIS DBus server available
6 * over the DBus session bus.
7 *
8 * This header is for internal GEIS use only and contains no client
9 * (externally-visible) symbols.
10 */
11
12/*
13 * Copyright 2011 Canonical Ltd.
14 *
15 * This library is free software; you can redistribute it and/or modify it under
16 * the terms of the GNU Lesser General Public License as published by the Free
17 * Software Foundation; either version 3 of the License, or (at your option) any
18 * later version.
19 *
20 * This library is distributed in the hope that it will be useful, but WITHOUT
21 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
22 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
23 * details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program. If not, see <http://www.gnu.org/licenses/>.
27 */
28#ifndef GEIS_DBUS_LOCATOR_H_
29#define GEIS_DBUS_LOCATOR_H_
30
31#include "geis/geis.h"
32#include "geis_dbus_client.h"
33
34
35typedef struct GeisDBusLocator *GeisDBusLocator;
36
37
38/**
39 * Creates a new GeisDBusLocator object.
40 *
41 * @param[in] client A GEIS DBus CLient.
42 */
43GeisDBusLocator
44geis_dbus_locator_new(GeisDBusClient client);
45
46/**
47 * Destroys a %GeisDBusLocator object.
48 *
49 * @param[in] locator A GeisDBusLocator.
50 */
51void
52geis_dbus_locator_delete(GeisDBusLocator locator);
53
54/**
55 * Gets the currently located server address.
56 *
57 * @param[in] locator A GeisDBusLocator.
58 */
59char *
60geis_dbus_locator_server_address(GeisDBusLocator locator);
61
62#endif /* GEIS_DBUS_LOCATOR_H_ */
063
=== modified file 'libutouch-geis/backend/test_fixture/geis_backend_test_fixture.c'
--- libutouch-geis/backend/test_fixture/geis_backend_test_fixture.c 2011-08-18 18:14:12 +0000
+++ libutouch-geis/backend/test_fixture/geis_backend_test_fixture.c 2011-10-17 21:56:23 +0000
@@ -77,8 +77,8 @@
77static GeisBackendToken _token_clone(GeisBackendToken);77static GeisBackendToken _token_clone(GeisBackendToken);
78static void _token_finalize(GeisBackendToken);78static void _token_finalize(GeisBackendToken);
79static void _token_compose(GeisBackendToken, GeisBackendToken);79static void _token_compose(GeisBackendToken, GeisBackendToken);
80static GeisStatus _token_activate(GeisBackendToken);80static GeisStatus _token_activate(GeisBackendToken, GeisSubscription);
81static GeisStatus _token_deactivate(GeisBackendToken);81static GeisStatus _token_deactivate(GeisBackendToken, GeisSubscription);
8282
83static struct GeisBackendTokenVtable _token_vtbl = {83static struct GeisBackendTokenVtable _token_vtbl = {
84 _token_clone,84 _token_clone,
@@ -361,7 +361,8 @@
361361
362362
363GeisStatus 363GeisStatus
364_token_activate(GeisBackendToken gbtoken)364_token_activate(GeisBackendToken gbtoken,
365 GeisSubscription subscription GEIS_UNUSED)
365{366{
366 GeisStatus status = GEIS_STATUS_SUCCESS;367 GeisStatus status = GEIS_STATUS_SUCCESS;
367 TestBackendToken token = _tbtoken_from_token(gbtoken);368 TestBackendToken token = _tbtoken_from_token(gbtoken);
@@ -371,7 +372,8 @@
371372
372373
373GeisStatus 374GeisStatus
374_token_deactivate(GeisBackendToken gbtoken GEIS_UNUSED)375_token_deactivate(GeisBackendToken gbtoken GEIS_UNUSED,
376 GeisSubscription subscription GEIS_UNUSED)
375{377{
376 GeisStatus status = GEIS_STATUS_SUCCESS;378 GeisStatus status = GEIS_STATUS_SUCCESS;
377 return status;379 return status;
@@ -381,7 +383,7 @@
381__attribute__((constructor))383__attribute__((constructor))
382static void _register_test_fixture()384static void _register_test_fixture()
383{385{
384 geis_register_backend(GEIS_INIT_UTOUCH_MOCK_ENGINE,386 geis_register_backend(GEIS_INIT_UTOUCH_MOCK_BACKEND,
385 sizeof(struct GeisBackendTestFixture),387 sizeof(struct GeisBackendTestFixture),
386 &tf_vtbl);388 &tf_vtbl);
387}389}
388390
=== modified file 'libutouch-geis/backend/xcb/geis_xcb_backend.c'
--- libutouch-geis/backend/xcb/geis_xcb_backend.c 2011-09-02 15:52:27 +0000
+++ libutouch-geis/backend/xcb/geis_xcb_backend.c 2011-10-17 21:56:23 +0000
@@ -105,7 +105,7 @@
105static void _construct(void *mem, Geis geis);105static void _construct(void *mem, Geis geis);
106static void _finalize(GeisBackend g);106static void _finalize(GeisBackend g);
107static GeisBackendToken _create_token(GeisBackend be, GeisBackendTokenInitState);107static GeisBackendToken _create_token(GeisBackend be, GeisBackendTokenInitState);
108static void _fd_callback(int fd, GeisBackendMultiplexorEvent ev, void *ctx);108static void _fd_callback(int fd, GeisBackendMultiplexorActivity ev, void *ctx);
109109
110110
111static struct GeisBackendVtable be_vtbl = {111static struct GeisBackendVtable be_vtbl = {
@@ -116,7 +116,7 @@
116116
117117
118/* A handy little table to map grail types to geis gesture classes. */118/* A handy little table to map grail types to geis gesture classes. */
119struct GrailTypeToGeisClass119static struct GrailTypeToGeisClass
120{120{
121 GeisInteger grail_type;121 GeisInteger grail_type;
122 GeisGestureClass geis_class;122 GeisGestureClass geis_class;
@@ -156,7 +156,8 @@
156 { GRAIL_TYPE_MTOUCH, NULL }156 { GRAIL_TYPE_MTOUCH, NULL }
157};157};
158158
159GeisSize s_grail_type_map_size = sizeof(s_grail_type_map) / sizeof(struct GrailTypeToGeisClass);159static GeisSize s_grail_type_map_size = sizeof(s_grail_type_map)
160 / sizeof(struct GrailTypeToGeisClass);
160161
161static void162static void
162_set_grail_type_class(GeisInteger grail_type, GeisGestureClass geis_class)163_set_grail_type_class(GeisInteger grail_type, GeisGestureClass geis_class)
@@ -653,7 +654,8 @@
653 }654 }
654655
655 be->xcb_fd = xcb_get_file_descriptor(be->xcb_connection);656 be->xcb_fd = xcb_get_file_descriptor(be->xcb_connection);
656 geis_multiplex_fd(be->geis, be->xcb_fd, _fd_callback, be);657 geis_multiplex_fd(be->geis, be->xcb_fd, GEIS_BE_MX_READ_AVAILABLE,
658 _fd_callback, be);
657659
658 be->sub_table = geis_xcb_backend_sub_table_new();660 be->sub_table = geis_xcb_backend_sub_table_new();
659661
@@ -933,9 +935,9 @@
933935
934/** @todo implement this */936/** @todo implement this */
935void937void
936_fd_callback(int fd GEIS_UNUSED,938_fd_callback(int fd GEIS_UNUSED,
937 GeisBackendMultiplexorEvent ev GEIS_UNUSED,939 GeisBackendMultiplexorActivity ev GEIS_UNUSED,
938 void *ctx)940 void *ctx)
939{941{
940 GeisXcbBackend be = (GeisXcbBackend)ctx;942 GeisXcbBackend be = (GeisXcbBackend)ctx;
941 _xcb_dispatch(be);943 _xcb_dispatch(be);
@@ -1022,7 +1024,7 @@
1022__attribute__((constructor))1024__attribute__((constructor))
1023static void _register_xcb_backend()1025static void _register_xcb_backend()
1024{1026{
1025 geis_register_backend(GEIS_INIT_UTOUCH_XCB,1027 geis_register_backend(GEIS_INIT_UTOUCH_XCB_BACKEND,
1026 sizeof(struct GeisXcbBackend),1028 sizeof(struct GeisXcbBackend),
1027 &be_vtbl);1029 &be_vtbl);
1028}1030}
10291031
=== modified file 'libutouch-geis/backend/xcb/geis_xcb_backend_token.c'
--- libutouch-geis/backend/xcb/geis_xcb_backend_token.c 2011-08-29 18:41:20 +0000
+++ libutouch-geis/backend/xcb/geis_xcb_backend_token.c 2011-10-17 21:56:23 +0000
@@ -55,8 +55,8 @@
55static GeisBackendToken _token_clone(GeisBackendToken);55static GeisBackendToken _token_clone(GeisBackendToken);
56static void _token_finalize(GeisBackendToken);56static void _token_finalize(GeisBackendToken);
57static void _token_compose(GeisBackendToken, GeisBackendToken);57static void _token_compose(GeisBackendToken, GeisBackendToken);
58static GeisStatus _token_activate(GeisBackendToken);58static GeisStatus _token_activate(GeisBackendToken, GeisSubscription);
59static GeisStatus _token_deactivate(GeisBackendToken);59static GeisStatus _token_deactivate(GeisBackendToken, GeisSubscription);
6060
61static struct GeisBackendTokenVtable _token_vtbl = {61static struct GeisBackendTokenVtable _token_vtbl = {
62 _token_clone,62 _token_clone,
@@ -317,7 +317,7 @@
317 * various back end subscriptions appropriately.317 * various back end subscriptions appropriately.
318 */318 */
319static GeisStatus 319static GeisStatus
320_token_activate(GeisBackendToken token)320_token_activate(GeisBackendToken token, GeisSubscription subscripton GEIS_UNUSED)
321{321{
322 GeisStatus status = GEIS_STATUS_UNKNOWN_ERROR;322 GeisStatus status = GEIS_STATUS_UNKNOWN_ERROR;
323 XcbBackendToken t = _xcb_token_from_geis_token(token);323 XcbBackendToken t = _xcb_token_from_geis_token(token);
@@ -338,7 +338,7 @@
338 * various back end subscriptions appropriately.338 * various back end subscriptions appropriately.
339 */339 */
340static GeisStatus 340static GeisStatus
341_token_deactivate(GeisBackendToken token)341_token_deactivate(GeisBackendToken token, GeisSubscription sub GEIS_UNUSED)
342{342{
343 GeisStatus status = GEIS_STATUS_SUCCESS;343 GeisStatus status = GEIS_STATUS_SUCCESS;
344 XcbBackendToken t = _xcb_token_from_geis_token(token);344 XcbBackendToken t = _xcb_token_from_geis_token(token);
345345
=== modified file 'libutouch-geis/backend/xcb/grail_gestures.c'
--- libutouch-geis/backend/xcb/grail_gestures.c 2011-07-22 15:54:50 +0000
+++ libutouch-geis/backend/xcb/grail_gestures.c 2011-10-17 21:56:23 +0000
@@ -505,7 +505,7 @@
505 (char *)grail_class->name);505 (char *)grail_class->name);
506 geis_frame_add_attr(frame, attr);506 geis_frame_add_attr(frame, attr);
507507
508 attr = geis_attr_new("geis gesture class id",508 attr = geis_attr_new(GEIS_CLASS_ATTRIBUTE_ID,
509 GEIS_ATTR_TYPE_INTEGER,509 GEIS_ATTR_TYPE_INTEGER,
510 (void *)&grail_class->geis_class_id);510 (void *)&grail_class->geis_class_id);
511 geis_frame_add_attr(frame, attr);511 geis_frame_add_attr(frame, attr);
512512
=== modified file 'libutouch-geis/geis.c'
--- libutouch-geis/geis.c 2011-08-21 16:28:27 +0000
+++ libutouch-geis/geis.c 2011-10-17 21:56:23 +0000
@@ -32,6 +32,7 @@
32#include "geis_attr.h"32#include "geis_attr.h"
33#include "geis_backend.h"33#include "geis_backend.h"
34#include "geis_class.h"34#include "geis_class.h"
35#include "server/geis_dbus_server.h" /* @TODO replace me */
35#include "geis_device.h"36#include "geis_device.h"
36#include "geis_backend_multiplexor.h"37#include "geis_backend_multiplexor.h"
37#include "geis_error.h"38#include "geis_error.h"
@@ -45,16 +46,6 @@
4546
4647
47/*48/*
48 * An internal struct to collect filterable attributes for facilities.
49 */
50typedef struct FilterableAttributeBag
51{
52 GeisFilterableAttribute store;
53 GeisSize size;
54 GeisSize count;
55} *FilterableAttributeBag;
56
57/*
58 * An internal structure to track processing callbacks in some order.49 * An internal structure to track processing callbacks in some order.
59 */50 */
60typedef struct GeisProcessingEntry *GeisProcessingEntry;51typedef struct GeisProcessingEntry *GeisProcessingEntry;
@@ -78,6 +69,8 @@
78 GeisSubBag subscription_bag;69 GeisSubBag subscription_bag;
79 GeisBackendMultiplexor backend_multiplexor;70 GeisBackendMultiplexor backend_multiplexor;
80 GeisBackend backend;71 GeisBackend backend;
72 GeisBoolean backend_pending;
73 GeisDBusServer server; /* @TODO: replace me */
81 GeisEventQueue input_event_queue;74 GeisEventQueue input_event_queue;
82 int input_event_signal_pipe[2];75 int input_event_signal_pipe[2];
83 GeisProcessingEntry processing_callbacks;76 GeisProcessingEntry processing_callbacks;
@@ -200,12 +193,14 @@
200 * Filters and transforms raw gesture events into cooked gesture events.193 * Filters and transforms raw gesture events into cooked gesture events.
201 */194 */
202static void195static void
203_input_event_handler(int fd, GeisBackendMultiplexorEvent mux_ev, void *context)196_input_event_handler(int fd,
197 GeisBackendMultiplexorActivity activity,
198 void *context)
204{199{
205 Geis geis = (Geis)context;200 Geis geis = (Geis)context;
206 GeisProcessingEntry cb;201 GeisProcessingEntry cb;
207202
208 if (mux_ev == GEIS_BE_MX_READ_AVAILABLE)203 if (activity & GEIS_BE_MX_READ_AVAILABLE)
209 {204 {
210 GeisEvent event;205 GeisEvent event;
211206
@@ -234,6 +229,20 @@
234 handled = _class_event_handler(geis, event);229 handled = _class_event_handler(geis, event);
235 break;230 break;
236231
232 case GEIS_EVENT_INIT_COMPLETE:
233 geis->backend_pending = GEIS_FALSE;
234 break;
235
236 case GEIS_EVENT_ERROR:
237 if (geis->backend_pending)
238 {
239 geis->backend = geis_backend_by_name(geis,
240 GEIS_INIT_UTOUCH_XCB_BACKEND);
241 geis->backend_pending = GEIS_FALSE;
242 handled = GEIS_TRUE;
243 }
244 break;
245
237 default:246 default:
238 break;247 break;
239 }248 }
@@ -273,93 +282,6 @@
273282
274283
275/*284/*
276 * Constructs a new filterable attribute bag.
277 */
278static FilterableAttributeBag
279_filterable_attribute_bag_new()
280{
281 FilterableAttributeBag bag = calloc(1, sizeof(struct FilterableAttributeBag));
282 if (!bag)
283 {
284 geis_error("failed to allocate filterable attribute bag");
285 goto final_exit;
286 }
287
288 bag->size = 2;
289 bag->count = 0;
290
291 bag->store = calloc(1, sizeof(struct GeisFilterableAttribute));
292 if (!bag)
293 {
294 geis_error("failed to allocate filterable attribute bag store");
295 goto unwind_bag;
296 }
297 goto final_exit;
298
299unwind_bag:
300 free(bag);
301 bag = NULL;
302final_exit:
303 return bag;
304}
305
306
307/*
308 * Destroys a filterable attribute bag.
309 */
310static void
311_filterable_attribute_bag_delete(FilterableAttributeBag bag)
312{
313 if (bag)
314 {
315 GeisSize i;
316 for (i = 0; i < bag->count; ++i)
317 {
318 free((char *)bag->store[i].name);
319 }
320 free(bag->store);
321 }
322 free(bag);
323}
324
325
326static void
327_filterable_attribute_copy(GeisFilterableAttribute src,
328 GeisFilterableAttribute dst)
329{
330 dst->name = strdup(src->name);
331 dst->type = src->type;
332 dst->add_term_callback = src->add_term_callback;
333 dst->add_term_context = src->add_term_context;
334}
335
336
337static void
338_filterable_attribute_bag_insert(FilterableAttributeBag bag,
339 GeisFilterableAttribute fa)
340{
341 GeisSize new_count = bag->count + 1;
342 if (new_count >= bag->size)
343 {
344 GeisSize new_size = bag->size * 2;
345 GeisSize allocation_size = new_size * sizeof(struct GeisFilterableAttribute);
346 GeisFilterableAttribute new_store = realloc(bag->store, allocation_size);
347 if (!new_store)
348 {
349 geis_error("failed to reallocate filterable attribute bag store");
350 }
351 else
352 {
353 bag->store = new_store;
354 bag->size = new_size;
355 }
356 }
357 _filterable_attribute_copy(fa, &bag->store[bag->count]);
358 bag->count = new_count;
359}
360
361
362/*
363 * Applies the back end callback to the back end token for each filterable285 * Applies the back end callback to the back end token for each filterable
364 * attribute with a name matching the argument.286 * attribute with a name matching the argument.
365 */287 */
@@ -371,13 +293,16 @@
371 void *value)293 void *value)
372{294{
373 GeisStatus status = GEIS_STATUS_SUCCESS;295 GeisStatus status = GEIS_STATUS_SUCCESS;
374 GeisSize i;296 GeisFilterableAttributeBagIter it;
375 for (i = 0; i < bag->count; ++i)297 for (it = geis_filterable_attribute_bag_begin(bag);
298 it != geis_filterable_attribute_bag_end(bag);
299 it = geis_filterable_attribute_bag_next(bag, it))
376 {300 {
377 GeisFilterableAttribute fa = &bag->store[i];301 if (0 == strcmp(it->name, name) && it->add_term_callback)
378 if (0 == strcmp(fa->name, name))
379 {302 {
380 status = fa->add_term_callback(token, fa->add_term_context, name, op, value);303 status = it->add_term_callback(token,
304 it->add_term_context,
305 name, op, value);
381 }306 }
382 }307 }
383 return status;308 return status;
@@ -389,11 +314,11 @@
389 */314 */
390GeisStatus315GeisStatus
391geis_filterable_attribute_foreach(Geis geis,316geis_filterable_attribute_foreach(Geis geis,
392 GeisFilterFacility facility,317 GeisFilterFacility facility,
393 GeisBackendToken token,318 GeisBackendToken token,
394 GeisString name,319 GeisString name,
395 GeisFilterOperation op,320 GeisFilterOperation op,
396 void *value)321 void *value)
397{322{
398 GeisStatus status = GEIS_STATUS_UNKNOWN_ERROR;323 GeisStatus status = GEIS_STATUS_UNKNOWN_ERROR;
399 switch (facility)324 switch (facility)
@@ -470,6 +395,7 @@
470 }395 }
471 geis_backend_multiplexor_add_fd(geis->backend_multiplexor,396 geis_backend_multiplexor_add_fd(geis->backend_multiplexor,
472 geis->input_event_signal_pipe[0],397 geis->input_event_signal_pipe[0],
398 GEIS_BE_MX_READ_AVAILABLE,
473 _input_event_handler,399 _input_event_handler,
474 geis);400 geis);
475401
@@ -482,7 +408,7 @@
482 }408 }
483 geis->output_event_callback = _default_output_event_callback;409 geis->output_event_callback = _default_output_event_callback;
484410
485 geis->class_filterable_attributes = _filterable_attribute_bag_new();411 geis->class_filterable_attributes = geis_filterable_attribute_bag_new();
486 if (!geis->class_filterable_attributes)412 if (!geis->class_filterable_attributes)
487 {413 {
488 geis_error_push(NULL, GEIS_STATUS_UNKNOWN_ERROR);414 geis_error_push(NULL, GEIS_STATUS_UNKNOWN_ERROR);
@@ -499,7 +425,7 @@
499 }425 }
500 geis->class_event_callback = _default_output_event_callback;426 geis->class_event_callback = _default_output_event_callback;
501427
502 geis->device_filterable_attributes = _filterable_attribute_bag_new();428 geis->device_filterable_attributes = geis_filterable_attribute_bag_new();
503 if (!geis->device_filterable_attributes)429 if (!geis->device_filterable_attributes)
504 {430 {
505 geis_error_push(NULL, GEIS_STATUS_UNKNOWN_ERROR);431 geis_error_push(NULL, GEIS_STATUS_UNKNOWN_ERROR);
@@ -516,13 +442,13 @@
516 }442 }
517 geis->device_event_callback = _default_output_event_callback;443 geis->device_event_callback = _default_output_event_callback;
518444
519 geis->region_filterable_attributes = _filterable_attribute_bag_new();445 geis->region_filterable_attributes = geis_filterable_attribute_bag_new();
520 if (!geis->region_filterable_attributes)446 if (!geis->region_filterable_attributes)
521 {447 {
522 goto unwind_device_bag;448 goto unwind_device_bag;
523 }449 }
524450
525 geis->special_filterable_attributes = _filterable_attribute_bag_new();451 geis->special_filterable_attributes = geis_filterable_attribute_bag_new();
526 if (!geis->special_filterable_attributes)452 if (!geis->special_filterable_attributes)
527 {453 {
528 goto unwind_region_attrs;454 goto unwind_region_attrs;
@@ -531,15 +457,15 @@
531 goto final_exit;457 goto final_exit;
532458
533unwind_region_attrs:459unwind_region_attrs:
534 _filterable_attribute_bag_delete(geis->region_filterable_attributes);460 geis_filterable_attribute_bag_delete(geis->region_filterable_attributes);
535unwind_device_bag:461unwind_device_bag:
536 geis_device_bag_delete(geis->devices);462 geis_device_bag_delete(geis->devices);
537unwind_device_attrs:463unwind_device_attrs:
538 _filterable_attribute_bag_delete(geis->device_filterable_attributes);464 geis_filterable_attribute_bag_delete(geis->device_filterable_attributes);
539unwind_class_bag:465unwind_class_bag:
540 geis_gesture_class_bag_delete(geis->gesture_classes);466 geis_gesture_class_bag_delete(geis->gesture_classes);
541unwind_class_attrs:467unwind_class_attrs:
542 _filterable_attribute_bag_delete(geis->class_filterable_attributes);468 geis_filterable_attribute_bag_delete(geis->class_filterable_attributes);
543unwind_output_queue:469unwind_output_queue:
544 geis_event_queue_delete(geis->output_event_queue);470 geis_event_queue_delete(geis->output_event_queue);
545unwind_input_signal_pipe:471unwind_input_signal_pipe:
@@ -564,6 +490,7 @@
564{490{
565 BACK_END_TYPE_NONE,491 BACK_END_TYPE_NONE,
566 BACK_END_TYPE_MOCK_ENGINE,492 BACK_END_TYPE_MOCK_ENGINE,
493 BACK_END_TYPE_DBUS,
567 BACK_END_TYPE_XCB494 BACK_END_TYPE_XCB
568} BackendType;495} BackendType;
569496
@@ -580,7 +507,7 @@
580 {507 {
581 if (0 == strcmp(init_arg_name, GEIS_INIT_SERVICE_PROVIDER))508 if (0 == strcmp(init_arg_name, GEIS_INIT_SERVICE_PROVIDER))
582 {509 {
583 geis_debug("initializing GEIS server");510 geis->server = geis_dbus_server_new(geis);
584 }511 }
585 else if (0 == strcmp(init_arg_name, GEIS_INIT_TRACK_DEVICES))512 else if (0 == strcmp(init_arg_name, GEIS_INIT_TRACK_DEVICES))
586 {513 {
@@ -590,7 +517,7 @@
590 {517 {
591 /* no longer supported */518 /* no longer supported */
592 }519 }
593 else if (0 == strcmp(init_arg_name, GEIS_INIT_UTOUCH_MOCK_ENGINE))520 else if (0 == strcmp(init_arg_name, GEIS_INIT_UTOUCH_MOCK_BACKEND))
594 {521 {
595 if (back_end_type != BACK_END_TYPE_NONE)522 if (back_end_type != BACK_END_TYPE_NONE)
596 {523 {
@@ -598,7 +525,15 @@
598 }525 }
599 back_end_type = BACK_END_TYPE_MOCK_ENGINE;526 back_end_type = BACK_END_TYPE_MOCK_ENGINE;
600 }527 }
601 else if (0 == strcmp(init_arg_name, GEIS_INIT_UTOUCH_XCB))528 else if (0 == strcmp(init_arg_name, GEIS_INIT_UTOUCH_DBUS_BACKEND))
529 {
530 if (back_end_type != BACK_END_TYPE_NONE)
531 {
532 geis_error("multiple back ends requested, only using last request");
533 }
534 back_end_type = BACK_END_TYPE_DBUS;
535 }
536 else if (0 == strcmp(init_arg_name, GEIS_INIT_UTOUCH_XCB_BACKEND))
602 {537 {
603 if (back_end_type != BACK_END_TYPE_NONE)538 if (back_end_type != BACK_END_TYPE_NONE)
604 {539 {
@@ -612,16 +547,22 @@
612547
613 if (back_end_type == BACK_END_TYPE_MOCK_ENGINE)548 if (back_end_type == BACK_END_TYPE_MOCK_ENGINE)
614 {549 {
615 geis->backend = geis_backend_by_name(geis, GEIS_INIT_UTOUCH_MOCK_ENGINE);550 geis->backend = geis_backend_by_name(geis, GEIS_INIT_UTOUCH_MOCK_BACKEND);
616 }551 }
617 else if (back_end_type ==BACK_END_TYPE_XCB)552 else if (back_end_type == BACK_END_TYPE_DBUS)
618 {553 {
619 geis->backend = geis_backend_by_name(geis, GEIS_INIT_UTOUCH_XCB);554 geis->backend = geis_backend_by_name(geis, GEIS_INIT_UTOUCH_DBUS_BACKEND);
555 geis->backend_pending = GEIS_TRUE;
556 }
557 else if (back_end_type == BACK_END_TYPE_XCB)
558 {
559 geis->backend = geis_backend_by_name(geis, GEIS_INIT_UTOUCH_XCB_BACKEND);
620 }560 }
621 else561 else
622 {562 {
623 geis_warning("back end not specified, defaulting to XCB");563 geis_warning("back end not specified, defaulting to DBus");
624 geis->backend = geis_backend_by_name(geis, GEIS_INIT_UTOUCH_XCB);564 geis->backend = geis_backend_by_name(geis, GEIS_INIT_UTOUCH_DBUS_BACKEND);
565 geis->backend_pending = GEIS_TRUE;
625 }566 }
626 if (!geis->backend)567 if (!geis->backend)
627 {568 {
@@ -681,16 +622,18 @@
681 }622 }
682623
683 geis_gesture_flick_delete(geis->flick);624 geis_gesture_flick_delete(geis->flick);
684 _filterable_attribute_bag_delete(geis->special_filterable_attributes);625 geis_filterable_attribute_bag_delete(geis->special_filterable_attributes);
685 _filterable_attribute_bag_delete(geis->region_filterable_attributes);626 geis_filterable_attribute_bag_delete(geis->region_filterable_attributes);
686 geis_device_bag_delete(geis->devices);627 geis_device_bag_delete(geis->devices);
687 _filterable_attribute_bag_delete(geis->device_filterable_attributes);628 geis_filterable_attribute_bag_delete(geis->device_filterable_attributes);
688 geis_gesture_class_bag_delete(geis->gesture_classes);629 geis_gesture_class_bag_delete(geis->gesture_classes);
689 _filterable_attribute_bag_delete(geis->class_filterable_attributes);630 geis_filterable_attribute_bag_delete(geis->class_filterable_attributes);
690 geis_event_queue_delete(geis->output_event_queue);631 geis_event_queue_delete(geis->output_event_queue);
691 close(geis->input_event_signal_pipe[0]);632 close(geis->input_event_signal_pipe[0]);
692 close(geis->input_event_signal_pipe[1]);633 close(geis->input_event_signal_pipe[1]);
693 geis_event_queue_delete(geis->input_event_queue);634 geis_event_queue_delete(geis->input_event_queue);
635 if (geis->server)
636 geis_dbus_server_delete(geis->server);
694 if (geis->backend)637 if (geis->backend)
695 geis_backend_delete(geis->backend);638 geis_backend_delete(geis->backend);
696 geis_backend_multiplexor_delete(geis->backend_multiplexor);639 geis_backend_multiplexor_delete(geis->backend_multiplexor);
@@ -930,13 +873,31 @@
930 * Adds a back end file descriptor to multiplex.873 * Adds a back end file descriptor to multiplex.
931 */874 */
932void875void
933geis_multiplex_fd(Geis geis,876geis_multiplex_fd(Geis geis,
934 int fd,877 int fd,
935 GeisBackendFdEventCallback callback,878 GeisBackendMultiplexorActivity activity,
936 void *context)879 GeisBackendFdEventCallback callback,
880 void *context)
937{881{
938 geis_backend_multiplexor_add_fd(geis->backend_multiplexor,882 geis_backend_multiplexor_add_fd(geis->backend_multiplexor,
939 fd, callback, context);883 fd,
884 activity,
885 callback,
886 context);
887}
888
889
890/*
891 * Modifies a multiplexed back end file descriptor.
892 */
893void
894geis_remultiplex_fd(Geis geis,
895 int fd,
896 GeisBackendMultiplexorActivity activity)
897{
898 geis_backend_multiplexor_modify_fd(geis->backend_multiplexor,
899 fd,
900 activity);
940}901}
941902
942903
@@ -957,10 +918,16 @@
957}918}
958919
959920
960GeisSubBag921GeisSize
961geis_subscription_bag(Geis geis)922geis_add_subscription(Geis geis, GeisSubscription subscription)
962{923{
963 return geis->subscription_bag;924 return geis_subscription_bag_insert(geis->subscription_bag, subscription);
925}
926
927void
928geis_remove_subscription(Geis geis, GeisSubscription subscription)
929{
930 geis_subscription_bag_remove(geis->subscription_bag, subscription);
964}931}
965932
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches

to all changes: