/* $XFree86: xc/programs/Xserver/GL/mesa/src/X/xf86glx.c,v 1.19 2003/07/16 01:38:27 dawes Exp $ */
/**************************************************************************

Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
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, sub license, 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 (including the
next paragraph) 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 NON-INFRINGEMENT.
IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS 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.

**************************************************************************/

/*
 * Authors:
 *   Kevin E. Martin <kevin@precisioninsight.com>
 *   Brian E. Paul <brian@precisioninsight.com>
 *
 */

#include <config.h>
#define GL_GLEXT_PROTOTYPES
#include <regionstr.h>
#include <resource.h>
#include <GL/gl.h>
#include <GL/glxint.h>
#include <GL/glxtokens.h>
#include <scrnintstr.h>
#include <glxserver.h>
#include <glxscreens.h>
#include <glxdrawable.h>
#include <glxcontext.h>
#include <glxext.h>
#include <glxutil.h>
#include "xf86glxint.h"
#include "context.h"
#include "xmesaP.h"
#include <GL/xf86glx.h>
#include "context.h"

/*
 * This define is for the glcore.h header file.
 * If you add it here, then make sure you also add it in
 * ../../../glx/Imakefile.
 */
#if 0
#define DEBUG
#include <GL/internal/glcore.h>
#undef DEBUG
#else
#include <GL/internal/glcore.h>
#endif

