~ubuntu-branches/ubuntu/karmic/empathy/karmic

« back to all changes in this revision

Viewing changes to debian/patches/20_libindicate.patch

  • Committer: Bazaar Package Importer
  • Author(s): Ken VanDine, Ken VanDine, Robert Ancell
  • Date: 2009-09-21 14:34:40 UTC
  • Revision ID: james.westby@ubuntu.com-20090921143440-5ihf4gt7kqakmnbm
Tags: 2.27.92-1ubuntu3
[Ken VanDine]
* debian/control:
  - Added libindicate-gtk-dev and libindicate-dev (>=0.2.0) to build depends
* debian/patches/30_raise_not_toggle.patch:
  - Always raise contact list when clicked (LP: #392153)
* debian/patches/99_autoconf.patch added

[Robert Ancell]
* debian/patches/10_use_notify_osd_icons.patch:
  - Use the notify-OSD icons for new messages (LP: #409828)
* debian/patches/20_libindicate.patch:
  - Integrate into messaging menu (LP: #340180)
* debian/control:
  - Remove Debian VCS links as they confuse debcheckout

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#
 
2
# Description: Integrate Empathy into the messaging menu
 
3
# Ubuntu: https://bugs.edge.launchpad.net/ubuntu/+source/empathy/+bug/340180
 
4
# Upstream: https://bugzilla.gnome.org/show_bug.cgi?id=574744
 
5
#
 
6
 
 
7
=== modified file 'configure.ac'
 
8
--- configure.ac        2009-09-18 18:41:05 +0000
 
9
+++ configure.ac        2009-09-18 18:41:20 +0000
 
10
@@ -41,6 +41,8 @@
 
11
 WEBKIT_REQUIRED=1.1.7
 
12
 KEYRING_REQUIRED=2.22
 
13
 NETWORK_MANAGER_REQUIRED=0.7.0
 
14
+INDICATE_REQUIRED=0.2.0
 
15
+INDICATE_GTK_REQUIRED=0.2.0
 
16
 
 
17
 # Use --enable-maintainer-mode to disabled deprecated symbols
 
18
 GNOME_MAINTAINER_MODE_DEFINES
 
19
@@ -380,6 +382,34 @@
 
20
 AM_CONDITIONAL(HAVE_NOTHERE, test "x$have_nothere" = "xyes")
 
21
 
 
22
 # -----------------------------------------------------------
 
23
+# libindicate
 
24
+# -----------------------------------------------------------
 
25
+AC_ARG_ENABLE(libindicate,
 
26
+              AS_HELP_STRING([--enable-libindicate=@<:@no/yes/auto@:>@],
 
27
+                             [build libindicate support]), ,
 
28
+                             enable_libindicate=auto)
 
29
+
 
30
+if test "x$enable_libindicate" != "xno"; then
 
31
+   PKG_CHECK_MODULES(INDICATE, 
 
32
+   [
 
33
+     indicate >= $INDICATE_REQUIRED,
 
34
+     indicate-gtk >= $INDICATE_GTK_REQUIRED
 
35
+   ], have_libindicate="yes", have_libindicate="no")
 
36
+
 
37
+   if test "x$have_libindicate" = "xyes"; then
 
38
+      AC_DEFINE(HAVE_LIBINDICATE, 1, [Define if you have libindicate])
 
39
+   fi
 
40
+else
 
41
+   have_libindicate=no
 
42
+fi
 
43
+
 
44
+if test "x$enable_libindicate" = "xyes" -a "x$have_libindicate" != "xyes"; then
 
45
+   AC_MSG_ERROR([Couldn't find libindicate.])
 
46
+fi
 
47
+
 
48
+AM_CONDITIONAL(HAVE_LIBINDICATE, test "x$have_libindicate" = "xyes")
 
49
+
 
50
+# -----------------------------------------------------------
 
51
 # Tests
 
52
 # -----------------------------------------------------------
 
53
 AC_ARG_ENABLE(tests,
 
54
@@ -487,26 +517,27 @@
 
55
 echo "
 
56
 Configure summary:
 
57
 
 
58
-       Compiler....................:  ${CC}
 
59
-       Compiler Flags..............:  ${CFLAGS}
 
60
-       Prefix......................:  ${prefix}
 
61
-       Shaved build................:  ${enable_shave}
 
62
-       Tests.......................:  ${have_check}
 
63
-       Coding style checks.........:  ${ENABLE_CODING_STYLE_CHECKS}
 
64
+       Compiler...............................:  ${CC}
 
65
+       Compiler Flags.........................:  ${CFLAGS}
 
66
+       Prefix.................................:  ${prefix}
 
67
+       Shaved build...........................:  ${enable_shave}
 
68
+       Tests..................................:  ${have_check}
 
69
+       Coding style checks....................:  ${ENABLE_CODING_STYLE_CHECKS}
 
70
 
 
71
     Features:
 
72
-       Spell checking (enchant)....:  ${have_enchant}
 
73
-       Display maps (libchamplain).:  ${have_libchamplain}
 
74
-       Location awareness (Geoclue):  ${have_geoclue}
 
75
-       Adium themes (Webkit).......:  ${have_webkit}
 
76
+       Spell checking (enchant)...............:  ${have_enchant}
 
77
+       Display maps (libchamplain)............:  ${have_libchamplain}
 
78
+       Location awareness (Geoclue)...........:  ${have_geoclue}
 
79
+       Adium themes (Webkit)..................:  ${have_webkit}
 
80
+       Message indicator support (libindicate):  ${have_libindicate}
 
81
 
 
82
     Connectivity:
 
83
-       NetworkManager integration..:  ${have_nm}
 
84
-       ConnMan integration.........:  ${have_connman}
 
85
+       NetworkManager integration.............:  ${have_nm}
 
86
+       ConnMan integration....................:  ${have_connman}
 
87
 
 
88
     Extras:
 
89
-       Documentation...............:  ${enable_gtk_doc}
 
90
-       Python bindings.............:  ${have_python}
 
91
-       Megaphone applet............:  ${have_megaphone}
 
92
-       Nothere applet..............:  ${have_nothere}
 
93
+       Documentation..........................:  ${enable_gtk_doc}
 
94
+       Python bindings........................:  ${have_python}
 
95
+       Megaphone applet.......................:  ${have_megaphone}
 
96
+       Nothere applet.........................:  ${have_nothere}
 
97
 "
 
98
 
 
99
=== modified file 'data/empathy.schemas.in'
 
100
--- data/empathy.schemas.in     2009-09-18 18:41:05 +0000
 
101
+++ data/empathy.schemas.in     2009-09-18 18:41:20 +0000
 
102
@@ -291,6 +291,21 @@
 
103
     </schema>
 
104
 
 
105
     <schema>
 
106
+      <key>/schemas/apps/empathy/notifications/use_libindicate</key>
 
107
+      <applyto>/apps/empathy/notifications/use_libindicate</applyto>
 
108
+      <owner>empathy</owner>
 
109
+      <type>bool</type>
 
110
+      <default>true</default>
 
111
+      <locale name="C">
 
112
+         <short>Use the messaging indicator</short>
 
113
+         <long>
 
114
+         Whether or not to use the messaging indicator, if false
 
115
+        the icon in the notification area will be displayed.
 
116
+         </long>
 
117
+      </locale>
 
118
+    </schema>
 
119
+
 
120
+    <schema>
 
121
        <key>/schemas/apps/empathy/ui/separate_chat_windows</key>
 
122
        <applyto>/apps/empathy/ui/separate_chat_windows</applyto>
 
123
        <owner>empathy</owner>
 
124
 
 
125
=== modified file 'libempathy-gtk/empathy-conf.h'
 
126
--- libempathy-gtk/empathy-conf.h       2009-09-18 18:41:05 +0000
 
127
+++ libempathy-gtk/empathy-conf.h       2009-09-18 18:41:20 +0000
 
128
@@ -74,6 +74,7 @@
 
129
 #define EMPATHY_PREFS_UI_AVATAR_DIRECTORY          EMPATHY_PREFS_PATH "/ui/avatar_directory"
 
130
 #define EMPATHY_PREFS_UI_SHOW_AVATARS              EMPATHY_PREFS_PATH "/ui/show_avatars"
 
131
 #define EMPATHY_PREFS_UI_COMPACT_CONTACT_LIST      EMPATHY_PREFS_PATH "/ui/compact_contact_list"
 
132
+#define EMPATHY_PREFS_UI_USE_LIBINDICATE           EMPATHY_PREFS_PATH "/notifications/use_libindicate"
 
133
 #define EMPATHY_PREFS_CONTACTS_SHOW_OFFLINE        EMPATHY_PREFS_PATH "/contacts/show_offline"
 
134
 #define EMPATHY_PREFS_CONTACTS_SORT_CRITERIUM      EMPATHY_PREFS_PATH "/contacts/sort_criterium"
 
135
 #define EMPATHY_PREFS_HINTS_CLOSE_MAIN_WINDOW      EMPATHY_PREFS_PATH "/hints/close_main_window"
 
136
 
 
137
=== modified file 'libempathy-gtk/empathy-ui-utils.c'
 
138
--- libempathy-gtk/empathy-ui-utils.c   2009-09-18 18:41:05 +0000
 
139
+++ libempathy-gtk/empathy-ui-utils.c   2009-09-18 18:41:20 +0000
 
140
@@ -1269,24 +1269,35 @@
 
141
        Display      *dpy;
 
142
        GdkWindow    *gdk_window;
 
143
 
 
144
-       gtk_status_icon_get_geometry (status_icon, NULL, &icon_location, NULL);
 
145
-       gdk_window = gtk_widget_get_window (GTK_WIDGET (window));
 
146
-       dpy = gdk_x11_drawable_get_xdisplay (gdk_window);
 
147
-
 
148
-       data[0] = icon_location.x;
 
149
-       data[1] = icon_location.y;
 
150
-       data[2] = icon_location.width;
 
151
-       data[3] = icon_location.height;
 
152
-
 
153
-       XChangeProperty (dpy,
 
154
-                        GDK_WINDOW_XID (gdk_window),
 
155
-                        gdk_x11_get_xatom_by_name_for_display (gdk_drawable_get_display (gdk_window),
 
156
-                        "_NET_WM_ICON_GEOMETRY"),
 
157
-                        XA_CARDINAL, 32, PropModeReplace,
 
158
-                        (guchar *)&data, 4);
 
159
+       // If the status icon isn't visible (because indicators are used) then
 
160
+       // attempting to change the properties of the status icon doesn't work.
 
161
+       if (gtk_status_icon_get_visible (status_icon)) {
 
162
+               gtk_status_icon_get_geometry (status_icon, NULL, &icon_location, NULL);
 
163
+               gdk_window = gtk_widget_get_window (GTK_WIDGET (window));
 
164
+               dpy = gdk_x11_drawable_get_xdisplay (gdk_window);
 
165
+
 
166
+               data[0] = icon_location.x;
 
167
+               data[1] = icon_location.y;
 
168
+               data[2] = icon_location.width;
 
169
+               data[3] = icon_location.height;
 
170
+
 
171
+               XChangeProperty (dpy,
 
172
+                                GDK_WINDOW_XID (gdk_window),
 
173
+                                gdk_x11_get_xatom_by_name_for_display (gdk_drawable_get_display (gdk_window),
 
174
+                                "_NET_WM_ICON_GEOMETRY"),
 
175
+                                XA_CARDINAL, 32, PropModeReplace,
 
176
+                                (guchar *)&data, 4);
 
177
+       }
 
178
 
 
179
        gtk_window_set_skip_taskbar_hint (window, TRUE);
 
180
-       gtk_window_iconify (window);
 
181
+       // If the status icon isn't present then the WM will probably choose to
 
182
+       // iconfy to the taskbar, which doesn't look as good as the taskbar
 
183
+       // entry has just been removed. Just hide instead.
 
184
+       if (gtk_status_icon_get_visible (status_icon)) {
 
185
+               gtk_window_iconify (window);
 
186
+       } else {
 
187
+               gtk_widget_hide (GTK_WIDGET(window));
 
188
+       }
 
189
 }
 
190
 
 
191
 /* Takes care of moving the window to the current workspace. */
 
192
 
 
193
=== modified file 'po/POTFILES.in'
 
194
--- po/POTFILES.in      2009-09-18 18:41:05 +0000
 
195
+++ po/POTFILES.in      2009-09-18 18:41:20 +0000
 
196
@@ -79,6 +79,8 @@
 
197
 [type: gettext/glade]src/empathy-import-dialog.ui
 
198
 src/empathy-import-widget.c
 
199
 src/empathy-import-mc4-accounts.c
 
200
+src/empathy-indicator.c
 
201
+src/empathy-indicator-manager.c
 
202
 src/empathy-main-window.c
 
203
 [type: gettext/glade]src/empathy-main-window.ui
 
204
 src/empathy-new-chatroom-dialog.c
 
205
 
 
206
=== modified file 'src/Makefile.am'
 
207
--- src/Makefile.am     2009-09-18 18:41:05 +0000
 
208
+++ src/Makefile.am     2009-09-18 18:41:20 +0000
 
209
@@ -4,8 +4,10 @@
 
210
 AM_CPPFLAGS =                                          \
 
211
        -I$(top_srcdir)                                 \
 
212
        -DG_LOG_DOMAIN=\"empathy\"                      \
 
213
+       -DDESKTOPDIR=\"$(datadir)/applications\"        \
 
214
        $(EMPATHY_CFLAGS)                               \
 
215
        $(LIBNOTIFY_CFLAGS)                             \
 
216
+       $(INDICATE_CFLAGS)                              \
 
217
        $(LIBCHAMPLAIN_CFLAGS)                          \
 
218
        $(DISABLE_DEPRECATED)                           \
 
219
        $(WEBKIT_CFLAGS)                                \
 
220
@@ -16,6 +18,7 @@
 
221
        $(top_builddir)/libempathy/libempathy.la                \
 
222
        $(top_builddir)/extensions/libemp-extensions.la         \
 
223
        $(LIBNOTIFY_LIBS)                                       \
 
224
+       $(INDICATE_LIBS)                                        \
 
225
        $(EMPATHY_LIBS)                                         \
 
226
        $(LIBCHAMPLAIN_LIBS)                                    \
 
227
        $(WEBKIT_LIBS)
 
228
@@ -85,6 +88,18 @@
 
229
        $(autostart_DATA)       \
 
230
        $(ui_DATA)
 
231
 
 
232
+if HAVE_LIBINDICATE
 
233
+empathy_handwritten_source +=                          \
 
234
+       empathy-indicator-manager.c             \
 
235
+       empathy-indicator-manager.h             \
 
236
+       empathy-indicator.c empathy-indicator.h
 
237
+else
 
238
+EXTRA_DIST +=                                  \
 
239
+       empathy-indicator-manager.c             \
 
240
+       empathy-indicator-manager.h             \
 
241
+       empathy-indicator.c empathy-indicator.h
 
242
+endif
 
243
+
 
244
 if HAVE_LIBCHAMPLAIN
 
245
 empathy_handwritten_source +=                          \
 
246
        empathy-map-view.c                      \
 
247
 
 
248
=== modified file 'src/empathy-chat-window.c'
 
249
--- src/empathy-chat-window.c   2009-09-18 18:41:05 +0000
 
250
+++ src/empathy-chat-window.c   2009-09-18 18:41:20 +0000
 
251
@@ -56,6 +56,11 @@
 
252
 #include "empathy-about-dialog.h"
 
253
 #include "empathy-misc.h"
 
254
 
 
255
+#ifdef HAVE_LIBINDICATE
 
256
+#include "empathy-indicator.h"
 
257
+#include "empathy-indicator-manager.h"
 
258
+#endif
 
259
+
 
260
 #define DEBUG_FLAG EMPATHY_DEBUG_CHAT
 
261
 #include <libempathy/empathy-debug.h>
 
262
 
 
263
@@ -72,6 +77,11 @@
 
264
        GtkWidget   *dialog;
 
265
        GtkWidget   *notebook;
 
266
        NotifyNotification *notification;
 
267
+#ifdef HAVE_LIBINDICATE
 
268
+       EmpathyIndicatorManager *indicator_manager;
 
269
+       /* EmpathyChat -> EmpathyIndicator for that chat, if any */
 
270
+       GHashTable  *indicators;
 
271
+#endif
 
272
 
 
273
        /* Menu items. */
 
274
        GtkUIManager *ui_manager;
 
275
@@ -935,6 +945,76 @@
 
276
        g_slice_free (NotificationData, cb_data);
 
277
 }
 
278
 
 
279
+#ifdef HAVE_LIBINDICATE
 
280
+static void
 
281
+chat_window_indicator_activate_cb (EmpathyIndicator *indicator,
 
282
+                                   NotificationData *cb_data)
 
283
+{
 
284
+       empathy_chat_window_present_chat (cb_data->chat);
 
285
+
 
286
+       empathy_indicator_hide (indicator);
 
287
+       g_object_unref (cb_data->chat);
 
288
+       g_slice_free (NotificationData, cb_data);
 
289
+}
 
290
+
 
291
+static void
 
292
+chat_window_add_indicator (EmpathyChatWindow *window,
 
293
+                                        EmpathyMessage *message,
 
294
+                                        EmpathyChat    *chat)
 
295
+{
 
296
+       EmpathyChatWindowPriv *priv = GET_PRIV (window);
 
297
+       EmpathyContact *sender;
 
298
+       const char *body;
 
299
+       NotificationData *cb_data;
 
300
+       gboolean use_libindicate;
 
301
+       EmpathyIndicator *indicator;
 
302
+
 
303
+       empathy_conf_get_bool (empathy_conf_get (),
 
304
+                              EMPATHY_PREFS_UI_USE_LIBINDICATE,
 
305
+                              &use_libindicate);
 
306
+
 
307
+       if (!use_libindicate) {
 
308
+               return;
 
309
+       }
 
310
+
 
311
+       cb_data = g_slice_new0 (NotificationData);
 
312
+       cb_data->chat = g_object_ref (chat);
 
313
+       cb_data->window = window;
 
314
+
 
315
+       sender = empathy_message_get_sender (message);
 
316
+       body = empathy_message_get_body (message);
 
317
+
 
318
+       indicator = g_hash_table_lookup (priv->indicators, chat);
 
319
+       if (indicator) {
 
320
+               empathy_indicator_update (indicator, body);
 
321
+       } else {
 
322
+               indicator = empathy_indicator_manager_create_indicator (priv->indicator_manager,
 
323
+                       sender, body);
 
324
+               g_signal_connect (indicator, "activate",
 
325
+                                 G_CALLBACK (chat_window_indicator_activate_cb), cb_data);
 
326
+               g_hash_table_insert (priv->indicators, chat, indicator);
 
327
+       }
 
328
+       empathy_indicator_show (indicator);
 
329
+}
 
330
+
 
331
+static void
 
332
+chat_window_remove_indicator (EmpathyChatWindow *window, EmpathyChat *chat)
 
333
+{
 
334
+       EmpathyIndicator *indicator;
 
335
+       EmpathyChatWindowPriv *priv = GET_PRIV (window);
 
336
+
 
337
+       indicator = g_hash_table_lookup (priv->indicators, chat);
 
338
+
 
339
+       if (!indicator) {
 
340
+               return;
 
341
+       }
 
342
+
 
343
+       empathy_indicator_hide (indicator);
 
344
+       g_hash_table_remove (priv->indicators, chat);
 
345
+       g_object_unref (indicator);
 
346
+}
 
347
+#endif
 
348
+
 
349
 static void
 
350
 chat_window_show_or_update_notification (EmpathyChatWindow *window,
 
351
                                         EmpathyMessage *message,
 
352
@@ -1067,6 +1147,9 @@
 
353
                empathy_sound_play (GTK_WIDGET (priv->dialog),
 
354
                    EMPATHY_SOUND_MESSAGE_INCOMING);
 
355
                chat_window_show_or_update_notification (window, message, chat);
 
356
+#ifdef HAVE_LIBINDICATE
 
357
+               chat_window_add_indicator (window, message, chat);
 
358
+#endif
 
359
        }
 
360
 }
 
361
 
 
362
@@ -1126,6 +1209,10 @@
 
363
        priv->chats_new_msg = g_list_remove (priv->chats_new_msg, chat);
 
364
 
 
365
        chat_window_update_chat_tab (chat);
 
366
+
 
367
+#ifdef HAVE_LIBINDICATE
 
368
+       chat_window_remove_indicator (window, chat);
 
369
+#endif
 
370
 }
 
371
 
 
372
 static void
 
373
@@ -1236,6 +1323,11 @@
 
374
        /* Update the title, since we now mark all unread messages as read. */
 
375
        chat_window_update_chat_tab (priv->current_chat);
 
376
 
 
377
+#ifdef HAVE_LIBINDICATE
 
378
+       /* Remove the indicator for the active chat */
 
379
+       chat_window_remove_indicator (window, priv->current_chat);
 
380
+#endif
 
381
+
 
382
        return FALSE;
 
383
 }
 
384
 
 
385
@@ -1452,6 +1544,11 @@
 
386
        g_object_unref (gui);
 
387
 
 
388
        priv->chatroom_manager = empathy_chatroom_manager_dup_singleton (NULL);
 
389
+#ifdef HAVE_LIBINDICATE
 
390
+       priv->indicator_manager = empathy_indicator_manager_dup_singleton ();
 
391
+       priv->indicators = g_hash_table_new_full (g_direct_hash, g_direct_equal,
 
392
+                             NULL, g_object_unref);
 
393
+#endif
 
394
 
 
395
        priv->notebook = gtk_notebook_new ();
 
396
        gtk_notebook_set_group (GTK_NOTEBOOK (priv->notebook), "EmpathyChatWindow");
 
397
 
 
398
=== added file 'src/empathy-indicator-manager.c'
 
399
--- src/empathy-indicator-manager.c     1970-01-01 00:00:00 +0000
 
400
+++ src/empathy-indicator-manager.c     2009-09-18 18:41:43 +0000
 
401
@@ -0,0 +1,459 @@
 
402
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
 
403
+/*
 
404
+ * Copyright (C) 2009 Canonical Ltd.
 
405
+ *
 
406
+ * This program is free software; you can redistribute it and/or
 
407
+ * modify it under the terms of the GNU General Public License as
 
408
+ * published by the Free Software Foundation; either version 2 of the
 
409
+ * License, or (at your option) any later version.
 
410
+ *
 
411
+ * This program is distributed in the hope that it will be useful,
 
412
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
413
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
414
+ * General Public License for more details.
 
415
+ *
 
416
+ * You should have received a copy of the GNU General Public
 
417
+ * License along with this program; if not, write to the
 
418
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
 
419
+ * Boston, MA  02110-1301  USA
 
420
+ *
 
421
+ * Authors: James Westby <james.westby@ubuntu.com>
 
422
+ *
 
423
+ */
 
424
+
 
425
+#include <config.h>
 
426
+
 
427
+#include <gtk/gtk.h>
 
428
+
 
429
+#include <libempathy/empathy-contact.h>
 
430
+#include <libempathy/empathy-dispatcher.h>
 
431
+#include <libempathy/empathy-utils.h>
 
432
+
 
433
+#include <libempathy-gtk/empathy-conf.h>
 
434
+#include <libempathy-gtk/empathy-ui-utils.h>
 
435
+
 
436
+#include <telepathy-glib/util.h>
 
437
+
 
438
+#include "empathy-event-manager.h"
 
439
+#include "empathy-indicator.h"
 
440
+#include "empathy-indicator-manager.h"
 
441
+#include "empathy-misc.h"
 
442
+
 
443
+#include <libindicate/server.h>
 
444
+
 
445
+#define INDICATOR_LOGIN_TIMEOUT 15
 
446
+#define EMPATHY_DESKTOP_PATH DESKTOPDIR "/empathy.desktop"
 
447
+
 
448
+#define GET_PRIV(obj) EMPATHY_GET_PRIV (obj, EmpathyIndicatorManager)
 
449
+
 
450
+enum {
 
451
+  SERVER_ACTIVATE,
 
452
+  LAST_SIGNAL
 
453
+};
 
454
+
 
455
+static guint signals[LAST_SIGNAL];
 
456
+
 
457
+typedef struct {
 
458
+  EmpathyEventManager *event_manager;
 
459
+  IndicateServer      *indicate_server;
 
460
+  GSList              *indicator_events;
 
461
+  GHashTable          *login_timeouts;
 
462
+} EmpathyIndicatorManagerPriv;
 
463
+
 
464
+typedef struct {
 
465
+  EmpathyIndicator    *indicator;
 
466
+  EmpathyEvent        *event;
 
467
+} IndicatorEvent;
 
468
+
 
469
+typedef struct {
 
470
+  EmpathyIndicatorManager *manager;
 
471
+  EmpathyIndicator        *indicator;
 
472
+} LoginData;
 
473
+
 
474
+G_DEFINE_TYPE (EmpathyIndicatorManager, empathy_indicator_manager, G_TYPE_OBJECT);
 
475
+
 
476
+static EmpathyIndicatorManager *manager_singleton = NULL;
 
477
+
 
478
+static EmpathyEvent *
 
479
+event_copy (EmpathyEvent *event)
 
480
+{
 
481
+       EmpathyEvent *ret = g_new0 (EmpathyEvent, 1);
 
482
+
 
483
+       ret->contact = g_object_ref (event->contact);
 
484
+       ret->icon_name = g_strdup (event->icon_name);
 
485
+       ret->header = g_strdup (event->header);
 
486
+       ret->message = g_strdup (event->message);
 
487
+       ret->must_ack = event->must_ack;
 
488
+
 
489
+       return ret;
 
490
+}
 
491
+
 
492
+static gboolean
 
493
+compare_events (EmpathyEvent *ev1, EmpathyEvent *ev2)
 
494
+{
 
495
+       return ((g_strcmp0 (ev1->icon_name, ev2->icon_name) == 0) &&
 
496
+               (g_strcmp0 (ev1->header, ev2->header) == 0) &&
 
497
+               (g_strcmp0 (ev1->message, ev2->message) == 0) &&
 
498
+               (ev1->must_ack == ev2->must_ack) &&
 
499
+               (ev1->contact == ev2->contact));
 
500
+}
 
501
+
 
502
+static IndicatorEvent *
 
503
+indicator_event_new (EmpathyIndicator *indicator,
 
504
+                    EmpathyEvent *event)
 
505
+{
 
506
+  IndicatorEvent *indicator_event;
 
507
+
 
508
+  indicator_event = g_slice_new0 (IndicatorEvent);
 
509
+  indicator_event->indicator = g_object_ref (indicator);
 
510
+  indicator_event->event = event_copy (event);
 
511
+
 
512
+  return indicator_event;
 
513
+}
 
514
+
 
515
+
 
516
+static void
 
517
+indicator_event_free (IndicatorEvent *indicator_event)
 
518
+{
 
519
+  g_object_unref (indicator_event->indicator);
 
520
+  g_free (indicator_event);
 
521
+}
 
522
+
 
523
+
 
524
+static void
 
525
+indicate_server_activate (IndicateServer *server,
 
526
+    EmpathyIndicatorManager *manager)
 
527
+{
 
528
+  g_signal_emit (manager, signals[SERVER_ACTIVATE], 0);
 
529
+}
 
530
+
 
531
+
 
532
+static void
 
533
+indicate_show_cb (EmpathyIndicator *indicator,
 
534
+    EmpathyEvent *event)
 
535
+{
 
536
+  empathy_event_activate (event);
 
537
+}
 
538
+
 
539
+
 
540
+static void
 
541
+indicator_manager_event_added_cb (EmpathyEventManager *event_manager,
 
542
+    EmpathyEvent *event,
 
543
+    EmpathyIndicatorManager *manager)
 
544
+{
 
545
+  EmpathyIndicator *indicator;
 
546
+  EmpathyIndicatorManagerPriv *priv;
 
547
+  IndicatorEvent *indicator_event;
 
548
+
 
549
+  priv = GET_PRIV (manager);
 
550
+
 
551
+  if (event->contact == NULL)
 
552
+    return;
 
553
+  indicator = empathy_indicator_new (event->contact, event->message, "im");
 
554
+  empathy_indicator_show (indicator);
 
555
+  g_signal_connect (G_OBJECT(indicator), "activate",
 
556
+      G_CALLBACK (indicate_show_cb),
 
557
+      event);
 
558
+  indicator_event = indicator_event_new (indicator, event);
 
559
+  g_object_unref (indicator);
 
560
+  priv->indicator_events = g_slist_prepend (priv->indicator_events,
 
561
+      indicator_event);
 
562
+}
 
563
+
 
564
+static void
 
565
+indicator_manager_event_removed_cb (EmpathyEventManager *event_manager,
 
566
+    EmpathyEvent *event,
 
567
+    EmpathyIndicatorManager *manager)
 
568
+{
 
569
+  EmpathyIndicatorManagerPriv *priv;
 
570
+  GSList *l;
 
571
+
 
572
+  priv = GET_PRIV (manager);
 
573
+
 
574
+  for (l = priv->indicator_events; l; l = l->next)
 
575
+  {
 
576
+    IndicatorEvent *indicator_event;
 
577
+    indicator_event = l->data;
 
578
+
 
579
+    if (compare_events (indicator_event->event, event)) {
 
580
+      priv->indicator_events = g_slist_remove (priv->indicator_events,
 
581
+          indicator_event);
 
582
+      empathy_indicator_hide (indicator_event->indicator);
 
583
+      return;
 
584
+    }
 
585
+  }
 
586
+}
 
587
+
 
588
+
 
589
+static void
 
590
+indicator_manager_event_updated_cb (EmpathyEventManager *event_manager,
 
591
+    EmpathyEvent *event,
 
592
+    EmpathyIndicatorManager *manager)
 
593
+{
 
594
+  EmpathyIndicatorManagerPriv *priv;
 
595
+  GSList *l;
 
596
+
 
597
+  priv = GET_PRIV (manager);
 
598
+
 
599
+  for (l = priv->indicator_events; l; l = l->next)
 
600
+  {
 
601
+    IndicatorEvent *indicator_event;
 
602
+    indicator_event = l->data;
 
603
+    if (compare_events (indicator_event->event, event)) {
 
604
+      empathy_indicator_update (indicator_event->indicator,
 
605
+          event->message);
 
606
+      return;
 
607
+    }
 
608
+  }
 
609
+}
 
610
+
 
611
+
 
612
+/* Remove the login indicator when it times out */
 
613
+static gboolean
 
614
+indicate_login_timeout (gpointer data)
 
615
+{
 
616
+  LoginData *login_data;
 
617
+  EmpathyIndicator *e_indicator;
 
618
+  EmpathyIndicatorManager *manager;
 
619
+  EmpathyIndicatorManagerPriv *priv;
 
620
+
 
621
+  login_data = (LoginData *) data;
 
622
+  e_indicator = login_data->indicator;
 
623
+  manager = login_data->manager;
 
624
+  priv = GET_PRIV (manager);
 
625
+
 
626
+  empathy_indicator_hide (e_indicator);
 
627
+  g_hash_table_remove (priv->login_timeouts, e_indicator);
 
628
+
 
629
+  return FALSE;
 
630
+}
 
631
+
 
632
+
 
633
+static void
 
634
+indicate_login_cb (EmpathyIndicator *e_indicator,
 
635
+    EmpathyIndicatorManager *manager)
 
636
+{
 
637
+  EmpathyIndicatorManagerPriv *priv;
 
638
+  GSList *events, *l;
 
639
+  EmpathyContact *contact;
 
640
+
 
641
+  priv = GET_PRIV (manager);
 
642
+
 
643
+  empathy_indicator_hide (e_indicator);
 
644
+  g_hash_table_remove (priv->login_timeouts, e_indicator);
 
645
+
 
646
+  contact = empathy_indicator_get_contact (e_indicator);
 
647
+  /* If the contact has an event activate it, otherwise the
 
648
+   * default handler of row-activated will be called. */
 
649
+  events = empathy_event_manager_get_events (priv->event_manager);
 
650
+  for (l = events; l; l = l->next) {
 
651
+    EmpathyEvent *event;
 
652
+
 
653
+    event = l->data;
 
654
+    if (event->contact == contact) {
 
655
+      empathy_event_activate (event);
 
656
+      return;
 
657
+    }
 
658
+  }
 
659
+
 
660
+  /* Else start a new conversation */
 
661
+  empathy_dispatcher_chat_with_contact (contact, NULL, NULL);
 
662
+}
 
663
+
 
664
+
 
665
+EmpathyIndicatorManager *
 
666
+empathy_indicator_manager_dup_singleton (void)
 
667
+{
 
668
+  return g_object_new (EMPATHY_TYPE_INDICATOR_MANAGER, NULL);
 
669
+}
 
670
+
 
671
+
 
672
+static void
 
673
+indicator_manager_dispose (GObject *object)
 
674
+{
 
675
+  EmpathyIndicatorManagerPriv *priv;
 
676
+
 
677
+  priv = GET_PRIV (object);
 
678
+
 
679
+  if (priv->indicator_events) {
 
680
+    g_slist_foreach (priv->indicator_events, (GFunc) indicator_event_free,
 
681
+        NULL);
 
682
+    g_slist_free (priv->indicator_events);
 
683
+    priv->indicator_events = NULL;
 
684
+  }
 
685
+  if (priv->event_manager) {
 
686
+    g_object_unref (priv->event_manager);
 
687
+    priv->event_manager = NULL;
 
688
+  }
 
689
+  if (priv->indicate_server) {
 
690
+    g_object_unref (priv->indicate_server);
 
691
+    priv->indicate_server = NULL;
 
692
+  }
 
693
+  if (priv->login_timeouts) {
 
694
+    g_hash_table_unref (priv->login_timeouts);
 
695
+    priv->login_timeouts = NULL;
 
696
+  }
 
697
+
 
698
+  G_OBJECT_CLASS (empathy_indicator_manager_parent_class)->dispose (object);  
 
699
+}
 
700
+
 
701
+
 
702
+static GObject *
 
703
+indicator_manager_constructor (GType type,
 
704
+    guint n_props,
 
705
+    GObjectConstructParam *props)
 
706
+{
 
707
+  GObject *retval;
 
708
+
 
709
+  if (manager_singleton != NULL) {
 
710
+    retval = g_object_ref (manager_singleton);
 
711
+  } else {
 
712
+    retval = G_OBJECT_CLASS (empathy_indicator_manager_parent_class)->constructor
 
713
+      (type, n_props, props);
 
714
+
 
715
+    manager_singleton = EMPATHY_INDICATOR_MANAGER (retval);
 
716
+    g_object_add_weak_pointer (retval, (gpointer) &manager_singleton);
 
717
+  }
 
718
+
 
719
+  return retval;
 
720
+}
 
721
+
 
722
+
 
723
+static void
 
724
+empathy_indicator_manager_class_init (EmpathyIndicatorManagerClass *klass)
 
725
+{
 
726
+  GObjectClass *object_class;
 
727
+
 
728
+  object_class = G_OBJECT_CLASS (klass);
 
729
+  object_class->dispose = indicator_manager_dispose;    
 
730
+  object_class->constructor = indicator_manager_constructor;
 
731
+
 
732
+  signals[SERVER_ACTIVATE] =
 
733
+      g_signal_new ("server-activate",
 
734
+          G_TYPE_FROM_CLASS (klass),
 
735
+          G_SIGNAL_RUN_LAST,
 
736
+          0,
 
737
+          NULL, NULL,
 
738
+          g_cclosure_marshal_VOID__VOID,
 
739
+          G_TYPE_NONE,
 
740
+          0);
 
741
+
 
742
+  g_type_class_add_private (object_class, sizeof (EmpathyIndicatorManagerPriv));
 
743
+}
 
744
+
 
745
+
 
746
+static void
 
747
+empathy_indicator_manager_init (EmpathyIndicatorManager *manager)
 
748
+{
 
749
+  EmpathyIndicatorManagerPriv *priv;
 
750
+
 
751
+  priv = G_TYPE_INSTANCE_GET_PRIVATE (manager,
 
752
+       EMPATHY_TYPE_INDICATOR_MANAGER, EmpathyIndicatorManagerPriv);
 
753
+  manager->priv = priv;
 
754
+
 
755
+  priv->event_manager = empathy_event_manager_dup_singleton ();
 
756
+  priv->login_timeouts = g_hash_table_new_full (NULL, NULL,
 
757
+      (GDestroyNotify) g_object_unref, (GDestroyNotify) g_source_unref);
 
758
+  priv->indicate_server = indicate_server_ref_default ();
 
759
+  indicate_server_set_type (priv->indicate_server, "message.instant");
 
760
+  indicate_server_set_desktop_file (priv->indicate_server,
 
761
+      EMPATHY_DESKTOP_PATH);
 
762
+
 
763
+  g_signal_connect (priv->indicate_server,
 
764
+      INDICATE_SERVER_SIGNAL_SERVER_DISPLAY,
 
765
+      G_CALLBACK (indicate_server_activate),
 
766
+      manager);
 
767
+
 
768
+  g_signal_connect (priv->event_manager, "event-added",
 
769
+      G_CALLBACK (indicator_manager_event_added_cb),
 
770
+      manager);
 
771
+  g_signal_connect (priv->event_manager, "event-removed",
 
772
+      G_CALLBACK (indicator_manager_event_removed_cb),
 
773
+      manager);
 
774
+  g_signal_connect (priv->event_manager, "event-updated",
 
775
+      G_CALLBACK (indicator_manager_event_updated_cb),
 
776
+      manager);
 
777
+}
 
778
+
 
779
+
 
780
+void
 
781
+empathy_indicator_manager_set_server_visible (EmpathyIndicatorManager *manager,
 
782
+    gboolean visible)
 
783
+{
 
784
+  EmpathyIndicatorManagerPriv *priv;
 
785
+
 
786
+  priv = GET_PRIV (manager);
 
787
+  if (visible) {
 
788
+    indicate_server_show (priv->indicate_server);
 
789
+  } else {
 
790
+    /* Causes a crash on next show currently due to object not being
 
791
+       unregistered from dbus
 
792
+    indicate_server_hide (priv->indicate_server);
 
793
+    */
 
794
+  }
 
795
+}
 
796
+
 
797
+
 
798
+EmpathyIndicator *
 
799
+empathy_indicator_manager_create_indicator (EmpathyIndicatorManager *manager,
 
800
+    EmpathyContact *sender,
 
801
+    const gchar *body)
 
802
+{
 
803
+  return empathy_indicator_new (sender, body, "im");
 
804
+}
 
805
+
 
806
+
 
807
+static LoginData *
 
808
+login_data_new (EmpathyIndicator *e_indicator,
 
809
+    EmpathyIndicatorManager *manager)
 
810
+{
 
811
+  LoginData *login_data;
 
812
+
 
813
+  login_data = g_slice_new0 (LoginData);
 
814
+  login_data->manager = g_object_ref (manager);
 
815
+  login_data->indicator = g_object_ref (e_indicator);
 
816
+
 
817
+  return login_data;
 
818
+}
 
819
+
 
820
+
 
821
+static void
 
822
+indicator_destroy_login_data (gpointer data)
 
823
+{
 
824
+  LoginData *login_data;
 
825
+
 
826
+  login_data = (LoginData *)data;
 
827
+
 
828
+  g_object_unref (login_data->manager);
 
829
+  g_object_unref (login_data->indicator);
 
830
+  g_slice_free (LoginData, login_data);   
 
831
+}
 
832
+
 
833
+
 
834
+/* Add an indicator for someone logging in. This will be displayed for
 
835
+ * a short period only.
 
836
+ */
 
837
+void
 
838
+empathy_indicator_manager_add_login_indicator (EmpathyIndicatorManager *manager,
 
839
+    EmpathyContact *contact)
 
840
+{
 
841
+  EmpathyIndicatorManagerPriv *priv;
 
842
+  GSource *timeout;
 
843
+  EmpathyIndicator *e_indicator;
 
844
+  LoginData *login_data;
 
845
+
 
846
+  priv = GET_PRIV (manager);
 
847
+  e_indicator = empathy_indicator_new (contact, NULL, "login");
 
848
+  login_data = login_data_new (e_indicator, manager);
 
849
+
 
850
+  timeout = g_timeout_source_new_seconds (INDICATOR_LOGIN_TIMEOUT);
 
851
+  g_source_set_callback (timeout, indicate_login_timeout, login_data,
 
852
+      indicator_destroy_login_data);
 
853
+  g_source_attach (timeout, NULL);
 
854
+
 
855
+  g_hash_table_insert (priv->login_timeouts, e_indicator, timeout);
 
856
+
 
857
+  g_signal_connect (e_indicator, "activate",
 
858
+      G_CALLBACK (indicate_login_cb), manager);
 
859
+  empathy_indicator_show (e_indicator);
 
860
+}
 
861
 
 
862
=== added file 'src/empathy-indicator-manager.h'
 
863
--- src/empathy-indicator-manager.h     1970-01-01 00:00:00 +0000
 
864
+++ src/empathy-indicator-manager.h     2009-09-18 18:41:20 +0000
 
865
@@ -0,0 +1,77 @@
 
866
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
 
867
+/*
 
868
+ * Copyright (C) 2009 Canonical Ltd.
 
869
+ *
 
870
+ * This program is free software; you can redistribute it and/or
 
871
+ * modify it under the terms of the GNU General Public License as
 
872
+ * published by the Free Software Foundation; either version 2 of the
 
873
+ * License, or (at your option) any later version.
 
874
+ *
 
875
+ * This program is distributed in the hope that it will be useful,
 
876
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
877
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
878
+ * General Public License for more details.
 
879
+ *
 
880
+ * You should have received a copy of the GNU General Public
 
881
+ * License along with this program; if not, write to the
 
882
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
 
883
+ * Boston, MA  02110-1301  USA
 
884
+ *
 
885
+ * Authors: James Westby <james.westby@ubuntu.com>
 
886
+ *
 
887
+ */
 
888
+
 
889
+#ifndef __EMPATHY_INDICATOR_MANAGER_H__
 
890
+#define __EMPATHY_INDICATOR_MANAGER_H__
 
891
+
 
892
+#include <glib.h>
 
893
+
 
894
+#include <libempathy/empathy-contact.h>
 
895
+#include "empathy-indicator.h"
 
896
+
 
897
+G_BEGIN_DECLS
 
898
+
 
899
+#define EMPATHY_TYPE_INDICATOR_MANAGER \
 
900
+  (empathy_indicator_manager_get_type ())
 
901
+#define EMPATHY_INDICATOR_MANAGER(o) \
 
902
+  (G_TYPE_CHECK_INSTANCE_CAST ((o), EMPATHY_TYPE_INDICATOR_MANAGER, \
 
903
+                               EmpathyIndicatorManager))
 
904
+#define EMPATHY_INDICATOR_MANAGER_CLASS(k) \
 
905
+  (G_TYPE_CHECK_CLASS_CAST((k), EMPATHY_TYPE_INDICATOR_MANAGER, \
 
906
+                           EmpathyIndicatorManagerClass))
 
907
+#define EMPATHY_IS_INDICATOR_MANAGER(o) \
 
908
+  (G_TYPE_CHECK_INSTANCE_TYPE ((o), EMPATHY_TYPE_INDICATOR_MANAGER))
 
909
+#define EMPATHY_IS_INDICATOR_MANAGER_CLASS(k) \
 
910
+  (G_TYPE_CHECK_CLASS_TYPE ((k), EMPATHY_TYPE_INDICATOR_MANAGER))
 
911
+#define EMPATHY_INDICATOR_MANAGER_GET_CLASS(o) \
 
912
+  (G_TYPE_INSTANCE_GET_CLASS ((o), EMPATHY_TYPE_INDICATOR_MANAGER, \
 
913
+                              EmpathyIndicatorManagerClass))
 
914
+
 
915
+typedef struct _EmpathyIndicatorManager      EmpathyIndicatorManager;
 
916
+typedef struct _EmpathyIndicatorManagerClass EmpathyIndicatorManagerClass;
 
917
+
 
918
+struct _EmpathyIndicatorManager {
 
919
+  GObject parent;
 
920
+  gpointer priv;
 
921
+};
 
922
+
 
923
+struct _EmpathyIndicatorManagerClass {
 
924
+  GObjectClass parent_class;
 
925
+};
 
926
+
 
927
+GType empathy_indicator_manager_get_type (void) G_GNUC_CONST;
 
928
+EmpathyIndicatorManager *empathy_indicator_manager_dup_singleton (void);
 
929
+void empathy_indicator_manager_set_server_visible (
 
930
+    EmpathyIndicatorManager *manager,
 
931
+    gboolean visible);
 
932
+EmpathyIndicator *empathy_indicator_manager_create_indicator (
 
933
+    EmpathyIndicatorManager *manager,
 
934
+    EmpathyContact *sender,
 
935
+    const gchar *body);
 
936
+void empathy_indicator_manager_add_login_indicator (
 
937
+    EmpathyIndicatorManager *manager,
 
938
+    EmpathyContact *contact);
 
939
+
 
940
+G_END_DECLS
 
941
+
 
942
+#endif /* __EMPATHY_INDICATOR_MANAGER_H__ */
 
943
 
 
944
=== added file 'src/empathy-indicator.c'
 
945
--- src/empathy-indicator.c     1970-01-01 00:00:00 +0000
 
946
+++ src/empathy-indicator.c     2009-09-18 18:41:20 +0000
 
947
@@ -0,0 +1,302 @@
 
948
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
 
949
+/*
 
950
+ * Copyright (C) 2009 Canonical Ltd.
 
951
+ *
 
952
+ * This program is free software; you can redistribute it and/or
 
953
+ * modify it under the terms of the GNU General Public License as
 
954
+ * published by the Free Software Foundation; either version 2 of the
 
955
+ * License, or (at your option) any later version.
 
956
+ *
 
957
+ * This program is distributed in the hope that it will be useful,
 
958
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
959
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
960
+ * General Public License for more details.
 
961
+ *
 
962
+ * You should have received a copy of the GNU General Public
 
963
+ * License along with this program; if not, write to the
 
964
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
 
965
+ * Boston, MA  02110-1301  USA
 
966
+ *
 
967
+ * Authors: James Westby <james.westby@ubuntu.com>
 
968
+ *
 
969
+ */
 
970
+
 
971
+#include <gtk/gtk.h>
 
972
+
 
973
+#include <libempathy/empathy-contact.h>
 
974
+#include <libempathy/empathy-utils.h>
 
975
+
 
976
+#include "empathy-indicator.h"
 
977
+#include "empathy-misc.h"
 
978
+
 
979
+#include <libindicate/indicator.h>
 
980
+
 
981
+#define GET_PRIV(obj) EMPATHY_GET_PRIV ((obj), EmpathyIndicator)
 
982
+
 
983
+enum {
 
984
+  PROP_0,
 
985
+  PROP_CONTACT,
 
986
+  PROP_BODY,
 
987
+  PROP_SUBTYPE,
 
988
+  PROP_VISIBLE
 
989
+};
 
990
+
 
991
+enum {
 
992
+  ACTIVATE,
 
993
+  LAST_SIGNAL
 
994
+};
 
995
+
 
996
+static guint signals[LAST_SIGNAL];
 
997
+
 
998
+typedef struct {
 
999
+  IndicateIndicator *indicator;
 
1000
+  EmpathyContact    *contact;
 
1001
+  gchar             *body;
 
1002
+  gchar             *subtype;
 
1003
+} EmpathyIndicatorPriv;
 
1004
+
 
1005
+G_DEFINE_TYPE (EmpathyIndicator, empathy_indicator, G_TYPE_OBJECT)
 
1006
+
 
1007
+
 
1008
+static void
 
1009
+empathy_indicator_dispose (GObject *object)
 
1010
+{
 
1011
+  EmpathyIndicatorPriv *priv;
 
1012
+
 
1013
+  priv = GET_PRIV (object);
 
1014
+
 
1015
+  if (priv->indicator) {
 
1016
+    g_object_unref (priv->indicator);
 
1017
+    priv->indicator = NULL;
 
1018
+  }
 
1019
+  if (priv->contact) {
 
1020
+    g_object_unref (priv->contact);
 
1021
+    priv->contact = NULL;
 
1022
+  }
 
1023
+
 
1024
+  G_OBJECT_CLASS (empathy_indicator_parent_class)->dispose (object);
 
1025
+}
 
1026
+
 
1027
+
 
1028
+static void
 
1029
+empathy_indicator_finalize (GObject *object)
 
1030
+{
 
1031
+  EmpathyIndicatorPriv *priv;
 
1032
+
 
1033
+  priv = GET_PRIV (object);
 
1034
+
 
1035
+  g_free (priv->body);
 
1036
+  g_free (priv->subtype);
 
1037
+
 
1038
+  G_OBJECT_CLASS (empathy_indicator_parent_class)->finalize (object);
 
1039
+}
 
1040
+
 
1041
+static void
 
1042
+indicate_show_cb (IndicateIndicator *indicator,
 
1043
+    EmpathyIndicator *e_indicator)
 
1044
+{
 
1045
+  g_signal_emit (e_indicator, signals[ACTIVATE], 0);
 
1046
+}
 
1047
+
 
1048
+
 
1049
+static IndicateIndicator *
 
1050
+empathy_indicator_get_indicator (EmpathyIndicator *e_indicator)
 
1051
+{
 
1052
+  EmpathyIndicatorPriv *priv;
 
1053
+    
 
1054
+  priv = GET_PRIV (e_indicator);
 
1055
+  if (priv->indicator)
 
1056
+    return priv->indicator;
 
1057
+    
 
1058
+  priv->indicator = indicate_indicator_new ();
 
1059
+  g_assert (priv->indicator);
 
1060
+  g_signal_connect (G_OBJECT (priv->indicator),
 
1061
+      INDICATE_INDICATOR_SIGNAL_DISPLAY,
 
1062
+      G_CALLBACK (indicate_show_cb),
 
1063
+      e_indicator);
 
1064
+
 
1065
+  return priv->indicator;
 
1066
+}
 
1067
+
 
1068
+
 
1069
+static void
 
1070
+empathy_indicator_set_property (GObject *object,
 
1071
+    guint param_id,
 
1072
+    const GValue *value,
 
1073
+    GParamSpec *pspec)
 
1074
+{
 
1075
+  EmpathyIndicator *e_indicator;
 
1076
+  EmpathyIndicatorPriv *priv;
 
1077
+  IndicateIndicator *indicator;
 
1078
+  GTimeVal time;
 
1079
+
 
1080
+  e_indicator = EMPATHY_INDICATOR (object);
 
1081
+  priv = GET_PRIV (e_indicator);
 
1082
+    
 
1083
+  indicator = empathy_indicator_get_indicator (e_indicator);
 
1084
+
 
1085
+  switch (param_id) {
 
1086
+  case PROP_CONTACT:
 
1087
+    priv->contact = g_object_ref (g_value_get_object (value));
 
1088
+    g_assert (priv->contact);
 
1089
+    indicate_indicator_set_property (indicator, "sender",
 
1090
+        empathy_contact_get_name (priv->contact));
 
1091
+    break;
 
1092
+  case PROP_BODY:
 
1093
+    if (priv->body)
 
1094
+      g_free (priv->body);
 
1095
+    priv->body = g_strdup (g_value_get_string (value));
 
1096
+    indicate_indicator_set_property (indicator, "body", priv->body);
 
1097
+    g_get_current_time (&time);
 
1098
+    indicate_indicator_set_property_time (indicator, "time", &time);
 
1099
+    break;
 
1100
+  case PROP_SUBTYPE:
 
1101
+    if (priv->subtype)
 
1102
+      g_free (priv->subtype);
 
1103
+    priv->subtype = g_strdup (g_value_get_string (value));
 
1104
+    indicate_indicator_set_property (indicator, "subtype", priv->subtype);
 
1105
+    break;
 
1106
+  case PROP_VISIBLE:
 
1107
+    if (g_value_get_boolean (value))
 
1108
+      indicate_indicator_show (indicator);
 
1109
+    else
 
1110
+      indicate_indicator_hide (indicator);
 
1111
+    break;
 
1112
+  default:
 
1113
+    G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
 
1114
+    break;
 
1115
+  }
 
1116
+}
 
1117
+
 
1118
+
 
1119
+static void
 
1120
+empathy_indicator_get_property (GObject *object,
 
1121
+    guint param_id,
 
1122
+    GValue *value,
 
1123
+    GParamSpec *pspec)
 
1124
+{
 
1125
+  EmpathyIndicator *e_indicator;
 
1126
+  EmpathyIndicatorPriv *priv;
 
1127
+
 
1128
+  e_indicator = EMPATHY_INDICATOR (object);
 
1129
+  priv = GET_PRIV (e_indicator);
 
1130
+
 
1131
+  switch (param_id) {
 
1132
+  case PROP_CONTACT:
 
1133
+    g_value_set_object (value, priv->contact);
 
1134
+    break;
 
1135
+  case PROP_BODY:
 
1136
+    g_value_set_string (value, priv->body);
 
1137
+    break;
 
1138
+  case PROP_SUBTYPE:
 
1139
+    g_value_set_string (value, priv->subtype);
 
1140
+    break;
 
1141
+  case PROP_VISIBLE:
 
1142
+    g_value_set_boolean (value, indicate_indicator_is_visible (priv->indicator));
 
1143
+    break;
 
1144
+  default:
 
1145
+    G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
 
1146
+    break;
 
1147
+  }
 
1148
+}
 
1149
+
 
1150
+
 
1151
+static void
 
1152
+empathy_indicator_class_init (EmpathyIndicatorClass *klass)
 
1153
+{
 
1154
+  GObjectClass *object_class;
 
1155
+
 
1156
+  object_class = G_OBJECT_CLASS (klass);
 
1157
+
 
1158
+  object_class->set_property = empathy_indicator_set_property;
 
1159
+  object_class->get_property = empathy_indicator_get_property;
 
1160
+  object_class->dispose = empathy_indicator_dispose;
 
1161
+  object_class->finalize = empathy_indicator_finalize;
 
1162
+
 
1163
+  g_object_class_install_property (object_class, PROP_CONTACT,
 
1164
+      g_param_spec_object ("contact",
 
1165
+          "Contact",
 
1166
+          "The contact being indicated",
 
1167
+          EMPATHY_TYPE_CONTACT,
 
1168
+          (G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)));
 
1169
+  g_object_class_install_property (object_class, PROP_BODY,
 
1170
+      g_param_spec_string ("body",
 
1171
+          "Body",
 
1172
+          "The text for this contact",
 
1173
+          NULL,
 
1174
+          (G_PARAM_READWRITE | G_PARAM_CONSTRUCT)));
 
1175
+  g_object_class_install_property (object_class, PROP_SUBTYPE,
 
1176
+      g_param_spec_string ("subtype",
 
1177
+          "Subtype",
 
1178
+          "The type of this indicator",
 
1179
+          NULL,
 
1180
+          (G_PARAM_READWRITE | G_PARAM_CONSTRUCT)));
 
1181
+  g_object_class_install_property (object_class, PROP_VISIBLE,
 
1182
+      g_param_spec_boolean ("visible",
 
1183
+          "Visible",
 
1184
+          "The visibility of this indicator",
 
1185
+          FALSE,
 
1186
+          G_PARAM_READWRITE));
 
1187
+
 
1188
+  signals[ACTIVATE] =
 
1189
+      g_signal_new ("activate",
 
1190
+          G_TYPE_FROM_CLASS (klass),
 
1191
+          G_SIGNAL_RUN_LAST,
 
1192
+          0,
 
1193
+          NULL, NULL,
 
1194
+          g_cclosure_marshal_VOID__VOID,
 
1195
+          G_TYPE_NONE,
 
1196
+          0);
 
1197
+
 
1198
+  g_type_class_add_private (object_class, sizeof (EmpathyIndicatorPriv));
 
1199
+}
 
1200
+
 
1201
+
 
1202
+static void
 
1203
+empathy_indicator_init (EmpathyIndicator *e_indicator)
 
1204
+{
 
1205
+  e_indicator->priv = G_TYPE_INSTANCE_GET_PRIVATE (e_indicator,
 
1206
+      EMPATHY_TYPE_INDICATOR,
 
1207
+      EmpathyIndicatorPriv);
 
1208
+}
 
1209
+
 
1210
+
 
1211
+EmpathyIndicator *
 
1212
+empathy_indicator_new (EmpathyContact *sender,
 
1213
+    const gchar *body,
 
1214
+    const gchar *subtype)
 
1215
+{
 
1216
+  return g_object_new (EMPATHY_TYPE_INDICATOR, "contact", sender, "body", body,
 
1217
+      "subtype", subtype, NULL);
 
1218
+}
 
1219
+
 
1220
+
 
1221
+void
 
1222
+empathy_indicator_show (EmpathyIndicator *e_indicator)
 
1223
+{
 
1224
+  g_object_set (e_indicator, "visible", TRUE, NULL);
 
1225
+}
 
1226
+
 
1227
+
 
1228
+void
 
1229
+empathy_indicator_hide (EmpathyIndicator *e_indicator)
 
1230
+{
 
1231
+  g_object_set (e_indicator, "visible", FALSE, NULL);
 
1232
+}
 
1233
+
 
1234
+
 
1235
+void
 
1236
+empathy_indicator_update (EmpathyIndicator *e_indicator,
 
1237
+    const gchar *body)
 
1238
+{
 
1239
+  g_object_set (e_indicator, "body", body, NULL);
 
1240
+}
 
1241
+
 
1242
+
 
1243
+EmpathyContact *
 
1244
+empathy_indicator_get_contact (EmpathyIndicator *e_indicator)
 
1245
+{
 
1246
+  EmpathyContact *contact;
 
1247
+  g_object_get (e_indicator, "contact", &contact, NULL);
 
1248
+  return contact;
 
1249
+}
 
1250
 
 
1251
=== added file 'src/empathy-indicator.h'
 
1252
--- src/empathy-indicator.h     1970-01-01 00:00:00 +0000
 
1253
+++ src/empathy-indicator.h     2009-09-18 18:41:20 +0000
 
1254
@@ -0,0 +1,65 @@
 
1255
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
 
1256
+/*
 
1257
+ * Copyright (C) 2009 Canonical Ltd.
 
1258
+ *
 
1259
+ * This program is free software; you can redistribute it and/or
 
1260
+ * modify it under the terms of the GNU General Public License as
 
1261
+ * published by the Free Software Foundation; either version 2 of the
 
1262
+ * License, or (at your option) any later version.
 
1263
+ *
 
1264
+ * This program is distributed in the hope that it will be useful,
 
1265
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
1266
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
1267
+ * General Public License for more details.
 
1268
+ *
 
1269
+ * You should have received a copy of the GNU General Public
 
1270
+ * License along with this program; if not, write to the
 
1271
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
 
1272
+ * Boston, MA  02110-1301  USA
 
1273
+ *
 
1274
+ * Authors: James Westby <james.westby@ubuntu.com>
 
1275
+ *
 
1276
+ */
 
1277
+
 
1278
+#ifndef __EMPATHY_INDICATOR_H__
 
1279
+#define __EMPATHY_INDICATOR_H__
 
1280
+
 
1281
+#include <glib.h>
 
1282
+
 
1283
+#include <libempathy/empathy-contact.h>
 
1284
+
 
1285
+G_BEGIN_DECLS
 
1286
+
 
1287
+#define EMPATHY_TYPE_INDICATOR         (empathy_indicator_get_type ())
 
1288
+#define EMPATHY_INDICATOR(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), EMPATHY_TYPE_INDICATOR, EmpathyIndicator))
 
1289
+#define EMPATHY_INDICATOR_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST((k), EMPATHY_TYPE_INDICATOR, EmpathyIndicatorClass))
 
1290
+#define EMPATHY_IS_INDICATOR(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), EMPATHY_TYPE_INDICATOR))
 
1291
+#define EMPATHY_IS_INDICATOR_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), EMPATHY_TYPE_INDICATOR))
 
1292
+#define EMPATHY_INDICATOR_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), EMPATHY_TYPE_INDICATOR, EmpathyIndicatorClass))
 
1293
+
 
1294
+typedef struct _EmpathyIndicator      EmpathyIndicator;
 
1295
+typedef struct _EmpathyIndicatorClass EmpathyIndicatorClass;
 
1296
+
 
1297
+struct _EmpathyIndicator {
 
1298
+  GObject parent;
 
1299
+  gpointer priv;
 
1300
+};
 
1301
+
 
1302
+struct _EmpathyIndicatorClass {
 
1303
+  GObjectClass parent_class;
 
1304
+};
 
1305
+
 
1306
+GType empathy_indicator_get_type (void) G_GNUC_CONST;
 
1307
+EmpathyIndicator *empathy_indicator_new (EmpathyContact *sender,
 
1308
+    const gchar *body,
 
1309
+    const gchar *type);
 
1310
+void empathy_indicator_show (EmpathyIndicator *e_indicator);
 
1311
+void empathy_indicator_hide (EmpathyIndicator *e_indicator);
 
1312
+void empathy_indicator_update (EmpathyIndicator *e_indicator,
 
1313
+    const gchar *body);
 
1314
+EmpathyContact *empathy_indicator_get_contact (EmpathyIndicator *e_indicator);
 
1315
+
 
1316
+G_END_DECLS
 
1317
+
 
1318
+
 
1319
+#endif /* __EMPATHY-INDICATOR_H__ */
 
1320
 
 
1321
=== modified file 'src/empathy-main-window.c'
 
1322
--- src/empathy-main-window.c   2009-09-18 18:41:05 +0000
 
1323
+++ src/empathy-main-window.c   2009-09-18 18:41:20 +0000
 
1324
@@ -61,6 +61,10 @@
 
1325
 #include "empathy-event-manager.h"
 
1326
 #include "empathy-ft-manager.h"
 
1327
 
 
1328
+#ifdef HAVE_LIBINDICATE
 
1329
+#include "empathy-indicator-manager.h"
 
1330
+#endif
 
1331
+
 
1332
 #define DEBUG_FLAG EMPATHY_DEBUG_OTHER
 
1333
 #include <libempathy/empathy-debug.h>
 
1334
 
 
1335
@@ -111,6 +115,10 @@
 
1336
 
 
1337
        /* Actions that are enabled when there are connected accounts */
 
1338
        GList                  *actions_connected;
 
1339
+#ifdef HAVE_LIBINDICATE
 
1340
+       EmpathyIndicatorManager *indicator_manager;
 
1341
+       GHashTable              *indicator_timeouts;
 
1342
+#endif
 
1343
 } EmpathyMainWindow;
 
