Merge branch 'mesa_7_5_branch'
[mesa.git] / src / egl / main / eglapi.c
index d9c8845aa493077ecd8ea59b361de5f154fd774a..f0a6f7f935569c43e8334adbf719ca0f90d1b3ec 100644 (file)
@@ -31,8 +31,8 @@
 
 
 #include <stdio.h>
+#include <stdlib.h>
 #include <string.h>
-/**#include "glapi.h"**/
 #include "eglcontext.h"
 #include "egldisplay.h"
 #include "egltypedefs.h"
 
 
 /**
- * NOTE: displayName is treated as a string in _eglChooseDriver()!!!
- * This will probably change!
- * See _eglChooseDriver() for details!
+ * This is typically the first EGL function that an application calls.
+ * We initialize our global vars and create a private _EGLDisplay object.
  */
-EGLDisplay APIENTRY
-eglGetDisplay(NativeDisplayType displayName)
+EGLDisplay EGLAPIENTRY
+eglGetDisplay(NativeDisplayType nativeDisplay)
 {
    _EGLDisplay *dpy;
    _eglInitGlobals();
-   dpy = _eglNewDisplay(displayName);
-   if (dpy)
-      return dpy->Handle;
-   else
-      return EGL_NO_DISPLAY;
+   dpy = _eglFindDisplay(nativeDisplay);
+   if (!dpy) {
+      dpy = _eglNewDisplay(nativeDisplay);
+      if (dpy)
+         _eglLinkDisplay(dpy);
+   }
+   return _eglGetDisplayHandle(dpy);
 }
 
 
-EGLBoolean APIENTRY
+/**
+ * This is typically the second EGL function that an application calls.
+ * Here we load/initialize the actual hardware driver.
+ */
+EGLBoolean EGLAPIENTRY
 eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
 {
+   EGLint major_int, minor_int;
+
    if (dpy) {
-      _EGLDriver *drv = _eglChooseDriver(dpy);
-      if (drv)
-         return drv->Initialize(drv, dpy, major, minor);
+      EGLBoolean retVal;
+      _EGLDisplay *dpyPriv = _eglLookupDisplay(dpy);
+      if (!dpyPriv) {
+         return EGL_FALSE;
+      }
+      dpyPriv->Driver = _eglOpenDriver(dpyPriv,
+                                       dpyPriv->DriverName,
+                                       dpyPriv->DriverArgs);
+      if (!dpyPriv->Driver) {
+         return EGL_FALSE;
+      }
+      /* Initialize the particular driver now */
+      retVal = dpyPriv->Driver->API.Initialize(dpyPriv->Driver, dpy,
+                                               &major_int, &minor_int);
+
+      dpyPriv->Driver->APImajor = major_int;
+      dpyPriv->Driver->APIminor = minor_int;
+      snprintf(dpyPriv->Driver->Version, sizeof(dpyPriv->Driver->Version),
+               "%d.%d (%s)", major_int, minor_int, dpyPriv->Driver->Name);
+
+      /* Update applications version of major and minor if not NULL */
+      if((major != NULL) && (minor != NULL))
+      {
+         *major = major_int;
+         *minor = minor_int;
+      }
+
+      return retVal;
    }
    return EGL_FALSE;
 }
 
 
-EGLBoolean APIENTRY
+EGLBoolean EGLAPIENTRY
 eglTerminate(EGLDisplay dpy)
 {
    _EGLDriver *drv = _eglLookupDriver(dpy);
@@ -83,231 +115,224 @@ eglTerminate(EGLDisplay dpy)
 }
 
 
-const char * APIENTRY
+const char * EGLAPIENTRY
 eglQueryString(EGLDisplay dpy, EGLint name)
 {
    _EGLDriver *drv = _eglLookupDriver(dpy);
    if (drv)
-      return drv->QueryString(drv, dpy, name);
+      return drv->API.QueryString(drv, dpy, name);
    else
       return NULL;
 }
 
 
-EGLBoolean APIENTRY
+EGLBoolean EGLAPIENTRY
 eglGetConfigs(EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config)
 {
    _EGLDriver *drv = _eglLookupDriver(dpy);
    /* XXX check drv for null in remaining functions */
-   return drv->GetConfigs(drv, dpy, configs, config_size, num_config);
+   return drv->API.GetConfigs(drv, dpy, configs, config_size, num_config);
 }
 
 
-EGLBoolean APIENTRY
+EGLBoolean EGLAPIENTRY
 eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config)
 {
    _EGLDriver *drv = _eglLookupDriver(dpy);
-   return drv->ChooseConfig(drv, dpy, attrib_list, configs, config_size, num_config);
+   return drv->API.ChooseConfig(drv, dpy, attrib_list, configs, config_size, num_config);
 }
 
 
-EGLBoolean APIENTRY
+EGLBoolean EGLAPIENTRY
 eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value)
 {
    _EGLDriver *drv = _eglLookupDriver(dpy);
-   return drv->GetConfigAttrib(drv, dpy, config, attribute, value);
+   return drv->API.GetConfigAttrib(drv, dpy, config, attribute, value);
 }
 
 
-EGLContext APIENTRY
+EGLContext EGLAPIENTRY
 eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_list, const EGLint *attrib_list)
 {
    _EGLDriver *drv = _eglLookupDriver(dpy);
-   return drv->CreateContext(drv, dpy, config, share_list, attrib_list);
+   return drv->API.CreateContext(drv, dpy, config, share_list, attrib_list);
 }
 
 
-EGLBoolean APIENTRY
+EGLBoolean EGLAPIENTRY
 eglDestroyContext(EGLDisplay dpy, EGLContext ctx)
 {
    _EGLDriver *drv = _eglLookupDriver(dpy);
-   return drv->DestroyContext(drv, dpy, ctx);
+   return drv->API.DestroyContext(drv, dpy, ctx);
 }
 
 
-EGLBoolean APIENTRY
+EGLBoolean EGLAPIENTRY
 eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx)
 {
    _EGLDriver *drv = _eglLookupDriver(dpy);
-   return drv->MakeCurrent(drv, dpy, draw, read, ctx);
+   return drv->API.MakeCurrent(drv, dpy, draw, read, ctx);
 }
 
 
-EGLBoolean APIENTRY
+EGLBoolean EGLAPIENTRY
 eglQueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value)
 {
    _EGLDriver *drv = _eglLookupDriver(dpy);
-   return drv->QueryContext(drv, dpy, ctx, attribute, value);
+   return drv->API.QueryContext(drv, dpy, ctx, attribute, value);
 }
 
 
-EGLSurface APIENTRY
+EGLSurface EGLAPIENTRY
 eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, NativeWindowType window, const EGLint *attrib_list)
 {
    _EGLDriver *drv = _eglLookupDriver(dpy);
-   return drv->CreateWindowSurface(drv, dpy, config, window, attrib_list);
+   return drv->API.CreateWindowSurface(drv, dpy, config, window, attrib_list);
 }
 
 
-EGLSurface APIENTRY
+EGLSurface EGLAPIENTRY
 eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config, NativePixmapType pixmap, const EGLint *attrib_list)
 {
    _EGLDriver *drv = _eglLookupDriver(dpy);
-   return drv->CreatePixmapSurface(drv, dpy, config, pixmap, attrib_list);
+   return drv->API.CreatePixmapSurface(drv, dpy, config, pixmap, attrib_list);
 }
 
 
-EGLSurface APIENTRY
+EGLSurface EGLAPIENTRY
 eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list)
 {
    _EGLDriver *drv = _eglLookupDriver(dpy);
-   return drv->CreatePbufferSurface(drv, dpy, config, attrib_list);
+   return drv->API.CreatePbufferSurface(drv, dpy, config, attrib_list);
 }
 
 
-EGLBoolean APIENTRY
+EGLBoolean EGLAPIENTRY
 eglDestroySurface(EGLDisplay dpy, EGLSurface surface)
 {
    _EGLDriver *drv = _eglLookupDriver(dpy);
-   return drv->DestroySurface(drv, dpy, surface);
+   return drv->API.DestroySurface(drv, dpy, surface);
 }
 
 
-EGLBoolean APIENTRY
+EGLBoolean EGLAPIENTRY
 eglQuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value)
 {
    _EGLDriver *drv = _eglLookupDriver(dpy);
-   return drv->QuerySurface(drv, dpy, surface, attribute, value);
+   return drv->API.QuerySurface(drv, dpy, surface, attribute, value);
 }
 
 
-EGLBoolean APIENTRY
+EGLBoolean EGLAPIENTRY
 eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value)
 {
    _EGLDriver *drv = _eglLookupDriver(dpy);
-   return drv->SurfaceAttrib(drv, dpy, surface, attribute, value);
+   return drv->API.SurfaceAttrib(drv, dpy, surface, attribute, value);
 }
 
 