struct _glapi_table __glMesaRenderTable = {
	glNewList,
	glEndList,
	glCallList,
	glCallLists,
	glDeleteLists,
	glGenLists,
	glListBase,
	glBegin,
	glBitmap,
	glColor3b,
	glColor3bv,
	glColor3d,
	glColor3dv,
	glColor3f,
	glColor3fv,
	glColor3i,
	glColor3iv,
	glColor3s,
	glColor3sv,
	glColor3ub,
	glColor3ubv,
	glColor3ui,
	glColor3uiv,
	glColor3us,
	glColor3usv,
	glColor4b,
	glColor4bv,
	glColor4d,
	glColor4dv,
	glColor4f,
	glColor4fv,
	glColor4i,
	glColor4iv,
	glColor4s,
	glColor4sv,
	glColor4ub,
	glColor4ubv,
	glColor4ui,
	glColor4uiv,
	glColor4us,
	glColor4usv,
	glEdgeFlag,
	glEdgeFlagv,
	glEnd,
	glIndexd,
	glIndexdv,
	glIndexf,
	glIndexfv,
	glIndexi,
	glIndexiv,
	glIndexs,
	glIndexsv,
	glNormal3b,
	glNormal3bv,
	glNormal3d,
	glNormal3dv,
	glNormal3f,
	glNormal3fv,
	glNormal3i,
	glNormal3iv,
	glNormal3s,
	glNormal3sv,
	glRasterPos2d,
	glRasterPos2dv,
	glRasterPos2f,
	glRasterPos2fv,
	glRasterPos2i,
	glRasterPos2iv,
	glRasterPos2s,
	glRasterPos2sv,
	glRasterPos3d,
	glRasterPos3dv,
	glRasterPos3f,
	glRasterPos3fv,
	glRasterPos3i,
	glRasterPos3iv,
	glRasterPos3s,
	glRasterPos3sv,
	glRasterPos4d,
	glRasterPos4dv,
	glRasterPos4f,
	glRasterPos4fv,
	glRasterPos4i,
	glRasterPos4iv,
	glRasterPos4s,
	glRasterPos4sv,
	glRectd,
	glRectdv,
	glRectf,
	glRectfv,
	glRecti,
	glRectiv,
	glRects,
	glRectsv,
	glTexCoord1d,
	glTexCoord1dv,
	glTexCoord1f,
	glTexCoord1fv,
	glTexCoord1i,
	glTexCoord1iv,
	glTexCoord1s,
	glTexCoord1sv,
	glTexCoord2d,
	glTexCoord2dv,
	glTexCoord2f,
	glTexCoord2fv,
	glTexCoord2i,
	glTexCoord2iv,
	glTexCoord2s,
	glTexCoord2sv,
	glTexCoord3d,
	glTexCoord3dv,
	glTexCoord3f,
	glTexCoord3fv,
	glTexCoord3i,
	glTexCoord3iv,
	glTexCoord3s,
	glTexCoord3sv,
	glTexCoord4d,
	glTexCoord4dv,
	glTexCoord4f,
	glTexCoord4fv,
	glTexCoord4i,
	glTexCoord4iv,
	glTexCoord4s,
	glTexCoord4sv,
	glVertex2d,
	glVertex2dv,
	glVertex2f,
	glVertex2fv,
	glVertex2i,
	glVertex2iv,
	glVertex2s,
	glVertex2sv,
	glVertex3d,
	glVertex3dv,
	glVertex3f,
	glVertex3fv,
	glVertex3i,
	glVertex3iv,
	glVertex3s,
	glVertex3sv,
	glVertex4d,
	glVertex4dv,
	glVertex4f,
	glVertex4fv,
	glVertex4i,
	glVertex4iv,
	glVertex4s,
	glVertex4sv,
	glClipPlane,
	glColorMaterial,
	glCullFace,
	glFogf,
	glFogfv,
	glFogi,
	glFogiv,
	glFrontFace,
	glHint,
	glLightf,
	glLightfv,
	glLighti,
	glLightiv,
	glLightModelf,
	glLightModelfv,
	glLightModeli,
	glLightModeliv,
	glLineStipple,
	glLineWidth,
	glMaterialf,
	glMaterialfv,
	glMateriali,
	glMaterialiv,
	glPointSize,
	glPolygonMode,
	glPolygonStipple,
	glScissor,
	glShadeModel,
	glTexParameterf,
	glTexParameterfv,
	glTexParameteri,
	glTexParameteriv,
	glTexImage1D,
	glTexImage2D,
	glTexEnvf,
	glTexEnvfv,
	glTexEnvi,
	glTexEnviv,
	glTexGend,
	glTexGendv,
	glTexGenf,
	glTexGenfv,
	glTexGeni,
	glTexGeniv,
	glFeedbackBuffer,
	glSelectBuffer,
	glRenderMode,
	glInitNames,
	glLoadName,
	glPassThrough,
	glPopName,
	glPushName,
	glDrawBuffer,
	glClear,
	glClearAccum,
	glClearIndex,
	glClearColor,
	glClearStencil,
	glClearDepth,
	glStencilMask,
	glColorMask,
	glDepthMask,
	glIndexMask,
	glAccum,
	glDisable,
	glEnable,
	glFinish,
	glFlush,
	glPopAttrib,
	glPushAttrib,
	glMap1d,
	glMap1f,
	glMap2d,
	glMap2f,
	glMapGrid1d,
	glMapGrid1f,
	glMapGrid2d,
	glMapGrid2f,
	glEvalCoord1d,
	glEvalCoord1dv,
	glEvalCoord1f,
	glEvalCoord1fv,
	glEvalCoord2d,
	glEvalCoord2dv,
	glEvalCoord2f,
	glEvalCoord2fv,
	glEvalMesh1,
	glEvalPoint1,
	glEvalMesh2,
	glEvalPoint2,
	glAlphaFunc,
	glBlendFunc,
	glLogicOp,
	glStencilFunc,
	glStencilOp,
	glDepthFunc,
	glPixelZoom,
	glPixelTransferf,
	glPixelTransferi,
	glPixelStoref,
	glPixelStorei,
	glPixelMapfv,
	glPixelMapuiv,
	glPixelMapusv,
	glReadBuffer,
	glCopyPixels,
	glReadPixels,
	glDrawPixels,
	glGetBooleanv,
	glGetClipPlane,
	glGetDoublev,
	glGetError,
	glGetFloatv,
	glGetIntegerv,
	glGetLightfv,
	glGetLightiv,
	glGetMapdv,
	glGetMapfv,
	glGetMapiv,
	glGetMaterialfv,
	glGetMaterialiv,
	glGetPixelMapfv,
	glGetPixelMapuiv,
	glGetPixelMapusv,
	glGetPolygonStipple,
	glGetString,
	glGetTexEnvfv,
	glGetTexEnviv,
	glGetTexGendv,
	glGetTexGenfv,
	glGetTexGeniv,
	glGetTexImage,
	glGetTexParameterfv,
	glGetTexParameteriv,
	glGetTexLevelParameterfv,
	glGetTexLevelParameteriv,
	glIsEnabled,
	glIsList,
	glDepthRange,
	glFrustum,
	glLoadIdentity,
	glLoadMatrixf,
	glLoadMatrixd,
	glMatrixMode,
	glMultMatrixf,
	glMultMatrixd,
	glOrtho,
	glPopMatrix,
	glPushMatrix,
	glRotated,
	glRotatef,
	glScaled,
	glScalef,
	glTranslated,
	glTranslatef,
	glViewport,
	glArrayElement,
	glBindTexture,
	glColorPointer,
	glDisableClientState,
	glDrawArrays,
	glDrawElements,
	glEdgeFlagPointer,
	glEnableClientState,
	glIndexPointer,
	glIndexub,
	glIndexubv,
	glInterleavedArrays,
	glNormalPointer,
	glPolygonOffset,
	glTexCoordPointer,
	glVertexPointer,
	glAreTexturesResident,
	glCopyTexImage1D,
	glCopyTexImage2D,
	glCopyTexSubImage1D,
	glCopyTexSubImage2D,
	glDeleteTextures,
	glGenTextures,
	glGetPointerv,
	glIsTexture,
	glPrioritizeTextures,
	glTexSubImage1D,
	glTexSubImage2D,
	glPopClientAttrib,
	glPushClientAttrib,
	glBlendColor,
	glBlendEquation,
	glDrawRangeElements,
	glColorTable,
	glColorTableParameterfv,
	glColorTableParameteriv,
	glCopyColorTable,
	glGetColorTable,
	glGetColorTableParameterfv,
	glGetColorTableParameteriv,
	glColorSubTable,
	glCopyColorSubTable,
	glConvolutionFilter1D,
	glConvolutionFilter2D,
	glConvolutionParameterf,
	glConvolutionParameterfv,
	glConvolutionParameteri,
	glConvolutionParameteriv,
	glCopyConvolutionFilter1D,
	glCopyConvolutionFilter2D,
	glGetConvolutionFilter,
	glGetConvolutionParameterfv,
	glGetConvolutionParameteriv,
	glGetSeparableFilter,
	glSeparableFilter2D,
	glGetHistogram,
	glGetHistogramParameterfv,
	glGetHistogramParameteriv,
	glGetMinmax,
	glGetMinmaxParameterfv,
	glGetMinmaxParameteriv,
	glHistogram,
	glMinmax,
	glResetHistogram,
	glResetMinmax,
	glTexImage3D,
	glTexSubImage3D,
	glCopyTexSubImage3D,
	glActiveTextureARB,
	glClientActiveTextureARB,
	glMultiTexCoord1dARB,
	glMultiTexCoord1dvARB,
	glMultiTexCoord1fARB,
	glMultiTexCoord1fvARB,
	glMultiTexCoord1iARB,
	glMultiTexCoord1ivARB,
	glMultiTexCoord1sARB,
	glMultiTexCoord1svARB,
	glMultiTexCoord2dARB,
	glMultiTexCoord2dvARB,
	glMultiTexCoord2fARB,
	glMultiTexCoord2fvARB,
	glMultiTexCoord2iARB,
	glMultiTexCoord2ivARB,
	glMultiTexCoord2sARB,
	glMultiTexCoord2svARB,
	glMultiTexCoord3dARB,
	glMultiTexCoord3dvARB,
	glMultiTexCoord3fARB,
	glMultiTexCoord3fvARB,
	glMultiTexCoord3iARB,
	glMultiTexCoord3ivARB,
	glMultiTexCoord3sARB,
	glMultiTexCoord3svARB,
	glMultiTexCoord4dARB,
	glMultiTexCoord4dvARB,
	glMultiTexCoord4fARB,
	glMultiTexCoord4fvARB,
	glMultiTexCoord4iARB,
	glMultiTexCoord4ivARB,
	glMultiTexCoord4sARB,
	glMultiTexCoord4svARB,
	glLoadTransposeMatrixfARB,
	glLoadTransposeMatrixdARB,
	glMultTransposeMatrixfARB,
	glMultTransposeMatrixdARB,
	glSampleCoverageARB,
	glDrawBuffersARB,
	glPolygonOffsetEXT,
	glGetTexFilterFuncSGIS,
	glTexFilterFuncSGIS,
	glGetHistogramEXT,
	glGetHistogramParameterfvEXT,
	glGetHistogramParameterivEXT,
	glGetMinmaxEXT,
	glGetMinmaxParameterfvEXT,
	glGetMinmaxParameterivEXT,
	glGetConvolutionFilterEXT,
	glGetConvolutionParameterfvEXT,
	glGetConvolutionParameterivEXT,
	glGetSeparableFilterEXT,
	glGetColorTableSGI,
	glGetColorTableParameterfvSGI,
	glGetColorTableParameterivSGI,
	glPixelTexGenSGIX,
	glPixelTexGenParameteriSGIS,
	glPixelTexGenParameterivSGIS,
	glPixelTexGenParameterfSGIS,
	glPixelTexGenParameterfvSGIS,
	glGetPixelTexGenParameterivSGIS,
	glGetPixelTexGenParameterfvSGIS,
	glTexImage4DSGIS,
	glTexSubImage4DSGIS,
	glAreTexturesResidentEXT,
	glGenTexturesEXT,
	glIsTextureEXT,
	glDetailTexFuncSGIS,
	glGetDetailTexFuncSGIS,
	glSharpenTexFuncSGIS,
	glGetSharpenTexFuncSGIS,
	glSampleMaskSGIS,
	glSamplePatternSGIS,
	glColorPointerEXT,
	glEdgeFlagPointerEXT,
	glIndexPointerEXT,
	glNormalPointerEXT,
	glTexCoordPointerEXT,
	glVertexPointerEXT,
	glSpriteParameterfSGIX,
	glSpriteParameterfvSGIX,
	glSpriteParameteriSGIX,
	glSpriteParameterivSGIX,
	glPointParameterfEXT,
	glPointParameterfvEXT,
	glGetInstrumentsSGIX,
	glInstrumentsBufferSGIX,
	glPollInstrumentsSGIX,
	glReadInstrumentsSGIX,
	glStartInstrumentsSGIX,
	glStopInstrumentsSGIX,
	glFrameZoomSGIX,
	glTagSampleBufferSGIX,
	glReferencePlaneSGIX,
	glFlushRasterSGIX,
	glGetListParameterfvSGIX,
	glGetListParameterivSGIX,
	glListParameterfSGIX,
	glListParameterfvSGIX,
	glListParameteriSGIX,
	glListParameterivSGIX,
	glFragmentColorMaterialSGIX,
	glFragmentLightfSGIX,
	glFragmentLightfvSGIX,
	glFragmentLightiSGIX,
	glFragmentLightivSGIX,
	glFragmentLightModelfSGIX,
	glFragmentLightModelfvSGIX,
	glFragmentLightModeliSGIX,
	glFragmentLightModelivSGIX,
	glFragmentMaterialfSGIX,
	glFragmentMaterialfvSGIX,
	glFragmentMaterialiSGIX,
	glFragmentMaterialivSGIX,
	glGetFragmentLightfvSGIX,
	glGetFragmentLightivSGIX,
	glGetFragmentMaterialfvSGIX,
	glGetFragmentMaterialivSGIX,
	glLightEnviSGIX,
	glVertexWeightfEXT,
	glVertexWeightfvEXT,
	glVertexWeightPointerEXT,
	glFlushVertexArrayRangeNV,
	glVertexArrayRangeNV,
	glCombinerParameterfvNV,
	glCombinerParameterfNV,
	glCombinerParameterivNV,
	glCombinerParameteriNV,
	glCombinerInputNV,
	glCombinerOutputNV,
	glFinalCombinerInputNV,
	glGetCombinerInputParameterfvNV,
	glGetCombinerInputParameterivNV,
	glGetCombinerOutputParameterfvNV,
	glGetCombinerOutputParameterivNV,
	glGetFinalCombinerInputParameterfvNV,
	glGetFinalCombinerInputParameterivNV,
	glResizeBuffersMESA,
	glWindowPos2dMESA,
	glWindowPos2dvMESA,
	glWindowPos2fMESA,
	glWindowPos2fvMESA,
	glWindowPos2iMESA,
	glWindowPos2ivMESA,
	glWindowPos2sMESA,
	glWindowPos2svMESA,
	glWindowPos3dMESA,
	glWindowPos3dvMESA,
	glWindowPos3fMESA,
	glWindowPos3fvMESA,
	glWindowPos3iMESA,
	glWindowPos3ivMESA,
	glWindowPos3sMESA,
	glWindowPos3svMESA,
	glWindowPos4dMESA,
	glWindowPos4dvMESA,
	glWindowPos4fMESA,
	glWindowPos4fvMESA,
	glWindowPos4iMESA,
	glWindowPos4ivMESA,
	glWindowPos4sMESA,
	glWindowPos4svMESA,
	glBlendFuncSeparateEXT,
	glIndexMaterialEXT,
	glIndexFuncEXT,
	glLockArraysEXT,
	glUnlockArraysEXT,
	glCullParameterdvEXT,
	glCullParameterfvEXT,
	glHintPGI,
	glFogCoordfEXT,
	glFogCoordfvEXT,
	glFogCoorddEXT,
	glFogCoorddvEXT,
	glFogCoordPointerEXT,
	glGetColorTableEXT,
	glGetColorTableParameterivEXT,
	glGetColorTableParameterfvEXT,
	glTbufferMask3DFX,
	glCompressedTexImage3DARB,
	glCompressedTexImage2DARB,
	glCompressedTexImage1DARB,
	glCompressedTexSubImage3DARB,
	glCompressedTexSubImage2DARB,
	glCompressedTexSubImage1DARB,
	glGetCompressedTexImageARB,
	glSecondaryColor3bEXT,
	glSecondaryColor3bvEXT,
	glSecondaryColor3dEXT,
	glSecondaryColor3dvEXT,
	glSecondaryColor3fEXT,
	glSecondaryColor3fvEXT,
	glSecondaryColor3iEXT,
	glSecondaryColor3ivEXT,
	glSecondaryColor3sEXT,
	glSecondaryColor3svEXT,
	glSecondaryColor3ubEXT,
	glSecondaryColor3ubvEXT,
	glSecondaryColor3uiEXT,
	glSecondaryColor3uivEXT,
	glSecondaryColor3usEXT,
	glSecondaryColor3usvEXT,
	glSecondaryColorPointerEXT,
	glAreProgramsResidentNV,
	glBindProgramNV,
	glDeleteProgramsNV,
	glExecuteProgramNV,
	glGenProgramsNV,
	glGetProgramParameterdvNV,
	glGetProgramParameterfvNV,
	glGetProgramivNV,
	glGetProgramStringNV,
	glGetTrackMatrixivNV,
	glGetVertexAttribdvARB,
	glGetVertexAttribfvARB,
	glGetVertexAttribivARB,
	glGetVertexAttribPointervNV,
	glIsProgramNV,
	glLoadProgramNV,
	glProgramParameter4dNV,
	glProgramParameter4dvNV,
	glProgramParameter4fNV,
	glProgramParameter4fvNV,
	glProgramParameters4dvNV,
	glProgramParameters4fvNV,
	glRequestResidentProgramsNV,
	glTrackMatrixNV,
	glVertexAttribPointerNV,
	glVertexAttrib1dARB,
	glVertexAttrib1dvARB,
	glVertexAttrib1fARB,
	glVertexAttrib1fvARB,
	glVertexAttrib1sARB,
	glVertexAttrib1svARB,
	glVertexAttrib2dARB,
	glVertexAttrib2dvARB,
	glVertexAttrib2fARB,
	glVertexAttrib2fvARB,
	glVertexAttrib2sARB,
	glVertexAttrib2svARB,
	glVertexAttrib3dARB,
	glVertexAttrib3dvARB,
	glVertexAttrib3fARB,
	glVertexAttrib3fvARB,
	glVertexAttrib3sARB,
	glVertexAttrib3svARB,
	glVertexAttrib4dARB,
	glVertexAttrib4dvARB,
	glVertexAttrib4fARB,
	glVertexAttrib4fvARB,
	glVertexAttrib4sARB,
	glVertexAttrib4svARB,
	glVertexAttrib4NubARB,
	glVertexAttrib4NubvARB,
	glVertexAttribs1dvNV,
	glVertexAttribs1fvNV,
	glVertexAttribs1svNV,
	glVertexAttribs2dvNV,
	glVertexAttribs2fvNV,
	glVertexAttribs2svNV,
	glVertexAttribs3dvNV,
	glVertexAttribs3fvNV,
	glVertexAttribs3svNV,
	glVertexAttribs4dvNV,
	glVertexAttribs4fvNV,
	glVertexAttribs4svNV,
	glVertexAttribs4ubvNV,
	glPointParameteriNV,
	glPointParameterivNV,
	glMultiDrawArraysEXT,
	glMultiDrawElementsEXT,
	glActiveStencilFaceEXT,
	glDeleteFencesNV,
	glGenFencesNV,
	glIsFenceNV,
	glTestFenceNV,
	glGetFenceivNV,
	glFinishFenceNV,
	glSetFenceNV,
	glVertexAttrib4bvARB,
	glVertexAttrib4ivARB,
	glVertexAttrib4ubvARB,
	glVertexAttrib4usvARB,
	glVertexAttrib4uivARB,
	glVertexAttrib4NbvARB,
	glVertexAttrib4NsvARB,
	glVertexAttrib4NivARB,
	glVertexAttrib4NusvARB,
	glVertexAttrib4NuivARB,
	glVertexAttribPointerARB,
	glEnableVertexAttribArrayARB,
	glDisableVertexAttribArrayARB,
	glProgramStringARB,
	glProgramEnvParameter4dARB,
	glProgramEnvParameter4dvARB,
	glProgramEnvParameter4fARB,
	glProgramEnvParameter4fvARB,
	glProgramLocalParameter4dARB,
	glProgramLocalParameter4dvARB,
	glProgramLocalParameter4fARB,
	glProgramLocalParameter4fvARB,
	glGetProgramEnvParameterdvARB,
	glGetProgramEnvParameterfvARB,
	glGetProgramLocalParameterdvARB,
	glGetProgramLocalParameterfvARB,
	glGetProgramivARB,
	glGetProgramStringARB,
	glProgramNamedParameter4fNV,
	glProgramNamedParameter4dNV,
	glProgramNamedParameter4fvNV,
	glProgramNamedParameter4dvNV,
	glGetProgramNamedParameterfvNV,
	glGetProgramNamedParameterdvNV,
	glBindBufferARB,
	glBufferDataARB,
	glBufferSubDataARB,
	glDeleteBuffersARB,
	glGenBuffersARB,
	glGetBufferParameterivARB,
	glGetBufferPointervARB,
	glGetBufferSubDataARB,
	glIsBufferARB,
	glMapBufferARB,
	glUnmapBufferARB,
	glDepthBoundsEXT,
	glGenQueriesARB,
	glDeleteQueriesARB,
	glIsQueryARB,
	glBeginQueryARB,
	glEndQueryARB,
	glGetQueryivARB,
	glGetQueryObjectivARB,
	glGetQueryObjectuivARB,
	glMultiModeDrawArraysIBM,
	glMultiModeDrawElementsIBM,
	glBlendEquationSeparateEXT,
	glDeleteObjectARB,
	glGetHandleARB,
	glDetachObjectARB,
	glCreateShaderObjectARB,
	glShaderSourceARB,
	glCompileShaderARB,
	glCreateProgramObjectARB,
	glAttachObjectARB,
	glLinkProgramARB,
	glUseProgramObjectARB,
	glValidateProgramARB,
	glUniform1fARB,
	glUniform2fARB,
	glUniform3fARB,
	glUniform4fARB,
	glUniform1iARB,
	glUniform2iARB,
	glUniform3iARB,
	glUniform4iARB,
	glUniform1fvARB,
	glUniform2fvARB,
	glUniform3fvARB,
	glUniform4fvARB,
	glUniform1ivARB,
	glUniform2ivARB,
	glUniform3ivARB,
	glUniform4ivARB,
	glUniformMatrix2fvARB,
	glUniformMatrix3fvARB,
	glUniformMatrix4fvARB,
	glGetObjectParameterfvARB,
	glGetObjectParameterivARB,
	glGetInfoLogARB,
	glGetAttachedObjectsARB,
	glGetUniformLocationARB,
	glGetActiveUniformARB,
	glGetUniformfvARB,
	glGetUniformivARB,
	glGetShaderSourceARB,
	glBindAttribLocationARB,
	glGetActiveAttribARB,
	glGetAttribLocationARB,
	glGetVertexAttribdvNV,
	glGetVertexAttribfvNV,
	glGetVertexAttribivNV,
	glVertexAttrib1dNV,
	glVertexAttrib1dvNV,
	glVertexAttrib1fNV,
	glVertexAttrib1fvNV,
	glVertexAttrib1sNV,
	glVertexAttrib1svNV,
	glVertexAttrib2dNV,
	glVertexAttrib2dvNV,
	glVertexAttrib2fNV,
	glVertexAttrib2fvNV,
	glVertexAttrib2sNV,
	glVertexAttrib2svNV,
	glVertexAttrib3dNV,
	glVertexAttrib3dvNV,
	glVertexAttrib3fNV,
	glVertexAttrib3fvNV,
	glVertexAttrib3sNV,
	glVertexAttrib3svNV,
	glVertexAttrib4dNV,
	glVertexAttrib4dvNV,
	glVertexAttrib4fNV,
	glVertexAttrib4fvNV,
	glVertexAttrib4sNV,
	glVertexAttrib4svNV,
	glVertexAttrib4ubNV,
	glVertexAttrib4ubvNV,
	glGenFragmentShadersATI,
	glBindFragmentShaderATI,
	glDeleteFragmentShaderATI,
	glBeginFragmentShaderATI,
	glEndFragmentShaderATI,
	glPassTexCoordATI,
	glSampleMapATI,
	glColorFragmentOp1ATI,
	glColorFragmentOp2ATI,
	glColorFragmentOp3ATI,
	glAlphaFragmentOp1ATI,
	glAlphaFragmentOp2ATI,
	glAlphaFragmentOp3ATI,
	glSetFragmentShaderConstantATI,
	glIsRenderbufferEXT,
	glBindRenderbufferEXT,
	glDeleteRenderbuffersEXT,
	glGenRenderbuffersEXT,
	glRenderbufferStorageEXT,
	glGetRenderbufferParameterivEXT,
	glIsFramebufferEXT,
	glBindFramebufferEXT,
	glDeleteFramebuffersEXT,
	glGenFramebuffersEXT,
	glCheckFramebufferStatusEXT,
	glFramebufferTexture1DEXT,
	glFramebufferTexture2DEXT,
	glFramebufferTexture3DEXT,
	glFramebufferRenderbufferEXT,
	glGetFramebufferAttachmentParameterivEXT,
	glGenerateMipmapEXT,
	glStencilFuncSeparate,
	glStencilOpSeparate,
	glStencilMaskSeparate,
	glGetQueryObjecti64vEXT,
	glGetQueryObjectui64vEXT,
};