1344
 
 
1345
 static EmpathyMainWindow *window = NULL;
 
1346
@@ -600,6 +608,10 @@
 
1347
         /* someone is logging in */
 
1348
         empathy_sound_play (GTK_WIDGET (window->window),
 
1349
           EMPATHY_SOUND_CONTACT_CONNECTED);
 
1350
+#ifdef HAVE_LIBINDICATE
 
1351
+        empathy_indicator_manager_add_login_indicator (window->indicator_manager,
 
1352
+          contact);
 
1353
+#endif
 
1354
     }
 
1355
 }
 
1356
 
 
1357
@@ -664,6 +676,10 @@
 
1358
        g_object_unref (window->event_manager);
 
1359
        g_object_unref (window->ui_manager);
 
1360
 
 
1361
+#ifdef HAVE_LIBINDICATE
 
1362
+       g_object_unref (window->indicator_manager);
 
1363
+#endif
 
1364
+
 
1365
        g_free (window);
 
1366
 }
 
1367
 
 
1368
@@ -1238,6 +1254,10 @@
 
1369
                              "help_contents", "activate", main_window_help_contents_cb,
 
1370
                              NULL);
 
1371
 
 
1372
+#ifdef HAVE_LIBINDICATE
 
1373
+       window->indicator_manager = empathy_indicator_manager_dup_singleton ();
 
