94
95
static void set_property (GObject * obj, guint id, const GValue * value, GParamSpec * pspec);
95
96
static void get_property (GObject * obj, guint id, GValue * value, GParamSpec * pspec);
96
97
/* Private Funcs */
97
static void layout_update (DBusGProxy * proxy, gint revision, DbusmenuClient * client);
98
static void id_prop_update (DBusGProxy * proxy, guint id, gchar * property, gchar * value, DbusmenuClient * client);
98
static void layout_update (DBusGProxy * proxy, gint revision, guint parent, DbusmenuClient * client);
99
static void id_prop_update (DBusGProxy * proxy, guint id, gchar * property, GValue * value, DbusmenuClient * client);
99
100
static void id_update (DBusGProxy * proxy, guint id, DbusmenuClient * client);
100
101
static void build_proxies (DbusmenuClient * client);
101
102
static guint parse_node_get_id (xmlNodePtr node);
102
103
static DbusmenuMenuitem * parse_layout_xml(DbusmenuClient * client, xmlNodePtr node, DbusmenuMenuitem * item, DbusmenuMenuitem * parent, DBusGProxy * proxy);
103
104
static gint parse_layout (DbusmenuClient * client, const gchar * layout);
104
static void update_layout_cb (DBusGProxy * proxy, DBusGProxyCall * call, void * data);
105
static void update_layout_cb (DBusGProxy * proxy, guint rev, gchar * xml, GError * in_error, void * data);
105
106
static void update_layout (DbusmenuClient * client);
106
107
static void menuitem_get_properties_cb (DBusGProxy * proxy, GHashTable * properties, GError * error, gpointer data);
215
216
DbusmenuClientPrivate * priv = DBUSMENU_CLIENT_GET_PRIVATE(object);
217
218
if (priv->layoutcall != NULL) {
218
dbus_g_proxy_cancel_call(priv->propproxy, priv->layoutcall);
219
dbus_g_proxy_cancel_call(priv->menuproxy, priv->layoutcall);
219
220
priv->layoutcall = NULL;
221
222
if (priv->menuproxy != NULL) {
308
309
/* Annoying little wrapper to make the right function update */
310
layout_update (DBusGProxy * proxy, gint revision, DbusmenuClient * client)
311
layout_update (DBusGProxy * proxy, gint revision, guint parent, DbusmenuClient * client)
312
313
DbusmenuClientPrivate * priv = DBUSMENU_CLIENT_GET_PRIVATE(client);
313
314
priv->current_revision = revision;
320
321
/* Signal from the server that a property has changed
321
322
on one of our menuitems */
323
id_prop_update (DBusGProxy * proxy, guint id, gchar * property, gchar * value, DbusmenuClient * client)
324
id_prop_update (DBusGProxy * proxy, guint id, gchar * property, GValue * value, DbusmenuClient * client)
325
326
#ifdef MASSIVEDEBUGGING
326
g_debug("Property change sent to client for item %d property %s value %s", id, property, g_utf8_strlen(value, 50) < 25 ? value : "<too long>");
328
g_value_init(&valstr, G_TYPE_STRING);
329
g_value_transform(value, &valstr);
330
g_debug("Property change sent to client for item %d property %s value %s", id, property, g_utf8_strlen(g_value_get_string(&valstr), 50) < 25 ? g_value_get_string(&valstr) : "<too long>");
331
g_value_unset(&valstr);
329
334
DbusmenuClientPrivate * priv = DBUSMENU_CLIENT_GET_PRIVATE(client);
332
337
DbusmenuMenuitem * menuitem = dbusmenu_menuitem_find_id(priv->root, id);
333
338
g_return_if_fail(menuitem != NULL);
335
dbusmenu_menuitem_property_set(menuitem, property, value);
340
dbusmenu_menuitem_property_set_value(menuitem, property, value);
351
356
DbusmenuMenuitem * menuitem = dbusmenu_menuitem_find_id(priv->root, id);
352
357
g_return_if_fail(menuitem != NULL);
354
org_ayatana_dbusmenu_get_properties_async(proxy, id, menuitem_get_properties_cb, menuitem);
359
gchar * properties[1] = {NULL}; /* This gets them all */
360
g_debug("Getting properties");
361
org_ayatana_dbusmenu_get_properties_async(proxy, id, (const gchar **)properties, menuitem_get_properties_cb, menuitem);
360
367
dbus_owner_change (DBusGProxy * proxy, const gchar * name, const gchar * prev, const gchar * new, DbusmenuClient * client)
362
369
DbusmenuClientPrivate * priv = DBUSMENU_CLIENT_GET_PRIVATE(client);
370
/* g_debug("Owner change: %s %s %s", name, prev, new); */
364
if (!(new != NULL && prev == NULL)) {
372
if (!(new[0] != '\0' && prev[0] == '\0')) {
365
373
/* If it's not someone new getting on the bus, sorry we
366
374
simply just don't care. It's not that your service isn't
367
375
important to someone, just not us. You'll find the right
464
472
if (error != NULL) {
465
473
g_warning("Unable to get property proxy for %s on %s: %s", priv->dbus_name, priv->dbus_object, error->message);
466
474
g_error_free(error);
475
build_dbus_proxy(client);
469
478
g_object_add_weak_pointer(G_OBJECT(priv->propproxy), (gpointer *)&priv->propproxy);
477
486
if (error != NULL) {
478
487
g_warning("Unable to get dbusmenu proxy for %s on %s: %s", priv->dbus_name, priv->dbus_object, error->message);
479
488
g_error_free(error);
489
build_dbus_proxy(client);
482
492
g_object_add_weak_pointer(G_OBJECT(priv->menuproxy), (gpointer *)&priv->menuproxy);
488
498
priv->dbusproxy = NULL;
491
dbus_g_proxy_add_signal(priv->menuproxy, "LayoutUpdate", G_TYPE_INT, G_TYPE_INVALID);
501
dbus_g_object_register_marshaller(_dbusmenu_server_marshal_VOID__INT_UINT, G_TYPE_NONE, G_TYPE_INT, G_TYPE_UINT, G_TYPE_INVALID);
502
dbus_g_proxy_add_signal(priv->menuproxy, "LayoutUpdate", G_TYPE_INT, G_TYPE_UINT, G_TYPE_INVALID);
492
503
dbus_g_proxy_connect_signal(priv->menuproxy, "LayoutUpdate", G_CALLBACK(layout_update), client, NULL);
494
dbus_g_object_register_marshaller(_dbusmenu_server_marshal_VOID__UINT_STRING_STRING, G_TYPE_NONE, G_TYPE_UINT, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INVALID);
495
dbus_g_proxy_add_signal(priv->menuproxy, "IdPropUpdate", G_TYPE_UINT, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INVALID);
496
dbus_g_proxy_connect_signal(priv->menuproxy, "IdPropUpdate", G_CALLBACK(id_prop_update), client, NULL);
505
dbus_g_object_register_marshaller(_dbusmenu_server_marshal_VOID__UINT_STRING_POINTER, G_TYPE_NONE, G_TYPE_UINT, G_TYPE_STRING, G_TYPE_VALUE, G_TYPE_INVALID);
506
dbus_g_proxy_add_signal(priv->menuproxy, "ItemPropertyUpdated", G_TYPE_UINT, G_TYPE_STRING, G_TYPE_VALUE, G_TYPE_INVALID);
507
dbus_g_proxy_connect_signal(priv->menuproxy, "ItemPropertyUpdated", G_CALLBACK(id_prop_update), client, NULL);
498
dbus_g_proxy_add_signal(priv->menuproxy, "IdUpdate", G_TYPE_UINT, G_TYPE_INVALID);
499
dbus_g_proxy_connect_signal(priv->menuproxy, "IdUpdate", G_CALLBACK(id_update), client, NULL);
509
dbus_g_proxy_add_signal(priv->menuproxy, "ItemUpdated", G_TYPE_UINT, G_TYPE_INVALID);
510
dbus_g_proxy_connect_signal(priv->menuproxy, "ItemUpdated", G_CALLBACK(id_update), client, NULL);
501
512
update_layout(client);
565
576
get_properties_helper (gpointer key, gpointer value, gpointer data)
567
dbusmenu_menuitem_property_set((DbusmenuMenuitem *)data, (gchar *)key, (gchar *)value);
578
dbusmenu_menuitem_property_set_value((DbusmenuMenuitem *)data, (gchar *)key, (GValue *)value);
606
617
const gchar * type;
607
618
DbusmenuClientTypeHandler newfunc = NULL;
609
type = dbusmenu_menuitem_property_get(propdata->item, "type");
620
type = dbusmenu_menuitem_property_get(propdata->item, DBUSMENU_MENUITEM_PROP_TYPE);
610
621
if (type != NULL) {
611
622
newfunc = g_hash_table_lookup(priv->type_handlers, type);
647
658
menuitem_activate (DbusmenuMenuitem * mi, DbusmenuClient * client)
649
660
DbusmenuClientPrivate * priv = DBUSMENU_CLIENT_GET_PRIVATE(client);
650
org_ayatana_dbusmenu_call_async (priv->menuproxy, dbusmenu_menuitem_get_id(mi), menuitem_call_cb, mi);
662
g_value_init(&value, G_TYPE_INT);
663
g_value_set_int(&value, 0);
664
org_ayatana_dbusmenu_event_async (priv->menuproxy, dbusmenu_menuitem_get_id(mi), "clicked", &value, menuitem_call_cb, mi);
689
703
propdata->item = item;
690
704
propdata->parent = parent;
692
org_ayatana_dbusmenu_get_properties_async(proxy, id, menuitem_get_properties_new_cb, propdata);
706
gchar * properties[1] = {NULL}; /* This gets them all */
707
org_ayatana_dbusmenu_get_properties_async(proxy, id, (const gchar **)properties, menuitem_get_properties_new_cb, propdata);
694
709
g_warning("Unable to allocate memory to get properties for menuitem. This menuitem will never be realized.");
772
787
/* When the layout property returns, here's where we take care of that. */
774
update_layout_cb (DBusGProxy * proxy, DBusGProxyCall * call, void * data)
789
update_layout_cb (DBusGProxy * proxy, guint rev, gchar * xml, GError * error, void * data)
776
791
DbusmenuClient * client = DBUSMENU_CLIENT(data);
777
792
DbusmenuClientPrivate * priv = DBUSMENU_CLIENT_GET_PRIVATE(client);
779
GError * error = NULL;
782
priv->layoutcall = NULL;
783
if (!dbus_g_proxy_end_call(proxy, call, &error, G_TYPE_VALUE, &value, G_TYPE_INVALID)) {
784
795
g_warning("Getting layout failed on client %s object %s: %s", priv->dbus_name, priv->dbus_object, error->message);
789
const gchar * xml = g_value_get_string(&value);
790
/* g_debug("Got layout string: %s", xml); */
791
gint rev = parse_layout(client, xml);
799
if (!parse_layout(client, xml)) {
794
800
g_warning("Unable to parse layout!");
798
804
priv->my_revision = rev;
799
805
/* g_debug("Root is now: 0x%X", (unsigned int)priv->root); */
806
priv->layoutcall = NULL;
800
807
#ifdef MASSIVEDEBUGGING
801
808
g_debug("Client signaling layout has changed.");
827
priv->layoutcall = dbus_g_proxy_begin_call (priv->propproxy,
832
G_TYPE_STRING, "org.ayatana.dbusmenu",
833
G_TYPE_STRING, "layout",
834
G_TYPE_INVALID, G_TYPE_VALUE, G_TYPE_INVALID);
834
priv->layoutcall = org_ayatana_dbusmenu_get_layout_async(priv->menuproxy,
835
0, /* Parent is the root */