extern __GLXextensionInfo __glDDXExtensionInfo;
extern __GLXscreenInfo __glDDXScreenInfo;

static __MESA_screen  MESAScreens[MAXSCREENS];
static __GLcontext   *MESA_CC        = NULL;

static int                 numConfigs     = 0;
static __GLXvisualConfig  *visualConfigs  = NULL;
static void              **visualPrivates = NULL;


static int count_bits(unsigned int n)
{
   int bits = 0;

   while (n > 0) {
      if (n & 1) bits++;
      n >>= 1;
   }
   return bits;
}


static XMesaVisual find_mesa_visual(int screen, VisualID vid)
{
    XMesaVisual xm_vis = NULL;
    __MESA_screen *pMScr = &MESAScreens[screen];
    int i;

    for (i = 0; i < pMScr->num_vis; i++) {
	if (pMScr->glx_vis[i].vid == vid) {
	    xm_vis = pMScr->xm_vis[i];
	    break;
	}
    }

    return xm_vis;
}


/*
 * In the case the driver defines no GLX visuals we'll use these.
 * Note that for TrueColor and DirectColor visuals, bufferSize is the 
 * sum of redSize, greenSize, blueSize and alphaSize, which may be larger 
 * than the nplanes/rootDepth of the server's X11 visuals
 */