1374
+#endif
 
1375
+
 
1376
        /* Set up connection related widgets. */
 
1377
        main_window_connection_items_setup (window, gui);
 
1378
 
 
1379
 
 
1380
=== modified file 'src/empathy-preferences.c'
 
1381
--- src/empathy-preferences.c   2009-09-18 18:41:05 +0000
 
1382
+++ src/empathy-preferences.c   2009-09-18 18:41:20 +0000
 
1383
@@ -53,6 +53,7 @@
 
1384
 
 
1385
        GtkWidget *checkbutton_show_smileys;
 
1386
        GtkWidget *checkbutton_show_contacts_in_rooms;
 
1387
+       GtkWidget *checkbutton_use_libindicate;
 
1388
        GtkWidget *combobox_chat_theme;
 
1389
        GtkWidget *checkbutton_separate_chat_windows;
 
1390
        GtkWidget *checkbutton_autoconnect;
 
1391
@@ -215,6 +216,14 @@
 
1392
                                          EMPATHY_PREFS_CHAT_SHOW_SMILEYS,
 
1393
                                          preferences->checkbutton_show_smileys);
 
1394
 
 
1395
+#ifdef HAVE_LIBINDICATE
 
1396
+       preferences_hookup_toggle_button (preferences,
 
1397
+                                         EMPATHY_PREFS_UI_USE_LIBINDICATE,
 
1398
+                                         preferences->checkbutton_use_libindicate);
 
