X11DRV: load the XRandR extention dynamically

Mike McCormack mike at codeweavers.com
Thu Apr 1 04:51:19 CST 2004


Anybody want to test this out for me?

Mike


Changelog:
* load the XRandR extention dynamically
-------------- next part --------------
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	1 Apr 2004 09:59:24 -0000
@@ -39,6 +39,35 @@
 
 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 +80,40 @@
 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(xrender_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:
+    }
+    return r;
+}
+
 static int XRandRErrorHandler(Display *dpy, XErrorEvent *event, void *arg)
 {
     return 1;
@@ -93,9 +156,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 +168,7 @@
               res = i;
           }
     }
-    XRRFreeScreenConfigInfo(sc);
+    pXRRFreeScreenConfigInfo(sc);
     wine_tsx11_unlock();
     if (res == -1)
     {
@@ -129,8 +192,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 +214,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 +223,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 +245,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 +269,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];
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	1 Apr 2004 09:59:24 -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 libXrender 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