summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonny Lamb <jonny.lamb@collabora.co.uk>2015-07-20 22:05:46 +0200
committerJonny Lamb <jonny.lamb@collabora.co.uk>2015-07-22 17:05:17 +0200
commite3a20f380d646873fe818f3cb13b54931c2ad0fd (patch)
tree21beff5afd20575ac7000da36decfeebd174d783
parent0a2f2166b4d233c1f3c69d37885243d4ffe13e0d (diff)
egldevice: copy udev dlopen code in from loader.c
This code is copied nearly verbatim from src/loader/loader.c. It should be put somewhere so both files can reference the same code without copy & pasting. Signed-off-by: Jonny Lamb <jonny.lamb@collabora.co.uk>
-rw-r--r--src/egl/main/egldevice.c54
1 files changed, 54 insertions, 0 deletions
diff --git a/src/egl/main/egldevice.c b/src/egl/main/egldevice.c
index c5c8e9433d..c79daff7fc 100644
--- a/src/egl/main/egldevice.c
+++ b/src/egl/main/egldevice.c
@@ -26,8 +26,14 @@
**************************************************************************/
+#ifdef HAVE_LIBUDEV
+#include <dlfcn.h>
+#include <libudev.h>
+#endif
+
#include "egldevice.h"
#include "eglglobals.h"
+#include "egllog.h"
#include "egltypedefs.h"
@@ -62,6 +68,54 @@ out:
return info;
}
+/* TODO: this is all copied from loader.c. it should probably be put somewhere
+ * common so both there and here can use the same source. also, if it remains
+ * here, it needs a mutex.*/
+#ifdef HAVE_LIBUDEV
+
+static void *udev_handle = NULL;
+
+static void *
+udev_dlopen_handle(void)
+{
+ if (!udev_handle) {
+ udev_handle = dlopen("libudev.so.1", RTLD_LOCAL | RTLD_LAZY);
+
+ if (!udev_handle) {
+ /* libudev.so.1 changed the return types of the two unref functions
+ * from voids to pointers. We don't use those return values, and the
+ * only ABI I've heard that cares about this kind of change (calling
+ * a function with a void * return that actually only returns void)
+ * might be ia64.
+ */
+ udev_handle = dlopen("libudev.so.0", RTLD_LOCAL | RTLD_LAZY);
+
+ if (!udev_handle) {
+ _eglLog(_EGL_WARNING, "Couldn't dlopen libudev.so.1 or "
+ "libudev.so.0, device detection may be broken.\n");
+ }
+ }
+ }
+
+ return udev_handle;
+}
+
+static int dlsym_failed = 0;
+
+static void *
+checked_dlsym(void *dlopen_handle, const char *name)
+{
+ void *result = dlsym(dlopen_handle, name);
+ if (!result)
+ dlsym_failed = 1;
+ return result;
+}
+
+#define UDEV_SYMBOL(ret, name, args) \
+ ret (*name) args = checked_dlsym(udev_dlopen_handle(), #name);
+
+#endif /* HAVE_LIBUDEV */
+
/**
* Finish device management.
*/