Changed: #1034 Use Xcursor extension if available

This commit is contained in:
kervala 2010-11-18 21:53:05 +01:00
parent d43562fd80
commit 44621ee859
3 changed files with 151 additions and 90 deletions

View file

@ -53,6 +53,11 @@ IF(UNIX AND NOT APPLE)
ADD_DEFINITIONS(-DHAVE_XRENDER) ADD_DEFINITIONS(-DHAVE_XRENDER)
TARGET_LINK_LIBRARIES(${NLDRV_OGL_LIB} ${X11_Xrender_LIB}) TARGET_LINK_LIBRARIES(${NLDRV_OGL_LIB} ${X11_Xrender_LIB})
ENDIF(X11_Xrender_FOUND) ENDIF(X11_Xrender_FOUND)
IF(X11_Xcursor_FOUND)
INCLUDE_DIRECTORIES(${X11_Xcursor_INCLUDE_PATH})
ADD_DEFINITIONS(-DHAVE_XCURSOR)
TARGET_LINK_LIBRARIES(${NLDRV_OGL_LIB} ${X11_Xcursor_LIB})
ENDIF(X11_Xcursor_FOUND)
ENDIF(UNIX AND NOT APPLE) ENDIF(UNIX AND NOT APPLE)
IF(NOT APPLE AND WITH_PCH) IF(NOT APPLE AND WITH_PCH)

View file

