Merge branch 'master' into asm-shader-rework-1
[mesa.git] / src / egl / main / egldriver.c
index 80fa49b7ab553348cdf3407e58754a572ef9b5c5..f2a864cd8a705f50ce45178a99636495c771a310 100644 (file)
@@ -5,7 +5,6 @@
 
 #include <assert.h>
 #include <string.h>
-#include <dlfcn.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include "eglconfig.h"
 #include "eglsurface.h"
 
 #if defined(_EGL_PLATFORM_X)
+#include <dlfcn.h>
 #include "eglx.h"
 #elif defined(_EGL_PLATFORM_WINDOWS)
-/* XXX to do */
-#elif defined(_EGL_PLATFORM_WINCE)
-/* XXX to do */
+/* Use static linking on Windows for now */
+#define WINDOWS_STATIC_LINK
+#endif
+
+/**
+ * Wrappers for dlopen/dlclose()
+ */
+#if defined(_EGL_PLATFORM_WINDOWS)
+#ifdef WINDOWS_STATIC_LINK
+   static const char *DefaultDriverName = "Windows EGL Static Library";
+#else
+   /* XXX Need to decide how to do dynamic name lookup on Windows */
+   static const char *DefaultDriverName = "TBD";
+#endif
+   static const char *SysFS = NULL;
+   typedef HMODULE lib_handle;
+
+   static HMODULE
+   open_library(const char *filename)
+   {
+#ifdef WINDOWS_STATIC_LINK
+      return 0;
+#else
+      return LoadLibrary(filename);
 #endif
+   }
 
+   static void
+   close_library(HMODULE lib)
+   {
+#ifdef WINDOWS_STATIC_LINK
+#else
+      FreeLibrary(lib);
+#endif
+   }
 
-static const char *DefaultDriverName = ":0";
-static const char *SysFS = "/sys/class";
+#elif defined(_EGL_PLATFORM_X)
+   static const char *DefaultDriverName = ":0";
+   static const char *SysFS = "/sys/class";
 
+   typedef void * lib_handle;
 
+   static void *
+   open_library(const char *filename)
+   {
+      return dlopen(filename, RTLD_LAZY);
+   }
 
+   static void
+   close_library(void *lib)
+   {
+      dlclose(lib);
+   }
+   
+#endif
 
 /**
  * Given a card number, use sysfs to determine the DRI driver name.
  */
-static const char *
+const char *
 _eglChooseDRMDriver(int card)
 {
 #if 0
@@ -70,7 +114,6 @@ _eglChooseDRMDriver(int card)
 #endif
 }
 
-
 /**
  * XXX this function is totally subject change!!!
  *
@@ -92,15 +135,23 @@ _eglChooseDRMDriver(int card)
 const char *
 _eglChooseDriver(_EGLDisplay *dpy)
 {
+   /* Under Windows, the NativeDisplay is an HDC handle, therefore */
+   /* it can't be interpreted as a string or a pointer. */
+#if defined(_EGL_PLATFORM_WINDOWS)
+   const char *displayString = NULL;
+#else
    const char *displayString = (const char *) dpy->NativeDisplay;
+#endif
    const char *driverName = NULL;
 
    (void) DefaultDriverName;
 
+#if defined(_EGL_PLATFORM_X)
    /* First, if the EGL_DRIVER env var is set, use that */
    driverName = getenv("EGL_DRIVER");
    if (driverName)
       return _eglstrdup(driverName);
+#endif
 
 #if 0
    if (!displayString) {
@@ -135,15 +186,11 @@ _eglChooseDriver(_EGLDisplay *dpy)
          }
       }
    }
