+ GossipChatPriv *priv;
+ GList *l;
+ gboolean was_composing;
+
+ priv = GET_PRIV (chat);
+
+ was_composing = (priv->compositors != NULL);
+
+ /* Find the contact in the list. After that l is the list elem or NULL */
+ for (l = priv->compositors; l; l = l->next) {
+ if (gossip_contact_equal (contact, l->data)) {
+ break;
+ }
+ }
+
+ switch (state) {
+ case TP_CHANNEL_CHAT_STATE_GONE:
+ case TP_CHANNEL_CHAT_STATE_INACTIVE:
+ case TP_CHANNEL_CHAT_STATE_ACTIVE:
+ /* Contact is not composing */
+ if (l) {
+ priv->compositors = g_list_remove_link (priv->compositors, l);
+ g_object_unref (l->data);
+ g_list_free1 (l);
+ }
+ break;
+ case TP_CHANNEL_CHAT_STATE_PAUSED:
+ case TP_CHANNEL_CHAT_STATE_COMPOSING:
+ /* Contact is composing */
+ if (!l) {
+ priv->compositors = g_list_prepend (priv->compositors,
+ g_object_ref (contact));
+ }
+ break;
+ default:
+ g_assert_not_reached ();
+ }
+
+ gossip_debug (DEBUG_DOMAIN, "Was composing: %s now composing: %s",
+ was_composing ? "yes" : "no",
+ priv->compositors ? "yes" : "no");
+
+ if ((was_composing && !priv->compositors) ||
+ (!was_composing && priv->compositors)) {
+ /* Composing state changed */
+ g_signal_emit (chat, signals[COMPOSING], 0,
+ (gboolean) priv->compositors);
+ }