summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlberto Mardegan <mardy@users.sourceforge.net>2008-04-08 10:39:40 +0000
committerAlberto Mardegan <mardy@users.sourceforge.net>2008-04-08 10:39:40 +0000
commit14533942c63e05d809ee14e6f25e047a15695d14 (patch)
tree7cb5360cb281add8875d9cda63d9c4958ac0900a
parentb1c0b7df486c9f92a0f37dfad8d6d40582b2234e (diff)
downloadtelepathy-mission-control-14533942c63e05d809ee14e6f25e047a15695d14.tar.gz
Implement libmissioncontrol's McAccount and McAccountMonitor using the new DBus API (called in blocking mode).
git-svn-id: https://mission-control.svn.sourceforge.net/svnroot/mission-control/trunk@322 d91c8aed-3f2b-0410-a83d-924a1c20a0ba
-rw-r--r--libmissioncontrol/Makefile.am12
-rw-r--r--libmissioncontrol/mc-account-manager-proxy.c60
-rw-r--r--libmissioncontrol/mc-account-manager-proxy.h56
-rw-r--r--libmissioncontrol/mc-account-monitor-priv.h5
-rw-r--r--libmissioncontrol/mc-account-monitor.c305
-rw-r--r--libmissioncontrol/mc-account-priv.h26
-rw-r--r--libmissioncontrol/mc-account-proxy.c57
-rw-r--r--libmissioncontrol/mc-account-proxy.h56
-rw-r--r--libmissioncontrol/mc-account.c1588
-rw-r--r--libmissioncontrol/mc.c112
-rw-r--r--libmissioncontrol/mc.h26
-rw-r--r--src/Makefile.am4
-rw-r--r--src/mcd-account-compat.c153
-rw-r--r--src/mcd-account-compat.h39
-rw-r--r--src/mcd-account-manager.c41
-rw-r--r--src/mcd-account-manager.h2
-rw-r--r--src/mcd-account.c83
-rw-r--r--src/mcd-account.h6
-rw-r--r--src/mcd-master.c11
-rw-r--r--src/mcd-presence-frame.c13
-rw-r--r--src/mcd-presence-frame.h1
-rw-r--r--src/mcd-service.c21
-rw-r--r--tools/Makefile.am1
-rw-r--r--tools/glib-blocking-client-gen.py1014
-rw-r--r--xml/Account.xml2
-rw-r--r--xml/Account_Interface_Compat.xml46
-rw-r--r--xml/Makefile.am4
-rw-r--r--xml/nmc5.xml1
28 files changed, 2562 insertions, 1183 deletions
diff --git a/libmissioncontrol/Makefile.am b/libmissioncontrol/Makefile.am
index b83a18fc..a7500fee 100644
--- a/libmissioncontrol/Makefile.am
+++ b/libmissioncontrol/Makefile.am
@@ -34,9 +34,11 @@ libmissioncontrol_client_la_SOURCES = \
mc-protocol-priv.h \
mc-profile.c \
mc-account.c \
+ mc-account-proxy.c \
mc-account-priv.h \
mc-account-monitor.c \
mc-account-monitor-priv.h \
+ mc-account-manager-proxy.c \
mc-signals-marshal.c \
mc-enum-types.c \
mission-control-signals-marshal.c \
@@ -48,7 +50,9 @@ libmissioncontrol_client_include_HEADERS = \
dbus-api.h \
mc.h \
mc-account.h \
+ mc-account-proxy.h \
mc-account-monitor.h \
+ mc-account-manager-proxy.h \
mc-enum-types.h \
mc-profile.h \
mc-protocol.h \
@@ -60,6 +64,8 @@ libmissioncontrol_client_include_HEADERS = \
genincludedir = $(libmissioncontrol_client_includedir)/_gen
nodist_geninclude_HEADERS = \
+ _gen/cli-Account.h \
+ _gen/cli-Account_Manager.h \
_gen/cli-nmc4.h \
_gen/enums.h \
_gen/interfaces.h \
@@ -67,6 +73,8 @@ nodist_geninclude_HEADERS = \
_gen/svc-nmc4.h
nodist_libmissioncontrol_client_la_SOURCES = \
+ _gen/cli-Account-body.h \
+ _gen/cli-Account_Manager-body.h \
_gen/cli-nmc4-body.h \
_gen/gtypes-body.h \
_gen/interfaces-body.h \
@@ -196,8 +204,8 @@ _gen/%.xml: $(top_srcdir)/xml/%.xml $(wildcard $(top_srcdir)/xml/*.xml)
$< > $@
_gen/cli-%-body.h _gen/cli-%.h: _gen/%.xml \
- $(tools_dir)/glib-client-gen.py Makefile.am
- $(PYTHON) $(tools_dir)/glib-client-gen.py \
+ $(tools_dir)/glib-blocking-client-gen.py Makefile.am
+ $(PYTHON) $(tools_dir)/glib-blocking-client-gen.py \
--group=`echo $* | tr x- x_` \
--iface-quark-prefix=MC_IFACE_QUARK \
$< Mc_Cli _gen/cli-$*
diff --git a/libmissioncontrol/mc-account-manager-proxy.c b/libmissioncontrol/mc-account-manager-proxy.c
new file mode 100644
index 00000000..bdb4750b
--- /dev/null
+++ b/libmissioncontrol/mc-account-manager-proxy.c
@@ -0,0 +1,60 @@
+/*
+ * mc-account_manager-manager-proxy.c - Subclass of TpProxy
+ *
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "mc-account-manager-proxy.h"
+#include <telepathy-glib/proxy-subclass.h>
+#include <telepathy-glib/errors.h>
+#include "_gen/interfaces.h"
+#include "_gen/cli-Account_Manager-body.h"
+#include "_gen/signals-marshal.h"
+#include "_gen/register-dbus-glib-marshallers-body.h"
+
+struct _McAccountManagerProxyClass {
+ TpProxyClass parent_class;
+};
+
+struct _McAccountManagerProxy {
+ TpProxy parent;
+};
+
+G_DEFINE_TYPE (McAccountManagerProxy, mc_account_manager_proxy, TP_TYPE_PROXY);
+
+static void
+mc_account_manager_proxy_init (McAccountManagerProxy *self)
+{
+}
+
+static void
+mc_account_manager_proxy_class_init (McAccountManagerProxyClass *klass)
+{
+ GType type = MC_TYPE_ACCOUNT_MANAGER_PROXY;
+ TpProxyClass *proxy_class = (TpProxyClass *) klass;
+
+ /* the API is stateless, so we can keep the same proxy across restarts */
+ proxy_class->must_have_unique_name = FALSE;
+
+ proxy_class->interface = MC_IFACE_QUARK_ACCOUNT_MANAGER;
+ _mc_ext_register_dbus_glib_marshallers ();
+ tp_proxy_or_subclass_hook_on_interface_add (type, mc_cli_Account_Manager_add_signals);
+
+ tp_proxy_subclass_add_error_mapping (type, TP_ERROR_PREFIX, TP_ERRORS,
+ TP_TYPE_ERROR);
+}
+
diff --git a/libmissioncontrol/mc-account-manager-proxy.h b/libmissioncontrol/mc-account-manager-proxy.h
new file mode 100644
index 00000000..1f79ba38
--- /dev/null
+++ b/libmissioncontrol/mc-account-manager-proxy.h
@@ -0,0 +1,56 @@
+/*
+ * mc-account-manager-proxy.h - Subclass of TpProxy
+ *
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __LIBMISSIONCONTROL_ACCOUNT_MANAGER_PROXY_H__
+#define __LIBMISSIONCONTROL_ACCOUNT_MANAGER_PROXY_H__
+
+#include <telepathy-glib/proxy.h>
+
+G_BEGIN_DECLS
+
+typedef struct _McAccountManagerProxy McAccountManagerProxy;
+typedef struct _McAccountManagerProxyClass McAccountManagerProxyClass;
+typedef struct _McAccountManagerProxyPrivate McAccountManagerProxyPrivate;
+
+GType mc_account_manager_proxy_get_type (void);
+
+#define MC_TYPE_ACCOUNT_MANAGER_PROXY \
+ (mc_account_manager_proxy_get_type ())
+#define MC_ACCOUNT_MANAGER_PROXY(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), MC_TYPE_ACCOUNT_MANAGER_PROXY, \
+ McAccountManagerProxy))
+#define MC_ACCOUNT_MANAGER_PROXY_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST ((klass), MC_TYPE_ACCOUNT_MANAGER_PROXY, \
+ McAccountManagerProxyClass))
+#define MC_IS_ACCOUNT_MANAGER_PROXY(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MC_TYPE_ACCOUNT_MANAGER_PROXY))
+#define MC_IS_ACCOUNT_MANAGER_PROXY_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), MC_TYPE_ACCOUNT_MANAGER_PROXY))
+#define MC_ACCOUNT_MANAGER_PROXY_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), MC_TYPE_ACCOUNT_MANAGER_PROXY, \
+ McAccountManagerProxyClass))
+
+
+G_END_DECLS
+
+/* auto-generated stubs */
+#include <libmissioncontrol/_gen/cli-Account_Manager.h>
+
+#endif
diff --git a/libmissioncontrol/mc-account-monitor-priv.h b/libmissioncontrol/mc-account-monitor-priv.h
index c55c2c3f..3e3c42d9 100644
--- a/libmissioncontrol/mc-account-monitor-priv.h
+++ b/libmissioncontrol/mc-account-monitor-priv.h
@@ -26,6 +26,11 @@
McAccount * _mc_account_monitor_lookup (McAccountMonitor *monitor, const gchar *unique_name);
GList * _mc_account_monitor_list (McAccountMonitor *monitor);
+McAccount *_mc_account_monitor_create_account (McAccountMonitor *monitor,
+ const gchar *manager,
+ const gchar *protocol,
+ const gchar *display_name,
+ GHashTable *parameters);
#endif /* __MC_ACCOUNT_MONITOR_PRIV_H__ */
diff --git a/libmissioncontrol/mc-account-monitor.c b/libmissioncontrol/mc-account-monitor.c
index 9e4ad040..db3a154f 100644
--- a/libmissioncontrol/mc-account-monitor.c
+++ b/libmissioncontrol/mc-account-monitor.c
@@ -24,12 +24,19 @@
#include <string.h>
#include <strings.h>
+#include <telepathy-glib/proxy.h>
+#include <telepathy-glib/dbus.h>
+#include <telepathy-glib/svc-generic.h>
+#include "_gen/interfaces.h"
#include <gconf/gconf-client.h>
#include "mc-account.h"
#include "mc-account-priv.h"
#include "mc-account-monitor.h"
+#include "mc-account-monitor-priv.h"
+#include "mc-account-manager-proxy.h"
#include "mc-signals-marshal.h"
+#include "mc.h"
G_DEFINE_TYPE (McAccountMonitor, mc_account_monitor, G_TYPE_OBJECT);
@@ -51,8 +58,7 @@ static guint signals[NUM_SIGNALS];
typedef struct
{
- GConfClient *gconf_client;
- guint gconf_connection;
+ TpProxy *proxy;
GHashTable *accounts;
} McAccountMonitorPrivate;
@@ -62,11 +68,6 @@ mc_account_monitor_finalize (GObject *object)
McAccountMonitor *self = MC_ACCOUNT_MONITOR (object);
McAccountMonitorPrivate *priv = MC_ACCOUNT_MONITOR_PRIV (self);
- gconf_client_notify_remove (priv->gconf_client, priv->gconf_connection);
- gconf_client_remove_dir (
- priv->gconf_client, MC_ACCOUNTS_GCONF_BASE, NULL);
- g_object_unref (priv->gconf_client);
-
g_hash_table_destroy (priv->accounts);
}
@@ -169,7 +170,7 @@ mc_account_monitor_class_init (McAccountMonitorClass *klass)
* retrieve the account object).
* @param: The name of the parameter which changed.
*
- * Emitted when an account parameter is changed.
+ * NOTE: this signal is no longer emitted in this version.
*/
signals[PARAM_CHANGED] = g_signal_new (
"param-changed",
@@ -182,195 +183,138 @@ mc_account_monitor_class_init (McAccountMonitorClass *klass)
G_TYPE_STRING, G_TYPE_STRING);
}
-static gchar *
-_account_name_from_key (const gchar *key)
+static void
+on_account_removed (TpProxy *proxy, const gchar *object_path,
+ gpointer user_data, GObject *weak_object)
{
- guint base_len = strlen (MC_ACCOUNTS_GCONF_BASE);
- const gchar *base, *slash;
-
- g_assert (key == strstr (key, MC_ACCOUNTS_GCONF_BASE));
- if (strlen (key) <= base_len + 1) return NULL;
-
- base = key + base_len + 1;
- slash = index (base, '/');
+ McAccountMonitor *monitor = MC_ACCOUNT_MONITOR (weak_object);
+ McAccountMonitorPrivate *priv = user_data;
+ const gchar *name;
+ McAccount *account;
- if (slash == NULL)
- return g_strdup (base);
- else
- return g_strndup (base, slash - base);
-}
-
-static const gchar *
-key_name (const gchar *path_key)
-{
- const gchar *key = 0;
+ name = MC_ACCOUNT_UNIQUE_NAME_FROM_PATH (object_path);
+ g_debug ("%s called for account %s", G_STRFUNC, name);
- while (*path_key != 0)
+ account = g_hash_table_lookup (priv->accounts, name);
+ g_debug ("Account is %sknown", account ? "" : "not ");
+ if (account)
{
- if (*path_key == '/') key = path_key + 1;
- path_key++;
+ if (mc_account_is_enabled (account))
+ {
+ _mc_account_set_enabled_priv (account, FALSE);
+ g_signal_emit (monitor, signals[SIGNAL_DISABLED], 0, name);
+ }
+ g_signal_emit (monitor, signals[SIGNAL_DELETED], 0, name);
+ g_hash_table_remove (priv->accounts, name);
}
- return key;
}
static void
-_gconf_notify_cb (GConfClient *client, guint conn_id, GConfEntry *entry,
- gpointer user_data)
+on_account_validity_changed (TpProxy *proxy, const gchar *object_path,
+ gboolean valid, gpointer user_data,
+ GObject *weak_object)
{
- McAccountMonitor *monitor = MC_ACCOUNT_MONITOR (user_data);
- McAccountMonitorPrivate *priv = MC_ACCOUNT_MONITOR_PRIV (monitor);
- gchar *name = NULL;
- McAccount *account;
- const gchar *key;
-
- key = key_name (entry->key);
- name = _account_name_from_key (entry->key);
- if (!name) return;
- account = g_hash_table_lookup (priv->accounts, name);
-
- /* Was account complete before? */
- if (account == NULL)
- {
- account = _mc_account_new (name);
-
- /* Account was not complete before and it just become complete */
- if (mc_account_is_complete (account))
- {
- g_hash_table_insert (priv->accounts, g_strdup (name), account);
- g_signal_emit (monitor, signals[SIGNAL_CREATED], 0, name);
-
- /* check if the account is enabled and, in case, emit the respective
- * signal */
- if (mc_account_is_enabled (account))
- {
- g_signal_emit (monitor, signals[SIGNAL_ENABLED], 0, name);
- }
- }
- else
- {
- g_object_unref (account);
- /* We don't do anything for incomplete accounts */
- }
- }
- else if (strcmp (key, MC_ACCOUNTS_GCONF_KEY_DELETED) == 0)
- {
- /* if account is deleted, remove it */
- if (entry->value != NULL && entry->value->type == GCONF_VALUE_BOOL &&
- gconf_value_get_bool (entry->value))
- {
- if (mc_account_is_enabled (account))
- {
- _mc_account_set_enabled_priv (account, FALSE);
- g_signal_emit (monitor, signals[SIGNAL_DISABLED], 0, name);
- }
- g_signal_emit (monitor, signals[SIGNAL_DELETED], 0, name);
- g_hash_table_remove (priv->accounts, name);
- }
- }
- else if (strcmp (key, MC_ACCOUNTS_GCONF_KEY_ENABLED) == 0)
+ McAccountMonitor *monitor = MC_ACCOUNT_MONITOR (weak_object);
+ McAccountMonitorPrivate *priv = user_data;
+ const gchar *name;
+ McAccount *account;
+
+ name = MC_ACCOUNT_UNIQUE_NAME_FROM_PATH (object_path);
+ g_debug ("%s called for account %s (%d)", G_STRFUNC, name, valid);
+
+ account = g_hash_table_lookup (priv->accounts, name);
+ g_debug ("Account is %sknown", account ? "" : "not ");
+ if (account)
{
- if (entry->value != NULL && entry->value->type == GCONF_VALUE_BOOL)
- {
- if (gconf_value_get_bool (entry->value))
- {
- _mc_account_set_enabled_priv (account, TRUE);
- g_signal_emit (monitor, signals[SIGNAL_ENABLED], 0, name);
- }
- else
- {
- _mc_account_set_enabled_priv (account, FALSE);
- g_signal_emit (monitor, signals[SIGNAL_DISABLED], 0, name);
- }
- }
+ /* the old implementation didn't report signals for account
+ * completeness, and for account deletion we have another signal; so,
+ * we have nothing to do here */
}
- else if (strcmp (key, MC_ACCOUNTS_GCONF_KEY_AVATAR_TOKEN) != 0)
+ else if (valid)
{
- const gchar *value;
-
- /* report the changed value to the McAccount, if it's a cached setting */
- if (entry->value != NULL && entry->value->type == GCONF_VALUE_STRING)
- value = gconf_value_get_string (entry->value);
- else
- value = NULL;
-
- if (strcmp (key, MC_ACCOUNTS_GCONF_KEY_NORMALIZED_NAME) == 0)
- _mc_account_set_normalized_name_priv (account, value);
- else if (strcmp (key, MC_ACCOUNTS_GCONF_KEY_DISPLAY_NAME) == 0)
- _mc_account_set_display_name_priv (account, value);
-
- /* Emit the rest as value changed signal */
- g_signal_emit (monitor, signals[SIGNAL_CHANGED], 0, name);
-
- if (strncmp (key, "param-", 6) == 0)
- g_signal_emit (monitor, signals[PARAM_CHANGED], 0,
- name, key + 6);
+ account = _mc_account_new (priv->proxy->dbus_daemon, object_path);
+ g_hash_table_insert (priv->accounts, g_strdup (name), account);
+ g_signal_emit (monitor, signals[SIGNAL_CREATED], 0, name);
+
+ /* check if the account is enabled and, in case, emit the respective
+ * signal */
+ if (mc_account_is_enabled (account))
+ {
+ g_signal_emit (monitor, signals[SIGNAL_ENABLED], 0, name);
+ }
}
-
- /* If we are enabling/disabling account */
- g_free (name);
}
static void
mc_account_monitor_init (McAccountMonitor *self)
{
- GError *error = NULL;
- GConfClient *client = gconf_client_get_default ();
- GSList *i, *dirs;
- McAccountMonitorPrivate *priv;
-
- self->priv = G_TYPE_INSTANCE_GET_PRIVATE(self,
- MC_TYPE_ACCOUNT_MONITOR, McAccountMonitorPrivate);
- priv = MC_ACCOUNT_MONITOR_PRIV (self);
- priv->accounts = NULL;
- priv->gconf_client = client;
- dirs = gconf_client_all_dirs (client, MC_ACCOUNTS_GCONF_BASE, &error);
-
- if (NULL != error)
+ GError *error = NULL;
+ McAccountMonitorPrivate *priv;
+ TpDBusDaemon *dbus_daemon;
+ DBusGConnection *connection;
+ GValue *val_accounts;
+ const gchar **accounts, **name;
+
+ self->priv = G_TYPE_INSTANCE_GET_PRIVATE(self,
+ MC_TYPE_ACCOUNT_MONITOR, McAccountMonitorPrivate);
+ priv = MC_ACCOUNT_MONITOR_PRIV (self);
+ connection = dbus_g_bus_get (DBUS_BUS_STARTER, &error);
+ if (error)
{
- g_print ("Error: %s\n", error->message);
- g_assert_not_reached ();
+ g_printerr ("Failed to open connection to bus: %s", error->message);
+ g_error_free (error);
+ return;
}
-
- priv->accounts = g_hash_table_new_full (
- g_str_hash, g_str_equal, (GDestroyNotify) g_free, g_object_unref);
-
- for (i = dirs; NULL != i; i = i->next)
+ dbus_daemon = tp_dbus_daemon_new (connection);
+ priv->proxy = g_object_new (MC_TYPE_ACCOUNT_MANAGER_PROXY,
+ "dbus-daemon", dbus_daemon,
+ "bus-name", MC_ACCOUNT_MANAGER_DBUS_SERVICE,
+ "object-path", MC_ACCOUNT_MANAGER_DBUS_OBJECT,
+ NULL);
+ g_assert (priv->proxy != NULL);
+ priv->accounts = NULL;
+
+ if (NULL != error)
{
- gchar *name = _account_name_from_key (i->data);
- McAccount *account = _mc_account_new (name);
-
- /* Only pick up accounts which are not yet deleted. */
- if (mc_account_is_complete (account))
- {
- g_hash_table_insert (priv->accounts, g_strdup (name), account);
- }
- else
- {
- g_object_unref (account);
- }
- g_free (i->data);
- g_free (name);
+ g_print ("Error: %s\n", error->message);
+ g_assert_not_reached ();
}
- g_slist_free (dirs);
-
- gconf_client_add_dir (
- client, MC_ACCOUNTS_GCONF_BASE, GCONF_CLIENT_PRELOAD_NONE, &error);
+ priv->accounts = g_hash_table_new_full (g_str_hash, g_str_equal,
+ (GDestroyNotify) g_free,
+ g_object_unref);
- if (NULL != error)
+ mc_cli_dbus_properties_do_get (priv->proxy, -1,
+ MC_IFACE_ACCOUNT_MANAGER, "ValidAccounts",
+ &val_accounts, &error);
+ if (error)
{
- g_print ("Error: %s\n", error->message);
- g_assert_not_reached ();
+ g_warning ("Error getting accounts: %s", error->message);
+ g_error_free (error);
+ error = NULL;
}
+ accounts = g_value_get_boxed (val_accounts);
- priv->gconf_connection = gconf_client_notify_add (
- client, MC_ACCOUNTS_GCONF_BASE, _gconf_notify_cb, self, NULL, &error);
-
- if (NULL != error)
+ for (name = accounts; *name != NULL; name++)
{
- g_print ("Error: %s\n", error->message);
- g_assert_not_reached ();
+ McAccount *account;
+ const gchar *unique_name;
+
+ account = _mc_account_new (dbus_daemon, *name);
+ unique_name = MC_ACCOUNT_UNIQUE_NAME_FROM_PATH (*name);
+ g_hash_table_insert (priv->accounts, g_strdup (unique_name), account);
}
+ g_value_unset (val_accounts);
+ g_free (val_accounts);
+
+ mc_cli_account_manager_connect_to_account_removed (priv->proxy,
+ on_account_removed,
+ priv, NULL,
+ (GObject *)self, NULL);
+ mc_cli_account_manager_connect_to_account_validity_changed (priv->proxy,
+ on_account_validity_changed,
+ priv, NULL,
+ (GObject *)self, NULL);
}
McAccount *
@@ -485,3 +429,28 @@ mc_account_monitor_get_supported_presences (McAccountMonitor *monitor)
return data;
}
+McAccount *
+_mc_account_monitor_create_account (McAccountMonitor *monitor,
+ const gchar *manager,
+ const gchar *protocol,
+ const gchar *display_name,
+ GHashTable *parameters)
+{
+ McAccountMonitorPrivate *priv = MC_ACCOUNT_MONITOR_PRIV (monitor);
+ gchar *object_path;
+ GError *error = NULL;
+
+ mc_cli_account_manager_do_create_account (priv->proxy, -1,
+ manager, protocol,
+ display_name, parameters,
+ &object_path, &error);
+ if (error)
+ {
+ g_warning ("%s failed: %s", G_STRFUNC, error->message);
+ g_error_free (error);
+ return NULL;
+ }
+
+ return _mc_account_new (priv->proxy->dbus_daemon, object_path);
+}
+
diff --git a/libmissioncontrol/mc-account-priv.h b/libmissioncontrol/mc-account-priv.h
index a5c2f4c6..6cc48509 100644
--- a/libmissioncontrol/mc-account-priv.h
+++ b/libmissioncontrol/mc-account-priv.h
@@ -24,24 +24,34 @@
#ifndef __MC_ACCOUNT_PRIV_H__
#define __MC_ACCOUNT_PRIV_H__
-#define MC_ACCOUNTS_GCONF_BASE "/apps/telepathy/mc/accounts"
-#define MC_ACCOUNTS_GCONF_KEY_DISPLAY_NAME "display_name"
-#define MC_ACCOUNTS_GCONF_KEY_NORMALIZED_NAME "normalized_name"
-#define MC_ACCOUNTS_GCONF_KEY_ENABLED "enabled"
+#define MC_ACCOUNT_MANAGER_DBUS_SERVICE "org.freedesktop.Telepathy.AccountManager"
+#define MC_ACCOUNT_MANAGER_DBUS_OBJECT "/org/freedesktop/Telepathy/AccountManager"
+#define MC_ACCOUNT_DBUS_OBJECT_BASE "/org/freedesktop/Telepathy/Account/"
+
+#define MC_ACCOUNTS_GCONF_KEY_DISPLAY_NAME "DisplayName"
+#define MC_ACCOUNTS_GCONF_KEY_NORMALIZED_NAME "NormalizedName"
+#define MC_ACCOUNTS_GCONF_KEY_VALID "Valid"
+#define MC_ACCOUNTS_GCONF_KEY_ENABLED "Enabled"
+#define MC_ACCOUNTS_GCONF_KEY_PARAMETERS "Parameters"
#define MC_ACCOUNTS_GCONF_KEY_DELETED "deleted"
-#define MC_ACCOUNTS_GCONF_KEY_PROFILE "profile"
+#define MC_ACCOUNTS_GCONF_KEY_PROFILE "Profile"
#define MC_ACCOUNTS_GCONF_KEY_PARAM_ACCOUNT "account"
+#define MC_ACCOUNTS_GCONF_KEY_AVATAR "Avatar"
+#define MC_ACCOUNTS_GCONF_KEY_AVATAR_FILE "AvatarFile"
#define MC_ACCOUNTS_GCONF_KEY_AVATAR_TOKEN "avatar_token"
#define MC_ACCOUNTS_GCONF_KEY_AVATAR_MIME "avatar_mime"
#define MC_ACCOUNTS_GCONF_KEY_AVATAR_ID "avatar_id"
#define MC_ACCOUNTS_GCONF_KEY_DATA_DIR "data_dir"
-#define MC_ACCOUNTS_GCONF_KEY_ALIAS "alias"
-#define MC_ACCOUNTS_GCONF_KEY_SECONDARY_VCARD_FIELDS "secondary_vcard_fields"
+#define MC_ACCOUNTS_GCONF_KEY_ALIAS "Nickname"
+#define MC_ACCOUNTS_GCONF_KEY_SECONDARY_VCARD_FIELDS "SecondaryVCardFields"
-McAccount * _mc_account_new (const gchar *unique_name);
+McAccount *_mc_account_new (TpDBusDaemon *dbus_daemon,
+ const gchar *object_path);
void _mc_account_set_enabled_priv (McAccount *account, gboolean enabled);
void _mc_account_set_normalized_name_priv (McAccount *account, const gchar *name);
void _mc_account_set_display_name_priv (McAccount *account, const gchar *name);
+#define MC_ACCOUNT_UNIQUE_NAME_FROM_PATH(object_path) \
+ (object_path + (sizeof (MC_ACCOUNT_DBUS_OBJECT_BASE) - 1))
#endif /* __MC_ACCOUNT_PRIV_H__ */
diff --git a/libmissioncontrol/mc-account-proxy.c b/libmissioncontrol/mc-account-proxy.c
new file mode 100644
index 00000000..54fa36bb
--- /dev/null
+++ b/libmissioncontrol/mc-account-proxy.c
@@ -0,0 +1,57 @@
+/*
+ * mc-account-proxy.c - Subclass of TpProxy
+ *
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "mc-account-proxy.h"
+#include <telepathy-glib/proxy-subclass.h>
+#include <telepathy-glib/errors.h>
+#include "_gen/interfaces.h"
+#include "_gen/cli-Account-body.h"
+
+struct _McAccountProxyClass {
+ TpProxyClass parent_class;
+};
+
+struct _McAccountProxy {
+ TpProxy parent;
+};
+
+G_DEFINE_TYPE (McAccountProxy, mc_account_proxy, TP_TYPE_PROXY);
+
+static void
+mc_account_proxy_init (McAccountProxy *self)
+{
+}
+
+static void
+mc_account_proxy_class_init (McAccountProxyClass *klass)
+{
+ GType type = MC_TYPE_ACCOUNT_PROXY;
+ TpProxyClass *proxy_class = (TpProxyClass *) klass;
+
+ /* the API is stateless, so we can keep the same proxy across restarts */
+ proxy_class->must_have_unique_name = FALSE;
+
+ proxy_class->interface = MC_IFACE_QUARK_ACCOUNT;
+ tp_proxy_or_subclass_hook_on_interface_add (type, mc_cli_Account_add_signals);
+
+ tp_proxy_subclass_add_error_mapping (type, TP_ERROR_PREFIX, TP_ERRORS,
+ TP_TYPE_ERROR);
+}
+
diff --git a/libmissioncontrol/mc-account-proxy.h b/libmissioncontrol/mc-account-proxy.h
new file mode 100644
index 00000000..faafa57c
--- /dev/null
+++ b/libmissioncontrol/mc-account-proxy.h
@@ -0,0 +1,56 @@
+/*
+ * mc-account-proxy.h - Subclass of TpProxy
+ *
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __LIBMISSIONCONTROL_ACCOUNT_PROXY_H__
+#define __LIBMISSIONCONTROL_ACCOUNT_PROXY_H__
+
+#include <telepathy-glib/proxy.h>
+
+G_BEGIN_DECLS
+
+typedef struct _McAccountProxy McAccountProxy;
+typedef struct _McAccountProxyClass McAccountProxyClass;
+typedef struct _McAccountProxyPrivate McAccountProxyPrivate;
+
+GType mc_account_proxy_get_type (void);
+
+#define MC_TYPE_ACCOUNT_PROXY \
+ (mc_account_proxy_get_type ())
+#define MC_ACCOUNT_PROXY(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), MC_TYPE_ACCOUNT_PROXY, \
+ McAccountProxy))
+#define MC_ACCOUNT_PROXY_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST ((klass), MC_TYPE_ACCOUNT_PROXY, \
+ McAccountProxyClass))
+#define MC_IS_ACCOUNT_PROXY(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MC_TYPE_ACCOUNT_PROXY))
+#define MC_IS_ACCOUNT_PROXY_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), MC_TYPE_ACCOUNT_PROXY))
+#define MC_ACCOUNT_PROXY_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), MC_TYPE_ACCOUNT_PROXY, \
+ McAccountProxyClass))
+
+
+G_END_DECLS
+
+/* auto-generated stubs */
+#include <libmissioncontrol/_gen/cli-Account.h>
+
+#endif
diff --git a/libmissioncontrol/mc-account.c b/libmissioncontrol/mc-account.c
index 8e4634d9..6fce736b 100644
--- a/libmissioncontrol/mc-account.c
+++ b/libmissioncontrol/mc-account.c
@@ -33,34 +33,53 @@
#include <glib/gstdio.h>
#include "mc-account.h"
+#include "mc-account-proxy.h"
#include "mc-account-priv.h"
#include "mc-account-monitor.h"
#include "mc-account-monitor-priv.h"
#include "mc-profile.h"
+#include "mc.h"
#include <config.h>
#define MC_ACCOUNTS_MAX 1024
#define MC_AVATAR_FILENAME "avatar.bin"
-#define MC_ACCOUNT_PRIV(account) ((McAccountPrivate *)account->priv)
+#define MC_ACCOUNT_PRIV(account) ((McAccountPrivate *)MC_ACCOUNT (account)->priv)
G_DEFINE_TYPE (McAccount, mc_account, G_TYPE_OBJECT);
typedef struct
{
+ TpProxy *proxy;
+ gchar *manager_name;
+ gchar *protocol_name;
gchar *unique_name;
gchar *profile_name;
GSList *display_names;
GSList *normalized_names;
+ gchar *alias;
gboolean enabled;
+ gboolean valid;
+ gchar *last_name;
+ gchar *last_value;
+ gint avatar_id;
} McAccountPrivate;
-static gboolean mc_account_set_deleted (McAccount *account, gboolean deleted);
-static gboolean mc_account_is_deleted (McAccount *account);
-static gboolean _mc_account_gconf_get_boolean (McAccount *account,
- const gchar *name, gboolean param, gboolean *value);
-static gboolean _mc_account_gconf_get_string (McAccount *account,
- const gchar *name, gboolean param, gchar **value);
+static GSList *set_first_element (GSList *list, const gchar *value);
+
+static void
+mc_account_dispose (GObject *object)
+{
+ McAccount *self = MC_ACCOUNT(object);
+ McAccountPrivate *priv = MC_ACCOUNT_PRIV (self);
+
+ if (priv->proxy)
+ {
+ g_object_unref (priv->proxy);
+ priv->proxy = NULL;
+ }
+ G_OBJECT_CLASS (mc_account_parent_class)->dispose (object);
+}
static void
mc_account_finalize (GObject *object)
@@ -68,12 +87,17 @@ mc_account_finalize (GObject *object)
McAccount *self = MC_ACCOUNT(object);
McAccountPrivate *priv = MC_ACCOUNT_PRIV (self);
+ g_free (priv->manager_name);
+ g_free (priv->protocol_name);
g_free (priv->unique_name);
g_free (priv->profile_name);
g_slist_foreach (priv->display_names, (GFunc)g_free, NULL);
g_slist_free (priv->display_names);
g_slist_foreach (priv->normalized_names, (GFunc)g_free, NULL);
g_slist_free (priv->normalized_names);
+ g_free (priv->alias);
+ g_free (priv->last_name);
+ g_free (priv->last_value);
}
static void
@@ -88,32 +112,157 @@ mc_account_clear_cache (void)
{
}
+static inline gboolean
+parse_object_path (McAccountPrivate *priv, const gchar *object_path)
+{
+ gchar manager[64], protocol[64], unique_name[256];
+ gint n;
+
+ n = sscanf (object_path, MC_ACCOUNT_DBUS_OBJECT_BASE "%[^/]/%[^/]/%s",
+ manager, protocol, unique_name);
+ if (n != 3) return FALSE;
+
+ priv->manager_name = g_strdup (manager);
+ priv->protocol_name = g_strdup (protocol);
+ priv->unique_name = g_strdup (MC_ACCOUNT_UNIQUE_NAME_FROM_PATH (object_path));
+ return TRUE;
+}
+
+static void
+print_prop (gpointer key, gpointer ht_value, gpointer userdata)
+{
+ const gchar *name = key;
+ const GValue *value = ht_value;
+
+ g_debug ("prop: %s (%s)", name, G_VALUE_TYPE_NAME (value));
+}
+
+static void
+on_account_property_changed (TpProxy *proxy, GHashTable *properties,
+ gpointer user_data, GObject *weak_object)
+{
+ //McAccount *account = MC_ACCOUNT (weak_object);
+ McAccountPrivate *priv = user_data;
+ const GValue *value;
+
+ g_debug ("%s called on %s", G_STRFUNC, priv->unique_name);
+
+ g_hash_table_foreach (properties, print_prop, NULL);
+ value = g_hash_table_lookup (properties, MC_ACCOUNTS_GCONF_KEY_VALID);
+ if (value)
+ priv->valid = g_value_get_boolean (value);
+
+ value = g_hash_table_lookup (properties, MC_ACCOUNTS_GCONF_KEY_NORMALIZED_NAME);
+ if (value)
+ priv->normalized_names = set_first_element (priv->normalized_names,
+ g_value_get_string (value));
+
+ value = g_hash_table_lookup (properties, MC_ACCOUNTS_GCONF_KEY_DISPLAY_NAME);
+ if (value)
+ priv->display_names = set_first_element (priv->display_names,
+ g_value_get_string (value));
+
+ value = g_hash_table_lookup (properties, MC_ACCOUNTS_GCONF_KEY_ALIAS);
+ if (value)
+ {
+ g_free (priv->alias);
+ priv->alias = g_value_dup_string (value);
+ }
+
+ value = g_hash_table_lookup (properties, MC_ACCOUNTS_GCONF_KEY_AVATAR);
+ if (value)
+ priv->avatar_id = time(0);
+
+ /* FIXME: we should also emit the "param-changed" signal if an account
+ * parameter changed, but since is was used only be the mission-control
+ * process, we can skip now. Besides, we wouldn't know which parameter
+ * actually changed */
+
+ /* emit the account-changed signal */
+ McAccountMonitor *monitor = mc_account_monitor_new ();
+ g_signal_emit_by_name (monitor, "account-changed", priv->unique_name);
+ g_object_unref (monitor);
+}
+
McAccount *
-_mc_account_new (const gchar *unique_name)
+_mc_account_new (TpDBusDaemon *dbus_daemon, const gchar *object_path)
{
- McAccountPrivate *priv;
- McAccount *new;
- gboolean enabled;
- gchar *name;
+ McAccountPrivate *priv;
+ McAccount *new;
+ GHashTable *properties;
+ GError *error = NULL;
+
+ new = (McAccount *)g_object_new (MC_TYPE_ACCOUNT, NULL);
+ priv = MC_ACCOUNT_PRIV (new);
+ priv->proxy = g_object_new (MC_TYPE_ACCOUNT_PROXY,
+ "dbus-daemon", dbus_daemon,
+ "bus-name", MC_ACCOUNT_MANAGER_DBUS_SERVICE,
+ "object-path", object_path,
+ NULL);
+ if (!priv->proxy ||
+ !parse_object_path (priv, object_path))
+ return NULL;
+
+ mc_cli_account_connect_to_account_property_changed (priv->proxy,
+ on_account_property_changed,
+ priv, NULL,
+ (GObject *)new, NULL);
+
+ mc_cli_dbus_properties_do_get_all (priv->proxy, -1,
+ MC_IFACE_ACCOUNT,
+ &properties, &error);
+ if (error)
+ {
+ g_warning ("Properties error: %s", error->message);
+ g_error_free (error);
+ }
+ else
+ {
+ GValue *value;
+
+ value = g_hash_table_lookup (properties, MC_ACCOUNTS_GCONF_KEY_ENABLED);
+ if (value)
+ priv->enabled = g_value_get_boolean (value);
- new = (McAccount *)g_object_new (MC_TYPE_ACCOUNT, NULL);
- priv = MC_ACCOUNT_PRIV (new);
- priv->unique_name = g_strdup (unique_name);
+ value = g_hash_table_lookup (properties, MC_ACCOUNTS_GCONF_KEY_VALID);
+ if (value)
+ priv->valid = g_value_get_boolean (value);
- /* get enabledness status */
- if (_mc_account_gconf_get_boolean (new, MC_ACCOUNTS_GCONF_KEY_ENABLED,
- FALSE, &enabled) && enabled)
- priv->enabled = TRUE;
+ value = g_hash_table_lookup (properties, MC_ACCOUNTS_GCONF_KEY_NORMALIZED_NAME);
+ if (value)
+ priv->normalized_names = g_slist_prepend (NULL, g_value_dup_string (value));
- if (_mc_account_gconf_get_string (new, MC_ACCOUNTS_GCONF_KEY_NORMALIZED_NAME,
- FALSE, &name))
- priv->normalized_names = g_slist_prepend (NULL, name);
+ value = g_hash_table_lookup (properties, MC_ACCOUNTS_GCONF_KEY_DISPLAY_NAME);
+ if (value)
+ priv->display_names = g_slist_prepend (NULL, g_value_dup_string (value));
- if (_mc_account_gconf_get_string (new, MC_ACCOUNTS_GCONF_KEY_DISPLAY_NAME,
- FALSE, &name))
- priv->display_names = g_slist_prepend (NULL, name);
+ value = g_hash_table_lookup (properties, MC_ACCOUNTS_GCONF_KEY_ALIAS);
+ if (value)
+ priv->alias = g_value_dup_string (value);
- return new;
+ g_hash_table_destroy (properties);
+ }
+
+ mc_cli_dbus_properties_do_get_all (priv->proxy, -1,
+ MC_IFACE_ACCOUNT_INTERFACE_COMPAT,
+ &properties, &error);
+ if (error)
+ {
+ g_warning ("Compat properties error: %s", error->message);
+ g_error_free (error);
+ }
+ else
+ {
+ GValue *value;
+
+ value = g_hash_table_lookup (properties, MC_ACCOUNTS_GCONF_KEY_PROFILE);
+ if (value)
+ priv->profile_name = g_value_dup_string (value);
+
+ g_hash_table_destroy (properties);
+ }
+
+ return new;
}
void
@@ -175,200 +324,10 @@ mc_account_class_init (McAccountClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
g_type_class_add_private (object_class, sizeof (McAccountPrivate));
+ object_class->dispose = mc_account_dispose;
object_class->finalize = mc_account_finalize;
}
-/* Returns the data dir for the given account name.
- * Returned string must be freed by caller. */
-static gchar *
-get_account_data_path (const gchar *unique_name)
-{
- const gchar *base;
-
- base = g_getenv ("MC_ACCOUNT_DIR");
- if (!base)
- base = ACCOUNTS_DIR;
- if (!base)
- return NULL;
-
- if (base[0] == '~')
- return g_build_filename (g_get_home_dir(), base + 1, unique_name, NULL);
- else
- return g_build_filename (base, unique_name, NULL);
-}
-
-/* if key is NULL, returns the gconf dir for the given account name,
- * otherwise returns the full key. prepends key with param- if
- * param is TRUE. returned string must be freed by caller. */
-static gchar *
-_mc_account_path (const gchar *unique_name,
- const gchar *key,
- gboolean param)
-{
- if (key != NULL)
- {
- if (param)
- {
- return g_strconcat (MC_ACCOUNTS_GCONF_BASE, "/",
- unique_name, "/param-",
- key, NULL);
- }
- else
- {
- return g_strconcat (MC_ACCOUNTS_GCONF_BASE, "/",
- unique_name, "/",
- key, NULL);
- }
- }
- else
- {
- return g_strconcat (MC_ACCOUNTS_GCONF_BASE, "/",
- unique_name, NULL);
- }
-}
-
-static GConfValue *
-_mc_account_gconf_get (McAccount *account,
- const gchar *name,
- gboolean param)
-{
- GConfClient *client;
- gchar *key;
- GConfValue *value;
-
- g_return_val_if_fail (account != NULL, NULL);
- g_return_val_if_fail (MC_ACCOUNT_PRIV (account)->unique_name != NULL,
- NULL);
- g_return_val_if_fail (name != NULL, NULL);
-
- client = gconf_client_get_default ();
- g_return_val_if_fail (client != NULL, NULL);
-
- key = _mc_account_path (MC_ACCOUNT_PRIV (account)->unique_name,
- name, param);
- value = gconf_client_get (client, key, NULL);
-
- g_object_unref (client);
- g_free (key);
-
- return value;
-}
-
-static gboolean
-_mc_account_gconf_get_boolean (McAccount *account,
- const gchar *name,
- gboolean param,
- gboolean *value)
-{
- GConfValue *val;
-
- g_return_val_if_fail (value != NULL, FALSE);
-
- val = _mc_account_gconf_get (account, name, param);
-
- if (val == NULL)
- {
- return FALSE;
- }
-
- if (val->type != GCONF_VALUE_BOOL)
- {
- gconf_value_free (val);
- return FALSE;
- }
-
- *value = gconf_value_get_bool (val);
- gconf_value_free (val);
-
- return TRUE;
-}
-
-static gboolean
-_mc_account_gconf_get_int (McAccount *account,
- const gchar *name,
- gboolean param,
- gint *value)
-{
- GConfValue *val;
-
- g_return_val_if_fail (value != NULL, FALSE);
-
- val = _mc_account_gconf_get (account, name, param);
-
- if (val == NULL)
- {
- return FALSE;
- }
-
- if (val->type != GCONF_VALUE_INT)
- {
- gconf_value_free (val);
- return FALSE;
- }
-
- *value = gconf_value_get_int (val);
- gconf_value_free (val);
-
- return TRUE;
-}
-
-static gboolean
-_mc_account_gconf_get_string (McAccount *account,
- const gchar *name,
- gboolean param,
- gchar **value)
-{
- GConfValue *val;
-
- g_return_val_if_fail (value != NULL, FALSE);
-
- val = _mc_account_gconf_get (account, name, param);
-
- if (val == NULL)
- {
- return FALSE;
- }
-
- if (val->type != GCONF_VALUE_STRING)
- {
- gconf_value_free (val);
- return FALSE;
- }
-
- *value = g_strdup (gconf_value_get_string (val));
- gconf_value_free (val);
-
- return TRUE;
-}
-
-static gboolean
-_mc_account_gconf_set_string (McAccount *account, const gchar *name,
- const gchar *value)
-{
- GConfClient *client;
- gchar *key;
- gboolean ok;
-
- g_return_val_if_fail (account != NULL, FALSE);
- g_return_val_if_fail (MC_ACCOUNT_PRIV (account)->unique_name != NULL,
- FALSE);
-
- client = gconf_client_get_default ();
- g_return_val_if_fail (client != NULL, FALSE);
-
- key = _mc_account_path (MC_ACCOUNT_PRIV (account)->unique_name,
- name, FALSE);
- if (value)
- ok = gconf_client_set_string (client, key, value, NULL);
- else
- ok = gconf_client_unset (client, key, NULL);
-
- g_free (key);
- g_object_unref (client);
-
- return ok;
-}
-
/**
* mc_account_lookup:
* @unique_name: The unique name of the account.
@@ -391,8 +350,8 @@ mc_account_lookup (const gchar *unique_name)
gboolean
_filter_account (McAccount *acct, gpointer data)
{
- const gchar *compare_account;
- gchar *gconf_account, *normalized_name;
+ const gchar *compare_account, *normalized_name;
+ gchar *gconf_account;
gboolean ret;
g_return_val_if_fail (acct != NULL, FALSE);
@@ -401,10 +360,9 @@ _filter_account (McAccount *acct, gpointer data)
compare_account = (const gchar *) data;
- if (!_mc_account_gconf_get_string (acct,
- MC_ACCOUNTS_GCONF_KEY_PARAM_ACCOUNT,
- TRUE, &gconf_account))
- return FALSE;
+ if (mc_account_get_param_string (acct, "account", &gconf_account) ==
+ MC_ACCOUNT_SETTING_ABSENT)
+ return FALSE;
ret = (0 == strcmp(gconf_account, compare_account));
@@ -412,14 +370,11 @@ _filter_account (McAccount *acct, gpointer data)
if (!ret)
{
- if (!_mc_account_gconf_get_string (acct,
- MC_ACCOUNTS_GCONF_KEY_NORMALIZED_NAME,
- FALSE, &normalized_name))
+ normalized_name = mc_account_get_normalized_name (acct);
+ if (!normalized_name)
return FALSE;
ret = (0 == strcmp(normalized_name, compare_account));
-
- g_free (normalized_name);
}
return ret;
@@ -518,163 +473,50 @@ mc_account_free (McAccount* account)
McAccount *
mc_account_create (McProfile *profile)
{
- McAccount *ret = NULL;
- GConfClient *client;
- const gchar *profile_name;
- gchar *unique_name, *key, *data_dir = NULL;
- guint i = 0;
- gboolean ok;
-
- g_return_val_if_fail (profile != NULL, NULL);
-
- client = gconf_client_get_default ();
- g_return_val_if_fail (client != NULL, NULL);
-
- profile_name = mc_profile_get_unique_name (profile);
-
- /* find the first free account with this profile */
- unique_name = NULL;
- while (unique_name == NULL && i < MC_ACCOUNTS_MAX)
- {
- gchar *path;
-
- unique_name = g_strdup_printf ("%s%u", profile_name, i);
-
- path = _mc_account_path (unique_name, NULL, FALSE);
- if (gconf_client_dir_exists (client, path, NULL))
- {
- g_free (unique_name);
- unique_name = NULL;
- i++;
- }
- g_free (path);
- }
-
- if (unique_name == NULL)
- goto OUT;
-
- key = _mc_account_path (unique_name, MC_ACCOUNTS_GCONF_KEY_PROFILE, FALSE);
- ok = gconf_client_set_string (client, key, profile_name, NULL);
- g_free (key);
-
- if (!ok)
- goto OUT;
-
- /* create the directory for storing the binary objects (i.e., avatar) */
- data_dir = get_account_data_path (unique_name);
- if (g_mkdir_with_parents (data_dir, 0777) != 0)
- goto OUT;
- /* and store it in GConf */
- key = _mc_account_path (unique_name, MC_ACCOUNTS_GCONF_KEY_DATA_DIR, FALSE);
- ok = gconf_client_set_string (client, key, data_dir, NULL);
- g_free (key);
-
- /* Account is disabled by default, because there is no guarantee
- * the account is usable at this point. The one who created the
- * account should enable it when its ready.
- */
- ret = _mc_account_new (unique_name);
-
-OUT:
- g_free (data_dir);
- g_free (unique_name);
- g_object_unref (client);
-
- return ret;
-}
-
-static gchar *
-_account_name_from_key (const gchar *key)
-{
- guint base_len = strlen (MC_ACCOUNTS_GCONF_BASE);
- const gchar *base, *slash;
-
- g_assert (key == strstr (key, MC_ACCOUNTS_GCONF_BASE));
- g_assert (strlen (key) > base_len + 1);
-
- base = key + base_len + 1;
- slash = strchr (base, '/');
-
- if (slash == NULL)
- return g_strdup (base);
- else
- return g_strndup (base, slash - base);
-}
-
-static gboolean
-mc_account_expunge_deleted (gpointer user_data)
-{
- GConfClient *client;
- gchar *key;
- GSList *entries, *tmp;
- gboolean ok = TRUE;
- GError *error = NULL;
- GSList *i, *dirs;
-
- client = gconf_client_get_default ();
- g_return_val_if_fail (client != NULL, FALSE);
-
- dirs = gconf_client_all_dirs (client, MC_ACCOUNTS_GCONF_BASE, &error);
+ McAccountMonitor *monitor;
+ McAccount *account;
+ McAccountPrivate *priv;
+ McProtocol *protocol;
+ McManager *manager;
+ const gchar *manager_name, *protocol_name;
+ GHashTable *params;
+ GValue value = { 0 };
+
+ protocol = mc_profile_get_protocol (profile);
+ if (!protocol) return NULL;
+ manager = mc_protocol_get_manager (protocol);
+ if (!manager) return NULL;
+
+ protocol_name = mc_protocol_get_name (protocol);
+ manager_name = mc_manager_get_unique_name (manager);
+ monitor = mc_account_monitor_new ();
+ params = g_hash_table_new (g_str_hash, g_str_equal);
+ account = _mc_account_monitor_create_account (monitor, manager_name,
+ protocol_name, NULL,
+ params);
+ g_hash_table_destroy (params);
+ g_object_unref (protocol);
+ g_object_unref (monitor);
+ g_object_unref (manager);
- if (NULL != error)
- {
- g_print ("Error: %s\n", error->message);
- g_assert_not_reached ();
- }
- for (i = dirs; NULL != i; i = i->next)
+ if (account)
{
- gchar *unique_name = _account_name_from_key (i->data);
- gchar *data_dir_str;
- GDir *data_dir;
-
- McAccount *account = _mc_account_new (unique_name);
-
- if (!mc_account_is_deleted (account))
- {
- g_object_unref (account);
- g_free (i->data);
- g_free (unique_name);
- continue;
- }
-
- key = _mc_account_path (unique_name, NULL, FALSE);
- entries = gconf_client_all_entries (client, key, NULL);
- g_free (key);
-
- for (tmp = entries; tmp != NULL; tmp = tmp->next)
- {
- GConfEntry *entry;
- entry = (GConfEntry*) tmp->data;
-
- if (!gconf_client_unset (client, entry->key, NULL))
- ok = FALSE;
-
- gconf_entry_free (entry);
- }
-
- data_dir_str = get_account_data_path (unique_name);
- data_dir = g_dir_open (data_dir_str, 0, NULL);
- if (data_dir)
- {
- const gchar *filename;
- while ((filename = g_dir_read_name (data_dir)) != NULL)
- {
- gchar *path;
- path = g_build_filename (data_dir_str, filename, NULL);
- g_remove (path);
- g_free (path);
- }
- g_dir_close (data_dir);
- g_rmdir (data_dir_str);
- }
- g_free (data_dir_str);
-
- g_free (i->data);
- g_free (unique_name);
- g_slist_free (entries);
+ GError *error = NULL;
+ priv = account->priv;
+ g_value_init (&value, G_TYPE_STRING);
+ g_value_set_static_string (&value, mc_profile_get_unique_name (profile));
+ mc_cli_dbus_properties_do_set (priv->proxy, -1,
+ MC_IFACE_ACCOUNT_INTERFACE_COMPAT,
+ MC_ACCOUNTS_GCONF_KEY_PROFILE,
+ &value, &error);
+ if (error)
+ {
+ g_warning ("setting profile on %s failed: %s",
+ priv->unique_name, error->message);
+ g_error_free (error);
+ }
}
- g_object_unref (client);
- return FALSE;
+ return account;
}
/**
@@ -689,21 +531,21 @@ mc_account_expunge_deleted (gpointer user_data)
gboolean
mc_account_delete (McAccount *account)
{
- gboolean ok;
+ McAccountPrivate *priv = MC_ACCOUNT_PRIV (account);
+ GError *error = NULL;
- g_return_val_if_fail (account != NULL, FALSE);
- g_return_val_if_fail (MC_ACCOUNT_PRIV(account)->unique_name != NULL,
- FALSE);
- mc_account_set_enabled (account, FALSE);
-
- ok = mc_account_set_deleted (account, TRUE);
+ mc_account_set_enabled (account, FALSE);
+
+ mc_cli_account_do_remove (priv->proxy, -1, &error);
+ if (error)
+ {
+ g_warning ("%s on %s failed: %s",
+ G_STRFUNC, priv->unique_name, error->message);
+ g_error_free (error);
+ return FALSE;
+ }
- /* Expunge deleted accounts after 5 secs. We can't expunge the accounts
- * immediately because there might be other people using the accounts
- * and gconf signaling is really async.
- */
- g_timeout_add (2000, (GSourceFunc)mc_account_expunge_deleted, NULL);
- return ok;
+ return TRUE;
}
/**
@@ -765,24 +607,10 @@ mc_accounts_list_by_enabled (gboolean enabled)
static gboolean
_filter_profile (McAccount *acct, gpointer data)
{
- McProfile *profile;
- gchar *profile_name;
- gboolean ret;
-
- g_return_val_if_fail (acct != NULL, FALSE);
- g_return_val_if_fail (MC_ACCOUNT_PRIV (acct)->unique_name != NULL, FALSE);
- g_return_val_if_fail (data != NULL, FALSE);
-
- profile = (McProfile *) data;
-
- if (!_mc_account_gconf_get_string (acct, MC_ACCOUNTS_GCONF_KEY_PROFILE,
- FALSE, &profile_name))
- return FALSE;
-
- ret = (0 == strcmp (profile_name, mc_profile_get_unique_name (profile)));
- g_free (profile_name);
+ McAccountPrivate *priv = acct->priv;
+ gchar *profile_name = data;
- return ret;
+ return strcmp (priv->profile_name, profile_name) == 0;
}
/**
@@ -797,12 +625,15 @@ _filter_profile (McAccount *acct, gpointer data)
GList *
mc_accounts_list_by_profile (McProfile *profile)
{
+ const gchar *profile_name;
GList *ret;
g_return_val_if_fail (profile != NULL, NULL);
+ profile_name = mc_profile_get_unique_name (profile);
+ g_return_val_if_fail (profile_name != NULL, NULL);
ret = mc_accounts_list ();
- ret = mc_accounts_filter (ret, _filter_profile, profile);
+ ret = mc_accounts_filter (ret, _filter_profile, (gchar *)profile_name);
return ret;
}
@@ -840,8 +671,7 @@ static gboolean
_filter_secondary_vcard_field (McAccount *acct, gpointer data)
{
const gchar *vcard_field;
- GConfValue *val;
- GSList *fields;
+ GList *fields, *field;
gboolean ret;
g_return_val_if_fail (acct != NULL, FALSE);
@@ -850,18 +680,18 @@ _filter_secondary_vcard_field (McAccount *acct, gpointer data)
vcard_field = (const gchar *) data;
- val = _mc_account_gconf_get (acct,
- MC_ACCOUNTS_GCONF_KEY_SECONDARY_VCARD_FIELDS, FALSE);
- if (val == NULL) return FALSE;
+ fields = mc_account_get_secondary_vcard_fields (acct);
+ if (fields == NULL) return FALSE;
ret = FALSE;
- for (fields = gconf_value_get_list(val); fields; fields = fields->next) {
- if (0 == strcmp(vcard_field, gconf_value_get_string(fields->data))) {
+ for (field = fields; field != NULL; field = field->next) {
+ if (0 == strcmp(vcard_field, fields->data)) {
ret = TRUE;
}
}
- gconf_value_free(val);
+ g_list_foreach (fields, (GFunc)g_free, NULL);
+ g_list_free (fields);
return ret;
}
@@ -875,35 +705,34 @@ _filter_secondary_vcard_field (McAccount *acct, gpointer data)
gboolean
mc_account_set_secondary_vcard_fields (McAccount *account, const GList *fields)
{
- GConfClient *client;
- gchar *key;
- gboolean ok;
-
- g_return_val_if_fail (account != NULL, FALSE);
- g_return_val_if_fail (MC_ACCOUNT_PRIV (account)->unique_name != NULL,
- FALSE);
-
- client = gconf_client_get_default ();
- g_return_val_if_fail (client != NULL, FALSE);
-
- key = _mc_account_path (MC_ACCOUNT_PRIV (account)->unique_name,
- MC_ACCOUNTS_GCONF_KEY_SECONDARY_VCARD_FIELDS, FALSE);
- if (fields)
+ McAccountPrivate *priv = MC_ACCOUNT_PRIV (account);
+ GValue value = { 0 };
+ GError *error = NULL;
+ gchar **v_fields;
+ guint len, i;
+
+ len = g_list_length ((GList *)fields);
+ v_fields = g_malloc (sizeof (gchar *) * (len + 1));
+ for (i = 0; fields; fields = fields->next, i++)
+ v_fields[i] = g_strdup (fields->data);
+ v_fields[i] = NULL;
+
+ g_value_init (&value, G_TYPE_STRV);
+ g_value_take_boxed (&value, v_fields);
+ mc_cli_dbus_properties_do_set (priv->proxy, -1,
+ MC_IFACE_ACCOUNT_INTERFACE_COMPAT,
+ MC_ACCOUNTS_GCONF_KEY_SECONDARY_VCARD_FIELDS,
+ &value, &error);
+ g_value_unset (&value);
+ if (error)
{
- GSList *s_fields = NULL;
-
- for (; fields != NULL; fields = fields->next)
- s_fields = g_slist_prepend (s_fields, fields->data);
-
- ok = gconf_client_set_list (client, key, GCONF_VALUE_STRING, s_fields, NULL);
+ g_warning ("%s on %s failed: %s",
+ G_STRFUNC, priv->unique_name, error->message);
+ g_error_free (error);
+ return FALSE;
}
else
- ok = gconf_client_unset (client, key, NULL);
-
- g_free (key);
- g_object_unref (client);
-
- return ok;
+ return TRUE;
}
/**
@@ -916,20 +745,37 @@ mc_account_set_secondary_vcard_fields (McAccount *account, const GList *fields)
GList *
mc_account_get_secondary_vcard_fields (McAccount * acct)
{
- GConfValue *val;
- GSList *fields;
- GList *ret = NULL;
-
- val = _mc_account_gconf_get (acct,
- MC_ACCOUNTS_GCONF_KEY_SECONDARY_VCARD_FIELDS, FALSE);
- if (val == NULL) return NULL;
+#ifdef GET_SECONDARY_VCARD_FIELDS
+ McAccountPrivate *priv = MC_ACCOUNT_PRIV (acct);
+ GValue *val_fields;
+ GList *ret = NULL;
+ gchar **fields, **field;
+ GError *error = NULL;
+
+ mc_cli_dbus_properties_do_get (priv->proxy, -1,
+ MC_IFACE_ACCOUNT_INTERFACE_COMPAT,
+ MC_ACCOUNTS_GCONF_KEY_SECONDARY_VCARD_FIELDS,
+ &val_fields, &error);
+ if (error)
+ {
+ g_warning ("%s on %s failed: %s",
+ G_STRFUNC, priv->unique_name, error->message);
+ g_error_free (error);
+ return NULL;
+ }
+ fields = g_value_get_boxed (val_fields);
+ g_free (val_fields);
- for (fields = gconf_value_get_list(val); fields; fields = fields->next) {
- ret = g_list_prepend(ret, g_strdup(gconf_value_get_string(fields->data)));
- }
+ /* put the fields into a list */
+ for (field = fields; *field != NULL; field++)
+ ret = g_list_append (ret, *field);
+ g_free (fields);
- gconf_value_free(val);
- return ret;
+ return ret;
+#else
+ g_warning ("%s is disabled due to spamming", G_STRFUNC);
+ return NULL;
+#endif
}
/**
@@ -1058,15 +904,9 @@ mc_account_get_normalized_name (McAccount *account)
gboolean
mc_account_set_normalized_name (McAccount *account, const gchar *name)
{
- if (_mc_account_gconf_set_string (account,
- MC_ACCOUNTS_GCONF_KEY_NORMALIZED_NAME,
- name))
- {
- _mc_account_set_normalized_name_priv (account, name);
- return TRUE;
- }
- else
- return FALSE;
+ g_warning ("%s: only mission-control should call this function!",
+ G_STRFUNC);
+ return FALSE;
}
/**
@@ -1105,9 +945,22 @@ mc_account_get_profile (McAccount *account)
priv = MC_ACCOUNT_PRIV (account);
if (G_UNLIKELY (!priv->profile_name))
{
- if (!_mc_account_gconf_get_string (account, MC_ACCOUNTS_GCONF_KEY_PROFILE,
- FALSE, &priv->profile_name))
- return NULL;
+ GValue *val_profile;
+ GError *error = NULL;
+
+ mc_cli_dbus_properties_do_get (priv->proxy, -1,
+ MC_IFACE_ACCOUNT_INTERFACE_COMPAT,
+ MC_ACCOUNTS_GCONF_KEY_PROFILE,
+ &val_profile, &error);
+ if (error)
+ {
+ g_warning ("%s: getting profile for %s failed: %s",
+ G_STRFUNC, priv->unique_name, error->message);
+ g_error_free (error);
+ return NULL;
+ }
+ priv->profile_name = (gchar *)g_value_get_string (val_profile);
+ g_free (val_profile);
}
return mc_profile_lookup (priv->profile_name);
@@ -1145,15 +998,25 @@ mc_account_get_display_name (McAccount *account)
gboolean
mc_account_set_display_name (McAccount *account, const gchar *name)
{
- if (_mc_account_gconf_set_string (account,
- MC_ACCOUNTS_GCONF_KEY_DISPLAY_NAME,
- (name && *name) ? name : NULL))
+ McAccountPrivate *priv = MC_ACCOUNT_PRIV (account);
+ GValue value = { 0 };
+ GError *error = NULL;
+
+ g_value_init (&value, G_TYPE_STRING);
+ g_value_set_static_string (&value, name);
+ mc_cli_dbus_properties_do_set (priv->proxy, -1,
+ MC_IFACE_ACCOUNT,
+ MC_ACCOUNTS_GCONF_KEY_DISPLAY_NAME,
+ &value, &error);
+ if (error)
{
- _mc_account_set_display_name_priv (account, name);
- return TRUE;
+ g_warning ("%s on %s failed: %s",
+ G_STRFUNC, priv->unique_name, error->message);
+ g_error_free (error);
+ return FALSE;
}
else
- return FALSE;
+ return TRUE;
}
/**
@@ -1172,44 +1035,6 @@ mc_account_is_enabled (McAccount *account)
return MC_ACCOUNT_PRIV (account)->enabled;
}
-static gboolean
-mc_account_is_deleted (McAccount *account)
-{
- gboolean deleted;
-
- g_return_val_if_fail (account != NULL, FALSE);
- g_return_val_if_fail (MC_ACCOUNT_PRIV (account)->unique_name != NULL, FALSE);
-
- if (!_mc_account_gconf_get_boolean (account, MC_ACCOUNTS_GCONF_KEY_DELETED,
- FALSE, &deleted))
- return FALSE;
-
- return deleted;
-}
-
-static gboolean
-mc_account_set_deleted (McAccount *account, gboolean deleted)
-{
- GConfClient *client;
- gchar *key;
- gboolean ok;
-
- g_return_val_if_fail (account != NULL, FALSE);
- g_return_val_if_fail (MC_ACCOUNT_PRIV (account)->unique_name != NULL, FALSE);
-
- client = gconf_client_get_default ();
- g_return_val_if_fail (client != NULL, FALSE);
-
- key = _mc_account_path (MC_ACCOUNT_PRIV (account)->unique_name,
- MC_ACCOUNTS_GCONF_KEY_DELETED, FALSE);
- ok = gconf_client_set_bool (client, key, deleted, NULL);
-
- g_free (key);
- g_object_unref (client);
-
- return ok;
-}
-
/**
* mc_account_set_enabled:
* @account: The #McAccount.
@@ -1220,27 +1045,49 @@ mc_account_set_deleted (McAccount *account, gboolean deleted)
* Return value: %TRUE, or %FALSE if some error occurred.
*/
gboolean
-mc_account_set_enabled (McAccount *account, const gboolean enabled)
-{
- GConfClient *client;
- gchar *key;
- gboolean ok;
-
- g_return_val_if_fail (account != NULL, FALSE);
- g_return_val_if_fail (MC_ACCOUNT_PRIV (account)->unique_name != NULL, FALSE);
-
- client = gconf_client_get_default ();
- g_return_val_if_fail (client != NULL, FALSE);
-
- gconf_client_suggest_sync (client, NULL);
- key = _mc_account_path (MC_ACCOUNT_PRIV (account)->unique_name,
- MC_ACCOUNTS_GCONF_KEY_ENABLED, FALSE);
- ok = gconf_client_set_bool (client, key, enabled, NULL);
+mc_account_set_enabled (McAccount *account, gboolean enabled)
+{
+ McAccountPrivate *priv = MC_ACCOUNT_PRIV (account);
+ GValue value = { 0 };
+ GError *error = NULL;
+
+ g_value_init (&value, G_TYPE_BOOLEAN);
+ g_value_set_boolean (&value, enabled);
+ mc_cli_dbus_properties_do_set (priv->proxy, -1,
+ MC_IFACE_ACCOUNT,
+ MC_ACCOUNTS_GCONF_KEY_ENABLED,
+ &value, &error);
+ if (error)
+ {
+ g_warning ("%s on %s failed: %s",
+ G_STRFUNC, priv->unique_name, error->message);
+ g_error_free (error);
+ return FALSE;
+ }
+ else
+ return TRUE;
+}
- g_free (key);
- g_object_unref (client);
+static gboolean
+mc_account_get_param (McAccount *account, const gchar *name,
+ GValue *dst_value)
+{
+ GHashTable *parameters;
+ GValue *value;
+ gboolean ok = FALSE;
- return ok;
+ g_debug ("%s: %s", G_STRFUNC, name);
+ parameters = mc_account_get_params (account);
+ if (!parameters) return FALSE;
+ value = g_hash_table_lookup (parameters, name);
+ if (value)
+ {
+ g_value_init (dst_value, G_VALUE_TYPE (value));
+ g_value_copy (value, dst_value);
+ ok = TRUE;
+ }
+ g_hash_table_destroy (parameters);
+ return ok;
}
/**
@@ -1259,6 +1106,7 @@ mc_account_get_param_boolean (McAccount *account,
gboolean *value)
{
McAccountSettingState ret;
+ GValue val = { 0 };
g_return_val_if_fail (account != NULL, MC_ACCOUNT_SETTING_ABSENT);
g_return_val_if_fail (MC_ACCOUNT_PRIV (account)->unique_name != NULL,
@@ -1270,8 +1118,9 @@ mc_account_get_param_boolean (McAccount *account,
ret = MC_ACCOUNT_SETTING_ABSENT;
- if (_mc_account_gconf_get_boolean (account, name, TRUE, value))
+ if (mc_account_get_param (account, name, &val))
{
+ *value = g_value_get_boolean (&val);
ret = MC_ACCOUNT_SETTING_FROM_ACCOUNT;
}
else
@@ -1485,6 +1334,7 @@ mc_account_get_param_int (McAccount *account,
gint int_val;
McProfile *profile;
const gchar *def;
+ GValue val = { 0 };
g_return_val_if_fail (account != NULL, MC_ACCOUNT_SETTING_ABSENT);
g_return_val_if_fail (MC_ACCOUNT_PRIV (account)->unique_name != NULL,
@@ -1494,8 +1344,26 @@ mc_account_get_param_int (McAccount *account,
/* TODO: retreive type from protocol and check it matches */
- if (_mc_account_gconf_get_int (account, name, TRUE, value))
+ if (mc_account_get_param (account, name, &val))
+ {
+ if (G_VALUE_TYPE (&val) == G_TYPE_INT)
+ *value = g_value_get_int (&val);
+ else if (g_value_type_transformable (G_VALUE_TYPE (&val), G_TYPE_INT))
+ {
+ GValue trans = { 0 };
+
+ g_value_init (&trans, G_TYPE_INT);
+ g_value_transform (&val, &trans);
+ *value = g_value_get_int (&trans);
+ }
+ else
+ {
+ g_warning ("%s: param %s has type %s (expecting integer)",
+ G_STRFUNC, name, G_VALUE_TYPE_NAME (&val));
+ return MC_ACCOUNT_SETTING_ABSENT;
+ }
return MC_ACCOUNT_SETTING_FROM_ACCOUNT;
+ }
profile = mc_account_get_profile (account);
def = mc_profile_get_default_setting (profile, name);
@@ -1569,6 +1437,8 @@ mc_account_get_param_string (McAccount *account,
{
McProfile *profile;
const gchar *def;
+ GValue val = { 0 };
+ McAccountPrivate *priv = MC_ACCOUNT_PRIV (account);
g_return_val_if_fail (account != NULL, MC_ACCOUNT_SETTING_ABSENT);
g_return_val_if_fail (MC_ACCOUNT_PRIV (account)->unique_name != NULL,
@@ -1578,8 +1448,23 @@ mc_account_get_param_string (McAccount *account,
/* TODO: retreive type from protocol and check it matches */
- if (_mc_account_gconf_get_string (account, name, TRUE, value))
+ if (priv->last_name && strcmp (priv->last_name, name) == 0)
+ {
+ g_warning ("%s: you are calling me for the same param (%s), please cache it",
+ G_STRFUNC, name);
+ *value = g_strdup (priv->last_value);
return MC_ACCOUNT_SETTING_FROM_ACCOUNT;
+ }
+ g_free (priv->last_name);
+ priv->last_name = NULL;
+ if (mc_account_get_param (account, name, &val))
+ {
+ *value = (gchar *)g_value_get_string (&val);
+ g_free (priv->last_value);
+ priv->last_name = g_strdup (name);
+ priv->last_value = g_strdup (*value);
+ return MC_ACCOUNT_SETTING_FROM_ACCOUNT;
+ }
profile = mc_account_get_profile (account);
def = mc_profile_get_default_setting (profile, name);
@@ -1614,6 +1499,35 @@ mc_account_get_param_string (McAccount *account,
return MC_ACCOUNT_SETTING_ABSENT;
}
+static gboolean
+mc_account_set_param (McAccount *account, const gchar *name,
+ const GValue *value)
+{
+ McAccountPrivate *priv = MC_ACCOUNT_PRIV (account);
+ const gchar *unset[] = { NULL, NULL };
+ GHashTable *set;
+ GError *error = NULL;
+
+ set = g_hash_table_new (g_str_hash, g_str_equal);
+ if (value)
+ g_hash_table_insert (set, (gpointer)name, (gpointer)value);
+ else
+ unset[0] = name;
+ mc_cli_account_do_update_parameters (priv->proxy, -1,
+ set, unset,
+ &error);
+ g_hash_table_destroy (set);
+ if (error)
+ {
+ g_warning ("%s on %s failed: %s",
+ G_STRFUNC, priv->unique_name, error->message);
+ g_error_free (error);
+ return FALSE;
+ }
+ else
+ return TRUE;
+}
+
/**
* mc_account_set_param_boolean:
* @account: The #McAccount.
@@ -1629,26 +1543,53 @@ mc_account_set_param_boolean (McAccount *account,
const gchar *name,
gboolean value)
{
- GConfClient *client;
- gchar *key;
- gboolean ok;
-
- g_return_val_if_fail (account != NULL, FALSE);
- g_return_val_if_fail (MC_ACCOUNT_PRIV (account)->unique_name != NULL,
- FALSE);
- g_return_val_if_fail (name != NULL, FALSE);
-
- client = gconf_client_get_default ();
- g_return_val_if_fail (client != NULL, FALSE);
+ GValue val = { 0 };
- key = _mc_account_path (MC_ACCOUNT_PRIV (account)->unique_name, name,
- TRUE);
- ok = gconf_client_set_bool (client, key, value, NULL);
+ g_value_init (&val, G_TYPE_BOOLEAN);
+ g_value_set_boolean (&val, value);
+ return mc_account_set_param (account, name, &val);
+}
- g_free (key);
- g_object_unref (client);
+static inline GType
+get_param_type (McAccount *account, const gchar *name)
+{
+ McProfile *profile;
+ McProtocol *protocol;
+ GType ret = G_TYPE_INT;
- return ok;
+ profile = mc_account_get_profile (account);
+ if (profile)
+ {
+ protocol = mc_profile_get_protocol (profile);
+ if (protocol)
+ {
+ GSList *params, *param;
+
+ params = mc_protocol_get_params (protocol);
+ for (param = params; param != NULL; param = param->next)
+ {
+ McProtocolParam *p = param->data;
+ if (strcmp (p->name, name) == 0)
+ {
+ switch (p->signature[0])
+ {
+ case DBUS_TYPE_INT16:
+ case DBUS_TYPE_INT32:
+ ret = G_TYPE_INT;
+ break;
+ case DBUS_TYPE_UINT16:
+ case DBUS_TYPE_UINT32:
+ ret = G_TYPE_UINT;
+ break;
+ }
+ break;
+ }
+ }
+ g_object_unref (protocol);
+ }
+ g_object_unref (profile);
+ }
+ return ret;
}
/**
@@ -1666,26 +1607,16 @@ mc_account_set_param_int (McAccount *account,
const gchar *name,
gint value)
{
- GConfClient *client;
- gchar *key;
- gboolean ok;
-
- g_return_val_if_fail (account != NULL, FALSE);
- g_return_val_if_fail (MC_ACCOUNT_PRIV (account)->unique_name != NULL,
- FALSE);
- g_return_val_if_fail (name != NULL, FALSE);
-
- client = gconf_client_get_default ();
- g_return_val_if_fail (client != NULL, FALSE);
-
- key = _mc_account_path (MC_ACCOUNT_PRIV (account)->unique_name, name,
- TRUE);
- ok = gconf_client_set_int (client, key, value, NULL);
-
- g_free (key);
- g_object_unref (client);
+ GValue val = { 0 };
+ GType type;
- return ok;
+ type = get_param_type (account, name);
+ g_value_init (&val, type);
+ if (type == G_TYPE_INT)
+ g_value_set_int (&val, value);
+ else
+ g_value_set_uint (&val, (guint)value);
+ return mc_account_set_param (account, name, &val);
}
/**
@@ -1703,26 +1634,11 @@ mc_account_set_param_string (McAccount *account,
const gchar *name,
const gchar *value)
{
- GConfClient *client;
- gchar *key;
- gboolean ok;
-
- g_return_val_if_fail (account != NULL, FALSE);
- g_return_val_if_fail (MC_ACCOUNT_PRIV (account)->unique_name != NULL,
- FALSE);
- g_return_val_if_fail (name != NULL, FALSE);
-
- client = gconf_client_get_default ();
- g_return_val_if_fail (client != NULL, FALSE);
-
- key = _mc_account_path (MC_ACCOUNT_PRIV (account)->unique_name, name,
- TRUE);
- ok = gconf_client_set_string (client, key, value, NULL);
+ GValue val = { 0 };
- g_free (key);
- g_object_unref (client);
-
- return ok;
+ g_value_init (&val, G_TYPE_STRING);
+ g_value_set_static_string (&val, value);
+ return mc_account_set_param (account, name, &val);
}
/**
@@ -1737,111 +1653,7 @@ mc_account_set_param_string (McAccount *account,
gboolean
mc_account_unset_param (McAccount *account, const gchar *name)
{
- McAccountPrivate *priv = MC_ACCOUNT_PRIV (account);
- GConfClient *client;
- gchar *key;
- gboolean ok;
-
- g_return_val_if_fail (account != NULL, FALSE);
- g_return_val_if_fail (MC_ACCOUNT_PRIV (account)->unique_name != NULL,
- FALSE);
- g_return_val_if_fail (name != NULL, FALSE);
-
- client = gconf_client_get_default ();
- g_return_val_if_fail (client != NULL, FALSE);
-
- key = _mc_account_path (priv->unique_name, name, TRUE);
- ok = gconf_client_unset (client, key, NULL);
-
- g_free (key);
- g_object_unref (client);
-
- return ok;
-}
-
-static void
-_g_value_free (gpointer data)
-{
- GValue *value = (GValue *) data;
- g_value_unset (value);
- g_free (value);
-}
-
-static void
-_add_one_setting (McAccount *account,
- McProtocolParam *param,
- GHashTable *hash)
-{
- GValue *value = NULL;
- McAccountSettingState ret = MC_ACCOUNT_SETTING_ABSENT;
-
- g_return_if_fail (account != NULL);
- g_return_if_fail (MC_ACCOUNT_PRIV (account)->unique_name != NULL);
- g_return_if_fail (param != NULL);
- g_return_if_fail (param->name != NULL);
- g_return_if_fail (param->signature != NULL);
-
- switch (param->signature[0])
- {
- case DBUS_TYPE_STRING:
- {
- char *tmp;
- ret = mc_account_get_param_string (account, param->name, &tmp);
- if (ret != MC_ACCOUNT_SETTING_ABSENT)
- {
- value = g_new0(GValue, 1);
- g_value_init (value, G_TYPE_STRING);
- g_value_take_string (value, tmp);
- }
- break;
- }
- case DBUS_TYPE_INT16:
- case DBUS_TYPE_INT32:
- {
- gint tmp;
- ret = mc_account_get_param_int (account, param->name, &tmp);
- if (ret != MC_ACCOUNT_SETTING_ABSENT)
- {
- value = g_new0(GValue, 1);
- g_value_init (value, G_TYPE_INT);
- g_value_set_int (value, tmp);
- }
- break;
- }
- case DBUS_TYPE_UINT16:
- case DBUS_TYPE_UINT32:
- {
- gint tmp;
- ret = mc_account_get_param_int (account, param->name, &tmp);
- if (ret != MC_ACCOUNT_SETTING_ABSENT)
- {
- value = g_new0(GValue, 1);
- g_value_init (value, G_TYPE_UINT);
- g_value_set_uint (value, tmp);
- }
- break;
- }
- case DBUS_TYPE_BOOLEAN:
- {
- gboolean tmp;
- ret = mc_account_get_param_boolean (account, param->name, &tmp);
- if (ret != MC_ACCOUNT_SETTING_ABSENT)
- {
- value = g_new0(GValue, 1);
- g_value_init (value, G_TYPE_BOOLEAN);
- g_value_set_boolean (value, tmp);
- }
- break;
- }
- default:
- g_warning ("%s: skipping parameter %s, unknown type %s", G_STRFUNC, param->name, param->signature);
- }
-
- if (ret != MC_ACCOUNT_SETTING_ABSENT && hash != NULL)
- {
- g_return_if_fail (value != NULL);
- g_hash_table_insert (hash, g_strdup (param->name), value);
- }
+ return mc_account_set_param (account, name, NULL);
}
/**
@@ -1856,48 +1668,33 @@ _add_one_setting (McAccount *account,
GHashTable *
mc_account_get_params (McAccount *account)
{
- McProfile *profile = NULL;
- McProtocol *protocol = NULL;
- GSList *params, *tmp;
- GHashTable *ret = NULL;
-
- g_return_val_if_fail (account != NULL, NULL);
- g_return_val_if_fail (MC_ACCOUNT_PRIV (account)->unique_name != NULL,
- NULL);
+ GHashTable *parameters;
+ McAccountPrivate *priv = MC_ACCOUNT_PRIV (account);
+ GValue *val_parameters;
+ GError *error = NULL;
- profile = mc_account_get_profile (account);
- if (profile == NULL)
- {
- g_debug ("%s: getting profile failed", G_STRFUNC);
- goto OUT;
- }
+ g_return_val_if_fail (account != NULL, NULL);
+ g_return_val_if_fail (MC_ACCOUNT_PRIV (account)->unique_name != NULL,
+ NULL);
- protocol = mc_profile_get_protocol (profile);
- if (protocol == NULL)
+ mc_cli_dbus_properties_do_get (priv->proxy, -1,
+ MC_IFACE_ACCOUNT,
+ MC_ACCOUNTS_GCONF_KEY_PARAMETERS,
+ &val_parameters, &error);
+ if (error)
{
- g_debug ("%s: getting protocol failed", G_STRFUNC);
- goto OUT;
+ g_warning ("%s: getting parameters for %s failed: %s",
+ G_STRFUNC, priv->unique_name, error->message);
+ g_error_free (error);
+ return NULL;
}
- ret = g_hash_table_new_full (g_str_hash, g_str_equal,
- (GDestroyNotify) g_free,
- (GDestroyNotify) _g_value_free);
-
- params = mc_protocol_get_params (protocol);
+ parameters = g_value_get_boxed (val_parameters);
- for (tmp = params; tmp != NULL; tmp = tmp->next)
- _add_one_setting (account, (McProtocolParam *) tmp->data, ret);
+ /* this does not free the hastable */
+ g_free (val_parameters);
- mc_protocol_free_params_list (params);
-
-OUT:
- if (protocol)
- g_object_unref (protocol);
-
- if (profile)
- g_object_unref (profile);
-
- return ret;
+ return parameters;
}
/**
@@ -1912,104 +1709,9 @@ OUT:
gboolean
mc_account_is_complete (McAccount *account)
{
- McProfile *profile = NULL;
- McProtocol *protocol = NULL;
- GSList *params = NULL, *tmp;
- gboolean ret = TRUE;
-
- g_return_val_if_fail (account != NULL, FALSE);
-
- /* Check if account was expunged */
- if (MC_ACCOUNT_PRIV (account)->unique_name == NULL)
- return FALSE;
-
- /* Check if account was deleted */
- if (mc_account_is_deleted (account))
- return FALSE;
-
- profile = mc_account_get_profile (account);
- if (profile == NULL)
- {
- ret = FALSE;
- goto OUT;
- }
-
- protocol = mc_profile_get_protocol (profile);
- if (protocol == NULL)
- {
- ret = FALSE;
- goto OUT;
- }
-
- params = mc_protocol_get_params (protocol);
-
- for (tmp = params; tmp != NULL; tmp = tmp->next)
- {
- McProtocolParam *param;
- const gchar *def;
- GConfValue *val;
-
- param = (McProtocolParam *) tmp->data;
-
- if (!(param->flags & MC_PROTOCOL_PARAM_REQUIRED))
- continue;
-
- if (param == NULL || param->name == NULL || param->signature == NULL)
- {
- ret = FALSE;
- break;
- }
-
- /* TODO: check this value can be mapped to the desired type */
- def = mc_profile_get_default_setting (profile, param->name);
- if (def)
- {
- continue;
- }
-
- val = _mc_account_gconf_get (account, param->name, TRUE);
- if (val == NULL)
- {
- ret = FALSE;
- break;
- }
-
- /* TODO: unduplicate this type mapping */
- switch (param->signature[0])
- {
- case DBUS_TYPE_BOOLEAN:
- if (val->type != GCONF_VALUE_BOOL)
- ret = FALSE;
- break;
- case DBUS_TYPE_INT16:
- case DBUS_TYPE_UINT16:
- if (val->type != GCONF_VALUE_INT)
- ret = FALSE;
- break;
- case DBUS_TYPE_STRING:
- if (val->type != GCONF_VALUE_STRING)
- ret = FALSE;
- break;
- default:
- ret = FALSE;
- }
-
- gconf_value_free (val);
-
- if (ret == FALSE)
- break;
- }
-
- mc_protocol_free_params_list (params);
-
-OUT:
- if (profile != NULL)
- g_object_unref (profile);
-
- if (protocol != NULL)
- g_object_unref (protocol);
+ g_return_val_if_fail (account != NULL, FALSE);
- return ret;
+ return MC_ACCOUNT_PRIV (account)->valid;
}
/**
@@ -2107,67 +1809,37 @@ gboolean
mc_account_set_avatar_from_data (McAccount *account, const gchar *data,
gsize len, const gchar *mime_type)
{
- gchar *data_dir, *filename_out;
- GConfClient *client;
- gboolean ret = TRUE;
- gchar *key;
-
- g_return_val_if_fail (account != NULL, FALSE);
-
- data_dir = get_account_data_path (MC_ACCOUNT_PRIV(account)->unique_name);
- filename_out = g_build_filename (data_dir, MC_AVATAR_FILENAME, NULL);
- if (!g_file_test (data_dir, G_FILE_TEST_EXISTS))
- g_mkdir_with_parents (data_dir, 0777);
- g_free (data_dir);
-
- if (data)
+ McAccountPrivate *priv = MC_ACCOUNT_PRIV (account);
+ GValue value = { 0 };
+ GError *error = NULL;
+ GArray avatar;
+ GType type;
+
+ avatar.data = (gchar *)data;
+ avatar.len = len;
+ type = dbus_g_type_get_struct ("GValueArray",
+ dbus_g_type_get_collection ("GArray",
+ G_TYPE_UCHAR),
+ G_TYPE_STRING,
+ G_TYPE_INVALID);
+ g_value_init (&value, type);
+ g_value_set_static_boxed (&value, dbus_g_type_specialized_construct (type));
+ GValueArray *va = (GValueArray *) g_value_get_boxed (&value);
+ g_value_take_boxed (va->values, &avatar);
+ g_value_set_static_string (va->values + 1, mime_type);
+ mc_cli_dbus_properties_do_set (priv->proxy, -1,
+ MC_IFACE_ACCOUNT,
+ MC_ACCOUNTS_GCONF_KEY_AVATAR,
+ &value, &error);
+ if (error)
{
- if (!g_file_set_contents (filename_out, data, (gssize)len, NULL))
- {
- g_warning ("%s: writing to file %s failed", G_STRLOC,
- filename_out);
- g_free (filename_out);
- return FALSE;
- }
+ g_warning ("%s on %s failed: %s",
+ G_STRFUNC, priv->unique_name, error->message);
+ g_error_free (error);
+ return FALSE;
}
else
- {
- /* create an empty file; this will cause MC to clear the current
- * avatar */
- FILE *f_out = fopen (filename_out, "w");
- fclose (f_out);
- }
-
- client = gconf_client_get_default ();
- g_return_val_if_fail (client != NULL, FALSE);
-
- key = _mc_account_path (MC_ACCOUNT_PRIV (account)->unique_name,
- MC_ACCOUNTS_GCONF_KEY_AVATAR_TOKEN, FALSE);
- ret = gconf_client_unset(client, key, NULL);
- g_free (key);
- if (!ret) goto error;
-
- /* put an ID for the avatar, so that listeners of the "account-changed"
- * signal will be able to determine whether the avatar has changed without
- * having to load the file */
- key = _mc_account_path (MC_ACCOUNT_PRIV (account)->unique_name,
- MC_ACCOUNTS_GCONF_KEY_AVATAR_ID, FALSE);
- ret = gconf_client_set_int(client, key, time(0), NULL);
- g_free (key);
-
- if (mime_type)
- {
- key = _mc_account_path (MC_ACCOUNT_PRIV (account)->unique_name,
- MC_ACCOUNTS_GCONF_KEY_AVATAR_MIME, FALSE);
- ret = gconf_client_set_string (client, key, mime_type, NULL);
- g_free (key);
- }
-
-error:
- g_object_unref (client);
- g_free (filename_out);
-
- return ret;
+ return TRUE;
}
/**
@@ -2183,9 +1855,9 @@ error:
gboolean
mc_account_set_avatar_token (McAccount *account, const gchar *token)
{
- return _mc_account_gconf_set_string (account,
- MC_ACCOUNTS_GCONF_KEY_AVATAR_TOKEN,
- token);
+ g_warning ("%s: only mission-control should call this function!",
+ G_STRFUNC);
+ return FALSE;
}
/**
@@ -2201,9 +1873,9 @@ mc_account_set_avatar_token (McAccount *account, const gchar *token)
gboolean
mc_account_set_avatar_mime_type (McAccount *account, const gchar *mime_type)
{
- return _mc_account_gconf_set_string (account,
- MC_ACCOUNTS_GCONF_KEY_AVATAR_MIME,
- mime_type);
+ g_warning ("%s: only mission-control should call this function!",
+ G_STRFUNC);
+ return FALSE;
}
/**
@@ -2223,43 +1895,54 @@ gboolean
mc_account_get_avatar (McAccount *account, gchar **filename,
gchar **mime_type, gchar **token)
{
- gchar *data_dir;
- GConfClient *client;
- gchar *key;
-
- g_return_val_if_fail (account != NULL, FALSE);
+ McAccountPrivate *priv = MC_ACCOUNT_PRIV (account);
+ GValue *val_avatar;
+ GError *error = NULL;
if (filename)
{
- data_dir =
- get_account_data_path (MC_ACCOUNT_PRIV (account)->unique_name);
- *filename = g_build_filename (data_dir, MC_AVATAR_FILENAME, NULL);
- if (!g_file_test (data_dir, G_FILE_TEST_EXISTS))
- g_mkdir_with_parents (data_dir, 0777);
- g_free (data_dir);
+ mc_cli_dbus_properties_do_get (priv->proxy, -1,
+ MC_IFACE_ACCOUNT_INTERFACE_COMPAT,
+ MC_ACCOUNTS_GCONF_KEY_AVATAR_FILE,
+ &val_avatar, &error);
+ if (error)
+ {
+ g_warning ("%s: getting avatar file for %s failed: %s",
+ G_STRFUNC, priv->unique_name, error->message);
+ g_error_free (error);
+ return FALSE;
+ }
+ *filename = (gchar *)g_value_get_string (val_avatar);
+ g_free (val_avatar);
}
- client = gconf_client_get_default ();
- g_return_val_if_fail (client != NULL, FALSE);
-
- if (token)
+ if (mime_type)
{
- key = _mc_account_path (MC_ACCOUNT_PRIV (account)->unique_name,
- MC_ACCOUNTS_GCONF_KEY_AVATAR_TOKEN, FALSE);
- *token = gconf_client_get_string (client, key, NULL);
- g_free (key);
+ mc_cli_dbus_properties_do_get (priv->proxy, -1,
+ MC_IFACE_ACCOUNT,
+ MC_ACCOUNTS_GCONF_KEY_AVATAR,
+ &val_avatar, &error);
+ if (error)
+ {
+ g_warning ("%s: getting avatar for %s failed: %s",
+ G_STRFUNC, priv->unique_name, error->message);
+ g_error_free (error);
+ return FALSE;
+ }
+ GValueArray *va = (GValueArray *) g_value_get_boxed (val_avatar);
+ g_debug ("value array at %p, type %s, %d elems", va, G_VALUE_TYPE_NAME (val_avatar), va->n_values);
+ *mime_type = g_value_dup_string (va->values + 1);
+ g_value_unset (val_avatar);
+ g_free (val_avatar);
}
- if (mime_type)
+ /* we cannot know the token, but it was used only for mission-control */
+ if (token)
{
- key = _mc_account_path (MC_ACCOUNT_PRIV (account)->unique_name,
- MC_ACCOUNTS_GCONF_KEY_AVATAR_MIME, FALSE);
- *mime_type = gconf_client_get_string (client, key, NULL);
- g_free (key);
+ g_warning ("%s: only mission-control should retrieve the token!",
+ G_STRFUNC);
}
- g_object_unref (client);
-
return TRUE;
}
@@ -2275,22 +1958,9 @@ mc_account_get_avatar (McAccount *account, gchar **filename,
gint
mc_account_get_avatar_id (McAccount *account)
{
- GConfClient *client;
- gchar *key;
- gint ret;
+ McAccountPrivate *priv = MC_ACCOUNT_PRIV (account);
- g_return_val_if_fail (account != NULL, 0);
-
- client = gconf_client_get_default ();
- g_return_val_if_fail (client != NULL, 0);
-
- key = _mc_account_path (MC_ACCOUNT_PRIV (account)->unique_name,
- MC_ACCOUNTS_GCONF_KEY_AVATAR_ID, FALSE);
- ret = gconf_client_get_int (client, key, NULL);
- g_free (key);
-
- g_object_unref (client);
- return ret;
+ return priv->avatar_id;
}
/**
@@ -2306,22 +1976,8 @@ mc_account_get_avatar_id (McAccount *account)
gboolean
mc_account_reset_avatar_id (McAccount *account)
{
- GConfClient *client;
- gchar *key;
- gboolean ok;
-
- g_return_val_if_fail (account != FALSE, 0);
-
- client = gconf_client_get_default ();
- g_return_val_if_fail (client != FALSE, 0);
-
- key = _mc_account_path (MC_ACCOUNT_PRIV (account)->unique_name,
- MC_ACCOUNTS_GCONF_KEY_AVATAR_ID, FALSE);
- ok = gconf_client_set_int (client, key, time(0), NULL);
- g_free (key);
-
- g_object_unref (client);
- return ok;
+ /* does nothing */
+ return TRUE;
}
/**
@@ -2335,16 +1991,9 @@ mc_account_reset_avatar_id (McAccount *account)
gchar *
mc_account_get_alias (McAccount *account)
{
- gchar *name;
-
g_return_val_if_fail (account != NULL, NULL);
- if (!_mc_account_gconf_get_string (account,
- MC_ACCOUNTS_GCONF_KEY_ALIAS,
- FALSE, &name))
- return NULL;
-
- return name;
+ return g_strdup (MC_ACCOUNT_PRIV (account)->alias);
}
/**
@@ -2359,7 +2008,24 @@ mc_account_get_alias (McAccount *account)
gboolean
mc_account_set_alias (McAccount *account, const gchar *alias)
{
- return _mc_account_gconf_set_string (account,
- MC_ACCOUNTS_GCONF_KEY_ALIAS,
- alias);
+ McAccountPrivate *priv = MC_ACCOUNT_PRIV (account);
+ GValue value = { 0 };
+ GError *error = NULL;
+
+ g_value_init (&value, G_TYPE_STRING);
+ g_value_set_static_string (&value, alias);
+ mc_cli_dbus_properties_do_set (priv->proxy, -1,
+ MC_IFACE_ACCOUNT,
+ MC_ACCOUNTS_GCONF_KEY_ALIAS,
+ &value, &error);
+ if (error)
+ {
+ g_warning ("%s on %s failed: %s",
+ G_STRFUNC, priv->unique_name, error->message);
+ g_error_free (error);
+ return FALSE;
+ }
+ else
+ return TRUE;
}
+
diff --git a/libmissioncontrol/mc.c b/libmissioncontrol/mc.c
index f78a44e8..e8a19d14 100644
--- a/libmissioncontrol/mc.c
+++ b/libmissioncontrol/mc.c
@@ -22,6 +22,10 @@
*/
#include <gmodule.h>
+#include <telepathy-glib/dbus.h>
+#include <telepathy-glib/interfaces.h>
+#include <telepathy-glib/proxy-subclass.h>
+
#include "mc.h"
@@ -48,3 +52,111 @@ mc_make_resident (void)
g_module_make_resident (module);
}
+gboolean
+mc_cli_dbus_properties_do_get (gpointer proxy,
+ gint timeout_ms,
+ const gchar *in_Interface_Name,
+ const gchar *in_Property_Name,
+ GValue **out_Value,
+ GError **error)
+{
+ DBusGProxy *iface;
+ GQuark interface = TP_IFACE_QUARK_DBUS_PROPERTIES;
+ GValue *o_Value = g_new0 (GValue, 1);
+
+ g_return_val_if_fail (TP_IS_PROXY (proxy), FALSE);
+
+ iface = tp_proxy_borrow_interface_by_id
+ ((TpProxy *) proxy, interface, error);
+
+ if (iface == NULL)
+ return FALSE;
+
+ if(dbus_g_proxy_call_with_timeout (iface,
+ "Get",
+ timeout_ms,
+ error,
+ G_TYPE_STRING, in_Interface_Name,
+ G_TYPE_STRING, in_Property_Name,
+ G_TYPE_INVALID,
+ G_TYPE_VALUE, o_Value,
+ G_TYPE_INVALID))
+ {
+ *out_Value = o_Value;
+ return TRUE;
+ }
+ else
+ {
+ g_free (o_Value);
+ return FALSE;
+ }
+}
+
+
+gboolean
+mc_cli_dbus_properties_do_get_all (gpointer proxy,
+ gint timeout_ms,
+ const gchar *in_Interface_Name,
+ GHashTable **out_Properties,
+ GError **error)
+{
+ DBusGProxy *iface;
+ GQuark interface = TP_IFACE_QUARK_DBUS_PROPERTIES;
+ GHashTable *o_Properties;
+
+ g_return_val_if_fail (TP_IS_PROXY (proxy), FALSE);
+
+ iface = tp_proxy_borrow_interface_by_id
+ ((TpProxy *) proxy, interface, error);
+
+ if (iface == NULL)
+ return FALSE;
+
+ if (dbus_g_proxy_call_with_timeout (iface,
+ "GetAll",
+ timeout_ms,
+ error,
+ G_TYPE_STRING, in_Interface_Name,
+ G_TYPE_INVALID,
+ (dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE)), &o_Properties,
+ G_TYPE_INVALID))
+ {
+ *out_Properties = o_Properties;
+
+ return TRUE;
+ }
+ else
+ return FALSE;
+}
+
+
+gboolean
+mc_cli_dbus_properties_do_set (gpointer proxy,
+ gint timeout_ms,
+ const gchar *in_Interface_Name,
+ const gchar *in_Property_Name,
+ const GValue *in_Value,
+ GError **error)
+{
+ DBusGProxy *iface;
+ GQuark interface = TP_IFACE_QUARK_DBUS_PROPERTIES;
+
+ g_return_val_if_fail (TP_IS_PROXY (proxy), FALSE);
+
+ iface = tp_proxy_borrow_interface_by_id
+ ((TpProxy *) proxy, interface, error);
+
+ if (iface == NULL)
+ return FALSE;
+
+ return dbus_g_proxy_call_with_timeout (iface,
+ "Set",
+ timeout_ms,
+ error,
+ G_TYPE_STRING, in_Interface_Name,
+ G_TYPE_STRING, in_Property_Name,
+ G_TYPE_VALUE, in_Value,
+ G_TYPE_INVALID);
+}
+
+
diff --git a/libmissioncontrol/mc.h b/libmissioncontrol/mc.h
index 0dc16017..260f52d1 100644
--- a/libmissioncontrol/mc.h
+++ b/libmissioncontrol/mc.h
@@ -21,9 +21,35 @@
*
*/
+#ifndef __MC_H__
+#define __MC_H__
+
+#include <glib-object.h>
+
G_BEGIN_DECLS
void mc_make_resident (void);
+gboolean mc_cli_dbus_properties_do_get (gpointer proxy,
+ gint timeout_ms,
+ const gchar *in_Interface_Name,
+ const gchar *in_Property_Name,
+ GValue **out_Value,
+ GError **error);
+
+gboolean mc_cli_dbus_properties_do_get_all (gpointer proxy,
+ gint timeout_ms,
+ const gchar *in_Interface_Name,
+ GHashTable **out_Properties,
+ GError **error);
+
+gboolean mc_cli_dbus_properties_do_set (gpointer proxy,
+ gint timeout_ms,
+ const gchar *in_Interface_Name,
+ const gchar *in_Property_Name,
+ const GValue *in_Value,
+ GError **error);
+
G_END_DECLS
+#endif
diff --git a/src/Makefile.am b/src/Makefile.am
index e93a3002..4eaa0434 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -6,6 +6,7 @@ INCLUDES = $(GCONF_CFLAGS) $(TELEPATHY_CFLAGS) \
mission_control_includedir = $(includedir)/mission-control
mission_control_include = \
mcd-account.h \
+ mcd-account-compat.h \
mcd-account-manager.h \
mcd-dbusprop.h \
mcd-debug.h \
@@ -31,6 +32,7 @@ nodist_geninclude_HEADERS = \
_gen/interfaces.h \
_gen/gtypes.h \
_gen/svc-Account.h \
+ _gen/svc-Account_Interface_Compat.h \
_gen/svc-Account_Manager.h
nodist_libmissioncontrol_server_la_SOURCES = \
@@ -41,6 +43,7 @@ nodist_libmissioncontrol_server_la_SOURCES = \
_gen/signals-marshal.h \
_gen/signals-marshal.list \
_gen/svc-Account.c \
+ _gen/svc-Account_Interface_Compat.c \
_gen/svc-Account_Manager.c
@@ -73,6 +76,7 @@ libmissioncontrol_server_la_LDFLAGS = -export-dynamic \
libmissioncontrol_server_la_SOURCES = \
mcd-account.c \
+ mcd-account-compat.c \
mcd-account-manager.c \
mcd-dbusprop.c \
mcd-debug.c \
diff --git a/src/mcd-account-compat.c b/src/mcd-account-compat.c
new file mode 100644
index 00000000..fa64240f
--- /dev/null
+++ b/src/mcd-account-compat.c
@@ -0,0 +1,153 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 8 -*- */
+/*
+ * This file is part of mission-control
+ *
+ * Copyright (C) 2008 Nokia Corporation.
+ *
+ * Contact: Alberto Mardegan <alberto.mardegan@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <glib/gstdio.h>
+#include <glib/gi18n.h>
+#include <config.h>
+
+#include <telepathy-glib/svc-generic.h>
+#include <telepathy-glib/gtypes.h>
+#include <telepathy-glib/util.h>
+#include "mcd-account.h"
+#include "mcd-account-priv.h"
+#include "mcd-account-compat.h"
+#include "mcd-account-manager.h"
+#include "_gen/interfaces.h"
+
+
+static void
+set_profile (TpSvcDBusProperties *self, const gchar *name,
+ const GValue *value)
+{
+ McdAccount *account = MCD_ACCOUNT (self);
+ const gchar *string, *unique_name;
+ GKeyFile *keyfile;
+
+ keyfile = mcd_account_get_keyfile (account);
+ unique_name = mcd_account_get_unique_name (account);
+ string = g_value_get_string (value);
+ if (string && string[0] != 0)
+ g_key_file_set_string (keyfile, unique_name,
+ name, string);
+ else
+ {
+ g_key_file_remove_key (keyfile, unique_name,
+ name, NULL);
+ }
+ mcd_account_manager_write_conf (keyfile);
+}
+
+static void
+get_profile (TpSvcDBusProperties *self, const gchar *name, GValue *value)
+{
+ McdAccount *account = MCD_ACCOUNT (self);
+ const gchar *unique_name;
+ GKeyFile *keyfile;
+ gchar *string;
+
+ keyfile = mcd_account_get_keyfile (account);
+ unique_name = mcd_account_get_unique_name (account);
+ string = g_key_file_get_string (keyfile, unique_name,
+ name, NULL);
+ g_value_init (value, G_TYPE_STRING);
+ g_value_take_string (value, string);
+}
+
+static void
+get_avatar_file (TpSvcDBusProperties *self, const gchar *name, GValue *value)
+{
+ McdAccount *account = MCD_ACCOUNT (self);
+ gchar *string;
+
+ string = mcd_account_get_avatar_filename (account);
+ g_value_init (value, G_TYPE_STRING);
+ g_value_take_string (value, string);
+}
+
+static void
+set_secondary_vcard_fields (TpSvcDBusProperties *self, const gchar *name,
+ const GValue *value)
+{
+ McdAccount *account = MCD_ACCOUNT (self);
+ const gchar *unique_name, **fields, **field;
+ GKeyFile *keyfile;
+
+ keyfile = mcd_account_get_keyfile (account);
+ unique_name = mcd_account_get_unique_name (account);
+ fields = g_value_get_boxed (value);
+ if (fields)
+ {
+ gsize len;
+
+ for (field = fields, len = 0; *field; field++, len++);
+ g_key_file_set_string_list (keyfile, unique_name,
+ name, fields, len);
+ }
+ else
+ {
+ g_key_file_remove_key (keyfile, unique_name,
+ name, NULL);
+ }
+ mcd_account_manager_write_conf (keyfile);
+}
+
+static void
+get_secondary_vcard_fields (TpSvcDBusProperties *self, const gchar *name,
+ GValue *value)
+{
+ McdAccount *account = MCD_ACCOUNT (self);
+ GKeyFile *keyfile;
+ const gchar *unique_name;
+ gchar **fields;
+
+ keyfile = mcd_account_get_keyfile (account);
+ unique_name = mcd_account_get_unique_name (account);
+ fields = g_key_file_get_string_list (keyfile, unique_name,
+ name, NULL, NULL);
+ g_value_init (value, G_TYPE_STRV);
+ g_value_take_boxed (value, fields);
+}
+
+
+McdDBusProp account_compat_properties[] = {
+ { "Profile", set_profile, get_profile },
+ { "AvatarFile", NULL, get_avatar_file },
+ { "SecondaryVCardFields", set_secondary_vcard_fields, get_secondary_vcard_fields },
+ { 0 },
+};
+
+const McdDBusProp *
+_mcd_account_compat_get_properties (void)
+{
+ return account_compat_properties;
+}
+
+void
+_mcd_account_compat_iface_init (McSvcAccountInterfaceCompatClass *iface,
+ gpointer iface_data)
+{
+}
+
diff --git a/src/mcd-account-compat.h b/src/mcd-account-compat.h
new file mode 100644
index 00000000..44fd04a0
--- /dev/null
+++ b/src/mcd-account-compat.h
@@ -0,0 +1,39 @@
+/*
+ * mcd-account.h - the Telepathy Account D-Bus interface (service side)
+ *
+ * Copyright (C) 2008 Collabora Ltd. <http://www.collabora.co.uk/>
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __MCD_ACCOUNT_COMPAT_H__
+#define __MCD_ACCOUNT_COMPAT_H__
+
+#include <telepathy-glib/dbus.h>
+#include <telepathy-glib/enums.h>
+/* auto-generated stubs */
+#include "_gen/svc-Account_Interface_Compat.h"
+
+#include "mcd-dbusprop.h"
+
+G_BEGIN_DECLS
+
+const McdDBusProp *_mcd_account_compat_get_properties (void);
+void _mcd_account_compat_iface_init (McSvcAccountInterfaceCompatClass *iface,
+ gpointer iface_data);
+
+G_END_DECLS
+#endif
diff --git a/src/mcd-account-manager.c b/src/mcd-account-manager.c
index 7fd2c860..0087a6ee 100644
--- a/src/mcd-account-manager.c
+++ b/src/mcd-account-manager.c
@@ -30,6 +30,7 @@
#include <dbus/dbus.h>
#include <telepathy-glib/svc-generic.h>
+#include <telepathy-glib/util.h>
#include <telepathy-glib/errors.h>
#include "mcd-account-manager.h"
#include "mcd-account.h"
@@ -185,10 +186,12 @@ complete_account_creation (McdAccountManager *account_manager,
}
static gchar *
-create_unique_name (McdAccountManagerPrivate *priv, GHashTable *params)
+create_unique_name (McdAccountManagerPrivate *priv, const gchar *manager,
+ const gchar *protocol, GHashTable *params)
{
gchar *path, *seq, *unique_name = NULL;
const gchar *base = NULL;
+ gchar *esc_manager, *esc_protocol, *esc_base;
GValue *value;
gint i, len;
@@ -199,9 +202,16 @@ create_unique_name (McdAccountManagerPrivate *priv, GHashTable *params)
if (!base)
base = "account";
- len = strlen (base);
+ esc_manager = tp_escape_as_identifier (manager);
+ esc_protocol = tp_escape_as_identifier (protocol);
+ esc_base = tp_escape_as_identifier (base);
+ /* add two chars for the "/" */
+ len = strlen (esc_manager) + strlen (esc_protocol) + strlen (esc_base) + 2;
path = g_malloc (len + 5);
- strcpy (path, base);
+ sprintf (path, "%s/%s/%s", esc_manager, esc_protocol, esc_base);
+ g_free (esc_manager);
+ g_free (esc_protocol);
+ g_free (esc_base);
seq = path + len;
for (i = 0; i < 1024; i++)
{
@@ -237,7 +247,7 @@ mcd_account_manager_create_account (McdAccountManager *account_manager,
return FALSE;
}
- unique_name = create_unique_name (priv, params);
+ unique_name = create_unique_name (priv, manager, protocol, params);
if (G_UNLIKELY (unique_name == NULL))
{
g_warning ("Couldn't create a unique name");
@@ -620,3 +630,26 @@ mcd_account_manager_lookup_account (McdAccountManager *account_manager,
return g_hash_table_lookup (priv->accounts, name);
}
+static gboolean
+find_by_path (gpointer key, gpointer value, gpointer user_data)
+{
+ McdAccount *account = value;
+ const gchar *object_path = user_data;
+
+ if (strcmp (object_path,
+ mcd_account_get_object_path (account)) == 0)
+ return TRUE;
+ return FALSE;
+}
+
+/* NOTE: this might become unused when the presence-frame gets removed */
+McdAccount *
+mcd_account_manager_lookup_account_by_path (McdAccountManager *account_manager,
+ const gchar *object_path)
+{
+ McdAccountManagerPrivate *priv = account_manager->priv;
+
+ return g_hash_table_find (priv->accounts, find_by_path,
+ (gpointer)object_path);
+}
+
diff --git a/src/mcd-account-manager.h b/src/mcd-account-manager.h
index 097dffe9..be1feda3 100644
--- a/src/mcd-account-manager.h
+++ b/src/mcd-account-manager.h
@@ -69,5 +69,7 @@ GHashTable *mcd_account_manager_get_valid_accounts (McdAccountManager *account_m
McdAccount *mcd_account_manager_lookup_account (McdAccountManager *account_manager,
const gchar *name);
+McdAccount *mcd_account_manager_lookup_account_by_path (McdAccountManager *account_manager,
+ const gchar *object_path);
#endif
diff --git a/src/mcd-account.c b/src/mcd-account.c
index 960a3980..028a51a0 100644
--- a/src/mcd-account.c
+++ b/src/mcd-account.c
@@ -29,10 +29,11 @@
#include <config.h>
#include <telepathy-glib/svc-generic.h>
-#include <telepathy-glib/gtypes.h>
#include <telepathy-glib/util.h>
+#include <telepathy-glib/gtypes.h>
#include "mcd-account.h"
#include "mcd-account-priv.h"
+#include "mcd-account-compat.h"
#include "mcd-account-manager.h"
#include "mcd-signals-marshal.h"
#include "mcd-manager.h"
@@ -57,6 +58,8 @@ G_DEFINE_TYPE_WITH_CODE (McdAccount, mcd_account, G_TYPE_OBJECT,
account_iface_init);
G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_DBUS_PROPERTIES,
properties_iface_init);
+ G_IMPLEMENT_INTERFACE (MC_TYPE_SVC_ACCOUNT_INTERFACE_COMPAT,
+ _mcd_account_compat_iface_init);
)
struct _McdAccountPrivate
@@ -239,6 +242,7 @@ mcd_account_request_presence_int (McdAccount *account,
return TRUE;
}
+#ifdef DELAY_PROPERTY_CHANGED
static gboolean
emit_property_changed (gpointer userdata)
{
@@ -257,6 +261,7 @@ emit_property_changed (gpointer userdata)
priv->properties_source = 0;
return FALSE;
}
+#endif
/*
* This function is responsible of emitting the AccountPropertyChanged signal.
@@ -268,6 +273,7 @@ static void
mcd_account_changed_property (McdAccount *account, const gchar *key,
const GValue *value)
{
+#ifdef DELAY_PROPERTY_CHANGED
McdAccountPrivate *priv = account->priv;
GValue *val;
@@ -305,6 +311,17 @@ mcd_account_changed_property (McdAccount *account, const gchar *key,
g_value_init (val, G_VALUE_TYPE (value));
g_value_copy (value, val);
g_hash_table_insert (priv->changed_properties, (gpointer)key, val);
+#else
+ GHashTable *properties;
+
+ g_debug ("%s called: %s", G_STRFUNC, key);
+ properties = g_hash_table_new (g_str_hash, g_str_equal);
+ g_hash_table_insert (properties, (gpointer)key, (gpointer)value);
+ mc_svc_account_emit_account_property_changed (account,
+ properties);
+
+ g_hash_table_destroy (properties);
+#endif
}
static gboolean
@@ -1043,6 +1060,8 @@ account_update_parameters (McSvcAccount *self, GHashTable *set,
{
McdAccount *account = MCD_ACCOUNT (self);
McdAccountPrivate *priv = account->priv;
+ GHashTable *parameters;
+ GValue value = { 0 };
GError *error = NULL;
g_debug ("%s called for %s", G_STRFUNC, priv->unique_name);
@@ -1059,6 +1078,13 @@ account_update_parameters (McSvcAccount *self, GHashTable *set,
mcd_account_unset_parameters (account, unset);
+ /* emit the PropertiesChanged signal */
+ parameters = mcd_account_get_parameters (account);
+ g_value_init (&value, TP_HASH_TYPE_STRING_VARIANT_MAP);
+ g_value_take_boxed (&value, parameters);
+ mcd_account_changed_property (account, "Parameters", &value);
+ g_value_unset (&value);
+
mcd_account_check_validity (account);
mcd_account_manager_write_conf (priv->keyfile);
mc_svc_account_return_from_update_parameters (context);
@@ -1095,7 +1121,6 @@ mcd_account_setup (McdAccount *account)
{
McdAccountPrivate *priv = account->priv;
gboolean valid;
- gchar *ch, *name;
if (!priv->keyfile || !priv->unique_name) return FALSE;
@@ -1109,17 +1134,8 @@ mcd_account_setup (McdAccount *account)
MC_ACCOUNTS_KEY_PROTOCOL, NULL);
if (!priv->protocol_name) return FALSE;
- name = tp_escape_as_identifier (priv->unique_name);
priv->object_path = g_strconcat (MC_ACCOUNT_DBUS_OBJECT_BASE,
- priv->manager_name, "/",
- priv->protocol_name, "/",
- name, NULL);
- g_free (name);
- /* seems that the dash is an invalid character... */
- for (ch = priv->object_path + sizeof(MC_ACCOUNT_DBUS_OBJECT_BASE);
- *ch != 0;
- ch++)
- if (*ch == '-') *ch = '_';
+ priv->unique_name, NULL);
priv->enabled =
g_key_file_get_boolean (priv->keyfile, priv->unique_name,
@@ -1378,6 +1394,9 @@ mcd_account_init (McdAccount *account)
/* add the interface properties */
dbusprop_add_interface (TP_SVC_DBUS_PROPERTIES (account),
MC_IFACE_ACCOUNT, account_properties);
+ dbusprop_add_interface (TP_SVC_DBUS_PROPERTIES (account),
+ MC_IFACE_ACCOUNT_INTERFACE_COMPAT,
+ _mcd_account_compat_get_properties());
priv->conn_status = TP_CONNECTION_STATUS_DISCONNECTED;
}
@@ -1676,6 +1695,15 @@ mcd_account_set_normalized_name (McdAccount *account, const gchar *name)
mcd_account_manager_write_conf (priv->keyfile);
}
+gchar *
+mcd_account_get_normalized_name (McdAccount *account)
+{
+ McdAccountPrivate *priv = account->priv;
+
+ return g_key_file_get_string (priv->keyfile, priv->unique_name,
+ MC_ACCOUNTS_KEY_NORMALIZED_NAME, NULL);
+}
+
void
mcd_account_set_avatar_token (McdAccount *account, const gchar *token)
{
@@ -1755,16 +1783,13 @@ mcd_account_get_avatar (McdAccount *account, GArray **avatar,
gchar **mime_type)
{
McdAccountPrivate *priv = MCD_ACCOUNT_PRIV (account);
- gchar *data_dir, *filename;
+ gchar *filename;
*mime_type = g_key_file_get_string (priv->keyfile, priv->unique_name,
MC_ACCOUNTS_KEY_AVATAR_MIME, NULL);
if (avatar) *avatar = NULL;
- data_dir = get_account_data_path (priv);
- g_debug("data dir: %s", data_dir);
- filename = g_build_filename (data_dir, MC_AVATAR_FILENAME, NULL);
- g_free (data_dir);
+ filename = mcd_account_get_avatar_filename (account);
if (filename && g_file_test (filename, G_FILE_TEST_EXISTS))
{
@@ -1915,10 +1940,14 @@ mcd_account_check_validity (McdAccount *account)
valid = mcd_account_check_parameters (account);
if (valid != priv->valid)
{
+ GValue value = { 0 };
g_debug ("Account validity changed (old: %d, new: %d)",
priv->valid, valid);
priv->valid = valid;
g_signal_emit (account, signals[VALIDITY_CHANGED], 0, valid);
+ g_value_init (&value, G_TYPE_BOOLEAN);
+ g_value_set_boolean (&value, valid);
+ mcd_account_changed_property (account, "Valid", &value);
}
return valid;
}
@@ -2030,3 +2059,23 @@ mcd_account_request_channel_nmc4 (McdAccount *account,
error);
}
+GKeyFile *
+mcd_account_get_keyfile (McdAccount *account)
+{
+ McdAccountPrivate *priv = MCD_ACCOUNT_PRIV (account);
+ return priv->keyfile;
+}
+
+/* this is public because of mcd-account-compat */
+gchar *
+mcd_account_get_avatar_filename (McdAccount *account)
+{
+ McdAccountPrivate *priv = account->priv;
+ gchar *data_dir, *filename;
+
+ data_dir = get_account_data_path (priv);
+ g_debug("data dir: %s", data_dir);
+ filename = g_build_filename (data_dir, MC_AVATAR_FILENAME, NULL);
+ g_free (data_dir);
+ return filename;
+}
diff --git a/src/mcd-account.h b/src/mcd-account.h
index 90c06532..5fcde941 100644
--- a/src/mcd-account.h
+++ b/src/mcd-account.h
@@ -64,6 +64,8 @@ gboolean mcd_account_delete (McdAccount *account, GError **error);
const gchar *mcd_account_get_unique_name (McdAccount *account);
const gchar *mcd_account_get_object_path (McdAccount *account);
+GKeyFile *mcd_account_get_keyfile (McdAccount *account);
+
gboolean mcd_account_is_valid (McdAccount *account);
gboolean mcd_account_check_validity (McdAccount *account);
@@ -91,6 +93,7 @@ void mcd_account_get_requested_presence (McdAccount *account,
const gchar **message);
void mcd_account_set_normalized_name (McdAccount *account, const gchar *name);
+gchar *mcd_account_get_normalized_name (McdAccount *account);
gboolean mcd_account_set_avatar (McdAccount *account, const GArray *avatar,
const gchar *mime_type, const gchar *token,
@@ -115,4 +118,7 @@ McdConnection *mcd_account_get_connection (McdAccount *account);
gboolean mcd_account_request_channel_nmc4 (McdAccount *account,
const struct mcd_channel_request *req,
GError **error);
+
+gchar *mcd_account_get_avatar_filename (McdAccount *account);
+
#endif
diff --git a/src/mcd-master.c b/src/mcd-master.c
index 848c471c..761cf648 100644
--- a/src/mcd-master.c
+++ b/src/mcd-master.c
@@ -867,15 +867,14 @@ mcd_master_get_account_for_connection (McdMaster *master,
GError **error)
{
McdConnection *connection;
+ McdAccount *account;
connection = mcd_master_get_connection (master, object_path, error);
- if (connection)
+ if (connection &&
+ (account = mcd_connection_get_account (connection)))
{
- McAccount *account;
-
- g_object_get (G_OBJECT (connection), "account", &account, NULL);
- *ret_unique_name = g_strdup (mc_account_get_unique_name (account));
- g_object_unref (G_OBJECT (account));
+
+ *ret_unique_name = g_strdup (mcd_account_get_unique_name (account));
return TRUE;
}
return FALSE;
diff --git a/src/mcd-presence-frame.c b/src/mcd-presence-frame.c
index 866428e8..d49abf55 100644
--- a/src/mcd-presence-frame.c
+++ b/src/mcd-presence-frame.c
@@ -603,9 +603,13 @@ add_account (gpointer key, gpointer value, gpointer userdata)
static void
on_account_validity_changed (McdAccountManager *account_manager,
- McdAccount *account, gboolean valid,
+ const gchar *object_path, gboolean valid,
McdPresenceFrame *presence_frame)
{
+ McdAccount *account;
+
+ account = mcd_account_manager_lookup_account_by_path (account_manager,
+ object_path);
if (valid)
mcd_presence_frame_add_account (presence_frame, account);
else
@@ -630,3 +634,10 @@ mcd_presence_frame_set_account_manager (McdPresenceFrame *presence_frame,
presence_frame);
}
+GList *
+mcd_presence_frame_get_accounts (McdPresenceFrame *presence_frame)
+{
+ McdPresenceFramePrivate *priv = MCD_PRESENCE_FRAME_PRIV (presence_frame);
+ return priv->accounts;
+}
+
diff --git a/src/mcd-presence-frame.h b/src/mcd-presence-frame.h
index bcbe627c..707375c5 100644
--- a/src/mcd-presence-frame.h
+++ b/src/mcd-presence-frame.h
@@ -102,6 +102,7 @@ gboolean mcd_presence_frame_is_stable (McdPresenceFrame *presence_frame);
void mcd_presence_frame_set_account_manager (McdPresenceFrame *presence_frame,
McdAccountManager *account_manager);
+GList *mcd_presence_frame_get_accounts (McdPresenceFrame *presence_frame);
G_END_DECLS
#endif /* MCD_PRESENCE_FRAME_H */
diff --git a/src/mcd-service.c b/src/mcd-service.c
index d33a5019..a784b628 100644
--- a/src/mcd-service.c
+++ b/src/mcd-service.c
@@ -308,7 +308,6 @@ mcd_service_get_current_status(GObject *obj,
McPresence *requested_presence,
GPtrArray **accounts, GError **error)
{
-#if 0
McdServicePrivate *priv = MCD_OBJECT_PRIV (obj);
GList *account_list, *account_node;
GType type;
@@ -320,23 +319,22 @@ mcd_service_get_current_status(GObject *obj,
type = dbus_g_type_get_struct ("GValueArray", G_TYPE_STRING, G_TYPE_UINT,
G_TYPE_UINT, G_TYPE_UINT, G_TYPE_INVALID);
- account_list = mc_accounts_list_by_enabled (TRUE);
+ account_list = mcd_presence_frame_get_accounts (priv->presence_frame);
for (account_node = account_list; account_node != NULL;
account_node = g_list_next (account_node))
{
- McAccount *account = account_node->data;
+ McdAccount *account = account_node->data;
GValue account_data = { 0, };
- const gchar *name;
+ const gchar *name, *p_status, *p_message;
TpConnectionStatus status;
TpConnectionStatusReason reason;
- McPresence presence;
+ TpConnectionPresenceType presence;
- name = mc_account_get_unique_name (account);
+ name = mcd_account_get_unique_name (account);
+ mcd_account_get_current_presence (account, &presence,
+ &p_status, &p_message);
status = mcd_presence_frame_get_account_status (priv->presence_frame,
account);
- presence =
- mcd_presence_frame_get_account_presence (priv->presence_frame,
- account);
reason =
mcd_presence_frame_get_account_status_reason (priv->presence_frame,
account);
@@ -353,12 +351,7 @@ mcd_service_get_current_status(GObject *obj,
g_ptr_array_add (*accounts, g_value_get_boxed (&account_data));
}
- mc_accounts_list_free (account_list);
return TRUE;
-#else
- g_warning ("%s not implemented", G_STRFUNC);
- return FALSE;
-#endif
}
static void
diff --git a/tools/Makefile.am b/tools/Makefile.am
index 1e9fe2ed..c6051d58 100644
--- a/tools/Makefile.am
+++ b/tools/Makefile.am
@@ -3,6 +3,7 @@ EXTRA_DIST = \
c-interfaces-generator.xsl \
doc-generator.xsl \
glib-client-gen.py \
+ glib-blocking-client-gen.py \
glib-client-marshaller-gen.py \
glib-interfaces-generator.xsl \
glib-interfaces-body-generator.xsl \
diff --git a/tools/glib-blocking-client-gen.py b/tools/glib-blocking-client-gen.py
new file mode 100644
index 00000000..c20dcd4a
--- /dev/null
+++ b/tools/glib-blocking-client-gen.py
@@ -0,0 +1,1014 @@
+#!/usr/bin/python
+
+# glib-client-gen.py: "I Can't Believe It's Not dbus-binding-tool"
+#
+# Generate GLib client wrappers from the Telepathy specification.
+# The master copy of this program is in the telepathy-glib repository -
+# please make any changes there.
+#
+# Copyright (C) 2006-2008 Collabora Ltd. <http://www.collabora.co.uk/>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+import sys
+import os.path
+import xml.dom.minidom
+from getopt import gnu_getopt
+
+from libglibcodegen import Signature, type_to_gtype, cmp_by_name, \
+ camelcase_to_lower, get_docstring
+
+
+NS_TP = "http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0"
+
+class Generator(object):
+
+ def __init__(self, dom, prefix, basename, opts):
+ self.dom = dom
+ self.__header = []
+ self.__body = []
+
+ self.prefix_lc = prefix.lower()
+ self.prefix_uc = prefix.upper()
+ self.prefix_mc = prefix.replace('_', '')
+ self.basename = basename
+ self.group = opts.get('--group', None)
+ self.iface_quark_prefix = opts.get('--iface-quark-prefix', None)
+ self.proxy_cls = opts.get('--subclass', 'TpProxy') + ' *'
+ self.proxy_arg = opts.get('--subclass', 'void') + ' *'
+ self.proxy_assert = opts.get('--subclass-assert', 'TP_IS_PROXY')
+ self.proxy_doc = ('A #%s or subclass'
+ % opts.get('--subclass', 'TpProxy'))
+ if self.proxy_arg == 'void *':
+ self.proxy_arg = 'gpointer '
+
+ def h(self, s):
+ self.__header.append(s)
+
+ def b(self, s):
+ self.__body.append(s)
+
+ def get_iface_quark(self):
+ assert self.iface_dbus is not None
+ assert self.iface_uc is not None
+ if self.iface_quark_prefix is None:
+ return 'g_quark_from_static_string (\"%s\")' % self.iface_dbus
+ else:
+ return '%s_%s' % (self.iface_quark_prefix, self.iface_uc)
+
+ def do_signal(self, iface, signal):
+ iface_lc = iface.lower()
+
+ member = signal.getAttribute('name')
+ member_lc = camelcase_to_lower(member)
+ member_uc = member_lc.upper()
+
+ arg_count = 0
+ args = []
+ out_args = []
+
+ for arg in signal.getElementsByTagName('arg'):
+ name = arg.getAttribute('name')
+ type = arg.getAttribute('type')
+ tp_type = arg.getAttribute('tp:type')
+
+ if not name:
+ name = 'arg%u' % arg_count
+ arg_count += 1
+ else:
+ name = 'arg_%s' % name
+
+ info = type_to_gtype(type)
+ args.append((name, info, tp_type, arg))
+
+ callback_name = ('%s_%s_signal_callback_%s'
+ % (self.prefix_lc, iface_lc, member_lc))
+ collect_name = ('_%s_%s_collect_args_of_%s'
+ % (self.prefix_lc, iface_lc, member_lc))
+ invoke_name = ('_%s_%s_invoke_callback_for_%s'
+ % (self.prefix_lc, iface_lc, member_lc))
+
+ # Example:
+ #
+ # typedef void (*tp_cli_connection_signal_callback_new_channel)
+ # (TpConnection *proxy, const gchar *arg_object_path,
+ # const gchar *arg_channel_type, guint arg_handle_type,
+ # guint arg_handle, gboolean arg_suppress_handler,
+ # gpointer user_data, GObject *weak_object);
+
+ self.b('/**')
+ self.b(' * %s:' % callback_name)
+ self.b(' * @proxy: The proxy on which %s_%s_connect_to_%s ()'
+ % (self.prefix_lc, iface_lc, member_lc))
+ self.b(' * was called')
+
+ for arg in args:
+ name, info, tp_type, elt = arg
+ ctype, gtype, marshaller, pointer = info
+
+ self.b(' * @%s: <![CDATA[%s]]>' % (name,
+ get_docstring(elt) or '(Undocumented)'))
+
+ self.b(' * @user_data: User-supplied data')
+ self.b(' * @weak_object: User-supplied weakly referenced object')
+ self.b(' *')
+ self.b(' * Represents the signature of a callback for the signal %s.'
+ % member)
+ self.b(' */')
+ self.h('typedef void (*%s) (%sproxy,'
+ % (callback_name, self.proxy_cls))
+
+ for arg in args:
+ name, info, tp_type, elt = arg
+ ctype, gtype, marshaller, pointer = info
+
+ const = pointer and 'const ' or ''
+
+ self.h(' %s%s%s,' % (const, ctype, name))
+
+ self.h(' gpointer user_data, GObject *weak_object);')
+
+ if args:
+ self.b('static void')
+ self.b('%s (DBusGProxy *proxy,' % collect_name)
+
+ for arg in args:
+ name, info, tp_type, elt = arg
+ ctype, gtype, marshaller, pointer = info
+
+ const = pointer and 'const ' or ''
+
+ self.b(' %s%s%s,' % (const, ctype, name))
+
+ self.b(' TpProxySignalConnection *sc)')
+ self.b('{')
+ self.b(' GValueArray *args = g_value_array_new (%d);' % len(args))
+ self.b(' GValue blank = { 0 };')
+ self.b(' guint i;')
+ self.b('')
+ self.b(' g_value_init (&blank, G_TYPE_INT);')
+ self.b('')
+ self.b(' for (i = 0; i < %d; i++)' % len(args))
+ self.b(' g_value_array_append (args, &blank);')
+ self.b('')
+
+ for i, arg in enumerate(args):
+ name, info, tp_type, elt = arg
+ ctype, gtype, marshaller, pointer = info
+
+ self.b(' g_value_unset (args->values + %d);' % i)
+ self.b(' g_value_init (args->values + %d, %s);' % (i, gtype))
+
+ if gtype == 'G_TYPE_STRING':
+ self.b(' g_value_set_string (args->values + %d, %s);'
+ % (i, name))
+ elif marshaller == 'BOXED':
+ self.b(' g_value_set_boxed (args->values + %d, %s);'
+ % (i, name))
+ elif gtype == 'G_TYPE_UCHAR':
+ self.b(' g_value_set_uchar (args->values + %d, %s);'
+ % (i, name))
+ elif gtype == 'G_TYPE_BOOLEAN':
+ self.b(' g_value_set_boolean (args->values + %d, %s);'
+ % (i, name))
+ elif gtype == 'G_TYPE_INT':
+ self.b(' g_value_set_int (args->values + %d, %s);'
+ % (i, name))
+ elif gtype == 'G_TYPE_UINT':
+ self.b(' g_value_set_uint (args->values + %d, %s);'
+ % (i, name))
+ elif gtype == 'G_TYPE_INT64':
+ self.b(' g_value_set_int (args->values + %d, %s);'
+ % (i, name))
+ elif gtype == 'G_TYPE_UINT64':
+ self.b(' g_value_set_uint (args->values + %d, %s);'
+ % (i, name))
+ elif gtype == 'G_TYPE_DOUBLE':
+ self.b(' g_value_set_double (args->values + %d, %s);'
+ % (i, name))
+ else:
+ assert False, ("Don't know how to put %s in a GValue"
+ % gtype)
+ self.b('')
+
+ self.b(' tp_proxy_signal_connection_v0_take_results (sc, args);')
+ self.b('}')
+
+ self.b('static void')
+ self.b('%s (TpProxy *tpproxy,' % invoke_name)
+ self.b(' GError *error,')
+ self.b(' GValueArray *args,')
+ self.b(' GCallback generic_callback,')
+ self.b(' gpointer user_data,')
+ self.b(' GObject *weak_object)')
+ self.b('{')
+ self.b(' %s callback =' % callback_name)
+ self.b(' (%s) generic_callback;' % callback_name)
+ self.b('')
+ self.b(' if (callback != NULL)')
+ self.b(' callback (g_object_ref (tpproxy),')
+
+ # FIXME: factor out into a function
+ for i, arg in enumerate(args):
+ name, info, tp_type, elt = arg
+ ctype, gtype, marshaller, pointer = info
+
+ if marshaller == 'BOXED':
+ self.b(' g_value_get_boxed (args->values + %d),' % i)
+ elif gtype == 'G_TYPE_STRING':
+ self.b(' g_value_get_string (args->values + %d),' % i)
+ elif gtype == 'G_TYPE_UCHAR':
+ self.b(' g_value_get_uchar (args->values + %d),' % i)
+ elif gtype == 'G_TYPE_BOOLEAN':
+ self.b(' g_value_get_boolean (args->values + %d),' % i)
+ elif gtype == 'G_TYPE_UINT':
+ self.b(' g_value_get_uint (args->values + %d),' % i)
+ elif gtype == 'G_TYPE_INT':
+ self.b(' g_value_get_int (args->values + %d),' % i)
+ elif gtype == 'G_TYPE_UINT64':
+ self.b(' g_value_get_uint64 (args->values + %d),' % i)
+ elif gtype == 'G_TYPE_INT64':
+ self.b(' g_value_get_int64 (args->values + %d),' % i)
+ elif gtype == 'G_TYPE_DOUBLE':
+ self.b(' g_value_get_double (args->values + %d),' % i)
+ else:
+ assert False, "Don't know how to get %s from a GValue" % gtype
+
+ self.b(' user_data,')
+ self.b(' weak_object);')
+ self.b('')
+
+ if len(args) > 0:
+ self.b(' g_value_array_free (args);')
+ else:
+ self.b(' if (args != NULL)')
+ self.b(' g_value_array_free (args);')
+ self.b('')
+
+ self.b(' g_object_unref (tpproxy);')
+ self.b('}')
+
+ # Example:
+ #
+ # TpProxySignalConnection *
+ # tp_cli_connection_connect_to_new_channel
+ # (TpConnection *proxy,
+ # tp_cli_connection_signal_callback_new_channel callback,
+ # gpointer user_data,
+ # GDestroyNotify destroy);
+ #
+ # destroy is invoked when the signal becomes disconnected. This
+ # is either because the signal has been disconnected explicitly
+ # by the user, because the TpProxy has become invalid and
+ # emitted the 'invalidated' signal, or because the weakly referenced
+ # object has gone away.
+
+ self.b('/**')
+ self.b(' * %s_%s_connect_to_%s:'
+ % (self.prefix_lc, iface_lc, member_lc))
+ self.b(' * @proxy: %s' % self.proxy_doc)
+ self.b(' * @callback: Callback to be called when the signal is')
+ self.b(' * received')
+ self.b(' * @user_data: User-supplied data for the callback')
+ self.b(' * @destroy: Destructor for the user-supplied data, which')
+ self.b(' * will be called when this signal is disconnected, or')
+ self.b(' * before this function returns %NULL')
+ self.b(' * @weak_object: A #GObject which will be weakly referenced; ')
+ self.b(' * if it is destroyed, this callback will automatically be')
+ self.b(' * disconnected')
+ self.b(' * @error: If not %NULL, used to raise an error if %NULL is')
+ self.b(' * returned')
+ self.b(' *')
+ self.b(' * Connect a handler to the signal %s.' % member)
+ self.b(' *')
+ self.b(' * <![CDATA[%s]]>'
+ % (get_docstring(signal) or '(Undocumented)'))
+ self.b(' *')
+ self.b(' * Returns: a #TpProxySignalConnection containing all of the')
+ self.b(' * above, which can be used to disconnect the signal; or')
+ self.b(' * %NULL if the proxy does not have the desired interface')
+ self.b(' * or has become invalid.')
+ self.b(' */')
+ self.h('TpProxySignalConnection *%s_%s_connect_to_%s (%sproxy,'
+ % (self.prefix_lc, iface_lc, member_lc, self.proxy_arg))
+ self.h(' %s callback,' % callback_name)
+ self.h(' gpointer user_data,')
+ self.h(' GDestroyNotify destroy,')
+ self.h(' GObject *weak_object,')
+ self.h(' GError **error);')
+
+ self.b('TpProxySignalConnection *')
+ self.b('%s_%s_connect_to_%s (%sproxy,'
+ % (self.prefix_lc, iface_lc, member_lc, self.proxy_arg))
+ self.b(' %s callback,' % callback_name)
+ self.b(' gpointer user_data,')
+ self.b(' GDestroyNotify destroy,')
+ self.b(' GObject *weak_object,')
+ self.b(' GError **error)')
+ self.b('{')
+ self.b(' GType expected_types[%d] = {' % (len(args) + 1))
+
+ for arg in args:
+ name, info, tp_type, elt = arg
+ ctype, gtype, marshaller, pointer = info
+
+ self.b(' %s,' % gtype)
+
+ self.b(' G_TYPE_INVALID };')
+ self.b('')
+ self.b(' g_return_val_if_fail (%s (proxy), NULL);'
+ % self.proxy_assert)
+ self.b(' g_return_val_if_fail (callback != NULL, NULL);')
+ self.b('')
+ self.b(' return tp_proxy_signal_connection_v0_new ((TpProxy *) proxy,')
+ self.b(' %s, \"%s\",' % (self.get_iface_quark(), member))
+ self.b(' expected_types,')
+
+ if args:
+ self.b(' G_CALLBACK (%s),' % collect_name)
+ else:
+ self.b(' NULL, /* no args => no collector function */')
+
+ self.b(' %s,' % invoke_name)
+ self.b(' G_CALLBACK (callback), user_data, destroy,')
+ self.b(' weak_object, error);')
+ self.b('}')
+ self.b('')
+
+ self.h('')
+
+ def do_method(self, iface, method):
+ iface_lc = iface.lower()
+
+ member = method.getAttribute('name')
+ member_lc = camelcase_to_lower(member)
+ member_uc = member_lc.upper()
+
+ in_count = 0
+ ret_count = 0
+ in_args = []
+ out_args = []
+
+ for arg in method.getElementsByTagName('arg'):
+ name = arg.getAttribute('name')
+ direction = arg.getAttribute('direction')
+ type = arg.getAttribute('type')
+ tp_type = arg.getAttribute('tp:type')
+
+ if direction != 'out':
+ if not name:
+ name = 'in%u' % in_count
+ in_count += 1
+ else:
+ name = 'in_%s' % name
+ else:
+ if not name:
+ name = 'out%u' % ret_count
+ ret_count += 1
+ else:
+ name = 'out_%s' % name
+
+ info = type_to_gtype(type)
+ if direction != 'out':
+ in_args.append((name, info, tp_type, arg))
+ else:
+ out_args.append((name, info, tp_type, arg))
+
+ # Async reply callback type
+
+ # Example:
+ # void (*tp_cli_properties_interface_callback_for_get_properties)
+ # (TpProxy *proxy,
+ # const GPtrArray *out0,
+ # const GError *error,
+ # gpointer user_data,
+ # GObject *weak_object);
+
+ self.b('/**')
+ self.b(' * %s_%s_callback_for_%s:'
+ % (self.prefix_lc, iface_lc, member_lc))
+ self.b(' * @proxy: the proxy on which the call was made')
+
+ for arg in out_args:
+ name, info, tp_type, elt = arg
+ ctype, gtype, marshaller, pointer = info
+
+ self.b(' * @%s: Used to return an \'out\' argument if @error is '
+ '%%NULL: <![CDATA[%s]]>'
+ % (name, get_docstring(elt) or '(Undocumented)'))
+
+ self.b(' * @error: %NULL on success, or an error on failure')
+ self.b(' * @user_data: user-supplied data')
+ self.b(' * @weak_object: user-supplied object')
+ self.b(' *')
+ self.b(' * Signature of the callback called when a %s method call'
+ % member)
+ self.b(' * succeeds or fails.')
+ self.b(' */')
+
+ callback_name = '%s_%s_callback_for_%s' % (self.prefix_lc, iface_lc,
+ member_lc)
+
+ self.h('typedef void (*%s) (%sproxy,'
+ % (callback_name, self.proxy_cls))
+
+ for arg in out_args:
+ name, info, tp_type, elt = arg
+ ctype, gtype, marshaller, pointer = info
+ const = pointer and 'const ' or ''
+
+ self.h(' %s%s%s,' % (const, ctype, name))
+
+ self.h(' const GError *error, gpointer user_data,')
+ self.h(' GObject *weak_object);')
+ self.h('')
+
+ # Async callback implementation
+
+ invoke_callback = '_%s_%s_invoke_callback_%s' % (self.prefix_lc,
+ iface_lc,
+ member_lc)
+
+ collect_callback = '_%s_%s_collect_callback_%s' % (self.prefix_lc,
+ iface_lc,
+ member_lc)
+
+ # The callback called by dbus-glib; this ends the call and collects
+ # the results into a GValueArray.
+ self.b('static void')
+ self.b('%s (DBusGProxy *proxy,' % collect_callback)
+ self.b(' DBusGProxyCall *call,')
+ self.b(' gpointer user_data)')
+ self.b('{')
+ self.b(' GError *error = NULL;')
+
+ if len(out_args) > 0:
+ self.b(' GValueArray *args;')
+ self.b(' GValue blank = { 0 };')
+ self.b(' guint i;')
+
+ for arg in out_args:
+ name, info, tp_type, elt = arg
+ ctype, gtype, marshaller, pointer = info
+
+ self.b(' %s%s;' % (ctype, name))
+
+ self.b('')
+ self.b(' dbus_g_proxy_end_call (proxy, call, &error,')
+
+ for arg in out_args:
+ name, info, tp_type, elt = arg
+ ctype, gtype, marshaller, pointer = info
+
+ self.b(' %s, &%s,' % (gtype, name))
+
+ self.b(' G_TYPE_INVALID);')
+
+ if len(out_args) == 0:
+ self.b(' tp_proxy_pending_call_v0_take_results (user_data, error,'
+ 'NULL);')
+ else:
+ self.b('')
+ self.b(' if (error != NULL)')
+ self.b(' {')
+ self.b(' tp_proxy_pending_call_v0_take_results (user_data, error,')
+ self.b(' NULL);')
+ self.b(' return;')
+ self.b(' }')
+ self.b('')
+ self.b(' args = g_value_array_new (%d);' % len(out_args))
+ self.b(' g_value_init (&blank, G_TYPE_INT);')
+ self.b('')
+ self.b(' for (i = 0; i < %d; i++)' % len(out_args))
+ self.b(' g_value_array_append (args, &blank);')
+
+ for i, arg in enumerate(out_args):
+ name, info, tp_type, elt = arg
+ ctype, gtype, marshaller, pointer = info
+
+ self.b('')
+ self.b(' g_value_unset (args->values + %d);' % i)
+ self.b(' g_value_init (args->values + %d, %s);' % (i, gtype))
+
+ if gtype == 'G_TYPE_STRING':
+ self.b(' g_value_take_string (args->values + %d, %s);'
+ % (i, name))
+ elif marshaller == 'BOXED':
+ self.b(' g_value_take_boxed (args->values + %d, %s);'
+ % (i, name))
+ elif gtype == 'G_TYPE_UCHAR':
+ self.b(' g_value_set_uchar (args->values + %d, %s);'
+ % (i, name))
+ elif gtype == 'G_TYPE_BOOLEAN':
+ self.b(' g_value_set_boolean (args->values + %d, %s);'
+ % (i, name))
+ elif gtype == 'G_TYPE_INT':
+ self.b(' g_value_set_int (args->values + %d, %s);'
+ % (i, name))
+ elif gtype == 'G_TYPE_UINT':
+ self.b(' g_value_set_uint (args->values + %d, %s);'
+ % (i, name))
+ elif gtype == 'G_TYPE_INT64':
+ self.b(' g_value_set_int (args->values + %d, %s);'
+ % (i, name))
+ elif gtype == 'G_TYPE_UINT64':
+ self.b(' g_value_set_uint (args->values + %d, %s);'
+ % (i, name))
+ elif gtype == 'G_TYPE_DOUBLE':
+ self.b(' g_value_set_double (args->values + %d, %s);'
+ % (i, name))
+ else:
+ assert False, ("Don't know how to put %s in a GValue"
+ % gtype)
+
+ self.b(' tp_proxy_pending_call_v0_take_results (user_data, '
+ 'NULL, args);')
+
+ self.b('}')
+
+ self.b('static void')
+ self.b('%s (TpProxy *self,' % invoke_callback)
+ self.b(' GError *error,')
+ self.b(' GValueArray *args,')
+ self.b(' GCallback generic_callback,')
+ self.b(' gpointer user_data,')
+ self.b(' GObject *weak_object)')
+ self.b('{')
+ self.b(' %s callback = (%s) generic_callback;'
+ % (callback_name, callback_name))
+ self.b('')
+ self.b(' if (error != NULL)')
+ self.b(' {')
+ self.b(' callback ((%s) self,' % self.proxy_cls)
+
+ for arg in out_args:
+ name, info, tp_type, elt = arg
+ ctype, gtype, marshaller, pointer = info
+
+ if marshaller == 'BOXED' or pointer:
+ self.b(' NULL,')
+ elif gtype == 'G_TYPE_DOUBLE':
+ self.b(' 0.0,')
+ else:
+ self.b(' 0,')
+
+ self.b(' error, user_data, weak_object);')
+ self.b(' g_error_free (error);')
+ self.b(' return;')
+ self.b(' }')
+
+ self.b(' callback ((%s) self,' % self.proxy_cls)
+
+ # FIXME: factor out into a function
+ for i, arg in enumerate(out_args):
+ name, info, tp_type, elt = arg
+ ctype, gtype, marshaller, pointer = info
+
+ if marshaller == 'BOXED':
+ self.b(' g_value_get_boxed (args->values + %d),' % i)
+ elif gtype == 'G_TYPE_STRING':
+ self.b(' g_value_get_string (args->values + %d),' % i)
+ elif gtype == 'G_TYPE_UCHAR':
+ self.b(' g_value_get_uchar (args->values + %d),' % i)
+ elif gtype == 'G_TYPE_BOOLEAN':
+ self.b(' g_value_get_boolean (args->values + %d),' % i)
+ elif gtype == 'G_TYPE_UINT':
+ self.b(' g_value_get_uint (args->values + %d),' % i)
+ elif gtype == 'G_TYPE_INT':
+ self.b(' g_value_get_int (args->values + %d),' % i)
+ elif gtype == 'G_TYPE_UINT64':
+ self.b(' g_value_get_uint64 (args->values + %d),' % i)
+ elif gtype == 'G_TYPE_INT64':
+ self.b(' g_value_get_int64 (args->values + %d),' % i)
+ elif gtype == 'G_TYPE_DOUBLE':
+ self.b(' g_value_get_double (args->values + %d),' % i)
+ else:
+ assert False, "Don't know how to get %s from a GValue" % gtype
+
+ self.b(' error, user_data, weak_object);')
+ self.b('')
+
+ if len(out_args) > 0:
+ self.b(' g_value_array_free (args);')
+ else:
+ self.b(' if (args != NULL)')
+ self.b(' g_value_array_free (args);')
+
+ self.b('}')
+ self.b('')
+
+ # Async stub
+
+ # Example:
+ # TpProxyPendingCall *
+ # tp_cli_properties_interface_call_get_properties
+ # (gpointer proxy,
+ # gint timeout_ms,
+ # const GArray *in_properties,
+ # tp_cli_properties_interface_callback_for_get_properties callback,
+ # gpointer user_data,
+ # GDestroyNotify *destructor);
+
+ self.h('TpProxyPendingCall *%s_%s_call_%s (%sproxy,'
+ % (self.prefix_lc, iface_lc, member_lc, self.proxy_arg))
+ self.h(' gint timeout_ms,')
+
+ self.b('/**')
+ self.b(' * %s_%s_call_%s:'
+ % (self.prefix_lc, iface_lc, member_lc))
+ self.b(' * @proxy: the #TpProxy')
+ self.b(' * @timeout_ms: the timeout in milliseconds, or -1 to use the')
+ self.b(' * default')
+
+ for arg in in_args:
+ name, info, tp_type, elt = arg
+ ctype, gtype, marshaller, pointer = info
+
+ self.b(' * @%s: Used to pass an \'in\' argument: <![CDATA[%s]]>'
+ % (name, get_docstring(elt) or '(Undocumented)'))
+
+ self.b(' * @callback: called when the method call succeeds or fails')
+ self.b(' * @user_data: user-supplied data passed to the callback')
+ self.b(' * @destroy: called with the user_data as argument, after the')
+ self.b(' * call has succeeded, failed or been cancelled')
+ self.b(' * @weak_object: A #GObject which will be weakly referenced; ')
+ self.b(' * if it is destroyed, this callback will automatically be')
+ self.b(' * disconnected')
+ self.b(' *')
+ self.b(' * Start a %s method call.' % member)
+ self.b(' *')
+ self.b(' * <![CDATA[%s]]>'
+ % (get_docstring(method) or '(Undocumented)'))
+ self.b(' *')
+ self.b(' * Returns: a #TpProxyPendingCall representing the call in')
+ self.b(' * progress. It is borrowed from the object, and will become')
+ self.b(' * invalid when the callback is called, the call is')
+ self.b(' * cancelled or the #TpProxy becomes invalid.')
+ self.b(' */')
+ self.b('TpProxyPendingCall *\n%s_%s_call_%s (%sproxy,'
+ % (self.prefix_lc, iface_lc, member_lc, self.proxy_arg))
+ self.b(' gint timeout_ms,')
+
+ for arg in in_args:
+ name, info, tp_type, elt = arg
+ ctype, gtype, marshaller, pointer = info
+
+ const = pointer and 'const ' or ''
+
+ self.h(' %s%s%s,' % (const, ctype, name))
+ self.b(' %s%s%s,' % (const, ctype, name))
+
+ self.h(' %s callback,' % callback_name)
+ self.h(' gpointer user_data,')
+ self.h(' GDestroyNotify destroy,')
+ self.h(' GObject *weak_object);')
+ self.h('')
+
+ self.b(' %s callback,' % callback_name)
+ self.b(' gpointer user_data,')
+ self.b(' GDestroyNotify destroy,')
+ self.b(' GObject *weak_object)')
+ self.b('{')
+ self.b(' GError *error = NULL;')
+ self.b(' GQuark interface = %s;' % self.get_iface_quark())
+ self.b(' DBusGProxy *iface;')
+ self.b('')
+ self.b(' g_return_val_if_fail (%s (proxy), NULL);'
+ % self.proxy_assert)
+ self.b('')
+ self.b(' iface = tp_proxy_borrow_interface_by_id (')
+ self.b(' (TpProxy *) proxy,')
+ self.b(' interface, &error);')
+ self.b('')
+ self.b(' if (iface == NULL)')
+ self.b(' {')
+ self.b(' if (callback != NULL)')
+ self.b(' callback (proxy,')
+
+ for arg in out_args:
+ name, info, tp_type, elt = arg
+ ctype, gtype, marshaller, pointer = info
+
+ if pointer:
+ self.b(' NULL,')
+ else:
+ self.b(' 0,')
+
+ self.b(' error, user_data, weak_object);')
+ self.b(' g_error_free (error);')
+ self.b(' return NULL;')
+ self.b(' }')
+ self.b('')
+ self.b(' if (callback == NULL)')
+ self.b(' {')
+ self.b(' dbus_g_proxy_call_no_reply (iface, "%s",' % member)
+
+ for arg in in_args:
+ name, info, tp_type, elt = arg
+ ctype, gtype, marshaller, pointer = info
+
+ const = pointer and 'const ' or ''
+
+ self.b(' %s, %s,' % (gtype, name))
+
+ self.b(' G_TYPE_INVALID);')
+ self.b(' return NULL;')
+ self.b(' }')
+ self.b(' else')
+ self.b(' {')
+ self.b(' TpProxyPendingCall *data;')
+ self.b('')
+ self.b(' data = tp_proxy_pending_call_v0_new ((TpProxy *) proxy,')
+ self.b(' interface, "%s", iface,' % member)
+ self.b(' %s,' % invoke_callback)
+ self.b(' G_CALLBACK (callback), user_data, destroy,')
+ self.b(' weak_object, FALSE);')
+ self.b(' tp_proxy_pending_call_v0_take_pending_call (data,')
+ self.b(' dbus_g_proxy_begin_call_with_timeout (iface,')
+ self.b(' "%s",' % member)
+ self.b(' %s,' % collect_callback)
+ self.b(' data,')
+ self.b(' tp_proxy_pending_call_v0_completed,')
+ self.b(' timeout_ms,')
+
+ for arg in in_args:
+ name, info, tp_type, elt = arg
+ ctype, gtype, marshaller, pointer = info
+
+ const = pointer and 'const ' or ''
+
+ self.b(' %s, %s,' % (gtype, name))
+
+ self.b(' G_TYPE_INVALID));')
+ self.b('')
+ self.b(' return data;')
+ self.b(' }')
+ self.b('}')
+ self.b('')
+
+ # Non reentrant blocking calls
+ # Example:
+ # gboolean tp_cli_properties_interface_do_get_properties
+ # (gpointer proxy,
+ # gint timeout_ms,
+ # const GArray *in_properties,
+ # GPtrArray **out0,
+ # GError **error);
+
+ self.h('gboolean %s_%s_do_%s (%sproxy,'
+ % (self.prefix_lc, iface_lc, member_lc, self.proxy_arg))
+ self.h(' gint timeout_ms,')
+
+ self.b('/**')
+ self.b(' * %s_%s_do_%s:' % (self.prefix_lc, iface_lc, member_lc))
+ self.b(' * @proxy: %s' % self.proxy_doc)
+ self.b(' * @timeout_ms: Timeout in milliseconds, or -1 for default')
+
+ for arg in in_args:
+ name, info, tp_type, elt = arg
+ ctype, gtype, marshaller, pointer = info
+
+ self.b(' * @%s: Used to pass an \'in\' argument: <![CDATA[%s]]>'
+ % (name, get_docstring(elt) or '(Undocumented)'))
+
+ for arg in out_args:
+ name, info, tp_type, elt = arg
+ ctype, gtype, marshaller, pointer = info
+
+ self.b(' * @%s: Used to return an \'out\' argument if %%TRUE is '
+ 'returned: <![CDATA[%s]]>'
+ % (name, get_docstring(elt) or '(Undocumented)'))
+
+ self.b(' * @error: If not %NULL, used to return errors if %FALSE ')
+ self.b(' * is returned')
+ self.b(' *')
+ self.b(' * Call the method %s and block' % member)
+ self.b(' * until it returns.')
+ self.b(' *')
+ self.b(' * <![CDATA[%s]]>'
+ % (get_docstring(method) or '(Undocumented)'))
+ self.b(' *')
+ self.b(' * Returns: TRUE on success, FALSE and sets @error on error')
+ self.b(' */')
+ self.b('gboolean\n%s_%s_do_%s (%sproxy,'
+ % (self.prefix_lc, iface_lc, member_lc, self.proxy_arg))
+ self.b(' gint timeout_ms,')
+
+ for arg in in_args:
+ name, info, tp_type, elt = arg
+ ctype, gtype, marshaller, pointer = info
+
+ const = pointer and 'const ' or ''
+
+ self.h(' %s%s%s,' % (const, ctype, name))
+ self.b(' %s%s%s,' % (const, ctype, name))
+
+ for arg in out_args:
+ name, info, tp_type, elt = arg
+ ctype, gtype, marshaller, pointer = info
+
+ self.h(' %s*%s,' % (ctype, name))
+ self.b(' %s*%s,' % (ctype, name))
+
+ self.h(' GError **error);')
+ self.h('')
+
+ self.b(' GError **error)')
+ self.b('{')
+ self.b(' DBusGProxy *iface;')
+ self.b(' GQuark interface = %s;' % self.get_iface_quark())
+ for arg in out_args:
+ name, info, tp_type, elt = arg
+ ctype, gtype, marshaller, pointer = info
+
+ self.b(' %si_%s;' % (ctype, name))
+ self.b('')
+ self.b(' g_return_val_if_fail (%s (proxy), FALSE);'
+ % self.proxy_assert)
+ self.b('')
+ self.b(' iface = tp_proxy_borrow_interface_by_id')
+ self.b(' ((TpProxy *) proxy, interface, error);')
+ self.b('')
+ self.b(' if (iface == NULL)')
+ self.b(' return FALSE;')
+ self.b('')
+ self.b(' if (dbus_g_proxy_call_with_timeout (iface,')
+ self.b(' "%s",' % member)
+ self.b(' timeout_ms,')
+ self.b(' error,')
+
+ for arg in in_args:
+ name, info, tp_type, elt = arg
+ ctype, gtype, marshaller, pointer = info
+
+ const = pointer and 'const ' or ''
+
+ self.b(' %s, %s,' % (gtype, name))
+
+ self.b(' G_TYPE_INVALID,')
+
+ for arg in out_args:
+ name, info, tp_type, elt = arg
+ ctype, gtype, marshaller, pointer = info
+
+ self.b(' %s, &i_%s,' % (gtype, name))
+ self.b(' G_TYPE_INVALID))')
+ self.b(' {')
+ for arg in out_args:
+ name, info, tp_type, elt = arg
+ ctype, gtype, marshaller, pointer = info
+
+ self.b(' *%s = i_%s;' % (name, name))
+ self.b(' return TRUE;')
+ self.b(' }')
+ self.b(' else')
+ self.b(' return FALSE;')
+ self.b('}')
+ self.b('')
+
+ # leave a gap for the end of the method
+ self.b('')
+ self.h('')
+
+ def do_signal_add(self, signal):
+ marshaller_items = []
+ gtypes = []
+
+ for i in signal.getElementsByTagName('arg'):
+ name = i.getAttribute('name')
+ type = i.getAttribute('type')
+ info = type_to_gtype(type)
+ # type, GType, STRING, is a pointer
+ gtypes.append(info[1])
+
+ self.b(' dbus_g_proxy_add_signal (proxy, "%s",'
+ % signal.getAttribute('name'))
+ for gtype in gtypes:
+ self.b(' %s,' % gtype)
+ self.b(' G_TYPE_INVALID);')
+
+ def do_interface(self, node):
+ ifaces = node.getElementsByTagName('interface')
+ assert len(ifaces) == 1
+ iface = ifaces[0]
+ name = node.getAttribute('name').replace('/', '')
+
+ self.iface = name
+ self.iface_lc = name.lower()
+ self.iface_uc = name.upper()
+ self.iface_mc = name.replace('_', '')
+ self.iface_dbus = iface.getAttribute('name')
+
+ signals = node.getElementsByTagName('signal')
+ methods = node.getElementsByTagName('method')
+
+ self.b('static inline void')
+ self.b('%s_add_signals_for_%s (DBusGProxy *proxy)'
+ % (self.prefix_lc, name.lower()))
+ self.b('{')
+
+ for signal in signals:
+ self.do_signal_add(signal)
+
+ self.b('}')
+ self.b('')
+ self.b('')
+
+ for signal in signals:
+ self.do_signal(name, signal)
+
+ for method in methods:
+ self.do_method(name, method)
+
+ self.iface_dbus = None
+
+ def __call__(self):
+
+ self.h('G_BEGIN_DECLS')
+ self.h('')
+
+ self.b('/* We don\'t want gtkdoc scanning this file, it\'ll get')
+ self.b(' * confused by seeing function definitions, so mark it as: */')
+ self.b('/*<private_header>*/')
+ self.b('')
+
+ nodes = self.dom.getElementsByTagName('node')
+ nodes.sort(cmp_by_name)
+
+ for node in nodes:
+ self.do_interface(node)
+
+ if self.group is not None:
+
+ self.b('/*')
+ self.b(' * %s_%s_add_signals:' % (self.prefix_lc, self.group))
+ self.b(' * @self: the #TpProxy')
+ self.b(' * @quark: a quark whose string value is the interface')
+ self.b(' * name whose signals should be added')
+ self.b(' * @proxy: the D-Bus proxy to which to add the signals')
+ self.b(' * @unused: not used for anything')
+ self.b(' *')
+ self.b(' * Tell dbus-glib that @proxy has the signatures of all')
+ self.b(' * signals on the given interface, if it\'s one we')
+ self.b(' * support.')
+ self.b(' *')
+ self.b(' * This function should be used as a signal handler for')
+ self.b(' * #TpProxy::interface-added.')
+ self.b(' */')
+ self.b('static void')
+ self.b('%s_%s_add_signals (TpProxy *self,'
+ % (self.prefix_lc, self.group))
+ self.b(' guint quark,')
+ self.b(' DBusGProxy *proxy,')
+ self.b(' gpointer unused)')
+
+ self.b('{')
+
+ for node in nodes:
+ iface = node.getElementsByTagName('interface')[0]
+ self.iface_dbus = iface.getAttribute('name')
+ name = node.getAttribute('name').replace('/', '').lower()
+ self.iface_uc = name.upper()
+ self.b(' if (quark == %s)' % self.get_iface_quark())
+ self.b(' %s_add_signals_for_%s (proxy);'
+ % (self.prefix_lc, name))
+
+ self.b('}')
+ self.b('')
+
+ self.h('G_END_DECLS')
+ self.h('')
+
+ open(self.basename + '.h', 'w').write('\n'.join(self.__header))
+ open(self.basename + '-body.h', 'w').write('\n'.join(self.__body))
+
+
+def types_to_gtypes(types):
+ return [type_to_gtype(t)[1] for t in types]
+
+
+if __name__ == '__main__':
+ options, argv = gnu_getopt(sys.argv[1:], '',
+ ['group=', 'subclass=', 'subclass-assert=',
+ 'iface-quark-prefix='])
+
+ opts = {}
+
+ for option, value in options:
+ opts[option] = value
+
+ dom = xml.dom.minidom.parse(argv[0])
+
+ Generator(dom, argv[1], argv[2], opts)()
diff --git a/xml/Account.xml b/xml/Account.xml
index 303b9079..ddc09017 100644
--- a/xml/Account.xml
+++ b/xml/Account.xml
@@ -192,7 +192,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
</tp:docstring>
</property>
- <property name="enabled" type="b" access="readwrite">
+ <property name="Enabled" type="b" access="readwrite">
<tp:docstring xmlns="http://www.w3.org/1999/xhtml">
<p>This property gives the users the possibility to prevent an account
from being used; account editor UIs should let the user modify this
diff --git a/xml/Account_Interface_Compat.xml b/xml/Account_Interface_Compat.xml
new file mode 100644
index 00000000..af68a5b1
--- /dev/null
+++ b/xml/Account_Interface_Compat.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0" ?>
+<node name="/Account_Interface_Compat" xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
+ <tp:copyright>Copyright (C) 2008 Nokia Corporation</tp:copyright>
+ <tp:license xmlns="http://www.w3.org/1999/xhtml">
+ <p>This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.</p>
+
+<p>This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.</p>
+
+<p>You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.</p>
+ </tp:license>
+ <interface name="org.freedesktop.Telepathy.Account.Interface.Compat">
+ <tp:requires interface="org.freedesktop.Telepathy.Account"/>
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The Compat interface holds properties necessary for maintaining the
+ libmissioncontrol compatible layer.</p>
+ </tp:docstring>
+
+ <property name="Profile" type="s" access="readwrite">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The name of the profile.</p>
+ </tp:docstring>
+ </property>
+
+ <property name="AvatarFile" type="s" access="read">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>The location of the avatar.</p>
+ </tp:docstring>
+ </property>
+
+ <property name="SecondaryVCardFields" type="as" access="readwrite">
+ <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
+ <p>List of secondary VCard fields.</p>
+ </tp:docstring>
+ </property>
+
+ </interface>
+</node>
+<!-- vim:set sw=2 sts=2 et ft=xml: -->
diff --git a/xml/Makefile.am b/xml/Makefile.am
index 005b4ce8..965a272d 100644
--- a/xml/Makefile.am
+++ b/xml/Makefile.am
@@ -5,7 +5,9 @@ DROP_NAMESPACE = sed -e 's@xmlns:tp="http://telepathy\.freedesktop\.org/wiki/Dbu
SPECS = MissionControl.xml \
Account_Manager.xml \
- Account.xml
+ Account.xml \
+ Account_Interface_Compat.xml
+
SPECS_GEN = ${SPECS:.xml=-gen.xml}
diff --git a/xml/nmc5.xml b/xml/nmc5.xml
index 062535f2..fc3d30c6 100644
--- a/xml/nmc5.xml
+++ b/xml/nmc5.xml
@@ -5,6 +5,7 @@
<tp:copyright>Copyright (C) 2008 Nokia Corporation</tp:copyright>
<xi:include href="Account.xml"/>
+<xi:include href="Account_Interface_Compat.xml"/>
<xi:include href="Account_Manager.xml"/>
</tp:spec>