Merge lp://qastaging/~ted/libindicator/multi-item-per-module into lp://qastaging/libindicator/0.4

Proposed by Ted Gould
Status: Merged
Merged at revision: not available
Proposed branch: lp://qastaging/~ted/libindicator/multi-item-per-module
Merge into: lp://qastaging/libindicator/0.4
Diff against target: 1120 lines
13 files modified
.bzrignore (+3/-0)
configure.ac (+2/-2)
libindicator/Makefile.am (+1/-1)
libindicator/indicator-object.c (+202/-148)
libindicator/indicator-object.h (+69/-7)
libindicator/indicator.h (+4/-18)
libindicator/indicator.pc.in (+2/-2)
tests/Makefile.am (+33/-4)
tests/dummy-indicator-blank.c (+0/-1)
tests/dummy-indicator-null.c (+76/-4)
tests/dummy-indicator-signaler.c (+109/-0)
tests/dummy-indicator-simple.c (+74/-4)
tests/test-loader.c (+41/-4)
To merge this branch: bzr merge lp://qastaging/~ted/libindicator/multi-item-per-module
Reviewer Review Type Date Requested Status
Indicator Applet Developers Pending
Review via email: mp+14429@code.qastaging.launchpad.net
To post a comment you must log in.
Revision history for this message
Ted Gould (ted) wrote :

This changes the indicator-object interface so that it can support multiple entries per object. But it's change a lot more than that in that it now is based on a GObject subclass instead of being a bunch of functions exported. There is only one function exported, that which registers the type. We then allocate an entry of that type, and boom, effectively everything else is local and exposed through GObject magic.

This makes old indicators incompatible, so appropriate versions were bumped.

Revision history for this message
Mark Shuttleworth (sabdfl) wrote :

We're going to some lengths to be open to the Qt world - how does this
use of GObject affect that?

Revision history for this message
Ted Gould (ted) wrote :

On Thu, 2009-11-05 at 18:51 +0000, Mark Shuttleworth wrote:
> We're going to some lengths to be open to the Qt world - how does this
> use of GObject affect that?

This is at the point in the stack where we'd have to reimplement for Qt
anyway. It's right at the point of the visualization so this code can
only really be used for the GTK implementation. The Qt code would have
to use a different mechanism (Plasma?) to load these in.

Revision history for this message
Mark Shuttleworth (sabdfl) wrote :

Ted Gould wrote:
> On Thu, 2009-11-05 at 18:51 +0000, Mark Shuttleworth wrote:
>
>> We're going to some lengths to be open to the Qt world - how does this
>> use of GObject affect that?
>>
>
> This is at the point in the stack where we'd have to reimplement for Qt
> anyway. It's right at the point of the visualization so this code can
> only really be used for the GTK implementation. The Qt code would have
> to use a different mechanism (Plasma?) to load these in.
>

