diff options
-rw-r--r-- | libempathy/empathy-contact.c | 74 | ||||
-rw-r--r-- | libempathy/empathy-contact.h | 9 |
2 files changed, 72 insertions, 11 deletions
diff --git a/libempathy/empathy-contact.c b/libempathy/empathy-contact.c index 541858673..a8a617c29 100644 --- a/libempathy/empathy-contact.c +++ b/libempathy/empathy-contact.c @@ -53,8 +53,15 @@ typedef struct { gboolean is_user; guint hash; EmpathyContactReady ready; + GList *ready_callbacks; } EmpathyContactPriv; +typedef struct { + EmpathyContactReady ready; + EmpathyContactReadyCb *callback; + gpointer user_data; +} ReadyCbData; + static void contact_finalize (GObject *object); static void contact_get_property (GObject *object, guint param_id, GValue *value, GParamSpec *pspec); @@ -330,6 +337,21 @@ contact_set_property (GObject *object, }; } +static gboolean +contact_is_ready (EmpathyContact *contact, EmpathyContactReady ready) +{ + EmpathyContactPriv *priv = GET_PRIV (contact); + + /* When the name is NULL, empathy_contact_get_name() fallback to the id. + * When the caller want to wait the name to be ready, it also want to wait + * the id to be ready in case of fallback. */ + if ((ready & EMPATHY_CONTACT_READY_NAME) && G_STR_EMPTY (priv->name)) + ready |= EMPATHY_CONTACT_READY_ID; + + return (priv->ready & ready) == ready; +} + + static void contact_set_ready_flag (EmpathyContact *contact, EmpathyContactReady flag) @@ -338,8 +360,24 @@ contact_set_ready_flag (EmpathyContact *contact, if (!(priv->ready & flag)) { + GList *l, *ln; + priv->ready |= flag; g_object_notify (G_OBJECT (contact), "ready"); + + for (l = priv->ready_callbacks ; l != NULL ; l = ln ) + { + ReadyCbData *d = (ReadyCbData *)l->data; + ln = g_list_next (l); + + if (contact_is_ready (contact, d->ready)) + { + d->callback (contact, d->user_data); + + priv->ready_callbacks = g_list_delete_link + (priv->ready_callbacks, l); + } + } } } @@ -768,22 +806,36 @@ empathy_contact_hash (gconstpointer key) return priv->hash; } -static gboolean -contact_is_ready_func (GObject *contact, - gpointer user_data) +void empathy_contact_call_when_ready (EmpathyContact *contact, + EmpathyContactReady ready, EmpathyContactReadyCb *callback, gpointer + user_data) { EmpathyContactPriv *priv = GET_PRIV (contact); - EmpathyContactReady ready; - ready = GPOINTER_TO_UINT (user_data); + g_return_if_fail (contact != NULL); + g_return_if_fail (callback != NULL); - /* When the name is NULL, empathy_contact_get_name() fallback to the id. - * When the caller want to wait the name to be ready, it also want to wait - * the id to be ready in case of fallback. */ - if ((ready & EMPATHY_CONTACT_READY_NAME) && G_STR_EMPTY (priv->name)) - ready |= EMPATHY_CONTACT_READY_ID; + if (contact_is_ready (contact, ready)) + { + callback (contact, user_data); + } + else + { + ReadyCbData *d = g_slice_new0 (ReadyCbData); + d->ready = ready; + d->callback = callback; + d->user_data = user_data; + priv->ready_callbacks = g_list_prepend (priv->ready_callbacks, + d); + } +} - return (priv->ready & ready) == ready; +static gboolean +contact_is_ready_func (GObject *contact, + gpointer user_data) +{ + return contact_is_ready (EMPATHY_CONTACT (contact), + GPOINTER_TO_UINT (user_data)); } void diff --git a/libempathy/empathy-contact.h b/libempathy/empathy-contact.h index d8a1a791f..19f15c3c5 100644 --- a/libempathy/empathy-contact.h +++ b/libempathy/empathy-contact.h @@ -112,14 +112,23 @@ gboolean empathy_contact_can_voip (EmpathyContact *contact); gboolean empathy_contact_can_send_files (EmpathyContact *contact); gboolean empathy_contact_equal (gconstpointer v1, gconstpointer v2); guint empathy_contact_hash (gconstpointer key); + +typedef void (EmpathyContactReadyCb) + (EmpathyContact *contact, gpointer user_data); +void empathy_contact_call_when_ready (EmpathyContact *contact, + EmpathyContactReady ready, EmpathyContactReadyCb *callback, gpointer + user_data); + void empathy_contact_run_until_ready (EmpathyContact *contact, EmpathyContactReady ready, GMainLoop **loop); + void empathy_contact_load_avatar_data (EmpathyContact *contact, const guchar *data, const gsize len, const gchar *format, const gchar *token); gboolean empathy_contact_load_avatar_cache (EmpathyContact *contact, const gchar *token); + #define EMPATHY_TYPE_AVATAR (empathy_avatar_get_type ()) GType empathy_avatar_get_type (void) G_GNUC_CONST; EmpathyAvatar * empathy_avatar_new (guchar *data, |