/* * Given a display pointer and screen number, determine the name of * the DRI driver for the screen. (I.e. "r128", "tdfx", etc). * Return True for success, False for failure. */ static Bool GetDriverName(Display *dpy, int scrNum, char **driverName) { int directCapable; Bool b; int driverMajor, driverMinor, driverPatch; *driverName = NULL; if (!XF86DRIQueryDirectRenderingCapable(dpy, scrNum, &directCapable)) { ErrorMessageF("XF86DRIQueryDirectRenderingCapable failed\n"); return False; } if (!directCapable) { ErrorMessageF("XF86DRIQueryDirectRenderingCapable returned false\n"); return False; } b = XF86DRIGetClientDriverName(dpy, scrNum, &driverMajor, &driverMinor, &driverPatch, driverName); if (!b) { ErrorMessageF("Cannot determine driver name for screen %d\n", scrNum); return False; } InfoMessageF("XF86DRIGetClientDriverName: %d.%d.%d %s (screen %d)\n", driverMajor, driverMinor, driverPatch, *driverName, scrNum); return True; }
/* * Given a display pointer and screen number, determine the name of * the DRI driver for the screen (i.e., "i965", "radeon", "nouveau", etc). * Return True for success, False for failure. */ static Bool driGetDriverName(Display * dpy, int scrNum, char **driverName) { int directCapable; Bool b; int event, error; int driverMajor, driverMinor, driverPatch; *driverName = NULL; if (XF86DRIQueryExtension(dpy, &event, &error)) { /* DRI1 */ if (!XF86DRIQueryDirectRenderingCapable(dpy, scrNum, &directCapable)) { ErrorMessageF("XF86DRIQueryDirectRenderingCapable failed\n"); return False; } if (!directCapable) { ErrorMessageF("XF86DRIQueryDirectRenderingCapable returned false\n"); return False; } b = XF86DRIGetClientDriverName(dpy, scrNum, &driverMajor, &driverMinor, &driverPatch, driverName); if (!b) { ErrorMessageF("Cannot determine driver name for screen %d\n", scrNum); return False; } InfoMessageF("XF86DRIGetClientDriverName: %d.%d.%d %s (screen %d)\n", driverMajor, driverMinor, driverPatch, *driverName, scrNum); return True; } else if (DRI2QueryExtension(dpy, &event, &error)) { /* DRI2 */ char *dev; Bool ret = DRI2Connect(dpy, RootWindow(dpy, scrNum), driverName, &dev); if (ret) free(dev); return ret; } return False; }
/** * Try to \c dlopen the named driver. * * This function adds the "_dri.so" suffix to the driver name and searches the * directories specified by the \c LIBGL_DRIVERS_PATH environment variable in * order to find the driver. * * \param driverName - a name like "i965", "radeon", "nouveau", etc. * * \returns * A handle from \c dlopen, or \c NULL if driver file not found. */ _X_HIDDEN void * driOpenDriver(const char *driverName) { void *glhandle, *handle; const char *libPaths, *p, *next; char realDriverName[200]; int len; /* Attempt to make sure libGL symbols will be visible to the driver */ glhandle = dlopen(GL_LIB_NAME, RTLD_NOW | RTLD_GLOBAL); libPaths = NULL; if (geteuid() == getuid()) { /* don't allow setuid apps to use LIBGL_DRIVERS_PATH */ libPaths = getenv("LIBGL_DRIVERS_PATH"); if (!libPaths) libPaths = getenv("LIBGL_DRIVERS_DIR"); /* deprecated */ } if (libPaths == NULL) libPaths = DEFAULT_DRIVER_DIR; handle = NULL; for (p = libPaths; *p; p = next) { next = strchr(p, ':'); if (next == NULL) { len = strlen(p); next = p + len; } else { len = next - p; next++; } #ifdef GLX_USE_TLS snprintf(realDriverName, sizeof realDriverName, "%.*s/tls/%s_dri.so", len, p, driverName); InfoMessageF("OpenDriver: trying %s\n", realDriverName); handle = dlopen(realDriverName, RTLD_NOW | RTLD_GLOBAL); #endif if (handle == NULL) { snprintf(realDriverName, sizeof realDriverName, "%.*s/%s_dri.so", len, p, driverName); InfoMessageF("OpenDriver: trying %s\n", realDriverName); handle = dlopen(realDriverName, RTLD_NOW | RTLD_GLOBAL); } if (handle != NULL) break; else InfoMessageF("dlopen %s failed (%s)\n", realDriverName, dlerror()); } if (!handle) ErrorMessageF("unable to load driver: %s_dri.so\n", driverName); if (glhandle) dlclose(glhandle); return handle; }
/** * Try to \c dlopen the named driver. * * This function adds the "_dri.so" suffix to the driver name and searches the * directories specified by the \c LIBGL_DRIVERS_PATH environment variable in * order to find the driver. * * \param driverName - a name like "tdfx", "i810", "mga", etc. * * \returns * A handle from \c dlopen, or \c NULL if driver file not found. */ static __DRIdriver *OpenDriver(const char *driverName) { char *libPaths = NULL; char libDir[1000]; int i; __DRIdriver *driver; /* First, search Drivers list to see if we've already opened this driver */ for (driver = Drivers; driver; driver = driver->next) { if (strcmp(driver->name, driverName) == 0) { /* found it */ return driver; } } if (geteuid() == getuid()) { /* don't allow setuid apps to use LIBGL_DRIVERS_PATH */ libPaths = getenv("LIBGL_DRIVERS_PATH"); if (!libPaths) libPaths = getenv("LIBGL_DRIVERS_DIR"); /* deprecated */ } if (!libPaths) libPaths = DEFAULT_DRIVER_DIR; for ( i = 0 ; ExtractDir(i, libPaths, 1000, libDir) != 0 ; i++ ) { char realDriverName[200]; 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); handle = dlopen(realDriverName, RTLD_NOW | RTLD_GLOBAL); } if ( handle != NULL ) { /* allocate __DRIdriver struct */ driver = (__DRIdriver *) Xmalloc(sizeof(__DRIdriver)); if (!driver) return NULL; /* out of memory! */ /* init the struct */ driver->name = __glXstrdup(driverName); if (!driver->name) { Xfree(driver); return NULL; /* out of memory! */ } driver->createNewScreenFunc = (PFNCREATENEWSCREENFUNC) dlsym(handle, createNewScreenName); if ( driver->createNewScreenFunc == NULL ) { /* If the driver doesn't have this symbol then something's * really, really wrong. */ 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; } driver->handle = handle; /* put at head of linked list */ driver->next = Drivers; Drivers = driver; return driver; } else { ErrorMessageF("dlopen %s failed (%s)\n", realDriverName, dlerror()); } } ErrorMessageF("unable to find driver: %s_dri.so\n", driverName); return NULL; }