-EGLBoolean APIENTRY
+EGLBoolean EGLAPIENTRY
 eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
 {
    _EGLDriver *drv = _eglLookupDriver(dpy);
-   return drv->BindTexImage(drv, dpy, surface, buffer);
+   return drv->API.BindTexImage(drv, dpy, surface, buffer);
 }
 
 
-EGLBoolean APIENTRY
+EGLBoolean EGLAPIENTRY
 eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
 {
    _EGLDriver *drv = _eglLookupDriver(dpy);
-   return drv->ReleaseTexImage(drv, dpy, surface, buffer);
+   return drv->API.ReleaseTexImage(drv, dpy, surface, buffer);
 }
 
 
-EGLBoolean APIENTRY
+EGLBoolean EGLAPIENTRY
 eglSwapInterval(EGLDisplay dpy, EGLint interval)
 {
    _EGLDriver *drv = _eglLookupDriver(dpy);
-   return drv->SwapInterval(drv, dpy, interval);
+   return drv->API.SwapInterval(drv, dpy, interval);
 }
 
 
-EGLBoolean APIENTRY
+EGLBoolean EGLAPIENTRY
 eglSwapBuffers(EGLDisplay dpy, EGLSurface draw)
 {
    _EGLDriver *drv = _eglLookupDriver(dpy);
-   return drv->SwapBuffers(drv, dpy, draw);
+   return drv->API.SwapBuffers(drv, dpy, draw);
 }
 
 
-EGLBoolean APIENTRY
+EGLBoolean EGLAPIENTRY
 eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, NativePixmapType target)
 {
    _EGLDriver *drv = _eglLookupDriver(dpy);
-   return drv->CopyBuffers(drv, dpy, surface, target);
+   return drv->API.CopyBuffers(drv, dpy, surface, target);
 }
 
 
-EGLBoolean APIENTRY
+EGLBoolean EGLAPIENTRY
 eglWaitGL(void)
 {
    EGLDisplay dpy = eglGetCurrentDisplay();
    if (dpy != EGL_NO_DISPLAY) {
       _EGLDriver *drv = _eglLookupDriver(dpy);
-      return drv->WaitGL(drv, dpy);
+      return drv->API.WaitGL(drv, dpy);
    }
    else
       return EGL_FALSE;
 }
 
 
-EGLBoolean APIENTRY
+EGLBoolean EGLAPIENTRY
 eglWaitNative(EGLint engine)
 {
    EGLDisplay dpy = eglGetCurrentDisplay();
    if (dpy != EGL_NO_DISPLAY) {
       _EGLDriver *drv = _eglLookupDriver(dpy);
-      return drv->WaitNative(drv, dpy, engine);
+      return drv->API.WaitNative(drv, dpy, engine);
    }
    else
       return EGL_FALSE;
 }
 
 
-EGLDisplay APIENTRY
+EGLDisplay EGLAPIENTRY
 eglGetCurrentDisplay(void)
 {
    _EGLDisplay *dpy = _eglGetCurrentDisplay();
-   if (dpy)
-      return dpy->Handle;
-   else
-      return EGL_NO_DISPLAY;
+   return _eglGetDisplayHandle(dpy);
 }
 
 
-EGLContext APIENTRY
+EGLContext EGLAPIENTRY
 eglGetCurrentContext(void)
 {
    _EGLContext *ctx = _eglGetCurrentContext();
-   if (ctx)
-      return ctx->Handle;
-   else
-      return EGL_NO_CONTEXT;
+   return _eglGetContextHandle(ctx);
 }
 
 
-EGLSurface APIENTRY
+EGLSurface EGLAPIENTRY
 eglGetCurrentSurface(EGLint readdraw)
 {
    _EGLSurface *s = _eglGetCurrentSurface(readdraw);
-   if (s)
-      return s->Handle;
-   else
-      return EGL_NO_SURFACE;
+   return _eglGetSurfaceHandle(s);
 }
 
 
-EGLint APIENTRY
+EGLint EGLAPIENTRY
 eglGetError(void)
 {
-   EGLint e = _eglGlobal.LastError;
-   _eglGlobal.LastError = EGL_SUCCESS;
+   _EGLThreadInfo *t = _eglGetCurrentThread();
+   EGLint e = t->LastError;
+   if (!_eglIsCurrentThreadDummy())
+      t->LastError = EGL_SUCCESS;
    return e;
 }
 
 
