Commit 2c709c59 authored by Andrew Riedi's avatar Andrew Riedi Committed by Alexandre Julliard

winex11.drv: Add legacy 32-bit cursor support.

parent 735df246
...@@ -560,9 +560,11 @@ static Cursor create_xcursor_cursor( Display *display, CURSORICONINFO *ptr ) ...@@ -560,9 +560,11 @@ static Cursor create_xcursor_cursor( Display *display, CURSORICONINFO *ptr )
*/ */
static Cursor create_cursor( Display *display, CURSORICONINFO *ptr ) static Cursor create_cursor( Display *display, CURSORICONINFO *ptr )
{ {
Pixmap pixmapBits, pixmapMask, pixmapMaskInv, pixmapAll; Pixmap pixmapBits, pixmapMask, pixmapMaskInv = 0, pixmapAll;
XColor fg, bg; XColor fg, bg;
Cursor cursor = None; Cursor cursor = None;
POINT hotspot;
char *bitMask32 = NULL;
#ifdef HAVE_X11_XCURSOR_XCURSOR_H #ifdef HAVE_X11_XCURSOR_XCURSOR_H
if (pXcursorImageLoadCursor) return create_xcursor_cursor( display, ptr ); if (pXcursorImageLoadCursor) return create_xcursor_cursor( display, ptr );
...@@ -589,6 +591,7 @@ static Cursor create_cursor( Display *display, CURSORICONINFO *ptr ) ...@@ -589,6 +591,7 @@ static Cursor create_cursor( Display *display, CURSORICONINFO *ptr )
TRACE("Bitmap %dx%d planes=%d bpp=%d bytesperline=%d\n", TRACE("Bitmap %dx%d planes=%d bpp=%d bytesperline=%d\n",
ptr->nWidth, ptr->nHeight, ptr->bPlanes, ptr->bBitsPerPixel, ptr->nWidth, ptr->nHeight, ptr->bPlanes, ptr->bBitsPerPixel,
ptr->nWidthBytes); ptr->nWidthBytes);
/* Create a pixmap and transfer all the bits to it */ /* Create a pixmap and transfer all the bits to it */
/* NOTE: Following hack works, but only because XFree depth /* NOTE: Following hack works, but only because XFree depth
...@@ -635,6 +638,10 @@ static Cursor create_cursor( Display *display, CURSORICONINFO *ptr ) ...@@ -635,6 +638,10 @@ static Cursor create_cursor( Display *display, CURSORICONINFO *ptr )
switch (ptr->bBitsPerPixel) switch (ptr->bBitsPerPixel)
{ {
case 32:
bitMask32 = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
ptr->nWidth * ptr->nHeight / 8 );
/* Fallthrough */
case 24: case 24:
rbits = 8; rbits = 8;
gbits = 8; gbits = 8;
...@@ -683,6 +690,20 @@ static Cursor create_cursor( Display *display, CURSORICONINFO *ptr ) ...@@ -683,6 +690,20 @@ static Cursor create_cursor( Display *display, CURSORICONINFO *ptr )
red = green = blue = 0; red = green = blue = 0;
switch (ptr->bBitsPerPixel) switch (ptr->bBitsPerPixel)
{ {
case 32:
theChar = theImage[byteIndex++];
blue = theChar;
theChar = theImage[byteIndex++];
green = theChar;
theChar = theImage[byteIndex++];
red = theChar;
theChar = theImage[byteIndex++];
/* If the alpha channel is >5% transparent,
* assume that we can add it to the bitMask32.
*/
if (theChar > 0x0D)
*(bitMask32 + (y*xmax+x)/8) |= 1 << (x & 7);
break;
case 24: case 24:
theChar = theImage[byteIndex++]; theChar = theImage[byteIndex++];
blue = theChar; blue = theChar;
...@@ -767,21 +788,20 @@ static Cursor create_cursor( Display *display, CURSORICONINFO *ptr ) ...@@ -767,21 +788,20 @@ static Cursor create_cursor( Display *display, CURSORICONINFO *ptr )
/* Now create the 2 pixmaps for bits and mask */ /* Now create the 2 pixmaps for bits and mask */
pixmapBits = XCreatePixmap( display, root_window, ptr->nWidth, ptr->nHeight, 1 ); pixmapBits = XCreatePixmap( display, root_window, ptr->nWidth, ptr->nHeight, 1 );
pixmapMask = XCreatePixmap( display, root_window, ptr->nWidth, ptr->nHeight, 1 ); if (ptr->bBitsPerPixel != 32)
{
pixmapMaskInv = XCreatePixmap( display, root_window, ptr->nWidth, ptr->nHeight, 1 ); pixmapMaskInv = XCreatePixmap( display, root_window, ptr->nWidth, ptr->nHeight, 1 );
pixmapMask = XCreatePixmap( display, root_window, ptr->nWidth, ptr->nHeight, 1 );
/* Make sure everything went OK so far */ /* Make sure everything went OK so far */
if (pixmapBits && pixmapMask && pixmapMaskInv) if (pixmapBits && pixmapMask && pixmapMaskInv)
{ {
POINT hotspot;
/* We have to do some magic here, as cursors are not fully /* We have to do some magic here, as cursors are not fully
* compatible between Windows and X11. Under X11, there * compatible between Windows and X11. Under X11, there are
* are only 3 possible color cursor: black, white and * only 3 possible color cursor: black, white and masked. So
* masked. So we map the 4th Windows color (invert the * we map the 4th Windows color (invert the bits on the screen)
* bits on the screen) to black and an additional white bit on * to black and an additional white bit on an other place
* an other place (+1,+1). This require some boolean arithmetic: * (+1,+1). This require some boolean arithmetic:
* *
* Windows | X11 * Windows | X11
* And Xor Result | Bits Mask Result * And Xor Result | Bits Mask Result
...@@ -795,8 +815,8 @@ static Cursor create_cursor( Display *display, CURSORICONINFO *ptr ) ...@@ -795,8 +815,8 @@ static Cursor create_cursor( Display *display, CURSORICONINFO *ptr )
* Mask = not 'And' or 'Xor' or 'And2' and 'Xor2' * Mask = not 'And' or 'Xor' or 'And2' and 'Xor2'
* *
* FIXME: apparently some servers do support 'inverted' color. * FIXME: apparently some servers do support 'inverted' color.
* I don't know if it's correct per the X spec, but maybe * I don't know if it's correct per the X spec, but maybe we
* we ought to take advantage of it. -- AJ * ought to take advantage of it. -- AJ
*/ */
XSetFunction( display, gc, GXcopy ); XSetFunction( display, gc, GXcopy );
XCopyArea( display, pixmapAll, pixmapBits, gc, XCopyArea( display, pixmapAll, pixmapBits, gc,
...@@ -821,6 +841,15 @@ static Cursor create_cursor( Display *display, CURSORICONINFO *ptr ) ...@@ -821,6 +841,15 @@ static Cursor create_cursor( Display *display, CURSORICONINFO *ptr )
XCopyArea( display, pixmapMaskInv, pixmapBits, gc, XCopyArea( display, pixmapMaskInv, pixmapBits, gc,
0, 0, ptr->nWidth, ptr->nHeight, 1, 1 ); 0, 0, ptr->nWidth, ptr->nHeight, 1, 1 );
XSetFunction( display, gc, GXcopy ); XSetFunction( display, gc, GXcopy );
}
}
else
{
pixmapMask = XCreateBitmapFromData( display, root_window,
bitMask32, ptr->nWidth,
ptr->nHeight );
HeapFree( GetProcessHeap(), 0, bitMask32 );
}
/* Make sure hotspot is valid */ /* Make sure hotspot is valid */
hotspot.x = ptr->ptHotSpot.x; hotspot.x = ptr->ptHotSpot.x;
...@@ -831,9 +860,10 @@ static Cursor create_cursor( Display *display, CURSORICONINFO *ptr ) ...@@ -831,9 +860,10 @@ static Cursor create_cursor( Display *display, CURSORICONINFO *ptr )
hotspot.x = ptr->nWidth / 2; hotspot.x = ptr->nWidth / 2;
hotspot.y = ptr->nHeight / 2; hotspot.y = ptr->nHeight / 2;
} }
if (pixmapBits && pixmapMask)
cursor = XCreatePixmapCursor( display, pixmapBits, pixmapMask, cursor = XCreatePixmapCursor( display, pixmapBits, pixmapMask,
&fg, &bg, hotspot.x, hotspot.y ); &fg, &bg, hotspot.x, hotspot.y );
}
/* Now free everything */ /* Now free everything */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment