Attached is an updated patch that works with amd64. I just changed the xpm icon buffer to an array of unsigned long (instead of CARD32). I'm sure that is not the correct approach, but it seems to work just fine.

--
Scott Barker       sc...@mostlylinux.ca
Linux Consultant   http://www.mostlylinux.ca/scott
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/changelog wmctrl-1.07.mine/debian/changelog
--- wmctrl-1.07/debian/changelog        2008-02-10 11:19:54.000000000 -0700
+++ wmctrl-1.07.mine/debian/changelog   2008-02-10 11:17:49.000000000 -0700
@@ -1,3 +1,9 @@
+wmctrl (1.07-6local1) unstable; urgency=low
+
+  * Add ability to change application icons.
+
+ -- Scott Barker <sc...@mostlylinux.ca>  Sun, 10 Feb 2008 11:17:26 -0700
+
 wmctrl (1.07-6) unstable; urgency=low
 
   * Reverted CARD32 patch, which was broken on amd64; use fix from Chris
diff -urbBw wmctrl-1.07/debian/control wmctrl-1.07.mine/debian/control
--- wmctrl-1.07/debian/control  2008-02-10 11:19:54.000000000 -0700
+++ wmctrl-1.07.mine/debian/control     2008-02-10 11:19:42.000000000 -0700
@@ -2,7 +2,7 @@
 Section: x11
 Priority: optional
 Maintainer: Decklin Foster <deck...@red-bean.com>
-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:19:54.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 @@
     
 }/*}}}*/
 
+void window_set_mini_icon (Display *disp, Window win, /* {{{ */
+        char *path, char mode) {
+    XpmImage xpmImage;
+    XpmInfo xpmInfo;
+    Colormap colormap;
+    CARD32 *xpmColors;
+    XColor xc;
+    char *c;
+    unsigned long *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 = (unsigned long *)g_malloc0( iconBufferSize * sizeof( unsigned 
long ) );
+
+    iconBuffer[0] = (unsigned long)xpmImage.width;
+    iconBuffer[1] = (unsigned long)xpmImage.height;
+    for (i = 0; i < xpmImage.width * xpmImage.height; i++) {
+      iconBuffer[i+2] = (unsigned long)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