#define NUM_FALLBACK_CONFIGS 5
static __GLXvisualConfig FallbackConfigs[NUM_FALLBACK_CONFIGS] = {
  /* [0] = RGB, double buffered, Z */
  {
    -1,                 /* vid */
    -1,                 /* class */
    True,               /* rgba */
    -1, -1, -1, 0,      /* rgba sizes */
    -1, -1, -1, 0,      /* rgba masks */
     0,  0,  0, 0,      /* rgba accum sizes */
    True,               /* doubleBuffer */
    False,              /* stereo */
    -1,                 /* bufferSize */
    16,                 /* depthSize */
    0,                  /* stencilSize */
    0,                  /* auxBuffers */
    0,                  /* level */
    GLX_NONE,           /* visualRating */
    GLX_NONE,           /* transparentPixel */
    0, 0, 0, 0,         /* transparent rgba color (floats scaled to ints) */
    0                   /* transparentIndex */
  },
  /* [1] = RGB, double buffered, Z, stencil, accum */
  {
    -1,                 /* vid */
    -1,                 /* class */
    True,               /* rgba */
    -1, -1, -1, 0,      /* rgba sizes */
    -1, -1, -1, 0,      /* rgba masks */
    16, 16, 16, 0,      /* rgba accum sizes */
    True,               /* doubleBuffer */
    False,              /* stereo */
    -1,                 /* bufferSize */
    16,                 /* depthSize */
    8,                  /* stencilSize */
    0,                  /* auxBuffers */
    0,                  /* level */
    GLX_NONE,           /* visualRating */
    GLX_NONE,           /* transparentPixel */
    0, 0, 0, 0,         /* transparent rgba color (floats scaled to ints) */
    0                   /* transparentIndex */
  },
  /* [2] = RGB+Alpha, double buffered, Z, stencil, accum */
  {
    -1,                 /* vid */
    -1,                 /* class */
    True,               /* rgba */
    -1, -1, -1, 8,      /* rgba sizes */
    -1, -1, -1, -1,     /* rgba masks */
    16, 16, 16, 16,     /* rgba accum sizes */
    True,               /* doubleBuffer */
    False,              /* stereo */
    -1,                 /* bufferSize */
    16,                 /* depthSize */
    8,                  /* stencilSize */
    0,                  /* auxBuffers */
    0,                  /* level */
    GLX_NONE,           /* visualRating */
    GLX_NONE,           /* transparentPixel */
    0, 0, 0, 0,         /* transparent rgba color (floats scaled to ints) */
    0                   /* transparentIndex */
  },
  /* [3] = RGB+Alpha, single buffered, Z, stencil, accum */
  {
    -1,                 /* vid */
    -1,                 /* class */
    True,               /* rgba */
    -1, -1, -1, 8,      /* rgba sizes */
    -1, -1, -1, -1,     /* rgba masks */
    16, 16, 16, 16,     /* rgba accum sizes */
    False,              /* doubleBuffer */
    False,              /* stereo */
    -1,                 /* bufferSize */
    16,                 /* depthSize */
    8,                  /* stencilSize */
    0,                  /* auxBuffers */
    0,                  /* level */
    GLX_NONE,           /* visualRating */
    GLX_NONE,           /* transparentPixel */
    0, 0, 0, 0,         /* transparent rgba color (floats scaled to ints) */
    0                   /* transparentIndex */
  },
  /* [4] = CI, double buffered, Z */
  {
    -1,                 /* vid */
    -1,                 /* class */
    False,              /* rgba? (false = color index) */
    -1, -1, -1, 0,      /* rgba sizes */
    -1, -1, -1, 0,      /* rgba masks */
     0,  0,  0, 0,      /* rgba accum sizes */
    True,               /* doubleBuffer */
    False,              /* stereo */
    -1,                 /* bufferSize */
    16,                 /* depthSize */
    0,                  /* stencilSize */
    0,                  /* auxBuffers */
    0,                  /* level */
    GLX_NONE,           /* visualRating */
    GLX_NONE,           /* transparentPixel */
    0, 0, 0, 0,         /* transparent rgba color (floats scaled to ints) */
    0                   /* transparentIndex */
  },
};

