]> git.0d.be Git - empathy.git/commitdiff
Drop Chandler and Filter, do not use MC for dispatching channels, do it ourself.
authorXavier Claessens <xclaesse@src.gnome.org>
Sat, 19 Apr 2008 18:36:22 +0000 (18:36 +0000)
committerXavier Claessens <xclaesse@src.gnome.org>
Sat, 19 Apr 2008 18:36:22 +0000 (18:36 +0000)
svn path=/trunk/; revision=967

22 files changed:
docs/libempathy/libempathy-docs.sgml
docs/libempathy/libempathy.types
extensions/Chandler.xml [deleted file]
extensions/Filter.xml [deleted file]
extensions/Makefile.am
extensions/misc.xml
libempathy/Makefile.am
libempathy/empathy-chandler.c [deleted file]
libempathy/empathy-chandler.h [deleted file]
libempathy/empathy-filter.c [deleted file]
libempathy/empathy-filter.h [deleted file]
libempathy/empathy-utils.c
src/Makefile.am
src/empathy-call-chandler.c [deleted file]
src/empathy-call.chandler [deleted file]
src/empathy-chat.chandler [deleted file]
src/empathy-filter.c [new file with mode: 0644]
src/empathy-filter.h [new file with mode: 0644]
src/empathy-status-icon.c
src/empathy.c
src/org.gnome.Empathy.Call.service.in [deleted file]
src/org.gnome.Empathy.Chat.service.in [deleted file]

index 9a434682d143c0ae668c75898ed59ee2788c0916..0bdc4999bd56fb24f367a9049efd9b5d4a9ab463 100644 (file)
@@ -26,7 +26,6 @@
       <xi:include href="xml/empathy-contact-manager.xml"/>
       <xi:include href="xml/empathy-contact.xml"/>
       <xi:include href="xml/empathy-enum-types.xml"/>
-      <xi:include href="xml/empathy-filter.xml"/>
       <xi:include href="xml/empathy-idle.xml"/>
       <xi:include href="xml/empathy-irc-server.xml"/>
       <xi:include href="xml/empathy-irc-network.xml"/>
index 5bb32666b1c86b5ea9e9bdc358cf06a8fc8d26d3..27e7223b8de0647c464ff946255344d01a8b6386 100644 (file)
@@ -3,7 +3,6 @@ empathy_contact_manager_get_type
 empathy_reg_ex_type_get_type
 empathy_message_type_get_type
 empathy_capabilities_get_type
-empathy_filter_get_type
 empathy_idle_get_type
 empathy_log_manager_get_type
 empathy_message_get_gtype
diff --git a/extensions/Chandler.xml b/extensions/Chandler.xml
deleted file mode 100644 (file)
index e26932e..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<node name="/Chandler">
-  <interface name="org.freedesktop.Telepathy.ChannelHandler">
-    <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" />
-    </method>
-  </interface>
-</node>
diff --git a/extensions/Filter.xml b/extensions/Filter.xml
deleted file mode 100644 (file)
index e6ef814..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<node name="/Filter">
-  <interface name="org.freedesktop.Telepathy.MissionControl.Filter">
-    <method name="FilterChannel">
-      <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="id" />
-    </method>
-    <signal name="Process">
-      <arg type="u" name="id"/>
-      <arg type="b" name="process"/>
-    </signal>
-  </interface>
-</node>
index e065d43652436246d46bc0a5457d97cd6e2eb19f..1e765b88838700762f489247965dccadb341646c 100644 (file)
@@ -10,9 +10,7 @@ EXTRA_DIST = \
     all.xml \
     misc.xml \
     Channel_Handler.xml \
-    Stream_Engine.xml \
-    Chandler.xml \
-    Filter.xml
+    Stream_Engine.xml
 
 noinst_LTLIBRARIES = libemp-extensions.la
 
index e3d909bb4dc2285a1cc2e149d37e0512851d5364..2bca333bf22de9833b39a86ef4739d623ec0fc2c 100644 (file)
@@ -6,7 +6,5 @@
 
 <xi:include href="Stream_Engine.xml"/>
 <xi:include href="Channel_Handler.xml"/>
-<xi:include href="Chandler.xml"/>
-<xi:include href="Filter.xml"/>
 
 </tp:spec>
index 19873bee11f403ca5607cf1c2ad88b4c889e3526..e18088cf175c598c101d63b174406adc613bdfc8 100644 (file)
@@ -35,8 +35,6 @@ libempathy_la_SOURCES =                                       \
        empathy-tp-chat.c                               \
        empathy-tp-roomlist.c                           \
        empathy-tp-call.c                               \
-       empathy-chandler.c                              \
-       empathy-filter.c                                \
        empathy-idle.c                                  \
        empathy-log-manager.c                           \
        empathy-irc-network-manager.c                   \
@@ -75,8 +73,6 @@ libempathy_headers =                          \
        empathy-tp-chat.h                       \
        empathy-tp-roomlist.h                   \
        empathy-tp-call.h                       \
-       empathy-chandler.h                      \
-       empathy-filter.h                        \
        empathy-idle.h                          \
        empathy-log-manager.h                   \
        empathy-irc-network-manager.h           \