1399
+#else
 
1400
+       gtk_widget_hide (GTK_WIDGET (preferences->checkbutton_use_libindicate));
 
1401
+#endif
 
1402
+
 
1403
        preferences_hookup_toggle_button (preferences,
 
1404
                                          EMPATHY_PREFS_CHAT_SHOW_CONTACTS_IN_ROOMS,
 
1405
                                          preferences->checkbutton_show_contacts_in_rooms);
 
1406
@@ -1137,6 +1146,7 @@
 
1407
                "notebook", &preferences->notebook,
 
1408
                "checkbutton_show_smileys", &preferences->checkbutton_show_smileys,
 
1409
                "checkbutton_show_contacts_in_rooms", &preferences->checkbutton_show_contacts_in_rooms,
 
1410
+               "checkbutton_use_libindicate", &preferences->checkbutton_use_libindicate,
 
1411
                "combobox_chat_theme", &preferences->combobox_chat_theme,
 
1412
                "checkbutton_separate_chat_windows", &preferences->checkbutton_separate_chat_windows,
 
1413
                "checkbutton_autoconnect", &preferences->checkbutton_autoconnect,
 
1414
 
 
1415
=== modified file 'src/empathy-preferences.ui'
 
1416
--- src/empathy-preferences.ui  2009-09-18 18:41:05 +0000
 
