Merge lp:~indicator-applet-developers/libindicator/ubuntu into lp:~ubuntu-desktop/libindicator/ubuntu

Proposed by Ted Gould
Status: Merged
Merge reported by: Ken VanDine
Merged at revision: not available
Proposed branch: lp:~indicator-applet-developers/libindicator/ubuntu
Merge into: lp:~ubuntu-desktop/libindicator/ubuntu
Diff against target: 3570 lines (+3246/-29)
41 files modified
.bzrignore (+40/-0)
Makefile.am (+3/-1)
autogen.sh (+1/-1)
configure.ac (+17/-2)
debian/changelog (+21/-0)
debian/control (+26/-2)
debian/libindicator-dev.install (+4/-0)
debian/libindicator-tools.install (+1/-0)
debian/libindicator0.install (+1/-0)
libindicator/Makefile.am (+53/-2)
libindicator/dbus-shared.h (+28/-0)
libindicator/indicator-object.c (+344/-0)
libindicator/indicator-object.h (+123/-0)
libindicator/indicator-service-manager.c (+493/-0)
libindicator/indicator-service-manager.h (+88/-0)
libindicator/indicator-service.c (+479/-0)
libindicator/indicator-service.h (+85/-0)
libindicator/indicator-service.xml (+21/-0)
libindicator/indicator.h (+4/-18)
libindicator/indicator.pc.in (+3/-3)
tests/Makefile.am (+308/-0)
tests/dummy-indicator-blank.c (+5/-0)
tests/dummy-indicator-null.c (+95/-0)
tests/dummy-indicator-signaler.c (+109/-0)
tests/dummy-indicator-simple.c (+98/-0)
tests/service-manager-connect-service.c (+48/-0)
tests/service-manager-connect.c (+63/-0)
tests/service-manager-connect.service.in (+3/-0)
tests/service-manager-no-connect.c (+47/-0)
tests/service-manager-nostart-connect.c (+65/-0)
tests/service-shutdown-timeout.c (+46/-0)
tests/service-version-bad-service.c (+47/-0)
tests/service-version-bad.service.in (+3/-0)
tests/service-version-good-service.c (+47/-0)
tests/service-version-good.service.in (+3/-0)
tests/service-version-manager.c (+64/-0)
tests/service-version-values.h (+4/-0)
tests/session.conf.in (+40/-0)
tests/test-loader.c (+146/-0)
tools/Makefile.am (+21/-0)
tools/indicator-loader.c (+149/-0)
To merge this branch: bzr merge lp:~indicator-applet-developers/libindicator/ubuntu
Reviewer Review Type Date Requested Status
Ken VanDine Pending
Review via email: mp+15966@code.launchpad.net
To post a comment you must log in.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file '.bzrignore'
--- .bzrignore 2009-08-07 15:06:32 +0000
+++ .bzrignore 2009-12-10 17:02:12 +0000
@@ -103,3 +103,43 @@
103data/GNOME_IndicatorAppletSUS.server103data/GNOME_IndicatorAppletSUS.server
104data/GNOME_IndicatorAppletSUS.server.in104data/GNOME_IndicatorAppletSUS.server.in
105src-sus/indicator-applet-no-sus105src-sus/indicator-applet-no-sus
106libindicator/libindicator.la
107libindicator/libindicator_la-indicator-object.
108libindicator/libindicator_la-indicator-object.lo
109tests/loader-check-results.xml
110tests/loader-check-results.html
111tests/test-loader
112tests/libdummy-indicator-null.la
113tests/libdummy_indicator_null_la-dummy-indicator-null.lo
114tests/libdummy-indicator-simple.la
115tests/libdummy_indicator_simple_la-dummy-indicator-simple.lo
116tests/libdummy-indicator-blank.la
117tests/libdummy_indicator_blank_la-dummy-indicator-blank.lo
118libindicator-[0-9].[0-9].[0-9].tar.gz
119libindicator-[0-9].[0-9].[0-9].tar.gz.asc
120libindicator/libindicator_la-indicator-instance.lo
121tests/libdummy-indicator-signaler.la
122tests/libdummy_indicator_signaler_la-dummy-indicator-signaler.lo
123libindicator/indicator-service-client.h
124libindicator/indicator-service-server.h
125libindicator/libindicator_la-indicator-service.lo
126libindicator/libindicator_la-indicator-service-manager.lo
127tests/service-shutdown-timeout
128tests/loader-tester
129tests/service-shutdown-timeout-tester
130tests/service-manager-no-connect
131tests/service-manager-no-connect-tester
132tests/service-manager-connect
133tests/service-manager-connect-service
134tests/service-manager-connect-tester
135tests/session.conf
136tests/service-manager-connect.service
137tools/indicator-loader
138tests/service-version-bad-service
139tests/service-version-bad.service
140tests/service-version-good-service
141tests/service-version-good.service
142tests/service-version-manager
143tests/service-version-tester
144tests/service-manager-connect-nostart-tester
145tests/service-manager-nostart-connect
106146
=== modified file 'Makefile.am'
--- Makefile.am 2009-08-18 16:52:09 +0000
+++ Makefile.am 2009-12-10 17:02:12 +0000
@@ -1,6 +1,8 @@
11
2SUBDIRS = \2SUBDIRS = \
3 libindicator3 libindicator \
4 tests \
5 tools
46
5DISTCLEANFILES = \7DISTCLEANFILES = \
6 libindicator-*.tar.gz8 libindicator-*.tar.gz
79
=== modified file 'autogen.sh'
--- autogen.sh 2009-08-18 16:52:09 +0000
+++ autogen.sh 2009-12-10 17:02:12 +0000
@@ -8,4 +8,4 @@
8}8}
99
10USE_GNOME2_MACROS=1 \10USE_GNOME2_MACROS=1 \
11gnome-autogen.sh11. gnome-autogen.sh
1212
=== modified file 'configure.ac'
--- configure.ac 2009-10-08 14:16:40 +0000
+++ configure.ac 2009-12-10 17:02:12 +0000
@@ -1,10 +1,10 @@
11
2AC_INIT(libindicator, 0.2.1, ted@canonical.com)2AC_INIT(libindicator, 0.3.0, ted@canonical.com)
33
4AC_PREREQ(2.53)4AC_PREREQ(2.53)
55
6AM_CONFIG_HEADER(config.h)6AM_CONFIG_HEADER(config.h)
7AM_INIT_AUTOMAKE(libindicator, 0.2.1)7AM_INIT_AUTOMAKE(libindicator, 0.3.0)
88
9AM_MAINTAINER_MODE9AM_MAINTAINER_MODE
10m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES])10m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES])
@@ -21,6 +21,19 @@
21m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])])21m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])])
2222
23##############################23##############################
24# Dependencies
25##############################
26
27GTK_REQUIRED_VERSION=2.18
28DBUS_REQUIRED_VERSION=0.76
29
30PKG_CHECK_MODULES(LIBINDICATOR, gtk+-2.0 >= $GTK_REQUIRED_VERSION
31 dbus-glib-1 >= $DBUS_REQUIRED_VERSION)
32
33AC_SUBST(LIBINDICATOR_CFLAGS)
34AC_SUBST(LIBINDICATOR_LIBS)
35
36##############################
24# Custom Junk37# Custom Junk
25##############################38##############################
2639
@@ -73,6 +86,8 @@
73Makefile86Makefile
74libindicator/Makefile87libindicator/Makefile
75libindicator/indicator.pc88libindicator/indicator.pc
89tests/Makefile
90tools/Makefile
76])91])
7792
78###########################93###########################
7994
=== modified file 'debian/changelog'
--- debian/changelog 2009-10-09 06:12:31 +0000
+++ debian/changelog 2009-12-10 17:02:12 +0000
@@ -1,3 +1,24 @@
1libindicator (0.3.0-0ubuntu1~ppa1) karmic; urgency=low
2
3 * Upstream 0.3.0 Release
4 * Adds a new tool to load indicators from the command line.
5 * Adds an object for loading indicators.
6 * Changes the indicator interface to be object based.
7 * debian/control, debian/libindicator0: Adding in a new packages
8 for the binary library.
9 * debian/control, debian/libindicator-tools: Adding in a new
10 package for the tools of libindicator.
11
12 -- Ted Gould <ted@ubuntu.com> Thu, 10 Dec 2009 10:59:37 -0600
13
14libindicator (0.2.1-0ubuntu2~ppa1) karmic; urgency=low
15
16 * Adding in service management code.
17 * debian/control: Adding a target for libindicator0
18 * Adding libindicator0.install and libindicator-dev.install
19
20 -- Ted Gould <ted@ubuntu.com> Wed, 04 Nov 2009 08:19:01 -0600
21
1libindicator (0.2.1-0ubuntu1) karmic; urgency=low22libindicator (0.2.1-0ubuntu1) karmic; urgency=low
223
3 * Upstream release 0.2.1 (LP: #446619)24 * Upstream release 0.2.1 (LP: #446619)
425
=== modified file 'debian/control'
--- debian/control 2009-08-25 06:33:06 +0000
+++ debian/control 2009-12-10 17:02:12 +0000
@@ -4,21 +4,45 @@
4Maintainer: Ubuntu Core Developers <ubuntu-devel-discuss@lists.ubuntu.com>4Maintainer: Ubuntu Core Developers <ubuntu-devel-discuss@lists.ubuntu.com>
5Build-Depends: debhelper (>= 5.0),5Build-Depends: debhelper (>= 5.0),
6 cdbs (>= 0.4.41),6 cdbs (>= 0.4.41),
7 libtool7 libgtk2.0-dev (>= 2.12.0),
8 libdbus-glib-1-dev,
9 libtool,
10 intltool,
11 gtk-doc-tools
8Standards-Version: 3.8.012Standards-Version: 3.8.0
9Homepage: https://launchpad.net/libindicator13Homepage: https://launchpad.net/libindicator
10Vcs-Bzr: https://code.launchpad.net/~ubuntu-desktop/libindicator/ubuntu14Vcs-Bzr: https://code.launchpad.net/~ubuntu-desktop/libindicator/ubuntu
11Vcs-Browser: http://bazaar.launchpad.net/~ubuntu-desktop/libindicator/ubuntu15Vcs-Browser: http://bazaar.launchpad.net/~ubuntu-desktop/libindicator/ubuntu
1216
17Package: libindicator0
18Section: libs
19Architecture: any
20Depends: ${shlibs:Depends},
21 ${misc:Depends}
22Description: GNOME panel indicator applet - shared library
23 This library contains information to build indicators to go into
24 the indicator applet.
25 .
26 This package contains files that are needed to build applications.
27
13Package: libindicator-dev28Package: libindicator-dev
14Section: libdevel29Section: libdevel
15Architecture: any30Architecture: any
16Depends: ${shlibs:Depends},31Depends: ${shlibs:Depends},
17 ${misc:Depends},32 ${misc:Depends},
18 libgtk2.0-dev (>= 2.12.0)33 libgtk2.0-dev (>= 2.12.0),
34 libindicator0 (= ${binary:Version})
19Description: GNOME panel indicator applet - shared library35Description: GNOME panel indicator applet - shared library
20 This library contains information to build indicators to go into36 This library contains information to build indicators to go into
21 the indicator applet.37 the indicator applet.
22 .38 .
23 This package contains files that are needed to build applications.39 This package contains files that are needed to build applications.
2440
41Package: libindicator-tools
42Section: devel
43Architecture: any
44Depends: ${shlibs:Depends},
45 ${misc:Depends},
46 libindicator0 (= ${binary:Version})
47Description: Need a better description
48
2549
=== added file 'debian/libindicator-dev.install'
--- debian/libindicator-dev.install 1970-01-01 00:00:00 +0000
+++ debian/libindicator-dev.install 2009-12-10 17:02:12 +0000
@@ -0,0 +1,4 @@
1debian/tmp/usr/include/libindicator-0.3/libindicator/*
2debian/tmp/usr/lib/pkgconfig/indicator.pc
3debian/tmp/usr/lib/libindicator.a
4debian/tmp/usr/lib/libindicator.so
05
=== added file 'debian/libindicator-tools.install'
--- debian/libindicator-tools.install 1970-01-01 00:00:00 +0000
+++ debian/libindicator-tools.install 2009-12-10 17:02:12 +0000
@@ -0,0 +1,1 @@
1debian/tmp/usr/lib/libindicator/*
02
=== added file 'debian/libindicator0.install'
--- debian/libindicator0.install 1970-01-01 00:00:00 +0000
+++ debian/libindicator0.install 2009-12-10 17:02:12 +0000
@@ -0,0 +1,1 @@
1debian/tmp/usr/lib/libindicator.so.*
02
=== modified file 'libindicator/Makefile.am'
--- libindicator/Makefile.am 2009-04-21 19:15:22 +0000
+++ libindicator/Makefile.am 2009-12-10 17:02:12 +0000
@@ -1,14 +1,65 @@
1BUILT_SOURCES =
2CLEANFILES =
1EXTRA_DIST = \3EXTRA_DIST = \
2 indicator.pc.in4 indicator.pc.in
35
4libindicatorincludedir=$(includedir)/libindicator-0.1/libindicator6libindicatorincludedir=$(includedir)/libindicator-0.3/libindicator
57
6indicator_headers = \8indicator_headers = \
7 indicator.h9 indicator.h \
10 indicator-object.h \
11 indicator-service.h \
12 indicator-service-manager.h
813
9libindicatorinclude_HEADERS = \14libindicatorinclude_HEADERS = \
10 $(indicator_headers)15 $(indicator_headers)
1116
17lib_LTLIBRARIES = \
18 libindicator.la
19
20libindicator_la_SOURCES = \
21 $(indicator_headers) \
22 dbus-shared.h \
23 indicator-object.c \
24 indicator-service.c \
25 indicator-service-manager.c
26
27libindicator_la_CFLAGS = \
28 $(LIBINDICATOR_CFLAGS) \
29 -DG_LOG_DOMAIN=\"libindicator\" \
30 -Wall -Werror
31
32libindicator_la_LIBADD = \
33 $(LIBINDICATOR_LIBS)
34
12pkgconfig_DATA = indicator.pc35pkgconfig_DATA = indicator.pc
13pkgconfigdir = $(libdir)/pkgconfig36pkgconfigdir = $(libdir)/pkgconfig
1437
38##################################
39# DBus Specs
40##################################
41
42DBUS_SPECS = \
43 indicator-service.xml
44
45%-client.h: %.xml
46 dbus-binding-tool \
47 --prefix=_$(subst -,_,$(basename $(notdir $<)))_client \
48 --mode=glib-client \
49 --output=$@ \
50 $<
51
52%-server.h: %.xml
53 dbus-binding-tool \
54 --prefix=_$(subst -,_,$(basename $(notdir $<)))_server \
55 --mode=glib-server \
56 --output=$@ \
57 $<
58
59BUILT_SOURCES += \
60 $(DBUS_SPECS:.xml=-client.h) \
61 $(DBUS_SPECS:.xml=-server.h)
62
63CLEANFILES += $(BUILT_SOURCES)
64
65EXTRA_DIST += $(DBUS_SPECS)
1566
=== added file 'libindicator/dbus-shared.h'
--- libindicator/dbus-shared.h 1970-01-01 00:00:00 +0000
+++ libindicator/dbus-shared.h 2009-12-10 17:02:12 +0000
@@ -0,0 +1,28 @@
1/*
2Shared defines for DBus interfaces and API versions to
3make sure the server and client agree.
4
5Copyright 2009 Canonical Ltd.
6
7Authors:
8 Ted Gould <ted@canonical.com>
9
10This library is free software; you can redistribute it and/or
11modify it under the terms of the GNU General Public License
12version 3.0 as published by the Free Software Foundation.
13
14This library is distributed in the hope that it will be useful,
15but WITHOUT ANY WARRANTY; without even the implied warranty of
16MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17GNU General Public License version 3.0 for more details.
18
19You should have received a copy of the GNU General Public
20License along with this library. If not, see
21<http://www.gnu.org/licenses/>.
22*/
23
24#define INDICATOR_SERVICE_INTERFACE "org.ayatana.indicator.service"
25#define INDICATOR_SERVICE_OBJECT "/org/ayatana/indicator/service"
26
27#define INDICATOR_SERVICE_VERSION 1
28
029
=== added file 'libindicator/indicator-object.c'
--- libindicator/indicator-object.c 1970-01-01 00:00:00 +0000
+++ libindicator/indicator-object.c 2009-12-10 17:02:12 +0000
@@ -0,0 +1,344 @@
1/*
2An object to represent loadable indicator modules to make loading
3them easy and objectified.
4
5Copyright 2009 Canonical Ltd.
6
7Authors:
8 Ted Gould <ted@canonical.com>
9
10This library is free software; you can redistribute it and/or
11modify it under the terms of the GNU General Public License
12version 3.0 as published by the Free Software Foundation.
13
14This library is distributed in the hope that it will be useful,
15but WITHOUT ANY WARRANTY; without even the implied warranty of
16MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17GNU General Public License version 3.0 for more details.
18
19You should have received a copy of the GNU General Public
20License along with this library. If not, see
21<http://www.gnu.org/licenses/>.
22*/
23
24#ifdef HAVE_CONFIG_H
25#include "config.h"
26#endif
27
28#include "indicator.h"
29#include "indicator-object.h"
30
31/**
32 IndicatorObjectPrivate:
33 @module: The loaded module representing the object. Note to
34 subclasses: This will not be set when you're initalized.
35 @entry: A default entry for objects that don't need all the
36 fancy stuff. This works with #get_entries_default.
37 @gotten_entries: A check to see if the @entry has been
38 populated intelligently yet.
39
40 Structure to define the memory for the private area
41 of the object instance.
42*/
43struct _IndicatorObjectPrivate {
44 GModule * module;
45
46 /* For get_entries_default */
47 IndicatorObjectEntry entry;
48 gboolean gotten_entries;
49};
50
51#define INDICATOR_OBJECT_GET_PRIVATE(o) (INDICATOR_OBJECT(o)->priv)
52
53/* Signals Stuff */
54enum {
55 ENTRY_ADDED,
56 ENTRY_REMOVED,
57 LAST_SIGNAL
58};
59
60static guint signals[LAST_SIGNAL] = { 0 };
61
62/* GObject stuff */
63static void indicator_object_class_init (IndicatorObjectClass *klass);
64static void indicator_object_init (IndicatorObject *self);
65static void indicator_object_dispose (GObject *object);
66static void indicator_object_finalize (GObject *object);
67
68static GList * get_entries_default (IndicatorObject * io);
69
70G_DEFINE_TYPE (IndicatorObject, indicator_object, G_TYPE_OBJECT);
71
72/* Setup the class and put the functions into the
73 class structure */
74static void
75indicator_object_class_init (IndicatorObjectClass *klass)
76{
77 GObjectClass *object_class = G_OBJECT_CLASS (klass);
78
79 g_type_class_add_private (klass, sizeof (IndicatorObjectPrivate));
80
81 object_class->dispose = indicator_object_dispose;
82 object_class->finalize = indicator_object_finalize;
83
84 klass->get_label = NULL;
85 klass->get_menu = NULL;
86 klass->get_image = NULL;
87
88 klass->get_entries = get_entries_default;
89
90 /**
91 IndicatorObject::entry-added:
92 @arg0: The #IndicatorObject object
93
94 Signaled when a new entry is added and should
95 be shown by the person using this object.
96 */
97 signals[ENTRY_ADDED] = g_signal_new (INDICATOR_OBJECT_SIGNAL_ENTRY_ADDED,
98 G_TYPE_FROM_CLASS(klass),
99 G_SIGNAL_RUN_LAST,
100 G_STRUCT_OFFSET (IndicatorObjectClass, entry_added),
101 NULL, NULL,
102 g_cclosure_marshal_VOID__POINTER,
103 G_TYPE_NONE, 1, G_TYPE_POINTER, G_TYPE_NONE);
104
105 /**
106 IndicatorObject::entry-removed:
107 @arg0: The #IndicatorObject object
108
109 Signaled when an entry is removed and should
110 be removed by the person using this object.
111 */
112 signals[ENTRY_REMOVED] = g_signal_new (INDICATOR_OBJECT_SIGNAL_ENTRY_REMOVED,
113 G_TYPE_FROM_CLASS(klass),
114 G_SIGNAL_RUN_LAST,
115 G_STRUCT_OFFSET (IndicatorObjectClass, entry_removed),
116 NULL, NULL,
117 g_cclosure_marshal_VOID__POINTER,
118 G_TYPE_NONE, 1, G_TYPE_POINTER, G_TYPE_NONE);
119
120 return;
121}
122
123/* Initialize an instance */
124static void
125indicator_object_init (IndicatorObject *self)
126{
127 self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, INDICATOR_OBJECT_TYPE, IndicatorObjectPrivate);
128
129 self->priv->module = NULL;
130
131 self->priv->entry.menu = NULL;
132 self->priv->entry.label = NULL;
133 self->priv->entry.image = NULL;
134
135 self->priv->gotten_entries = FALSE;
136
137 return;
138}
139
140/* Unref the objects that we're holding on to. */
141static void
142indicator_object_dispose (GObject *object)
143{
144
145 G_OBJECT_CLASS (indicator_object_parent_class)->dispose (object);
146 return;
147}
148
149/* A small helper function that closes a module but
150 in the function prototype of a GSourceFunc. */
151static gboolean
152module_unref (gpointer data)
153{
154 if (!g_module_close((GModule *)data)) {
155 /* All we can do is warn. */
156 g_warning("Unable to close module!");
157 }
158 return FALSE;
159}
160
161/* Free memory */
162static void
163indicator_object_finalize (GObject *object)
164{
165 IndicatorObjectPrivate * priv = INDICATOR_OBJECT_GET_PRIVATE(object);
166
167 if (priv->module != NULL) {
168 /* Wow, this is convoluted. So basically we want to unref
169 the module which will cause the code it included to be
170 removed. But, since it's finalize function is the function
171 that called this one, we can't really remove it before
172 it finishes being executed. So we're putting the job into
173 the main loop to remove it the next time it gets a chance.
174 Slightly non-deterministic, but should work. */
175 g_idle_add(module_unref, priv->module);
176 priv->module = NULL;
177 }
178
179 G_OBJECT_CLASS (indicator_object_parent_class)->finalize (object);
180 return;
181}
182
183/**
184 indicator_object_new_from_file:
185 @file: Filename containing a loadable module
186
187 This function builds an #IndicatorObject using the symbols
188 that are found in @file. The module is loaded and the
189 references are all kept by the object. To unload the
190 module the object must be destroyed.
191
192 Return value: A valid #IndicatorObject or #NULL if error.
193*/
194IndicatorObject *
195indicator_object_new_from_file (const gchar * file)
196{
197 GObject * object = NULL;
198 GModule * module = NULL;
199
200 /* Check to make sure the name exists and that the
201 file itself exists */
202 if (file == NULL) {
203 g_warning("Invalid filename.");
204 return NULL;
205 }
206
207 if (!g_file_test(file, G_FILE_TEST_EXISTS)) {
208 g_warning("File '%s' does not exist.", file);
209 return NULL;
210 }
211
212 /* Grab the g_module reference, pull it in but let's
213 keep the symbols local to avoid conflicts. */
214 module = g_module_open(file,
215 G_MODULE_BIND_LAZY | G_MODULE_BIND_LOCAL);
216 if (module == NULL) {
217 g_warning("Unable to load module: %s", file);
218 return NULL;
219 }
220
221 /* Look for the version function, error if not found. */
222 get_version_t lget_version = NULL;
223 if (!g_module_symbol(module, INDICATOR_GET_VERSION_S, (gpointer *)(&lget_version))) {
224 g_warning("Unable to get the symbol for getting the version.");
225 return NULL;
226 }
227
228 /* Check the version with the macro and make sure we're
229 all talking the same language. */
230 if (!INDICATOR_VERSION_CHECK(lget_version())) {
231 g_warning("Indicator using API version '%s' we're expecting '%s'", lget_version(), INDICATOR_VERSION);
232 return NULL;
233 }
234
235 /* The function for grabbing a label from the module
236 execute it, and make sure everything is a-okay */
237 get_type_t lget_type = NULL;
238 if (!g_module_symbol(module, INDICATOR_GET_TYPE_S, (gpointer *)(&lget_type))) {
239 g_warning("Unable to get '" INDICATOR_GET_TYPE_S "' symbol from module: %s", file);
240 goto unrefandout;
241 }
242 if (lget_type == NULL) {
243 g_warning("Symbol '" INDICATOR_GET_TYPE_S "' is (null) in module: %s", file);
244 goto unrefandout;
245 }
246
247 /* A this point we allocate the object, any code beyond
248 here needs to deallocate it if we're returning in an
249 error'd state. */
250 object = g_object_new(lget_type(), NULL);
251 if (object == NULL) {
252 g_warning("Unable to build an object if type '%d' in module: %s", (gint)lget_type(), file);
253 goto unrefandout;
254 }
255 if (!INDICATOR_IS_OBJECT(object)) {
256 g_warning("Type '%d' in file %s is not a subclass of IndicatorObject.", (gint)lget_type(), file);
257 goto unrefandout;
258 }
259
260 IndicatorObjectPrivate * priv = INDICATOR_OBJECT_GET_PRIVATE(object);
261 /* Now we can track the module */
262 priv->module = module;
263
264 return INDICATOR_OBJECT(object);
265
266 /* Error, let's drop the object and return NULL. Sad when
267 this happens. */
268unrefandout:
269 if (object != NULL) {
270 g_object_unref(object);
271 }
272 if (module != NULL) {
273 g_object_unref(module);
274 }
275 g_warning("Error building IndicatorObject from file: %s", file);
276 return NULL;
277}
278
279/* The default get entries function uses the other single
280 entries in the class to create an entry structure and
281 put it into a list. This makes it simple for simple objects
282 to create the list. Small changes from the way they
283 previously were. */
284static GList *
285get_entries_default (IndicatorObject * io)
286{
287 IndicatorObjectPrivate * priv = INDICATOR_OBJECT_GET_PRIVATE(io);
288
289 if (!priv->gotten_entries) {
290 IndicatorObjectClass * class = INDICATOR_OBJECT_GET_CLASS(io);
291
292 if (class->get_label) {
293 priv->entry.label = class->get_label(io);
294 }
295
296 if (class->get_image) {
297 priv->entry.image = class->get_image(io);
298 }
299
300 if (priv->entry.image == NULL && priv->entry.label == NULL) {
301 g_warning("IndicatorObject class does not create an image or a label. We need one of those.");
302 return NULL;
303 }
304
305 if (class->get_menu) {
306 priv->entry.menu = class->get_menu(io);
307 }
308
309 if (priv->entry.menu == NULL) {
310 g_warning("IndicatorObject class does not create a menu. We need one of those.");
311 return NULL;
312 }
313
314 priv->gotten_entries = TRUE;
315 }
316
317 return g_list_append(NULL, &(priv->entry));
318}
319
320/**
321 indicator_object_get_entires:
322 @io: #IndicatorObject to query
323
324 This function looks on the class for the object and calls
325 it's #IndicatorObjectClass::get_entries function. The
326 list should be owned by the caller, but the individual
327 enteries should not be.
328
329 Return value: A list if #IndicatorObjectEntry structures or
330 NULL if there is an error.
331*/
332GList *
333indicator_object_get_entries (IndicatorObject * io)
334{
335 g_return_val_if_fail(INDICATOR_IS_OBJECT(io), NULL);
336 IndicatorObjectClass * class = INDICATOR_OBJECT_GET_CLASS(io);
337
338 if (class->get_entries) {
339 return class->get_entries(io);
340 }
341
342 g_error("No get_entries function on object. It must have been deleted?!?!");
343 return NULL;
344}
0345
=== added file 'libindicator/indicator-object.h'
--- libindicator/indicator-object.h 1970-01-01 00:00:00 +0000
+++ libindicator/indicator-object.h 2009-12-10 17:02:12 +0000
@@ -0,0 +1,123 @@
1/*
2An object to represent loadable indicator modules to make loading
3them easy and objectified.
4
5Copyright 2009 Canonical Ltd.
6
7Authors:
8 Ted Gould <ted@canonical.com>
9
10This library is free software; you can redistribute it and/or
11modify it under the terms of the GNU General Public License
12version 3.0 as published by the Free Software Foundation.
13
14This library is distributed in the hope that it will be useful,
15but WITHOUT ANY WARRANTY; without even the implied warranty of
16MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17GNU General Public License version 3.0 for more details.
18
19You should have received a copy of the GNU General Public
20License along with this library. If not, see
21<http://www.gnu.org/licenses/>.
22*/
23
24#ifndef __INDICATOR_OBJECT_H__
25#define __INDICATOR_OBJECT_H__
26
27#include <glib.h>
28#include <glib-object.h>
29
30G_BEGIN_DECLS
31
32#define INDICATOR_OBJECT_TYPE (indicator_object_get_type ())
33#define INDICATOR_OBJECT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), INDICATOR_OBJECT_TYPE, IndicatorObject))
34#define INDICATOR_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), INDICATOR_OBJECT_TYPE, IndicatorObjectClass))
35#define INDICATOR_IS_OBJECT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), INDICATOR_OBJECT_TYPE))
36#define INDICATOR_IS_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), INDICATOR_OBJECT_TYPE))
37#define INDICATOR_OBJECT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), INDICATOR_OBJECT_TYPE, IndicatorObjectClass))
38
39#define INDICATOR_OBJECT_SIGNAL_ENTRY_ADDED "entry-added"
40#define INDICATOR_OBJECT_SIGNAL_ENTRY_ADDED_ID (g_signal_lookup(INDICATOR_OBJECT_SIGNAL_ENTRY_ADDED, INDICATOR_OBJECT_TYPE))
41#define INDICATOR_OBJECT_SIGNAL_ENTRY_REMOVED "entry-removed"
42#define INDICATOR_OBJECT_SIGNAL_ENTRY_REMOVED_ID (g_signal_lookup(INDICATOR_OBJECT_SIGNAL_ENTRY_REMOVED, INDICATOR_OBJECT_TYPE))
43
44typedef struct _IndicatorObject IndicatorObject;
45typedef struct _IndicatorObjectClass IndicatorObjectClass;
46typedef struct _IndicatorObjectPrivate IndicatorObjectPrivate;
47typedef struct _IndicatorObjectEntry IndicatorObjectEntry;
48
49/**
50 IndicatorObjectClass:
51 @parent_class: #GObjectClass
52 @get_label: Gets the label for this object. Should be set
53 to #NULL if @get_entries is set. Should NOT ref the
54 object.
55 @get_image: Gets the image for this object. Should be set
56 to #NULL if @get_entries is set. Should NOT ref the
57 object.
58 @get_menu: Gets the image for this object. Should be set
59 to #NULL if @get_entries is set. Should NOT ref the
60 object.
61 @get_entries: Gets all of the entires for this object returning
62 a #GList of #IndicatorObjectEntries. The list should be
63 under the ownership of the caller but the entires will
64 not be.
65 @entry_added: Slot for #IndicatorObject::entry-added
66 @entry_removed: Slot for #IndicatorObject::entry-removed
67 @indicator_object_reserved_1: Reserved for future use
68 @indicator_object_reserved_2: Reserved for future use
69 @indicator_object_reserved_3: Reserved for future use
70 @indicator_object_reserved_4: Reserved for future use
71*/
72struct _IndicatorObjectClass {
73 GObjectClass parent_class;
74
75 /* Virtual Functions */
76 GtkLabel * (*get_label) (IndicatorObject * io);
77 GtkImage * (*get_image) (IndicatorObject * io);
78 GtkMenu * (*get_menu) (IndicatorObject * io);
79
80 GList * (*get_entries) (IndicatorObject * io);
81
82 /* Signals */
83 void (*entry_added) (IndicatorObject * io, IndicatorObjectEntry * entry, gpointer user_data);
84 void (*entry_removed) (IndicatorObject * io, IndicatorObjectEntry * entry, gpointer user_data);
85
86 /* Reserved */
87 void (* indicator_object_reserved_1) (void);
88 void (* indicator_object_reserved_2) (void);
89 void (* indicator_object_reserved_3) (void);
90 void (* indicator_object_reserved_4) (void);
91};
92
93/**
94 IndicatorObject:
95 @parent: #GObject
96 @priv: A cached reference to the private data for the
97 instance.
98*/
99struct _IndicatorObject {
100 GObject parent;
101 IndicatorObjectPrivate * priv;
102};
103
104/**
105 IndicatorObjectEntry:
106 @label: The label to be shown on the panel
107 @image: The image to be shown on the panel
108 @menu: The menu to be added to the menubar
109*/
110struct _IndicatorObjectEntry {
111 GtkLabel * label;
112 GtkImage * image;
113 GtkMenu * menu;
114};
115
116GType indicator_object_get_type (void);
117IndicatorObject * indicator_object_new_from_file (const gchar * file);
118
119GList * indicator_object_get_entries (IndicatorObject * io);
120
121G_END_DECLS
122
123#endif
0124
=== added file 'libindicator/indicator-service-manager.c'
--- libindicator/indicator-service-manager.c 1970-01-01 00:00:00 +0000
+++ libindicator/indicator-service-manager.c 2009-12-10 17:02:12 +0000
@@ -0,0 +1,493 @@
1/*
2An object used to manage services. Either start them or
3just connect to them.
4
5Copyright 2009 Canonical Ltd.
6
7Authors:
8 Ted Gould <ted@canonical.com>
9
10This library is free software; you can redistribute it and/or
11modify it under the terms of the GNU General Public License
12version 3.0 as published by the Free Software Foundation.
13
14This library is distributed in the hope that it will be useful,
15but WITHOUT ANY WARRANTY; without even the implied warranty of
16MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17GNU General Public License version 3.0 for more details.
18
19You should have received a copy of the GNU General Public
20License along with this library. If not, see
21<http://www.gnu.org/licenses/>.
22*/
23
24#ifdef HAVE_CONFIG_H
25#include "config.h"
26#endif
27
28#include <dbus/dbus-glib-bindings.h>
29#include <dbus/dbus-glib-lowlevel.h>
30
31#include "indicator-service-manager.h"
32#include "indicator-service-client.h"
33#include "dbus-shared.h"
34
35/* Private Stuff */
36/**
37 IndicatorServiceManagerPrivate:
38 @name: The well known dbus name the service should be on.
39 @dbus_proxy: A proxy to talk to the dbus daemon.
40 @service_proxy: The proxy to the service itself.
41 @connected: Whether we're connected to the service or not.
42 @this_service_version: The version of the service that we're looking for.
43 @bus: A reference to the bus so we don't have to keep getting it.
44*/
45typedef struct _IndicatorServiceManagerPrivate IndicatorServiceManagerPrivate;
46struct _IndicatorServiceManagerPrivate {
47 gchar * name;
48 DBusGProxy * dbus_proxy;
49 DBusGProxy * service_proxy;
50 gboolean connected;
51 guint this_service_version;
52 DBusGConnection * bus;
53};
54
55/* Signals Stuff */
56enum {
57 CONNECTION_CHANGE,
58 LAST_SIGNAL
59};
60
61static guint signals[LAST_SIGNAL] = { 0 };
62
63
64/* Properties */
65/* Enum for the properties so that they can be quickly
66 found and looked up. */
67enum {
68 PROP_0,
69 PROP_NAME,
70 PROP_VERSION
71};
72
73/* The strings so that they can be slowly looked up. */
74#define PROP_NAME_S "name"
75#define PROP_VERSION_S "version"
76
77/* GObject Stuff */
78#define INDICATOR_SERVICE_MANAGER_GET_PRIVATE(o) \
79(G_TYPE_INSTANCE_GET_PRIVATE ((o), INDICATOR_SERVICE_MANAGER_TYPE, IndicatorServiceManagerPrivate))
80
81static void indicator_service_manager_class_init (IndicatorServiceManagerClass *klass);
82static void indicator_service_manager_init (IndicatorServiceManager *self);
83static void indicator_service_manager_dispose (GObject *object);
84static void indicator_service_manager_finalize (GObject *object);
85
86/* Prototypes */
87static void set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec);
88static void get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec);
89static void start_service (IndicatorServiceManager * service);
90
91G_DEFINE_TYPE (IndicatorServiceManager, indicator_service_manager, G_TYPE_OBJECT);
92
93/* Build all of our signals and proxies and tie everything
94 all together. Lovely. */
95static void
96indicator_service_manager_class_init (IndicatorServiceManagerClass *klass)
97{
98 GObjectClass *object_class = G_OBJECT_CLASS (klass);
99
100 g_type_class_add_private (klass, sizeof (IndicatorServiceManagerPrivate));
101
102 object_class->dispose = indicator_service_manager_dispose;
103 object_class->finalize = indicator_service_manager_finalize;
104
105 /* Property funcs */
106 object_class->set_property = set_property;
107 object_class->get_property = get_property;
108
109 /**
110 IndicatorServiceManager::connecton-change:
111 @arg0: The #IndicatorServiceManager object
112 @arg1: The state of the connection, TRUE is connected.
113
114 Signaled when the service is connected or disconnected
115 depending on it's previous state.
116 */
117 signals[CONNECTION_CHANGE] = g_signal_new (INDICATOR_SERVICE_MANAGER_SIGNAL_CONNECTION_CHANGE,
118 G_TYPE_FROM_CLASS(klass),
119 G_SIGNAL_RUN_LAST,
120 G_STRUCT_OFFSET (IndicatorServiceManagerClass, connection_change),
121 NULL, NULL,
122 g_cclosure_marshal_VOID__BOOLEAN,
123 G_TYPE_NONE, 1, G_TYPE_BOOLEAN, G_TYPE_NONE);
124
125 /* Properties */
126 g_object_class_install_property(object_class, PROP_NAME,
127 g_param_spec_string(PROP_NAME_S,
128 "The DBus name for the service to monitor",
129 "This is the name that should be used to start a service.",
130 NULL,
131 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
132 g_object_class_install_property(object_class, PROP_VERSION,
133 g_param_spec_uint(PROP_VERSION_S,
134 "The version of the service that we're expecting.",
135 "A number to check and reject a service if it gives us the wrong number. This should match across the manager and the service",
136 0, G_MAXUINT, 0,
137 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
138
139 return;
140}
141
142/* This inits all the variable and sets up the proxy
143 to dbus. It doesn't look for the service as at this
144 point we don't know it's name. */
145static void
146indicator_service_manager_init (IndicatorServiceManager *self)
147{
148 IndicatorServiceManagerPrivate * priv = INDICATOR_SERVICE_MANAGER_GET_PRIVATE(self);
149
150 /* Get the private variables in a decent state */
151 priv->name = NULL;
152 priv->dbus_proxy = NULL;
153 priv->service_proxy = NULL;
154 priv->connected = FALSE;
155 priv->this_service_version = 0;
156 priv->bus = NULL;
157
158 /* Start talkin' dbus */
159 GError * error = NULL;
160 priv->bus = dbus_g_bus_get(DBUS_BUS_SESSION, &error);
161 if (error != NULL) {
162 g_error("Unable to get session bus for manager: %s", error->message);
163 g_error_free(error);
164 return;
165 }
166
167 priv->dbus_proxy = dbus_g_proxy_new_for_name_owner(priv->bus,
168 DBUS_SERVICE_DBUS,
169 DBUS_PATH_DBUS,
170 DBUS_INTERFACE_DBUS,
171 &error);
172 if (error != NULL) {
173 g_error("Unable to get the proxy to DBus: %s", error->message);
174 g_error_free(error);
175 return;
176 }
177
178 return;
179}
180
181/* If we're connected this provides all the signals to say
182 that we're about to not be. Then it takes down the proxies
183 and tells the service that we're not interested in being
184 its friend anymore either. */
185static void
186indicator_service_manager_dispose (GObject *object)
187{
188 IndicatorServiceManagerPrivate * priv = INDICATOR_SERVICE_MANAGER_GET_PRIVATE(object);
189
190 /* If we were connected we need to make sure to
191 tell people that it's no longer the case. */
192 if (priv->connected) {
193 priv->connected = FALSE;
194 g_signal_emit(object, signals[CONNECTION_CHANGE], 0, FALSE, TRUE);
195 }
196
197 /* Destory our DBus proxy, we won't need it. */
198 if (priv->dbus_proxy != NULL) {
199 g_object_unref(G_OBJECT(priv->dbus_proxy));
200 priv->dbus_proxy = NULL;
201 }
202
203 /* If we have a proxy, tell it we're shutting down. Just
204 to be polite about it. */
205 if (priv->service_proxy != NULL) {
206 dbus_g_proxy_call_no_reply(priv->service_proxy, "UnWatch", G_TYPE_INVALID);
207 }
208
209 /* Destory our service proxy, we won't need it. */
210 if (priv->service_proxy != NULL) {
211 g_object_unref(G_OBJECT(priv->service_proxy));
212 priv->service_proxy = NULL;
213 }
214
215 /* Let's see if our parents want to do anything. */
216 G_OBJECT_CLASS (indicator_service_manager_parent_class)->dispose (object);
217 return;
218}
219
220/* Ironically, we don't allocate a lot of memory ourselves. */
221static void
222indicator_service_manager_finalize (GObject *object)
223{
224 IndicatorServiceManagerPrivate * priv = INDICATOR_SERVICE_MANAGER_GET_PRIVATE(object);
225
226 if (priv->name != NULL) {
227 g_free(priv->name);
228 priv->name = NULL;
229 }
230
231 G_OBJECT_CLASS (indicator_service_manager_parent_class)->finalize (object);
232 return;
233}
234
235/* Either copies the name into the private variable or
236 sets the version. Do it wrong and it'll get upset. */
237static void
238set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec)
239{
240 IndicatorServiceManager * self = INDICATOR_SERVICE_MANAGER(object);
241 g_return_if_fail(self != NULL);
242
243 IndicatorServiceManagerPrivate * priv = INDICATOR_SERVICE_MANAGER_GET_PRIVATE(self);
244 g_return_if_fail(priv != NULL);
245
246 switch (prop_id) {
247 /* *********************** */
248 case PROP_NAME:
249 if (priv->name != NULL) {
250 g_error("Name can not be set twice!");
251 return;
252 }
253 priv->name = g_value_dup_string(value);
254 start_service(self);
255 break;
256 /* *********************** */
257 case PROP_VERSION:
258 priv->this_service_version = g_value_get_uint(value);
259 break;
260 /* *********************** */
261 default:
262 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
263 break;
264 }
265
266 return;
267}
268
269/* Grabs the values from the private variables and
270 puts them into the value. */
271static void
272get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec)
273{
274 IndicatorServiceManager * self = INDICATOR_SERVICE_MANAGER(object);
275 g_return_if_fail(self != NULL);
276
277 IndicatorServiceManagerPrivate * priv = INDICATOR_SERVICE_MANAGER_GET_PRIVATE(self);
278 g_return_if_fail(priv != NULL);
279
280 switch (prop_id) {
281 /* *********************** */
282 case PROP_NAME:
283 g_value_set_string(value, priv->name);
284 break;
285 /* *********************** */
286 case PROP_VERSION:
287 g_value_set_uint(value, priv->this_service_version);
288 break;
289 /* *********************** */
290 default:
291 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
292 break;
293 }
294
295 return;
296}
297
298/* A callback from telling a service that we want to watch
299 it. It gives us the service API version and the version
300 of the other APIs it supports. We check both of those.
301 If they don't match then we unwatch it. Otherwise, we
302 signal a connection change to tell the rest of the world
303 that we have a service now. */
304static void
305watch_cb (DBusGProxy * proxy, guint service_api_version, guint this_service_version, GError * error, gpointer user_data)
306{
307 IndicatorServiceManagerPrivate * priv = INDICATOR_SERVICE_MANAGER_GET_PRIVATE(user_data);
308
309 if (error != NULL) {
310 g_warning("Unable to set watch on '%s': '%s'", priv->name, error->message);
311 g_error_free(error);
312 return;
313 }
314
315 if (service_api_version != INDICATOR_SERVICE_VERSION) {
316 g_warning("Service is using a different version of the service interface. Expecting %d and got %d.", INDICATOR_SERVICE_VERSION, service_api_version);
317 dbus_g_proxy_call_no_reply(priv->service_proxy, "UnWatch", G_TYPE_INVALID);
318 return;
319 }
320
321 if (this_service_version != priv->this_service_version) {
322 g_warning("Service is using a different API version than the manager. Expecting %d and got %d.", priv->this_service_version, this_service_version);
323 dbus_g_proxy_call_no_reply(priv->service_proxy, "UnWatch", G_TYPE_INVALID);
324 return;
325 }
326
327 if (!priv->connected) {
328 priv->connected = TRUE;
329 g_signal_emit(G_OBJECT(user_data), signals[CONNECTION_CHANGE], 0, TRUE, TRUE);
330 }
331
332 return;
333}
334
335/* The callback after asking the dbus-daemon to start a
336 service for us. It can return success or failure, on
337 failure we can't do much. But, with sucess, we start
338 to build a proxy and tell the service that we're watching. */
339static void
340start_service_cb (DBusGProxy * proxy, guint status, GError * error, gpointer user_data)
341{
342 IndicatorServiceManagerPrivate * priv = INDICATOR_SERVICE_MANAGER_GET_PRIVATE(user_data);
343
344 if (error != NULL) {
345 g_warning("Unable to start service '%s': %s", priv->name, error->message);
346 return;
347 }
348
349 if (status != DBUS_START_REPLY_SUCCESS && status != DBUS_START_REPLY_ALREADY_RUNNING) {
350 g_warning("Status of starting the process '%s' was an error: %d", priv->name, status);
351 return;
352 }
353
354 /* Woot! it's running. Let's do it some more. */
355 priv->service_proxy = dbus_g_proxy_new_for_name_owner(priv->bus,
356 priv->name,
357 INDICATOR_SERVICE_OBJECT,
358 INDICATOR_SERVICE_INTERFACE,
359 &error);
360 g_object_add_weak_pointer(G_OBJECT(priv->service_proxy), (gpointer *)&(priv->service_proxy));
361
362 org_ayatana_indicator_service_watch_async(priv->service_proxy,
363 watch_cb,
364 user_data);
365
366 return;
367}
368
369/* The function that handles getting us connected to the service.
370 In many cases it will start the service, but if the service
371 is already there it just allocates the service proxy and acts
372 like it was no big deal. */
373static void
374start_service (IndicatorServiceManager * service)
375{
376 GError * error = NULL;
377 IndicatorServiceManagerPrivate * priv = INDICATOR_SERVICE_MANAGER_GET_PRIVATE(service);
378
379 g_return_if_fail(priv->dbus_proxy != NULL);
380 g_return_if_fail(priv->name != NULL);
381
382 /* Check to see if we can get a proxy to it first. */
383 priv->service_proxy = dbus_g_proxy_new_for_name_owner(priv->bus,
384 priv->name,
385 INDICATOR_SERVICE_OBJECT,
386 INDICATOR_SERVICE_INTERFACE,
387 &error);
388
389 if (error != NULL) {
390 /* We don't care about the error, just start the service anyway. */
391 g_error_free(error);
392 org_freedesktop_DBus_start_service_by_name_async (priv->dbus_proxy,
393 priv->name,
394 0,
395 start_service_cb,
396 service);
397 } else {
398 g_object_add_weak_pointer(G_OBJECT(priv->service_proxy), (gpointer *)&(priv->service_proxy));
399
400 /* If we got a proxy just because we're good people then
401 we need to call watch on it just like 'start_service_cb'
402 does. */
403 org_ayatana_indicator_service_watch_async(priv->service_proxy,
404 watch_cb,
405 service);
406 }
407
408 return;
409}
410
411/* API */
412
413/**
414 indicator_service_manager_new:
415 @dbus_name: The well known name of the service on DBus
416
417 This creates a new service manager object. If the service
418 is not running it will start it. No matter what, it will
419 give a IndicatorServiceManager::connection-changed event
420 signal when it gets connected.
421
422 Return value: A brand new lovely #IndicatorServiceManager
423 object.
424*/
425IndicatorServiceManager *
426indicator_service_manager_new (gchar * dbus_name)
427{
428 GObject * obj = g_object_new(INDICATOR_SERVICE_MANAGER_TYPE,
429 PROP_NAME_S, dbus_name,
430 NULL);
431
432 return INDICATOR_SERVICE_MANAGER(obj);
433}
434
435/**
436 inicator_service_manager_new_version:
437 @dbus_name: The well known name of the service on DBus
438 @version: Version of the service we expect
439
440 This creates a new service manager object. It also sets
441 the version of the service that we're expecting to see.
442 In general, it behaves similarly to #indicator_service_manager_new()
443 except that it checks @version against the version returned
444 by the service.
445
446 Return value: A brand new lovely #IndicatorServiceManager
447 object.
448*/
449IndicatorServiceManager *
450indicator_service_manager_new_version (gchar * dbus_name, guint version)
451{
452 GObject * obj = g_object_new(INDICATOR_SERVICE_MANAGER_TYPE,
453 PROP_NAME_S, dbus_name,
454 PROP_VERSION_S, version,
455 NULL);
456
457 return INDICATOR_SERVICE_MANAGER(obj);
458}
459
460/**
461 indicator_service_manager_connected:
462 @sm: #IndicatorServiceManager object to check
463
464 Checks to see if the service manager is connected to a
465 service.
466
467 Return value: #TRUE if there is a service connceted.
468*/
469gboolean
470indicator_service_manager_connected (IndicatorServiceManager * sm)
471{
472 g_return_val_if_fail(INDICATOR_IS_SERVICE_MANAGER(sm), FALSE);
473 IndicatorServiceManagerPrivate * priv = INDICATOR_SERVICE_MANAGER_GET_PRIVATE(sm);
474 return priv->connected;
475}
476
477/**
478 indicator_service_manager_set_refresh:
479 @sm: #IndicatorServiceManager object to configure
480 @time_in_ms: The refresh time in milliseconds
481
482 Use this function to set the amount of time between restarting
483 services that may crash or shutdown. This is mostly useful
484 for testing and development.
485
486 NOTE: Not yet implemented.
487*/
488void
489indicator_service_manager_set_refresh (IndicatorServiceManager * sm, guint time_in_ms)
490{
491
492 return;
493}
0494
=== added file 'libindicator/indicator-service-manager.h'
--- libindicator/indicator-service-manager.h 1970-01-01 00:00:00 +0000
+++ libindicator/indicator-service-manager.h 2009-12-10 17:02:12 +0000
@@ -0,0 +1,88 @@
1/*
2An object used to manage services. Either start them or
3just connect to them.
4
5Copyright 2009 Canonical Ltd.
6
7Authors:
8 Ted Gould <ted@canonical.com>
9
10This library is free software; you can redistribute it and/or
11modify it under the terms of the GNU General Public License
12version 3.0 as published by the Free Software Foundation.
13
14This library is distributed in the hope that it will be useful,
15but WITHOUT ANY WARRANTY; without even the implied warranty of
16MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17GNU General Public License version 3.0 for more details.
18
19You should have received a copy of the GNU General Public
20License along with this library. If not, see
21<http://www.gnu.org/licenses/>.
22*/
23
24#ifndef __INDICATOR_SERVICE_MANAGER_H__
25#define __INDICATOR_SERVICE_MANAGER_H__
26
27#include <glib.h>
28#include <glib-object.h>
29
30G_BEGIN_DECLS
31
32#define INDICATOR_SERVICE_MANAGER_TYPE (indicator_service_manager_get_type ())
33#define INDICATOR_SERVICE_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), INDICATOR_SERVICE_MANAGER_TYPE, IndicatorServiceManager))
34#define INDICATOR_SERVICE_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), INDICATOR_SERVICE_MANAGER_TYPE, IndicatorServiceManagerClass))
35#define INDICATOR_IS_SERVICE_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), INDICATOR_SERVICE_MANAGER_TYPE))
36#define INDICATOR_IS_SERVICE_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), INDICATOR_SERVICE_MANAGER_TYPE))
37#define INDICATOR_SERVICE_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), INDICATOR_SERVICE_MANAGER_TYPE, IndicatorServiceManagerClass))
38
39#define INDICATOR_SERVICE_MANAGER_SIGNAL_CONNECTION_CHANGE "connection-change"
40
41typedef struct _IndicatorServiceManager IndicatorServiceManager;
42typedef struct _IndicatorServiceManagerClass IndicatorServiceManagerClass;
43
44/**
45 IndicatorServiceManagerClass:
46 @parent: #GObjectClass
47 @connection_changed: Slot for #IndicatorServiceManager::connection-changed.
48 @indicator_service_manager_reserved1: Reserved for future use.
49 @indicator_service_manager_reserved2: Reserved for future use.
50 @indicator_service_manager_reserved3: Reserved for future use.
51 @indicator_service_manager_reserved4: Reserved for future use.
52
53*/
54struct _IndicatorServiceManagerClass {
55 GObjectClass parent_class;
56
57 /* Signals */
58 void (*connection_change) (IndicatorServiceManager * sm, gboolean connected, gpointer user_data);
59
60 /* Buffer */
61 void (*indicator_service_manager_reserved1) (void);
62 void (*indicator_service_manager_reserved2) (void);
63 void (*indicator_service_manager_reserved3) (void);
64 void (*indicator_service_manager_reserved4) (void);
65};
66
67/**
68 IndicatorServiceManager:
69 @parent: #GObject
70
71*/
72struct _IndicatorServiceManager {
73 GObject parent;
74
75};
76
77GType indicator_service_manager_get_type (void);
78
79IndicatorServiceManager * indicator_service_manager_new (gchar * dbus_name);
80IndicatorServiceManager * indicator_service_manager_new_version (gchar * dbus_name,
81 guint version);
82gboolean indicator_service_manager_connected (IndicatorServiceManager * sm);
83void indicator_service_manager_set_refresh (IndicatorServiceManager * sm,
84 guint time_in_ms);
85
86G_END_DECLS
87
88#endif
089
=== added file 'libindicator/indicator-service.c'
--- libindicator/indicator-service.c 1970-01-01 00:00:00 +0000
+++ libindicator/indicator-service.c 2009-12-10 17:02:12 +0000
@@ -0,0 +1,479 @@
1/*
2An object used to provide a simple interface for a service
3to query version and manage whether it's running.
4
5Copyright 2009 Canonical Ltd.
6
7Authors:
8 Ted Gould <ted@canonical.com>
9
10This library is free software; you can redistribute it and/or
11modify it under the terms of the GNU General Public License
12version 3.0 as published by the Free Software Foundation.
13
14This library is distributed in the hope that it will be useful,
15but WITHOUT ANY WARRANTY; without even the implied warranty of
16MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17GNU General Public License version 3.0 for more details.
18
19You should have received a copy of the GNU General Public
20License along with this library. If not, see
21<http://www.gnu.org/licenses/>.
22*/
23
24#ifdef HAVE_CONFIG_H
25#include "config.h"
26#endif
27#include <dbus/dbus-glib-bindings.h>
28#include <dbus/dbus-glib-lowlevel.h>
29
30#include "indicator-service.h"
31
32/* DBus Prototypes */
33static gboolean _indicator_service_server_watch (IndicatorService * service, DBusGMethodInvocation * method);
34static gboolean _indicator_service_server_un_watch (IndicatorService * service, DBusGMethodInvocation * method);
35
36#include "indicator-service-server.h"
37#include "dbus-shared.h"
38
39/* Private Stuff */
40/**
41 IndicatorSevicePrivate:
42 @name: The DBus well known name for the service.
43 @dbus_proxy: A proxy for talking to the dbus bus manager.
44 @timeout: The source ID for the timeout event.
45 @watcher: A list of processes on dbus that are watching us.
46 @this_service_version: The version to hand out that we're
47 implementing. May not be set, so we'll send zero (default).
48*/
49typedef struct _IndicatorServicePrivate IndicatorServicePrivate;
50struct _IndicatorServicePrivate {
51 gchar * name;
52 DBusGProxy * dbus_proxy;
53 guint timeout;
54 GList * watchers;
55 guint this_service_version;
56};
57
58/* Signals Stuff */
59enum {
60 SHUTDOWN,
61 LAST_SIGNAL
62};
63
64static guint signals[LAST_SIGNAL] = { 0 };
65
66/* Properties */
67/* Enum for the properties so that they can be quickly
68 found and looked up. */
69enum {
70 PROP_0,
71 PROP_NAME,
72 PROP_VERSION
73};
74
75/* The strings so that they can be slowly looked up. */
76#define PROP_NAME_S "name"
77#define PROP_VERSION_S "version"
78
79/* GObject Stuff */
80#define INDICATOR_SERVICE_GET_PRIVATE(o) \
81 (G_TYPE_INSTANCE_GET_PRIVATE ((o), INDICATOR_SERVICE_TYPE, IndicatorServicePrivate))
82
83static void indicator_service_class_init (IndicatorServiceClass *klass);
84static void indicator_service_init (IndicatorService *self);
85static void indicator_service_dispose (GObject *object);
86static void indicator_service_finalize (GObject *object);
87
88/* Other prototypes */
89static void set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec);
90static void get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec);
91static void try_and_get_name (IndicatorService * service);
92
93G_DEFINE_TYPE (IndicatorService, indicator_service, G_TYPE_OBJECT);
94
95static void
96indicator_service_class_init (IndicatorServiceClass *klass)
97{
98 GObjectClass *object_class = G_OBJECT_CLASS (klass);
99
100 g_type_class_add_private (klass, sizeof (IndicatorServicePrivate));
101
102 object_class->dispose = indicator_service_dispose;
103 object_class->finalize = indicator_service_finalize;
104
105 /* Property funcs */
106 object_class->set_property = set_property;
107 object_class->get_property = get_property;
108
109 /* Properties */
110 g_object_class_install_property(object_class, PROP_NAME,
111 g_param_spec_string(PROP_NAME_S,
112 "The DBus name for this service",
113 "This is the name that should be used on DBus for this service.",
114 NULL,
115 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
116 g_object_class_install_property(object_class, PROP_VERSION,
117 g_param_spec_uint(PROP_VERSION_S,
118 "The version of the service that we're implementing.",
119 "A number to represent the version of the other APIs the service provides. This should match across the manager and the service",
120 0, G_MAXUINT, 0,
121 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
122
123 /* Signals */
124
125 /**
126 IndicatorService::shutdown:
127 @arg0: The #IndicatorService object
128
129 Signaled when the service should shutdown as no one
130 is listening anymore.
131 */
132 signals[SHUTDOWN] = g_signal_new (INDICATOR_SERVICE_SIGNAL_SHUTDOWN,
133 G_TYPE_FROM_CLASS(klass),
134 G_SIGNAL_RUN_LAST,
135 G_STRUCT_OFFSET (IndicatorServiceClass, shutdown),
136 NULL, NULL,
137 g_cclosure_marshal_VOID__VOID,
138 G_TYPE_NONE, 0, G_TYPE_NONE);
139
140 /* Initialize the object as a DBus type */
141 dbus_g_object_type_install_info(INDICATOR_SERVICE_TYPE,
142 &dbus_glib__indicator_service_server_object_info);
143
144 return;
145}
146
147/* This function builds the variables, sets up the dbus
148 proxy and registers the object on dbus. Importantly,
149 it does not request a name as we don't know what name
150 we have yet. */
151static void
152indicator_service_init (IndicatorService *self)
153{
154 IndicatorServicePrivate * priv = INDICATOR_SERVICE_GET_PRIVATE(self);
155
156 /* Get the private variables in a decent state */
157 priv->name = NULL;
158 priv->dbus_proxy = NULL;
159 priv->timeout = 0;
160 priv->watchers = NULL;
161 priv->this_service_version = 0;
162
163 /* Start talkin' dbus */
164 GError * error = NULL;
165 DBusGConnection * bus = dbus_g_bus_get(DBUS_BUS_STARTER, &error);
166 if (error != NULL) {
167 g_error("Unable to get starter bus: %s", error->message);
168 g_error_free(error);
169
170 /* Okay, fine let's try the session bus then. */
171 /* I think this should automatically, but I can't find confirmation
172 of that, so we're putting the extra little code in here. */
173 error = NULL;
174 bus = dbus_g_bus_get(DBUS_BUS_SESSION, &error);
175 if (error != NULL) {
176 g_error("Unable to get session bus: %s", error->message);
177 g_error_free(error);
178 return;
179 }
180 }
181
182 priv->dbus_proxy = dbus_g_proxy_new_for_name_owner(bus,
183 DBUS_SERVICE_DBUS,
184 DBUS_PATH_DBUS,
185 DBUS_INTERFACE_DBUS,
186 &error);
187 if (error != NULL) {
188 g_error("Unable to get the proxy to DBus: %s", error->message);
189 g_error_free(error);
190 return;
191 }
192
193 dbus_g_connection_register_g_object(bus,
194 INDICATOR_SERVICE_OBJECT,
195 G_OBJECT(self));
196
197 return;
198}
199
200/* Unrefcounting the proxies and making sure that our
201 timeout doesn't come to haunt us. */
202static void
203indicator_service_dispose (GObject *object)
204{
205 IndicatorServicePrivate * priv = INDICATOR_SERVICE_GET_PRIVATE(object);
206
207 if (priv->dbus_proxy != NULL) {
208 g_object_unref(G_OBJECT(priv->dbus_proxy));
209 priv->dbus_proxy = NULL;
210 }
211
212 if (priv->timeout != 0) {
213 g_source_remove(priv->timeout);
214 priv->timeout = 0;
215 }
216
217 G_OBJECT_CLASS (indicator_service_parent_class)->dispose (object);
218 return;
219}
220
221/* Freeing the name we're looking for and all of the
222 information on the watchers we're tracking. */
223static void
224indicator_service_finalize (GObject *object)
225{
226 IndicatorServicePrivate * priv = INDICATOR_SERVICE_GET_PRIVATE(object);
227
228 if (priv->name != NULL) {
229 g_free(priv->name);
230 }
231
232 if (priv->watchers != NULL) {
233 g_list_foreach(priv->watchers, (GFunc)g_free, NULL);
234 g_list_free(priv->watchers);
235 priv->watchers = NULL;
236 }
237
238 G_OBJECT_CLASS (indicator_service_parent_class)->finalize (object);
239 return;
240}
241
242/* Either copies a string for the name or it just grabs
243 the value of the version. */
244static void
245set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec)
246{
247 IndicatorService * self = INDICATOR_SERVICE(object);
248 g_return_if_fail(self != NULL);
249
250 IndicatorServicePrivate * priv = INDICATOR_SERVICE_GET_PRIVATE(self);
251 g_return_if_fail(priv != NULL);
252
253 switch (prop_id) {
254 /* *********************** */
255 case PROP_NAME:
256 if (G_VALUE_HOLDS_STRING(value)) {
257 if (priv->name != NULL) {
258 g_error("Name can not be set twice!");
259 return;
260 }
261 priv->name = g_value_dup_string(value);
262 try_and_get_name(self);
263 } else {
264 g_warning("Name property requires a string value.");
265 }
266 break;
267 /* *********************** */
268 case PROP_VERSION:
269 priv->this_service_version = g_value_get_uint(value);
270 break;
271 /* *********************** */
272 default:
273 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
274 break;
275 }
276
277 return;
278}
279
280/* Copies out the name into a value or the version number.
281 Probably this is the least useful code in this file. */
282static void
283get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec)
284{
285 IndicatorService * self = INDICATOR_SERVICE(object);
286 g_return_if_fail(self != NULL);
287
288 IndicatorServicePrivate * priv = INDICATOR_SERVICE_GET_PRIVATE(self);
289 g_return_if_fail(priv != NULL);
290
291 switch (prop_id) {
292 /* *********************** */
293 case PROP_NAME:
294 if (G_VALUE_HOLDS_STRING(value)) {
295 g_value_set_string(value, priv->name);
296 } else {
297 g_warning("Name property requires a string value.");
298 }
299 break;
300 /* *********************** */
301 case PROP_VERSION:
302 g_value_set_uint(value, priv->this_service_version);
303 break;
304 /* *********************** */
305 default:
306 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
307 break;
308 }
309
310 return;
311}
312
313/* This is the function that gets executed if we timeout
314 because there are no watchers. We sent the shutdown
315 signal and hope someone does something sane with it. */
316static gboolean
317timeout_no_watchers (gpointer data)
318{
319 g_signal_emit(G_OBJECT(data), signals[SHUTDOWN], 0, TRUE);
320 return FALSE;
321}
322
323/* The callback from our request to get a well known name
324 on dbus. If we can't get it we send the shutdown signal.
325 Else we start the timer to see if anyone cares about us. */
326static void
327try_and_get_name_cb (DBusGProxy * proxy, guint status, GError * error, gpointer data)
328{
329 IndicatorService * service = INDICATOR_SERVICE(data);
330 g_return_if_fail(service != NULL);
331
332 if (status != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER && status != DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER) {
333 /* The already owner seems like it shouldn't ever
334 happen, but I have a hard time throwing an error
335 on it as we did achieve our goals. */
336 g_signal_emit(G_OBJECT(data), signals[SHUTDOWN], 0, TRUE);
337 return;
338 }
339
340 IndicatorServicePrivate * priv = INDICATOR_SERVICE_GET_PRIVATE(service);
341 priv->timeout = g_timeout_add(500, timeout_no_watchers, service);
342
343 return;
344}
345
346/* This function sets up the request for the name on dbus. */
347static void
348try_and_get_name (IndicatorService * service)
349{
350 IndicatorServicePrivate * priv = INDICATOR_SERVICE_GET_PRIVATE(service);
351 g_return_if_fail(priv->dbus_proxy != NULL);
352 g_return_if_fail(priv->name != NULL);
353
354 org_freedesktop_DBus_request_name_async(priv->dbus_proxy,
355 priv->name,
356 DBUS_NAME_FLAG_DO_NOT_QUEUE,
357 try_and_get_name_cb,
358 service);
359
360 return;
361}
362
363/* Here is the function that gets called by the dbus
364 interface "Watch" function. It is an async function so
365 that we can get the sender and store that information. We
366 put them in a list and reset the timeout. */
367static gboolean
368_indicator_service_server_watch (IndicatorService * service, DBusGMethodInvocation * method)
369{
370 g_return_val_if_fail(INDICATOR_IS_SERVICE(service), FALSE);
371 IndicatorServicePrivate * priv = INDICATOR_SERVICE_GET_PRIVATE(service);
372
373 priv->watchers = g_list_append(priv->watchers,
374 g_strdup(dbus_g_method_get_sender(method)));
375
376 if (priv->timeout != 0) {
377 g_source_remove(priv->timeout);
378 priv->timeout = 0;
379 }
380
381 dbus_g_method_return(method, INDICATOR_SERVICE_VERSION, priv->this_service_version);
382 return TRUE;
383}
384
385/* Mung g_strcmp0 into GCompareFunc */
386static gint
387find_watcher (gconstpointer a, gconstpointer b)
388{
389 return g_strcmp0((const gchar *)a, (const gchar *)b);
390}
391
392/* A function connecting into the dbus interface for the
393 "UnWatch" function. It is also an async function to get
394 the sender. It then looks the sender up and removes them
395 from the list of watchers. If there are none left, it then
396 starts the timer for the shutdown signal. */
397static gboolean
398_indicator_service_server_un_watch (IndicatorService * service, DBusGMethodInvocation * method)
399{
400 g_return_val_if_fail(INDICATOR_IS_SERVICE(service), FALSE);
401 IndicatorServicePrivate * priv = INDICATOR_SERVICE_GET_PRIVATE(service);
402
403 /* Remove us from the watcher list here */
404 GList * watcher_item = g_list_find_custom(priv->watchers, dbus_g_method_get_sender(method), find_watcher);
405 if (watcher_item != NULL) {
406 /* Free the watcher */
407 gchar * name = watcher_item->data;
408 priv->watchers = g_list_remove(priv->watchers, name);
409 g_free(name);
410 } else {
411 /* Odd that we couldn't find the person, but, eh */
412 g_warning("Unable to find watcher who is unwatching: %s", dbus_g_method_get_sender(method));
413 }
414
415 /* If we're out of watchers set the timeout for shutdown */
416 if (priv->watchers == NULL) {
417 if (priv->timeout != 0) {
418 /* This should never really happen, but let's ensure that
419 bad things don't happen if it does. */
420 g_warning("No watchers timeout set twice. Resolving, but odd.");
421 g_source_remove(priv->timeout);
422 priv->timeout = 0;
423 }
424 /* If we don't get a new watcher quickly, we'll shutdown. */
425 priv->timeout = g_timeout_add(500, timeout_no_watchers, service);
426 }
427
428 dbus_g_method_return(method);
429 return TRUE;
430}
431
432/* API */
433
434/**
435 indicator_service_new:
436 @name: The name for the service on dbus
437
438 This function creates the service on DBus and tries to
439 get a well-known name specified in @name. If the name
440 can't be estabilished then the #IndicatorService::shutdown
441 signal will be sent.
442
443 Return value: A brand new #IndicatorService object or #NULL
444 if there is an error.
445*/
446IndicatorService *
447indicator_service_new (gchar * name)
448{
449 GObject * obj = g_object_new(INDICATOR_SERVICE_TYPE,
450 PROP_NAME_S, name,
451 NULL);
452
453 return INDICATOR_SERVICE(obj);
454}
455
456/**
457 indicator_service_new_version:
458 @name: The name for the service on dbus
459 @version: The version of the other interfaces provide
460 by the service.
461
462 This function creates the service on DBus and tries to
463 get a well-known name specified in @name. If the name
464 can't be estabilished then the #IndicatorService::shutdown
465 signal will be sent.
466
467 Return value: A brand new #IndicatorService object or #NULL
468 if there is an error.
469*/
470IndicatorService *
471indicator_service_new_version (gchar * name, guint version)
472{
473 GObject * obj = g_object_new(INDICATOR_SERVICE_TYPE,
474 PROP_NAME_S, name,
475 PROP_VERSION_S, version,
476 NULL);
477
478 return INDICATOR_SERVICE(obj);
479}
0480
=== added file 'libindicator/indicator-service.h'
--- libindicator/indicator-service.h 1970-01-01 00:00:00 +0000
+++ libindicator/indicator-service.h 2009-12-10 17:02:12 +0000
@@ -0,0 +1,85 @@
1/*
2An object used to provide a simple interface for a service
3to query version and manage whether it's running.
4
5Copyright 2009 Canonical Ltd.
6
7Authors:
8 Ted Gould <ted@canonical.com>
9
10This library is free software; you can redistribute it and/or
11modify it under the terms of the GNU General Public License
12version 3.0 as published by the Free Software Foundation.
13
14This library is distributed in the hope that it will be useful,
15but WITHOUT ANY WARRANTY; without even the implied warranty of
16MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17GNU General Public License version 3.0 for more details.
18
19You should have received a copy of the GNU General Public
20License along with this library. If not, see
21<http://www.gnu.org/licenses/>.
22*/
23
24#ifndef __INDICATOR_SERVICE_H__
25#define __INDICATOR_SERVICE_H__
26
27#include <glib.h>
28#include <glib-object.h>
29
30G_BEGIN_DECLS
31
32#define INDICATOR_SERVICE_TYPE (indicator_service_get_type ())
33#define INDICATOR_SERVICE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), INDICATOR_SERVICE_TYPE, IndicatorService))
34#define INDICATOR_SERVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), INDICATOR_SERVICE_TYPE, IndicatorServiceClass))
35#define INDICATOR_IS_SERVICE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), INDICATOR_SERVICE_TYPE))
36#define INDICATOR_IS_SERVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), INDICATOR_SERVICE_TYPE))
37#define INDICATOR_SERVICE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), INDICATOR_SERVICE_TYPE, IndicatorServiceClass))
38
39#define INDICATOR_SERVICE_SIGNAL_SHUTDOWN "shutdown"
40
41typedef struct _IndicatorService IndicatorService;
42typedef struct _IndicatorServiceClass IndicatorServiceClass;
43
44/**
45 IndicatorServiceClass:
46 @parent_class: #GObjectClass
47 @shutdown: Slot for IndicatorServiceClass::shutdown
48 @indicator_service_reserved1: Reserved for future use
49 @indicator_service_reserved2: Reserved for future use
50 @indicator_service_reserved3: Reserved for future use
51 @indicator_service_reserved4: Reserved for future use
52
53*/
54struct _IndicatorServiceClass {
55 GObjectClass parent_class;
56
57 /* Signals */
58 void (*shutdown) (IndicatorService * service, gpointer user_data);
59
60 /* Reserved */
61 void (*indicator_service_reserved1) (void);
62 void (*indicator_service_reserved2) (void);
63 void (*indicator_service_reserved3) (void);
64 void (*indicator_service_reserved4) (void);
65};
66
67/**
68 IndicatorService:
69 @parent: #GObject
70
71*/
72struct _IndicatorService {
73 GObject parent;
74
75};
76
77GType indicator_service_get_type (void);
78
79IndicatorService * indicator_service_new (gchar * name);
80IndicatorService * indicator_service_new_version (gchar * name,
81 guint version);
82
83G_END_DECLS
84
85#endif
086
=== added file 'libindicator/indicator-service.xml'
--- libindicator/indicator-service.xml 1970-01-01 00:00:00 +0000
+++ libindicator/indicator-service.xml 2009-12-10 17:02:12 +0000
@@ -0,0 +1,21 @@
1<?xml version="1.0" encoding="UTF-8"?>
2<node name="/">
3 <interface name="org.ayatana.indicator.service">
4<!-- Properties -->
5 <!-- None currently -->
6
7<!-- Methods -->
8 <method name="Watch">
9 <annotation name="org.freedesktop.DBus.GLib.Async" value="true" />
10 <arg type="u" name="version" direction="out" />
11 <arg type="u" name="service_version" direction="out" />
12 </method>
13 <method name="UnWatch">
14 <annotation name="org.freedesktop.DBus.GLib.Async" value="true" />
15 </method>
16
17<!-- Signals -->
18 <!-- None currently -->
19
20 </interface>
21</node>
022
=== modified file 'libindicator/indicator.h'
--- libindicator/indicator.h 2009-10-06 15:00:34 +0000
+++ libindicator/indicator.h 2009-12-10 17:02:12 +0000
@@ -25,31 +25,17 @@
2525
26#include <gtk/gtk.h>26#include <gtk/gtk.h>
2727
28#define INDICATOR_GET_LABEL_S "get_label"
29typedef GtkLabel * (*get_label_t)(void);
30GtkLabel * get_label (void);
31
32#define INDICATOR_GET_ICON_S "get_icon"
33typedef GtkImage * (*get_icon_t) (void);
34GtkImage * get_icon (void);
35
36#define INDICATOR_GET_MENU_S "get_menu"
37typedef GtkMenu * (*get_menu_t) (void);
38GtkMenu * get_menu (void);
39
40#define INDICATOR_GET_VERSION_S "get_version"28#define INDICATOR_GET_VERSION_S "get_version"
41typedef gchar * (*get_version_t) (void);29typedef gchar * (*get_version_t) (void);
42gchar * get_version (void);30gchar * get_version (void);
4331
44#define INDICATOR_VERSION "0.2.0"32#define INDICATOR_VERSION "0.3.0"
45#define INDICATOR_SET_VERSION gchar * get_version(void) { return INDICATOR_VERSION; }33#define INDICATOR_SET_VERSION gchar * get_version(void) { return INDICATOR_VERSION; }
46#define INDICATOR_VERSION_CHECK(x) (!g_strcmp0(x, INDICATOR_VERSION))34#define INDICATOR_VERSION_CHECK(x) (!g_strcmp0(x, INDICATOR_VERSION))
4735
48#define INDICATOR_GET_NAME_S "get_name"36#define INDICATOR_GET_TYPE_S "get_type"
49typedef gchar * (*get_name_t) (void);37typedef GType (*get_type_t) (void);
50gchar * get_name (void);38#define INDICATOR_SET_TYPE(x) GType get_type (void) { return x; }
51#define INDICATOR_SET_NAME(x) gchar * get_name(void) {return (x); }
52
5339
54#endif /* __LIBINDICATOR_INDICATOR_H_SEEN__ */40#endif /* __LIBINDICATOR_INDICATOR_H_SEEN__ */
5541
5642
=== modified file 'libindicator/indicator.pc.in'
--- libindicator/indicator.pc.in 2009-08-08 15:55:54 +0000
+++ libindicator/indicator.pc.in 2009-12-10 17:02:12 +0000
@@ -4,12 +4,12 @@
4bindir=@bindir@4bindir=@bindir@
5includedir=@includedir@5includedir=@includedir@
66
7indicatordir=${libdir}/indicators/2/7indicatordir=${libdir}/indicators/3/
8iconsdir=@datarootdir@/@PACKAGE@/icons/8iconsdir=@datarootdir@/@PACKAGE@/icons/
99
10Cflags: -I${includedir}/libindicator-0.110Cflags: -I${includedir}/libindicator-0.3
11Requires: gtk+-2.011Requires: gtk+-2.0
12Libs: 12Libs: -lindicator
1313
14Name: libindicator14Name: libindicator
15Description: libindicator.15Description: libindicator.
1616
=== added directory 'tests'
=== added file 'tests/Makefile.am'
--- tests/Makefile.am 1970-01-01 00:00:00 +0000
+++ tests/Makefile.am 2009-12-10 17:02:12 +0000
@@ -0,0 +1,308 @@
1TESTS =
2DISTCLEANFILES =
3
4check_PROGRAMS =
5
6lib_LTLIBRARIES = \
7 libdummy-indicator-blank.la \
8 libdummy-indicator-null.la \
9 libdummy-indicator-signaler.la \
10 libdummy-indicator-simple.la
11
12DBUS_RUNNER=dbus-test-runner --dbus-config /usr/share/dbus-test-runner/session.conf
13
14#############################
15# Test Loader
16#############################
17
18check_PROGRAMS += test-loader
19
20test_loader_SOURCES = \
21 test-loader.c
22
23test_loader_CFLAGS = \
24 -Wall -Werror \
25 $(LIBINDICATOR_CFLAGS) -I$(top_srcdir) \
26 -DBUILD_DIR="\"$(builddir)\""
27
28test_loader_LDADD = \
29 $(LIBINDICATOR_LIBS) \
30 -L$(top_builddir)/libindicator/.libs \
31 -lindicator
32
33#############################
34# Dummy Indicator Blank
35#############################
36
37libdummy_indicator_blank_la_SOURCES = \
38 dummy-indicator-blank.c
39
40libdummy_indicator_blank_la_CFLAGS = \
41 -Wall -Werror \
42 $(LIBINDICATOR_CFLAGS) -I$(top_srcdir)
43
44libdummy_indicator_blank_la_LIBADD = \
45 $(LIBINDICATOR_LIBS) \
46 -L$(top_builddir)/libindicator/.libs \
47 -lindicator
48
49libdummy_indicator_blank_la_LDFLAGS = \
50 -module \
51 -avoid-version
52
53#############################
54# Dummy Indicator NULL
55#############################
56
57libdummy_indicator_null_la_SOURCES = \
58 dummy-indicator-null.c
59
60libdummy_indicator_null_la_CFLAGS = \
61 -Wall -Werror \
62 $(LIBINDICATOR_CFLAGS) -I$(top_srcdir)
63
64libdummy_indicator_null_la_LIBADD = \
65 $(LIBINDICATOR_LIBS) \
66 -L$(top_builddir)/libindicator/.libs \
67 -lindicator
68
69libdummy_indicator_null_la_LDFLAGS = \
70 -module \
71 -avoid-version
72
73#############################
74# Dummy Indicator Signaler
75#############################
76
77libdummy_indicator_signaler_la_SOURCES = \
78 dummy-indicator-signaler.c
79
80libdummy_indicator_signaler_la_CFLAGS = \
81 -Wall -Werror \
82 $(LIBINDICATOR_CFLAGS) -I$(top_srcdir)
83
84libdummy_indicator_signaler_la_LIBADD = \
85 $(LIBINDICATOR_LIBS) \
86 -L$(top_builddir)/libindicator/.libs \
87 -lindicator
88
89libdummy_indicator_signaler_la_LDFLAGS = \
90 -module \
91 -avoid-version
92
93#############################
94# Dummy Indicator Simple
95#############################
96
97libdummy_indicator_simple_la_SOURCES = \
98 dummy-indicator-simple.c
99
100libdummy_indicator_simple_la_CFLAGS = \
101 -Wall -Werror \
102 $(LIBINDICATOR_CFLAGS) -I$(top_srcdir)
103
104libdummy_indicator_simple_la_LIBADD = \
105 $(LIBINDICATOR_LIBS) \
106 -L$(top_builddir)/libindicator/.libs \
107 -lindicator
108
109libdummy_indicator_simple_la_LDFLAGS = \
110 -module \
111 -avoid-version
112
113#############################
114# Service Shutdown Timeout
115#############################
116
117check_PROGRAMS += service-shutdown-timeout
118
119service_shutdown_timeout_SOURCES = \
120 service-shutdown-timeout.c
121
122service_shutdown_timeout_CFLAGS = \
123 -Wall -Werror \
124 $(LIBINDICATOR_CFLAGS) -I$(top_srcdir)
125
126service_shutdown_timeout_LDADD = \
127 $(LIBINDICATOR_LIBS) \
128 $(top_builddir)/libindicator/.libs/libindicator.a
129
130service-shutdown-timeout-tester: service-shutdown-timeout Makefile
131 @echo "#!/bin/sh" > service-shutdown-timeout-tester
132 @echo $(DBUS_RUNNER) --task ./service-shutdown-timeout >> service-shutdown-timeout-tester
133 @chmod +x service-shutdown-timeout-tester
134
135TESTS += service-shutdown-timeout-tester
136DISTCLEANFILES += service-shutdown-timeout-tester
137
138#############################
139# Service Manager No Connect
140#############################
141
142check_PROGRAMS += service-manager-no-connect
143
144service_manager_no_connect_SOURCES = \
145 service-manager-no-connect.c
146
147service_manager_no_connect_CFLAGS = \
148 -Wall -Werror \
149 $(LIBINDICATOR_CFLAGS) -I$(top_srcdir)
150
151service_manager_no_connect_LDADD = \
152 $(LIBINDICATOR_LIBS) \
153 $(top_builddir)/libindicator/.libs/libindicator.a
154
155service-manager-no-connect-tester: service-manager-no-connect Makefile.am
156 @echo "#!/bin/sh" > service-manager-no-connect-tester
157 @echo $(DBUS_RUNNER) --task ./service-manager-no-connect >> service-manager-no-connect-tester
158 @chmod +x service-manager-no-connect-tester
159
160TESTS += service-manager-no-connect-tester
161DISTCLEANFILES += service-manager-no-connect-tester
162
163#############################
164# Service Manager Connect
165#############################
166
167session.conf: $(srcdir)/session.conf.in Makefile.am
168 sed -e "s|\@servicedir\@|$(abspath $(builddir))|" $< > $@
169
170service-manager-connect.service: $(srcdir)/service-manager-connect.service.in Makefile.am
171 sed -e "s|\@builddir\@|$(abspath $(builddir))|" $< > $@
172
173check_PROGRAMS += service-manager-connect
174
175service_manager_connect_SOURCES = \
176 service-manager-connect.c
177
178service_manager_connect_CFLAGS = \
179 -Wall -Werror \
180 $(LIBINDICATOR_CFLAGS) -I$(top_srcdir)
181
182service_manager_connect_LDADD = \
183 $(LIBINDICATOR_LIBS) \
184 $(top_builddir)/libindicator/.libs/libindicator.a
185
186check_PROGRAMS += service-manager-connect-service
187
188service_manager_connect_service_SOURCES = \
189 service-manager-connect-service.c
190
191service_manager_connect_service_CFLAGS = \
192 -Wall -Werror \
193 $(LIBINDICATOR_CFLAGS) -I$(top_srcdir)
194
195service_manager_connect_service_LDADD = \
196 $(LIBINDICATOR_LIBS) \
197 $(top_builddir)/libindicator/.libs/libindicator.a
198
199service-manager-connect-tester: service-manager-connect service-manager-connect-service session.conf service-manager-connect.service Makefile.am
200 @echo "#!/bin/sh" > service-manager-connect-tester
201 @echo dbus-test-runner --dbus-config $(builddir)/session.conf --task ./service-manager-connect >> service-manager-connect-tester
202 @chmod +x service-manager-connect-tester
203
204TESTS += service-manager-connect-tester
205DISTCLEANFILES += service-manager-connect-tester session.conf service-manager-connect.service
206
207#############################
208# Service Versions
209#############################
210
211service-version-good.service: $(srcdir)/service-version-good.service.in Makefile.am
212 sed -e "s|\@builddir\@|$(abspath $(builddir))|" $< > $@
213
214service-version-bad.service: $(srcdir)/service-version-bad.service.in Makefile.am
215 sed -e "s|\@builddir\@|$(abspath $(builddir))|" $< > $@
216
217check_PROGRAMS += service-version-manager
218
219service_version_manager_SOURCES = \
220 service-version-values.h \
221 service-version-manager.c
222
223service_version_manager_CFLAGS = \
224 -Wall -Werror \
225 $(LIBINDICATOR_CFLAGS) -I$(top_srcdir)
226
227service_version_manager_LDADD = \
228 $(LIBINDICATOR_LIBS) \
229 $(top_builddir)/libindicator/.libs/libindicator.a
230
231check_PROGRAMS += service-version-bad-service
232
233service_version_bad_service_SOURCES = \
234 service-version-values.h \
235 service-version-bad-service.c
236
237service_version_bad_service_CFLAGS = \
238 -Wall -Werror \
239 $(LIBINDICATOR_CFLAGS) -I$(top_srcdir)
240
241service_version_bad_service_LDADD = \
242 $(LIBINDICATOR_LIBS) \
243 $(top_builddir)/libindicator/.libs/libindicator.a
244
245check_PROGRAMS += service-version-good-service
246
247service_version_good_service_SOURCES = \
248 service-version-values.h \
249 service-version-good-service.c
250
251service_version_good_service_CFLAGS = \
252 -Wall -Werror \
253 $(LIBINDICATOR_CFLAGS) -I$(top_srcdir)
254
255service_version_good_service_LDADD = \
256 $(LIBINDICATOR_LIBS) \
257 $(top_builddir)/libindicator/.libs/libindicator.a
258
259service-version-tester: service-version-manager service-version-bad-service service-version-good-service session.conf service-version-bad.service service-version-good.service Makefile.am
260 @echo "#!/bin/sh" > $@
261 @echo dbus-test-runner --dbus-config $(builddir)/session.conf --task ./service-version-manager >> $@
262 @chmod +x $@
263
264TESTS += service-version-tester
265DISTCLEANFILES += service-version-tester service-version-bad.service service-version-good.service
266
267#############################
268# Service Manager Shutdown
269#############################
270
271check_PROGRAMS += service-manager-nostart-connect
272
273service_manager_nostart_connect_SOURCES = \
274 service-manager-nostart-connect.c
275
276service_manager_nostart_connect_CFLAGS = \
277 -Wall -Werror \
278 $(LIBINDICATOR_CFLAGS) -I$(top_srcdir)
279
280service_manager_nostart_connect_LDADD = \
281 $(LIBINDICATOR_LIBS) \
282 $(top_builddir)/libindicator/.libs/libindicator.a
283
284service-manager-connect-nostart-tester: service-manager-nostart-connect service-manager-connect-service Makefile.am
285 @echo "#!/bin/sh" > $@
286 @echo dbus-test-runner --task ./service-manager-nostart-connect --task ./service-manager-connect-service >> $@
287 @chmod +x $@
288
289TESTS += service-manager-connect-nostart-tester
290DISTCLEANFILES += service-manager-connect-nostart-tester
291
292#############################
293# Test stuff
294#############################
295
296XML_REPORT = loader-check-results.xml
297HTML_REPORT = loader-check-results.html
298
299loader-tester: test-loader libdummy-indicator-null.la libdummy-indicator-simple.la Makefile
300 @echo "#!/bin/sh" > loader-tester
301 @echo gtester -k --verbose -o=$(XML_REPORT) ./test-loader >> loader-tester
302 @chmod +x loader-tester
303
304TESTS += loader-tester
305DISTCLEANFILES += loader-tester
306
307DISTCLEANFILES += $(XML_REPORT) $(HTML_REPORT)
308
0309
=== added file 'tests/dummy-indicator-blank.c'
--- tests/dummy-indicator-blank.c 1970-01-01 00:00:00 +0000
+++ tests/dummy-indicator-blank.c 2009-12-10 17:02:12 +0000
@@ -0,0 +1,5 @@
1
2#include "libindicator/indicator.h"
3
4INDICATOR_SET_VERSION
5
06
=== added file 'tests/dummy-indicator-null.c'
--- tests/dummy-indicator-null.c 1970-01-01 00:00:00 +0000
+++ tests/dummy-indicator-null.c 2009-12-10 17:02:12 +0000
@@ -0,0 +1,95 @@
1
2#include <glib.h>
3#include <glib-object.h>
4
5#include "libindicator/indicator.h"
6#include "libindicator/indicator-object.h"
7
8#define DUMMY_INDICATOR_NULL_TYPE (dummy_indicator_null_get_type ())
9#define DUMMY_INDICATOR_NULL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), DUMMY_INDICATOR_NULL_TYPE, DummyIndicatorNull))
10#define DUMMY_INDICATOR_NULL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), DUMMY_INDICATOR_NULL_TYPE, DummyIndicatorNullClass))
11#define IS_DUMMY_INDICATOR_NULL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), DUMMY_INDICATOR_NULL_TYPE))
12#define IS_DUMMY_INDICATOR_NULL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), DUMMY_INDICATOR_NULL_TYPE))
13#define DUMMY_INDICATOR_NULL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), DUMMY_INDICATOR_NULL_TYPE, DummyIndicatorNullClass))
14
15typedef struct _DummyIndicatorNull DummyIndicatorNull;
16typedef struct _DummyIndicatorNullClass DummyIndicatorNullClass;
17
18struct _DummyIndicatorNullClass {
19 IndicatorObjectClass parent_class;
20};
21
22struct _DummyIndicatorNull {
23 IndicatorObject parent;
24};
25
26GType dummy_indicator_null_get_type (void);
27
28INDICATOR_SET_VERSION
29INDICATOR_SET_TYPE(DUMMY_INDICATOR_NULL_TYPE)
30
31
32GtkLabel *
33get_label (IndicatorObject * io)
34{
35 return NULL;
36}
37
38GtkImage *
39get_icon (IndicatorObject * io)
40{
41 return NULL;
42}
43
44GtkMenu *
45get_menu (IndicatorObject * io)
46{
47 return NULL;
48}
49
50static void dummy_indicator_null_class_init (DummyIndicatorNullClass *klass);
51static void dummy_indicator_null_init (DummyIndicatorNull *self);
52static void dummy_indicator_null_dispose (GObject *object);
53static void dummy_indicator_null_finalize (GObject *object);
54
55G_DEFINE_TYPE (DummyIndicatorNull, dummy_indicator_null, INDICATOR_OBJECT_TYPE);
56
57static void
58dummy_indicator_null_class_init (DummyIndicatorNullClass *klass)
59{
60 GObjectClass *object_class = G_OBJECT_CLASS (klass);
61
62 object_class->dispose = dummy_indicator_null_dispose;
63 object_class->finalize = dummy_indicator_null_finalize;
64
65 IndicatorObjectClass * io_class = INDICATOR_OBJECT_CLASS(klass);
66
67 io_class->get_label = get_label;
68 io_class->get_image = get_icon;
69 io_class->get_menu = get_menu;
70
71 return;
72}
73
74static void
75dummy_indicator_null_init (DummyIndicatorNull *self)
76{
77
78 return;
79}
80
81static void
82dummy_indicator_null_dispose (GObject *object)
83{
84
85 G_OBJECT_CLASS (dummy_indicator_null_parent_class)->dispose (object);
86 return;
87}
88
89static void
90dummy_indicator_null_finalize (GObject *object)
91{
92
93 G_OBJECT_CLASS (dummy_indicator_null_parent_class)->finalize (object);
94 return;
95}
096
=== added file 'tests/dummy-indicator-signaler.c'
--- tests/dummy-indicator-signaler.c 1970-01-01 00:00:00 +0000
+++ tests/dummy-indicator-signaler.c 2009-12-10 17:02:12 +0000
@@ -0,0 +1,109 @@
1#include <glib.h>
2#include <glib-object.h>
3
4#include "libindicator/indicator.h"
5#include "libindicator/indicator-object.h"
6
7#define DUMMY_INDICATOR_SIGNALER_TYPE (dummy_indicator_signaler_get_type ())
8#define DUMMY_INDICATOR_SIGNALER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), DUMMY_INDICATOR_SIGNALER_TYPE, DummyIndicatorSignaler))
9#define DUMMY_INDICATOR_SIGNALER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), DUMMY_INDICATOR_SIGNALER_TYPE, DummyIndicatorSignalerClass))
10#define IS_DUMMY_INDICATOR_SIGNALER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), DUMMY_INDICATOR_SIGNALER_TYPE))
11#define IS_DUMMY_INDICATOR_SIGNALER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), DUMMY_INDICATOR_SIGNALER_TYPE))
12#define DUMMY_INDICATOR_SIGNALER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), DUMMY_INDICATOR_SIGNALER_TYPE, DummyIndicatorSignalerClass))
13
14typedef struct _DummyIndicatorSignaler DummyIndicatorSignaler;
15typedef struct _DummyIndicatorSignalerClass DummyIndicatorSignalerClass;
16
17struct _DummyIndicatorSignalerClass {
18 IndicatorObjectClass parent_class;
19};
20
21struct _DummyIndicatorSignaler {
22 IndicatorObject parent;
23};
24
25GType dummy_indicator_signaler_get_type (void);
26
27INDICATOR_SET_VERSION
28INDICATOR_SET_TYPE(DUMMY_INDICATOR_SIGNALER_TYPE)
29
30GtkLabel *
31get_label (IndicatorObject * io)
32{
33 return GTK_LABEL(gtk_label_new("Signaler Item"));
34}
35
36GtkImage *
37get_icon (IndicatorObject * io)
38{
39 return GTK_IMAGE(gtk_image_new());
40}
41
42GtkMenu *
43get_menu (IndicatorObject * io)
44{
45 GtkMenu * main_menu = GTK_MENU(gtk_menu_new());
46 GtkWidget * loading_item = gtk_menu_item_new_with_label("Loading...");
47 gtk_menu_shell_append(GTK_MENU_SHELL(main_menu), loading_item);
48 gtk_widget_show(GTK_WIDGET(loading_item));
49
50 return main_menu;
51}
52
53static void dummy_indicator_signaler_class_init (DummyIndicatorSignalerClass *klass);
54static void dummy_indicator_signaler_init (DummyIndicatorSignaler *self);
55static void dummy_indicator_signaler_dispose (GObject *object);
56static void dummy_indicator_signaler_finalize (GObject *object);
57
58G_DEFINE_TYPE (DummyIndicatorSignaler, dummy_indicator_signaler, INDICATOR_OBJECT_TYPE);
59
60static void
61dummy_indicator_signaler_class_init (DummyIndicatorSignalerClass *klass)
62{
63 GObjectClass *object_class = G_OBJECT_CLASS (klass);
64
65 object_class->dispose = dummy_indicator_signaler_dispose;
66 object_class->finalize = dummy_indicator_signaler_finalize;
67
68 IndicatorObjectClass * io_class = INDICATOR_OBJECT_CLASS(klass);
69
70 io_class->get_label = get_label;
71 io_class->get_image = get_icon;
72 io_class->get_menu = get_menu;
73
74 return;
75}
76
77static gboolean
78idle_signal (gpointer data)
79{
80 DummyIndicatorSignaler * self = DUMMY_INDICATOR_SIGNALER(data);
81
82 g_signal_emit(G_OBJECT(self), INDICATOR_OBJECT_SIGNAL_ENTRY_ADDED_ID, 0, GUINT_TO_POINTER(5), TRUE);
83 g_signal_emit(G_OBJECT(self), INDICATOR_OBJECT_SIGNAL_ENTRY_REMOVED_ID, 0, GUINT_TO_POINTER(5), TRUE);
84
85 return FALSE; /* Don't queue again */
86}
87
88static void
89dummy_indicator_signaler_init (DummyIndicatorSignaler *self)
90{
91 g_idle_add(idle_signal, self);
92 return;
93}
94
95static void
96dummy_indicator_signaler_dispose (GObject *object)
97{
98
99 G_OBJECT_CLASS (dummy_indicator_signaler_parent_class)->dispose (object);
100 return;
101}
102
103static void
104dummy_indicator_signaler_finalize (GObject *object)
105{
106
107 G_OBJECT_CLASS (dummy_indicator_signaler_parent_class)->finalize (object);
108 return;
109}
0110
=== added file 'tests/dummy-indicator-simple.c'
--- tests/dummy-indicator-simple.c 1970-01-01 00:00:00 +0000
+++ tests/dummy-indicator-simple.c 2009-12-10 17:02:12 +0000
@@ -0,0 +1,98 @@
1#include <glib.h>
2#include <glib-object.h>
3
4#include "libindicator/indicator.h"
5#include "libindicator/indicator-object.h"
6
7#define DUMMY_INDICATOR_SIMPLE_TYPE (dummy_indicator_simple_get_type ())
8#define DUMMY_INDICATOR_SIMPLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), DUMMY_INDICATOR_SIMPLE_TYPE, DummyIndicatorSimple))
9#define DUMMY_INDICATOR_SIMPLE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), DUMMY_INDICATOR_SIMPLE_TYPE, DummyIndicatorSimpleClass))
10#define IS_DUMMY_INDICATOR_SIMPLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), DUMMY_INDICATOR_SIMPLE_TYPE))
11#define IS_DUMMY_INDICATOR_SIMPLE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), DUMMY_INDICATOR_SIMPLE_TYPE))
12#define DUMMY_INDICATOR_SIMPLE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), DUMMY_INDICATOR_SIMPLE_TYPE, DummyIndicatorSimpleClass))
13
14typedef struct _DummyIndicatorSimple DummyIndicatorSimple;
15typedef struct _DummyIndicatorSimpleClass DummyIndicatorSimpleClass;
16
17struct _DummyIndicatorSimpleClass {
18 IndicatorObjectClass parent_class;
19};
20
21struct _DummyIndicatorSimple {
22 IndicatorObject parent;
23};
24
25GType dummy_indicator_simple_get_type (void);
26
27INDICATOR_SET_VERSION
28INDICATOR_SET_TYPE(DUMMY_INDICATOR_SIMPLE_TYPE)
29
30GtkLabel *
31get_label (IndicatorObject * io)
32{
33 return GTK_LABEL(gtk_label_new("Simple Item"));
34}
35
36GtkImage *
37get_icon (IndicatorObject * io)
38{
39 return GTK_IMAGE(gtk_image_new());
40}
41
42GtkMenu *
43get_menu (IndicatorObject * io)
44{
45 GtkMenu * main_menu = GTK_MENU(gtk_menu_new());
46 GtkWidget * loading_item = gtk_menu_item_new_with_label("Loading...");
47 gtk_menu_shell_append(GTK_MENU_SHELL(main_menu), loading_item);
48 gtk_widget_show(GTK_WIDGET(loading_item));
49
50 return main_menu;
51}
52
53static void dummy_indicator_simple_class_init (DummyIndicatorSimpleClass *klass);
54static void dummy_indicator_simple_init (DummyIndicatorSimple *self);
55static void dummy_indicator_simple_dispose (GObject *object);
56static void dummy_indicator_simple_finalize (GObject *object);
57
58G_DEFINE_TYPE (DummyIndicatorSimple, dummy_indicator_simple, INDICATOR_OBJECT_TYPE);
59
60static void
61dummy_indicator_simple_class_init (DummyIndicatorSimpleClass *klass)
62{
63 GObjectClass *object_class = G_OBJECT_CLASS (klass);
64
65 object_class->dispose = dummy_indicator_simple_dispose;
66 object_class->finalize = dummy_indicator_simple_finalize;
67
68 IndicatorObjectClass * io_class = INDICATOR_OBJECT_CLASS(klass);
69
70 io_class->get_label = get_label;
71 io_class->get_image = get_icon;
72 io_class->get_menu = get_menu;
73
74 return;
75}
76
77static void
78dummy_indicator_simple_init (DummyIndicatorSimple *self)
79{
80
81 return;
82}
83
84static void
85dummy_indicator_simple_dispose (GObject *object)
86{
87
88 G_OBJECT_CLASS (dummy_indicator_simple_parent_class)->dispose (object);
89 return;
90}
91
92static void
93dummy_indicator_simple_finalize (GObject *object)
94{
95
96 G_OBJECT_CLASS (dummy_indicator_simple_parent_class)->finalize (object);
97 return;
98}
099
=== added file 'tests/service-manager-connect-service.c'
--- tests/service-manager-connect-service.c 1970-01-01 00:00:00 +0000
+++ tests/service-manager-connect-service.c 2009-12-10 17:02:12 +0000
@@ -0,0 +1,48 @@
1
2#include <glib.h>
3#include "libindicator/indicator-service.h"
4
5static GMainLoop * mainloop = NULL;
6static gboolean passed = FALSE;
7
8gboolean
9timeout (gpointer data)
10{
11 passed = FALSE;
12 g_debug("Timeout with no shutdown.");
13 g_main_loop_quit(mainloop);
14 return FALSE;
15}
16
17void
18shutdown (void)
19{
20 g_debug("Shutdown");
21 passed = TRUE;
22 g_main_loop_quit(mainloop);
23 return;
24}
25
26int
27main (int argc, char ** argv)
28{
29 g_type_init();
30
31 g_debug("Starting service");
32
33 IndicatorService * is = indicator_service_new("org.ayatana.test");
34 g_signal_connect(G_OBJECT(is), INDICATOR_SERVICE_SIGNAL_SHUTDOWN, shutdown, NULL);
35
36 g_timeout_add_seconds(1, timeout, NULL);
37
38 mainloop = g_main_loop_new(NULL, FALSE);
39 g_main_loop_run(mainloop);
40
41 g_debug("Quiting");
42 if (passed) {
43 g_debug("Passed");
44 return 0;
45 }
46 g_debug("Failed");
47 return 1;
48}
049
=== added file 'tests/service-manager-connect.c'
--- tests/service-manager-connect.c 1970-01-01 00:00:00 +0000
+++ tests/service-manager-connect.c 2009-12-10 17:02:12 +0000
@@ -0,0 +1,63 @@
1
2#include <glib.h>
3#include "libindicator/indicator-service-manager.h"
4
5static GMainLoop * mainloop = NULL;
6static gboolean passed = FALSE;
7
8gboolean
9timeout (gpointer data)
10{
11 passed = FALSE;
12 g_error("Timeout with no connection.");
13 g_main_loop_quit(mainloop);
14 return FALSE;
15}
16
17void
18connection (IndicatorServiceManager * sm, gboolean connected, gpointer user_data)
19{
20 static gboolean has_connected = FALSE;
21
22 if (has_connected && connected) {
23 g_warning("We got two connected signals. FAIL.");
24 passed = FALSE;
25 return;
26 }
27
28 if (!connected) {
29 g_debug("Not connected");
30 return;
31 }
32
33 has_connected = TRUE;
34 g_debug("Connection");
35 passed = TRUE;
36 g_main_loop_quit(mainloop);
37 return;
38}
39
40int
41main (int argc, char ** argv)
42{
43 g_type_init();
44 g_log_set_always_fatal(G_LOG_LEVEL_CRITICAL);
45
46 IndicatorServiceManager * is = indicator_service_manager_new("org.ayatana.test");
47 g_signal_connect(G_OBJECT(is), INDICATOR_SERVICE_MANAGER_SIGNAL_CONNECTION_CHANGE, G_CALLBACK(connection), NULL);
48
49 g_timeout_add_seconds(1, timeout, NULL);
50
51 mainloop = g_main_loop_new(NULL, FALSE);
52 g_main_loop_run(mainloop);
53
54 g_object_unref(is);
55
56 g_debug("Quiting");
57 if (passed) {
58 g_debug("Passed");
59 return 0;
60 }
61 g_debug("Failed");
62 return 1;
63}
064
=== added file 'tests/service-manager-connect.service.in'
--- tests/service-manager-connect.service.in 1970-01-01 00:00:00 +0000
+++ tests/service-manager-connect.service.in 2009-12-10 17:02:12 +0000
@@ -0,0 +1,3 @@
1[D-BUS Service]
2Name=org.ayatana.test
3Exec=@builddir@/service-manager-connect-service
04
=== added file 'tests/service-manager-no-connect.c'
--- tests/service-manager-no-connect.c 1970-01-01 00:00:00 +0000
+++ tests/service-manager-no-connect.c 2009-12-10 17:02:12 +0000
@@ -0,0 +1,47 @@
1
2#include <glib.h>
3#include "libindicator/indicator-service-manager.h"
4
5static GMainLoop * mainloop = NULL;
6static gboolean passed = FALSE;
7
8gboolean
9timeout (gpointer data)
10{
11 passed = TRUE;
12 g_debug("Timeout with no connection.");
13 g_main_loop_quit(mainloop);
14 return FALSE;
15}
16
17void
18connection (void)
19{
20 g_debug("Connection");
21 passed = FALSE;
22 g_main_loop_quit(mainloop);
23 return;
24}
25
26int
27main (int argc, char ** argv)
28{
29 g_type_init();
30 g_log_set_always_fatal(G_LOG_LEVEL_CRITICAL);
31
32 IndicatorServiceManager * is = indicator_service_manager_new("my.test.name");
33 g_signal_connect(G_OBJECT(is), INDICATOR_SERVICE_MANAGER_SIGNAL_CONNECTION_CHANGE, connection, NULL);
34
35 g_timeout_add_seconds(1, timeout, NULL);
36
37 mainloop = g_main_loop_new(NULL, FALSE);
38 g_main_loop_run(mainloop);
39
40 g_debug("Quiting");
41 if (passed) {
42 g_debug("Passed");
43 return 0;
44 }
45 g_debug("Failed");
46 return 1;
47}
048
=== added file 'tests/service-manager-nostart-connect.c'
--- tests/service-manager-nostart-connect.c 1970-01-01 00:00:00 +0000
+++ tests/service-manager-nostart-connect.c 2009-12-10 17:02:12 +0000
@@ -0,0 +1,65 @@
1
2#include <glib.h>
3#include "libindicator/indicator-service-manager.h"
4
5static GMainLoop * mainloop = NULL;
6static gboolean passed = FALSE;
7
8gboolean
9timeout (gpointer data)
10{
11 passed = FALSE;
12 g_error("Timeout with no connection.");
13 g_main_loop_quit(mainloop);
14 return FALSE;
15}
16
17void
18connection (IndicatorServiceManager * sm, gboolean connected, gpointer user_data)
19{
20 static gboolean has_connected = FALSE;
21
22 if (has_connected && connected) {
23 g_warning("We got two connected signals. FAIL.");
24 passed = FALSE;
25 return;
26 }
27
28 if (!connected) {
29 g_debug("Not connected");
30 return;
31 }
32
33 has_connected = TRUE;
34 g_debug("Connection");
35 passed = TRUE;
36 g_main_loop_quit(mainloop);
37 return;
38}
39
40int
41main (int argc, char ** argv)
42{
43 g_type_init();
44 g_log_set_always_fatal(G_LOG_LEVEL_CRITICAL);
45
46 g_usleep(150000);
47
48 IndicatorServiceManager * is = indicator_service_manager_new("org.ayatana.test");
49 g_signal_connect(G_OBJECT(is), INDICATOR_SERVICE_MANAGER_SIGNAL_CONNECTION_CHANGE, G_CALLBACK(connection), NULL);
50
51 g_timeout_add_seconds(1, timeout, NULL);
52
53 mainloop = g_main_loop_new(NULL, FALSE);
54 g_main_loop_run(mainloop);
55
56 g_object_unref(is);
57
58 g_debug("Quiting");
59 if (passed) {
60 g_debug("Passed");
61 return 0;
62 }
63 g_debug("Failed");
64 return 1;
65}
066
=== added file 'tests/service-shutdown-timeout.c'
--- tests/service-shutdown-timeout.c 1970-01-01 00:00:00 +0000
+++ tests/service-shutdown-timeout.c 2009-12-10 17:02:12 +0000
@@ -0,0 +1,46 @@
1
2#include <glib.h>
3#include "libindicator/indicator-service.h"
4
5static GMainLoop * mainloop = NULL;
6static gboolean passed = FALSE;
7
8gboolean
9timeout (gpointer data)
10{
11 passed = FALSE;
12 g_error("Timeout with no shutdown.");
13 g_main_loop_quit(mainloop);
14 return FALSE;
15}
16
17void
18shutdown (void)
19{
20 g_debug("Shutdown");
21 passed = TRUE;
22 g_main_loop_quit(mainloop);
23 return;
24}
25
26int
27main (int argc, char ** argv)
28{
29 g_type_init();
30
31 IndicatorService * is = indicator_service_new("my.test.name");
32 g_signal_connect(G_OBJECT(is), INDICATOR_SERVICE_SIGNAL_SHUTDOWN, shutdown, NULL);
33
34 g_timeout_add_seconds(1, timeout, NULL);
35
36 mainloop = g_main_loop_new(NULL, FALSE);
37 g_main_loop_run(mainloop);
38
39 g_debug("Quiting");
40 if (passed) {
41 g_debug("Passed");
42 return 0;
43 }
44 g_debug("Failed");
45 return 1;
46}
047
=== added file 'tests/service-version-bad-service.c'
--- tests/service-version-bad-service.c 1970-01-01 00:00:00 +0000
+++ tests/service-version-bad-service.c 2009-12-10 17:02:12 +0000
@@ -0,0 +1,47 @@
1
2#include <glib.h>
3#include "libindicator/indicator-service.h"
4#include "service-version-values.h"
5
6static GMainLoop * mainloop = NULL;
7static gboolean passed = FALSE;
8
9gboolean
10timeout (gpointer data)
11{
12 passed = FALSE;
13 g_debug("Timeout with no shutdown.");
14 g_main_loop_quit(mainloop);
15 return FALSE;
16}
17
18void
19shutdown (void)
20{
21 g_debug("Shutdown");
22 passed = TRUE;
23 g_main_loop_quit(mainloop);
24 return;
25}
26
27int
28main (int argc, char ** argv)
29{
30 g_type_init();
31
32 IndicatorService * is = indicator_service_new_version("org.ayatana.version.bad", SERVICE_VERSION_BAD);
33 g_signal_connect(G_OBJECT(is), INDICATOR_SERVICE_SIGNAL_SHUTDOWN, shutdown, NULL);
34
35 g_timeout_add_seconds(1, timeout, NULL);
36
37 mainloop = g_main_loop_new(NULL, FALSE);
38 g_main_loop_run(mainloop);
39
40 g_debug("Quiting");
41 if (passed) {
42 g_debug("Passed");
43 return 0;
44 }
45 g_debug("Failed");
46 return 1;
47}
048
=== added file 'tests/service-version-bad.service.in'
--- tests/service-version-bad.service.in 1970-01-01 00:00:00 +0000
+++ tests/service-version-bad.service.in 2009-12-10 17:02:12 +0000
@@ -0,0 +1,3 @@
1[D-BUS Service]
2Name=org.ayatana.version.bad
3Exec=@builddir@/service-version-bad-service
04
=== added file 'tests/service-version-good-service.c'
--- tests/service-version-good-service.c 1970-01-01 00:00:00 +0000
+++ tests/service-version-good-service.c 2009-12-10 17:02:12 +0000
@@ -0,0 +1,47 @@
1
2#include <glib.h>
3#include "libindicator/indicator-service.h"
4#include "service-version-values.h"
5
6static GMainLoop * mainloop = NULL;
7static gboolean passed = FALSE;
8
9gboolean
10timeout (gpointer data)
11{
12 passed = FALSE;
13 g_debug("Timeout with no shutdown.");
14 g_main_loop_quit(mainloop);
15 return FALSE;
16}
17
18void
19shutdown (void)
20{
21 g_debug("Shutdown");
22 passed = TRUE;
23 g_main_loop_quit(mainloop);
24 return;
25}
26
27int
28main (int argc, char ** argv)
29{
30 g_type_init();
31
32 IndicatorService * is = indicator_service_new_version("org.ayatana.version.good", SERVICE_VERSION_GOOD);
33 g_signal_connect(G_OBJECT(is), INDICATOR_SERVICE_SIGNAL_SHUTDOWN, shutdown, NULL);
34
35 g_timeout_add_seconds(1, timeout, NULL);
36
37 mainloop = g_main_loop_new(NULL, FALSE);
38 g_main_loop_run(mainloop);
39
40 g_debug("Quiting");
41 if (passed) {
42 g_debug("Passed");
43 return 0;
44 }
45 g_debug("Failed");
46 return 1;
47}
048
=== added file 'tests/service-version-good.service.in'
--- tests/service-version-good.service.in 1970-01-01 00:00:00 +0000
+++ tests/service-version-good.service.in 2009-12-10 17:02:12 +0000
@@ -0,0 +1,3 @@
1[D-BUS Service]
2Name=org.ayatana.version.good
3Exec=@builddir@/service-version-good-service
04
=== added file 'tests/service-version-manager.c'
--- tests/service-version-manager.c 1970-01-01 00:00:00 +0000
+++ tests/service-version-manager.c 2009-12-10 17:02:12 +0000
@@ -0,0 +1,64 @@
1
2#include <glib.h>
3#include "libindicator/indicator-service-manager.h"
4#include "service-version-values.h"
5
6static GMainLoop * mainloop = NULL;
7static gboolean con_good = FALSE;
8static gboolean con_bad = FALSE;
9
10gboolean
11timeout (gpointer data)
12{
13 g_debug("Timeout.");
14 g_main_loop_quit(mainloop);
15 return FALSE;
16}
17
18void
19connection_bad (IndicatorServiceManager * sm, gboolean connected, gpointer user_data)
20{
21 if (!connected) return;
22 g_debug("Connection From Bad!");
23 con_bad = TRUE;
24 return;
25}
26
27void
28connection_good (IndicatorServiceManager * sm, gboolean connected, gpointer user_data)
29{
30 if (!connected) return;
31 g_debug("Connection From Good.");
32 con_good = TRUE;
33 return;
34}
35
36int
37main (int argc, char ** argv)
38{
39 g_type_init();
40 g_log_set_always_fatal(G_LOG_LEVEL_CRITICAL);
41 g_print("Manager: DBUS_SESSION_BUS_ADDRESS = %s\n", g_getenv("DBUS_SESSION_BUS_ADDRESS"));
42
43 IndicatorServiceManager * goodis = indicator_service_manager_new_version("org.ayatana.version.good", SERVICE_VERSION_GOOD);
44 g_signal_connect(G_OBJECT(goodis), INDICATOR_SERVICE_MANAGER_SIGNAL_CONNECTION_CHANGE, G_CALLBACK(connection_good), NULL);
45
46 IndicatorServiceManager * badis = indicator_service_manager_new_version("org.ayatana.version.bad", SERVICE_VERSION_GOOD);
47 g_signal_connect(G_OBJECT(badis), INDICATOR_SERVICE_MANAGER_SIGNAL_CONNECTION_CHANGE, G_CALLBACK(connection_bad), NULL);
48
49 g_timeout_add_seconds(1, timeout, NULL);
50
51 mainloop = g_main_loop_new(NULL, FALSE);
52 g_main_loop_run(mainloop);
53
54 g_object_unref(goodis);
55 g_object_unref(badis);
56
57 g_debug("Quiting");
58 if (con_good && !con_bad) {
59 g_debug("Passed");
60 return 0;
61 }
62 g_debug("Failed");
63 return 1;
64}
065
=== added file 'tests/service-version-values.h'
--- tests/service-version-values.h 1970-01-01 00:00:00 +0000
+++ tests/service-version-values.h 2009-12-10 17:02:12 +0000
@@ -0,0 +1,4 @@
1
2#define SERVICE_VERSION_GOOD 1342
3#define SERVICE_VERSION_BAD 543
4
05
=== added file 'tests/session.conf.in'
--- tests/session.conf.in 1970-01-01 00:00:00 +0000
+++ tests/session.conf.in 2009-12-10 17:02:12 +0000
@@ -0,0 +1,40 @@
1<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-Bus Bus Configuration 1.0//EN"
2 "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
3<busconfig>
4 <!-- If we fork, keep the user's original umask to avoid affecting
5 the behavior of child processes. -->
6 <keep_umask/>
7
8 <listen>unix:tmpdir=/tmp</listen>
9
10 <servicedir>@servicedir@</servicedir>
11
12 <policy context="default">
13 <!-- Allow everything to be sent -->
14 <allow send_destination="*" eavesdrop="true"/>
15 <!-- Allow everything to be received -->
16 <allow eavesdrop="true"/>
17 <!-- Allow anyone to own anything -->
18 <allow own="*"/>
19 </policy>
20
21 <!-- raise the service start timeout to 40 seconds as it can timeout
22 on the live cd on slow machines -->
23 <limit name="service_start_timeout">60000</limit>
24
25 <!-- the memory limits are 1G instead of say 4G because they can't exceed 32-bit signed int max -->
26 <limit name="max_incoming_bytes">1000000000</limit>
27 <limit name="max_outgoing_bytes">1000000000</limit>
28 <limit name="max_message_size">1000000000</limit>
29 <limit name="service_start_timeout">120000</limit>
30 <limit name="auth_timeout">240000</limit>
31 <limit name="max_completed_connections">100000</limit>
32 <limit name="max_incomplete_connections">10000</limit>
33 <limit name="max_connections_per_user">100000</limit>
34 <limit name="max_pending_service_starts">10000</limit>
35 <limit name="max_names_per_connection">50000</limit>
36 <limit name="max_match_rules_per_connection">50000</limit>
37 <limit name="max_replies_per_connection">50000</limit>
38 <limit name="reply_timeout">300000</limit>
39
40</busconfig>
041
=== added file 'tests/test-loader.c'
--- tests/test-loader.c 1970-01-01 00:00:00 +0000
+++ tests/test-loader.c 2009-12-10 17:02:12 +0000
@@ -0,0 +1,146 @@
1#include <gtk/gtk.h>
2#include "libindicator/indicator-object.h"
3
4void destroy_cb (gpointer data, GObject * object);
5
6void
7entry_change_cb (IndicatorObject * io, IndicatorObjectEntry * entry, gpointer data)
8{
9 gpointer * valuestore = (gpointer *)data;
10 *valuestore = entry;
11 return;
12}
13
14void
15test_loader_filename_dummy_signaler (void)
16{
17 IndicatorObject * object = indicator_object_new_from_file(BUILD_DIR "/.libs/libdummy-indicator-signaler.so");
18 g_assert(object != NULL);
19
20 gpointer added_value = NULL, removed_value = NULL;
21
22 g_signal_connect(G_OBJECT(object), INDICATOR_OBJECT_SIGNAL_ENTRY_ADDED, G_CALLBACK(entry_change_cb), &added_value);
23 g_signal_connect(G_OBJECT(object), INDICATOR_OBJECT_SIGNAL_ENTRY_REMOVED, G_CALLBACK(entry_change_cb), &removed_value);
24
25 GList * list = indicator_object_get_entries(object);
26 g_assert(list != NULL);
27 g_list_free(list);
28
29 while (g_main_context_pending(NULL)) {
30 g_main_context_iteration(NULL, TRUE);
31 }
32
33 g_assert(GPOINTER_TO_UINT(added_value) == 5);
34 g_assert(GPOINTER_TO_UINT(removed_value) == 5);
35
36 g_object_unref(object);
37
38 return;
39}
40
41
42void
43test_loader_filename_dummy_simple_accessors (void)
44{
45 IndicatorObject * object = indicator_object_new_from_file(BUILD_DIR "/.libs/libdummy-indicator-simple.so");
46 g_assert(object != NULL);
47
48 g_assert(indicator_object_get_entries(object) != NULL);
49
50 g_object_unref(object);
51
52 return;
53}
54
55void
56test_loader_filename_dummy_simple (void)
57{
58 IndicatorObject * object = indicator_object_new_from_file(BUILD_DIR "/.libs/libdummy-indicator-simple.so");
59 g_assert(object != NULL);
60
61 gboolean unreffed = FALSE;
62 g_object_weak_ref(G_OBJECT(object), destroy_cb, &unreffed);
63
64 g_object_unref(object);
65 g_assert(unreffed == TRUE);
66
67 return;
68}
69
70void
71test_loader_filename_dummy_blank (void)
72{
73 IndicatorObject * object = indicator_object_new_from_file(BUILD_DIR "/.libs/libdummy-indicator-blank.so");
74 g_assert(object == NULL);
75 return;
76}
77
78void
79test_loader_filename_dummy_null (void)
80{
81 IndicatorObject * object = indicator_object_new_from_file(BUILD_DIR "/.libs/libdummy-indicator-null.so");
82 g_assert(object != NULL);
83 g_assert(indicator_object_get_entries(object) == NULL);
84 g_object_unref(G_OBJECT(object));
85 return;
86}
87
88void
89test_loader_filename_bad (void)
90{
91 IndicatorObject * object = indicator_object_new_from_file("/this/file/should/not/exist.so");
92 g_assert(object == NULL);
93 return;
94}
95
96void
97destroy_cb (gpointer data, GObject * object)
98{
99 gboolean * bob = (gboolean *)data;
100 *bob = TRUE;
101 return;
102}
103
104void
105test_loader_refunref (void)
106{
107 GObject * object = g_object_new(INDICATOR_OBJECT_TYPE, NULL);
108
109 gboolean unreffed = FALSE;
110 g_object_weak_ref(object, destroy_cb, &unreffed);
111
112 g_object_unref(object);
113
114 g_assert(unreffed == TRUE);
115
116 return;
117}
118
119void
120test_loader_creation_deletion_suite (void)
121{
122 g_test_add_func ("/libindicator/loader/ref_and_unref", test_loader_refunref);
123 g_test_add_func ("/libindicator/loader/filename_bad", test_loader_filename_bad);
124 g_test_add_func ("/libindicator/loader/dummy/null_load", test_loader_filename_dummy_null);
125 g_test_add_func ("/libindicator/loader/dummy/blank_load", test_loader_filename_dummy_null);
126 g_test_add_func ("/libindicator/loader/dummy/simple_load", test_loader_filename_dummy_simple);
127 g_test_add_func ("/libindicator/loader/dummy/simple_accessors", test_loader_filename_dummy_simple_accessors);
128 g_test_add_func ("/libindicator/loader/dummy/signaler", test_loader_filename_dummy_signaler);
129
130 return;
131}
132
133
134int
135main (int argc, char ** argv)
136{
137 g_type_init ();
138 g_test_init (&argc, &argv, NULL);
139 gtk_init(&argc, &argv);
140
141 test_loader_creation_deletion_suite();
142
143 g_log_set_always_fatal(G_LOG_LEVEL_CRITICAL);
144
145 return g_test_run();
146}
0147
=== added directory 'tools'
=== added file 'tools/Makefile.am'
--- tools/Makefile.am 1970-01-01 00:00:00 +0000
+++ tools/Makefile.am 2009-12-10 17:02:12 +0000
@@ -0,0 +1,21 @@
1
2libexec_PROGRAMS = \
3 indicator-loader
4
5#############################
6# Indicator Loader
7#############################
8
9indicator_loader_SOURCES = \
10 indicator-loader.c
11
12indicator_loader_CFLAGS = \
13 -Wall -Werror \
14 $(LIBINDICATOR_CFLAGS) -I$(top_srcdir) \
15 -DBUILD_DIR="\"$(builddir)\""
16
17indicator_loader_LDADD = \
18 $(LIBINDICATOR_LIBS) \
19 -L$(top_builddir)/libindicator/.libs \
20 -lindicator
21
022
=== added file 'tools/indicator-loader.c'
--- tools/indicator-loader.c 1970-01-01 00:00:00 +0000
+++ tools/indicator-loader.c 2009-12-10 17:02:12 +0000
@@ -0,0 +1,149 @@
1/*
2A small test loader for loading indicators in test suites
3and during development of them.
4
5Copyright 2009 Canonical Ltd.
6
7Authors:
8 Ted Gould <ted@canonical.com>
9
10This library is free software; you can redistribute it and/or
11modify it under the terms of the GNU General Public License
12version 3.0 as published by the Free Software Foundation.
13
14This library is distributed in the hope that it will be useful,
15but WITHOUT ANY WARRANTY; without even the implied warranty of
16MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17GNU General Public License version 3.0 for more details.
18
19You should have received a copy of the GNU General Public
20License along with this library. If not, see
21<http://www.gnu.org/licenses/>.
22*/
23
24
25#include <gtk/gtk.h>
26#include <libindicator/indicator-object.h>
27
28#define ENTRY_DATA_NAME "indicator-custom-entry-data"
29
30static void
31entry_added (IndicatorObject * io, IndicatorObjectEntry * entry, gpointer user_data)
32{
33 g_debug("Signal: Entry Added");
34
35 GtkWidget * menuitem = gtk_menu_item_new();
36 GtkWidget * hbox = gtk_hbox_new(FALSE, 3);
37
38 if (entry->image != NULL) {
39 gtk_box_pack_start(GTK_BOX(hbox), GTK_WIDGET(entry->image), FALSE, FALSE, 0);
40 }
41 if (entry->label != NULL) {
42 gtk_box_pack_start(GTK_BOX(hbox), GTK_WIDGET(entry->label), FALSE, FALSE, 0);
43 }
44 gtk_container_add(GTK_CONTAINER(menuitem), hbox);
45 gtk_widget_show(hbox);
46
47 if (entry->menu != NULL) {
48 gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), GTK_WIDGET(entry->menu));
49 }
50
51 gtk_menu_shell_append(GTK_MENU_SHELL(user_data), menuitem);
52 gtk_widget_show(menuitem);
53
54 g_object_set_data(G_OBJECT(menuitem), ENTRY_DATA_NAME, entry);
55
56 return;
57}
58
59static void
60entry_removed_cb (GtkWidget * widget, gpointer userdata)
61{
62 gpointer data = g_object_get_data(G_OBJECT(widget), ENTRY_DATA_NAME);
63
64 if (data != userdata) {
65 return;
66 }
67
68 gtk_widget_destroy(widget);
69 return;
70}
71
72static void
73entry_removed (IndicatorObject * io, IndicatorObjectEntry * entry, gpointer user_data)
74{
75 g_debug("Signal: Entry Removed");
76
77 gtk_container_foreach(GTK_CONTAINER(user_data), entry_removed_cb, entry);
78
79 return;
80}
81
82static gboolean
83load_module (const gchar * name, GtkWidget * menu)
84{
85 g_debug("Looking at Module: %s", name);
86 g_return_val_if_fail(name != NULL, FALSE);
87
88 if (!g_str_has_suffix(name, G_MODULE_SUFFIX)) {
89 return FALSE;
90 }
91
92 g_debug("Loading Module: %s", name);
93
94 /* Build the object for the module */
95 IndicatorObject * io = indicator_object_new_from_file(name);
96
97 /* Connect to it's signals */
98 g_signal_connect(G_OBJECT(io), INDICATOR_OBJECT_SIGNAL_ENTRY_ADDED, G_CALLBACK(entry_added), menu);
99 g_signal_connect(G_OBJECT(io), INDICATOR_OBJECT_SIGNAL_ENTRY_REMOVED, G_CALLBACK(entry_removed), menu);
100
101 /* Work on the entries */
102 GList * entries = indicator_object_get_entries(io);
103 GList * entry = NULL;
104
105 for (entry = entries; entry != NULL; entry = g_list_next(entry)) {
106 IndicatorObjectEntry * entrydata = (IndicatorObjectEntry *)entry->data;
107 entry_added(io, entrydata, menu);
108 }
109
110 g_list_free(entries);
111
112 return TRUE;
113}
114
115static void
116destroy (gpointer data)
117{
118 gtk_main_quit();
119 return;
120}
121
122int
123main (int argc, char ** argv)
124{
125 gtk_init(&argc, &argv);
126
127 if (argc != 2) {
128 g_error("Need filename");
129 return 1;
130 }
131
132 GtkWidget * menubar = gtk_menu_bar_new();
133 if (!load_module(argv[1], menubar)) {
134 g_error("Unable to load module");
135 return 1;
136 }
137
138 GtkWidget * window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
139 g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(destroy), NULL);
140
141 gtk_container_add(GTK_CONTAINER(window), menubar);
142
143 gtk_widget_show(menubar);
144 gtk_widget_show(window);
145
146 gtk_main();
147
148 return 0;
149}

Subscribers

People subscribed via source and target branches

to all changes: