diff --git a/src/mesa/drivers/x11/glxapi.c b/src/mesa/drivers/x11/glxapi.c index 1e12dea579e..f64bc20bdef 100644 --- a/src/mesa/drivers/x11/glxapi.c +++ b/src/mesa/drivers/x11/glxapi.c @@ -1,8 +1,8 @@ -/* $Id: glxapi.c,v 1.7 1999/11/25 17:37:49 brianp Exp $ */ +/* $Id: glxapi.c,v 1.8 1999/11/28 20:07:33 brianp Exp $ */ /* * Mesa 3-D graphics library - * Version: 3.1 + * Version: 3.3 * * Copyright (C) 1999 Brian Paul All Rights Reserved. * @@ -25,584 +25,774 @@ */ - - - /* - * GLX API functions which either call fake or real GLX implementations - * - * To enable real GLX encoding the REALGLX preprocessor symbol should be - * defined on the command line. + * This is the GLX API dispatcher. Calls to the glX* functions are + * either routed to real (SGI / Utah) GLX encoders or to Mesa's + * pseudo-GLX module. */ - -#ifdef HAVE_CONFIG_H -#include "conf.h" -#endif - -#include -#include -#include "GL/glx.h" -#include "fakeglx.h" -#include "realglx.h" - - -#ifdef REALGLX -static Display *CurrentDisplay = NULL; -#endif +#include +#include +#include "glxapi.h" /* - * This functions determines whether a call to a glX*() function should - * be routed to the "fake" (Mesa) or "real" (GLX-encoder) functions. - * Input: dpy - the X display. - * Return: GL_TRUE if the given display supports the real GLX extension, - * GL_FALSE otherwise. + * XXX - this really shouldn't be here. + * Instead, add -DUSE_MESA_GLX to the compiler flags when needed. */ -static GLboolean display_has_glx( Display *dpy ) +#define USE_MESA_GLX 1 + + +/* Rather than include possibly non-existant headers... */ +#ifdef USE_SGI_GLX +extern struct _glxapi_table *_sgi_GetGLXDispatchtable(void); +#endif +#ifdef USE_UTAH_GLX +extern struct _glxapi_table *_utah_GetGLXDispatchTable(void); +#endif +#ifdef USE_MESA_GLX +extern struct _glxapi_table *_mesa_GetGLXDispatchTable(void); +#endif + + + +struct display_dispatch { + Display *Dpy; + struct _glxapi_table *Table; + struct display_dispatch *Next; +}; + +static struct display_dispatch *DispatchList = NULL; + + +static struct _glxapi_table * +get_dispatch(Display *dpy) { - /* TODO: we should use a lookup table to avoid calling XQueryExtension - * every time. + static Display *prevDisplay = NULL; + static struct _glxapi_table *prevTable = NULL; + + if (!dpy) + return NULL; + + /* try cached display */ + if (dpy == prevDisplay) { + return prevTable; + } + + /* 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 (SGI / Utah) + * or Mesa's pseudo-GLX. */ - int ignore; - if (XQueryExtension( dpy, "GLX", &ignore, &ignore, &ignore )) { - return GL_TRUE; - } - else { - return GL_FALSE; - } -} + { + struct _glxapi_table *t = NULL; - - -XVisualInfo *glXChooseVisual( Display *dpy, int screen, int *list ) -{ -#ifdef REALGLX - if (display_has_glx(dpy)) - return Real_glXChooseVisual( dpy, screen, list ); - else +#if defined(USE_SGI_GLX) || defined(USE_UTAH_GLX) + if (!getenv("MESA_FORCE_SOFTX")) { + int ignore; + if (XQueryExtension( dpy, "GLX", &ignore, &ignore, &ignore )) { + /* the X server has the GLX extension */ +#if defined(USE_SGI_GLX) + t = _sgi_GetGLXDispatchtable(); +#elif defined(USE_UTAH_GLX) + t = _utah_GetGLXDispatchTable(); #endif - return Fake_glXChooseVisual( dpy, screen, list ); -} - - - -int glXGetConfig( Display *dpy, XVisualInfo *visinfo, int attrib, int *value ) -{ -#ifdef REALGLX - if (display_has_glx(dpy)) - return Real_glXGetConfig( dpy, visinfo, attrib, value ); - else -#endif - return Fake_glXGetConfig( dpy, visinfo, attrib, value ); -} - - - -GLXContext glXCreateContext( Display *dpy, XVisualInfo *visinfo, - GLXContext shareList, Bool direct ) -{ -#ifdef REALGLX - if (display_has_glx(dpy)) - return Real_glXCreateContext( dpy, visinfo, shareList, direct ); - else -#endif - return Fake_glXCreateContext( dpy, visinfo, shareList, direct ); -} - - - -void glXDestroyContext( Display *dpy, GLXContext ctx ) -{ -#ifdef REALGLX - if (display_has_glx(dpy)) - Real_glXDestroyContext( dpy, ctx ); - else -#endif - Fake_glXDestroyContext( dpy, ctx ); -} - - - -void glXCopyContext( Display *dpy, GLXContext src, GLXContext dst, - GLuint mask ) -{ -#ifdef REALGLX - if (display_has_glx(dpy)) - Real_glXCopyContext( dpy, src, dst, mask ); - else -#endif - Fake_glXCopyContext( dpy, src, dst, mask ); -} - - - -Bool glXMakeCurrent( Display *dpy, GLXDrawable drawable, GLXContext ctx ) -{ -#ifdef REALGLX - if (display_has_glx(dpy)) { - if (Real_glXMakeCurrent( dpy, drawable, ctx )) { - CurrentDisplay = dpy; - return True; + } } - else { - return False; +#endif + +#if defined(USE_MESA_GLX) + if (!t) { + t = _mesa_GetGLXDispatchTable(); + assert(t); /* this has to work */ + } +#endif + + if (t) { + struct display_dispatch *d; + d = (struct display_dispatch *) 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; + } } } - else { - if (Fake_glXMakeCurrent( dpy, drawable, ctx )) { - CurrentDisplay = dpy; - return True; - } - else { - return False; - } - } -#else - return Fake_glXMakeCurrent( dpy, drawable, ctx ); -#endif + + /* 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; } -GLXContext glXGetCurrentContext( void ) -{ -#ifdef REALGLX - if (display_has_glx(CurrentDisplay)) - return Real_glXGetCurrentContext(); - else -#endif - return Fake_glXGetCurrentContext(); -} - - - -GLXDrawable glXGetCurrentDrawable( void ) -{ -#ifdef REALGLX - if (display_has_glx(CurrentDisplay)) - return Real_glXGetCurrentDrawable(); - else -#endif - return Fake_glXGetCurrentDrawable(); -} - - - -GLXPixmap glXCreateGLXPixmap( Display *dpy, XVisualInfo *visinfo, - Pixmap pixmap ) -{ -#ifdef REALGLX - if (display_has_glx(dpy)) - return Real_glXCreateGLXPixmap( dpy, visinfo, pixmap ); - else -#endif - return Fake_glXCreateGLXPixmap( dpy, visinfo, pixmap ); -} - - -void glXDestroyGLXPixmap( Display *dpy, GLXPixmap pixmap ) -{ -#ifdef REALGLX - if (display_has_glx(dpy)) - Real_glXDestroyGLXPixmap( dpy, pixmap ); - else -#endif - Fake_glXDestroyGLXPixmap( dpy, pixmap ); -} - - - -Bool glXQueryExtension( Display *dpy, int *errorb, int *event ) -{ -#ifdef REALGLX - if (display_has_glx(dpy)) - return Real_glXQueryExtension( dpy, errorb, event ); - else -#endif - return Fake_glXQueryExtension( dpy, errorb, event ); -} - - - -Bool glXIsDirect( Display *dpy, GLXContext ctx ) -{ -#ifdef REALGLX - if (display_has_glx(dpy)) - return Real_glXIsDirect( dpy, ctx ); - else -#endif - return Fake_glXIsDirect( dpy, ctx ); -} - - - -void glXSwapBuffers( Display *dpy, GLXDrawable drawable ) -{ -#ifdef REALGLX - if (display_has_glx(dpy)) - Real_glXSwapBuffers( dpy, drawable ); - else -#endif - Fake_glXSwapBuffers( dpy, drawable ); -} - - - -void glXCopySubBufferMESA( Display *dpy, GLXDrawable drawable, - int x, int y, int width, int height ) -{ -#ifdef REALGLX - /* can't implement! */ - return; -#endif - Fake_glXCopySubBufferMESA( dpy, drawable, x, y, width, height ); -} - - - -Bool glXQueryVersion( Display *dpy, int *maj, int *min ) -{ -#ifdef REALGLX - if (display_has_glx(dpy)) - return Real_glXQueryVersion( dpy, maj, min ); - else -#endif - return Fake_glXQueryVersion( dpy, maj, min ); -} - - - -void glXUseXFont( Font font, int first, int count, int listBase ) -{ -#ifdef REALGLX - if (display_has_glx(CurrentDisplay)) - Real_glXUseXFont( font, first, count, listBase ); - else -#endif - Fake_glXUseXFont( font, first, count, listBase ); -} - - -void glXWaitGL( void ) -{ -#ifdef REALGLX - if (display_has_glx(CurrentDisplay)) - Real_glXWaitGL(); - else -#endif - Fake_glXWaitGL(); -} - - - -void glXWaitX( void ) -{ -#ifdef REALGLX - if (display_has_glx(CurrentDisplay)) - Real_glXWaitX(); - else -#endif - Fake_glXWaitX(); -} - - - -/* GLX 1.1 and later */ -const char *glXQueryExtensionsString( Display *dpy, int screen ) -{ -#ifdef REALGLX - if (display_has_glx(dpy)) - return Real_glXQueryExtensionsString( dpy, screen ); - else -#endif - return Fake_glXQueryExtensionsString( dpy, screen ); -} - - - -/* GLX 1.1 and later */ -const char *glXQueryServerString( Display *dpy, int screen, int name ) -{ -#ifdef REALGLX - if (display_has_glx(dpy)) - return Real_glXQueryServerString( dpy, screen, name ); - else -#endif - return Fake_glXQueryServerString( dpy, screen, name ); -} - - - -/* GLX 1.1 and later */ -const char *glXGetClientString( Display *dpy, int name ) -{ -#ifdef REALGLX - if (display_has_glx(dpy)) - return Real_glXGetClientString( dpy, name ); - else -#endif - return Fake_glXGetClientString( dpy, name ); -} - - - -/* GLX 1.2 and later */ -Display *glXGetCurrentDisplay( void ) -{ -#ifdef REALGLX - if (display_has_glx(dpy)) - return Real_glXGetCurrentDisplay(); - else -#endif - return Fake_glXGetCurrentDisplay(); -} +/* Set by glXMakeCurrent() and glXMakeContextCurrent() only */ +static Display *CurrentDisplay = NULL; +static GLXContext CurrentContext = 0; +static GLXDrawable CurrentDrawable = 0; +static GLXDrawable CurrentReadDrawable = 0; /* - * GLX 1.3 and later - * XXX these are just no-op stubs for now. + * GLX API entrypoints */ -GLXFBConfig glXChooseFBConfig( Display *dpy, int screen, - const int *attribList, int *nitems ) + + +XVisualInfo *glXChooseVisual(Display *dpy, int screen, int *list) { - (void) dpy; - (void) screen; - (void) attribList; - (void) nitems; - return 0; + struct _glxapi_table *t = get_dispatch(dpy); + if (!t) + return NULL; + return (t->ChooseVisual)(dpy, screen, list); } -int glXGetFBConfigAttrib( Display *dpy, GLXFBConfig config, - int attribute, int *value ) +void glXCopyContext(Display *dpy, GLXContext src, GLXContext dst, GLuint mask) { - (void) dpy; - (void) config; - (void) attribute; - (void) value; - return 0; + struct _glxapi_table *t = get_dispatch(dpy); + if (!t) + return; + (t->CopyContext)(dpy, src, dst, mask); } -XVisualInfo *glXGetVisualFromFBConfig( Display *dpy, GLXFBConfig config ) +GLXContext glXCreateContext(Display *dpy, XVisualInfo *visinfo, GLXContext shareList, Bool direct) { - (void) dpy; - (void) config; - return 0; -} - - -GLXWindow glXCreateWindow( Display *dpy, GLXFBConfig config, Window win, - const int *attribList ) -{ - (void) dpy; - (void) config; - (void) win; - (void) attribList; - return 0; -} - - -void glXDestroyWindow( Display *dpy, GLXWindow window ) -{ - (void) dpy; - (void) window; - return; -} - - -GLXPixmap glXCreatePixmap( Display *dpy, GLXFBConfig config, Pixmap pixmap, - const int *attribList ) -{ - (void) dpy; - (void) config; - (void) pixmap; - (void) attribList; - return 0; -} - - -void glXDestroyPixmap( Display *dpy, GLXPixmap pixmap ) -{ - (void) dpy; - (void) pixmap; - return; -} - - -GLXPbuffer glXCreatePbuffer( Display *dpy, GLXFBConfig config, - const int *attribList ) -{ - (void) dpy; - (void) config; - (void) attribList; - return 0; -} - - -void glXDestroyPbuffer( Display *dpy, GLXPbuffer pbuf ) -{ - (void) dpy; - (void) pbuf; -} - - -void glXQueryDrawable( Display *dpy, GLXDrawable draw, int attribute, - unsigned int *value ) -{ - (void) dpy; - (void) draw; - (void) attribute; - (void) value; -} - - -GLXContext glXCreateNewContext( Display *dpy, GLXFBConfig config, - int renderType, GLXContext shareList, - Bool direct ) -{ - (void) dpy; - (void) config; - (void) renderType; - (void) shareList; - (void) direct; - return 0; -} - - -Bool glXMakeContextCurrent( Display *dpy, GLXDrawable draw, GLXDrawable read, - GLXContext ctx ) -{ -#ifdef REALGX - if (display_has_glx(dpy)) - return Real_glXMakeContextCurrent(dpy, draw, read, ctx); - else -#endif - return Fake_glXMakeContextCurrent(dpy, draw, read, ctx); -} - - -GLXDrawable glXGetCurrentReadDrawable( void ) -{ -#ifdef REALGX - if (display_has_glx(dpy)) - return Real_glXGetCurrentReadDrawable(); - else -#endif - return Fake_glXGetCurrentReadDrawable(); -} - - -int glXQueryContext( Display *dpy, GLXContext ctx, int attribute, int *value ) -{ - (void) dpy; - (void) ctx; - (void) attribute; - (void) value; - return 0; -} - - -void glXSelectEvent( Display *dpy, GLXDrawable drawable, unsigned long mask ) -{ - (void) dpy; - (void) drawable; - (void) mask; -} - - -void glXGetSelectedEvent( Display *dpy, GLXDrawable drawable, - unsigned long *mask ) -{ - (void) dpy; - (void) drawable; - (void) mask; -} - - - - -#ifdef GLX_MESA_release_buffers -Bool glXReleaseBuffersMESA( Display *dpy, Window w ) -{ -#ifdef REALGLX - if (display_has_glx(dpy)) - return GL_FALSE; - else -#endif - return Fake_glXReleaseBuffersMESA( dpy, w ); -} -#endif - - -#ifdef GLX_MESA_pixmap_colormap -GLXPixmap glXCreateGLXPixmapMESA( Display *dpy, XVisualInfo *visinfo, - Pixmap pixmap, Colormap cmap ) -{ -#ifdef REALGLX - if (display_has_glx(dpy)) + struct _glxapi_table *t = get_dispatch(dpy); + if (!t) return 0; - else + return (t->CreateContext)(dpy, visinfo, shareList, direct); +} + + +GLXPixmap glXCreateGLXPixmap(Display *dpy, XVisualInfo *visinfo, Pixmap pixmap) +{ + struct _glxapi_table *t = get_dispatch(dpy); + if (!t) + return 0; + return (t->CreateGLXPixmap)(dpy, visinfo, pixmap); +} + + +void glXDestroyContext(Display *dpy, GLXContext ctx) +{ + struct _glxapi_table *t = get_dispatch(dpy); + if (!t) + return; + (t->DestroyContext)(dpy, ctx); +} + + +void glXDestroyGLXPixmap(Display *dpy, GLXPixmap pixmap) +{ + struct _glxapi_table *t = get_dispatch(dpy); + if (!t) + return; + (t->DestroyGLXPixmap)(dpy, pixmap); +} + + +int glXGetConfig(Display *dpy, XVisualInfo *visinfo, int attrib, int *value) +{ + struct _glxapi_table *t = get_dispatch(dpy); + if (!t) + return GLX_NO_EXTENSION; + return (t->GetConfig)(dpy, visinfo, attrib, value); +} + + +GLXContext glXGetCurrentContext(void) +{ + return CurrentContext; +} + + +GLXDrawable glXGetCurrentDrawable(void) +{ + return CurrentDrawable; +} + + +Bool glXIsDirect(Display *dpy, GLXContext ctx) +{ + struct _glxapi_table *t = get_dispatch(dpy); + if (!t) + return False; + return (t->IsDirect)(dpy, ctx); +} + + +Bool glXMakeCurrent(Display *dpy, GLXDrawable drawable, GLXContext ctx) +{ + Bool b; + struct _glxapi_table *t = get_dispatch(dpy); + if (!t) + return False; + b = (*t->MakeCurrent)(dpy, drawable, ctx); + if (b) { + CurrentDisplay = dpy; + CurrentContext = ctx; + CurrentDrawable = drawable; + CurrentReadDrawable = drawable; + } + return b; +} + + +Bool glXQueryExtension(Display *dpy, int *errorb, int *event) +{ + struct _glxapi_table *t = get_dispatch(dpy); + if (!t) + return False; + return (t->QueryExtension)(dpy, errorb, event); +} + + +Bool glXQueryVersion(Display *dpy, int *maj, int *min) +{ + struct _glxapi_table *t = get_dispatch(dpy); + if (!t) + return False; + return (t->QueryVersion)(dpy, maj, min); +} + + +void glXSwapBuffers(Display *dpy, GLXDrawable drawable) +{ + struct _glxapi_table *t = get_dispatch(dpy); + if (!t) + return; + (t->SwapBuffers)(dpy, drawable); +} + + +void glXUseXFont(Font font, int first, int count, int listBase) +{ + struct _glxapi_table *t = get_dispatch(CurrentDisplay); + if (!t) + return; + (t->UseXFont)(font, first, count, listBase); +} + + +void glXWaitGL(void) +{ + struct _glxapi_table *t = get_dispatch(CurrentDisplay); + if (!t) + return; + (t->WaitGL)(); +} + + +void glXWaitX(void) +{ + struct _glxapi_table *t = get_dispatch(CurrentDisplay); + if (!t) + return; + (t->WaitX)(); +} + + + +#ifdef _GLXAPI_VERSION_1_1 + +const char *glXGetClientString(Display *dpy, int name) +{ + struct _glxapi_table *t = get_dispatch(dpy); + if (!t) + return NULL; + return (t->GetClientString)(dpy, name); +} + + +const char *glXQueryExtensionsString(Display *dpy, int screen) +{ + struct _glxapi_table *t = get_dispatch(dpy); + if (!t) + return NULL; + return (t->QueryExtensionsString)(dpy, screen); +} + + +const char *glXQueryServerString(Display *dpy, int screen, int name) +{ + struct _glxapi_table *t = get_dispatch(dpy); + if (!t) + return NULL; + return (t->QueryServerString)(dpy, screen, name); +} + #endif - return Fake_glXCreateGLXPixmapMESA( dpy, visinfo, pixmap, cmap ); + + + +#ifdef _GLXAPI_VERSION_1_2 +Display *glXGetCurrentDisplay(void) +{ + return CurrentDisplay; } #endif -#ifdef GLX_SGI_video_sync +#ifdef _GLXAPI_VERSION_1_3 + +GLXFBConfig glXChooseFBConfig(Display *dpy, int screen, const int *attribList, int *nitems) +{ + struct _glxapi_table *t = get_dispatch(dpy); + if (!t) + return 0; + return (t->ChooseFBConfig)(dpy, screen, attribList, nitems); +} + + +GLXContext glXCreateNewContext(Display *dpy, GLXFBConfig config, int renderType, GLXContext shareList, Bool direct) +{ + struct _glxapi_table *t = get_dispatch(dpy); + if (!t) + return 0; + return (t->CreateNewContext)(dpy, config, renderType, shareList, direct); +} + + +GLXPbuffer glXCreatePbuffer(Display *dpy, GLXFBConfig config, const int *attribList) +{ + struct _glxapi_table *t = get_dispatch(dpy); + if (!t) + return 0; + return (t->CreatePbuffer)(dpy, config, attribList); +} + + +GLXPixmap glXCreatePixmap(Display *dpy, GLXFBConfig config, Pixmap pixmap, const int *attribList) +{ + struct _glxapi_table *t = get_dispatch(dpy); + if (!t) + return 0; + return (t->CreatePixmap)(dpy, config, pixmap, attribList); +} + + +GLXWindow glXCreateWindow(Display *dpy, GLXFBConfig config, Window win, const int *attribList) +{ + struct _glxapi_table *t = get_dispatch(dpy); + if (!t) + return 0; + return (t->CreateWindow)(dpy, config, win, attribList); +} + + +void glXDestroyPbuffer(Display *dpy, GLXPbuffer pbuf) +{ + struct _glxapi_table *t = get_dispatch(dpy); + if (!t) + return; + (t->DestroyPbuffer)(dpy, pbuf); +} + + +void glXDestroyPixmap(Display *dpy, GLXPixmap pixmap) +{ + struct _glxapi_table *t = get_dispatch(dpy); + if (!t) + return; + (t->DestroyPixmap)(dpy, pixmap); +} + + +void glXDestroyWindow(Display *dpy, GLXWindow window) +{ + struct _glxapi_table *t = get_dispatch(dpy); + if (!t) + return; + (t->DestroyWindow)(dpy, window); +} + + +GLXDrawable glXGetCurrentReadDrawable(void) +{ + return CurrentReadDrawable; +} + + +int glXGetFBConfigAttrib(Display *dpy, GLXFBConfig config, int attribute, int *value) +{ + struct _glxapi_table *t = get_dispatch(dpy); + if (!t) + return GLX_NO_EXTENSION; + return (t->GetFBConfigAttrib)(dpy, config, attribute, value); +} + + +void glXGetSelectedEvent(Display *dpy, GLXDrawable drawable, unsigned long *mask) +{ + struct _glxapi_table *t = get_dispatch(dpy); + if (!t) + return; + (t->GetSelectedEvent)(dpy, drawable, mask); +} + + +XVisualInfo *glXGetVisualFromFBConfig(Display *dpy, GLXFBConfig config) +{ + struct _glxapi_table *t = get_dispatch(dpy); + if (!t) + return NULL; + return (t->GetVisualFromFBConfig)(dpy, config); +} + + +Bool glXMakeContextCurrent(Display *dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx) +{ + struct _glxapi_table *t = get_dispatch(dpy); + Bool b; + if (!t) + return False; + b = (t->MakeContextCurrent)(dpy, draw, read, ctx); + if (b) { + CurrentDisplay = dpy; + CurrentContext = ctx; + CurrentDrawable = draw; + CurrentReadDrawable = read; + } + return b; +} + + +int glXQueryContext(Display *dpy, GLXContext ctx, int attribute, int *value) +{ + struct _glxapi_table *t = get_dispatch(dpy); + assert(t); + if (!t) + return 0; /* XXX correct? */ + return (t->QueryContext)(dpy, ctx, attribute, value); +} + + +void glXQueryDrawable(Display *dpy, GLXDrawable draw, int attribute, unsigned int *value) +{ + struct _glxapi_table *t = get_dispatch(dpy); + if (!t) + return; + (t->QueryDrawable)(dpy, draw, attribute, value); +} + + +void glXSelectEvent(Display *dpy, GLXDrawable drawable, unsigned long mask) +{ + struct _glxapi_table *t = get_dispatch(dpy); + if (!t) + return; + (t->SelectEvent)(dpy, drawable, mask); +} + +#endif /* _GLXAPI_VERSION_1_3 */ + + +#ifdef _GLXAPI_EXT_import_context + +void glXFreeContextEXT(Display *dpy, GLXContext context) +{ + struct _glxapi_table *t = get_dispatch(dpy); + if (!t) + return; + (t->FreeContextEXT)(dpy, context); +} + + +GLXContextID glXGetContextIDEXT(const GLXContext context) +{ + /* XXX is this function right? */ + struct _glxapi_table *t = get_dispatch(CurrentDisplay); + if (!t) + return 0; + return (t->GetContextIDEXT)(context); +} + + +Display *glXGetCurrentDisplayEXT(void) +{ + return CurrentDisplay; +} + + +GLXContext glXImportContextEXT(Display *dpy, GLXContextID contextID) +{ + struct _glxapi_table *t = get_dispatch(dpy); + if (!t) + return 0; + return (t->ImportContextEXT)(dpy, contextID); +} + +int glXQueryContextInfoEXT(Display *dpy, GLXContext context, int attribute,int *value) +{ + struct _glxapi_table *t = get_dispatch(dpy); + if (!t) + return 0; /* XXX ok? */ + return (t->QueryContextInfoEXT)(dpy, context, attribute, value); +} + +#endif + + +#ifdef _GLXAPI_SGI_video_sync -/* - * This function doesn't really do anything. But, at least one - * application uses the function so this stub is useful. - */ int glXGetVideoSyncSGI(unsigned int *count) { - static unsigned int counter = 0; - *count = counter++; + struct _glxapi_table *t = get_dispatch(CurrentDisplay); + if (!t) + return 0; + return (t->GetVideoSyncSGI)(count); +} + + +int glXWaitVideoSyncSGI(int divisor, int remainder, unsigned int *count) +{ + struct _glxapi_table *t = get_dispatch(CurrentDisplay); + if (!t) + return 0; + return (t->WaitVideoSyncSGI)(divisor, remainder, count); +} + +#endif + + +#ifdef _GLXAPI_MESA_copy_sub_buffer + +void glXCopySubBufferMESA(Display *dpy, GLXDrawable drawable, int x, int y, int width, int height) +{ + struct _glxapi_table *t = get_dispatch(dpy); + if (!t) + return; + (t->CopySubBufferMESA)(dpy, drawable, x, y, width, height); +} + +#endif + + +#ifdef _GLXAPI_MESA_release_buffers + +Bool glXReleaseBuffersMESA(Display *dpy, Window w) +{ + struct _glxapi_table *t = get_dispatch(dpy); + if (!t) + return False; + return (t->ReleaseBuffersMESA)(dpy, w); +} + +#endif + + +#ifdef _GLXAPI_MESA_pixmap_colormap + +GLXPixmap glXCreateGLXPixmapMESA(Display *dpy, XVisualInfo *visinfo, Pixmap pixmap, Colormap cmap) +{ + struct _glxapi_table *t = get_dispatch(dpy); + if (!t) + return 0; + return (t->CreateGLXPixmapMESA)(dpy, visinfo, pixmap, cmap); +} + +#endif + + +#ifdef _GLXAPI_MESA_set_3dfx_mode + +GLboolean glXSet3DfxModeMESA(GLint mode) +{ + struct _glxapi_table *t = get_dispatch(CurrentDisplay); + if (!t) + return False; + return (t->Set3DfxModeMESA)(mode); +} + +#endif + + + +/**********************************************************************/ +/* 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 _GLXAPI_EXT_import_context + "GLX_EXT_import_context", +#endif +#ifdef _GLXAPI_SGI_video_sync + "GLX_SGI_video_sync", +#endif +#ifdef _GLXAPI_MESA_copy_sub_buffer + "GLX_MESA_copy_sub_buffer", +#endif +#ifdef _GLXAPI_MESA_release_buffers + "GLX_MESA_release_buffers", +#endif +#ifdef _GLXAPI_MESA_pixmap_colormap + "GLX_MESA_pixmap_colormap", +#endif +#ifdef _GLXAPI_MESA_set_3dfx_mode + "GLX_MESA_set_3dfx_mode", +#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; } /* - * Again, this is really just a stub function. + * Initialize all functions in given dispatch table to be no-ops */ -int glXWaitVideoSyncSGI(int divisor, int remainder, unsigned int *count) +void +_glxapi_set_no_op_table(struct _glxapi_table *t) { - static unsigned int counter = 0; - while (counter % divisor != remainder) - counter++; - *count = counter; - return 0; + GLuint n = _glxapi_get_dispatch_table_size(); + GLuint i; + void **dispatch = (void **) t; + for (i = 0; i < n; i++) { + dispatch[i] = (void *) generic_no_op_func; + } } + + +struct name_address_pair { + const char *Name; + GLvoid *Address; +}; + +static struct name_address_pair GLX_functions[] = { + { "glXChooseVisual", (GLvoid *) glXChooseVisual }, + { "glXCopyContext", (GLvoid *) glXCopyContext }, + { "glXCreateContext", (GLvoid *) glXCreateContext }, + { "glXCreateGLXPixmap", (GLvoid *) glXCreateGLXPixmap }, + { "glXDestroyContext", (GLvoid *) glXDestroyContext }, + { "glXDestroyGLXPixmap", (GLvoid *) glXDestroyGLXPixmap }, + { "glXGetConfig", (GLvoid *) glXGetConfig }, + { "glXIsDirect", (GLvoid *) glXIsDirect }, + { "glXMakeCurrent", (GLvoid *) glXMakeCurrent }, + { "glXQueryExtension", (GLvoid *) glXQueryExtension }, + { "glXQueryVersion", (GLvoid *) glXQueryVersion }, + { "glXSwapBuffers", (GLvoid *) glXSwapBuffers }, + { "glXUseXFont", (GLvoid *) glXUseXFont }, + { "glXWaitGL", (GLvoid *) glXWaitGL }, + { "glXWaitX", (GLvoid *) glXWaitX }, + +#ifdef _GLXAPI_VERSION_1_1 + { "glXGetClientString", (GLvoid *) glXGetClientString }, + { "glXQueryExtensionsString", (GLvoid *) glXQueryExtensionsString }, + { "glXQueryServerString", (GLvoid *) glXQueryServerString }, #endif +#ifdef _GLXAPI_VERSION_1_2 + /*{ "glXGetCurrentDisplay", (GLvoid *) glXGetCurrentDisplay },*/ +#endif + +#ifdef _GLXAPI_VERSION_1_3 + { "glXChooseFBConfig", (GLvoid *) glXChooseFBConfig }, + { "glXCreateNewContext", (GLvoid *) glXCreateNewContext }, + { "glXCreatePbuffer", (GLvoid *) glXCreatePbuffer }, + { "glXCreatePixmap", (GLvoid *) glXCreatePixmap }, + { "glXCreateWindow", (GLvoid *) glXCreateWindow }, + { "glXDestroyPbuffer", (GLvoid *) glXDestroyPbuffer }, + { "glXDestroyPixmap", (GLvoid *) glXDestroyPixmap }, + { "glXDestroyWindow", (GLvoid *) glXDestroyWindow }, + { "glXGetFBConfigAttrib", (GLvoid *) glXGetFBConfigAttrib }, + { "glXGetSelectedEvent", (GLvoid *) glXGetSelectedEvent }, + { "glXGetVisualFromFBConfig", (GLvoid *) glXGetVisualFromFBConfig }, + { "glXMakeContextCurrent", (GLvoid *) glXMakeContextCurrent }, + { "glXQueryContext", (GLvoid *) glXQueryContext }, + { "glXQueryDrawable", (GLvoid *) glXQueryDrawable }, + { "glXSelectEvent", (GLvoid *) glXSelectEvent }, +#endif + +#ifdef _GLXAPI_SGI_video_sync + { "glXGetVideoSyncSGI", (GLvoid *) glXGetVideoSyncSGI }, + { "glXWaitVideoSyncSGI", (GLvoid *) glXWaitVideoSyncSGI }, +#endif + +#ifdef _GLXAPI_MESA_copy_sub_buffer + { "glXCopySubBufferMESA", (GLvoid *) glXCopySubBufferMESA }, +#endif + +#ifdef _GLXAPI_MESA_release_buffers + { "glXReleaseBuffersMESA", (GLvoid *) glXReleaseBuffersMESA }, +#endif + +#ifdef _GLXAPI_MESA_pixmap_colormap + { "glXCreateGLXPixmapMESA", (GLvoid *) glXCreateGLXPixmapMESA }, +#endif + +#ifdef _GLXAPI_MESA_set_3dfx_mode + { "glXSet3DfxModeMESA", (GLvoid *) glXSet3DfxModeMESA }, +#endif + + { NULL, NULL } /* end of list */ +}; -#ifdef GLX_MESA_set_3dfx_mode -GLboolean glXSet3DfxModeMESA( GLint mode ) + +/* + * Return address of named glX function, or NULL if not found. + */ +const GLvoid * +_glxapi_get_proc_address(const char *funcName) { -#ifdef REALGLX - return GL_FALSE; -#else - return Fake_glXSet3DfxModeMESA( mode ); -#endif -} -#endif - - - -#if 0 /* spec for this not finalized yet */ -void (*glXGetProcAddressEXT( const GLubyte *procName ))() -{ -#ifdef REALGLX + GLuint i; + for (i = 0; GLX_functions[i].Name; i++) { + if (strcmp(GLX_functions[i].Name, funcName) == 0) + return GLX_functions[i].Address; + } return NULL; -#else - return Fake_glXGetProcAddress( procName ); -#endif } -#endif