Merge lp:~ted/libdbusmenu/parse-serializable-menuitem into lp:libdbusmenu/0.5

Proposed by Ted Gould
Status: Superseded
Proposed branch: lp:~ted/libdbusmenu/parse-serializable-menuitem
Merge into: lp:libdbusmenu/0.5
Prerequisite: lp:~ted/libdbusmenu/now-with-parsing
Diff against target: 743 lines (+505/-22)
12 files modified
.bzrignore (+3/-0)
docs/libdbusmenu-gtk/reference/Makefile.am (+1/-1)
docs/libdbusmenu-gtk/reference/libdbusmenu-gtk-docs.sgml (+1/-1)
libdbusmenu-glib/client.c (+69/-7)
libdbusmenu-glib/client.h (+7/-1)
libdbusmenu-gtk/Makefile.am (+5/-2)
libdbusmenu-gtk/client.c (+4/-4)
libdbusmenu-gtk/dbusmenu-gtk.h (+1/-0)
libdbusmenu-gtk/menuitem.h (+2/-2)
libdbusmenu-gtk/parser.c (+16/-4)
libdbusmenu-gtk/serializablemenuitem.c (+288/-0)
libdbusmenu-gtk/serializablemenuitem.h (+108/-0)
To merge this branch: bzr merge lp:~ted/libdbusmenu/parse-serializable-menuitem
Reviewer Review Type Date Requested Status
Mikkel Kamstrup Erlandsen (community) Needs Information
Review via email: mp+47605@code.launchpad.net

This proposal has been superseded by a proposal from 2011-01-27.

Description of the change

Makes the parser look at serializable menuitems. This is also dependent on the serializable menuitem branch, but I can't be dependent on two. Please ignore that file :)

To post a comment you must log in.
Revision history for this message
Mikkel Kamstrup Erlandsen (kamstrup) wrote :

How does this branch relate to https://code.launchpad.net/~ted/dbusmenu/serializable-menuitem/+merge/47604 ? They look identical?

review: Needs Information
196. By Ted Gould

Updating to serializeable menuitem branch. Some function prototype changes.

197. By Ted Gould

Fix changing prototypes.