1417
+++ src/empathy-preferences.ui  2009-09-18 18:41:20 +0000
 
1418
@@ -250,6 +250,20 @@
 
1419
                     <property name="position">1</property>
 
1420
                   </packing>
 
1421
                 </child>
 
1422
+                <child>
 
1423
+                  <object class="GtkCheckButton" id="checkbutton_use_libindicate">
 
1424
+                    <property name="label" translatable="yes">Use message indicators</property>
 
1425
+                    <property name="visible">True</property>
 
1426
+                    <property name="can_focus">True</property>
 
1427
+                    <property name="receives_default">False</property>
 
1428
+                    <property name="draw_indicator">True</property>
 
1429
+                  </object>
 
1430
+                  <packing>
 
1431
+                    <property name="expand">False</property>
 
1432
+                    <property name="fill">False</property>
 
1433
+                    <property name="position">2</property>
 
1434
+                  </packing>
 
1435
+                </child>
 
1436
               </object>
 
1437
               <packing>
 
1438
                 <property name="position">1</property>
 
1439
 
 
1440
=== modified file 'src/empathy-status-icon.c'
 
1441
--- src/empathy-status-icon.c   2009-09-18 18:41:05 +0000
 
1442
+++ src/empathy-status-icon.c   2009-09-18 18:41:20 +0000
 