OK, thanks.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file '.bzrignore'
2--- .bzrignore 2009-11-02 17:21:20 +0000
3+++ .bzrignore 2009-11-04 17:40:26 +0000
4@@ -117,6 +117,9 @@
5 tests/libdummy_indicator_blank_la-dummy-indicator-blank.lo
6 libindicator-[0-9].[0-9].[0-9].tar.gz
7 libindicator-[0-9].[0-9].[0-9].tar.gz.asc
8+libindicator/libindicator_la-indicator-instance.lo
9+tests/libdummy-indicator-signaler.la
10+tests/libdummy_indicator_signaler_la-dummy-indicator-signaler.lo
11 libindicator/indicator-service-client.h
12 libindicator/indicator-service-server.h
13 libindicator/libindicator_la-indicator-service.lo
14
15=== modified file 'configure.ac'
16--- configure.ac 2009-11-04 02:27:00 +0000
17+++ configure.ac 2009-11-04 17:40:26 +0000
18@@ -1,10 +1,10 @@
19
20-AC_INIT(libindicator, 0.2.1, ted@canonical.com)
21+AC_INIT(libindicator, 0.3.0, ted@canonical.com)
22
23 AC_PREREQ(2.53)
24
25 AM_CONFIG_HEADER(config.h)
26-AM_INIT_AUTOMAKE(libindicator, 0.2.1)
27+AM_INIT_AUTOMAKE(libindicator, 0.3.0)
28
29 AM_MAINTAINER_MODE
30 m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES])
31
32=== modified file 'libindicator/Makefile.am'
33--- libindicator/Makefile.am 2009-11-02 16:48:18 +0000
34+++ libindicator/Makefile.am 2009-11-04 17:40:26 +0000
35@@ -3,7 +3,7 @@
36 EXTRA_DIST = \
37 indicator.pc.in
38
39-libindicatorincludedir=$(includedir)/libindicator-0.1/libindicator
40+libindicatorincludedir=$(includedir)/libindicator-0.3/libindicator
41
42 indicator_headers = \
43 indicator.h \
44
45=== modified file 'libindicator/indicator-object.c'
46--- libindicator/indicator-object.c 2009-11-04 02:27:00 +0000
47+++ libindicator/indicator-object.c 2009-11-04 17:40:26 +0000
48@@ -30,28 +30,43 @@
49
50 /**
51 IndicatorObjectPrivate:
52- @label: The label representing this indicator or #NULL if none.
53- @icon: The icon representing this indicator or #NULL if none.
54- @menu: The menu representing this indicator or #NULL if none.
55+ @module: The loaded module representing the object. Note to
56+ subclasses: This will not be set when you're initalized.
57+ @entry: A default entry for objects that don't need all the
58+ fancy stuff. This works with #get_entries_default.
59+ @gotten_entries: A check to see if the @entry has been
60+ populated intelligently yet.
61
62 Structure to define the memory for the private area
63 of the object instance.
64 */
65-typedef struct _IndicatorObjectPrivate IndicatorObjectPrivate;
66 struct _IndicatorObjectPrivate {
67- GtkLabel * label;
68- GtkImage * icon;
69- GtkMenu * menu;
70-};
71-
72-#define INDICATOR_OBJECT_GET_PRIVATE(o) \
73- (G_TYPE_INSTANCE_GET_PRIVATE ((o), INDICATOR_OBJECT_TYPE, IndicatorObjectPrivate))
74-
75+ GModule * module;
76+
77+ /* For get_entries_default */
78+ IndicatorObjectEntry entry;
79+ gboolean gotten_entries;
80+};
81+
82+#define INDICATOR_OBJECT_GET_PRIVATE(o) (INDICATOR_OBJECT(o)->priv)
83+
84+/* Signals Stuff */
85+enum {
86+ ENTRY_ADDED,
87+ ENTRY_REMOVED,
88+ LAST_SIGNAL
89+};
90+
91+static guint signals[LAST_SIGNAL] = { 0 };
92+
93+/* GObject stuff */
94 static void indicator_object_class_init (IndicatorObjectClass *klass);
95 static void indicator_object_init (IndicatorObject *self);
96 static void indicator_object_dispose (GObject *object);
97 static void indicator_object_finalize (GObject *object);
98
99+static GList * get_entries_default (IndicatorObject * io);
100+
101 G_DEFINE_TYPE (IndicatorObject, indicator_object, G_TYPE_OBJECT);
102
103 /* Setup the class and put the functions into the
104@@ -66,6 +81,42 @@
105 object_class->dispose = indicator_object_dispose;
106 object_class->finalize = indicator_object_finalize;
107
108+ klass->get_label = NULL;
109+ klass->get_menu = NULL;
110+ klass->get_image = NULL;
111+
112+ klass->get_entries = get_entries_default;
113+
114+ /**
115+ IndicatorObject::entry-added:
116+ @arg0: The #IndicatorObject object
117+
118+ Signaled when a new entry is added and should
119+ be shown by the person using this object.
120+ */
121+ signals[ENTRY_ADDED] = g_signal_new (INDICATOR_OBJECT_SIGNAL_ENTRY_ADDED,
122+ G_TYPE_FROM_CLASS(klass),
123+ G_SIGNAL_RUN_LAST,
124+ G_STRUCT_OFFSET (IndicatorObjectClass, entry_added),
125+ NULL, NULL,
126+ g_cclosure_marshal_VOID__POINTER,
127+ G_TYPE_NONE, 1, G_TYPE_POINTER, G_TYPE_NONE);
128+
129+ /**
130+ IndicatorObject::entry-removed:
131+ @arg0: The #IndicatorObject object
132+
133+ Signaled when an entry is removed and should
134+ be removed by the person using this object.
135+ */
136+ signals[ENTRY_REMOVED] = g_signal_new (INDICATOR_OBJECT_SIGNAL_ENTRY_REMOVED,
137+ G_TYPE_FROM_CLASS(klass),
138+ G_SIGNAL_RUN_LAST,
139+ G_STRUCT_OFFSET (IndicatorObjectClass, entry_removed),
140+ NULL, NULL,
141+ g_cclosure_marshal_VOID__POINTER,
142+ G_TYPE_NONE, 1, G_TYPE_POINTER, G_TYPE_NONE);
143+
144 return;
145 }
146
147@@ -73,11 +124,15 @@
148 static void
149 indicator_object_init (IndicatorObject *self)
150 {
151- IndicatorObjectPrivate * priv = INDICATOR_OBJECT_GET_PRIVATE(self);
152-
153- priv->label = NULL;
154- priv->icon = NULL;
155- priv->menu = NULL;
156+ self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, INDICATOR_OBJECT_TYPE, IndicatorObjectPrivate);
157+
158+ self->priv->module = NULL;
159+
160+ self->priv->entry.menu = NULL;
161+ self->priv->entry.label = NULL;
162+ self->priv->entry.image = NULL;
163+
164+ self->priv->gotten_entries = FALSE;
165
166 return;
167 }
168@@ -86,31 +141,40 @@
169 static void
170 indicator_object_dispose (GObject *object)
171 {
172- IndicatorObjectPrivate * priv = INDICATOR_OBJECT_GET_PRIVATE(object);
173-
174- if (priv->label != NULL) {
175- g_object_unref(priv->label);
176- priv->label = NULL;
177- }
178-
179- if (priv->icon != NULL) {
180- g_object_unref(priv->icon);
181- priv->icon = NULL;
182- }
183-
184- if (priv->menu != NULL) {
185- g_object_unref(priv->menu);
186- priv->menu = NULL;
187- }
188
189 G_OBJECT_CLASS (indicator_object_parent_class)->dispose (object);
190 return;
191 }
192
193+/* A small helper function that closes a module but
194+ in the function prototype of a GSourceFunc. */
195+static gboolean
196+module_unref (gpointer data)
197+{
198+ if (!g_module_close((GModule *)data)) {
199+ /* All we can do is warn. */
200+ g_warning("Unable to close module!");
201+ }
202+ return FALSE;
203+}
204+
205 /* Free memory */
206 static void
207 indicator_object_finalize (GObject *object)
208 {
209+ IndicatorObjectPrivate * priv = INDICATOR_OBJECT_GET_PRIVATE(object);
210+
211+ if (priv->module != NULL) {
212+ /* Wow, this is convoluted. So basically we want to unref
213+ the module which will cause the code it included to be
214+ removed. But, since it's finalize function is the function
215+ that called this one, we can't really remove it before
216+ it finishes being executed. So we're putting the job into
217+ the main loop to remove it the next time it gets a chance.
218+ Slightly non-deterministic, but should work. */
219+ g_idle_add(module_unref, priv->module);
220+ priv->module = NULL;
221+ }
222
223 G_OBJECT_CLASS (indicator_object_parent_class)->finalize (object);
224 return;
225@@ -130,6 +194,9 @@
226 IndicatorObject *
227 indicator_object_new_from_file (const gchar * file)
228 {
229+ GObject * object = NULL;
230+ GModule * module = NULL;
231+
232 /* Check to make sure the name exists and that the
233 file itself exists */
234 if (file == NULL) {
235@@ -144,9 +211,9 @@
236
237 /* Grab the g_module reference, pull it in but let's
238 keep the symbols local to avoid conflicts. */
239- GModule * module = g_module_open(file,
240- G_MODULE_BIND_LAZY | G_MODULE_BIND_LOCAL);
241- if(module == NULL) {
242+ module = g_module_open(file,
243+ G_MODULE_BIND_LAZY | G_MODULE_BIND_LOCAL);
244+ if (module == NULL) {
245 g_warning("Unable to load module: %s", file);
246 return NULL;
247 }
248@@ -165,126 +232,113 @@
249 return NULL;
250 }
251
252+ /* The function for grabbing a label from the module
253+ execute it, and make sure everything is a-okay */
254+ get_type_t lget_type = NULL;
255+ if (!g_module_symbol(module, INDICATOR_GET_TYPE_S, (gpointer *)(&lget_type))) {
256+ g_warning("Unable to get '" INDICATOR_GET_TYPE_S "' symbol from module: %s", file);
257+ goto unrefandout;
258+ }
259+ if (lget_type == NULL) {
260+ g_warning("Symbol '" INDICATOR_GET_TYPE_S "' is (null) in module: %s", file);
261+ goto unrefandout;
262+ }
263+
264 /* A this point we allocate the object, any code beyond
265 here needs to deallocate it if we're returning in an
266 error'd state. */
267- GObject * object = g_object_new(INDICATOR_OBJECT_TYPE, NULL);
268+ object = g_object_new(lget_type(), NULL);
269+ if (object == NULL) {
270+ g_warning("Unable to build an object if type '%d' in module: %s", lget_type(), file);
271+ goto unrefandout;
272+ }
273+ if (!INDICATOR_IS_OBJECT(object)) {
274+ g_warning("Type '%d' in file %s is not a subclass of IndicatorObject.", lget_type(), file);
275+ goto unrefandout;
276+ }
277+
278 IndicatorObjectPrivate * priv = INDICATOR_OBJECT_GET_PRIVATE(object);
279-
280- /* The function for grabbing a label from the module
281- execute it, and make sure everything is a-okay */
282- get_label_t lget_label = NULL;
283- if (!g_module_symbol(module, INDICATOR_GET_LABEL_S, (gpointer *)(&lget_label))) {
284- g_warning("Unable to get '" INDICATOR_GET_LABEL_S "' symbol from module: %s", file);
285- goto unrefandout;
286- }
287- if (lget_label == NULL) {
288- g_warning("Symbol '" INDICATOR_GET_LABEL_S "' is (null) in module: %s", file);
289- goto unrefandout;
290- }
291- priv->label = lget_label();
292- if (priv->label) {
293- g_object_ref(G_OBJECT(priv->label));
294- }
295-
296- /* The function for grabbing an icon from the module
297- execute it, and make sure everything is a-okay */
298- get_icon_t lget_icon = NULL;
299- if (!g_module_symbol(module, INDICATOR_GET_ICON_S, (gpointer *)(&lget_icon))) {
300- g_warning("Unable to get '" INDICATOR_GET_ICON_S "' symbol from module: %s", file);
301- goto unrefandout;
302- }
303- if (lget_icon == NULL) {
304- g_warning("Symbol '" INDICATOR_GET_ICON_S "' is (null) in module: %s", file);
305- goto unrefandout;
306- }
307- priv->icon = lget_icon();
308- if (priv->icon) {
309- g_object_ref(G_OBJECT(priv->icon));
310- }
311-
312- /* The function for grabbing a menu from the module
313- execute it, and make sure everything is a-okay */
314- get_menu_t lget_menu = NULL;
315- if (!g_module_symbol(module, INDICATOR_GET_MENU_S, (gpointer *)(&lget_menu))) {
316- g_warning("Unable to get '" INDICATOR_GET_MENU_S "' symbol from module: %s", file);
317- goto unrefandout;
318- }
319- if (lget_menu == NULL) {
320- g_warning("Symbol '" INDICATOR_GET_MENU_S "' is (null) in module: %s", file);
321- goto unrefandout;
322- }
323- priv->menu = lget_menu();
324- if (priv->menu) {
325- g_object_ref(G_OBJECT(priv->menu));
326- }
327-
328- if (priv->label == NULL && priv->icon == NULL) {
329- /* This is the case where there is nothing to display,
330- kinda odd that we'd have a module with nothing. */
331- g_warning("No label or icon. Odd.");
332- goto unrefandout;
333- }
334+ /* Now we can track the module */
335+ priv->module = module;
336
337 return INDICATOR_OBJECT(object);
338
339 /* Error, let's drop the object and return NULL. Sad when
340 this happens. */
341 unrefandout:
342- g_object_unref(object);
343- return NULL;
344-}
345-
346-/**
347- indicator_object_get_label:
348- @io: An #IndicatorObject.
349-
350- A function to get the label for a particular object. This
351- function does not increase the refcount. That's your job
352- if you want to do it.
353-
354- Return value: A #GtkLabel or #NULL if unavailable.
355-*/
356-GtkLabel *
357-indicator_object_get_label (IndicatorObject * io)
358-{
359- g_return_val_if_fail(INDICATOR_IS_OBJECT(io), NULL);
360- IndicatorObjectPrivate * priv = INDICATOR_OBJECT_GET_PRIVATE(io);
361- return priv->label;
362-}
363-
364-/**
365- indicator_object_get_icon:
366- @io: An #IndicatorObject.
367-
368- A function to get the icon for a particular object. This
369- function does not increase the refcount. That's your job
370- if you want to do it.
371-
372- Return value: A #GtkImage or #NULL if unavailable.
373-*/
374-GtkImage *
375-indicator_object_get_icon (IndicatorObject * io)
376-{
377- g_return_val_if_fail(INDICATOR_IS_OBJECT(io), NULL);
378- IndicatorObjectPrivate * priv = INDICATOR_OBJECT_GET_PRIVATE(io);
379- return priv->icon;
380-}
381-
382-/**
383- indicator_object_get_menu:
384- @io: An #IndicatorObject.
385-
386- A function to get the menu for a particular object. This
387- function does not increase the refcount. That's your job
388- if you want to do it.
389-
390- Return value: A #GtkMenu or #NULL if unavailable.
391-*/
392-GtkMenu *
393-indicator_object_get_menu (IndicatorObject * io)
394-{
395- g_return_val_if_fail(INDICATOR_IS_OBJECT(io), NULL);
396- IndicatorObjectPrivate * priv = INDICATOR_OBJECT_GET_PRIVATE(io);
397- return priv->menu;
398+ if (object != NULL) {
399+ g_object_unref(object);
400+ }
401+ if (module != NULL) {
402+ g_object_unref(module);
403+ }
404+ g_warning("Error building IndicatorObject from file: %s", file);
405+ return NULL;
406+}
407+
408+/* The default get entries function uses the other single
409+ entries in the class to create an entry structure and
410+ put it into a list. This makes it simple for simple objects
411+ to create the list. Small changes from the way they
412+ previously were. */
413+static GList *
414+get_entries_default (IndicatorObject * io)
415+{
416+ IndicatorObjectPrivate * priv = INDICATOR_OBJECT_GET_PRIVATE(io);
417+
418+ if (!priv->gotten_entries) {
419+ IndicatorObjectClass * class = INDICATOR_OBJECT_GET_CLASS(io);
420+
421+ if (class->get_label) {
422+ priv->entry.label = class->get_label(io);
423+ }
424+
425+ if (class->get_image) {
426+ priv->entry.image = class->get_image(io);
427+ }
428+
429+ if (priv->entry.image == NULL && priv->entry.label == NULL) {
430+ g_warning("IndicatorObject class does not create an image or a label. We need one of those.");
431+ return NULL;
432+ }
433+
434+ if (class->get_menu) {
435+ priv->entry.menu = class->get_menu(io);
436+ }
437+
438+ if (priv->entry.menu == NULL) {
439+ g_warning("IndicatorObject class does not create a menu. We need one of those.");
440+ return NULL;
441+ }
442+
443+ priv->gotten_entries = TRUE;
444+ }
445+
446+ return g_list_append(NULL, &(priv->entry));
447+}
448+
449+/**
450+ indicator_object_get_entires:
451+ @io: #IndicatorObject to query
452+
453+ This function looks on the class for the object and calls
454+ it's #IndicatorObjectClass::get_entries function. The
455+ list should be owned by the caller, but the individual
456+ enteries should not be.
457+
458+ Return value: A list if #IndicatorObjectEntry structures or
459+ NULL if there is an error.
460+*/
461+GList *
462+indicator_object_get_entries (IndicatorObject * io)
463+{
464+ g_return_val_if_fail(INDICATOR_IS_OBJECT(io), NULL);
465+ IndicatorObjectClass * class = INDICATOR_OBJECT_GET_CLASS(io);
466+
467+ if (class->get_entries) {
468+ return class->get_entries(io);
469+ }
470+
471+ g_error("No get_entries function on object. It must have been deleted?!?!");
472+ return NULL;
473 }
474
475=== modified file 'libindicator/indicator-object.h'
476--- libindicator/indicator-object.h 2009-11-04 02:27:00 +0000
477+++ libindicator/indicator-object.h 2009-11-04 17:40:26 +0000
478@@ -36,25 +36,87 @@
479 #define INDICATOR_IS_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), INDICATOR_OBJECT_TYPE))
480 #define INDICATOR_OBJECT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), INDICATOR_OBJECT_TYPE, IndicatorObjectClass))
481
482-typedef struct _IndicatorObject IndicatorObject;
483-typedef struct _IndicatorObjectClass IndicatorObjectClass;
484-
485+#define INDICATOR_OBJECT_SIGNAL_ENTRY_ADDED "entry-added"
486+#define INDICATOR_OBJECT_SIGNAL_ENTRY_ADDED_ID (g_signal_lookup(INDICATOR_OBJECT_SIGNAL_ENTRY_ADDED, INDICATOR_OBJECT_TYPE))
487+#define INDICATOR_OBJECT_SIGNAL_ENTRY_REMOVED "entry-removed"
488+#define INDICATOR_OBJECT_SIGNAL_ENTRY_REMOVED_ID (g_signal_lookup(INDICATOR_OBJECT_SIGNAL_ENTRY_REMOVED, INDICATOR_OBJECT_TYPE))
489+
490+typedef struct _IndicatorObject IndicatorObject;
491+typedef struct _IndicatorObjectClass IndicatorObjectClass;
492+typedef struct _IndicatorObjectPrivate IndicatorObjectPrivate;
493+typedef struct _IndicatorObjectEntry IndicatorObjectEntry;
494+
495+/**
496+ IndicatorObjectClass:
497+ @parent_class: #GObjectClass
498+ @get_label: Gets the label for this object. Should be set
499+ to #NULL if @get_entries is set. Should NOT ref the
500+ object.
501+ @get_image: Gets the image for this object. Should be set
502+ to #NULL if @get_entries is set. Should NOT ref the
503+ object.
504+ @get_menu: Gets the image for this object. Should be set
505+ to #NULL if @get_entries is set. Should NOT ref the
506+ object.
507+ @get_entries: Gets all of the entires for this object returning
508+ a #GList of #IndicatorObjectEntries. The list should be
509+ under the ownership of the caller but the entires will
510+ not be.
511+ @entry_added: Slot for #IndicatorObject::entry-added
512+ @entry_removed: Slot for #IndicatorObject::entry-removed
513+ @indicator_object_reserved_1: Reserved for future use
514+ @indicator_object_reserved_2: Reserved for future use
515+ @indicator_object_reserved_3: Reserved for future use
516+ @indicator_object_reserved_4: Reserved for future use
517+*/
518 struct _IndicatorObjectClass {
519 GObjectClass parent_class;
520-
521+
522+ /* Virtual Functions */
523+ GtkLabel * (*get_label) (IndicatorObject * io);
524+ GtkImage * (*get_image) (IndicatorObject * io);
525+ GtkMenu * (*get_menu) (IndicatorObject * io);
526+
527+ GList * (*get_entries) (IndicatorObject * io);
528+
529+ /* Signals */
530+ void (*entry_added) (IndicatorObject * io, IndicatorObjectEntry * entry, gpointer user_data);
531+ void (*entry_removed) (IndicatorObject * io, IndicatorObjectEntry * entry, gpointer user_data);
532+
533+ /* Reserved */
534+ void (* indicator_object_reserved_1) (void);
535+ void (* indicator_object_reserved_2) (void);
536+ void (* indicator_object_reserved_3) (void);
537+ void (* indicator_object_reserved_4) (void);
538 };
539
540+/**
541+ IndicatorObject:
542+ @parent: #GObject
543+ @priv: A cached reference to the private data for the
544+ instance.
545+*/
546 struct _IndicatorObject {
547 GObject parent;
548+ IndicatorObjectPrivate * priv;
549+};
550
551+/**
552+ IndicatorObjectEntry:
553+ @label: The label to be shown on the panel
554+ @image: The image to be shown on the panel
555+ @menu: The menu to be added to the menubar
556+*/
557+struct _IndicatorObjectEntry {
558+ GtkLabel * label;
559+ GtkImage * image;
560+ GtkMenu * menu;
561 };
562
563 GType indicator_object_get_type (void);
564 IndicatorObject * indicator_object_new_from_file (const gchar * file);
565
566-GtkLabel * indicator_object_get_label (IndicatorObject * io);
567-GtkImage * indicator_object_get_icon (IndicatorObject * io);
568-GtkMenu * indicator_object_get_menu (IndicatorObject * io);
569+GList * indicator_object_get_entries (IndicatorObject * io);
570
571 G_END_DECLS
572
573
574=== modified file 'libindicator/indicator.h'
575--- libindicator/indicator.h 2009-10-06 15:00:34 +0000
576+++ libindicator/indicator.h 2009-11-04 17:40:26 +0000
577@@ -25,31 +25,17 @@
578
579 #include <gtk/gtk.h>
580
581-#define INDICATOR_GET_LABEL_S "get_label"
582-typedef GtkLabel * (*get_label_t)(void);
583-GtkLabel * get_label (void);
584-
585-#define INDICATOR_GET_ICON_S "get_icon"
586-typedef GtkImage * (*get_icon_t) (void);
587-GtkImage * get_icon (void);
588-
589-#define INDICATOR_GET_MENU_S "get_menu"
590-typedef GtkMenu * (*get_menu_t) (void);
591-GtkMenu * get_menu (void);
592-
593 #define INDICATOR_GET_VERSION_S "get_version"
594 typedef gchar * (*get_version_t) (void);
595 gchar * get_version (void);
596
597-#define INDICATOR_VERSION "0.2.0"
598+#define INDICATOR_VERSION "0.3.0"
599 #define INDICATOR_SET_VERSION gchar * get_version(void) { return INDICATOR_VERSION; }
600 #define INDICATOR_VERSION_CHECK(x) (!g_strcmp0(x, INDICATOR_VERSION))
601
602-#define INDICATOR_GET_NAME_S "get_name"
603-typedef gchar * (*get_name_t) (void);
604-gchar * get_name (void);
605-#define INDICATOR_SET_NAME(x) gchar * get_name(void) {return (x); }
606-
607+#define INDICATOR_GET_TYPE_S "get_type"
608+typedef GType (*get_type_t) (void);
609+#define INDICATOR_SET_TYPE(x) GType get_type (void) { return x; }
610
611 #endif /* __LIBINDICATOR_INDICATOR_H_SEEN__ */
612
613
614=== modified file 'libindicator/indicator.pc.in'
615--- libindicator/indicator.pc.in 2009-11-02 23:12:06 +0000
616+++ libindicator/indicator.pc.in 2009-11-04 17:40:26 +0000
617@@ -4,10 +4,10 @@
618 bindir=@bindir@
619 includedir=@includedir@
620
621-indicatordir=${libdir}/indicators/2/
622+indicatordir=${libdir}/indicators/3/
623 iconsdir=@datarootdir@/@PACKAGE@/icons/
624
625-Cflags: -I${includedir}/libindicator-0.1
626+Cflags: -I${includedir}/libindicator-0.3
627 Requires: gtk+-2.0
628 Libs: -lindicator
629
630
631=== modified file 'tests/Makefile.am'
632--- tests/Makefile.am 2009-11-02 22:17:31 +0000
633+++ tests/Makefile.am 2009-11-04 17:40:26 +0000
634@@ -11,6 +11,7 @@
635 lib_LTLIBRARIES = \
636 libdummy-indicator-blank.la \
637 libdummy-indicator-null.la \
638+ libdummy-indicator-signaler.la \
639 libdummy-indicator-simple.la
640
641 DBUS_RUNNER=dbus-test-runner --dbus-config /usr/share/dbus-test-runner/session.conf
642@@ -28,7 +29,9 @@
643 -DBUILD_DIR="\"$(builddir)\""
644
645 test_loader_LDADD = \
646- $(LIBINDICATOR_LIBS) $(top_builddir)/libindicator/.libs/libindicator.a
647+ $(LIBINDICATOR_LIBS) \
648+ -L$(top_builddir)/libindicator/.libs \
649+ -lindicator
650
651 #############################
652 # Dummy Indicator Blank
653@@ -42,7 +45,9 @@
654 $(LIBINDICATOR_CFLAGS) -I$(top_srcdir)
655
656 libdummy_indicator_blank_la_LIBADD = \
657- $(LIBINDICATOR_LIBS)
658+ $(LIBINDICATOR_LIBS) \
659+ -L$(top_builddir)/libindicator/.libs \
660+ -lindicator
661
662 libdummy_indicator_blank_la_LDFLAGS = \
663 -module \
664@@ -60,13 +65,35 @@
665 $(LIBINDICATOR_CFLAGS) -I$(top_srcdir)
666
667 libdummy_indicator_null_la_LIBADD = \
668- $(LIBINDICATOR_LIBS)
669+ $(LIBINDICATOR_LIBS) \
670+ -L$(top_builddir)/libindicator/.libs \
671+ -lindicator
672
673 libdummy_indicator_null_la_LDFLAGS = \
674 -module \
675 -avoid-version
676
677 #############################
678+# Dummy Indicator Signaler
679+#############################
680+
681+libdummy_indicator_signaler_la_SOURCES = \
682+ dummy-indicator-signaler.c
683+
684+libdummy_indicator_signaler_la_CFLAGS = \
685+ -Wall -Werror \
686+ $(LIBINDICATOR_CFLAGS) -I$(top_srcdir)
687+
688+libdummy_indicator_signaler_la_LIBADD = \
689+ $(LIBINDICATOR_LIBS) \
690+ -L$(top_builddir)/libindicator/.libs \
691+ -lindicator
692+
693+libdummy_indicator_signaler_la_LDFLAGS = \
694+ -module \
695+ -avoid-version
696+
697+#############################
698 # Dummy Indicator Simple
699 #############################
700
701@@ -78,7 +105,9 @@
702 $(LIBINDICATOR_CFLAGS) -I$(top_srcdir)
703
704 libdummy_indicator_simple_la_LIBADD = \
705- $(LIBINDICATOR_LIBS)
706+ $(LIBINDICATOR_LIBS) \
707+ -L$(top_builddir)/libindicator/.libs \
708+ -lindicator
709
710 libdummy_indicator_simple_la_LDFLAGS = \
711 -module \
712
713=== modified file 'tests/dummy-indicator-blank.c'
714--- tests/dummy-indicator-blank.c 2009-10-12 02:49:22 +0000
715+++ tests/dummy-indicator-blank.c 2009-11-04 17:40:26 +0000
716@@ -2,5 +2,4 @@
717 #include "libindicator/indicator.h"
718
719 INDICATOR_SET_VERSION
720-INDICATOR_SET_NAME("dummy-indicator-null")
721
722
723=== modified file 'tests/dummy-indicator-null.c'
724--- tests/dummy-indicator-null.c 2009-10-08 21:03:20 +0000
725+++ tests/dummy-indicator-null.c 2009-11-04 17:40:26 +0000
726@@ -1,23 +1,95 @@
727
728+#include <glib.h>
729+#include <glib-object.h>
730+
731 #include "libindicator/indicator.h"
732+#include "libindicator/indicator-object.h"
733+
734+#define DUMMY_INDICATOR_NULL_TYPE (dummy_indicator_null_get_type ())
735+#define DUMMY_INDICATOR_NULL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), DUMMY_INDICATOR_NULL_TYPE, DummyIndicatorNull))
736+#define DUMMY_INDICATOR_NULL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), DUMMY_INDICATOR_NULL_TYPE, DummyIndicatorNullClass))
737+#define IS_DUMMY_INDICATOR_NULL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), DUMMY_INDICATOR_NULL_TYPE))
738+#define IS_DUMMY_INDICATOR_NULL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), DUMMY_INDICATOR_NULL_TYPE))
739+#define DUMMY_INDICATOR_NULL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), DUMMY_INDICATOR_NULL_TYPE, DummyIndicatorNullClass))
740+
741+typedef struct _DummyIndicatorNull DummyIndicatorNull;
742+typedef struct _DummyIndicatorNullClass DummyIndicatorNullClass;
743+
744+struct _DummyIndicatorNullClass {
745+ IndicatorObjectClass parent_class;
746+};
747+
748+struct _DummyIndicatorNull {
749+ IndicatorObject parent;
750+};
751+
752+GType dummy_indicator_null_get_type (void);
753
754 INDICATOR_SET_VERSION
755-INDICATOR_SET_NAME("dummy-indicator-null")
756+INDICATOR_SET_TYPE(DUMMY_INDICATOR_NULL_TYPE)
757+
758
759 GtkLabel *
760-get_label (void)
761+get_label (IndicatorObject * io)
762 {
763 return NULL;
764 }
765
766 GtkImage *
767-get_icon (void)
768+get_icon (IndicatorObject * io)
769 {
770 return NULL;
771 }
772
773 GtkMenu *
774-get_menu (void)
775+get_menu (IndicatorObject * io)
776 {
777 return NULL;
778 }
779+
780+static void dummy_indicator_null_class_init (DummyIndicatorNullClass *klass);
781+static void dummy_indicator_null_init (DummyIndicatorNull *self);
782+static void dummy_indicator_null_dispose (GObject *object);
783+static void dummy_indicator_null_finalize (GObject *object);
784+
785+G_DEFINE_TYPE (DummyIndicatorNull, dummy_indicator_null, INDICATOR_OBJECT_TYPE);
786+
787+static void
788+dummy_indicator_null_class_init (DummyIndicatorNullClass *klass)
789+{
790+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
791+
792+ object_class->dispose = dummy_indicator_null_dispose;
793+ object_class->finalize = dummy_indicator_null_finalize;
794+
795+ IndicatorObjectClass * io_class = INDICATOR_OBJECT_CLASS(klass);
796+
797+ io_class->get_label = get_label;
798+ io_class->get_image = get_icon;
799+ io_class->get_menu = get_menu;
800+
801+ return;
802+}
803+
804+static void
805+dummy_indicator_null_init (DummyIndicatorNull *self)
806+{
807+
808+ return;
809+}
810+
811+static void
812+dummy_indicator_null_dispose (GObject *object)
813+{
814+
815+ G_OBJECT_CLASS (dummy_indicator_null_parent_class)->dispose (object);
816+ return;
817+}
818+
819+static void
820+dummy_indicator_null_finalize (GObject *object)
821+{
822+
823+ G_OBJECT_CLASS (dummy_indicator_null_parent_class)->finalize (object);
824+ return;
825+}
826
827=== added file 'tests/dummy-indicator-signaler.c'
828--- tests/dummy-indicator-signaler.c 1970-01-01 00:00:00 +0000
829+++ tests/dummy-indicator-signaler.c 2009-11-04 17:40:26 +0000
830@@ -0,0 +1,109 @@
831+#include <glib.h>
832+#include <glib-object.h>
833+
834+#include "libindicator/indicator.h"
835+#include "libindicator/indicator-object.h"
836+
837+#define DUMMY_INDICATOR_SIGNALER_TYPE (dummy_indicator_signaler_get_type ())
838+#define DUMMY_INDICATOR_SIGNALER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), DUMMY_INDICATOR_SIGNALER_TYPE, DummyIndicatorSignaler))
839+#define DUMMY_INDICATOR_SIGNALER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), DUMMY_INDICATOR_SIGNALER_TYPE, DummyIndicatorSignalerClass))
840+#define IS_DUMMY_INDICATOR_SIGNALER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), DUMMY_INDICATOR_SIGNALER_TYPE))
841+#define IS_DUMMY_INDICATOR_SIGNALER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), DUMMY_INDICATOR_SIGNALER_TYPE))
842+#define DUMMY_INDICATOR_SIGNALER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), DUMMY_INDICATOR_SIGNALER_TYPE, DummyIndicatorSignalerClass))
843+
844+typedef struct _DummyIndicatorSignaler DummyIndicatorSignaler;
845+typedef struct _DummyIndicatorSignalerClass DummyIndicatorSignalerClass;
846+
847+struct _DummyIndicatorSignalerClass {
848+ IndicatorObjectClass parent_class;
849+};
850+
851+struct _DummyIndicatorSignaler {
852+ IndicatorObject parent;
853+};
854+
855+GType dummy_indicator_signaler_get_type (void);
856+
857+INDICATOR_SET_VERSION
858+INDICATOR_SET_TYPE(DUMMY_INDICATOR_SIGNALER_TYPE)
859+
860+GtkLabel *
861+get_label (IndicatorObject * io)
862+{
863+ return GTK_LABEL(gtk_label_new("Signaler Item"));
864+}
865+
866+GtkImage *
867+get_icon (IndicatorObject * io)
868+{
869+ return GTK_IMAGE(gtk_image_new());
870+}
871+
872+GtkMenu *
873+get_menu (IndicatorObject * io)
874+{
875+ GtkMenu * main_menu = GTK_MENU(gtk_menu_new());
876+ GtkWidget * loading_item = gtk_menu_item_new_with_label("Loading...");
877+ gtk_menu_shell_append(GTK_MENU_SHELL(main_menu), loading_item);
878+ gtk_widget_show(GTK_WIDGET(loading_item));
879+
880+ return main_menu;
881+}
882+
883+static void dummy_indicator_signaler_class_init (DummyIndicatorSignalerClass *klass);
884+static void dummy_indicator_signaler_init (DummyIndicatorSignaler *self);
885+static void dummy_indicator_signaler_dispose (GObject *object);
886+static void dummy_indicator_signaler_finalize (GObject *object);
887+
888+G_DEFINE_TYPE (DummyIndicatorSignaler, dummy_indicator_signaler, INDICATOR_OBJECT_TYPE);
889+
890+static void
891+dummy_indicator_signaler_class_init (DummyIndicatorSignalerClass *klass)
892+{
893+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
894+
895+ object_class->dispose = dummy_indicator_signaler_dispose;
896+ object_class->finalize = dummy_indicator_signaler_finalize;
897+
898+ IndicatorObjectClass * io_class = INDICATOR_OBJECT_CLASS(klass);
899+
900+ io_class->get_label = get_label;
901+ io_class->get_image = get_icon;
902+ io_class->get_menu = get_menu;
903+
904+ return;
905+}
906+
907+static gboolean
908+idle_signal (gpointer data)
909+{
910+ DummyIndicatorSignaler * self = DUMMY_INDICATOR_SIGNALER(data);
911+
912+ g_signal_emit(G_OBJECT(self), INDICATOR_OBJECT_SIGNAL_ENTRY_ADDED_ID, 0, GUINT_TO_POINTER(5), TRUE);
913+ g_signal_emit(G_OBJECT(self), INDICATOR_OBJECT_SIGNAL_ENTRY_REMOVED_ID, 0, GUINT_TO_POINTER(5), TRUE);
914+
915+ return FALSE; /* Don't queue again */
916+}
917+
918+static void
919+dummy_indicator_signaler_init (DummyIndicatorSignaler *self)
920+{
921+ g_idle_add(idle_signal, self);
922+ return;
923+}
924+
925+static void
926+dummy_indicator_signaler_dispose (GObject *object)
927+{
928+
929+ G_OBJECT_CLASS (dummy_indicator_signaler_parent_class)->dispose (object);
930+ return;
931+}
932+
933+static void
934+dummy_indicator_signaler_finalize (GObject *object)
935+{
936+
937+ G_OBJECT_CLASS (dummy_indicator_signaler_parent_class)->finalize (object);
938+ return;
939+}
940
941=== modified file 'tests/dummy-indicator-simple.c'
942--- tests/dummy-indicator-simple.c 2009-10-09 00:17:04 +0000
943+++ tests/dummy-indicator-simple.c 2009-11-04 17:40:26 +0000
944@@ -1,23 +1,46 @@
945+#include <glib.h>
946+#include <glib-object.h>
947
948 #include "libindicator/indicator.h"
949+#include "libindicator/indicator-object.h"
950+
951+#define DUMMY_INDICATOR_SIMPLE_TYPE (dummy_indicator_simple_get_type ())
952+#define DUMMY_INDICATOR_SIMPLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), DUMMY_INDICATOR_SIMPLE_TYPE, DummyIndicatorSimple))
953+#define DUMMY_INDICATOR_SIMPLE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), DUMMY_INDICATOR_SIMPLE_TYPE, DummyIndicatorSimpleClass))
954+#define IS_DUMMY_INDICATOR_SIMPLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), DUMMY_INDICATOR_SIMPLE_TYPE))
955+#define IS_DUMMY_INDICATOR_SIMPLE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), DUMMY_INDICATOR_SIMPLE_TYPE))
956+#define DUMMY_INDICATOR_SIMPLE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), DUMMY_INDICATOR_SIMPLE_TYPE, DummyIndicatorSimpleClass))
957+
958+typedef struct _DummyIndicatorSimple DummyIndicatorSimple;
959+typedef struct _DummyIndicatorSimpleClass DummyIndicatorSimpleClass;
960+
961+struct _DummyIndicatorSimpleClass {
962+ IndicatorObjectClass parent_class;
963+};
964+
965+struct _DummyIndicatorSimple {
966+ IndicatorObject parent;
967+};
968+
969+GType dummy_indicator_simple_get_type (void);
970
971 INDICATOR_SET_VERSION
972-INDICATOR_SET_NAME("dummy-indicator-simple")
973+INDICATOR_SET_TYPE(DUMMY_INDICATOR_SIMPLE_TYPE)
974
975 GtkLabel *
976-get_label (void)
977+get_label (IndicatorObject * io)
978 {
979 return GTK_LABEL(gtk_label_new("Simple Item"));
980 }
981
982 GtkImage *
983-get_icon (void)
984+get_icon (IndicatorObject * io)
985 {
986 return GTK_IMAGE(gtk_image_new());
987 }
988
989 GtkMenu *
990-get_menu (void)
991+get_menu (IndicatorObject * io)
992 {
993 GtkMenu * main_menu = GTK_MENU(gtk_menu_new());
994 GtkWidget * loading_item = gtk_menu_item_new_with_label("Loading...");
995@@ -26,3 +49,50 @@
996
997 return main_menu;
998 }
999+
1000+static void dummy_indicator_simple_class_init (DummyIndicatorSimpleClass *klass);
1001+static void dummy_indicator_simple_init (DummyIndicatorSimple *self);
1002+static void dummy_indicator_simple_dispose (GObject *object);
1003+static void dummy_indicator_simple_finalize (GObject *object);
1004+
1005+G_DEFINE_TYPE (DummyIndicatorSimple, dummy_indicator_simple, INDICATOR_OBJECT_TYPE);
1006+
1007+static void
1008+dummy_indicator_simple_class_init (DummyIndicatorSimpleClass *klass)
1009+{
1010+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
1011+
1012+ object_class->dispose = dummy_indicator_simple_dispose;
1013+ object_class->finalize = dummy_indicator_simple_finalize;
1014+
1015+ IndicatorObjectClass * io_class = INDICATOR_OBJECT_CLASS(klass);
1016+
1017+ io_class->get_label = get_label;
1018+ io_class->get_image = get_icon;
1019+ io_class->get_menu = get_menu;
1020+
1021+ return;
1022+}
1023+
1024+static void
1025+dummy_indicator_simple_init (DummyIndicatorSimple *self)
1026+{
1027+
1028+ return;
1029+}
1030+
1031+static void
1032+dummy_indicator_simple_dispose (GObject *object)
1033+{
1034+
1035+ G_OBJECT_CLASS (dummy_indicator_simple_parent_class)->dispose (object);
1036+ return;
1037+}
1038+
1039+static void
1040+dummy_indicator_simple_finalize (GObject *object)
1041+{
1042+
1043+ G_OBJECT_CLASS (dummy_indicator_simple_parent_class)->finalize (object);
1044+ return;
1045+}
1046
1047=== modified file 'tests/test-loader.c'
1048--- tests/test-loader.c 2009-10-12 02:50:46 +0000
1049+++ tests/test-loader.c 2009-11-04 17:40:26 +0000
1050@@ -4,14 +4,48 @@
1051 void destroy_cb (gpointer data, GObject * object);
1052
1053 void
1054+entry_change_cb (IndicatorObject * io, IndicatorObjectEntry * entry, gpointer data)
1055+{
1056+ gpointer * valuestore = (gpointer *)data;
1057+ *valuestore = entry;
1058+ return;
1059+}
1060+
1061+void
1062+test_loader_filename_dummy_signaler (void)
1063+{
1064+ IndicatorObject * object = indicator_object_new_from_file(BUILD_DIR "/.libs/libdummy-indicator-signaler.so");
1065+ g_assert(object != NULL);
1066+
1067+ gpointer added_value = NULL, removed_value = NULL;
1068+
1069+ g_signal_connect(G_OBJECT(object), INDICATOR_OBJECT_SIGNAL_ENTRY_ADDED, G_CALLBACK(entry_change_cb), &added_value);
1070+ g_signal_connect(G_OBJECT(object), INDICATOR_OBJECT_SIGNAL_ENTRY_REMOVED, G_CALLBACK(entry_change_cb), &removed_value);
1071+
1072+ GList * list = indicator_object_get_entries(object);
1073+ g_assert(list != NULL);
1074+ g_list_free(list);
1075+
1076+ while (g_main_context_pending(NULL)) {
1077+ g_main_context_iteration(NULL, TRUE);
1078+ }
1079+
1080+ g_assert(GPOINTER_TO_UINT(added_value) == 5);
1081+ g_assert(GPOINTER_TO_UINT(removed_value) == 5);
1082+
1083+ g_object_unref(object);
1084+
1085+ return;
1086+}
1087+
1088+
1089+void
1090 test_loader_filename_dummy_simple_accessors (void)
1091 {
1092 IndicatorObject * object = indicator_object_new_from_file(BUILD_DIR "/.libs/libdummy-indicator-simple.so");
1093 g_assert(object != NULL);
1094
1095- g_assert(indicator_object_get_label(object) != NULL);
1096- g_assert(indicator_object_get_menu(object) != NULL);
1097- g_assert(indicator_object_get_icon(object) != NULL);
1098+ g_assert(indicator_object_get_entries(object) != NULL);
1099
1100 g_object_unref(object);
1101
1102@@ -45,7 +79,9 @@
1103 test_loader_filename_dummy_null (void)
1104 {
1105 IndicatorObject * object = indicator_object_new_from_file(BUILD_DIR "/.libs/libdummy-indicator-null.so");
1106- g_assert(object == NULL);
1107+ g_assert(object != NULL);
1108+ g_assert(indicator_object_get_entries(object) == NULL);
1109+ g_object_unref(G_OBJECT(object));
1110 return;
1111 }
1112
1113@@ -89,6 +125,7 @@
1114 g_test_add_func ("/libindicator/loader/dummy/blank_load", test_loader_filename_dummy_null);
1115 g_test_add_func ("/libindicator/loader/dummy/simple_load", test_loader_filename_dummy_simple);
1116 g_test_add_func ("/libindicator/loader/dummy/simple_accessors", test_loader_filename_dummy_simple_accessors);
1117+ g_test_add_func ("/libindicator/loader/dummy/signaler", test_loader_filename_dummy_signaler);
1118
1119 return;
1120 }

Subscribers

People subscribed via source and target branches