From d214f6ff3b4fe6c7fd5f9a52db7ec2241ef04e78 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Fri, 11 Mar 2011 13:56:53 -0800 Subject: [PATCH] Added support for the Xcursor library for color cursors --- configure | 210 ++++++++++++++++++++++++++++++----- configure.in | 31 +++++- include/SDL_config.h.in | 2 + src/video/x11/SDL_x11dyn.c | 4 + src/video/x11/SDL_x11dyn.h | 3 + src/video/x11/SDL_x11mouse.c | 46 +++++++- src/video/x11/SDL_x11sym.h | 8 ++ src/video/x11/SDL_x11video.h | 3 + 8 files changed, 276 insertions(+), 31 deletions(-) diff --git a/configure b/configure index 66afcc567..49dadde90 100755 --- a/configure +++ b/configure @@ -1537,6 +1537,8 @@ Optional Features: --enable-dummyaudio support the dummy audio driver [default=yes] --enable-video-x11 use X11 video driver [default=yes] --enable-x11-shared dynamically load X11 support [default=maybe] + --enable-video-x11-xcursor + enable X11 Xcursor support [default=yes] --enable-video-x11-xinerama enable X11 Xinerama support [default=yes] --enable-video-x11-xinput @@ -3769,13 +3771,13 @@ if test "${lt_cv_nm_interface+set}" = set; then else lt_cv_nm_interface="BSD nm" echo "int some_variable = 0;" > conftest.$ac_ext - (eval echo "\"\$as_me:3772: $ac_compile\"" >&5) + (eval echo "\"\$as_me:3774: $ac_compile\"" >&5) (eval "$ac_compile" 2>conftest.err) cat conftest.err >&5 - (eval echo "\"\$as_me:3775: $NM \\\"conftest.$ac_objext\\\"\"" >&5) + (eval echo "\"\$as_me:3777: $NM \\\"conftest.$ac_objext\\\"\"" >&5) (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) cat conftest.err >&5 - (eval echo "\"\$as_me:3778: output\"" >&5) + (eval echo "\"\$as_me:3780: output\"" >&5) cat conftest.out >&5 if $GREP 'External.*some_variable' conftest.out > /dev/null; then lt_cv_nm_interface="MS dumpbin" @@ -5002,7 +5004,7 @@ ia64-*-hpux*) ;; *-*-irix6*) # Find out which ABI we are using. - echo '#line 5005 "configure"' > conftest.$ac_ext + echo '#line 5007 "configure"' > conftest.$ac_ext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? @@ -6118,7 +6120,7 @@ if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | else ac_cv_header_stdc=no fi -rm -f -r conftest* +rm -f conftest* fi @@ -6139,7 +6141,7 @@ if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | else ac_cv_header_stdc=no fi -rm -f -r conftest* +rm -f conftest* fi @@ -7163,11 +7165,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:7166: $lt_compile\"" >&5) + (eval echo "\"\$as_me:7168: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:7170: \$? = $ac_status" >&5 + echo "$as_me:7172: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -7502,11 +7504,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:7505: $lt_compile\"" >&5) + (eval echo "\"\$as_me:7507: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:7509: \$? = $ac_status" >&5 + echo "$as_me:7511: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -7607,11 +7609,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:7610: $lt_compile\"" >&5) + (eval echo "\"\$as_me:7612: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:7614: \$? = $ac_status" >&5 + echo "$as_me:7616: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -7662,11 +7664,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:7665: $lt_compile\"" >&5) + (eval echo "\"\$as_me:7667: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:7669: \$? = $ac_status" >&5 + echo "$as_me:7671: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -10420,7 +10422,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 10423 "configure" +#line 10425 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -10516,7 +10518,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 10519 "configure" +#line 10521 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -14198,11 +14200,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:14201: $lt_compile\"" >&5) + (eval echo "\"\$as_me:14203: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:14205: \$? = $ac_status" >&5 + echo "$as_me:14207: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -14297,11 +14299,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:14300: $lt_compile\"" >&5) + (eval echo "\"\$as_me:14302: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:14304: \$? = $ac_status" >&5 + echo "$as_me:14306: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -14349,11 +14351,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:14352: $lt_compile\"" >&5) + (eval echo "\"\$as_me:14354: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:14356: \$? = $ac_status" >&5 + echo "$as_me:14358: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -15962,7 +15964,7 @@ if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | else ac_cv_header_stdc=no fi -rm -f -r conftest* +rm -f conftest* fi @@ -15983,7 +15985,7 @@ if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | else ac_cv_header_stdc=no fi -rm -f -r conftest* +rm -f conftest* fi @@ -16374,7 +16376,7 @@ if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | else ac_cv_define_M_PI=no fi -rm -f -r conftest* +rm -f conftest* fi @@ -16571,7 +16573,7 @@ if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | else ac_cv_os_cray=no fi -rm -f -r conftest* +rm -f conftest* fi { echo "$as_me:$LINENO: result: $ac_cv_os_cray" >&5 @@ -22639,7 +22641,7 @@ _ACEOF eval "ac_im_$ac_var=\`\${MAKE-make} $ac_var 2>/dev/null | sed -n 's/^$ac_var=//p'\`" done # Open Windows xmkmf reportedly sets LIBDIR instead of USRLIBDIR. - for ac_extension in a so sl dylib la dll; do + for ac_extension in a so sl; do if test ! -f "$ac_im_usrlibdir/libX11.$ac_extension" && test -f "$ac_im_libdir/libX11.$ac_extension"; then ac_im_usrlibdir=$ac_im_libdir; break @@ -22792,7 +22794,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 for ac_dir in `echo "$ac_x_includes $ac_x_header_dirs" | sed s/include/lib/g` do # Don't even attempt the hair of trying to link an X program! - for ac_extension in a so sl dylib la dll; do + for ac_extension in a so sl; do if test -r "$ac_dir/libX11.$ac_extension"; then ac_x_libraries=$ac_dir break 2 @@ -23928,10 +23930,11 @@ fi case "$host" in - *-*-darwin*) # Latest Mac OS X actually ships with Xrandr/Xrender libs... + *-*-darwin*) x11_symbols_private=yes x11_lib='/usr/X11R6/lib/libX11.6.dylib' x11ext_lib='/usr/X11R6/lib/libXext.6.dylib' + xcursor_lib='/usr/X11R6/lib/libXcursor.1.dylib' xinerama_lib='/usr/X11R6/lib/libXinerama.1.dylib' xinput_lib='/usr/X11R6/lib/libXi.6.dylib' xrandr_lib='/usr/X11R6/lib/libXrandr.2.dylib' @@ -23942,6 +23945,7 @@ fi *) x11_lib=`find_lib "libX11.so.*" "$X_LIBS -L/usr/X11/$base_libdir -L/usr/X11R6/$base_libdir" | sed 's/.*\/\(.*\)/\1/; q'` x11ext_lib=`find_lib "libXext.so.*" "$X_LIBS -L/usr/X11/$base_libdir -L/usr/X11R6/$base_libdir" | sed 's/.*\/\(.*\)/\1/; q'` + xcursor_lib=`find_lib "libXcursor.so.*" "$X_LIBS -L/usr/X11/$base_libdir -L/usr/X11R6/$base_libdir" | sed 's/.*\/\(.*\)/\1/; q'` xinerama_lib=`find_lib "libXinerama.so.*" "$X_LIBS -L/usr/X11/$base_libdir -L/usr/X11R6/$base_libdir" | sed 's/.*\/\(.*\)/\1/; q'` xinput_lib=`find_lib "libXi.so.*" "$X_LIBS -L/usr/X11/$base_libdir -L/usr/X11R6/$base_libdir" | sed 's/.*\/\(.*\)/\1/; q'` xrandr_lib=`find_lib "libXrandr.so.*" "$X_LIBS -L/usr/X11/$base_libdir -L/usr/X11R6/$base_libdir" | sed 's/.*\/\(.*\)/\1/; q'` @@ -23998,6 +24002,154 @@ _ACEOF fi have_video=yes + # Check whether --enable-video-x11-xcursor was given. +if test "${enable_video_x11_xcursor+set}" = set; then + enableval=$enable_video_x11_xcursor; +else + enable_video_x11_xcursor=yes +fi + + if test x$enable_video_x11_xcursor = xyes; then + definitely_enable_video_x11_xcursor=no + { echo "$as_me:$LINENO: checking for X11/Xcursor/Xcursor.h" >&5 +echo $ECHO_N "checking for X11/Xcursor/Xcursor.h... $ECHO_C" >&6; } +if test "${ac_cv_header_X11_Xcursor_Xcursor_h+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include + + +#include +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +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_compile") 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_objext; then + ac_cv_header_X11_Xcursor_Xcursor_h=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_header_X11_Xcursor_Xcursor_h=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_header_X11_Xcursor_Xcursor_h" >&5 +echo "${ECHO_T}$ac_cv_header_X11_Xcursor_Xcursor_h" >&6; } +if test $ac_cv_header_X11_Xcursor_Xcursor_h = yes; then + have_xcursor_h_hdr=yes +else + have_xcursor_h_hdr=no +fi + + + if test x$have_xcursor_h_hdr = xyes; then + if test x$enable_x11_shared = xyes && test x$xcursor_lib != x ; then + echo "-- dynamic libXcursor -> $xcursor_lib" + cat >>confdefs.h <<_ACEOF +#define SDL_VIDEO_DRIVER_X11_DYNAMIC_XCURSOR "$xcursor_lib" +_ACEOF + + definitely_enable_video_x11_xcursor=yes + else + { echo "$as_me:$LINENO: checking for XcursorImageCreate in -lXcursor" >&5 +echo $ECHO_N "checking for XcursorImageCreate in -lXcursor... $ECHO_C" >&6; } +if test "${ac_cv_lib_Xcursor_XcursorImageCreate+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lXcursor $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 XcursorImageCreate (); +int +main () +{ +return XcursorImageCreate (); + ; + 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 + ac_cv_lib_Xcursor_XcursorImageCreate=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_Xcursor_XcursorImageCreate=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ echo "$as_me:$LINENO: result: $ac_cv_lib_Xcursor_XcursorImageCreate" >&5 +echo "${ECHO_T}$ac_cv_lib_Xcursor_XcursorImageCreate" >&6; } +if test $ac_cv_lib_Xcursor_XcursorImageCreate = yes; then + have_xcursor_lib=yes +fi + + if test x$have_xcursor_lib = xyes ; then + EXTRA_LDFLAGS="$EXTRA_LDFLAGS -lXcursor" + definitely_enable_video_x11_xcursor=yes + fi + fi + fi + fi + if test x$definitely_enable_video_x11_xcursor = xyes; then + cat >>confdefs.h <<\_ACEOF +#define SDL_VIDEO_DRIVER_X11_XCURSOR 1 +_ACEOF + + fi # Check whether --enable-video-x11-xinerama was given. if test "${enable_video_x11_xinerama+set}" = set; then enableval=$enable_video_x11_xinerama; diff --git a/configure.in b/configure.in index 1ebd4b56e..4fddcd30f 100644 --- a/configure.in +++ b/configure.in @@ -1023,10 +1023,11 @@ AC_HELP_STRING([--enable-x11-shared], [dynamically load X11 support [[default=ma , enable_x11_shared=maybe) case "$host" in - *-*-darwin*) # Latest Mac OS X actually ships with Xrandr/Xrender libs... + *-*-darwin*) x11_symbols_private=yes x11_lib='/usr/X11R6/lib/libX11.6.dylib' x11ext_lib='/usr/X11R6/lib/libXext.6.dylib' + xcursor_lib='/usr/X11R6/lib/libXcursor.1.dylib' xinerama_lib='/usr/X11R6/lib/libXinerama.1.dylib' xinput_lib='/usr/X11R6/lib/libXi.6.dylib' xrandr_lib='/usr/X11R6/lib/libXrandr.2.dylib' @@ -1037,6 +1038,7 @@ AC_HELP_STRING([--enable-x11-shared], [dynamically load X11 support [[default=ma *) x11_lib=[`find_lib "libX11.so.*" "$X_LIBS -L/usr/X11/$base_libdir -L/usr/X11R6/$base_libdir" | sed 's/.*\/\(.*\)/\1/; q'`] x11ext_lib=[`find_lib "libXext.so.*" "$X_LIBS -L/usr/X11/$base_libdir -L/usr/X11R6/$base_libdir" | sed 's/.*\/\(.*\)/\1/; q'`] + xcursor_lib=[`find_lib "libXcursor.so.*" "$X_LIBS -L/usr/X11/$base_libdir -L/usr/X11R6/$base_libdir" | sed 's/.*\/\(.*\)/\1/; q'`] xinerama_lib=[`find_lib "libXinerama.so.*" "$X_LIBS -L/usr/X11/$base_libdir -L/usr/X11R6/$base_libdir" | sed 's/.*\/\(.*\)/\1/; q'`] xinput_lib=[`find_lib "libXi.so.*" "$X_LIBS -L/usr/X11/$base_libdir -L/usr/X11R6/$base_libdir" | sed 's/.*\/\(.*\)/\1/; q'`] xrandr_lib=[`find_lib "libXrandr.so.*" "$X_LIBS -L/usr/X11/$base_libdir -L/usr/X11R6/$base_libdir" | sed 's/.*\/\(.*\)/\1/; q'`] @@ -1082,6 +1084,33 @@ AC_HELP_STRING([--enable-x11-shared], [dynamically load X11 support [[default=ma fi have_video=yes + AC_ARG_ENABLE(video-x11-xcursor, +AC_HELP_STRING([--enable-video-x11-xcursor], [enable X11 Xcursor support [[default=yes]]]), + , enable_video_x11_xcursor=yes) + if test x$enable_video_x11_xcursor = xyes; then + definitely_enable_video_x11_xcursor=no + AC_CHECK_HEADER(X11/Xcursor/Xcursor.h, + have_xcursor_h_hdr=yes, + have_xcursor_h_hdr=no, + [#include + ]) + if test x$have_xcursor_h_hdr = xyes; then + if test x$enable_x11_shared = xyes && test x$xcursor_lib != x ; then + echo "-- dynamic libXcursor -> $xcursor_lib" + AC_DEFINE_UNQUOTED(SDL_VIDEO_DRIVER_X11_DYNAMIC_XCURSOR, "$xcursor_lib") + definitely_enable_video_x11_xcursor=yes + else + AC_CHECK_LIB(Xcursor, XcursorImageCreate, have_xcursor_lib=yes) + if test x$have_xcursor_lib = xyes ; then + EXTRA_LDFLAGS="$EXTRA_LDFLAGS -lXcursor" + definitely_enable_video_x11_xcursor=yes + fi + fi + fi + fi + if test x$definitely_enable_video_x11_xcursor = xyes; then + AC_DEFINE(SDL_VIDEO_DRIVER_X11_XCURSOR) + fi AC_ARG_ENABLE(video-x11-xinerama, AC_HELP_STRING([--enable-video-x11-xinerama], [enable X11 Xinerama support [[default=yes]]]), , enable_video_x11_xinerama=yes) diff --git a/include/SDL_config.h.in b/include/SDL_config.h.in index e5f416bee..1c6f73b95 100644 --- a/include/SDL_config.h.in +++ b/include/SDL_config.h.in @@ -265,11 +265,13 @@ #undef SDL_VIDEO_DRIVER_X11 #undef SDL_VIDEO_DRIVER_X11_DYNAMIC #undef SDL_VIDEO_DRIVER_X11_DYNAMIC_XEXT +#undef SDL_VIDEO_DRIVER_X11_DYNAMIC_XCURSOR #undef SDL_VIDEO_DRIVER_X11_DYNAMIC_XINERAMA #undef SDL_VIDEO_DRIVER_X11_DYNAMIC_XINPUT #undef SDL_VIDEO_DRIVER_X11_DYNAMIC_XRANDR #undef SDL_VIDEO_DRIVER_X11_DYNAMIC_XSS #undef SDL_VIDEO_DRIVER_X11_DYNAMIC_XVIDMODE +#undef SDL_VIDEO_DRIVER_X11_XCURSOR #undef SDL_VIDEO_DRIVER_X11_XINERAMA #undef SDL_VIDEO_DRIVER_X11_XINPUT #undef SDL_VIDEO_DRIVER_X11_XRANDR diff --git a/src/video/x11/SDL_x11dyn.c b/src/video/x11/SDL_x11dyn.c index 66239b449..96072dad0 100644 --- a/src/video/x11/SDL_x11dyn.c +++ b/src/video/x11/SDL_x11dyn.c @@ -46,6 +46,9 @@ typedef struct #ifndef SDL_VIDEO_DRIVER_X11_DYNAMIC_XEXT #define SDL_VIDEO_DRIVER_X11_DYNAMIC_XEXT NULL #endif +#ifndef SDL_VIDEO_DRIVER_X11_DYNAMIC_XCURSOR +#define SDL_VIDEO_DRIVER_X11_DYNAMIC_XCURSOR NULL +#endif #ifndef SDL_VIDEO_DRIVER_X11_DYNAMIC_XINERAMA #define SDL_VIDEO_DRIVER_X11_DYNAMIC_XINERAMA NULL #endif @@ -65,6 +68,7 @@ typedef struct static x11dynlib x11libs[] = { {NULL, SDL_VIDEO_DRIVER_X11_DYNAMIC}, {NULL, SDL_VIDEO_DRIVER_X11_DYNAMIC_XEXT}, + {NULL, SDL_VIDEO_DRIVER_X11_DYNAMIC_XCURSOR}, {NULL, SDL_VIDEO_DRIVER_X11_DYNAMIC_XINERAMA}, {NULL, SDL_VIDEO_DRIVER_X11_DYNAMIC_XINPUT}, {NULL, SDL_VIDEO_DRIVER_X11_DYNAMIC_XRANDR}, diff --git a/src/video/x11/SDL_x11dyn.h b/src/video/x11/SDL_x11dyn.h index 38adf538f..7a2bef164 100644 --- a/src/video/x11/SDL_x11dyn.h +++ b/src/video/x11/SDL_x11dyn.h @@ -44,6 +44,9 @@ #include #endif +#if SDL_VIDEO_DRIVER_X11_XCURSOR +#include +#endif #if SDL_VIDEO_DRIVER_X11_XINERAMA #include #endif diff --git a/src/video/x11/SDL_x11mouse.c b/src/video/x11/SDL_x11mouse.c index eed2b9363..448de7ac5 100644 --- a/src/video/x11/SDL_x11mouse.c +++ b/src/video/x11/SDL_x11mouse.c @@ -20,6 +20,8 @@ slouken@libsdl.org */ #include "SDL_config.h" + +#include "SDL_assert.h" #include "SDL_x11video.h" #include "SDL_x11mouse.h" #include "../../events/SDL_mouse_c.h" @@ -81,6 +83,35 @@ X11_CreateDefaultCursor() return cursor; } +#if SDL_VIDEO_DRIVER_X11_XCURSOR +static Cursor +X11_CreateXCursorCursor(SDL_Surface * surface, int hot_x, int hot_y) +{ + Display *display = GetDisplay(); + Cursor cursor = None; + XcursorImage *image; + + image = XcursorImageCreate(surface->w, surface->h); + if (!image) { + SDL_OutOfMemory(); + return None; + } + image->xhot = hot_x; + image->yhot = hot_y; + image->delay = 0; + + SDL_assert(surface->format->format == SDL_PIXELFORMAT_ARGB8888); + SDL_assert(surface->pitch == surface->w * 4); + SDL_memcpy(image->pixels, surface->pixels, surface->h * surface->pitch); + + cursor = XcursorImageLoadCursor(display, image); + + XcursorImageDestroy(image); + + return cursor; +} +#endif /* SDL_VIDEO_DRIVER_X11_XCURSOR */ + static Cursor X11_CreatePixmapCursor(SDL_Surface * surface, int hot_x, int hot_y) { @@ -101,6 +132,9 @@ X11_CreatePixmapCursor(SDL_Surface * surface, int hot_x, int hot_y) return None; } + /* Code below assumes ARGB pixel format */ + SDL_assert(surface->format->format == SDL_PIXELFORMAT_ARGB8888); + rfg = gfg = bfg = rbg = gbg = bbg = fgBits = 0; for (y = 0; y < surface->h; ++y) { ptr = (Uint32 *)((Uint8 *)surface->pixels + y * surface->pitch); @@ -162,7 +196,17 @@ X11_CreateCursor(SDL_Surface * surface, int hot_x, int hot_y) cursor = SDL_calloc(1, sizeof(*cursor)); if (cursor) { - cursor->driverdata = (void*)X11_CreatePixmapCursor(surface, hot_x, hot_y); + Cursor x11_cursor = None; + +#if SDL_VIDEO_DRIVER_X11_XCURSOR + if (SDL_X11_HAVE_XCURSOR) { + x11_cursor = X11_CreateXCursorCursor(surface, hot_x, hot_y); + } +#endif + if (x11_cursor == None) { + x11_cursor = X11_CreatePixmapCursor(surface, hot_x, hot_y); + } + cursor->driverdata = (void*)x11_cursor; } else { SDL_OutOfMemory(); } diff --git a/src/video/x11/SDL_x11sym.h b/src/video/x11/SDL_x11sym.h index 54a070bc2..fef7589db 100644 --- a/src/video/x11/SDL_x11sym.h +++ b/src/video/x11/SDL_x11sym.h @@ -175,6 +175,14 @@ SDL_X11_SYM(int,ipAllocateData,(ChannelPtr a,IPCard b,IPDataPtr * c),(a,b,c),ret SDL_X11_SYM(int,ipUnallocateAndSendData,(ChannelPtr a,IPCard b),(a,b),return) #endif +/* XCursor support */ +#if SDL_VIDEO_DRIVER_X11_XCURSOR +SDL_X11_MODULE(XCURSOR) +SDL_X11_SYM(XcursorImage*,XcursorImageCreate,(int a,int b),(a,b),) +SDL_X11_SYM(void,XcursorImageDestroy,(XcursorImage *a),(a),) +SDL_X11_SYM(Cursor,XcursorImageLoadCursor,(Display *a,const XcursorImage *b),(a,b),) +#endif + /* Xinerama support */ #if SDL_VIDEO_DRIVER_X11_XINERAMA SDL_X11_MODULE(XINERAMA) diff --git a/src/video/x11/SDL_x11video.h b/src/video/x11/SDL_x11video.h index 86a9199c5..02f5ec8c1 100644 --- a/src/video/x11/SDL_x11video.h +++ b/src/video/x11/SDL_x11video.h @@ -32,6 +32,9 @@ #include #include +#if SDL_VIDEO_DRIVER_X11_XCURSOR +#include +#endif #if SDL_VIDEO_DRIVER_X11_XINERAMA #include #endif