Merge lp:~dbusmenu-team/libdbusmenu/ubuntu into lp:~ubuntu-desktop/libdbusmenu/ubuntu

Proposed by Ted Gould
Status: Merged
Merged at revision: not available
Proposed branch: lp:~dbusmenu-team/libdbusmenu/ubuntu
Merge into: lp:~ubuntu-desktop/libdbusmenu/ubuntu
Diff against target: 1407 lines (+1182/-8)
15 files modified
.bzrignore (+5/-0)
Makefile.am (+1/-1)
configure.ac (+3/-3)
debian/changelog (+9/-0)
debian/rules (+2/-2)
libdbusmenu-glib/Makefile.am (+3/-0)
libdbusmenu-glib/client.c (+130/-1)
libdbusmenu-glib/menuitem-proxy.c (+362/-0)
libdbusmenu-glib/menuitem-proxy.h (+74/-0)
libdbusmenu-glib/server.c (+20/-1)
tests/Makefile.am (+54/-0)
tests/test-glib-proxy-client.c (+171/-0)
tests/test-glib-proxy-proxy.c (+80/-0)
tests/test-glib-proxy-server.c (+126/-0)
tests/test-glib-proxy.h (+142/-0)
To merge this branch: bzr merge lp:~dbusmenu-team/libdbusmenu/ubuntu
Reviewer Review Type Date Requested Status
Sebastien Bacher Pending
Review via email: mp+19633@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Ted Gould (ted) wrote :

0.2.5

lp:~dbusmenu-team/libdbusmenu/ubuntu updated
67. By Sebastien Bacher

