David Barth has proposed merging lp:~dbarth/indicator-me/gwibber-service into lp:indicator-me with lp:~dbarth/indicator-me/character-limit as a prerequisite.
Requested reviews: Indicator Applet Developers (indicator-applet-developers) Big patch to be able to monitor the gwibber service and update the UI. See commit below. -- https://code.launchpad.net/~dbarth/indicator-me/gwibber-service/+merge/21490 Your team ayatana-commits is subscribed to branch lp:indicator-me.
=== modified file 'src/me-service-gwibber.c' --- src/me-service-gwibber.c 2010-03-10 14:39:43 +0000 +++ src/me-service-gwibber.c 2010-03-16 20:51:26 +0000 @@ -1,6 +1,6 @@ /* -Logic to send messages via gwibber +GObject wrapper for the gwibber service Copyright 2010 Canonical Ltd. @@ -20,48 +20,278 @@ with this program. If not, see <http://www.gnu.org/licenses/>. */ +#include "me-service-gwibber.h" + #include <glib.h> + #include <dbus/dbus-glib.h> +#include <dbus/dbus-glib-bindings.h> #define GWIBBER_ADDRESS "com.Gwibber.Service" #define GWIBBER_OBJECT "/com/gwibber/Service" #define GWIBBER_INTERFACE "com.Gwibber.Service" -static DBusGProxy * gwibber_proxy = NULL; - -/* - static */ void -gwibber_response (DBusGProxy * proxy, DBusGProxyCall * call, gpointer data) -{ - g_debug ("gwibber_send_response"); - - return; -} - -static void -setup_gwibber_proxy (void) { - DBusGConnection * bus = dbus_g_bus_get(DBUS_BUS_SESSION, NULL); - g_return_if_fail(bus != NULL); - - if (gwibber_proxy == NULL) { - gwibber_proxy = dbus_g_proxy_new_for_name(bus, - GWIBBER_ADDRESS, - GWIBBER_OBJECT, - GWIBBER_INTERFACE); - } - g_return_if_fail (gwibber_proxy != NULL); +/* gobject infrastructure */ + +typedef struct _GwibberServicePrivate GwibberServicePrivate; +struct _GwibberServicePrivate { + DBusGProxy * dbus_proxy; + DBusGProxy * service_proxy; + int status; + gboolean has_configured_accounts; +}; + +/* Signals */ +enum { + STATUS_CHANGED, + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL] = { 0 }; + +/* Prototypes */ +static void gwibber_service_class_init (GwibberServiceClass *klass); +static void gwibber_service_init (GwibberService *self); +static void gwibber_service_dispose (GObject *object); +static void gwibber_service_finalize (GObject *object); + +static void dbus_namechange (DBusGProxy * proxy, const gchar * name, const gchar * prev, const gchar * new, GwibberService * self); +static void gwibber_exists_cb (DBusGProxy * proxy, gboolean exists, GError * error, gpointer userdata); +static void setup_service_proxy (GwibberService *self); +static void query_account_manager (GwibberService *self); + +G_DEFINE_TYPE (GwibberService, gwibber_service, G_TYPE_OBJECT); + +#define GWIBBER_SERVICE_GET_PRIVATE(o) \ +(G_TYPE_INSTANCE_GET_PRIVATE ((o), GWIBBER_SERVICE_TYPE, GwibberServicePrivate)) + +static void +gwibber_service_class_init (GwibberServiceClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + g_type_class_add_private (klass, sizeof (GwibberServicePrivate)); + + object_class->dispose = gwibber_service_dispose; + object_class->finalize = gwibber_service_finalize; + + signals[STATUS_CHANGED] = g_signal_new(GWIBBER_SERVICE_SIGNAL_STATUS_CHANGED, + G_TYPE_FROM_CLASS(klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET(GwibberServiceClass, status_changed), + NULL, NULL, + g_cclosure_marshal_VOID__UINT, + G_TYPE_NONE, 1, G_TYPE_UINT); + return; +} + +/* Creating an instance of the status provider. We set the variables + and create an TpAccountManager object. It does all the hard + work in this module of tracking MissionControl and enumerating the + accounts and all that jazz. */ +static void +gwibber_service_init (GwibberService *self) +{ + GwibberServicePrivate * priv = GWIBBER_SERVICE_GET_PRIVATE(self); + + priv->dbus_proxy = NULL; + priv->service_proxy = NULL; + priv->status = GWIBBER_SERVICE_STATUS_NOT_RUNNING; + priv->has_configured_accounts = FALSE; + + DBusGConnection * bus = dbus_g_bus_get(DBUS_BUS_SESSION, NULL); + g_return_if_fail(bus != NULL); /* Can't do anymore DBus stuff without this, + all non-DBus stuff should be done */ + + GError * error = NULL; + + /* Set up the dbus Proxy */ + priv->dbus_proxy = dbus_g_proxy_new_for_name_owner (bus, + DBUS_SERVICE_DBUS, + DBUS_PATH_DBUS, + DBUS_INTERFACE_DBUS, + &error); + if (error != NULL) { + g_warning("Unable to connect to DBus events: %s", error->message); + g_error_free(error); + return; + } + + /* Configure the name owner changing */ + dbus_g_proxy_add_signal(priv->dbus_proxy, "NameOwnerChanged", + G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, + G_TYPE_INVALID); + dbus_g_proxy_connect_signal(priv->dbus_proxy, "NameOwnerChanged", + G_CALLBACK(dbus_namechange), + self, NULL); + + org_freedesktop_DBus_name_has_owner_async(priv->dbus_proxy, GWIBBER_ADDRESS, gwibber_exists_cb, self); + + return; +} + +/* Unref the account manager and move on. Sadly, we're + leaving the show. */ +static void +gwibber_service_dispose (GObject *object) +{ + GwibberServicePrivate * priv = GWIBBER_SERVICE_GET_PRIVATE(object); + + if (priv->dbus_proxy != NULL) { + g_object_unref(priv->dbus_proxy); + priv->dbus_proxy = NULL; + } + + if (priv->service_proxy != NULL) { + g_object_unref(priv->service_proxy); + priv->service_proxy = NULL; + } + + G_OBJECT_CLASS (gwibber_service_parent_class)->dispose (object); + return; +} + +/* Pass to superclass */ +static void +gwibber_service_finalize (GObject *object) +{ + G_OBJECT_CLASS (gwibber_service_parent_class)->finalize (object); + return; +} + + +/* Watch for Gwibber coming on and off the bus. */ +static void +dbus_namechange (DBusGProxy * proxy, const gchar * name, const gchar * prev, const gchar * new, GwibberService * self) +{ + g_return_if_fail (IS_GWIBBER_SERVICE (self)); + + GwibberServicePrivate * priv = GWIBBER_SERVICE_GET_PRIVATE(self); + + if (prev[0] == '\0' && g_strcmp0(name, GWIBBER_ADDRESS) == 0) { + g_debug("Gwibber Service coming online"); + priv->status = GWIBBER_SERVICE_STATUS_RUNNING; + if (priv->service_proxy == NULL) + setup_service_proxy (self); + query_account_manager (self); + } + + if (new[0] == '\0' && g_strcmp0(name, GWIBBER_ADDRESS) == 0) { + g_debug("Gwibber Service going offline"); + priv->status = GWIBBER_SERVICE_STATUS_NOT_RUNNING; + g_signal_emit (G_OBJECT (self), GWIBBER_SERVICE_SIGNAL_STATUS_CHANGED_ID, 0, priv->status, TRUE); + } + + return; +} + +static void +get_accounts_response (DBusGProxy * proxy, DBusGProxyCall * call, gpointer data) +{ + GError *error = NULL; + gchar *accounts_string = NULL; + + dbus_g_proxy_end_call (proxy, call, &error, + G_TYPE_STRING, &accounts_string, + G_TYPE_INVALID); + + if (error != NULL) { + g_error_free (error); + g_warning ("GetAccounts: %s", error->message); + return; + } + + /* don't print the accounts string, it contains passwords */ + /* g_debug ("GetAccounts: %s", accounts_string); */ + + g_return_if_fail (IS_GWIBBER_SERVICE (data)); + GwibberServicePrivate * priv = GWIBBER_SERVICE_GET_PRIVATE(data); + g_return_if_fail (priv != NULL); + + priv->status = GWIBBER_SERVICE_STATUS_RUNNING; + priv->has_configured_accounts = g_strrstr (accounts_string, " \"send_enabled\": true,") ? TRUE : FALSE; + + /* trigger a status update */ + g_signal_emit (G_OBJECT (data), + GWIBBER_SERVICE_SIGNAL_STATUS_CHANGED_ID, + 0, priv->status, TRUE); + + return; +} + +static void +query_account_manager (GwibberService *self) +{ + g_return_if_fail (IS_GWIBBER_SERVICE (self)); + + GwibberServicePrivate * priv = GWIBBER_SERVICE_GET_PRIVATE(self); + + if (priv->service_proxy == NULL) { + g_warning ("no service_proxy, can't query for accounts"); + return; + } + + dbus_g_proxy_begin_call(priv->service_proxy, + "GetAccounts", + get_accounts_response, + self, + NULL, + G_TYPE_INVALID); +} + +static void +setup_service_proxy (GwibberService *self) +{ + g_return_if_fail (IS_GWIBBER_SERVICE (self)); + + GwibberServicePrivate * priv = GWIBBER_SERVICE_GET_PRIVATE(self); + + DBusGConnection * bus = dbus_g_bus_get(DBUS_BUS_SESSION, NULL); + g_return_if_fail(bus != NULL); /* Can't do anymore DBus stuff without this, + all non-DBus stuff should be done */ + + if (priv->service_proxy == NULL) { + priv->service_proxy = dbus_g_proxy_new_for_name(bus, + GWIBBER_ADDRESS, + GWIBBER_OBJECT, + GWIBBER_INTERFACE); + } +} + +static void +gwibber_exists_cb (DBusGProxy * proxy, gboolean exists, GError * error, gpointer userdata) +{ + if (error) { + g_warning ("Unable to check if Gwibber is running: %s", error->message); + return; + } + + if (exists) { + setup_service_proxy (GWIBBER_SERVICE (userdata)); + query_account_manager (GWIBBER_SERVICE (userdata)); + } + + return; +} + +GwibberService * gwibber_service_new (void){ + return GWIBBER_SERVICE (g_object_new (GWIBBER_SERVICE_TYPE, NULL)); +} + +static void +send_message_response (DBusGProxy * proxy, DBusGProxyCall * call, gpointer data) +{ + g_debug ("send_message_response"); return; } void -gwibber_send (const gchar *msg) +gwibber_service_send (GwibberService *self, const gchar *msg) { - setup_gwibber_proxy (); + g_return_if_fail (IS_GWIBBER_SERVICE (self)); - if (gwibber_proxy == NULL) { - g_warning ("Can not get a gwibber proxy object"); - } + GwibberServicePrivate * priv = GWIBBER_SERVICE_GET_PRIVATE(self); GValue value = {0}; g_value_init(&value, G_TYPE_STRING); @@ -69,9 +299,17 @@ g_debug ("gwibber_send: %s\n", msg); - dbus_g_proxy_begin_call(gwibber_proxy, + if (priv->service_proxy == NULL) { + setup_service_proxy (self); + if (priv->service_proxy == NULL) { + g_warning ("can't setup service_proxy"); + return; + } + } + + dbus_g_proxy_begin_call(priv->service_proxy, "SendMessage", - gwibber_response, + send_message_response, NULL, NULL, G_TYPE_VALUE, @@ -82,3 +320,24 @@ return; } + +void gwibber_send (const char *msg) +{ + static GwibberService *singleton = NULL; + + if (! singleton) { + singleton = gwibber_service_new (); + } + + gwibber_service_send (singleton, msg); +} + +gboolean +gwibber_service_has_configured_accounts (GwibberService *self) +{ + g_return_val_if_fail (IS_GWIBBER_SERVICE (self), FALSE); + + GwibberServicePrivate * priv = GWIBBER_SERVICE_GET_PRIVATE(self); + + return priv->has_configured_accounts; +} === modified file 'src/me-service-gwibber.h' --- src/me-service-gwibber.h 2010-02-04 20:52:03 +0000 +++ src/me-service-gwibber.h 2010-03-16 20:51:26 +0000 @@ -20,16 +20,56 @@ with this program. If not, see <http://www.gnu.org/licenses/>. */ -#ifndef __ME_SERVICE_GWIBBER_H__ -#define __ME_SERVICE_GWIBBER_H__ +#ifndef __GWIBBER_SERVICE_H__ +#define __GWIBBER_SERVICE_H__ #include <glib.h> +#include <glib-object.h> G_BEGIN_DECLS +#define GWIBBER_SERVICE_TYPE (gwibber_service_get_type ()) +#define GWIBBER_SERVICE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GWIBBER_SERVICE_TYPE, GwibberService)) +#define GWIBBER_SERVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GWIBBER_SERVICE_TYPE, GwibberServiceClass)) +#define IS_GWIBBER_SERVICE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GWIBBER_SERVICE_TYPE)) +#define IS_GWIBBER_SERVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GWIBBER_SERVICE_TYPE)) +#define GWIBBER_SERVICE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GWIBBER_SERVICE_TYPE, GwibberServiceClass)) + +typedef enum +{ + GWIBBER_SERVICE_STATUS_NOT_RUNNING, + /* GWIBBER_SERVICE_STATUS_LOADING_STARTED, + GWIBBER_SERVICE_STATUS_LOADING_COMPLETE, */ + GWIBBER_SERVICE_STATUS_RUNNING, + GWIBBER_SERVICE_STATUS_LAST +} +GwibberServiceStatus; + +#define GWIBBER_SERVICE_SIGNAL_STATUS_CHANGED "status-changed" +#define GWIBBER_SERVICE_SIGNAL_STATUS_CHANGED_ID (g_signal_lookup(GWIBBER_SERVICE_SIGNAL_STATUS_CHANGED, GWIBBER_SERVICE_TYPE)) + +typedef struct _GwibberServiceClass GwibberServiceClass; +struct _GwibberServiceClass { + GObjectClass parent_class; + + /* Signals */ + void (*status_changed) (GwibberServiceStatus newstatus); +}; + +typedef struct _GwibberService GwibberService; +struct _GwibberService { + GObject parent; +}; + +GType gwibber_service_get_type (void) G_GNUC_CONST; +GwibberService * gwibber_service_new (void); +void gwibber_service_send (GwibberService *self, const gchar *msg); +gboolean gwibber_service_has_configured_accounts (GwibberService *self); + +/* old API */ void gwibber_send (const gchar *msg); G_END_DECLS -#endif /* __ME_SERVICE_GWIBBER_H__ */ +#endif /* __GWIBBER_SERVICE_H__ */ === modified file 'src/me-service.c' --- src/me-service.c 2010-03-16 20:51:26 +0000 +++ src/me-service.c 2010-03-16 20:51:26 +0000 @@ -51,6 +51,7 @@ #include "status-provider-pidgin.h" #include "status-provider-telepathy.h" +#include "me-service-gwibber.h" #include "entry-menu-item.h" typedef StatusProvider * (*newfunc) (void); @@ -80,6 +81,7 @@ /* STATUS_PROVIDER_STATUS_DISCONNECTED */"user-offline" }; +static GwibberService * gwibber = NULL; static DbusmenuMenuitem * root_menuitem = NULL; static DbusmenuMenuitem * status_menuitems[STATUS_PROVIDER_STATUS_LAST] = {0}; @@ -87,6 +89,7 @@ static StatusServiceDbus * dbus_interface = NULL; static StatusProviderStatus global_status = STATUS_PROVIDER_STATUS_DISCONNECTED; static GFileMonitor *avatar_monitor = NULL; +static DbusmenuMenuitem *broadcast_field = NULL; static void status_update (void) { @@ -166,6 +169,38 @@ } static void +gwibber_status_update (GwibberService *instance, GwibberServiceStatus status, gpointer data) { + g_return_if_fail (instance != NULL); + + g_debug ("gwibber service status changed to: %d", status); + + if (broadcast_field == NULL) { + g_warning ("no broadcast field to update"); + return; + } + + if (! gwibber_service_has_configured_accounts (instance)) { + g_debug ("no configured accounts detected, so hiding the broadcast field"); + dbusmenu_menuitem_property_set_bool (broadcast_field, DBUSMENU_MENUITEM_PROP_VISIBLE, FALSE); + return; + } + + if (! dbusmenu_menuitem_property_get_bool (broadcast_field, DBUSMENU_MENUITEM_PROP_VISIBLE)) + dbusmenu_menuitem_property_set_bool (broadcast_field, DBUSMENU_MENUITEM_PROP_VISIBLE, TRUE); + + if (status == GWIBBER_SERVICE_STATUS_RUNNING) { + g_debug ("enabling the broadcast field"); + dbusmenu_menuitem_property_set_bool (broadcast_field, DBUSMENU_MENUITEM_PROP_ENABLED, TRUE); + } else { + g_debug ("disabling the broadcast field"); + dbusmenu_menuitem_property_set_bool (broadcast_field, DBUSMENU_MENUITEM_PROP_ENABLED, FALSE); + } + + return; +} + + +static void status_menu_click (DbusmenuMenuitem * mi, guint timestamp, gpointer data) { StatusProviderStatus status = (StatusProviderStatus)GPOINTER_TO_INT(data); @@ -249,7 +284,12 @@ status_update(); - return FALSE; + gwibber = gwibber_service_new (); + if (gwibber != NULL) { + g_signal_connect (G_OBJECT (gwibber), GWIBBER_SERVICE_SIGNAL_STATUS_CHANGED, G_CALLBACK (gwibber_status_update), NULL); + } + + return FALSE; } #define GCONF_ANONYMOUS "/system/indicator/me/anonymous" @@ -362,8 +402,10 @@ build_user_item(root); - DbusmenuMenuitem *entry = DBUSMENU_MENUITEM (entry_menu_item_new()); - dbusmenu_menuitem_child_append(root, entry); + broadcast_field = DBUSMENU_MENUITEM (entry_menu_item_new()); + dbusmenu_menuitem_property_set_bool (broadcast_field, DBUSMENU_MENUITEM_PROP_ENABLED, TRUE); + dbusmenu_menuitem_property_set_bool (broadcast_field, DBUSMENU_MENUITEM_PROP_VISIBLE, FALSE); + dbusmenu_menuitem_child_append(root, broadcast_field); StatusProviderStatus i; for (i = STATUS_PROVIDER_STATUS_ONLINE; i < STATUS_PROVIDER_STATUS_LAST; i++) {
_______________________________________________ Mailing list: https://launchpad.net/~ayatana-commits Post to : [email protected] Unsubscribe : https://launchpad.net/~ayatana-commits More help : https://help.launchpad.net/ListHelp

