Custom icons per window class/name patch

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


Howdy!  Thanks to the use Harold's linux box I was able to get the
colors correct for all the apps I've tried under 16 and 32 bit color
(mozilla, gftp, ethereal).  For some reasons ethereal and some other
apps register a 16x16 pixmap.  Maybe they do a WM_HINTS to change
it to a bigger one after the window is created, if that's the case the
code does not yet have that hook put it.

Most tests have 24-bpp icons, if someone has a 16-bpp icon it would
be a good thing to test!  And 8bpp display modes are funky, I don't do
colormap lookups or anything like that.  Feel free to fix that if you
still have a video card with 256K of RAM. ;)

---------8<----------------
/* 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, effXDepth;
   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;

   if (pixmap->drawable.depth==15)
     effXDepth = 16;
   else
     effXDepth = pixmap->drawable.depth;

   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, 0xffffffff, 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;

   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 (effXDepth == 24 || effXDepth == 32) {
         ptr += posX*(effXBPP/8);
         /* 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++); // alpha
           *(outPtr++) = *(ptr++); // green
           *(outPtr++) = *(ptr++); // red
           *(outPtr++) = *(ptr++); // blue
           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 ( effXDepth == 16 ) {
         ptr += posX*(effXBPP/8);

         /* 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++) = 0; // alpha
           *(outPtr++) = (color & 31) << 2;
           *(outPtr++) = ((color>>5) & 31) << 2;
           *(outPtr++) = ((color>>10) & 31) << 2;
           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 10:54 PM 5/24/2003 +0100, you wrote:
>Hi
>
>Earle's replacement X->Windoze function is ace, my test results are:-
>
>xterm X icon
>xeyes 'eyes' icon
>xclock 'clock' icon
>ethereal 'their weird e' icon
>Mozilla 'coloured.. maybe wrong, too pixelly to tell!' icon?
>Qt (say hello example) X icon
>Konqueror 'coloured file' icon
>RealPlayer(linux realplay) X icon
>acroread(linux acrobat) 'correct, but low resolution!' icon
>
>
>Running on XP Pro at 1280x1024 Screen, Color quality 16 bit.
>
>That's a pretty impressive piece of code.
>
>Colin

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



More information about the Cygwin-xfree mailing list