Package: wmctrl
Version: 1.07-6
Severity: wishlist
Tags: patch

I needed the ability to change the icon for applications (I use xfce,
which provides no native way of doing this), so I modified wmctrl to
include this capability. The patch is attached to this email if you are
interested. 

-- System Information:
Debian Release: lenny/sid
  APT prefers testing
  APT policy: (500, 'testing'), (500, 'stable')
Architecture: i386 (i686)

Kernel: Linux 2.6.22-3-vserver-686 (SMP w/2 CPU cores)
Locale: LANG=C, LC_CTYPE=en_CA.iso8859-1 (charmap=ISO-8859-1)
Shell: /bin/sh linked to /bin/bash

Versions of packages wmctrl depends on:
ii  libc6                       2.7-6        GNU C Library: Shared libraries
ii  libglib2.0-0                2.14.5-2     The GLib library of C routines
ii  libice6                     2:1.0.4-1    X11 Inter-Client Exchange library
ii  libsm6                      2:1.0.3-1+b1 X11 Session Management library
ii  libx11-6                    2:1.0.3-7    X11 client-side library
ii  libxmu6                     2:1.0.4-1    X11 miscellaneous utility library

wmctrl recommends no packages.

-- no debconf information
diff -urbBw wmctrl-1.07/Makefile.am wmctrl-1.07.mine/Makefile.am
--- wmctrl-1.07/Makefile.am	2005-01-03 11:48:35.000000000 -0700
+++ wmctrl-1.07.mine/Makefile.am	2008-02-10 10:43:28.000000000 -0700
@@ -1,7 +1,7 @@
 
 AM_CFLAGS = -Wall
 AM_CPPFLAGS = @X_CFLAGS@ @GLIB_CFLAGS@
-LDADD = @X_LIBS@ @X_PRE_LIBS@ -lX11 -lXmu @X_EXTRA_LIBS@ @GLIB_LIBS@
+LDADD = @X_LIBS@ @X_PRE_LIBS@ -lX11 -lXmu -lXpm @X_EXTRA_LIBS@ @GLIB_LIBS@
 
 bin_PROGRAMS = wmctrl
 wmctrl_SOURCES = main.c
diff -urbBw wmctrl-1.07/Makefile.in wmctrl-1.07.mine/Makefile.in
--- wmctrl-1.07/Makefile.in	2005-01-28 20:33:05.000000000 -0700
+++ wmctrl-1.07.mine/Makefile.in	2008-02-10 10:43:29.000000000 -0700
@@ -115,7 +115,7 @@
 
 AM_CFLAGS = -Wall
 AM_CPPFLAGS = @X_CFLAGS@ @GLIB_CFLAGS@
-LDADD = @X_LIBS@ @X_PRE_LIBS@ -lX11 -lXmu @X_EXTRA_LIBS@ @GLIB_LIBS@
+LDADD = @X_LIBS@ @X_PRE_LIBS@ -lX11 -lXmu -lXpm @X_EXTRA_LIBS@ @GLIB_LIBS@
 
 bin_PROGRAMS = wmctrl
 wmctrl_SOURCES = main.c
diff -urbBw wmctrl-1.07/debian/control wmctrl-1.07.mine/debian/control
--- wmctrl-1.07/debian/control	2008-02-10 11:09:53.000000000 -0700
+++ wmctrl-1.07.mine/debian/control	2008-02-10 10:54:15.000000000 -0700
@@ -2,7 +2,7 @@
 Section: x11
 Priority: optional
 Maintainer: Decklin Foster <[EMAIL PROTECTED]>
-Build-Depends: debhelper (>= 4.0.0), x11proto-core-dev, libx11-dev, libxmu-dev, libglib2.0-dev (>= 2.4.0)
+Build-Depends: debhelper (>= 4.0.0), x11proto-core-dev, libx11-dev, libxmu-dev, libxpm-dev libglib2.0-dev (>= 2.4.0)
 Standards-Version: 3.6.2
 
 Package: wmctrl
diff -urbBw wmctrl-1.07/main.c wmctrl-1.07.mine/main.c
--- wmctrl-1.07/main.c	2008-02-10 11:09:53.000000000 -0700
+++ wmctrl-1.07.mine/main.c	2008-02-10 11:08:05.000000000 -0700
@@ -34,6 +34,8 @@
 #include <X11/Xatom.h>
 #include <X11/cursorfont.h>
 #include <X11/Xmu/WinUtil.h>
+#include <X11/xpm.h>
+#include <X11/Xmd.h>
 #include <glib.h>
 
 #define _NET_WM_STATE_REMOVE        0    /* remove/unset property */
@@ -64,6 +66,7 @@
 "                       argument and list of possible states is given below.\n" \
 "  -r <WIN> -N <STR>    Set the name (long title) of the window.\n" \
 "  -r <WIN> -I <STR>    Set the icon name (short title) of the window.\n" \
+"  -r <WIN> -M <PATH>   Set the mini-icon of the window to the xpm bitmap in <PATH>.\n" \
 "  -r <WIN> -T <STR>    Set both the name and the icon name of the window.\n" \
 "  -k (on|off)          Activate or deactivate window manager's\n" \
 "                       \"showing the desktop\" mode. Many window managers\n" \
@@ -264,7 +267,7 @@
         }
     }
    
