This is the mail archive of the cygwin-xfree@cygwin.com mailing list for the Cygwin XFree86 project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

RE: Custom icons per window class/name patch


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]