Merge lp://qastaging/~ted/libindicator/multi-item-per-module into lp://qastaging/libindicator/0.4
- multi-item-per-module
- Merge into trunk
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 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Indicator Applet Developers | Pending | ||
Review via email: mp+14429@code.qastaging.launchpad.net |
Commit message
Description of the change
Ted Gould (ted) wrote : | # |
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?
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.
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
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 | } |
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.