1443
@@ -28,6 +28,7 @@
 
1444
 #include <gtk/gtk.h>
 
1445
 #include <gdk/gdkkeysyms.h>
 
1446
 
 
1447
+#include <libnotify/notify.h>
 
1448
 #include <libnotify/notification.h>
 
1449
 
 
1450
 #include <libempathy/empathy-utils.h>
 
1451
@@ -40,12 +41,18 @@
 
1452
 #include <libempathy-gtk/empathy-images.h>
 
1453
 #include <libempathy-gtk/empathy-new-message-dialog.h>
 
1454
 
 
1455
+#include <telepathy-glib/util.h>
 
1456
+
 
1457
 #include "empathy-accounts-dialog.h"
 
1458
 #include "empathy-status-icon.h"
 
1459
 #include "empathy-preferences.h"
 
1460
 #include "empathy-event-manager.h"
 
1461
 #include "empathy-misc.h"
 
1462
 
 
1463
+#ifdef HAVE_LIBINDICATE
 
1464
+#include "empathy-indicator-manager.h"
 
1465
+#endif
 
1466
+
 
1467
 #define DEBUG_FLAG EMPATHY_DEBUG_DISPATCHER
 
1468
 #include <libempathy/empathy-debug.h>
 
1469
 
 
1470
@@ -69,6 +76,9 @@
 
