aboutsummaryrefslogtreecommitdiff
path: root/libdbusmenu-glib
diff options
context:
space:
mode:
authorTed Gould <ted@gould.cx>2011-02-14 22:32:51 -0600
committerTed Gould <ted@gould.cx>2011-02-14 22:32:51 -0600
commiteef89215a5632e7e08b39bab1ab9795b5cdebf7d (patch)
treeb5b967f8a9e290b6fa54f5b3331d74ad087209db /libdbusmenu-glib
parent1f1eb89cbf0317ea9e464354cd47b11502efc9de (diff)
parent931994f499108dec95c7e6c9022848667b69848f (diff)
downloadlibdbusmenu-eef89215a5632e7e08b39bab1ab9795b5cdebf7d.tar.gz
libdbusmenu-eef89215a5632e7e08b39bab1ab9795b5cdebf7d.tar.bz2
libdbusmenu-eef89215a5632e7e08b39bab1ab9795b5cdebf7d.zip
Merging in the no-xml based layout branch
Diffstat (limited to 'libdbusmenu-glib')
-rw-r--r--libdbusmenu-glib/client.c135
-rw-r--r--libdbusmenu-glib/dbus-menu.xml76
-rw-r--r--libdbusmenu-glib/menuitem-private.h4
-rw-r--r--libdbusmenu-glib/menuitem.c44
-rw-r--r--libdbusmenu-glib/menuitem.h11
-rw-r--r--libdbusmenu-glib/server.c69
6 files changed, 159 insertions, 180 deletions
diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c
index 9502bfd..6a9dc23 100644
--- a/libdbusmenu-glib/client.c
+++ b/libdbusmenu-glib/client.c
@@ -32,9 +32,6 @@ License version 3 and version 2.1 along with this program. If not, see
#include <gio/gio.h>
-#include <libxml/parser.h>
-#include <libxml/tree.h>
-
#include "client.h"
#include "menuitem.h"
#include "menuitem-private.h"
@@ -151,9 +148,8 @@ static void layout_update (GDBusProxy * proxy, guint revision, gint parent, Dbus
static void id_prop_update (GDBusProxy * proxy, gint id, gchar * property, GVariant * value, DbusmenuClient * client);
static void id_update (GDBusProxy * proxy, gint id, DbusmenuClient * client);
static void build_proxies (DbusmenuClient * client);
-static gint parse_node_get_id (xmlNodePtr node);
-static DbusmenuMenuitem * parse_layout_xml(DbusmenuClient * client, xmlNodePtr node, DbusmenuMenuitem * item, DbusmenuMenuitem * parent, GDBusProxy * proxy);
-static gint parse_layout (DbusmenuClient * client, const gchar * layout);
+static DbusmenuMenuitem * parse_layout_xml(DbusmenuClient * client, GVariant * layout, DbusmenuMenuitem * item, DbusmenuMenuitem * parent, GDBusProxy * proxy);
+static gint parse_layout (DbusmenuClient * client, GVariant * layout);
static void update_layout_cb (GObject * proxy, GAsyncResult * res, gpointer data);
static void update_layout (DbusmenuClient * client);
static void menuitem_get_properties_cb (GVariant * properties, GError * error, gpointer data);
@@ -1103,40 +1099,6 @@ menuproxy_signal_cb (GDBusProxy * proxy, gchar * sender, gchar * signal, GVarian
return;
}
-/* Get the ID attribute of the node, parse it and
- return it. Also we're checking to ensure the node
- is a 'menu' here. */
-static gint
-parse_node_get_id (xmlNodePtr node)
-{
- if (node == NULL) {
- return -1;
- }
- if (node->type != XML_ELEMENT_NODE) {
- return -1;
- }
- if (g_strcmp0((gchar *)node->name, "menu") != 0) {
- /* This kills some nodes early */
- g_warning("XML Node is not 'menu' it is '%s'", node->name);
- return -1;
- }
-
- xmlAttrPtr attrib;
- for (attrib = node->properties; attrib != NULL; attrib = attrib->next) {
- if (g_strcmp0((gchar *)attrib->name, "id") == 0) {
- if (attrib->children != NULL) {
- gint id = (guint)g_ascii_strtoll((gchar *)attrib->children->content, NULL, 10);
- /* g_debug ("Found ID: %d", id); */
- return id;
- }
- break;
- }
- }
-
- g_warning("Unable to find an ID on the node");
- return -1;
-}
-
/* This is the callback for the properties on a menu item. There
should be all of them in the Hash, and they we use foreach to
copy them into the menuitem.
@@ -1439,10 +1401,14 @@ parse_layout_update (DbusmenuMenuitem * item, DbusmenuClient * client)
/* Parse recursively through the XML and make it into
objects as need be */
static DbusmenuMenuitem *
-parse_layout_xml(DbusmenuClient * client, xmlNodePtr node, DbusmenuMenuitem * item, DbusmenuMenuitem * parent, GDBusProxy * proxy)
+parse_layout_xml(DbusmenuClient * client, GVariant * layout, DbusmenuMenuitem * item, DbusmenuMenuitem * parent, GDBusProxy * proxy)
{
+ if (layout == NULL) {
+ return NULL;
+ }
+
/* First verify and figure out what we've got */
- gint id = parse_node_get_id(node);
+ gint id = g_variant_get_int32(g_variant_get_child_value(layout, 0));
if (id < 0) {
return NULL;
}
@@ -1454,20 +1420,26 @@ parse_layout_xml(DbusmenuClient * client, xmlNodePtr node, DbusmenuMenuitem * it
g_return_val_if_fail(id == dbusmenu_menuitem_get_id(item), NULL);
/* Some variables */
- xmlNodePtr children;
- guint position;
+ GVariantIter children;
+ g_variant_iter_init(&children, g_variant_get_child_value(layout, 2));
+ GVariant * child;
+
+ guint position = 0;
GList * oldchildren = g_list_copy(dbusmenu_menuitem_get_children(item));
/* g_debug("Starting old children: %d", g_list_length(oldchildren)); */
/* Go through all the XML Nodes and make sure that we have menuitems
to cover those XML nodes. */
- for (children = node->children, position = 0; children != NULL; children = children->next, position++) {
+ while ((child = g_variant_iter_next_value(&children)) != NULL) {
/* g_debug("Looking at child: %d", position); */
- gint childid = parse_node_get_id(children);
+ if (g_variant_is_of_type(child, G_VARIANT_TYPE_VARIANT)) {
+ child = g_variant_get_variant(child);
+ }
+
+ gint childid = g_variant_get_int32(g_variant_get_child_value(child, 0));
if (childid < 0) {
/* Don't increment the position when there isn't a valid
node in the XML tree. It's probably a comment. */
- position--;
continue;
}
DbusmenuMenuitem * childmi = NULL;
@@ -1500,6 +1472,8 @@ parse_layout_xml(DbusmenuClient * client, xmlNodePtr node, DbusmenuMenuitem * it
dbusmenu_menuitem_child_reorder(item, childmi, position);
parse_layout_update(childmi, client);
}
+
+ position++;
}
/* Remove any children that are no longer used by this version of
@@ -1522,14 +1496,20 @@ parse_layout_xml(DbusmenuClient * client, xmlNodePtr node, DbusmenuMenuitem * it
}
/* now it's time to recurse down the tree. */
- children = node->children;
+ g_variant_iter_init(&children, g_variant_get_child_value(layout, 2));
+
+ child = g_variant_iter_next_value(&children);
GList * childmis = dbusmenu_menuitem_get_children(item);
- while (children != NULL && childmis != NULL) {
- gint xmlid = parse_node_get_id(children);
+ while (child != NULL && childmis != NULL) {
+ if (g_variant_is_of_type(child, G_VARIANT_TYPE_VARIANT)) {
+ child = g_variant_get_variant(child);
+ }
+
+ gint xmlid = g_variant_get_int32(g_variant_get_child_value(child, 0));
/* If this isn't a valid menu item we need to move on
until we have one. This avoids things like comments. */
if (xmlid < 0) {
- children = children->next;
+ child = g_variant_iter_next_value(&children);
continue;
}
@@ -1538,13 +1518,14 @@ parse_layout_xml(DbusmenuClient * client, xmlNodePtr node, DbusmenuMenuitem * it
g_debug("Recursing parse_layout_xml. XML ID: %d MI ID: %d", xmlid, miid);
#endif
- parse_layout_xml(client, children, DBUSMENU_MENUITEM(childmis->data), item, proxy);
+ parse_layout_xml(client, child, DBUSMENU_MENUITEM(childmis->data), item, proxy);
- children = children->next;
+ child = g_variant_iter_next_value(&children);
childmis = g_list_next(childmis);
}
- if (children != NULL) {
- g_warning("Sync failed, now we've got extra XML nodes.");
+
+ if (child != NULL) {
+ g_warning("Sync failed, now we've got extra layout nodes.");
}
if (childmis != NULL) {
g_warning("Sync failed, now we've got extra menu items.");
@@ -1556,7 +1537,7 @@ parse_layout_xml(DbusmenuClient * client, xmlNodePtr node, DbusmenuMenuitem * it
/* Take the layout passed to us over DBus and turn it into
a set of beautiful objects */
static gint
-parse_layout (DbusmenuClient * client, const gchar * layout)
+parse_layout (DbusmenuClient * client, GVariant * layout)
{
#ifdef MASSIVEDEBUGGING
g_debug("Client Parsing a new layout");
@@ -1564,17 +1545,6 @@ parse_layout (DbusmenuClient * client, const gchar * layout)
DbusmenuClientPrivate * priv = DBUSMENU_CLIENT_GET_PRIVATE(client);
- xmlDocPtr xmldoc;
-
- /* No one should need more characters than this! */
- xmldoc = xmlReadMemory(layout, g_utf8_strlen(layout, 1024*1024), "dbusmenu.xml", NULL, 0);
-
- xmlNodePtr root = xmlDocGetRootElement(xmldoc);
-
- if (root == NULL) {
- g_warning("Unable to get root node of menu XML");
- }
-
DbusmenuMenuitem * oldroot = priv->root;
if (priv->root == NULL) {
@@ -1583,11 +1553,10 @@ parse_layout (DbusmenuClient * client, const gchar * layout)
parse_layout_update(priv->root, client);
}
- priv->root = parse_layout_xml(client, root, priv->root, NULL, priv->menuproxy);
- xmlFreeDoc(xmldoc);
+ priv->root = parse_layout_xml(client, layout, priv->root, NULL, priv->menuproxy);
if (priv->root == NULL) {
- g_warning("Unable to parse layout on client %s object %s: %s", priv->dbus_name, priv->dbus_object, layout);
+ g_warning("Unable to parse layout on client %s object %s: %s", priv->dbus_name, priv->dbus_object, g_variant_print(layout, TRUE));
}
if (priv->root != oldroot) {
@@ -1628,14 +1597,10 @@ update_layout_cb (GObject * proxy, GAsyncResult * res, gpointer data)
goto out;
}
- guint rev;
- gchar * xml;
-
- g_variant_get(params, "(us)", &rev, &xml);
- g_variant_unref(params);
+ guint rev = g_variant_get_uint32(g_variant_get_child_value(params, 0));
+ GVariant * layout = g_variant_get_child_value(params, 1);
- guint parseable = parse_layout(client, xml);
- g_free(xml);
+ guint parseable = parse_layout(client, layout);
if (parseable == 0) {
g_warning("Unable to parse layout!");
@@ -1661,6 +1626,10 @@ out:
priv->layoutcall = NULL;
}
+ if (params != NULL) {
+ g_variant_unref(params);
+ }
+
g_object_unref(G_OBJECT(client));
return;
}
@@ -1688,10 +1657,20 @@ update_layout (DbusmenuClient * client)
priv->layoutcall = g_cancellable_new();
+ GVariantBuilder tupleb;
+ g_variant_builder_init(&tupleb, G_VARIANT_TYPE_TUPLE);
+
+ g_variant_builder_add_value(&tupleb, g_variant_new_int32(0)); // root
+ g_variant_builder_add_value(&tupleb, g_variant_new_int32(-1)); // recurse
+ g_variant_builder_add_value(&tupleb, g_variant_new_array(G_VARIANT_TYPE_STRING, NULL, 0)); // props
+
+ GVariant * args = g_variant_builder_end(&tupleb);
+ // g_debug("Args (type: %s): %s", g_variant_get_type_string(args), g_variant_print(args, TRUE));
+
g_object_ref(G_OBJECT(client));
g_dbus_proxy_call(priv->menuproxy,
"GetLayout",
- g_variant_new("(i)", 0), /* root */
+ args,
G_DBUS_CALL_FLAGS_NONE,
-1, /* timeout */
priv->layoutcall, /* cancellable */
diff --git a/libdbusmenu-glib/dbus-menu.xml b/libdbusmenu-glib/dbus-menu.xml
index b5f5627..da14c63 100644
--- a/libdbusmenu-glib/dbus-menu.xml
+++ b/libdbusmenu-glib/dbus-menu.xml
@@ -174,34 +174,38 @@ License version 3 and version 2.1 along with this program. If not, see
<!-- Functions -->
<method name="GetLayout">
- <dox:d><![CDATA[
- Provides an XML representation of the menu hierarchy
-
- XML syntax:
-
- @verbatim
-<menu id="0"> # Root container
- <menu id="1"> # First level menu, for example "File"
- <menu id="2"/> ~ Second level menu, for example "Open"
- <menu id="3"/>
- ...
- </menu>
- <menu id="4"> # Another first level menu, say "Edit"
- ...
- </menu>
- ...
-</menu>
- @endverbatim
- ]]></dox:d>
+ <dox:d>
+ Provides the layout and propertiers that are attached to the entries
+ that are in the layout. It only gives the items that are children
+ of the item that is specified in @parentId. It will return all of the
+ properties or specific ones depending of the value in @propertyNames.
+
+ The format is recursive, where the second 'v' is in the same format
+ as the original 'a(ia(sv)a(v))'. If the @recursive flag is set to
+ less than one then the second array will have zero entries.
+ </dox:d>
<arg type="i" name="parentId" direction="in">
<dox:d>The ID of the parent node for the layout. For
grabbing the layout from the root node use zero.</dox:d>
</arg>
+ <arg type="i" name="recurse" direction="in">
+ <dox:d>
+ The amount of levels of recursion to use. -1, as value would
+ deliver all the items under the @parentId.
+ </dox:d>
+ </arg>
+ <arg type="as" name="propertyNames" direction="in" >
+ <dox:d>
+ The list of item properties we are
+ interested in. If there are no entries in the list all of
+ the properties will be sent.
+ </dox:d>
+ </arg>
<arg type="u" name="revision" direction="out">
<dox:d>The revision number of the layout. For matching
with layoutUpdated signals.</dox:d>
</arg>
- <arg type="s" name="layout" direction="out">
+ <arg type="(ia{sv}av)" name="layout" direction="out">
<dox:d>The layout as an XML string of IDs.</dox:d>
</arg>
</method>
@@ -236,33 +240,21 @@ License version 3 and version 2.1 along with this program. If not, see
</arg>
</method>
- <method name="GetChildren">
- <annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="DBusMenuItemList"/>
- <arg type="i" name="id" direction="in" />
- <arg type="as" name="propertyNames" direction="in" />
- <arg type="a(ia{sv})" name="properties" direction="out" />
- </method>
-
<method name="GetProperty">
- <arg type="i" name="id" direction="in" />
- <arg type="s" name="name" direction="in" />
- <arg type="v" name="value" direction="out" />
- </method>
-
- <method name="GetProperties">
<dox:d>
- Returns multiple properties in one call. This is more efficient than
- GetProperty.
-
+ Get a signal property on a single item. This is not useful if you're
+ going to implement this interface, it should only be used if you're
+ debugging via a commandline tool.
</dox:d>
- <annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="QVariantMap"/>
- <arg type="i" name="id" direction="in" >
- <dox:d>The item whose properties we want to retrieve.</dox:d>
+ <arg type="i" name="id" direction="in">
+ <dox:d>the id of the item which received the event</dox:d>
</arg>
- <arg type="as" name="propertyNames" direction="in" >
- <dox:d>List of string name of the properties we want. If the list contains no entries, all properties are sent.</dox:d>
+ <arg type="s" name="name" direction="in">
+ <dox:d>the name of the property to get</dox:d>
+ </arg>
+ <arg type="v" name="value" direction="out">
+ <dox:d>the value of the property</dox:d>
</arg>
- <arg type="a{sv}" name="properties" direction="out" />
</method>
<method name="Event">
diff --git a/libdbusmenu-glib/menuitem-private.h b/libdbusmenu-glib/menuitem-private.h
index 7f8ba23..89319dc 100644
--- a/libdbusmenu-glib/menuitem-private.h
+++ b/libdbusmenu-glib/menuitem-private.h
@@ -33,10 +33,10 @@ License version 3 and version 2.1 along with this program. If not, see
G_BEGIN_DECLS
-void dbusmenu_menuitem_buildxml (DbusmenuMenuitem * mi, GPtrArray * array);
+GVariant * dbusmenu_menuitem_build_variant (DbusmenuMenuitem * mi, const gchar ** properties, gint recurse);
gboolean dbusmenu_menuitem_realized (DbusmenuMenuitem * mi);
void dbusmenu_menuitem_set_realized (DbusmenuMenuitem * mi);
-GVariant * dbusmenu_menuitem_properties_variant (DbusmenuMenuitem * mi);
+GVariant * dbusmenu_menuitem_properties_variant (DbusmenuMenuitem * mi, const gchar ** properties);
gboolean dbusmenu_menuitem_property_is_default (DbusmenuMenuitem * mi, const gchar * property);
G_END_DECLS
diff --git a/libdbusmenu-glib/menuitem.c b/libdbusmenu-glib/menuitem.c
index 3f85efa..7ea54e2 100644
--- a/libdbusmenu-glib/menuitem.c
+++ b/libdbusmenu-glib/menuitem.c
@@ -1264,7 +1264,7 @@ variant_helper (gpointer in_key, gpointer in_value, gpointer user_data)
Return Value: A GVariant of type "a{sv}" or NULL on error.
*/
GVariant *
-dbusmenu_menuitem_properties_variant (DbusmenuMenuitem * mi)
+dbusmenu_menuitem_properties_variant (DbusmenuMenuitem * mi, const gchar ** properties)
{
g_return_val_if_fail(DBUSMENU_IS_MENUITEM(mi), NULL);
@@ -1322,7 +1322,7 @@ dbusmenu_menuitem_get_root (DbusmenuMenuitem * mi)
/**
- dbusmenu_menuitem_buildxml:
+ dbusmenu_menuitem_buildvariant:
@mi: #DbusmenuMenuitem to represent in XML
@array: (element-type utf8): A list of string that will be turned into an XML file
@@ -1332,28 +1332,50 @@ dbusmenu_menuitem_get_root (DbusmenuMenuitem * mi)
start tag and one that is a closing tag. It will allow it's
children to place their own tags in the array in between those two.
*/
-void
-dbusmenu_menuitem_buildxml (DbusmenuMenuitem * mi, GPtrArray * array)
+GVariant *
+dbusmenu_menuitem_build_variant (DbusmenuMenuitem * mi, const gchar ** properties, gint recurse)
{
- g_return_if_fail(DBUSMENU_IS_MENUITEM(mi));
+ g_return_val_if_fail(DBUSMENU_IS_MENUITEM(mi), NULL);
gint id = 0;
if (!dbusmenu_menuitem_get_root(mi)) {
id = dbusmenu_menuitem_get_id(mi);
}
+ /* This is the tuple that'll build up being a representation of
+ this entry */
+ GVariantBuilder tupleb;
+ g_variant_builder_init(&tupleb, G_VARIANT_TYPE_TUPLE);
+
+ /* Add our ID */
+ g_variant_builder_add_value(&tupleb, g_variant_new_int32(id));
+
+ /* Figure out the properties */
+ GVariant * props = dbusmenu_menuitem_properties_variant(mi, properties);
+ if (props != NULL) {
+ g_variant_builder_add_value(&tupleb, props);
+ } else {
+ g_variant_builder_add_value(&tupleb, g_variant_parse(G_VARIANT_TYPE("a{sv}"), "[ ]", NULL, NULL, NULL));
+ }
+
+ /* Pillage the children */
GList * children = dbusmenu_menuitem_get_children(mi);
- if (children == NULL) {
- g_ptr_array_add(array, g_strdup_printf("<menu id=\"%d\"/>", id));
+ if (children == NULL && recurse != 0) {
+ g_variant_builder_add_value(&tupleb, g_variant_new_array(G_VARIANT_TYPE_VARIANT, NULL, 0));
} else {
- g_ptr_array_add(array, g_strdup_printf("<menu id=\"%d\">", id));
+ GVariantBuilder childrenbuilder;
+ g_variant_builder_init(&childrenbuilder, G_VARIANT_TYPE_ARRAY);
+
for ( ; children != NULL; children = children->next) {
- dbusmenu_menuitem_buildxml(DBUSMENU_MENUITEM(children->data), array);
+ GVariant * child = dbusmenu_menuitem_build_variant(DBUSMENU_MENUITEM(children->data), properties, recurse - 1);
+
+ g_variant_builder_add_value(&childrenbuilder, g_variant_new_variant(child));
}
- g_ptr_array_add(array, g_strdup("</menu>"));
+
+ g_variant_builder_add_value(&tupleb, g_variant_builder_end(&childrenbuilder));
}
- return;
+ return g_variant_builder_end(&tupleb);
}
typedef struct {
diff --git a/libdbusmenu-glib/menuitem.h b/libdbusmenu-glib/menuitem.h
index a4c7611..c36e0e9 100644
--- a/libdbusmenu-glib/menuitem.h
+++ b/libdbusmenu-glib/menuitem.h
@@ -111,14 +111,15 @@ struct _DbusmenuMenuitem
typedef void (*dbusmenu_menuitem_about_to_show_cb) (DbusmenuMenuitem * mi, gpointer user_data);
/**
- * dbusmenu_menuitem_buildxml_slot_t:
+ * dbusmenu_menuitem_buildvariant_slot_t:
* @mi: (in): Menu item that should be built from
- * @stringarray: (inout) (transfer none) (array) (element-type utf8): An array of strings that can be combined into an XML file.
*
* This is the function that is called to represent this menu item
- * as an XML fragment. Should call it's own children.
+ * as a variant. Should call it's own children.
+ *
+ * Return value: (transfer full) A variant representing this item and it's children
*/
-typedef void (*dbusmenu_menuitem_buildxml_slot_t) (DbusmenuMenuitem * mi, GPtrArray* stringarray);
+typedef GVariant * (*dbusmenu_menuitem_buildvariant_slot_t) (DbusmenuMenuitem * mi, gchar ** properties);
/**
* DbusmenuMenuitemClass:
@@ -155,7 +156,7 @@ struct _DbusmenuMenuitemClass
void (*realized) (void);
/* Virtual functions */
- dbusmenu_menuitem_buildxml_slot_t buildxml;
+ dbusmenu_menuitem_buildvariant_slot_t buildvariant;
void (*handle_event) (DbusmenuMenuitem * mi, const gchar * name, GVariant * value, guint timestamp);
void (*send_about_to_show) (DbusmenuMenuitem * mi, void (*cb) (DbusmenuMenuitem * mi, gpointer user_data), gpointer cb_data);
diff --git a/libdbusmenu-glib/server.c b/libdbusmenu-glib/server.c
index 362e2cb..4fe7bdc 100644
--- a/libdbusmenu-glib/server.c
+++ b/libdbusmenu-glib/server.c
@@ -472,17 +472,6 @@ set_property (GObject * obj, guint id, const GValue * value, GParamSpec * pspec)
}
static void
-xmlarray_foreach_free (gpointer arrayentry, gpointer userdata)
-{
- if (arrayentry != NULL) {
- /* g_debug("Freeing pointer: %s", (gchar *)arrayentry); */
- g_free(arrayentry);
- }
-
- return;
-}
-
-static void
get_property (GObject * obj, guint id, GValue * value, GParamSpec * pspec)
{
DbusmenuServerPrivate * priv = DBUSMENU_SERVER_GET_PRIVATE(obj);
@@ -1026,26 +1015,28 @@ bus_get_layout (DbusmenuServer * server, GVariant * params, GDBusMethodInvocatio
{
DbusmenuServerPrivate * priv = DBUSMENU_SERVER_GET_PRIVATE(server);
- gint parent = 0;
- g_variant_get(params, "(i)", &parent);
+ /* Input */
+ gint parent = g_variant_get_int32(g_variant_get_child_value(params, 0));
+ gint recurse = g_variant_get_int32(g_variant_get_child_value(params, 1));
+ const gchar ** props = g_variant_get_strv(g_variant_get_child_value(params, 2), NULL);
+ /* Output */
guint revision = priv->layout_revision;
- GPtrArray * xmlarray = g_ptr_array_new();
+ GVariant * items = NULL;
- if (parent == 0) {
- if (priv->root == NULL) {
- /* g_debug("Getting layout without root node!"); */
- g_ptr_array_add(xmlarray, g_strdup("<menu id=\"0\"/>"));
- } else {
- dbusmenu_menuitem_buildxml(priv->root, xmlarray);
- }
- } else {
- DbusmenuMenuitem * item = NULL;
- if (priv->root != NULL) {
- item = dbusmenu_menuitem_find_id(priv->root, parent);
- }
+ if (priv->root != NULL) {
+ items = dbusmenu_menuitem_build_variant(priv->root, props, recurse);
+ }
- if (item == NULL) {
+ /* What happens if we don't have anything? */
+ if (items == NULL) {
+ if (parent == 0) {
+ /* We should always have a root, so we'll make up one for
+ right now. */
+ items = g_variant_parse(G_VARIANT_TYPE("(ia{sv}av)"), "(0, [], [])", NULL, NULL, NULL);
+ } else {
+ /* If we were looking for a specific ID that's an error that
+ we should send back, so let's do that. */
g_dbus_method_invocation_return_error(invocation,
error_quark(),
INVALID_MENUITEM_ID,
@@ -1053,23 +1044,17 @@ bus_get_layout (DbusmenuServer * server, GVariant * params, GDBusMethodInvocatio
parent);
return;
}
- dbusmenu_menuitem_buildxml(item, xmlarray);
}
- g_ptr_array_add(xmlarray, NULL);
- /* build string */
- gchar * layout = g_strjoinv("", (gchar **)xmlarray->pdata);
+ /* Build the final variant tuple */
+ GVariantBuilder tuplebuilder;
+ g_variant_builder_init(&tuplebuilder, G_VARIANT_TYPE_TUPLE);
- g_ptr_array_foreach(xmlarray, xmlarray_foreach_free, NULL);
- g_ptr_array_free(xmlarray, TRUE);
+ g_variant_builder_add_value(&tuplebuilder, g_variant_new_uint32(revision));
+ g_variant_builder_add_value(&tuplebuilder, items);
g_dbus_method_invocation_return_value(invocation,
- g_variant_new("(us)",
- revision,
- layout));
-
- g_free(layout);
-
+ g_variant_builder_end(&tuplebuilder));
return;
}
@@ -1143,7 +1128,7 @@ bus_get_properties (DbusmenuServer * server, GVariant * params, GDBusMethodInvoc
return;
}
- GVariant * dict = dbusmenu_menuitem_properties_variant(mi);
+ GVariant * dict = dbusmenu_menuitem_properties_variant(mi, NULL);
g_dbus_method_invocation_return_value(invocation, g_variant_new("(a{sv})", dict));
@@ -1191,7 +1176,7 @@ bus_get_group_properties (DbusmenuServer * server, GVariant * params, GDBusMetho
GVariantBuilder wbuilder;
g_variant_builder_init(&wbuilder, G_VARIANT_TYPE_TUPLE);
g_variant_builder_add(&wbuilder, "i", id);
- GVariant * props = dbusmenu_menuitem_properties_variant(mi);
+ GVariant * props = dbusmenu_menuitem_properties_variant(mi, NULL);
if (props == NULL) {
GError * error = NULL;
@@ -1251,7 +1236,7 @@ serialize_menuitem(gpointer data, gpointer user_data)
gint id = dbusmenu_menuitem_get_id(mi);
g_variant_builder_add_value(&tuple, g_variant_new_int32(id));
- GVariant * props = dbusmenu_menuitem_properties_variant(mi);
+ GVariant * props = dbusmenu_menuitem_properties_variant(mi, NULL);
g_variant_builder_add_value(&tuple, props);
g_variant_builder_add_value(builder, g_variant_builder_end(&tuple));