diff options
author | Ken VanDine <ken.vandine@canonical.com> | 2010-01-08 12:47:52 -0500 |
---|---|---|
committer | Ken VanDine <ken.vandine@canonical.com> | 2010-01-08 12:47:52 -0500 |
commit | f25b2c9f2fb6448506decd9bd89052d3eb94ab4e (patch) | |
tree | dcf63a656d2fb0e26068e800672a00e1c079818d /libdbusmenu-glib/server.c | |
parent | 0ab4e0cd4974e8f2a963b16f9abed2bd6c7eac12 (diff) | |
parent | 214b29a5e3a400b8180bca7f079fbc89ab683644 (diff) | |
download | libdbusmenu-f25b2c9f2fb6448506decd9bd89052d3eb94ab4e.tar.gz libdbusmenu-f25b2c9f2fb6448506decd9bd89052d3eb94ab4e.tar.bz2 libdbusmenu-f25b2c9f2fb6448506decd9bd89052d3eb94ab4e.zip |
* Upstream release 0.2.0
- Remove unused libdbusmenu-qt
- Changing API to be V0.2 for reals
- Adding underline support
- Test suite fixes and automation support
- dbus-dumper tool
- Switch to org.ayatana
- Fixing the handling of typed properties, especially bools.
- Adding GetChildren function for getting a single submenu
- Starting to watch DBus if the proxy builds fail.
- Test suite fixes
- Fixing the consistency between the #defines and what
was used in the code.
* debian/control, debian/libdbusmenu-tools.install: Setting
up a package for the new dbusmenu-dumper tool.
* debian/control: Mentioning nicely that this will cause
indicator-messages << 0.3 and indicator-session << 0.2 to
break.
Diffstat (limited to 'libdbusmenu-glib/server.c')
-rw-r--r-- | libdbusmenu-glib/server.c | 173 |
1 files changed, 133 insertions, 40 deletions
diff --git a/libdbusmenu-glib/server.c b/libdbusmenu-glib/server.c index 84bfffe..0971162 100644 --- a/libdbusmenu-glib/server.c +++ b/libdbusmenu-glib/server.c @@ -30,16 +30,22 @@ License version 3 and version 2.1 along with this program. If not, see #include "config.h" #endif +#include "menuitem-private.h" #include "server.h" #include "server-marshal.h" /* DBus Prototypes */ +static gboolean _dbusmenu_server_get_layout (DbusmenuServer * server, guint parent, guint * revision, gchar ** layout, GError ** error); static gboolean _dbusmenu_server_get_property (DbusmenuServer * server, guint id, gchar * property, gchar ** value, GError ** error); -static gboolean _dbusmenu_server_get_properties (DbusmenuServer * server, guint id, GHashTable ** dict, GError ** error); -static gboolean _dbusmenu_server_call (DbusmenuServer * server, guint id, GError ** error); +static gboolean _dbusmenu_server_get_properties (DbusmenuServer * server, guint id, GPtrArray * properties, GHashTable ** dict, GError ** error); +static gboolean _dbusmenu_server_get_group_properties (DbusmenuServer * server, GArray * ids, GArray * properties, GHashTable ** values, GError ** error); +static gboolean _dbusmenu_server_event (DbusmenuServer * server, guint id, gchar * eventid, GValue * data, GError ** error); +static gboolean _dbusmenu_server_get_children (DbusmenuServer * server, guint id, GPtrArray * properties, GPtrArray ** output, GError ** error); #include "dbusmenu-server.h" +#define DBUSMENU_VERSION_NUMBER 1 + /* Privates, I'll show you mine... */ typedef struct _DbusmenuServerPrivate DbusmenuServerPrivate; @@ -68,7 +74,7 @@ enum { PROP_0, PROP_DBUS_OBJECT, PROP_ROOT_NODE, - PROP_LAYOUT + PROP_VERSION }; /* Errors */ @@ -76,6 +82,7 @@ enum { INVALID_MENUITEM_ID, INVALID_PROPERTY_NAME, UNKNOWN_DBUS_ERROR, + NOT_IMPLEMENTED, LAST_ERROR }; @@ -86,7 +93,7 @@ static void dbusmenu_server_dispose (GObject *object); static void dbusmenu_server_finalize (GObject *object); static void set_property (GObject * obj, guint id, const GValue * value, GParamSpec * pspec); static void get_property (GObject * obj, guint id, GValue * value, GParamSpec * pspec); -static void menuitem_property_changed (DbusmenuMenuitem * mi, gchar * property, gchar * value, DbusmenuServer * server); +static void menuitem_property_changed (DbusmenuMenuitem * mi, gchar * property, GValue * value, DbusmenuServer * server); static void menuitem_child_added (DbusmenuMenuitem * parent, DbusmenuMenuitem * child, guint pos, DbusmenuServer * server); static void menuitem_child_removed (DbusmenuMenuitem * parent, DbusmenuMenuitem * child, DbusmenuServer * server); static void menuitem_signals_create (DbusmenuMenuitem * mi, gpointer data); @@ -122,8 +129,8 @@ dbusmenu_server_class_init (DbusmenuServerClass *class) G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET(DbusmenuServerClass, id_prop_update), NULL, NULL, - _dbusmenu_server_marshal_VOID__UINT_STRING_STRING, - G_TYPE_NONE, 3, G_TYPE_UINT, G_TYPE_STRING, G_TYPE_STRING); + _dbusmenu_server_marshal_VOID__UINT_STRING_POINTER, + G_TYPE_NONE, 3, G_TYPE_UINT, G_TYPE_STRING, G_TYPE_VALUE); /** DbusmenuServer::id-update: @arg0: The #DbusmenuServer emitting the signal. @@ -145,6 +152,7 @@ dbusmenu_server_class_init (DbusmenuServerClass *class) @arg0: The #DbusmenuServer emitting the signal. @arg1: A revision number representing which revision the update represents itself as. + @arg2: The ID of the parent for this update. This signal is emitted any time the layout of the menuitems under this server is changed. @@ -154,8 +162,8 @@ dbusmenu_server_class_init (DbusmenuServerClass *class) G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET(DbusmenuServerClass, layout_update), NULL, NULL, - g_cclosure_marshal_VOID__INT, - G_TYPE_NONE, 1, G_TYPE_INT); + _dbusmenu_server_marshal_VOID__INT_UINT, + G_TYPE_NONE, 2, G_TYPE_INT, G_TYPE_UINT); g_object_class_install_property (object_class, PROP_DBUS_OBJECT, @@ -168,10 +176,10 @@ dbusmenu_server_class_init (DbusmenuServerClass *class) "The base object of the menus that are served", DBUSMENU_TYPE_MENUITEM, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - g_object_class_install_property (object_class, PROP_LAYOUT, - g_param_spec_string(DBUSMENU_SERVER_PROP_LAYOUT, "XML Layout of the menus", - "A simple XML string that describes the layout of the menus", - "<menu />", + g_object_class_install_property (object_class, PROP_VERSION, + g_param_spec_uint(DBUSMENU_SERVER_PROP_VERSION, "Dbusmenu API version", + "The version of the DBusmenu API that we're implementing.", + DBUSMENU_VERSION_NUMBER, DBUSMENU_VERSION_NUMBER, DBUSMENU_VERSION_NUMBER, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); dbus_g_object_type_install_info(DBUSMENU_TYPE_SERVER, &dbus_glib__dbusmenu_server_object_info); @@ -240,11 +248,8 @@ set_property (GObject * obj, guint id, const GValue * value, GParamSpec * pspec) g_debug("Setting root node to NULL"); } priv->layout_revision++; - g_signal_emit(obj, signals[LAYOUT_UPDATE], 0, priv->layout_revision, TRUE); + g_signal_emit(obj, signals[LAYOUT_UPDATE], 0, priv->layout_revision, 0, TRUE); break; - case PROP_LAYOUT: - /* Can't set this, fall through to error */ - g_warning("Can not set property: layout"); default: g_return_if_reached(); break; @@ -276,25 +281,9 @@ get_property (GObject * obj, guint id, GValue * value, GParamSpec * pspec) case PROP_ROOT_NODE: g_value_set_object(value, priv->root); break; - case PROP_LAYOUT: { - GPtrArray * xmlarray = g_ptr_array_new(); - if (priv->root == NULL) { - /* g_debug("Getting layout without root node!"); */ - g_ptr_array_add(xmlarray, g_strdup_printf("<menu revision=\"%d\" />", priv->layout_revision)); - } else { - dbusmenu_menuitem_buildxml(priv->root, xmlarray, priv->layout_revision); - } - g_ptr_array_add(xmlarray, NULL); - - /* build string */ - gchar * finalstring = g_strjoinv("", (gchar **)xmlarray->pdata); - g_value_take_string(value, finalstring); - /* g_debug("Final string: %s", finalstring); */ - - g_ptr_array_foreach(xmlarray, xmlarray_foreach_free, NULL); - g_ptr_array_free(xmlarray, TRUE); + case PROP_VERSION: + g_value_set_uint(value, DBUSMENU_VERSION_NUMBER); break; - } default: g_return_if_reached(); break; @@ -304,7 +293,7 @@ get_property (GObject * obj, guint id, GValue * value, GParamSpec * pspec) } static void -menuitem_property_changed (DbusmenuMenuitem * mi, gchar * property, gchar * value, DbusmenuServer * server) +menuitem_property_changed (DbusmenuMenuitem * mi, gchar * property, GValue * value, DbusmenuServer * server) { g_signal_emit(G_OBJECT(server), signals[ID_PROP_UPDATE], 0, dbusmenu_menuitem_get_id(mi), property, value, TRUE); return; @@ -317,7 +306,7 @@ menuitem_child_added (DbusmenuMenuitem * parent, DbusmenuMenuitem * child, guint /* TODO: We probably need to group the layout update signals to make the number more reasonble. */ DbusmenuServerPrivate * priv = DBUSMENU_SERVER_GET_PRIVATE(server); priv->layout_revision++; - g_signal_emit(G_OBJECT(server), signals[LAYOUT_UPDATE], 0, priv->layout_revision, TRUE); + g_signal_emit(G_OBJECT(server), signals[LAYOUT_UPDATE], 0, priv->layout_revision, 0, TRUE); return; } @@ -328,7 +317,7 @@ menuitem_child_removed (DbusmenuMenuitem * parent, DbusmenuMenuitem * child, Dbu /* TODO: We probably need to group the layout update signals to make the number more reasonble. */ DbusmenuServerPrivate * priv = DBUSMENU_SERVER_GET_PRIVATE(server); priv->layout_revision++; - g_signal_emit(G_OBJECT(server), signals[LAYOUT_UPDATE], 0, priv->layout_revision, TRUE); + g_signal_emit(G_OBJECT(server), signals[LAYOUT_UPDATE], 0, priv->layout_revision, 0, TRUE); return; } @@ -337,7 +326,7 @@ menuitem_child_moved (DbusmenuMenuitem * parent, DbusmenuMenuitem * child, guint { DbusmenuServerPrivate * priv = DBUSMENU_SERVER_GET_PRIVATE(server); priv->layout_revision++; - g_signal_emit(G_OBJECT(server), signals[LAYOUT_UPDATE], 0, priv->layout_revision, TRUE); + g_signal_emit(G_OBJECT(server), signals[LAYOUT_UPDATE], 0, priv->layout_revision, 0, TRUE); return; } @@ -376,6 +365,36 @@ error_quark (void) } /* DBus interface */ +static gboolean +_dbusmenu_server_get_layout (DbusmenuServer * server, guint parent, guint * revision, gchar ** layout, GError ** error) +{ + DbusmenuServerPrivate * priv = DBUSMENU_SERVER_GET_PRIVATE(server); + + *revision = priv->layout_revision; + GPtrArray * xmlarray = g_ptr_array_new(); + + if (parent == 0) { + if (priv->root == NULL) { + /* g_debug("Getting layout without root node!"); */ + g_ptr_array_add(xmlarray, g_strdup_printf("<menu revision=\"%d\" />", priv->layout_revision)); + } else { + dbusmenu_menuitem_buildxml(priv->root, xmlarray, priv->layout_revision); + } + } else { + DbusmenuMenuitem * item = dbusmenu_menuitem_find_id(priv->root, parent); + dbusmenu_menuitem_buildxml(item, xmlarray, priv->layout_revision); + } + g_ptr_array_add(xmlarray, NULL); + + /* build string */ + *layout = g_strjoinv("", (gchar **)xmlarray->pdata); + + g_ptr_array_foreach(xmlarray, xmlarray_foreach_free, NULL); + g_ptr_array_free(xmlarray, TRUE); + + return TRUE; +} + static gboolean _dbusmenu_server_get_property (DbusmenuServer * server, guint id, gchar * property, gchar ** value, GError ** error) { @@ -422,7 +441,7 @@ _dbusmenu_server_get_property (DbusmenuServer * server, guint id, gchar * proper } static gboolean -_dbusmenu_server_get_properties (DbusmenuServer * server, guint id, GHashTable ** dict, GError ** error) +_dbusmenu_server_get_properties (DbusmenuServer * server, guint id, GPtrArray * properties, GHashTable ** dict, GError ** error) { DbusmenuServerPrivate * priv = DBUSMENU_SERVER_GET_PRIVATE(server); DbusmenuMenuitem * mi = dbusmenu_menuitem_find_id(priv->root, id); @@ -444,7 +463,81 @@ _dbusmenu_server_get_properties (DbusmenuServer * server, guint id, GHashTable * } static gboolean -_dbusmenu_server_call (DbusmenuServer * server, guint id, GError ** error) +_dbusmenu_server_get_group_properties (DbusmenuServer * server, GArray * ids, GArray * properties, GHashTable ** values, GError ** error) +{ + if (error != NULL) { + g_set_error(error, + error_quark(), + NOT_IMPLEMENTED, + "The GetGroupProperties function is not implemented, sorry."); + } + return FALSE; +} + +static void +_gvalue_array_append_uint(GValueArray *array, guint i) +{ + GValue value = {0}; + + g_value_init(&value, G_TYPE_UINT); + g_value_set_uint(&value, i); + g_value_array_append(array, &value); + g_value_unset(&value); +} + +static void +_gvalue_array_append_hashtable(GValueArray *array, GHashTable * dict) +{ + GValue value = {0}; + + g_value_init(&value, dbus_g_type_get_map("GHashTable", G_TYPE_STRING, G_TYPE_VALUE)); + g_value_set_boxed(&value, dict); + g_value_array_append(array, &value); + g_value_unset(&value); +} + +static void +serialize_menuitem(gpointer data, gpointer user_data) +{ + DbusmenuMenuitem * mi = DBUSMENU_MENUITEM(data); + GPtrArray * output = (GPtrArray *)(user_data); + + guint id = dbusmenu_menuitem_get_id(mi); + GHashTable * dict = dbusmenu_menuitem_properties_copy(mi); + + GValueArray * item = g_value_array_new(1); + _gvalue_array_append_uint(item, id); + _gvalue_array_append_hashtable(item, dict); + + g_ptr_array_add(output, item); +} + +static gboolean +_dbusmenu_server_get_children (DbusmenuServer * server, guint id, GPtrArray * properties, GPtrArray ** output, GError ** error) +{ + DbusmenuServerPrivate * priv = DBUSMENU_SERVER_GET_PRIVATE(server); + DbusmenuMenuitem * mi = id == 0 ? priv->root : dbusmenu_menuitem_find_id(priv->root, id); + + if (mi == NULL) { + if (error != NULL) { + g_set_error(error, + error_quark(), + INVALID_MENUITEM_ID, + "The ID supplied %d does not refer to a menu item we have", + id); + } + return FALSE; + } + + *output = g_ptr_array_new(); + GList * children = dbusmenu_menuitem_get_children(mi); + g_list_foreach(children, serialize_menuitem, *output); + + return TRUE; +} + +static gboolean +_dbusmenu_server_event (DbusmenuServer * server, guint id, gchar * eventid, GValue * data, GError ** error) { DbusmenuServerPrivate * priv = DBUSMENU_SERVER_GET_PRIVATE(server); DbusmenuMenuitem * mi = dbusmenu_menuitem_find_id(priv->root, id); |