[Telepathy-commits] [telepathy-glib/master] TpConnection: track self-handle and add GObject property and C accessor

Simon McVittie simon.mcvittie at collabora.co.uk
Wed Feb 4 09:08:15 PST 2009


---
 docs/reference/telepathy-glib-sections.txt |    1 +
 telepathy-glib/connection-internal.h       |    1 +
 telepathy-glib/connection.c                |  121 +++++++++++++++++++++++++--
 telepathy-glib/connection.h                |    2 +
 4 files changed, 116 insertions(+), 9 deletions(-)

diff --git a/docs/reference/telepathy-glib-sections.txt b/docs/reference/telepathy-glib-sections.txt
index b50a27c..95ffa36 100644
--- a/docs/reference/telepathy-glib-sections.txt
+++ b/docs/reference/telepathy-glib-sections.txt
@@ -2232,6 +2232,7 @@ TpConnectionWhenReadyCb
 tp_connection_call_when_ready
 tp_connection_is_ready
 tp_connection_get_status
+tp_connection_get_self_handle
 TpConnectionRequestHandlesCb
 tp_connection_request_handles
 TpConnectionHoldHandlesCb
diff --git a/telepathy-glib/connection-internal.h b/telepathy-glib/connection-internal.h
index 87e1f63..0f02b9b 100644
--- a/telepathy-glib/connection-internal.h
+++ b/telepathy-glib/connection-internal.h
@@ -33,6 +33,7 @@ struct _TpConnectionPrivate {
     /* GArray of TpConnectionProc */
     GArray *introspect_needed;
 
+    TpHandle self_handle;
     TpConnectionStatus status;
     TpConnectionStatusReason status_reason;
     GError *connection_error /* initialized statically */;
diff --git a/telepathy-glib/connection.c b/telepathy-glib/connection.c
index 17384d7..8e048ca 100644
--- a/telepathy-glib/connection.c
+++ b/telepathy-glib/connection.c
@@ -116,6 +116,7 @@ enum
   PROP_STATUS = 1,
   PROP_STATUS_REASON,
   PROP_CONNECTION_READY,
+  PROP_SELF_HANDLE,
   N_PROPS
 };
 
@@ -272,12 +273,69 @@ introspect_contacts (TpConnection *self)
 }
 
 static void