1471
        GtkAction           *show_window_item;
 
1472
        GtkAction           *new_message_item;
 
1473
        GtkAction           *status_item;
 
1474
+#ifdef HAVE_LIBINDICATE
 
1475
+       EmpathyIndicatorManager *indicator_manager;
 
1476
+#endif
 
1477
 } EmpathyStatusIconPriv;
 
1478
 
 
1479
 G_DEFINE_TYPE (EmpathyStatusIcon, empathy_status_icon, G_TYPE_OBJECT);
 
1480
@@ -81,6 +91,33 @@
 
1481
        return FALSE;
 
1482
 }
 
1483
 
 
1484
+/* Query whether the notification server supports the "action"
 
1485
+ * extension to the notifications specification, if it doesn't
 
1486
+ * the sending actions has undefined results.
 
1487
+ */
 
1488
+static gboolean
 
1489
+notification_server_supports_actions (void)
 
1490
+{
 
1491
+       GList *caps = notify_get_server_caps ();
 
1492
+       GList *l;
 
1493
+       gboolean ret = FALSE;
 
1494
+
 
1495
+       for (l = caps; l; l = l->next) {
 
1496
+               gchar *cap = (gchar *) l->data;
 
1497
+               if (!cap) {
 
1498
+                       continue;
 
1499
+               }
 
1500
+               if (!tp_strdiff (cap, "actions")) {
 
1501
+                       ret = TRUE;
 
1502
+                       break;
 
1503
+               }
 
1504
+       }
 
1505
+       g_list_foreach (caps, (GFunc)g_free, NULL);
 
1506
+       g_list_free (caps);
 
1507
+
 
1508
+       return ret;
 
1509
+}
 
