20
20
with this program. If not, see <http://www.gnu.org/licenses/>.
23
#include "me-service-gwibber.h"
24
27
#include <dbus/dbus-glib.h>
26
#define GWIBBER_ADDRESS "com.Gwibber.Service"
27
#define GWIBBER_OBJECT "/com/gwibber/Service"
28
#define GWIBBER_INTERFACE "com.Gwibber.Service"
30
static DBusGProxy * gwibber_proxy = NULL;
34
gwibber_response (DBusGProxy * proxy, DBusGProxyCall * call, gpointer data)
36
g_debug ("gwibber_send_response");
42
setup_gwibber_proxy (void) {
43
DBusGConnection * bus = dbus_g_bus_get(DBUS_BUS_SESSION, NULL);
44
g_return_if_fail(bus != NULL);
46
if (gwibber_proxy == NULL) {
47
gwibber_proxy = dbus_g_proxy_new_for_name(bus,
52
g_return_if_fail (gwibber_proxy != NULL);
28
#include <dbus/dbus-glib-bindings.h>
30
#define DBUS_SERVICE_ADDRESS "com.Gwibber.Service"
31
#define DBUS_SERVICE_SERVICE_OBJECT "/com/gwibber/Service"
32
#define DBUS_SERVICE_SERVICE_INTERFACE "com.Gwibber.Service"
34
#define DBUS_SERVICE_ACCOUNTS_OBJECT "/com/gwibber/Accounts"
35
#define DBUS_SERVICE_ACCOUNTS_INTERFACE "com.Gwibber.Accounts"
37
/* gobject infrastructure */
39
typedef struct _GwibberServicePrivate GwibberServicePrivate;
40
struct _GwibberServicePrivate {
41
DBusGProxy * dbus_proxy;
42
DBusGProxy * service_proxy;
43
DBusGProxy * accounts_proxy;
45
gboolean has_configured_accounts;
54
static guint signals[LAST_SIGNAL] = { 0 };
57
static void gwibber_service_class_init (GwibberServiceClass *klass);
58
static void gwibber_service_init (GwibberService *self);
59
static void gwibber_service_dispose (GObject *object);
60
static void gwibber_service_finalize (GObject *object);
62
static void dbus_namechange (DBusGProxy * proxy, const gchar * name, const gchar * prev, const gchar * new, GwibberService * self);
63
static void gwibber_exists_cb (DBusGProxy * proxy, gboolean exists, GError * error, gpointer userdata);
64
static void setup_service_proxies (GwibberService *self);
65
static void query_account_manager (GwibberService *self);
67
G_DEFINE_TYPE (GwibberService, gwibber_service, G_TYPE_OBJECT);
69
#define GWIBBER_SERVICE_GET_PRIVATE(o) \
70
(G_TYPE_INSTANCE_GET_PRIVATE ((o), GWIBBER_SERVICE_TYPE, GwibberServicePrivate))
73
gwibber_service_class_init (GwibberServiceClass *klass)
75
GObjectClass *object_class = G_OBJECT_CLASS (klass);
77
g_type_class_add_private (klass, sizeof (GwibberServicePrivate));
79
object_class->dispose = gwibber_service_dispose;
80
object_class->finalize = gwibber_service_finalize;
82
signals[STATUS_CHANGED] = g_signal_new(GWIBBER_SERVICE_SIGNAL_STATUS_CHANGED,
83
G_TYPE_FROM_CLASS(klass),
85
G_STRUCT_OFFSET(GwibberServiceClass, status_changed),
87
g_cclosure_marshal_VOID__UINT,
88
G_TYPE_NONE, 1, G_TYPE_UINT);
93
gwibber_service_init (GwibberService *self)
95
GwibberServicePrivate * priv = GWIBBER_SERVICE_GET_PRIVATE(self);
97
priv->dbus_proxy = NULL;
98
priv->service_proxy = NULL;
99
priv->accounts_proxy = NULL;
100
priv->status = GWIBBER_SERVICE_STATUS_NOT_RUNNING;
101
priv->has_configured_accounts = FALSE;
103
DBusGConnection * bus = dbus_g_bus_get(DBUS_BUS_SESSION, NULL);
104
g_return_if_fail(bus != NULL); /* Can't do anymore DBus stuff without this,
105
all non-DBus stuff should be done */
107
GError * error = NULL;
109
/* Set up the dbus Proxy */
110
priv->dbus_proxy = dbus_g_proxy_new_for_name_owner (bus,
116
g_warning("Unable to connect to DBus events: %s", error->message);
121
/* Configure the name owner changing */
122
dbus_g_proxy_add_signal(priv->dbus_proxy, "NameOwnerChanged",
123
G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING,
125
dbus_g_proxy_connect_signal(priv->dbus_proxy, "NameOwnerChanged",
126
G_CALLBACK(dbus_namechange),
129
org_freedesktop_DBus_name_has_owner_async(priv->dbus_proxy, DBUS_SERVICE_ADDRESS, gwibber_exists_cb, self);
135
gwibber_service_dispose (GObject *object)
137
GwibberServicePrivate * priv = GWIBBER_SERVICE_GET_PRIVATE(object);
139
if (priv->dbus_proxy != NULL) {
140
g_object_unref(priv->dbus_proxy);
141
priv->dbus_proxy = NULL;
144
if (priv->service_proxy != NULL) {
145
g_object_unref(priv->service_proxy);
146
priv->service_proxy = NULL;
149
if (priv->accounts_proxy != NULL) {
150
g_object_unref(priv->accounts_proxy);
151
priv->accounts_proxy = NULL;
154
G_OBJECT_CLASS (gwibber_service_parent_class)->dispose (object);
159
gwibber_service_finalize (GObject *object)
161
G_OBJECT_CLASS (gwibber_service_parent_class)->finalize (object);
166
/* Watch for Gwibber coming on and off the bus. */
168
dbus_namechange (DBusGProxy * proxy, const gchar * name, const gchar * prev, const gchar * new, GwibberService * self)
170
g_return_if_fail (IS_GWIBBER_SERVICE (self));
172
GwibberServicePrivate * priv = GWIBBER_SERVICE_GET_PRIVATE(self);
174
if (prev[0] == '\0' && g_strcmp0(name, DBUS_SERVICE_ADDRESS) == 0) {
175
g_debug("Gwibber Service coming online");
176
priv->status = GWIBBER_SERVICE_STATUS_RUNNING;
177
if (priv->service_proxy == NULL ||
178
priv->accounts_proxy == NULL)
179
setup_service_proxies (self);
180
query_account_manager (self);
183
if (new[0] == '\0' && g_strcmp0(name, DBUS_SERVICE_ADDRESS) == 0) {
184
g_debug("Gwibber Service going offline");
185
priv->status = GWIBBER_SERVICE_STATUS_NOT_RUNNING;
186
g_signal_emit (G_OBJECT (self), GWIBBER_SERVICE_SIGNAL_STATUS_CHANGED_ID, 0, priv->status, TRUE);
187
if (priv->service_proxy != NULL) {
188
g_object_unref(priv->service_proxy);
189
priv->service_proxy = NULL;
191
if (priv->accounts_proxy != NULL) {
192
g_object_unref(priv->accounts_proxy);
193
priv->accounts_proxy = NULL;
201
get_accounts_response (DBusGProxy * proxy, DBusGProxyCall * call, gpointer data)
203
GError *error = NULL;
204
gchar *accounts_string = NULL;
206
dbus_g_proxy_end_call (proxy, call, &error,
207
G_TYPE_STRING, &accounts_string,
211
g_warning ("GetAccounts: %s", error->message);
212
g_error_free (error);
213
g_free (accounts_string);
217
/* don't print the accounts string, it contains passwords */
218
/* g_debug ("GetAccounts: %s", accounts_string); */
220
g_return_if_fail (IS_GWIBBER_SERVICE (data));
221
GwibberServicePrivate * priv = GWIBBER_SERVICE_GET_PRIVATE(data);
222
g_return_if_fail (priv != NULL);
223
/* Note: not free'ing accounts_string here, but g_return_if_fail are
224
meant to catch design errors, not runtime ones */
226
priv->status = GWIBBER_SERVICE_STATUS_RUNNING;
227
priv->has_configured_accounts = g_strrstr (accounts_string, " \"send_enabled\": true,") ? TRUE : FALSE;
229
/* trigger a status update */
230
g_signal_emit (G_OBJECT (data),
231
GWIBBER_SERVICE_SIGNAL_STATUS_CHANGED_ID,
232
0, priv->status, TRUE);
234
g_free (accounts_string);
240
query_account_manager (GwibberService *self)
242
g_return_if_fail (IS_GWIBBER_SERVICE (self));
244
GwibberServicePrivate * priv = GWIBBER_SERVICE_GET_PRIVATE(self);
246
if (priv->service_proxy == NULL) {
247
g_warning ("no service_proxy, can't query for accounts");
251
dbus_g_proxy_begin_call(priv->service_proxy,
253
get_accounts_response,
260
accounts_changed (DBusGProxy *proxy, const gchar *id, GwibberService *self)
262
g_return_if_fail (IS_GWIBBER_SERVICE (self));
264
g_debug ("accounts_changed");
266
query_account_manager (self);
272
setup_service_proxies (GwibberService *self)
274
g_return_if_fail (IS_GWIBBER_SERVICE (self));
276
GwibberServicePrivate * priv = GWIBBER_SERVICE_GET_PRIVATE(self);
278
DBusGConnection * bus = dbus_g_bus_get(DBUS_BUS_SESSION, NULL);
279
g_return_if_fail(bus != NULL); /* Can't do anymore DBus stuff without this,
280
all non-DBus stuff should be done */
282
if (priv->service_proxy == NULL) {
283
priv->service_proxy = dbus_g_proxy_new_for_name(
285
DBUS_SERVICE_ADDRESS,
286
DBUS_SERVICE_SERVICE_OBJECT,
287
DBUS_SERVICE_SERVICE_INTERFACE);
288
if (priv->service_proxy == NULL) {
289
g_warning ("can't setup service_proxy");
294
if (priv->accounts_proxy == NULL) {
295
priv->accounts_proxy =
296
dbus_g_proxy_new_for_name(bus,
297
DBUS_SERVICE_ADDRESS,
298
DBUS_SERVICE_ACCOUNTS_OBJECT,
299
DBUS_SERVICE_ACCOUNTS_INTERFACE);
300
if (priv->accounts_proxy == NULL) {
301
g_warning ("can't setup accounts_proxy");
306
/* Monitor signals about account changes */
307
dbus_g_proxy_add_signal(priv->accounts_proxy, "AccountChanged",
310
dbus_g_proxy_connect_signal(priv->accounts_proxy, "AccountChanged",
311
G_CALLBACK(accounts_changed),
313
dbus_g_proxy_add_signal(priv->accounts_proxy, "AccountDeleted",
316
dbus_g_proxy_connect_signal(priv->accounts_proxy, "AccountDeleted",
317
G_CALLBACK(accounts_changed),
323
gwibber_exists_cb (DBusGProxy * proxy, gboolean exists, GError * error, gpointer userdata)
326
g_warning ("Unable to check if Gwibber is running: %s", error->message);
331
setup_service_proxies (GWIBBER_SERVICE (userdata));
332
query_account_manager (GWIBBER_SERVICE (userdata));
338
GwibberService * gwibber_service_new (void){
339
return GWIBBER_SERVICE (g_object_new (GWIBBER_SERVICE_TYPE, NULL));
343
send_message_response (DBusGProxy * proxy, DBusGProxyCall * call, gpointer data)
345
g_debug ("send_message_response");
58
gwibber_send (const gchar *msg)
351
gwibber_service_send (GwibberService *self, const gchar *msg)
60
setup_gwibber_proxy ();
353
g_return_if_fail (IS_GWIBBER_SERVICE (self));
62
if (gwibber_proxy == NULL) {
63
g_warning ("Can not get a gwibber proxy object");
355
GwibberServicePrivate * priv = GWIBBER_SERVICE_GET_PRIVATE(self);
66
357
GValue value = {0};
67
358
g_value_init(&value, G_TYPE_STRING);