diff --git a/libempathy/empathy-chandler.c b/libempathy/empathy-chandler.c
deleted file mode 100644 (file)
index 2fdb372..0000000
+++ /dev/null
@@ -1,183 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * Copyright (C) 2007-2008 Collabora Ltd.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Authors: Xavier Claessens <xclaesse@gmail.com>
- */
-
-#include <config.h>
-
-#include <telepathy-glib/dbus.h>
-#include <telepathy-glib/connection.h>
-#include <telepathy-glib/channel.h>
-
-#include <extensions/extensions.h>
-#include "empathy-chandler.h"
-#include "empathy-debug.h"
-
-#define DEBUG_DOMAIN "EmpathyChandler"
-
-static void chandler_iface_init (EmpSvcChandlerClass *klass);
-
-enum {
-       NEW_CHANNEL,
-       LAST_SIGNAL
-};
-
-static guint signals[LAST_SIGNAL];
-
-G_DEFINE_TYPE_WITH_CODE (EmpathyChandler, empathy_chandler, G_TYPE_OBJECT,
-                        G_IMPLEMENT_INTERFACE (EMP_TYPE_SVC_CHANDLER,
-                                               chandler_iface_init));
-
-typedef struct {
-       EmpathyChandler *chandler;
-       gchar           *bus_name;
-       gchar           *connection;
-       gchar           *channel_type;
-       gchar           *channel;
-       guint            handle_type;
-       guint            handle;
-} IdleData;
-
-static gboolean
-handle_channel_idle_cb (gpointer data)
-{
-       IdleData            *idle_data = data;
-       TpChannel           *chan;
-       TpConnection        *conn;
-       static TpDBusDaemon *daemon = NULL;
-
-       if (!daemon) {
-               daemon = tp_dbus_daemon_new (tp_get_bus ());
-       }
-
-       conn = tp_connection_new (daemon, idle_data->bus_name,
-                                 idle_data->connection, NULL);
-       chan = tp_channel_new (conn, idle_data->channel, idle_data->channel_type,
-                              idle_data->handle_type, idle_data->handle, NULL);
-       tp_channel_run_until_ready (chan, NULL, NULL);
-
-       empathy_debug (DEBUG_DOMAIN, "New channel to be handled: "
-                                    "type=%s handle=%d",
-                                    idle_data->channel_type, idle_data->handle);
-       g_signal_emit (idle_data->chandler, signals[NEW_CHANNEL], 0, chan);
-
-       g_object_unref (chan);
-       g_object_unref (conn);
-       g_free (idle_data->bus_name);
-       g_free (idle_data->connection);
-       g_free (idle_data->channel_type);
-       g_free (idle_data->channel);
-       g_slice_free (IdleData, idle_data);
-
-       return FALSE;
-}
-
-static void
-my_handle_channel (EmpSvcChandler        *self,
-                  const gchar           *bus_name,
-                  const gchar           *connection,
-                  const gchar           *channel_type,
-                  const gchar           *channel,
-                  guint                  handle_type,
-                  guint                  handle,
-                  DBusGMethodInvocation *context)
-{
-       EmpathyChandler *chandler = EMPATHY_CHANDLER (self);
-       IdleData        *data;
-
-       data = g_slice_new (IdleData);
-       data->chandler = chandler;
-       data->bus_name = g_strdup (bus_name);
-       data->connection = g_strdup (connection);
-       data->channel_type = g_strdup (channel_type);
-       data->channel = g_strdup (channel);
-       data->handle_type = handle_type;
-       data->handle = handle;
-       g_idle_add_full (G_PRIORITY_HIGH,
-                        handle_channel_idle_cb,
-                        data, NULL);
-
-       emp_svc_chandler_return_from_handle_channel (context);
-}
-
-static void
-empathy_chandler_class_init (EmpathyChandlerClass *klass)
-{
-       signals[NEW_CHANNEL] =
-               g_signal_new ("new-channel",
-                             G_OBJECT_CLASS_TYPE (klass),
-                             G_SIGNAL_RUN_LAST,
-                             0,
-                             NULL, NULL,
-                             g_cclosure_marshal_VOID__OBJECT,
-                             G_TYPE_NONE,
-                             1, TP_TYPE_CHANNEL);
-}
-
-static void
-chandler_iface_init (EmpSvcChandlerClass *klass)
-{
-#define IMPLEMENT(x) emp_svc_chandler_implement_##x \
-    (klass, my_##x)
-  IMPLEMENT (handle_channel);
-#undef IMPLEMENT
-}
-
-static void
-empathy_chandler_init (EmpathyChandler *chandler)
-{
-}
-
-EmpathyChandler *
-empathy_chandler_new (const gchar *bus_name,
-                     const gchar *object_path)
-{
-       EmpathyChandler *chandler;
-       DBusGProxy      *proxy;
-       guint            result;
-       GError          *error = NULL;
-
-       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, bus_name,
-                               G_TYPE_UINT, DBUS_NAME_FLAG_DO_NOT_QUEUE,
-                               G_TYPE_INVALID,
-                               G_TYPE_UINT, &result,
-                               G_TYPE_INVALID)) {
-               empathy_debug (DEBUG_DOMAIN,
-                             "Failed to request name: %s",
-                             error ? error->message : "No error given");
-               g_clear_error (&error);
-
-               return NULL;
-       }
-       g_object_unref (proxy);
-
-       chandler = g_object_new (EMPATHY_TYPE_CHANDLER, NULL);
-       dbus_g_connection_register_g_object (tp_get_bus (),
-                                            object_path,
-                                            G_OBJECT (chandler));
-
-       return chandler;
-}
-
diff --git a/libempathy/empathy-chandler.h b/libempathy/empathy-chandler.h
deleted file mode 100644 (file)
index 6835dda..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * Copyright (C) 2007-2008 Collabora Ltd.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- * Authors: Xavier Claessens <xclaesse@gmail.com>
- */
-
-#ifndef __EMPATHY_CHANDLER_H__
-#define __EMPATHY_CHANDLER_H__
-
-#include <glib.h>
-
-G_BEGIN_DECLS
-
-#define EMPATHY_TYPE_CHANDLER         (empathy_chandler_get_type ())
-#define EMPATHY_CHANDLER(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), EMPATHY_TYPE_CHANDLER, EmpathyChandler))
-#define EMPATHY_CHANDLER_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST ((k), EMPATHY_TYPE_CHANDLER, EmpathyChandlerClass))
-#define EMPATHY_IS_CHANDLER(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), EMPATHY_TYPE_CHANDLER))
-#define EMPATHY_IS_CHANDLER_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), EMPATHY_TYPE_CHANDLER))
-#define EMPATHY_CHANDLER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), EMPATHY_TYPE_CHANDLER, EmpathyChandlerClass))
-
-typedef struct _EmpathyChandler      EmpathyChandler;
-typedef struct _EmpathyChandlerClass EmpathyChandlerClass;
-
-struct _EmpathyChandler {
-       GObject parent;
-};
-
-struct _EmpathyChandlerClass {
-       GObjectClass parent_class;
-};
-
-GType            empathy_chandler_get_type (void) G_GNUC_CONST;
-EmpathyChandler *empathy_chandler_new      (const gchar *bus_name,
-                                           const gchar *object_path);
-
-G_END_DECLS
-
-#endif /* __EMPATHY_CHANDLER_H__ */
diff --git a/libempathy/empathy-filter.c b/libempathy/empathy-filter.c
deleted file mode 100644 (file)
index 08f9ee6..0000000
+++ /dev/null
@@ -1,262 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * Copyright (C) 2007-2008 Collabora Ltd.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Authors: Xavier Claessens <xclaesse@gmail.com>
- */
-
-#include <config.h>
-
-#include <telepathy-glib/dbus.h>
-#include <telepathy-glib/connection.h>
-
-#include <extensions/extensions.h>
-#include "empathy-filter.h"
-#include "empathy-debug.h"
-#include "empathy-utils.h"
-
-#define GET_PRIV(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
-                      EMPATHY_TYPE_FILTER, EmpathyFilterPriv))
-
-#define DEBUG_DOMAIN "EmpathyFilter"
-
-struct _EmpathyFilterPriv {
-       GHashTable *table;
-};
-
-static void empathy_filter_class_init (EmpathyFilterClass *klass);
-static void empathy_filter_init       (EmpathyFilter      *filter);
-static void filter_iface_init         (EmpSvcFilterClass  *klass);
-
-enum {
-       NEW_CHANNEL,
-       LAST_SIGNAL
-};
-
-static guint signals[LAST_SIGNAL];
-
-G_DEFINE_TYPE_WITH_CODE (EmpathyFilter, empathy_filter, G_TYPE_OBJECT,
-                        G_IMPLEMENT_INTERFACE (EMP_TYPE_SVC_FILTER,
-                                               filter_iface_init));
-
-typedef struct {
-       EmpathyFilter *filter;
-       gchar         *bus_name;
-       gchar         *connection;
-       gchar         *channel_type;
-       gchar         *channel;
-       guint          handle_type;
-       guint          handle;
-       guint          id;
-} IdleData;
-
-static gboolean
-filter_channel_idle_cb (gpointer data)
-{
-       IdleData            *idle_data = data;
-       EmpathyFilterPriv   *priv = GET_PRIV (idle_data->filter);
-       TpChannel           *chan;
-       TpConnection        *conn;
-       static TpDBusDaemon *daemon = NULL;
-
-       if (!daemon) {
-               daemon = tp_dbus_daemon_new (tp_get_bus ());
-       }
-
-       conn = tp_connection_new (daemon, idle_data->bus_name,
-                                 idle_data->connection, NULL);
-       tp_connection_run_until_ready (conn, FALSE, NULL, NULL);
-       chan = tp_channel_new (conn, idle_data->channel, idle_data->channel_type,
-                              idle_data->handle_type, idle_data->handle, NULL);
-       tp_channel_run_until_ready (chan, NULL, NULL);
-
-       g_hash_table_insert (priv->table, chan, GUINT_TO_POINTER (idle_data->id));
-
-       empathy_debug (DEBUG_DOMAIN, "New channel to be filtred: "
-                                    "type=%s handle=%d id=%d",
-                                    idle_data->channel_type, idle_data->handle,
-                                    idle_data->id);
-
-       g_signal_emit (idle_data->filter, signals[NEW_CHANNEL], 0, chan);
-
-       g_object_unref (conn);
-       g_free (idle_data->bus_name);
-       g_free (idle_data->connection);
-       g_free (idle_data->channel_type);
-       g_free (idle_data->channel);
-       g_slice_free (IdleData, idle_data);
-
-       return FALSE;
-}
-
-static void
-my_filter_channel (EmpSvcFilter          *self,
-                  const gchar           *bus_name,
-                  const gchar           *connection,
-                  const gchar           *channel_type,
-                  const gchar           *channel,
-                  guint                  handle_type,
-                  guint                  handle,
-                  guint                  id,
-                  DBusGMethodInvocation *context)
-{
-       EmpathyFilter *filter = EMPATHY_FILTER (self);
-       IdleData      *data;
-
-       data = g_slice_new (IdleData);
-       data->filter = filter;
-       data->bus_name = g_strdup (bus_name);
-       data->connection = g_strdup (connection);
-       data->channel_type = g_strdup (channel_type);
-       data->channel = g_strdup (channel);
-       data->handle_type = handle_type;
-       data->handle = handle;
-       data->id = id;
-       g_idle_add_full (G_PRIORITY_HIGH,
-                        filter_channel_idle_cb,
-                        data, NULL);
-
-       emp_svc_filter_return_from_filter_channel (context);
-}
-
-static void
-filter_finalize (GObject *object)
-{
-       EmpathyFilterPriv *priv;
-
-       priv = GET_PRIV (object);
-
-       g_hash_table_destroy (priv->table);
-}
-
-static void
-empathy_filter_class_init (EmpathyFilterClass *klass)
-{
-       GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
-       object_class->finalize = filter_finalize;
-
-       signals[NEW_CHANNEL] =
-               g_signal_new ("new-channel",
-                             G_OBJECT_CLASS_TYPE (klass),
-                             G_SIGNAL_RUN_LAST,
-                             0,
-                             NULL, NULL,
-                             g_cclosure_marshal_VOID__OBJECT,
-                             G_TYPE_NONE,
-                             1, TP_TYPE_CHANNEL);
-
-       g_type_class_add_private (object_class, sizeof (EmpathyFilterPriv));
-}
-
-static void
-filter_iface_init (EmpSvcFilterClass *klass)
-{
-#define IMPLEMENT(x) emp_svc_filter_implement_##x \
-    (klass, my_##x)
-  IMPLEMENT (filter_channel);
-#undef IMPLEMENT
-}
-
-static void
-empathy_filter_init (EmpathyFilter *filter)
-{
-       EmpathyFilterPriv *priv;
-
-       priv = GET_PRIV (filter);
-
-       priv->table = g_hash_table_new_full (g_direct_hash, g_direct_equal,
-                                            (GDestroyNotify) g_object_unref,
-                                            NULL);
-}
-
-EmpathyFilter *
-empathy_filter_new (const gchar *bus_name,
-                   const gchar *object_path,
-                   const gchar *channel_type,
-                   guint        priority,
-                   guint        flags)
-{
-       MissionControl  *mc;
-       EmpathyFilter   *filter;
-       DBusGProxy      *proxy;
-       guint            result;
-       GError          *error = NULL;
-
-       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, bus_name,
-                               G_TYPE_UINT, DBUS_NAME_FLAG_DO_NOT_QUEUE,
-                               G_TYPE_INVALID,
-                               G_TYPE_UINT, &result,
-                               G_TYPE_INVALID)) {
-               empathy_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 (),
-                                            object_path,
-                                            G_OBJECT (filter));
-
-       mc = empathy_mission_control_new ();
-
-       mission_control_register_filter (mc,
-                                        bus_name,
-                                        object_path,
-                                        channel_type,
-                                        priority,
-                                        flags,
-                                        NULL);
-       g_object_unref (mc);
-
-       return filter;
-}
-
-void
-empathy_filter_process (EmpathyFilter *filter,
-                       TpChannel     *channel,
-                       gboolean       process)
-{
-       EmpathyFilterPriv *priv;
-       guint              id;
-
-       g_return_if_fail (EMPATHY_IS_FILTER (filter));
-       g_return_if_fail (TP_IS_CHANNEL (channel));
-
-       priv = GET_PRIV (filter);
-
-       id = GPOINTER_TO_UINT (g_hash_table_lookup (priv->table, channel));
-       g_return_if_fail (id != 0);
-
-       empathy_debug (DEBUG_DOMAIN, "Processing channel id %d: %s",
-                      id, process ? "Yes" : "No");
-
-       emp_svc_filter_emit_process (filter, id, process);
-
-       g_hash_table_remove (priv->table, channel);
-}
-
diff --git a/libempathy/empathy-filter.h b/libempathy/empathy-filter.h
deleted file mode 100644 (file)
index 3e383ce..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * Copyright (C) 2007-2008 Collabora Ltd.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- * Authors: Xavier Claessens <xclaesse@gmail.com>
- */
-
-#ifndef __EMPATHY_FILTER_H__
-#define __EMPATHY_FILTER_H__
-
-#include <glib.h>
-
-#include <telepathy-glib/channel.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;
-typedef struct _EmpathyFilterPriv  EmpathyFilterPriv;
-
-struct _EmpathyFilter {
-       GObject parent;
-};
-
-struct _EmpathyFilterClass {
-       GObjectClass parent_class;
-};
-
-GType          empathy_filter_get_type (void) G_GNUC_CONST;
-EmpathyFilter *empathy_filter_new      (const gchar   *bus_name,
-                                       const gchar   *object_path,
-                                       const gchar   *channel_type,
-                                       guint          priority,
-                                       guint          flags);
-void           empathy_filter_process  (EmpathyFilter *filter,
-                                       TpChannel     *channel,
-                                       gboolean       process);
-
-G_END_DECLS
-
-#endif /* __EMPATHY_FILTER_H__ */
index 3876cdf48ac521cca2977c1b1313710e9aac082c..9132cbfc916cf6d6fd867296de195520218cc7a9 100644 (file)
@@ -353,21 +353,19 @@ empathy_call_with_contact (EmpathyContact *contact)
 
        g_return_if_fail (EMPATHY_IS_CONTACT (contact));
 
-       /* StreamedMedia channels must have handle=0 and handle_type=none.
-        * To call a contact we have to add him in the group interface of the
-        * channel. MissionControl will detect the channel creation and 
-        * dispatch it to the VoIP chandler automatically. */
-
        mc = empathy_mission_control_new ();
        account = empathy_contact_get_account (contact);
        connection = mission_control_get_tpconnection (mc, account, NULL);
        tp_connection_run_until_ready (connection, FALSE, NULL, NULL);
+       g_object_unref (mc);
 