1510
+
 
1511
 static void
 
1512
 status_icon_notification_closed_cb (NotifyNotification *notification,
 
1513
                                    EmpathyStatusIcon  *icon)
 
1514
@@ -110,8 +147,14 @@
 
1515
                 */
 
1516
                g_idle_add ((GSourceFunc) activate_event, priv->event);
 
1517
        } else {
 
1518
-               /* inhibit other updates for this event */
 
1519
-               empathy_event_inhibit_updates (priv->event);
 
1520
+               /* inhibit other updates for this event, but only if
 
1521
+                * the server supports actions, using that as a proxy
 
1522
+                * for being click-through, as many notifications aren't
 
1523
+                * a problem then. Maybe not the right thing to do.
 
1524
+                */
 
1525
+               if (notification_server_supports_actions ()) {
 
1526
+                       empathy_event_inhibit_updates (priv->event);
 
1527
+               }
 
1528
        }
 
1529
 }
 
1530
 
 
1531
@@ -318,6 +361,28 @@
 
1532
        }
 
1533
 }
 
1534
 
 
1535
+#ifdef HAVE_LIBINDICATE
 
1536
+static void
 
1537
+status_icon_set_use_libindicate (EmpathyStatusIcon *icon,
 
1538
+                           gboolean           use_libindicate)
 
1539
+{
 
1540
+       EmpathyStatusIconPriv *priv = GET_PRIV (icon);
 
1541
+
 
1542
+       if (use_libindicate) {
 
1543
+               empathy_indicator_manager_set_server_visible (priv->indicator_manager,
 
1544
+                               TRUE);
 
1545
+               /* Hide the status icon so there are not two ways to access empathy.
 
1546
+                * Should use libindicate's "interest" to confirm someone is listening.
 
1547
+                */
 
1548
+               gtk_status_icon_set_visible (priv->icon, FALSE);
 
1549
+       } else {
 
1550
+               empathy_indicator_manager_set_server_visible (priv->indicator_manager,
 
1551
+                               FALSE);
 
1552
+               gtk_status_icon_set_visible (priv->icon, TRUE);
 
1553
+       }
 
1554
+}
 
1555
+#endif
 
1556
+
 
1557
 static void
 
1558
 status_icon_notify_visibility_cb (EmpathyConf *conf,
 
1559
                                  const gchar *key,
 
1560
@@ -331,16 +396,56 @@
 
1561
        }
 
1562
 }
 
1563
 
 
1564
+#ifdef HAVE_LIBINDICATE
 
1565
+static void
 
1566
+status_icon_notify_libindicate_cb (EmpathyConf *conf,
 
1567
+                                 const gchar *key,
 
1568
+                                 gpointer     user_data)
 
1569
+{
 
1570
+       EmpathyStatusIcon *icon = user_data;
 
1571
+       gboolean           use_libindicate = FALSE;
 
1572
+
 
1573
+       if (empathy_conf_get_bool (conf, key, &use_libindicate)) {
 
1574
+               status_icon_set_use_libindicate (icon, use_libindicate);
 
1575
+       }
 
1576
+}
 
1577
+#endif
 
1578
+
 
1579
 static void
 
1580
 status_icon_toggle_visibility (EmpathyStatusIcon *icon)
 
1581
 {
 
1582
        EmpathyStatusIconPriv *priv = GET_PRIV (icon);
 
1583
        gboolean               visible;
 
1584
+#ifdef HAVE_LIBINDICATE
 
1585
+       gboolean               use_libindicate;
 
1586
+#endif
 
1587
 
 
1588
        visible = gtk_window_is_active (priv->window);
 
1589
+#ifdef HAVE_LIBINDICATE
 
1590
+       empathy_conf_get_bool (empathy_conf_get (),
 
1591
+                              EMPATHY_PREFS_UI_USE_LIBINDICATE,
 
1592
+                              &use_libindicate);
 
1593
+       if (use_libindicate) {
 
1594
+               /* If indicators are used then we may very well not be active
 
1595
+                * when toggled, as they are usually windows themselves. This
 
1596
+                * makes it damn hard to toggle, so we just look at whether
 
1597
+                * we are visible.
 
1598
+                */
 
1599
+               visible = GTK_WIDGET_VISIBLE (priv->window);
 
1600
+       }
 
1601
+#endif
 
1602
        status_icon_set_visibility (icon, !visible, TRUE);
 
1603
 }
 
1604
 
 
1605
+#ifdef HAVE_LIBINDICATE
 
1606
+static void
 
1607
+indicate_server_activate_cb (EmpathyIndicatorManager *manager,
 
1608
+                                 EmpathyStatusIcon *icon)
 
1609
+{
 
1610
+       status_icon_toggle_visibility (icon);
 
1611
+}
 
1612
+#endif
 
1613
+
 
1614
 static void
 
1615
 status_icon_idle_notify_cb (EmpathyStatusIcon *icon)
 
1616
 {
 
1617
@@ -521,6 +626,10 @@
 
1618
        g_object_unref (priv->account_manager);
 
1619
        g_object_unref (priv->event_manager);
 
1620
        g_object_unref (priv->ui_manager);
 
1621
+
 
1622
+#ifdef HAVE_LIBINDICATE
 
1623
+       g_object_unref (priv->indicator_manager);
 
1624
+#endif
 
1625
 }
 
1626
 
 
1627
 static void
 
1628
@@ -555,6 +664,13 @@
 
1629
                                 status_icon_notify_visibility_cb,
 
1630
                                 icon);
 
1631
 
 
1632
+#ifdef HAVE_LIBINDICATE
 
1633
+       empathy_conf_notify_add (empathy_conf_get (),
 
1634
+                                EMPATHY_PREFS_UI_USE_LIBINDICATE,
 
1635
+                                status_icon_notify_libindicate_cb,
 
1636
+                                icon);
 
1637
+#endif
 
1638
+
 
1639
        status_icon_create_menu (icon);
 
1640
        status_icon_idle_notify_cb (icon);
 
1641
 
 
1642
@@ -584,6 +700,9 @@
 
1643
        EmpathyStatusIconPriv *priv;
 
1644
        EmpathyStatusIcon     *icon;
 
1645
        gboolean               should_hide;
 
1646
+#ifdef HAVE_LIBINDICATE
 
1647
+       gboolean               use_libindicate;
 
1648
+#endif
 
1649
 
 
1650
        g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
 
1651
 
 
1652
@@ -591,6 +710,12 @@
 
1653
        priv = GET_PRIV (icon);
 
1654
 
 
1655
        priv->window = g_object_ref (window);
 
1656
+#ifdef HAVE_LIBINDICATE
 
1657
+       priv->indicator_manager = empathy_indicator_manager_dup_singleton ();
 
1658
+       g_signal_connect (priv->indicator_manager, "server-activate",
 
1659
+                         G_CALLBACK (indicate_server_activate_cb),
 
1660
+                         icon);
 
1661
+#endif
 
1662
 
 
1663
        g_signal_connect_after (priv->window, "key-press-event",
 
1664
                          G_CALLBACK (status_icon_key_press_event_cb),
 
1665
@@ -608,6 +733,13 @@
 
1666
                should_hide = TRUE;
 
1667
        }
 
1668
 
 
1669
+#ifdef HAVE_LIBINDICATE
 
1670
+       empathy_conf_get_bool (empathy_conf_get (),
 
1671
+                              EMPATHY_PREFS_UI_USE_LIBINDICATE,
 
1672
+                              &use_libindicate);
 
1673
+       status_icon_set_use_libindicate (icon, use_libindicate);
 
1674
+#endif
 
1675
+
 
1676
        if (gtk_window_is_active (priv->window) == should_hide) {
 
1677
                status_icon_set_visibility (icon, !should_hide, FALSE);
 
1678
        }
 
1679