1 /* $Id: glxapi.c,v 1.21 2001/05/24 00:00:57 brianp Exp $ */
4 * Mesa 3-D graphics library
7 * Copyright (C) 1999-2000 Brian Paul All Rights Reserved.
9 * Permission is hereby granted, free of charge, to any person obtaining a
10 * copy of this software and associated documentation files (the "Software"),
11 * to deal in the Software without restriction, including without limitation
12 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 * and/or sell copies of the Software, and to permit persons to whom the
14 * Software is furnished to do so, subject to the following conditions:
16 * The above copyright notice and this permission notice shall be included
17 * in all copies or substantial portions of the Software.
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
23 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 * This is the GLX API dispatcher. Calls to the glX* functions are
30 * either routed to real (SGI / Utah) GLX encoders or to Mesa's
39 /*#include <dlfcn.h>*/ /* XXX not portable? */
45 * XXX - this really shouldn't be here.
46 * Instead, add -DUSE_MESA_GLX to the compiler flags when needed.
48 #define USE_MESA_GLX 1
51 /* Rather than include possibly non-existant headers... */
53 extern struct _glxapi_table
*_sgi_GetGLXDispatchTable(void);
56 extern struct _glxapi_table
*_utah_GetGLXDispatchTable(void);
59 extern struct _glxapi_table
*_mesa_GetGLXDispatchTable(void);
64 struct display_dispatch
{
66 struct _glxapi_table
*Table
;
67 struct display_dispatch
*Next
;
70 static struct display_dispatch
*DispatchList
= NULL
;
73 /* Display -> Dispatch caching */
74 static Display
*prevDisplay
= NULL
;
75 static struct _glxapi_table
*prevTable
= NULL
;
78 static struct _glxapi_table
*
79 get_dispatch(Display
*dpy
)
84 /* search list of display/dispatch pairs for this display */
86 const struct display_dispatch
*d
= DispatchList
;
91 return d
->Table
; /* done! */
97 /* A new display, determine if we should use real GLX (SGI / Utah)
98 * or Mesa's pseudo-GLX.
101 struct _glxapi_table
*t
= NULL
;
103 #if defined(USE_SGI_GLX) || defined(USE_UTAH_GLX)
104 if (!getenv("MESA_FORCE_SOFTX")) {
106 if (XQueryExtension( dpy
, "GLX", &ignore
, &ignore
, &ignore
)) {
107 /* the X server has the GLX extension */
108 #if defined(USE_SGI_GLX)
109 t
= _sgi_GetGLXDispatchTable();
110 #elif defined(USE_UTAH_GLX)
111 t
= _utah_GetGLXDispatchTable();
117 #if defined(USE_MESA_GLX)
119 t
= _mesa_GetGLXDispatchTable();
120 assert(t
); /* this has to work */
125 struct display_dispatch
*d
;
126 d
= (struct display_dispatch
*) malloc(sizeof(struct display_dispatch
));
130 /* insert at head of list */
131 d
->Next
= DispatchList
;
141 /* If we get here that means we can't use real GLX on this display
142 * and the Mesa pseudo-GLX software renderer wasn't compiled in.
143 * Or, we ran out of memory!
149 #define GET_DISPATCH(DPY, TABLE) \
150 if (DPY == prevDisplay) { \
157 TABLE = get_dispatch(DPY); \
163 /* Set by glXMakeCurrent() and glXMakeContextCurrent() only */
164 static Display
*CurrentDisplay
= NULL
;
165 static GLXContext CurrentContext
= 0;
166 static GLXDrawable CurrentDrawable
= 0;
167 static GLXDrawable CurrentReadDrawable
= 0;
172 * GLX API entrypoints
176 XVisualInfo
*glXChooseVisual(Display
*dpy
, int screen
, int *list
)
178 struct _glxapi_table
*t
;
179 GET_DISPATCH(dpy
, t
);
182 return (t
->ChooseVisual
)(dpy
, screen
, list
);
186 void glXCopyContext(Display
*dpy
, GLXContext src
, GLXContext dst
, unsigned long mask
)
188 struct _glxapi_table
*t
;
189 GET_DISPATCH(dpy
, t
);
192 (t
->CopyContext
)(dpy
, src
, dst
, mask
);
196 GLXContext
glXCreateContext(Display
*dpy
, XVisualInfo
*visinfo
, GLXContext shareList
, Bool direct
)
198 struct _glxapi_table
*t
;
199 GET_DISPATCH(dpy
, t
);
202 return (t
->CreateContext
)(dpy
, visinfo
, shareList
, direct
);
206 GLXPixmap
glXCreateGLXPixmap(Display
*dpy
, XVisualInfo
*visinfo
, Pixmap pixmap
)
208 struct _glxapi_table
*t
;
209 GET_DISPATCH(dpy
, t
);
212 return (t
->CreateGLXPixmap
)(dpy
, visinfo
, pixmap
);
216 void glXDestroyContext(Display
*dpy
, GLXContext ctx
)
218 struct _glxapi_table
*t
;
219 GET_DISPATCH(dpy
, t
);
222 (t
->DestroyContext
)(dpy
, ctx
);
226 void glXDestroyGLXPixmap(Display
*dpy
, GLXPixmap pixmap
)
228 struct _glxapi_table
*t
;
229 GET_DISPATCH(dpy
, t
);
232 (t
->DestroyGLXPixmap
)(dpy
, pixmap
);
236 int glXGetConfig(Display
*dpy
, XVisualInfo
*visinfo
, int attrib
, int *value
)
238 struct _glxapi_table
*t
;
239 GET_DISPATCH(dpy
, t
);
241 return GLX_NO_EXTENSION
;
242 return (t
->GetConfig
)(dpy
, visinfo
, attrib
, value
);
246 GLXContext
glXGetCurrentContext(void)
248 return CurrentContext
;
252 GLXDrawable
glXGetCurrentDrawable(void)
254 return CurrentDrawable
;
258 Bool
glXIsDirect(Display
*dpy
, GLXContext ctx
)
260 struct _glxapi_table
*t
;
261 GET_DISPATCH(dpy
, t
);
264 return (t
->IsDirect
)(dpy
, ctx
);
268 Bool
glXMakeCurrent(Display
*dpy
, GLXDrawable drawable
, GLXContext ctx
)
271 struct _glxapi_table
*t
;
272 GET_DISPATCH(dpy
, t
);
275 b
= (*t
->MakeCurrent
)(dpy
, drawable
, ctx
);
277 CurrentDisplay
= dpy
;
278 CurrentContext
= ctx
;
279 CurrentDrawable
= drawable
;
280 CurrentReadDrawable
= drawable
;
286 Bool
glXQueryExtension(Display
*dpy
, int *errorb
, int *event
)
288 struct _glxapi_table
*t
;
289 GET_DISPATCH(dpy
, t
);
292 return (t
->QueryExtension
)(dpy
, errorb
, event
);
296 Bool
glXQueryVersion(Display
*dpy
, int *maj
, int *min
)
298 struct _glxapi_table
*t
;
299 GET_DISPATCH(dpy
, t
);
302 return (t
->QueryVersion
)(dpy
, maj
, min
);
306 void glXSwapBuffers(Display
*dpy
, GLXDrawable drawable
)
308 struct _glxapi_table
*t
;
309 GET_DISPATCH(dpy
, t
);
312 (t
->SwapBuffers
)(dpy
, drawable
);
316 void glXUseXFont(Font font
, int first
, int count
, int listBase
)
318 struct _glxapi_table
*t
;
319 GET_DISPATCH(CurrentDisplay
, t
);
322 (t
->UseXFont
)(font
, first
, count
, listBase
);
328 struct _glxapi_table
*t
;
329 GET_DISPATCH(CurrentDisplay
, t
);
338 struct _glxapi_table
*t
;
339 GET_DISPATCH(CurrentDisplay
, t
);
347 #ifdef GLX_VERSION_1_1
349 const char *glXGetClientString(Display
*dpy
, int name
)
351 struct _glxapi_table
*t
;
352 GET_DISPATCH(dpy
, t
);
355 return (t
->GetClientString
)(dpy
, name
);
359 const char *glXQueryExtensionsString(Display
*dpy
, int screen
)
361 struct _glxapi_table
*t
;
362 GET_DISPATCH(dpy
, t
);
365 return (t
->QueryExtensionsString
)(dpy
, screen
);
369 const char *glXQueryServerString(Display
*dpy
, int screen
, int name
)
371 struct _glxapi_table
*t
;
372 GET_DISPATCH(dpy
, t
);
375 return (t
->QueryServerString
)(dpy
, screen
, name
);
382 #ifdef GLX_VERSION_1_2
383 Display
*glXGetCurrentDisplay(void)
385 return CurrentDisplay
;
391 #ifdef GLX_VERSION_1_3
393 GLXFBConfig
*glXChooseFBConfig(Display
*dpy
, int screen
, const int *attribList
, int *nitems
)
395 struct _glxapi_table
*t
;
396 GET_DISPATCH(dpy
, t
);
399 return (t
->ChooseFBConfig
)(dpy
, screen
, attribList
, nitems
);
403 GLXContext
glXCreateNewContext(Display
*dpy
, GLXFBConfig config
, int renderType
, GLXContext shareList
, Bool direct
)
405 struct _glxapi_table
*t
;
406 GET_DISPATCH(dpy
, t
);
409 return (t
->CreateNewContext
)(dpy
, config
, renderType
, shareList
, direct
);
413 GLXPbuffer
glXCreatePbuffer(Display
*dpy
, GLXFBConfig config
, const int *attribList
)
415 struct _glxapi_table
*t
;
416 GET_DISPATCH(dpy
, t
);
419 return (t
->CreatePbuffer
)(dpy
, config
, attribList
);
423 GLXPixmap
glXCreatePixmap(Display
*dpy
, GLXFBConfig config
, Pixmap pixmap
, const int *attribList
)
425 struct _glxapi_table
*t
;
426 GET_DISPATCH(dpy
, t
);
429 return (t
->CreatePixmap
)(dpy
, config
, pixmap
, attribList
);
433 GLXWindow
glXCreateWindow(Display
*dpy
, GLXFBConfig config
, Window win
, const int *attribList
)
435 struct _glxapi_table
*t
;
436 GET_DISPATCH(dpy
, t
);
439 return (t
->CreateWindow
)(dpy
, config
, win
, attribList
);
443 void glXDestroyPbuffer(Display
*dpy
, GLXPbuffer pbuf
)
445 struct _glxapi_table
*t
;
446 GET_DISPATCH(dpy
, t
);
449 (t
->DestroyPbuffer
)(dpy
, pbuf
);
453 void glXDestroyPixmap(Display
*dpy
, GLXPixmap pixmap
)
455 struct _glxapi_table
*t
;
456 GET_DISPATCH(dpy
, t
);
459 (t
->DestroyPixmap
)(dpy
, pixmap
);
463 void glXDestroyWindow(Display
*dpy
, GLXWindow window
)
465 struct _glxapi_table
*t
;
466 GET_DISPATCH(dpy
, t
);
469 (t
->DestroyWindow
)(dpy
, window
);
473 GLXDrawable
glXGetCurrentReadDrawable(void)
475 return CurrentReadDrawable
;
479 int glXGetFBConfigAttrib(Display
*dpy
, GLXFBConfig config
, int attribute
, int *value
)
481 struct _glxapi_table
*t
;
482 GET_DISPATCH(dpy
, t
);
484 return GLX_NO_EXTENSION
;
485 return (t
->GetFBConfigAttrib
)(dpy
, config
, attribute
, value
);
489 GLXFBConfig
*glXGetFBConfigs(Display
*dpy
, int screen
, int *nelements
)
491 struct _glxapi_table
*t
;
492 GET_DISPATCH(dpy
, t
);
495 return (t
->GetFBConfigs
)(dpy
, screen
, nelements
);
498 void glXGetSelectedEvent(Display
*dpy
, GLXDrawable drawable
, unsigned long *mask
)
500 struct _glxapi_table
*t
;
501 GET_DISPATCH(dpy
, t
);
504 (t
->GetSelectedEvent
)(dpy
, drawable
, mask
);
508 XVisualInfo
*glXGetVisualFromFBConfig(Display
*dpy
, GLXFBConfig config
)
510 struct _glxapi_table
*t
;
511 GET_DISPATCH(dpy
, t
);
514 return (t
->GetVisualFromFBConfig
)(dpy
, config
);
518 Bool
glXMakeContextCurrent(Display
*dpy
, GLXDrawable draw
, GLXDrawable read
, GLXContext ctx
)
521 struct _glxapi_table
*t
;
522 GET_DISPATCH(dpy
, t
);
525 b
= (t
->MakeContextCurrent
)(dpy
, draw
, read
, ctx
);
527 CurrentDisplay
= dpy
;
528 CurrentContext
= ctx
;
529 CurrentDrawable
= draw
;
530 CurrentReadDrawable
= read
;
536 int glXQueryContext(Display
*dpy
, GLXContext ctx
, int attribute
, int *value
)
538 struct _glxapi_table
*t
;
539 GET_DISPATCH(dpy
, t
);
542 return 0; /* XXX correct? */
543 return (t
->QueryContext
)(dpy
, ctx
, attribute
, value
);
547 void glXQueryDrawable(Display
*dpy
, GLXDrawable draw
, int attribute
, unsigned int *value
)
549 struct _glxapi_table
*t
;
550 GET_DISPATCH(dpy
, t
);
553 (t
->QueryDrawable
)(dpy
, draw
, attribute
, value
);
557 void glXSelectEvent(Display
*dpy
, GLXDrawable drawable
, unsigned long mask
)
559 struct _glxapi_table
*t
;
560 GET_DISPATCH(dpy
, t
);
563 (t
->SelectEvent
)(dpy
, drawable
, mask
);
566 #endif /* GLX_VERSION_1_3 */
569 #ifdef GLX_SGI_swap_control
571 int glXSwapIntervalSGI(int interval
)
573 struct _glxapi_table
*t
;
574 GET_DISPATCH(CurrentDisplay
, t
);
577 return (t
->SwapIntervalSGI
)(interval
);
583 #ifdef GLX_SGI_video_sync
585 int glXGetVideoSyncSGI(unsigned int *count
)
587 struct _glxapi_table
*t
;
588 GET_DISPATCH(CurrentDisplay
, t
);
591 return (t
->GetVideoSyncSGI
)(count
);
594 int glXWaitVideoSyncSGI(int divisor
, int remainder
, unsigned int *count
)
596 struct _glxapi_table
*t
;
597 GET_DISPATCH(CurrentDisplay
, t
);
600 return (t
->WaitVideoSyncSGI
)(divisor
, remainder
, count
);
606 #ifdef GLX_SGI_make_current_read
608 Bool
glXMakeCurrentReadSGI(Display
*dpy
, GLXDrawable draw
, GLXDrawable read
, GLXContext ctx
)
610 struct _glxapi_table
*t
;
611 GET_DISPATCH(dpy
, t
);
614 return (t
->MakeCurrentReadSGI
)(dpy
, draw
, read
, ctx
);
617 GLXDrawable
glXGetCurrentReadDrawableSGI(void)
619 struct _glxapi_table
*t
;
620 GET_DISPATCH(CurrentDisplay
, t
);
623 return (t
->GetCurrentReadDrawableSGI
)();
629 #if defined(_VL_H) && defined(GLX_SGIX_video_source)
631 GLXVideoSourceSGIX
glXCreateGLXVideoSourceSGIX(Display
*dpy
, int screen
, VLServer server
, VLPath path
, int nodeClass
, VLNode drainNode
)
633 struct _glxapi_table
*t
;
634 GET_DISPATCH(dpy
, t
);
637 return (t
->CreateGLXVideoSourceSGIX
)(dpy
, screen
, server
, path
, nodeClass
, drainNode
);
640 void glXDestroyGLXVideoSourceSGIX(Display
*dpy
, GLXVideoSourceSGIX src
)
642 struct _glxapi_table
*t
;
643 GET_DISPATCH(dpy
, t
);
646 return (t
->DestroyGLXVideoSourceSGIX
)(dpy
, src
);
652 #ifdef GLX_EXT_import_context
654 void glXFreeContextEXT(Display
*dpy
, GLXContext context
)
656 struct _glxapi_table
*t
;
657 GET_DISPATCH(dpy
, t
);
660 (t
->FreeContextEXT
)(dpy
, context
);
663 GLXContextID
glXGetContextIDEXT(const GLXContext context
)
665 /* XXX is this function right? */
666 struct _glxapi_table
*t
;
667 GET_DISPATCH(CurrentDisplay
, t
);
670 return (t
->GetContextIDEXT
)(context
);
673 Display
*glXGetCurrentDisplayEXT(void)
675 return CurrentDisplay
;
678 GLXContext
glXImportContextEXT(Display
*dpy
, GLXContextID contextID
)
680 struct _glxapi_table
*t
;
681 GET_DISPATCH(dpy
, t
);
684 return (t
->ImportContextEXT
)(dpy
, contextID
);
687 int glXQueryContextInfoEXT(Display
*dpy
, GLXContext context
, int attribute
,int *value
)
689 struct _glxapi_table
*t
;
690 GET_DISPATCH(dpy
, t
);
692 return 0; /* XXX ok? */
693 return (t
->QueryContextInfoEXT
)(dpy
, context
, attribute
, value
);
699 #ifdef GLX_SGIX_fbconfig
701 int glXGetFBConfigAttribSGIX(Display
*dpy
, GLXFBConfigSGIX config
, int attribute
, int *value
)
703 struct _glxapi_table
*t
;
704 GET_DISPATCH(dpy
, t
);
707 return (t
->GetFBConfigAttribSGIX
)(dpy
, config
, attribute
, value
);
710 GLXFBConfigSGIX
*glXChooseFBConfigSGIX(Display
*dpy
, int screen
, int *attrib_list
, int *nelements
)
712 struct _glxapi_table
*t
;
713 GET_DISPATCH(dpy
, t
);
716 return (t
->ChooseFBConfigSGIX
)(dpy
, screen
, attrib_list
, nelements
);
719 GLXPixmap
glXCreateGLXPixmapWithConfigSGIX(Display
*dpy
, GLXFBConfigSGIX config
, Pixmap pixmap
)
721 struct _glxapi_table
*t
;
722 GET_DISPATCH(dpy
, t
);
725 return (t
->CreateGLXPixmapWithConfigSGIX
)(dpy
, config
, pixmap
);
728 GLXContext
glXCreateContextWithConfigSGIX(Display
*dpy
, GLXFBConfigSGIX config
, int render_type
, GLXContext share_list
, Bool direct
)
730 struct _glxapi_table
*t
;
731 GET_DISPATCH(dpy
, t
);
734 return (t
->CreateContextWithConfigSGIX
)(dpy
, config
, render_type
, share_list
, direct
);
737 XVisualInfo
* glXGetVisualFromFBConfigSGIX(Display
*dpy
, GLXFBConfigSGIX config
)
739 struct _glxapi_table
*t
;
740 GET_DISPATCH(dpy
, t
);
743 return (t
->GetVisualFromFBConfigSGIX
)(dpy
, config
);
746 GLXFBConfigSGIX
glXGetFBConfigFromVisualSGIX(Display
*dpy
, XVisualInfo
*vis
)
748 struct _glxapi_table
*t
;
749 GET_DISPATCH(dpy
, t
);
752 return (t
->GetFBConfigFromVisualSGIX
)(dpy
, vis
);
758 #ifdef GLX_SGIX_pbuffer
760 GLXPbufferSGIX
glXCreateGLXPbufferSGIX(Display
*dpy
, GLXFBConfigSGIX config
, unsigned int width
, unsigned int height
, int *attrib_list
)
762 struct _glxapi_table
*t
;
763 GET_DISPATCH(dpy
, t
);
766 return (t
->CreateGLXPbufferSGIX
)(dpy
, config
, width
, height
, attrib_list
);
769 void glXDestroyGLXPbufferSGIX(Display
*dpy
, GLXPbufferSGIX pbuf
)
771 struct _glxapi_table
*t
;
772 GET_DISPATCH(dpy
, t
);
775 (t
->DestroyGLXPbufferSGIX
)(dpy
, pbuf
);
778 int glXQueryGLXPbufferSGIX(Display
*dpy
, GLXPbufferSGIX pbuf
, int attribute
, unsigned int *value
)
780 struct _glxapi_table
*t
;
781 GET_DISPATCH(dpy
, t
);
784 return (t
->QueryGLXPbufferSGIX
)(dpy
, pbuf
, attribute
, value
);
787 void glXSelectEventSGIX(Display
*dpy
, GLXDrawable drawable
, unsigned long mask
)
789 struct _glxapi_table
*t
;
790 GET_DISPATCH(dpy
, t
);
793 (t
->SelectEventSGIX
)(dpy
, drawable
, mask
);
796 void glXGetSelectedEventSGIX(Display
*dpy
, GLXDrawable drawable
, unsigned long *mask
)
798 struct _glxapi_table
*t
;
799 GET_DISPATCH(dpy
, t
);
802 (t
->GetSelectedEventSGIX
)(dpy
, drawable
, mask
);
808 #ifdef GLX_SGI_cushion
810 void glXCushionSGI(Display
*dpy
, Window win
, float cushion
)
812 struct _glxapi_table
*t
;
813 GET_DISPATCH(dpy
, t
);
816 (t
->CushionSGI
)(dpy
, win
, cushion
);
822 #ifdef GLX_SGIX_video_resize
824 int glXBindChannelToWindowSGIX(Display
*dpy
, int screen
, int channel
, Window window
)
826 struct _glxapi_table
*t
;
827 GET_DISPATCH(dpy
, t
);
830 return (t
->BindChannelToWindowSGIX
)(dpy
, screen
, channel
, window
);
833 int glXChannelRectSGIX(Display
*dpy
, int screen
, int channel
, int x
, int y
, int w
, int h
)
835 struct _glxapi_table
*t
;
836 GET_DISPATCH(dpy
, t
);
839 return (t
->ChannelRectSGIX
)(dpy
, screen
, channel
, x
, y
, w
, h
);
842 int glXQueryChannelRectSGIX(Display
*dpy
, int screen
, int channel
, int *x
, int *y
, int *w
, int *h
)
844 struct _glxapi_table
*t
;
845 GET_DISPATCH(dpy
, t
);
848 return (t
->QueryChannelRectSGIX
)(dpy
, screen
, channel
, x
, y
, w
, h
);
851 int glXQueryChannelDeltasSGIX(Display
*dpy
, int screen
, int channel
, int *dx
, int *dy
, int *dw
, int *dh
)
853 struct _glxapi_table
*t
;
854 GET_DISPATCH(dpy
, t
);
857 return (t
->QueryChannelDeltasSGIX
)(dpy
, screen
, channel
, dx
, dy
, dw
, dh
);
860 int glXChannelRectSyncSGIX(Display
*dpy
, int screen
, int channel
, GLenum synctype
)
862 struct _glxapi_table
*t
;
863 GET_DISPATCH(dpy
, t
);
866 return (t
->ChannelRectSyncSGIX
)(dpy
, screen
, channel
, synctype
);
872 #if defined(_DM_BUFFER_H_) && defined(GLX_SGIX_dmbuffer)
874 Bool
glXAssociateDMPbufferSGIX(Display
*dpy
, GLXPbufferSGIX pbuffer
, DMparams
*params
, DMbuffer dmbuffer
)
876 struct _glxapi_table
*t
;
877 GET_DISPATCH(dpy
, t
);
880 return (t
->AssociateDMPbufferSGIX
)(dpy
, pbuffer
, params
, dmbuffer
);
886 #ifdef GLX_SGIX_swap_group
888 void glXJoinSwapGroupSGIX(Display
*dpy
, GLXDrawable drawable
, GLXDrawable member
)
890 struct _glxapi_table
*t
;
891 GET_DISPATCH(dpy
, t
);
894 (*t
->JoinSwapGroupSGIX
)(dpy
, drawable
, member
);
900 #ifdef GLX_SGIX_swap_barrier
902 void glXBindSwapBarrierSGIX(Display
*dpy
, GLXDrawable drawable
, int barrier
)
904 struct _glxapi_table
*t
;
905 GET_DISPATCH(dpy
, t
);
908 (*t
->BindSwapBarrierSGIX
)(dpy
, drawable
, barrier
);
911 Bool
glXQueryMaxSwapBarriersSGIX(Display
*dpy
, int screen
, int *max
)
913 struct _glxapi_table
*t
;
914 GET_DISPATCH(dpy
, t
);
917 return (*t
->QueryMaxSwapBarriersSGIX
)(dpy
, screen
, max
);
923 #ifdef GLX_SUN_get_transparent_index
925 Status
glXGetTransparentIndexSUN(Display
*dpy
, Window overlay
, Window underlay
, long *pTransparent
)
927 struct _glxapi_table
*t
;
928 GET_DISPATCH(dpy
, t
);
931 return (*t
->GetTransparentIndexSUN
)(dpy
, overlay
, underlay
, pTransparent
);
937 #ifdef GLX_MESA_copy_sub_buffer
939 void glXCopySubBufferMESA(Display
*dpy
, GLXDrawable drawable
, int x
, int y
, int width
, int height
)
941 struct _glxapi_table
*t
;
942 GET_DISPATCH(dpy
, t
);
945 (t
->CopySubBufferMESA
)(dpy
, drawable
, x
, y
, width
, height
);
951 #ifdef GLX_MESA_release_buffers
953 Bool
glXReleaseBuffersMESA(Display
*dpy
, Window w
)
955 struct _glxapi_table
*t
;
956 GET_DISPATCH(dpy
, t
);
959 return (t
->ReleaseBuffersMESA
)(dpy
, w
);
965 #ifdef GLX_MESA_pixmap_colormap
967 GLXPixmap
glXCreateGLXPixmapMESA(Display
*dpy
, XVisualInfo
*visinfo
, Pixmap pixmap
, Colormap cmap
)
969 struct _glxapi_table
*t
;
970 GET_DISPATCH(dpy
, t
);
973 return (t
->CreateGLXPixmapMESA
)(dpy
, visinfo
, pixmap
, cmap
);
979 #ifdef GLX_MESA_set_3dfx_mode
981 Bool
glXSet3DfxModeMESA(int mode
)
983 struct _glxapi_table
*t
;
984 GET_DISPATCH(CurrentDisplay
, t
);
987 return (t
->Set3DfxModeMESA
)(mode
);
994 /**********************************************************************/
995 /* GLX API management functions */
996 /**********************************************************************/
1000 _glxapi_get_version(void)
1007 * Return array of extension strings.
1010 _glxapi_get_extensions(void)
1012 static const char *extensions
[] = {
1013 #ifdef GLX_EXT_import_context
1014 "GLX_EXT_import_context",
1016 #ifdef GLX_SGI_video_sync
1017 "GLX_SGI_video_sync",
1019 #ifdef GLX_MESA_copy_sub_buffer
1020 "GLX_MESA_copy_sub_buffer",
1022 #ifdef GLX_MESA_release_buffers
1023 "GLX_MESA_release_buffers",
1025 #ifdef GLX_MESA_pixmap_colormap
1026 "GLX_MESA_pixmap_colormap",
1028 #ifdef GLX_MESA_set_3dfx_mode
1029 "GLX_MESA_set_3dfx_mode",
1038 * Return size of the GLX dispatch table, in entries, not bytes.
1041 _glxapi_get_dispatch_table_size(void)
1043 return sizeof(struct _glxapi_table
) / sizeof(void *);
1048 generic_no_op_func(void)
1055 * Initialize all functions in given dispatch table to be no-ops
1058 _glxapi_set_no_op_table(struct _glxapi_table
*t
)
1060 GLuint n
= _glxapi_get_dispatch_table_size();
1062 void **dispatch
= (void **) t
;
1063 for (i
= 0; i
< n
; i
++) {
1064 dispatch
[i
] = (void *) generic_no_op_func
;
1071 * Open the named library and use dlsym() to populate the given dispatch
1072 * table with GLX function pointers.
1073 * Return: true = all OK
1074 * false = can't open libName or can't get required GLX function
1077 _glxapi_load_library_table(const char *libName
, struct _glxapi_table
*t
)
1080 void **entry
; /* used to avoid a lot of cast/type warnings */
1082 libHandle
= dlopen(libName
, 0);
1087 #define GET_REQ_FUNCTION(ENTRY, NAME) \
1088 entry = (void **) &(t->ENTRY); \
1089 *entry = dlsym(libHandle, NAME); \
1091 fprintf(stderr, "libGL Error: couldn't load %s from %s\n", \
1093 dlclose(libHandle); \
1097 /* 1.0 and 1.1 functions */
1098 GET_REQ_FUNCTION(ChooseVisual
, "glXChooseVisual");
1099 GET_REQ_FUNCTION(CopyContext
, "glXCopyContext");
1100 GET_REQ_FUNCTION(CreateContext
, "glXCreateContext");
1101 GET_REQ_FUNCTION(CreateGLXPixmap
, "glXCreateGLXPixmap");
1102 GET_REQ_FUNCTION(DestroyContext
, "glXDestroyContext");
1103 GET_REQ_FUNCTION(GetConfig
, "glXGetConfig");
1104 GET_REQ_FUNCTION(IsDirect
, "glXIsDirect");
1105 GET_REQ_FUNCTION(MakeCurrent
, "glXMakeCurrent");
1106 GET_REQ_FUNCTION(QueryExtension
, "glXQueryExtension");
1107 GET_REQ_FUNCTION(QueryVersion
, "glXQueryVersion");
1108 GET_REQ_FUNCTION(SwapBuffers
, "glXSwapBuffers");
1109 GET_REQ_FUNCTION(UseXFont
, "glXUseXFont");
1110 GET_REQ_FUNCTION(WaitGL
, "glXWaitGL");
1111 GET_REQ_FUNCTION(WaitX
, "glXWaitX");
1112 GET_REQ_FUNCTION(GetClientString
, "glXGetClientString");
1113 GET_REQ_FUNCTION(QueryExtensionsString
, "glXQueryExtensionsString");
1114 GET_REQ_FUNCTION(QueryServerString
, "glXQueryServerString");
1116 #define GET_OPT_FUNCTION(ENTRY, NAME) \
1117 entry = (void **) &(t->ENTRY); \
1118 *entry = dlsym(libHandle, NAME); \
1120 *entry = (void *) generic_no_op_func; \
1123 /* 1.2, 1.3 and extensions */
1124 GET_OPT_FUNCTION(ChooseFBConfig
, "glXChooseFBConfig");
1125 GET_OPT_FUNCTION(CreateNewContext
, "glXCreateNewContext");
1126 GET_OPT_FUNCTION(CreatePbuffer
, "glXCreatePbuffer");
1127 GET_OPT_FUNCTION(CreatePixmap
, "glXCreatePixmap");
1128 GET_OPT_FUNCTION(CreateWindow
, "glXCreateWindow");
1129 GET_OPT_FUNCTION(DestroyPbuffer
, "glXDestroyPbuffer");
1130 GET_OPT_FUNCTION(DestroyPixmap
, "glXDestroyPixmap");
1131 GET_OPT_FUNCTION(DestroyWindow
, "glXDestroyWindow");
1132 GET_OPT_FUNCTION(GetFBConfigAttrib
, "glXGetFBConfigAttrib");
1133 GET_OPT_FUNCTION(GetFBConfigs
, "glXGetFBConfigs");
1134 GET_OPT_FUNCTION(GetSelectedEvent
, "glXGetSelectedEvent");
1135 GET_OPT_FUNCTION(GetVisualFromFBConfig
, "glXGetVisualFromFBConfig");
1136 GET_OPT_FUNCTION(MakeContextCurrent
, "glXMakeContextCurrent");
1137 GET_OPT_FUNCTION(QueryContext
, "glXQueryContext");
1138 GET_OPT_FUNCTION(QueryDrawable
, "glXQueryDrawable");
1139 GET_OPT_FUNCTION(SelectEvent
, "glXSelectEvent");
1140 #ifdef GLX_SGI_swap_control
1141 GET_OPT_FUNCTION(SwapIntervalSGI
, "glXSwapIntervalSGI");
1143 #ifdef GLX_SGI_video_sync
1144 GET_OPT_FUNCTION(GetVideoSyncSGI
, "glXGetVideoSyncSGI");
1145 GET_OPT_FUNCTION(WaitVideoSyncSGI
, "glXWaitVideoSyncSGI");
1147 #ifdef GLX_SGI_make_current_read
1148 GET_OPT_FUNCTION(MakeCurrentReadSGI
, "glXMakeCurrentReadSGI");
1149 GET_OPT_FUNCTION(GetCurrentReadDrawableSGI
, "glXGetCurrentReadDrawableSGI");
1151 #if defined(_VL_H) && defined(GLX_SGIX_video_source)
1152 GET_OPT_FUNCTION(CreateGLXVideoSourceSGIX
, "glXCreateGLXVideoSourceSGIX");
1153 GET_OPT_FUNCTION(DestroyGLXVideoSourceSGIX
, "glXDestroyGLXVideoSourceSGIX");
1155 #ifdef GLX_EXT_import_context
1156 GET_OPT_FUNCTION(FreeContextEXT
, "glXFreeContextEXT");
1157 GET_OPT_FUNCTION(GetContextIDEXT
, "glXGetContextIDEXT");
1158 GET_OPT_FUNCTION(GetCurrentDisplayEXT
, "glXGetCurrentDisplayEXT");
1159 GET_OPT_FUNCTION(ImportContextEXT
, "glXImportContextEXT");
1160 GET_OPT_FUNCTION(QueryContextInfoEXT
, "glXQueryContextInfoEXT");
1162 #ifdef GLX_SGIX_fbconfig
1163 GET_OPT_FUNCTION(GetFBConfigAttribSGIX
, "glXGetFBConfigAttribSGIX");
1164 GET_OPT_FUNCTION(ChooseFBConfigSGIX
, "glXChooseFBConfigSGIX");
1165 GET_OPT_FUNCTION(CreateGLXPixmapWithConfigSGIX
, "glXCreateGLXPixmapWithConfigSGIX");
1166 GET_OPT_FUNCTION(CreateContextWithConfigSGIX
, "glXCreateContextWithConfigSGIX");
1167 GET_OPT_FUNCTION(GetVisualFromFBConfigSGIX
, "glXGetVisualFromFBConfigSGIX");
1168 GET_OPT_FUNCTION(GetFBConfigFromVisualSGIX
, "glXGetFBConfigFromVisualSGIX");
1170 #ifdef GLX_SGIX_pbuffer
1171 GET_OPT_FUNCTION(CreateGLXPbufferSGIX
, "glXCreateGLXPbufferSGIX");
1172 GET_OPT_FUNCTION(DestroyGLXPbufferSGIX
, "glXDestroyGLXPbufferSGIX");
1173 GET_OPT_FUNCTION(QueryGLXPbufferSGIX
, "glXQueryGLXPbufferSGIX");
1174 GET_OPT_FUNCTION(SelectEventSGIX
, "glXSelectEventSGIX");
1175 GET_OPT_FUNCTION(GetSelectedEventSGIX
, "glXGetSelectedEventSGIX");
1177 #ifdef GLX_SGI_cushion
1178 GET_OPT_FUNCTION(CushionSGI
, "glXCushionSGI");
1180 #ifdef GLX_SGIX_video_resize
1181 GET_OPT_FUNCTION(BindChannelToWindowSGIX
, "glXBindChannelToWindowSGIX");
1182 GET_OPT_FUNCTION(ChannelRectSGIX
, "glXChannelRectSGIX");
1183 GET_OPT_FUNCTION(QueryChannelRectSGIX
, "glXQueryChannelRectSGIX");
1184 GET_OPT_FUNCTION(QueryChannelDeltasSGIX
, "glXQueryChannelDeltasSGIX");
1185 GET_OPT_FUNCTION(ChannelRectSyncSGIX
, "glXChannelRectSyncSGIX");
1187 #if defined (_DM_BUFFER_H_) && defined(GLX_SGIX_dmbuffer)
1188 GET_OPT_FUNCTION(AssociateDMPbufferSGIX
, "glXAssociateDMPbufferSGIX");
1190 #ifdef GLX_SGIX_swap_group
1191 GET_OPT_FUNCTION(JoinSwapGroupSGIX
, "glXJoinSwapGroupSGIX");
1193 #ifdef GLX_SGIX_swap_barrier
1194 GET_OPT_FUNCTION(BindSwapBarrierSGIX
, "glXBindSwapBarrierSGIX");
1195 GET_OPT_FUNCTION(QueryMaxSwapBarriersSGIX
, "glXQueryMaxSwapBarriersSGIX");
1197 #ifdef GLX_SUN_get_transparent_index
1198 GET_OPT_FUNCTION(GetTransparentIndexSUN
, "glXGetTransparentIndexSUN");
1200 #ifdef GLX_MESA_copy_sub_buffer
1201 GET_OPT_FUNCTION(CopySubBufferMESA
, "glXCopySubBufferMESA");
1203 #ifdef GLX_MESA_release_buffers
1204 GET_OPT_FUNCTION(ReleaseBuffersMESA
, "glXReleaseBuffersMESA");
1206 #ifdef GLX_MESA_pixmap_colormap
1207 GET_OPT_FUNCTION(CreateGLXPixmapMESA
, "glXCreateGLXPixmapMESA");
1209 #ifdef GLX_MESA_set_3dfx_mode
1210 GET_OPT_FUNCTION(Set3DfxModeMESA
, "glXSet3DfxModeMESA");
1219 struct name_address_pair
{
1224 static struct name_address_pair GLX_functions
[] = {
1225 { "glXChooseVisual", (GLvoid
*) glXChooseVisual
},
1226 { "glXCopyContext", (GLvoid
*) glXCopyContext
},
1227 { "glXCreateContext", (GLvoid
*) glXCreateContext
},
1228 { "glXCreateGLXPixmap", (GLvoid
*) glXCreateGLXPixmap
},
1229 { "glXDestroyContext", (GLvoid
*) glXDestroyContext
},
1230 { "glXDestroyGLXPixmap", (GLvoid
*) glXDestroyGLXPixmap
},
1231 { "glXGetConfig", (GLvoid
*) glXGetConfig
},
1232 { "glXGetCurrentContext", (GLvoid
*) glXGetCurrentContext
},
1233 { "glXGetCurrentDrawable", (GLvoid
*) glXGetCurrentDrawable
},
1234 { "glXIsDirect", (GLvoid
*) glXIsDirect
},
1235 { "glXMakeCurrent", (GLvoid
*) glXMakeCurrent
},
1236 { "glXQueryExtension", (GLvoid
*) glXQueryExtension
},
1237 { "glXQueryVersion", (GLvoid
*) glXQueryVersion
},
1238 { "glXSwapBuffers", (GLvoid
*) glXSwapBuffers
},
1239 { "glXUseXFont", (GLvoid
*) glXUseXFont
},
1240 { "glXWaitGL", (GLvoid
*) glXWaitGL
},
1241 { "glXWaitX", (GLvoid
*) glXWaitX
},
1243 #ifdef GLX_VERSION_1_1
1244 { "glXGetClientString", (GLvoid
*) glXGetClientString
},
1245 { "glXQueryExtensionsString", (GLvoid
*) glXQueryExtensionsString
},
1246 { "glXQueryServerString", (GLvoid
*) glXQueryServerString
},
1249 #ifdef GLX_VERSION_1_2
1250 { "glXGetCurrentDisplay", (GLvoid
*) glXGetCurrentDisplay
},
1253 #ifdef GLX_VERSION_1_3
1254 { "glXChooseFBConfig", (GLvoid
*) glXChooseFBConfig
},
1255 { "glXCreateNewContext", (GLvoid
*) glXCreateNewContext
},
1256 { "glXCreatePbuffer", (GLvoid
*) glXCreatePbuffer
},
1257 { "glXCreatePixmap", (GLvoid
*) glXCreatePixmap
},
1258 { "glXCreateWindow", (GLvoid
*) glXCreateWindow
},
1259 { "glXDestroyPbuffer", (GLvoid
*) glXDestroyPbuffer
},
1260 { "glXDestroyPixmap", (GLvoid
*) glXDestroyPixmap
},
1261 { "glXDestroyWindow", (GLvoid
*) glXDestroyWindow
},
1262 { "glXGetCurrentReadDrawable", (GLvoid
*) glXGetCurrentReadDrawable
},
1263 { "glXGetFBConfigAttrib", (GLvoid
*) glXGetFBConfigAttrib
},
1264 { "glXGetSelectedEvent", (GLvoid
*) glXGetSelectedEvent
},
1265 { "glXGetVisualFromFBConfig", (GLvoid
*) glXGetVisualFromFBConfig
},
1266 { "glXMakeContextCurrent", (GLvoid
*) glXMakeContextCurrent
},
1267 { "glXQueryContext", (GLvoid
*) glXQueryContext
},
1268 { "glXQueryDrawable", (GLvoid
*) glXQueryDrawable
},
1269 { "glXSelectEvent", (GLvoid
*) glXSelectEvent
},
1272 #ifdef GLX_SGI_video_sync
1273 { "glXGetVideoSyncSGI", (GLvoid
*) glXGetVideoSyncSGI
},
1274 { "glXWaitVideoSyncSGI", (GLvoid
*) glXWaitVideoSyncSGI
},
1277 #ifdef GLX_MESA_copy_sub_buffer
1278 { "glXCopySubBufferMESA", (GLvoid
*) glXCopySubBufferMESA
},
1281 #ifdef GLX_MESA_release_buffers
1282 { "glXReleaseBuffersMESA", (GLvoid
*) glXReleaseBuffersMESA
},
1285 #ifdef GLX_MESA_pixmap_colormap
1286 { "glXCreateGLXPixmapMESA", (GLvoid
*) glXCreateGLXPixmapMESA
},
1289 #ifdef GLX_MESA_set_3dfx_mode
1290 { "glXSet3DfxModeMESA", (GLvoid
*) glXSet3DfxModeMESA
},
1293 { "glXGetProcAddressARB", (GLvoid
*) glXGetProcAddressARB
},
1295 { NULL
, NULL
} /* end of list */
1301 * Return address of named glX function, or NULL if not found.
1304 _glxapi_get_proc_address(const char *funcName
)
1307 for (i
= 0; GLX_functions
[i
].Name
; i
++) {
1308 if (strcmp(GLX_functions
[i
].Name
, funcName
) == 0)
1309 return GLX_functions
[i
].Address
;
1317 * This function does not get dispatched through the dispatch table
1318 * since it's really a "meta" function.
1320 void (*glXGetProcAddressARB(const GLubyte
*procName
))()
1322 typedef void (*gl_function
)();
1325 f
= (gl_function
) _glxapi_get_proc_address((const char *) procName
);
1330 f
= (gl_function
) _glapi_get_proc_address((const char *) procName
);