MissionControl *mc;
/* connection to connection data mapping */
GHashTable *connections;
+ GHashTable *outstanding_classes_requests;
gpointer token;
GSList *tubes;
GPtrArray *requestable_channels;
} ConnectionData;
+typedef struct
+{
+ EmpathyDispatcher *dispatcher;
+ char *channel_type;
+ guint handle_type;
+ EmpathyDispatcherFindChannelClassCb *callback;
+ gpointer user_data;
+} FindChannelRequest;
+
static DispatchData *
new_dispatch_data (TpChannel *channel,
GObject *channel_wrapper)
}
}
+static void
+free_find_channel_request (FindChannelRequest *r)
+{
+ g_object_unref (r->dispatcher);
+ g_free (r->channel_type);
+ g_slice_free (FindChannelRequest, r);
+}
+
static void
dispatcher_connection_invalidated_cb (TpConnection *connection,
guint domain,
else
{
ConnectionData *cd;
+ GList *requests, *l;
+ FindChannelRequest *request;
+ GStrv retval;
cd = g_hash_table_lookup (priv->connections, proxy);
g_assert (cd != NULL);
cd->requestable_channels = g_boxed_copy (
TP_ARRAY_TYPE_REQUESTABLE_CHANNEL_CLASS_LIST, requestable_channels);
+
+ requests = g_hash_table_lookup (priv->outstanding_classes_requests,
+ proxy);
+
+ for (l = requests; l != NULL; l = l->next)
+ {
+ request = l->data;
+
+ retval = empathy_dispatcher_find_channel_class (dispatcher,
+ TP_CONNECTION (proxy), request->channel_type,
+ request->handle_type);
+ request->callback (retval, request->user_data);
+
+ free_find_channel_request (request);
+ }
+
+ g_hash_table_remove (priv->outstanding_classes_requests, proxy);
}
}
GList *l;
GHashTableIter iter;
gpointer connection;
+ GList *list;
g_signal_handlers_disconnect_by_func (priv->account_manager,
dispatcher_new_connection_cb, object);
dispatcher_connection_invalidated_cb, object);
}
+ g_hash_table_iter_init (&iter, priv->outstanding_classes_requests);
+ while (g_hash_table_iter_next (&iter, &connection, (gpointer *) &list))
+ {
+ g_list_foreach (list, (GFunc) free_find_channel_request, NULL);
+ }
+
g_object_unref (priv->account_manager);
g_object_unref (priv->mc);
g_hash_table_destroy (priv->connections);
+ g_hash_table_destroy (priv->outstanding_classes_requests);
}
static void
priv->connections = g_hash_table_new_full (g_direct_hash, g_direct_equal,
g_object_unref, (GDestroyNotify) free_connection_data);
+ priv->outstanding_classes_requests = g_hash_table_new_full (g_direct_hash,
+ g_direct_equal, g_object_unref, NULL);
+
priv->channels = NULL;
connections = empathy_account_manager_dup_connections (priv->account_manager);
return NULL;
}
+void
+empathy_dispatcher_find_channel_class_async (EmpathyDispatcher *dispatcher,
+ TpConnection *connection,
+ const gchar *channel_type,
+ guint handle_type,
+ EmpathyDispatcherFindChannelClassCb callback,
+ gpointer user_data)
+{
+ GStrv retval;
+ EmpathyDispatcherPriv *priv;
+ GList *requests;
+ FindChannelRequest *request;
+
+ g_return_if_fail (EMPATHY_IS_DISPATCHER (dispatcher));
+ g_return_if_fail (TP_IS_CONNECTION (connection));
+ g_return_if_fail (channel_type != NULL);
+ g_return_if_fail (handle_type != 0);
+
+ /* own a reference to the object, so that clients can unref the singleton
+ * while waiting for the cb
+ */
+ priv = GET_PRIV (g_object_ref (dispatcher));
+ retval = empathy_dispatcher_find_channel_class (dispatcher, connection,
+ channel_type, handle_type);
+
+ if (retval != NULL)
+ {
+ g_object_unref (dispatcher);
+ callback (retval, user_data);
+ return;
+ }
+
+ requests = g_hash_table_lookup (priv->outstanding_classes_requests,
+ connection);
+
+ /* append another request for this connection */
+ request = g_slice_new0 (FindChannelRequest);
+ request->dispatcher = dispatcher;
+ request->channel_type = g_strdup (channel_type);
+ request->handle_type = handle_type;
+ request->callback = callback;
+ request->user_data = user_data;
+
+ requests = g_list_prepend (requests, request);
+
+ g_hash_table_insert (priv->outstanding_classes_requests,
+ connection, requests);
+}
typedef void (EmpathyDispatcherRequestCb) (
EmpathyDispatchOperation *dispatch, const GError *error,
gpointer user_data);
+typedef void (EmpathyDispatcherFindChannelClassCb) (
+ GStrv channel_class, gpointer user_data);
GType empathy_dispatcher_get_type (void) G_GNUC_CONST;
GStrv empathy_dispatcher_find_channel_class (EmpathyDispatcher *dispatcher,
TpConnection *connection, const gchar *channel_type, guint handle_type);
+void empathy_dispatcher_find_channel_class_async (EmpathyDispatcher *dispatcher,
+ TpConnection *connection, const gchar *channel_type, guint handle_type,
+ EmpathyDispatcherFindChannelClassCb callback, gpointer user_data);
+
/* Get the dispatcher singleton */
EmpathyDispatcher * empathy_dispatcher_dup_singleton (void);