Unmerged revisions

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file '.bzrignore'
2--- .bzrignore 2011-01-26 23:19:47 +0000
3+++ .bzrignore 2011-01-26 23:19:47 +0000
4@@ -220,6 +220,9 @@
5 libdbusmenu-gtk/DbusmenuGtk-0.4.vapi
6 libdbusmenu-gtk/dbusmenu-gtk-0.4.pc
7 libdbusmenu-gtk/dbusmenu-gtk3-0.4.pc
8+libdbusmenu-gtk/libdbusmenu_gtk_la-serializablemenuitem.lo
9+docs/libdbusmenu-gtk/reference/html/DbusmenuGtkSerializableMenuItem.html
10+docs/libdbusmenu-gtk/reference/tmpl/serializablemenuitem.sgml
11 libdbusmenu-gtk/libdbusmenu_gtk_la-parser.lo
12 test-gtk-parser
13 test-gtk-parser-test
14
15=== modified file 'docs/libdbusmenu-gtk/reference/Makefile.am'
16--- docs/libdbusmenu-gtk/reference/Makefile.am 2010-11-23 21:19:52 +0000
17+++ docs/libdbusmenu-gtk/reference/Makefile.am 2011-01-26 23:19:47 +0000
18@@ -54,7 +54,7 @@
19
20 # Header files to ignore when scanning.
21 # e.g. IGNORE_HFILES=gtkdebug.h gtkintl.h
22-IGNORE_HFILES=
23+IGNORE_HFILES=genericmenuitem.h
24
25 # Images to copy into HTML directory.
26 # e.g. HTML_IMAGES=$(top_srcdir)/gtk/stock-icons/stock_about_24.png
27
28=== modified file 'docs/libdbusmenu-gtk/reference/libdbusmenu-gtk-docs.sgml'
29--- docs/libdbusmenu-gtk/reference/libdbusmenu-gtk-docs.sgml 2010-06-09 16:24:31 +0000
30+++ docs/libdbusmenu-gtk/reference/libdbusmenu-gtk-docs.sgml 2011-01-26 23:19:47 +0000
31@@ -13,8 +13,8 @@
32 <title>API</title>
33 <xi:include href="xml/menu.xml"/>
34 <xi:include href="xml/client.xml"/>
35- <xi:include href="xml/genericmenuitem.xml"/>
36 <xi:include href="xml/menuitem.xml"/>
37+ <xi:include href="xml/serializablemenuitem.xml"/>
38
39 </chapter>
40 <chapter id="object-tree">
41
42=== modified file 'libdbusmenu-glib/client.c'
43--- libdbusmenu-glib/client.c 2011-01-26 23:12:22 +0000
44+++ libdbusmenu-glib/client.c 2011-01-26 23:19:47 +0000
45@@ -120,6 +120,15 @@
46 guint timestamp;
47 };
48
49+typedef struct _type_handler_t type_handler_t;
50+struct _type_handler_t {
51+ DbusmenuClient * client;
52+ DbusmenuClientTypeHandler cb;
53+ DbusmenuClientTypeDestroyHandler destroy_cb;
54+ gpointer user_data;
55+ gchar * type;
56+};
57+
58
59 #define DBUSMENU_CLIENT_GET_PRIVATE(o) (DBUSMENU_CLIENT(o)->priv)
60 #define DBUSMENU_INTERFACE "com.canonical.dbusmenu"
61@@ -148,6 +157,7 @@
62 static void menuproxy_build_cb (GObject * object, GAsyncResult * res, gpointer user_data);
63 static void menuproxy_name_changed_cb (GObject * object, GParamSpec * pspec, gpointer user_data);
64 static void menuproxy_signal_cb (GDBusProxy * proxy, gchar * sender, gchar * signal, GVariant * params, gpointer user_data);
65+static void type_handler_destroy (gpointer user_data);
66
67 /* Globals */
68 static GDBusNodeInfo * dbusmenu_node_info = NULL;
69@@ -310,7 +320,7 @@
70 priv->dbusproxy = 0;
71
72 priv->type_handlers = g_hash_table_new_full(g_str_hash, g_str_equal,
73- g_free, NULL);
74+ g_free, type_handler_destroy);
75
76 priv->delayed_idle = 0;
77 priv->delayed_property_list = g_array_new(TRUE, FALSE, sizeof(gchar *));
78@@ -1153,17 +1163,17 @@
79 gboolean handled = FALSE;
80
81 const gchar * type;
82- DbusmenuClientTypeHandler newfunc = NULL;
83+ type_handler_t * th = NULL;
84
85 type = dbusmenu_menuitem_property_get(propdata->item, DBUSMENU_MENUITEM_PROP_TYPE);
86 if (type != NULL) {
87- newfunc = g_hash_table_lookup(priv->type_handlers, type);
88+ th = (type_handler_t *)g_hash_table_lookup(priv->type_handlers, type);
89 } else {
90- newfunc = g_hash_table_lookup(priv->type_handlers, DBUSMENU_CLIENT_TYPES_DEFAULT);
91+ th = (type_handler_t *)g_hash_table_lookup(priv->type_handlers, DBUSMENU_CLIENT_TYPES_DEFAULT);
92 }
93
94- if (newfunc != NULL) {
95- handled = newfunc(propdata->item, propdata->parent, propdata->client);
96+ if (th != NULL && th->cb != NULL) {
97+ handled = th->cb(propdata->item, propdata->parent, propdata->client, th->user_data);
98 }
99
100 #ifdef MASSIVEDEBUGGING
101@@ -1679,6 +1689,19 @@
102 return priv->root;
103 }
104
105+/* Remove the type handler when we're all done with it */
106+static void
107+type_handler_destroy (gpointer user_data)
108+{
109+ type_handler_t * th = (type_handler_t *)user_data;
110+ if (th->destroy_cb != NULL) {
111+ th->destroy_cb(th->client, th->type, th->user_data);
112+ }
113+ g_free(th->type);
114+ g_free(th);
115+ return;
116+}
117+
118 /**
119 dbusmenu_client_add_type_handler:
120 @client: Client where we're getting types coming in
121@@ -1703,6 +1726,37 @@
122 gboolean
123 dbusmenu_client_add_type_handler (DbusmenuClient * client, const gchar * type, DbusmenuClientTypeHandler newfunc)
124 {
125+ return dbusmenu_client_add_type_handler_full(client, type, newfunc, NULL, NULL);
126+}
127+
128+/**
129+ dbusmenu_client_add_type_handler_full:
130+ @client: Client where we're getting types coming in
131+ @type: A text string that will be matched with the 'type'
132+ property on incoming menu items
133+ @newfunc: The function that will be executed with those new
134+ items when they come in.
135+ @user_data: Data passed to @newfunc when it is called
136+ @destroy_func: A function that is called when the type handler is
137+ removed (usually on client destruction) which will free
138+ the resources in @user_data.
139+
140+ This function connects into the type handling of the #DbusmenuClient.
141+ Every new menuitem that comes in immediately gets asked for it's
142+ properties. When we get those properties we check the 'type'
143+ property and look to see if it matches a handler that is known
144+ by the client. If so, the @newfunc function is executed on that
145+ #DbusmenuMenuitem. If not, then the DbusmenuClient::new-menuitem
146+ signal is sent.
147+
148+ In the future the known types will be sent to the server so that it
149+ can make choices about the menu item types availble.
150+
151+ Return value: If registering the new type was successful.
152+*/
153+gboolean
154+dbusmenu_client_add_type_handler_full (DbusmenuClient * client, const gchar * type, DbusmenuClientTypeHandler newfunc, gpointer user_data, DbusmenuClientTypeDestroyHandler destroy_func)
155+{
156 g_return_val_if_fail(DBUSMENU_IS_CLIENT(client), FALSE);
157 g_return_val_if_fail(type != NULL, FALSE);
158
159@@ -1723,6 +1777,14 @@
160 return FALSE;
161 }
162
163- g_hash_table_insert(priv->type_handlers, g_strdup(type), newfunc);
164+ type_handler_t * th = g_new0(type_handler_t, 1);
165+ th->client = client;
166+ th->cb = newfunc;
167+ th->destroy_cb = destroy_func;
168+ th->user_data = user_data;
169+ th->type = g_strdup(type);
170+
171+ g_hash_table_insert(priv->type_handlers, g_strdup(type), th);
172 return TRUE;
173 }
174+
175
176=== modified file 'libdbusmenu-glib/client.h'
177--- libdbusmenu-glib/client.h 2010-11-18 03:07:51 +0000
178+++ libdbusmenu-glib/client.h 2011-01-26 23:19:47 +0000
179@@ -110,7 +110,8 @@
180 DbusmenuClientPrivate * priv;
181 };
182
183-typedef gboolean (*DbusmenuClientTypeHandler) (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client);
184+typedef gboolean (*DbusmenuClientTypeHandler) (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client, gpointer user_data);
185+typedef void (*DbusmenuClientTypeDestroyHandler) (DbusmenuClient * client, const gchar * type, gpointer user_data);
186
187 GType dbusmenu_client_get_type (void);
188 DbusmenuClient * dbusmenu_client_new (const gchar * name,
189@@ -119,6 +120,11 @@
190 gboolean dbusmenu_client_add_type_handler (DbusmenuClient * client,
191 const gchar * type,
192 DbusmenuClientTypeHandler newfunc);
193+gboolean dbusmenu_client_add_type_handler_full (DbusmenuClient * client,
194+ const gchar * type,
195+ DbusmenuClientTypeHandler newfunc,
196+ gpointer user_data,
197+ DbusmenuClientTypeDestroyHandler destory_func);
198 void dbusmenu_client_send_event (DbusmenuClient * client,
199 gint id,
200 const gchar * name,
201
202=== modified file 'libdbusmenu-gtk/Makefile.am'
203--- libdbusmenu-gtk/Makefile.am 2011-01-26 23:19:47 +0000
204+++ libdbusmenu-gtk/Makefile.am 2011-01-26 23:19:47 +0000
205@@ -24,7 +24,8 @@
206 client.h \
207 menu.h \
208 menuitem.h \
209- parser.h
210+ parser.h \
211+ serializablemenuitem.h
212
213 libdbusmenu_gtk_la_SOURCES = \
214 client.h \
215@@ -36,7 +37,9 @@
216 menuitem.h \
217 menuitem.c \
218 parser.h \
219- parser.c
220+ parser.c \
221+ serializablemenuitem.h \
222+ serializablemenuitem.c
223
224 libdbusmenu_gtk_la_LDFLAGS = \
225 -version-info $(LIBDBUSMENU_CURRENT):$(LIBDBUSMENU_REVISION):$(LIBDBUSMENU_AGE) \
226
227=== modified file 'libdbusmenu-gtk/client.c'
228--- libdbusmenu-gtk/client.c 2011-01-18 21:59:36 +0000
229+++ libdbusmenu-gtk/client.c 2011-01-26 23:19:47 +0000
230@@ -54,8 +54,8 @@
231 static void move_child (DbusmenuMenuitem * mi, DbusmenuMenuitem * child, guint new, guint old, DbusmenuGtkClient * gtkclient);
232 static void item_activate (DbusmenuClient * client, DbusmenuMenuitem * mi, guint timestamp, gpointer userdata);
233
234-static gboolean new_item_normal (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client);
235-static gboolean new_item_seperator (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client);
236+static gboolean new_item_normal (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client, gpointer user_data);
237+static gboolean new_item_seperator (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client, gpointer user_data);
238
239 static void process_visible (DbusmenuMenuitem * mi, GtkMenuItem * gmi, GVariant * value);
240 static void process_sensitive (DbusmenuMenuitem * mi, GtkMenuItem * gmi, GVariant * value);
241@@ -684,7 +684,7 @@
242 /* The base type handler that builds a plain ol'
243 GtkMenuItem to represent, well, the GtkMenuItem */
244 static gboolean
245-new_item_normal (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client)
246+new_item_normal (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client, gpointer user_data)
247 {
248 g_return_val_if_fail(DBUSMENU_IS_MENUITEM(newitem), FALSE);
249 g_return_val_if_fail(DBUSMENU_IS_GTKCLIENT(client), FALSE);
250@@ -719,7 +719,7 @@
251 /* Type handler for the seperators where it builds
252 a GtkSeparator to act as the GtkMenuItem */
253 static gboolean
254-new_item_seperator (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client)
255+new_item_seperator (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client, gpointer user_data)
256 {
257 g_return_val_if_fail(DBUSMENU_IS_MENUITEM(newitem), FALSE);
258 g_return_val_if_fail(DBUSMENU_IS_GTKCLIENT(client), FALSE);
259
260=== modified file 'libdbusmenu-gtk/dbusmenu-gtk.h'
261--- libdbusmenu-gtk/dbusmenu-gtk.h 2011-01-21 16:35:55 +0000
262+++ libdbusmenu-gtk/dbusmenu-gtk.h 2011-01-26 23:19:47 +0000
263@@ -36,5 +36,6 @@
264 #include <libdbusmenu-gtk/client.h>
265 #include <libdbusmenu-gtk/menu.h>
266 #include <libdbusmenu-gtk/menuitem.h>
267+#include <libdbusmenu-gtk/serializablemenuitem.h>
268
269 #endif /* __DBUSMENU_GLIB_H__ */
270
271=== modified file 'libdbusmenu-gtk/menuitem.h'
272--- libdbusmenu-gtk/menuitem.h 2010-12-13 13:40:01 +0000
273+++ libdbusmenu-gtk/menuitem.h 2011-01-26 23:19:47 +0000
274@@ -26,8 +26,8 @@
275 <http://www.gnu.org/licenses/>
276 */
277
278-#ifndef __DBUSMENU_GTKMENUITEM_H__
279-#define __DBUSMENU_GTKMENUITEM_H__ 1
280+#ifndef DBUSMENU_GTK_MENUITEM_H__
281+#define DBUSMENU_GTK_MENUITEM_H__ 1
282
283 #include <glib.h>
284 #include <gdk-pixbuf/gdk-pixbuf.h>
285
286=== modified file 'libdbusmenu-gtk/parser.c'
287--- libdbusmenu-gtk/parser.c 2011-01-26 23:19:47 +0000
288+++ libdbusmenu-gtk/parser.c 2011-01-26 23:19:47 +0000
289@@ -28,6 +28,7 @@
290
291 #include "parser.h"
292 #include "menuitem.h"
293+#include "serializablemenuitem.h"
294
295 #define CACHED_MENUITEM "dbusmenu-gtk-parser-cached-item"
296
297@@ -240,13 +241,23 @@
298 }
299 }
300
301+/* Turn a widget into a dbusmenu item depending on the type of GTK
302+ object that it is. */
303 static DbusmenuMenuitem *
304 construct_dbusmenu_for_widget (GtkWidget * widget)
305 {
306- DbusmenuMenuitem *mi = dbusmenu_menuitem_new ();
307+ /* If it's a subclass of our serializable menu item then we can
308+ use its own build function */
309+ if (DBUSMENU_IS_GTK_SERIALIZABLE_MENU_ITEM(widget)) {
310+ DbusmenuGtkSerializableMenuItem * smi = DBUSMENU_GTK_SERIALIZABLE_MENU_ITEM(widget);
311+ return dbusmenu_gtk_serializable_menu_item_build_dbusmenu_menuitem(smi);
312+ }
313
314+ /* If it's a standard GTK Menu Item we need to do some of our own work */
315 if (GTK_IS_MENU_ITEM (widget))
316 {
317+ DbusmenuMenuitem *mi = dbusmenu_menuitem_new ();
318+
319 gboolean visible = FALSE;
320 gboolean sensitive = FALSE;
321 if (GTK_IS_SEPARATOR_MENU_ITEM (widget))
322@@ -379,11 +390,12 @@
323 "notify",
324 G_CALLBACK (widget_notify_cb),
325 mi);
326+ return mi;
327 }
328
329- return mi;
330-
331- return NULL;
332+ /* If it's none of those we're going to just create a
333+ generic menuitem as a place holder for it. */
334+ return dbusmenu_menuitem_new();
335 }
336
337 static void
338
339=== added file 'libdbusmenu-gtk/serializablemenuitem.c'
340--- libdbusmenu-gtk/serializablemenuitem.c 1970-01-01 00:00:00 +0000
341+++ libdbusmenu-gtk/serializablemenuitem.c 2011-01-26 23:19:47 +0000
342@@ -0,0 +1,288 @@
343+/*
344+An object to act as a base class for easy GTK widgets that can be
345+transfered over dbusmenu.
346+
347+Copyright 2011 Canonical Ltd.
348+
349+Authors:
350+ Ted Gould <ted@canonical.com>
351+
352+This program is free software: you can redistribute it and/or modify it
353+under the terms of either or both of the following licenses:
354+
355+1) the GNU Lesser General Public License version 3, as published by the
356+Free Software Foundation; and/or
357+2) the GNU Lesser General Public License version 2.1, as published by
358+the Free Software Foundation.
359+
360+This program is distributed in the hope that it will be useful, but
361+WITHOUT ANY WARRANTY; without even the implied warranties of
362+MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
363+PURPOSE. See the applicable version of the GNU Lesser General Public
364+License for more details.
365+
366+You should have received a copy of both the GNU Lesser General Public
367+License version 3 and version 2.1 along with this program. If not, see
368+<http://www.gnu.org/licenses/>
369+*/
370+
371+#ifdef HAVE_CONFIG_H
372+#include "config.h"
373+#endif
374+
375+#include "client.h"
376+#include "serializablemenuitem.h"
377+
378+/**
379+ DbusmenuGtkSerializableMenuItemPrivate:
380+ @mi: Menuitem to watch the property changes from
381+*/
382+struct _DbusmenuGtkSerializableMenuItemPrivate {
383+ DbusmenuMenuitem * mi;
384+};
385+
386+/* Properties */
387+enum {
388+ PROP_0,
389+ PROP_MENUITEM
390+};
391+
392+/* Private macro, only used in object init */
393+#define DBUSMENU_GTK_SERIALIZABLE_MENU_ITEM_GET_PRIVATE(o) \
394+(G_TYPE_INSTANCE_GET_PRIVATE ((o), DBUSMENU_TYPE_GTK_SERIALIZABLE_MENU_ITEM, DbusmenuGtkSerializableMenuItemPrivate))
395+
396+/* Function prototypes */
397+static void dbusmenu_gtk_serializable_menu_item_class_init (DbusmenuGtkSerializableMenuItemClass *klass);
398+static void dbusmenu_gtk_serializable_menu_item_init (DbusmenuGtkSerializableMenuItem *self);
399+static void dbusmenu_gtk_serializable_menu_item_dispose (GObject *object);
400+static void dbusmenu_gtk_serializable_menu_item_finalize (GObject *object);
401+static void set_property (GObject * obj,
402+ guint id,
403+ const GValue * value,
404+ GParamSpec * pspec);
405+static void get_property (GObject * obj,
406+ guint id,
407+ GValue * value,
408+ GParamSpec * pspec);
409+
410+/* GObject boiler plate */
411+G_DEFINE_TYPE (DbusmenuGtkSerializableMenuItem, dbusmenu_gtk_serializable_menu_item, GTK_TYPE_MENU_ITEM);
412+
413+/* Initialize the stuff in the class structure */
414+static void
415+dbusmenu_gtk_serializable_menu_item_class_init (DbusmenuGtkSerializableMenuItemClass *klass)
416+{
417+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
418+
419+ g_type_class_add_private (klass, sizeof (DbusmenuGtkSerializableMenuItemPrivate));
420+
421+ object_class->dispose = dbusmenu_gtk_serializable_menu_item_dispose;
422+ object_class->finalize = dbusmenu_gtk_serializable_menu_item_finalize;
423+ object_class->set_property = set_property;
424+ object_class->get_property = get_property;
425+
426+ g_object_class_install_property (object_class, PROP_MENUITEM,
427+ g_param_spec_object(DBUSMENU_GTK_SERIALIZABLE_MENU_ITEM_PROP_MENUITEM, "DBusmenu Menuitem attached to item",
428+ "A menuitem who's properties are being watched and where changes should be watched for updates. It is the responsibility of subclasses to set up the signal handlers for those property changes.",
429+ DBUSMENU_TYPE_MENUITEM,
430+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
431+
432+ return;
433+}
434+
435+/* Initialize the object structures and private structure */
436+static void
437+dbusmenu_gtk_serializable_menu_item_init (DbusmenuGtkSerializableMenuItem *self)
438+{
439+ self->priv = DBUSMENU_GTK_SERIALIZABLE_MENU_ITEM_GET_PRIVATE(self);
440+
441+ self->priv->mi = NULL;
442+
443+ return;
444+}
445+
446+/* Free all references to objects */
447+static void
448+dbusmenu_gtk_serializable_menu_item_dispose (GObject *object)
449+{
450+ DbusmenuGtkSerializableMenuItem * smi = DBUSMENU_GTK_SERIALIZABLE_MENU_ITEM(object);
451+ g_return_if_fail(smi != NULL);
452+
453+ if (smi->priv->mi != NULL) {
454+ g_object_unref(G_OBJECT(smi->priv->mi));
455+ smi->priv->mi = NULL;
456+ }
457+
458+
459+ G_OBJECT_CLASS (dbusmenu_gtk_serializable_menu_item_parent_class)->dispose (object);
460+ return;
461+}
462+
463+/* Free memory */
464+static void
465+dbusmenu_gtk_serializable_menu_item_finalize (GObject *object)
466+{
467+
468+
469+
470+ G_OBJECT_CLASS (dbusmenu_gtk_serializable_menu_item_parent_class)->finalize (object);
471+ return;
472+}
473+
474+/* Set an object property */
475+static void
476+set_property (GObject * obj, guint id, const GValue * value, GParamSpec * pspec)
477+{
478+ DbusmenuGtkSerializableMenuItem * smi = DBUSMENU_GTK_SERIALIZABLE_MENU_ITEM(obj);
479+
480+ switch (id) {
481+ case PROP_MENUITEM:
482+ smi->priv->mi = g_value_get_object(value);
483+ break;
484+ default:
485+ g_return_if_reached();
486+ break;
487+ }
488+
489+ return;
490+}
491+
492+/* Get an object property */
493+static void
494+get_property (GObject * obj, guint id, GValue * value, GParamSpec * pspec)
495+{
496+ DbusmenuGtkSerializableMenuItem * smi = DBUSMENU_GTK_SERIALIZABLE_MENU_ITEM(obj);
497+
498+ switch (id) {
499+ case PROP_MENUITEM:
500+ g_value_set_object(value, smi->priv->mi);
501+ break;
502+ default:
503+ g_return_if_reached();
504+ break;
505+ }
506+
507+ return;
508+}
509+
510+/**
511+ dbusmenu_gtk_serializable_menu_item_build_dbusmenu_menuitem:
512+ @smi: #DbusmenuGtkSerializableMenuItem to build a #DbusmenuMenuitem mirroring
513+
514+ This function is for menu items that are instanciated from
515+ GTK and have their properites set using GTK functions. This
516+ builds a #DbusmenuMenuitem that then has the properties that
517+ should be sent over the bus to create a new item of this
518+ type on the other side.
519+
520+ Return value: (transfer full) A #DbusmenuMenuitem who's values will be
521+ set by this object.
522+*/
523+DbusmenuMenuitem *
524+dbusmenu_gtk_serializable_menu_item_build_dbusmenu_menuitem (DbusmenuGtkSerializableMenuItem * smi)
525+{
526+ g_return_val_if_fail(DBUSMENU_IS_GTK_SERIALIZABLE_MENU_ITEM(smi), NULL);
527+
528+ DbusmenuGtkSerializableMenuItemClass * klass = DBUSMENU_GTK_SERIALIZABLE_MENU_ITEM_GET_CLASS(smi);
529+ if (klass->build_dbusmenu_menuitem != NULL) {
530+ return klass->build_dbusmenu_menuitem(smi);
531+ }
532+
533+ return NULL;
534+}
535+
536+/* Callback to the generic type handler */
537+typedef struct _type_handler_t type_handler_t;
538+struct _type_handler_t {
539+ DbusmenuGtkSerializableMenuItemClass * class;
540+ GType type;
541+};
542+
543+/* Handle the type with this item. */
544+static gboolean
545+type_handler (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client, gpointer user_data)
546+{
547+ type_handler_t * th = (type_handler_t *)user_data;
548+
549+ DbusmenuGtkSerializableMenuItem * smi = DBUSMENU_GTK_SERIALIZABLE_MENU_ITEM(g_object_new(th->type, NULL));
550+ g_return_val_if_fail(smi != NULL, FALSE);
551+
552+ dbusmenu_gtk_serializable_menu_item_set_dbusmenu_menuitem(smi, newitem);
553+ dbusmenu_gtkclient_newitem_base(DBUSMENU_GTKCLIENT(client), newitem, GTK_MENU_ITEM(smi), parent);
554+
555+ return TRUE;
556+}
557+
558+/* Destruction is inevitable */
559+static void
560+type_destroy_handler (DbusmenuClient * client, const gchar * type, gpointer user_data)
561+{
562+ g_return_if_fail(user_data != NULL);
563+ type_handler_t * th = (type_handler_t *)user_data;
564+ g_type_class_unref(th->class);
565+ g_free(user_data);
566+ return;
567+}
568+
569+/**
570+ dbusmenu_gtk_serializable_menu_item_register_to_client:
571+ @client: #DbusmenuClient that we should register a type at.
572+ @item_type: The #GType of a class that is a subclass of #DbusmenuGtkSerializableMenuItem
573+
574+ Registers a generic handler for dealing with all subclasses of
575+ #DbusmenuGtkSerializableMenuItem. This handler responds to the callback,
576+ creates a new object and attaches it to the appropriate #DbusmenuMenuitem
577+ object.
578+*/
579+void
580+dbusmenu_gtk_serializable_menu_item_register_to_client (DbusmenuClient * client, GType item_type)
581+{
582+ g_return_if_fail(g_type_is_a(item_type, DBUSMENU_TYPE_GTK_SERIALIZABLE_MENU_ITEM));
583+
584+ gpointer type_class = g_type_class_ref(item_type);
585+ g_return_if_fail(type_class != NULL);
586+
587+ DbusmenuGtkSerializableMenuItemClass * class = DBUSMENU_GTK_SERIALIZABLE_MENU_ITEM_CLASS(type_class);
588+
589+ if (class->get_type_string == NULL) {
590+ g_type_class_unref(type_class);
591+ g_error("No 'get_type_string' in subclass of DbusmenuGtkSerializableMenuItem");
592+ return;
593+ }
594+
595+ /* Register type */
596+ type_handler_t * th = g_new0(type_handler_t, 1);
597+ th->class = class;
598+ th->type = item_type;
599+ if (!dbusmenu_client_add_type_handler_full(client, class->get_type_string(), type_handler, th, type_destroy_handler)) {
600+ type_destroy_handler(client, class->get_type_string(), th);
601+ }
602+
603+ /* Register defaults */
604+ /* TODO: Need API on another branch */
605+
606+ return;
607+}
608+
609+/**
610+ dbusmenu_gtk_serializable_menu_item_set_dbusmenu_menuitem:
611+ @smi: #DbusmenuGtkSerializableMenuItem to set the @DbusmenuGtkSerializableMenuItem::dbusmenu-menuitem of
612+ @mi: Menuitem to get the properties from
613+
614+ This function is used on the server side to signal to the object
615+ that it should get its' property change events from @mi instead
616+ of expecting calls to its' API. A call to this function sets the
617+ property and subclasses should listen to the notify signal to
618+ pick up this property being set.
619+*/
620+void
621+dbusmenu_gtk_serializable_menu_item_set_dbusmenu_menuitem (DbusmenuGtkSerializableMenuItem * smi, DbusmenuMenuitem * mi)
622+{
623+ g_return_if_fail(DBUSMENU_IS_GTK_SERIALIZABLE_MENU_ITEM(smi));
624+ g_return_if_fail(mi != NULL);
625+
626+ smi->priv->mi = mi;
627+ g_object_notify(G_OBJECT(smi), DBUSMENU_GTK_SERIALIZABLE_MENU_ITEM_PROP_MENUITEM);
628+
629+ return;
630+}
631
632=== added file 'libdbusmenu-gtk/serializablemenuitem.h'
633--- libdbusmenu-gtk/serializablemenuitem.h 1970-01-01 00:00:00 +0000
634+++ libdbusmenu-gtk/serializablemenuitem.h 2011-01-26 23:19:47 +0000
635@@ -0,0 +1,108 @@
636+/*
637+An object to act as a base class for easy GTK widgets that can be
638+transfered over dbusmenu.
639+
640+Copyright 2011 Canonical Ltd.
641+
642+Authors:
643+ Ted Gould <ted@canonical.com>
644+
645+This program is free software: you can redistribute it and/or modify it
646+under the terms of either or both of the following licenses:
647+
648+1) the GNU Lesser General Public License version 3, as published by the
649+Free Software Foundation; and/or
650+2) the GNU Lesser General Public License version 2.1, as published by
651+the Free Software Foundation.
652+
653+This program is distributed in the hope that it will be useful, but
654+WITHOUT ANY WARRANTY; without even the implied warranties of
655+MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
656+PURPOSE. See the applicable version of the GNU Lesser General Public
657+License for more details.
658+
659+You should have received a copy of both the GNU Lesser General Public
660+License version 3 and version 2.1 along with this program. If not, see
661+<http://www.gnu.org/licenses/>
662+*/
663+
664+#ifndef DBUSMENU_GTK_SERIALIZABLE_MENU_ITEM_H__
665+#define DBUSMENU_GTK_SERIALIZABLE_MENU_ITEM_H__ 1
666+
667+#include <glib.h>
668+#include <glib-object.h>
669+#include <gtk/gtk.h>
670+#include <libdbusmenu-glib/menuitem.h>
671+#include <libdbusmenu-glib/client.h>
672+
673+G_BEGIN_DECLS
674+
675+#define DBUSMENU_TYPE_GTK_SERIALIZABLE_MENU_ITEM (dbusmenu_gtk_serializable_menu_item_get_type ())
676+#define DBUSMENU_GTK_SERIALIZABLE_MENU_ITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), DBUSMENU_TYPE_GTK_SERIALIZABLE_MENU_ITEM, DbusmenuGtkSerializableMenuItem))
677+#define DBUSMENU_GTK_SERIALIZABLE_MENU_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), DBUSMENU_TYPE_GTK_SERIALIZABLE_MENU_ITEM, DbusmenuGtkSerializableMenuItemClass))
678+#define DBUSMENU_IS_GTK_SERIALIZABLE_MENU_ITEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), DBUSMENU_TYPE_GTK_SERIALIZABLE_MENU_ITEM))
679+#define DBUSMENU_IS_GTK_SERIALIZABLE_MENU_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), DBUSMENU_TYPE_GTK_SERIALIZABLE_MENU_ITEM))
680+#define DBUSMENU_GTK_SERIALIZABLE_MENU_ITEM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), DBUSMENU_TYPE_GTK_SERIALIZABLE_MENU_ITEM, DbusmenuGtkSerializableMenuItemClass))
681+
682+#define DBUSMENU_GTK_SERIALIZABLE_MENU_ITEM_PROP_MENUITEM "dbusmenu-menuitem"
683+
684+typedef struct _DbusmenuGtkSerializableMenuItem DbusmenuGtkSerializableMenuItem;
685+typedef struct _DbusmenuGtkSerializableMenuItemClass DbusmenuGtkSerializableMenuItemClass;
686+typedef struct _DbusmenuGtkSerializableMenuItemPrivate DbusmenuGtkSerializableMenuItemPrivate;
687+
688+/**
689+ DbusmenuGtkSerializableMenuItemClass:
690+ @parent_class: Inherit from GtkMenuItem
691+ @get_type_string: Static function to get a string describing this type
692+ @get_default_properties: Return a hashtable of defaults for the menu item type
693+ @build_dbusmenu_menuitem: Build a menuitem that can be sent over dbus
694+ @_dbusmenu_gtk_serializable_menu_item_reserved1: Reserved for future use.
695+ @_dbusmenu_gtk_serializable_menu_item_reserved2: Reserved for future use.
696+ @_dbusmenu_gtk_serializable_menu_item_reserved3: Reserved for future use.
697+ @_dbusmenu_gtk_serializable_menu_item_reserved4: Reserved for future use.
698+ @_dbusmenu_gtk_serializable_menu_item_reserved5: Reserved for future use.
699+ @_dbusmenu_gtk_serializable_menu_item_reserved6: Reserved for future use.
700+*/
701+struct _DbusmenuGtkSerializableMenuItemClass {
702+ GtkMenuItemClass parent_class;
703+
704+ /* Subclassable functions */
705+ const gchar * (*get_type_string) (void);
706+ GHashTable * (*get_default_properties) (void);
707+
708+ DbusmenuMenuitem * (*build_dbusmenu_menuitem) (DbusmenuGtkSerializableMenuItem * smi);
709+
710+ /* Signals */
711+
712+
713+
714+ /* Empty Space */
715+ /*< Private >*/
716+ void (*_dbusmenu_gtk_serializable_menu_item_reserved1) (void);
717+ void (*_dbusmenu_gtk_serializable_menu_item_reserved2) (void);
718+ void (*_dbusmenu_gtk_serializable_menu_item_reserved3) (void);
719+ void (*_dbusmenu_gtk_serializable_menu_item_reserved4) (void);
720+ void (*_dbusmenu_gtk_serializable_menu_item_reserved5) (void);
721+ void (*_dbusmenu_gtk_serializable_menu_item_reserved6) (void);
722+};
723+
724+/**
725+ DbusmenuGtkSerializableMenuItem:
726+ @parent: Inherit from GtkMenuItem
727+ @priv: Blind structure of private variables
728+*/
729+struct _DbusmenuGtkSerializableMenuItem {
730+ GtkMenuItem parent;
731+
732+ DbusmenuGtkSerializableMenuItemPrivate * priv;
733+};
734+
735+GType dbusmenu_gtk_serializable_menu_item_get_type (void);
736+
737+DbusmenuMenuitem * dbusmenu_gtk_serializable_menu_item_build_dbusmenu_menuitem (DbusmenuGtkSerializableMenuItem * smi);
738+void dbusmenu_gtk_serializable_menu_item_register_to_client (DbusmenuClient * client, GType item_type);
739+void dbusmenu_gtk_serializable_menu_item_set_dbusmenu_menuitem (DbusmenuGtkSerializableMenuItem * smi, DbusmenuMenuitem * mi);
740+
741+G_END_DECLS
742+
743+#endif

Subscribers

People subscribed via source and target branches