+       /* We abuse of suppress_handler, TRUE means OUTGOING. The channel
+        * will be catched in EmpathyFilter */
        if (!tp_cli_connection_run_request_channel (connection, -1,
                                                    TP_IFACE_CHANNEL_TYPE_STREAMED_MEDIA,
                                                    TP_HANDLE_TYPE_NONE,
                                                    0,
-                                                   FALSE,
+                                                   TRUE,
                                                    &object_path,
                                                    &error,
                                                    NULL)) {
@@ -375,7 +373,6 @@ empathy_call_with_contact (EmpathyContact *contact)
                              "Couldn't request channel: %s",
                              error ? error->message : "No error given");
                g_clear_error (&error);
-               g_object_unref (mc);
                g_object_unref (connection);
                return;
        }
@@ -399,7 +396,6 @@ empathy_call_with_contact (EmpathyContact *contact)
        g_object_unref (factory);
        g_object_unref (self_contact);
        g_object_unref (group);
-       g_object_unref (mc);
        g_object_unref (connection);
        g_object_unref (channel);
        g_free (object_path);
@@ -427,31 +423,43 @@ empathy_call_with_contact_id (McAccount *account, const gchar *contact_id)
 void
 empathy_chat_with_contact (EmpathyContact  *contact)
 {
-       MissionControl *mc;
+       MissionControl        *mc;
+       McAccount             *account;
+       TpConnection          *connection;
+
+       g_return_if_fail (EMPATHY_IS_CONTACT (contact));
 
        mc = empathy_mission_control_new ();
-       mission_control_request_channel (mc,
-                                        empathy_contact_get_account (contact),
-                                        TP_IFACE_CHANNEL_TYPE_TEXT,
-                                        empathy_contact_get_handle (contact),
-                                        TP_HANDLE_TYPE_CONTACT,
-                                        NULL, NULL);
+       account = empathy_contact_get_account (contact);
+       connection = mission_control_get_tpconnection (mc, account, NULL);
+       tp_connection_run_until_ready (connection, FALSE, NULL, NULL);
        g_object_unref (mc);
+
+       /* We abuse of suppress_handler, TRUE means OUTGOING. The channel
+        * will be catched in EmpathyFilter */
+       tp_cli_connection_call_request_channel (connection, -1,
+                                               TP_IFACE_CHANNEL_TYPE_TEXT,
+                                               TP_HANDLE_TYPE_CONTACT,
+                                               empathy_contact_get_handle (contact),
+                                               TRUE,
+                                               NULL, NULL, NULL, NULL);
+       g_object_unref (connection);
 }
 
 void
 empathy_chat_with_contact_id (McAccount *account, const gchar *contact_id)
 {
-       MissionControl *mc;
+       EmpathyContactFactory *factory;
+       EmpathyContact        *contact;
 
-       mc = empathy_mission_control_new ();
-       mission_control_request_channel_with_string_handle (mc,
-                                                           account,
-                                                           TP_IFACE_CHANNEL_TYPE_TEXT,
-                                                           contact_id,
-                                                           TP_HANDLE_TYPE_CONTACT,
-                                                           NULL, NULL);
-       g_object_unref (mc);
+       factory = empathy_contact_factory_new ();
+       contact = empathy_contact_factory_get_from_id (factory, account, contact_id);
+       empathy_contact_run_until_ready (contact, EMPATHY_CONTACT_READY_HANDLE, NULL);
+
+       empathy_chat_with_contact (contact);
+
+       g_object_unref (contact);
+       g_object_unref (factory);
 }
 
 const gchar *
index 133f7f5b52642621afa1ce8f4feb06dbb5291734..6c3fc1e1cd1fa6bfce3d0d480c6cd7c9e039cd50 100644 (file)
@@ -29,23 +29,13 @@ empathy_SOURCES =                                                   \
        empathy-chatrooms-window.c empathy-chatrooms-window.h           \
        empathy-main-window.c empathy-main-window.h                     \
        empathy-preferences.c empathy-preferences.h                     \
+       empathy-call-window.c empathy-call-window.h                     \
+       empathy-filter.c empathy-filter.h                               \
        ephy-spinner.c ephy-spinner.h
 
 empathy_accounts_SOURCES = empathy-accounts.c
 empathy_logs_SOURCES = empathy-logs.c
 
-# Dbus service files
-servicedir = $(datadir)/dbus-1/services
-service_DATA =                                                 \
-       org.gnome.Empathy.Chat.service
-
-%.service: %.service.in Makefile
-       @sed -e "s|\@libexecdir\@|$(libexecdir)|" $< | sed -e "s|\@bindir\@|$(bindir)|" > $@
-
-chandlerdir = $(datadir)/telepathy/managers
-chandler_DATA =                                                        \
-       empathy-chat.chandler
-
 gladedir = $(datadir)/empathy
 glade_DATA =                                   \
        empathy-call-window.glade               \
@@ -56,26 +46,9 @@ glade_DATA =                                         \
        empathy-new-chatroom-dialog.glade       \
        empathy-status-icon.glade
 
-BUILT_SOURCES =                                                        \
-       $(service_DATA)
-
 EXTRA_DIST =                                                   \
-       org.gnome.Empathy.Chat.service.in                       \
-       org.gnome.Empathy.Call.service.in                       \
        $(autostart_DATA)                                       \
-       $(chandler_DATA)                                        \
        $(glade_DATA)
 
 CLEANFILES = $(BUILT_SOURCES)
 
