[darcs-to-svn @ many changes]
authorXavier Claessens <xclaesse@src.gnome.org>
Tue, 8 May 2007 20:08:17 +0000 (20:08 +0000)
committerXavier Claessens <xclaesse@src.gnome.org>
Tue, 8 May 2007 20:08:17 +0000 (20:08 +0000)
svn path=/trunk/; revision=35

14 files changed:
libempathy-gtk/Makefile.am
libempathy-gtk/gossip-chat.c
libempathy-gtk/gossip-private-chat.c
libempathy/Makefile.am
libempathy/empathy-contact-list.c
libempathy/empathy-marshal.list
libempathy/empathy-tp-chat.c
libempathy/empathy-tp-chat.h
src/Makefile.am
src/empathy-filter-plugin.c
src/empathy-filter.c [new file with mode: 0644]
src/empathy-filter.h [new file with mode: 0644]
src/empathy-filter.xml [new file with mode: 0644]
src/empathy-main.c

index c5b66b7..b18845a 100644 (file)
@@ -1,4 +1,6 @@
 AM_CPPFLAGS =                                           \
+       -I.                                             \
+       -I$(top_srcdir)                                 \
        $(EMPATHY_CFLAGS)                               \
        $(WARN_CFLAGS)
 
index e8906db..706dca2 100644 (file)
@@ -133,6 +133,10 @@ static void             chat_composing_start              (GossipChat      *chat
 static void             chat_composing_stop               (GossipChat      *chat);
 static void             chat_composing_remove_timeout     (GossipChat      *chat);
 static gboolean         chat_composing_stop_timeout_cb    (GossipChat      *chat);
+static void             chat_state_changed_cb             (EmpathyTpChat   *tp_chat,
+                                                          GossipContact   *contact,
+                                                          TelepathyChannelChatState  state,
+                                                          GossipChat      *chat);
 
 enum {
        COMPOSING,
@@ -954,10 +958,8 @@ chat_composing_start (GossipChat *chat)
                /* Just restart the timeout */
                chat_composing_remove_timeout (chat);
        } else {
-       /* FIXME:
-               gossip_session_send_composing (gossip_app_get_session (),
-                                              priv->contact, TRUE);
-                                             */
+               empathy_tp_chat_set_state (priv->tp_chat,
+                                          TP_CHANNEL_CHAT_STATE_COMPOSING);
        }
 
        priv->composing_stop_timeout_id = g_timeout_add (
@@ -974,9 +976,8 @@ chat_composing_stop (GossipChat *chat)
        priv = GET_PRIV (chat);
 
        chat_composing_remove_timeout (chat);
-       /* FIXME:
-       gossip_session_send_composing (gossip_app_get_session (),
-                                      priv->contact, FALSE);*/
+       empathy_tp_chat_set_state (priv->tp_chat,
+                                  TP_CHANNEL_CHAT_STATE_ACTIVE);
 }
 
 static void
@@ -1000,13 +1001,21 @@ chat_composing_stop_timeout_cb (GossipChat *chat)
        priv = GET_PRIV (chat);
 
        priv->composing_stop_timeout_id = 0;
-       /* FIXME:
-       gossip_session_send_composing (gossip_app_get_session (),
-                                      priv->contact, FALSE);*/
+       empathy_tp_chat_set_state (priv->tp_chat,
+                                  TP_CHANNEL_CHAT_STATE_ACTIVE);
 
        return FALSE;
 }
 
