#include <unistd.h>
#include <X11/Xlibint.h>
#include <X11/extensions/Xext.h>
-#include "extutil.h"
+#include <X11/extensions/extutil.h>
#include "glxclient.h"
#include "xf86dri.h"
#include "sarea.h"
#define RTLD_GLOBAL 0
#endif
-#ifdef BUILT_IN_DRI_DRIVER
-
-extern void *__driCreateScreen(Display *dpy, int scrn, __DRIscreen *psc,
- int numConfigs, __GLXvisualConfig *config);
-
-
-#else /* BUILT_IN_DRI_DRIVER */
-
#ifndef DEFAULT_DRIVER_DIR
/* this is normally defined in the Imakefile */
}
-/*
- * We'll save a pointer to this function when we couldn't find a
- * direct rendering driver for a given screen.
- */
-static void *DummyCreateScreen(Display *dpy, int scrn, __DRIscreen *psc,
- int numConfigs, __GLXvisualConfig *config)
-{
- (void) dpy;
- (void) scrn;
- (void) psc;
- (void) numConfigs;
- (void) config;
- return NULL;
-}
-
-
-
/**
* Extract the ith directory path out of a colon-separated list of paths. No
* more than \c dirLen characters, including the terminating \c NUL, will be
}
+/**
+ * Versioned name of the expected \c __driCreateNewScreen function.
+ *
+ * The version of the last incompatible loader/driver inteface change is
+ * appended to the name of the \c __driCreateNewScreen function. This
+ * prevents loaders from trying to load drivers that are too old.
+ *
+ * \todo
+ * Create a macro or something so that this is automatically updated.
+ */
+static const char createNewScreenName[] = "__driCreateNewScreen_20050727";
+
+
/**
* Try to \c dlopen the named driver.
*
void *handle = NULL;
+ /* If TLS support is enabled, try to open the TLS version of the driver
+ * binary first. If that fails, try the non-TLS version.
+ */
+#ifdef GLX_USE_TLS
+ snprintf(realDriverName, 200, "%s/tls/%s_dri.so", libDir, driverName);
+ InfoMessageF("OpenDriver: trying %s\n", realDriverName);
+ handle = dlopen(realDriverName, RTLD_NOW | RTLD_GLOBAL);
+#endif
+
if ( handle == NULL ) {
snprintf(realDriverName, 200, "%s/%s_dri.so", libDir, driverName);
InfoMessageF("OpenDriver: trying %s\n", realDriverName);
return NULL; /* out of memory! */
}
- driver->createScreenFunc = (CreateScreenFunc)
- dlsym(handle, "__driCreateScreen");
- driver->createNewScreenFunc = (CreateNewScreenFunc)
- dlsym(handle, "__driCreateNewScreen");
+ driver->createNewScreenFunc = (PFNCREATENEWSCREENFUNC)
+ dlsym(handle, createNewScreenName);
- if ( (driver->createScreenFunc == NULL)
- && (driver->createNewScreenFunc == NULL) ) {
+ if ( driver->createNewScreenFunc == NULL ) {
/* If the driver doesn't have this symbol then something's
* really, really wrong.
*/
- ErrorMessageF("Neither __driCreateScreen or __driCreateNewScreen "
- "are defined in %s_dri.so!\n", driverName);
+ ErrorMessageF("%s not defined in %s_dri.so!\n"
+ "Your driver may be too old for this libGL.\n",
+ createNewScreenName, driverName);
Xfree(driver);
dlclose(handle);
continue;
}
-#endif /* BUILT_IN_DRI_DRIVER */
-
-
/* This function isn't currently used.
*/
static void driDestroyDisplay(Display *dpy, void *private)
*/
pdisp->private = NULL;
pdisp->destroyDisplay = NULL;
- pdisp->createScreen = NULL;
if (!XF86DRIQueryExtension(dpy, &eventBase, &errorBase)) {
return NULL;
pdisp->destroyDisplay = driDestroyDisplay;
- /* allocate array of pointers to createScreen funcs */
- pdisp->createScreen = (CreateScreenFunc *) Xmalloc(numScreens * sizeof(void *));
- if (!pdisp->createScreen) {
- Xfree(pdpyp);
- return NULL;
- }
-
- /* allocate array of pointers to createScreen funcs */
- pdisp->createNewScreen = (CreateNewScreenFunc *) Xmalloc(numScreens * sizeof(void *));
+ /* allocate array of pointers to createNewScreen funcs */
+ pdisp->createNewScreen = (PFNCREATENEWSCREENFUNC *)
+ Xmalloc(numScreens * sizeof(void *));
if (!pdisp->createNewScreen) {
- Xfree(pdisp->createScreen);
Xfree(pdpyp);
return NULL;
}
pdpyp->libraryHandles = (void **) Xmalloc(numScreens * sizeof(void*));
if (!pdpyp->libraryHandles) {
Xfree(pdisp->createNewScreen);
- Xfree(pdisp->createScreen);
Xfree(pdpyp);
return NULL;
}
-#ifdef BUILT_IN_DRI_DRIVER
- /* we'll statically bind to the built-in __driCreateScreen function */
- for (scrn = 0; scrn < numScreens; scrn++) {
- pdisp->createScreen[scrn] = __driCreateScreen;
- pdisp->createNewScreen[scrn] = NULL;
- pdpyp->libraryHandles[scrn] = NULL;
- }
-
-#else
/* dynamically discover DRI drivers for all screens, saving each
* driver's "__driCreateScreen" function pointer. That's the bootstrap
* entrypoint for all DRI drivers.
for (scrn = 0; scrn < numScreens; scrn++) {
__DRIdriver *driver = driGetDriver(dpy, scrn);
if (driver) {
- pdisp->createScreen[scrn] = driver->createScreenFunc;
pdisp->createNewScreen[scrn] = driver->createNewScreenFunc;
pdpyp->libraryHandles[scrn] = driver->handle;
}
else {
- pdisp->createScreen[scrn] = DummyCreateScreen;
pdisp->createNewScreen[scrn] = NULL;
pdpyp->libraryHandles[scrn] = NULL;
}
}
-#endif
return (void *)pdpyp;
}