Index: libegg/tray/eggtrayicon.c
===================================================================
RCS file: /cvs/gnome/libegg/libegg/tray/eggtrayicon.c,v
retrieving revision 1.7
diff -u -r1.7 eggtrayicon.c
--- libegg/tray/eggtrayicon.c	5 Jun 2005 14:42:35 -0000	1.7
+++ libegg/tray/eggtrayicon.c	9 Jun 2005 00:59:33 -0000
@@ -20,6 +20,7 @@
 
 #include <config.h>
 #include <string.h>
+#include <stdlib.h>
 #include <libintl.h>
 
 #include "eggtrayicon.h"
@@ -143,6 +144,192 @@
     }
 }
 
+
+static gboolean
+panel_applet_parse_color (const gchar *color_str,
+			  GdkColor    *color)
+{
+  int r, g, b;
+
+  g_assert (color_str && color);
+
+  if (sscanf (color_str, "%4x%4x%4x", &r, &g, &b) != 3)
+    return FALSE;
+
+  color->red   = r;
+  color->green = g;
+  color->blue  = b;
+
+  return TRUE;
+}
+
+static gboolean
+egg_tray_icon_parse_pixmap_str (const char      *str,
+				GdkNativeWindow *xid,
+				int             *x,
+				int             *y)
+{
+  char **elements;
+  char  *tmp;
+
+  g_return_val_if_fail (str != NULL, FALSE);
+  g_return_val_if_fail (xid != NULL, FALSE);
+  g_return_val_if_fail (x != NULL, FALSE);
+  g_return_val_if_fail (y != NULL, FALSE);
+
+  elements = g_strsplit (str, ",", -1);
+
+  if (!elements)
+    return FALSE;
+
+  if (!elements [0] || !*elements [0] ||
+      !elements [1] || !*elements [1] ||
+      !elements [2] || !*elements [2])
+    goto ERROR_AND_FREE;
+
+  *xid = strtol (elements [0], &tmp, 10);
+  if (tmp == elements [0])
+    goto ERROR_AND_FREE;
+
+  *x   = strtol (elements [1], &tmp, 10);
+  if (tmp == elements [1])
+    goto ERROR_AND_FREE;
+
+  *y   = strtol (elements [2], &tmp, 10);
+  if (tmp == elements [2])
+    goto ERROR_AND_FREE;
+
+  g_strfreev (elements);
+  return TRUE;
+
+ERROR_AND_FREE:
+  g_strfreev (elements);
+  return FALSE;
+}
+
+static GdkPixmap *
+egg_tray_icon_get_pixmap (GdkWindow       *window,
+                          const char      *bg_str)
+{
+  GdkNativeWindow  xid;
+  GdkPixmap       *pixmap;
+  GdkDisplay      *display;
+  GdkPixmap       *retval;
+  GdkGC           *gc;
+  int              width;
+  int              height;
+  int              x, y;
+
+  if (!egg_tray_icon_parse_pixmap_str (bg_str, &xid, &x, &y))
+    return NULL;
+
+  gc = gdk_gc_new (GDK_DRAWABLE (window));
+
+  g_return_val_if_fail (GDK_IS_GC (gc), NULL);
+
+  display = gdk_display_get_default ();
+
+  pixmap = gdk_pixmap_lookup_for_display (display, xid);
+  if (pixmap)
+    g_object_ref (pixmap);
+  else
+    pixmap = gdk_pixmap_foreign_new_for_display (display, xid);
+
+  g_return_val_if_fail (pixmap != NULL, NULL);
+
+  gdk_drawable_get_size (GDK_DRAWABLE (window),
+			 &width, &height);
+
+  retval = gdk_pixmap_new (window, width, height, -1);
+
+  gdk_draw_drawable (GDK_DRAWABLE (retval),
+		     gc,
+		     GDK_DRAWABLE (pixmap),
+		     x, y,
+		     0, 0,
+		     width, height);
+
+  g_object_unref (gc);
+  g_object_unref (pixmap);
+
+  return retval;
+}
+
+static void
+egg_tray_icon_update_background (EggTrayIcon *icon, const char *bg_str)
+{
+  GtkWidget  *widget = GTK_WIDGET (icon);
+  GtkRcStyle *rc_style;
+  GtkStyle   *style;
+
+  /* reset style */
+  gtk_widget_set_style (widget, NULL);
+  rc_style = gtk_rc_style_new ();
+  gtk_widget_modify_style (widget, rc_style);
+  gtk_rc_style_unref (rc_style);
+
+  if (!strncmp (bg_str, "color:", 6))
+    {
+      GdkColor colour;
+
+      if (panel_applet_parse_color (bg_str + 6, &colour))
+	gtk_widget_modify_bg (widget, GTK_STATE_NORMAL, &colour);
+    }
+  else if (!strncmp (bg_str, "pixmap:", 7))
+    {
+      GdkPixmap *pixmap;
+
+      if ((pixmap = egg_tray_icon_get_pixmap (widget->window, bg_str + 7)))
+	{
+	  style = gtk_style_copy (widget->style);
+	  if (style->bg_pixmap[GTK_STATE_NORMAL])
+	    g_object_unref (style->bg_pixmap[GTK_STATE_NORMAL]);
+	  style->bg_pixmap[GTK_STATE_NORMAL] = g_object_ref (pixmap);
+	  gtk_widget_set_style (widget, style);
+	  g_object_unref (style);
+	  g_object_unref (pixmap);
+	}
+    }
+}
+
+static void
+egg_tray_icon_get_background_property (EggTrayIcon *icon)
+{
+  Display *xdisplay;
+  Atom type;
+  int format;
+  unsigned char *prop;
+  gulong nitems;
+  gulong bytes_after;
+  int error, result;
+  Window mywindow;
+
+  mywindow = GDK_DRAWABLE_XID( GTK_WIDGET (icon)->window );
+
+  g_assert (icon->manager_window != None);
+  
+  xdisplay = GDK_DISPLAY_XDISPLAY (gtk_widget_get_display (GTK_WIDGET (icon)));
+
+  gdk_error_trap_push ();
+  type = None;
+  result = XGetWindowProperty (xdisplay, mywindow,
+			       icon->background_atom,
+			       0, G_MAXLONG, FALSE,
+			       XA_STRING,
+			       &type, &format, &nitems,
+			       &bytes_after, &prop);
+  error = gdk_error_trap_pop ();
+
+  if (error || result != Success)
+    return;
+
+  if (type == XA_STRING)
+    egg_tray_icon_update_background (icon, prop);
+
+  if (prop)
+    XFree (prop);
+}
+
 static void
 egg_tray_icon_get_orientation_property (EggTrayIcon *icon)
 {
@@ -219,6 +406,14 @@
 	  egg_tray_icon_manager_window_destroyed (icon);
 	}
     }