-   else {
+   else 
+   {
       /* NativeDisplay is not a string! */
 #if defined(_EGL_PLATFORM_X)
       driverName = _xeglChooseDriver(dpy);
-#elif defined(_EGL_PLATFORM_WINDOWS)
-      /* XXX to do */
-      driverName = _weglChooseDriver(dpy);
-#elif defined(_EGL_PLATFORM_WINCE)
-      /* XXX to do */
 #else
       driverName = DefaultDriverName;
 #endif
@@ -165,39 +212,60 @@ _eglOpenDriver(_EGLDisplay *dpy, const char *driverName, const char *args)
 {
    _EGLDriver *drv;
    _EGLMain_t mainFunc;
-   void *lib;
+   lib_handle lib;
    char driverFilename[1000];
 
    assert(driverName);
 
+#if defined(_EGL_PLATFORM_WINDOWS)
+/* Use static linking on Windows for now */
+#ifdef WINDOWS_STATIC_LINK
+   lib = 0;
+   mainFunc = (_EGLMain_t)_eglMain;
+#else
+   /* XXX untested */
+   sprintf(driverFilename, "%s.dll", driverName);
+   _eglLog(_EGL_DEBUG, "dlopen(%s)", driverFilename);
+   lib = open_library(driverFilename);
+   if (!lib) {
+      _eglLog(_EGL_WARNING, "Could not open %s",
+              driverFilename);
+      return NULL;
+   }
+   mainFunc = (_EGLMain_t) GetProcAddress(lib, "_eglMain");
+#endif
+#elif defined(_EGL_PLATFORM_X)
    /* XXX also prepend a directory path??? */
    sprintf(driverFilename, "%s.so", driverName);
-
    _eglLog(_EGL_DEBUG, "dlopen(%s)", driverFilename);
-   lib = dlopen(driverFilename, RTLD_NOW);
+   lib = open_library(driverFilename);
    if (!lib) {
       _eglLog(_EGL_WARNING, "Could not open %s (%s)",
               driverFilename, dlerror());
       return NULL;
    }
-
    mainFunc = (_EGLMain_t) dlsym(lib, "_eglMain");
+#endif
+
    if (!mainFunc) {
       _eglLog(_EGL_WARNING, "_eglMain not found in %s", driverFilename);
-      dlclose(lib);
+      close_library(lib);
       return NULL;
    }
 
    drv = mainFunc(dpy, args);
    if (!drv) {
-      dlclose(lib);
+      close_library(lib);
       return NULL;
    }
+
    /* with a recurvise open you want the inner most handle */
-   if (!drv->LibHandle)
+   if (!drv->LibHandle) {
       drv->LibHandle = lib;
-   else
-      dlclose(lib);
+   }
+   else {
+      close_library(lib);
+   }
 
    /* update the global notion of supported APIs */
    _eglGlobal.ClientAPIsMask |= drv->ClientAPIsMask;
@@ -214,14 +282,14 @@ _eglCloseDriver(_EGLDriver *drv, EGLDisplay dpy)
    void *handle = drv->LibHandle;
    EGLBoolean b;
 
-   _eglLog(_EGL_INFO, "Closing driver");
+   _eglLog(_EGL_DEBUG, "Closing %s", drv->Name);
 
-   /*
-    * XXX check for currently bound context/surfaces and delete them?
-    */
+   _eglReleaseDisplayResources(drv, dpy);
 
    b = drv->API.Terminate(drv, dpy);
-   dlclose(handle);
+
+   close_library(handle);
+
    return b;
 }
 
@@ -306,3 +374,50 @@ _eglInitDriverFallbacks(_EGLDriver *drv)
    drv->API.CreatePbufferFromClientBuffer = _eglCreatePbufferFromClientBuffer;
 #endif /* EGL_VERSION_1_2 */
 }
+
+
+
+/**
+ * Try to determine which EGL APIs (OpenGL, OpenGL ES, OpenVG, etc)
+ * are supported on the system by looking for standard library names.
+ */
+EGLint
+_eglFindAPIs(void)
+{
+   EGLint mask = 0x0;
+   lib_handle lib;
+#if defined(_EGL_PLATFORM_WINDOWS)
+   /* XXX not sure about these names */
+   const char *es1_libname = "libGLESv1_CM.dll";
+   const char *es2_libname = "libGLESv2.dll";
+   const char *gl_libname = "OpenGL32.dll";
+   const char *vg_libname = "libOpenVG.dll";
+#elif defined(_EGL_PLATFORM_X)
+   const char *es1_libname = "libGLESv1_CM.so";
+   const char *es2_libname = "libGLESv2.so";
+   const char *gl_libname = "libGL.so";
+   const char *vg_libname = "libOpenVG.so";
+#endif
+
+   if ((lib = open_library(es1_libname))) {
+      close_library(lib);
+      mask |= EGL_OPENGL_ES_BIT;
+   }
+
+   if ((lib = open_library(es2_libname))) {
+      close_library(lib);
+      mask |= EGL_OPENGL_ES2_BIT;
+   }
+
+   if ((lib = open_library(gl_libname))) {
+      close_library(lib);
+      mask |= EGL_OPENGL_BIT;
+   }
+
+   if ((lib = open_library(vg_libname))) {
+      close_library(lib);
+      mask |= EGL_OPENVG_BIT;
+   }
+
+   return mask;
+}