-void (* APIENTRY eglGetProcAddress(const char *procname))()
+void (* EGLAPIENTRY eglGetProcAddress(const char *procname))()
 {
    typedef void (*genericFunc)();
    struct name_function {
@@ -346,8 +371,27 @@ void (* APIENTRY eglGetProcAddress(const char *procname))()
       { "eglWaitGL", (_EGLProc) eglWaitGL },
       { "eglWaitNative", (_EGLProc) eglWaitNative },
       /* Extensions */
-      { "eglShowSurfaceMESA", (_EGLProc) NULL },
-      { "eglGetModesMESA", (_EGLProc) NULL },
+#ifdef EGL_MESA_screen_surface
+      { "eglChooseModeMESA", (_EGLProc) eglChooseModeMESA },
+      { "eglGetModesMESA", (_EGLProc) eglGetModesMESA },
+      { "eglGetModeAttribMESA", (_EGLProc) eglGetModeAttribMESA },
+      { "eglCopyContextMESA", (_EGLProc) eglCopyContextMESA },
+      { "eglGetScreensMESA", (_EGLProc) eglGetScreensMESA },
+      { "eglCreateScreenSurfaceMESA", (_EGLProc) eglCreateScreenSurfaceMESA },
+      { "eglShowScreenSurfaceMESA", (_EGLProc) eglShowScreenSurfaceMESA },
+      { "eglScreenPositionMESA", (_EGLProc) eglScreenPositionMESA },
+      { "eglQueryScreenMESA", (_EGLProc) eglQueryScreenMESA },
+      { "eglQueryScreenSurfaceMESA", (_EGLProc) eglQueryScreenSurfaceMESA },
+      { "eglQueryScreenModeMESA", (_EGLProc) eglQueryScreenModeMESA },
+      { "eglQueryModeStringMESA", (_EGLProc) eglQueryModeStringMESA },
+#endif /* EGL_MESA_screen_surface */
+#ifdef EGL_VERSION_1_2
+      { "eglBindAPI", (_EGLProc) eglBindAPI },
+      { "eglCreatePbufferFromClientBuffer", (_EGLProc) eglCreatePbufferFromClientBuffer },
+      { "eglQueryAPI", (_EGLProc) eglQueryAPI },
+      { "eglReleaseThread", (_EGLProc) eglReleaseThread },
+      { "eglWaitClient", (_EGLProc) eglWaitClient },
+#endif /* EGL_VERSION_1_2 */
       { NULL, NULL }
    };
    EGLint i;
@@ -356,12 +400,15 @@ void (* APIENTRY eglGetProcAddress(const char *procname))()
          return (genericFunc) egl_functions[i].function;
       }
    }
-#if 0
-   /* XXX enable this code someday */
-   return (genericFunc) _glapi_get_proc_address(procname);
-#else
+
+   /* now loop over drivers to query their procs */
+   for (i = 0; i < _eglGlobal.NumDrivers; i++) {
+      _EGLProc p = _eglGlobal.Drivers[i]->API.GetProcAddress(procname);
+      if (p)
+         return p;
+   }
+
    return NULL;
-#endif
 }
 
 
@@ -369,36 +416,58 @@ void (* APIENTRY eglGetProcAddress(const char *procname))()
  * EGL_MESA_screen extension
  */
 
-EGLBoolean APIENTRY
-eglChooseModeMESA(EGLDisplay dpy, EGLint screen_number,
+EGLBoolean EGLAPIENTRY
+eglChooseModeMESA(EGLDisplay dpy, EGLScreenMESA screen,
                   const EGLint *attrib_list, EGLModeMESA *modes,
                   EGLint modes_size, EGLint *num_modes)
 {
    _EGLDriver *drv = _eglLookupDriver(dpy);
    if (drv)
-      return drv->ChooseModeMESA(drv, dpy, screen_number, attrib_list, modes, modes_size, num_modes);
+      return drv->API.ChooseModeMESA(drv, dpy, screen, attrib_list, modes, modes_size, num_modes);
    else
       return EGL_FALSE;
 }
 
 
-EGLBoolean APIENTRY
-eglGetModesMESA(EGLDisplay dpy, EGLint screen_number, EGLModeMESA *modes, EGLint mode_size, EGLint *num_mode)
+EGLBoolean EGLAPIENTRY
+eglGetModesMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLModeMESA *modes, EGLint mode_size, EGLint *num_mode)
 {
    _EGLDriver *drv = _eglLookupDriver(dpy);
    if (drv)
-      return drv->GetModesMESA(drv, dpy, screen_number, modes, mode_size, num_mode);
+      return drv->API.GetModesMESA(drv, dpy, screen, modes, mode_size, num_mode);
    else
       return EGL_FALSE;
 }
 
 