+  else if (xev->xany.window == GDK_DRAWABLE_XID (GTK_WIDGET (icon)->window))
+    {
+      if (xev->xany.type == PropertyNotify &&
+	  xev->xproperty.atom == icon->background_atom)
+	{
+	  egg_tray_icon_get_background_property (icon);
+	}
+    }
   
   return GDK_FILTER_CONTINUE;
 }
@@ -376,6 +571,10 @@
   icon->orientation_atom = XInternAtom (xdisplay,
 					"_NET_SYSTEM_TRAY_ORIENTATION",
 					False);
+
+  icon->background_atom = XInternAtom (xdisplay,
+				       "_NET_SYSTEM_TRAY_BACKGROUND",
+				       False);
 
   egg_tray_icon_update_manager_window (icon, FALSE);
   egg_tray_icon_send_dock_request (icon);
Index: libegg/tray/eggtrayicon.h
===================================================================
RCS file: /cvs/gnome/libegg/libegg/tray/eggtrayicon.h,v
retrieving revision 1.4
diff -u -r1.4 eggtrayicon.h
--- libegg/tray/eggtrayicon.h	9 Apr 2003 01:05:44 -0000	1.4
+++ libegg/tray/eggtrayicon.h	9 Jun 2005 00:59:33 -0000
@@ -46,6 +46,7 @@
   Atom manager_atom;
   Atom system_tray_opcode_atom;
   Atom orientation_atom;