void *__glXMalloc(size_t size) __attribute__((weak));
void *__glXCalloc(size_t numElements, size_t elementSize) __attribute__((weak));
void *__glXRealloc(void *addr, size_t newSize) __attribute__((weak));
void __glXFree(void *addr) __attribute__((weak));

void *
__glXMalloc(size_t size)
{
    void *addr;

    if (size == 0) {
	return NULL;
    }
    addr = (void *) xalloc(size);
    if (addr == NULL) {
	/* XXX: handle out of memory error */
	return NULL;
    }
    return addr;
}

void *
__glXCalloc(size_t numElements, size_t elementSize)
{
    void *addr;
    size_t size;

    if ((numElements == 0) || (elementSize == 0)) {
	return NULL;
    }
    size = numElements * elementSize;
    addr = (void *) xalloc(size);
    if (addr == NULL) {
	/* XXX: handle out of memory error */
	return NULL;
    }
    __glXMemset(addr, 0, size);
    return addr;
}

void *
__glXRealloc(void *addr, size_t newSize)
{
    void *newAddr;

    if (addr) {
	if (newSize == 0) {
	    xfree(addr);
	    return NULL;
	} else {
	    newAddr = xrealloc(addr, newSize);
	}
    } else {
	if (newSize == 0) {
	    return NULL;
	} else {
	    newAddr = xalloc(newSize);
	}
    }
    if (newAddr == NULL) {
	return NULL;	/* XXX: out of memory */
    }

    return newAddr;
}

void
__glXFree(void *addr)
{
    if (addr) {
	xfree(addr);
    }
}