-if HAVE_VOIP
-libexec_PROGRAMS = empathy-call-chandler
-empathy_call_chandler_SOURCES =                                \
-       empathy-call-chandler.c                         \
-       empathy-call-window.c empathy-call-window.h
-service_DATA +=        org.gnome.Empathy.Call.service
-chandler_DATA += empathy-call.chandler
-else
-EXTRA_DIST += empathy-call.chandler
-endif
-
diff --git a/src/empathy-call-chandler.c b/src/empathy-call-chandler.c
deleted file mode 100644 (file)
index 313fe73..0000000
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- *  Copyright (C) 2007 Elliot Fairweather
- *
- *  This library is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU Lesser General Public
- *  License as published by the Free Software Foundation; either
- *  version 2.1 of the License, or (at your option) any later version.
- *
- *  This library 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
- *  Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this library; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- *  Authors: Elliot Fairweather <elliot.fairweather@collabora.co.uk>
- */
-
-#include <gtk/gtk.h>
-
-#include <libmissioncontrol/mission-control.h>
-
-#include <libempathy/empathy-tp-call.h>
-#include <libempathy/empathy-chandler.h>
-#include <libempathy/empathy-debug.h>
-#include <libempathy/empathy-utils.h>
-
-#include "empathy-call-window.h"
-
-#define DEBUG_DOMAIN "CallChandler"
-
-static guint nb_calls = 0;
-
-static void
-weak_notify (gpointer data,
-             GObject *where_the_object_was)
-{
-  nb_calls--;
-  if (nb_calls == 0)
-    {
-      empathy_debug (DEBUG_DOMAIN, "No more calls, leaving...");
-      gtk_main_quit ();
-    }
-}
-
-static void
-new_channel_cb (EmpathyChandler *chandler,
-                TpChannel *channel,
-                MissionControl *mc)
-{
-  EmpathyTpCall *call;
-
-  call = empathy_tp_call_new (channel);
-  empathy_call_window_new (call);
-  g_object_unref (call);
-
-  nb_calls++;
-  g_object_weak_ref (G_OBJECT (call), weak_notify, NULL);
-}
-
-int
-main (int argc, char *argv[])
-{
-  MissionControl *mc;
-  EmpathyChandler *chandler;
-
-  gtk_init (&argc, &argv);
-
-  mc = empathy_mission_control_new ();
-
-  chandler = empathy_chandler_new ("org.gnome.Empathy.CallChandler",
-      "/org/gnome/Empathy/CallChandler");
-  g_signal_connect (chandler, "new-channel",
-      G_CALLBACK (new_channel_cb), mc);
-
-  empathy_debug (DEBUG_DOMAIN, "Ready to handle new streamed media channels");
-
-  gtk_main ();
-
-  g_object_unref (chandler);
-  g_object_unref (mc);
-
-  return EXIT_SUCCESS;
-}
diff --git a/src/empathy-call.chandler b/src/empathy-call.chandler
deleted file mode 100644 (file)
index 88ad9e7..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-[ChannelHandler]
-BusName = org.gnome.Empathy.CallChandler
-ObjectPath = /org/gnome/Empathy/CallChandler
-ChannelType = org.freedesktop.Telepathy.Channel.Type.StreamedMedia
-TypeSpecificCapabilities = 15
diff --git a/src/empathy-chat.chandler b/src/empathy-chat.chandler
deleted file mode 100644 (file)
index 7de2f28..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-[ChannelHandler]
-BusName = org.gnome.Empathy.ChatChandler
-ObjectPath = /org/gnome/Empathy/ChatChandler
-ChannelType = org.freedesktop.Telepathy.Channel.Type.Text
-
diff --git a/src/empathy-filter.c b/src/empathy-filter.c
new file mode 100644 (file)
index 0000000..d7a6d65
--- /dev/null
@@ -0,0 +1,555 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2007-2008 Collabora Ltd.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Authors: Xavier Claessens <xclaesse@gmail.com>
+ */
+
+#include <config.h>
+
+#include <string.h>
+
+#include <glib/gi18n.h>
+
+#include <telepathy-glib/enums.h>
+#include <telepathy-glib/channel.h>
+#include <telepathy-glib/connection.h>
+#include <telepathy-glib/util.h>
+
+#include <libmissioncontrol/mission-control.h>
+#include <libmissioncontrol/mc-account.h>
+
+#include <libempathy/empathy-tp-chat.h>
+#include <libempathy/empathy-tp-call.h>
+#include <libempathy/empathy-utils.h>
+#include <libempathy/empathy-debug.h>
+
+#include <libempathy-gtk/empathy-chat.h>
+#include <libempathy-gtk/empathy-images.h>
+
+#include "empathy-filter.h"
+#include "empathy-chat-window.h"
+#include "empathy-call-window.h"
+
+#define GET_PRIV(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
+                      EMPATHY_TYPE_FILTER, EmpathyFilterPriv))
+
+#define DEBUG_DOMAIN "Filter"
+
+struct _EmpathyFilterPriv {
+       GSList         *events;
+       GHashTable     *accounts;
+       gpointer        token;
+       MissionControl *mc;
+};
+
+static void empathy_filter_class_init (EmpathyFilterClass *klass);
+static void empathy_filter_init       (EmpathyFilter      *filter);
+
+G_DEFINE_TYPE (EmpathyFilter, empathy_filter, G_TYPE_OBJECT);
+
+enum {
+       PROP_0,
+       PROP_TOP_EVENT,
+};
+
+typedef void (*FilterFunc) (EmpathyFilter *filter,
+                           gpointer       user_data);
+
+typedef struct {
+       EmpathyFilterEvent public;
+       FilterFunc         func;
+       gpointer           user_data;
+} EmpathyFilterEventExt;
+
+static void
+filter_event_free (EmpathyFilterEventExt *event)
+{
+       g_free (event->public.icon_name);
+       g_free (event->public.message);
+       g_slice_free (EmpathyFilterEventExt, event);
+}
+
+static void
+filter_emit_event (EmpathyFilter *filter,
+                  const gchar   *icon_name,
+                  const gchar   *message,
+                  FilterFunc     func,
+                  gpointer       user_data)
+{
+       EmpathyFilterPriv     *priv = GET_PRIV (filter);
+       EmpathyFilterEventExt *event;
+
+       empathy_debug (DEBUG_DOMAIN, "Emit event, icon_name=%s message='%s'",
+                      icon_name, message);
+
+       event = g_slice_new0 (EmpathyFilterEventExt);
+       event->func = func;
+       event->user_data = user_data;
+       event->public.icon_name = g_strdup (icon_name);
+       event->public.message = g_strdup (message);
+
+       priv->events = g_slist_append (priv->events, event);
+       if (priv->events->data == event) {
+               g_object_notify (G_OBJECT (filter), "top-event");
+       }
+}
+
+void
+empathy_filter_activate_event (EmpathyFilter      *filter,
+                              EmpathyFilterEvent *event)
+{
+       EmpathyFilterPriv     *priv = GET_PRIV (filter);
+       EmpathyFilterEventExt *event_ext;
+       GSList                *l;
+       gboolean               is_top;
+
+       g_return_if_fail (EMPATHY_IS_FILTER (filter));
+       g_return_if_fail (event != NULL);
+
+       if (!(l = g_slist_find (priv->events, event))) {
+               return;
+       }
+
+       empathy_debug (DEBUG_DOMAIN, "Activating event");
+
+       event_ext = (EmpathyFilterEventExt*) event;
+       if (event_ext->func) {
+               event_ext->func (filter, event_ext->user_data);
+       }
+
+       is_top = (l == priv->events);
+       priv->events = g_slist_delete_link (priv->events, l);
+       if (is_top) {
+               g_object_notify (G_OBJECT (filter), "top-event");
+       }
+
+       filter_event_free (event_ext);
+}
+
+EmpathyFilterEvent *
+empathy_filter_get_top_event (EmpathyFilter *filter)
+{
+       EmpathyFilterPriv *priv = GET_PRIV (filter);
+
+       g_return_val_if_fail (EMPATHY_IS_FILTER (filter), NULL);
+
+       return priv->events ? priv->events->data : NULL;
+}
+
+static void
+filter_chat_dispatch (EmpathyFilter *filter,
+                     gpointer       user_data)
+{
+       EmpathyTpChat *tp_chat = EMPATHY_TP_CHAT (user_data);
+       McAccount     *account;
+       EmpathyChat   *chat;
+       const gchar   *id;
+
+       id = empathy_tp_chat_get_id (tp_chat);
+       account = empathy_tp_chat_get_account (tp_chat);
+       chat = empathy_chat_window_find_chat (account, id);
+
+       if (chat) {
+               empathy_chat_set_tp_chat (chat, tp_chat);
+       } else {
+               chat = empathy_chat_new (tp_chat);
+       }
+
+       empathy_chat_window_present_chat (chat);
+       g_object_unref (tp_chat);
+}
+
+static void
+filter_chat_message_received_cb (EmpathyTpChat   *tp_chat,
+                                EmpathyMessage  *message,
+                                EmpathyFilter   *filter)
+{
+       EmpathyContact  *sender;
+       gchar           *msg;
+
+       g_signal_handlers_disconnect_by_func (tp_chat,
+                                             filter_chat_message_received_cb,
+                                             filter);
+
+       sender = empathy_message_get_sender (message);
+       msg = g_strdup_printf (_("New message from %s:\n%s"),
+                              empathy_contact_get_name (sender),
+                              empathy_message_get_body (message));
+
+       filter_emit_event (filter, EMPATHY_IMAGE_NEW_MESSAGE, msg,
+                          filter_chat_dispatch, tp_chat);
+
+       g_free (msg);
+}
+
+static void
+filter_chat_handle_channel (EmpathyFilter *filter,
+                           TpChannel     *channel,
+                           gboolean       is_incoming)
+{
+       EmpathyTpChat *tp_chat;
+
+       empathy_debug (DEBUG_DOMAIN, "New text channel to be filtered: %p",
+                      channel);
+
+       tp_chat = empathy_tp_chat_new (channel, FALSE);
+       if (is_incoming) {
+               filter_chat_dispatch (filter, tp_chat);
+       } else {
+               g_signal_connect (tp_chat, "message-received",
+                                 G_CALLBACK (filter_chat_message_received_cb),
+                                 filter);
+       }
+}
+
+static void
+filter_call_dispatch (EmpathyFilter *filter,
+                     gpointer       user_data)
+{
+       EmpathyTpCall *call = EMPATHY_TP_CALL (user_data);
+
+       empathy_call_window_new (call);
+       g_object_unref (call);
+}
+
+static void
+filter_call_contact_notify_cb (EmpathyTpCall *call,
+                              gpointer       unused,
+                              EmpathyFilter *filter)
+{
+       EmpathyContact *contact;
+       gchar          *msg;
+
+       g_object_get (call, "contact", &contact, NULL);
+       if (!contact) {
+               return;
+       }
+
+       empathy_contact_run_until_ready (contact,
+                                        EMPATHY_CONTACT_READY_NAME,
+                                        NULL);
+
+       msg = g_strdup_printf (_("Incoming call from %s"),
+                              empathy_contact_get_name (contact));
+
+       filter_emit_event (filter, EMPATHY_IMAGE_VOIP, msg,
+                          filter_call_dispatch, call);
+
+       g_free (msg);
+       g_object_unref (contact);
+}
+
+static void
+filter_call_handle_channel (EmpathyFilter *filter,
+                           TpChannel     *channel,
+                           gboolean       is_incoming)
+{
+       EmpathyTpCall *call;
+
+       empathy_debug (DEBUG_DOMAIN, "New media channel to be filtered: %p",
+                      channel);
+
+       call = empathy_tp_call_new (channel);
+       if (is_incoming) {
+               filter_call_dispatch (filter, call);
+       } else {
+               g_signal_connect (call, "notify::contact",
+                                 G_CALLBACK (filter_call_contact_notify_cb),
+                                 filter);      
+       }
+}
+
+#if 0
+static void
+status_icon_pendings_changed_cb (EmpathyContactManager *manager,
+                                EmpathyContact        *contact,
+                                EmpathyContact        *actor,
+                                guint                  reason,
+                                gchar                 *message,
+                                gboolean               is_pending,
+                                EmpathyStatusIcon     *icon)
+{
+       EmpathyStatusIconPriv *priv;
+       StatusIconEvent       *event;
+       GString               *str;
+
+       priv = GET_PRIV (icon);
+
+       if (!is_pending) {
+               /* FIXME: We should remove the event */
+               return;
+       }
+
+       empathy_contact_run_until_ready (contact,
+                                        EMPATHY_CONTACT_READY_NAME,
+                                        NULL);
+
+       str = g_string_new (NULL);
+       g_string_printf (str, _("Subscription requested by %s"),
+                        empathy_contact_get_name (contact));   
+       if (!G_STR_EMPTY (message)) {
+               g_string_append_printf (str, _("\nMessage: %s"), message);
+       }
+
+       event = status_icon_event_new (icon, GTK_STOCK_DIALOG_QUESTION, str->str);
+       event->user_data = g_object_ref (contact);
+       event->func = status_icon_event_subscribe_cb;
+
+       g_string_free (str, TRUE);
+}
+
+static void
+status_icon_event_subscribe_cb (StatusIconEvent *event)
+{
+       EmpathyContact *contact;
+
+       contact = EMPATHY_CONTACT (event->user_data);
+
+       empathy_subscription_dialog_show (contact, NULL);
+
+       g_object_unref (contact);
+}
+       g_signal_connect (priv->manager, "pendings-changed",
+                         G_CALLBACK (status_icon_pendings_changed_cb),
+                         icon);
+
+       pendings = empathy_contact_list_get_pendings (EMPATHY_CONTACT_LIST (priv->manager));
+       for (l = pendings; l; l = l->next) {
+               EmpathyPendingInfo *info;
+
+               info = l->data;
+               status_icon_pendings_changed_cb (priv->manager,
+                                                info->member,
+                                                info->actor,
+                                                0,
+                                                info->message,
+                                                TRUE,
+                                                icon);
+               empathy_pending_info_free (info);
+       }
+       g_list_free (pendings);
+#endif
+
+static void
+filter_connection_invalidated_cb (TpConnection  *connection,
+                                 guint          domain,
+                                 gint           code,
+                                 gchar         *message,
+                                 EmpathyFilter *filter)
+{
+       EmpathyFilterPriv *priv = GET_PRIV (filter);
+       GHashTableIter     iter;
+       gpointer           key, value;
+
+       empathy_debug (DEBUG_DOMAIN, "connection invalidated: %s", message);
+
+       g_hash_table_iter_init (&iter, priv->accounts);
+       while (g_hash_table_iter_next (&iter, &key, &value)) {
+               if (value == connection) {
+                       g_hash_table_remove (priv->accounts, key);
+                       break;
+               }
+       }
+}
+
+typedef void (*HandleChannelFunc) (EmpathyFilter *filter,
+                                  TpChannel     *channel,
+                                  gboolean       is_incoming);
+
+static void
+filter_conection_new_channel_cb (TpConnection *connection,
+                                const gchar  *object_path,
+                                const gchar  *channel_type,
+                                guint         handle_type,
+                                guint         handle,
+                                gboolean      suppress_handler,
+                                gpointer      user_data,
+                                GObject      *filter)
+{
+       HandleChannelFunc  func = NULL;
+       TpChannel         *channel;
+       
+       if (!tp_strdiff (channel_type, TP_IFACE_CHANNEL_TYPE_TEXT)) {
+               func = filter_chat_handle_channel;
+       }
+       else if (!tp_strdiff (channel_type, TP_IFACE_CHANNEL_TYPE_STREAMED_MEDIA)) {
+               func = filter_call_handle_channel;
+       } else {
+               empathy_debug (DEBUG_DOMAIN, "Unknown channel type %s",
+                              channel_type);
+               return;
+       }
+
+       channel = tp_channel_new (connection, object_path, channel_type,
+                                 handle_type, handle, NULL);
+       tp_channel_run_until_ready (channel, NULL, NULL);
+
+       /* We abuse of suppress_handler, TRUE means OUTGOING */
+       func (EMPATHY_FILTER (filter), channel, suppress_handler);
+
+       g_object_unref (channel);
+}
+
+static void
+filter_connection_ready_cb (TpConnection  *connection,
+                           gpointer       unused,
+                           EmpathyFilter *filter)
+{
+       empathy_debug (DEBUG_DOMAIN, "Connection ready, accepting new channels");
+       tp_cli_connection_connect_to_new_channel (connection,
+                                                 filter_conection_new_channel_cb,
+                                                 NULL, NULL,
+                                                 G_OBJECT (filter), NULL);
+}
+
+static void
+filter_update_account (EmpathyFilter *filter,
+                      McAccount     *account)
+{
+       EmpathyFilterPriv *priv = GET_PRIV (filter);
+       TpConnection      *connection;
+       gboolean           ready;
+
+       connection = g_hash_table_lookup (priv->accounts, account);
+       if (connection) {
+               return;
+       }
+
+       connection = mission_control_get_tpconnection (priv->mc, account, NULL);
+       if (!connection) {
+               return;
+       }
+
+       g_hash_table_insert (priv->accounts, g_object_ref (account), connection);
+       g_signal_connect (connection, "invalidated",
+                         G_CALLBACK (filter_connection_invalidated_cb),
+                         filter);
+
+       g_object_get (connection, "connection-ready", &ready, NULL);
+       if (ready) {
+               filter_connection_ready_cb (connection, NULL, filter);
+       } else {
+               g_signal_connect (connection, "notify::connection-ready",
+                                 G_CALLBACK (filter_connection_ready_cb),
+                                 filter);
+       }
+}
+
+static void
+filter_status_changed_cb (MissionControl           *mc,
+                         TpConnectionStatus        status,
+                         McPresence                presence,
+                         TpConnectionStatusReason  reason,
+                         const gchar              *unique_name,
+                         EmpathyFilter            *filter)
+{
+       McAccount *account;
+
+       account = mc_account_lookup (unique_name);
+       filter_update_account (filter, account);
+       g_object_unref (account);
+}
+
+static void
+filter_finalize (GObject *object)
+{
+       EmpathyFilterPriv *priv = GET_PRIV (object);
+
+       empathy_disconnect_account_status_changed (priv->token);
+       g_object_unref (priv->mc);
+
+       g_slist_foreach (priv->events, (GFunc) filter_event_free, NULL);
+       g_slist_free (priv->events);
+
+       g_hash_table_destroy (priv->accounts);
+}
+
+static void
+filter_get_property (GObject    *object,
+                    guint       param_id,
+                    GValue     *value,
+                    GParamSpec *pspec)
+{
+       EmpathyFilterPriv *priv = GET_PRIV (object);
+
+       switch (param_id) {
+       case PROP_TOP_EVENT:
+               g_value_set_pointer (value, priv->events ? priv->events->data : NULL);
+               break;
+       default:
+               G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+               break;
+       };
+}
+
+static void
+empathy_filter_class_init (EmpathyFilterClass *klass)
+{
+       GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+       object_class->finalize = filter_finalize;
+       object_class->get_property = filter_get_property;
+
+       g_object_class_install_property (object_class,
+                                        PROP_TOP_EVENT,
+                                        g_param_spec_pointer ("top-event",
+                                                              "The top event",
+                                                              "The first event in the events list",
+                                                              G_PARAM_READABLE));
+
+       g_type_class_add_private (object_class, sizeof (EmpathyFilterPriv));
+}
+
+static void
+empathy_filter_init (EmpathyFilter *filter)
+{
+       EmpathyFilterPriv *priv = GET_PRIV (filter);
+       GList             *accounts, *l;
+
+       priv->mc = empathy_mission_control_new ();
+       priv->token = empathy_connect_to_account_status_changed (priv->mc,
+               G_CALLBACK (filter_status_changed_cb),
+               filter, NULL);
+
+       priv->accounts = g_hash_table_new_full (empathy_account_hash,
+                                               empathy_account_equal,
+                                               g_object_unref,
+                                               g_object_unref);
+       accounts = mc_accounts_list_by_enabled (TRUE);
+       for (l = accounts; l; l = l->next) {
+               filter_update_account (filter, l->data);
+               g_object_unref (l->data);
+       }
+       g_list_free (accounts);
+}
+
+EmpathyFilter *
+empathy_filter_new (void)
+{
+       static EmpathyFilter *filter = NULL;
+
+       if (!filter) {
+               filter = g_object_new (EMPATHY_TYPE_FILTER, NULL);
+               g_object_add_weak_pointer (G_OBJECT (filter), (gpointer) &filter);
+       } else {
+               g_object_ref (filter);
+       }
+
+       return filter;
+}
+
diff --git a/src/empathy-filter.h b/src/empathy-filter.h
new file mode 100644 (file)
index 0000000..bf3c746
--- /dev/null
@@ -0,0 +1,61 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2007-2008 Collabora Ltd.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  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;
+typedef struct _EmpathyFilterPriv  EmpathyFilterPriv;
+
+struct _EmpathyFilter {
+       GObject      parent;
+};
+
+struct _EmpathyFilterClass {
+       GObjectClass parent_class;
+};
+
+typedef struct {
+       gchar *icon_name;
+       gchar *message;
+} EmpathyFilterEvent;
+
+GType               empathy_filter_get_type       (void) G_GNUC_CONST;
+EmpathyFilter *     empathy_filter_new            (void);
+void                empathy_filter_activate_event (EmpathyFilter      *filter,
+                                                  EmpathyFilterEvent *event);
+EmpathyFilterEvent *empathy_filter_get_top_event  (EmpathyFilter      *filter);
+
+G_END_DECLS
+
+#endif /* __EMPATHY_FILTER_H__ */
index 18788fb7d16beaf135f0a10227439166208dabb5..cd086d199005931cf441f5beea81dfacf65e7944 100644 (file)
 #include <glade/glade.h>
 #include <glib/gi18n.h>
 
