X11DRV: load the XRandR extention dynamically

Alex Pasadyn ajp at mail.utexas.edu
Fri Apr 2 21:58:26 CST 2004


Mike McCormack wrote:
> 
> Anybody want to test this out for me?
> 
> Mike
> 
> 
> Changelog:
> * load the XRandR extention dynamically
> 


I tested it, and I had to change a couple things to make it work. 
Please try this one instead.

- updated #ifdefs (HAVE_LIBXRANDR -> HAVE_X11_EXTENSIONS_XRANDR_H)
- add some #includes
- fixed a couple cut-and-pastes-gone-bad (xrender -> xrandr)


Cheers!

Alex
-------------- next part --------------
Index: dlls/x11drv/x11drv_main.c
===================================================================
RCS file: /home/wine/wine/dlls/x11drv/x11drv_main.c,v
retrieving revision 1.88
diff -u -r1.88 x11drv_main.c
--- dlls/x11drv/x11drv_main.c	13 Feb 2004 03:58:21 -0000	1.88
+++ dlls/x11drv/x11drv_main.c	3 Apr 2004 02:57:33 -0000
@@ -397,7 +397,7 @@
     /* initialize XVidMode */
     X11DRV_XF86VM_Init();
 #endif
-#ifdef HAVE_LIBXRANDR
+#ifdef HAVE_X11_EXTENSIONS_XRANDR_H
     /* initialize XRandR */
     X11DRV_XRandR_Init();
 #endif
Index: dlls/x11drv/xrandr.c
===================================================================
RCS file: /home/wine/wine/dlls/x11drv/xrandr.c,v
retrieving revision 1.5
diff -u -r1.5 xrandr.c
--- dlls/x11drv/xrandr.c	13 Feb 2004 03:58:21 -0000	1.5
+++ dlls/x11drv/xrandr.c	3 Apr 2004 02:57:34 -0000
@@ -19,10 +19,11 @@
  */
 
 #include "config.h"
+#include "wine/port.h"
 #include <string.h>
 #include <stdio.h>
 
-#ifdef HAVE_LIBXRANDR
+#ifdef HAVE_X11_EXTENSIONS_XRANDR_H
 
 #include <X11/Xlib.h>
 #include <X11/extensions/Xrandr.h>
@@ -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 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 @@
     
     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 @@
               res = i;
           }
     }
-    XRRFreeScreenConfigInfo(sc);
+    pXRRFreeScreenConfigInfo(sc);
     wine_tsx11_unlock();
     if (res == -1)
     {
@@ -129,8 +195,8 @@
     
     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 @@
                         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 @@
             {
                 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 @@
     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 @@
         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];
@@ -249,4 +316,4 @@
     }
 }
 
-#endif /* HAVE_LIBXRANDR */
+#endif /* HAVE_X11_EXTENSIONS_XRANDR_H */
Index: dlls/x11drv/xrandr.h
===================================================================
RCS file: /home/wine/wine/dlls/x11drv/xrandr.h,v
retrieving revision 1.1
diff -u -r1.1 xrandr.h
--- dlls/x11drv/xrandr.h	16 Oct 2003 00:21:42 -0000	1.1
+++ dlls/x11drv/xrandr.h	3 Apr 2004 02:57:34 -0000
@@ -24,10 +24,10 @@
 # error You must include config.h to use this header
 #endif
 
-#ifdef HAVE_LIBXRANDR
+#ifdef HAVE_X11_EXTENSIONS_XRANDR_H
 
 void X11DRV_XRandR_Init(void);
 void X11DRV_XRandR_Cleanup(void);
 
-#endif /* HAVE_LIBXRANDR */
+#endif /* HAVE_X11_EXTENSIONS_XRANDR_H */
 #endif /* __WINE_XRANDR_H */
Index: configure.ac
===================================================================
RCS file: /home/wine/wine/configure.ac,v
retrieving revision 1.259
diff -u -r1.259 configure.ac
--- configure.ac	27 Mar 2004 01:48:52 -0000	1.259
+++ configure.ac	3 Apr 2004 02:57:31 -0000
@@ -250,16 +250,6 @@
                   $X_LIBS -lXext -lX11 $X_EXTRA_LIBS)
         fi
 
-        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)
-        fi
-
         dnl *** Check for XVideo extension supporting XvImages
         if test "$ac_cv_header_X11_extensions_Xvlib_h" = "yes"
         then
@@ -996,6 +986,7 @@
   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)
Index: include/config.h.in
===================================================================
RCS file: /home/wine/wine/include/config.h.in,v
retrieving revision 1.185
diff -u -r1.185 config.h.in
--- include/config.h.in	27 Mar 2004 01:48:52 -0000	1.185
+++ include/config.h.in	1 Apr 2004 09:59:24 -0000
@@ -275,9 +275,6 @@
 /* Define to 1 if you have the `xpg4' library (-lxpg4). */
 #undef HAVE_LIBXPG4
 
-/* Define if you have the Xrandr library */
-#undef HAVE_LIBXRANDR
-
 /* Define if you have the X Shape extension */
 #undef HAVE_LIBXSHAPE
 
@@ -883,6 +880,9 @@
 
 /* Define to the soname of the libXrender library. */
 #undef SONAME_LIBXRENDER
+
+/* Define to the soname of the libXrandr library. */
+#undef SONAME_LIBXRANDR
 
 /* If using the C implementation of alloca, define if you know the
    direction of stack growth for your system; otherwise it will be


More information about the wine-patches mailing list