I looked the code bit more. Then I thought I hate if and removed some of
them. Now I think code is cleaner but it has minor performance hit when
cursor don't have alpha. But create_cursor won't be called every frame.
? dlls/winex11.drv/.mouse.c.swp
Index: dlls/winex11.drv/mouse.c
===================================================================
RCS file: /home/wine/wine/dlls/winex11.drv/mouse.c,v
retrieving revision 1.1
diff -u -p -t -r1.1 mouse.c
--- dlls/winex11.drv/mouse.c 16 Jun 2006 13:19:17 -0000 1.1
+++ dlls/winex11.drv/mouse.c 25 Jun 2006 08:27:41 -0000
@@ -422,16 +422,18 @@ static Cursor create_cursor( Display *di
}
else
{
- int rbits, gbits, bbits, red, green, blue;
+ int rbits, gbits, bbits,abits, red, green, blue, alpha;
int rfg, gfg, bfg, rbg, gbg, bbg;
int rscale, gscale, bscale;
int x, y, xmax, ymax, bitIndex, byteIndex, xorIndex;
unsigned char *theMask, *theImage, theChar;
int threshold, fgBits, bgBits, bitShifted;
- BYTE pXorBits[128]; /* Up to 32x32 icons */
+ BYTE pXorBits[128], pAndBits[128]; /* Up to 32x32 icons; could use same array but ... */
switch (ptr->bBitsPerPixel)
{
+ case 32:
+ abits = 8;
case 24:
rbits = 8;
gbits = 8;
@@ -473,13 +475,18 @@ static Cursor create_cursor( Display *di
ymax = (ptr->nHeight > 32) ? 32 : ptr->nHeight;
memset(pXorBits, 0, 128);
+
+ memset(pAndBits, 0, 128);
+
for (y=0; y<ymax; y++)
{
for (x=0; x<xmax; x++)
{
red = green = blue = 0;
+ alpha = 255; // This is vissible?
switch (ptr->bBitsPerPixel)
{
+ case 32:
case 24:
theChar = theImage[byteIndex++];
blue = theChar;
@@ -487,6 +494,11 @@ static Cursor create_cursor( Display *di
green = theChar;
theChar = theImage[byteIndex++];
red = theChar;
+ if (ptr->bBitsPerPixel == 32)
+ {
+ theChar = theImage[byteIndex++];
+ alpha = theChar;
+ }
break;
case 16:
theChar = theImage[byteIndex++];
@@ -498,8 +510,19 @@ static Cursor create_cursor( Display *di
break;
}
- if (red+green+blue > threshold)
+
+ //bg or fg?
+ // If there is alpha for fg color then we should calculate avarange
+ // alpha and use that to create transperancy for cursor (at least my gnome
+ // has transperancy with xorg 7)
+ if (alpha < threshold>>3)
+ {
+ // Transperant
+ pAndBits[xorIndex] |= bitShifted;
+ }
+ else if (red+green+blue > threshold)
{
+ // Foreground
rfg += red;
gfg += green;
bfg += blue;
@@ -508,10 +531,19 @@ static Cursor create_cursor( Display *di
}
else
{
+ // Background
rbg += red;
gbg += green;
bbg += blue;
}
+ // What is going on?
+/* TRACE("Cursor file pixel, red=%d green=%d blue=%d alpha=%d Xor=%d And=%d\n",
+ red,
+ green,
+ blue,
+ alpha,
+ pXorBits[xorIndex]&bitShifted,
+ pAndBits[xorIndex]&bitShifted);*/
if (x%8 == 7)
{
bitShifted = 0x01;
@@ -539,8 +571,12 @@ static Cursor create_cursor( Display *di
bg.blue = bbg * bscale / bgBits;
}
else bg.red = bg.green = bg.blue = 0;
- pixmapBits = XCreateBitmapFromData( display, root_window, (char *)pXorBits, xmax, ymax );
- if (!pixmapBits)
+
+ pixmapBits = XCreateBitmapFromData( display, root_window, (char *)pXorBits, xmax, ymax );
+ pixmapMask = XCreateBitmapFromData( display, root_window, (char *)pAndBits, xmax, ymax );
+
+ if (!pixmapBits
+ && !pixmapMask)
{
XFreePixmap( display, pixmapAll );
XFreeGC( display, gc );
@@ -556,6 +592,15 @@ static Cursor create_cursor( Display *di
/* Put the image */
XCopyArea( display, pixmapBits, pixmapAll, gc,
0, 0, xmax, ymax, 0, ptr->nHeight );
+
+ if (ptr->bBitsPerPixel == 32)
+ {
+ // Keep original transperancy if not rgba cursor
+ XCopyArea( display, pixmapMask, pixmapAll, gc,
+ 0, 0, xmax, ymax, 0, 0);
+ }
+
+ XFreePixmap( display, pixmapMask );
XFreePixmap( display, pixmapBits );
}
image->data = NULL;