diff --git a/configure b/configure index 27467ec7048..d25d2a63780 100755 --- a/configure +++ b/configure @@ -8265,38 +8265,25 @@ fi if test "$ac_cv_header_X11_extensions_Xrandr_h" = "yes" then - echo "$as_me:$LINENO: checking for XRRSetScreenConfigAndRate in -lXrandr" >&5 -echo $ECHO_N "checking for XRRSetScreenConfigAndRate in -lXrandr... $ECHO_C" >&6 -if test "${ac_cv_lib_Xrandr_XRRSetScreenConfigAndRate+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lXrandr $X_LIBS -lXrender -lXext -lX11 $X_EXTRA_LIBS $LIBS" -cat >conftest.$ac_ext <<_ACEOF + cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ - -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char XRRSetScreenConfigAndRate (); +#include +#include int main () { -XRRSetScreenConfigAndRate (); +static typeof(XRRSetScreenConfigAndRate) * func; ; return 0; } _ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 @@ -8309,35 +8296,23 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' + { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then - ac_cv_lib_Xrandr_XRRSetScreenConfigAndRate=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_lib_Xrandr_XRRSetScreenConfigAndRate=no -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -echo "$as_me:$LINENO: result: $ac_cv_lib_Xrandr_XRRSetScreenConfigAndRate" >&5 -echo "${ECHO_T}$ac_cv_lib_Xrandr_XRRSetScreenConfigAndRate" >&6 -if test $ac_cv_lib_Xrandr_XRRSetScreenConfigAndRate = yes; then cat >>confdefs.h <<\_ACEOF #define HAVE_LIBXRANDR 1 _ACEOF - X_PRE_LIBS="$X_PRE_LIBS -lXrandr -lXrender" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 fi - +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi if test "$ac_cv_header_X11_extensions_Xvlib_h" = "yes" @@ -14907,6 +14882,80 @@ cat >>confdefs.h <<_ACEOF _ACEOF fi +echo "$as_me:$LINENO: checking for -lXrandr soname" >&5 +echo $ECHO_N "checking for -lXrandr soname... $ECHO_C" >&6 +if test "${ac_cv_lib_soname_Xrandr+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_get_soname_save_LIBS=$LIBS +LIBS="-lXrandr $X_LIBS -lXext -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 gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char XRRQueryExtension (); +int +main () +{ +XRRQueryExtension (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&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); } && + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_soname_Xrandr=`$ac_cv_path_LDD conftest$ac_exeext | grep libXrandr\\.so | sed 's/^.*\(libXrandr\.so[^ ]*\).*$/\1/'` + if test "x$ac_cv_lib_soname_Xrandr" = "x" + then + ac_cv_lib_soname_Xrandr="libXrandr.so" + fi +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_soname_Xrandr="libXrandr.so" +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LIBS=$ac_get_soname_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_soname_Xrandr" >&5 +echo "${ECHO_T}$ac_cv_lib_soname_Xrandr" >&6 +if test "x$ac_cv_lib_soname_Xrandr" != xNONE +then +cat >>confdefs.h <<_ACEOF +#define SONAME_LIBXRANDR "$ac_cv_lib_soname_Xrandr" +_ACEOF +fi + echo "$as_me:$LINENO: checking for -lfreetype soname" >&5 echo $ECHO_N "checking for -lfreetype soname... $ECHO_C" >&6 if test "${ac_cv_lib_soname_freetype+set}" = set; then diff --git a/configure.ac b/configure.ac index b461aca0264..5cbdf928005 100644 --- a/configure.ac +++ b/configure.ac @@ -253,11 +253,9 @@ then dnl *** Check for X RandR extension if test "$ac_cv_header_X11_extensions_Xrandr_h" = "yes" then - AC_CHECK_LIB(Xrandr, XRRSetScreenConfigAndRate, - [ AC_DEFINE(HAVE_LIBXRANDR, 1, [Define if you have the Xrandr library]) - X_PRE_LIBS="$X_PRE_LIBS -lXrandr -lXrender" - ],, - $X_LIBS -lXrender -lXext -lX11 $X_EXTRA_LIBS) + AC_TRY_COMPILE([#include +#include ],[static typeof(XRRSetScreenConfigAndRate) * func;], + [AC_DEFINE(HAVE_LIBXRANDR, 1, [Define if you have the Xrandr library])]) fi dnl *** Check for XVideo extension supporting XvImages @@ -999,6 +997,7 @@ then WINE_GET_SONAME(Xext,XextCreateExtension,[$X_LIBS -lX11 $X_EXTRA_LIBS]) WINE_GET_SONAME(Xi,XOpenDevice,[$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(freetype,FT_Init_FreeType,[$X_LIBS]) WINE_GET_SONAME(GL,glXQueryExtension,[$X_LIBS $X_EXTRA_LIBS]) WINE_GET_SONAME(cups,cupsGetDefault) diff --git a/dlls/x11drv/xrandr.c b/dlls/x11drv/xrandr.c index 53d351388ac..f9bc41c637c 100644 --- a/dlls/x11drv/xrandr.c +++ b/dlls/x11drv/xrandr.c @@ -19,6 +19,7 @@ */ #include "config.h" +#include "wine/port.h" #include #include @@ -35,10 +36,40 @@ #include "winbase.h" #include "wingdi.h" #include "ddrawi.h" +#include "wine/library.h" #include "wine/debug.h" WINE_DEFAULT_DEBUG_CHANNEL(xrandr); +static void *xrandr_handle; + +/* some default values just in case */ +#ifndef SONAME_LIBX11 +#define SONAME_LIBX11 "libX11.so" +#endif +#ifndef SONAME_LIBXEXT +#define SONAME_LIBXEXT "libXext.so" +#endif +#ifndef SONAME_LIBXRENDER +#define SONAME_LIBXRENDER "libXrender.so" +#endif +#ifndef SONAME_LIBXRANDR +#define SONAME_LIBXRANDR "libXrandr.so" +#endif + +#define MAKE_FUNCPTR(f) static typeof(f) * p##f; +MAKE_FUNCPTR(XRRConfigCurrentConfiguration) +MAKE_FUNCPTR(XRRConfigCurrentRate) +MAKE_FUNCPTR(XRRFreeScreenConfigInfo) +MAKE_FUNCPTR(XRRGetScreenInfo) +MAKE_FUNCPTR(XRRQueryExtension) +MAKE_FUNCPTR(XRRQueryVersion) +MAKE_FUNCPTR(XRRRates) +MAKE_FUNCPTR(XRRSetScreenConfig) +MAKE_FUNCPTR(XRRSetScreenConfigAndRate) +MAKE_FUNCPTR(XRRSizes) +#undef MAKE_FUNCPTR + extern int usexrandr; static int xrandr_event, xrandr_error, xrandr_major, xrandr_minor; @@ -51,6 +82,41 @@ static unsigned int real_xrandr_sizes_count; static int *real_xrandr_rates_count; static unsigned int real_xrandr_modes_count; +int load_xrandr(void) +{ + int r = 0; + + if (wine_dlopen(SONAME_LIBX11, RTLD_NOW|RTLD_GLOBAL, NULL, 0) && + wine_dlopen(SONAME_LIBXEXT, RTLD_NOW|RTLD_GLOBAL, NULL, 0) && + wine_dlopen(SONAME_LIBXRENDER, RTLD_NOW|RTLD_GLOBAL, NULL, 0) && + (xrandr_handle = wine_dlopen(SONAME_LIBXRANDR, RTLD_NOW, NULL, 0))) + { + +#define LOAD_FUNCPTR(f) \ + if((p##f = wine_dlsym(xrandr_handle, #f, NULL, 0)) == NULL) \ + goto sym_not_found; + + LOAD_FUNCPTR(XRRConfigCurrentConfiguration) + LOAD_FUNCPTR(XRRConfigCurrentRate) + LOAD_FUNCPTR(XRRFreeScreenConfigInfo) + LOAD_FUNCPTR(XRRGetScreenInfo) + LOAD_FUNCPTR(XRRQueryExtension) + LOAD_FUNCPTR(XRRQueryVersion) + LOAD_FUNCPTR(XRRRates) + LOAD_FUNCPTR(XRRSetScreenConfig) + LOAD_FUNCPTR(XRRSetScreenConfigAndRate) + LOAD_FUNCPTR(XRRSizes) + +#undef LOAD_FUNCPTR + + r = 1; /* success */ + +sym_not_found: + if (!r) TRACE("Unable to load function ptrs from XRandR library\n"); + } + return r; +} + static int XRandRErrorHandler(Display *dpy, XErrorEvent *event, void *arg) { return 1; @@ -93,9 +159,9 @@ static int X11DRV_XRandR_GetCurrentMode(void) wine_tsx11_lock(); root = RootWindow (gdi_display, DefaultScreen(gdi_display)); - sc = XRRGetScreenInfo (gdi_display, root); - size = XRRConfigCurrentConfiguration (sc, &rot); - rate = XRRConfigCurrentRate (sc); + sc = pXRRGetScreenInfo (gdi_display, root); + size = pXRRConfigCurrentConfiguration (sc, &rot); + rate = pXRRConfigCurrentRate (sc); for (i = 0; i < real_xrandr_modes_count; i++) { if ( (dd_modes[i].dwWidth == real_xrandr_sizes[size].width ) && @@ -105,7 +171,7 @@ static int X11DRV_XRandR_GetCurrentMode(void) res = i; } } - XRRFreeScreenConfigInfo(sc); + pXRRFreeScreenConfigInfo(sc); wine_tsx11_unlock(); if (res == -1) { @@ -129,8 +195,8 @@ static void X11DRV_XRandR_SetCurrentMode(int mode) wine_tsx11_lock(); root = RootWindow (gdi_display, DefaultScreen(gdi_display)); - sc = XRRGetScreenInfo (gdi_display, root); - size = XRRConfigCurrentConfiguration (sc, &rot); + sc = pXRRGetScreenInfo (gdi_display, root); + size = pXRRConfigCurrentConfiguration (sc, &rot); if (dwBpp != dd_modes[mode].dwBPP) { FIXME("Cannot change screen BPP from %ld to %ld\n", dwBpp, dd_modes[mode].dwBPP); @@ -151,7 +217,7 @@ static void X11DRV_XRandR_SetCurrentMode(int mode) rate = real_xrandr_rates[i][j]; TRACE("Resizing X display to %ldx%ld @%d Hz\n", dd_modes[mode].dwWidth, dd_modes[mode].dwHeight, rate); - stat = XRRSetScreenConfigAndRate (gdi_display, sc, root, + stat = pXRRSetScreenConfigAndRate (gdi_display, sc, root, size, rot, rate, CurrentTime); } } @@ -160,12 +226,12 @@ static void X11DRV_XRandR_SetCurrentMode(int mode) { TRACE("Resizing X display to %ldx%ld\n", dd_modes[mode].dwWidth, dd_modes[mode].dwHeight); - stat = XRRSetScreenConfig (gdi_display, sc, root, + stat = pXRRSetScreenConfig (gdi_display, sc, root, size, rot, CurrentTime); } } } - XRRFreeScreenConfigInfo(sc); + pXRRFreeScreenConfigInfo(sc); wine_tsx11_unlock(); if (stat == RRSetConfigSuccess) X11DRV_handle_desktop_resize( dd_modes[mode].dwWidth, dd_modes[mode].dwHeight ); @@ -182,21 +248,22 @@ void X11DRV_XRandR_Init(void) if (xrandr_major) return; /* already initialized? */ if (!usexrandr) return; /* disabled in config */ if (using_wine_desktop) return; /* not compatible with desktop mode */ + if (!load_xrandr()) return; /* can't load the Xrandr library */ /* see if Xrandr is available */ wine_tsx11_lock(); - ok = XRRQueryExtension(gdi_display, &xrandr_event, &xrandr_error); + ok = pXRRQueryExtension(gdi_display, &xrandr_event, &xrandr_error); if (ok) { X11DRV_expect_error(gdi_display, XRandRErrorHandler, NULL); - ok = XRRQueryVersion(gdi_display, &xrandr_major, &xrandr_minor); + ok = pXRRQueryVersion(gdi_display, &xrandr_major, &xrandr_minor); if (X11DRV_check_error()) ok = FALSE; } if (ok) { TRACE("Found XRandR - major: %d, minor: %d\n", xrandr_major, xrandr_minor); /* retrieve modes */ - real_xrandr_sizes = XRRSizes(gdi_display, DefaultScreen(gdi_display), &real_xrandr_sizes_count); + real_xrandr_sizes = pXRRSizes(gdi_display, DefaultScreen(gdi_display), &real_xrandr_sizes_count); ok = (real_xrandr_sizes_count>0); } if (ok) @@ -205,7 +272,7 @@ void X11DRV_XRandR_Init(void) real_xrandr_rates_count = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(int) * real_xrandr_sizes_count); for (i=0; i < real_xrandr_sizes_count; i++) { - real_xrandr_rates[i] = XRRRates (gdi_display, DefaultScreen(gdi_display), i, &(real_xrandr_rates_count[i])); + real_xrandr_rates[i] = pXRRRates (gdi_display, DefaultScreen(gdi_display), i, &(real_xrandr_rates_count[i])); if (real_xrandr_rates_count[i]) { nmodes += real_xrandr_rates_count[i]; diff --git a/include/config.h.in b/include/config.h.in index b56687b7a2a..8de0eddfa29 100644 --- a/include/config.h.in +++ b/include/config.h.in @@ -887,6 +887,9 @@ /* Define to the soname of the libXi library. */ #undef SONAME_LIBXI +/* Define to the soname of the libXrandr library. */ +#undef SONAME_LIBXRANDR + /* Define to the soname of the libXrender library. */ #undef SONAME_LIBXRENDER