blob: 1e12dea579ea9addef32cd31090edc49699a7449 [file] [log] [blame]
/* $Id: glxapi.c,v 1.7 1999/11/25 17:37:49 brianp Exp $ */
/*
* Mesa 3-D graphics library
* Version: 3.1
*
* Copyright (C) 1999 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
* BRIAN PAUL 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.
*/
/*
* 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.
*/
#ifdef HAVE_CONFIG_H
#include "conf.h"
#endif
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include "GL/glx.h"
#include "fakeglx.h"
#include "realglx.h"
#ifdef REALGLX
static Display *CurrentDisplay = NULL;
#endif
/*
* 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.
*/
static GLboolean display_has_glx( Display *dpy )
{
/* TODO: we should use a lookup table to avoid calling XQueryExtension
* every time.
*/
int ignore;
if (XQueryExtension( dpy, "GLX", &ignore, &ignore, &ignore )) {
return GL_TRUE;
}
else {
return GL_FALSE;
}
}
XVisualInfo *glXChooseVisual( Display *dpy, int screen, int *list )
{
#ifdef REALGLX
if (display_has_glx(dpy))
return Real_glXChooseVisual( dpy, screen, list );
else
#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;
}
}
else {
if (Fake_glXMakeCurrent( dpy, drawable, ctx )) {
CurrentDisplay = dpy;
return True;
}
else {
return False;
}
}
#else
return Fake_glXMakeCurrent( dpy, drawable, ctx );
#endif
}
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();
}
/*
* GLX 1.3 and later
* XXX these are just no-op stubs for now.
*/
GLXFBConfig glXChooseFBConfig( Display *dpy, int screen,
const int *attribList, int *nitems )
{
(void) dpy;
(void) screen;
(void) attribList;
(void) nitems;
return 0;
}
int glXGetFBConfigAttrib( Display *dpy, GLXFBConfig config,
int attribute, int *value )
{
(void) dpy;
(void) config;
(void) attribute;
(void) value;
return 0;
}
XVisualInfo *glXGetVisualFromFBConfig( Display *dpy, GLXFBConfig config )
{
(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))
return 0;
else
#endif
return Fake_glXCreateGLXPixmapMESA( dpy, visinfo, pixmap, cmap );
}
#endif
#ifdef GLX_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++;
return 0;
}
/*
* Again, this is really just a stub function.
*/
int glXWaitVideoSyncSGI(int divisor, int remainder, unsigned int *count)
{
static unsigned int counter = 0;
while (counter % divisor != remainder)
counter++;
*count = counter;
return 0;
}
#endif
#ifdef GLX_MESA_set_3dfx_mode
GLboolean glXSet3DfxModeMESA( GLint mode )
{
#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
return NULL;
#else
return Fake_glXGetProcAddress( procName );
#endif
}
#endif