aboutsummaryrefslogtreecommitdiff
path: root/src/core/eggtrayicon.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/eggtrayicon.c')
-rw-r--r--src/core/eggtrayicon.c729
1 files changed, 0 insertions, 729 deletions
diff --git a/src/core/eggtrayicon.c b/src/core/eggtrayicon.c
deleted file mode 100644
index 182953e5..00000000
--- a/src/core/eggtrayicon.c
+++ /dev/null
@@ -1,729 +0,0 @@
1/*
2 This file is part of GNUnet.
3 (C) 2006 Christian Grothoff (and other contributing authors)
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 2, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19*/
20/*
21 * @file src/core/eggtrayicon.c
22 * @brief adds a system tray icon
23 * @author Anders Carlsson
24 * @author Christian Grothoff (minor modifications and code clean up)
25 */
26
27/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
28/* eggtrayicon.c
29 * Copyright (C) 2002 Anders Carlsson <andersca@gnu.org>
30 *
31 * This library is free software; you can redistribute it and/or
32 * modify it under the terms of the GNU Lesser General Public
33 * License as published by the Free Software Foundation; either
34 * version 2 of the License, or (at your option) any later version.
35 *
36 * This library is distributed in the hope that it will be useful,
37 * but WITHOUT ANY WARRANTY; without even the implied warranty of
38 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
39 * Lesser General Public License for more details.
40 *
41 * You should have received a copy of the GNU Lesser General Public
42 * License along with this library; if not, write to the
43 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
44 * Boston, MA 02111-1307, USA.
45 */
46
47#include "platform.h"
48#include "gnunetgtk_common.h"
49#include <gtk/gtkversion.h>
50
51#if !GTK_CHECK_VERSION (2,10,0) && !defined(WINDOWS)
52#include "eggtrayicon.h"
53#include <gtk/gtkplug.h>
54#include <gdk/gdkx.h>
55#include <X11/Xatom.h>
56
57G_BEGIN_DECLS
58#define EGG_TYPE_TRAY_ICON (egg_tray_icon_get_type ())
59#define EGG_TRAY_ICON(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EGG_TYPE_TRAY_ICON, EggTrayIcon))
60#define EGG_TRAY_ICON_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EGG_TYPE_TRAY_ICON, EggTrayIconClass))
61#define EGG_IS_TRAY_ICON(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EGG_TYPE_TRAY_ICON))
62#define EGG_IS_TRAY_ICON_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EGG_TYPE_TRAY_ICON))
63#define EGG_TRAY_ICON_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EGG_TYPE_TRAY_ICON, EggTrayIconClass))
64typedef struct _EggTrayIcon EggTrayIcon;
65typedef struct _EggTrayIconClass EggTrayIconClass;
66
67struct _EggTrayIcon
68{
69 GtkPlug parent_instance;
70
71 guint stamp;
72
73 Atom selection_atom;
74 Atom manager_atom;
75 Atom system_tray_opcode_atom;
76 Atom orientation_atom;
77 Window manager_window;
78
79 GtkOrientation orientation;
80};
81
82struct _EggTrayIconClass
83{
84 GtkPlugClass parent_class;
85};
86
87GType egg_tray_icon_get_type (void);
88
89#if GTK_CHECK_VERSION(2,1,0)
90EggTrayIcon *egg_tray_icon_new_for_screen (GdkScreen * screen,
91 const gchar * name);
92#endif
93
94EggTrayIcon *egg_tray_icon_new (const gchar * name);
95
96guint egg_tray_icon_send_message (EggTrayIcon * icon,
97 gint timeout,
98 const char *message, gint len);
99void egg_tray_icon_cancel_message (EggTrayIcon * icon, guint id);
100
101GtkOrientation egg_tray_icon_get_orientation (EggTrayIcon * icon);
102
103
104static gboolean tray_clicked (GtkWidget * trayContextMenu, GdkEvent * event);
105static gboolean on_tray_quit_activate (GtkWidget * widget, GdkEvent * event,
106 gpointer data);
107
108G_END_DECLS
109#define SYSTEM_TRAY_REQUEST_DOCK 0
110#define SYSTEM_TRAY_BEGIN_MESSAGE 1
111#define SYSTEM_TRAY_CANCEL_MESSAGE 2
112#define SYSTEM_TRAY_ORIENTATION_HORZ 0
113#define SYSTEM_TRAY_ORIENTATION_VERT 1
114 enum
115{
116 PROP_0,
117 PROP_ORIENTATION
118};
119
120static GtkPlugClass *parent_class = NULL;
121
122static void egg_tray_icon_init (EggTrayIcon * icon);
123static void egg_tray_icon_class_init (EggTrayIconClass * klass);
124
125static void egg_tray_icon_get_property (GObject * object,
126 guint prop_id,
127 GValue * value, GParamSpec * pspec);
128
129static void egg_tray_icon_realize (GtkWidget * widget);
130static void egg_tray_icon_unrealize (GtkWidget * widget);
131
132static void egg_tray_icon_update_manager_window (EggTrayIcon * icon,
133 gboolean dock_if_realized);
134static void egg_tray_icon_manager_window_destroyed (EggTrayIcon * icon);
135
136static Display *
137getDisplay (GtkWidget * w)
138{
139#if GTK_CHECK_VERSION(2,1,0)
140 return GDK_DISPLAY_XDISPLAY (gtk_widget_get_display (w));
141#else
142 return gdk_display;
143#endif
144}
145
146static GdkWindow *
147getWindow (EggTrayIcon * icon)
148{
149#if GTK_CHECK_VERSION(2,1,0)
150 return
151 gdk_window_lookup_for_display (gtk_widget_get_display (GTK_WIDGET (icon)),
152 icon->manager_window);
153#else
154 return gdk_window_lookup (icon->manager_window);
155#endif
156}
157
158GType
159egg_tray_icon_get_type (void)
160{
161 static GType our_type = 0;
162
163 if (our_type == 0)
164 {
165 our_type = g_type_from_name ("EggTrayIcon");
166
167 if (our_type == 0)
168 {
169 static const GTypeInfo our_info = {
170 sizeof (EggTrayIconClass),
171 (GBaseInitFunc) NULL,
172 (GBaseFinalizeFunc) NULL,
173 (GClassInitFunc) egg_tray_icon_class_init,
174 NULL, /* class_finalize */
175 NULL, /* class_data */
176 sizeof (EggTrayIcon),
177 0, /* n_preallocs */
178 (GInstanceInitFunc) egg_tray_icon_init,
179 NULL /* value_table */
180 };
181
182 our_type =
183 g_type_register_static (GTK_TYPE_PLUG, "EggTrayIcon", &our_info,
184 0);
185 }
186 else if (parent_class == NULL)
187 {
188 /* we're reheating the old class from a previous instance - engage ugly hack =( */
189 egg_tray_icon_class_init ((EggTrayIconClass *)
190 g_type_class_peek (our_type));
191 }
192 }
193
194 return our_type;
195}
196
197static void
198egg_tray_icon_init (EggTrayIcon * icon)
199{
200 icon->stamp = 1;
201 icon->orientation = GTK_ORIENTATION_HORIZONTAL;
202
203 gtk_widget_add_events (GTK_WIDGET (icon), GDK_PROPERTY_CHANGE_MASK);
204}
205
206static void
207egg_tray_icon_class_init (EggTrayIconClass * klass)
208{
209 GObjectClass *gobject_class = (GObjectClass *) klass;
210 GtkWidgetClass *widget_class = (GtkWidgetClass *) klass;
211
212 parent_class = g_type_class_peek_parent (klass);
213
214 gobject_class->get_property = egg_tray_icon_get_property;
215
216 widget_class->realize = egg_tray_icon_realize;
217 widget_class->unrealize = egg_tray_icon_unrealize;
218
219 g_object_class_install_property (gobject_class,
220 PROP_ORIENTATION,
221 g_param_spec_enum ("orientation",
222 _("Orientation"),
223 _
224 ("The orientation of the tray."),
225 GTK_TYPE_ORIENTATION,
226 GTK_ORIENTATION_HORIZONTAL,
227 G_PARAM_READABLE));
228}
229
230static void
231egg_tray_icon_get_property (GObject * object,
232 guint prop_id, GValue * value, GParamSpec * pspec)
233{
234 EggTrayIcon *icon = EGG_TRAY_ICON (object);
235
236 switch (prop_id)
237 {
238 case PROP_ORIENTATION:
239 g_value_set_enum (value, icon->orientation);
240 break;
241 default:
242 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
243 break;
244 }
245}
246
247static void
248egg_tray_icon_get_orientation_property (EggTrayIcon * icon)
249{
250 Display *xdisplay;
251 Atom type;
252 int format;
253 union
254 {
255 gulong *prop;
256 guchar *prop_ch;
257 } prop =
258 {
259 NULL};
260 gulong nitems;
261 gulong bytes_after;
262 int error, result;
263
264 g_return_if_fail (icon->manager_window != None);
265
266 xdisplay = getDisplay (GTK_WIDGET (icon));
267
268 gdk_error_trap_push ();
269 type = None;
270 result = XGetWindowProperty (xdisplay,
271 icon->manager_window,
272 icon->orientation_atom,
273 0, G_MAXLONG, FALSE,
274 XA_CARDINAL,
275 &type, &format, &nitems,
276 &bytes_after, &(prop.prop_ch));
277 error = gdk_error_trap_pop ();
278
279 if (error || result != Success)
280 return;
281
282 if (type == XA_CARDINAL)
283 {
284 GtkOrientation orientation;
285
286 orientation = (prop.prop[0] == SYSTEM_TRAY_ORIENTATION_HORZ) ?
287 GTK_ORIENTATION_HORIZONTAL : GTK_ORIENTATION_VERTICAL;
288
289 if (icon->orientation != orientation)
290 {
291 icon->orientation = orientation;
292
293 g_object_notify (G_OBJECT (icon), "orientation");
294 }
295 }
296
297 if (prop.prop)
298 XFree (prop.prop);
299}
300
301static GdkFilterReturn
302egg_tray_icon_manager_filter (GdkXEvent * xevent, GdkEvent * event,
303 gpointer user_data)
304{
305 EggTrayIcon *icon = user_data;
306 XEvent *xev = (XEvent *) xevent;
307
308 if (xev->xany.type == ClientMessage &&
309 xev->xclient.message_type == icon->manager_atom &&
310 xev->xclient.data.l[1] == icon->selection_atom)
311 {
312 egg_tray_icon_update_manager_window (icon, TRUE);
313 }
314 else if (xev->xany.window == icon->manager_window)
315 {
316 if (xev->xany.type == PropertyNotify &&
317 xev->xproperty.atom == icon->orientation_atom)
318 {
319 egg_tray_icon_get_orientation_property (icon);
320 }
321 if (xev->xany.type == DestroyNotify)
322 {
323 egg_tray_icon_manager_window_destroyed (icon);
324 }
325 }
326
327 return GDK_FILTER_CONTINUE;
328}
329
330static void
331egg_tray_icon_unrealize (GtkWidget * widget)
332{
333 EggTrayIcon *icon = EGG_TRAY_ICON (widget);
334 GdkWindow *root_window;
335
336 if (icon->manager_window != None)
337 {
338 GdkWindow *gdkwin;
339
340 gdkwin = getWindow (icon);
341 gdk_window_remove_filter (gdkwin, egg_tray_icon_manager_filter, icon);
342 }
343
344#if GTK_CHECK_VERSION(2,1,0)
345 root_window = gdk_screen_get_root_window (gtk_widget_get_screen (widget));
346#else
347 root_window = gdk_window_lookup (gdk_x11_get_default_root_xwindow ());
348#endif
349
350 gdk_window_remove_filter (root_window, egg_tray_icon_manager_filter, icon);
351
352 if (GTK_WIDGET_CLASS (parent_class)->unrealize)
353 (*GTK_WIDGET_CLASS (parent_class)->unrealize) (widget);
354}
355
356static void
357egg_tray_icon_send_manager_message (EggTrayIcon * icon,
358 long message,
359 Window window,
360 long data1, long data2, long data3)
361{
362 XClientMessageEvent ev;
363 Display *display;
364
365 ev.type = ClientMessage;
366 ev.window = window;
367 ev.message_type = icon->system_tray_opcode_atom;
368 ev.format = 32;
369 ev.data.l[0] = gdk_x11_get_server_time (GTK_WIDGET (icon)->window);
370 ev.data.l[1] = message;
371 ev.data.l[2] = data1;
372 ev.data.l[3] = data2;
373 ev.data.l[4] = data3;
374
375 display = getDisplay (GTK_WIDGET (icon));
376
377 gdk_error_trap_push ();
378 XSendEvent (display,
379 icon->manager_window, False, NoEventMask, (XEvent *) & ev);
380 XSync (display, False);
381 gdk_error_trap_pop ();
382}
383
384static void
385egg_tray_icon_send_dock_request (EggTrayIcon * icon)
386{
387 egg_tray_icon_send_manager_message (icon,
388 SYSTEM_TRAY_REQUEST_DOCK,
389 icon->manager_window,
390 gtk_plug_get_id (GTK_PLUG (icon)),
391 0, 0);
392}
393
394static void
395egg_tray_icon_update_manager_window (EggTrayIcon * icon,
396 gboolean dock_if_realized)
397{
398 Display *xdisplay;
399
400 if (icon->manager_window != None)
401 return;
402
403 xdisplay = getDisplay (GTK_WIDGET (icon));
404 XGrabServer (xdisplay);
405
406 icon->manager_window = XGetSelectionOwner (xdisplay, icon->selection_atom);
407
408 if (icon->manager_window != None)
409 XSelectInput (xdisplay,
410 icon->manager_window,
411 StructureNotifyMask | PropertyChangeMask);
412
413 XUngrabServer (xdisplay);
414 XFlush (xdisplay);
415
416 if (icon->manager_window != None)
417 {
418 GdkWindow *gdkwin;
419
420 gdkwin = getWindow (icon);
421 gdk_window_add_filter (gdkwin, egg_tray_icon_manager_filter, icon);
422
423 if (dock_if_realized && GTK_WIDGET_REALIZED (icon))
424 egg_tray_icon_send_dock_request (icon);
425
426 egg_tray_icon_get_orientation_property (icon);
427 }
428}
429
430static void
431egg_tray_icon_manager_window_destroyed (EggTrayIcon * icon)
432{
433 GdkWindow *gdkwin;
434
435 g_return_if_fail (icon->manager_window != None);
436
437 gdkwin = getWindow (icon);
438 gdk_window_remove_filter (gdkwin, egg_tray_icon_manager_filter, icon);
439
440 icon->manager_window = None;
441
442 egg_tray_icon_update_manager_window (icon, TRUE);
443}
444
445static void
446egg_tray_icon_realize (GtkWidget * widget)
447{
448 EggTrayIcon *icon = EGG_TRAY_ICON (widget);
449 gint screen;
450 Display *xdisplay;
451 char buffer[256];
452 GdkWindow *root_window;
453
454 if (GTK_WIDGET_CLASS (parent_class)->realize)
455 GTK_WIDGET_CLASS (parent_class)->realize (widget);
456
457#if GTK_CHECK_VERSION(2,1,0)
458 screen = gdk_screen_get_number (gtk_widget_get_screen (widget));
459 xdisplay = GDK_DISPLAY_XDISPLAY (gtk_widget_get_display (widget));
460#else
461 screen = XScreenNumberOfScreen (DefaultScreenOfDisplay (gdk_display));
462 xdisplay = gdk_display;
463#endif
464
465 /* Now see if there's a manager window around */
466 g_snprintf (buffer, sizeof (buffer), "_NET_SYSTEM_TRAY_S%d", screen);
467
468 icon->selection_atom = XInternAtom (xdisplay, buffer, False);
469
470 icon->manager_atom = XInternAtom (xdisplay, "MANAGER", False);
471
472 icon->system_tray_opcode_atom = XInternAtom (xdisplay,
473 "_NET_SYSTEM_TRAY_OPCODE",
474 False);
475
476 icon->orientation_atom = XInternAtom (xdisplay,
477 "_NET_SYSTEM_TRAY_ORIENTATION",
478 False);
479
480 egg_tray_icon_update_manager_window (icon, FALSE);
481 egg_tray_icon_send_dock_request (icon);
482
483#if GTK_CHECK_VERSION(2,1,0)
484 root_window = gdk_screen_get_root_window (gtk_widget_get_screen (widget));
485#else
486 root_window = gdk_window_lookup (gdk_x11_get_default_root_xwindow ());
487#endif
488
489 /* Add a root window filter so that we get changes on MANAGER */
490 gdk_window_add_filter (root_window, egg_tray_icon_manager_filter, icon);
491}
492
493#if GTK_CHECK_VERSION(2,1,0)
494EggTrayIcon *
495egg_tray_icon_new_for_screen (GdkScreen * screen, const char *name)
496{
497 g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL);
498
499 return g_object_new (EGG_TYPE_TRAY_ICON, "screen", screen, "title", name,
500 NULL);
501}
502#endif
503
504EggTrayIcon *
505egg_tray_icon_new (const gchar * name)
506{
507 return g_object_new (EGG_TYPE_TRAY_ICON, "title", name, NULL);
508}
509
510guint
511egg_tray_icon_send_message (EggTrayIcon * icon,
512 gint timeout, const gchar * message, gint len)
513{
514 guint stamp;
515
516 g_return_val_if_fail (EGG_IS_TRAY_ICON (icon), 0);
517 g_return_val_if_fail (timeout >= 0, 0);
518 g_return_val_if_fail (message != NULL, 0);
519
520 if (icon->manager_window == None)
521 return 0;
522
523 if (len < 0)
524 len = strlen (message);
525
526 stamp = icon->stamp++;
527
528 /* Get ready to send the message */
529 egg_tray_icon_send_manager_message (icon, SYSTEM_TRAY_BEGIN_MESSAGE,
530 (Window)
531 gtk_plug_get_id (GTK_PLUG (icon)),
532 timeout, len, stamp);
533
534 /* Now to send the actual message */
535 gdk_error_trap_push ();
536 while (len > 0)
537 {
538 XClientMessageEvent ev;
539 Display *xdisplay;
540
541 xdisplay = getDisplay (GTK_WIDGET (icon));
542
543 ev.type = ClientMessage;
544 ev.window = (Window) gtk_plug_get_id (GTK_PLUG (icon));
545 ev.format = 8;
546 ev.message_type = XInternAtom (xdisplay,
547 "_NET_SYSTEM_TRAY_MESSAGE_DATA", False);
548 if (len > 20)
549 {
550 memcpy (&ev.data, message, 20);
551 len -= 20;
552 message += 20;
553 }
554 else
555 {
556 memcpy (&ev.data, message, len);
557 len = 0;
558 }
559
560 XSendEvent (xdisplay,
561 icon->manager_window, False, StructureNotifyMask,
562 (XEvent *) & ev);
563 XSync (xdisplay, False);
564 }
565 gdk_error_trap_pop ();
566
567 return stamp;
568}
569
570void
571egg_tray_icon_cancel_message (EggTrayIcon * icon, guint id)
572{
573 g_return_if_fail (EGG_IS_TRAY_ICON (icon));
574 g_return_if_fail (id > 0);
575
576 egg_tray_icon_send_manager_message (icon, SYSTEM_TRAY_CANCEL_MESSAGE,
577 (Window)
578 gtk_plug_get_id (GTK_PLUG (icon)), id,
579 0, 0);
580}
581
582GtkOrientation
583egg_tray_icon_get_orientation (EggTrayIcon * icon)
584{
585 g_return_val_if_fail (EGG_IS_TRAY_ICON (icon), GTK_ORIENTATION_HORIZONTAL);
586
587 return icon->orientation;
588}
589#endif /* !GTK_CHECK_VERSION (2,10,0) && !defined(WINDOWS) */
590
591
592/* Callback for the "Quit" element on the tray icon menu */
593static gboolean
594on_tray_quit_activate (GtkWidget * widget, GdkEvent * event, gpointer data)
595{
596 GNUNET_GTK_main_quit ();
597 return TRUE;
598}
599
600/* Function activated when the user clicks the tray icon */
601static gboolean
602tray_clicked (GtkWidget * widget, GdkEvent * event)
603{
604#if GTK_CHECK_VERSION(2,10,0)
605 GtkWidget *root;
606 root =
607 glade_xml_get_widget (GNUNET_GTK_get_main_glade_XML (), "mainWindow");
608 GdkWindowState main_window_state;
609 if (gtk_window_is_active (GTK_WINDOW (root)))
610 gtk_widget_hide (root);
611 else
612 gtk_window_present (GTK_WINDOW (root));
613 main_window_state = GNUNET_GTK_get_main_window_state ();
614 if (main_window_state & GDK_WINDOW_STATE_MAXIMIZED)
615 gtk_window_maximize (GTK_WINDOW (root));
616 return TRUE;
617#elif !defined (WINDOWS)
618 if (event->type == GDK_BUTTON_PRESS)
619 {
620 GdkEventButton *event_button;
621 event_button = (GdkEventButton *) event;
622 if (event_button->button == 1)
623 {
624 GtkWidget *root;
625 root =
626 glade_xml_get_widget (GNUNET_GTK_get_main_glade_XML (),
627 "mainWindow");
628 GdkWindowState main_window_state;
629 if (gtk_window_is_active (GTK_WINDOW (root)))
630 gtk_widget_hide (root);
631 else
632 gtk_window_present (GTK_WINDOW (root));
633 main_window_state = GNUNET_GTK_get_main_window_state ();
634 if (main_window_state & GDK_WINDOW_STATE_MAXIMIZED)
635 gtk_window_maximize (GTK_WINDOW (root));
636 return TRUE;
637 }
638 else if (event_button->button == 3)
639 {
640 GtkMenu *trayContextMenu;
641 trayContextMenu = GTK_MENU (widget);
642 g_return_val_if_fail (GTK_IS_MENU (trayContextMenu), FALSE);
643 gtk_menu_popup (trayContextMenu, NULL, NULL, NULL, NULL,
644 event_button->button, event_button->time);
645 return TRUE;
646 }
647 }
648 return FALSE;
649#endif
650}
651
652#if GTK_CHECK_VERSION(2,10,0)
653/* Function activated when the user tries to popup the menu */
654static gboolean
655on_tray_popup_menu (GtkStatusIcon * status_icon, guint button,
656 guint activate_time, gpointer trayContextMenu)
657{
658 gtk_menu_popup (GTK_MENU (trayContextMenu), NULL, NULL, NULL, NULL,
659 button, activate_time);
660 return TRUE;
661}
662#endif
663
664/* Initiate the system tray icon */
665void
666initTrayIcon ()
667{
668#if GTK_CHECK_VERSION (2,10,0)
669 GtkStatusIcon *trayIcon;
670 GtkWidget *trayContextMenu;
671 GladeXML *trayContextMenuXML;
672 GtkWidget *tray_quit;
673
674 trayContextMenuXML =
675 glade_xml_new (GNUNET_GTK_get_glade_filename (), "trayContextMenu",
676 PACKAGE_NAME);
677 trayContextMenu = glade_xml_get_widget (trayContextMenuXML,
678 "trayContextMenu");
679 trayIcon = GNUNET_GTK_get_trayIcon ();
680 gtk_status_icon_set_from_icon_name (trayIcon, "gnunet-gtk");
681 gtk_status_icon_set_tooltip (trayIcon, _("GNU's peer-to-peer network"));
682 tray_quit = glade_xml_get_widget (trayContextMenuXML, "tray_quit");
683 g_signal_connect_swapped (G_OBJECT (tray_quit), "activate",
684 G_CALLBACK (on_tray_quit_activate),
685 trayContextMenu);
686 g_signal_connect_swapped (G_OBJECT (trayIcon), "activate",
687 G_CALLBACK (tray_clicked), trayContextMenu);
688 g_signal_connect (G_OBJECT (trayIcon), "popup-menu",
689 G_CALLBACK (on_tray_popup_menu), trayContextMenu);
690#elif !defined(WINDOWS)
691 static EggTrayIcon *tray_icon;
692 static GtkWidget *tray_icon_image;
693 static GtkTooltips *tray_icon_tooltip;
694 GtkWidget *eventbox, *trayContextMenu, *tray_quit;
695 GdkPixbuf *pixbuf;
696 GladeXML *trayContextMenuXML;
697 char *instDir;
698 char *iconPath;
699
700 trayContextMenuXML =
701 glade_xml_new (GNUNET_GTK_get_glade_filename (), "trayContextMenu",
702 PACKAGE_NAME);
703 trayContextMenu =
704 glade_xml_get_widget (trayContextMenuXML, "trayContextMenu");
705 tray_quit = glade_xml_get_widget (trayContextMenuXML, "tray_quit");
706
707 tray_icon = egg_tray_icon_new (_("GNU's peer-to-peer network"));
708 instDir = GNUNET_get_installation_path (GNUNET_IPK_SELF_PREFIX);
709 iconPath = GNUNET_malloc (strlen (instDir) + strlen ("share/gnunet-gtk/gnunet-gtk-status-connected.svg") + 1);
710 strcpy (iconPath, instDir);
711 strcat (iconPath, "share/gnunet-gtk/gnunet-gtk-status-connected.svg");
712 GNUNET_free (instDir);
713 pixbuf = gdk_pixbuf_new_from_file (iconPath, NULL);
714 GNUNET_free (iconPath);
715 tray_icon_image = gtk_image_new_from_pixbuf (pixbuf);
716 eventbox = gtk_event_box_new ();
717 gtk_container_add (GTK_CONTAINER (eventbox), tray_icon_image);
718 gtk_container_add (GTK_CONTAINER (tray_icon), eventbox);
719 g_signal_connect (G_OBJECT (tray_quit), "activate",
720 G_CALLBACK (on_tray_quit_activate), NULL);
721 g_signal_connect_swapped (G_OBJECT (eventbox), "button_press_event",
722 G_CALLBACK (tray_clicked), trayContextMenu);
723 tray_icon_tooltip = gtk_tooltips_new ();
724 gtk_tooltips_set_tip (tray_icon_tooltip, GTK_WIDGET (tray_icon),
725 _("GNU's peer-to-peer network"), NULL);
726 gtk_widget_show (eventbox);
727 gtk_widget_show_all (GTK_WIDGET (tray_icon));
728#endif
729}