winex11.drv: Add Xcursor support for 32 bit cursors.
Based on patch by Henri Verbeet.
This commit is contained in:
parent
7b289821b1
commit
23e2cb1f59
|
@ -7672,9 +7672,11 @@ then
|
|||
|
||||
|
||||
|
||||
|
||||
for ac_header in X11/Xlib.h \
|
||||
X11/XKBlib.h \
|
||||
X11/Xutil.h \
|
||||
X11/Xcursor/Xcursor.h \
|
||||
X11/extensions/shape.h \
|
||||
X11/extensions/XInput.h \
|
||||
X11/extensions/XShm.h \
|
||||
|
@ -14722,6 +14724,82 @@ cat >>confdefs.h <<_ACEOF
|
|||
#define SONAME_LIBXRANDR "$ac_cv_lib_soname_Xrandr"
|
||||
_ACEOF
|
||||
|
||||
fi
|
||||
|
||||
{ echo "$as_me:$LINENO: checking for -lXcursor soname" >&5
|
||||
echo $ECHO_N "checking for -lXcursor soname... $ECHO_C" >&6; }
|
||||
if test "${ac_cv_lib_soname_Xcursor+set}" = set; then
|
||||
echo $ECHO_N "(cached) $ECHO_C" >&6
|
||||
else
|
||||
ac_get_soname_save_LIBS=$LIBS
|
||||
LIBS="-lXcursor $X_LIBS -lX11 $X_EXTRA_LIBS $LIBS"
|
||||
cat >conftest.$ac_ext <<_ACEOF
|
||||
/* confdefs.h. */
|
||||
_ACEOF
|
||||
cat confdefs.h >>conftest.$ac_ext
|
||||
cat >>conftest.$ac_ext <<_ACEOF
|
||||
/* end confdefs.h. */
|
||||
|
||||
/* Override any GCC internal prototype to avoid an error.
|
||||
Use char because int might match the return type of a GCC
|
||||
builtin and then its argument prototype would still apply. */
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
#endif
|
||||
char XcursorImageLoadCursor ();
|
||||
int
|
||||
main ()
|
||||
{
|
||||
return XcursorImageLoadCursor ();
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
rm -f conftest.$ac_objext conftest$ac_exeext
|
||||
if { (ac_try="$ac_link"
|
||||
case "(($ac_try" in
|
||||
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
|
||||
*) ac_try_echo=$ac_try;;
|
||||
esac
|
||||
eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
|
||||
(eval "$ac_link") 2>conftest.er1
|
||||
ac_status=$?
|
||||
grep -v '^ *+' conftest.er1 >conftest.err
|
||||
rm -f conftest.er1
|
||||
cat conftest.err >&5
|
||||
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||
(exit $ac_status); } && {
|
||||
test -z "$ac_c_werror_flag" ||
|
||||
test ! -s conftest.err
|
||||
} && test -s conftest$ac_exeext &&
|
||||
$as_test_x conftest$ac_exeext; then
|
||||
case "$LIBEXT" in
|
||||
dylib) ac_cv_lib_soname_Xcursor=`otool -L conftest$ac_exeext | grep libXcursor\\.[0-9A-Za-z.]*dylib | sed -e "s/^.*\/\(libXcursor\.[0-9A-Za-z.]*dylib\).*$/\1/"';2,$d'` ;;
|
||||
so) ac_cv_lib_soname_Xcursor=`$ac_cv_path_LDD conftest$ac_exeext | grep libXcursor\\.so | sed -e "s/^.*\(libXcursor\.so[^ ]*\).*$/\1/"';2,$d'` ;;
|
||||
esac
|
||||
if test "x$ac_cv_lib_soname_Xcursor" = "x"
|
||||
then
|
||||
ac_cv_lib_soname_Xcursor="libXcursor.$LIBEXT"
|
||||
fi
|
||||
else
|
||||
echo "$as_me: failed program was:" >&5
|
||||
sed 's/^/| /' conftest.$ac_ext >&5
|
||||
|
||||
ac_cv_lib_soname_Xcursor="libXcursor.$LIBEXT"
|
||||
fi
|
||||
|
||||
rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
|
||||
conftest$ac_exeext conftest.$ac_ext
|
||||
LIBS=$ac_get_soname_save_LIBS
|
||||
fi
|
||||
{ echo "$as_me:$LINENO: result: $ac_cv_lib_soname_Xcursor" >&5
|
||||
echo "${ECHO_T}$ac_cv_lib_soname_Xcursor" >&6; }
|
||||
if test "${ac_cv_lib_soname_Xcursor+set}" = set; then
|
||||
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define SONAME_LIBXCURSOR "$ac_cv_lib_soname_Xcursor"
|
||||
_ACEOF
|
||||
|
||||
fi
|
||||
|
||||
{ echo "$as_me:$LINENO: checking for -lfreetype soname" >&5
|
||||
|
|
|
@ -335,6 +335,7 @@ then
|
|||
AC_CHECK_HEADERS([X11/Xlib.h \
|
||||
X11/XKBlib.h \
|
||||
X11/Xutil.h \
|
||||
X11/Xcursor/Xcursor.h \
|
||||
X11/extensions/shape.h \
|
||||
X11/extensions/XInput.h \
|
||||
X11/extensions/XShm.h \
|
||||
|
@ -1151,6 +1152,7 @@ then
|
|||
WINE_GET_SONAME(Xinerama,XineramaQueryScreens,[$X_LIBS -lXext -lX11 $X_EXTRA_LIBS])
|
||||
WINE_GET_SONAME(Xrender,XRenderQueryExtension,[$X_LIBS -lXext -lX11 $X_EXTRA_LIBS])
|
||||
WINE_GET_SONAME(Xrandr,XRRQueryExtension,[$X_LIBS -lXext -lX11 $X_EXTRA_LIBS])
|
||||
WINE_GET_SONAME(Xcursor,XcursorImageLoadCursor,[$X_LIBS -lX11 $X_EXTRA_LIBS])
|
||||
WINE_GET_SONAME(freetype,FT_Init_FreeType,[$X_LIBS])
|
||||
WINE_GET_SONAME(GL,glXQueryExtension,[$X_LIBS $X_EXTRA_LIBS])
|
||||
WINE_GET_SONAME(hal,libhal_ctx_new)
|
||||
|
|
|
@ -89,6 +89,9 @@ static void device_init(void)
|
|||
/* Initialize XRender */
|
||||
X11DRV_XRender_Init();
|
||||
|
||||
/* Init Xcursor */
|
||||
X11DRV_Xcursor_Init();
|
||||
|
||||
palette_size = X11DRV_PALETTE_Init();
|
||||
|
||||
X11DRV_BITMAP_Init();
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
* X11 mouse driver
|
||||
*
|
||||
* Copyright 1998 Ulrich Weigand
|
||||
* Copyright 2007 Henri Verbeet
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
@ -19,10 +20,24 @@
|
|||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "wine/port.h"
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#ifdef HAVE_X11_XCURSOR_XCURSOR_H
|
||||
# include <X11/Xcursor/Xcursor.h>
|
||||
# ifndef SONAME_LIBXCURSOR
|
||||
# define SONAME_LIBXCURSOR "libXcursor.so"
|
||||
# endif
|
||||
static void *xcursor_handle;
|
||||
# define MAKE_FUNCPTR(f) static typeof(f) * p##f
|
||||
MAKE_FUNCPTR(XcursorImageCreate);
|
||||
MAKE_FUNCPTR(XcursorImageDestroy);
|
||||
MAKE_FUNCPTR(XcursorImageLoadCursor);
|
||||
# undef MAKE_FUNCPTR
|
||||
#endif /* HAVE_X11_XCURSOR_XCURSOR_H */
|
||||
|
||||
#define NONAMELESSUNION
|
||||
#define NONAMELESSSTRUCT
|
||||
#include "windef.h"
|
||||
|
@ -32,6 +47,7 @@
|
|||
#include "win.h"
|
||||
#include "x11drv.h"
|
||||
#include "wine/server.h"
|
||||
#include "wine/library.h"
|
||||
#include "wine/debug.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(cursor);
|
||||
|
@ -75,6 +91,32 @@ static RECT cursor_clip; /* Cursor clipping rect */
|
|||
|
||||
BOOL X11DRV_SetCursorPos( INT x, INT y );
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* X11DRV_Xcursor_Init
|
||||
*
|
||||
* Load the Xcursor library for use.
|
||||
*/
|
||||
void X11DRV_Xcursor_Init(void)
|
||||
{
|
||||
#ifdef HAVE_X11_XCURSOR_XCURSOR_H
|
||||
xcursor_handle = wine_dlopen(SONAME_LIBXCURSOR, RTLD_NOW, NULL, 0);
|
||||
if (!xcursor_handle) /* wine_dlopen failed. */
|
||||
{
|
||||
WARN("Xcursor failed to load. Using fallback code.\n");
|
||||
return;
|
||||
}
|
||||
#define LOAD_FUNCPTR(f) \
|
||||
p##f = wine_dlsym(xcursor_handle, #f, NULL, 0)
|
||||
|
||||
LOAD_FUNCPTR(XcursorImageCreate);
|
||||
LOAD_FUNCPTR(XcursorImageDestroy);
|
||||
LOAD_FUNCPTR(XcursorImageLoadCursor);
|
||||
#undef LOAD_FUNCPTR
|
||||
#endif /* HAVE_X11_XCURSOR_XCURSOR_H */
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* get_coords
|
||||
*
|
||||
|
@ -352,6 +394,165 @@ void X11DRV_send_mouse_input( HWND hwnd, DWORD flags, DWORD x, DWORD y,
|
|||
}
|
||||
|
||||
|
||||
#ifdef HAVE_X11_XCURSOR_XCURSOR_H
|
||||
|
||||
/***********************************************************************
|
||||
* create_cursor_image
|
||||
*
|
||||
* Create an XcursorImage from a CURSORICONINFO
|
||||
*/
|
||||
static XcursorImage *create_cursor_image( CURSORICONINFO *ptr )
|
||||
{
|
||||
int x, xmax;
|
||||
int y, ymax;
|
||||
int and_size, xor_size;
|
||||
unsigned char *and_bits, *and_ptr, *xor_bits, *xor_ptr;
|
||||
int and_width_bytes, xor_width_bytes;
|
||||
XcursorPixel *pixel_ptr;
|
||||
XcursorImage *image;
|
||||
|
||||
ymax = (ptr->nHeight > 32) ? 32 : ptr->nHeight;
|
||||
xmax = (ptr->nWidth > 32) ? 32 : ptr->nWidth;
|
||||
|
||||
and_width_bytes = xmax / 8;
|
||||
xor_width_bytes = and_width_bytes * ptr->bBitsPerPixel;
|
||||
|
||||
and_size = ptr->nWidth * ptr->nHeight / 8;
|
||||
and_ptr = and_bits = (unsigned char *)(ptr + 1);
|
||||
|
||||
xor_size = xor_width_bytes * ptr->nHeight;
|
||||
xor_ptr = xor_bits = and_ptr + and_size;
|
||||
|
||||
image = pXcursorImageCreate( xmax, ymax );
|
||||
pixel_ptr = image->pixels;
|
||||
|
||||
/* On windows, to calculate the color for a pixel, first an AND is done
|
||||
* with the background and the "and" bitmap, then an XOR with the "xor"
|
||||
* bitmap. This means that when the data in the "and" bitmap is 0, the
|
||||
* pixel will get the color as specified in the "xor" bitmap.
|
||||
* However, if the data in the "and" bitmap is 1, the result will be the
|
||||
* background XOR'ed with the value in the "xor" bitmap. In case the "xor"
|
||||
* data is completely black (0x000000) the pixel will become transparent,
|
||||
* in case it's white (0xffffff) the pixel will become the inverse of the
|
||||
* background color.
|
||||
*
|
||||
* Since we can't support inverting colors, we map the grayscale value of
|
||||
* the "xor" data to the alpha channel, and xor the the color with either
|
||||
* black or white.
|
||||
*/
|
||||
for (y = 0; y < ymax; ++y)
|
||||
{
|
||||
and_ptr = and_bits + (y * and_width_bytes);
|
||||
xor_ptr = xor_bits + (y * xor_width_bytes);
|
||||
|
||||
for (x = 0; x < xmax; ++x)
|
||||
{
|
||||
/* Xcursor pixel data is in ARGB format, with A in the high byte */
|
||||
switch (ptr->bBitsPerPixel)
|
||||
{
|
||||
case 32:
|
||||
/* BGRA, 8 bits each */
|
||||
*pixel_ptr = *xor_ptr++;
|
||||
*pixel_ptr |= *xor_ptr++ << 8;
|
||||
*pixel_ptr |= *xor_ptr++ << 16;
|
||||
*pixel_ptr |= *xor_ptr++ << 24;
|
||||
break;
|
||||
|
||||
case 24:
|
||||
/* BGR, 8 bits each */
|
||||
*pixel_ptr = *xor_ptr++;
|
||||
*pixel_ptr |= *xor_ptr++ << 8;
|
||||
*pixel_ptr |= *xor_ptr++ << 16;
|
||||
break;
|
||||
|
||||
case 16:
|
||||
/* BGR, 5 red, 6 green, 5 blue */
|
||||
*pixel_ptr = *xor_ptr * 0x1f;
|
||||
*pixel_ptr |= (*xor_ptr & 0xe0) << 3;
|
||||
++xor_ptr;
|
||||
*pixel_ptr |= (*xor_ptr & 0x07) << 11;
|
||||
*pixel_ptr |= (*xor_ptr & 0xf8) << 13;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
if (*xor_ptr & (1 << (7 - (x & 7)))) *pixel_ptr = 0xffffff;
|
||||
else *pixel_ptr = 0;
|
||||
if ((x & 7) == 7) ++xor_ptr;
|
||||
break;
|
||||
|
||||
default:
|
||||
FIXME("Currently no support for cursors with %d bits per pixel\n", ptr->bBitsPerPixel);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ptr->bBitsPerPixel != 32)
|
||||
{
|
||||
/* Alpha channel */
|
||||
if (~*and_ptr & (1 << (7 - (x & 7)))) *pixel_ptr |= 0xff << 24;
|
||||
else if (*pixel_ptr)
|
||||
{
|
||||
int alpha = (*pixel_ptr & 0xff) * 0.30f
|
||||
+ ((*pixel_ptr & 0xff00) >> 8) * 0.55f
|
||||
+ ((*pixel_ptr & 0xff0000) >> 16) * 0.15f;
|
||||
*pixel_ptr ^= ((x + y) % 2) ? 0xffffff : 0x000000;
|
||||
*pixel_ptr |= alpha << 24;
|
||||
}
|
||||
if ((x & 7) == 7) ++and_ptr;
|
||||
}
|
||||
++pixel_ptr;
|
||||
}
|
||||
}
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* create_xcursor_cursor
|
||||
*
|
||||
* Use Xcursor to create an X cursor from a Windows one.
|
||||
*/
|
||||
static Cursor create_xcursor_cursor( Display *display, CURSORICONINFO *ptr )
|
||||
{
|
||||
Cursor cursor;
|
||||
XcursorImage *image;
|
||||
|
||||
if (!ptr) /* Create an empty cursor */
|
||||
{
|
||||
image = pXcursorImageCreate( 1, 1 );
|
||||
image->xhot = 0;
|
||||
image->yhot = 0;
|
||||
*(image->pixels) = 0;
|
||||
cursor = pXcursorImageLoadCursor( display, image );
|
||||
pXcursorImageDestroy( image );
|
||||
|
||||
return cursor;
|
||||
}
|
||||
|
||||
image = create_cursor_image( ptr );
|
||||
if (!image) return 0;
|
||||
|
||||
/* Make sure hotspot is valid */
|
||||
image->xhot = ptr->ptHotSpot.x;
|
||||
image->yhot = ptr->ptHotSpot.y;
|
||||
if (image->xhot < 0 || image->xhot >= image->width ||
|
||||
image->yhot < 0 || image->yhot >= image->height)
|
||||
{
|
||||
image->xhot = image->width / 2;
|
||||
image->yhot = image->height / 2;
|
||||
}
|
||||
|
||||
image->delay = 0;
|
||||
|
||||
cursor = pXcursorImageLoadCursor( display, image );
|
||||
pXcursorImageDestroy( image );
|
||||
|
||||
return cursor;
|
||||
}
|
||||
|
||||
#endif /* HAVE_X11_XCURSOR_XCURSOR_H */
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* create_cursor
|
||||
*
|
||||
|
@ -363,6 +564,10 @@ static Cursor create_cursor( Display *display, CURSORICONINFO *ptr )
|
|||
XColor fg, bg;
|
||||
Cursor cursor = None;
|
||||
|
||||
#ifdef HAVE_X11_XCURSOR_XCURSOR_H
|
||||
if (pXcursorImageLoadCursor) return create_xcursor_cursor( display, ptr );
|
||||
#endif
|
||||
|
||||
if (!ptr) /* Create an empty cursor */
|
||||
{
|
||||
static const char data[] = { 0 };
|
||||
|
|
|
@ -228,6 +228,7 @@ extern BOOL X11DRV_SwapBuffers(X11DRV_PDEVICE *physDev);
|
|||
|
||||
/* X11 driver internal functions */
|
||||
|
||||
extern void X11DRV_Xcursor_Init(void);
|
||||
extern void X11DRV_BITMAP_Init(void);
|
||||
extern void X11DRV_FONT_Init( int log_pixels_x, int log_pixels_y );
|
||||
|
||||
|
|
|
@ -924,6 +924,9 @@
|
|||
/* Define to 1 if you have the <X11/extensions/XShm.h> header file. */
|
||||
#undef HAVE_X11_EXTENSIONS_XSHM_H
|
||||
|
||||
/* Define to 1 if you have the <X11/Xcursor/Xcursor.h> header file. */
|
||||
#undef HAVE_X11_XCURSOR_XCURSOR_H
|
||||
|
||||
/* Define to 1 if you have the <X11/XKBlib.h> header file. */
|
||||
#undef HAVE_X11_XKBLIB_H
|
||||
|
||||
|
@ -1029,6 +1032,9 @@
|
|||
/* Define to the soname of the libX11 library. */
|
||||
#undef SONAME_LIBX11
|
||||
|
||||
/* Define to the soname of the libXcursor library. */
|
||||
#undef SONAME_LIBXCURSOR
|
||||
|
||||
/* Define to the soname of the libXext library. */
|
||||
#undef SONAME_LIBXEXT
|
||||
|
||||
|
|
Loading…
Reference in New Issue