-EGLBoolean APIENTRY
+EGLBoolean EGLAPIENTRY
 eglGetModeAttribMESA(EGLDisplay dpy, EGLModeMESA mode, EGLint attribute, EGLint *value)
 {
    _EGLDriver *drv = _eglLookupDriver(dpy);
    if (drv)
-      return drv->GetModeAttribMESA(drv, dpy, mode, attribute, value);
+      return drv->API.GetModeAttribMESA(drv, dpy, mode, attribute, value);
+   else
+      return EGL_FALSE;
+}
+
+
+EGLBoolean EGLAPIENTRY
+eglCopyContextMESA(EGLDisplay dpy, EGLContext source, EGLContext dest, EGLint mask)
+{
+   _EGLDriver *drv = _eglLookupDriver(dpy);
+   if (drv)
+      return drv->API.CopyContextMESA(drv, dpy, source, dest, mask);
+   else
+      return EGL_FALSE;
+}
+
+
+EGLBoolean
+eglGetScreensMESA(EGLDisplay dpy, EGLScreenMESA *screens, EGLint max_screens, EGLint *num_screens)
+{
+   _EGLDriver *drv = _eglLookupDriver(dpy);
+   if (drv)
+      return drv->API.GetScreensMESA(drv, dpy, screens, max_screens, num_screens);
    else
       return EGL_FALSE;
 }
@@ -407,56 +476,172 @@ eglGetModeAttribMESA(EGLDisplay dpy, EGLModeMESA mode, EGLint attribute, EGLint
 EGLSurface
 eglCreateScreenSurfaceMESA(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list)
 {
-   return EGL_FALSE;
+   _EGLDriver *drv = _eglLookupDriver(dpy);
+   return drv->API.CreateScreenSurfaceMESA(drv, dpy, config, attrib_list);
 }
 
 
 EGLBoolean
-eglShowSurfaceMESA(EGLDisplay dpy, EGLint screen, EGLSurface surface)
+eglShowScreenSurfaceMESA(EGLDisplay dpy, EGLint screen, EGLSurface surface, EGLModeMESA mode)
 {
-   return EGL_FALSE;
+   _EGLDriver *drv = _eglLookupDriver(dpy);
+   return drv->API.ShowScreenSurfaceMESA(drv, dpy, screen, surface, mode);
 }
 
 
 EGLBoolean
-eglScreenModeMESA(EGLDisplay dpy, EGLint screen_number, EGLModeMESA mode)
+eglScreenPositionMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLint x, EGLint y)
 {
-   return EGL_FALSE;
+   _EGLDriver *drv = _eglLookupDriver(dpy);
+   return drv->API.ScreenPositionMESA(drv, dpy, screen, x, y);
 }
 
 
 EGLBoolean
-eglScreenAttribsMESA(EGLDisplay dpy, EGLint screen, const EGLint *attrib_list)
+eglQueryScreenMESA( EGLDisplay dpy, EGLScreenMESA screen, EGLint attribute, EGLint *value)
 {
-   return EGL_FALSE;
+   _EGLDriver *drv = _eglLookupDriver(dpy);
+   return drv->API.QueryScreenMESA(drv, dpy, screen, attribute, value);
 }
 
 
 EGLBoolean
-eglQueryDisplayMESA(EGLDisplay dpy, EGLint attribute, EGLint *value)
+eglQueryScreenSurfaceMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLSurface *surface)
 {
-   return EGL_FALSE;
+   _EGLDriver *drv = _eglLookupDriver(dpy);
+   return drv->API.QueryScreenSurfaceMESA(drv, dpy, screen, surface);
 }
 
 
 EGLBoolean
-eglQueryScreenSurfaceMESA(EGLDisplay dpy, EGLint screen_number, EGLSurface *surface)
+eglQueryScreenModeMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLModeMESA *mode)
 {
-   return EGL_FALSE;
+   _EGLDriver *drv = _eglLookupDriver(dpy);
+   return drv->API.QueryScreenModeMESA(drv, dpy, screen, mode);
 }
 
 
