# HG changeset patch # User Elliott Sales de Andrade # Date 1271197742 0 # Node ID 823c3917d53394d9ac547279ed761abf07eac823 # Parent 0c764778c7651c3a118b217ec8062d49f190fcbf Mark already got rid of gtkdocklet-x11.c, so I don't think we need to hold on to EggTrayIcon either. diff -r 0c764778c765 -r 823c3917d533 pidgin/Makefile.am --- a/pidgin/Makefile.am Tue Apr 13 16:28:32 2010 +0000 +++ b/pidgin/Makefile.am Tue Apr 13 22:29:02 2010 +0000 @@ -75,7 +75,6 @@ bin_PROGRAMS = pidgin pidgin_SOURCES = \ - eggtrayicon.c \ pidginstock.c \ gtkaccount.c \ gtkblist.c \ @@ -126,7 +125,6 @@ pidgintooltip.c pidgin_headers = \ - eggtrayicon.h \ gtkaccount.h \ gtkblist.h \ gtkblist-theme.h \ diff -r 0c764778c765 -r 823c3917d533 pidgin/eggtrayicon.c --- a/pidgin/eggtrayicon.c Tue Apr 13 16:28:32 2010 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,617 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* eggtrayicon.c - * Copyright (C) 2002 Anders Carlsson - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02111-1301, USA. - */ - -#include -#include - -#include "eggtrayicon.h" - -#include - -#define _(x) x -#define N_(x) x - -#define SYSTEM_TRAY_REQUEST_DOCK 0 -#define SYSTEM_TRAY_BEGIN_MESSAGE 1 -#define SYSTEM_TRAY_CANCEL_MESSAGE 2 - -#define SYSTEM_TRAY_ORIENTATION_HORZ 0 -#define SYSTEM_TRAY_ORIENTATION_VERT 1 - -enum { - PROP_0, - PROP_ORIENTATION -}; - -static GtkPlugClass *parent_class = NULL; - -static void egg_tray_icon_init (EggTrayIcon *icon); -static void egg_tray_icon_class_init (EggTrayIconClass *klass); - -static void egg_tray_icon_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec); - -static void egg_tray_icon_realize (GtkWidget *widget); -static void egg_tray_icon_unrealize (GtkWidget *widget); - -static void egg_tray_icon_add (GtkContainer *container, - GtkWidget *widget); - -static void egg_tray_icon_update_manager_window (EggTrayIcon *icon, - gboolean dock_if_realized); -static void egg_tray_icon_manager_window_destroyed (EggTrayIcon *icon); - -GType -egg_tray_icon_get_type (void) -{ - static GType our_type = 0; - - if (our_type == 0) - { - our_type = g_type_from_name("EggTrayIcon"); - - if (our_type == 0) - { - static const GTypeInfo our_info = - { - sizeof (EggTrayIconClass), - (GBaseInitFunc) NULL, - (GBaseFinalizeFunc) NULL, - (GClassInitFunc) egg_tray_icon_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (EggTrayIcon), - 0, /* n_preallocs */ - (GInstanceInitFunc) egg_tray_icon_init, - NULL /* value_table */ - }; - - our_type = g_type_register_static (GTK_TYPE_PLUG, "EggTrayIcon", &our_info, 0); - } - else if (parent_class == NULL) - { - /* we're reheating the old class from a previous instance - engage ugly hack =( */ - egg_tray_icon_class_init((EggTrayIconClass *)g_type_class_peek(our_type)); - } - } - - return our_type; -} - -static void -egg_tray_icon_init (EggTrayIcon *icon) -{ - icon->stamp = 1; - icon->orientation = GTK_ORIENTATION_HORIZONTAL; - - gtk_widget_add_events (GTK_WIDGET (icon), GDK_PROPERTY_CHANGE_MASK); -} - -static void -egg_tray_icon_class_init (EggTrayIconClass *klass) -{ - GObjectClass *gobject_class = (GObjectClass *)klass; - GtkWidgetClass *widget_class = (GtkWidgetClass *)klass; - GtkContainerClass *container_class = (GtkContainerClass *)klass; - - parent_class = g_type_class_peek_parent (klass); - - gobject_class->get_property = egg_tray_icon_get_property; - - widget_class->realize = egg_tray_icon_realize; - widget_class->unrealize = egg_tray_icon_unrealize; - - container_class->add = egg_tray_icon_add; - - g_object_class_install_property (gobject_class, - PROP_ORIENTATION, - g_param_spec_enum ("orientation", - _("Orientation"), - _("The orientation of the tray."), - GTK_TYPE_ORIENTATION, - GTK_ORIENTATION_HORIZONTAL, - G_PARAM_READABLE)); -} - -static void -egg_tray_icon_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - EggTrayIcon *icon = EGG_TRAY_ICON (object); - - switch (prop_id) - { - case PROP_ORIENTATION: - g_value_set_enum (value, icon->orientation); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static Display * -egg_tray_icon_get_x_display(EggTrayIcon *icon) -{ - Display *xdisplay = NULL; - -#if GTK_CHECK_VERSION(2,1,0) - { - GdkDisplay *display = gtk_widget_get_display (GTK_WIDGET (icon)); - if (!GDK_IS_DISPLAY (display)) - display = gdk_display_get_default (); - - xdisplay = GDK_DISPLAY_XDISPLAY (display); - } -#else - xdisplay = gdk_display; -#endif - - return xdisplay; -} - -static void -egg_tray_icon_get_orientation_property (EggTrayIcon *icon) -{ - Display *xdisplay; - Atom type; - int format; - union { - gulong *prop; - guchar *prop_ch; - } prop = { NULL }; - gulong nitems; - gulong bytes_after; - int error, result; - - g_return_if_fail(icon->manager_window != None); - - xdisplay = egg_tray_icon_get_x_display(icon); - - if (xdisplay == NULL) - return; - - gdk_error_trap_push (); - type = None; - result = XGetWindowProperty (xdisplay, - icon->manager_window, - icon->orientation_atom, - 0, G_MAXLONG, FALSE, - XA_CARDINAL, - &type, &format, &nitems, - &bytes_after, &(prop.prop_ch)); - error = gdk_error_trap_pop (); - - if (error || result != Success) - return; - - if (type == XA_CARDINAL) - { - GtkOrientation orientation; - - orientation = (prop.prop [0] == SYSTEM_TRAY_ORIENTATION_HORZ) ? - GTK_ORIENTATION_HORIZONTAL : - GTK_ORIENTATION_VERTICAL; - - if (icon->orientation != orientation) - { - icon->orientation = orientation; - - g_object_notify (G_OBJECT (icon), "orientation"); - } - } - - if (prop.prop) - XFree (prop.prop); -} - -static GdkFilterReturn -egg_tray_icon_manager_filter (GdkXEvent *xevent, GdkEvent *event, gpointer user_data) -{ - EggTrayIcon *icon = user_data; - XEvent *xev = (XEvent *)xevent; - - if (xev->xany.type == ClientMessage && - xev->xclient.message_type == icon->manager_atom && - xev->xclient.data.l[1] == icon->selection_atom) - { - egg_tray_icon_update_manager_window (icon, TRUE); - } - else if (xev->xany.window == icon->manager_window) - { - if (xev->xany.type == PropertyNotify && - xev->xproperty.atom == icon->orientation_atom) - { - egg_tray_icon_get_orientation_property (icon); - } - if (xev->xany.type == DestroyNotify) - { - egg_tray_icon_manager_window_destroyed (icon); - } - } - - return GDK_FILTER_CONTINUE; -} - -static void -egg_tray_icon_unrealize (GtkWidget *widget) -{ - EggTrayIcon *icon = EGG_TRAY_ICON (widget); - GdkWindow *root_window; - - if (icon->manager_window != None) - { - GdkWindow *gdkwin; - -#if GTK_CHECK_VERSION(2,1,0) - gdkwin = gdk_window_lookup_for_display (gtk_widget_get_display (widget), - icon->manager_window); -#else - gdkwin = gdk_window_lookup (icon->manager_window); -#endif - - gdk_window_remove_filter (gdkwin, egg_tray_icon_manager_filter, icon); - } - -#if GTK_CHECK_VERSION(2,1,0) - root_window = gdk_screen_get_root_window (gtk_widget_get_screen (widget)); -#else - root_window = gdk_window_lookup (gdk_x11_get_default_root_xwindow ()); -#endif - - gdk_window_remove_filter (root_window, egg_tray_icon_manager_filter, icon); - - if (GTK_WIDGET_CLASS (parent_class)->unrealize) - (* GTK_WIDGET_CLASS (parent_class)->unrealize) (widget); -} - -static void -egg_tray_icon_send_manager_message (EggTrayIcon *icon, - long message, - Window window, - long data1, - long data2, - long data3) -{ - XClientMessageEvent ev; - Display *display; - - ev.type = ClientMessage; - ev.window = window; - ev.message_type = icon->system_tray_opcode_atom; - ev.format = 32; - ev.data.l[0] = gdk_x11_get_server_time (GTK_WIDGET (icon)->window); - ev.data.l[1] = message; - ev.data.l[2] = data1; - ev.data.l[3] = data2; - ev.data.l[4] = data3; - -#if GTK_CHECK_VERSION(2,1,0) - display = GDK_DISPLAY_XDISPLAY (gtk_widget_get_display (GTK_WIDGET (icon))); -#else - display = gdk_display; -#endif - - gdk_error_trap_push (); - XSendEvent (display, - icon->manager_window, False, NoEventMask, (XEvent *)&ev); - XSync (display, False); - gdk_error_trap_pop (); -} - -static void -egg_tray_icon_send_dock_request (EggTrayIcon *icon) -{ - egg_tray_icon_send_manager_message (icon, - SYSTEM_TRAY_REQUEST_DOCK, - icon->manager_window, - gtk_plug_get_id (GTK_PLUG (icon)), - 0, 0); -} - -static void -egg_tray_icon_update_manager_window (EggTrayIcon *icon, - gboolean dock_if_realized) -{ - Display *xdisplay; - - if (icon->manager_window != None) - return; - - xdisplay = egg_tray_icon_get_x_display(icon); - - if (xdisplay == NULL) - return; - - XGrabServer (xdisplay); - - icon->manager_window = XGetSelectionOwner (xdisplay, - icon->selection_atom); - - if (icon->manager_window != None) - XSelectInput (xdisplay, - icon->manager_window, StructureNotifyMask|PropertyChangeMask); - - XUngrabServer (xdisplay); - XFlush (xdisplay); - - if (icon->manager_window != None) - { - GdkWindow *gdkwin; - -#if GTK_CHECK_VERSION(2,1,0) - gdkwin = gdk_window_lookup_for_display (gtk_widget_get_display (GTK_WIDGET (icon)), - icon->manager_window); -#else - gdkwin = gdk_window_lookup (icon->manager_window); -#endif - - gdk_window_add_filter (gdkwin, egg_tray_icon_manager_filter, icon); - - if (dock_if_realized && GTK_WIDGET_REALIZED (icon)) - egg_tray_icon_send_dock_request (icon); - - egg_tray_icon_get_orientation_property (icon); - } -} - -static void -egg_tray_icon_manager_window_destroyed (EggTrayIcon *icon) -{ - GdkWindow *gdkwin; - - g_return_if_fail (icon->manager_window != None); - -#if GTK_CHECK_VERSION(2,1,0) - gdkwin = gdk_window_lookup_for_display (gtk_widget_get_display (GTK_WIDGET (icon)), - icon->manager_window); -#else - gdkwin = gdk_window_lookup (icon->manager_window); -#endif - - gdk_window_remove_filter (gdkwin, egg_tray_icon_manager_filter, icon); - - icon->manager_window = None; - - egg_tray_icon_update_manager_window (icon, TRUE); -} - -static gboolean -transparent_expose_event (GtkWidget *widget, GdkEventExpose *event, gpointer user_data) -{ - GtkWidget *focus_child = NULL; - gint border_width, x, y, width, height; - gboolean retval = FALSE; - - gdk_window_clear_area (widget->window, event->area.x, event->area.y, - event->area.width, event->area.height); - - if (GTK_WIDGET_CLASS (parent_class)->expose_event) - retval = GTK_WIDGET_CLASS (parent_class)->expose_event (widget, event); - - if (GTK_CONTAINER (widget)->focus_child) - focus_child = GTK_CONTAINER (GTK_CONTAINER (widget)->focus_child)->focus_child; - if (focus_child && GTK_WIDGET_HAS_FOCUS (focus_child)) - { - border_width = GTK_CONTAINER (widget)->border_width; - - x = widget->allocation.x + border_width; - y = widget->allocation.y + border_width; - - width = widget->allocation.width - 2 * border_width; - height = widget->allocation.height - 2 * border_width; - - gtk_paint_focus (widget->style, widget->window, - GTK_WIDGET_STATE (widget), - &event->area, widget, "tray_icon", - x, y, width, height); - } - - return retval; -} - -static void -make_transparent_again (GtkWidget *widget, GtkStyle *previous_style, - gpointer user_data) -{ - gdk_window_set_back_pixmap(widget->window, NULL, TRUE); -} - -static void -make_transparent (GtkWidget *widget, gpointer user_data) -{ - if (GTK_WIDGET_NO_WINDOW (widget) || GTK_WIDGET_APP_PAINTABLE (widget)) - return; - - gtk_widget_set_app_paintable (widget, TRUE); - gtk_widget_set_double_buffered (widget, FALSE); - gdk_window_set_back_pixmap (widget->window, NULL, TRUE); - g_signal_connect (widget, "expose_event", - G_CALLBACK (transparent_expose_event), NULL); - g_signal_connect_after (widget, "style_set", - G_CALLBACK (make_transparent_again), NULL); -} - -static void -egg_tray_icon_realize (GtkWidget *widget) -{ - EggTrayIcon *icon = EGG_TRAY_ICON (widget); - gint screen; - Display *xdisplay; - char buffer[256]; - GdkWindow *root_window; - - if (GTK_WIDGET_CLASS (parent_class)->realize) - GTK_WIDGET_CLASS (parent_class)->realize (widget); - - make_transparent (widget, NULL); - - xdisplay = egg_tray_icon_get_x_display(icon); - - if (xdisplay == NULL) - return; - -#if GTK_CHECK_VERSION(2,1,0) - screen = gdk_screen_get_number (gtk_widget_get_screen (widget)); -#else - screen = XScreenNumberOfScreen (DefaultScreenOfDisplay (gdk_display)); -#endif - - /* Now see if there's a manager window around */ - g_snprintf (buffer, sizeof (buffer), - "_NET_SYSTEM_TRAY_S%d", - screen); - - icon->selection_atom = XInternAtom (xdisplay, buffer, False); - - icon->manager_atom = XInternAtom (xdisplay, "MANAGER", False); - - icon->system_tray_opcode_atom = XInternAtom (xdisplay, - "_NET_SYSTEM_TRAY_OPCODE", - False); - - icon->orientation_atom = XInternAtom (xdisplay, - "_NET_SYSTEM_TRAY_ORIENTATION", - False); - - egg_tray_icon_update_manager_window (icon, FALSE); - egg_tray_icon_send_dock_request (icon); - -#if GTK_CHECK_VERSION(2,1,0) - root_window = gdk_screen_get_root_window (gtk_widget_get_screen (widget)); -#else - root_window = gdk_window_lookup (gdk_x11_get_default_root_xwindow ()); -#endif - - /* Add a root window filter so that we get changes on MANAGER */ - gdk_window_add_filter (root_window, - egg_tray_icon_manager_filter, icon); -} - -static void -egg_tray_icon_add (GtkContainer *container, GtkWidget *widget) -{ - g_signal_connect (widget, "realize", - G_CALLBACK (make_transparent), NULL); - GTK_CONTAINER_CLASS (parent_class)->add (container, widget); -} - -#if GTK_CHECK_VERSION(2,1,0) -EggTrayIcon * -egg_tray_icon_new_for_screen (GdkScreen *screen, const char *name) -{ - g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL); - - return g_object_new (EGG_TYPE_TRAY_ICON, "screen", screen, "title", name, NULL); -} -#endif - -EggTrayIcon* -egg_tray_icon_new (const gchar *name) -{ - return g_object_new (EGG_TYPE_TRAY_ICON, "title", name, NULL); -} - -guint -egg_tray_icon_send_message (EggTrayIcon *icon, - gint timeout, - const gchar *message, - gint len) -{ - guint stamp; - - g_return_val_if_fail (EGG_IS_TRAY_ICON (icon), 0); - g_return_val_if_fail (timeout >= 0, 0); - g_return_val_if_fail (message != NULL, 0); - - if (icon->manager_window == None) - return 0; - - if (len < 0) - len = strlen (message); - - stamp = icon->stamp++; - - /* Get ready to send the message */ - egg_tray_icon_send_manager_message (icon, SYSTEM_TRAY_BEGIN_MESSAGE, - (Window)gtk_plug_get_id (GTK_PLUG (icon)), - timeout, len, stamp); - - /* Now to send the actual message */ - gdk_error_trap_push (); - while (len > 0) - { - XClientMessageEvent ev; - Display *xdisplay; - - xdisplay = egg_tray_icon_get_x_display(icon); - - if (xdisplay == NULL) - return 0; - - ev.type = ClientMessage; - ev.window = (Window)gtk_plug_get_id (GTK_PLUG (icon)); - ev.format = 8; - ev.message_type = XInternAtom (xdisplay, - "_NET_SYSTEM_TRAY_MESSAGE_DATA", False); - if (len > 20) - { - memcpy (&ev.data, message, 20); - len -= 20; - message += 20; - } - else - { - memcpy (&ev.data, message, len); - len = 0; - } - - XSendEvent (xdisplay, - icon->manager_window, False, StructureNotifyMask, (XEvent *)&ev); - XSync (xdisplay, False); - } - gdk_error_trap_pop (); - - return stamp; -} - -void -egg_tray_icon_cancel_message (EggTrayIcon *icon, - guint id) -{ - g_return_if_fail (EGG_IS_TRAY_ICON (icon)); - g_return_if_fail (id > 0); - - egg_tray_icon_send_manager_message (icon, SYSTEM_TRAY_CANCEL_MESSAGE, - (Window)gtk_plug_get_id (GTK_PLUG (icon)), - id, 0, 0); -} - -GtkOrientation -egg_tray_icon_get_orientation (EggTrayIcon *icon) -{ - g_return_val_if_fail (EGG_IS_TRAY_ICON (icon), GTK_ORIENTATION_HORIZONTAL); - - return icon->orientation; -} diff -r 0c764778c765 -r 823c3917d533 pidgin/eggtrayicon.h --- a/pidgin/eggtrayicon.h Tue Apr 13 16:28:32 2010 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,79 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* eggtrayicon.h - * Copyright (C) 2002 Anders Carlsson - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02111-1301, USA. - */ - -#ifndef __EGG_TRAY_ICON_H__ -#define __EGG_TRAY_ICON_H__ - -#include -#include - -G_BEGIN_DECLS - -#define EGG_TYPE_TRAY_ICON (egg_tray_icon_get_type ()) -#define EGG_TRAY_ICON(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EGG_TYPE_TRAY_ICON, EggTrayIcon)) -#define EGG_TRAY_ICON_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EGG_TYPE_TRAY_ICON, EggTrayIconClass)) -#define EGG_IS_TRAY_ICON(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EGG_TYPE_TRAY_ICON)) -#define EGG_IS_TRAY_ICON_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EGG_TYPE_TRAY_ICON)) -#define EGG_TRAY_ICON_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EGG_TYPE_TRAY_ICON, EggTrayIconClass)) - -typedef struct _EggTrayIcon EggTrayIcon; -typedef struct _EggTrayIconClass EggTrayIconClass; - -struct _EggTrayIcon -{ - GtkPlug parent_instance; - - guint stamp; - - Atom selection_atom; - Atom manager_atom; - Atom system_tray_opcode_atom; - Atom orientation_atom; - Window manager_window; - - GtkOrientation orientation; -}; - -struct _EggTrayIconClass -{ - GtkPlugClass parent_class; -}; - -GType egg_tray_icon_get_type (void); - -#if GTK_CHECK_VERSION(2,1,0) -EggTrayIcon *egg_tray_icon_new_for_screen (GdkScreen *screen, - const gchar *name); -#endif - -EggTrayIcon *egg_tray_icon_new (const gchar *name); - -guint egg_tray_icon_send_message (EggTrayIcon *icon, - gint timeout, - const char *message, - gint len); -void egg_tray_icon_cancel_message (EggTrayIcon *icon, - guint id); - -GtkOrientation egg_tray_icon_get_orientation (EggTrayIcon *icon); - -G_END_DECLS - -#endif /* __EGG_TRAY_ICON_H__ */