[mutter] iconcache: Correctly interpret monochrome icons



commit 654d966e6ce95b376101dac2889e207da8de4016
Author: Owen W. Taylor <otaylor fishsoup net>
Date:   Mon Mar 21 18:45:20 2011 -0400

    iconcache: Correctly interpret monochrome icons
    
    Getting the contents of a depth-1 pixmap through cairo gives us
    an alpha pixmap. We need to convert to a monochrome pixmap
    as is expected by the ICCCM definition of WM_HINTS.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=641975

 src/core/iconcache.c |   44 ++++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 42 insertions(+), 2 deletions(-)
---
diff --git a/src/core/iconcache.c b/src/core/iconcache.c
index 547aee0..d298467 100644
--- a/src/core/iconcache.c
+++ b/src/core/iconcache.c
@@ -323,6 +323,40 @@ get_pixmap_geometry (MetaDisplay *display,
     *d = depth;
 }
 
+static void
+apply_foreground_background (GdkPixbuf *pixbuf)
+{
+  int w, h;
+  int i, j;
+  guchar *pixels;
+  int stride;
+
+  w = gdk_pixbuf_get_width (pixbuf);
+  h = gdk_pixbuf_get_height (pixbuf);
+  pixels = gdk_pixbuf_get_pixels (pixbuf);
+  stride = gdk_pixbuf_get_rowstride (pixbuf);
+
+  i = 0;
+  while (i < h)
+    {
+      j = 0;
+      while (j < w)
+        {
+          guchar *p = pixels + i * stride + j * 4;
+          if (p[3] == 0)
+            p[0] = p[1] = p[2] =  0xff; /* white background */
+          else
+            p[0] = p[1] = p[2] = 0x00; /* black foreground */
+
+          p[3] = 0xff;
+
+          ++j;
+        }
+
+      ++i;
+    }
+}
+
 static GdkPixbuf*
 apply_mask (GdkPixbuf *pixbuf,
             GdkPixbuf *mask)
@@ -379,19 +413,25 @@ try_pixmap_and_mask (MetaDisplay *display,
 {
   GdkPixbuf *unscaled = NULL;
   GdkPixbuf *mask = NULL;
-  int w, h;
+  int w, h, d;
 
   if (src_pixmap == None)
     return FALSE;
 
   meta_error_trap_push (display);
 
-  get_pixmap_geometry (display, src_pixmap, &w, &h, NULL);
+  get_pixmap_geometry (display, src_pixmap, &w, &h, &d);
 
   unscaled = meta_gdk_pixbuf_get_from_pixmap (src_pixmap,
                                               0, 0,
                                               w, h);
 
+  /* A depth 1 pixmap has 0 background, and 1 foreground, but
+   * cairo and meta_gdk_pixbuf_get_from_pixmap consider it
+   * to be 0 transparent, 1 opaque */
+  if (d == 1)
+    apply_foreground_background (unscaled);
+
   if (unscaled && src_mask != None)
     {
       get_pixmap_geometry (display, src_mask, &w, &h, NULL);



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]