@ -27,6 +27,9 @@
# ifdef HAVE_XRENDER # ifdef HAVE_XRENDER
# include <X11/extensions/Xrender.h> # include <X11/extensions/Xrender.h>
# endif // HAVE_XRENDER # endif // HAVE_XRENDER
# ifdef HAVE_XCURSOR
# include <X11/Xcursor/Xcursor.h>
# endif // HAVE_XCURSOR
#endif // NL_OS_UNIX #endif // NL_OS_UNIX
#include "nel/misc/mouse_device.h" #include "nel/misc/mouse_device.h"
@ -118,7 +121,17 @@ bool CDriverGL::isAlphaBlendedCursorSupported()
} }
#elif defined(NL_OS_MAC) #elif defined(NL_OS_MAC)
#elif defined(NL_OS_UNIX) #elif defined(NL_OS_UNIX)
_AlphaBlendedCursorSupported = _xrender_version > 0;
_AlphaBlendedCursorSupported = false;
#ifdef HAVE_XCURSOR
if (!_AlphaBlendedCursorSupported && XcursorSupportsARGB(_dpy))
_AlphaBlendedCursorSupported = true;
#endif // HAVE_XCURSOR
if (!_AlphaBlendedCursorSupported && _xrender_version > 0)
_AlphaBlendedCursorSupported = true;
#endif #endif
_AlphaBlendedCursorSupportRetrieved = true; _AlphaBlendedCursorSupportRetrieved = true;
@ -807,8 +820,12 @@ bool CDriverGL::getBestCursorSize(uint srcWidth, uint srcHeight, uint &dstWidth,
#elif defined(NL_OS_MAC) #elif defined(NL_OS_MAC)
#elif defined(NL_OS_UNIX) #elif defined(NL_OS_UNIX)
Status res = XQueryBestCursor(_dpy, _win, srcWidth, srcHeight, &dstWidth, &dstHeight); Status status = XQueryBestCursor(_dpy, _win, srcWidth, srcHeight, &dstWidth, &dstHeight);
nlwarning("XQueryBestCursor returned %d", (sint)res);
if (!status)
{
nlwarning("XQueryBestCursor failed");
}
#endif #endif
@ -821,7 +838,7 @@ bool CDriverGL::convertBitmapToCursor(const NLMISC::CBitmap &bitmap, nlCursor &c
return convertBitmapToIcon(bitmap, cursor, iconWidth, iconHeight, iconDepth, col, hotSpotX, hotSpotY, true); return convertBitmapToIcon(bitmap, cursor, iconWidth, iconHeight, iconDepth, col, hotSpotX, hotSpotY, true);
#elif defined(NL_OS_UNIX) && defined(HAVE_XRENDER) && !defined(NL_OS_MAC) #elif defined(NL_OS_UNIX) && !defined(NL_OS_MAC)
CBitmap src = bitmap; CBitmap src = bitmap;
@ -858,13 +875,41 @@ bool CDriverGL::convertBitmapToCursor(const NLMISC::CBitmap &bitmap, nlCursor &c
} }
while (srcColorPtr != srcColorPtrLast); while (srcColorPtr != srcColorPtrLast);
#ifdef HAVE_XCURSOR
if (XcursorSupportsARGB(_dpy))
{
XcursorImage *image = XcursorImageCreate(iconWidth, iconHeight);
if (!image)
{
nlwarning("Failed to create a XcusorImage with size %ux%u", iconWidth, iconHeight);
}
else
{
image->xhot = (uint)hotSpotX;
image->yhot = (uint)hotSpotY;
memcpy(image->pixels, &colorBm.getPixels(0)[0], colorBm.getSize()*4);
cursor = XcursorImageLoadCursor(_dpy, image);
XcursorImageDestroy(image);
}
}
#endif // HAVE_XCURSOR
#ifdef HAVE_XRENDER
if (_xrender_version > 0)
{
// use malloc() because X will free() data itself // use malloc() because X will free() data itself
CRGBA *src32 = (CRGBA*)malloc(colorBm.getSize()*4); CRGBA *src32 = (CRGBA*)malloc(colorBm.getSize()*4);
memcpy(src32, &colorBm.getPixels(0)[0], colorBm.getSize()*4); memcpy(src32, &colorBm.getPixels(0)[0], colorBm.getSize()*4);
uint size = iconWidth * iconHeight; uint size = iconWidth * iconHeight;
// Create the icon pixmap
sint screen = DefaultScreen(_dpy); sint screen = DefaultScreen(_dpy);
Visual *visual = DefaultVisual(_dpy, screen); Visual *visual = DefaultVisual(_dpy, screen);
@ -874,7 +919,7 @@ bool CDriverGL::convertBitmapToCursor(const NLMISC::CBitmap &bitmap, nlCursor &c
return false; return false;
} }
// create the icon pixmap // Create the icon image
XImage* image = XCreateImage(_dpy, visual, 32, ZPixmap, 0, (char*)src32, iconWidth, iconHeight, 32, 0); XImage* image = XCreateImage(_dpy, visual, 32, ZPixmap, 0, (char*)src32, iconWidth, iconHeight, 32, 0);
if (!image) if (!image)
@ -883,6 +928,7 @@ bool CDriverGL::convertBitmapToCursor(const NLMISC::CBitmap &bitmap, nlCursor &c
return false; return false;
} }
// Create the icon pixmap
Pixmap pixmap = XCreatePixmap(_dpy, _win, iconWidth, iconHeight, 32 /* defDepth */); Pixmap pixmap = XCreatePixmap(_dpy, _win, iconWidth, iconHeight, 32 /* defDepth */);
if (!pixmap) if (!pixmap)
@ -891,6 +937,7 @@ bool CDriverGL::convertBitmapToCursor(const NLMISC::CBitmap &bitmap, nlCursor &c
return false; return false;
} }
// Create the icon graphic contest
GC gc = XCreateGC(_dpy, pixmap, 0, NULL); GC gc = XCreateGC(_dpy, pixmap, 0, NULL);
if (!gc) if (!gc)
@ -900,12 +947,16 @@ bool CDriverGL::convertBitmapToCursor(const NLMISC::CBitmap &bitmap, nlCursor &c
} }
sint res = XPutImage(_dpy, pixmap, gc, image, 0, 0, 0, 0, iconWidth, iconHeight); sint res = XPutImage(_dpy, pixmap, gc, image, 0, 0, 0, 0, iconWidth, iconHeight);
// should return 0
nlwarning("XPutImage returned %d", res);
res = XFreeGC(_dpy, gc); if (res)
// should return 1 {
nlwarning("XFreeGC returned %d", res); nlwarning("XPutImage failed with code %d", res);
}
if (!XFreeGC(_dpy, gc))
{
nlwarning("XFreeGC failed");
}
if (image->data) if (image->data)
{ {
@ -940,11 +991,16 @@ bool CDriverGL::convertBitmapToCursor(const NLMISC::CBitmap &bitmap, nlCursor &c
} }
XRenderFreePicture(_dpy, picture); XRenderFreePicture(_dpy, picture);
res = XFreePixmap(_dpy, pixmap);
// should return 1 if (!XFreePixmap(_dpy, pixmap))
nlwarning("XFreePixmap returned %d", res); {
nlwarning("XFreePixmap failed");
}
return true; return true;
}
#endif // HAVE_XRENDER
#else #else

View file

@ -351,14 +351,14 @@ bool CDriverGL::init (uint windowIcon, emptyProc exitFunc)
_xrender_version = 0; _xrender_version = 0;
#ifdef HAVE_XRENDER #ifdef HAVE_XRENDER
sint render_major, render_event, render_error; sint xrender_major, xrender_event, xrender_error;
if (XQueryExtension(_dpy, "RENDER", &render_major, &render_event, &render_error) && if (XQueryExtension(_dpy, "RENDER", &xrender_major, &xrender_event, &xrender_error) &&
XRenderQueryExtension(_dpy, &render_event, &render_error)) XRenderQueryExtension(_dpy, &xrender_event, &xrender_error))
{ {
sint render_minor = 0; sint xrender_minor = 0;
XRenderQueryVersion(_dpy, &render_major, &render_minor); XRenderQueryVersion(_dpy, &xrender_major, &xrender_minor);
_xrender_version = render_major * 100 + render_minor; _xrender_version = xrender_major * 100 + xrender_minor;
nlinfo("3D: XRender %d.%d found", render_major, render_minor); nlinfo("3D: XRender %d.%d found", xrender_major, xrender_minor);
} }
#endif // HAVE_XRENDER #endif // HAVE_XRENDER