Cell: use mem_dup()
[mesa.git] / src / egl / main / egldriver.c
index e2120e383a8d62cb2d9aa4d9da4e8ca33560130b..bda06dd827d539854769f302d0675b765fbd368c 100644 (file)
@@ -7,6 +7,7 @@
 #include "egldisplay.h"
 #include "egldriver.h"
 #include "eglglobals.h"
+#include "egllog.h"
 #include "eglmode.h"
 #include "eglscreen.h"
 #include "eglsurface.h"
@@ -43,20 +44,20 @@ _eglChooseDriver(EGLDisplay display)
       /* use default */
    }
    else if (name[0] == ':' && (name[1] >= '0' && name[1] <= '9') && !name[2]) {
-      printf("EGL: Use driver for screen: %s\n", name);
       /* XXX probe hardware here to determine which driver to open */
-      /* driverName = "something"; */
+      driverName = "libEGLdri";
    }
    else if (name[0] == '!') {
       /* use specified driver name */
       driverName = name + 1;
-      printf("EGL: Use driver named %s\n", driverName);
    }
    else {
       /* Maybe display was returned by XOpenDisplay? */
-      printf("EGL: can't parse display pointer\n");
+      _eglLog(_EGL_FATAL, "eglChooseDriver() bad name");
    }
 
+   _eglLog(_EGL_INFO, "eglChooseDriver() choosing %s", driverName);
+
    drv = _eglOpenDriver(dpy, driverName);
    dpy->Driver = drv;
 