static Bool init_visuals(int *nvisualp, VisualPtr *visualp,
			 VisualID *defaultVisp,
			 int ndepth, DepthPtr pdepth,
			 int rootDepth)
{
    int numRGBconfigs;
    int numCIconfigs;
    int numVisuals = *nvisualp;
    int numNewVisuals;
    int numNewConfigs;
    VisualPtr pVisual = *visualp;
    VisualPtr pVisualNew = NULL;
    VisualID *orig_vid = NULL;
    __GLXvisualConfig *glXVisualPtr = NULL;
    __GLXvisualConfig *pNewVisualConfigs = NULL;
    void **glXVisualPriv;
    void **pNewVisualPriv;
    int found_default;
    int i, j, k;

    if (numConfigs > 0)
        numNewConfigs = numConfigs;
    else
        numNewConfigs = NUM_FALLBACK_CONFIGS;

    /* Alloc space for the list of new GLX visuals */
    pNewVisualConfigs = (__GLXvisualConfig *)
                     __glXMalloc(numNewConfigs * sizeof(__GLXvisualConfig));
    if (!pNewVisualConfigs) {
	return FALSE;
    }

    /* Alloc space for the list of new GLX visual privates */
    pNewVisualPriv = (void **) __glXMalloc(numNewConfigs * sizeof(void *));
    if (!pNewVisualPriv) {
	__glXFree(pNewVisualConfigs);
	return FALSE;
    }

    /*
    ** If SetVisualConfigs was not called, then use default GLX
    ** visual configs.
    */
    if (numConfigs == 0) {
	memcpy(pNewVisualConfigs, FallbackConfigs,
               NUM_FALLBACK_CONFIGS * sizeof(__GLXvisualConfig));
	memset(pNewVisualPriv, 0, NUM_FALLBACK_CONFIGS * sizeof(void *));
    }
    else {
        /* copy driver's visual config info */
        for (i = 0; i < numConfigs; i++) {
            pNewVisualConfigs[i] = visualConfigs[i];
            pNewVisualPriv[i] = visualPrivates[i];
        }
    }

    /* Count the number of RGB and CI visual configs */
    numRGBconfigs = 0;
    numCIconfigs = 0;
    for (i = 0; i < numNewConfigs; i++) {
	if (pNewVisualConfigs[i].rgba)
	    numRGBconfigs++;
	else
	    numCIconfigs++;
    }

    /* Count the total number of visuals to compute */
    numNewVisuals = 0;
    for (i = 0; i < numVisuals; i++) {
        numNewVisuals +=
	    (pVisual[i].class == TrueColor || pVisual[i].class == DirectColor)
	    ? numRGBconfigs : numCIconfigs;
    }

    /* Reset variables for use with the next screen/driver's visual configs */
    visualConfigs = NULL;
    numConfigs = 0;

    /* Alloc temp space for the list of orig VisualIDs for each new visual */
    orig_vid = (VisualID *)__glXMalloc(numNewVisuals * sizeof(VisualID));
    if (!orig_vid) {
	__glXFree(pNewVisualPriv);
	__glXFree(pNewVisualConfigs);
	return FALSE;
    }

    /* Alloc space for the list of glXVisuals */
    glXVisualPtr = (__GLXvisualConfig *)__glXMalloc(numNewVisuals *
						    sizeof(__GLXvisualConfig));
    if (!glXVisualPtr) {
	__glXFree(orig_vid);
	__glXFree(pNewVisualPriv);
	__glXFree(pNewVisualConfigs);
	return FALSE;
    }

    /* Alloc space for the list of glXVisualPrivates */
    glXVisualPriv = (void **)__glXMalloc(numNewVisuals * sizeof(void *));
    if (!glXVisualPriv) {
	__glXFree(glXVisualPtr);
	__glXFree(orig_vid);
	__glXFree(pNewVisualPriv);
	__glXFree(pNewVisualConfigs);
	return FALSE;
    }

    /* Alloc space for the new list of the X server's visuals */
    pVisualNew = (VisualPtr)__glXMalloc(numNewVisuals * sizeof(VisualRec));
    if (!pVisualNew) {
	__glXFree(glXVisualPriv);
	__glXFree(glXVisualPtr);
	__glXFree(orig_vid);
	__glXFree(pNewVisualPriv);
	__glXFree(pNewVisualConfigs);
	return FALSE;
    }

    /* Initialize the new visuals */
    found_default = FALSE;
    for (i = j = 0; i < numVisuals; i++) {
        int is_rgb = (pVisual[i].class == TrueColor ||
		      pVisual[i].class == DirectColor);

	for (k = 0; k < numNewConfigs; k++) {
	    if (pNewVisualConfigs[k].rgba != is_rgb)
		continue;

	    /* Initialize the new visual */
	    pVisualNew[j] = pVisual[i];
	    pVisualNew[j].vid = FakeClientID(0);

	    /* Check for the default visual */
	    if (!found_default && pVisual[i].vid == *defaultVisp) {
		*defaultVisp = pVisualNew[j].vid;
		found_default = TRUE;
	    }

	    /* Save the old VisualID */
	    orig_vid[j] = pVisual[i].vid;

	    /* Initialize the glXVisual */
	    glXVisualPtr[j] = pNewVisualConfigs[k];
	    glXVisualPtr[j].vid = pVisualNew[j].vid;

	    /*
	     * If the class is -1, then assume the X visual information
	     * is identical to what GLX needs, and take them from the X
	     * visual.  NOTE: if class != -1, then all other fields MUST
	     * be initialized.
	     */
	    if (glXVisualPtr[j].class == -1) {
		glXVisualPtr[j].class      = pVisual[i].class;
		glXVisualPtr[j].redSize    = count_bits(pVisual[i].redMask);
		glXVisualPtr[j].greenSize  = count_bits(pVisual[i].greenMask);
		glXVisualPtr[j].blueSize   = count_bits(pVisual[i].blueMask);
		glXVisualPtr[j].alphaSize  = glXVisualPtr[j].alphaSize;
		glXVisualPtr[j].redMask    = pVisual[i].redMask;
		glXVisualPtr[j].greenMask  = pVisual[i].greenMask;
		glXVisualPtr[j].blueMask   = pVisual[i].blueMask;
		glXVisualPtr[j].alphaMask  = glXVisualPtr[j].alphaMask;
#ifdef COMPOSITE
		if (pVisual[i].nplanes == 32 && glXVisualPtr[j].alphaSize == 0)
		{
		    glXVisualPtr[j].alphaSize  = 8;
		    glXVisualPtr[j].alphaMask  = ~(pVisual[i].redMask   |
						   pVisual[i].greenMask |
						   pVisual[i].blueMask);
		}
#endif
		if (is_rgb) {
		    glXVisualPtr[j].bufferSize = glXVisualPtr[j].redSize +
		                                 glXVisualPtr[j].greenSize +
		                                 glXVisualPtr[j].blueSize +
		                                 glXVisualPtr[j].alphaSize;
		} else {
		    glXVisualPtr[j].bufferSize = rootDepth;
		}
#ifdef COMPOSITE
		if (pVisual[i].nplanes == 32)
		    glXVisualPtr[j].visualRating = GLX_NON_CONFORMANT_CONFIG;
#endif
	    }

	    /* Save the device-dependent private for this visual */
	    glXVisualPriv[j] = pNewVisualPriv[k];

	    j++;
	}
    }

    assert(j <= numNewVisuals);

    /* Save the GLX visuals in the screen structure */
    MESAScreens[screenInfo.numScreens-1].num_vis = numNewVisuals;
    MESAScreens[screenInfo.numScreens-1].glx_vis = glXVisualPtr;
    MESAScreens[screenInfo.numScreens-1].private = glXVisualPriv;

    /* Set up depth's VisualIDs */
    for (i = 0; i < ndepth; i++) {
	int numVids = 0;
	VisualID *pVids = NULL;
	int k, n = 0;

	/* Count the new number of VisualIDs at this depth */
	for (j = 0; j < pdepth[i].numVids; j++)
	    for (k = 0; k < numNewVisuals; k++)
		if (pdepth[i].vids[j] == orig_vid[k])
		    numVids++;

	/* Allocate a new list of VisualIDs for this depth */
	pVids = (VisualID *)__glXMalloc(numVids * sizeof(VisualID));

	/* Initialize the new list of VisualIDs for this depth */
	for (j = 0; j < pdepth[i].numVids; j++)
	    for (k = 0; k < numNewVisuals; k++)
		if (pdepth[i].vids[j] == orig_vid[k])
		    pVids[n++] = pVisualNew[k].vid;

	/* Update this depth's list of VisualIDs */
	__glXFree(pdepth[i].vids);
	pdepth[i].vids = pVids;
	pdepth[i].numVids = numVids;
    }

    /* Update the X server's visuals */
    *nvisualp = numNewVisuals;
    *visualp = pVisualNew;

    /* Free the old list of the X server's visuals */
    __glXFree(pVisual);

    /* Clean up temporary allocations */
    __glXFree(orig_vid);
    __glXFree(pNewVisualPriv);
    __glXFree(pNewVisualConfigs);

    /* Free the private list created by DDX HW driver */
    if (visualPrivates)
        xfree(visualPrivates);
    visualPrivates = NULL;

    return TRUE;
}

void __MESA_setVisualConfigs(int nconfigs, __GLXvisualConfig *configs,
			     void **privates)
{
    numConfigs = nconfigs;
    visualConfigs = configs;
    visualPrivates = privates;
}

Bool __MESA_initVisuals(VisualPtr *visualp, DepthPtr *depthp,
			int *nvisualp, int *ndepthp, int *rootDepthp,
			VisualID *defaultVisp, unsigned long sizes,
			int bitsPerRGB)
{
    /*
     * Setup the visuals supported by this particular screen.
     */
    return init_visuals(nvisualp, visualp, defaultVisp,
			*ndepthp, *depthp, *rootDepthp);
}