+  Atom background_atom;
   Window manager_window;
 
   GtkOrientation orientation;
Index: libegg/tray/eggtraymanager.c
===================================================================
RCS file: /cvs/gnome/libegg/libegg/tray/eggtraymanager.c,v
retrieving revision 1.7
diff -u -r1.7 eggtraymanager.c
--- libegg/tray/eggtraymanager.c	9 Apr 2003 01:05:44 -0000	1.7
+++ libegg/tray/eggtraymanager.c	9 Jun 2005 00:59:33 -0000
@@ -557,6 +557,10 @@
 					   "_NET_SYSTEM_TRAY_ORIENTATION",
 					   FALSE);
   egg_tray_manager_set_orientation_property (manager);
+
+  manager->background_atom = XInternAtom (DisplayOfScreen (xscreen),
+					  "_NET_SYSTEM_TRAY_BACKGROUND",
+					  FALSE);
   
   timestamp = gdk_x11_get_server_time (invisible->window);
   XSetSelectionOwner (DisplayOfScreen (xscreen), manager->selection_atom,
@@ -722,4 +726,26 @@
   g_return_val_if_fail (EGG_IS_TRAY_MANAGER (manager), GTK_ORIENTATION_HORIZONTAL);
 
   return manager->orientation;
+}
+
+void
+egg_tray_manager_set_background (EggTrayManager *manager,
+				 GtkSocket      *socket,
+				 const char     *bg_str)
+{
+  Window *window;
+
+  if (!manager->invisible || !manager->invisible->window)
+    return;
+
+  g_assert (manager->background_atom != None);
+
+  window = g_object_get_data (G_OBJECT (socket), "egg-tray-child-window");
+
+  XChangeProperty (GDK_WINDOW_XDISPLAY (manager->invisible->window),
+		   *window,
+		   manager->background_atom,
+		   XA_STRING, 8,
+		   PropModeReplace,
+		   bg_str, strlen (bg_str) + 1);
 }
Index: libegg/tray/eggtraymanager.h
===================================================================
RCS file: /cvs/gnome/libegg/libegg/tray/eggtraymanager.h,v
retrieving revision 1.6
diff -u -r1.6 eggtraymanager.h
--- libegg/tray/eggtraymanager.h	9 Apr 2003 01:05:44 -0000	1.6
+++ libegg/tray/eggtraymanager.h	9 Jun 2005 00:59:33 -0000
@@ -22,6 +22,7 @@
 #define __EGG_TRAY_MANAGER_H__
 
 #include <gtk/gtkwidget.h>
+#include <gtk/gtksocket.h>
 #include <gdk/gdkx.h>
 
 G_BEGIN_DECLS
@@ -45,6 +46,7 @@
   Atom selection_atom;
   Atom message_data_atom;
   Atom orientation_atom;
+  Atom background_atom;
   
   GtkWidget *invisible;
   GdkScreen *screen;
@@ -87,6 +89,10 @@
 void            egg_tray_manager_set_orientation (EggTrayManager      *manager,
 						  GtkOrientation       orientation);
 GtkOrientation  egg_tray_manager_get_orientation (EggTrayManager      *manager);
+void            egg_tray_manager_set_background  (EggTrayManager      *manager,
+						  GtkSocket           *socket,
+						  const char          *bg_str);
+
 
 G_END_DECLS
 