+const char *
+eglQueryModeStringMESA(EGLDisplay dpy, EGLModeMESA mode)
+{
+   _EGLDriver *drv = _eglLookupDriver(dpy);
+   return drv->API.QueryModeStringMESA(drv, dpy, mode);
+}
+
+
+/**
+ ** EGL 1.2
+ **/
+
+#ifdef EGL_VERSION_1_2
+
+
+/**
+ * Specify the client API to use for subsequent calls including:
+ *  eglCreateContext()
+ *  eglGetCurrentContext()
+ *  eglGetCurrentDisplay()
+ *  eglGetCurrentSurface()
+ *  eglMakeCurrent(when the ctx parameter is EGL NO CONTEXT)
+ *  eglWaitClient()
+ *  eglWaitNative()
+ * See section 3.7 "Rendering Context" in the EGL specification for details.
+ */
 EGLBoolean
-eglQueryScreenModeMESA(EGLDisplay dpy, EGLint screen_number, EGLModeMESA *mode)
+eglBindAPI(EGLenum api)
 {
-   return EGL_FALSE;
+   _EGLThreadInfo *t = _eglGetCurrentThread();
+
+   if (_eglIsCurrentThreadDummy())
+      return _eglError(EGL_BAD_ALLOC, "eglBindAPI");
+
+   if (!_eglIsApiValid(api))
+      return _eglError(EGL_BAD_PARAMETER, "eglBindAPI");
+
+   switch (api) {
+#ifdef EGL_VERSION_1_4
+   case EGL_OPENGL_API:
+      if (_eglGlobal.ClientAPIsMask & EGL_OPENGL_BIT) {
+         t->CurrentAPIIndex = _eglConvertApiToIndex(api);
+         return EGL_TRUE;
+      }
+      _eglError(EGL_BAD_PARAMETER, "eglBindAPI");
+      return EGL_FALSE;
+#endif
+   case EGL_OPENGL_ES_API:
+      if (_eglGlobal.ClientAPIsMask & (EGL_OPENGL_ES_BIT | EGL_OPENGL_ES2_BIT)) {
+         t->CurrentAPIIndex = _eglConvertApiToIndex(api);
+         return EGL_TRUE;
+      }
+      _eglError(EGL_BAD_PARAMETER, "eglBindAPI");
+      return EGL_FALSE;
+   case EGL_OPENVG_API:
+      if (_eglGlobal.ClientAPIsMask & EGL_OPENVG_BIT) {
+         t->CurrentAPIIndex = _eglConvertApiToIndex(api);
+         return EGL_TRUE;
+      }
+      _eglError(EGL_BAD_PARAMETER, "eglBindAPI");
+      return EGL_FALSE;
+   default:
+      return EGL_FALSE;
+   }
+   return EGL_TRUE;
+}
+
+
+/**
+ * Return the last value set with eglBindAPI().
+ */
+EGLenum
+eglQueryAPI(void)
+{
+   /* returns one of EGL_OPENGL_API, EGL_OPENGL_ES_API or EGL_OPENVG_API */
+   _EGLThreadInfo *t = _eglGetCurrentThread();
+   return _eglConvertApiFromIndex(t->CurrentAPIIndex);
+}
+
+
+EGLSurface
+eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype,
+                                 EGLClientBuffer buffer, EGLConfig config,
+                                 const EGLint *attrib_list)
+{
+   _EGLDriver *drv = _eglLookupDriver(dpy);
+   return drv->API.CreatePbufferFromClientBuffer(drv, dpy, buftype, buffer,
+                                                 config, attrib_list);
 }
 
 
 EGLBoolean
-eglQueryScreenMESA( EGLDisplay dpy, EGLint screen_number, EGLint attribute, EGLint *value)
+eglReleaseThread(void)
 {
-   return EGL_FALSE;
+   EGLDisplay dpy;
+
+   if (_eglIsCurrentThreadDummy())
+      return EGL_TRUE;
+
+   dpy = eglGetCurrentDisplay();
+   if (dpy) {
+      _EGLDriver *drv = _eglLookupDriver(dpy);
+      /* unbind context */
+      (void) drv->API.MakeCurrent(drv, dpy, EGL_NO_SURFACE,
+                                  EGL_NO_SURFACE, EGL_NO_CONTEXT);
+   }
+   _eglDestroyCurrentThread();
+   return EGL_TRUE;
 }
 
 
+EGLBoolean
+eglWaitClient(void)
+{
+   EGLDisplay dpy = eglGetCurrentDisplay();
+   if (dpy != EGL_NO_DISPLAY) {
+      _EGLDriver *drv = _eglLookupDriver(dpy);
+      return drv->API.WaitClient(drv, dpy);
+   }
+   else
+      return EGL_FALSE;
+}
+
+#endif /* EGL_VERSION_1_2 */