static void fixup_visuals(int screen)
{
    ScreenPtr pScreen = screenInfo.screens[screen];
    __MESA_screen *pMScr = &MESAScreens[screen];
    __GLXvisualConfig *pGLXVis  = pMScr->glx_vis;
    VisualPtr pVis;
    int i, j;

    for (i = 0; i < pMScr->num_vis; i++, pGLXVis++) {
	pVis = pScreen->visuals;

	/* Find a visual that matches the GLX visual's class and size */
	for (j = 0; j < pScreen->numVisuals; j++, pVis++) {
	    if (pVis->class == pGLXVis->class &&
		(pVis->nplanes == (pGLXVis->bufferSize - pGLXVis->alphaSize)
#ifdef COMPOSITE
		 || (pVis->nplanes == pGLXVis->bufferSize)
#endif
		    )) {

		/* Fixup the masks */
		pGLXVis->redMask   = pVis->redMask;
		pGLXVis->greenMask = pVis->greenMask;
		pGLXVis->blueMask  = pVis->blueMask;

		/* Recalc the sizes */
		pGLXVis->redSize   = count_bits(pGLXVis->redMask);
		pGLXVis->greenSize = count_bits(pGLXVis->greenMask);
		pGLXVis->blueSize  = count_bits(pGLXVis->blueMask);
	    }
	}
    }
}

static void init_screen_visuals(int screen)
{
    ScreenPtr pScreen = screenInfo.screens[screen];
    __GLXvisualConfig *pGLXVis = MESAScreens[screen].glx_vis;
    XMesaVisual *pXMesaVisual;
    VisualPtr pVis;
    int *used;
    int i, j;

    /* Alloc space for the list of XMesa visuals */
    pXMesaVisual = (XMesaVisual *)__glXMalloc(MESAScreens[screen].num_vis *
					      sizeof(XMesaVisual));
    __glXMemset(pXMesaVisual, 0,
		MESAScreens[screen].num_vis * sizeof(XMesaVisual));

    used = (int *)__glXMalloc(pScreen->numVisuals * sizeof(int));
    __glXMemset(used, 0, pScreen->numVisuals * sizeof(int));

    for (i = 0; i < MESAScreens[screen].num_vis; i++, pGLXVis++) {

	pVis = pScreen->visuals;
	for (j = 0; j < pScreen->numVisuals; j++, pVis++) {

	    if (pVis->class == pGLXVis->class &&
		(pVis->nplanes == (pGLXVis->bufferSize - pGLXVis->alphaSize)
#ifdef COMPOSITE
		 || (pVis->nplanes == pGLXVis->bufferSize)
#endif
		    ) && !used[j]) {

		if (pVis->redMask   == pGLXVis->redMask &&
		    pVis->greenMask == pGLXVis->greenMask &&
		    pVis->blueMask  == pGLXVis->blueMask) {

		    /* Create the XMesa visual */
		    pXMesaVisual[i] =
                         XMesaCreateVisual(pScreen,
					   pVis,
					   pGLXVis->rgba,
					   (pGLXVis->alphaSize > 0),
					   pGLXVis->doubleBuffer,
					   pGLXVis->stereo,
					   GL_TRUE, /* ximage_flag */
					   pGLXVis->depthSize,
					   pGLXVis->stencilSize,
					   pGLXVis->accumRedSize,
					   pGLXVis->accumGreenSize,
					   pGLXVis->accumBlueSize,
					   pGLXVis->accumAlphaSize,
                                           0,  /* numSamples */
					   pGLXVis->level,
                                           pGLXVis->visualRating );
		    /* Set the VisualID */
		    pGLXVis->vid = pVis->vid;

		    /* Mark this visual used */
		    used[j] = 1;

		    break;
		}
	    }
	}
    }

    __glXFree(used);

    MESAScreens[screen].xm_vis = pXMesaVisual;
}

Bool __MESA_screenProbe(int screen)
{
    /*
     * Set up the current screen's visuals.
     */
    __glDDXScreenInfo.pGlxVisual = MESAScreens[screen].glx_vis;
    __glDDXScreenInfo.pVisualPriv = MESAScreens[screen].private;
    __glDDXScreenInfo.numVisuals =
	__glDDXScreenInfo.numUsableVisuals = MESAScreens[screen].num_vis;

    /*
     * Set the current screen's createContext routine.  This could be
     * wrapped by a DDX GLX context creation routine.
     */
    __glDDXScreenInfo.createContext = __MESA_createContext;

    /*
     * The ordering of the rgb compenents might have been changed by the
     * driver after mi initialized them.
     */
    fixup_visuals(screen);

    /*
     * Find the GLX visuals that are supported by this screen and create
     * XMesa's visuals.
     */
    init_screen_visuals(screen);

    return TRUE;
}

extern void __MESA_resetExtension(void)
{
    int i, j;

    XMesaReset();

    for (i = 0; i < screenInfo.numScreens; i++) {
	for (j = 0; j < MESAScreens[i].num_vis; j++) {
	  if (MESAScreens[i].xm_vis[j]) {
	        XMesaDestroyVisual(MESAScreens[i].xm_vis[j]);
		MESAScreens[i].xm_vis[j] = NULL;
	  }
	}
	__glXFree(MESAScreens[i].glx_vis);
	MESAScreens[i].glx_vis = NULL;
	__glXFree(MESAScreens[i].private);
	MESAScreens[i].private = NULL;
	__glXFree(MESAScreens[i].xm_vis);
	MESAScreens[i].xm_vis = NULL;
	MESAScreens[i].num_vis = 0;
    }
    __glDDXScreenInfo.pGlxVisual = NULL;
    MESA_CC = NULL;
}

void __MESA_createBuffer(__GLXdrawablePrivate *glxPriv)
{
    DrawablePtr pDraw = glxPriv->pDraw;
    XMesaVisual xm_vis = find_mesa_visual(pDraw->pScreen->myNum,
					  glxPriv->pGlxVisual->vid);
    __GLdrawablePrivate *glPriv = &glxPriv->glPriv;
    __MESA_buffer buf;

    buf = (__MESA_buffer)__glXMalloc(sizeof(struct __MESA_bufferRec));
    buf->xm_buf = 0;
    buf->pDraw = pDraw;
    buf->xm_vis = xm_vis;

    /* Wrap the front buffer's resize routine */
    buf->fbresize = glPriv->frontBuffer.resize;
    glPriv->frontBuffer.resize = __MESA_resizeBuffers;

    /* Wrap the swap buffers routine */
    buf->fbswap = glxPriv->swapBuffers;
    glxPriv->swapBuffers = __MESA_swapBuffers;

    /* Wrap the render texture routines */
    buf->fbbind = glxPriv->bindBuffers;
    glxPriv->bindBuffers = __MESA_bindBuffers;
    buf->fbrelease = glxPriv->releaseBuffers;
    glxPriv->releaseBuffers = __MESA_releaseBuffers;

    /* Mesa doesn't support render texture on its own */
    glxPriv->texTarget = GLX_NO_TEXTURE_EXT;

    /* Save Mesa's private buffer structure */
    glPriv->private = (void *)buf;
    glPriv->freePrivate = __MESA_destroyBuffer;
}

static void __MESA_allocateBuffer (__GLdrawablePrivate *glPriv)
{
    __MESA_buffer buf = glPriv->private;

    if (!buf->xm_buf)
    {
	/* Create Mesa's buffers */
	if (buf->pDraw->type == DRAWABLE_WINDOW)
	{
	    buf->xm_buf = (void *)
		XMesaCreateWindowBuffer (buf->xm_vis, (WindowPtr) buf->pDraw);
	}
	else
	{
	    buf->xm_buf = (void *)
		XMesaCreatePixmapBuffer (buf->xm_vis, (PixmapPtr) buf->pDraw, 0);
	}
    }
}

