aboutsummaryrefslogtreecommitdiffstats
path: root/debian/patches
diff options
context:
space:
mode:
Diffstat (limited to 'debian/patches')
-rw-r--r--debian/patches/01_lpi.patch74
-rw-r--r--debian/patches/02_notifications_focus.patch14
-rw-r--r--debian/patches/10_use_notify_osd_icons.patch21
-rw-r--r--debian/patches/11_empathy_accounts_category.patch16
-rw-r--r--debian/patches/20_libindicate.patch1652
-rw-r--r--debian/patches/21_login_indicators.patch58
-rw-r--r--debian/patches/23_idomessagedialog_for_voip_and_ft.patch208
-rw-r--r--debian/patches/31_really_raise_window.patch75
-rw-r--r--debian/patches/34_start_raised_execpt_in_session.patch35
-rw-r--r--debian/patches/36_chat_window_default_size.patch21
-rw-r--r--debian/patches/37_facebook_default.patch21
-rw-r--r--debian/patches/38_lp_569289.patch13
-rw-r--r--debian/patches/40_unity_launcher_count.patch282
-rw-r--r--debian/patches/41_unity_launcher_progress.patch159
-rw-r--r--debian/patches/series14
15 files changed, 2663 insertions, 0 deletions
diff --git a/debian/patches/01_lpi.patch b/debian/patches/01_lpi.patch
new file mode 100644
index 000000000..234872333
--- /dev/null
+++ b/debian/patches/01_lpi.patch
@@ -0,0 +1,74 @@
+=== modified file 'configure.ac'
+--- a/configure.ac
++++ b/configure.ac
+@@ -161,6 +161,7 @@
+ telepathy-glib >= $TELEPATHY_GLIB_REQUIRED
+ telepathy-logger-0.2 >= $TELEPATHY_LOGGER
+ x11
++ launchpad-integration
+ ])
+
+ PKG_CHECK_MODULES(YELL, [telepathy-yell])
+--- a/src/empathy-chat-window.c
++++ b/src/empathy-chat-window.c
+@@ -36,6 +36,9 @@
+ #include <glib/gi18n.h>
+ #include <libnotify/notification.h>
+
++/* Add launchpad hooks */
++#include <launchpad-integration.h>
++
+ #include <telepathy-glib/telepathy-glib.h>
+
+ #include <libempathy/empathy-contact.h>
+@@ -2090,6 +2093,9 @@
+ chat_window_chat_manager_chats_changed_cb (priv->chat_manager,
+ empathy_chat_manager_get_num_chats (priv->chat_manager),
+ window);
++
++ /* Add launchpad hooks */
++ launchpad_integration_add_ui (priv->ui_manager, "/chats_menubar/menu_help/LaunchpadItems");
+ }
+
+ EmpathyChatWindow *
+--- a/src/empathy-chat-window.ui
++++ b/src/empathy-chat-window.ui
+@@ -197,6 +197,7 @@
+ </menu>
+ <menu action="menu_help">
+ <menuitem action="menu_help_contents"/>
++ <placeholder name="LaunchpadItems"/>
+ <menuitem action="menu_help_about"/>
+ </menu>
+ </menubar>
+--- a/src/empathy-main-window.c
++++ b/src/empathy-main-window.c
+@@ -33,6 +33,9 @@
+ #include <telepathy-glib/util.h>
+ #include <folks/folks.h>
+
++/* Add launchpad hooks */
++#include <launchpad-integration.h>
++
+ #include <libempathy/empathy-contact.h>
+ #include <libempathy/empathy-idle.h>
+ #include <libempathy/empathy-utils.h>
+@@ -2112,6 +2115,8 @@
+ main_window_notify_contact_list_size_cb (priv->gsettings_ui,
+ EMPATHY_PREFS_UI_SHOW_AVATARS,
+ window);
++
++ launchpad_integration_add_ui (priv->ui_manager, "/menubar/help/LaunchpadItems");
+ }
+
+ GtkWidget *
+--- a/src/empathy-main-window.ui
++++ b/src/empathy-main-window.ui
+@@ -277,6 +277,7 @@
+ <menu action="help">
+ <menuitem action="help_contents"/>
+ <menuitem action="help_debug"/>
++ <placeholder name="LaunchpadItems"/>
+ <menuitem action="help_about"/>
+ </menu>
+ </menubar>
diff --git a/debian/patches/02_notifications_focus.patch b/debian/patches/02_notifications_focus.patch
new file mode 100644
index 000000000..1156207b2
--- /dev/null
+++ b/debian/patches/02_notifications_focus.patch
@@ -0,0 +1,14 @@
+## Description: add some description
+## Origin/Author: add some origin or author
+## Bug: bug URL
+--- a/data/org.gnome.Empathy.gschema.xml.in
++++ b/data/org.gnome.Empathy.gschema.xml.in
+@@ -153,7 +153,7 @@
+ <_description>Whether to show popup notifications when away or busy.</_description>
+ </key>
+ <key name="notifications-focus" type="b">
+- <default>false</default>
++ <default>true</default>
+ <_summary>Pop up notifications if the chat isn't focused</_summary>
+ <_description>Whether to show a popup notification when receiving a new message even if the chat is already opened, but not focused.</_description>
+ </key>
diff --git a/debian/patches/10_use_notify_osd_icons.patch b/debian/patches/10_use_notify_osd_icons.patch
new file mode 100644
index 000000000..09f3c7d05
--- /dev/null
+++ b/debian/patches/10_use_notify_osd_icons.patch
@@ -0,0 +1,21 @@
+Description: Use the notify-osd image for new messages
+Bug: https://bugs.edge.launchpad.net/ubuntu/karmic/+source/empathy/+bug/409828
+
+From 18170177bf037f682438ddcb93b8682563db7c64 Mon Sep 17 00:00:00 2001
+From: Robert Ancell <robert.ancell@canonical.com>
+Date: Thu, 17 Sep 2009 17:42:26 +1000
+Subject: [PATCH] Use the notify-osd image for new messages
+
+Index: empathy-2.31.3/libempathy-gtk/empathy-images.h
+===================================================================
+--- empathy-2.31.3.orig/libempathy-gtk/empathy-images.h 2010-06-18 12:19:59.454507811 +1000
++++ empathy-2.31.3/libempathy-gtk/empathy-images.h 2010-06-18 12:20:06.804510537 +1000
+@@ -36,7 +36,7 @@
+ #define EMPATHY_IMAGE_PENDING "empathy-pending"
+
+ #define EMPATHY_IMAGE_MESSAGE "im-message"
+-#define EMPATHY_IMAGE_NEW_MESSAGE "im-message-new"
++#define EMPATHY_IMAGE_NEW_MESSAGE "notification-message-im"
+ #define EMPATHY_IMAGE_TYPING "user-typing"
+ #define EMPATHY_IMAGE_CONTACT_INFORMATION "gtk-info"
+ #define EMPATHY_IMAGE_GROUP_MESSAGE "system-users"
diff --git a/debian/patches/11_empathy_accounts_category.patch b/debian/patches/11_empathy_accounts_category.patch
new file mode 100644
index 000000000..edacba337
--- /dev/null
+++ b/debian/patches/11_empathy_accounts_category.patch
@@ -0,0 +1,16 @@
+Description: Put empathy-accounts in correct category
+Bug: https://bugzilla.gnome.org/show_bug.cgi?id=611913
+
+Index: empathy-2.32.2/data/empathy-accounts.desktop.in.in
+===================================================================
+--- empathy-2.32.2.orig/data/empathy-accounts.desktop.in.in 2010-11-24 17:22:17.415693001 +1100
++++ empathy-2.32.2/data/empathy-accounts.desktop.in.in 2010-11-24 17:22:20.075693001 +1100
+@@ -7,7 +7,7 @@
+ StartupNotify=true
+ Terminal=false
+ Type=Application
+-Categories=GNOME;GTK;Settings;DesktopSettings;
++Categories=GNOME;GTK;Settings;X-GNOME-PersonalSettings;
+ X-GNOME-Settings-Panel=empathy-accounts
+ X-GNOME-Bugzilla-Bugzilla=GNOME
+ X-GNOME-Bugzilla-Product=empathy
diff --git a/debian/patches/20_libindicate.patch b/debian/patches/20_libindicate.patch
new file mode 100644
index 000000000..ff78d8bf8
--- /dev/null
+++ b/debian/patches/20_libindicate.patch
@@ -0,0 +1,1652 @@
+=== modified file 'configure.ac'
+--- a/configure.ac
++++ b/configure.ac
+@@ -56,6 +56,8 @@
+ NETWORK_MANAGER_REQUIRED=0.7.0
+ WEBKIT_REQUIRED=1.1.15
+ GNOME_CONTROL_CENTER_GTK3_REQUIRED=2.31.4
++INDICATE_REQUIRED=0.4.91
++INDICATE_GTK_REQUIRED=0.4.91
+
+ # telepathy-yell
+ prev_top_build_prefix=$ac_top_build_prefix
+@@ -480,6 +482,34 @@
+ AC_SUBST(MEEGO_LIBS)
+
+ # -----------------------------------------------------------
++# libindicate
++# -----------------------------------------------------------
++AC_ARG_ENABLE(libindicate,
++ AS_HELP_STRING([--enable-libindicate=@<:@no/yes/auto@:>@],
++ [build libindicate support]), ,
++ enable_libindicate=auto)
++
++if test "x$enable_libindicate" != "xno"; then
++ PKG_CHECK_MODULES(INDICATE,
++ [
++ indicate-0.5 >= $INDICATE_REQUIRED,
++ indicate-gtk-0.5 >= $INDICATE_GTK_REQUIRED
++ ], have_libindicate="yes", have_libindicate="no")
++
++ if test "x$have_libindicate" = "xyes"; then
++ AC_DEFINE(HAVE_LIBINDICATE, 1, [Define if you have libindicate])
++ fi
++else
++ have_libindicate=no
++fi
++
++if test "x$enable_libindicate" = "xyes" -a "x$have_libindicate" != "xyes"; then
++ AC_MSG_ERROR([Couldn't find libindicate.])
++fi
++
++AM_CONDITIONAL(HAVE_LIBINDICATE, test "x$have_libindicate" = "xyes")
++
++# -----------------------------------------------------------
+ # nautilus-sendto
+ # -----------------------------------------------------------
+ AC_ARG_ENABLE(nautilus-sendto,
+@@ -581,6 +611,7 @@
+ CA Cert Path................: ${GTLS_SYSTEM_CA_FILE}
+
+ Features:
++ Message indicator support (libindicate): ${have_libindicate}
+ Spell checking (enchant)....: ${have_enchant}
+ Display maps (libchamplain).: ${have_libchamplain}
+ Location awareness (Geoclue): ${have_geoclue}
+--- a/data/org.gnome.Empathy.gschema.xml.in
++++ b/data/org.gnome.Empathy.gschema.xml.in
+@@ -86,6 +86,11 @@
+ <_summary>The position for the chat window side pane</_summary>
+ <_description>The stored position (in pixels) of the chat window side pane.</_description>
+ </key>
++ <key name="use-libindicate" type="b">
++ <default>true</default>
++ <summary>Use the messaging indicator</summary>
++ <description>Whether or not to use the messaging indicator, if false the icon in the notification area will be displayed.</description>
++ </key>
+ </schema>
+ <schema id="org.gnome.Empathy.contacts" path="/apps/empathy/contacts/">
+ <key name="sort-criterium" type="s">
+--- a/libempathy-gtk/empathy-ui-utils.c
++++ b/libempathy-gtk/empathy-ui-utils.c
+@@ -1567,25 +1567,36 @@
+ Display *dpy;
+ GdkWindow *gdk_window;
+
+- gtk_status_icon_get_geometry (status_icon, NULL, &icon_location, NULL);
+- gdk_window = gtk_widget_get_window (GTK_WIDGET (window));
+- dpy = gdk_x11_drawable_get_xdisplay (gdk_window);
++ // If the status icon isn't visible (because indicators are used) then
++ // attempting to change the properties of the status icon doesn't work.
++ if (gtk_status_icon_get_visible (status_icon)) {
++ gtk_status_icon_get_geometry (status_icon, NULL, &icon_location, NULL);
++ gdk_window = gtk_widget_get_window (GTK_WIDGET (window));
++ dpy = gdk_x11_drawable_get_xdisplay (gdk_window);
+
+- data[0] = icon_location.x;
+- data[1] = icon_location.y;
+- data[2] = icon_location.width;
+- data[3] = icon_location.height;
++ data[0] = icon_location.x;
++ data[1] = icon_location.y;
++ data[2] = icon_location.width;
++ data[3] = icon_location.height;
+
+- XChangeProperty (dpy,
+- GDK_WINDOW_XID (gdk_window),
+- gdk_x11_get_xatom_by_name_for_display (
+- gdk_drawable_get_display (gdk_window),
+- "_NET_WM_ICON_GEOMETRY"),
+- XA_CARDINAL, 32, PropModeReplace,
+- (guchar *)&data, 4);
++ XChangeProperty (dpy,
++ GDK_WINDOW_XID (gdk_window),
++ gdk_x11_get_xatom_by_name_for_display (
++ gdk_drawable_get_display (gdk_window),
++ "_NET_WM_ICON_GEOMETRY"),
++ XA_CARDINAL, 32, PropModeReplace,
++ (guchar *)&data, 4);
++ }
+
+ gtk_window_set_skip_taskbar_hint (window, TRUE);
+- gtk_window_iconify (window);
++ // If the status icon isn't present then the WM will probably choose to
++ // iconfy to the taskbar, which doesn't look as good as the taskbar
++ // entry has just been removed. Just hide instead.
++ if (gtk_status_icon_get_visible (status_icon)) {
++ gtk_window_iconify (window);
++ } else {
++ gtk_widget_hide (GTK_WIDGET(window));
++ }
+ }
+
+ /* Takes care of moving the window to the current workspace. */
+--- a/libempathy/empathy-gsettings.h
++++ b/libempathy/empathy-gsettings.h
+@@ -71,6 +71,7 @@
+ #define EMPATHY_PREFS_UI_SHOW_AVATARS "show-avatars"
+ #define EMPATHY_PREFS_UI_SHOW_PROTOCOLS "show-protocols"
+ #define EMPATHY_PREFS_UI_COMPACT_CONTACT_LIST "compact-contact-list"
++#define EMPATHY_PREFS_UI_USE_LIBINDICATE "use-libindicate"
+ #define EMPATHY_PREFS_UI_CHAT_WINDOW_PANED_POS "chat-window-paned-pos"
+ #define EMPATHY_PREFS_UI_SHOW_OFFLINE "show-offline"
+
+--- a/po/POTFILES.in
++++ b/po/POTFILES.in
+@@ -97,6 +97,8 @@
+ [type: gettext/glade]src/empathy-ft-manager.ui
+ src/empathy-import-dialog.c
+ src/empathy-import-widget.c
++src/empathy-indicator.c
++src/empathy-indicator-manager.c
+ [type: gettext/glade]src/empathy-import-dialog.ui
+ src/empathy-import-widget.c
+ src/empathy-main-window.c
+--- a/src/Makefile.am
++++ b/src/Makefile.am
+@@ -8,6 +8,7 @@
+ $(ERROR_CFLAGS) \
+ -I$(top_srcdir) \
+ -DG_LOG_DOMAIN=\"empathy\" \
++ -DDESKTOPDIR=\"$(datadir)/applications\" \
+ -DBIN_DIR=\"$(bindir)\" \
+ $(DISABLE_DEPRECATED) \
+ $(WARN_CFLAGS) \
+@@ -17,6 +18,7 @@
+ AM_CPPFLAGS = \
+ $(CPPFLAGS_COMMON) \
+ $(LIBNOTIFY_CFLAGS) \
++ $(INDICATE_CFLAGS) \
+ $(UNIQUE_CFLAGS) \
+ $(LIBCHAMPLAIN_CFLAGS) \
+ $(WEBKIT_CFLAGS) \
+@@ -27,6 +29,7 @@
+ $(top_builddir)/libempathy/libempathy.la \
+ $(top_builddir)/extensions/libemp-extensions.la \
+ $(LIBNOTIFY_LIBS) \
++ $(INDICATE_LIBS) \
+ $(UNIQUE_LIBS) \
+ $(EMPATHY_LIBS) \
+ $(GTK_LIBS) \
+@@ -200,6 +203,7 @@
+ $(LIBNOTIFY_LIBS) \
+ $(UNIQUE_LIBS) \
+ $(EMPATHY_LIBS) \
++ $(INDICATE_LIBS) \
+ $(LIBCHAMPLAIN_LIBS) \
+ $(WEBKIT_LIBS) \
+ $(NULL)
+@@ -232,6 +236,18 @@
+ $(autostart_DATA) \
+ $(ui_DATA)
+
++if HAVE_LIBINDICATE
++empathy_handwritten_source += \
++ empathy-indicator-manager.c \
++ empathy-indicator-manager.h \
++ empathy-indicator.c empathy-indicator.h
++else
++EXTRA_DIST += \
++ empathy-indicator-manager.c \
++ empathy-indicator-manager.h \
++ empathy-indicator.c empathy-indicator.h
++endif
++
+ if HAVE_LIBCHAMPLAIN
+ empathy_handwritten_source += \
+ empathy-map-view.c \
+--- a/src/empathy-chat-window.c
++++ b/src/empathy-chat-window.c
+@@ -63,6 +63,11 @@
+ #include "empathy-about-dialog.h"
+ #include "empathy-invite-participant-dialog.h"
+
++#ifdef HAVE_LIBINDICATE
++#include "empathy-indicator.h"
++#include "empathy-indicator-manager.h"
++#endif
++
+ #define DEBUG_FLAG EMPATHY_DEBUG_CHAT
+ #include <libempathy/empathy-debug.h>
+
+@@ -86,7 +91,11 @@
+ GtkWidget *dialog;
+ GtkWidget *notebook;
+ NotifyNotification *notification;
+-
++#ifdef HAVE_LIBINDICATE
++ EmpathyIndicatorManager *indicator_manager;
++ /* EmpathyChat -> EmpathyIndicator for that chat, if any */
++ GHashTable *indicators;
++#endif
+ GtkTargetList *contact_targets;
+ GtkTargetList *file_targets;
+
+@@ -1278,6 +1287,72 @@
+ }
+ }
+
++#ifdef HAVE_LIBINDICATE
++static void
++chat_window_indicator_activate_cb (EmpathyIndicator *indicator, guint timestamp,
++ EmpathyChat *chat)
++{
++ empathy_chat_window_present_chat (chat, timestamp);
++ empathy_indicator_hide (indicator);
++}
++
++static void
++chat_window_add_indicator (EmpathyChatWindow *window,
++ EmpathyMessage *message,
++ EmpathyChat *chat)
++{
++ EmpathyChatWindowPriv *priv = GET_PRIV (window);
++ EmpathyContact *sender;
++ const char *body;
++ gboolean use_libindicate;
++ EmpathyIndicator *indicator = NULL;
++ GSettings *gsettings;
++
++ gsettings = g_settings_new (EMPATHY_PREFS_UI_SCHEMA);
++ use_libindicate = g_settings_get_boolean (gsettings, EMPATHY_PREFS_UI_USE_LIBINDICATE);
++ g_object_unref (gsettings);
++
++ if (!use_libindicate) {
++ return;
++ }
++
++ sender = empathy_message_get_sender (message);
++ body = empathy_message_get_body (message);
++
++ indicator = g_hash_table_lookup (priv->indicators, chat);
++ if (indicator != NULL) {
++ DEBUG ("indicator exists");
++ empathy_indicator_update (indicator, body);
++ } else {
++ DEBUG ("indicator doesn't exist yet, creating a new indicator");
++ indicator = empathy_indicator_manager_create_indicator (priv->indicator_manager,
++ sender, body);
++ g_signal_connect (indicator, "activate",
++ G_CALLBACK (chat_window_indicator_activate_cb), chat);
++
++ g_hash_table_insert (priv->indicators, chat, indicator);
++ }
++ empathy_indicator_show (indicator);
++}
++
++static void
++chat_window_remove_indicator (EmpathyChatWindow *window, EmpathyChat *chat)
++{
++ EmpathyIndicator *indicator = NULL;
++ EmpathyChatWindowPriv *priv = GET_PRIV (window);
++
++ indicator = g_hash_table_lookup (priv->indicators, chat);
++
++ if ((indicator) && (indicator != NULL)) {
++ DEBUG ("indicator is %p", indicator);
++ empathy_indicator_hide (indicator);
++ g_hash_table_remove (priv->indicators, chat);
++ } else {
++ DEBUG ("indicator is NULL, nothing to remove");
++ }
++}
++#endif
++
+ static void
+ chat_window_show_or_update_notification (EmpathyChatWindow *window,
+ EmpathyMessage *message,
+@@ -1454,6 +1529,9 @@
+
+ empathy_sound_play (GTK_WIDGET (priv->dialog),
+ EMPATHY_SOUND_MESSAGE_INCOMING);
++#ifdef HAVE_LIBINDICATE
++ chat_window_add_indicator (window, message, chat);
++#endif
+
+ /* Pending messages have already been displayed in the approver, so we don't
+ * display a notification for those. */
+@@ -1526,6 +1604,10 @@
+ empathy_chat_messages_read (chat);
+
+ chat_window_update_chat_tab (chat);
++
++#ifdef HAVE_LIBINDICATE
++ chat_window_remove_indicator (window, chat);
++#endif
+ }
+
+ static void
+@@ -1642,6 +1724,11 @@
+ /* Update the title, since we now mark all unread messages as read. */
+ chat_window_update_chat_tab_full (priv->current_chat, FALSE);
+
++#ifdef HAVE_LIBINDICATE
++ /* Remove the indicator for the active chat */
++ chat_window_remove_indicator (window, priv->current_chat);
++#endif
++
+ return FALSE;
+ }
+
+@@ -1986,6 +2073,11 @@
+ g_object_unref (gui);
+
+ priv->chatroom_manager = empathy_chatroom_manager_dup_singleton (NULL);
++#ifdef HAVE_LIBINDICATE
++ priv->indicator_manager = empathy_indicator_manager_dup_singleton ();
++ priv->indicators = g_hash_table_new_full (g_direct_hash, g_direct_equal,
++ NULL, g_object_unref);
++#endif
+
+ priv->notebook = gtk_notebook_new ();
+ gtk_notebook_set_group (GTK_NOTEBOOK (priv->notebook), "EmpathyChatWindow");
+--- /dev/null
++++ b/src/empathy-indicator-manager.c
+@@ -0,0 +1,467 @@
++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
++/*
++ * Copyright (C) 2009 Canonical Ltd.
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public
++ * License along with this program; if not, write to the
++ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
++ * Boston, MA 02110-1301 USA
++ *
++ * Authors: James Westby <james.westby@ubuntu.com>
++ *
++ */
++
++#include <config.h>
++
++#include <gtk/gtk.h>
++
++#include <libempathy/empathy-contact.h>
++#include <libempathy/empathy-dispatcher.h>
++#include <libempathy/empathy-utils.h>
++
++#include <libempathy-gtk/empathy-ui-utils.h>
++#include <libempathy-gtk/empathy-notify-manager.h>
++
++#include <telepathy-glib/util.h>
++
++#include "empathy-event-manager.h"
++#include "empathy-indicator.h"
++#include "empathy-indicator-manager.h"
++
++#include <libindicate/server.h>
++#include <libindicate/indicator.h>
++
++#define DEBUG_FLAG EMPATHY_DEBUG_OTHER
++#include <libempathy/empathy-debug.h>
++
++#define INDICATOR_LOGIN_TIMEOUT 15
++#define EMPATHY_DESKTOP_PATH DESKTOPDIR "/empathy.desktop"
++
++#define GET_PRIV(obj) EMPATHY_GET_PRIV (obj, EmpathyIndicatorManager)
++
++enum {
++ SERVER_ACTIVATE,
++ LAST_SIGNAL
++};
++
++static guint signals[LAST_SIGNAL];
++
++typedef struct {
++ EmpathyEventManager *event_manager;
++ IndicateServer *indicate_server;
++ GSList *indicator_events;
++ GHashTable *login_timeouts;
++} EmpathyIndicatorManagerPriv;
++
++typedef struct {
++ EmpathyIndicator *indicator;
++ EmpathyEvent *event;
++} IndicatorEvent;
++
++typedef struct {
++ EmpathyIndicatorManager *manager;
++ EmpathyIndicator *indicator;
++} LoginData;
++
++G_DEFINE_TYPE (EmpathyIndicatorManager, empathy_indicator_manager, G_TYPE_OBJECT);
++
++static EmpathyIndicatorManager *manager_singleton = NULL;
++
++static EmpathyEvent *
++event_copy (EmpathyEvent *event)
++{
++ EmpathyEvent *ret = g_new0 (EmpathyEvent, 1);
++
++ ret->contact = g_object_ref (event->contact);
++ ret->icon_name = g_strdup (event->icon_name);
++ ret->header = g_strdup (event->header);
++ ret->message = g_strdup (event->message);
++ ret->must_ack = event->must_ack;
++
++ return ret;
++}
++
++static gboolean
++compare_events (EmpathyEvent *ev1, EmpathyEvent *ev2)
++{
++ return ((g_strcmp0 (ev1->icon_name, ev2->icon_name) == 0) &&
++ (g_strcmp0 (ev1->header, ev2->header) == 0) &&
++ (ev1->must_ack == ev2->must_ack) &&
++ (ev1->contact == ev2->contact));
++}
++
++static IndicatorEvent *
++indicator_event_new (EmpathyIndicator *indicator,
++ EmpathyEvent *event)
++{
++ IndicatorEvent *indicator_event;
++
++ indicator_event = g_slice_new0 (IndicatorEvent);
++ indicator_event->indicator = g_object_ref (indicator);
++ indicator_event->event = event_copy (event);
++
++ return indicator_event;
++}
++
++
++static void
++indicator_event_free (IndicatorEvent *indicator_event)
++{
++ g_object_unref (indicator_event->indicator);
++ g_free (indicator_event);
++}
++
++
++static void
++indicate_server_activate (IndicateServer *server, guint timestamp,
++ EmpathyIndicatorManager *manager)
++{
++ g_signal_emit (manager, signals[SERVER_ACTIVATE], 0, timestamp);
++}
++
++
++static void
++indicate_show_cb (EmpathyIndicator *indicator, guint timestamp,
++ EmpathyEvent *event)
++{
++ empathy_event_activate (event);
++}
++
++
++static void
++indicator_manager_event_added_cb (EmpathyEventManager *event_manager,
++ EmpathyEvent *event,
++ EmpathyIndicatorManager *manager)
++{
++ EmpathyIndicator *indicator = NULL;
++ EmpathyIndicatorManagerPriv *priv;
++ IndicatorEvent *indicator_event;
++
++ priv = GET_PRIV (manager);
++
++ DEBUG ("Event added");
++
++ if (event->contact == NULL)
++ return;
++
++ indicator = empathy_indicator_new (event->contact, event->message, "im");
++ if (indicator == NULL) {
++ return;
++ }
++
++ empathy_indicator_show (indicator);
++ g_signal_connect (G_OBJECT(indicator), "activate",
++ G_CALLBACK (indicate_show_cb),
++ event);
++ indicator_event = indicator_event_new (indicator, event);
++ g_object_unref (indicator);
++ priv->indicator_events = g_slist_prepend (priv->indicator_events,
++ indicator_event);
++}
++
++static void
++indicator_manager_event_removed_cb (EmpathyEventManager *event_manager,
++ EmpathyEvent *event,
++ EmpathyIndicatorManager *manager)
++{
++ EmpathyIndicatorManagerPriv *priv;
++ GSList *l;
++
++ priv = GET_PRIV (manager);
++
++ DEBUG ("Event removed");
++
++ for (l = priv->indicator_events; l; l = l->next)
++ {
++ IndicatorEvent *indicator_event;
++ indicator_event = l->data;
++
++ if (compare_events (indicator_event->event, event)) {
++ priv->indicator_events = g_slist_remove (priv->indicator_events,
++ indicator_event);
++ empathy_indicator_hide (indicator_event->indicator);
++ return;
++ }
++ }
++}
++
++
++static void
++indicator_manager_event_updated_cb (EmpathyEventManager *event_manager,
++ EmpathyEvent *event,
++ EmpathyIndicatorManager *manager)
++{
++ EmpathyIndicatorManagerPriv *priv;
++ GSList *l;
++
++ priv = GET_PRIV (manager);
++
++ for (l = priv->indicator_events; l; l = l->next)
++ {
++ IndicatorEvent *indicator_event;
++ indicator_event = l->data;
++ if (compare_events (indicator_event->event, event)) {
++ empathy_indicator_update (indicator_event->indicator,
++ event->message);
++ return;
++ }
++ }
++}
++
++
++/* Remove the login indicator when it times out */
++static gboolean
++indicate_login_timeout (gpointer data)
++{
++ LoginData *login_data;
++ EmpathyIndicator *e_indicator;
++ EmpathyIndicatorManager *manager;
++ EmpathyIndicatorManagerPriv *priv;
++
++ login_data = (LoginData *) data;
++ e_indicator = login_data->indicator;
++ manager = login_data->manager;
++ priv = GET_PRIV (manager);
++
++ empathy_indicator_hide (e_indicator);
++ g_hash_table_remove (priv->login_timeouts, e_indicator);
++
++ return FALSE;
++}
++
++
++static void
++indicate_login_cb (EmpathyIndicator *e_indicator, guint timestamp,
++ EmpathyIndicatorManager *manager)
++{
++ EmpathyIndicatorManagerPriv *priv;
++ GSList *events, *l;
++ EmpathyContact *contact;
++
++ priv = GET_PRIV (manager);
++
++ empathy_indicator_hide (e_indicator);
++ g_hash_table_remove (priv->login_timeouts, e_indicator);
++
++ contact = empathy_indicator_get_contact (e_indicator);
++ /* If the contact has an event activate it, otherwise the
++ * default handler of row-activated will be called. */
++ events = empathy_event_manager_get_events (priv->event_manager);
++ for (l = events; l; l = l->next) {
++ EmpathyEvent *event;
++
++ event = l->data;
++ if (event->contact == contact) {
++ empathy_event_activate (event);
++ return;
++ }
++ }
++
++ /* Else start a new conversation */
++ empathy_dispatcher_chat_with_contact (contact, timestamp);
++}
++
++
++EmpathyIndicatorManager *
++empathy_indicator_manager_dup_singleton (void)
++{
++ return g_object_new (EMPATHY_TYPE_INDICATOR_MANAGER, NULL);
++}
++
++
++static void
++indicator_manager_dispose (GObject *object)
++{
++ EmpathyIndicatorManagerPriv *priv;
++
++ priv = GET_PRIV (object);
++
++ if (priv->indicator_events) {
++ g_slist_foreach (priv->indicator_events, (GFunc) indicator_event_free,
++ NULL);
++ g_slist_free (priv->indicator_events);
++ priv->indicator_events = NULL;
++ }
++ if (priv->event_manager) {
++ g_object_unref (priv->event_manager);
++ priv->event_manager = NULL;
++ }
++ if (priv->indicate_server) {
++ g_object_unref (priv->indicate_server);
++ priv->indicate_server = NULL;
++ }
++ if (priv->login_timeouts) {
++ g_hash_table_unref (priv->login_timeouts);
++ priv->login_timeouts = NULL;
++ }
++
++ G_OBJECT_CLASS (empathy_indicator_manager_parent_class)->dispose (object);
++}
++
++
++static GObject *
++indicator_manager_constructor (GType type,
++ guint n_props,
++ GObjectConstructParam *props)
++{
++ GObject *retval;
++
++ if (manager_singleton != NULL) {
++ retval = g_object_ref (manager_singleton);
++ } else {
++ retval = G_OBJECT_CLASS (empathy_indicator_manager_parent_class)->constructor
++ (type, n_props, props);
++
++ manager_singleton = EMPATHY_INDICATOR_MANAGER (retval);
++ g_object_add_weak_pointer (retval, (gpointer) &manager_singleton);
++ }
++
++ return retval;
++}
++
++
++static void
++empathy_indicator_manager_class_init (EmpathyIndicatorManagerClass *klass)
++{
++ GObjectClass *object_class;
++
++ object_class = G_OBJECT_CLASS (klass);
++ object_class->dispose = indicator_manager_dispose;
++ object_class->constructor = indicator_manager_constructor;
++
++ signals[SERVER_ACTIVATE] =
++ g_signal_new ("server-activate",
++ G_TYPE_FROM_CLASS (klass),
++ G_SIGNAL_RUN_LAST,
++ 0,
++ NULL, NULL,
++ g_cclosure_marshal_VOID__UINT,
++ G_TYPE_NONE, 1, G_TYPE_UINT);
++
++ g_type_class_add_private (object_class, sizeof (EmpathyIndicatorManagerPriv));
++}
++
++
++static void
++empathy_indicator_manager_init (EmpathyIndicatorManager *manager)
++{
++ EmpathyIndicatorManagerPriv *priv;
++
++ priv = G_TYPE_INSTANCE_GET_PRIVATE (manager,
++ EMPATHY_TYPE_INDICATOR_MANAGER, EmpathyIndicatorManagerPriv);
++ manager->priv = priv;
++
++ priv->event_manager = empathy_event_manager_dup_singleton ();
++ priv->login_timeouts = g_hash_table_new_full (NULL, NULL,
++ (GDestroyNotify) g_object_unref, (GDestroyNotify) g_source_unref);
++ priv->indicate_server = indicate_server_ref_default ();
++ indicate_server_set_type (priv->indicate_server, "message.instant");
++ indicate_server_set_desktop_file (priv->indicate_server,
++ EMPATHY_DESKTOP_PATH);
++
++ g_signal_connect (priv->indicate_server,
++ INDICATE_SERVER_SIGNAL_SERVER_DISPLAY,
++ G_CALLBACK (indicate_server_activate),
++ manager);
++
++ g_signal_connect (priv->event_manager, "event-added",
++ G_CALLBACK (indicator_manager_event_added_cb),
++ manager);
++ g_signal_connect (priv->event_manager, "event-removed",
++ G_CALLBACK (indicator_manager_event_removed_cb),
++ manager);
++ g_signal_connect (priv->event_manager, "event-updated",
++ G_CALLBACK (indicator_manager_event_updated_cb),
++ manager);
++}
++
++void
++empathy_indicator_manager_set_server_visible (EmpathyIndicatorManager *manager,
++ gboolean visible)
++{
++ EmpathyIndicatorManagerPriv *priv;
++
++ priv = GET_PRIV (manager);
++ if (visible) {
++ DEBUG ("Show indicator");
++ indicate_server_show (priv->indicate_server);
++ } else {
++ DEBUG ("Hide indicator");
++ indicate_server_hide (priv->indicate_server);
++ }
++}
++
++
++EmpathyIndicator *
++empathy_indicator_manager_create_indicator (EmpathyIndicatorManager *manager,
++ EmpathyContact *sender,
++ const gchar *body)
++{
++ return empathy_indicator_new (sender, body, "im");
++}
++
++
++static LoginData *
++login_data_new (EmpathyIndicator *e_indicator,
++ EmpathyIndicatorManager *manager)
++{
++ LoginData *login_data;
++
++ login_data = g_slice_new0 (LoginData);
++ login_data->manager = g_object_ref (manager);
++ login_data->indicator = g_object_ref (e_indicator);
++
++ return login_data;
++}
++
++
++static void
++indicator_destroy_login_data (gpointer data)
++{
++ LoginData *login_data;
++
++ login_data = (LoginData *)data;
++
++ g_object_unref (login_data->manager);
++ g_object_unref (login_data->indicator);
++ g_slice_free (LoginData, login_data);
++}
++
++
++/* Add an indicator for someone logging in. This will be displayed for
++ * a short period only.
++ */
++void
++empathy_indicator_manager_add_login_indicator (EmpathyIndicatorManager *manager,
++ EmpathyContact *contact)
++{
++ EmpathyIndicatorManagerPriv *priv;
++ GSource *timeout;
++ EmpathyIndicator *e_indicator;
++ LoginData *login_data;
++
++ priv = GET_PRIV (manager);
++ e_indicator = empathy_indicator_new (contact, NULL, "login");
++ login_data = login_data_new (e_indicator, manager);
++
++ timeout = g_timeout_source_new_seconds (INDICATOR_LOGIN_TIMEOUT);
++ g_source_set_callback (timeout, indicate_login_timeout, login_data,
++ indicator_destroy_login_data);
++ g_source_attach (timeout, NULL);
++
++ g_hash_table_insert (priv->login_timeouts, e_indicator, timeout);
++
++ g_signal_connect (e_indicator, "activate",
++ G_CALLBACK (indicate_login_cb), manager);
++ empathy_indicator_show (e_indicator);
++}
+--- /dev/null
++++ b/src/empathy-indicator-manager.h
+@@ -0,0 +1,77 @@
++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
++/*
++ * Copyright (C) 2009 Canonical Ltd.
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public
++ * License along with this program; if not, write to the
++ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
++ * Boston, MA 02110-1301 USA
++ *
++ * Authors: James Westby <james.westby@ubuntu.com>
++ *
++ */
++
++#ifndef __EMPATHY_INDICATOR_MANAGER_H__
++#define __EMPATHY_INDICATOR_MANAGER_H__
++
++#include <glib.h>
++
++#include <libempathy/empathy-contact.h>
++#include "empathy-indicator.h"
++
++G_BEGIN_DECLS
++
++#define EMPATHY_TYPE_INDICATOR_MANAGER \
++ (empathy_indicator_manager_get_type ())
++#define EMPATHY_INDICATOR_MANAGER(o) \
++ (G_TYPE_CHECK_INSTANCE_CAST ((o), EMPATHY_TYPE_INDICATOR_MANAGER, \
++ EmpathyIndicatorManager))
++#define EMPATHY_INDICATOR_MANAGER_CLASS(k) \
++ (G_TYPE_CHECK_CLASS_CAST((k), EMPATHY_TYPE_INDICATOR_MANAGER, \
++ EmpathyIndicatorManagerClass))
++#define EMPATHY_IS_INDICATOR_MANAGER(o) \
++ (G_TYPE_CHECK_INSTANCE_TYPE ((o), EMPATHY_TYPE_INDICATOR_MANAGER))
++#define EMPATHY_IS_INDICATOR_MANAGER_CLASS(k) \
++ (G_TYPE_CHECK_CLASS_TYPE ((k), EMPATHY_TYPE_INDICATOR_MANAGER))
++#define EMPATHY_INDICATOR_MANAGER_GET_CLASS(o) \
++ (G_TYPE_INSTANCE_GET_CLASS ((o), EMPATHY_TYPE_INDICATOR_MANAGER, \
++ EmpathyIndicatorManagerClass))
++
++typedef struct _EmpathyIndicatorManager EmpathyIndicatorManager;
++typedef struct _EmpathyIndicatorManagerClass EmpathyIndicatorManagerClass;
++
++struct _EmpathyIndicatorManager {
++ GObject parent;
++ gpointer priv;
++};
++
++struct _EmpathyIndicatorManagerClass {
++ GObjectClass parent_class;
++};
++
++GType empathy_indicator_manager_get_type (void) G_GNUC_CONST;
++EmpathyIndicatorManager *empathy_indicator_manager_dup_singleton (void);
++void empathy_indicator_manager_set_server_visible (
++ EmpathyIndicatorManager *manager,
++ gboolean visible);
++EmpathyIndicator *empathy_indicator_manager_create_indicator (
++ EmpathyIndicatorManager *manager,
++ EmpathyContact *sender,
++ const gchar *body);
++void empathy_indicator_manager_add_login_indicator (
++ EmpathyIndicatorManager *manager,
++ EmpathyContact *contact);
++
++G_END_DECLS
++
++#endif /* __EMPATHY_INDICATOR_MANAGER_H__ */
+--- /dev/null
++++ b/src/empathy-indicator.c
+@@ -0,0 +1,325 @@
++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
++/*
++ * Copyright (C) 2009 Canonical Ltd.
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public
++ * License along with this program; if not, write to the
++ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
++ * Boston, MA 02110-1301 USA
++ *
++ * Authors: James Westby <james.westby@ubuntu.com>
++ *
++ */
++
++#include <gtk/gtk.h>
++
++#include <libempathy/empathy-contact.h>
++#include <libempathy/empathy-utils.h>
++
++#include <libempathy-gtk/empathy-ui-utils.h>
++#include <libempathy-gtk/empathy-notify-manager.h>
++
++#include "empathy-indicator.h"
++
++#include <libindicate/indicator.h>
++#include <libindicate-gtk/indicator.h>
++
++#define DEBUG_FLAG EMPATHY_DEBUG_OTHER
++#include <libempathy/empathy-debug.h>
++
++#define GET_PRIV(obj) EMPATHY_GET_PRIV ((obj), EmpathyIndicator)
++
++enum {
++ PROP_0,
++ PROP_CONTACT,
++ PROP_BODY,
++ PROP_SUBTYPE,
++ PROP_VISIBLE
++};
++
++enum {
++ ACTIVATE,
++ LAST_SIGNAL
++};
++
++static guint signals[LAST_SIGNAL];
++
++typedef struct {
++ IndicateIndicator *indicator;
++ EmpathyContact *contact;
++ gchar *body;
++ gchar *subtype;
++} EmpathyIndicatorPriv;
++
++G_DEFINE_TYPE (EmpathyIndicator, empathy_indicator, G_TYPE_OBJECT)
++
++
++static void
++empathy_indicator_dispose (GObject *object)
++{
++ EmpathyIndicatorPriv *priv;
++
++ priv = GET_PRIV (object);
++
++ if (priv->indicator) {
++ g_object_unref (priv->indicator);
++ priv->indicator = NULL;
++ }
++ if (priv->contact) {
++ g_object_unref (priv->contact);
++ priv->contact = NULL;
++ }
++
++ G_OBJECT_CLASS (empathy_indicator_parent_class)->dispose (object);
++}
++
++
++static void
++empathy_indicator_finalize (GObject *object)
++{
++ EmpathyIndicatorPriv *priv;
++
++ priv = GET_PRIV (object);
++
++ g_free (priv->body);
++ g_free (priv->subtype);
++
++ G_OBJECT_CLASS (empathy_indicator_parent_class)->finalize (object);
++}
++
++static void
++indicate_show_cb (IndicateIndicator *indicator, guint timestamp,
++ EmpathyIndicator *e_indicator)
++{
++ g_signal_emit (e_indicator, signals[ACTIVATE], 0, timestamp);
++}
++
++
++static IndicateIndicator *
++empathy_indicator_get_indicator (EmpathyIndicator *e_indicator)
++{
++ EmpathyIndicatorPriv *priv;
++
++ priv = GET_PRIV (e_indicator);
++ if (priv->indicator)
++ return priv->indicator;
++
++ priv->indicator = indicate_indicator_new ();
++ g_assert (priv->indicator);
++ g_signal_connect (G_OBJECT (priv->indicator),
++ INDICATE_INDICATOR_SIGNAL_DISPLAY,
++ G_CALLBACK (indicate_show_cb),
++ e_indicator);
++
++ return priv->indicator;
++}
++
++
++static void
++empathy_indicator_set_property (GObject *object,
++ guint param_id,
++ const GValue *value,
++ GParamSpec *pspec)
++{
++ EmpathyIndicator *e_indicator;
++ EmpathyIndicatorPriv *priv;
++ IndicateIndicator *indicator;
++ GTimeVal time;
++ GdkPixbuf *pixbuf_avatar = NULL;
++
++ e_indicator = EMPATHY_INDICATOR (object);
++ priv = GET_PRIV (e_indicator);
++
++ indicator = empathy_indicator_get_indicator (e_indicator);
++
++ switch (param_id) {
++ case PROP_CONTACT:
++ priv->contact = g_object_ref (g_value_get_object (value));
++ g_assert (priv->contact);
++ indicate_indicator_set_property (indicator, "sender",
++ empathy_contact_get_alias (priv->contact));
++ /* get the scaled avatar (22,22) until LP bug #433143 is fixed then switch to
++ to letting indicate-messages handle the scaling by setting the size to 0, 0 */
++ pixbuf_avatar = empathy_pixbuf_avatar_from_contact_scaled (priv->contact, 22, 22);
++ if (pixbuf_avatar != NULL)
++ {
++ indicate_indicator_set_property_icon(indicator, "icon", pixbuf_avatar);
++ g_object_unref(G_OBJECT(pixbuf_avatar));
++ }
++ break;
++ case PROP_BODY:
++ if (priv->body)
++ g_free (priv->body);
++ priv->body = g_strdup (g_value_get_string (value));
++ indicate_indicator_set_property (indicator, "body", priv->body);
++ if (priv->body != NULL) {
++ g_get_current_time (&time);
++ indicate_indicator_set_property_time (indicator, "time", &time);
++ }
++ break;
++ case PROP_SUBTYPE:
++ if (priv->subtype)
++ g_free (priv->subtype);
++ priv->subtype = g_strdup (g_value_get_string (value));
++ indicate_indicator_set_property (indicator, "subtype", priv->subtype);
++ if (g_strcmp0 (priv->subtype, "login") != 0 ) {
++ indicate_indicator_set_property (indicator, "draw-attention", "true");
++ }
++ break;
++ case PROP_VISIBLE:
++ if (g_value_get_boolean (value))
++ indicate_indicator_show (indicator);
++ else
++ indicate_indicator_hide (indicator);
++ break;
++ default:
++ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
++ break;
++ }
++}
++
++
++static void
++empathy_indicator_get_property (GObject *object,
++ guint param_id,
++ GValue *value,
++ GParamSpec *pspec)
++{
++ EmpathyIndicator *e_indicator;
++ EmpathyIndicatorPriv *priv;
++
++ e_indicator = EMPATHY_INDICATOR (object);
++ priv = GET_PRIV (e_indicator);
++
++ switch (param_id) {
++ case PROP_CONTACT:
++ g_value_set_object (value, priv->contact);
++ break;
++ case PROP_BODY:
++ g_value_set_string (value, priv->body);
++ break;
++ case PROP_SUBTYPE:
++ g_value_set_string (value, priv->subtype);
++ break;
++ case PROP_VISIBLE:
++ g_value_set_boolean (value, indicate_indicator_is_visible (priv->indicator));
++ break;
++ default:
++ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
++ break;
++ }
++}
++
++
++static void
++empathy_indicator_class_init (EmpathyIndicatorClass *klass)
++{
++ GObjectClass *object_class;
++
++ object_class = G_OBJECT_CLASS (klass);
++
++ object_class->set_property = empathy_indicator_set_property;
++ object_class->get_property = empathy_indicator_get_property;
++ object_class->dispose = empathy_indicator_dispose;
++ object_class->finalize = empathy_indicator_finalize;
++
++ g_object_class_install_property (object_class, PROP_CONTACT,
++ g_param_spec_object ("contact",
++ "Contact",
++ "The contact being indicated",
++ EMPATHY_TYPE_CONTACT,
++ (G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)));
++ g_object_class_install_property (object_class, PROP_BODY,
++ g_param_spec_string ("body",
++ "Body",
++ "The text for this contact",
++ NULL,
++ (G_PARAM_READWRITE | G_PARAM_CONSTRUCT)));
++ g_object_class_install_property (object_class, PROP_SUBTYPE,
++ g_param_spec_string ("subtype",
++ "Subtype",
++ "The type of this indicator",
++ NULL,
++ (G_PARAM_READWRITE | G_PARAM_CONSTRUCT)));
++ g_object_class_install_property (object_class, PROP_VISIBLE,
++ g_param_spec_boolean ("visible",
++ "Visible",
++ "The visibility of this indicator",
++ FALSE,
++ G_PARAM_READWRITE));
++
++ signals[ACTIVATE] =
++ g_signal_new ("activate",
++ G_TYPE_FROM_CLASS (klass),
++ G_SIGNAL_RUN_LAST,
++ 0,
++ NULL, NULL,
++ g_cclosure_marshal_VOID__UINT,
++ G_TYPE_NONE, 1, G_TYPE_UINT);
++
++ g_type_class_add_private (object_class, sizeof (EmpathyIndicatorPriv));
++}
++
++
++static void
++empathy_indicator_init (EmpathyIndicator *e_indicator)
++{
++ e_indicator->priv = G_TYPE_INSTANCE_GET_PRIVATE (e_indicator,
++ EMPATHY_TYPE_INDICATOR,
++ EmpathyIndicatorPriv);
++}
++
++
++EmpathyIndicator *
++empathy_indicator_new (EmpathyContact *sender,
++ const gchar *body,
++ const gchar *subtype)
++{
++ DEBUG ("Creating a new indicator");
++ return g_object_new (EMPATHY_TYPE_INDICATOR, "contact", sender, "body", body,
++ "subtype", subtype, NULL);
++}
++
++
++void
++empathy_indicator_show (EmpathyIndicator *e_indicator)
++{
++ DEBUG ("Showing indicator %p", e_indicator);
++ g_object_set (e_indicator, "visible", TRUE, NULL);
++}
++
++
++void
++empathy_indicator_hide (EmpathyIndicator *e_indicator)
++{
++ DEBUG ("Hiding indicator %p", e_indicator);
++ g_object_set (e_indicator, "visible", FALSE, NULL);
++}
++
++
++void
++empathy_indicator_update (EmpathyIndicator *e_indicator,
++ const gchar *body)
++{
++ DEBUG ("Updating existing indicator %p", e_indicator);
++ g_object_set (e_indicator, "body", body, NULL);
++}
++
++
++EmpathyContact *
++empathy_indicator_get_contact (EmpathyIndicator *e_indicator)
++{
++ EmpathyContact *contact;
++ g_object_get (e_indicator, "contact", &contact, NULL);
++ return contact;
++}
+--- /dev/null
++++ b/src/empathy-indicator.h
+@@ -0,0 +1,65 @@
++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
++/*
++ * Copyright (C) 2009 Canonical Ltd.
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 2 of the
++ * License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public
++ * License along with this program; if not, write to the
++ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
++ * Boston, MA 02110-1301 USA
++ *
++ * Authors: James Westby <james.westby@ubuntu.com>
++ *
++ */
++
++#ifndef __EMPATHY_INDICATOR_H__
++#define __EMPATHY_INDICATOR_H__
++
++#include <glib.h>
++
++#include <libempathy/empathy-contact.h>
++
++G_BEGIN_DECLS
++
++#define EMPATHY_TYPE_INDICATOR (empathy_indicator_get_type ())
++#define EMPATHY_INDICATOR(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), EMPATHY_TYPE_INDICATOR, EmpathyIndicator))
++#define EMPATHY_INDICATOR_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), EMPATHY_TYPE_INDICATOR, EmpathyIndicatorClass))
++#define EMPATHY_IS_INDICATOR(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), EMPATHY_TYPE_INDICATOR))
++#define EMPATHY_IS_INDICATOR_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), EMPATHY_TYPE_INDICATOR))
++#define EMPATHY_INDICATOR_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), EMPATHY_TYPE_INDICATOR, EmpathyIndicatorClass))
++
++typedef struct _EmpathyIndicator EmpathyIndicator;
++typedef struct _EmpathyIndicatorClass EmpathyIndicatorClass;
++
++struct _EmpathyIndicator {
++ GObject parent;
++ gpointer priv;
++};
++
++struct _EmpathyIndicatorClass {
++ GObjectClass parent_class;
++};
++
++GType empathy_indicator_get_type (void) G_GNUC_CONST;
++EmpathyIndicator *empathy_indicator_new (EmpathyContact *sender,
++ const gchar *body,
++ const gchar *type);
++void empathy_indicator_show (EmpathyIndicator *e_indicator);
++void empathy_indicator_hide (EmpathyIndicator *e_indicator);
++void empathy_indicator_update (EmpathyIndicator *e_indicator,
++ const gchar *body);
++EmpathyContact *empathy_indicator_get_contact (EmpathyIndicator *e_indicator);
++
++G_END_DECLS
++
++
++#endif /* __EMPATHY-INDICATOR_H__ */
+--- a/src/empathy-main-window.c
++++ b/src/empathy-main-window.c
+@@ -82,6 +82,10 @@
+ #include "empathy-ft-manager.h"
+ #include "empathy-migrate-butterfly-logs.h"
+
++#ifdef HAVE_LIBINDICATE
++#include "empathy-indicator-manager.h"
++#endif
++
+ #define DEBUG_FLAG EMPATHY_DEBUG_OTHER
+ #include <libempathy/empathy-debug.h>
+
+@@ -161,6 +165,10 @@
+
+ /* Actions that are enabled when there are connected accounts */
+ GList *actions_connected;
++#ifdef HAVE_LIBINDICATE
++ EmpathyIndicatorManager *indicator_manager;
++ GHashTable *indicator_timeouts;
++#endif
+
+ /* The idle event source to migrate butterfly's logs */
+ guint butterfly_log_migration_members_changed_id;
+@@ -433,11 +441,23 @@
+ EmpathyEvent *event,
+ EmpathyMainWindow *window)
+ {
++ EmpathyMainWindowPriv *priv = GET_PRIV (window);
++
+ if (event->contact) {
+ main_window_flash_start (window);
+ } else if (event->type == EMPATHY_EVENT_TYPE_AUTH) {
+ main_window_auth_display (window, event);
+ }
++
++ #ifdef HAVE_LIBINDICATE
++ if (event->type == EMPATHY_EVENT_TYPE_PRESENCE &&
++ tp_connection_presence_type_cmp_availability (empathy_contact_get_presence (event->contact),
++ TP_CONNECTION_PRESENCE_TYPE_OFFLINE) > 0) {
++ empathy_indicator_manager_add_login_indicator (priv->indicator_manager,
++ event->contact);
++ }
++ #endif
++
+ }
+
+ static void
+@@ -1004,6 +1024,10 @@
+ g_object_unref (priv->ui_manager);
+ g_object_unref (priv->chatroom_manager);
+
++#ifdef HAVE_LIBINDICATE
++ g_object_unref (priv->indicator_manager);
++#endif
++
+ g_object_unref (priv->gsettings_ui);
+ g_object_unref (priv->gsettings_contacts);
+
+@@ -2072,6 +2096,10 @@
+ l = l->next;
+ }
+
++#ifdef HAVE_LIBINDICATE
++ priv->indicator_manager = empathy_indicator_manager_dup_singleton ();
++#endif
++
+ /* Show offline ? */
+ show_offline = g_settings_get_boolean (priv->gsettings_ui,
+ EMPATHY_PREFS_UI_SHOW_OFFLINE);
+--- a/src/empathy-preferences.c
++++ b/src/empathy-preferences.c
+@@ -56,6 +56,7 @@
+
+ GtkWidget *checkbutton_show_smileys;
+ GtkWidget *checkbutton_show_contacts_in_rooms;
++ GtkWidget *checkbutton_use_libindicate;
+ GtkWidget *combobox_chat_theme;
+ GtkWidget *checkbutton_separate_chat_windows;
+ GtkWidget *checkbutton_events_notif_area;
+@@ -235,6 +236,16 @@
+ priv->checkbutton_show_smileys,
+ "active",
+ G_SETTINGS_BIND_DEFAULT);
++#ifdef HAVE_LIBINDICATE
++ g_settings_bind (priv->gsettings_ui,
++ EMPATHY_PREFS_UI_USE_LIBINDICATE,
++ priv->checkbutton_use_libindicate,
++ "active",
++ G_SETTINGS_BIND_DEFAULT);
++#else
++ gtk_widget_hide (GTK_WIDGET (priv->checkbutton_use_libindicate));
++#endif
++
+ g_settings_bind (priv->gsettings_chat,
+ EMPATHY_PREFS_CHAT_SHOW_CONTACTS_IN_ROOMS,
+ priv->checkbutton_show_contacts_in_rooms,
+@@ -890,6 +901,7 @@
+ "notebook", &priv->notebook,
+ "checkbutton_show_smileys", &priv->checkbutton_show_smileys,
+ "checkbutton_show_contacts_in_rooms", &priv->checkbutton_show_contacts_in_rooms,
++ "checkbutton_use_libindicate", &priv->checkbutton_use_libindicate,
+ "combobox_chat_theme", &priv->combobox_chat_theme,
+ "checkbutton_separate_chat_windows", &priv->checkbutton_separate_chat_windows,
+ "checkbutton_events_notif_area", &priv->checkbutton_events_notif_area,
+--- a/src/empathy-preferences.ui
++++ b/src/empathy-preferences.ui
+@@ -266,6 +266,20 @@
+ <property name="position">1</property>
+ </packing>
+ </child>
++ <child>
++ <object class="GtkCheckButton" id="checkbutton_use_libindicate">
++ <property name="label" translatable="yes">Show incoming messages in the messaging menu</property>
++ <property name="visible">True</property>
++ <property name="can_focus">True</property>
++ <property name="receives_default">False</property>
++ <property name="draw_indicator">True</property>
++ </object>
++ <packing>
++ <property name="expand">False</property>
++ <property name="fill">False</property>
++ <property name="position">2</property>
++ </packing>
++ </child>
+ </object>
+ <packing>
+ <property name="position">1</property>
+--- a/src/empathy-status-icon.c
++++ b/src/empathy-status-icon.c
+@@ -29,6 +29,7 @@
+ #include <gdk/gdkkeysyms.h>
+ #include <glib/gi18n.h>
+
++#include <libnotify/notify.h>
+ #include <libnotify/notification.h>
+ #include <libnotify/notify.h>
+
+@@ -52,6 +53,12 @@
+ #include "empathy-preferences.h"
+ #include "empathy-event-manager.h"
+
++#ifdef HAVE_LIBINDICATE
++#include "empathy-indicator-manager.h"
++#include <libindicate/server.h>
++#include <libindicate/interests.h>
++#endif
++
+ #define DEBUG_FLAG EMPATHY_DEBUG_DISPATCHER
+ #include <libempathy/empathy-debug.h>
+
+@@ -76,6 +83,10 @@
+ GtkAction *show_window_item;
+ GtkAction *new_message_item;
+ GtkAction *status_item;
++#ifdef HAVE_LIBINDICATE
++ EmpathyIndicatorManager *indicator_manager;
++ IndicateServer *indicate_server;
++#endif
+ } EmpathyStatusIconPriv;
+
+ G_DEFINE_TYPE (EmpathyStatusIcon, empathy_status_icon, G_TYPE_OBJECT);
+@@ -457,6 +468,92 @@
+ empathy_window_present (GTK_WINDOW (priv->window));
+ }
+ }
++#ifdef HAVE_LIBINDICATE
++static void
++empathy_status_icon_set_visible (gboolean show_icon, EmpathyStatusIcon *icon)
++{
++ EmpathyStatusIconPriv *priv = GET_PRIV (icon);
++ gtk_status_icon_set_visible (priv->icon, show_icon);
++}
++
++static void
++empathy_indicator_interest_status_icon (gboolean icon_visibility,
++ EmpathyStatusIcon *icon)
++{
++ EmpathyStatusIconPriv *priv = GET_PRIV (icon);
++ EmpathyIndicatorManager *manager;
++ gboolean use_libindicate;
++
++ manager = empathy_indicator_manager_dup_singleton();
++ use_libindicate = g_settings_get_boolean (priv->gsettings_ui,
++ EMPATHY_PREFS_UI_USE_LIBINDICATE);
++
++ if (use_libindicate && !icon_visibility) {
++ empathy_indicator_manager_set_server_visible (manager, TRUE);
++ /* Hide the status icon so there are not two ways to access
++ * empathy.
++ */
++ DEBUG ("Hiding the icon, we are shown in the indicator");
++ empathy_status_icon_set_visible (FALSE, icon);
++ } else {
++ empathy_indicator_manager_set_server_visible (manager,
++ FALSE);
++ DEBUG ("Show the icon, we are not shown in the indicator");
++ empathy_status_icon_set_visible (TRUE, icon);
++ }
++}
++
++static void
++empathy_indicator_interest_added (IndicateServer * server,
++ IndicateInterests interest, EmpathyStatusIcon *icon)
++{
++ if (interest != INDICATE_INTEREST_SERVER_SIGNAL) {
++ return;
++ }
++ DEBUG ("Indicator received interest-added signal");
++ empathy_indicator_interest_status_icon(FALSE, icon);
++}
++
++static void
++empathy_indicator_interest_removed (IndicateServer * server,
++ IndicateInterests interest, EmpathyStatusIcon *icon)
++{
++ if (interest != INDICATE_INTEREST_SERVER_SIGNAL) {
++ return;
++ }
++
++ DEBUG ("Indicator received interest-removed signal");
++ empathy_indicator_interest_status_icon(TRUE, icon);
++}
++
++static void
++status_icon_set_use_libindicate (EmpathyStatusIcon *icon,
++ gboolean use_libindicate)
++{
++ EmpathyStatusIconPriv *priv = GET_PRIV (icon);
++
++ if (use_libindicate) {
++ empathy_indicator_manager_set_server_visible (priv->indicator_manager, TRUE);
++ } else {
++ empathy_indicator_manager_set_server_visible (priv->indicator_manager, FALSE);
++ empathy_status_icon_set_visible(TRUE, icon);
++ }
++}
++
++static void
++status_icon_notify_libindicate_cb (GSettings *gsettings,
++ const gchar *key,
++ gpointer user_data)
++{
++ EmpathyStatusIcon *icon = user_data;
++ EmpathyStatusIconPriv *priv = GET_PRIV (icon);
++ gboolean use_libindicate;
++
++ use_libindicate = g_settings_get_boolean (priv->gsettings_ui,
++ EMPATHY_PREFS_UI_USE_LIBINDICATE);
++ status_icon_set_use_libindicate (icon, use_libindicate);
++}
++#endif
+
+ static void
+ status_icon_notify_visibility_cb (GSettings *gsettings,
+@@ -476,10 +573,36 @@
+ EmpathyStatusIconPriv *priv = GET_PRIV (icon);
+ gboolean visible;
+
++
+ visible = gtk_window_is_active (priv->window);
++#ifdef HAVE_LIBINDICATE
++ gboolean use_libindicate;
++ use_libindicate = g_settings_get_boolean (priv->gsettings_ui,
++ EMPATHY_PREFS_UI_USE_LIBINDICATE);
++ if (use_libindicate) {
++ /* If indicators are used then we may very well not be active
++ * when toggled, as they are usually windows themselves. This
++ * makes it damn hard to toggle, so we just look at whether
++ * we are visible.
++ */
++ visible = GTK_WIDGET_VISIBLE (priv->window);
++ status_icon_set_visibility (icon, TRUE, TRUE);
++ return;
++ }
++#endif
++
+ status_icon_set_visibility (icon, !visible, TRUE);
+ }
+
++#ifdef HAVE_LIBINDICATE
++static void
++indicate_server_activate_cb (EmpathyIndicatorManager *manager,
++ guint timestamp, EmpathyStatusIcon *icon)
++{
++ status_icon_toggle_visibility (icon);
++}
++#endif
++
+ static void
+ status_icon_presence_changed_cb (EmpathyStatusIcon *icon)
+ {
+@@ -663,6 +786,9 @@
+ g_object_unref (priv->notify_mgr);
+ g_object_unref (priv->gsettings_ui);
+ g_object_unref (priv->window);
++#ifdef HAVE_LIBINDICATE
++ g_object_unref (priv->indicator_manager);
++#endif
+ }
+
+ static void
+@@ -723,6 +849,13 @@
+ G_CALLBACK (status_icon_notify_visibility_cb),
+ icon);
+
++#ifdef HAVE_LIBINDICATE
++ g_signal_connect (priv->gsettings_ui,
++ "changed::" EMPATHY_PREFS_UI_USE_LIBINDICATE,
++ G_CALLBACK (status_icon_notify_libindicate_cb),
++ icon);
++#endif
++
+ status_icon_create_menu (icon);
+
+ g_signal_connect_swapped (priv->account_manager,
+@@ -755,6 +888,9 @@
+ EmpathyStatusIconPriv *priv;
+ EmpathyStatusIcon *icon;
+ gboolean should_hide;
++#ifdef HAVE_LIBINDICATE
++ gboolean use_libindicate;
++#endif
+
+ g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
+
+@@ -762,6 +898,24 @@
+ priv = GET_PRIV (icon);
+
+ priv->window = g_object_ref (window);
++#ifdef HAVE_LIBINDICATE
++ priv->indicator_manager = empathy_indicator_manager_dup_singleton ();
++ priv->indicate_server = indicate_server_ref_default ();
++
++ g_signal_connect (priv->indicator_manager, "server-activate",
++ G_CALLBACK (indicate_server_activate_cb),
++ icon);
++
++ g_signal_connect (priv->indicate_server,
++ INDICATE_SERVER_SIGNAL_INTEREST_ADDED,
++ G_CALLBACK(empathy_indicator_interest_added),
++ icon);
++
++ g_signal_connect (priv->indicate_server,
++ INDICATE_SERVER_SIGNAL_INTEREST_REMOVED,
++ G_CALLBACK(empathy_indicator_interest_removed),
++ icon);
++#endif
+
+ g_signal_connect_after (priv->window, "key-press-event",
+ G_CALLBACK (status_icon_key_press_event_cb),
+@@ -778,6 +932,12 @@
+ should_hide = TRUE;
+ }
+
++#ifdef HAVE_LIBINDICATE
++ use_libindicate = g_settings_get_boolean (priv->gsettings_ui,
++ EMPATHY_PREFS_UI_USE_LIBINDICATE);
++ status_icon_set_use_libindicate (icon, use_libindicate);
++#endif
++
+ status_icon_set_visibility (icon, !should_hide, FALSE);
+
+ return icon;
diff --git a/debian/patches/21_login_indicators.patch b/debian/patches/21_login_indicators.patch
new file mode 100644
index 000000000..7ab13e29f
--- /dev/null
+++ b/debian/patches/21_login_indicators.patch
@@ -0,0 +1,58 @@
+Description: Only display indicator for signon events if the preference is set
+Bug: https://bugs.launchpad.net/bugs/533857
+
+=== modified file 'src/empathy-indicator-manager.c'
+Index: empathy-2.31.4/src/empathy-indicator-manager.c
+===================================================================
+--- empathy-2.31.4.orig/src/empathy-indicator-manager.c 2010-07-06 13:47:10.156662001 +1000
++++ empathy-2.31.4/src/empathy-indicator-manager.c 2010-07-06 13:47:57.146662001 +1000
+@@ -25,6 +25,7 @@
+
+ #include <gtk/gtk.h>
+
++#include <libempathy/empathy-gsettings.h>
+ #include <libempathy/empathy-contact.h>
+ #include <libempathy/empathy-dispatcher.h>
+ #include <libempathy/empathy-utils.h>
+@@ -449,19 +450,28 @@
+ GSource *timeout;
+ EmpathyIndicator *e_indicator;
+ LoginData *login_data;
++ gboolean contact_signon_notifications;
++ GSettings *gsettings;
+
+- priv = GET_PRIV (manager);
+- e_indicator = empathy_indicator_new (contact, NULL, "login");
+- login_data = login_data_new (e_indicator, manager);
++ gsettings = g_settings_new (EMPATHY_PREFS_NOTIFICATIONS_SCHEMA);
++ contact_signon_notifications = g_settings_get_boolean (gsettings, EMPATHY_PREFS_NOTIFICATIONS_CONTACT_SIGNIN);
++ g_object_unref (gsettings);
++
++ if (contact_signon_notifications) {
++ priv = GET_PRIV (manager);
++ e_indicator = empathy_indicator_new (contact, NULL, "login");
++ login_data = login_data_new (e_indicator, manager);
++
++ timeout = g_timeout_source_new_seconds (INDICATOR_LOGIN_TIMEOUT);
++ g_source_set_callback (timeout, indicate_login_timeout, login_data,
++ indicator_destroy_login_data);
++ g_source_attach (timeout, NULL);
++
++ g_hash_table_insert (priv->login_timeouts, e_indicator, timeout);
++
++ g_signal_connect (e_indicator, "activate",
++ G_CALLBACK (indicate_login_cb), manager);
++ empathy_indicator_show (e_indicator);
++ }
+
+- timeout = g_timeout_source_new_seconds (INDICATOR_LOGIN_TIMEOUT);
+- g_source_set_callback (timeout, indicate_login_timeout, login_data,
+- indicator_destroy_login_data);
+- g_source_attach (timeout, NULL);
+-
+- g_hash_table_insert (priv->login_timeouts, e_indicator, timeout);
+-
+- g_signal_connect (e_indicator, "activate",
+- G_CALLBACK (indicate_login_cb), manager);
+- empathy_indicator_show (e_indicator);
+ }
diff --git a/debian/patches/23_idomessagedialog_for_voip_and_ft.patch b/debian/patches/23_idomessagedialog_for_voip_and_ft.patch
new file mode 100644
index 000000000..f6b701fbf
--- /dev/null
+++ b/debian/patches/23_idomessagedialog_for_voip_and_ft.patch
@@ -0,0 +1,208 @@
+=== modified file 'configure.ac'
+--- a/configure.ac
++++ b/configure.ac
+@@ -44,6 +44,7 @@
+ TELEPATHY_GLIB_REQUIRED=0.14.1
+ TELEPATHY_LOGGER=0.2.0
+ UNIQUE_REQUIRED=1.1.2
++IDO_REQUIRED=0.1.14
+
+ # Optionnal deps
+ CLUTTER_GTK_REQUIRED=0.10
+@@ -162,6 +163,7 @@
+ libxml-2.0
+ telepathy-glib >= $TELEPATHY_GLIB_REQUIRED
+ telepathy-logger-0.2 >= $TELEPATHY_LOGGER
++ libido-0.1 >= $IDO_REQUIRED
+ x11
+ launchpad-integration
+ ])
+--- a/src/empathy-event-manager.c
++++ b/src/empathy-event-manager.c
+@@ -48,6 +48,9 @@
+ #include <libempathy-gtk/empathy-contact-dialogs.h>
+ #include <libempathy-gtk/empathy-sound.h>
+
++#include <libido/idomessagedialog.h>
++#include <libempathy-gtk/empathy-ui-utils.h>
++
+ #include "empathy-event-manager.h"
+ #include "empathy-main-window.h"
+
+@@ -473,6 +476,7 @@
+ }
+ }
+
++
+ static void
+ event_manager_call_window_confirmation_dialog_response_cb (GtkDialog *dialog,
+ gint response, gpointer user_data)
+@@ -499,13 +503,75 @@
+ }
+
+ static void
++event_channel_process_ft_func (EventPriv *event)
++{
++ GtkWidget *dialog;
++ GtkWidget *button;
++ GtkWidget *image;
++ gint width, height;
++ GdkPixbuf *avatar;
++
++ if (event->approval->dialog != NULL)
++ {
++ gtk_window_present (GTK_WINDOW (event->approval->dialog));
++ return;
++ }
++
++ dialog = ido_message_dialog_new (NULL,
++ GTK_DIALOG_MODAL,
++ GTK_MESSAGE_QUESTION,
++ GTK_BUTTONS_NONE,
++ _("Incoming file transfer from %s"),
++ empathy_contact_get_alias (event->approval->contact));
++ gtk_message_dialog_format_secondary_markup (GTK_WINDOW (dialog), _("%s is sending you a file. Do you want to accept it?"),
++ empathy_contact_get_alias (event->approval->contact));
++
++ avatar = empathy_pixbuf_avatar_from_contact_scaled (event->approval->contact, 48, 48);
++ if (avatar != NULL)
++ {
++ image = gtk_image_new_from_pixbuf (avatar);
++ } else {
++ /* Set image of the dialog */
++ image = gtk_image_new_from_icon_name (EMPATHY_IMAGE_DOCUMENT_SEND,
++ GTK_ICON_SIZE_DIALOG);
++ }
++
++ gtk_message_dialog_set_image (GTK_MESSAGE_DIALOG (dialog), image);
++ gtk_widget_show (image);
++
++ gtk_dialog_set_default_response (GTK_DIALOG (dialog),
++ GTK_RESPONSE_OK);
++
++ button = gtk_dialog_add_button (GTK_DIALOG (dialog),
++ _("_Reject"), GTK_RESPONSE_REJECT);
++ image = gtk_image_new_from_icon_name ("stop",
++ GTK_ICON_SIZE_BUTTON);
++ gtk_button_set_image (GTK_BUTTON (button), image);
++
++ button = gtk_dialog_add_button (GTK_DIALOG (dialog),
++ _("_Accept"), GTK_RESPONSE_ACCEPT);
++
++ image = gtk_image_new_from_icon_name ("filesaveas.png", GTK_ICON_SIZE_BUTTON);
++ gtk_button_set_image (GTK_BUTTON (button), image);
++
++ g_signal_connect (dialog, "response",
++ G_CALLBACK (event_manager_call_window_confirmation_dialog_response_cb),
++ event->approval);
++
++ gtk_widget_show (dialog);
++
++ event->approval->dialog = dialog;
++}
++
++static void
+ event_channel_process_voip_func (EventPriv *event)
+ {
+ GtkWidget *dialog;
+ GtkWidget *button;
+ GtkWidget *image;
+ gboolean video;
+- gchar *title;
++ gint width, height;
++ GdkPixbuf *avatar;
+ EmpathyEventType etype = event->public.type;
+
+ if (event->approval->dialog != NULL)
+@@ -532,33 +598,33 @@
+ return;
+ }
+
+- dialog = gtk_message_dialog_new (NULL, 0,
+- GTK_MESSAGE_QUESTION, GTK_BUTTONS_NONE,
+- video ? _("Incoming video call"): _("Incoming call"));
+-
+- gtk_message_dialog_format_secondary_text (
+- GTK_MESSAGE_DIALOG (dialog), video ?
+- _("%s is video calling you. Do you want to answer?"):
+- _("%s is calling you. Do you want to answer?"),
+- empathy_contact_get_alias (event->approval->contact));
+-
+- title = g_strdup_printf (_("Incoming call from %s"),
+- empathy_contact_get_alias (event->approval->contact));
+-
+- gtk_window_set_title (GTK_WINDOW (dialog), title);
+- g_free (title);
+-
+- /* Set image of the dialog */
+- if (video)
++ dialog = ido_message_dialog_new (NULL,
++ GTK_DIALOG_MODAL,
++ GTK_MESSAGE_QUESTION,
++ GTK_BUTTONS_NONE,
++ video ? _("Incoming video call from %s"): _("Incoming call from %s"), empathy_contact_get_alias (event->approval->contact));
++ gtk_message_dialog_format_secondary_markup (GTK_WINDOW (dialog), video ?
++ _("%s is video calling you. Do you want to answer?"):
++ _("%s is calling you. Do you want to answer?"),
++ empathy_contact_get_alias (event->approval->contact));
++
++ avatar = empathy_pixbuf_avatar_from_contact_scaled (event->approval->contact, 48, 48);
++ if (avatar != NULL)
++ {
++ image = gtk_image_new_from_pixbuf (avatar);
++ } else {
++ /* Set image of the dialog */
++ if (video)
+ {
+ image = gtk_image_new_from_icon_name (EMPATHY_IMAGE_VIDEO_CALL,
+ GTK_ICON_SIZE_DIALOG);
+ }
+- else
++ else
+ {
+ image = gtk_image_new_from_icon_name (EMPATHY_IMAGE_VOIP,
+ GTK_ICON_SIZE_DIALOG);
+ }
++ }
+
+ gtk_message_dialog_set_image (GTK_MESSAGE_DIALOG (dialog), image);
+ gtk_widget_show (image);
+@@ -955,7 +1021,7 @@
+ event_manager_add (approval->manager, NULL,
+ approval->contact, EMPATHY_EVENT_TYPE_TRANSFER,
+ EMPATHY_IMAGE_DOCUMENT_SEND, header, NULL,
+- approval, event_channel_process_func, NULL);
++ approval, event_channel_process_ft_func, NULL);
+
+ /* FIXME better sound for incoming file transfers ?*/
+ empathy_sound_play (window, EMPATHY_SOUND_CONVERSATION_NEW);
+--- a/src/empathy-indicator-manager.c
++++ b/src/empathy-indicator-manager.c
+@@ -144,6 +144,12 @@
+ EmpathyEvent *event,
+ EmpathyIndicatorManager *manager)
+ {
++ if (event->type == EMPATHY_EVENT_TYPE_VOIP
++ || event->type == EMPATHY_EVENT_TYPE_CALL
++ || event->type == EMPATHY_EVENT_TYPE_TRANSFER) {
++ return;
++ }
++
+ EmpathyIndicator *indicator = NULL;
+ EmpathyIndicatorManagerPriv *priv;
+ IndicatorEvent *indicator_event;
+--- a/src/empathy-status-icon.c
++++ b/src/empathy-status-icon.c
+@@ -226,6 +226,12 @@
+ }
+
+ if (priv->event) {
++ if (priv->event->type == EMPATHY_EVENT_TYPE_VOIP
++ || priv->event->type == EMPATHY_EVENT_TYPE_CALL
++ || priv->event->type == EMPATHY_EVENT_TYPE_TRANSFER) {
++ empathy_event_activate (priv->event);
++ return;
++ }
+ gchar *message_esc = NULL;
+ gboolean has_x_canonical_append;
+ NotifyNotification *notification = priv->notification;
diff --git a/debian/patches/31_really_raise_window.patch b/debian/patches/31_really_raise_window.patch
new file mode 100644
index 000000000..b4a7a5206
--- /dev/null
+++ b/debian/patches/31_really_raise_window.patch
@@ -0,0 +1,75 @@
+Description: Force focus of the window when selected from the indicator
+Bug: https://bugs.launchpad.net/bugs/442389
+
+=== modified file 'libempathy-gtk/empathy-ui-utils.c'
+--- a/libempathy-gtk/empathy-ui-utils.c
++++ b/libempathy-gtk/empathy-ui-utils.c
+@@ -1599,6 +1599,41 @@
+ }
+ }
+
++/* Really raise the window, even if the window manager doesn't agree */
++static void
++really_activate_window (GtkWindow *window)
++{
++ Screen *screen;
++ Time timestamp;
++ XEvent xev;
++
++ g_return_if_fail (GTK_IS_WINDOW (window));
++
++ screen = GDK_SCREEN_XSCREEN (gtk_widget_get_screen (GTK_WIDGET (window)));
++ timestamp = GDK_CURRENT_TIME;
++
++ xev.xclient.type = ClientMessage;
++ xev.xclient.serial = 0;
++ xev.xclient.send_event = True;
++ xev.xclient.display = GDK_DISPLAY ();
++ xev.xclient.window = GDK_WINDOW_XWINDOW (GTK_WIDGET (window)->window);
++ xev.xclient.message_type = gdk_x11_get_xatom_by_name ("_NET_ACTIVE_WINDOW");
++ xev.xclient.format = 32;
++ xev.xclient.data.l[0] = 2; /* Pager client type */
++ xev.xclient.data.l[1] = timestamp;
++ xev.xclient.data.l[2] = 0;
++ xev.xclient.data.l[3] = 0;
++ xev.xclient.data.l[4] = 0;
++
++ gdk_error_trap_push ();
++ XSendEvent (GDK_DISPLAY (),
++ RootWindowOfScreen (screen),
++ False,
++ SubstructureRedirectMask | SubstructureNotifyMask,
++ &xev);
++ gdk_error_trap_pop ();
++}
++
+ /* Takes care of moving the window to the current workspace. */
+ void
+ empathy_window_present_with_time (GtkWindow *window,
+@@ -1633,6 +1668,7 @@
+
+ gtk_window_set_skip_taskbar_hint (window, FALSE);
+ gtk_window_deiconify (window);
++ really_activate_window (window);
+ }
+
+ void
+--- a/src/empathy-event-manager.c
++++ b/src/empathy-event-manager.c
+@@ -47,6 +47,7 @@
+ #include <libempathy-gtk/empathy-images.h>
+ #include <libempathy-gtk/empathy-contact-dialogs.h>
+ #include <libempathy-gtk/empathy-sound.h>
++#include <libempathy-gtk/empathy-ui-utils.h>
+
+ #include <libido/idomessagedialog.h>
+ #include <libempathy-gtk/empathy-ui-utils.h>
+@@ -513,7 +514,7 @@
+
+ if (event->approval->dialog != NULL)
+ {
+- gtk_window_present (GTK_WINDOW (event->approval->dialog));
++ empathy_window_present (GTK_WINDOW (event->approval->dialog));
+ return;
+ }
+
diff --git a/debian/patches/34_start_raised_execpt_in_session.patch b/debian/patches/34_start_raised_execpt_in_session.patch
new file mode 100644
index 000000000..b92af8356
--- /dev/null
+++ b/debian/patches/34_start_raised_execpt_in_session.patch
@@ -0,0 +1,35 @@
+Description: If not started with the session, we should always raise
+Bug: bugs.launchpad.net/bugs/503052
+
+=== modified file 'src/empathy-status-icon.c'
+--- a/src/empathy-status-icon.c
++++ b/src/empathy-status-icon.c
+@@ -897,6 +897,9 @@
+ #ifdef HAVE_LIBINDICATE
+ gboolean use_libindicate;
+ #endif
++ const gchar *desktop_autostart_id;
++
++ desktop_autostart_id = g_getenv ("DESKTOP_AUTOSTART_ID");
+
+ g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
+
+@@ -932,8 +935,16 @@
+ icon);
+
+ if (!hide_contact_list) {
+- should_hide = g_settings_get_boolean (priv->gsettings_ui,
+- EMPATHY_PREFS_UI_MAIN_WINDOW_HIDDEN);
++ /* If not started with the session, we should raise the window.
++ https://bugs.launchpad.net/ubuntu/+source/empathy/+bug/503052 */
++ if (desktop_autostart_id == NULL) {
++ DEBUG ("Not started with session, showing contact list");
++ should_hide = FALSE;
++ } else {
++ DEBUG ("Auto-started with session, so honor the previous known state");
++ should_hide = g_settings_get_boolean (priv->gsettings_ui,
++ EMPATHY_PREFS_UI_MAIN_WINDOW_HIDDEN);
++ }
+ } else {
+ should_hide = TRUE;
+ }
diff --git a/debian/patches/36_chat_window_default_size.patch b/debian/patches/36_chat_window_default_size.patch
new file mode 100644
index 000000000..302026fa4
--- /dev/null
+++ b/debian/patches/36_chat_window_default_size.patch
@@ -0,0 +1,21 @@
+Description: Make the default chat window size larger
+Bug: https://bugzilla.gnome.org/show_bug.cgi?id=612216
+Bug-Ubuntu: https://bugs.edge.launchpad.net/ubuntu/+source/empathy/+bug/509756
+
+https://bugzilla.gnome.org/show_bug.cgi?id=612216
+=== modified file 'src/empathy-chat-window.ui'
+Index: empathy-2.31.3/src/empathy-chat-window.ui
+===================================================================
+--- empathy-2.31.3.orig/src/empathy-chat-window.ui 2010-06-18 16:29:28.536792269 +1000
++++ empathy-2.31.3/src/empathy-chat-window.ui 2010-06-18 16:38:13.768792269 +1000
+@@ -206,8 +206,8 @@
+ <object class="GtkWindow" id="chat_window">
+ <property name="title" translatable="yes">Chat</property>
+ <property name="role">chat</property>
+- <property name="default_width">350</property>
+- <property name="default_height">250</property>
++ <property name="default_width">580</property>
++ <property name="default_height">480</property>
+ <child>
+ <object class="GtkVBox" id="chat_vbox">
+ <property name="visible">True</property>
diff --git a/debian/patches/37_facebook_default.patch b/debian/patches/37_facebook_default.patch
new file mode 100644
index 000000000..95b852989
--- /dev/null
+++ b/debian/patches/37_facebook_default.patch
@@ -0,0 +1,21 @@
+Descrption: Make facebook the default chat account type, it is the most popular now and fits with our Social From the Start theme for Lucid
+Author: ?
+
+=== modified file 'libempathy-gtk/empathy-protocol-chooser.c'
+--- old/libempathy-gtk/empathy-protocol-chooser.c 2010-03-16 13:30:07 +0000
++++ new/libempathy-gtk/empathy-protocol-chooser.c 2010-03-16 13:36:37 +0000
+@@ -137,10 +137,10 @@
+ COL_IS_FACEBOOK, &is_facebook,
+ -1);
+
+- if (is_gtalk || is_facebook)
++ if (is_facebook)
++ cmp = -1;
++ else
+ cmp = 1;
+- else
+- cmp = -1;
+ }
+ }
+
+
diff --git a/debian/patches/38_lp_569289.patch b/debian/patches/38_lp_569289.patch
new file mode 100644
index 000000000..9b89f578b
--- /dev/null
+++ b/debian/patches/38_lp_569289.patch
@@ -0,0 +1,13 @@
+=== modified file 'libempathy-gtk/empathy-irc-network-chooser.c'
+--- old/libempathy-gtk/empathy-irc-network-chooser.c 2011-02-24 17:01:06 +0000
++++ new/libempathy-gtk/empathy-irc-network-chooser.c 2011-02-24 17:08:47 +0000
+@@ -40,7 +40,7 @@
+
+ #include "empathy-irc-network-chooser.h"
+
+-#define DEFAULT_IRC_NETWORK "irc.gimp.org"
++#define DEFAULT_IRC_NETWORK "chat.freenode.net"
+ #define DEFAULT_IRC_PORT 6667
+ #define DEFAULT_IRC_SSL FALSE
+
+
diff --git a/debian/patches/40_unity_launcher_count.patch b/debian/patches/40_unity_launcher_count.patch
new file mode 100644
index 000000000..ed35e5c51
--- /dev/null
+++ b/debian/patches/40_unity_launcher_count.patch
@@ -0,0 +1,282 @@
+=== modified file 'configure.ac'
+--- a/configure.ac
++++ b/configure.ac
+@@ -59,6 +59,7 @@
+ GNOME_CONTROL_CENTER_GTK3_REQUIRED=2.31.4
+ INDICATE_REQUIRED=0.4.91
+ INDICATE_GTK_REQUIRED=0.4.91
++UNITY_REQUIRED=3.4.0
+
+ # telepathy-yell
+ prev_top_build_prefix=$ac_top_build_prefix
+@@ -506,12 +507,41 @@
+ fi
+
+ if test "x$enable_libindicate" = "xyes" -a "x$have_libindicate" != "xyes"; then
+- AC_MSG_ERROR([Couldn't find libindicate.])
++ AC_MSG_ERROR([Could not find libindicate.])
+ fi
+
+ AM_CONDITIONAL(HAVE_LIBINDICATE, test "x$have_libindicate" = "xyes")
+
+ # -----------------------------------------------------------
++# libunity
++# -----------------------------------------------------------
++AC_ARG_ENABLE(libunity,
++ AS_HELP_STRING([--enable-libunity=@<:@no/yes/auto@:>@],
++ [build libunity support]), ,
++ enable_libunity=auto)
++
++if test "x$enable_unity" != "xno"; then
++ PKG_CHECK_MODULES(UNITY,
++ [
++ unity >= $UNITY_REQUIRED
++ ], have_unity="yes", have_unity="no")
++
++ if test "x$have_unity" = "xyes"; then
++ AC_DEFINE(HAVE_UNITY, 1, [Define if you have unity])
++ fi
++else
++ have_unity=no
++fi
++
++if test "x$enable_unity" = "xyes" -a "x$have_unity" != "xyes"; then
++ AC_MSG_ERROR([Could not find libunity.])
++fi
++
++AM_CONDITIONAL(HAVE_UNITY, test "x$have_unity" = "xyes")
++AC_SUBST([UNITY_CFLAGS])
++AC_SUBST([UNITY_LIBS])
++
++# -----------------------------------------------------------
+ # nautilus-sendto
+ # -----------------------------------------------------------
+ AC_ARG_ENABLE(nautilus-sendto,
+@@ -614,6 +644,7 @@
+
+ Features:
+ Message indicator support (libindicate): ${have_libindicate}
++ Unity panel support (unity).: ${have_unity}
+ Spell checking (enchant)....: ${have_enchant}
+ Display maps (libchamplain).: ${have_libchamplain}
+ Location awareness (Geoclue): ${have_geoclue}
+--- a/src/Makefile.am
++++ b/src/Makefile.am
+@@ -19,6 +19,7 @@
+ $(CPPFLAGS_COMMON) \
+ $(LIBNOTIFY_CFLAGS) \
+ $(INDICATE_CFLAGS) \
++ $(UNITY_CFLAGS) \
+ $(UNIQUE_CFLAGS) \
+ $(LIBCHAMPLAIN_CFLAGS) \
+ $(WEBKIT_CFLAGS) \
+@@ -30,6 +31,7 @@
+ $(top_builddir)/extensions/libemp-extensions.la \
+ $(LIBNOTIFY_LIBS) \
+ $(INDICATE_LIBS) \
++ $(UNITY_LIBS) \
+ $(UNIQUE_LIBS) \
+ $(EMPATHY_LIBS) \
+ $(GTK_LIBS) \
+@@ -204,6 +206,7 @@
+ $(UNIQUE_LIBS) \
+ $(EMPATHY_LIBS) \
+ $(INDICATE_LIBS) \
++ $(UNITY_LIBS) \
+ $(LIBCHAMPLAIN_LIBS) \
+ $(WEBKIT_LIBS) \
+ $(NULL)
+--- a/src/empathy-chat-window.c
++++ b/src/empathy-chat-window.c
+@@ -71,6 +71,10 @@
+ #define DEBUG_FLAG EMPATHY_DEBUG_CHAT
+ #include <libempathy/empathy-debug.h>
+
++#ifdef HAVE_UNITY
++#include <unity.h>
++#endif
++
+ /* Macro to compare guint32 X timestamps, while accounting for wrapping around
+ */
+ #define X_EARLIER_OR_EQL(t1, t2) \
+@@ -96,6 +100,9 @@
+ /* EmpathyChat -> EmpathyIndicator for that chat, if any */
+ GHashTable *indicators;
+ #endif
++#ifdef HAVE_UNITY
++ UnityLauncherEntry *launcher;
++#endif
+ GtkTargetList *contact_targets;
+ GtkTargetList *file_targets;
+
+@@ -1329,8 +1336,19 @@
+ sender, body);
+ g_signal_connect (indicator, "activate",
+ G_CALLBACK (chat_window_indicator_activate_cb), chat);
+-
+ g_hash_table_insert (priv->indicators, chat, indicator);
++#ifdef HAVE_UNITY
++ if (priv->launcher != NULL)
++ {
++ gint count = g_hash_table_size (priv->indicators);
++ DEBUG ("unity launcher: count is now %d", count);
++ if (count > 0)
++ {
++ unity_launcher_entry_set_count (priv->launcher, count);
++ unity_launcher_entry_set_count_visible (priv->launcher, TRUE);
++ }
++ }
++#endif
+ }
+ empathy_indicator_show (indicator);
+ }
+@@ -1347,6 +1365,25 @@
+ DEBUG ("indicator is %p", indicator);
+ empathy_indicator_hide (indicator);
+ g_hash_table_remove (priv->indicators, chat);
++#ifdef HAVE_UNITY
++ if (priv->launcher != NULL)
++ {
++ gint count = g_hash_table_size (priv->indicators);
++ DEBUG ("unity launcher: count is %d", count);
++ if (count > 0)
++ {
++ DEBUG ("unity launcher: setting count to %d", count);
++ unity_launcher_entry_set_count (priv->launcher, count);
++ unity_launcher_entry_set_count_visible (priv->launcher, TRUE);
++ } else {
++ unity_launcher_entry_set_count (priv->launcher, count);
++ DEBUG ("unity launcher: hiding count");
++ unity_launcher_entry_set_count_visible (priv->launcher, FALSE);
++ }
++ }
++#endif
++
++
+ } else {
+ DEBUG ("indicator is NULL, nothing to remove");
+ }
+@@ -1980,6 +2017,11 @@
+ priv->chat_manager = NULL;
+ }
+
++ if (priv->launcher) {
++ g_object_unref (priv->launcher);
++ priv->launcher = NULL;
++ }
++
+ chat_windows = g_list_remove (chat_windows, window);
+ gtk_widget_destroy (priv->dialog);
+
+@@ -2078,6 +2120,9 @@
+ priv->indicators = g_hash_table_new_full (g_direct_hash, g_direct_equal,
+ NULL, g_object_unref);
+ #endif
++#ifdef HAVE_UNITY
++ priv->launcher = unity_launcher_entry_get_for_desktop_id ("empathy.desktop");
++#endif
+
+ priv->notebook = gtk_notebook_new ();
+ gtk_notebook_set_group (GTK_NOTEBOOK (priv->notebook), "EmpathyChatWindow");
+--- a/src/empathy-indicator-manager.c
++++ b/src/empathy-indicator-manager.c
+@@ -45,6 +45,10 @@
+ #define DEBUG_FLAG EMPATHY_DEBUG_OTHER
+ #include <libempathy/empathy-debug.h>
+
++#ifdef HAVE_UNITY
++#include <unity.h>
++#endif
++
+ #define INDICATOR_LOGIN_TIMEOUT 15
+ #define EMPATHY_DESKTOP_PATH DESKTOPDIR "/empathy.desktop"
+
+@@ -62,6 +66,9 @@
+ IndicateServer *indicate_server;
+ GSList *indicator_events;
+ GHashTable *login_timeouts;
++#ifdef HAVE_UNITY
++ UnityLauncherEntry *launcher;
++#endif
+ } EmpathyIndicatorManagerPriv;
+
+ typedef struct {
+@@ -174,6 +181,20 @@
+ g_object_unref (indicator);
+ priv->indicator_events = g_slist_prepend (priv->indicator_events,
+ indicator_event);
++#ifdef HAVE_UNITY
++ if (priv->launcher == NULL)
++ {
++ return;
++ }
++ gint count = g_slist_length (priv->indicator_events);
++ DEBUG ("unity launcher: count is %d", count);
++ if (count > 0)
++ {
++ unity_launcher_entry_set_count (priv->launcher, count);
++ unity_launcher_entry_set_count_visible (priv->launcher, TRUE);
++ }
++#endif
++
+ }
+
+ static void
+@@ -197,6 +218,26 @@
+ priv->indicator_events = g_slist_remove (priv->indicator_events,
+ indicator_event);
+ empathy_indicator_hide (indicator_event->indicator);
++#ifdef HAVE_UNITY
++ if (priv->launcher == NULL)
++ {
++ DEBUG ("unity launcher: launcher is NULL");
++ return;
++ }
++
++ gint count = g_slist_length (priv->indicator_events);
++ DEBUG ("unity launcher: count is %d", count);
++ if (count > 0)
++ {
++ DEBUG ("unity launcher: setting count to %d", count);
++ unity_launcher_entry_set_count (priv->launcher, count);
++ unity_launcher_entry_set_count_visible (priv->launcher, TRUE);
++ } else {
++ unity_launcher_entry_set_count (priv->launcher, count);
++ DEBUG ("unity launcher: hiding count");
++ unity_launcher_entry_set_count_visible (priv->launcher, FALSE);
++ }
++#endif
+ return;
+ }
+ }
+@@ -213,6 +254,8 @@
+
+ priv = GET_PRIV (manager);
+
++ DEBUG ("Event updated");
++
+ for (l = priv->indicator_events; l; l = l->next)
+ {
+ IndicatorEvent *indicator_event;
+@@ -307,6 +350,10 @@
+ g_object_unref (priv->indicate_server);
+ priv->indicate_server = NULL;
+ }
++ if (priv->launcher) {
++ g_object_unref (priv->launcher);
++ priv->launcher = NULL;
++ }
+ if (priv->login_timeouts) {
+ g_hash_table_unref (priv->login_timeouts);
+ priv->login_timeouts = NULL;
+@@ -381,6 +428,10 @@
+ G_CALLBACK (indicate_server_activate),
+ manager);
+
++#ifdef HAVE_UNITY
++ priv->launcher = unity_launcher_entry_get_for_desktop_id ("empathy.desktop");
++#endif
++
+ g_signal_connect (priv->event_manager, "event-added",
+ G_CALLBACK (indicator_manager_event_added_cb),
+ manager);
diff --git a/debian/patches/41_unity_launcher_progress.patch b/debian/patches/41_unity_launcher_progress.patch
new file mode 100644
index 000000000..b4735fd70
--- /dev/null
+++ b/debian/patches/41_unity_launcher_progress.patch
@@ -0,0 +1,159 @@
+=== modified file 'src/empathy-ft-manager.c'
+--- old/src/empathy-ft-manager.c 2011-02-15 17:11:00 +0000
++++ new/src/empathy-ft-manager.c 2011-02-16 21:48:36 +0000
+@@ -46,6 +46,8 @@
+
+ #include "empathy-ft-manager.h"
+
++#include <unity.h>
++
+ enum
+ {
+ COL_PERCENT,
+@@ -65,6 +67,7 @@
+ GtkWidget *open_button;
+ GtkWidget *abort_button;
+ GtkWidget *clear_button;
++ UnityLauncherEntry *launcher;
+ } EmpathyFTManagerPriv;
+
+ enum
+@@ -83,6 +86,53 @@
+ static void ft_handler_hashing_started_cb (EmpathyFTHandler *handler,
+ EmpathyFTManager *manager);
+
++static gchar * ft_manager_format_progress_bytes_and_percentage (
++ guint64 current,
++ guint64 total,
++ gdouble speed,
++ int *percentage);
++
++static void
++ft_update_unity_launcher (EmpathyFTManager *manager)
++{
++ EmpathyFTManagerPriv *priv;
++
++ priv = GET_PRIV (manager);
++ g_return_if_fail (priv->launcher != NULL);
++
++ guint64 current_bytes = 0;
++ guint64 total_bytes = 0;
++ int percentage;
++ gdouble progress;
++ GHashTableIter iter;
++ gpointer handler;
++
++ g_hash_table_iter_init (&iter, priv->ft_handler_to_row_ref);
++ while (g_hash_table_iter_next (&iter, &handler, NULL))
++ {
++ if (!empathy_ft_handler_is_completed (handler) &&
++ !empathy_ft_handler_is_cancelled (handler))
++ {
++ current_bytes = current_bytes + empathy_ft_handler_get_transferred_bytes (handler);
++ total_bytes = total_bytes + empathy_ft_handler_get_total_bytes (handler);
++ }
++ }
++ ft_manager_format_progress_bytes_and_percentage (current_bytes, total_bytes, -1, &percentage);
++
++ progress = percentage;
++ progress = progress / 100;
++
++ unity_launcher_entry_set_progress (priv->launcher, progress);
++ if (progress > 0 && progress < 100)
++ {
++ unity_launcher_entry_set_progress_visible (priv->launcher, TRUE);
++ }
++ else
++ {
++ unity_launcher_entry_set_progress_visible (priv->launcher, FALSE);
++ }
++}
++
+ static gchar *
+ ft_manager_format_interval (guint interval)
+ {
+@@ -392,6 +442,8 @@
+ COL_PERCENT, percentage,
+ -1);
+
++ ft_update_unity_launcher (manager);
++
+ gtk_tree_path_free (path);
+
+ }
+@@ -458,6 +510,8 @@
+ ft_manager_clear_handler_time (manager, row_ref);
+ ft_manager_update_buttons (manager);
+
++ ft_update_unity_launcher (manager);
++
+ g_free (message);
+ }
+
+@@ -465,6 +519,7 @@
+ do_real_transfer_done (EmpathyFTManager *manager,
+ EmpathyFTHandler *handler)
+ {
++ EmpathyFTManagerPriv *priv;
+ const char *contact_name;
+ const char *filename;
+ char *first_line, *second_line, *message;
+@@ -474,6 +529,8 @@
+ GtkRecentManager *recent_manager;
+ GFile *file;
+
++ priv = GET_PRIV (manager);
++
+ row_ref = ft_manager_get_row_from_handler (manager, handler);
+ g_return_if_fail (row_ref != NULL);
+
+@@ -499,6 +556,8 @@
+ ft_manager_update_handler_message (manager, row_ref, message);
+ ft_manager_clear_handler_time (manager, row_ref);
+
++ ft_update_unity_launcher (manager);
++
+ /* update buttons */
+ ft_manager_update_buttons (manager);
+
+@@ -535,6 +594,8 @@
+ DEBUG ("Transfer done, no hashing");
+
+ do_real_transfer_done (manager, handler);
++
++ ft_update_unity_launcher (manager);
+ }
+
+ static void
+@@ -576,6 +637,8 @@
+ EmpathyTpFile *tp_file,
+ EmpathyFTManager *manager)
+ {
++ EmpathyFTManagerPriv *priv;
++ priv = GET_PRIV (manager);
+ guint64 transferred_bytes, total_bytes;
+
+ DEBUG ("Transfer started");
+@@ -1054,6 +1117,12 @@
+
+ g_hash_table_destroy (priv->ft_handler_to_row_ref);
+
++ if (priv->launcher != NULL)
++ {
++ g_object_unref(priv->launcher);
++ priv->launcher = NULL;
++ }
++
+ G_OBJECT_CLASS (empathy_ft_manager_parent_class)->finalize (object);
+ }
+
+@@ -1071,6 +1140,8 @@
+ g_direct_equal, (GDestroyNotify) g_object_unref,
+ (GDestroyNotify) gtk_tree_row_reference_free);
+
++ priv->launcher = unity_launcher_entry_get_for_desktop_id ("empathy.desktop");
++
+ ft_manager_build_ui (manager);
+ }
+
+
diff --git a/debian/patches/series b/debian/patches/series
new file mode 100644
index 000000000..3670f45d4
--- /dev/null
+++ b/debian/patches/series
@@ -0,0 +1,14 @@
+01_lpi.patch
+02_notifications_focus.patch
+10_use_notify_osd_icons.patch
+11_empathy_accounts_category.patch
+20_libindicate.patch
+21_login_indicators.patch
+23_idomessagedialog_for_voip_and_ft.patch
+31_really_raise_window.patch
+34_start_raised_execpt_in_session.patch
+36_chat_window_default_size.patch
+37_facebook_default.patch
+38_lp_569289.patch
+40_unity_launcher_count.patch
+41_unity_launcher_progress.patch