1 /* $Id: glxapi.c,v 1.26 2001/05/29 19:48:46 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.\n");
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 #ifdef GLX_BUILD_IN_XLIB_MESA
676 /* Use real libGL's glXGetCurrentDisplayEXT() function */
678 /* stand-alone Mesa */
679 Display
*glXGetCurrentDisplayEXT(void)
681 return glXGetCurrentDisplay();
685 GLXContext
glXImportContextEXT(Display
*dpy
, GLXContextID contextID
)
687 struct _glxapi_table
*t
;
688 GET_DISPATCH(dpy
, t
);
691 return (t
->ImportContextEXT
)(dpy
, contextID
);
694 int glXQueryContextInfoEXT(Display
*dpy
, GLXContext context
, int attribute
,int *value
)
696 struct _glxapi_table
*t
;
697 GET_DISPATCH(dpy
, t
);
699 return 0; /* XXX ok? */
700 return (t
->QueryContextInfoEXT
)(dpy
, context
, attribute
, value
);
705 /*** GLX_SGIX_fbconfig ***/
707 int glXGetFBConfigAttribSGIX(Display
*dpy
, GLXFBConfigSGIX config
, int attribute
, int *value
)
709 struct _glxapi_table
*t
;
710 GET_DISPATCH(dpy
, t
);
713 return (t
->GetFBConfigAttribSGIX
)(dpy
, config
, attribute
, value
);
716 GLXFBConfigSGIX
*glXChooseFBConfigSGIX(Display
*dpy
, int screen
, int *attrib_list
, int *nelements
)
718 struct _glxapi_table
*t
;
719 GET_DISPATCH(dpy
, t
);
722 return (t
->ChooseFBConfigSGIX
)(dpy
, screen
, attrib_list
, nelements
);
725 GLXPixmap
glXCreateGLXPixmapWithConfigSGIX(Display
*dpy
, GLXFBConfigSGIX config
, Pixmap pixmap
)
727 struct _glxapi_table
*t
;
728 GET_DISPATCH(dpy
, t
);
731 return (t
->CreateGLXPixmapWithConfigSGIX
)(dpy
, config
, pixmap
);
734 GLXContext
glXCreateContextWithConfigSGIX(Display
*dpy
, GLXFBConfigSGIX config
, int render_type
, GLXContext share_list
, Bool direct
)
736 struct _glxapi_table
*t
;
737 GET_DISPATCH(dpy
, t
);
740 return (t
->CreateContextWithConfigSGIX
)(dpy
, config
, render_type
, share_list
, direct
);
743 XVisualInfo
* glXGetVisualFromFBConfigSGIX(Display
*dpy
, GLXFBConfigSGIX config
)
745 struct _glxapi_table
*t
;
746 GET_DISPATCH(dpy
, t
);
749 return (t
->GetVisualFromFBConfigSGIX
)(dpy
, config
);
752 GLXFBConfigSGIX
glXGetFBConfigFromVisualSGIX(Display
*dpy
, XVisualInfo
*vis
)
754 struct _glxapi_table
*t
;
755 GET_DISPATCH(dpy
, t
);
758 return (t
->GetFBConfigFromVisualSGIX
)(dpy
, vis
);
763 /*** GLX_SGIX_pbuffer ***/
765 GLXPbufferSGIX
glXCreateGLXPbufferSGIX(Display
*dpy
, GLXFBConfigSGIX config
, unsigned int width
, unsigned int height
, int *attrib_list
)
767 struct _glxapi_table
*t
;
768 GET_DISPATCH(dpy
, t
);
771 return (t
->CreateGLXPbufferSGIX
)(dpy
, config
, width
, height
, attrib_list
);
774 void glXDestroyGLXPbufferSGIX(Display
*dpy
, GLXPbufferSGIX pbuf
)
776 struct _glxapi_table
*t
;
777 GET_DISPATCH(dpy
, t
);
780 (t
->DestroyGLXPbufferSGIX
)(dpy
, pbuf
);
783 int glXQueryGLXPbufferSGIX(Display
*dpy
, GLXPbufferSGIX pbuf
, int attribute
, unsigned int *value
)
785 struct _glxapi_table
*t
;
786 GET_DISPATCH(dpy
, t
);
789 return (t
->QueryGLXPbufferSGIX
)(dpy
, pbuf
, attribute
, value
);
792 void glXSelectEventSGIX(Display
*dpy
, GLXDrawable drawable
, unsigned long mask
)
794 struct _glxapi_table
*t
;
795 GET_DISPATCH(dpy
, t
);
798 (t
->SelectEventSGIX
)(dpy
, drawable
, mask
);
801 void glXGetSelectedEventSGIX(Display
*dpy
, GLXDrawable drawable
, unsigned long *mask
)
803 struct _glxapi_table
*t
;
804 GET_DISPATCH(dpy
, t
);
807 (t
->GetSelectedEventSGIX
)(dpy
, drawable
, mask
);
812 /*** GLX_SGI_cushion ***/
814 void glXCushionSGI(Display
*dpy
, Window win
, float cushion
)
816 struct _glxapi_table
*t
;
817 GET_DISPATCH(dpy
, t
);
820 (t
->CushionSGI
)(dpy
, win
, cushion
);
825 /*** GLX_SGIX_video_resize ***/
827 int glXBindChannelToWindowSGIX(Display
*dpy
, int screen
, int channel
, Window window
)
829 struct _glxapi_table
*t
;
830 GET_DISPATCH(dpy
, t
);
833 return (t
->BindChannelToWindowSGIX
)(dpy
, screen
, channel
, window
);
836 int glXChannelRectSGIX(Display
*dpy
, int screen
, int channel
, int x
, int y
, int w
, int h
)
838 struct _glxapi_table
*t
;
839 GET_DISPATCH(dpy
, t
);
842 return (t
->ChannelRectSGIX
)(dpy
, screen
, channel
, x
, y
, w
, h
);
845 int glXQueryChannelRectSGIX(Display
*dpy
, int screen
, int channel
, int *x
, int *y
, int *w
, int *h
)
847 struct _glxapi_table
*t
;
848 GET_DISPATCH(dpy
, t
);
851 return (t
->QueryChannelRectSGIX
)(dpy
, screen
, channel
, x
, y
, w
, h
);
854 int glXQueryChannelDeltasSGIX(Display
*dpy
, int screen
, int channel
, int *dx
, int *dy
, int *dw
, int *dh
)
856 struct _glxapi_table
*t
;
857 GET_DISPATCH(dpy
, t
);
860 return (t
->QueryChannelDeltasSGIX
)(dpy
, screen
, channel
, dx
, dy
, dw
, dh
);
863 int glXChannelRectSyncSGIX(Display
*dpy
, int screen
, int channel
, GLenum synctype
)
865 struct _glxapi_table
*t
;
866 GET_DISPATCH(dpy
, t
);
869 return (t
->ChannelRectSyncSGIX
)(dpy
, screen
, channel
, synctype
);
874 #if defined(_DM_BUFFER_H_)
876 Bool
glXAssociateDMPbufferSGIX(Display
*dpy
, GLXPbufferSGIX pbuffer
, DMparams
*params
, DMbuffer dmbuffer
)
878 struct _glxapi_table
*t
;
879 GET_DISPATCH(dpy
, t
);
882 return (t
->AssociateDMPbufferSGIX
)(dpy
, pbuffer
, params
, dmbuffer
);
888 /*** GLX_SGIX_swap_group ***/
890 void glXJoinSwapGroupSGIX(Display
*dpy
, GLXDrawable drawable
, GLXDrawable member
)
892 struct _glxapi_table
*t
;
893 GET_DISPATCH(dpy
, t
);
896 (*t
->JoinSwapGroupSGIX
)(dpy
, drawable
, member
);
900 /*** 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
);
922 /*** GLX_SUN_get_transparent_index ***/
924 Status
glXGetTransparentIndexSUN(Display
*dpy
, Window overlay
, Window underlay
, long *pTransparent
)
926 struct _glxapi_table
*t
;
927 GET_DISPATCH(dpy
, t
);
930 return (*t
->GetTransparentIndexSUN
)(dpy
, overlay
, underlay
, pTransparent
);
935 /*** GLX_MESA_copy_sub_buffer ***/
937 void glXCopySubBufferMESA(Display
*dpy
, GLXDrawable drawable
, int x
, int y
, int width
, int height
)
939 struct _glxapi_table
*t
;
940 GET_DISPATCH(dpy
, t
);
943 (t
->CopySubBufferMESA
)(dpy
, drawable
, x
, y
, width
, height
);
948 /*** GLX_MESA_release_buffers ***/
950 Bool
glXReleaseBuffersMESA(Display
*dpy
, Window w
)
952 struct _glxapi_table
*t
;
953 GET_DISPATCH(dpy
, t
);
956 return (t
->ReleaseBuffersMESA
)(dpy
, w
);
961 /*** GLX_MESA_pixmap_colormap ***/
963 GLXPixmap
glXCreateGLXPixmapMESA(Display
*dpy
, XVisualInfo
*visinfo
, Pixmap pixmap
, Colormap cmap
)
965 struct _glxapi_table
*t
;
966 GET_DISPATCH(dpy
, t
);
969 return (t
->CreateGLXPixmapMESA
)(dpy
, visinfo
, pixmap
, cmap
);
974 /*** GLX_MESA_set_3dfx_mode ***/
976 Bool
glXSet3DfxModeMESA(int mode
)
978 struct _glxapi_table
*t
;
979 Display
*dpy
= glXGetCurrentDisplay();
980 GET_DISPATCH(dpy
, t
);
983 return (t
->Set3DfxModeMESA
)(mode
);
989 /**********************************************************************/
990 /* GLX API management functions */
991 /**********************************************************************/
995 _glxapi_get_version(void)
1002 * Return array of extension strings.
1005 _glxapi_get_extensions(void)
1007 static const char *extensions
[] = {
1008 #ifdef GLX_EXT_import_context
1009 "GLX_EXT_import_context",
1011 #ifdef GLX_SGI_video_sync
1012 "GLX_SGI_video_sync",
1014 #ifdef GLX_MESA_copy_sub_buffer
1015 "GLX_MESA_copy_sub_buffer",
1017 #ifdef GLX_MESA_release_buffers
1018 "GLX_MESA_release_buffers",
1020 #ifdef GLX_MESA_pixmap_colormap
1021 "GLX_MESA_pixmap_colormap",
1023 #ifdef GLX_MESA_set_3dfx_mode
1024 "GLX_MESA_set_3dfx_mode",
1033 * Return size of the GLX dispatch table, in entries, not bytes.
1036 _glxapi_get_dispatch_table_size(void)
1038 return sizeof(struct _glxapi_table
) / sizeof(void *);
1043 generic_no_op_func(void)
1050 * Initialize all functions in given dispatch table to be no-ops
1053 _glxapi_set_no_op_table(struct _glxapi_table
*t
)
1055 GLuint n
= _glxapi_get_dispatch_table_size();
1057 void **dispatch
= (void **) t
;
1058 for (i
= 0; i
< n
; i
++) {
1059 dispatch
[i
] = (void *) generic_no_op_func
;
1066 * Open the named library and use dlsym() to populate the given dispatch
1067 * table with GLX function pointers.
1068 * Return: true = all OK
1069 * false = can't open libName or can't get required GLX function
1072 _glxapi_load_library_table(const char *libName
, struct _glxapi_table
*t
)
1075 void **entry
; /* used to avoid a lot of cast/type warnings */
1077 libHandle
= dlopen(libName
, 0);
1082 #define GET_REQ_FUNCTION(ENTRY, NAME) \
1083 entry = (void **) &(t->ENTRY); \
1084 *entry = dlsym(libHandle, NAME); \
1086 fprintf(stderr, "libGL Error: couldn't load %s from %s\n", \
1088 dlclose(libHandle); \
1092 /* 1.0 and 1.1 functions */
1093 GET_REQ_FUNCTION(ChooseVisual
, "glXChooseVisual");
1094 GET_REQ_FUNCTION(CopyContext
, "glXCopyContext");
1095 GET_REQ_FUNCTION(CreateContext
, "glXCreateContext");
1096 GET_REQ_FUNCTION(CreateGLXPixmap
, "glXCreateGLXPixmap");
1097 GET_REQ_FUNCTION(DestroyContext
, "glXDestroyContext");
1098 GET_REQ_FUNCTION(GetConfig
, "glXGetConfig");
1099 GET_REQ_FUNCTION(IsDirect
, "glXIsDirect");
1100 GET_REQ_FUNCTION(MakeCurrent
, "glXMakeCurrent");
1101 GET_REQ_FUNCTION(QueryExtension
, "glXQueryExtension");
1102 GET_REQ_FUNCTION(QueryVersion
, "glXQueryVersion");
1103 GET_REQ_FUNCTION(SwapBuffers
, "glXSwapBuffers");
1104 GET_REQ_FUNCTION(UseXFont
, "glXUseXFont");
1105 GET_REQ_FUNCTION(WaitGL
, "glXWaitGL");
1106 GET_REQ_FUNCTION(WaitX
, "glXWaitX");
1107 GET_REQ_FUNCTION(GetClientString
, "glXGetClientString");
1108 GET_REQ_FUNCTION(QueryExtensionsString
, "glXQueryExtensionsString");
1109 GET_REQ_FUNCTION(QueryServerString
, "glXQueryServerString");
1111 #define GET_OPT_FUNCTION(ENTRY, NAME) \
1112 entry = (void **) &(t->ENTRY); \
1113 *entry = dlsym(libHandle, NAME); \
1115 *entry = (void *) generic_no_op_func; \
1118 /* 1.2, 1.3 and extensions */
1119 GET_OPT_FUNCTION(ChooseFBConfig
, "glXChooseFBConfig");
1120 GET_OPT_FUNCTION(CreateNewContext
, "glXCreateNewContext");
1121 GET_OPT_FUNCTION(CreatePbuffer
, "glXCreatePbuffer");
1122 GET_OPT_FUNCTION(CreatePixmap
, "glXCreatePixmap");
1123 GET_OPT_FUNCTION(CreateWindow
, "glXCreateWindow");
1124 GET_OPT_FUNCTION(DestroyPbuffer
, "glXDestroyPbuffer");
1125 GET_OPT_FUNCTION(DestroyPixmap
, "glXDestroyPixmap");
1126 GET_OPT_FUNCTION(DestroyWindow
, "glXDestroyWindow");
1127 GET_OPT_FUNCTION(GetFBConfigAttrib
, "glXGetFBConfigAttrib");
1128 GET_OPT_FUNCTION(GetFBConfigs
, "glXGetFBConfigs");
1129 GET_OPT_FUNCTION(GetSelectedEvent
, "glXGetSelectedEvent");
1130 GET_OPT_FUNCTION(GetVisualFromFBConfig
, "glXGetVisualFromFBConfig");
1131 GET_OPT_FUNCTION(MakeContextCurrent
, "glXMakeContextCurrent");
1132 GET_OPT_FUNCTION(QueryContext
, "glXQueryContext");
1133 GET_OPT_FUNCTION(QueryDrawable
, "glXQueryDrawable");
1134 GET_OPT_FUNCTION(SelectEvent
, "glXSelectEvent");
1135 /*** GLX_SGI_swap_control ***/
1136 GET_OPT_FUNCTION(SwapIntervalSGI
, "glXSwapIntervalSGI");
1137 /*** GLX_SGI_video_sync ***/
1138 GET_OPT_FUNCTION(GetVideoSyncSGI
, "glXGetVideoSyncSGI");
1139 GET_OPT_FUNCTION(WaitVideoSyncSGI
, "glXWaitVideoSyncSGI");
1140 /*** GLX_SGI_make_current_read ***/
1141 GET_OPT_FUNCTION(MakeCurrentReadSGI
, "glXMakeCurrentReadSGI");
1142 GET_OPT_FUNCTION(GetCurrentReadDrawableSGI
, "glXGetCurrentReadDrawableSGI");
1143 /*** GLX_SGIX_video_source ***/
1145 GET_OPT_FUNCTION(CreateGLXVideoSourceSGIX
, "glXCreateGLXVideoSourceSGIX");
1146 GET_OPT_FUNCTION(DestroyGLXVideoSourceSGIX
, "glXDestroyGLXVideoSourceSGIX");
1148 /*** GLX_EXT_import_context ***/
1149 GET_OPT_FUNCTION(FreeContextEXT
, "glXFreeContextEXT");
1150 GET_OPT_FUNCTION(GetContextIDEXT
, "glXGetContextIDEXT");
1151 GET_OPT_FUNCTION(GetCurrentDisplayEXT
, "glXGetCurrentDisplayEXT");
1152 GET_OPT_FUNCTION(ImportContextEXT
, "glXImportContextEXT");
1153 GET_OPT_FUNCTION(QueryContextInfoEXT
, "glXQueryContextInfoEXT");
1154 /*** GLX_SGIX_fbconfig ***/
1155 GET_OPT_FUNCTION(GetFBConfigAttribSGIX
, "glXGetFBConfigAttribSGIX");
1156 GET_OPT_FUNCTION(ChooseFBConfigSGIX
, "glXChooseFBConfigSGIX");
1157 GET_OPT_FUNCTION(CreateGLXPixmapWithConfigSGIX
, "glXCreateGLXPixmapWithConfigSGIX");
1158 GET_OPT_FUNCTION(CreateContextWithConfigSGIX
, "glXCreateContextWithConfigSGIX");
1159 GET_OPT_FUNCTION(GetVisualFromFBConfigSGIX
, "glXGetVisualFromFBConfigSGIX");
1160 GET_OPT_FUNCTION(GetFBConfigFromVisualSGIX
, "glXGetFBConfigFromVisualSGIX");
1161 /*** GLX_SGIX_pbuffer ***/
1162 GET_OPT_FUNCTION(CreateGLXPbufferSGIX
, "glXCreateGLXPbufferSGIX");
1163 GET_OPT_FUNCTION(DestroyGLXPbufferSGIX
, "glXDestroyGLXPbufferSGIX");
1164 GET_OPT_FUNCTION(QueryGLXPbufferSGIX
, "glXQueryGLXPbufferSGIX");
1165 GET_OPT_FUNCTION(SelectEventSGIX
, "glXSelectEventSGIX");
1166 GET_OPT_FUNCTION(GetSelectedEventSGIX
, "glXGetSelectedEventSGIX");
1167 /*** GLX_SGI_cushion ***/
1168 GET_OPT_FUNCTION(CushionSGI
, "glXCushionSGI");
1169 /*** GLX_SGIX_video_resize ***/
1170 GET_OPT_FUNCTION(BindChannelToWindowSGIX
, "glXBindChannelToWindowSGIX");
1171 GET_OPT_FUNCTION(ChannelRectSGIX
, "glXChannelRectSGIX");
1172 GET_OPT_FUNCTION(QueryChannelRectSGIX
, "glXQueryChannelRectSGIX");
1173 GET_OPT_FUNCTION(QueryChannelDeltasSGIX
, "glXQueryChannelDeltasSGIX");
1174 GET_OPT_FUNCTION(ChannelRectSyncSGIX
, "glXChannelRectSyncSGIX");
1175 /*** GLX_SGIX_dmbuffer ***/
1176 #if defined (_DM_BUFFER_H_)
1177 GET_OPT_FUNCTION(AssociateDMPbufferSGIX
, "glXAssociateDMPbufferSGIX");
1179 /*** GLX_SGIX_swap_group ***/
1180 GET_OPT_FUNCTION(JoinSwapGroupSGIX
, "glXJoinSwapGroupSGIX");
1181 /*** GLX_SGIX_swap_barrier ***/
1182 GET_OPT_FUNCTION(BindSwapBarrierSGIX
, "glXBindSwapBarrierSGIX");
1183 GET_OPT_FUNCTION(QueryMaxSwapBarriersSGIX
, "glXQueryMaxSwapBarriersSGIX");
1184 /*** GLX_SUN_get_transparent_index ***/
1185 GET_OPT_FUNCTION(GetTransparentIndexSUN
, "glXGetTransparentIndexSUN");
1186 /*** GLX_MESA_copy_sub_buffer ***/
1187 GET_OPT_FUNCTION(CopySubBufferMESA
, "glXCopySubBufferMESA");
1188 /*** GLX_MESA_release_buffers ***/
1189 GET_OPT_FUNCTION(ReleaseBuffersMESA
, "glXReleaseBuffersMESA");
1190 /*** GLX_MESA_pixmap_colormap ***/
1191 GET_OPT_FUNCTION(CreateGLXPixmapMESA
, "glXCreateGLXPixmapMESA");
1192 /*** GLX_MESA_set_3dfx_mode ***/
1193 GET_OPT_FUNCTION(Set3DfxModeMESA
, "glXSet3DfxModeMESA");
1201 struct name_address_pair
{
1206 static struct name_address_pair GLX_functions
[] = {
1207 /*** GLX_VERSION_1_0 ***/
1208 { "glXChooseVisual", (GLvoid
*) glXChooseVisual
},
1209 { "glXCopyContext", (GLvoid
*) glXCopyContext
},
1210 { "glXCreateContext", (GLvoid
*) glXCreateContext
},
1211 { "glXCreateGLXPixmap", (GLvoid
*) glXCreateGLXPixmap
},
1212 { "glXDestroyContext", (GLvoid
*) glXDestroyContext
},
1213 { "glXDestroyGLXPixmap", (GLvoid
*) glXDestroyGLXPixmap
},
1214 { "glXGetConfig", (GLvoid
*) glXGetConfig
},
1215 { "glXGetCurrentContext", (GLvoid
*) glXGetCurrentContext
},
1216 { "glXGetCurrentDrawable", (GLvoid
*) glXGetCurrentDrawable
},
1217 { "glXIsDirect", (GLvoid
*) glXIsDirect
},
1218 { "glXMakeCurrent", (GLvoid
*) glXMakeCurrent
},
1219 { "glXQueryExtension", (GLvoid
*) glXQueryExtension
},
1220 { "glXQueryVersion", (GLvoid
*) glXQueryVersion
},
1221 { "glXSwapBuffers", (GLvoid
*) glXSwapBuffers
},
1222 { "glXUseXFont", (GLvoid
*) glXUseXFont
},
1223 { "glXWaitGL", (GLvoid
*) glXWaitGL
},
1224 { "glXWaitX", (GLvoid
*) glXWaitX
},
1226 /*** GLX_VERSION_1_1 ***/
1227 { "glXGetClientString", (GLvoid
*) glXGetClientString
},
1228 { "glXQueryExtensionsString", (GLvoid
*) glXQueryExtensionsString
},
1229 { "glXQueryServerString", (GLvoid
*) glXQueryServerString
},
1231 /*** GLX_VERSION_1_2 ***/
1232 { "glXGetCurrentDisplay", (GLvoid
*) glXGetCurrentDisplay
},
1234 /*** GLX_VERSION_1_3 ***/
1235 { "glXChooseFBConfig", (GLvoid
*) glXChooseFBConfig
},
1236 { "glXCreateNewContext", (GLvoid
*) glXCreateNewContext
},
1237 { "glXCreatePbuffer", (GLvoid
*) glXCreatePbuffer
},
1238 { "glXCreatePixmap", (GLvoid
*) glXCreatePixmap
},
1239 { "glXCreateWindow", (GLvoid
*) glXCreateWindow
},
1240 { "glXDestroyPbuffer", (GLvoid
*) glXDestroyPbuffer
},
1241 { "glXDestroyPixmap", (GLvoid
*) glXDestroyPixmap
},
1242 { "glXDestroyWindow", (GLvoid
*) glXDestroyWindow
},
1243 { "glXGetCurrentReadDrawable", (GLvoid
*) glXGetCurrentReadDrawable
},
1244 { "glXGetFBConfigAttrib", (GLvoid
*) glXGetFBConfigAttrib
},
1245 { "glXGetFBConfigs", (GLvoid
*) glXGetFBConfigs
},
1246 { "glXGetSelectedEvent", (GLvoid
*) glXGetSelectedEvent
},
1247 { "glXGetVisualFromFBConfig", (GLvoid
*) glXGetVisualFromFBConfig
},
1248 { "glXMakeContextCurrent", (GLvoid
*) glXMakeContextCurrent
},
1249 { "glXQueryContext", (GLvoid
*) glXQueryContext
},
1250 { "glXQueryDrawable", (GLvoid
*) glXQueryDrawable
},
1251 { "glXSelectEvent", (GLvoid
*) glXSelectEvent
},
1253 /*** GLX_SGI_swap_control ***/
1254 { "glXSwapIntervalSGI", (GLvoid
*) glXSwapIntervalSGI
},
1256 /*** GLX_SGI_video_sync ***/
1257 { "glXGetVideoSyncSGI", (GLvoid
*) glXGetVideoSyncSGI
},
1258 { "glXWaitVideoSyncSGI", (GLvoid
*) glXWaitVideoSyncSGI
},
1260 /*** GLX_SGI_make_current_read ***/
1261 { "glXMakeCurrentReadSGI", (GLvoid
*) glXMakeCurrentReadSGI
},
1262 { "glXGetCurrentReadDrawableSGI", (GLvoid
*) glXGetCurrentReadDrawableSGI
},
1264 /*** GLX_SGIX_video_source ***/
1266 { "glXCreateGLXVideoSourceSGIX", (GLvoid
*) glXCreateGLXVideoSourceSGIX
},
1267 { "glXDestroyGLXVideoSourceSGIX", (GLvoid
*) glXDestroyGLXVideoSourceSGIX
},
1270 /*** GLX_EXT_import_context ***/
1271 { "glXFreeContextEXT", (GLvoid
*) glXFreeContextEXT
},
1272 { "glXGetContextIDEXT", (GLvoid
*) glXGetContextIDEXT
},
1273 { "glXGetCurrentDisplayEXT", (GLvoid
*) glXGetCurrentDisplayEXT
},
1274 { "glXImportContextEXT", (GLvoid
*) glXImportContextEXT
},
1275 { "glXQueryContextInfoEXT", (GLvoid
*) glXQueryContextInfoEXT
},
1277 /*** GLX_SGIX_fbconfig ***/
1278 { "glXGetFBConfigAttribSGIX", (GLvoid
*) glXGetFBConfigAttribSGIX
},
1279 { "glXChooseFBConfigSGIX", (GLvoid
*) glXChooseFBConfigSGIX
},
1280 { "glXCreateGLXPixmapWithConfigSGIX", (GLvoid
*) glXCreateGLXPixmapWithConfigSGIX
},
1281 { "glXCreateContextWithConfigSGIX", (GLvoid
*) glXCreateContextWithConfigSGIX
},
1282 { "glXGetVisualFromFBConfigSGIX", (GLvoid
*) glXGetVisualFromFBConfigSGIX
},
1283 { "glXGetFBConfigFromVisualSGIX", (GLvoid
*) glXGetFBConfigFromVisualSGIX
},
1285 /*** GLX_SGIX_pbuffer ***/
1286 { "glXCreateGLXPbufferSGIX", (GLvoid
*) glXCreateGLXPbufferSGIX
},
1287 { "glXDestroyGLXPbufferSGIX", (GLvoid
*) glXDestroyGLXPbufferSGIX
},
1288 { "glXQueryGLXPbufferSGIX", (GLvoid
*) glXQueryGLXPbufferSGIX
},
1289 { "glXSelectEventSGIX", (GLvoid
*) glXSelectEventSGIX
},
1290 { "glXGetSelectedEventSGIX", (GLvoid
*) glXGetSelectedEventSGIX
},
1292 /*** GLX_SGI_cushion ***/
1293 { "glXCushionSGI", (GLvoid
*) glXCushionSGI
},
1295 /*** GLX_SGIX_video_resize ***/
1296 { "glXBindChannelToWindowSGIX", (GLvoid
*) glXBindChannelToWindowSGIX
},
1297 { "glXChannelRectSGIX", (GLvoid
*) glXChannelRectSGIX
},
1298 { "glXQueryChannelRectSGIX", (GLvoid
*) glXQueryChannelRectSGIX
},
1299 { "glXQueryChannelDeltasSGIX", (GLvoid
*) glXQueryChannelDeltasSGIX
},
1300 { "glXChannelRectSyncSGIX", (GLvoid
*) glXChannelRectSyncSGIX
},
1302 /*** GLX_SGIX_dmbuffer **/
1303 #if defined(_DM_BUFFER_H_)
1304 { "glXAssociateDMPbufferSGIX", (GLvoid
*) glXAssociateDMPbufferSGIX
},
1307 /*** GLX_SGIX_swap_group ***/
1308 { "glXJoinSwapGroupSGIX", (GLvoid
*) glXJoinSwapGroupSGIX
},
1310 /*** GLX_SGIX_swap_barrier ***/
1311 { "glXBindSwapBarrierSGIX", (GLvoid
*) glXBindSwapBarrierSGIX
},
1312 { "glXQueryMaxSwapBarriersSGIX", (GLvoid
*) glXQueryMaxSwapBarriersSGIX
},
1314 /*** GLX_SUN_get_transparent_index ***/
1315 { "glXGetTransparentIndexSUN", (GLvoid
*) glXGetTransparentIndexSUN
},
1317 /*** GLX_MESA_copy_sub_buffer ***/
1318 { "glXCopySubBufferMESA", (GLvoid
*) glXCopySubBufferMESA
},
1320 /*** GLX_MESA_pixmap_colormap ***/
1321 { "glXCreateGLXPixmapMESA", (GLvoid
*) glXCreateGLXPixmapMESA
},
1323 /*** GLX_MESA_release_buffers ***/
1324 { "glXReleaseBuffersMESA", (GLvoid
*) glXReleaseBuffersMESA
},
1326 /*** GLX_MESA_set_3dfx_mode ***/
1327 { "glXSet3DfxModeMESA", (GLvoid
*) glXSet3DfxModeMESA
},
1329 /*** GLX_ARB_get_proc_address ***/
1330 { "glXGetProcAddressARB", (GLvoid
*) glXGetProcAddressARB
},
1332 { NULL
, NULL
} /* end of list */
1338 * Return address of named glX function, or NULL if not found.
1341 _glxapi_get_proc_address(const char *funcName
)
1344 for (i
= 0; GLX_functions
[i
].Name
; i
++) {
1345 if (strcmp(GLX_functions
[i
].Name
, funcName
) == 0)
1346 return GLX_functions
[i
].Address
;
1354 * This function does not get dispatched through the dispatch table
1355 * since it's really a "meta" function.
1357 void (*glXGetProcAddressARB(const GLubyte
*procName
))()
1359 typedef void (*gl_function
)();
1362 f
= (gl_function
) _glxapi_get_proc_address((const char *) procName
);
1367 f
= (gl_function
) _glapi_get_proc_address((const char *) procName
);