@@ -71,44 +72,42 @@ _eglChooseDriver(EGLDisplay display)
 _EGLDriver *
 _eglOpenDriver(_EGLDisplay *dpy, const char *driverName)
 {
+   _EGLDriver *drv;
+   _EGLMain_t mainFunc;
    void *lib;
    char driverFilename[1000];
 
    /* XXX also prepend a directory path??? */
    sprintf(driverFilename, "%s.so", driverName);
 
-#if 1
+   _eglLog(_EGL_DEBUG, "dlopen(%s)", driverFilename);
    lib = dlopen(driverFilename, RTLD_NOW);
-   if (lib) {
-      _EGLDriver *drv;
-      _EGLMain_t mainFunc;
-
-      mainFunc = (_EGLMain_t) dlsym(lib, "_eglMain");
-      if (!mainFunc) {
-         fprintf(stderr, "_eglMain not found in %s", (char *) driverFilename);
-         dlclose(lib);
-         return NULL;
-      }
-
-      drv = mainFunc(dpy);
-      if (!drv) {
-         dlclose(lib);
-         return NULL;
-      }
+   if (!lib) {
+      _eglLog(_EGL_WARNING, "Could not open %s (%s)",
+              driverFilename, dlerror());
+      return NULL;
+   }
 
-      drv->LibHandle = lib;
-      drv->Display = dpy;
-      return drv;
+   mainFunc = (_EGLMain_t) dlsym(lib, "_eglMain");
+   if (!mainFunc) {
+      _eglLog(_EGL_WARNING, "_eglMain not found in %s", driverFilename);
+      dlclose(lib);
+      return NULL;
    }
-   else {
-      fprintf(stderr, "EGLdebug: Error opening %s: %s\n",
-              driverFilename, dlerror());
+
+   drv = mainFunc(dpy);
+   if (!drv) {
+      dlclose(lib);
       return NULL;
    }
-#else
-   /* use built-in driver */
-   return _eglDefaultMain(d);
-#endif
+   /* with a recurvise open you want the inner most handle */
+   if (!drv->LibHandle)
+      drv->LibHandle = lib;
+   else
+      dlclose(lib);
+
+   drv->Display = dpy;
+   return drv;
 }
 
 
@@ -117,13 +116,14 @@ _eglCloseDriver(_EGLDriver *drv, EGLDisplay dpy)
 {
    void *handle = drv->LibHandle;
    EGLBoolean b;
-   fprintf(stderr, "EGL debug: Closing driver\n");
+
+   _eglLog(_EGL_INFO, "Closing driver");
 
    /*
     * XXX check for currently bound context/surfaces and delete them?
     */
 
-   b = drv->Terminate(drv, dpy);
+   b = drv->API.Terminate(drv, dpy);
    dlclose(handle);
    return b;
 }
@@ -153,50 +153,72 @@ _eglInitDriverFallbacks(_EGLDriver *drv)
    /* If a pointer is set to NULL, then the device driver _really_ has
     * to implement it.
     */
-   drv->Initialize = NULL;
-   drv->Terminate = NULL;
-
-   drv->GetConfigs = _eglGetConfigs;
-   drv->ChooseConfig = _eglChooseConfig;
-   drv->GetConfigAttrib = _eglGetConfigAttrib;
-
-   drv->CreateContext = _eglCreateContext;
-   drv->DestroyContext = _eglDestroyContext;
-   drv->MakeCurrent = _eglMakeCurrent;
-   drv->QueryContext = _eglQueryContext;
-
-   drv->CreateWindowSurface = _eglCreateWindowSurface;
-   drv->CreatePixmapSurface = _eglCreatePixmapSurface;
-   drv->CreatePbufferSurface = _eglCreatePbufferSurface;
-   drv->DestroySurface = _eglDestroySurface;
-   drv->QuerySurface = _eglQuerySurface;
-   drv->SurfaceAttrib = _eglSurfaceAttrib;
-   drv->BindTexImage = _eglBindTexImage;
-   drv->ReleaseTexImage = _eglReleaseTexImage;
-   drv->SwapInterval = _eglSwapInterval;
-   drv->SwapBuffers = _eglSwapBuffers;
-   drv->CopyBuffers = _eglCopyBuffers;
-
-   drv->QueryString = _eglQueryString;
-   drv->WaitGL = _eglWaitGL;
-   drv->WaitNative = _eglWaitNative;
-
-   /* EGL_MESA_screen */
-   drv->ChooseModeMESA = _eglChooseModeMESA; 
-   drv->GetModesMESA = _eglGetModesMESA;
-   drv->GetModeAttribMESA = _eglGetModeAttribMESA;
-   drv->GetScreensMESA = _eglGetScreensMESA;
-   drv->CreateScreenSurfaceMESA = _eglCreateScreenSurfaceMESA;
-   drv->ShowSurfaceMESA = _eglShowSurfaceMESA;
-   drv->ScreenPositionMESA = _eglScreenPositionMESA;
-   drv->QueryDisplayMESA = _eglQueryDisplayMESA;
-   drv->QueryScreenMESA = _eglQueryScreenMESA;
-   drv->QueryScreenSurfaceMESA = _eglQueryScreenSurfaceMESA;
-   drv->QueryScreenModeMESA = _eglQueryScreenModeMESA;
-   drv->QueryModeStringMESA = _eglQueryModeStringMESA;
+   drv->API.Initialize = NULL;
+   drv->API.Terminate = NULL;
+
+   drv->API.GetConfigs = _eglGetConfigs;
+   drv->API.ChooseConfig = _eglChooseConfig;
+   drv->API.GetConfigAttrib = _eglGetConfigAttrib;
+
+   drv->API.CreateContext = _eglCreateContext;
+   drv->API.DestroyContext = _eglDestroyContext;
+   drv->API.MakeCurrent = _eglMakeCurrent;
+   drv->API.QueryContext = _eglQueryContext;
+
+   drv->API.CreateWindowSurface = _eglCreateWindowSurface;
+   drv->API.CreatePixmapSurface = _eglCreatePixmapSurface;
+   drv->API.CreatePbufferSurface = _eglCreatePbufferSurface;
+   drv->API.DestroySurface = _eglDestroySurface;
+   drv->API.QuerySurface = _eglQuerySurface;
+   drv->API.SurfaceAttrib = _eglSurfaceAttrib;
+   drv->API.BindTexImage = _eglBindTexImage;
+   drv->API.ReleaseTexImage = _eglReleaseTexImage;
+   drv->API.SwapInterval = _eglSwapInterval;
+   drv->API.SwapBuffers = _eglSwapBuffers;
+   drv->API.CopyBuffers = _eglCopyBuffers;
+
+   drv->API.QueryString = _eglQueryString;
+   drv->API.WaitGL = _eglWaitGL;
+   drv->API.WaitNative = _eglWaitNative;
+
+#ifdef EGL_MESA_screen_surface
+   drv->API.ChooseModeMESA = _eglChooseModeMESA; 
+   drv->API.GetModesMESA = _eglGetModesMESA;
+   drv->API.GetModeAttribMESA = _eglGetModeAttribMESA;
+   drv->API.GetScreensMESA = _eglGetScreensMESA;
+   drv->API.CreateScreenSurfaceMESA = _eglCreateScreenSurfaceMESA;
+   drv->API.ShowScreenSurfaceMESA = _eglShowScreenSurfaceMESA;
+   drv->API.ScreenPositionMESA = _eglScreenPositionMESA;
+   drv->API.QueryScreenMESA = _eglQueryScreenMESA;
+   drv->API.QueryScreenSurfaceMESA = _eglQueryScreenSurfaceMESA;
+   drv->API.QueryScreenModeMESA = _eglQueryScreenModeMESA;
+   drv->API.QueryModeStringMESA = _eglQueryModeStringMESA;
+#endif /* EGL_MESA_screen_surface */
+
+#ifdef EGL_VERSION_1_2
+   drv->API.CreatePbufferFromClientBuffer = _eglCreatePbufferFromClientBuffer;
+#endif /* EGL_VERSION_1_2 */
+}
+
+
+/**
+ * Examine the individual extension enable/disable flags and recompute
+ * the driver's Extensions string.
+ */
+static void
+_eglUpdateExtensionsString(_EGLDriver *drv)
+{
+   drv->Extensions.String[0] = 0;
+
+   if (drv->Extensions.MESA_screen_surface)
+      strcat(drv->Extensions.String, "EGL_MESA_screen_surface ");
+   if (drv->Extensions.MESA_copy_context)
+      strcat(drv->Extensions.String, "EGL_MESA_copy_context ");
+   assert(strlen(drv->Extensions.String) < MAX_EXTENSIONS_LEN);
 }
 
 
+
 const char *
 _eglQueryString(_EGLDriver *drv, EGLDisplay dpy, EGLint name)
 {
@@ -208,7 +230,13 @@ _eglQueryString(_EGLDriver *drv, EGLDisplay dpy, EGLint name)
    case EGL_VERSION:
       return "1.0";
    case EGL_EXTENSIONS:
-      return "";
+      _eglUpdateExtensionsString(drv);
+      return drv->Extensions.String;
+#ifdef EGL_VERSION_1_2
+   case EGL_CLIENT_APIS:
+      /* XXX need to initialize somewhere */
+      return drv->ClientAPIs;
+#endif
    default:
       _eglError(EGL_BAD_PARAMETER, "eglQueryString");
       return NULL;
@@ -232,6 +260,13 @@ _eglWaitNative(_EGLDriver *drv, EGLDisplay dpy, EGLint engine)
    /* just a placeholder */
    (void) drv;
    (void) dpy;
-   (void) engine;
+   switch (engine) {
+   case EGL_CORE_NATIVE_ENGINE:
+      break;
+   default:
+      _eglError(EGL_BAD_PARAMETER, "eglWaitNative(engine)");
+      return EGL_FALSE;
+   }
+
    return EGL_TRUE;
 }