+_tp_connection_set_self_handle (TpConnection *self,
+                 guint self_handle)
+{
+  if (self_handle != self->priv->self_handle)
+    {
+      self->priv->self_handle = self_handle;
+      g_object_notify ((GObject *) self, "self-handle");
+    }
+}
+
+static void
+got_self_handle (TpConnection *self,
+                 guint self_handle,
+                 const GError *error,
+                 gpointer user_data G_GNUC_UNUSED,
+                 GObject *user_object G_GNUC_UNUSED)
+{
+
+  if (error != NULL)
+    {
+      DEBUG ("%p: GetSelfHandle() failed: %s", self, error->message);
+      self_handle = 0;
+      /* FIXME: abort the readying process */
+    }
+
+  _tp_connection_set_self_handle (self, self_handle);
+  tp_connection_continue_introspection (self);
+}
+
+static void
+on_self_handle_changed (TpConnection *self,
+                        guint self_handle,
+                        gpointer user_data G_GNUC_UNUSED,
+                        GObject *user_object G_GNUC_UNUSED)
+{
+  _tp_connection_set_self_handle (self, self_handle);
+}
+
+static void
+get_self_handle (TpConnection *self)
+{
+  g_assert (self->priv->introspect_needed != NULL);
+
+  tp_cli_connection_connect_to_self_handle_changed (self,
+      on_self_handle_changed, NULL, NULL, NULL, NULL);
+
+  /* GetSelfHandle is deprecated in favour of the SelfHandle property,
+   * but until Connection has other interesting properties, there's no point in
+   * trying to implement a fast path; GetSelfHandle is the only one guaranteed
+   * to work, so we'll sometimes have to call it anyway */
+  tp_cli_connection_call_get_self_handle (self, -1,
+       got_self_handle, NULL, NULL, NULL);
+}
+
+static void
 tp_connection_got_interfaces_cb (TpConnection *self,
                                  const gchar **interfaces,
                                  const GError *error,
                                  gpointer user_data,
                                  GObject *user_object)
 {
+  TpConnectionProc func;
+
   if (error != NULL)
     {
       DEBUG ("%p: GetInterfaces() failed, assuming no interfaces: %s",
@@ -291,6 +349,9 @@ tp_connection_got_interfaces_cb (TpConnection *self,
   self->priv->introspect_needed = g_array_new (FALSE, FALSE,
       sizeof (TpConnectionProc));
 
+  func = get_self_handle;
+  g_array_append_val (self->priv->introspect_needed, func);
+
   if (interfaces != NULL)
     {
       const gchar **iter;
@@ -306,15 +367,13 @@ tp_connection_got_interfaces_cb (TpConnection *self,
 
               if (q == TP_IFACE_QUARK_CONNECTION_INTERFACE_CONTACTS)
                 {
-                  TpConnectionProc func = introspect_contacts;
-
+                  func = introspect_contacts;
                   g_array_append_val (self->priv->introspect_needed, func);
                 }
               else if (q == TP_IFACE_QUARK_CONNECTION_INTERFACE_ALIASING)
                 {
                   /* call GetAliasFlags */
-                  TpConnectionProc func = introspect_aliasing;
-
+                  func = introspect_aliasing;
                   g_array_append_val (self->priv->introspect_needed,
                       func);
                 }
@@ -322,16 +381,14 @@ tp_connection_got_interfaces_cb (TpConnection *self,
               else if (q == TP_IFACE_QUARK_CONNECTION_INTERFACE_AVATARS)
                 {
                   /* call GetAvatarRequirements */
-                  TpConnectionProc func = introspect_avatars;
-
+                  func = introspect_avatars;
                   g_array_append_val (self->priv->introspect_needed,
                       func);
                 }
               else if (q == TP_IFACE_QUARK_CONNECTION_INTERFACE_PRESENCE)
                 {
                   /* call GetStatuses */
-                  TpConnectionProc func = introspect_presence;
-
+                  func = introspect_presence;
                   g_array_append_val (self->priv->introspect_needed,
                       func);
                 }
@@ -529,6 +586,13 @@ tp_connection_got_status_cb (TpConnection *self,
     }
 }
 
+static void
+tp_connection_invalidated (TpConnection *self)
+{
+  _tp_connection_set_self_handle (self, 0);
+  _tp_connection_clean_up_handle_refs (self);
+}
+
 static GObject *
 tp_connection_constructor (GType type,
                            guint n_params,
@@ -555,7 +619,7 @@ tp_connection_constructor (GType type,
   _tp_connection_init_handle_refs (self);
 
   g_signal_connect (self, "invalidated",
-      G_CALLBACK (_tp_connection_clean_up_handle_refs), NULL);
+      G_CALLBACK (tp_connection_invalidated), NULL);
 
   DEBUG ("Returning %p", self);
   return (GObject *) self;
@@ -670,6 +734,19 @@ tp_connection_class_init (TpConnectionClass *klass)
       param_spec);
 
   /**
+   * TpConnection:self-handle:
+   *
+   * The %TP_HANDLE_TYPE_CONTACT handle of the local user on this connection,
+   * or 0 if we don't know yet or if the connection has become invalid.
+   */
+  param_spec = g_param_spec_uint ("self-handle", "Self handle",
+      "The local user's Contact handle on this connection", 0, G_MAXUINT32,
+      0,
+      G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+  g_object_class_install_property (object_class, PROP_SELF_HANDLE,
+      param_spec);
+
+  /**
    * TpConnection:status-reason:
    *
    * The reason why #TpConnection:status changed to its current value,
@@ -783,6 +860,32 @@ finally:
 }
 
 /**
+ * tp_connection_get_self_handle:
+ * @self: a connection
+ *
+ * Return the %TP_HANDLE_TYPE_CONTACT handle of the local user on this
+ * connection, or 0 if the connection is not ready (the
+ * TpConnection:connection-ready property is false) or has become invalid
+ * (the TpProxy::invalidated signal).
+ *
+ * The returned handle is not necessarily valid forever (the
+ * notify::self-handle signal will be emitted if it changes, which can happen
+ * on protocols such as IRC). Construct a #TpContact object if you want to
+ * track the local user's identifier in the protocol, or other information
+ * like their presence status, over time.
+ *
+ * Returns: the value of the TpConnection:self-handle property
+ *
+ * Since: 0.7.UNRELEASED
+ */
+TpHandle
+tp_connection_get_self_handle (TpConnection *self)
+{
+  g_return_val_if_fail (TP_IS_CONNECTION (self), 0);
+  return self->priv->self_handle;
+}
+
+/**
  * tp_connection_get_status:
  * @self: a connection
  * @reason: a TpConnectionStatusReason, or %NULL
diff --git a/telepathy-glib/connection.h b/telepathy-glib/connection.h
index 248316f..46c345e 100644
--- a/telepathy-glib/connection.h
+++ b/telepathy-glib/connection.h
@@ -76,6 +76,8 @@ TpConnection *tp_connection_new (TpDBusDaemon *dbus, const gchar *bus_name,
 TpConnectionStatus tp_connection_get_status (TpConnection *self,
     TpConnectionStatusReason *reason);
 
+TpHandle tp_connection_get_self_handle (TpConnection *self);
+
 gboolean tp_connection_is_ready (TpConnection *self);
 
 gboolean tp_connection_run_until_ready (TpConnection *self,
-- 
1.5.6.5




More information about the telepathy-commits mailing list