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