From c75366000d272b58a0475139b88abf6e54ba0871 Mon Sep 17 00:00:00 2001
From: Olivier Fourdan <fourdan.olivier@wanadoo.fr>
Date: Mon, 31 May 2004 21:06:38 +0000
Subject: [PATCH] Fix potential memleak in libxfcegui4 Improve internals of png
 composition in xfwm4 Prepare support for icons in xfwm4 (not quite there yet)

(Old svn revision: 11773)
---
 src/hints.c    | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++
 src/hints.h    |  4 ++++
 src/mypixmap.c | 45 ++++++++++++++++++++++++++++++++++---
 3 files changed, 107 insertions(+), 3 deletions(-)

diff --git a/src/hints.c b/src/hints.c
index 9ce24cce3..aa599be88 100644
--- a/src/hints.c
+++ b/src/hints.c
@@ -119,6 +119,7 @@ Atom utf8_string;
 /* KDE extension */
 Atom kde_net_wm_context_help;
 Atom kde_net_wm_system_tray_window_for;
+Atom kwm_win_icon;
 
 /* Systray similation for older KDE apps */
 Atom net_system_tray_manager;
@@ -314,6 +315,7 @@ initKDEHints (Display * dpy)
         XInternAtom (dpy, "_NET_WM_CONTEXT_HELP", FALSE);
     kde_net_wm_system_tray_window_for = 
         XInternAtom (dpy, "_KDE_NET_WM_SYSTEM_TRAY_WINDOW_FOR", FALSE);
+    kwm_win_icon = XInternAtom (dpy, "KWM_WIN_ICON", FALSE);
 }
 
 void
@@ -1041,6 +1043,65 @@ getWindowCommand (Display * dpy, Window window, char ***argv, int *argc)
     return FALSE;
 }
 
+gboolean
+getKDEIcon (Display * dpy, Window window, Pixmap * pixmap, Pixmap * mask)
+{
+    Atom type;
+    int format;
+    unsigned long nitems;
+    unsigned long bytes_after;
+    Pixmap *icons;
+
+    *pixmap = None;
+    *mask = None;
+
+    icons = NULL;
+    if (XGetWindowProperty (dpy, window, kwm_win_icon, 0L, G_MAXLONG,
+            FALSE, kwm_win_icon, &type, &format, &nitems, &bytes_after,
+	    (unsigned char **)&icons) != Success)
+    {
+        return FALSE;
+    }
+
+    if (type != kwm_win_icon)
+    {
+        XFree (icons);
+        return FALSE;
+    }
+
+    *pixmap = icons[0];
+    *mask = icons[1];
+
+    XFree (icons);
+
+    return TRUE;
+}
+
+gboolean
+getRGBIconData (Display * dpy, Window window, unsigned long **data, unsigned long *nitems)
+{
+    Atom type;
+    int format;
+    unsigned long bytes_after;
+
+    if (XGetWindowProperty (dpy, window, net_wm_icon, 0L, G_MAXLONG,
+                            FALSE, XA_CARDINAL, &type, &format, nitems,
+                            &bytes_after, (unsigned char **)data) != Success)
+    {
+	data = NULL;
+        return FALSE;
+    }
+    
+    if (type != XA_CARDINAL)
+    {
+        XFree (*data);
+	data = NULL;
+        return FALSE;
+    }
+
+    return TRUE;
+}
+
 #ifdef HAVE_LIBSTARTUP_NOTIFICATION
 gboolean
 getWindowStartupId (Display * dpy, Window window, char **startup_id)
diff --git a/src/hints.h b/src/hints.h
index 6ea5c0723..c4759775d 100644
--- a/src/hints.h
+++ b/src/hints.h
@@ -185,6 +185,7 @@ extern Atom net_workarea;
 /* KDE extension */
 extern Atom kde_net_wm_context_help;
 extern Atom kde_net_wm_system_tray_window_for;
+extern Atom kwm_win_icon;
 
 /* Systray similation for older KDE apps */
 extern Atom net_system_tray_manager;
@@ -223,6 +224,9 @@ Window getClientLeader (Display *, Window);
 gboolean getNetWMUserTime (Display *, Window, Time *);
 gboolean getClientID (Display *, Window, char **);
 gboolean getWindowCommand (Display *, Window, char ***, int *);
+gboolean getKDEIcon (Display *, Window, Pixmap *, Pixmap *);
+gboolean getRGBIconData (Display *, Window, unsigned long **, unsigned long *);
+
 #ifdef HAVE_LIBSTARTUP_NOTIFICATION
 gboolean getWindowStartupId (Display *, Window, char **);
 #endif
diff --git a/src/mypixmap.c b/src/mypixmap.c
index aa711d095..555d7d75f 100644
--- a/src/mypixmap.c
+++ b/src/mypixmap.c
@@ -42,6 +42,7 @@ myPixmapCompose (MyPixmap * pm, gchar * dir, gchar * file)
     GdkPixbuf *alpha;
     GdkPixbuf *src;
     GdkPixmap *destw;
+    GdkColormap *cmap;
     GError *error = NULL;
 
     filepng = g_strdup_printf ("%s.%s", file, "png");
@@ -66,20 +67,58 @@ myPixmapCompose (MyPixmap * pm, gchar * dir, gchar * file)
         g_object_unref (alpha);
         return FALSE;
     }
-    destw = gdk_pixmap_foreign_new (pm->pixmap);
+    destw = gdk_xid_table_lookup (pm->pixmap);
+    if (destw)
+    {
+        g_object_ref (G_OBJECT (destw));
+    }
+    else
+    {
+         destw = gdk_pixmap_foreign_new (pm->pixmap);
+    }
+    
     if (!destw)
     {
         DBG ("Cannot get pixmap");
         g_object_unref (alpha);
         return FALSE;
     }
-    
-    src = gdk_pixbuf_get_from_drawable(NULL, GDK_DRAWABLE (destw), gdk_screen_get_rgb_colormap (md->gscr), 
+
+    cmap = gdk_drawable_get_colormap (destw);
+    if (cmap)
+    {
+        g_object_ref (G_OBJECT (cmap));
+    }
+    if (cmap == NULL)
+    {
+        if (gdk_drawable_get_depth (destw) == 1)
+        {
+            cmap = NULL;
+        }
+        else
+        {
+            cmap = gdk_screen_get_rgb_colormap (md->gscr);
+            g_object_ref (G_OBJECT (cmap));
+        }
+    }
+
+    if (cmap && (gdk_colormap_get_visual (cmap)->depth != gdk_drawable_get_depth (destw)))
+    {
+        g_object_unref (G_OBJECT (cmap));
+        cmap = NULL;
+    }
+
+    src = gdk_pixbuf_get_from_drawable(NULL, GDK_DRAWABLE (destw), cmap, 
                                         0, 0, 0, 0, pm->width, pm->height);
     gdk_pixbuf_composite (alpha, src, 0, 0, pm->width, pm->height,
                           0, 0, 1.0, 1.0, GDK_INTERP_NEAREST, 255);
     gdk_draw_pixbuf (GDK_DRAWABLE (destw), NULL, src, 0, 0, 0, 0,
                      pm->width, pm->height, GDK_RGB_DITHER_NONE, 0, 0);                 
+
+    if (cmap)
+    {
+        g_object_unref (G_OBJECT (cmap));
+    }
     g_object_unref (alpha);
     g_object_unref (src);
     g_object_unref (destw);
-- 
GitLab