releasing version 0.2.5-0ubuntu1

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file '.bzrignore'
--- .bzrignore 2010-02-05 07:30:25 +0000
+++ .bzrignore 2010-02-18 17:06:16 +0000
@@ -60,3 +60,8 @@
60tests/test-glib-objects.xml60tests/test-glib-objects.xml
61tools/testapp/dbusmenu-testapp61tools/testapp/dbusmenu-testapp
62libdbusmenu-glib/libdbusmenu_glib_la-client-menuitem.lo62libdbusmenu-glib/libdbusmenu_glib_la-client-menuitem.lo
63libdbusmenu-glib/libdbusmenu_glib_la-menuitem-proxy.lo
64tests/test-glib-proxy-client
65tests/test-glib-proxy-server
66tests/test-glib-proxy-proxy
67tests/test-glib-proxy
6368
=== modified file 'Makefile.am'
--- Makefile.am 2010-01-07 17:13:09 +0000
+++ Makefile.am 2010-02-18 17:06:16 +0000
@@ -1,3 +1,3 @@
11EXTRA_DIST = COPYING.2.1 COPYING-GPL3
2SUBDIRS = libdbusmenu-glib libdbusmenu-gtk tools tests po2SUBDIRS = libdbusmenu-glib libdbusmenu-gtk tools tests po
33
44
=== modified file 'configure.ac'
--- configure.ac 2010-02-11 16:09:27 +0000
+++ configure.ac 2010-02-18 17:06:16 +0000
@@ -1,11 +1,11 @@
11
2AC_INIT(libdbusmenu, 0.2.4, ted@canonical.com)2AC_INIT(libdbusmenu, 0.2.5, ted@canonical.com)
3AC_COPYRIGHT([Copyright 2009,2010 Canonical])3AC_COPYRIGHT([Copyright 2009,2010 Canonical])
44
5AC_PREREQ(2.53)5AC_PREREQ(2.53)
66
7AM_CONFIG_HEADER(config.h)7AM_CONFIG_HEADER(config.h)
8AM_INIT_AUTOMAKE(libdbusmenu, 0.2.4)8AM_INIT_AUTOMAKE(libdbusmenu, 0.2.5)
99
10AM_MAINTAINER_MODE10AM_MAINTAINER_MODE
1111
@@ -66,7 +66,7 @@
66###########################66###########################
6767
68LIBDBUSMENU_CURRENT=168LIBDBUSMENU_CURRENT=1
69LIBDBUSMENU_REVISION=269LIBDBUSMENU_REVISION=3
70LIBDBUSMENU_AGE=070LIBDBUSMENU_AGE=0
7171
72AC_SUBST(LIBDBUSMENU_CURRENT)72AC_SUBST(LIBDBUSMENU_CURRENT)
7373
=== modified file 'debian/changelog'
--- debian/changelog 2010-02-11 16:13:58 +0000
+++ debian/changelog 2010-02-18 17:06:16 +0000
@@ -1,3 +1,12 @@
1libdbusmenu (0.2.5-0ubuntu1~ppa1) lucid; urgency=low
2
3 * Upstream release 0.2.5
4 * Adding in menuitem proxy object.
5 * Adding ID to default <menu> item.
6 * debian/rules: Updating shlibs
7
8 -- Ted Gould <ted@ubuntu.com> Thu, 18 Feb 2010 11:00:24 -0600
9
1libdbusmenu (0.2.4-0ubuntu1) lucid; urgency=low10libdbusmenu (0.2.4-0ubuntu1) lucid; urgency=low
211
3 * Upstream release 0.2.412 * Upstream release 0.2.4
413
=== modified file 'debian/rules'
--- debian/rules 2010-02-04 22:09:19 +0000
+++ debian/rules 2010-02-18 17:06:16 +0000
@@ -6,6 +6,6 @@
6DEB_CONFIGURE_EXTRA_FLAGS += --disable-scrollkeeper6DEB_CONFIGURE_EXTRA_FLAGS += --disable-scrollkeeper
7LDFLAGS += -Wl,-z,defs -Wl,--as-needed7LDFLAGS += -Wl,-z,defs -Wl,--as-needed
88
9DEB_DH_MAKESHLIBS_ARGS_libdbusmenu-gtk1 += -V 'libdbusmenu-gtk1 (>= 0.2.2)'9DEB_DH_MAKESHLIBS_ARGS_libdbusmenu-gtk1 += -V 'libdbusmenu-gtk1 (>= 0.2.5)'
10DEB_DH_MAKESHLIBS_ARGS_libdbusmenu-glib1 += -V 'libdbusmenu-glib1 (>= 0.2.2)'10DEB_DH_MAKESHLIBS_ARGS_libdbusmenu-glib1 += -V 'libdbusmenu-glib1 (>= 0.2.5)'
1111
1212
=== modified file 'libdbusmenu-glib/Makefile.am'
--- libdbusmenu-glib/Makefile.am 2010-02-04 02:00:36 +0000
+++ libdbusmenu-glib/Makefile.am 2010-02-18 17:06:16 +0000
@@ -12,6 +12,7 @@
1212
13libdbusmenu_glibinclude_HEADERS = \13libdbusmenu_glibinclude_HEADERS = \
14 menuitem.h \14 menuitem.h \
15 menuitem-proxy.h \
15 server.h \16 server.h \
16 client.h17 client.h
1718
@@ -23,6 +24,8 @@
23 menuitem-marshal.h \24 menuitem-marshal.h \
24 menuitem-marshal.c \25 menuitem-marshal.c \
25 menuitem-private.h \26 menuitem-private.h \
27 menuitem-proxy.h \
28 menuitem-proxy.c \
26 server.h \29 server.h \
27 server.c \30 server.c \
28 server-marshal.h \31 server-marshal.h \
2932
=== modified file 'libdbusmenu-glib/client.c'
--- libdbusmenu-glib/client.c 2010-02-09 17:13:51 +0000
+++ libdbusmenu-glib/client.c 2010-02-18 17:06:16 +0000
@@ -75,6 +75,8 @@
75 DBusGProxy * dbusproxy;75 DBusGProxy * dbusproxy;
7676
77 GHashTable * type_handlers;77 GHashTable * type_handlers;
78
79 GArray * delayed_properties;
78};80};
7981
80typedef struct _newItemPropData newItemPropData;82typedef struct _newItemPropData newItemPropData;
@@ -85,6 +87,21 @@
85 DbusmenuMenuitem * parent;87 DbusmenuMenuitem * parent;
86};88};
8789
90typedef struct _propertyDelay propertyDelay;
91struct _propertyDelay
92{
93 guint revision;
94 GArray * entries;
95};
96
97typedef struct _propertyDelayValue propertyDelayValue;
98struct _propertyDelayValue
99{
100 gint id;
101 gchar * name;
102 GValue value;
103};
104
88#define DBUSMENU_CLIENT_GET_PRIVATE(o) \105#define DBUSMENU_CLIENT_GET_PRIVATE(o) \
89(G_TYPE_INSTANCE_GET_PRIVATE ((o), DBUSMENU_TYPE_CLIENT, DbusmenuClientPrivate))106(G_TYPE_INSTANCE_GET_PRIVATE ((o), DBUSMENU_TYPE_CLIENT, DbusmenuClientPrivate))
90107
@@ -208,6 +225,8 @@
208 priv->type_handlers = g_hash_table_new_full(g_str_hash, g_str_equal,225 priv->type_handlers = g_hash_table_new_full(g_str_hash, g_str_equal,
209 g_free, NULL);226 g_free, NULL);
210227
228 priv->delayed_properties = g_array_new(FALSE, TRUE, sizeof(propertyDelay));
229
211 return;230 return;
212}231}
213232
@@ -255,6 +274,23 @@
255 g_hash_table_destroy(priv->type_handlers);274 g_hash_table_destroy(priv->type_handlers);
256 }275 }
257276
277 if (priv->delayed_properties) {
278 gint i;
279 for (i = 0; i < priv->delayed_properties->len; i++) {
280 propertyDelay * delay = &g_array_index(priv->delayed_properties, propertyDelay, i);
281 gint j;
282 for (j = 0; j < delay->entries->len; j++) {
283 propertyDelayValue * value = &g_array_index(delay->entries, propertyDelayValue, j);
284 g_free(value->name);
285 g_value_unset(&value->value);
286 }
287 g_array_free(delay->entries, TRUE);
288 delay->entries = NULL;
289 }
290 g_array_free(priv->delayed_properties, TRUE);
291 priv->delayed_properties = NULL;
292 }
293
258 G_OBJECT_CLASS (dbusmenu_client_parent_class)->finalize (object);294 G_OBJECT_CLASS (dbusmenu_client_parent_class)->finalize (object);
259 return;295 return;
260}296}
@@ -319,6 +355,49 @@
319 return;355 return;
320}356}
321357
358/* Add an entry to the set of entries that are delayed until the
359 layout has been updated to this revision */
360static void
361delay_prop_update (guint revision, GArray * delayarray, gint id, gchar * prop, GValue * value)
362{
363 propertyDelay * delay = NULL;
364 gint i;
365
366 /* First look for something with this revision number. This
367 array should be really short, probably not more than an entry or
368 two so there is no reason to optimize this. */
369 for (i = 0; i < delayarray->len; i++) {
370 propertyDelay * localdelay = &g_array_index(delayarray, propertyDelay, i);
371 if (localdelay->revision == revision) {
372 delay = localdelay;
373 break;
374 }
375 }
376
377 /* If we don't have any entires for this revision number then we
378 need to create a new one with it's own array of entires. */
379 if (delay == NULL) {
380 propertyDelay localdelay = {0};
381 localdelay.revision = revision;
382 localdelay.entries = g_array_new(FALSE, TRUE, sizeof(propertyDelayValue));
383
384 g_array_append_val(delayarray, localdelay);
385 delay = &g_array_index(delayarray, propertyDelay, delayarray->len - 1);
386 }
387
388 /* Build the actual entry and tack it on the end of the array
389 of entries */
390 propertyDelayValue delayvalue = {0};
391 delayvalue.id = id;
392 delayvalue.name = g_strdup(prop);
393
394 g_value_init(&delayvalue.value, G_VALUE_TYPE(value));
395 g_value_copy(value, &delayvalue.value);
396
397 g_array_append_val(delay->entries, delayvalue);
398 return;
399}
400
322/* Signal from the server that a property has changed401/* Signal from the server that a property has changed
323 on one of our menuitems */402 on one of our menuitems */
324static void403static void
@@ -333,7 +412,16 @@
333 #endif412 #endif
334413
335 DbusmenuClientPrivate * priv = DBUSMENU_CLIENT_GET_PRIVATE(client);414 DbusmenuClientPrivate * priv = DBUSMENU_CLIENT_GET_PRIVATE(client);
336 g_return_if_fail(priv->root != NULL);415
416 /* If we're not on the right revision, we need to cache the property
417 changes as it could be that the menuitems don't exist yet. */
418 if (priv->root == NULL || priv->my_revision != priv->current_revision) {
419 #ifdef MASSIVEDEBUGGING
420 g_debug("Delaying prop update until rev %d for id %d property %s", priv->current_revision, id, property);
421 #endif
422 delay_prop_update(priv->current_revision, priv->delayed_properties, id, property, value);
423 return;
424 }
337425
338 DbusmenuMenuitem * menuitem = dbusmenu_menuitem_find_id(priv->root, id);426 DbusmenuMenuitem * menuitem = dbusmenu_menuitem_find_id(priv->root, id);
339 g_return_if_fail(menuitem != NULL);427 g_return_if_fail(menuitem != NULL);
@@ -810,16 +898,19 @@
810 DbusmenuClient * client = DBUSMENU_CLIENT(data);898 DbusmenuClient * client = DBUSMENU_CLIENT(data);
811 DbusmenuClientPrivate * priv = DBUSMENU_CLIENT_GET_PRIVATE(client);899 DbusmenuClientPrivate * priv = DBUSMENU_CLIENT_GET_PRIVATE(client);
812900
901 /* Check to make sure this isn't an issue */
813 if (error != NULL) {902 if (error != NULL) {
814 g_warning("Getting layout failed on client %s object %s: %s", priv->dbus_name, priv->dbus_object, error->message);903 g_warning("Getting layout failed on client %s object %s: %s", priv->dbus_name, priv->dbus_object, error->message);
815 return;904 return;
816 }905 }
817906
907 /* Try to take in the layout that we got */
818 if (!parse_layout(client, xml)) {908 if (!parse_layout(client, xml)) {
819 g_warning("Unable to parse layout!");909 g_warning("Unable to parse layout!");
820 return;910 return;
821 }911 }
822912
913 /* Success, so we need to update our local variables */
823 priv->my_revision = rev;914 priv->my_revision = rev;
824 /* g_debug("Root is now: 0x%X", (unsigned int)priv->root); */915 /* g_debug("Root is now: 0x%X", (unsigned int)priv->root); */
825 priv->layoutcall = NULL;916 priv->layoutcall = NULL;
@@ -828,6 +919,44 @@
828 #endif 919 #endif
829 g_signal_emit(G_OBJECT(client), signals[LAYOUT_UPDATED], 0, TRUE);920 g_signal_emit(G_OBJECT(client), signals[LAYOUT_UPDATED], 0, TRUE);
830921
922 /* Apply the delayed properties that were queued up while
923 we were waiting on this layout update. */
924 if (G_LIKELY(priv->delayed_properties != NULL)) {
925 gint i;
926 for (i = 0; i < priv->delayed_properties->len; i++) {
927 propertyDelay * delay = &g_array_index(priv->delayed_properties, propertyDelay, i);
928 if (delay->revision > priv->my_revision) {
929 /* Check to see if this is for future revisions, which
930 is possible if there is a ton of updates. */
931 break;
932 }
933
934 gint j;
935 for (j = 0; j < delay->entries->len; j++) {
936 propertyDelayValue * value = &g_array_index(delay->entries, propertyDelayValue, j);
937 DbusmenuMenuitem * mi = dbusmenu_menuitem_find_id(priv->root, value->id);
938 if (mi != NULL) {
939 #ifdef MASSIVEDEBUGGING
940 g_debug("Applying delayed property id %d property %s", value->id, value->name);
941 #endif
942 dbusmenu_menuitem_property_set_value(mi, value->name, &value->value);
943 }
944 g_free(value->name);
945 g_value_unset(&value->value);
946 }
947 g_array_free(delay->entries, TRUE);
948
949 /* We're removing the entry and moving the index down one
950 to ensure that we adjust for the shift in the array. The
951 reality is that i is always 0. You understood this loop
952 until you got here, didn't you :) */
953 g_array_remove_index(priv->delayed_properties, i);
954 i--;
955 }
956 }
957
958 /* Check to see if we got another update in the time this
959 one was issued. */
831 if (priv->my_revision < priv->current_revision) {960 if (priv->my_revision < priv->current_revision) {
832 update_layout(client);961 update_layout(client);
833 }962 }
834963
=== added file 'libdbusmenu-glib/menuitem-proxy.c'
--- libdbusmenu-glib/menuitem-proxy.c 1970-01-01 00:00:00 +0000
+++ libdbusmenu-glib/menuitem-proxy.c 2010-02-18 17:06:16 +0000
@@ -0,0 +1,362 @@
1/*
2An object to ferry over properties and signals between two different
3dbusmenu instances. Useful for services.
4
5Copyright 2010 Canonical Ltd.
6
7Authors:
8 Ted Gould <ted@canonical.com>
9
10This program is free software: you can redistribute it and/or modify it
11under the terms of either or both of the following licenses:
12
131) the GNU Lesser General Public License version 3, as published by the
14Free Software Foundation; and/or
152) the GNU Lesser General Public License version 2.1, as published by
16the Free Software Foundation.
17
18This program is distributed in the hope that it will be useful, but
19WITHOUT ANY WARRANTY; without even the implied warranties of
20MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
21PURPOSE. See the applicable version of the GNU Lesser General Public
22License for more details.
23
24You should have received a copy of both the GNU Lesser General Public
25License version 3 and version 2.1 along with this program. If not, see
26<http://www.gnu.org/licenses/>
27*/
28
29#ifdef HAVE_CONFIG_H
30#include "config.h"
31#endif
32
33#include "menuitem-proxy.h"
34
35typedef struct _DbusmenuMenuitemProxyPrivate DbusmenuMenuitemProxyPrivate;
36struct _DbusmenuMenuitemProxyPrivate {
37 DbusmenuMenuitem * mi;
38 gulong sig_property_changed;
39 gulong sig_child_added;
40 gulong sig_child_removed;
41 gulong sig_child_moved;
42};
43
44/* Properties */
45enum {
46 PROP_0,
47 PROP_MENU_ITEM
48};
49
50#define PROP_MENU_ITEM_S "menu-item"
51
52#define DBUSMENU_MENUITEM_PROXY_GET_PRIVATE(o) \
53(G_TYPE_INSTANCE_GET_PRIVATE ((o), DBUSMENU_TYPE_MENUITEM_PROXY, DbusmenuMenuitemProxyPrivate))
54
55static void dbusmenu_menuitem_proxy_class_init (DbusmenuMenuitemProxyClass *klass);
56static void dbusmenu_menuitem_proxy_init (DbusmenuMenuitemProxy *self);
57static void dbusmenu_menuitem_proxy_dispose (GObject *object);
58static void dbusmenu_menuitem_proxy_finalize (GObject *object);
59static void set_property (GObject * obj, guint id, const GValue * value, GParamSpec * pspec);
60static void get_property (GObject * obj, guint id, GValue * value, GParamSpec * pspec);
61static void handle_event (DbusmenuMenuitem * mi, const gchar * name, const GValue * value, guint timestamp);
62static void add_menuitem (DbusmenuMenuitemProxy * pmi, DbusmenuMenuitem * mi);
63static void remove_menuitem (DbusmenuMenuitemProxy * pmi);
64
65G_DEFINE_TYPE (DbusmenuMenuitemProxy, dbusmenu_menuitem_proxy, DBUSMENU_TYPE_MENUITEM);
66
67static void
68dbusmenu_menuitem_proxy_class_init (DbusmenuMenuitemProxyClass *klass)
69{
70 GObjectClass *object_class = G_OBJECT_CLASS (klass);
71
72 g_type_class_add_private (klass, sizeof (DbusmenuMenuitemProxyPrivate));
73
74 object_class->dispose = dbusmenu_menuitem_proxy_dispose;
75 object_class->finalize = dbusmenu_menuitem_proxy_finalize;
76 object_class->set_property = set_property;
77 object_class->get_property = get_property;
78
79 DbusmenuMenuitemClass * miclass = DBUSMENU_MENUITEM_CLASS(klass);
80
81 miclass->handle_event = handle_event;
82
83 g_object_class_install_property (object_class, PROP_MENU_ITEM,
84 g_param_spec_object(PROP_MENU_ITEM_S, "The Menuitem we're proxying",
85 "An instance of the DbusmenuMenuitem class that this menuitem will mimic.",
86 DBUSMENU_TYPE_MENUITEM,
87 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
88
89 return;
90}
91
92static void
93dbusmenu_menuitem_proxy_init (DbusmenuMenuitemProxy *self)
94{
95 DbusmenuMenuitemProxyPrivate * priv = DBUSMENU_MENUITEM_PROXY_GET_PRIVATE(self);
96
97 priv->mi = NULL;
98
99 priv->sig_property_changed = 0;
100 priv->sig_child_added = 0;
101 priv->sig_child_removed = 0;
102 priv->sig_child_moved = 0;
103
104 return;
105}
106
107/* Remove references to objects */
108static void
109dbusmenu_menuitem_proxy_dispose (GObject *object)
110{
111 remove_menuitem(DBUSMENU_MENUITEM_PROXY(object));
112
113 G_OBJECT_CLASS (dbusmenu_menuitem_proxy_parent_class)->dispose (object);
114 return;
115}
116
117/* Free any memory that we've allocated */
118static void
119dbusmenu_menuitem_proxy_finalize (GObject *object)
120{
121
122 G_OBJECT_CLASS (dbusmenu_menuitem_proxy_parent_class)->finalize (object);
123 return;
124}
125
126/* Set a property using the generic GObject interface */
127static void
128set_property (GObject * obj, guint id, const GValue * value, GParamSpec * pspec)
129{
130 switch (id) {
131 case PROP_MENU_ITEM: {
132 GObject * lobj = g_value_get_object(value);
133 add_menuitem(DBUSMENU_MENUITEM_PROXY(obj), DBUSMENU_MENUITEM(lobj));
134 break;
135 }
136 default:
137 G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, id, pspec);
138 break;
139 }
140
141 return;
142}
143
144/* Get a property using the generic GObject interface */
145static void
146get_property (GObject * obj, guint id, GValue * value, GParamSpec * pspec)
147{
148 DbusmenuMenuitemProxyPrivate * priv = DBUSMENU_MENUITEM_PROXY_GET_PRIVATE(obj);
149
150 switch (id) {
151 case PROP_MENU_ITEM:
152 g_value_set_object(value, priv->mi);
153 break;
154 default:
155 G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, id, pspec);
156 break;
157 }
158
159 return;
160}
161
162/* Takes the event and passes it along to the item that we're
163 playing proxy for. */
164static void
165handle_event (DbusmenuMenuitem * mi, const gchar * name, const GValue * value, guint timestamp)
166{
167 g_return_if_fail(DBUSMENU_IS_MENUITEM_PROXY(mi));
168 DbusmenuMenuitemProxyPrivate * priv = DBUSMENU_MENUITEM_PROXY_GET_PRIVATE(mi);
169 g_return_if_fail(priv->mi != NULL);
170 return dbusmenu_menuitem_handle_event(priv->mi, name, value, timestamp);
171}
172
173/* Watches a property change and makes sure to put that value
174 into our property list. */
175static void
176proxy_item_property_changed (DbusmenuMenuitem * mi, gchar * property, GValue * value, gpointer user_data)
177{
178 DbusmenuMenuitemProxy * pmi = DBUSMENU_MENUITEM_PROXY(user_data);
179 dbusmenu_menuitem_property_set_value(DBUSMENU_MENUITEM(pmi), property, value);
180 return;
181}
182
183/* Looks for a child getting added and wraps it and places it
184 in our list of children. */
185static void
186proxy_item_child_added (DbusmenuMenuitem * parent, DbusmenuMenuitem * child, guint position, gpointer user_data)
187{
188 DbusmenuMenuitemProxy * pmi = DBUSMENU_MENUITEM_PROXY(user_data);
189 DbusmenuMenuitemProxy * child_pmi = dbusmenu_menuitem_proxy_new(child);
190 dbusmenu_menuitem_child_add_position(DBUSMENU_MENUITEM(pmi), DBUSMENU_MENUITEM(child_pmi), position);
191 return;
192}
193
194/* Find the wrapper for this child and remove it as well. */
195static void
196proxy_item_child_removed (DbusmenuMenuitem * parent, DbusmenuMenuitem * child, gpointer user_data)
197{
198 DbusmenuMenuitemProxy * pmi = DBUSMENU_MENUITEM_PROXY(user_data);
199 GList * children = dbusmenu_menuitem_get_children(DBUSMENU_MENUITEM(pmi));
200 DbusmenuMenuitemProxy * finalpmi = NULL;
201 GList * childitem;
202
203 for (childitem = children; childitem != NULL; childitem = g_list_next(childitem)) {
204 DbusmenuMenuitemProxy * childpmi = (DbusmenuMenuitemProxy *)childitem->data;
205 DbusmenuMenuitem * childmi = dbusmenu_menuitem_proxy_get_wrapped(childpmi);
206 if (childmi == child) {
207 finalpmi = childpmi;
208 break;
209 }
210 }
211
212 if (finalpmi != NULL) {
213 dbusmenu_menuitem_child_delete(DBUSMENU_MENUITEM(pmi), DBUSMENU_MENUITEM(finalpmi));
214 }
215
216 return;
217}
218
219/* Find the wrapper for the item and move it in our child list */
220static void
221proxy_item_child_moved (DbusmenuMenuitem * parent, DbusmenuMenuitem * child, guint newpos, guint oldpos, gpointer user_data)
222{
223 DbusmenuMenuitemProxy * pmi = DBUSMENU_MENUITEM_PROXY(user_data);
224 GList * children = dbusmenu_menuitem_get_children(DBUSMENU_MENUITEM(pmi));
225 DbusmenuMenuitemProxy * finalpmi = NULL;
226 GList * childitem;
227
228 for (childitem = children; childitem != NULL; childitem = g_list_next(childitem)) {
229 DbusmenuMenuitemProxy * childpmi = (DbusmenuMenuitemProxy *)childitem->data;
230 DbusmenuMenuitem * childmi = dbusmenu_menuitem_proxy_get_wrapped(childpmi);
231 if (childmi == child) {
232 finalpmi = childpmi;
233 break;
234 }
235 }
236
237 if (finalpmi != NULL) {
238 dbusmenu_menuitem_child_reorder(DBUSMENU_MENUITEM(pmi), DBUSMENU_MENUITEM(finalpmi), newpos);
239 }
240
241 return;
242}
243
244/* Making g_object_unref into a GFunc */
245static void
246func_g_object_unref (gpointer data, gpointer user_data)
247{
248 return g_object_unref(G_OBJECT(data));
249}
250
251/* References all of the things we need for talking to this menuitem
252 including signals and other data. If the menuitem already has
253 properties we need to signal that they've changed for us. */
254static void
255add_menuitem (DbusmenuMenuitemProxy * pmi, DbusmenuMenuitem * mi)
256{
257 /* Put it in private */
258 DbusmenuMenuitemProxyPrivate * priv = DBUSMENU_MENUITEM_PROXY_GET_PRIVATE(pmi);
259 if (priv->mi != NULL) {
260 remove_menuitem(pmi);
261 }
262 priv->mi = mi;
263 g_object_ref(G_OBJECT(priv->mi));
264
265 /* Attach signals */
266 priv->sig_property_changed = g_signal_connect(G_OBJECT(priv->mi), DBUSMENU_MENUITEM_SIGNAL_PROPERTY_CHANGED, G_CALLBACK(proxy_item_property_changed), pmi);
267 priv->sig_child_added = g_signal_connect(G_OBJECT(priv->mi), DBUSMENU_MENUITEM_SIGNAL_CHILD_ADDED, G_CALLBACK(proxy_item_child_added), pmi);
268 priv->sig_child_removed = g_signal_connect(G_OBJECT(priv->mi), DBUSMENU_MENUITEM_SIGNAL_CHILD_REMOVED, G_CALLBACK(proxy_item_child_removed), pmi);
269 priv->sig_child_moved = g_signal_connect(G_OBJECT(priv->mi), DBUSMENU_MENUITEM_SIGNAL_CHILD_MOVED, G_CALLBACK(proxy_item_child_moved), pmi);
270
271 /* Grab (cache) Properties */
272 GList * props = dbusmenu_menuitem_properties_list(priv->mi);
273 GList * prop;
274 for (prop = props; prop != NULL; prop = g_list_next(prop)) {
275 gchar * prop_name = (gchar *)prop->data;
276 dbusmenu_menuitem_property_set_value(DBUSMENU_MENUITEM(pmi), prop_name, dbusmenu_menuitem_property_get_value(priv->mi, prop_name));
277 }
278 g_list_free(props);
279
280 /* Go through children and wrap them */
281 GList * children = dbusmenu_menuitem_get_children(priv->mi);
282 GList * child;
283 for (child = children; child != NULL; child = g_list_next(child)) {
284 DbusmenuMenuitemProxy * child_pmi = dbusmenu_menuitem_proxy_new(DBUSMENU_MENUITEM(child->data));
285 dbusmenu_menuitem_child_append(DBUSMENU_MENUITEM(pmi), DBUSMENU_MENUITEM(child_pmi));
286 }
287
288 return;
289}
290
291/* Removes the menuitem from being our proxy. Typically this isn't
292 done until this object is destroyed, but who knows?!? */
293static void
294remove_menuitem (DbusmenuMenuitemProxy * pmi)
295{
296 DbusmenuMenuitemProxyPrivate * priv = DBUSMENU_MENUITEM_PROXY_GET_PRIVATE(pmi);
297 if (priv->mi == NULL) {
298 return;
299 }
300
301 /* Remove signals */
302 if (priv->sig_property_changed != 0) {
303 g_signal_handler_disconnect(G_OBJECT(priv->mi), priv->sig_property_changed);
304 }
305 if (priv->sig_child_added != 0) {
306 g_signal_handler_disconnect(G_OBJECT(priv->mi), priv->sig_child_added);
307 }
308 if (priv->sig_child_removed != 0) {
309 g_signal_handler_disconnect(G_OBJECT(priv->mi), priv->sig_child_removed);
310 }
311 if (priv->sig_child_moved != 0) {
312 g_signal_handler_disconnect(G_OBJECT(priv->mi), priv->sig_child_moved);
313 }
314
315 /* Unref */
316 g_object_unref(G_OBJECT(priv->mi));
317 priv->mi = NULL;
318
319 /* Remove our own children */
320 GList * children = dbusmenu_menuitem_take_children(DBUSMENU_MENUITEM(pmi));
321 g_list_foreach(children, func_g_object_unref, NULL);
322 g_list_free(children);
323
324 return;
325}
326
327/**
328 dbusmenu_menuitem_proxy_new:
329 @mi: The #DbusmenuMenuitem to proxy
330
331 Builds a new #DbusmenuMenuitemProxy object that proxies
332 all of the values for @mi.
333
334 Return value: A new #DbusmenuMenuitemProxy object.
335*/
336DbusmenuMenuitemProxy *
337dbusmenu_menuitem_proxy_new (DbusmenuMenuitem * mi)
338{
339 DbusmenuMenuitemProxy * pmi = g_object_new(DBUSMENU_TYPE_MENUITEM_PROXY,
340 PROP_MENU_ITEM_S, mi,
341 NULL);
342
343 return pmi;
344}
345
346/**
347 dbusmenu_menuitem_proxy_get_wrapped:
348 @pmi: #DbusmenuMenuitemProxy to look into
349
350 Accesses the private variable of which #DbusmenuMenuitem
351 we are doing the proxying for.
352
353 Return value: A #DbusmenuMenuitem object or a #NULL if we
354 don't have one or there is an error.
355*/
356DbusmenuMenuitem *
357dbusmenu_menuitem_proxy_get_wrapped (DbusmenuMenuitemProxy * pmi)
358{
359 g_return_val_if_fail(DBUSMENU_MENUITEM_PROXY(pmi), NULL);
360 DbusmenuMenuitemProxyPrivate * priv = DBUSMENU_MENUITEM_PROXY_GET_PRIVATE(pmi);
361 return priv->mi;
362}
0363
=== added file 'libdbusmenu-glib/menuitem-proxy.h'
--- libdbusmenu-glib/menuitem-proxy.h 1970-01-01 00:00:00 +0000
+++ libdbusmenu-glib/menuitem-proxy.h 2010-02-18 17:06:16 +0000
@@ -0,0 +1,74 @@
1/*
2An object to ferry over properties and signals between two different
3dbusmenu instances. Useful for services.
4
5Copyright 2010 Canonical Ltd.
6
7Authors:
8 Ted Gould <ted@canonical.com>
9
10This program is free software: you can redistribute it and/or modify it
11under the terms of either or both of the following licenses:
12
131) the GNU Lesser General Public License version 3, as published by the
14Free Software Foundation; and/or
152) the GNU Lesser General Public License version 2.1, as published by
16the Free Software Foundation.
17
18This program is distributed in the hope that it will be useful, but
19WITHOUT ANY WARRANTY; without even the implied warranties of
20MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
21PURPOSE. See the applicable version of the GNU Lesser General Public
22License for more details.
23
24You should have received a copy of both the GNU Lesser General Public
25License version 3 and version 2.1 along with this program. If not, see
26<http://www.gnu.org/licenses/>
27*/
28
29#ifndef __DBUSMENU_MENUITEM_PROXY_H__
30#define __DBUSMENU_MENUITEM_PROXY_H__
31
32#include <glib.h>
33#include <glib-object.h>
34#include "menuitem.h"
35
36G_BEGIN_DECLS
37
38#define DBUSMENU_TYPE_MENUITEM_PROXY (dbusmenu_menuitem_proxy_get_type ())
39#define DBUSMENU_MENUITEM_PROXY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), DBUSMENU_TYPE_MENUITEM_PROXY, DbusmenuMenuitemProxy))
40#define DBUSMENU_MENUITEM_PROXY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), DBUSMENU_TYPE_MENUITEM_PROXY, DbusmenuMenuitemProxyClass))
41#define DBUSMENU_IS_MENUITEM_PROXY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), DBUSMENU_TYPE_MENUITEM_PROXY))
42#define DBUSMENU_IS_MENUITEM_PROXY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), DBUSMENU_TYPE_MENUITEM_PROXY))
43#define DBUSMENU_MENUITEM_PROXY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), DBUSMENU_TYPE_MENUITEM_PROXY, DbusmenuMenuitemProxyClass))
44
45typedef struct _DbusmenuMenuitemProxy DbusmenuMenuitemProxy;
46typedef struct _DbusmenuMenuitemProxyClass DbusmenuMenuitemProxyClass;
47
48/**
49 DbusmenuMenuitemProxyClass:
50 @parent_class: The Class of #DbusmeneMenuitem
51
52 Functions and signal slots for #DbusmenuMenuitemProxy.
53*/
54struct _DbusmenuMenuitemProxyClass {
55 DbusmenuMenuitemClass parent_class;
56};
57
58/**
59 DbusmeneMenuitemProxy:
60 @parent: The instance of #DbusmenuMenuitem
61
62 Public instance data for a #DbusmenuMenuitemProxy.
63*/
64struct _DbusmenuMenuitemProxy {
65 DbusmenuMenuitem parent;
66};
67
68GType dbusmenu_menuitem_proxy_get_type (void);
69DbusmenuMenuitemProxy * dbusmenu_menuitem_proxy_new (DbusmenuMenuitem * mi);
70DbusmenuMenuitem * dbusmenu_menuitem_proxy_get_wrapped (DbusmenuMenuitemProxy * pmi);
71
72G_END_DECLS
73
74#endif
075
=== modified file 'libdbusmenu-glib/server.c'
--- libdbusmenu-glib/server.c 2010-02-09 16:52:21 +0000
+++ libdbusmenu-glib/server.c 2010-02-18 17:06:16 +0000
@@ -301,10 +301,29 @@
301 return;301 return;
302}302}
303303
304/* Adds the signals for this entry to the list and looks at
305 the children of this entry to add the signals we need
306 as well. We like signals. */
307static void
308added_check_children (gpointer data, gpointer user_data)
309{
310 DbusmenuMenuitem * mi = (DbusmenuMenuitem *)data;
311 DbusmenuServer * server = (DbusmenuServer *)user_data;
312
313 menuitem_signals_create(mi, server);
314 g_list_foreach(dbusmenu_menuitem_get_children(mi), added_check_children, server);
315
316 return;
317}
318
319/* Callback for when a child is added. We need to connect everything
320 up and signal that the layout has changed. */
304static void321static void
305menuitem_child_added (DbusmenuMenuitem * parent, DbusmenuMenuitem * child, guint pos, DbusmenuServer * server)322menuitem_child_added (DbusmenuMenuitem * parent, DbusmenuMenuitem * child, guint pos, DbusmenuServer * server)
306{323{
307 menuitem_signals_create(child, server);324 menuitem_signals_create(child, server);
325 g_list_foreach(dbusmenu_menuitem_get_children(child), added_check_children, server);
326
308 /* TODO: We probably need to group the layout update signals to make the number more reasonble. */327 /* TODO: We probably need to group the layout update signals to make the number more reasonble. */
309 DbusmenuServerPrivate * priv = DBUSMENU_SERVER_GET_PRIVATE(server);328 DbusmenuServerPrivate * priv = DBUSMENU_SERVER_GET_PRIVATE(server);
310 priv->layout_revision++;329 priv->layout_revision++;
@@ -378,7 +397,7 @@
378 if (parent == 0) {397 if (parent == 0) {
379 if (priv->root == NULL) {398 if (priv->root == NULL) {
380 /* g_debug("Getting layout without root node!"); */399 /* g_debug("Getting layout without root node!"); */
381 g_ptr_array_add(xmlarray, g_strdup("<menu/>"));400 g_ptr_array_add(xmlarray, g_strdup("<menu id=\"0\"/>"));
382 } else {401 } else {
383 dbusmenu_menuitem_buildxml(priv->root, xmlarray);402 dbusmenu_menuitem_buildxml(priv->root, xmlarray);
384 }403 }
385404
=== modified file 'tests/Makefile.am'
--- tests/Makefile.am 2010-02-05 18:35:58 +0000
+++ tests/Makefile.am 2010-02-18 17:06:16 +0000
@@ -5,6 +5,7 @@
5 test-glib-objects-test \5 test-glib-objects-test \
6 test-glib-layout \6 test-glib-layout \
7 test-glib-properties \7 test-glib-properties \
8 test-glib-proxy \
8 test-glib-simple-items \9 test-glib-simple-items \
9 test-gtk-label \10 test-gtk-label \
10 test-gtk-reorder11 test-gtk-reorder
@@ -16,6 +17,9 @@
16 test-glib-layout-server \17 test-glib-layout-server \
17 test-glib-properties-client \18 test-glib-properties-client \
18 test-glib-properties-server \19 test-glib-properties-server \
20 test-glib-proxy-client \
21 test-glib-proxy-server \
22 test-glib-proxy-proxy \
19 test-gtk-label-client \23 test-gtk-label-client \
20 test-gtk-label-server \24 test-gtk-label-server \
21 test-glib-simple-items \25 test-glib-simple-items \
@@ -127,6 +131,56 @@
127 ../libdbusmenu-glib/libdbusmenu-glib.la \131 ../libdbusmenu-glib/libdbusmenu-glib.la \
128 $(DBUSMENUGLIB_LIBS)132 $(DBUSMENUGLIB_LIBS)
129133
134######################
135# Test Glib Proxy
136######################
137
138test-glib-proxy: test-glib-proxy-client test-glib-proxy-server test-glib-proxy-proxy Makefile.am
139 @echo "#!/bin/bash" > $@
140 @echo $(DBUS_RUNNER) --task ./test-glib-proxy-client --task-name Client --task ./test-glib-proxy-server --task-name Server --ignore-return \\ >> $@
141 @echo --task ./test-glib-proxy-proxy --parameter test.proxy.first_proxy --parameter test.proxy.second_proxy --task-name Proxy01 --ignore-return \\ >> $@
142 @echo --task ./test-glib-proxy-proxy --parameter test.proxy.second_proxy --parameter test.proxy.third_proxy --task-name Proxy02 --ignore-return \\ >> $@
143 @echo --task ./test-glib-proxy-proxy --parameter test.proxy.third_proxy --parameter test.proxy.fourth_proxy --task-name Proxy03 --ignore-return \\ >> $@
144 @echo --task ./test-glib-proxy-proxy --parameter test.proxy.fourth_proxy --parameter test.proxy.last_proxy --task-name Proxy04 --ignore-return \\ >> $@
145 @echo --task ./test-glib-proxy-proxy --parameter test.proxy.last_proxy --parameter test.proxy.server --task-name Proxy05 --ignore-return >> $@
146 @chmod +x $@
147
148test_glib_proxy_server_SOURCES = \
149 test-glib-proxy.h \
150 test-glib-proxy-server.c
151
152test_glib_proxy_server_CFLAGS = \
153 -I $(srcdir)/.. \
154 $(DBUSMENUGLIB_CFLAGS) -Wall -Werror
155
156test_glib_proxy_server_LDADD = \
157 ../libdbusmenu-glib/libdbusmenu-glib.la \
158 $(DBUSMENUGLIB_LIBS)
159
160test_glib_proxy_client_SOURCES = \
161 test-glib-proxy.h \
162 test-glib-proxy-client.c
163
164test_glib_proxy_client_CFLAGS = \
165 -I $(srcdir)/.. \
166 $(DBUSMENUGLIB_CFLAGS) -Wall -Werror
167
168test_glib_proxy_client_LDADD = \
169 ../libdbusmenu-glib/libdbusmenu-glib.la \
170 $(DBUSMENUGLIB_LIBS)
171
172test_glib_proxy_proxy_SOURCES = \
173 test-glib-proxy.h \
174 test-glib-proxy-proxy.c
175
176test_glib_proxy_proxy_CFLAGS = \
177 -I $(srcdir)/.. \
178 $(DBUSMENUGLIB_CFLAGS) -Wall -Werror
179
180test_glib_proxy_proxy_LDADD = \
181 ../libdbusmenu-glib/libdbusmenu-glib.la \
182 $(DBUSMENUGLIB_LIBS)
183
130#########################184#########################
131# Test Glib Simple Items185# Test Glib Simple Items
132#########################186#########################
133187
=== added file 'tests/test-glib-proxy-client.c'
--- tests/test-glib-proxy-client.c 1970-01-01 00:00:00 +0000
+++ tests/test-glib-proxy-client.c 2010-02-18 17:06:16 +0000
@@ -0,0 +1,171 @@
1/*
2A test for libdbusmenu to ensure its quality.
3
4Copyright 2009 Canonical Ltd.
5
6Authors:
7 Ted Gould <ted@canonical.com>
8
9This program is free software: you can redistribute it and/or modify it
10under the terms of the GNU General Public License version 3, as published
11by the Free Software Foundation.
12
13This program is distributed in the hope that it will be useful, but
14WITHOUT ANY WARRANTY; without even the implied warranties of
15MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
16PURPOSE. See the GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License along
19with this program. If not, see <http://www.gnu.org/licenses/>.
20*/
21
22#include <glib.h>
23
24#include <libdbusmenu-glib/client.h>
25#include <libdbusmenu-glib/menuitem.h>
26
27#include "test-glib-proxy.h"
28
29static guint layouton = -1;
30static GMainLoop * mainloop = NULL;
31static gboolean passed = TRUE;
32static guint death_timer = 0;
33
34static gboolean
35verify_props (DbusmenuMenuitem * mi, gchar ** properties)
36{
37 if (properties == NULL) {
38 return TRUE;
39 }
40
41 /* Verify they're all there and correct */
42 guint i;
43 for (i = 0; properties[i] != NULL; i += 2) {
44 const gchar * value = dbusmenu_menuitem_property_get(mi, properties[i]);
45 if (g_strcmp0(value, properties[i + 1])) {
46 g_debug("\tFailed as property '%s' should be '%s' and is '%s'", properties[i], properties[i+1], value);
47 return FALSE;
48 }
49 }
50
51 /* Verify that we don't have any extras */
52 // GList * props = dbusmenu_menuitem_properties_list(mi);
53
54 return TRUE;
55}
56
57static gboolean
58verify_root_to_layout(DbusmenuMenuitem * mi, proplayout_t * layout)
59{
60 g_debug("Verifying ID: %d", layout->id);
61
62 if (!verify_props(mi, layout->properties)) {
63 g_debug("\tFailed as unable to verify properties.");
64 return FALSE;
65 }
66
67 GList * children = dbusmenu_menuitem_get_children(mi);
68
69 if (children == NULL && layout->submenu == NULL) {
70 g_debug("\tPassed: %d", layout->id);
71 return TRUE;
72 }
73 if (children == NULL || layout->submenu == NULL) {
74 if (children == NULL) {
75 g_debug("\tFailed as there are no children but we have submenus");
76 } else {
77 g_debug("\tFailed as we have children but no submenu");
78 }
79 return FALSE;
80 }
81
82 guint i = 0;
83 for (i = 0; children != NULL && layout->submenu[i].id != -1; children = g_list_next(children), i++) {
84 if (!verify_root_to_layout(DBUSMENU_MENUITEM(children->data), &layout->submenu[i])) {
85 return FALSE;
86 }
87 }
88
89 if (children == NULL && layout->submenu[i].id == -1) {
90 g_debug("\tPassed: %d", layout->id);
91 return TRUE;
92 }
93
94 if (children != NULL) {
95 g_debug("\tFailed as there are still children but no submenus. (ID: %d)", layout->id);
96 } else {
97 g_debug("\tFailed as there are still submenus but no children. (ID: %d)", layout->id);
98 }
99 return FALSE;
100}
101
102static gboolean
103timer_func (gpointer data)
104{
105 g_debug("Death timer. Oops. Got to: %d", layouton);
106 passed = FALSE;
107 g_main_loop_quit(mainloop);
108 return FALSE;
109}
110
111static gboolean layout_verify_timer (gpointer data);
112
113static void
114layout_updated (DbusmenuClient * client, gpointer data)
115{
116 g_debug("Layout Updated");
117 if (dbusmenu_client_get_root(client) == NULL) {
118 g_debug("\tIgnored, no root");
119 return;
120 }
121 layouton++;
122 g_timeout_add (1500, layout_verify_timer, client);
123 return;
124}
125
126static gboolean
127layout_verify_timer (gpointer data)
128{
129 g_debug("Verifing Layout: %d", layouton);
130 DbusmenuMenuitem * menuroot = dbusmenu_client_get_root(DBUSMENU_CLIENT(data));
131 proplayout_t * layout = &layouts[layouton];
132
133 if (!verify_root_to_layout(menuroot, layout)) {
134 g_debug("FAILED LAYOUT: %d", layouton);
135 passed = FALSE;
136 } else {
137 /* Extend our death */
138 g_source_remove(death_timer);
139 death_timer = g_timeout_add_seconds(10, timer_func, data);
140 }
141
142 if (layouts[layouton+1].id == -1) {
143 g_main_loop_quit(mainloop);
144 }
145
146 return FALSE;
147}
148
149int
150main (int argc, char ** argv)
151{
152 g_type_init();
153
154 DbusmenuClient * client = dbusmenu_client_new("test.proxy.first_proxy", "/org/test");
155 g_signal_connect(G_OBJECT(client), DBUSMENU_CLIENT_SIGNAL_LAYOUT_UPDATED, G_CALLBACK(layout_updated), NULL);
156
157 death_timer = g_timeout_add_seconds(10, timer_func, client);
158
159 mainloop = g_main_loop_new(NULL, FALSE);
160 g_main_loop_run(mainloop);
161
162 g_object_unref(G_OBJECT(client));
163
164 if (passed) {
165 g_debug("Quiting");
166 return 0;
167 } else {
168 g_debug("Quiting as we're a failure");
169 return 1;
170 }
171}
0172
=== added file 'tests/test-glib-proxy-proxy.c'
--- tests/test-glib-proxy-proxy.c 1970-01-01 00:00:00 +0000
+++ tests/test-glib-proxy-proxy.c 2010-02-18 17:06:16 +0000
@@ -0,0 +1,80 @@
1#include <glib.h>
2
3#include <dbus/dbus.h>
4#include <dbus/dbus-glib.h>
5#include <dbus/dbus-glib-lowlevel.h>
6#include <dbus/dbus-glib-bindings.h>
7
8#include <libdbusmenu-glib/menuitem.h>
9#include <libdbusmenu-glib/menuitem-proxy.h>
10#include <libdbusmenu-glib/server.h>
11#include <libdbusmenu-glib/client.h>
12
13#include "test-glib-proxy.h"
14
15static DbusmenuServer * server = NULL;
16static DbusmenuClient * client = NULL;
17static GMainLoop * mainloop = NULL;
18
19void
20root_changed (DbusmenuClient * client, DbusmenuMenuitem * newroot, gpointer user_data)
21{
22 g_debug("New root: %X", (guint)newroot);
23
24 if (newroot == NULL) {
25 g_debug("Root removed, exiting");
26 g_main_loop_quit(mainloop);
27 return;
28 }
29
30 DbusmenuMenuitemProxy * pmi = dbusmenu_menuitem_proxy_new(newroot);
31 dbusmenu_server_set_root(server, DBUSMENU_MENUITEM(pmi));
32 return;
33}
34
35int
36main (int argc, char ** argv)
37{
38 g_type_init();
39
40 if (argc != 3) {
41 g_error ("Need two params");
42 return 1;
43 }
44
45 gchar * whoami = argv[1];
46 gchar * myproxy = argv[2];
47
48 g_debug("I am '%s' and I'm proxying '%s'", whoami, myproxy);
49
50 GError * error = NULL;
51 DBusGConnection * connection = dbus_g_bus_get(DBUS_BUS_SESSION, NULL);
52
53 g_debug("DBus ID: %s", dbus_connection_get_server_id(dbus_g_connection_get_connection(connection)));
54
55 DBusGProxy * bus_proxy = dbus_g_proxy_new_for_name(connection, DBUS_SERVICE_DBUS, DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS);
56 guint nameret = 0;
57
58 if (!org_freedesktop_DBus_request_name(bus_proxy, whoami, 0, &nameret, &error)) {
59 g_error("Unable to call to request name");
60 return 1;
61 }
62
63 if (nameret != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
64 g_error("Unable to get name");
65 return 1;
66 }
67
68 server = dbusmenu_server_new("/org/test");
69 client = dbusmenu_client_new(myproxy, "/org/test");
70
71 g_signal_connect(client, DBUSMENU_CLIENT_SIGNAL_ROOT_CHANGED, G_CALLBACK(root_changed), server);
72
73 mainloop = g_main_loop_new(NULL, FALSE);
74 g_main_loop_run(mainloop);
75
76 g_object_unref(G_OBJECT(server));
77 g_debug("Quiting");
78
79 return 0;
80}
081
=== added file 'tests/test-glib-proxy-server.c'
--- tests/test-glib-proxy-server.c 1970-01-01 00:00:00 +0000
+++ tests/test-glib-proxy-server.c 2010-02-18 17:06:16 +0000
@@ -0,0 +1,126 @@
1/*
2A test for libdbusmenu to ensure its quality.
3
4Copyright 2009 Canonical Ltd.
5
6Authors:
7 Ted Gould <ted@canonical.com>
8
9This program is free software: you can redistribute it and/or modify it
10under the terms of the GNU General Public License version 3, as published
11by the Free Software Foundation.
12
13This program is distributed in the hope that it will be useful, but
14WITHOUT ANY WARRANTY; without even the implied warranties of
15MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
16PURPOSE. See the GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License along
19with this program. If not, see <http://www.gnu.org/licenses/>.
20*/
21
22#include <glib.h>
23
24#include <dbus/dbus.h>
25#include <dbus/dbus-glib.h>
26#include <dbus/dbus-glib-lowlevel.h>
27#include <dbus/dbus-glib-bindings.h>
28
29#include <libdbusmenu-glib/menuitem.h>
30#include <libdbusmenu-glib/server.h>
31
32#include "test-glib-proxy.h"
33
34static void
35set_props (DbusmenuMenuitem * mi, gchar ** props)
36{
37 if (props == NULL) return;
38
39 guint i;
40 for (i = 0; props[i] != NULL; i += 2) {
41 dbusmenu_menuitem_property_set(mi, props[i], props[i+1]);
42 }
43
44 return;
45}
46
47static DbusmenuMenuitem *
48layout2menuitem (proplayout_t * layout)
49{
50 if (layout == NULL || layout->id == -1) return NULL;
51
52 DbusmenuMenuitem * local = dbusmenu_menuitem_new();
53 set_props(local, layout->properties);
54
55 if (layout->submenu != NULL) {
56 guint count;
57 for (count = 0; layout->submenu[count].id != -1; count++) {
58 DbusmenuMenuitem * child = layout2menuitem(&layout->submenu[count]);
59 if (child != NULL) {
60 dbusmenu_menuitem_child_append(local, child);
61 }
62 }
63 }
64
65 /* g_debug("Layout to menu return: 0x%X", (unsigned int)local); */
66 return local;
67}
68
69static guint layouton = 0;
70static DbusmenuServer * server = NULL;
71static GMainLoop * mainloop = NULL;
72
73static gboolean
74timer_func (gpointer data)
75{
76 if (layouts[layouton].id == -1) {
77 g_main_loop_quit(mainloop);
78 return FALSE;
79 }
80 g_debug("Updating to Layout %d", layouton);
81
82 DbusmenuMenuitem * mi = layout2menuitem(&layouts[layouton]);
83 dbusmenu_server_set_root(server, mi);
84 g_object_unref(G_OBJECT(mi));
85 layouton++;
86
87 return TRUE;
88}
89
90int
91main (int argc, char ** argv)
92{
93 g_type_init();
94
95 GError * error = NULL;
96 DBusGConnection * connection = dbus_g_bus_get(DBUS_BUS_SESSION, NULL);
97
98 g_debug("DBus ID: %s", dbus_connection_get_server_id(dbus_g_connection_get_connection(connection)));
99
100 DBusGProxy * bus_proxy = dbus_g_proxy_new_for_name(connection, DBUS_SERVICE_DBUS, DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS);
101 guint nameret = 0;
102
103 if (!org_freedesktop_DBus_request_name(bus_proxy, "test.proxy.server", 0, &nameret, &error)) {
104 g_error("Unable to call to request name");
105 return 1;
106 }
107
108 if (nameret != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
109 g_error("Unable to get name");
110 return 1;
111 }
112
113 server = dbusmenu_server_new("/org/test");
114
115 timer_func(NULL);
116 g_timeout_add(2500, timer_func, NULL);
117
118 mainloop = g_main_loop_new(NULL, FALSE);
119 g_main_loop_run(mainloop);
120
121 g_object_unref(G_OBJECT(server));
122 g_debug("Quiting");
123
124 return 0;
125}
126
0127
=== added file 'tests/test-glib-proxy.h'
--- tests/test-glib-proxy.h 1970-01-01 00:00:00 +0000
+++ tests/test-glib-proxy.h 2010-02-18 17:06:16 +0000
@@ -0,0 +1,142 @@
1/*
2A test for libdbusmenu to ensure its quality.
3
4Copyright 2009 Canonical Ltd.
5
6Authors:
7 Ted Gould <ted@canonical.com>
8
9This program is free software: you can redistribute it and/or modify it
10under the terms of the GNU General Public License version 3, as published
11by the Free Software Foundation.
12
13This program is distributed in the hope that it will be useful, but
14WITHOUT ANY WARRANTY; without even the implied warranties of
15MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
16PURPOSE. See the GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License along
19with this program. If not, see <http://www.gnu.org/licenses/>.
20*/
21
22
23#include <glib.h>
24
25typedef struct _proplayout_t proplayout_t;
26struct _proplayout_t {
27 gint id;
28 gchar ** properties;
29 proplayout_t * submenu;
30};
31
32gchar * props1[] = {"property1", "value1", "property2", "value2", NULL};
33gchar * props2[] = {"property00", "value00", "property01", "value01", "property02", "value02", "property03", "value03", "property04", "value04",
34 "property05", "value05", "property06", "value06", "property07", "value07", "property08", "value08", "property09", "value09",
35 "property10", "value10", "property11", "value11", "property12", "value12", "property13", "value13", "property14", "value14",
36 "property15", "value15", "property16", "value16", "property17", "value17", "property18", "value18", "property19", "value19",
37 "property20", "value20", "property21", "value21", "property22", "value22", "property23", "value23", "property24", "value24",
38 "property25", "value25", "property26", "value26", "property27", "value27", "property28", "value28", "property29", "value29",
39 "property30", "value30", "property31", "value31", "property32", "value32", "property33", "value33", "property34", "value34",
40 "property35", "value35", "property36", "value36", "property37", "value37", "property38", "value38", "property39", "value39",
41 "property40", "value40", "property41", "value41", "property42", "value42", "property43", "value43", "property44", "value44",
42 "property45", "value45", "property46", "value46", "property47", "value47", "property48", "value48", "property49", "value49",
43 "property50", "value50", "property51", "value51", "property52", "value52", "property53", "value53", "property54", "value54",
44 "property55", "value55", "property56", "value56", "property57", "value57", "property58", "value58", "property59", "value59",
45 "property60", "value60", "property61", "value61", "property62", "value62", "property63", "value63", "property64", "value64",
46 "property65", "value65", "property66", "value66", "property67", "value67", "property68", "value68", "property69", "value69",
47 "property70", "value70", "property71", "value71", "property72", "value72", "property73", "value73", "property74", "value74",
48 "property75", "value75", "property76", "value76", "property77", "value77", "property78", "value78", "property79", "value79",
49 "property80", "value80", "property81", "value81", "property82", "value82", "property83", "value83", "property84", "value84",
50 "property85", "value85", "property86", "value86", "property87", "value87", "property88", "value88", "property89", "value89",
51 "property90", "value90", "property91", "value91", "property92", "value92", "property93", "value93", "property94", "value94",
52 "property95", "value95", "property96", "value96", "property97", "value97", "property98", "value98", "property99", "value99",
53 NULL};
54gchar * props3[] = {"property name that is really long and will ensure that we can really have long property names, which could be important at some point.",
55 "And a property name that is really long should have a value that is really long, because well, that's an important part of the yin and yang of software testing.",
56 NULL};
57gchar * props4[] = {"icon-name", "network-status", "label", "Look at network", "right-column", "10:32", NULL};
58
59
60proplayout_t submenu_4_1[] = {
61 {id: 10, properties: props2, submenu: NULL},
62 {id: 11, properties: props2, submenu: NULL},
63 {id: 12, properties: props2, submenu: NULL},
64 {id: 13, properties: props2, submenu: NULL},
65 {id: 14, properties: props2, submenu: NULL},
66 {id: 15, properties: props2, submenu: NULL},
67 {id: 16, properties: props2, submenu: NULL},
68 {id: 17, properties: props2, submenu: NULL},
69 {id: 18, properties: props2, submenu: NULL},
70 {id: 19, properties: props2, submenu: NULL},
71 {id: -1, properties: NULL, submenu: NULL}
72};
73
74proplayout_t submenu_4_2[] = {
75 {id: 20, properties: props2, submenu: NULL},
76 {id: 21, properties: props2, submenu: NULL},
77 {id: 22, properties: props2, submenu: NULL},
78 {id: 23, properties: props2, submenu: NULL},
79 {id: 24, properties: props2, submenu: NULL},
80 {id: 25, properties: props2, submenu: NULL},
81 {id: 26, properties: props2, submenu: NULL},
82 {id: 27, properties: props2, submenu: NULL},
83 {id: 28, properties: props2, submenu: NULL},
84 {id: 29, properties: props2, submenu: NULL},
85 {id: -1, properties: NULL, submenu: NULL}
86};
87
88proplayout_t submenu_4_3[] = {
89 {id: 30, properties: props2, submenu: NULL},
90 {id: 31, properties: props2, submenu: NULL},
91 {id: 32, properties: props2, submenu: NULL},
92 {id: 33, properties: props2, submenu: NULL},
93 {id: 34, properties: props2, submenu: NULL},
94 {id: 35, properties: props2, submenu: NULL},
95 {id: 36, properties: props2, submenu: NULL},
96 {id: 37, properties: props2, submenu: NULL},
97 {id: 38, properties: props2, submenu: NULL},
98 {id: 39, properties: props2, submenu: NULL},
99 {id: -1, properties: NULL, submenu: NULL}
100};
101
102proplayout_t submenu_4_0[] = {
103 {id: 1, properties: props2, submenu: submenu_4_1},
104 {id: 2, properties: props2, submenu: submenu_4_2},
105 {id: 3, properties: props2, submenu: submenu_4_3},
106 {id: -1, properties: NULL, submenu: NULL}
107};
108
109proplayout_t submenu_5_5[] = {
110 {id: 205, properties: props3, submenu: NULL},
111 {id: -1, properties: NULL, submenu: NULL}
112};
113
114proplayout_t submenu_5_4[] = {
115 {id: 204, properties: props3, submenu: submenu_5_5},
116 {id: -1, properties: NULL, submenu: NULL}
117};
118
119proplayout_t submenu_5_3[] = {
120 {id: 203, properties: props3, submenu: submenu_5_4},
121 {id: -1, properties: NULL, submenu: NULL}
122};
123
124proplayout_t submenu_5_2[] = {
125 {id: 202, properties: props3, submenu: submenu_5_3},
126 {id: -1, properties: NULL, submenu: NULL}
127};
128
129proplayout_t submenu_5_1[] = {
130 {id: 201, properties: props3, submenu: submenu_5_2},
131 {id: -1, properties: NULL, submenu: NULL}
132};
133
134proplayout_t layouts[] = {
135 {id: 1, properties: props1, submenu: NULL},
136 {id: 10, properties: props2, submenu: submenu_4_1},
137 {id: 20, properties: props3, submenu: submenu_4_2},
138 {id: 100, properties: props2, submenu: submenu_4_0},
139 {id: 200, properties: props3, submenu: submenu_5_1},
140 {id: -1, properties: NULL, submenu: NULL}
141};
142

Subscribers

People subscribed via source and target branches

to all changes: