~ubuntu-branches/ubuntu/lucid/libdbusmenu/lucid

« back to all changes in this revision

Viewing changes to libdbusmenu-glib/client.c

  • Committer: Bazaar Package Importer
  • Author(s): Ted Gould
  • Date: 2010-01-08 08:42:59 UTC
  • mfrom: (1.1.8 upstream)
  • Revision ID: james.westby@ubuntu.com-20100108084259-y18hsadt6tqu7yto
Tags: 0.2.0-0ubuntu1
* 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.

Show diffs side-by-side

added added

removed removed

Lines of Context:
34
34
#include <libxml/tree.h>
35
35
 
36
36
#include "client.h"
 
37
#include "menuitem.h"
37
38
#include "dbusmenu-client.h"
38
39
#include "server-marshal.h"
39
40
 
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);
107
108
 
215
216
        DbusmenuClientPrivate * priv = DBUSMENU_CLIENT_GET_PRIVATE(object);
216
217
 
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;
220
221
        }
221
222
        if (priv->menuproxy != NULL) {
307
308
 
308
309
/* Annoying little wrapper to make the right function update */
309
310
static void
310
 
layout_update (DBusGProxy * proxy, gint revision, DbusmenuClient * client)
 
311
layout_update (DBusGProxy * proxy, gint revision, guint parent, DbusmenuClient * client)
311
312
{
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 */
322
323
static void
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)
324
325
{
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>");
 
327
        GValue valstr = {0};
 
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);
327
332
        #endif
328
333
 
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);
334
339
 
335
 
        dbusmenu_menuitem_property_set(menuitem, property, value);
 
340
        dbusmenu_menuitem_property_set_value(menuitem, property, value);
336
341
        return;
337
342
}
338
343
 
351
356
        DbusmenuMenuitem * menuitem = dbusmenu_menuitem_find_id(priv->root, id);
352
357
        g_return_if_fail(menuitem != NULL);
353
358
 
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);
355
362
        return;
356
363
}
357
364
 
360
367
dbus_owner_change (DBusGProxy * proxy, const gchar * name, const gchar * prev, const gchar * new, DbusmenuClient * client)
361
368
{
362
369
        DbusmenuClientPrivate * priv = DBUSMENU_CLIENT_GET_PRIVATE(client);
 
370
        /* g_debug("Owner change: %s %s %s", name, prev, new); */
363
371
 
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
369
377
                return;
370
378
        }
371
379
 
372
 
        if (g_strcmp0(new, priv->dbus_name)) {
 
380
        if (g_strcmp0(name, priv->dbus_name)) {
373
381
                /* Again, someone else's service. */
374
382
                return;
375
383
        }
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);
467
476
                return;
468
477
        }
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);
480
490
                return;
481
491
        }
482
492
        g_object_add_weak_pointer(G_OBJECT(priv->menuproxy), (gpointer *)&priv->menuproxy);
488
498
                priv->dbusproxy = NULL;
489
499
        }
490
500
 
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);
493
504
 
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);
497
508
 
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);
500
511
 
501
512
        update_layout(client);
502
513
 
564
575
static void
565
576
get_properties_helper (gpointer key, gpointer value, gpointer data)
566
577
{
567
 
        dbusmenu_menuitem_property_set((DbusmenuMenuitem *)data, (gchar *)key, (gchar *)value);
 
578
        dbusmenu_menuitem_property_set_value((DbusmenuMenuitem *)data, (gchar *)key, (GValue *)value);
568
579
        return;
569
580
}
570
581
 
606
617
        const gchar * type;
607
618
        DbusmenuClientTypeHandler newfunc = NULL;
608
619
        
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);
612
623
        } else {
647
658
menuitem_activate (DbusmenuMenuitem * mi, DbusmenuClient * client)
648
659
{
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);
 
661
        GValue value = {0};
 
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);
651
665
        return;
652
666
}
653
667
 
689
703
                        propdata->item    = item;
690
704
                        propdata->parent  = parent;
691
705
 
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);
693
708
                } else {
694
709
                        g_warning("Unable to allocate memory to get properties for menuitem.  This menuitem will never be realized.");
695
710
                }
771
786
 
772
787
/* When the layout property returns, here's where we take care of that. */
773
788
static void
774
 
update_layout_cb (DBusGProxy * proxy, DBusGProxyCall * call, void * data)
 
789
update_layout_cb (DBusGProxy * proxy, guint rev, gchar * xml, GError * error, void * data)
775
790
{
776
791
        DbusmenuClient * client = DBUSMENU_CLIENT(data);
777
792
        DbusmenuClientPrivate * priv = DBUSMENU_CLIENT_GET_PRIVATE(client);
778
793
 
779
 
        GError * error = NULL;
780
 
        GValue value = {0};
781
 
 
782
 
        priv->layoutcall = NULL;
783
 
        if (!dbus_g_proxy_end_call(proxy, call, &error, G_TYPE_VALUE, &value, G_TYPE_INVALID)) {
 
794
        if (error != NULL) {
784
795
                g_warning("Getting layout failed on client %s object %s: %s", priv->dbus_name, priv->dbus_object, error->message);
785
 
                g_error_free(error);
786
796
                return;
787
797
        }
788
798
 
789
 
        const gchar * xml = g_value_get_string(&value);
790
 
        /* g_debug("Got layout string: %s", xml); */
791
 
        gint rev = parse_layout(client, xml);
792
 
 
793
 
        if (rev == 0) {
 
799
        if (!parse_layout(client, xml)) {
794
800
                g_warning("Unable to parse layout!");
795
801
                return;
796
802
        }
797
803
 
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.");
802
809
        #endif 
816
823
{
817
824
        DbusmenuClientPrivate * priv = DBUSMENU_CLIENT_GET_PRIVATE(client);
818
825
 
819
 
        if (priv->propproxy == NULL) {
 
826
        if (priv->menuproxy == NULL) {
820
827
                return;
821
828
        }
822
829
 
824
831
                return;
825
832
        }
826
833
 
827
 
        priv->layoutcall = dbus_g_proxy_begin_call (priv->propproxy,
828
 
                                                    "Get",
829
 
                                                    update_layout_cb,
830
 
                                                    client,
831
 
                                                    NULL,
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 */
 
836
                                                                 update_layout_cb,
 
837
                                                                 client);
835
838
 
836
839
        return;
837
840
}