GLboolean __MESA_resizeBuffers(__GLdrawableBuffer *buffer,
			       GLint x, GLint y,
			       GLuint width, GLuint height, 
			       __GLdrawablePrivate *glPriv,
			       GLuint bufferMask)
{
    __MESA_buffer buf = (__MESA_buffer)glPriv->private;

    if (buf->xm_buf)
	XMesaResizeBuffers(buf->xm_buf);

    return (*buf->fbresize)(buffer, x, y, width, height, glPriv, bufferMask);
}

GLboolean __MESA_swapBuffers(__GLXdrawablePrivate *glxPriv)
{
    __MESA_buffer buf = (__MESA_buffer)glxPriv->glPriv.private;

    /*
    ** Do not call the wrapped swap buffers routine since Mesa has
    ** already done the swap.
    */
    XMesaSwapBuffers(buf->xm_buf);

    return GL_TRUE;
}

int __MESA_bindBuffers(__GLXdrawablePrivate *glxPriv,
		       int		    buffer)
{
    return FALSE;
}

int __MESA_releaseBuffers(__GLXdrawablePrivate *glxPriv,
			  int		       buffer)
{
    return FALSE;
}

void __MESA_destroyBuffer(__GLdrawablePrivate *glPriv)
{
    __MESA_buffer buf = (__MESA_buffer)glPriv->private;
    __GLXdrawablePrivate *glxPriv = (__GLXdrawablePrivate *)glPriv->other;

    /* Destroy Mesa's buffers */
    if (buf->xm_buf)
	XMesaDestroyBuffer(buf->xm_buf);

    /* Unwrap these routines */
    glxPriv->swapBuffers = buf->fbswap;
    glPriv->frontBuffer.resize = buf->fbresize;

    __glXFree(glPriv->private);
    glPriv->private = NULL;
}

__GLinterface *__MESA_createContext(__GLimports *imports,
				    __GLcontextModes *modes,
				    __GLinterface *shareGC)
{
    __GLcontext *gl_ctx = NULL;
    __GLcontext *m_share = NULL;
    __GLXcontext *glxc = (__GLXcontext *)imports->other;
    XMesaVisual xm_vis;

    if (shareGC) 
       m_share = (__GLcontext *)shareGC;

    xm_vis = find_mesa_visual(glxc->pScreen->myNum, glxc->pGlxVisual->vid);
    if (xm_vis) {
       XMesaContext xmshare = m_share ? m_share->DriverCtx : 0;
       XMesaContext xmctx = XMesaCreateContext(xm_vis, xmshare);
       gl_ctx = xmctx ? &xmctx->mesa : 0;
    }

    if (!gl_ctx)
       return NULL;
	
    gl_ctx->imports = *imports;
    gl_ctx->exports.destroyContext = __MESA_destroyContext;
    gl_ctx->exports.loseCurrent = __MESA_loseCurrent;
    gl_ctx->exports.makeCurrent = __MESA_makeCurrent;
    gl_ctx->exports.shareContext = __MESA_shareContext;
    gl_ctx->exports.copyContext = __MESA_copyContext;
    gl_ctx->exports.forceCurrent = __MESA_forceCurrent;
    gl_ctx->exports.notifyResize = __MESA_notifyResize;
    gl_ctx->exports.notifyDestroy = __MESA_notifyDestroy;
    gl_ctx->exports.notifySwapBuffers = __MESA_notifySwapBuffers;
    gl_ctx->exports.dispatchExec = __MESA_dispatchExec;
    gl_ctx->exports.beginDispatchOverride = __MESA_beginDispatchOverride;
    gl_ctx->exports.endDispatchOverride = __MESA_endDispatchOverride;

    return (__GLinterface *)gl_ctx;
}

GLboolean __MESA_destroyContext(__GLcontext *gc)
{
    XMesaContext xmesa = (XMesaContext) gc->DriverCtx;
    XMesaDestroyContext( xmesa );
    return GL_TRUE;
}

GLboolean __MESA_loseCurrent(__GLcontext *gc)
{
    XMesaContext xmesa = (XMesaContext) gc->DriverCtx;
    MESA_CC = NULL;
    GlxFlushContextCache ();
    return XMesaLoseCurrent(xmesa);
}

GLboolean __MESA_makeCurrent(__GLcontext *gc)
{
    __GLdrawablePrivate *drawPriv = gc->imports.getDrawablePrivate( gc );
    __MESA_buffer drawBuf = (__MESA_buffer)drawPriv->private;
    __GLdrawablePrivate *readPriv = gc->imports.getReadablePrivate( gc );
    __MESA_buffer readBuf = (__MESA_buffer)readPriv->private;
    XMesaContext xmesa = (XMesaContext) gc->DriverCtx;

    if (!drawBuf->xm_buf)
	__MESA_allocateBuffer (drawPriv);

    if (!readBuf->xm_buf)
	__MESA_allocateBuffer (readPriv);

    MESA_CC = gc;
    return XMesaMakeCurrent2(xmesa, drawBuf->xm_buf, readBuf->xm_buf);
}

GLboolean __MESA_shareContext(__GLcontext *gc, __GLcontext *gcShare)
{
    /* NOT_DONE */
    /* XXX I don't see where/how this could ever be called */
    ErrorF("__MESA_shareContext\n");
    return GL_FALSE;
}

GLboolean __MESA_copyContext(__GLcontext *dst, const __GLcontext *src,
			     GLuint mask)
{
    XMesaContext xm_dst = (XMesaContext) dst->DriverCtx;
    const XMesaContext xm_src = (const XMesaContext) src->DriverCtx;
    _mesa_copy_context(&xm_src->mesa, &xm_dst->mesa, mask);
    return GL_TRUE;
}

GLboolean __MESA_forceCurrent(__GLcontext *gc)
{
    XMesaContext xmesa = (XMesaContext) gc->DriverCtx;
    MESA_CC = gc;
    GlxSetRenderTables (&__glMesaRenderTable);
    return XMesaForceCurrent(xmesa);
}

GLboolean __MESA_notifyResize(__GLcontext *gc)
{
    /* NOT_DONE */
    ErrorF("__MESA_notifyResize\n");
    return GL_FALSE;
}

void __MESA_notifyDestroy(__GLcontext *gc)
{
    /* NOT_DONE */
    ErrorF("__MESA_notifyDestroy\n");
    return;
}

void __MESA_notifySwapBuffers(__GLcontext *gc)
{
    _mesa_notifySwapBuffers(gc);
}

struct __GLdispatchStateRec *__MESA_dispatchExec(__GLcontext *gc)
{
    /* NOT_DONE */
    ErrorF("__MESA_dispatchExec\n");
    return NULL;
}

void __MESA_beginDispatchOverride(__GLcontext *gc)
{
    /* NOT_DONE */
    ErrorF("__MESA_beginDispatchOverride\n");
    return;
}

void __MESA_endDispatchOverride(__GLcontext *gc)
{
    /* NOT_DONE */
    ErrorF("__MESA_endDispatchOverride\n");
    return;
}



__GLXextensionInfo __glDDXExtensionInfo __attribute__((weak)) = {
  GL_CORE_MESA,
  __MESA_resetExtension,
  __MESA_initVisuals,
  __MESA_setVisualConfigs
};

__GLXscreenInfo __glDDXScreenInfo __attribute__((weak)) = {
  __MESA_screenProbe,   /* Must be generic and handle all screens */
  __MESA_createContext, /* Substitute screen's createContext routine */
  __MESA_createBuffer,  /* Substitute screen's createBuffer routine */
  NULL,
  NULL,
  0,
  0,
  "Vendor String",
  "Version String",
  "Extensions String",
  NULL
};

