Custom icons per window class/name patch

Earle F. Philhower III earle@ziplabel.com
Sat May 24 21:15:00 GMT 2003


Try the following replacement X->Windoze function.  I'm not sure of the
color mapping, but Mozilla, ethereal, gftp, and others come up more or less
OK!

/* Scale an X icon bitmap into a Windoze icon bitmap */
static void
winScaleXBitmapToWindows( int iconSize, int effBPP, PixmapPtr pixmap, 
unsigned char *image)
{
   int row, column, effXBPP;
   unsigned char *outPtr;
   unsigned char *iconData = 0;
   int stride, xStride;
   float factX, factY;
   int posX, posY;
   unsigned char *ptr;
   unsigned int zero;
   unsigned int color;

   if (pixmap->drawable.bitsPerPixel==15)
     effXBPP = 16;
   else
     effXBPP = pixmap->drawable.bitsPerPixel;

   stride = ((iconSize * effBPP + 31)&(~31))/8; /* Need 32-bit aligned rows */
   xStride  = ((pixmap->drawable.width * effXBPP + 31)&(~31))/8;

   iconData = malloc( xStride * pixmap->drawable.height );
   miGetImage((DrawablePtr)&(pixmap->drawable), 0, 0,
              pixmap->drawable.width, pixmap->drawable.height,
              ZPixmap, 0xffff, iconData);

   /* Keep aspect ratio */
   factX = ((float)pixmap->drawable.width)/((float)iconSize);
   factY = ((float)pixmap->drawable.height)/((float)iconSize);
   if (factX>factY) factY = factX;
   else factX = factY;

   /* Out-of-bounds, fill icon with zero */
   zero = 0;
   ErrorF("%d bpp %d x %d!\n", 
effXBPP,pixmap->drawable.width,pixmap->drawable.height );

   for (row=0; row<iconSize; row++) {
     outPtr = image+stride*row;
     for (column=0; column<iconSize; column++) {
       posX = factX * column;
       posY = factY * row;

       ptr = iconData + posY*xStride;
       if ( effXBPP == 1 ) {
         ptr += posX/8;

         /* Out of X icon bounds, leave space blank */
         if (posX>=pixmap->drawable.width || posY>=pixmap->drawable.height)
           ptr = &zero;

         if ((*ptr) & (1<<(posX&7)))
           switch (effBPP) {
           case 32: *(outPtr++) = 0;
           case 24: *(outPtr++) = 0;
           case 16: *(outPtr++) = 0;
           case 8:  *(outPtr++) = 0;
             break;
           case 1:
             outPtr[column/8] &= ~(1<<(7-(column&7)));
             break;
           }
         else
           switch (effBPP) {
           case 32: *(outPtr++) = 255;
           case 24: *(outPtr++) = 255;
           case 16: *(outPtr++) = 255;
           case 8:  *(outPtr++) = 255;
             break;
           case 1:
             outPtr[column/8] |= (1<<(7-(column&7)));
             break;
           }
       } else if (effXBPP == 24 || effXBPP == 32) {
         ptr += posX*((effXBPP==32)?4:3);
         /* Out of X icon bounds, leave space blank */
         if (posX>=pixmap->drawable.width || posY>=pixmap->drawable.height)
           ptr = &zero;
         color = ((*ptr)<<16)+((*(ptr+1))<<8)+((*(ptr+2))<<0);
         switch (effBPP) {
         case 32:
           *(outPtr++) = *(ptr++);
           *(outPtr++) = *(ptr++);
           *(outPtr++) = *(ptr++);
           *(outPtr++) = 0;
           break;
         case 24:
           *(outPtr++) = *(ptr++);
           *(outPtr++) = *(ptr++);
           *(outPtr++) = *(ptr++);
           break;
         case 16:
           color = (((*ptr)>>2)<<10) + (((*(ptr+1))>>2)<<5) + 
(((*(ptr+2))>>2));
           *(outPtr++) = (color>>8);
           *(outPtr++) = (color&255);
           break;
         case 8:
           color = (((*ptr))) + (((*(ptr+1)))) + (((*(ptr+2))));
           color /= 3;
           *(outPtr) = color;
           break;
         case 1:
           if (color)
             outPtr[column/8] |= (1<<(7-(column&7)));
           else
             outPtr[column/8] &= ~(1<<(7-(column&7)));
         }


       } else if ( effXBPP == 16 ) {
         ptr += posX*2;

         /* Out of X icon bounds, leave space blank */
         if (posX>=pixmap->drawable.width || posY>=pixmap->drawable.height)
           ptr = &zero;
         color = ((*ptr)<<8)+(*(ptr+1));
         switch (effBPP) {
         case 32:
           *(outPtr++) = (color & 31) << 2;
           *(outPtr++) = ((color>>5) & 31) << 2;
           *(outPtr++) = ((color>>10) & 31) << 2;
           *(outPtr++) = 0;
           break;
         case 24:
           *(outPtr++) = (color & 31) << 2;
           *(outPtr++) = ((color>>5) & 31) << 2;
           *(outPtr++) = ((color>>10) & 31) << 2;
           break;
         case 16:
           *(outPtr++) = *(ptr++);
           *(outPtr++) = *(ptr++);
           break;
         case 8:
           *(outPtr++) = (( (color & 31) + ((color>>5) & 31) + ((color>>10) 
& 31))/3) << 2;
           break;
         case 1:
           if (color)
             outPtr[column/8] |= (1<<(7-(column&7)));
           else
             outPtr[column/8] &= ~(1<<(7-(column&7)));
           break;
         } /* end switch(effbpp) */
       } /* end if effxbpp==16) */
     } /* end for column */
   } /* end for row */
   free(iconData);
}

At 09:31 PM 5/24/2003 +0100, you wrote:
>Hi
>
>Ralf's hack stops the crash.
>xeyes, xclock etc have good icons.
>ethereal mozilla etc have 'scrambled icons' (for want of a better word!).
>
>However, the normal XFree applications do now look pretty impressive!
>
>Great stuff.
>
>Colin

-Earle F. Philhower, III
  earle@ziplabel.com
  cdrlabel - ZipLabel - FlpLabel
  http://www.cdrlabel.com



More information about the Cygwin-xfree mailing list