1 /* $Id: glxapi.c,v 1.24 2001/05/25 21:51:02 brianp Exp $ */
4 * Mesa 3-D graphics library
7 * Copyright (C) 1999-2001 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 the real GLX encoders or to Mesa's pseudo-GLX functions.
38 /*#include <dlfcn.h>*/ /* XXX not portable? */
43 extern struct _glxapi_table
*_real_GetGLXDispatchTable(void);
44 extern struct _glxapi_table
*_mesa_GetGLXDispatchTable(void);
47 struct display_dispatch
{
49 struct _glxapi_table
*Table
;
50 struct display_dispatch
*Next
;
53 static struct display_dispatch
*DispatchList
= NULL
;
56 /* Display -> Dispatch caching */
57 static Display
*prevDisplay
= NULL
;
58 static struct _glxapi_table
*prevTable
= NULL
;
61 static struct _glxapi_table
*
62 get_dispatch(Display
*dpy
)
67 /* search list of display/dispatch pairs for this display */
69 const struct display_dispatch
*d
= DispatchList
;
74 return d
->Table
; /* done! */
80 /* A new display, determine if we should use real GLX
81 * or Mesa's pseudo-GLX.
84 struct _glxapi_table
*t
= NULL
;
86 #ifdef GLX_BUILD_IN_XLIB_MESA
87 if (!getenv("LIBGL_FORCE_XMESA")) {
89 if (XQueryExtension( dpy
, "GLX", &ignore
, &ignore
, &ignore
)) {
90 /* the X server has the GLX extension */
91 t
= _real_GetGLXDispatchTable();
97 /* Fallback to Mesa with Xlib driver */
98 #ifdef GLX_BUILD_IN_XLIB_MESA
99 if (getenv("LIBGL_DEBUG")) {
101 "libGL: server lacks GLX extension. Using Mesa Xlib renderer.");
104 t
= _mesa_GetGLXDispatchTable();
105 assert(t
); /* this has to work */
109 struct display_dispatch
*d
;
110 d
= (struct display_dispatch
*) malloc(sizeof(struct display_dispatch
));
114 /* insert at head of list */
115 d
->Next
= DispatchList
;
125 /* If we get here that means we can't use real GLX on this display
126 * and the Mesa pseudo-GLX software renderer wasn't compiled in.
127 * Or, we ran out of memory!
133 #define GET_DISPATCH(DPY, TABLE) \
134 if (DPY == prevDisplay) { \
141 TABLE = get_dispatch(DPY); \
147 /* Set by glXMakeCurrent() and glXMakeContextCurrent() only */
148 #ifndef GLX_BUILD_IN_XLIB_MESA
149 static GLXContext CurrentContext
= 0;
150 #define __glXGetCurrentContext() CurrentContext;
155 * GLX API entrypoints
158 /*** GLX_VERSION_1_0 ***/
160 XVisualInfo
*glXChooseVisual(Display
*dpy
, int screen
, int *list
)
162 struct _glxapi_table
*t
;
163 GET_DISPATCH(dpy
, t
);
166 return (t
->ChooseVisual
)(dpy
, screen
, list
);
170 void glXCopyContext(Display
*dpy
, GLXContext src
, GLXContext dst
, unsigned long mask
)
172 struct _glxapi_table
*t
;
173 GET_DISPATCH(dpy
, t
);
176 (t
->CopyContext
)(dpy
, src
, dst
, mask
);
180 GLXContext
glXCreateContext(Display
*dpy
, XVisualInfo
*visinfo
, GLXContext shareList
, Bool direct
)
182 struct _glxapi_table
*t
;
183 GET_DISPATCH(dpy
, t
);
186 return (t
->CreateContext
)(dpy
, visinfo
, shareList
, direct
);
190 GLXPixmap
glXCreateGLXPixmap(Display
*dpy
, XVisualInfo
*visinfo
, Pixmap pixmap
)
192 struct _glxapi_table
*t
;
193 GET_DISPATCH(dpy
, t
);
196 return (t
->CreateGLXPixmap
)(dpy
, visinfo
, pixmap
);
200 void glXDestroyContext(Display
*dpy
, GLXContext ctx
)
202 struct _glxapi_table
*t
;
203 GET_DISPATCH(dpy
, t
);
206 (t
->DestroyContext
)(dpy
, ctx
);
210 void glXDestroyGLXPixmap(Display
*dpy
, GLXPixmap pixmap
)
212 struct _glxapi_table
*t
;
213 GET_DISPATCH(dpy
, t
);
216 (t
->DestroyGLXPixmap
)(dpy
, pixmap
);
220 int glXGetConfig(Display
*dpy
, XVisualInfo
*visinfo
, int attrib
, int *value
)
222 struct _glxapi_table
*t
;
223 GET_DISPATCH(dpy
, t
);
225 return GLX_NO_EXTENSION
;
226 return (t
->GetConfig
)(dpy
, visinfo
, attrib
, value
);
230 #ifdef GLX_BUILD_IN_XLIB_MESA
231 /* Use real libGL's glXGetCurrentContext() function */
233 /* stand-alone Mesa */
234 GLXContext
glXGetCurrentContext(void)
236 return CurrentContext
;
241 #ifdef GLX_BUILD_IN_XLIB_MESA
242 /* Use real libGL's glXGetCurrentContext() function */
244 /* stand-alone Mesa */
245 GLXDrawable
glXGetCurrentDrawable(void)
247 __GLXcontext
*gc
= (__GLXcontext
*) glXGetCurrentContext();
248 return gc
? gc
->currentDrawable
: 0;
253 Bool
glXIsDirect(Display
*dpy
, GLXContext ctx
)
255 struct _glxapi_table
*t
;
256 GET_DISPATCH(dpy
, t
);
259 return (t
->IsDirect
)(dpy
, ctx
);
263 Bool
glXMakeCurrent(Display
*dpy
, GLXDrawable drawable
, GLXContext ctx
)
266 struct _glxapi_table
*t
;
267 GET_DISPATCH(dpy
, t
);
270 b
= (*t
->MakeCurrent
)(dpy
, drawable
, ctx
);
271 #ifndef GLX_BUILD_IN_XLIB_MESA
273 CurrentContext
= ctx
;
280 Bool
glXQueryExtension(Display
*dpy
, int *errorb
, int *event
)
282 struct _glxapi_table
*t
;
283 GET_DISPATCH(dpy
, t
);
286 return (t
->QueryExtension
)(dpy
, errorb
, event
);
290 Bool
glXQueryVersion(Display
*dpy
, int *maj
, int *min
)
292 struct _glxapi_table
*t
;
293 GET_DISPATCH(dpy
, t
);
296 return (t
->QueryVersion
)(dpy
, maj
, min
);
300 void glXSwapBuffers(Display
*dpy
, GLXDrawable drawable
)
302 struct _glxapi_table
*t
;
303 GET_DISPATCH(dpy
, t
);
306 (t
->SwapBuffers
)(dpy
, drawable
);
310 void glXUseXFont(Font font
, int first
, int count
, int listBase
)
312 struct _glxapi_table
*t
;
313 Display
*dpy
= glXGetCurrentDisplay();
314 GET_DISPATCH(dpy
, t
);
317 (t
->UseXFont
)(font
, first
, count
, listBase
);
323 struct _glxapi_table
*t
;
324 Display
*dpy
= glXGetCurrentDisplay();
325 GET_DISPATCH(dpy
, t
);
334 struct _glxapi_table
*t
;
335 Display
*dpy
= glXGetCurrentDisplay();
336 GET_DISPATCH(dpy
, t
);
344 /*** GLX_VERSION_1_1 ***/
346 const char *glXGetClientString(Display
*dpy
, int name
)
348 struct _glxapi_table
*t
;
349 GET_DISPATCH(dpy
, t
);
352 return (t
->GetClientString
)(dpy
, name
);
356 const char *glXQueryExtensionsString(Display
*dpy
, int screen
)
358 struct _glxapi_table
*t
;
359 GET_DISPATCH(dpy
, t
);
362 return (t
->QueryExtensionsString
)(dpy
, screen
);
366 const char *glXQueryServerString(Display
*dpy
, int screen
, int name
)
368 struct _glxapi_table
*t
;
369 GET_DISPATCH(dpy
, t
);
372 return (t
->QueryServerString
)(dpy
, screen
, name
);
376 /*** GLX_VERSION_1_2 ***/
378 #if !defined(GLX_BUILD_IN_XLIB_MESA)
379 Display
*glXGetCurrentDisplay(void)
381 /* Same code as in libGL's glxext.c */
382 __GLXcontext
*gc
= (__GLXcontext
*) glXGetCurrentContext();
383 if (NULL
== gc
) return NULL
;
384 return gc
->currentDpy
;
390 /*** GLX_VERSION_1_3 ***/
392 GLXFBConfig
*glXChooseFBConfig(Display
*dpy
, int screen
, const int *attribList
, int *nitems
)
394 struct _glxapi_table
*t
;
395 GET_DISPATCH(dpy
, t
);
398 return (t
->ChooseFBConfig
)(dpy
, screen
, attribList
, nitems
);
402 GLXContext
glXCreateNewContext(Display
*dpy
, GLXFBConfig config
, int renderType
, GLXContext shareList
, Bool direct
)
404 struct _glxapi_table
*t
;
405 GET_DISPATCH(dpy
, t
);
408 return (t
->CreateNewContext
)(dpy
, config
, renderType
, shareList
, direct
);
412 GLXPbuffer
glXCreatePbuffer(Display
*dpy
, GLXFBConfig config
, const int *attribList
)
414 struct _glxapi_table
*t
;
415 GET_DISPATCH(dpy
, t
);
418 return (t
->CreatePbuffer
)(dpy
, config
, attribList
);
422 GLXPixmap
glXCreatePixmap(Display
*dpy
, GLXFBConfig config
, Pixmap pixmap
, const int *attribList
)
424 struct _glxapi_table
*t
;
425 GET_DISPATCH(dpy
, t
);
428 return (t
->CreatePixmap
)(dpy
, config
, pixmap
, attribList
);
432 GLXWindow
glXCreateWindow(Display
*dpy
, GLXFBConfig config
, Window win
, const int *attribList
)
434 struct _glxapi_table
*t
;
435 GET_DISPATCH(dpy
, t
);
438 return (t
->CreateWindow
)(dpy
, config
, win
, attribList
);
442 void glXDestroyPbuffer(Display
*dpy
, GLXPbuffer pbuf
)
444 struct _glxapi_table
*t
;
445 GET_DISPATCH(dpy
, t
);
448 (t
->DestroyPbuffer
)(dpy
, pbuf
);
452 void glXDestroyPixmap(Display
*dpy
, GLXPixmap pixmap
)
454 struct _glxapi_table
*t
;
455 GET_DISPATCH(dpy
, t
);
458 (t
->DestroyPixmap
)(dpy
, pixmap
);
462 void glXDestroyWindow(Display
*dpy
, GLXWindow window
)
464 struct _glxapi_table
*t
;
465 GET_DISPATCH(dpy
, t
);
468 (t
->DestroyWindow
)(dpy
, window
);
472 #ifdef GLX_BUILD_IN_XLIB_MESA
473 /* Use the glXGetCurrentReadDrawable() function from libGL */
475 GLXDrawable
glXGetCurrentReadDrawable(void)
477 __GLXcontext
*gc
= (__GLXcontext
*) glXGetCurrentContext();
478 return gc
? gc
->currentReadable
: 0;
483 int glXGetFBConfigAttrib(Display
*dpy
, GLXFBConfig config
, int attribute
, int *value
)
485 struct _glxapi_table
*t
;
486 GET_DISPATCH(dpy
, t
);
488 return GLX_NO_EXTENSION
;
489 return (t
->GetFBConfigAttrib
)(dpy
, config
, attribute
, value
);
493 GLXFBConfig
*glXGetFBConfigs(Display
*dpy
, int screen
, int *nelements
)
495 struct _glxapi_table
*t
;
496 GET_DISPATCH(dpy
, t
);
499 return (t
->GetFBConfigs
)(dpy
, screen
, nelements
);
502 void glXGetSelectedEvent(Display
*dpy
, GLXDrawable drawable
, unsigned long *mask
)
504 struct _glxapi_table
*t
;
505 GET_DISPATCH(dpy
, t
);
508 (t
->GetSelectedEvent
)(dpy
, drawable
, mask
);
512 XVisualInfo
*glXGetVisualFromFBConfig(Display
*dpy
, GLXFBConfig config
)
514 struct _glxapi_table
*t
;
515 GET_DISPATCH(dpy
, t
);
518 return (t
->GetVisualFromFBConfig
)(dpy
, config
);
522 Bool
glXMakeContextCurrent(Display
*dpy
, GLXDrawable draw
, GLXDrawable read
, GLXContext ctx
)
525 struct _glxapi_table
*t
;
526 GET_DISPATCH(dpy
, t
);
529 b
= (t
->MakeContextCurrent
)(dpy
, draw
, read
, ctx
);
530 #ifndef GLX_BUILD_IN_XLIB_MESA
532 CurrentContext
= ctx
;
539 int glXQueryContext(Display
*dpy
, GLXContext ctx
, int attribute
, int *value
)
541 struct _glxapi_table
*t
;
542 GET_DISPATCH(dpy
, t
);
545 return 0; /* XXX correct? */
546 return (t
->QueryContext
)(dpy
, ctx
, attribute
, value
);
550 void glXQueryDrawable(Display
*dpy
, GLXDrawable draw
, int attribute
, unsigned int *value
)
552 struct _glxapi_table
*t
;
553 GET_DISPATCH(dpy
, t
);
556 (t
->QueryDrawable
)(dpy
, draw
, attribute
, value
);
560 void glXSelectEvent(Display
*dpy
, GLXDrawable drawable
, unsigned long mask
)
562 struct _glxapi_table
*t
;
563 GET_DISPATCH(dpy
, t
);
566 (t
->SelectEvent
)(dpy
, drawable
, mask
);
571 /*** GLX_SGI_swap_control ***/
573 int glXSwapIntervalSGI(int interval
)
575 struct _glxapi_table
*t
;
576 Display
*dpy
= glXGetCurrentDisplay();
577 GET_DISPATCH(dpy
, t
);
580 return (t
->SwapIntervalSGI
)(interval
);
585 /*** GLX_SGI_video_sync ***/
587 int glXGetVideoSyncSGI(unsigned int *count
)
589 struct _glxapi_table
*t
;
590 Display
*dpy
= glXGetCurrentDisplay();
591 GET_DISPATCH(dpy
, t
);
594 return (t
->GetVideoSyncSGI
)(count
);
597 int glXWaitVideoSyncSGI(int divisor
, int remainder
, unsigned int *count
)
599 struct _glxapi_table
*t
;
600 Display
*dpy
= glXGetCurrentDisplay();
601 GET_DISPATCH(dpy
, t
);
604 return (t
->WaitVideoSyncSGI
)(divisor
, remainder
, count
);
609 /*** GLX_SGI_make_current_read ***/
611 Bool
glXMakeCurrentReadSGI(Display
*dpy
, GLXDrawable draw
, GLXDrawable read
, GLXContext ctx
)
613 struct _glxapi_table
*t
;
614 GET_DISPATCH(dpy
, t
);
617 return (t
->MakeCurrentReadSGI
)(dpy
, draw
, read
, ctx
);
620 #ifdef GLX_BUILD_IN_XLIB_MESA
621 /* Use glXGetCurrentReadDrawableSGI() from libGL */
623 /* stand-alone Mesa */
624 GLXDrawable
glXGetCurrentReadDrawableSGI(void)
626 return glXGetCurrentReadDrawable();
633 GLXVideoSourceSGIX
glXCreateGLXVideoSourceSGIX(Display
*dpy
, int screen
, VLServer server
, VLPath path
, int nodeClass
, VLNode drainNode
)
635 struct _glxapi_table
*t
;
636 GET_DISPATCH(dpy
, t
);
639 return (t
->CreateGLXVideoSourceSGIX
)(dpy
, screen
, server
, path
, nodeClass
, drainNode
);
642 void glXDestroyGLXVideoSourceSGIX(Display
*dpy
, GLXVideoSourceSGIX src
)
644 struct _glxapi_table
*t
;
645 GET_DISPATCH(dpy
, t
);
648 return (t
->DestroyGLXVideoSourceSGIX
)(dpy
, src
);
654 /*** GLX_EXT_import_context ***/
656 void glXFreeContextEXT(Display
*dpy
, GLXContext context
)
658 struct _glxapi_table
*t
;
659 GET_DISPATCH(dpy
, t
);
662 (t
->FreeContextEXT
)(dpy
, context
);
665 #ifdef GLX_BUILD_IN_XLIB_MESA
666 /* Use real libGL's glXGetContextIDEXT() function */
668 /* stand-alone Mesa */
669 GLXContextID
glXGetContextIDEXT(const GLXContext context
)
671 return ((__GLXcontext
*) context
)->xid
;
675 Display
*glXGetCurrentDisplayEXT(void)
677 return glXGetCurrentDisplay();
680 GLXContext
glXImportContextEXT(Display
*dpy
, GLXContextID contextID
)
682 struct _glxapi_table
*t
;
683 GET_DISPATCH(dpy
, t
);
686 return (t
->ImportContextEXT
)(dpy
, contextID
);
689 int glXQueryContextInfoEXT(Display
*dpy
, GLXContext context
, int attribute
,int *value
)
691 struct _glxapi_table
*t
;
692 GET_DISPATCH(dpy
, t
);
694 return 0; /* XXX ok? */
695 return (t
->QueryContextInfoEXT
)(dpy
, context
, attribute
, value
);
700 /*** GLX_SGIX_fbconfig ***/
702 int glXGetFBConfigAttribSGIX(Display
*dpy
, GLXFBConfigSGIX config
, int attribute
, int *value
)
704 struct _glxapi_table
*t
;
705 GET_DISPATCH(dpy
, t
);
708 return (t
->GetFBConfigAttribSGIX
)(dpy
, config
, attribute
, value
);
711 GLXFBConfigSGIX
*glXChooseFBConfigSGIX(Display
*dpy
, int screen
, int *attrib_list
, int *nelements
)
713 struct _glxapi_table
*t
;
714 GET_DISPATCH(dpy
, t
);
717 return (t
->ChooseFBConfigSGIX
)(dpy
, screen
, attrib_list
, nelements
);
720 GLXPixmap
glXCreateGLXPixmapWithConfigSGIX(Display
*dpy
, GLXFBConfigSGIX config
, Pixmap pixmap
)
722 struct _glxapi_table
*t
;
723 GET_DISPATCH(dpy
, t
);
726 return (t
->CreateGLXPixmapWithConfigSGIX
)(dpy
, config
, pixmap
);
729 GLXContext
glXCreateContextWithConfigSGIX(Display
*dpy
, GLXFBConfigSGIX config
, int render_type
, GLXContext share_list
, Bool direct
)
731 struct _glxapi_table
*t
;
732 GET_DISPATCH(dpy
, t
);
735 return (t
->CreateContextWithConfigSGIX
)(dpy
, config
, render_type
, share_list
, direct
);
738 XVisualInfo
* glXGetVisualFromFBConfigSGIX(Display
*dpy
, GLXFBConfigSGIX config
)
740 struct _glxapi_table
*t
;
741 GET_DISPATCH(dpy
, t
);
744 return (t
->GetVisualFromFBConfigSGIX
)(dpy
, config
);
747 GLXFBConfigSGIX
glXGetFBConfigFromVisualSGIX(Display
*dpy
, XVisualInfo
*vis
)
749 struct _glxapi_table
*t
;
750 GET_DISPATCH(dpy
, t
);
753 return (t
->GetFBConfigFromVisualSGIX
)(dpy
, vis
);
758 /*** 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
);
807 /*** GLX_SGI_cushion ***/
809 void glXCushionSGI(Display
*dpy
, Window win
, float cushion
)
811 struct _glxapi_table
*t
;
812 GET_DISPATCH(dpy
, t
);
815 (t
->CushionSGI
)(dpy
, win
, cushion
);
820 /*** GLX_SGIX_video_resize ***/
822 int glXBindChannelToWindowSGIX(Display
*dpy
, int screen
, int channel
, Window window
)
824 struct _glxapi_table
*t
;
825 GET_DISPATCH(dpy
, t
);
828 return (t
->BindChannelToWindowSGIX
)(dpy
, screen
, channel
, window
);
831 int glXChannelRectSGIX(Display
*dpy
, int screen
, int channel
, int x
, int y
, int w
, int h
)
833 struct _glxapi_table
*t
;
834 GET_DISPATCH(dpy
, t
);
837 return (t
->ChannelRectSGIX
)(dpy
, screen
, channel
, x
, y
, w
, h
);
840 int glXQueryChannelRectSGIX(Display
*dpy
, int screen
, int channel
, int *x
, int *y
, int *w
, int *h
)
842 struct _glxapi_table
*t
;
843 GET_DISPATCH(dpy
, t
);
846 return (t
->QueryChannelRectSGIX
)(dpy
, screen
, channel
, x
, y
, w
, h
);
849 int glXQueryChannelDeltasSGIX(Display
*dpy
, int screen
, int channel
, int *dx
, int *dy
, int *dw
, int *dh
)
851 struct _glxapi_table
*t
;
852 GET_DISPATCH(dpy
, t
);
855 return (t
->QueryChannelDeltasSGIX
)(dpy
, screen
, channel
, dx
, dy
, dw
, dh
);
858 int glXChannelRectSyncSGIX(Display
*dpy
, int screen
, int channel
, GLenum synctype
)
860 struct _glxapi_table
*t
;
861 GET_DISPATCH(dpy
, t
);
864 return (t
->ChannelRectSyncSGIX
)(dpy
, screen
, channel
, synctype
);
869 #if defined(_DM_BUFFER_H_)
871 Bool
glXAssociateDMPbufferSGIX(Display
*dpy
, GLXPbufferSGIX pbuffer
, DMparams
*params
, DMbuffer dmbuffer
)
873 struct _glxapi_table
*t
;
874 GET_DISPATCH(dpy
, t
);
877 return (t
->AssociateDMPbufferSGIX
)(dpy
, pbuffer
, params
, dmbuffer
);
883 /*** GLX_SGIX_swap_group ***/
885 void glXJoinSwapGroupSGIX(Display
*dpy
, GLXDrawable drawable
, GLXDrawable member
)
887 struct _glxapi_table
*t
;
888 GET_DISPATCH(dpy
, t
);
891 (*t
->JoinSwapGroupSGIX
)(dpy
, drawable
, member
);
895 /*** GLX_SGIX_swap_barrier ***/
897 void glXBindSwapBarrierSGIX(Display
*dpy
, GLXDrawable drawable
, int barrier
)
899 struct _glxapi_table
*t
;
900 GET_DISPATCH(dpy
, t
);
903 (*t
->BindSwapBarrierSGIX
)(dpy
, drawable
, barrier
);
906 Bool
glXQueryMaxSwapBarriersSGIX(Display
*dpy
, int screen
, int *max
)
908 struct _glxapi_table
*t
;
909 GET_DISPATCH(dpy
, t
);
912 return (*t
->QueryMaxSwapBarriersSGIX
)(dpy
, screen
, max
);
917 /*** GLX_SUN_get_transparent_index ***/
919 Status
glXGetTransparentIndexSUN(Display
*dpy
, Window overlay
, Window underlay
, long *pTransparent
)
921 struct _glxapi_table
*t
;
922 GET_DISPATCH(dpy
, t
);
925 return (*t
->GetTransparentIndexSUN
)(dpy
, overlay
, underlay
, pTransparent
);
930 /*** GLX_MESA_copy_sub_buffer ***/
932 void glXCopySubBufferMESA(Display
*dpy
, GLXDrawable drawable
, int x
, int y
, int width
, int height
)
934 struct _glxapi_table
*t
;
935 GET_DISPATCH(dpy
, t
);
938 (t
->CopySubBufferMESA
)(dpy
, drawable
, x
, y
, width
, height
);
943 /*** GLX_MESA_release_buffers ***/
945 Bool
glXReleaseBuffersMESA(Display
*dpy
, Window w
)
947 struct _glxapi_table
*t
;
948 GET_DISPATCH(dpy
, t
);
951 return (t
->ReleaseBuffersMESA
)(dpy
, w
);
956 /*** GLX_MESA_pixmap_colormap ***/
958 GLXPixmap
glXCreateGLXPixmapMESA(Display
*dpy
, XVisualInfo
*visinfo
, Pixmap pixmap
, Colormap cmap
)
960 struct _glxapi_table
*t
;
961 GET_DISPATCH(dpy
, t
);
964 return (t
->CreateGLXPixmapMESA
)(dpy
, visinfo
, pixmap
, cmap
);
969 /*** GLX_MESA_set_3dfx_mode ***/
971 Bool
glXSet3DfxModeMESA(int mode
)
973 struct _glxapi_table
*t
;
974 Display
*dpy
= glXGetCurrentDisplay();
975 GET_DISPATCH(dpy
, t
);
978 return (t
->Set3DfxModeMESA
)(mode
);
984 /**********************************************************************/
985 /* GLX API management functions */
986 /**********************************************************************/
990 _glxapi_get_version(void)
997 * Return array of extension strings.
1000 _glxapi_get_extensions(void)
1002 static const char *extensions
[] = {
1003 #ifdef GLX_EXT_import_context
1004 "GLX_EXT_import_context",
1006 #ifdef GLX_SGI_video_sync
1007 "GLX_SGI_video_sync",
1009 #ifdef GLX_MESA_copy_sub_buffer
1010 "GLX_MESA_copy_sub_buffer",
1012 #ifdef GLX_MESA_release_buffers
1013 "GLX_MESA_release_buffers",
1015 #ifdef GLX_MESA_pixmap_colormap
1016 "GLX_MESA_pixmap_colormap",
1018 #ifdef GLX_MESA_set_3dfx_mode
1019 "GLX_MESA_set_3dfx_mode",
1028 * Return size of the GLX dispatch table, in entries, not bytes.
1031 _glxapi_get_dispatch_table_size(void)
1033 return sizeof(struct _glxapi_table
) / sizeof(void *);
1038 generic_no_op_func(void)
1045 * Initialize all functions in given dispatch table to be no-ops
1048 _glxapi_set_no_op_table(struct _glxapi_table
*t
)
1050 GLuint n
= _glxapi_get_dispatch_table_size();
1052 void **dispatch
= (void **) t
;
1053 for (i
= 0; i
< n
; i
++) {
1054 dispatch
[i
] = (void *) generic_no_op_func
;
1061 * Open the named library and use dlsym() to populate the given dispatch
1062 * table with GLX function pointers.
1063 * Return: true = all OK
1064 * false = can't open libName or can't get required GLX function
1067 _glxapi_load_library_table(const char *libName
, struct _glxapi_table
*t
)
1070 void **entry
; /* used to avoid a lot of cast/type warnings */
1072 libHandle
= dlopen(libName
, 0);
1077 #define GET_REQ_FUNCTION(ENTRY, NAME) \
1078 entry = (void **) &(t->ENTRY); \
1079 *entry = dlsym(libHandle, NAME); \
1081 fprintf(stderr, "libGL Error: couldn't load %s from %s\n", \
1083 dlclose(libHandle); \
1087 /* 1.0 and 1.1 functions */
1088 GET_REQ_FUNCTION(ChooseVisual
, "glXChooseVisual");
1089 GET_REQ_FUNCTION(CopyContext
, "glXCopyContext");
1090 GET_REQ_FUNCTION(CreateContext
, "glXCreateContext");
1091 GET_REQ_FUNCTION(CreateGLXPixmap
, "glXCreateGLXPixmap");
1092 GET_REQ_FUNCTION(DestroyContext
, "glXDestroyContext");
1093 GET_REQ_FUNCTION(GetConfig
, "glXGetConfig");
1094 GET_REQ_FUNCTION(IsDirect
, "glXIsDirect");
1095 GET_REQ_FUNCTION(MakeCurrent
, "glXMakeCurrent");
1096 GET_REQ_FUNCTION(QueryExtension
, "glXQueryExtension");
1097 GET_REQ_FUNCTION(QueryVersion
, "glXQueryVersion");
1098 GET_REQ_FUNCTION(SwapBuffers
, "glXSwapBuffers");
1099 GET_REQ_FUNCTION(UseXFont
, "glXUseXFont");
1100 GET_REQ_FUNCTION(WaitGL
, "glXWaitGL");
1101 GET_REQ_FUNCTION(WaitX
, "glXWaitX");
1102 GET_REQ_FUNCTION(GetClientString
, "glXGetClientString");
1103 GET_REQ_FUNCTION(QueryExtensionsString
, "glXQueryExtensionsString");
1104 GET_REQ_FUNCTION(QueryServerString
, "glXQueryServerString");
1106 #define GET_OPT_FUNCTION(ENTRY, NAME) \
1107 entry = (void **) &(t->ENTRY); \
1108 *entry = dlsym(libHandle, NAME); \
1110 *entry = (void *) generic_no_op_func; \
1113 /* 1.2, 1.3 and extensions */
1114 GET_OPT_FUNCTION(ChooseFBConfig
, "glXChooseFBConfig");
1115 GET_OPT_FUNCTION(CreateNewContext
, "glXCreateNewContext");
1116 GET_OPT_FUNCTION(CreatePbuffer
, "glXCreatePbuffer");
1117 GET_OPT_FUNCTION(CreatePixmap
, "glXCreatePixmap");
1118 GET_OPT_FUNCTION(CreateWindow
, "glXCreateWindow");
1119 GET_OPT_FUNCTION(DestroyPbuffer
, "glXDestroyPbuffer");
1120 GET_OPT_FUNCTION(DestroyPixmap
, "glXDestroyPixmap");
1121 GET_OPT_FUNCTION(DestroyWindow
, "glXDestroyWindow");
1122 GET_OPT_FUNCTION(GetFBConfigAttrib
, "glXGetFBConfigAttrib");
1123 GET_OPT_FUNCTION(GetFBConfigs
, "glXGetFBConfigs");
1124 GET_OPT_FUNCTION(GetSelectedEvent
, "glXGetSelectedEvent");
1125 GET_OPT_FUNCTION(GetVisualFromFBConfig
, "glXGetVisualFromFBConfig");
1126 GET_OPT_FUNCTION(MakeContextCurrent
, "glXMakeContextCurrent");
1127 GET_OPT_FUNCTION(QueryContext
, "glXQueryContext");
1128 GET_OPT_FUNCTION(QueryDrawable
, "glXQueryDrawable");
1129 GET_OPT_FUNCTION(SelectEvent
, "glXSelectEvent");
1130 /*** GLX_SGI_swap_control ***/
1131 GET_OPT_FUNCTION(SwapIntervalSGI
, "glXSwapIntervalSGI");
1132 /*** GLX_SGI_video_sync ***/
1133 GET_OPT_FUNCTION(GetVideoSyncSGI
, "glXGetVideoSyncSGI");
1134 GET_OPT_FUNCTION(WaitVideoSyncSGI
, "glXWaitVideoSyncSGI");
1135 /*** GLX_SGI_make_current_read ***/
1136 GET_OPT_FUNCTION(MakeCurrentReadSGI
, "glXMakeCurrentReadSGI");
1137 GET_OPT_FUNCTION(GetCurrentReadDrawableSGI
, "glXGetCurrentReadDrawableSGI");
1138 /*** GLX_SGIX_video_source ***/
1140 GET_OPT_FUNCTION(CreateGLXVideoSourceSGIX
, "glXCreateGLXVideoSourceSGIX");
1141 GET_OPT_FUNCTION(DestroyGLXVideoSourceSGIX
, "glXDestroyGLXVideoSourceSGIX");
1143 /*** GLX_EXT_import_context ***/
1144 GET_OPT_FUNCTION(FreeContextEXT
, "glXFreeContextEXT");
1145 GET_OPT_FUNCTION(GetContextIDEXT
, "glXGetContextIDEXT");
1146 GET_OPT_FUNCTION(GetCurrentDisplayEXT
, "glXGetCurrentDisplayEXT");
1147 GET_OPT_FUNCTION(ImportContextEXT
, "glXImportContextEXT");
1148 GET_OPT_FUNCTION(QueryContextInfoEXT
, "glXQueryContextInfoEXT");
1149 /*** GLX_SGIX_fbconfig ***/
1150 GET_OPT_FUNCTION(GetFBConfigAttribSGIX
, "glXGetFBConfigAttribSGIX");
1151 GET_OPT_FUNCTION(ChooseFBConfigSGIX
, "glXChooseFBConfigSGIX");
1152 GET_OPT_FUNCTION(CreateGLXPixmapWithConfigSGIX
, "glXCreateGLXPixmapWithConfigSGIX");
1153 GET_OPT_FUNCTION(CreateContextWithConfigSGIX
, "glXCreateContextWithConfigSGIX");
1154 GET_OPT_FUNCTION(GetVisualFromFBConfigSGIX
, "glXGetVisualFromFBConfigSGIX");
1155 GET_OPT_FUNCTION(GetFBConfigFromVisualSGIX
, "glXGetFBConfigFromVisualSGIX");
1156 /*** GLX_SGIX_pbuffer ***/
1157 GET_OPT_FUNCTION(CreateGLXPbufferSGIX
, "glXCreateGLXPbufferSGIX");
1158 GET_OPT_FUNCTION(DestroyGLXPbufferSGIX
, "glXDestroyGLXPbufferSGIX");
1159 GET_OPT_FUNCTION(QueryGLXPbufferSGIX
, "glXQueryGLXPbufferSGIX");
1160 GET_OPT_FUNCTION(SelectEventSGIX
, "glXSelectEventSGIX");
1161 GET_OPT_FUNCTION(GetSelectedEventSGIX
, "glXGetSelectedEventSGIX");
1162 /*** GLX_SGI_cushion ***/
1163 GET_OPT_FUNCTION(CushionSGI
, "glXCushionSGI");
1164 /*** GLX_SGIX_video_resize ***/
1165 GET_OPT_FUNCTION(BindChannelToWindowSGIX
, "glXBindChannelToWindowSGIX");
1166 GET_OPT_FUNCTION(ChannelRectSGIX
, "glXChannelRectSGIX");
1167 GET_OPT_FUNCTION(QueryChannelRectSGIX
, "glXQueryChannelRectSGIX");
1168 GET_OPT_FUNCTION(QueryChannelDeltasSGIX
, "glXQueryChannelDeltasSGIX");
1169 GET_OPT_FUNCTION(ChannelRectSyncSGIX
, "glXChannelRectSyncSGIX");
1170 /*** GLX_SGIX_dmbuffer ***/
1171 #if defined (_DM_BUFFER_H_)
1172 GET_OPT_FUNCTION(AssociateDMPbufferSGIX
, "glXAssociateDMPbufferSGIX");
1174 /*** GLX_SGIX_swap_group ***/
1175 GET_OPT_FUNCTION(JoinSwapGroupSGIX
, "glXJoinSwapGroupSGIX");
1176 /*** GLX_SGIX_swap_barrier ***/
1177 GET_OPT_FUNCTION(BindSwapBarrierSGIX
, "glXBindSwapBarrierSGIX");
1178 GET_OPT_FUNCTION(QueryMaxSwapBarriersSGIX
, "glXQueryMaxSwapBarriersSGIX");
1179 /*** GLX_SUN_get_transparent_index ***/
1180 GET_OPT_FUNCTION(GetTransparentIndexSUN
, "glXGetTransparentIndexSUN");
1181 /*** GLX_MESA_copy_sub_buffer ***/
1182 GET_OPT_FUNCTION(CopySubBufferMESA
, "glXCopySubBufferMESA");
1183 /*** GLX_MESA_release_buffers ***/
1184 GET_OPT_FUNCTION(ReleaseBuffersMESA
, "glXReleaseBuffersMESA");
1185 /*** GLX_MESA_pixmap_colormap ***/
1186 GET_OPT_FUNCTION(CreateGLXPixmapMESA
, "glXCreateGLXPixmapMESA");
1187 /*** GLX_MESA_set_3dfx_mode ***/
1188 GET_OPT_FUNCTION(Set3DfxModeMESA
, "glXSet3DfxModeMESA");
1196 struct name_address_pair
{
1201 static struct name_address_pair GLX_functions
[] = {
1202 /*** GLX_VERSION_1_0 ***/
1203 { "glXChooseVisual", (GLvoid
*) glXChooseVisual
},
1204 { "glXCopyContext", (GLvoid
*) glXCopyContext
},
1205 { "glXCreateContext", (GLvoid
*) glXCreateContext
},
1206 { "glXCreateGLXPixmap", (GLvoid
*) glXCreateGLXPixmap
},
1207 { "glXDestroyContext", (GLvoid
*) glXDestroyContext
},
1208 { "glXDestroyGLXPixmap", (GLvoid
*) glXDestroyGLXPixmap
},
1209 { "glXGetConfig", (GLvoid
*) glXGetConfig
},
1210 { "glXGetCurrentContext", (GLvoid
*) glXGetCurrentContext
},
1211 { "glXGetCurrentDrawable", (GLvoid
*) glXGetCurrentDrawable
},
1212 { "glXIsDirect", (GLvoid
*) glXIsDirect
},
1213 { "glXMakeCurrent", (GLvoid
*) glXMakeCurrent
},
1214 { "glXQueryExtension", (GLvoid
*) glXQueryExtension
},
1215 { "glXQueryVersion", (GLvoid
*) glXQueryVersion
},
1216 { "glXSwapBuffers", (GLvoid
*) glXSwapBuffers
},
1217 { "glXUseXFont", (GLvoid
*) glXUseXFont
},
1218 { "glXWaitGL", (GLvoid
*) glXWaitGL
},
1219 { "glXWaitX", (GLvoid
*) glXWaitX
},
1221 /*** GLX_VERSION_1_1 ***/
1222 { "glXGetClientString", (GLvoid
*) glXGetClientString
},
1223 { "glXQueryExtensionsString", (GLvoid
*) glXQueryExtensionsString
},
1224 { "glXQueryServerString", (GLvoid
*) glXQueryServerString
},
1226 /*** GLX_VERSION_1_2 ***/
1227 { "glXGetCurrentDisplay", (GLvoid
*) glXGetCurrentDisplay
},
1229 /*** GLX_VERSION_1_3 ***/
1230 { "glXChooseFBConfig", (GLvoid
*) glXChooseFBConfig
},
1231 { "glXCreateNewContext", (GLvoid
*) glXCreateNewContext
},
1232 { "glXCreatePbuffer", (GLvoid
*) glXCreatePbuffer
},
1233 { "glXCreatePixmap", (GLvoid
*) glXCreatePixmap
},
1234 { "glXCreateWindow", (GLvoid
*) glXCreateWindow
},
1235 { "glXDestroyPbuffer", (GLvoid
*) glXDestroyPbuffer
},
1236 { "glXDestroyPixmap", (GLvoid
*) glXDestroyPixmap
},
1237 { "glXDestroyWindow", (GLvoid
*) glXDestroyWindow
},
1238 { "glXGetCurrentReadDrawable", (GLvoid
*) glXGetCurrentReadDrawable
},
1239 { "glXGetFBConfigAttrib", (GLvoid
*) glXGetFBConfigAttrib
},
1240 { "glXGetSelectedEvent", (GLvoid
*) glXGetSelectedEvent
},
1241 { "glXGetVisualFromFBConfig", (GLvoid
*) glXGetVisualFromFBConfig
},
1242 { "glXMakeContextCurrent", (GLvoid
*) glXMakeContextCurrent
},
1243 { "glXQueryContext", (GLvoid
*) glXQueryContext
},
1244 { "glXQueryDrawable", (GLvoid
*) glXQueryDrawable
},
1245 { "glXSelectEvent", (GLvoid
*) glXSelectEvent
},
1247 /*** GLX_SGI_video_sync ***/
1248 { "glXGetVideoSyncSGI", (GLvoid
*) glXGetVideoSyncSGI
},
1249 { "glXWaitVideoSyncSGI", (GLvoid
*) glXWaitVideoSyncSGI
},
1251 /*** GLX_MESA_copy_sub_buffer ***/
1252 { "glXCopySubBufferMESA", (GLvoid
*) glXCopySubBufferMESA
},
1254 /*** GLX_MESA_release_buffers ***/
1255 { "glXReleaseBuffersMESA", (GLvoid
*) glXReleaseBuffersMESA
},
1257 /*** GLX_MESA_pixmap_colormap ***/
1258 { "glXCreateGLXPixmapMESA", (GLvoid
*) glXCreateGLXPixmapMESA
},
1260 /*** GLX_MESA_set_3dfx_mode ***/
1261 { "glXSet3DfxModeMESA", (GLvoid
*) glXSet3DfxModeMESA
},
1263 /*** GLX_ARB_get_proc_address ***/
1264 { "glXGetProcAddressARB", (GLvoid
*) glXGetProcAddressARB
},
1266 { NULL
, NULL
} /* end of list */
1272 * Return address of named glX function, or NULL if not found.
1275 _glxapi_get_proc_address(const char *funcName
)
1278 for (i
= 0; GLX_functions
[i
].Name
; i
++) {
1279 if (strcmp(GLX_functions
[i
].Name
, funcName
) == 0)
1280 return GLX_functions
[i
].Address
;
1288 * This function does not get dispatched through the dispatch table
1289 * since it's really a "meta" function.
1291 void (*glXGetProcAddressARB(const GLubyte
*procName
))()
1293 typedef void (*gl_function
)();
1296 f
= (gl_function
) _glxapi_get_proc_address((const char *) procName
);
1301 f
= (gl_function
) _glapi_get_proc_address((const char *) procName
);