-    while ((opt = getopt(argc, argv, "FGVvhlupidmxa:r:s:c:t:w:k:o:n:g:e:b:N:I:T:R:")) != -1) {
+    while ((opt = getopt(argc, argv, "FGVvhlupidmxa:r:s:c:t:w:k:o:n:g:e:b:N:I:T:R:M:")) != -1) {
         missing_option = 0;
         switch (opt) {
             case 'F':
@@ -296,7 +299,7 @@
             case 'r':
                 options.param_window = optarg;
                 break; 
-            case 't': case 'e': case 'b': case 'N': case 'I': case 'T':
+            case 't': case 'e': case 'b': case 'N': case 'I': case 'T': case 'M':
                 options.param = optarg;
                 action = opt;
                 break;
@@ -356,7 +359,7 @@
             ret = wm_info(disp);
             break;
         case 'a': case 'c': case 'R': 
-        case 't': case 'e': case 'b': case 'N': case 'I': case 'T':
+        case 't': case 'e': case 'b': case 'N': case 'I': case 'T': case 'M':
             if (! options.param_window) {
                 fputs("No window was specified.\n", stderr);
                 return EXIT_FAILURE;
@@ -677,6 +680,64 @@
     
 }/*}}}*/
 
+static int window_set_mini_icon (Display *disp, Window win, /* {{{ */
+        char *path, char mode) {
+    XpmImage xpmImage;
+    XpmInfo xpmInfo;
+    Colormap colormap;
+    CARD32 *xpmColors;
+    XColor xc;
+    char *c;
+    CARD32 *iconBuffer;
+    int iconBufferSize;
+    int i;
+
+    if (XpmReadFileToXpmImage(path, &xpmImage, &xpmInfo) != 0) {
+      fputs("Invalid icon path.\n", stderr);
+      return EXIT_FAILURE;
+    }
+
+    colormap = DefaultColormap(disp, DefaultScreen(disp));
+    xpmColors = (CARD32 *)g_malloc0(xpmImage.ncolors * sizeof(CARD32));
+    for( i = 0; i < xpmImage.ncolors; i++ ) {
+      c = xpmImage.colorTable[i].c_color;
+      if (c == NULL) c = xpmImage.colorTable[i].g_color;
+      // else if (c == NULL) c = xpmImage.colorTable[i].g4_color;
+      // else if (c == NULL) c = xpmImage.colorTable[i].m_color;
+      // else if (c == NULL) c = xpmImage.colorTable[i].symbolic;
+      if (c == NULL) {
+        // Unknown color
+        xpmColors[i] = 0;
+      } else if (strcmp(c, "None") == 0) {
+        // No color - see thru
+        xpmColors[i] = 0;
+      } else if (XParseColor(disp, colormap, c, &xc)) {
+        // Color parsed successfully
+        ((char *)(xpmColors + i))[0] = xc.blue >> 8;
+        ((char *)(xpmColors + i))[1] = xc.green >> 8;
+        ((char *)(xpmColors + i))[2] = xc.red >> 8;
+        ((char *)(xpmColors + i))[3] = 0xff;
+      } else {
+        // Color parsing failed
+        xpmColors[i] = 0;
+      }
+    }
+
+    iconBufferSize = 2 + xpmImage.width * xpmImage.height;
+    iconBuffer = (CARD32 *)g_malloc0( iconBufferSize * sizeof( CARD32 ) );
+
+    iconBuffer[0] = xpmImage.width;
+    iconBuffer[1] = xpmImage.height;
+    for (i = 0; i < xpmImage.width * xpmImage.height; i++) {
+      iconBuffer[i+2] = xpmColors[xpmImage.data[i]];
+    }
+
+    XChangeProperty(disp, win, XInternAtom(disp, "_NET_WM_ICON", False), XInternAtom(disp, "CARDINAL", False), 32, PropModeReplace, (const unsigned char*)iconBuffer, iconBufferSize);
+
+    g_free(xpmColors);
+    g_free(iconBuffer);
+}/*}}}*/
+
 static int window_to_desktop (Display *disp, Window win, int desktop) {/*{{{*/
     unsigned long *cur_desktop = NULL;
     Window root = DefaultRootWindow(disp);
@@ -910,6 +971,10 @@
             window_set_title(disp, win, options.param, mode);
             return EXIT_SUCCESS;
 
+        case 'M':
+            window_set_mini_icon(disp, win, options.param, mode);
+            return EXIT_SUCCESS;
+
         default:
             fprintf(stderr, "Unknown action: '%c'\n", mode);
             return EXIT_FAILURE;
diff -urbBw wmctrl-1.07/wmctrl.1 wmctrl-1.07.mine/wmctrl.1
--- wmctrl-1.07/wmctrl.1	2005-01-03 11:42:52.000000000 -0700
+++ wmctrl-1.07.mine/wmctrl.1	2008-02-10 10:55:42.000000000 -0700
@@ -121,6 +121,13 @@
 .IR name .
 
 .TP
+.BI \-M " path"
+Set the mini-icon of the window specified by a
+.B \-r
+action to the xpm bitmap in
+.IR path .
+
+.TP
 .B \-k " (" on " | " off " )"
 Turn on or off the window manager's "show the desktop" mode (if the
 window manager implements this feature).

Reply via email to