~skypce/indicator-session/indicator-session

« back to all changes in this revision

Viewing changes to src/status-provider-mc5.c

  • Committer: Bazaar Package Importer
  • Author(s): Ken VanDine
  • Date: 2009-12-10 10:42:21 UTC
  • mfrom: (1.1.9 upstream)
  • mto: This revision was merged to the branch mainline in revision 14.
  • Revision ID: james.westby@ubuntu.com-20091210104221-vf7zqsien3deqc1p
Tags: 0.1.7+r58-0ubuntu1
* New snapshot for libindicator 0.3.0
* debian/control
  - build depend on libtelepathy-glib-dev instead of libempathy-dev
  - build depend on libindicator-dev >= 0.3.0
* removed 03_tp_glib.patch and 99_autoreconf.patch, applied upstream

Show diffs side-by-side

added added

removed removed

Lines of Context:
24
24
#include "config.h"
25
25
#endif
26
26
 
27
 
#include "libempathy/empathy-account-manager.h"
 
27
#include <telepathy-glib/account-manager.h>
28
28
 
29
29
#include "status-provider.h"
30
30
#include "status-provider-mc5.h"
31
31
#include "status-provider-mc5-marshal.h"
32
32
 
33
33
#include <dbus/dbus-glib.h>
 
34
#include <dbus/dbus-glib-bindings.h>
34
35
 
35
36
static gchar * sp_to_mc_map[STATUS_PROVIDER_STATUS_LAST] = {
36
37
        /* STATUS_PROVIDER_STATUS_ONLINE,  */  "available",
64
65
 
65
66
typedef struct _StatusProviderMC5Private StatusProviderMC5Private;
66
67
struct _StatusProviderMC5Private {
67
 
        EmpathyAccountManager * manager;
 
68
        TpAccountManager * manager;
68
69
        StatusProviderStatus status;
 
70
        DBusGProxy * dbus_proxy;
69
71
};
70
72
 
71
73
#define STATUS_PROVIDER_MC5_GET_PRIVATE(o) \
72
74
(G_TYPE_INSTANCE_GET_PRIVATE ((o), STATUS_PROVIDER_MC5_TYPE, StatusProviderMC5Private))
 
75
#define MC5_WELL_KNOWN_NAME  "org.freedesktop.Telepathy.MissionControl5"
73
76
 
74
77
/* Prototypes */
75
78
/* GObject stuff */
80
83
/* Internal Funcs */
81
84
static void set_status (StatusProvider * sp, StatusProviderStatus status);
82
85
static StatusProviderStatus get_status (StatusProvider * sp);
83
 
static void presence_changed (EmpathyAccountManager * eam, guint type, const gchar * type_str, const gchar * message, StatusProviderMC5 * sp);
 
86
static void presence_changed (TpAccountManager * eam, guint type, const gchar * type_str, const gchar * message, StatusProviderMC5 * sp);
 
87
static void dbus_namechange (DBusGProxy * proxy, const gchar * name, const gchar * prev, const gchar * new, StatusProviderMC5 * self);
 
88
static void mc5_exists_cb (DBusGProxy * proxy, gboolean exists, GError * error, gpointer userdata);
84
89
 
85
90
G_DEFINE_TYPE (StatusProviderMC5, status_provider_mc5, STATUS_PROVIDER_TYPE);
86
91
 
104
109
        return;
105
110
}
106
111
 
 
112
/* Build our telepathy account manager instance if we don't
 
113
   have one. */
 
114
static void
 
115
build_eam (StatusProviderMC5 * self)
 
116
{
 
117
        StatusProviderMC5Private * priv = STATUS_PROVIDER_MC5_GET_PRIVATE(self);
 
118
        static TpDBusDaemon *daemon = NULL;
 
119
        GError *error = NULL;
 
120
 
 
121
        if (priv->manager != NULL) {
 
122
                return;
 
123
        }
 
124
        /* the daemon is used to communicate via DBus */
 
125
        daemon = tp_dbus_daemon_dup(&error);
 
126
 
 
127
        if (daemon == NULL)
 
128
        {
 
129
                g_debug("Cannot create DBus daemon: %s\n", error->message);
 
130
                g_error_free(error);
 
131
                return;
 
132
        }
 
133
 
 
134
        priv->manager = TP_ACCOUNT_MANAGER (g_object_new (TP_TYPE_ACCOUNT_MANAGER,
 
135
                "dbus-daemon", daemon,
 
136
                "dbus-connection", ((TpProxy *) daemon)->dbus_connection,
 
137
                "bus-name", "org.freedesktop.Telepathy.MissionControl5",
 
138
                "object-path", "/org/freedesktop/Telepathy/AccountManager",
 
139
                NULL));
 
140
        g_signal_connect(G_OBJECT(priv->manager), "most-available-presence-changed", G_CALLBACK(presence_changed), self);
 
141
 
 
142
        return;
 
143
}
 
144
 
107
145
/* Creating an instance of the status provider.  We set the variables
108
 
   and create an EmpathyAccountManager object.  It does all the hard
 
146
   and create an TpAccountManager object.  It does all the hard
109
147
   work in this module of tracking MissionControl and enumerating the
110
148
   accounts and all that jazz. */
111
149
static void
116
154
        priv->status = STATUS_PROVIDER_STATUS_DISCONNECTED;
117
155
        priv->manager = NULL;
118
156
 
119
 
        g_signal_connect(G_OBJECT(priv->manager), "global-presence-changed", G_CALLBACK(presence_changed), self);
 
157
        DBusGConnection * bus = dbus_g_bus_get(DBUS_BUS_SESSION, NULL);
 
