2 * Copyright (C) 2009 Intel Corporation
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) version 3.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20 #include <glib-object.h>
23 #include "syncevo-server.h"
24 #include "syncevo-marshal.h"
25 #include "syncevo-server-bindings.h"
27 typedef struct _ServerAsyncData {
28 SyncevoServer *server;
41 static guint32 signals[LAST_SIGNAL] = {0, };
43 typedef struct _SyncevoServerPrivate {
45 } SyncevoServerPrivate;
47 #define GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), SYNCEVO_TYPE_SERVER, SyncevoServerPrivate))
48 G_DEFINE_TYPE (SyncevoServer, syncevo_server, G_TYPE_OBJECT);
50 static ServerAsyncData*
51 server_async_data_new (SyncevoServer *server,
55 ServerAsyncData *data;
57 data = g_slice_new0 (ServerAsyncData);
58 data->server = server;
59 data->callback = G_CALLBACK (callback);
60 data->userdata = userdata;
66 server_async_data_free (ServerAsyncData *data)
68 g_slice_free (ServerAsyncData, data);
72 generic_callback (DBusGProxy *proxy,
74 ServerAsyncData *data)
77 (*(SyncevoServerGenericCb)data->callback) (data->server,
81 server_async_data_free (data);
85 generic_error (ServerAsyncData *data)
89 error = g_error_new_literal (SYNCEVO_SERVER_ERROR_QUARK,
90 SYNCEVO_SERVER_ERROR_NO_DBUS_OBJECT,
91 "The D-Bus object does not exist");
92 (*(SyncevoServerGenericCb)data->callback) (data->server,
95 server_async_data_free (data);
101 templates_changed_cb (DBusGProxy *proxy,
102 SyncevoServer *server)
104 g_signal_emit (server, signals[TEMPLATES_CHANGED], 0);
108 session_changed_cb (DBusGProxy *proxy,
111 SyncevoServer *server)
113 g_signal_emit (server, signals[SESSION_CHANGED], 0,
114 session_path, started);
118 presence_cb (DBusGProxy *proxy,
122 SyncevoServer *server)
124 g_signal_emit (server, signals[PRESENCE_CHANGED], 0,
125 configuration, status, transport);
129 info_request_cb (DBusGProxy *proxy,
135 GHashTable *parameters,
136 SyncevoServer *server)
138 g_signal_emit (server, signals[INFO_REQUEST], 0,
139 id, session_path, state, handler_path, type, parameters);
143 proxy_destroy_cb (DBusGProxy *proxy,
144 SyncevoServer *server)
146 SyncevoServerPrivate *priv;
147 priv = GET_PRIVATE (server);
150 g_object_unref (priv->proxy);
154 g_signal_emit (server, signals[SHUTDOWN], 0);
159 detach_cb (DBusGProxy *proxy,
164 g_warning ("Server.Detach failed: %s", error->message);
165 g_error_free (error);
171 dispose (GObject *object)
173 SyncevoServerPrivate *priv;
175 priv = GET_PRIVATE (object);
178 dbus_g_proxy_disconnect_signal (priv->proxy, "SessionChanged",
179 G_CALLBACK (session_changed_cb),
181 dbus_g_proxy_disconnect_signal (priv->proxy, "Presence",
182 G_CALLBACK (presence_cb),
184 dbus_g_proxy_disconnect_signal (priv->proxy, "InfoRequest",
185 G_CALLBACK (info_request_cb),
187 dbus_g_proxy_disconnect_signal (priv->proxy, "TemplatesChanged",
188 G_CALLBACK (templates_changed_cb),
190 dbus_g_proxy_disconnect_signal (priv->proxy, "destroy",
191 G_CALLBACK (proxy_destroy_cb),
193 org_syncevolution_Server_detach (priv->proxy, NULL);
195 g_object_unref (priv->proxy);
199 G_OBJECT_CLASS (syncevo_server_parent_class)->dispose (object);
203 attach_cb (DBusGProxy *proxy,
208 g_warning ("Server.Attach failed: %s", error->message);
209 g_error_free (error);
214 syncevo_server_get_new_proxy (SyncevoServer *server)
216 DBusGConnection *connection;
219 SyncevoServerPrivate *priv;
222 priv = GET_PRIVATE (server);
225 connection = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
226 if (connection == NULL) {
227 g_printerr ("Failed to open connection to bus: %s\n",
229 g_error_free (error);
234 /* we want to use dbus_g_proxy_new_for_name_owner() for the destroy signal
235 * so need to start the service by hand by using DBUS proxy: */
236 proxy = dbus_g_proxy_new_for_name (connection,
239 DBUS_INTERFACE_DBUS);
240 if (!dbus_g_proxy_call (proxy, "StartServiceByName", NULL,
241 G_TYPE_STRING, DBUS_SERVICE_SYNCEVO_SERVER,
244 G_TYPE_UINT, &result,
246 g_warning ("StartServiceByName call failed");
248 g_object_unref (proxy);
251 priv->proxy = dbus_g_proxy_new_for_name_owner (connection,
252 DBUS_SERVICE_SYNCEVO_SERVER,
253 DBUS_PATH_SYNCEVO_SERVER,
254 DBUS_INTERFACE_SYNCEVO_SERVER,
256 if (priv->proxy == NULL) {
257 g_printerr ("dbus_g_proxy_new_for_name_owner() failed: %s\n", error->message);
258 g_error_free (error);
262 dbus_g_proxy_add_signal (priv->proxy, "SessionChanged",
263 DBUS_TYPE_G_OBJECT_PATH, G_TYPE_BOOLEAN, G_TYPE_INVALID);
264 dbus_g_proxy_connect_signal (priv->proxy, "SessionChanged",
265 G_CALLBACK (session_changed_cb), server, NULL);
266 dbus_g_proxy_add_signal (priv->proxy, "Presence",
267 G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INVALID);
268 dbus_g_proxy_connect_signal (priv->proxy, "Presence",
269 G_CALLBACK (presence_cb), server, NULL);
270 dbus_g_proxy_add_signal (priv->proxy, "InfoRequest",
272 DBUS_TYPE_G_OBJECT_PATH,
276 SYNCEVO_TYPE_STRING_STRING_HASHTABLE,
278 dbus_g_proxy_connect_signal (priv->proxy, "InfoRequest",
279 G_CALLBACK (info_request_cb), server, NULL);
280 dbus_g_proxy_add_signal (priv->proxy, "TemplatesChanged", G_TYPE_INVALID);
281 dbus_g_proxy_connect_signal (priv->proxy, "TemplatesChanged",
282 G_CALLBACK (templates_changed_cb), server, NULL);
283 g_signal_connect (priv->proxy, "destroy",
284 G_CALLBACK (proxy_destroy_cb), server);
286 org_syncevolution_Server_attach_async (priv->proxy,
287 (org_syncevolution_Server_attach_reply)attach_cb,
295 syncevo_server_init (SyncevoServer *server)
297 SyncevoServerPrivate *priv;
299 priv = GET_PRIVATE (server);
302 dbus_g_object_register_marshaller (syncevo_marshal_VOID__STRING_BOOLEAN,
304 DBUS_TYPE_G_OBJECT_PATH,
308 dbus_g_object_register_marshaller (syncevo_marshal_VOID__STRING_STRING_STRING,
315 dbus_g_object_register_marshaller (syncevo_marshal_VOID__STRING_STRING_STRING_STRING_STRING_BOXED,
318 DBUS_TYPE_G_OBJECT_PATH,
325 /* TemplatesChanged */
326 dbus_g_object_register_marshaller (g_cclosure_marshal_VOID__VOID,
330 syncevo_server_get_new_proxy (server);
334 syncevo_server_class_init (SyncevoServerClass *klass)
336 GObjectClass *o_class = (GObjectClass *) klass;
338 o_class->dispose = dispose;
340 g_type_class_add_private (klass, sizeof (SyncevoServerPrivate));
342 signals[SESSION_CHANGED] =
343 g_signal_new ("session-changed",
344 G_TYPE_FROM_CLASS (klass),
345 G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE,
346 G_STRUCT_OFFSET (SyncevoServerClass, session_changed),
348 syncevo_marshal_VOID__STRING_BOOLEAN,
350 2, G_TYPE_STRING, G_TYPE_BOOLEAN);
351 signals[PRESENCE_CHANGED] =
352 g_signal_new ("presence-changed",
353 G_TYPE_FROM_CLASS (klass),
354 G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE,
355 G_STRUCT_OFFSET (SyncevoServerClass, presence_changed),
357 syncevo_marshal_VOID__STRING_STRING_STRING,
359 3, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
360 signals[INFO_REQUEST] =
361 g_signal_new ("info-request",
362 G_TYPE_FROM_CLASS (klass),
363 G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE,
364 G_STRUCT_OFFSET (SyncevoServerClass, info_request),
366 syncevo_marshal_VOID__STRING_STRING_STRING_STRING_STRING_BOXED,
368 6, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_POINTER);
369 signals[TEMPLATES_CHANGED] =
370 g_signal_new ("templates-changed",
371 G_TYPE_FROM_CLASS (klass),
372 G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE,
373 G_STRUCT_OFFSET (SyncevoServerClass, templates_changed),
375 g_cclosure_marshal_VOID__VOID,
379 g_signal_new ("shutdown",
380 G_TYPE_FROM_CLASS (klass),
381 G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE,
382 G_STRUCT_OFFSET (SyncevoServerClass, shutdown),
384 g_cclosure_marshal_VOID__VOID,
390 syncevo_server_get_default ()
392 static SyncevoServer *server = NULL;
394 if (server == NULL) {
395 server = g_object_new (SYNCEVO_TYPE_SERVER, NULL);
396 g_object_add_weak_pointer (G_OBJECT (server),
401 return g_object_ref (server);
406 get_configs_callback (DBusGProxy *proxy,
409 ServerAsyncData *data)
411 if (data->callback) {
412 (*(SyncevoServerGetConfigsCb)data->callback) (data->server,
417 server_async_data_free (data);
421 get_configs_error (ServerAsyncData *data)
425 error = g_error_new_literal (SYNCEVO_SERVER_ERROR_QUARK,
426 SYNCEVO_SERVER_ERROR_NO_DBUS_OBJECT,
427 "Could not start service");
428 (*(SyncevoServerGetConfigsCb)data->callback) (data->server,
432 server_async_data_free (data);
438 syncevo_server_get_configs (SyncevoServer *syncevo,
440 SyncevoServerGetConfigsCb callback,
443 ServerAsyncData *data;
444 SyncevoServerPrivate *priv;
446 priv = GET_PRIVATE (syncevo);
448 data = server_async_data_new (syncevo, G_CALLBACK (callback), userdata);
450 if (!priv->proxy && !syncevo_server_get_new_proxy (syncevo)) {
452 g_idle_add ((GSourceFunc)get_configs_error, data);
457 org_syncevolution_Server_get_configs_async
460 (org_syncevolution_Server_get_configs_reply) get_configs_callback,
465 get_config_callback (DBusGProxy *proxy,
466 SyncevoConfig *configuration,
468 ServerAsyncData *data)
470 if (data->callback) {
471 (*(SyncevoServerGetConfigCb)data->callback) (data->server,
476 server_async_data_free (data);
480 get_config_error (ServerAsyncData *data)
484 error = g_error_new_literal (SYNCEVO_SERVER_ERROR_QUARK,
485 SYNCEVO_SERVER_ERROR_NO_DBUS_OBJECT,
486 "Could not start service");
487 (*(SyncevoServerGetConfigCb)data->callback) (data->server,
491 server_async_data_free (data);
497 syncevo_server_get_config (SyncevoServer *syncevo,
498 const char *config_name,
500 SyncevoServerGetConfigCb callback,
503 ServerAsyncData *data;
504 SyncevoServerPrivate *priv;
506 priv = GET_PRIVATE (syncevo);
508 data = server_async_data_new (syncevo, G_CALLBACK (callback), userdata);
510 if (!priv->proxy && !syncevo_server_get_new_proxy (syncevo)) {
512 g_idle_add ((GSourceFunc)get_config_error, data);
517 org_syncevolution_Server_get_config_async
521 (org_syncevolution_Server_get_config_reply) get_config_callback,
526 get_reports_callback (DBusGProxy *proxy,
527 SyncevoReports *reports,
529 ServerAsyncData *data)
531 if (data->callback) {
532 (*(SyncevoServerGetReportsCb)data->callback) (data->server,
537 server_async_data_free (data);
541 get_reports_error (ServerAsyncData *data)
545 error = g_error_new_literal (SYNCEVO_SERVER_ERROR_QUARK,
546 SYNCEVO_SERVER_ERROR_NO_DBUS_OBJECT,
547 "Could not start service");
548 (*(SyncevoServerGetReportsCb)data->callback) (data->server,
552 server_async_data_free (data);
558 syncevo_server_get_reports (SyncevoServer *syncevo,
559 const char *config_name,
562 SyncevoServerGetReportsCb callback,
565 ServerAsyncData *data;
566 SyncevoServerPrivate *priv;
568 priv = GET_PRIVATE (syncevo);
570 data = server_async_data_new (syncevo, G_CALLBACK (callback), userdata);
572 if (!priv->proxy && !syncevo_server_get_new_proxy (syncevo)) {
574 g_idle_add ((GSourceFunc)get_reports_error, data);
579 org_syncevolution_Server_get_reports_async
584 (org_syncevolution_Server_get_reports_reply) get_reports_callback,
589 start_session_callback (SyncevoServer *syncevo,
592 ServerAsyncData *data)
594 if (data->callback) {
595 (*(SyncevoServerStartSessionCb)data->callback) (data->server,
600 server_async_data_free (data);
604 start_session_error (ServerAsyncData *data)
608 error = g_error_new_literal (SYNCEVO_SERVER_ERROR_QUARK,
609 SYNCEVO_SERVER_ERROR_NO_DBUS_OBJECT,
610 "Could not start service");
611 (*(SyncevoServerStartSessionCb)data->callback) (data->server,
615 server_async_data_free (data);
621 syncevo_server_start_session (SyncevoServer *syncevo,
622 const char *config_name,
623 SyncevoServerStartSessionCb callback,
626 ServerAsyncData *data;
627 SyncevoServerPrivate *priv;
629 priv = GET_PRIVATE (syncevo);
631 data = server_async_data_new (syncevo, G_CALLBACK (callback), userdata);
633 if (!priv->proxy && !syncevo_server_get_new_proxy (syncevo)) {
635 g_idle_add ((GSourceFunc)start_session_error, data);
640 org_syncevolution_Server_start_session_async
643 (org_syncevolution_Server_start_session_reply) start_session_callback,
648 get_sessions_callback (SyncevoServer *syncevo,
649 SyncevoSessions *sessions,
651 ServerAsyncData *data)
653 if (data->callback) {
654 (*(SyncevoServerGetSessionsCb)data->callback) (data->server,
659 server_async_data_free (data);
663 get_sessions_error (ServerAsyncData *data)
667 error = g_error_new_literal (SYNCEVO_SERVER_ERROR_QUARK,
668 SYNCEVO_SERVER_ERROR_NO_DBUS_OBJECT,
669 "Could not start service");
670 (*(SyncevoServerGetSessionsCb)data->callback) (data->server,
674 server_async_data_free (data);
680 syncevo_server_get_sessions (SyncevoServer *syncevo,
681 SyncevoServerGetSessionsCb callback,
684 ServerAsyncData *data;
685 SyncevoServerPrivate *priv;
687 priv = GET_PRIVATE (syncevo);
689 data = server_async_data_new (syncevo, G_CALLBACK (callback), userdata);
691 if (!priv->proxy && !syncevo_server_get_new_proxy (syncevo)) {
693 g_idle_add ((GSourceFunc)get_sessions_error, data);
698 org_syncevolution_Server_get_sessions_async
700 (org_syncevolution_Server_get_reports_reply) get_sessions_callback,
706 check_presence_callback (SyncevoServer *syncevo,
710 ServerAsyncData *data)
712 if (data->callback) {
713 (*(SyncevoServerGetPresenceCb)data->callback) (data->server,
719 server_async_data_free (data);
723 check_presence_error (ServerAsyncData *data)
727 error = g_error_new_literal (SYNCEVO_SERVER_ERROR_QUARK,
728 SYNCEVO_SERVER_ERROR_NO_DBUS_OBJECT,
729 "Could not start service");
730 (*(SyncevoServerGetPresenceCb)data->callback) (data->server,
735 server_async_data_free (data);
742 syncevo_server_get_presence (SyncevoServer *syncevo,
743 const char *config_name,
744 SyncevoServerGetPresenceCb callback,
747 ServerAsyncData *data;
748 SyncevoServerPrivate *priv;
750 priv = GET_PRIVATE (syncevo);
752 data = server_async_data_new (syncevo, G_CALLBACK (callback), userdata);
754 if (!priv->proxy && !syncevo_server_get_new_proxy (syncevo)) {
756 g_idle_add ((GSourceFunc)check_presence_error, data);
761 org_syncevolution_Server_check_presence_async
764 (org_syncevolution_Server_check_presence_reply) check_presence_callback,
768 void syncevo_server_check_source (SyncevoServer *server,
771 SyncevoServerGenericCb callback,
774 ServerAsyncData *data;
775 SyncevoServerPrivate *priv;
777 priv = GET_PRIVATE (server);
779 data = server_async_data_new (server, G_CALLBACK (callback), userdata);
783 g_idle_add ((GSourceFunc)generic_error, data);
788 org_syncevolution_Server_check_source_async
792 (org_syncevolution_Server_check_source_reply) generic_callback,
797 syncevo_server_info_response (SyncevoServer *server,
800 GHashTable *response,
801 SyncevoServerGenericCb callback,
804 ServerAsyncData *data;
805 SyncevoServerPrivate *priv;
807 priv = GET_PRIVATE (server);
809 data = server_async_data_new (server, G_CALLBACK (callback), userdata);
813 g_idle_add ((GSourceFunc)generic_error, data);
818 org_syncevolution_Server_info_response_async
823 (org_syncevolution_Server_info_response_reply) generic_callback,