~ubuntu-branches/ubuntu/maverick/xchat/maverick

« back to all changes in this revision

Viewing changes to .pc/70_notification_strings_shorten.patch/src/fe-gtk/plugin-tray.c

  • Committer: Bazaar Package Importer
  • Author(s): Lorenzo De Liso
  • Date: 2010-06-21 22:47:10 UTC
  • mfrom: (2.1.7 sid)
  • Revision ID: james.westby@ubuntu.com-20100621224710-9t1iyiglri330pss
Tags: 2.8.8-1ubuntu1
* Merge from debian unstable (LP: #597042), remaining changes:
  - debian/patches:
    + series: Refreshed.
    + 01_serverlist.patch: Numerous changes to default serverlist.
    + 02_ubuntu_default_server.patch: select "Ubuntu servers" by default.
    + 37_lpi.patch: Add launchpad integration.
    + 38_autoconf.patch: Autoconf modifications for launchpad integration.
    + 45_brand_ctcp_version.patch: Add Ubuntu brand to CTCP version response.
    + 70_notification_strings_shorten.patch: Shorten notification strings.
  - debian/control:
    + Build-depend on libgtk2.0-dev (>= 2.10.0).
    + Build-depend on liblaunchpad-integration-dev.
    + Remove conflict/replaces on xchat-gnome.
    + Updated Maintainer field to match Ubuntu Developers.
  - debian/rules:
    + Make build independent of the python version.
  - debian/patches/45_ctcp_version_less_information.dpatch: 
    + Renamed to debian/patches/45_brand_ctcp_version.patch
    + Added short description.
* Converted all patches to quilt, as in debian quilt has been
  adopted, all old dpatch patches have been renamed with the 
  *.patch extension.
* Dropped changes:
  - 71_notification_icon_change.patch: can't be applied

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright (C) 2006-2007 Peter Zelezny. */
 
2
 
 
3
#include <string.h>
 
4
#include <unistd.h>
 
5
#include "../common/xchat-plugin.h"
 
6
#include "../common/xchat.h"
 
7
#include "../common/xchatc.h"
 
8
#include "../common/inbound.h"
 
9
#include "../common/server.h"
 
10
#include "../common/fe.h"
 
11
#include "../common/util.h"
 
12
#include "fe-gtk.h"
 
13
#include "pixmaps.h"
 
14
#include "maingui.h"
 
15
#include "menu.h"
 
16
#include <gtk/gtk.h>
 
17
 
 
18
#define LIBNOTIFY
 
19
 
 
20
typedef enum    /* current icon status */
 
21
{
 
22
        TS_NONE,
 
23
        TS_MESSAGE,
 
24
        TS_HIGHLIGHT,
 
25
        TS_FILEOFFER,
 
26
        TS_CUSTOM /* plugin */
 
27
} TrayStatus;
 
28
 
 
29
typedef enum
 
30
{
 
31
        WS_FOCUSED,
 
32
        WS_NORMAL,
 
33
        WS_HIDDEN
 
34
} WinStatus;
 
35
 
 
36
typedef GdkPixbuf* TrayIcon;
 
37
#define tray_icon_from_file(f) gdk_pixbuf_new_from_file(f,NULL)
 
38
#define tray_icon_free(i) g_object_unref(i)
 
39
 
 
40
#define ICON_NORMAL pix_xchat
 
41
#define ICON_MSG pix_tray_msg
 
42
#define ICON_HILIGHT pix_tray_hilight
 
43
#define ICON_FILE pix_tray_file
 
44
#define TIMEOUT 500
 
45
 
 
46
static GtkStatusIcon *sticon;
 
47
static gint flash_tag;
 
48
static TrayStatus tray_status;
 
49
static xchat_plugin *ph;
 
50
 
 
51
static TrayIcon custom_icon1;
 
52
static TrayIcon custom_icon2;
 
53
 
 
54
static int tray_priv_count = 0;
 
55
static int tray_pub_count = 0;
 
56
static int tray_hilight_count = 0;
 
57
static int tray_file_count = 0;
 
58
 
 
59
 
 
60
void tray_apply_setup (void);
 
61
 
 
62
 
 
63
static WinStatus
 
64
tray_get_window_status (void)
 
65
{
 
66
        const char *st;
 
67
 
 
68
        st = xchat_get_info (ph, "win_status");
 
69
 
 
70
        if (!st)
 
71
                return WS_HIDDEN;
 
72
 
 
73
        if (!strcmp (st, "active"))
 
74
                return WS_FOCUSED;
 
75
 
 
76
        if (!strcmp (st, "hidden"))
 
77
                return WS_HIDDEN;
 
78
 
 
79
        return WS_NORMAL;
 
80
}
 
81
 
 
82
static int
 
83
tray_count_channels (void)
 
84
{
 
85
        int cons = 0;
 
86
        GSList *list;
 
87
        session *sess;
 
88
 
 
89
        for (list = sess_list; list; list = list->next)
 
90
        {
 
91
                sess = list->data;
 
92
                if (sess->server->connected && sess->channel[0] &&
 
93
                         sess->type == SESS_CHANNEL)
 
94
                        cons++;
 
95
        }
 
96
        return cons;
 
97
}
 
98
 
 
99
static int
 
100
tray_count_networks (void)
 
101
{
 
102
        int cons = 0;
 
103
        GSList *list;
 
104
 
 
105
        for (list = serv_list; list; list = list->next)
 
106
        {
 
107
                if (((server *)list->data)->connected)
 
108
                        cons++;
 
109
        }
 
110
        return cons;
 
111
}
 
112
 
 
113
void
 
114
fe_tray_set_tooltip (const char *text)
 
115
{
 
116
        if (sticon)
 
117
                gtk_status_icon_set_tooltip (sticon, text);
 
118
}
 
119
 
 
120
#ifdef LIBNOTIFY
 
121
 
 
122
/* dynamic access to libnotify.so */
 
123
 
 
124
static void *nn_mod = NULL;
 
125
/* prototypes */
 
126
static gboolean (*nn_init) (char *);
 
127
static void (*nn_uninit) (void);
 
128
static void *(*nn_new_with_status_icon) (const gchar *summary, const gchar *message, const gchar *icon, GtkStatusIcon *status_icon);
 
129
static void *(*nn_new) (const gchar *summary, const gchar *message, const gchar *icon, GtkWidget *attach);
 
130
static gboolean (*nn_show) (void *noti, GError **error);
 
131
static void (*nn_set_timeout) (void *noti, gint timeout);
 
132
 
 
133
static void
 
134
libnotify_cleanup (void)
 
135
{
 
136
        if (nn_mod)
 
137
        {
 
138
                nn_uninit ();
 
139
                g_module_close (nn_mod);
 
140
                nn_mod = NULL;
 
141
        }
 
142
}
 
143
 
 
144
static gboolean
 
145
libnotify_notify_new (const char *title, const char *text, GtkStatusIcon *icon)
 
146
{
 
147
        void *noti;
 
148
 
 
149
        if (!nn_mod)
 
150
        {
 
151
                nn_mod = g_module_open ("libnotify", G_MODULE_BIND_LAZY);
 
152
                if (!nn_mod)
 
153
                {
 
154
                        nn_mod = g_module_open ("libnotify.so.1", G_MODULE_BIND_LAZY);
 
155
                        if (!nn_mod)
 
156
                                return FALSE;
 
157
                }
 
158
 
 
159
                if (!g_module_symbol (nn_mod, "notify_init", (gpointer)&nn_init))
 
160
                        goto bad;
 
161
                if (!g_module_symbol (nn_mod, "notify_uninit", (gpointer)&nn_uninit))
 
162
                        goto bad;
 
163
                if (!g_module_symbol (nn_mod, "notify_notification_new_with_status_icon", (gpointer)&nn_new_with_status_icon))
 
164
                        goto bad;
 
165
                if (!g_module_symbol (nn_mod, "notify_notification_new", (gpointer)&nn_new))
 
166
                        goto bad;
 
167
                if (!g_module_symbol (nn_mod, "notify_notification_show", (gpointer)&nn_show))
 
168
                        goto bad;
 
169
                if (!g_module_symbol (nn_mod, "notify_notification_set_timeout", (gpointer)&nn_set_timeout))
 
170
                        goto bad;
 
171
                if (!nn_init (PACKAGE_NAME))
 
172
                        goto bad;
 
173
        }
 
174
 
 
175
        text = strip_color (text, -1, STRIP_ALL|STRIP_ESCMARKUP);
 
176
        title = strip_color (title, -1, STRIP_ALL);
 
177
        noti = nn_new (title, text, XCHATSHAREDIR"/pixmaps/xchat.png", NULL);
 
178
        g_free ((char *)title);
 
179
        g_free ((char *)text);
 
180
 
 
181
        nn_set_timeout (noti, prefs.input_balloon_time*1000);
 
182
        nn_show (noti, NULL);
 
183
        g_object_unref (G_OBJECT (noti));
 
184
 
 
185
        return TRUE;
 
186
 
 
187
bad:
 
188
        g_module_close (nn_mod);
 
189
        nn_mod = NULL;
 
190
        return FALSE;
 
191
}
 
192
 
 
193
#endif
 
194
 
 
195
void
 
196
fe_tray_set_balloon (const char *title, const char *text)
 
197
{
 
198
#ifndef WIN32
 
199
        const char *argv[8];
 
200
        const char *path;
 
201
        char time[16];
 
202
        WinStatus ws;
 
203
 
 
204
        /* no balloons if the window is focused */
 
205
        ws = tray_get_window_status ();
 
206
        if (ws == WS_FOCUSED)
 
207
                return;
 
208
 
 
209
        /* bit 1 of flags means "no balloons unless hidden/iconified" */
 
210
        if (ws != WS_HIDDEN && (prefs.gui_tray_flags & 2))
 
211
                return;
 
212
 
 
213
        /* FIXME: this should close the current balloon */
 
214
        if (!text)
 
215
                return;
 
216
 
 
217
#ifdef LIBNOTIFY
 
218
        /* try it via libnotify.so */
 
219
        if (libnotify_notify_new (title, text, sticon))
 
220
                return; /* success */
 
221
#endif
 
222
 
 
223
        /* try it the crude way */
 
224
        path = g_find_program_in_path ("notify-send");
 
225
        if (path)
 
226
        {
 
227
                sprintf(time, "%d000",prefs.input_balloon_time);
 
228
                argv[0] = path;
 
229
                argv[1] = "-i";
 
230
                argv[2] = "gtk-dialog-info";
 
231
                if (access (XCHATSHAREDIR"/pixmaps/xchat.png", R_OK) == 0)
 
232
                        argv[2] = XCHATSHAREDIR"/pixmaps/xchat.png";
 
233
                argv[3] = "-t";
 
234
                argv[4] = time;
 
235
                argv[5] = title;
 
236
                text = strip_color (text, -1, STRIP_ALL|STRIP_ESCMARKUP);
 
237
                argv[6] = text;
 
238
                argv[7] = NULL;
 
239
                xchat_execv (argv);
 
240
                g_free ((char *)path);
 
241
                g_free ((char *)text);
 
242
        }
 
243
        else
 
244
        {
 
245
                /* show this error only once */
 
246
                static unsigned char said_it = FALSE;
 
247
                if (!said_it)
 
248
                {
 
249
                        said_it = TRUE;
 
250
                        fe_message (_("Cannot find 'notify-send' to open balloon alerts.\nPlease install libnotify."), FE_MSG_ERROR);
 
251
                }
 
252
        }
 
253
#endif
 
254
}
 
255
 
 
256
static void
 
257
tray_set_balloonf (const char *text, const char *format, ...)
 
258
{
 
259
        va_list args;
 
260
        char *buf;
 
261
 
 
262
        va_start (args, format);
 
263
        buf = g_strdup_vprintf (format, args);
 
264
        va_end (args);
 
265
 
 
266
        fe_tray_set_balloon (buf, text);
 
267
        g_free (buf);
 
268
}
 
269
 
 
270
static void
 
271
tray_set_tipf (const char *format, ...)
 
272
{
 
273
        va_list args;
 
274
        char *buf;
 
275
 
 
276
        va_start (args, format);
 
277
        buf = g_strdup_vprintf (format, args);
 
278
        va_end (args);
 
279
 
 
280
        fe_tray_set_tooltip (buf);
 
281
        g_free (buf);
 
282
}
 
283
 
 
284
static void
 
285
tray_stop_flash (void)
 
286
{
 
287
        int nets, chans;
 
288
 
 
289
        if (flash_tag)
 
290
        {
 
291
                g_source_remove (flash_tag);
 
292
                flash_tag = 0;
 
293
        }
 
294
 
 
295
        if (sticon)
 
296
        {
 
297
                gtk_status_icon_set_from_pixbuf (sticon, ICON_NORMAL);
 
298
                nets = tray_count_networks ();
 
299
                chans = tray_count_channels ();
 
300
                if (nets)
 
301
                        tray_set_tipf (_("XChat: Connected to %u networks and %u channels"),
 
302
                                                                nets, chans);
 
303
                else
 
304
                        tray_set_tipf ("XChat: %s", _("Not connected."));
 
305
        }
 
306
 
 
307
        if (custom_icon1)
 
308
        {
 
309
                tray_icon_free (custom_icon1);
 
310
                custom_icon1 = NULL;
 
311
        }
 
312
 
 
313
        if (custom_icon2)
 
314
        {
 
315
                tray_icon_free (custom_icon2);
 
316
                custom_icon2 = NULL;
 
317
        }
 
318
 
 
319
        tray_status = TS_NONE;
 
320
}
 
321
 
 
322
static void
 
323
tray_reset_counts (void)
 
324
{
 
325
        tray_priv_count = 0;
 
326
        tray_pub_count = 0;
 
327
        tray_hilight_count = 0;
 
328
        tray_file_count = 0;
 
329
}
 
330
 
 
331
static int
 
332
tray_timeout_cb (TrayIcon icon)
 
333
{
 
334
        if (custom_icon1)
 
335
        {
 
336
                if (gtk_status_icon_get_pixbuf (sticon) == custom_icon1)
 
337
                {
 
338
                        if (custom_icon2)
 
339
                                gtk_status_icon_set_from_pixbuf (sticon, custom_icon2);
 
340
                        else
 
341
                                gtk_status_icon_set_from_pixbuf (sticon, ICON_NORMAL);
 
342
                }
 
343
                else
 
344
                {
 
345
                        gtk_status_icon_set_from_pixbuf (sticon, custom_icon1);
 
346
                }
 
347
        }
 
348
        else
 
349
        {
 
350
                if (gtk_status_icon_get_pixbuf (sticon) == ICON_NORMAL)
 
351
                        gtk_status_icon_set_from_pixbuf (sticon, icon);
 
352
                else
 
353
                        gtk_status_icon_set_from_pixbuf (sticon, ICON_NORMAL);
 
354
        }
 
355
        return 1;
 
356
}
 
357
 
 
358
static void
 
359
tray_set_flash (TrayIcon icon)
 
360
{
 
361
        if (!sticon)
 
362
                return;
 
363
 
 
364
        /* already flashing the same icon */
 
365
        if (flash_tag && gtk_status_icon_get_pixbuf (sticon) == icon)
 
366
                return;
 
367
 
 
368
        /* no flashing if window is focused */
 
369
        if (tray_get_window_status () == WS_FOCUSED)
 
370
                return;
 
371
 
 
372
        tray_stop_flash ();
 
373
 
 
374
        gtk_status_icon_set_from_pixbuf (sticon, icon);
 
375
        flash_tag = g_timeout_add (TIMEOUT, (GSourceFunc) tray_timeout_cb, icon);
 
376
}
 
377
 
 
378
void
 
379
fe_tray_set_flash (const char *filename1, const char *filename2, int tout)
 
380
{
 
381
        tray_apply_setup ();
 
382
        if (!sticon)
 
383
                return;
 
384
 
 
385
        tray_stop_flash ();
 
386
 
 
387
        if (tout == -1)
 
388
                tout = TIMEOUT;
 
389
 
 
390
        custom_icon1 = tray_icon_from_file (filename1);
 
391
        if (filename2)
 
392
                custom_icon2 = tray_icon_from_file (filename2);
 
393
 
 
394
        gtk_status_icon_set_from_pixbuf (sticon, custom_icon1);
 
395
        flash_tag = g_timeout_add (tout, (GSourceFunc) tray_timeout_cb, NULL);
 
396
        tray_status = TS_CUSTOM;
 
397
}
 
398
 
 
399
void
 
400
fe_tray_set_icon (feicon icon)
 
401
{
 
402
        tray_apply_setup ();
 
403
        if (!sticon)
 
404
                return;
 
405
 
 
406
        tray_stop_flash ();
 
407
 
 
408
        switch (icon)
 
409
        {
 
410
        case FE_ICON_NORMAL:
 
411
                break;
 
412
        case FE_ICON_MESSAGE:
 
413
                tray_set_flash (ICON_MSG);
 
414
                break;
 
415
        case FE_ICON_HIGHLIGHT:
 
416
        case FE_ICON_PRIVMSG:
 
417
                tray_set_flash (ICON_HILIGHT);
 
418
                break;
 
419
        case FE_ICON_FILEOFFER:
 
420
                tray_set_flash (ICON_FILE);
 
421
        }
 
422
}
 
423
 
 
424
void
 
425
fe_tray_set_file (const char *filename)
 
426
{
 
427
        tray_apply_setup ();
 
428
        if (!sticon)
 
429
                return;
 
430
 
 
431
        tray_stop_flash ();
 
432
 
 
433
        if (filename)
 
434
        {
 
435
                custom_icon1 = tray_icon_from_file (filename);
 
436
                gtk_status_icon_set_from_pixbuf (sticon, custom_icon1);
 
437
                tray_status = TS_CUSTOM;
 
438
        }
 
439
}
 
440
 
 
441
gboolean
 
442
tray_toggle_visibility (gboolean force_hide)
 
443
{
 
444
        static int x, y;
 
445
        static GdkScreen *screen;
 
446
        GtkWindow *win;
 
447
 
 
448
        if (!sticon)
 
449
                return FALSE;
 
450
 
 
451
        /* ph may have an invalid context now */
 
452
        xchat_set_context (ph, xchat_find_context (ph, NULL, NULL));
 
453
 
 
454
        win = (GtkWindow *)xchat_get_info (ph, "win_ptr");
 
455
 
 
456
        tray_stop_flash ();
 
457
        tray_reset_counts ();
 
458
 
 
459
        if (!win)
 
460
                return FALSE;
 
461
 
 
462
#if GTK_CHECK_VERSION(2,20,0)
 
463
        if (force_hide || gtk_widget_get_visible (win))
 
464
#else
 
465
        if (force_hide || GTK_WIDGET_VISIBLE (win))
 
466
#endif
 
467
        {
 
468
                gtk_window_get_position (win, &x, &y);
 
469
                screen = gtk_window_get_screen (win);
 
470
                gtk_widget_hide (GTK_WIDGET (win));
 
471
        }
 
472
        else
 
473
        {
 
474
                gtk_window_set_screen (win, screen);
 
475
                gtk_window_move (win, x, y);
 
476
                gtk_widget_show (GTK_WIDGET (win));
 
477
                gtk_window_present (win);
 
478
        }
 
479
 
 
480
        return TRUE;
 
481
}
 
482
 
 
483
static void
 
484
tray_menu_restore_cb (GtkWidget *item, gpointer userdata)
 
485
{
 
486
        tray_toggle_visibility (FALSE);
 
487
}
 
488
 
 
489
static void
 
490
tray_menu_quit_cb (GtkWidget *item, gpointer userdata)
 
491
{
 
492
        mg_open_quit_dialog (FALSE);
 
493
}
 
494
 
 
495
/* returns 0-mixed 1-away 2-back */
 
496
 
 
497
static int
 
498
tray_find_away_status (void)
 
499
{
 
500
        GSList *list;
 
501
        server *serv;
 
502
        int away = 0;
 
503
        int back = 0;
 
504
 
 
505
        for (list = serv_list; list; list = list->next)
 
506
        {
 
507
                serv = list->data;
 
508
 
 
509
                if (serv->is_away || serv->reconnect_away)
 
510
                        away++;
 
511
                else
 
512
                        back++;
 
513
        }
 
514
 
 
515
        if (away && back)
 
516
                return 0;
 
517
 
 
518
        if (away)
 
519
                return 1;
 
520
 
 
521
        return 2;
 
522
}
 
523
 
 
524
static void
 
525
tray_foreach_server (GtkWidget *item, char *cmd)
 
526
{
 
527
        GSList *list;
 
528
        server *serv;
 
529
 
 
530
        for (list = serv_list; list; list = list->next)
 
531
        {
 
532
                serv = list->data;
 
533
                if (serv->connected)
 
534
                        handle_command (serv->server_session, cmd, FALSE);
 
535
        }
 
536
}
 
537
 
 
538
static GtkWidget *
 
539
tray_make_item (GtkWidget *menu, char *label, void *callback, void *userdata)
 
540
{
 
541
        GtkWidget *item;
 
542
 
 
543
        if (label)
 
544
                item = gtk_menu_item_new_with_mnemonic (label);
 
545
        else
 
546
                item = gtk_menu_item_new ();
 
547
        gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
 
548
        g_signal_connect (G_OBJECT (item), "activate",
 
549
                                                        G_CALLBACK (callback), userdata);
 
550
        gtk_widget_show (item);
 
551
 
 
552
        return item;
 
553
}
 
554
 
 
555
static void
 
556
tray_toggle_cb (GtkCheckMenuItem *item, unsigned int *setting)
 
557
{
 
558
        *setting = item->active;
 
559
}
 
560
 
 
561
static void
 
562
blink_item (unsigned int *setting, GtkWidget *menu, char *label)
 
563
{
 
564
        menu_toggle_item (label, menu, tray_toggle_cb, setting, *setting);
 
565
}
 
566
 
 
567
static void
 
568
tray_menu_destroy (GtkWidget *menu, gpointer userdata)
 
569
{
 
570
        gtk_widget_destroy (menu);
 
571
        g_object_unref (menu);
 
572
}
 
573
 
 
574
static void
 
575
tray_menu_cb (GtkWidget *widget, guint button, guint time, gpointer userdata)
 
576
{
 
577
        GtkWidget *menu;
 
578
        GtkWidget *submenu;
 
579
        GtkWidget *item;
 
580
        int away_status;
 
581
 
 
582
        /* ph may have an invalid context now */
 
583
        xchat_set_context (ph, xchat_find_context (ph, NULL, NULL));
 
584
 
 
585
        menu = gtk_menu_new ();
 
586
        /*gtk_menu_set_screen (GTK_MENU (menu), gtk_widget_get_screen (widget));*/
 
587
 
 
588
        if (tray_get_window_status () == WS_HIDDEN)
 
589
                tray_make_item (menu, _("_Restore"), tray_menu_restore_cb, NULL);
 
590
        else
 
591
                tray_make_item (menu, _("_Hide"), tray_menu_restore_cb, NULL);
 
592
        tray_make_item (menu, NULL, tray_menu_quit_cb, NULL);
 
593
 
 
594
        submenu = mg_submenu (menu, _("_Blink on"));
 
595
        blink_item (&prefs.input_tray_chans, submenu, _("Channel Message"));
 
596
        blink_item (&prefs.input_tray_priv, submenu, _("Private Message"));
 
597
        blink_item (&prefs.input_tray_hilight, submenu, _("Highlighted Message"));
 
598
        /*blink_item (BIT_FILEOFFER, submenu, _("File Offer"));*/
 
599
 
 
600
        submenu = mg_submenu (menu, _("_Change status"));
 
601
        away_status = tray_find_away_status ();
 
602
        item = tray_make_item (submenu, _("_Away"), tray_foreach_server, "away");
 
603
        if (away_status == 1)
 
604
                gtk_widget_set_sensitive (item, FALSE);
 
605
        item = tray_make_item (submenu, _("_Back"), tray_foreach_server, "back");
 
606
        if (away_status == 2)
 
607
                gtk_widget_set_sensitive (item, FALSE);
 
608
 
 
609
        tray_make_item (menu, NULL, tray_menu_quit_cb, NULL);
 
610
        mg_create_icon_item (_("_Quit"), GTK_STOCK_QUIT, menu, tray_menu_quit_cb, NULL);
 
611
 
 
612
        menu_add_plugin_items (menu, "\x5$TRAY", NULL);
 
613
 
 
614
        g_object_ref (menu);
 
615
        g_object_ref_sink (menu);
 
616
        g_object_unref (menu);
 
617
        g_signal_connect (G_OBJECT (menu), "selection-done",
 
618
                                                        G_CALLBACK (tray_menu_destroy), NULL);
 
619
 
 
620
        gtk_menu_popup (GTK_MENU (menu), NULL, NULL, gtk_status_icon_position_menu,
 
621
                                                 userdata, button, time);
 
622
}
 
623
 
 
624
static void
 
625
tray_init (void)
 
626
{
 
627
        flash_tag = 0;
 
628
        tray_status = TS_NONE;
 
629
        custom_icon1 = NULL;
 
630
        custom_icon2 = NULL;
 
631
 
 
632
        sticon = gtk_status_icon_new_from_pixbuf (ICON_NORMAL);
 
633
        if (!sticon)
 
634
                return;
 
635
        g_signal_connect (G_OBJECT (sticon), "popup-menu",
 
636
                                                        G_CALLBACK (tray_menu_cb), sticon);
 
637
        g_signal_connect (G_OBJECT (sticon), "activate",
 
638
                                                        G_CALLBACK (tray_menu_restore_cb), NULL);
 
639
}
 
640
 
 
641
static int
 
642
tray_hilight_cb (char *word[], void *userdata)
 
643
{
 
644
        /*if (tray_status == TS_HIGHLIGHT)
 
645
                return XCHAT_EAT_NONE;*/
 
646
 
 
647
        if (prefs.input_tray_hilight)
 
648
        {
 
649
                tray_set_flash (ICON_HILIGHT);
 
650
 
 
651
                /* FIXME: hides any previous private messages */
 
652
                tray_hilight_count++;
 
653
                if (tray_hilight_count == 1)
 
654
                        tray_set_tipf (_("XChat: Highlighted message from: %s (%s)"),
 
655
                                                                word[1], xchat_get_info (ph, "channel"));
 
656
                else
 
657
                        tray_set_tipf (_("XChat: %u highlighted messages, latest from: %s (%s)"),
 
658
                                                                tray_hilight_count, word[1], xchat_get_info (ph, "channel"));
 
659
        }
 
660
 
 
661
        if (prefs.input_balloon_hilight)
 
662
                tray_set_balloonf (word[2], _("XChat: Highlighted message from: %s (%s)"),
 
663
                                                                 word[1], xchat_get_info (ph, "channel"));
 
664
 
 
665
        return XCHAT_EAT_NONE;
 
666
}
 
667
 
 
668
static int
 
669
tray_message_cb (char *word[], void *userdata)
 
670
{
 
671
        if (/*tray_status == TS_MESSAGE ||*/ tray_status == TS_HIGHLIGHT)
 
672
                return XCHAT_EAT_NONE;
 
673
 
 
674
        if (prefs.input_tray_chans)
 
675
        {
 
676
                tray_set_flash (ICON_MSG);
 
677
 
 
678
                tray_pub_count++;
 
679
                if (tray_pub_count == 1)
 
680
                        tray_set_tipf (_("XChat: New public message from: %s (%s)"),
 
681
                                                                word[1], xchat_get_info (ph, "channel"));
 
682
                else
 
683
                        tray_set_tipf (_("XChat: %u new public messages."), tray_pub_count);
 
684
        }
 
685
 
 
686
        if (prefs.input_balloon_chans)
 
687
                tray_set_balloonf (word[2], _("XChat: New public message from: %s (%s)"),
 
688
                                                                 word[1], xchat_get_info (ph, "channel"));
 
689
 
 
690
        return XCHAT_EAT_NONE;
 
691
}
 
692
 
 
693
static void
 
694
tray_priv (char *from, char *text)
 
695
{
 
696
        const char *network;
 
697
 
 
698
        if (alert_match_word (from, prefs.irc_no_hilight))
 
699
                return;
 
700
 
 
701
        tray_set_flash (ICON_HILIGHT);
 
702
 
 
703
        network = xchat_get_info (ph, "network");
 
704
        if (!network)
 
705
                network = xchat_get_info (ph, "server");
 
706
 
 
707
        tray_priv_count++;
 
708
        if (tray_priv_count == 1)
 
709
                tray_set_tipf (_("XChat: Private message from: %s (%s)"),
 
710
                                                        from, network);
 
711
        else
 
712
                tray_set_tipf (_("XChat: %u private messages, latest from: %s (%s)"),
 
713
                                                        tray_priv_count, from, network);
 
714
 
 
715
        if (prefs.input_balloon_priv)
 
716
                tray_set_balloonf (text, _("XChat: Private message from: %s (%s)"),
 
717
                                                                 from, network);
 
718
}
 
719
 
 
720
static int
 
721
tray_priv_cb (char *word[], void *userdata)
 
722
{
 
723
        /*if (tray_status == TS_HIGHLIGHT)
 
724
                return XCHAT_EAT_NONE;*/
 
725
 
 
726
        if (prefs.input_tray_priv)
 
727
                tray_priv (word[1], word[2]);
 
728
 
 
729
        return XCHAT_EAT_NONE;
 
730
}
 
731
 
 
732
static int
 
733
tray_invited_cb (char *word[], void *userdata)
 
734
{
 
735
        /*if (tray_status == TS_HIGHLIGHT)
 
736
                return XCHAT_EAT_NONE;*/
 
737
 
 
738
        if (prefs.input_tray_priv)
 
739
                tray_priv (word[2], "Invited");
 
740
 
 
741
        return XCHAT_EAT_NONE;
 
742
}
 
743
 
 
744
static int
 
745
tray_dcc_cb (char *word[], void *userdata)
 
746
{
 
747
        const char *network;
 
748
 
 
749
/*      if (tray_status == TS_FILEOFFER)
 
750
                return XCHAT_EAT_NONE;*/
 
751
 
 
752
        network = xchat_get_info (ph, "network");
 
753
        if (!network)
 
754
                network = xchat_get_info (ph, "server");
 
755
 
 
756
        if (prefs.input_tray_priv)
 
757
        {
 
758
                tray_set_flash (ICON_FILE);
 
759
 
 
760
                tray_file_count++;
 
761
                if (tray_file_count == 1)
 
762
                        tray_set_tipf (_("XChat: File offer from: %s (%s)"),
 
763
                                                                word[1], network);
 
764
                else
 
765
                        tray_set_tipf (_("XChat: %u file offers, latest from: %s (%s)"),
 
766
                                                                tray_file_count, word[1], network);
 
767
        }
 
768
 
 
769
        if (prefs.input_balloon_priv)
 
770
                tray_set_balloonf ("", _("XChat: File offer from: %s (%s)"),
 
771
                                                                word[1], network);
 
772
 
 
773
        return XCHAT_EAT_NONE;
 
774
}
 
775
 
 
776
static int
 
777
tray_focus_cb (char *word[], void *userdata)
 
778
{
 
779
        tray_stop_flash ();
 
780
        tray_reset_counts ();
 
781
        return XCHAT_EAT_NONE;
 
782
}
 
783
 
 
784
static void
 
785
tray_cleanup (void)
 
786
{
 
787
        tray_stop_flash ();
 
788
 
 
789
        if (sticon)
 
790
        {
 
791
                g_object_unref ((GObject *)sticon);
 
792
                sticon = NULL;
 
793
        }
 
794
}
 
795
 
 
796
void
 
797
tray_apply_setup (void)
 
798
{
 
799
        if (sticon)
 
800
        {
 
801
                if (!prefs.gui_tray)
 
802
                        tray_cleanup ();
 
803
        }
 
804
        else
 
805
        {
 
806
                if (prefs.gui_tray)
 
807
                        tray_init ();
 
808
        }
 
809
}
 
810
 
 
811
int
 
812
tray_plugin_init (xchat_plugin *plugin_handle, char **plugin_name,
 
813
                                char **plugin_desc, char **plugin_version, char *arg)
 
814
{
 
815
        /* we need to save this for use with any xchat_* functions */
 
816
        ph = plugin_handle;
 
817
 
 
818
        *plugin_name = "";
 
819
        *plugin_desc = "";
 
820
        *plugin_version = "";
 
821
 
 
822
        xchat_hook_print (ph, "Channel Msg Hilight", -1, tray_hilight_cb, NULL);
 
823
        xchat_hook_print (ph, "Channel Action Hilight", -1, tray_hilight_cb, NULL);
 
824
 
 
825
        xchat_hook_print (ph, "Channel Message", -1, tray_message_cb, NULL);
 
826
        xchat_hook_print (ph, "Channel Action", -1, tray_message_cb, NULL);
 
827
        xchat_hook_print (ph, "Channel Notice", -1, tray_message_cb, NULL);
 
828
 
 
829
        xchat_hook_print (ph, "Private Message", -1, tray_priv_cb, NULL);
 
830
        xchat_hook_print (ph, "Private Message to Dialog", -1, tray_priv_cb, NULL);
 
831
        xchat_hook_print (ph, "Notice", -1, tray_priv_cb, NULL);
 
832
        xchat_hook_print (ph, "Invited", -1, tray_invited_cb, NULL);
 
833
 
 
834
        xchat_hook_print (ph, "DCC Offer", -1, tray_dcc_cb, NULL);
 
835
 
 
836
        xchat_hook_print (ph, "Focus Window", -1, tray_focus_cb, NULL);
 
837
 
 
838
        if (prefs.gui_tray)
 
839
                tray_init ();
 
840
 
 
841
        return 1;       /* return 1 for success */
 
842
}
 
843
 
 
844
int
 
845
tray_plugin_deinit (xchat_plugin *plugin_handle)
 
846
{
 
847
#ifdef WIN32
 
848
        tray_cleanup ();
 
849
#elif defined(LIBNOTIFY)
 
850
        libnotify_cleanup ();
 
851
#endif
 
852
        return 1;
 
853
}