158
        g_return_if_fail(bus != NULL); /* Can't do anymore DBus stuff without this,
 
159
                                          all non-DBus stuff should be done */
 
160
 
 
161
        GError * error = NULL;
 
162
 
 
163
        /* Set up the dbus Proxy */
 
164
        priv->dbus_proxy = dbus_g_proxy_new_for_name_owner (bus,
 
165
                                                            DBUS_SERVICE_DBUS,
 
166
                                                            DBUS_PATH_DBUS,
 
167
                                                            DBUS_INTERFACE_DBUS,
 
168
                                                            &error);
 
169
        if (error != NULL) {
 
170
                g_warning("Unable to connect to DBus events: %s", error->message);
 
171
                g_error_free(error);
 
172
                return;
 
173
        }
 
174
 
 
175
        /* Configure the name owner changing */
 
176
        dbus_g_proxy_add_signal(priv->dbus_proxy, "NameOwnerChanged",
 
177
                                G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING,
 
178
                                                        G_TYPE_INVALID);
 
179
        dbus_g_proxy_connect_signal(priv->dbus_proxy, "NameOwnerChanged",
 
180
                                G_CALLBACK(dbus_namechange),
 
181
                                self, NULL);
 
182
 
 
183
        org_freedesktop_DBus_name_has_owner_async(priv->dbus_proxy, MC5_WELL_KNOWN_NAME, mc5_exists_cb, self);
120
184
 
121
185
        return;
122
186
}
133
197
                priv->manager = NULL;
134
198
        }
135
199
 
 
200
        if (priv->dbus_proxy != NULL) {
 
201
                g_object_unref(priv->dbus_proxy);
 
202
                priv->dbus_proxy = NULL;
 
203
        }
 
204
 
136
205
        G_OBJECT_CLASS (status_provider_mc5_parent_class)->dispose (object);
137
206
        return;
138
207
}
146
215
        return;
147
216
}
148
217
 
 
218
/* Watch for MC5 Coming on and off the bus. */
 
219
static void
 
220
dbus_namechange (DBusGProxy * proxy, const gchar * name, const gchar * prev, const gchar * new, StatusProviderMC5 * self)
 
221
{
 
222
        /* g_debug("DBUS NAMECHANGE: %s %s %s", name, prev, new); */
 
223
 
 
224
        if (prev[0] == '\0' && g_strcmp0(name, MC5_WELL_KNOWN_NAME) == 0) {
 
225
                g_debug("MC5 Coming online");
 
226
                build_eam(self);
 
227
        }
 
228
        if (new[0] == '\0' && g_strcmp0(name, MC5_WELL_KNOWN_NAME) == 0) {
 
229
                g_debug("MC5 going offline");
 
230
                StatusProviderMC5Private * priv = STATUS_PROVIDER_MC5_GET_PRIVATE(self);
 
231
                if (priv->manager != NULL) {
 
232
                        g_object_unref(priv->manager);
 
233
                        priv->manager = NULL;
 
234
                }
 
235
 
 
236
                priv->status = STATUS_PROVIDER_STATUS_DISCONNECTED;
 
237
                g_signal_emit(G_OBJECT(self), STATUS_PROVIDER_SIGNAL_STATUS_CHANGED_ID, 0, priv->status, TRUE);
 
238
        }
 
239
 
 
240
        return;
 
241
}
 
242
 
 
243
/* Callback for the Dbus command to do HasOwner on
 
244
   the MC5 service.  If it exists, we want to have an
 
245
   account manager. */
 
246
static void
 
247
mc5_exists_cb (DBusGProxy * proxy, gboolean exists, GError * error, gpointer userdata)
 
248
{
 
249
        if (error) {
 
250
                g_warning("Unable to check if MC5 is running: %s", error->message);
 
251
                return;
 
252
        }
 
253
 
 
254
        if (exists) {
 
255
                build_eam(STATUS_PROVIDER_MC5(userdata));
 
256
        }
 
257
 
 
258
        return;
 
259
}
 
260
 
149
261
/**
150
262
        status_provider_mc5_new:
151
263
 
168
280
set_status (StatusProvider * sp, StatusProviderStatus status)
169
281
{
170
282
        StatusProviderMC5Private * priv = STATUS_PROVIDER_MC5_GET_PRIVATE(sp);
171
 
        if (priv->manager == NULL) {
172
 
                priv->manager = EMPATHY_ACCOUNT_MANAGER(g_object_new(EMPATHY_TYPE_ACCOUNT_MANAGER, NULL));
173
 
        }
174
283
 
175
 
        empathy_account_manager_request_global_presence(priv->manager, sp_to_tp_map[status], sp_to_mc_map[status], "");
 
284
        build_eam(STATUS_PROVIDER_MC5(sp));
 
285
        tp_account_manager_set_all_requested_presences(priv->manager, sp_to_tp_map[status], sp_to_mc_map[status], "");
176
286
 
177
287
        return;
178
288
}
192
302
        return priv->status;
193
303
}
194
304
 
195
 
/* A signal handler for when the EmpatyAccountManager believes
 
305
/* A signal handler for when the TpAccountManager believes
196
306
   that the global status has changed.  It roughly calculates this
197
307
   by finding the most available of all accounts that are active. */
198
308
static void
199
 
presence_changed (EmpathyAccountManager * eam, guint type, const gchar * type_str, const gchar * message, StatusProviderMC5 * sp)
 
309
presence_changed (TpAccountManager * eam, guint type, const gchar * type_str, const gchar * message, StatusProviderMC5 * sp)
200
310
{
201
311
        StatusProviderMC5Private * priv = STATUS_PROVIDER_MC5_GET_PRIVATE(sp);
202
312