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;


Reply via email to