+static void
+chat_state_changed_cb (EmpathyTpChat             *tp_chat,
+                      GossipContact             *contact,
+                      TelepathyChannelChatState  state,
+                      GossipChat                *chat)
+{
+       /* FIXME: not yet implemented */
+}
+
 gboolean
 gossip_chat_get_is_command (const gchar *str)
 {
@@ -1219,6 +1228,9 @@ gossip_chat_set_tp_chat (GossipChat    *chat,
        g_signal_connect (tp_chat, "message-received",
                          G_CALLBACK (chat_message_received_cb),
                          chat);
+       g_signal_connect (tp_chat, "chat-state-changed",
+                         G_CALLBACK (chat_state_changed_cb),
+                         chat);
        g_signal_connect (tp_chat, "destroy",
                          G_CALLBACK (chat_destroy_cb),
                          chat);
index a3bdbb6..0c27abf 100644 (file)
@@ -49,8 +49,6 @@
 
 #define DEBUG_DOMAIN "PrivateChat"
 
-#define COMPOSING_STOP_TIMEOUT 5
-
 #define GET_PRIV(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GOSSIP_TYPE_PRIVATE_CHAT, GossipPrivateChatPriv))
 
 struct _GossipPrivateChatPriv {   
index 98349b2..629fc36 100644 (file)
@@ -1,4 +1,6 @@
 AM_CPPFLAGS =                                           \
+       -I.                                             \
+       -I$(top_srcdir)                                 \
        -DDATADIR=\""$(datadir)"\"                      \
        -DLOCALEDIR=\""$(datadir)/locale"\"             \
        $(LIBEMPATHY_CFLAGS)                            \
index 4d4b692..f1cede9 100644 (file)
@@ -34,8 +34,9 @@
 #include <libtelepathy/tp-conn-iface-avatars-gen.h>
 
 #include "empathy-contact-list.h"
-#include "gossip-debug.h"
 #include "gossip-telepathy-group.h"
+#include "gossip-debug.h"
+#include "gossip-utils.h"
 
 #define GET_PRIV(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
                       EMPATHY_TYPE_CONTACT_LIST, EmpathyContactListPriv))
@@ -46,6 +47,7 @@
 struct _EmpathyContactListPriv {
        TpConn               *tp_conn;
        McAccount            *account;
+       MissionControl       *mc;
        GossipContact        *own_contact;
 
        GossipTelepathyGroup *known;
@@ -191,6 +193,12 @@ static void                   contact_list_parse_presence_foreach   (guint
 static void                   contact_list_presences_table_foreach  (const gchar                   *state_str,
                                                                     GHashTable                    *presences_table,
                                                                     GossipPresence               **presence);
+static void                   contact_list_status_changed_cb        (MissionControl                *mc,
+                                                                    TelepathyConnectionStatus      status,
+                                                                    McPresence                     presence,
+                                                                    TelepathyConnectionStatusReason reason,
+                                                                    const gchar                   *unique_name,
+                                                                    EmpathyContactList            *list);
 
 enum {
        CONTACT_ADDED,
@@ -273,8 +281,14 @@ contact_list_finalize (GObject *object)
 
        gossip_debug (DEBUG_DOMAIN, "finalize: %p", object);
 
+       dbus_g_proxy_disconnect_signal (DBUS_G_PROXY (priv->mc),
+                                       "AccountStatusChanged",
+                                       G_CALLBACK (contact_list_status_changed_cb),
+                                       list);
+
+       contact_list_finalize_proxies (list);
+
        if (priv->tp_conn) {
-               contact_list_finalize_proxies (list);
                g_object_unref (priv->tp_conn);
        }
 
@@ -292,6 +306,7 @@ contact_list_finalize (GObject *object)
 
        g_object_unref (priv->account);
        g_object_unref (priv->own_contact);
+       g_object_unref (priv->mc);
        g_hash_table_destroy (priv->groups);
        g_hash_table_destroy (priv->contacts);
 
@@ -304,7 +319,6 @@ empathy_contact_list_new (McAccount *account)
        EmpathyContactListPriv *priv;
        EmpathyContactList     *list;
        MissionControl         *mc;
-       TpConn                 *tp_conn;
        guint                   handle;
        GError                 *error = NULL;
 
@@ -317,19 +331,20 @@ empathy_contact_list_new (McAccount *account)
                return NULL;
        }
 
-       tp_conn = mission_control_get_connection (mc, account, NULL);
-       g_object_unref (mc);
-       g_return_val_if_fail (tp_conn != NULL, NULL);
-
        list = g_object_new (EMPATHY_TYPE_CONTACT_LIST, NULL);
        priv = GET_PRIV (list);
 
-       priv->tp_conn = tp_conn;
+       priv->tp_conn = mission_control_get_connection (mc, account, NULL);
        priv->account = g_object_ref (account);
+       priv->mc = mc;
 
        g_signal_connect (priv->tp_conn, "destroy",
                          G_CALLBACK (contact_list_destroy_cb),
                          list);
+       dbus_g_proxy_connect_signal (DBUS_G_PROXY (priv->mc),
+                                    "AccountStatusChanged",
+                                    G_CALLBACK (contact_list_status_changed_cb),
+                                    list, NULL);
 
        priv->aliasing_iface = tp_conn_get_interface (priv->tp_conn,
                                                      TELEPATHY_CONN_IFACE_ALIASING_QUARK);
@@ -753,12 +768,14 @@ contact_list_finalize_proxies (EmpathyContactList *list)
 
        priv = GET_PRIV (list);
 
-       g_signal_handlers_disconnect_by_func (priv->tp_conn,
-                                             contact_list_destroy_cb,
-                                             list);
-       dbus_g_proxy_disconnect_signal (DBUS_G_PROXY (priv->tp_conn), "NewChannel",
-                                       G_CALLBACK (contact_list_newchannel_cb),
-                                       list);
+       if (priv->tp_conn) {
+               g_signal_handlers_disconnect_by_func (priv->tp_conn,
+                                                     contact_list_destroy_cb,
+                                                     list);
+               dbus_g_proxy_disconnect_signal (DBUS_G_PROXY (priv->tp_conn), "NewChannel",
+                                               G_CALLBACK (contact_list_newchannel_cb),
+                                               list);
+       }
 
        if (priv->aliasing_iface) {
                dbus_g_proxy_disconnect_signal (priv->aliasing_iface,
@@ -783,15 +800,15 @@ contact_list_finalize_proxies (EmpathyContactList *list)
 }
 
 static void
-contact_list_destroy_cb (DBusGProxy           *proxy,
+contact_list_destroy_cb (DBusGProxy         *proxy,
                         EmpathyContactList *list)
 {
        EmpathyContactListPriv *priv;
 
        priv = GET_PRIV (list);
 
-       gossip_debug (DEBUG_DOMAIN, "Connection destroyed. "
-                                   "Account disconnected or CM crashed.");
+       gossip_debug (DEBUG_DOMAIN, "Connection destroyed... "
+                     "Account disconnected or CM crashed");
 
        /* DBus proxies should NOT be used anymore */
        g_object_unref (priv->tp_conn);
@@ -1767,3 +1784,32 @@ contact_list_presences_table_foreach (const gchar     *state_str,
        }
 }
 
+static void
+contact_list_status_changed_cb (MissionControl                  *mc,
+                               TelepathyConnectionStatus        status,
+                               McPresence                       presence,
+                               TelepathyConnectionStatusReason  reason,
+                               const gchar                     *unique_name,
+                               EmpathyContactList              *list)
+{
+       EmpathyContactListPriv *priv;
+       McAccount              *account;
+
+       priv = GET_PRIV (list);
+
+       account = mc_account_lookup (unique_name);
+       if (status != TP_CONN_STATUS_DISCONNECTED ||
+           !gossip_account_equal (account, priv->account)) {
+               g_object_unref (account);
+               return;
+       }
+
+       /* We are disconnected, do just like if the connection was destroyed */
+       g_signal_handlers_disconnect_by_func (priv->tp_conn,
+                                             contact_list_destroy_cb,
+                                             list);
+       contact_list_destroy_cb (DBUS_G_PROXY (priv->tp_conn), list);
+
+       g_object_unref (account);
+}
+
index c4c0922..b9bbd27 100644 (file)
@@ -2,3 +2,5 @@ VOID:POINTER,UINT,UINT,STRING
 VOID:OBJECT,UINT
 VOID:OBJECT,OBJECT
 VOID:INT,STRING
+VOID:OBJECT,OBJECT,UINT
+VOID:UINT,BOOLEAN
index 25639dd..4729cc2 100644 (file)
@@ -51,33 +51,35 @@ struct _EmpathyTpChatPriv {
        DBusGProxy            *chat_state_iface;
 };
 
-static void empathy_tp_chat_class_init (EmpathyTpChatClass *klass);
-static void empathy_tp_chat_init       (EmpathyTpChat      *chat);
-static void tp_chat_finalize           (GObject            *object);
-static void tp_chat_destroy_cb         (TpChan             *text_chan,
-                                       EmpathyTpChat      *chat);
-static void tp_chat_received_cb        (DBusGProxy         *text_iface,
-                                       guint               message_id,
-                                       guint               timestamp,
-                                       guint               from_handle,
-                                       guint               message_type,
-                                       guint               message_flags,
-                                       gchar              *message_body,
-                                       EmpathyTpChat      *chat);
-static void tp_chat_sent_cb            (DBusGProxy         *text_iface,
-                                       guint               timestamp,
-                                       guint               message_type,
-                                       gchar              *message_body,
-                                       EmpathyTpChat      *chat);
-static void tp_chat_state_changed_cb   (DBusGProxy         *chat_state_iface,
-                                       guint               handle,
-                                       EmpathyTpChatState  state,
-                                       EmpathyTpChat      *chat);
-static void tp_chat_emit_message       (EmpathyTpChat      *chat,
-                                       guint               type,
-                                       guint               timestamp,
-                                       guint               from_handle,
-                                       const gchar        *message_body);
+static void empathy_tp_chat_class_init (EmpathyTpChatClass        *klass);
+static void empathy_tp_chat_init       (EmpathyTpChat             *chat);
+static void tp_chat_finalize           (GObject                   *object);
+static void tp_chat_destroy_cb         (TpChan                    *text_chan,
+                                       EmpathyTpChat             *chat);
+static void tp_chat_closed_cb          (TpChan                    *text_chan,
+                                       EmpathyTpChat             *chat);
+static void tp_chat_received_cb        (DBusGProxy                *text_iface,
+                                       guint                      message_id,
+                                       guint                      timestamp,
+                                       guint                      from_handle,
+                                       guint                      message_type,
+                                       guint                      message_flags,
+                                       gchar                     *message_body,
+                                       EmpathyTpChat             *chat);
+static void tp_chat_sent_cb            (DBusGProxy                *text_iface,
+                                       guint                      timestamp,
+                                       guint                      message_type,
+                                       gchar                     *message_body,
+                                       EmpathyTpChat             *chat);
+static void tp_chat_state_changed_cb   (DBusGProxy                *chat_state_iface,
+                                       guint                      handle,
+                                       TelepathyChannelChatState  state,
+                                       EmpathyTpChat             *chat);
+static void tp_chat_emit_message       (EmpathyTpChat             *chat,
+                                       guint                      type,
+                                       guint                      timestamp,
+                                       guint                      from_handle,
+                                       const gchar               *message_body);
 
 enum {
        MESSAGE_RECEIVED,
@@ -207,6 +209,9 @@ empathy_tp_chat_new (McAccount *account,
        g_signal_connect (priv->tp_chan, "destroy",
                          G_CALLBACK (tp_chat_destroy_cb),
                          chat);
+       dbus_g_proxy_connect_signal (DBUS_G_PROXY (priv->tp_chan), "Closed",
+                                    G_CALLBACK (tp_chat_closed_cb),
+                                    chat, NULL);
        dbus_g_proxy_connect_signal (priv->text_iface, "Received",
                                     G_CALLBACK (tp_chat_received_cb),
                                     chat, NULL);
@@ -354,8 +359,8 @@ empathy_tp_chat_send (EmpathyTpChat *chat,
 }
 
 void
-empathy_tp_chat_send_state (EmpathyTpChat      *chat,
-                           EmpathyTpChatState  state)
+empathy_tp_chat_set_state (EmpathyTpChat             *chat,
+                          TelepathyChannelChatState  state)
 {
        EmpathyTpChatPriv *priv;
        GError            *error = NULL;
@@ -432,7 +437,7 @@ tp_chat_destroy_cb (TpChan        *text_chan,
 
        priv = GET_PRIV (chat);
 
-       gossip_debug (DEBUG_DOMAIN, "Channel destroyed");
+       gossip_debug (DEBUG_DOMAIN, "Channel Closed or CM crashed");
 
        g_object_unref  (priv->tp_chan);
        priv->tp_chan = NULL;
@@ -442,6 +447,22 @@ tp_chat_destroy_cb (TpChan        *text_chan,
        g_signal_emit (chat, signals[DESTROY], 0);
 }
 
+static void
+tp_chat_closed_cb (TpChan        *text_chan,
+                  EmpathyTpChat *chat)
+{
+       EmpathyTpChatPriv *priv;
+
+       priv = GET_PRIV (chat);
+
+       /* The channel is closed, do just like if the proxy was destroyed */
+       g_signal_handlers_disconnect_by_func (priv->tp_chan,
+                                             tp_chat_destroy_cb,
+                                             chat);
+       tp_chat_destroy_cb (text_chan, chat);
+
+}
+
 static void
 tp_chat_received_cb (DBusGProxy    *text_iface,
                     guint          message_id,
@@ -489,10 +510,10 @@ tp_chat_sent_cb (DBusGProxy    *text_iface,
 }
 
 static void
-tp_chat_state_changed_cb (DBusGProxy         *chat_state_iface,
-                         guint               handle,
-                         EmpathyTpChatState  state,
-                         EmpathyTpChat      *chat)
+tp_chat_state_changed_cb (DBusGProxy                *chat_state_iface,
+                         guint                      handle,
+                         TelepathyChannelChatState  state,
+                         EmpathyTpChat             *chat)
 {
        EmpathyTpChatPriv *priv;
        GossipContact     *contact;
@@ -501,6 +522,11 @@ tp_chat_state_changed_cb (DBusGProxy         *chat_state_iface,
 
        contact = empathy_contact_list_get_from_handle (priv->list, handle);
 
+       gossip_debug (DEBUG_DOMAIN, "Chat state changed for %s (%d): %d",
+                     gossip_contact_get_name (contact),
+                     handle,
+                     state);
+
        g_signal_emit (chat, signals[CHAT_STATE_CHANGED], 0, contact, state);
 
        g_object_unref (contact);
index 5737fce..28b7804 100644 (file)
@@ -26,6 +26,7 @@
 #include <glib.h>
 
 #include <libtelepathy/tp-chan.h>
+#include <libtelepathy/tp-constants.h>
 
 #include <libmissioncontrol/mc-account.h>
 
@@ -54,24 +55,16 @@ struct _EmpathyTpChatClass {
        GObjectClass parent_class;
 };
 
-typedef enum {
-    EMPATHY_TP_CHAT_STATE_GONE,
-    EMPATHY_TP_CHAT_STATE_INACTIVE,
-    EMPATHY_TP_CHAT_STATE_ACTIVE,
-    EMPATHY_TP_CHAT_STATE_PAUSED,
-    EMPATHY_TP_CHAT_STATE_COMPOSING
-} EmpathyTpChatState;
-
 GType          empathy_tp_chat_get_type         (void) G_GNUC_CONST;
-EmpathyTpChat *empathy_tp_chat_new              (McAccount          *account,
-                                                TpChan             *tp_chan);
-EmpathyTpChat *empathy_tp_chat_new_with_contact (GossipContact      *contact);
-void           empathy_tp_chat_request_pending  (EmpathyTpChat      *chat);
-void           empathy_tp_chat_send             (EmpathyTpChat      *chat,
-                                                GossipMessage      *message);
-void           empathy_tp_chat_send_state       (EmpathyTpChat      *chat,
-                                                EmpathyTpChatState  state);
-const gchar *  empathy_tp_chat_get_id           (EmpathyTpChat      *chat);
+EmpathyTpChat *empathy_tp_chat_new              (McAccount                 *account,
+                                                TpChan                    *tp_chan);
+EmpathyTpChat *empathy_tp_chat_new_with_contact (GossipContact             *contact);
+void           empathy_tp_chat_request_pending  (EmpathyTpChat             *chat);
+void           empathy_tp_chat_send             (EmpathyTpChat             *chat,
+                                                GossipMessage             *message);
+void           empathy_tp_chat_set_state        (EmpathyTpChat             *chat,
+                                                TelepathyChannelChatState  state);
+const gchar *  empathy_tp_chat_get_id           (EmpathyTpChat             *chat);
 
 G_END_DECLS
 
index 86ffade..2eb2d02 100644 (file)
@@ -1,33 +1,28 @@
-cflags = $(EMPATHY_CFLAGS)                                     \
-        $(WARN_CFLAGS)
-
-libs = $(top_builddir)/libempathy/libempathy.la                \
+AM_CPPFLAGS =                                                  \
+       -I.                                                     \
+       -I$(top_srcdir)                                         \
+       $(EMPATHY_CFLAGS)                                       \
+       $(WARN_CFLAGS)
+
+AM_LDFLAGS =                                                   \
+       $(top_builddir)/libempathy/libempathy.la                \
        $(top_builddir)/libempathy-gtk/libempathy-gtk.la        \
        $(EMPATHY_LIBS)
 
 bin_PROGRAMS = empathy empathy-accounts empathy-chat empathy-contact-list
 
-empathy_SOURCES = empathy-main.c
-empathy_CPPFLAGS = $(cflags)
-empathy_LDFLAGS = $(libs)
-
+empathy_SOURCES =                                              \
+       empathy-main.c                                          \
+       empathy-filter.c        empathy-filter.h
 empathy_accounts_SOURCES = empathy-accounts-main.c
-empathy_accounts_CPPFLAGS = $(cflags)
-empathy_accounts_LDFLAGS = $(libs)
-
 empathy_chat_SOURCES = empathy-chat-main.c
-empathy_chat_CPPFLAGS = $(cflags)
-empathy_chat_LDFLAGS = $(libs)
-
 empathy_contact_list_SOURCES = empathy-contact-list-main.c
-empathy_contact_list_CPPFLAGS = $(cflags)
-empathy_contact_list_LDFLAGS = $(libs)
 
 # MC plugin
-pluginlib_LTLIBRARIES = libempathy-filter-plugin.la
-libempathy_filter_plugin_la_SOURCES = empathy-filter-plugin.c
-libempathy_filter_plugin_la_CPPFLAGS = $(MISSION_CONTROL_PLUGINS_CFLAGS)
-libempathy_filter_plugin_la_LDFLAGS = $(MISSION_CONTROL_PLUGINS_LIBS)
+#pluginlib_LTLIBRARIES = libempathy-filter-plugin.la
+#libempathy_filter_plugin_la_SOURCES = empathy-filter-plugin.c
+#libempathy_filter_plugin_la_CPPFLAGS = $(MISSION_CONTROL_PLUGINS_CFLAGS)
+#libempathy_filter_plugin_la_LDFLAGS = $(MISSION_CONTROL_PLUGINS_LIBS)
 
 # Dbus service file
 servicedir = $(datadir)/dbus-1/services
@@ -46,11 +41,20 @@ autostart_in_files = empathy.desktop.in
 autostart_DATA = $(autostart_in_files:.desktop.in=.desktop)
 @INTLTOOL_DESKTOP_RULE@
 
+# Empathy filter DBus API
+empathy-filter-glue.h: empathy-filter.xml
+       $(LIBTOOL) --mode=execute $(DBUS_BINDING_TOOL) --prefix=empathy_filter --mode=glib-server --output=$@ $<
+empathy-filter-gen.h: empathy-filter.xml
+       $(LIBTOOL) --mode=execute $(DBUS_BINDING_TOOL) --prefix=empathy_filter --mode=glib-client --output=$@ $<
+
 BUILT_SOURCES =                                                        \
-       org.gnome.Empathy.Chat.service
+       org.gnome.Empathy.Chat.service                          \
+       empathy-filter-glue.h                                   \
+       empathy-filter-gen.h
 
 EXTRA_DIST =                                                   \
        org.gnome.Empathy.Chat.service.in                       \
+       empathy-filter.xml                                      \
        $(autostart_DATA)                                       \
        $(chandler_DATA)
 
index dfd7491..ee90d97 100644 (file)
 
 #include <glib.h>
 
-#include <mcd-dispatcher.h>
-#include <mcd-dispatcher-context.h>
+#include <dbus/dbus-glib.h>
 
-static void filter_plugin_text_channel (McdDispatcherContext *ctx);
+#include <libtelepathy/tp-helpers.h>
+#include <libtelepathy/tp-conn.h>
+
+#include <mission-control/mcd-dispatcher.h>
+#include <mission-control/mcd-dispatcher-context.h>
+#include <mission-control/mcd-channel.h>
+
+#include <libempathy/empathy-marshal-main.c>
+
+#include "empathy-filter-gen.h"
+
+static void filter_plugin_text_channel      (McdDispatcherContext *ctx);
+static void filter_plugin_handle_channel_cb (DBusGProxy           *proxy,
+                                            GError               *error,
+                                            McdDispatcherContext *ctx);
+static void filter_plugin_process_cb        (DBusGProxy           *filter,
+                                            guint                 context_handle,
+                                            gboolean              result,
+                                            McdDispatcher        *dispatcher);
 
 static McdFilter text_in_filters[] = {
-    {filter_plugin_text_channel, MCD_FILTER_PRIORITY_USER},
-    {NULL, 0}
+       {filter_plugin_text_channel, MCD_FILTER_PRIORITY_USER},
+       {NULL, 0}
 };
 
+static DBusGProxy *filter = NULL;
+static GHashTable *contexts = NULL;
+static guint n_contexts = 0;
+
 void
 mcd_filters_init (McdDispatcher *dispatcher)
 {
+       static gboolean initialized = FALSE;
+
+       if (initialized) {
+               return;
+       }
+
+       filter = dbus_g_proxy_new_for_name (tp_get_bus (),
+                                           "org.gnome.Empathy.Filter",
+                                           "/org/gnome/Empathy/Filter",
+                                           "org.gnome.Empathy.Filter");
+
+       dbus_g_object_register_marshaller (
+               empathy_marshal_VOID__UINT_BOOLEAN,
+               G_TYPE_NONE,
+               G_TYPE_UINT,
+               G_TYPE_BOOLEAN,
+               G_TYPE_INVALID);
+
+       dbus_g_proxy_add_signal (filter, "Process",
+                                G_TYPE_UINT,
+                                G_TYPE_BOOLEAN,
+                                G_TYPE_INVALID);
+       dbus_g_proxy_connect_signal (filter, "Process",
+                                    G_CALLBACK (filter_plugin_process_cb),
+                                    dispatcher,
+                                    NULL);
+       contexts = g_hash_table_new_full (g_direct_hash,
+                                         g_direct_equal,
+                                         NULL,
+                                         (GDestroyNotify) g_object_unref);
+
        mcd_dispatcher_register_filters (dispatcher,
                                         text_in_filters,
                                         TELEPATHY_CHAN_IFACE_TEXT_QUARK,
                                         MCD_FILTER_IN);
+
+       initialized = TRUE;
 }
 
 static void
 filter_plugin_text_channel (McdDispatcherContext *ctx)
 {
-       McdChannel  *channel;
-       const gchar *channel_name;
+       const TpConn *tp_conn;
+       McdChannel   *channel;
 
+       tp_conn = mcd_dispatcher_context_get_connection_object (ctx);
        channel = mcd_dispatcher_context_get_channel (ctx);
-       channel_name = mcd_channel_get_name (channel);
 
-       if (strcmp (channel_name, "goerge.w.bush@whitehouse.com") == 0) {
-               g_debug ("Blocking contact");
-               mcd_dispatcher_context_process (ctx, FALSE);
-               return;
-       }
+       n_contexts++;
+       g_hash_table_insert (contexts,
+                            GUINT_TO_POINTER (n_contexts),
+                            ctx);
+
+       empathy_filter_handle_channel_async (filter,
+                                            dbus_g_proxy_get_bus_name (DBUS_G_PROXY (tp_conn)),
+                                            dbus_g_proxy_get_path (DBUS_G_PROXY (tp_conn)),
+                                            mcd_channel_get_channel_type (channel),
+                                            mcd_channel_get_object_path (channel),
+                                            mcd_channel_get_handle_type (channel),
+                                            mcd_channel_get_handle (channel),
+                                            n_contexts,
+                                            (empathy_filter_handle_channel_reply) filter_plugin_handle_channel_cb,
+                                            ctx);
+}
+
+static void
+filter_plugin_handle_channel_cb (DBusGProxy           *proxy,
+                                GError               *error,
+                                McdDispatcherContext *ctx)
+{
+}
+
+static void
+filter_plugin_process_cb (DBusGProxy    *filter,
+                         guint          context_handle,
+                         gboolean       result,
+                         McdDispatcher *dispatcher)
+{
+       McdDispatcherContext *ctx;
 
-       mcd_dispatcher_context_process (ctx, TRUE);
+       g_print ("****processing\n");
+       ctx = g_hash_table_lookup (contexts, GUINT_TO_POINTER (context_handle));
+       mcd_dispatcher_context_process (ctx, result);
 }
 
diff --git a/src/empathy-filter.c b/src/empathy-filter.c
new file mode 100644 (file)
index 0000000..3696cc1
--- /dev/null
@@ -0,0 +1,173 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2007 Collabora Ltd.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program 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
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ * 
+ * Authors: Xavier Claessens <xclaesse@gmail.com>
+ */
+
+#include <config.h>
+
+#include <dbus/dbus-glib.h>
+
+#include <libtelepathy/tp-helpers.h>
+#include <libtelepathy/tp-conn.h>
+#include <libtelepathy/tp-chan.h>
+
+#include <libempathy/gossip-debug.h>
+#include <libempathy/empathy-marshal.h>
+
+#include "empathy-filter.h"
+
+#define DEBUG_DOMAIN "EmpathyFilter"
+
+static gboolean empathy_filter_handle_channel (EmpathyFilter  *filter,
+                                              const gchar    *bus_name,
+                                              const gchar    *connection,
+                                              const gchar    *channel_type,
+                                              const gchar    *channel,
+                                              guint           handle_type,
+                                              guint           handle,
+                                              guint           context_handle,
+                                              GError        **error);
+
+#include "empathy-filter-glue.h"
+
+enum {
+       NEW_CHANNEL,
+       PROCESS,
+       LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL];
+
+G_DEFINE_TYPE (EmpathyFilter, empathy_filter, G_TYPE_OBJECT)
+
+static void
+empathy_filter_class_init (EmpathyFilterClass *klass)
+{
+       signals[NEW_CHANNEL] =
+               g_signal_new ("new-channel",
+                             G_OBJECT_CLASS_TYPE (klass),
+                             G_SIGNAL_RUN_LAST,
+                             0,
+                             NULL, NULL,
+                             empathy_marshal_VOID__OBJECT_OBJECT_UINT,
+                             G_TYPE_NONE,
+                             3, TELEPATHY_CONN_TYPE, TELEPATHY_CHAN_TYPE, G_TYPE_UINT);
+
+       signals[PROCESS] =
+               g_signal_new ("process",
+                             G_OBJECT_CLASS_TYPE (klass),
+                             G_SIGNAL_RUN_LAST,
+                             0,
+                             NULL, NULL,
+                             empathy_marshal_VOID__UINT_BOOLEAN,
+                             G_TYPE_NONE,
+                             2, G_TYPE_UINT, G_TYPE_BOOLEAN);
+}
+
+static void
+empathy_filter_init (EmpathyFilter *filter)
+{
+}
+
+EmpathyFilter *
+empathy_filter_new (void)
+{
+       static gboolean  initialized = FALSE;
+       EmpathyFilter   *filter;
+       DBusGProxy      *proxy;
+       guint            result;
+       GError          *error = NULL;
+
+       if (!initialized) {
+               dbus_g_object_type_install_info (EMPATHY_TYPE_FILTER,
+                                                &dbus_glib_empathy_filter_object_info);
+               initialized = TRUE;
+       }
+
+       proxy = dbus_g_proxy_new_for_name (tp_get_bus (),
+                                          DBUS_SERVICE_DBUS,
+                                          DBUS_PATH_DBUS,
+                                          DBUS_INTERFACE_DBUS);
+
+       if (!dbus_g_proxy_call (proxy, "RequestName", &error,
+                               G_TYPE_STRING, "org.gnome.Empathy.Filter",
+                               G_TYPE_UINT, DBUS_NAME_FLAG_DO_NOT_QUEUE,
+                               G_TYPE_INVALID,
+                               G_TYPE_UINT, &result,
+                               G_TYPE_INVALID)) {
+               gossip_debug (DEBUG_DOMAIN,
+                             "Failed to request name: %s",
+                             error ? error->message : "No error given");
+               g_clear_error (&error);
+
+               return NULL;
+       }
+       g_object_unref (proxy);
+
+       filter = g_object_new (EMPATHY_TYPE_FILTER, NULL);
+       dbus_g_connection_register_g_object (tp_get_bus (),
+                                            "/org/gnome/Empathy/Filter",
+                                            G_OBJECT (filter));
+
+       return filter;
+}
+
+void
+empathy_filter_process (EmpathyFilter *filter,
+                       guint          context_handle,
+                       gboolean       result)
+{
+       g_print ("hello\n");
+       g_signal_emit (filter, signals[PROCESS], 0, context_handle, result);
+}
+
+static gboolean
+empathy_filter_handle_channel (EmpathyFilter  *filter,
+                                const gchar  *bus_name,
+                                const gchar  *connection,
+                                const gchar  *channel_type,
+                                const gchar  *channel,
+                                guint         handle_type,
+                                guint         handle,
+                                guint         context_handle,
+                                GError      **error)
+{
+       TpChan *tp_chan;
+       TpConn *tp_conn;
+
+       tp_conn = tp_conn_new (tp_get_bus (),
+                              bus_name,
+                              connection);
+
+       tp_chan = tp_chan_new (tp_get_bus(),
+                              bus_name,
+                              channel,
+                              channel_type,
+                              handle_type,
+                              handle);
+g_print ("new channel\n");
+       g_signal_emit (filter, signals[NEW_CHANNEL], 0, tp_conn, tp_chan, context_handle);
+
+       g_object_unref (tp_chan);
+       g_object_unref (tp_conn);
+
+       return TRUE;
+}
+
diff --git a/src/empathy-filter.h b/src/empathy-filter.h
new file mode 100644 (file)
index 0000000..071310b
--- /dev/null
@@ -0,0 +1,56 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2007 Collabora Ltd.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program 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
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Authors: Xavier Claessens <xclaesse@gmail.com>
+ */
+
+#ifndef __EMPATHY_FILTER_H__
+#define __EMPATHY_FILTER_H__
+
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+#define EMPATHY_TYPE_FILTER         (empathy_filter_get_type ())
+#define EMPATHY_FILTER(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), EMPATHY_TYPE_FILTER, EmpathyFilter))
+#define EMPATHY_FILTER_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST ((k), EMPATHY_TYPE_FILTER, EmpathyFilterClass))
+#define EMPATHY_IS_FILTER(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), EMPATHY_TYPE_FILTER))
+#define EMPATHY_IS_FILTER_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), EMPATHY_TYPE_FILTER))
+#define EMPATHY_FILTER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), EMPATHY_TYPE_FILTER, EmpathyFilterClass))
+
+typedef struct _EmpathyFilter      EmpathyFilter;
+typedef struct _EmpathyFilterClass EmpathyFilterClass;
+
+struct _EmpathyFilter {
+       GObject parent;
+};
+
+struct _EmpathyFilterClass {
+       GObjectClass parent_class;
+};
+
+GType          empathy_filter_get_type (void) G_GNUC_CONST;
+EmpathyFilter *empathy_filter_new      (void);
+void           empathy_filter_process  (EmpathyFilter *filter,
+                                       guint          context_handle,
+                                       gboolean       result);
+
+G_END_DECLS
+
+#endif /* __EMPATHY_FILTER_H__ */
diff --git a/src/empathy-filter.xml b/src/empathy-filter.xml
new file mode 100644 (file)
index 0000000..e6b8dae
--- /dev/null
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<node name="/Filter">
+  <interface name="org.gnome.Empathy.Filter">
+    <annotation name="org.freedesktop.DBus.GLib.ClientCSymbol" value="empathy_filter"/>
+    <method name="HandleChannel">
+      <arg direction="in" type="s" name="bus_name" />
+      <arg direction="in" type="o" name="connection" />
+      <arg direction="in" type="s" name="channel_type" />
+      <arg direction="in" type="o" name="channel" />
+      <arg direction="in" type="u" name="handle_type" />
+      <arg direction="in" type="u" name="handle" />
+      <arg direction="in" type="u" name="context_handle" />
+    </method>
+    <signal name="Process">
+      <arg type="u" name="context_handle" />
+      <arg type="u" name="result" />
+    </signal>
+  </interface>
+</node>
index fb5684a..afa1e11 100644 (file)
@@ -39,6 +39,8 @@
 #include <libempathy-gtk/gossip-status-presets.h>
 #include <libempathy-gtk/gossip-accounts-dialog.h>
 
+#include "empathy-filter.h"
+
 #define DEBUG_DOMAIN "Empathy"
 
 static void error_cb              (MissionControl *mc,
@@ -118,6 +120,18 @@ icon_activate_cb (GtkStatusIcon *status_icon,
        }
 }
 
+static void
+new_channel_cb (EmpathyFilter *filter,
+               TpConn        *tp_conn,
+               TpChan        *tp_chan,
+               guint          context_handle,
+               gpointer       user_data)
+{
+       gossip_debug (DEBUG_DOMAIN, "Filtering context handle: %d",
+                     context_handle);
+       empathy_filter_process (filter, context_handle, TRUE);
+}
+
 int
 main (int argc, char *argv[])
 {
@@ -126,9 +140,16 @@ main (int argc, char *argv[])
        GtkWidget        *window;
        MissionControl   *mc;
        McAccountMonitor *monitor;
+       EmpathyFilter    *filter;
 
        gtk_init (&argc, &argv);
 
+       /* Setting up channel filter */
+       filter = empathy_filter_new ();
+       g_signal_connect (filter, "new-channel",
+                         G_CALLBACK (new_channel_cb),
+                         NULL);
+
        /* Setting up MC */
        monitor = mc_account_monitor_new ();
        mc = mission_control_new (tp_get_bus ());