-#include <libmissioncontrol/mission-control.h>
-
-#include <libempathy/empathy-contact-list.h>
-#include <libempathy/empathy-contact-manager.h>
-#include <libempathy/empathy-contact.h>
-#include <libempathy/empathy-tp-chat.h>
 #include <libempathy/empathy-debug.h>
 #include <libempathy/empathy-utils.h>
 #include <libempathy/empathy-idle.h>
-#include <libempathy/empathy-filter.h>
 
-#include <libempathy-gtk/empathy-contact-dialogs.h>
 #include <libempathy-gtk/empathy-presence-chooser.h>
 #include <libempathy-gtk/empathy-conf.h>
 #include <libempathy-gtk/empathy-ui-utils.h>
@@ -48,7 +40,7 @@
 
 #include "empathy-status-icon.h"
 #include "empathy-preferences.h"
-
+#include "empathy-filter.h"
 
 #define GET_PRIV(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
                       EMPATHY_TYPE_STATUS_ICON, EmpathyStatusIconPriv))
 typedef struct _StatusIconEvent StatusIconEvent;
 
 struct _EmpathyStatusIconPriv {
-       GtkStatusIcon         *icon;
-       EmpathyContactManager *manager;
-       EmpathyFilter         *text_filter;
-       EmpathyFilter         *call_filter;
-       EmpathyIdle           *idle;
-       MissionControl        *mc;
-       GList                 *events;
-       gboolean               showing_event_icon;
-       StatusIconEvent       *flash_state_event;
-       guint                  blink_timeout;
-
-       GtkWindow             *window;
-       GtkWidget             *popup_menu;
-       GtkWidget             *show_window_item;
-       GtkWidget             *message_item;
-       GtkWidget             *status_item;
+       GtkStatusIcon      *icon;
+       EmpathyIdle        *idle;
+       EmpathyFilter      *filter;
+       EmpathyFilterEvent *event;
+       gboolean            showing_event_icon;
+       guint               blink_timeout;
+
+       GtkWindow          *window;
+       GtkWidget          *popup_menu;
+       GtkWidget          *show_window_item;
+       GtkWidget          *message_item;
+       GtkWidget          *status_item;
 };
 
-typedef void (*EventActivatedFunc) (StatusIconEvent *event);
+G_DEFINE_TYPE (EmpathyStatusIcon, empathy_status_icon, G_TYPE_OBJECT);
 
