| /* |
| * Mesa 3-D graphics library |
| * |
| * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. |
| * |
| * Permission is hereby granted, free of charge, to any person obtaining a |
| * copy of this software and associated documentation files (the "Software"), |
| * to deal in the Software without restriction, including without limitation |
| * the rights to use, copy, modify, merge, publish, distribute, sublicense, |
| * and/or sell copies of the Software, and to permit persons to whom the |
| * Software is furnished to do so, subject to the following conditions: |
| * |
| * The above copyright notice and this permission notice shall be included |
| * in all copies or substantial portions of the Software. |
| * |
| * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
| * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
| * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR |
| * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, |
| * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
| * OTHER DEALINGS IN THE SOFTWARE. |
| */ |
| |
| |
| /* |
| * This is the GLX API dispatcher. Calls to the glX* functions are |
| * either routed to the real GLX encoders or to Mesa's pseudo-GLX functions. |
| * See the glxapi.h file for more details. |
| */ |
| |
| |
| #include <assert.h> |
| #include <stdlib.h> |
| #include <stdio.h> |
| #include <string.h> |
| #include "main/glheader.h" |
| #include "main/compiler.h" |
| #include "glapi/glapi.h" |
| #include "glxapi.h" |
| |
| |
| extern struct _glxapi_table *_real_GetGLXDispatchTable(void); |
| extern struct _glxapi_table *_mesa_GetGLXDispatchTable(void); |
| |
| |
| struct display_dispatch { |
| Display *Dpy; |
| struct _glxapi_table *Table; |
| struct display_dispatch *Next; |
| }; |
| |
| |
| /** |
| * When GLX_INDIRECT_RENDERING is defined, some symbols are missing in |
| * libglapi.a. We need to define them here. |
| */ |
| #ifdef GLX_INDIRECT_RENDERING |
| |
| #include "glapi/glapitable.h" |
| |
| #define KEYWORD1 PUBLIC |
| |
| #if defined(USE_MGL_NAMESPACE) |
| #define NAME(func) mgl##func |
| #else |
| #define NAME(func) gl##func |
| #endif |
| |
| #define DISPATCH(FUNC, ARGS, MESSAGE) \ |
| GET_DISPATCH()->FUNC ARGS |
| |
| #define RETURN_DISPATCH(FUNC, ARGS, MESSAGE) \ |
| return GET_DISPATCH()->FUNC ARGS |
| |
| /* skip normal ones */ |
| #define _GLAPI_SKIP_NORMAL_ENTRY_POINTS |
| #include "glapi/glapitemp.h" |
| |
| #endif /* GLX_INDIRECT_RENDERING */ |
| |
| |
| static struct display_dispatch *DispatchList = NULL; |
| |
| |
| /* Display -> Dispatch caching */ |
| static Display *prevDisplay = NULL; |
| static struct _glxapi_table *prevTable = NULL; |
| |
| |
| static struct _glxapi_table * |
| get_dispatch(Display *dpy) |
| { |
| if (!dpy) |
| return NULL; |
| |
| /* search list of display/dispatch pairs for this display */ |
| { |
| const struct display_dispatch *d = DispatchList; |
| while (d) { |
| if (d->Dpy == dpy) { |
| prevDisplay = dpy; |
| prevTable = d->Table; |
| return d->Table; /* done! */ |
| } |
| d = d->Next; |
| } |
| } |
| |
| /* A new display, determine if we should use real GLX |
| * or Mesa's pseudo-GLX. |
| */ |
| { |
| struct _glxapi_table *t = _mesa_GetGLXDispatchTable(); |
| |
| if (t) { |
| struct display_dispatch *d; |
| d = malloc(sizeof(struct display_dispatch)); |
| if (d) { |
| d->Dpy = dpy; |
| d->Table = t; |
| /* insert at head of list */ |
| d->Next = DispatchList; |
| DispatchList = d; |
| /* update cache */ |
| prevDisplay = dpy; |
| prevTable = t; |
| return t; |
| } |
| } |
| } |
| |
| /* If we get here that means we can't use real GLX on this display |
| * and the Mesa pseudo-GLX software renderer wasn't compiled in. |
| * Or, we ran out of memory! |
| */ |
| return NULL; |
| } |
| |
| |
| /* Don't use the GET_DISPATCH defined in glthread.h */ |
| #undef GET_DISPATCH |
| |
| #define GET_DISPATCH(DPY, TABLE) \ |
| if (DPY == prevDisplay) { \ |
| TABLE = prevTable; \ |
| } \ |
| else if (!DPY) { \ |
| TABLE = NULL; \ |
| } \ |
| else { \ |
| TABLE = get_dispatch(DPY); \ |
| } |
| |
| |
| |
| |
| /** |
| * GLX API current context. |
| */ |
| #if defined(GLX_USE_TLS) |
| PUBLIC __thread void * CurrentContext |
| __attribute__((tls_model("initial-exec"))); |
| #elif defined(THREADS) |
| static _glthread_TSD ContextTSD; /**< Per-thread context pointer */ |
| #else |
| static GLXContext CurrentContext = 0; |
| #endif |
| |
| |
| static void |
| SetCurrentContext(GLXContext c) |
| { |
| #if defined(GLX_USE_TLS) |
| CurrentContext = c; |
| #elif defined(THREADS) |
| _glthread_SetTSD(&ContextTSD, c); |
| #else |
| CurrentContext = c; |
| #endif |
| } |
| |
| |
| /* |
| * GLX API entrypoints |
| */ |
| |
| /*** GLX_VERSION_1_0 ***/ |
| |
| XVisualInfo PUBLIC * |
| glXChooseVisual(Display *dpy, int screen, int *list) |
| { |
| struct _glxapi_table *t; |
| GET_DISPATCH(dpy, t); |
| if (!t) |
| return NULL; |
| return (t->ChooseVisual)(dpy, screen, list); |
| } |
| |
| |
| void PUBLIC |
| glXCopyContext(Display *dpy, GLXContext src, GLXContext dst, unsigned long mask) |
| { |
| struct _glxapi_table *t; |
| GET_DISPATCH(dpy, t); |
| if (!t) |
| return; |
| (t->CopyContext)(dpy, src, dst, mask); |
| } |
| |
| |
| GLXContext PUBLIC |
| glXCreateContext(Display *dpy, XVisualInfo *visinfo, GLXContext shareList, Bool direct) |
| { |
| struct _glxapi_table *t; |
| GET_DISPATCH(dpy, t); |
| if (!t) |
| return 0; |
| return (t->CreateContext)(dpy, visinfo, shareList, direct); |
| } |
| |
| |
| GLXPixmap PUBLIC |
| glXCreateGLXPixmap(Display *dpy, XVisualInfo *visinfo, Pixmap pixmap) |
| { |
| struct _glxapi_table *t; |
| GET_DISPATCH(dpy, t); |
| if (!t) |
| return 0; |
| return (t->CreateGLXPixmap)(dpy, visinfo, pixmap); |
| } |
| |
| |
| void PUBLIC |
| glXDestroyContext(Display *dpy, GLXContext ctx) |
| { |
| struct _glxapi_table *t; |
| GET_DISPATCH(dpy, t); |
| if (!t) |
| return; |
| if (glXGetCurrentContext() == ctx) |
| SetCurrentContext(NULL); |
| (t->DestroyContext)(dpy, ctx); |
| } |
| |
| |
| void PUBLIC |
| glXDestroyGLXPixmap(Display *dpy, GLXPixmap pixmap) |
| { |
| struct _glxapi_table *t; |
| GET_DISPATCH(dpy, t); |
| if (!t) |
| return; |
| (t->DestroyGLXPixmap)(dpy, pixmap); |
| } |
| |
| |
| int PUBLIC |
| glXGetConfig(Display *dpy, XVisualInfo *visinfo, int attrib, int *value) |
| { |
| struct _glxapi_table *t; |
| GET_DISPATCH(dpy, t); |
| if (!t) |
| return GLX_NO_EXTENSION; |
| return (t->GetConfig)(dpy, visinfo, attrib, value); |
| } |
| |
| |
| GLXContext PUBLIC |
| glXGetCurrentContext(void) |
| { |
| #if defined(GLX_USE_TLS) |
| return CurrentContext; |
| #elif defined(THREADS) |
| return (GLXContext) _glthread_GetTSD(&ContextTSD); |
| #else |
| return CurrentContext; |
| #endif |
| } |
| |
| |
| GLXDrawable PUBLIC |
| glXGetCurrentDrawable(void) |
| { |
| __GLXcontext *gc = (__GLXcontext *) glXGetCurrentContext(); |
| return gc ? gc->currentDrawable : 0; |
| } |
| |
| |
| Bool PUBLIC |
| glXIsDirect(Display *dpy, GLXContext ctx) |
| { |
| struct _glxapi_table *t; |
| GET_DISPATCH(dpy, t); |
| if (!t) |
| return False; |
| return (t->IsDirect)(dpy, ctx); |
| } |
| |
| |
| Bool PUBLIC |
| glXMakeCurrent(Display *dpy, GLXDrawable drawable, GLXContext ctx) |
| { |
| Bool b; |
| struct _glxapi_table *t; |
| GET_DISPATCH(dpy, t); |
| if (!t) { |
| return False; |
| } |
| b = (*t->MakeCurrent)(dpy, drawable, ctx); |
| if (b) { |
| SetCurrentContext(ctx); |
| } |
| return b; |
| } |
| |
| |
| Bool PUBLIC |
| glXQueryExtension(Display *dpy, int *errorb, int *event) |
| { |
| struct _glxapi_table *t; |
| GET_DISPATCH(dpy, t); |
| if (!t) |
| return False; |
| return (t->QueryExtension)(dpy, errorb, event); |
| } |
| |
| |
| Bool PUBLIC |
| glXQueryVersion(Display *dpy, int *maj, int *min) |
| { |
| struct _glxapi_table *t; |
| GET_DISPATCH(dpy, t); |
| if (!t) |
| return False; |
| return (t->QueryVersion)(dpy, maj, min); |
| } |
| |
| |
| void PUBLIC |
| glXSwapBuffers(Display *dpy, GLXDrawable drawable) |
| { |
| struct _glxapi_table *t; |
| GET_DISPATCH(dpy, t); |
| if (!t) |
| return; |
| (t->SwapBuffers)(dpy, drawable); |
| } |
| |
| |
| void PUBLIC |
| glXUseXFont(Font font, int first, int count, int listBase) |
| { |
| struct _glxapi_table *t; |
| Display *dpy = glXGetCurrentDisplay(); |
| GET_DISPATCH(dpy, t); |
| if (!t) |
| return; |
| (t->UseXFont)(font, first, count, listBase); |
| } |
| |
| |
| void PUBLIC |
| glXWaitGL(void) |
| { |
| struct _glxapi_table *t; |
| Display *dpy = glXGetCurrentDisplay(); |
| GET_DISPATCH(dpy, t); |
| if (!t) |
| return; |
| (t->WaitGL)(); |
| } |
| |
| |
| void PUBLIC |
| glXWaitX(void) |
| { |
| struct _glxapi_table *t; |
| Display *dpy = glXGetCurrentDisplay(); |
| GET_DISPATCH(dpy, t); |
| if (!t) |
| return; |
| (t->WaitX)(); |
| } |
| |
| |
| |
| /*** GLX_VERSION_1_1 ***/ |
| |
| const char PUBLIC * |
| glXGetClientString(Display *dpy, int name) |
| { |
| struct _glxapi_table *t; |
| GET_DISPATCH(dpy, t); |
| if (!t) |
| return NULL; |
| return (t->GetClientString)(dpy, name); |
| } |
| |
| |
| const char PUBLIC * |
| glXQueryExtensionsString(Display *dpy, int screen) |
| { |
| struct _glxapi_table *t; |
| GET_DISPATCH(dpy, t); |
| if (!t) |
| return NULL; |
| return (t->QueryExtensionsString)(dpy, screen); |
| } |
| |
| |
| const char PUBLIC * |
| glXQueryServerString(Display *dpy, int screen, int name) |
| { |
| struct _glxapi_table *t; |
| GET_DISPATCH(dpy, t); |
| if (!t) |
| return NULL; |
| return (t->QueryServerString)(dpy, screen, name); |
| } |
| |
| |
| /*** GLX_VERSION_1_2 ***/ |
| |
| Display PUBLIC * |
| glXGetCurrentDisplay(void) |
| { |
| /* Same code as in libGL's glxext.c */ |
| __GLXcontext *gc = (__GLXcontext *) glXGetCurrentContext(); |
| if (NULL == gc) return NULL; |
| return gc->currentDpy; |
| } |
| |
| |
| |
| /*** GLX_VERSION_1_3 ***/ |
| |
| GLXFBConfig PUBLIC * |
| glXChooseFBConfig(Display *dpy, int screen, const int *attribList, int *nitems) |
| { |
| struct _glxapi_table *t; |
| GET_DISPATCH(dpy, t); |
| if (!t) |
| return 0; |
| return (t->ChooseFBConfig)(dpy, screen, attribList, nitems); |
| } |
| |
| |
| GLXContext PUBLIC |
| glXCreateNewContext(Display *dpy, GLXFBConfig config, int renderType, GLXContext shareList, Bool direct) |
| { |
| struct _glxapi_table *t; |
| GET_DISPATCH(dpy, t); |
| if (!t) |
| return 0; |
| return (t->CreateNewContext)(dpy, config, renderType, shareList, direct); |
| } |
| |
| |
| GLXPbuffer PUBLIC |
| glXCreatePbuffer(Display *dpy, GLXFBConfig config, const int *attribList) |
| { |
| struct _glxapi_table *t; |
| GET_DISPATCH(dpy, t); |
| if (!t) |
| return 0; |
| return (t->CreatePbuffer)(dpy, config, attribList); |
| } |
| |
| |
| GLXPixmap PUBLIC |
| glXCreatePixmap(Display *dpy, GLXFBConfig config, Pixmap pixmap, const int *attribList) |
| { |
| struct _glxapi_table *t; |
| GET_DISPATCH(dpy, t); |
| if (!t) |
| return 0; |
| return (t->CreatePixmap)(dpy, config, pixmap, attribList); |
| } |
| |
| |
| GLXWindow PUBLIC |
| glXCreateWindow(Display *dpy, GLXFBConfig config, Window win, const int *attribList) |
| { |
| struct _glxapi_table *t; |
| GET_DISPATCH(dpy, t); |
| if (!t) |
| return 0; |
| return (t->CreateWindow)(dpy, config, win, attribList); |
| } |
| |
| |
| void PUBLIC |
| glXDestroyPbuffer(Display *dpy, GLXPbuffer pbuf) |
| { |
| struct _glxapi_table *t; |
| GET_DISPATCH(dpy, t); |
| if (!t) |
| return; |
| (t->DestroyPbuffer)(dpy, pbuf); |
| } |
| |
| |
| void PUBLIC |
| glXDestroyPixmap(Display *dpy, GLXPixmap pixmap) |
| { |
| struct _glxapi_table *t; |
| GET_DISPATCH(dpy, t); |
| if (!t) |
| return; |
| (t->DestroyPixmap)(dpy, pixmap); |
| } |
| |
| |
| void PUBLIC |
| glXDestroyWindow(Display *dpy, GLXWindow window) |
| { |
| struct _glxapi_table *t; |
| GET_DISPATCH(dpy, t); |
| if (!t) |
| return; |
| (t->DestroyWindow)(dpy, window); |
| } |
| |
| |
| GLXDrawable PUBLIC |
| glXGetCurrentReadDrawable(void) |
| { |
| __GLXcontext *gc = (__GLXcontext *) glXGetCurrentContext(); |
| return gc ? gc->currentReadable : 0; |
| } |
| |
| |
| int PUBLIC |
| glXGetFBConfigAttrib(Display *dpy, GLXFBConfig config, int attribute, int *value) |
| { |
| struct _glxapi_table *t; |
| GET_DISPATCH(dpy, t); |
| if (!t) |
| return GLX_NO_EXTENSION; |
| return (t->GetFBConfigAttrib)(dpy, config, attribute, value); |
| } |
| |
| |
| GLXFBConfig PUBLIC * |
| glXGetFBConfigs(Display *dpy, int screen, int *nelements) |
| { |
| struct _glxapi_table *t; |
| GET_DISPATCH(dpy, t); |
| if (!t) |
| return 0; |
| return (t->GetFBConfigs)(dpy, screen, nelements); |
| } |
| |
| void PUBLIC |
| glXGetSelectedEvent(Display *dpy, GLXDrawable drawable, unsigned long *mask) |
| { |
| struct _glxapi_table *t; |
| GET_DISPATCH(dpy, t); |
| if (!t) |
| return; |
| (t->GetSelectedEvent)(dpy, drawable, mask); |
| } |
| |
| |
| XVisualInfo PUBLIC * |
| glXGetVisualFromFBConfig(Display *dpy, GLXFBConfig config) |
| { |
| struct _glxapi_table *t; |
| GET_DISPATCH(dpy, t); |
| if (!t) |
| return NULL; |
| return (t->GetVisualFromFBConfig)(dpy, config); |
| } |
| |
| |
| Bool PUBLIC |
| glXMakeContextCurrent(Display *dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx) |
| { |
| Bool b; |
| struct _glxapi_table *t; |
| GET_DISPATCH(dpy, t); |
| if (!t) |
| return False; |
| b = (t->MakeContextCurrent)(dpy, draw, read, ctx); |
| if (b) { |
| SetCurrentContext(ctx); |
| } |
| return b; |
| } |
| |
| |
| int PUBLIC |
| glXQueryContext(Display *dpy, GLXContext ctx, int attribute, int *value) |
| { |
| struct _glxapi_table *t; |
| GET_DISPATCH(dpy, t); |
| assert(t); |
| if (!t) |
| return 0; /* XXX correct? */ |
| return (t->QueryContext)(dpy, ctx, attribute, value); |
| } |
| |
| |
| void PUBLIC |
| glXQueryDrawable(Display *dpy, GLXDrawable draw, int attribute, unsigned int *value) |
| { |
| struct _glxapi_table *t; |
| GET_DISPATCH(dpy, t); |
| if (!t) |
| return; |
| (t->QueryDrawable)(dpy, draw, attribute, value); |
| } |
| |
| |
| void PUBLIC |
| glXSelectEvent(Display *dpy, GLXDrawable drawable, unsigned long mask) |
| { |
| struct _glxapi_table *t; |
| GET_DISPATCH(dpy, t); |
| if (!t) |
| return; |
| (t->SelectEvent)(dpy, drawable, mask); |
| } |
| |
| |
| |
| /*** GLX_SGI_swap_control ***/ |
| |
| int PUBLIC |
| glXSwapIntervalSGI(int interval) |
| { |
| struct _glxapi_table *t; |
| Display *dpy = glXGetCurrentDisplay(); |
| GET_DISPATCH(dpy, t); |
| if (!t) |
| return 0; |
| return (t->SwapIntervalSGI)(interval); |
| } |
| |
| |
| |
| /*** GLX_SGI_video_sync ***/ |
| |
| int PUBLIC |
| glXGetVideoSyncSGI(unsigned int *count) |
| { |
| struct _glxapi_table *t; |
| Display *dpy = glXGetCurrentDisplay(); |
| GET_DISPATCH(dpy, t); |
| if (!t || !glXGetCurrentContext()) |
| return GLX_BAD_CONTEXT; |
| return (t->GetVideoSyncSGI)(count); |
| } |
| |
| int PUBLIC |
| glXWaitVideoSyncSGI(int divisor, int remainder, unsigned int *count) |
| { |
| struct _glxapi_table *t; |
| Display *dpy = glXGetCurrentDisplay(); |
| GET_DISPATCH(dpy, t); |
| if (!t || !glXGetCurrentContext()) |
| return GLX_BAD_CONTEXT; |
| return (t->WaitVideoSyncSGI)(divisor, remainder, count); |
| } |
| |
| |
| |
| /*** GLX_SGI_make_current_read ***/ |
| |
| Bool PUBLIC |
| glXMakeCurrentReadSGI(Display *dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx) |
| { |
| struct _glxapi_table *t; |
| GET_DISPATCH(dpy, t); |
| if (!t) |
| return False; |
| return (t->MakeCurrentReadSGI)(dpy, draw, read, ctx); |
| } |
| |
| GLXDrawable PUBLIC |
| glXGetCurrentReadDrawableSGI(void) |
| { |
| return glXGetCurrentReadDrawable(); |
| } |
| |
| |
| #if defined(_VL_H) |
| |
| GLXVideoSourceSGIX PUBLIC |
| glXCreateGLXVideoSourceSGIX(Display *dpy, int screen, VLServer server, VLPath path, int nodeClass, VLNode drainNode) |
| { |
| struct _glxapi_table *t; |
| GET_DISPATCH(dpy, t); |
| if (!t) |
| return 0; |
| return (t->CreateGLXVideoSourceSGIX)(dpy, screen, server, path, nodeClass, drainNode); |
| } |
| |
| void PUBLIC |
| glXDestroyGLXVideoSourceSGIX(Display *dpy, GLXVideoSourceSGIX src) |
| { |
| struct _glxapi_table *t; |
| GET_DISPATCH(dpy, t); |
| if (!t) |
| return 0; |
| return (t->DestroyGLXVideoSourceSGIX)(dpy, src); |
| } |
| |
| #endif |
| |
| |
| /*** GLX_EXT_import_context ***/ |
| |
| void PUBLIC |
| glXFreeContextEXT(Display *dpy, GLXContext context) |
| { |
| struct _glxapi_table *t; |
| GET_DISPATCH(dpy, t); |
| if (!t) |
| return; |
| (t->FreeContextEXT)(dpy, context); |
| } |
| |
| GLXContextID PUBLIC |
| glXGetContextIDEXT(const GLXContext context) |
| { |
| return ((__GLXcontext *) context)->xid; |
| } |
| |
| Display PUBLIC * |
| glXGetCurrentDisplayEXT(void) |
| { |
| return glXGetCurrentDisplay(); |
| } |
| |
| GLXContext PUBLIC |
| glXImportContextEXT(Display *dpy, GLXContextID contextID) |
| { |
| struct _glxapi_table *t; |
| GET_DISPATCH(dpy, t); |
| if (!t) |
| return 0; |
| return (t->ImportContextEXT)(dpy, contextID); |
| } |
| |
| int PUBLIC |
| glXQueryContextInfoEXT(Display *dpy, GLXContext context, int attribute,int *value) |
| { |
| struct _glxapi_table *t; |
| GET_DISPATCH(dpy, t); |
| if (!t) |
| return 0; /* XXX ok? */ |
| return (t->QueryContextInfoEXT)(dpy, context, attribute, value); |
| } |
| |
| |
| |
| /*** GLX_SGIX_fbconfig ***/ |
| |
| int PUBLIC |
| glXGetFBConfigAttribSGIX(Display *dpy, GLXFBConfigSGIX config, int attribute, int *value) |
| { |
| struct _glxapi_table *t; |
| GET_DISPATCH(dpy, t); |
| if (!t) |
| return 0; |
| return (t->GetFBConfigAttribSGIX)(dpy, config, attribute, value); |
| } |
| |
| GLXFBConfigSGIX PUBLIC * |
| glXChooseFBConfigSGIX(Display *dpy, int screen, int *attrib_list, int *nelements) |
| { |
| struct _glxapi_table *t; |
| GET_DISPATCH(dpy, t); |
| if (!t) |
| return 0; |
| return (t->ChooseFBConfigSGIX)(dpy, screen, attrib_list, nelements); |
| } |
| |
| GLXPixmap PUBLIC |
| glXCreateGLXPixmapWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config, Pixmap pixmap) |
| { |
| struct _glxapi_table *t; |
| GET_DISPATCH(dpy, t); |
| if (!t) |
| return 0; |
| return (t->CreateGLXPixmapWithConfigSGIX)(dpy, config, pixmap); |
| } |
| |
| GLXContext PUBLIC |
| glXCreateContextWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config, int render_type, GLXContext share_list, Bool direct) |
| { |
| struct _glxapi_table *t; |
| GET_DISPATCH(dpy, t); |
| if (!t) |
| return 0; |
| return (t->CreateContextWithConfigSGIX)(dpy, config, render_type, share_list, direct); |
| } |
| |
| XVisualInfo PUBLIC * |
| glXGetVisualFromFBConfigSGIX(Display *dpy, GLXFBConfigSGIX config) |
| { |
| struct _glxapi_table *t; |
| GET_DISPATCH(dpy, t); |
| if (!t) |
| return 0; |
| return (t->GetVisualFromFBConfigSGIX)(dpy, config); |
| } |
| |
| GLXFBConfigSGIX PUBLIC |
| glXGetFBConfigFromVisualSGIX(Display *dpy, XVisualInfo *vis) |
| { |
| struct _glxapi_table *t; |
| GET_DISPATCH(dpy, t); |
| if (!t) |
| return 0; |
| return (t->GetFBConfigFromVisualSGIX)(dpy, vis); |
| } |
| |
| |
| |
| /*** GLX_SGIX_pbuffer ***/ |
| |
| GLXPbufferSGIX PUBLIC |
| glXCreateGLXPbufferSGIX(Display *dpy, GLXFBConfigSGIX config, unsigned int width, unsigned int height, int *attrib_list) |
| { |
| struct _glxapi_table *t; |
| GET_DISPATCH(dpy, t); |
| if (!t) |
| return 0; |
| return (t->CreateGLXPbufferSGIX)(dpy, config, width, height, attrib_list); |
| } |
| |
| void PUBLIC |
| glXDestroyGLXPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuf) |
| { |
| struct _glxapi_table *t; |
| GET_DISPATCH(dpy, t); |
| if (!t) |
| return; |
| (t->DestroyGLXPbufferSGIX)(dpy, pbuf); |
| } |
| |
| int PUBLIC |
| glXQueryGLXPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuf, int attribute, unsigned int *value) |
| { |
| struct _glxapi_table *t; |
| GET_DISPATCH(dpy, t); |
| if (!t) |
| return 0; |
| return (t->QueryGLXPbufferSGIX)(dpy, pbuf, attribute, value); |
| } |
| |
| void PUBLIC |
| glXSelectEventSGIX(Display *dpy, GLXDrawable drawable, unsigned long mask) |
| { |
| struct _glxapi_table *t; |
| GET_DISPATCH(dpy, t); |
| if (!t) |
| return; |
| (t->SelectEventSGIX)(dpy, drawable, mask); |
| } |
| |
| void PUBLIC |
| glXGetSelectedEventSGIX(Display *dpy, GLXDrawable drawable, unsigned long *mask) |
| { |
| struct _glxapi_table *t; |
| GET_DISPATCH(dpy, t); |
| if (!t) |
| return; |
| (t->GetSelectedEventSGIX)(dpy, drawable, mask); |
| } |
| |
| |
| |
| /*** GLX_SGI_cushion ***/ |
| |
| void PUBLIC |
| glXCushionSGI(Display *dpy, Window win, float cushion) |
| { |
| struct _glxapi_table *t; |
| GET_DISPATCH(dpy, t); |
| if (!t) |
| return; |
| (t->CushionSGI)(dpy, win, cushion); |
| } |
| |
| |
| |
| /*** GLX_SGIX_video_resize ***/ |
| |
| int PUBLIC |
| glXBindChannelToWindowSGIX(Display *dpy, int screen, int channel , Window window) |
| { |
| struct _glxapi_table *t; |
| GET_DISPATCH(dpy, t); |
| if (!t) |
| return 0; |
| return (t->BindChannelToWindowSGIX)(dpy, screen, channel, window); |
| } |
| |
| int PUBLIC |
| glXChannelRectSGIX(Display *dpy, int screen, int channel, int x, int y, int w, int h) |
| { |
| struct _glxapi_table *t; |
| GET_DISPATCH(dpy, t); |
| if (!t) |
| return 0; |
| return (t->ChannelRectSGIX)(dpy, screen, channel, x, y, w, h); |
| } |
| |
| int PUBLIC |
| glXQueryChannelRectSGIX(Display *dpy, int screen, int channel, int *x, int *y, int *w, int *h) |
| { |
| struct _glxapi_table *t; |
| GET_DISPATCH(dpy, t); |
| if (!t) |
| return 0; |
| return (t->QueryChannelRectSGIX)(dpy, screen, channel, x, y, w, h); |
| } |
| |
| int PUBLIC |
| glXQueryChannelDeltasSGIX(Display *dpy, int screen, int channel, int *dx, int *dy, int *dw, int *dh) |
| { |
| struct _glxapi_table *t; |
| GET_DISPATCH(dpy, t); |
| if (!t) |
| return 0; |
| return (t->QueryChannelDeltasSGIX)(dpy, screen, channel, dx, dy, dw, dh); |
| } |
| |
| int PUBLIC |
| glXChannelRectSyncSGIX(Display *dpy, int screen, int channel, GLenum synctype) |
| { |
| struct _glxapi_table *t; |
| GET_DISPATCH(dpy, t); |
| if (!t) |
| return 0; |
| return (t->ChannelRectSyncSGIX)(dpy, screen, channel, synctype); |
| } |
| |
| |
| |
| #if defined(_DM_BUFFER_H_) |
| |
| Bool PUBLIC |
| glXAssociateDMPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuffer, DMparams *params, DMbuffer dmbuffer) |
| { |
| struct _glxapi_table *t; |
| GET_DISPATCH(dpy, t); |
| if (!t) |
| return False; |
| return (t->AssociateDMPbufferSGIX)(dpy, pbuffer, params, dmbuffer); |
| } |
| |
| #endif |
| |
| |
| /*** GLX_SGIX_swap_group ***/ |
| |
| void PUBLIC |
| glXJoinSwapGroupSGIX(Display *dpy, GLXDrawable drawable, GLXDrawable member) |
| { |
| struct _glxapi_table *t; |
| GET_DISPATCH(dpy, t); |
| if (!t) |
| return; |
| (*t->JoinSwapGroupSGIX)(dpy, drawable, member); |
| } |
| |
| |
| /*** GLX_SGIX_swap_barrier ***/ |
| |
| void PUBLIC |
| glXBindSwapBarrierSGIX(Display *dpy, GLXDrawable drawable, int barrier) |
| { |
| struct _glxapi_table *t; |
| GET_DISPATCH(dpy, t); |
| if (!t) |
| return; |
| (*t->BindSwapBarrierSGIX)(dpy, drawable, barrier); |
| } |
| |
| Bool PUBLIC |
| glXQueryMaxSwapBarriersSGIX(Display *dpy, int screen, int *max) |
| { |
| struct _glxapi_table *t; |
| GET_DISPATCH(dpy, t); |
| if (!t) |
| return False; |
| return (*t->QueryMaxSwapBarriersSGIX)(dpy, screen, max); |
| } |
| |
| |
| |
| /*** GLX_SUN_get_transparent_index ***/ |
| |
| Status PUBLIC |
| glXGetTransparentIndexSUN(Display *dpy, Window overlay, Window underlay, long *pTransparent) |
| { |
| struct _glxapi_table *t; |
| GET_DISPATCH(dpy, t); |
| if (!t) |
| return False; |
| return (*t->GetTransparentIndexSUN)(dpy, overlay, underlay, pTransparent); |
| } |
| |
| |
| |
| /*** GLX_MESA_copy_sub_buffer ***/ |
| |
| void PUBLIC |
| glXCopySubBufferMESA(Display *dpy, GLXDrawable drawable, int x, int y, int width, int height) |
| { |
| struct _glxapi_table *t; |
| GET_DISPATCH(dpy, t); |
| if (!t) |
| return; |
| (t->CopySubBufferMESA)(dpy, drawable, x, y, width, height); |
| } |
| |
| |
| |
| /*** GLX_MESA_release_buffers ***/ |
| |
| Bool PUBLIC |
| glXReleaseBuffersMESA(Display *dpy, Window w) |
| { |
| struct _glxapi_table *t; |
| GET_DISPATCH(dpy, t); |
| if (!t) |
| return False; |
| return (t->ReleaseBuffersMESA)(dpy, w); |
| } |
| |
| |
| |
| /*** GLX_MESA_pixmap_colormap ***/ |
| |
| GLXPixmap PUBLIC |
| glXCreateGLXPixmapMESA(Display *dpy, XVisualInfo *visinfo, Pixmap pixmap, Colormap cmap) |
| { |
| struct _glxapi_table *t; |
| GET_DISPATCH(dpy, t); |
| if (!t) |
| return 0; |
| return (t->CreateGLXPixmapMESA)(dpy, visinfo, pixmap, cmap); |
| } |
| |
| |
| |
| /*** GLX_MESA_set_3dfx_mode ***/ |
| |
| Bool PUBLIC |
| glXSet3DfxModeMESA(int mode) |
| { |
| struct _glxapi_table *t; |
| Display *dpy = glXGetCurrentDisplay(); |
| GET_DISPATCH(dpy, t); |
| if (!t) |
| return False; |
| return (t->Set3DfxModeMESA)(mode); |
| } |
| |
| |
| |
| /*** GLX_NV_vertex_array_range ***/ |
| |
| void PUBLIC * |
| glXAllocateMemoryNV( GLsizei size, |
| GLfloat readFrequency, |
| GLfloat writeFrequency, |
| GLfloat priority ) |
| { |
| struct _glxapi_table *t; |
| Display *dpy = glXGetCurrentDisplay(); |
| GET_DISPATCH(dpy, t); |
| if (!t) |
| return NULL; |
| return (t->AllocateMemoryNV)(size, readFrequency, writeFrequency, priority); |
| } |
| |
| |
| void PUBLIC |
| glXFreeMemoryNV( GLvoid *pointer ) |
| { |
| struct _glxapi_table *t; |
| Display *dpy = glXGetCurrentDisplay(); |
| GET_DISPATCH(dpy, t); |
| if (!t) |
| return; |
| (t->FreeMemoryNV)(pointer); |
| } |
| |
| |
| |
| |
| /*** GLX_MESA_agp_offset */ |
| |
| GLuint PUBLIC |
| glXGetAGPOffsetMESA( const GLvoid *pointer ) |
| { |
| struct _glxapi_table *t; |
| Display *dpy = glXGetCurrentDisplay(); |
| GET_DISPATCH(dpy, t); |
| if (!t) |
| return ~0; |
| return (t->GetAGPOffsetMESA)(pointer); |
| } |
| |
| |
| /*** GLX_EXT_texture_from_pixmap */ |
| |
| void PUBLIC |
| glXBindTexImageEXT(Display *dpy, GLXDrawable drawable, int buffer, |
| const int *attrib_list) |
| { |
| struct _glxapi_table *t; |
| GET_DISPATCH(dpy, t); |
| if (t) |
| t->BindTexImageEXT(dpy, drawable, buffer, attrib_list); |
| } |
| |
| void PUBLIC |
| glXReleaseTexImageEXT(Display *dpy, GLXDrawable drawable, int buffer) |
| { |
| struct _glxapi_table *t; |
| GET_DISPATCH(dpy, t); |
| if (t) |
| t->ReleaseTexImageEXT(dpy, drawable, buffer); |
| } |
| |
| |
| /**********************************************************************/ |
| /* GLX API management functions */ |
| /**********************************************************************/ |
| |
| |
| const char * |
| _glxapi_get_version(void) |
| { |
| return "1.3"; |
| } |
| |
| |
| /* |
| * Return array of extension strings. |
| */ |
| const char ** |
| _glxapi_get_extensions(void) |
| { |
| static const char *extensions[] = { |
| #ifdef GLX_EXT_import_context |
| "GLX_EXT_import_context", |
| #endif |
| #ifdef GLX_SGI_video_sync |
| "GLX_SGI_video_sync", |
| #endif |
| #ifdef GLX_MESA_copy_sub_buffer |
| "GLX_MESA_copy_sub_buffer", |
| #endif |
| #ifdef GLX_MESA_release_buffers |
| "GLX_MESA_release_buffers", |
| #endif |
| #ifdef GLX_MESA_pixmap_colormap |
| "GLX_MESA_pixmap_colormap", |
| #endif |
| #ifdef GLX_MESA_set_3dfx_mode |
| "GLX_MESA_set_3dfx_mode", |
| #endif |
| #ifdef GLX_SGIX_fbconfig |
| "GLX_SGIX_fbconfig", |
| #endif |
| #ifdef GLX_SGIX_pbuffer |
| "GLX_SGIX_pbuffer", |
| #endif |
| #ifdef GLX_EXT_texture_from_pixmap |
| "GLX_EXT_texture_from_pixmap", |
| #endif |
| #ifdef GLX_INTEL_swap_event |
| "GLX_INTEL_swap_event", |
| #endif |
| NULL |
| }; |
| return extensions; |
| } |
| |
| |
| /* |
| * Return size of the GLX dispatch table, in entries, not bytes. |
| */ |
| GLuint |
| _glxapi_get_dispatch_table_size(void) |
| { |
| return sizeof(struct _glxapi_table) / sizeof(void *); |
| } |
| |
| |
| static int |
| generic_no_op_func(void) |
| { |
| return 0; |
| } |
| |
| |
| /* |
| * Initialize all functions in given dispatch table to be no-ops |
| */ |
| void |
| _glxapi_set_no_op_table(struct _glxapi_table *t) |
| { |
| typedef int (*nop_func)(void); |
| nop_func *dispatch = (nop_func *) t; |
| GLuint n = _glxapi_get_dispatch_table_size(); |
| GLuint i; |
| for (i = 0; i < n; i++) { |
| dispatch[i] = generic_no_op_func; |
| } |
| } |
| |
| |
| struct name_address_pair { |
| const char *Name; |
| __GLXextFuncPtr Address; |
| }; |
| |
| static struct name_address_pair GLX_functions[] = { |
| /*** GLX_VERSION_1_0 ***/ |
| { "glXChooseVisual", (__GLXextFuncPtr) glXChooseVisual }, |
| { "glXCopyContext", (__GLXextFuncPtr) glXCopyContext }, |
| { "glXCreateContext", (__GLXextFuncPtr) glXCreateContext }, |
| { "glXCreateGLXPixmap", (__GLXextFuncPtr) glXCreateGLXPixmap }, |
| { "glXDestroyContext", (__GLXextFuncPtr) glXDestroyContext }, |
| { "glXDestroyGLXPixmap", (__GLXextFuncPtr) glXDestroyGLXPixmap }, |
| { "glXGetConfig", (__GLXextFuncPtr) glXGetConfig }, |
| { "glXGetCurrentContext", (__GLXextFuncPtr) glXGetCurrentContext }, |
| { "glXGetCurrentDrawable", (__GLXextFuncPtr) glXGetCurrentDrawable }, |
| { "glXIsDirect", (__GLXextFuncPtr) glXIsDirect }, |
| { "glXMakeCurrent", (__GLXextFuncPtr) glXMakeCurrent }, |
| { "glXQueryExtension", (__GLXextFuncPtr) glXQueryExtension }, |
| { "glXQueryVersion", (__GLXextFuncPtr) glXQueryVersion }, |
| { "glXSwapBuffers", (__GLXextFuncPtr) glXSwapBuffers }, |
| { "glXUseXFont", (__GLXextFuncPtr) glXUseXFont }, |
| { "glXWaitGL", (__GLXextFuncPtr) glXWaitGL }, |
| { "glXWaitX", (__GLXextFuncPtr) glXWaitX }, |
| |
| /*** GLX_VERSION_1_1 ***/ |
| { "glXGetClientString", (__GLXextFuncPtr) glXGetClientString }, |
| { "glXQueryExtensionsString", (__GLXextFuncPtr) glXQueryExtensionsString }, |
| { "glXQueryServerString", (__GLXextFuncPtr) glXQueryServerString }, |
| |
| /*** GLX_VERSION_1_2 ***/ |
| { "glXGetCurrentDisplay", (__GLXextFuncPtr) glXGetCurrentDisplay }, |
| |
| /*** GLX_VERSION_1_3 ***/ |
| { "glXChooseFBConfig", (__GLXextFuncPtr) glXChooseFBConfig }, |
| { "glXCreateNewContext", (__GLXextFuncPtr) glXCreateNewContext }, |
| { "glXCreatePbuffer", (__GLXextFuncPtr) glXCreatePbuffer }, |
| { "glXCreatePixmap", (__GLXextFuncPtr) glXCreatePixmap }, |
| { "glXCreateWindow", (__GLXextFuncPtr) glXCreateWindow }, |
| { "glXDestroyPbuffer", (__GLXextFuncPtr) glXDestroyPbuffer }, |
| { "glXDestroyPixmap", (__GLXextFuncPtr) glXDestroyPixmap }, |
| { "glXDestroyWindow", (__GLXextFuncPtr) glXDestroyWindow }, |
| { "glXGetCurrentReadDrawable", (__GLXextFuncPtr) glXGetCurrentReadDrawable }, |
| { "glXGetFBConfigAttrib", (__GLXextFuncPtr) glXGetFBConfigAttrib }, |
| { "glXGetFBConfigs", (__GLXextFuncPtr) glXGetFBConfigs }, |
| { "glXGetSelectedEvent", (__GLXextFuncPtr) glXGetSelectedEvent }, |
| { "glXGetVisualFromFBConfig", (__GLXextFuncPtr) glXGetVisualFromFBConfig }, |
| { "glXMakeContextCurrent", (__GLXextFuncPtr) glXMakeContextCurrent }, |
| { "glXQueryContext", (__GLXextFuncPtr) glXQueryContext }, |
| { "glXQueryDrawable", (__GLXextFuncPtr) glXQueryDrawable }, |
| { "glXSelectEvent", (__GLXextFuncPtr) glXSelectEvent }, |
| |
| /*** GLX_VERSION_1_4 ***/ |
| { "glXGetProcAddress", (__GLXextFuncPtr) glXGetProcAddress }, |
| |
| /*** GLX_SGI_swap_control ***/ |
| { "glXSwapIntervalSGI", (__GLXextFuncPtr) glXSwapIntervalSGI }, |
| |
| /*** GLX_SGI_video_sync ***/ |
| { "glXGetVideoSyncSGI", (__GLXextFuncPtr) glXGetVideoSyncSGI }, |
| { "glXWaitVideoSyncSGI", (__GLXextFuncPtr) glXWaitVideoSyncSGI }, |
| |
| /*** GLX_SGI_make_current_read ***/ |
| { "glXMakeCurrentReadSGI", (__GLXextFuncPtr) glXMakeCurrentReadSGI }, |
| { "glXGetCurrentReadDrawableSGI", (__GLXextFuncPtr) glXGetCurrentReadDrawableSGI }, |
| |
| /*** GLX_SGIX_video_source ***/ |
| #if defined(_VL_H) |
| { "glXCreateGLXVideoSourceSGIX", (__GLXextFuncPtr) glXCreateGLXVideoSourceSGIX }, |
| { "glXDestroyGLXVideoSourceSGIX", (__GLXextFuncPtr) glXDestroyGLXVideoSourceSGIX }, |
| #endif |
| |
| /*** GLX_EXT_import_context ***/ |
| { "glXFreeContextEXT", (__GLXextFuncPtr) glXFreeContextEXT }, |
| { "glXGetContextIDEXT", (__GLXextFuncPtr) glXGetContextIDEXT }, |
| { "glXGetCurrentDisplayEXT", (__GLXextFuncPtr) glXGetCurrentDisplayEXT }, |
| { "glXImportContextEXT", (__GLXextFuncPtr) glXImportContextEXT }, |
| { "glXQueryContextInfoEXT", (__GLXextFuncPtr) glXQueryContextInfoEXT }, |
| |
| /*** GLX_SGIX_fbconfig ***/ |
| { "glXGetFBConfigAttribSGIX", (__GLXextFuncPtr) glXGetFBConfigAttribSGIX }, |
| { "glXChooseFBConfigSGIX", (__GLXextFuncPtr) glXChooseFBConfigSGIX }, |
| { "glXCreateGLXPixmapWithConfigSGIX", (__GLXextFuncPtr) glXCreateGLXPixmapWithConfigSGIX }, |
| { "glXCreateContextWithConfigSGIX", (__GLXextFuncPtr) glXCreateContextWithConfigSGIX }, |
| { "glXGetVisualFromFBConfigSGIX", (__GLXextFuncPtr) glXGetVisualFromFBConfigSGIX }, |
| { "glXGetFBConfigFromVisualSGIX", (__GLXextFuncPtr) glXGetFBConfigFromVisualSGIX }, |
| |
| /*** GLX_SGIX_pbuffer ***/ |
| { "glXCreateGLXPbufferSGIX", (__GLXextFuncPtr) glXCreateGLXPbufferSGIX }, |
| { "glXDestroyGLXPbufferSGIX", (__GLXextFuncPtr) glXDestroyGLXPbufferSGIX }, |
| { "glXQueryGLXPbufferSGIX", (__GLXextFuncPtr) glXQueryGLXPbufferSGIX }, |
| { "glXSelectEventSGIX", (__GLXextFuncPtr) glXSelectEventSGIX }, |
| { "glXGetSelectedEventSGIX", (__GLXextFuncPtr) glXGetSelectedEventSGIX }, |
| |
| /*** GLX_SGI_cushion ***/ |
| { "glXCushionSGI", (__GLXextFuncPtr) glXCushionSGI }, |
| |
| /*** GLX_SGIX_video_resize ***/ |
| { "glXBindChannelToWindowSGIX", (__GLXextFuncPtr) glXBindChannelToWindowSGIX }, |
| { "glXChannelRectSGIX", (__GLXextFuncPtr) glXChannelRectSGIX }, |
| { "glXQueryChannelRectSGIX", (__GLXextFuncPtr) glXQueryChannelRectSGIX }, |
| { "glXQueryChannelDeltasSGIX", (__GLXextFuncPtr) glXQueryChannelDeltasSGIX }, |
| { "glXChannelRectSyncSGIX", (__GLXextFuncPtr) glXChannelRectSyncSGIX }, |
| |
| /*** GLX_SGIX_dmbuffer **/ |
| #if defined(_DM_BUFFER_H_) |
| { "glXAssociateDMPbufferSGIX", (__GLXextFuncPtr) glXAssociateDMPbufferSGIX }, |
| #endif |
| |
| /*** GLX_SGIX_swap_group ***/ |
| { "glXJoinSwapGroupSGIX", (__GLXextFuncPtr) glXJoinSwapGroupSGIX }, |
| |
| /*** GLX_SGIX_swap_barrier ***/ |
| { "glXBindSwapBarrierSGIX", (__GLXextFuncPtr) glXBindSwapBarrierSGIX }, |
| { "glXQueryMaxSwapBarriersSGIX", (__GLXextFuncPtr) glXQueryMaxSwapBarriersSGIX }, |
| |
| /*** GLX_SUN_get_transparent_index ***/ |
| { "glXGetTransparentIndexSUN", (__GLXextFuncPtr) glXGetTransparentIndexSUN }, |
| |
| /*** GLX_MESA_copy_sub_buffer ***/ |
| { "glXCopySubBufferMESA", (__GLXextFuncPtr) glXCopySubBufferMESA }, |
| |
| /*** GLX_MESA_pixmap_colormap ***/ |
| { "glXCreateGLXPixmapMESA", (__GLXextFuncPtr) glXCreateGLXPixmapMESA }, |
| |
| /*** GLX_MESA_release_buffers ***/ |
| { "glXReleaseBuffersMESA", (__GLXextFuncPtr) glXReleaseBuffersMESA }, |
| |
| /*** GLX_MESA_set_3dfx_mode ***/ |
| { "glXSet3DfxModeMESA", (__GLXextFuncPtr) glXSet3DfxModeMESA }, |
| |
| /*** GLX_ARB_get_proc_address ***/ |
| { "glXGetProcAddressARB", (__GLXextFuncPtr) glXGetProcAddressARB }, |
| |
| /*** GLX_NV_vertex_array_range ***/ |
| { "glXAllocateMemoryNV", (__GLXextFuncPtr) glXAllocateMemoryNV }, |
| { "glXFreeMemoryNV", (__GLXextFuncPtr) glXFreeMemoryNV }, |
| |
| /*** GLX_MESA_agp_offset ***/ |
| { "glXGetAGPOffsetMESA", (__GLXextFuncPtr) glXGetAGPOffsetMESA }, |
| |
| /*** GLX_EXT_texture_from_pixmap ***/ |
| { "glXBindTexImageEXT", (__GLXextFuncPtr) glXBindTexImageEXT }, |
| { "glXReleaseTexImageEXT", (__GLXextFuncPtr) glXReleaseTexImageEXT }, |
| |
| { NULL, NULL } /* end of list */ |
| }; |
| |
| |
| |
| /* |
| * Return address of named glX function, or NULL if not found. |
| */ |
| __GLXextFuncPtr |
| _glxapi_get_proc_address(const char *funcName) |
| { |
| GLuint i; |
| for (i = 0; GLX_functions[i].Name; i++) { |
| #ifdef MANGLE |
| /* skip the "m" prefix on the name */ |
| if (strcmp(GLX_functions[i].Name, funcName+1) == 0) |
| #else |
| if (strcmp(GLX_functions[i].Name, funcName) == 0) |
| #endif |
| return GLX_functions[i].Address; |
| } |
| return NULL; |
| } |
| |
| |
| |
| /* |
| * This function does not get dispatched through the dispatch table |
| * since it's really a "meta" function. |
| */ |
| __GLXextFuncPtr PUBLIC |
| glXGetProcAddressARB(const GLubyte *procName) |
| { |
| __GLXextFuncPtr f; |
| |
| f = _glxapi_get_proc_address((const char *) procName); |
| if (f) { |
| return f; |
| } |
| |
| f = (__GLXextFuncPtr) _glapi_get_proc_address((const char *) procName); |
| return f; |
| } |
| |
| |
| /* GLX 1.4 */ |
| void PUBLIC |
| (*glXGetProcAddress(const GLubyte *procName))() |
| { |
| return glXGetProcAddressARB(procName); |
| } |