-struct _StatusIconEvent {
-       gchar              *icon_name;
-       gchar              *message;
-       EventActivatedFunc  func;
-       gpointer            user_data;
-};
+static void
+status_icon_set_visibility (EmpathyStatusIcon *icon,
+                           gboolean           visible,
+                           gboolean           store)
+{
+       EmpathyStatusIconPriv *priv = GET_PRIV (icon);
 
+       if (store) {
+               empathy_conf_set_bool (empathy_conf_get (),
+                                      EMPATHY_PREFS_UI_MAIN_WINDOW_HIDDEN, !visible);
+       }
 
-static void       empathy_status_icon_class_init  (EmpathyStatusIconClass *klass);
-static void       empathy_status_icon_init        (EmpathyStatusIcon      *icon);
-static void       status_icon_finalize            (GObject                *object);
-static void       status_icon_text_filter_new_channel (EmpathyFilter      *filter,
-                                                  TpChannel              *channel,
-                                                  EmpathyStatusIcon      *icon);
-static void       status_icon_call_filter_new_channel (EmpathyFilter      *filter,
-                                                  TpChannel              *channel,
-                                                  EmpathyStatusIcon      *icon);
-static void       status_icon_message_received_cb (EmpathyTpChat          *tp_chat,
-                                                  EmpathyMessage         *message,
-                                                  EmpathyStatusIcon      *icon);
-static void       status_icon_idle_notify_cb      (EmpathyStatusIcon      *icon);
-static void       status_icon_update_tooltip      (EmpathyStatusIcon      *icon);
-static void       status_icon_set_from_state      (EmpathyStatusIcon      *icon);
-static void       status_icon_set_visibility      (EmpathyStatusIcon      *icon,
-                                                  gboolean                visible,
-                                                  gboolean                store);
-static void       status_icon_toggle_visibility   (EmpathyStatusIcon      *icon);
-static void       status_icon_activate_cb         (GtkStatusIcon          *status_icon,
-                                                  EmpathyStatusIcon      *icon);
-static gboolean   status_icon_delete_event_cb     (GtkWidget              *widget,
-                                                  GdkEvent               *event,
-                                                  EmpathyStatusIcon      *icon);
-static void       status_icon_popup_menu_cb       (GtkStatusIcon          *status_icon,
-                                                  guint                   button,
-                                                  guint                   activate_time,
-                                                  EmpathyStatusIcon      *icon);
-static void       status_icon_create_menu         (EmpathyStatusIcon      *icon);
-static void       status_icon_new_message_cb      (GtkWidget              *widget,
-                                                  EmpathyStatusIcon      *icon);
-static void       status_icon_quit_cb             (GtkWidget              *window,
-                                                  EmpathyStatusIcon      *icon);
-static void       status_icon_show_hide_window_cb (GtkWidget              *widget,
-                                                  EmpathyStatusIcon      *icon);
-static void       status_icon_pendings_changed_cb (EmpathyContactManager  *manager,
-                                                  EmpathyContact         *contact,
-                                                  EmpathyContact         *actor,
-                                                  guint                   reason,
-                                                  gchar                  *message,
-                                                  gboolean                is_pending,
-                                                  EmpathyStatusIcon      *icon);
-static void       status_icon_event_subscribe_cb  (StatusIconEvent        *event);
-static void       status_icon_event_flash_state_cb (StatusIconEvent       *event);
-static void       status_icon_event_msg_cb        (StatusIconEvent        *event);
-static StatusIconEvent * status_icon_event_new    (EmpathyStatusIcon      *icon,
-                                                  const gchar            *icon_name,
-                                                  const gchar            *message);
-static void       status_icon_event_remove        (EmpathyStatusIcon      *icon,
-                                                  StatusIconEvent        *event);
-static gboolean   status_icon_event_timeout_cb    (EmpathyStatusIcon      *icon);
-static void       status_icon_event_free          (StatusIconEvent        *event);
+       if (!visible) {
+               empathy_window_iconify (priv->window, priv->icon);
+       } else {
+               GList *accounts;
 
-G_DEFINE_TYPE (EmpathyStatusIcon, empathy_status_icon, G_TYPE_OBJECT);
+               empathy_window_present (GTK_WINDOW (priv->window), TRUE);
+       
+               /* Show the accounts dialog if there is no enabled accounts */
+               accounts = mc_accounts_list_by_enabled (TRUE);
+               if (accounts) {
+                       mc_accounts_list_free (accounts);
+               } else {
+                       empathy_debug (DEBUG_DOMAIN,
+                                     "No enabled account, Showing account dialog");
+                       empathy_accounts_dialog_show (GTK_WINDOW (priv->window));
+               }
+       }
+}
 
 static void
 status_icon_notify_visibility_cb (EmpathyConf *conf,
@@ -158,389 +114,112 @@ status_icon_notify_visibility_cb (EmpathyConf *conf,
 }
 
 static void
-empathy_status_icon_class_init (EmpathyStatusIconClass *klass)
-{
-       GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
-       object_class->finalize = status_icon_finalize;
-
-       g_type_class_add_private (object_class, sizeof (EmpathyStatusIconPriv));
-}
-
-static void
-empathy_status_icon_init (EmpathyStatusIcon *icon)
+status_icon_toggle_visibility (EmpathyStatusIcon *icon)
 {
-       EmpathyStatusIconPriv *priv;
-       GList                 *pendings, *l;
-
-       priv = GET_PRIV (icon);
-
-       priv->icon = gtk_status_icon_new ();
-       priv->manager = empathy_contact_manager_new ();
-       priv->mc = empathy_mission_control_new ();
-       priv->text_filter = empathy_filter_new ("org.gnome.Empathy.ChatFilter",
-                                               "/org/gnome/Empathy/ChatFilter",
-                                               TP_IFACE_CHANNEL_TYPE_TEXT,
-                                               MC_FILTER_PRIORITY_DIALOG,
-                                               MC_FILTER_FLAG_INCOMING);
-       priv->call_filter = empathy_filter_new ("org.gnome.Empathy.CallFilter",
-                                               "/org/gnome/Empathy/CallFilter",
-                                               TP_IFACE_CHANNEL_TYPE_STREAMED_MEDIA,
-                                               MC_FILTER_PRIORITY_DIALOG,
-                                               MC_FILTER_FLAG_INCOMING);
-
-       priv->idle = empathy_idle_new ();
-
-       /* make icon listen and respond to MAIN_WINDOW_HIDDEN changes */
-       empathy_conf_notify_add (empathy_conf_get (),
-                                EMPATHY_PREFS_UI_MAIN_WINDOW_HIDDEN,
-                                status_icon_notify_visibility_cb,
-                                icon);
-
-       status_icon_create_menu (icon);
-       status_icon_idle_notify_cb (icon);
-
-       g_signal_connect (priv->text_filter, "new-channel",
-                         G_CALLBACK (status_icon_text_filter_new_channel),
-                         icon);
-       g_signal_connect (priv->call_filter, "new-channel",
-                         G_CALLBACK (status_icon_call_filter_new_channel),
-                         icon);
-       g_signal_connect_swapped (priv->idle, "notify",
-                                 G_CALLBACK (status_icon_idle_notify_cb),
-                                 icon);
-       g_signal_connect (priv->icon, "activate",
-                         G_CALLBACK (status_icon_activate_cb),
-                         icon);
-       g_signal_connect (priv->icon, "popup-menu",
-                         G_CALLBACK (status_icon_popup_menu_cb),
-                         icon);
-       g_signal_connect (priv->manager, "pendings-changed",
-                         G_CALLBACK (status_icon_pendings_changed_cb),
-                         icon);
+       EmpathyStatusIconPriv *priv = GET_PRIV (icon);
+       gboolean               visible;
 
-       pendings = empathy_contact_list_get_pendings (EMPATHY_CONTACT_LIST (priv->manager));
-       for (l = pendings; l; l = l->next) {
-               EmpathyPendingInfo *info;
-
-               info = l->data;
-               status_icon_pendings_changed_cb (priv->manager,
-                                                info->member,
-                                                info->actor,
-                                                0,
-                                                info->message,
-                                                TRUE,
-                                                icon);
-               empathy_pending_info_free (info);
-       }
-       g_list_free (pendings);
+       visible = gtk_window_is_active (priv->window);
+       status_icon_set_visibility (icon, !visible, TRUE);
 }
 
 static void
-status_icon_finalize (GObject *object)
+status_icon_update_tooltip (EmpathyStatusIcon *icon)
 {
-       EmpathyStatusIconPriv *priv;
-
-       priv = GET_PRIV (object);
-
-       g_list_foreach (priv->events, (GFunc) status_icon_event_free, NULL);
-       g_list_free (priv->events);
+       EmpathyStatusIconPriv *priv = GET_PRIV (icon);
+       const gchar           *tooltip = NULL;
 
-       if (priv->blink_timeout) {
-               g_source_remove (priv->blink_timeout);
+       if (priv->event) {
+               tooltip = priv->event->message;
        }
 
-       g_object_unref (priv->icon);
-       g_object_unref (priv->window);
-       g_object_unref (priv->idle);
-       g_object_unref (priv->manager);
-       g_object_unref (priv->mc);
-       g_object_unref (priv->text_filter);
-       g_object_unref (priv->call_filter);
-}
-
-EmpathyStatusIcon *
-empathy_status_icon_new (GtkWindow *window)
-{
-       EmpathyStatusIconPriv *priv;
-       EmpathyStatusIcon     *icon;
-       gboolean               should_hide;
-
-       g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
-
-       icon = g_object_new (EMPATHY_TYPE_STATUS_ICON, NULL);
-       priv = GET_PRIV (icon);
-
-       priv->window = g_object_ref (window);
-
-       g_signal_connect (priv->window, "delete-event",
-                         G_CALLBACK (status_icon_delete_event_cb),
-                         icon);
-
-       empathy_conf_get_bool (empathy_conf_get (),
-                             EMPATHY_PREFS_UI_MAIN_WINDOW_HIDDEN,
-                             &should_hide);
-
-       if (gtk_window_is_active (priv->window) == should_hide) {
-               status_icon_set_visibility (icon, !should_hide, FALSE);
+       if (!tooltip) {
+               tooltip = empathy_idle_get_status (priv->idle);
        }
 
-       return icon;
-}
-
-static void
-status_icon_text_filter_new_channel (EmpathyFilter     *filter,
-                                    TpChannel         *channel,
-                                    EmpathyStatusIcon *icon)
-{
-       EmpathyTpChat *tp_chat;
-
-       empathy_debug (DEBUG_DOMAIN, "New text channel to be filtered for contact %p",
-                      channel);
-
-       tp_chat = empathy_tp_chat_new (channel, FALSE);
-       g_object_set_data (G_OBJECT (tp_chat), "filter", filter);
-       g_object_set_data (G_OBJECT (tp_chat), "channel", channel);
-
-       g_signal_connect (tp_chat, "message-received",
-                         G_CALLBACK (status_icon_message_received_cb),
-                         icon);
-}
-
-static void
-status_icon_message_received_cb (EmpathyTpChat     *tp_chat,
-                                EmpathyMessage    *message,
-                                EmpathyStatusIcon *icon)
-{
-       EmpathyContact  *sender;
-       gchar           *msg;
-       StatusIconEvent *event;
-
-       empathy_debug (DEBUG_DOMAIN, "Message received, add event");
-
-       g_signal_handlers_disconnect_by_func (tp_chat,
-                                             status_icon_message_received_cb,
-                                             icon);
-
-       sender = empathy_message_get_sender (message);
-       msg = g_strdup_printf (_("New message from %s:\n%s"),
-                              empathy_contact_get_name (sender),
-                              empathy_message_get_body (message));
-
-       event = status_icon_event_new (icon, EMPATHY_IMAGE_NEW_MESSAGE, msg);
-       event->func = status_icon_event_msg_cb;
-       event->user_data = tp_chat;
-       g_free (msg);
+       gtk_status_icon_set_tooltip (priv->icon, tooltip);      
 }
 
 static void
-status_icon_event_call_cb (StatusIconEvent *event)
+status_icon_update_icon (EmpathyStatusIcon *icon)
 {
-       EmpathyTpGroup *group;
-       EmpathyFilter  *filter;
-       TpChannel      *channel;
-
-       empathy_debug (DEBUG_DOMAIN, "Dispatching call channel");
-
-       group = event->user_data;
-       filter = g_object_get_data (G_OBJECT (group), "filter");
-       channel = g_object_get_data (G_OBJECT (group), "channel");
-       empathy_filter_process (filter, channel, TRUE);
-       g_object_unref (group);
-}
+       EmpathyStatusIconPriv *priv = GET_PRIV (icon);
+       const gchar           *icon_name;
 
-static void
-status_icon_call_filter_new_channel (EmpathyFilter     *filter,
-                                    TpChannel         *channel,
-                                    EmpathyStatusIcon *icon)
-{
-       EmpathyTpGroup     *group;
-       EmpathyPendingInfo *invitation;
-       EmpathyContact     *contact = NULL;
-
-       empathy_debug (DEBUG_DOMAIN, "New media channel to be filtered");
-
-       /* FIXME: We have to check if the user is member or local-pending to
-        * know if it's an incoming or outgoing call because of the way we
-        * request media channels MC can't know if it's incoming or outgoing */
-       group = empathy_tp_group_new (channel);
-       empathy_run_until_ready (group);
-
-       invitation = empathy_tp_group_get_invitation (group, &contact); 
-       if (!invitation) {
-               empathy_debug (DEBUG_DOMAIN, "Process OUTGOING call channel");
-               empathy_filter_process (filter, channel, TRUE);
+       if (priv->event && priv->showing_event_icon) {
+               icon_name = priv->event->icon_name;
        } else {
-               StatusIconEvent *event;
-               gchar           *msg;
-
-               /* We are local pending, it's an incoming call, we need to ask
-                * the user if he wants to accept the call. */
-               empathy_contact_run_until_ready (contact,
-                                                EMPATHY_CONTACT_READY_NAME,
-                                                NULL);
-
-               empathy_debug (DEBUG_DOMAIN, "INCOMING call, add event");
-
-               msg = g_strdup_printf (_("Incoming call from %s:\n%s"),
-                                      empathy_contact_get_name (contact),
-                                      invitation->message);
-
-               g_object_set_data (G_OBJECT (group), "filter", filter);
-               g_object_set_data (G_OBJECT (group), "channel", channel);
-               event = status_icon_event_new (icon, EMPATHY_IMAGE_VOIP, msg);
-               event->func = status_icon_event_call_cb;
-               event->user_data = group;
-               g_free (msg);
-       }
+               McPresence state;
 
-       if (contact) {
-               g_object_unref (contact);
+               state = empathy_idle_get_state (priv->idle);
+               icon_name = empathy_icon_name_for_presence (state);
        }
+
+       gtk_status_icon_set_from_icon_name (priv->icon, icon_name);
 }
 
 static void
 status_icon_idle_notify_cb (EmpathyStatusIcon *icon)
 {
-       EmpathyStatusIconPriv *priv;
-       McPresence             flash_state;
-
-       priv = GET_PRIV (icon);
-
-       flash_state = empathy_idle_get_flash_state (priv->idle);
-       if (flash_state != MC_PRESENCE_UNSET) {
-               const gchar *icon_name;
-
-               icon_name = empathy_icon_name_for_presence (flash_state);
-               if (!priv->flash_state_event) {
-                       /* We are now flashing */
-                       priv->flash_state_event = status_icon_event_new (icon, icon_name, NULL);
-                       priv->flash_state_event->user_data = icon;
-                       priv->flash_state_event->func = status_icon_event_flash_state_cb;
-               } else {
-                       /* We are still flashing but with another state */
-                       g_free (priv->flash_state_event->icon_name);
-                       priv->flash_state_event->icon_name = g_strdup (icon_name);
-               }
-       }
-       else if (priv->flash_state_event) {
-               /* We are no more flashing */
-               status_icon_event_remove (icon, priv->flash_state_event);
-               priv->flash_state_event = NULL;
-       }
-
-       if (!priv->showing_event_icon) {
-               status_icon_set_from_state (icon);
-       }
-
+       status_icon_update_icon (icon);
        status_icon_update_tooltip (icon);
 }
 
-static void
-status_icon_update_tooltip (EmpathyStatusIcon *icon)
-{
-       EmpathyStatusIconPriv *priv;
-       const gchar           *tooltip = NULL;
-
-       priv = GET_PRIV (icon);
-
-       if (priv->events) {
-               StatusIconEvent *event;
-
-               event = priv->events->data;
-               tooltip = event->message;
-       }
-
-       if (!tooltip) {
-               tooltip = empathy_idle_get_status (priv->idle);
-       }
-
-       gtk_status_icon_set_tooltip (priv->icon, tooltip);      
-}
-
-static void
-status_icon_set_from_state (EmpathyStatusIcon *icon)
+static gboolean
+status_icon_delete_event_cb (GtkWidget         *widget,
+                            GdkEvent          *event,
+                            EmpathyStatusIcon *icon)
 {
-       EmpathyStatusIconPriv *priv;
-       McPresence             state;
-       const gchar           *icon_name;
-
-       priv = GET_PRIV (icon);
-
-       state = empathy_idle_get_state (priv->idle);
-       icon_name = empathy_icon_name_for_presence (state);
-       gtk_status_icon_set_from_icon_name (priv->icon, icon_name);
+       status_icon_set_visibility (icon, FALSE, TRUE);
+       return TRUE;
 }
 
 static void
-status_icon_set_visibility (EmpathyStatusIcon *icon,
-                           gboolean           visible,
-                           gboolean           store)
+status_icon_activate_cb (GtkStatusIcon     *status_icon,
+                        EmpathyStatusIcon *icon)
 {
-       EmpathyStatusIconPriv *priv;
-
-       priv = GET_PRIV (icon);
+       EmpathyStatusIconPriv *priv = GET_PRIV (icon);
 
-       if (store) {
-               empathy_conf_set_bool (empathy_conf_get (),
-                                      EMPATHY_PREFS_UI_MAIN_WINDOW_HIDDEN, !visible);
-       }
+       empathy_debug (DEBUG_DOMAIN, "Activated: %s",
+                      priv->event ? "event" : "toggle");
 
-       if (!visible) {
-               empathy_window_iconify (priv->window, priv->icon);
-       } else {
-               GList *accounts;
+       if (priv->event) {
+               empathy_filter_activate_event (priv->filter, priv->event);
+               priv->event = empathy_filter_get_top_event (priv->filter);
+               status_icon_update_tooltip (icon);
+               status_icon_update_icon (icon);
 
-               empathy_window_present (GTK_WINDOW (priv->window), TRUE);
-       
-               /* Show the accounts dialog if there is no enabled accounts */
-               accounts = mc_accounts_list_by_enabled (TRUE);
-               if (accounts) {
-                       mc_accounts_list_free (accounts);
-               } else {
-                       empathy_debug (DEBUG_DOMAIN,
-                                     "No enabled account, Showing account dialog");
-                       empathy_accounts_dialog_show (GTK_WINDOW (priv->window));
+               if (!priv->event && priv->blink_timeout) {
+                       g_source_remove (priv->blink_timeout);
+                       priv->blink_timeout = 0;
                }
+       } else {
+               status_icon_toggle_visibility (icon);
        }
 }
 
 static void
-status_icon_toggle_visibility (EmpathyStatusIcon *icon)
+status_icon_show_hide_window_cb (GtkWidget         *widget,
+                                EmpathyStatusIcon *icon)
 {
-       EmpathyStatusIconPriv *priv = GET_PRIV (icon);
-       gboolean               visible;
+       gboolean visible;
 
-       visible = gtk_window_is_active (priv->window);
-       status_icon_set_visibility (icon, !visible, TRUE);
+       visible = gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (widget));
+       status_icon_set_visibility (icon, visible, TRUE);
 }
 
 static void
-status_icon_activate_cb (GtkStatusIcon     *status_icon,
-                        EmpathyStatusIcon *icon)
+status_icon_new_message_cb (GtkWidget         *widget,
+                           EmpathyStatusIcon *icon)
 {
-       EmpathyStatusIconPriv *priv;
-
-       priv = GET_PRIV (icon);
-
-       empathy_debug (DEBUG_DOMAIN, "Activated: %s",
-                      priv->events ? "event" : "toggle");
-
-       if (priv->events) {
-               status_icon_event_remove (icon, priv->events->data);
-       } else {
-               status_icon_toggle_visibility (icon);
-       }
+       empathy_new_message_dialog_show (NULL);
 }
 
-static gboolean
-status_icon_delete_event_cb (GtkWidget         *widget,
-                            GdkEvent          *event,
-                            EmpathyStatusIcon *icon)
+static void
+status_icon_quit_cb (GtkWidget         *window,
+                    EmpathyStatusIcon *icon)
 {
-       status_icon_set_visibility (icon, FALSE, TRUE);
-
-       return TRUE;
+       gtk_main_quit ();
 }
 
 static void
@@ -549,12 +228,10 @@ status_icon_popup_menu_cb (GtkStatusIcon     *status_icon,
                           guint              activate_time,
                           EmpathyStatusIcon *icon)
 {
-       EmpathyStatusIconPriv *priv;
+       EmpathyStatusIconPriv *priv = GET_PRIV (icon);
        GtkWidget             *submenu;
        gboolean               show;
 
-       priv = GET_PRIV (icon);
-
        show = empathy_window_get_is_visible (GTK_WINDOW (priv->window));
 
        g_signal_handlers_block_by_func (priv->show_window_item,
@@ -581,12 +258,10 @@ status_icon_popup_menu_cb (GtkStatusIcon     *status_icon,
 static void
 status_icon_create_menu (EmpathyStatusIcon *icon)
 {
-       EmpathyStatusIconPriv *priv;
+       EmpathyStatusIconPriv *priv = GET_PRIV (icon);
        GladeXML              *glade;
        gchar                 *filename;
 
-       priv = GET_PRIV (icon);
-
        filename = empathy_file_lookup ("empathy-status-icon.glade", "src");
        glade = empathy_glade_get_file (filename,
                                       "tray_menu",
@@ -608,191 +283,116 @@ status_icon_create_menu (EmpathyStatusIcon *icon)
        g_object_unref (glade);
 }
 
-static void
-status_icon_new_message_cb (GtkWidget         *widget,
-                           EmpathyStatusIcon *icon)
+static gboolean
+status_icon_blink_timeout_cb (EmpathyStatusIcon *icon)
 {
-       EmpathyStatusIconPriv *priv;
+       EmpathyStatusIconPriv *priv = GET_PRIV (icon);
 
-       priv = GET_PRIV (icon);
+       priv->showing_event_icon = !priv->showing_event_icon;
+       status_icon_update_icon (icon);
 
-       empathy_new_message_dialog_show (NULL);
+       return TRUE;
 }
 
 static void
-status_icon_quit_cb (GtkWidget         *window,
-                    EmpathyStatusIcon *icon)
+status_icon_top_event_notify_cb (EmpathyStatusIcon *icon)
 {
-       gtk_main_quit ();
-}
+       EmpathyStatusIconPriv *priv = GET_PRIV (icon);
 
-static void
-status_icon_show_hide_window_cb (GtkWidget         *widget,
-                                EmpathyStatusIcon *icon)
-{
-       gboolean visible;
+       priv->event = empathy_filter_get_top_event (priv->filter);
+       priv->showing_event_icon = priv->event != NULL;
+       status_icon_update_icon (icon);
+       status_icon_update_tooltip (icon);
 
-       visible = gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (widget));
-       status_icon_set_visibility (icon, visible, TRUE);
+       if (!priv->blink_timeout) {
+               priv->blink_timeout = g_timeout_add (BLINK_TIMEOUT,
+                                                    (GSourceFunc) status_icon_blink_timeout_cb,
+                                                    icon);
+       }
 }
 
 static void
-status_icon_pendings_changed_cb (EmpathyContactManager *manager,
-                                EmpathyContact        *contact,
-                                EmpathyContact        *actor,
-                                guint                  reason,
-                                gchar                 *message,
-                                gboolean               is_pending,
-                                EmpathyStatusIcon     *icon)
+status_icon_finalize (GObject *object)
 {
-       EmpathyStatusIconPriv *priv;
-       StatusIconEvent       *event;
-       GString               *str;
-
-       priv = GET_PRIV (icon);
-
-       if (!is_pending) {
-               /* FIXME: We should remove the event */
-               return;
-       }
+       EmpathyStatusIconPriv *priv = GET_PRIV (object);
 
-       empathy_contact_run_until_ready (contact,
-                                        EMPATHY_CONTACT_READY_NAME,
-                                        NULL);
-
-       str = g_string_new (NULL);
-       g_string_printf (str, _("Subscription requested by %s"),
-                        empathy_contact_get_name (contact));   
-       if (!G_STR_EMPTY (message)) {
-               g_string_append_printf (str, _("\nMessage: %s"), message);
+       if (priv->blink_timeout) {
+               g_source_remove (priv->blink_timeout);
        }
 
-       event = status_icon_event_new (icon, GTK_STOCK_DIALOG_QUESTION, str->str);
-       event->user_data = g_object_ref (contact);
-       event->func = status_icon_event_subscribe_cb;
-
-       g_string_free (str, TRUE);
+       g_object_unref (priv->icon);
+       g_object_unref (priv->idle);
+       g_object_unref (priv->filter);
 }
 
 static void
-status_icon_event_subscribe_cb (StatusIconEvent *event)
+empathy_status_icon_class_init (EmpathyStatusIconClass *klass)
 {
-       EmpathyContact *contact;
-
-       contact = EMPATHY_CONTACT (event->user_data);
+       GObjectClass *object_class = G_OBJECT_CLASS (klass);
 
-       empathy_subscription_dialog_show (contact, NULL);
+       object_class->finalize = status_icon_finalize;
 
-       g_object_unref (contact);
+       g_type_class_add_private (object_class, sizeof (EmpathyStatusIconPriv));
 }
 
 static void
-status_icon_event_flash_state_cb (StatusIconEvent *event)
+empathy_status_icon_init (EmpathyStatusIcon *icon)
 {
-       EmpathyStatusIconPriv *priv;
-
-       priv = GET_PRIV (event->user_data);
-
-       empathy_idle_set_flash_state (priv->idle, MC_PRESENCE_UNSET);
-}
+       EmpathyStatusIconPriv *priv = GET_PRIV (icon);
 
-static void
-status_icon_event_msg_cb (StatusIconEvent *event)
-{
-       EmpathyFilter *filter;
-       EmpathyTpChat *tp_chat;
-       TpChannel     *channel;
+       priv->icon = gtk_status_icon_new ();
+       priv->idle = empathy_idle_new ();
+       priv->filter = empathy_filter_new ();
 
-       empathy_debug (DEBUG_DOMAIN, "Dispatching text channel");
+       /* make icon listen and respond to MAIN_WINDOW_HIDDEN changes */
+       empathy_conf_notify_add (empathy_conf_get (),
+                                EMPATHY_PREFS_UI_MAIN_WINDOW_HIDDEN,
+                                status_icon_notify_visibility_cb,
+                                icon);
 
-       tp_chat = event->user_data;
-       filter = g_object_get_data (G_OBJECT (tp_chat), "filter");
-       channel = g_object_get_data (G_OBJECT (tp_chat), "channel");
-       empathy_filter_process (filter, channel, TRUE);
+       status_icon_create_menu (icon);
+       status_icon_idle_notify_cb (icon);
 
-       g_object_unref (tp_chat);
+       g_signal_connect_swapped (priv->idle, "notify",
+                                 G_CALLBACK (status_icon_idle_notify_cb),
+                                 icon);
+       g_signal_connect_swapped (priv->filter, "notify::top-event",
+                                 G_CALLBACK (status_icon_top_event_notify_cb),
+                                 icon);
+       g_signal_connect (priv->icon, "activate",
+                         G_CALLBACK (status_icon_activate_cb),
+                         icon);
+       g_signal_connect (priv->icon, "popup-menu",
+                         G_CALLBACK (status_icon_popup_menu_cb),
+                         icon);
 }
 
-static StatusIconEvent *
-status_icon_event_new (EmpathyStatusIcon *icon,
-                      const gchar       *icon_name,
-                      const gchar       *message)
+EmpathyStatusIcon *
+empathy_status_icon_new (GtkWindow *window)
 {
        EmpathyStatusIconPriv *priv;
-       StatusIconEvent       *event;
-
-       priv = GET_PRIV (icon);
-
-       event = g_slice_new0 (StatusIconEvent);
-       event->icon_name = g_strdup (icon_name);        
-       event->message = g_strdup (message);
-
-       priv->events = g_list_append (priv->events, event);
-       if (!priv->blink_timeout) {
-               priv->showing_event_icon = FALSE;
-               priv->blink_timeout = g_timeout_add (BLINK_TIMEOUT,
-                                                    (GSourceFunc) status_icon_event_timeout_cb,
-                                                    icon);
-               status_icon_event_timeout_cb (icon);
-               status_icon_update_tooltip (icon);
-       }
-
-       return event;
-}
+       EmpathyStatusIcon     *icon;
+       gboolean               should_hide;
 
-static void
-status_icon_event_remove (EmpathyStatusIcon *icon,
-                         StatusIconEvent   *event)
-{
-       EmpathyStatusIconPriv *priv;
+       g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
 
+       icon = g_object_new (EMPATHY_TYPE_STATUS_ICON, NULL);
        priv = GET_PRIV (icon);
 
-       if (event->func) {
-               event->func (event);
-       }
-       priv->events = g_list_remove (priv->events, event);
-       status_icon_event_free (event);
-       priv->showing_event_icon = FALSE;
-       status_icon_update_tooltip (icon);
-       status_icon_set_from_state (icon);
-
-       if (priv->events) {
-               return;
-       }
-
-       if (priv->blink_timeout) {
-               g_source_remove (priv->blink_timeout);
-               priv->blink_timeout = 0;
-       }
-}
-
-static gboolean
-status_icon_event_timeout_cb (EmpathyStatusIcon *icon)
-{
-       EmpathyStatusIconPriv *priv;
-
-       priv = GET_PRIV (icon);
+       priv->window = g_object_ref (window);
 
-       priv->showing_event_icon = !priv->showing_event_icon;
+       g_signal_connect (priv->window, "delete-event",
+                         G_CALLBACK (status_icon_delete_event_cb),
+                         icon);
 
-       if (!priv->showing_event_icon) {
-               status_icon_set_from_state (icon);
-       } else {
-               StatusIconEvent *event;
+       empathy_conf_get_bool (empathy_conf_get (),
+                             EMPATHY_PREFS_UI_MAIN_WINDOW_HIDDEN,
+                             &should_hide);
 
-               event = priv->events->data;
-               gtk_status_icon_set_from_icon_name (priv->icon, event->icon_name);
+       if (gtk_window_is_active (priv->window) == should_hide) {
+               status_icon_set_visibility (icon, !should_hide, FALSE);
        }
 
-       return TRUE;
-}
-
-static void
-status_icon_event_free (StatusIconEvent *event)
-{
-       g_free (event->icon_name);
-       g_free (event->message);
-       g_slice_free (StatusIconEvent, event);
+       return icon;
 }
 
index 11eb3c5d7ab2a64d21121e9b34d10d2572c294f2..b55cc7bc2d686c105e2e4d1cb6bbe70d724e76ea 100644 (file)
 #include <libebook/e-book.h>
 
 #include <telepathy-glib/util.h>
-#include <telepathy-glib/channel.h>
-#include <telepathy-glib/connection.h>
 #include <libmissioncontrol/mc-account.h>
 #include <libmissioncontrol/mission-control.h>
 
 #include <libempathy/empathy-idle.h>
-#include <libempathy/empathy-tp-chat.h>
-#include <libempathy/empathy-chandler.h>
 #include <libempathy/empathy-utils.h>
 #include <libempathy/empathy-debug.h>
 
 #include <libempathy-gtk/empathy-conf.h>
-#include <libempathy-gtk/empathy-chat.h>
 
 #include "empathy-main-window.h"
 #include "empathy-status-icon.h"
-#include "empathy-chat-window.h"
 #include "bacon-message-connection.h"
 
 #define DEBUG_DOMAIN "EmpathyMain"
-#define BUS_NAME "org.gnome.Empathy.ChatChandler"
-#define OBJECT_PATH "/org/gnome/Empathy/ChatChandler"
 
 static BaconMessageConnection *connection = NULL;
 
-static void
-new_text_channel_cb (EmpathyChandler *chandler,
-                    TpChannel       *channel,
-                    MissionControl  *mc)
-{
-       EmpathyTpChat *tp_chat;
-       TpConnection  *connection;
-       guint          handle_type;
-       guint          handle;
-       gchar        **names;
-       McAccount     *account;
-       EmpathyChat   *chat;
-       gchar         *id;
-       GArray        *handles;
-
-       g_object_get (channel,
-                     "connection", &connection,
-                     "handle-type", &handle_type,
-                     "handle", &handle,
-                     NULL);
-       handles = g_array_new (FALSE, FALSE, sizeof (guint));
-       g_array_append_val (handles, handle);
-       tp_cli_connection_run_inspect_handles (connection, -1,
-                                              handle_type, handles,
-                                              &names,
-                                              NULL, NULL);
-       id = *names;
-       g_free (names);
-       g_object_unref (connection);
-       g_array_free (handles, TRUE);
-
-       account = empathy_channel_get_account (channel);
-       chat = empathy_chat_window_find_chat (account, id);
-       g_free (id);
-
-       if (chat) {
-               /* The chat already exists */
-               if (!empathy_chat_get_tp_chat (chat)) {
-                       /* The chat died, give him the new text channel */
-                       tp_chat = empathy_tp_chat_new (channel, TRUE);
-                       empathy_run_until_ready (tp_chat);
-                       empathy_chat_set_tp_chat (chat, tp_chat);
-                       g_object_unref (tp_chat);
-               }
-               empathy_chat_window_present_chat (chat);
-
-               g_object_unref (account);
-               return;
-       }
-
-       tp_chat = empathy_tp_chat_new (channel, TRUE);
-       empathy_run_until_ready (tp_chat);
-
-       chat = empathy_chat_new (tp_chat);
-       empathy_chat_window_present_chat (chat);
-
-       g_object_unref (account);
-       g_object_unref (tp_chat);
-}
-
 static void
 service_ended_cb (MissionControl *mc,
                  gpointer        user_data)
@@ -374,7 +306,6 @@ main (int argc, char *argv[])
        GtkWidget         *window;
        MissionControl    *mc;
        EmpathyIdle       *idle;
-       EmpathyChandler   *chandler;
        gboolean           autoconnect = TRUE;
        gboolean           no_connect = FALSE; 
        GError            *error = NULL;
@@ -470,18 +401,10 @@ main (int argc, char *argv[])
                                                       window);
        }
 
-       /* Handle text channels */
-       chandler = empathy_chandler_new (BUS_NAME, OBJECT_PATH);
-       g_signal_connect (chandler, "new-channel",
-                         G_CALLBACK (new_text_channel_cb),
-                         mc);
-       empathy_debug (DEBUG_DOMAIN, "Ready to handle new text channels");
-
        gtk_main ();
 
        empathy_idle_set_state (idle, MC_PRESENCE_OFFLINE);
 
-       g_object_unref (chandler);
        g_object_unref (mc);
        g_object_unref (idle);
        g_object_unref (icon);
diff --git a/src/org.gnome.Empathy.Call.service.in b/src/org.gnome.Empathy.Call.service.in
deleted file mode 100644 (file)
index 1c4b95f..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-[D-BUS Service]
-Name=org.gnome.Empathy.CallChandler
-Exec=@libexecdir@/empathy-call-chandler
diff --git a/src/org.gnome.Empathy.Chat.service.in b/src/org.gnome.Empathy.Chat.service.in
deleted file mode 100644 (file)
index 2e614d9..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-[D-BUS Service]
-Name=org.gnome.Empathy.ChatChandler
-Exec=@bindir@/empathy