variety of updates to better conform to real GLX
[mesa.git] / src / mesa / drivers / x11 / glxapi.c
1 /* $Id: glxapi.c,v 1.17 2000/06/08 22:50:28 brianp Exp $ */
2
3 /*
4 * Mesa 3-D graphics library
5 * Version: 3.3
6 *
7 * Copyright (C) 1999-2000 Brian Paul All Rights Reserved.
8 *
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:
15 *
16 * The above copyright notice and this permission notice shall be included
17 * in all copies or substantial portions of the Software.
18 *
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.
25 */
26
27
28 /*
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
31 * pseudo-GLX module.
32 */
33
34
35 #include <assert.h>
36 #include <stdlib.h>
37 #include "glapi.h"
38 #include "glxapi.h"
39
40
41 /*
42 * XXX - this really shouldn't be here.
43 * Instead, add -DUSE_MESA_GLX to the compiler flags when needed.
44 */
45 #define USE_MESA_GLX 1
46
47
48 /* Rather than include possibly non-existant headers... */
49 #ifdef USE_SGI_GLX
50 extern struct _glxapi_table *_sgi_GetGLXDispatchtable(void);
51 #endif
52 #ifdef USE_UTAH_GLX
53 extern struct _glxapi_table *_utah_GetGLXDispatchTable(void);
54 #endif
55 #ifdef USE_MESA_GLX
56 extern struct _glxapi_table *_mesa_GetGLXDispatchTable(void);
57 #endif
58
59
60
61 struct display_dispatch {
62 Display *Dpy;
63 struct _glxapi_table *Table;
64 struct display_dispatch *Next;
65 };
66
67 static struct display_dispatch *DispatchList = NULL;
68
69
70 static struct _glxapi_table *
71 get_dispatch(Display *dpy)
72 {
73 static Display *prevDisplay = NULL;
74 static struct _glxapi_table *prevTable = NULL;
75
76 if (!dpy)
77 return NULL;
78
79 /* try cached display */
80 if (dpy == prevDisplay) {
81 return prevTable;
82 }
83
84 /* search list of display/dispatch pairs for this display */
85 {
86 const struct display_dispatch *d = DispatchList;
87 while (d) {
88 if (d->Dpy == dpy) {
89 prevDisplay = dpy;
90 prevTable = d->Table;
91 return d->Table; /* done! */
92 }
93 d = d->Next;
94 }
95 }
96
97 /* A new display, determine if we should use real GLX (SGI / Utah)
98 * or Mesa's pseudo-GLX.
99 */
100 {
101 struct _glxapi_table *t = NULL;
102
103 #if defined(USE_SGI_GLX) || defined(USE_UTAH_GLX)
104 if (!getenv("MESA_FORCE_SOFTX")) {
105 int ignore;
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();
112 #endif
113 }
114 }
115 #endif
116
117 #if defined(USE_MESA_GLX)
118 if (!t) {
119 t = _mesa_GetGLXDispatchTable();
120 assert(t); /* this has to work */
121 }
122 #endif
123
124 if (t) {
125 struct display_dispatch *d;
126 d = (struct display_dispatch *) malloc(sizeof(struct display_dispatch));
127 if (d) {
128 d->Dpy = dpy;
129 d->Table = t;
130 /* insert at head of list */
131 d->Next = DispatchList;
132 DispatchList = d;
133 /* update cache */
134 prevDisplay = dpy;
135 prevTable = t;
136 return t;
137 }
138 }
139 }
140
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!
144 */
145 return NULL;
146 }
147
148
149
150 /* Set by glXMakeCurrent() and glXMakeContextCurrent() only */
151 static Display *CurrentDisplay = NULL;
152 static GLXContext CurrentContext = 0;
153 static GLXDrawable CurrentDrawable = 0;
154 static GLXDrawable CurrentReadDrawable = 0;
155
156
157
158 /*
159 * GLX API entrypoints
160 */
161
162
163 XVisualInfo *glXChooseVisual(Display *dpy, int screen, int *list)
164 {
165 struct _glxapi_table *t = get_dispatch(dpy);
166 if (!t)
167 return NULL;
168 return (t->ChooseVisual)(dpy, screen, list);
169 }
170
171
172 void glXCopyContext(Display *dpy, GLXContext src, GLXContext dst, unsigned long mask)
173 {
174 struct _glxapi_table *t = get_dispatch(dpy);
175 if (!t)
176 return;
177 (t->CopyContext)(dpy, src, dst, mask);
178 }
179
180
181 GLXContext glXCreateContext(Display *dpy, XVisualInfo *visinfo, GLXContext shareList, Bool direct)
182 {
183 struct _glxapi_table *t = get_dispatch(dpy);
184 if (!t)
185 return 0;
186 return (t->CreateContext)(dpy, visinfo, shareList, direct);
187 }
188
189
190 GLXPixmap glXCreateGLXPixmap(Display *dpy, XVisualInfo *visinfo, Pixmap pixmap)
191 {
192 struct _glxapi_table *t = get_dispatch(dpy);
193 if (!t)
194 return 0;
195 return (t->CreateGLXPixmap)(dpy, visinfo, pixmap);
196 }
197
198
199 void glXDestroyContext(Display *dpy, GLXContext ctx)
200 {
201 struct _glxapi_table *t = get_dispatch(dpy);
202 if (!t)
203 return;
204 (t->DestroyContext)(dpy, ctx);
205 }
206
207
208 void glXDestroyGLXPixmap(Display *dpy, GLXPixmap pixmap)
209 {
210 struct _glxapi_table *t = get_dispatch(dpy);
211 if (!t)
212 return;
213 (t->DestroyGLXPixmap)(dpy, pixmap);
214 }
215
216
217 int glXGetConfig(Display *dpy, XVisualInfo *visinfo, int attrib, int *value)
218 {
219 struct _glxapi_table *t = get_dispatch(dpy);
220 if (!t)
221 return GLX_NO_EXTENSION;
222 return (t->GetConfig)(dpy, visinfo, attrib, value);
223 }
224
225
226 GLXContext glXGetCurrentContext(void)
227 {
228 return CurrentContext;
229 }
230
231
232 GLXDrawable glXGetCurrentDrawable(void)
233 {
234 return CurrentDrawable;
235 }
236
237
238 Bool glXIsDirect(Display *dpy, GLXContext ctx)
239 {
240 struct _glxapi_table *t = get_dispatch(dpy);
241 if (!t)
242 return False;
243 return (t->IsDirect)(dpy, ctx);
244 }
245
246
247 Bool glXMakeCurrent(Display *dpy, GLXDrawable drawable, GLXContext ctx)
248 {
249 Bool b;
250 struct _glxapi_table *t = get_dispatch(dpy);
251 if (!t)
252 return False;
253 b = (*t->MakeCurrent)(dpy, drawable, ctx);
254 if (b) {
255 CurrentDisplay = dpy;
256 CurrentContext = ctx;
257 CurrentDrawable = drawable;
258 CurrentReadDrawable = drawable;
259 }
260 return b;
261 }
262
263
264 Bool glXQueryExtension(Display *dpy, int *errorb, int *event)
265 {
266 struct _glxapi_table *t = get_dispatch(dpy);
267 if (!t)
268 return False;
269 return (t->QueryExtension)(dpy, errorb, event);
270 }
271
272
273 Bool glXQueryVersion(Display *dpy, int *maj, int *min)
274 {
275 struct _glxapi_table *t = get_dispatch(dpy);
276 if (!t)
277 return False;
278 return (t->QueryVersion)(dpy, maj, min);
279 }
280
281
282 void glXSwapBuffers(Display *dpy, GLXDrawable drawable)
283 {
284 struct _glxapi_table *t = get_dispatch(dpy);
285 if (!t)
286 return;
287 (t->SwapBuffers)(dpy, drawable);
288 }
289
290
291 void glXUseXFont(Font font, int first, int count, int listBase)
292 {
293 struct _glxapi_table *t = get_dispatch(CurrentDisplay);
294 if (!t)
295 return;
296 (t->UseXFont)(font, first, count, listBase);
297 }
298
299
300 void glXWaitGL(void)
301 {
302 struct _glxapi_table *t = get_dispatch(CurrentDisplay);
303 if (!t)
304 return;
305 (t->WaitGL)();
306 }
307
308
309 void glXWaitX(void)
310 {
311 struct _glxapi_table *t = get_dispatch(CurrentDisplay);
312 if (!t)
313 return;
314 (t->WaitX)();
315 }
316
317
318
319 #ifdef GLX_VERSION_1_1
320
321 const char *glXGetClientString(Display *dpy, int name)
322 {
323 struct _glxapi_table *t = get_dispatch(dpy);
324 if (!t)
325 return NULL;
326 return (t->GetClientString)(dpy, name);
327 }
328
329
330 const char *glXQueryExtensionsString(Display *dpy, int screen)
331 {
332 struct _glxapi_table *t = get_dispatch(dpy);
333 if (!t)
334 return NULL;
335 return (t->QueryExtensionsString)(dpy, screen);
336 }
337
338
339 const char *glXQueryServerString(Display *dpy, int screen, int name)
340 {
341 struct _glxapi_table *t = get_dispatch(dpy);
342 if (!t)
343 return NULL;
344 return (t->QueryServerString)(dpy, screen, name);
345 }
346
347 #endif
348
349
350
351 #ifdef GLX_VERSION_1_2
352 Display *glXGetCurrentDisplay(void)
353 {
354 return CurrentDisplay;
355 }
356 #endif
357
358
359
360 #ifdef GLX_VERSION_1_3
361
362 GLXFBConfig *glXChooseFBConfig(Display *dpy, int screen, const int *attribList, int *nitems)
363 {
364 struct _glxapi_table *t = get_dispatch(dpy);
365 if (!t)
366 return 0;
367 return (t->ChooseFBConfig)(dpy, screen, attribList, nitems);
368 }
369
370
371 GLXContext glXCreateNewContext(Display *dpy, GLXFBConfig config, int renderType, GLXContext shareList, Bool direct)
372 {
373 struct _glxapi_table *t = get_dispatch(dpy);
374 if (!t)
375 return 0;
376 return (t->CreateNewContext)(dpy, config, renderType, shareList, direct);
377 }
378
379
380 GLXPbuffer glXCreatePbuffer(Display *dpy, GLXFBConfig config, const int *attribList)
381 {
382 struct _glxapi_table *t = get_dispatch(dpy);
383 if (!t)
384 return 0;
385 return (t->CreatePbuffer)(dpy, config, attribList);
386 }
387
388
389 GLXPixmap glXCreatePixmap(Display *dpy, GLXFBConfig config, Pixmap pixmap, const int *attribList)
390 {
391 struct _glxapi_table *t = get_dispatch(dpy);
392 if (!t)
393 return 0;
394 return (t->CreatePixmap)(dpy, config, pixmap, attribList);
395 }
396
397
398 GLXWindow glXCreateWindow(Display *dpy, GLXFBConfig config, Window win, const int *attribList)
399 {
400 struct _glxapi_table *t = get_dispatch(dpy);
401 if (!t)
402 return 0;
403 return (t->CreateWindow)(dpy, config, win, attribList);
404 }
405
406
407 void glXDestroyPbuffer(Display *dpy, GLXPbuffer pbuf)
408 {
409 struct _glxapi_table *t = get_dispatch(dpy);
410 if (!t)
411 return;
412 (t->DestroyPbuffer)(dpy, pbuf);
413 }
414
415
416 void glXDestroyPixmap(Display *dpy, GLXPixmap pixmap)
417 {
418 struct _glxapi_table *t = get_dispatch(dpy);
419 if (!t)
420 return;
421 (t->DestroyPixmap)(dpy, pixmap);
422 }
423
424
425 void glXDestroyWindow(Display *dpy, GLXWindow window)
426 {
427 struct _glxapi_table *t = get_dispatch(dpy);
428 if (!t)
429 return;
430 (t->DestroyWindow)(dpy, window);
431 }
432
433
434 GLXDrawable glXGetCurrentReadDrawable(void)
435 {
436 return CurrentReadDrawable;
437 }
438
439
440 int glXGetFBConfigAttrib(Display *dpy, GLXFBConfig config, int attribute, int *value)
441 {
442 struct _glxapi_table *t = get_dispatch(dpy);
443 if (!t)
444 return GLX_NO_EXTENSION;
445 return (t->GetFBConfigAttrib)(dpy, config, attribute, value);
446 }
447
448
449 GLXFBConfig *glXGetFBConfigs(Display *dpy, int screen, int *nelements)
450 {
451 struct _glxapi_table *t = get_dispatch(dpy);
452 if (!t)
453 return 0;
454 return (t->GetFBConfigs)(dpy, screen, nelements);
455 }
456
457 void glXGetSelectedEvent(Display *dpy, GLXDrawable drawable, unsigned long *mask)
458 {
459 struct _glxapi_table *t = get_dispatch(dpy);
460 if (!t)
461 return;
462 (t->GetSelectedEvent)(dpy, drawable, mask);
463 }
464
465
466 XVisualInfo *glXGetVisualFromFBConfig(Display *dpy, GLXFBConfig config)
467 {
468 struct _glxapi_table *t = get_dispatch(dpy);
469 if (!t)
470 return NULL;
471 return (t->GetVisualFromFBConfig)(dpy, config);
472 }
473
474
475 Bool glXMakeContextCurrent(Display *dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx)
476 {
477 struct _glxapi_table *t = get_dispatch(dpy);
478 Bool b;
479 if (!t)
480 return False;
481 b = (t->MakeContextCurrent)(dpy, draw, read, ctx);
482 if (b) {
483 CurrentDisplay = dpy;
484 CurrentContext = ctx;
485 CurrentDrawable = draw;
486 CurrentReadDrawable = read;
487 }
488 return b;
489 }
490
491
492 int glXQueryContext(Display *dpy, GLXContext ctx, int attribute, int *value)
493 {
494 struct _glxapi_table *t = get_dispatch(dpy);
495 assert(t);
496 if (!t)
497 return 0; /* XXX correct? */
498 return (t->QueryContext)(dpy, ctx, attribute, value);
499 }
500
501
502 void glXQueryDrawable(Display *dpy, GLXDrawable draw, int attribute, unsigned int *value)
503 {
504 struct _glxapi_table *t = get_dispatch(dpy);
505 if (!t)
506 return;
507 (t->QueryDrawable)(dpy, draw, attribute, value);
508 }
509
510
511 void glXSelectEvent(Display *dpy, GLXDrawable drawable, unsigned long mask)
512 {
513 struct _glxapi_table *t = get_dispatch(dpy);
514 if (!t)
515 return;
516 (t->SelectEvent)(dpy, drawable, mask);
517 }
518
519 #endif /* GLX_VERSION_1_3 */
520
521
522 #ifdef GLX_EXT_import_context
523
524 void glXFreeContextEXT(Display *dpy, GLXContext context)
525 {
526 struct _glxapi_table *t = get_dispatch(dpy);
527 if (!t)
528 return;
529 (t->FreeContextEXT)(dpy, context);
530 }
531
532
533 GLXContextID glXGetContextIDEXT(const GLXContext context)
534 {
535 /* XXX is this function right? */
536 struct _glxapi_table *t = get_dispatch(CurrentDisplay);
537 if (!t)
538 return 0;
539 return (t->GetContextIDEXT)(context);
540 }
541
542
543 Display *glXGetCurrentDisplayEXT(void)
544 {
545 return CurrentDisplay;
546 }
547
548
549 GLXContext glXImportContextEXT(Display *dpy, GLXContextID contextID)
550 {
551 struct _glxapi_table *t = get_dispatch(dpy);
552 if (!t)
553 return 0;
554 return (t->ImportContextEXT)(dpy, contextID);
555 }
556
557 int glXQueryContextInfoEXT(Display *dpy, GLXContext context, int attribute,int *value)
558 {
559 struct _glxapi_table *t = get_dispatch(dpy);
560 if (!t)
561 return 0; /* XXX ok? */
562 return (t->QueryContextInfoEXT)(dpy, context, attribute, value);
563 }
564
565 #endif
566
567
568 #ifdef GLX_SGI_video_sync
569
570 int glXGetVideoSyncSGI(unsigned int *count)
571 {
572 struct _glxapi_table *t = get_dispatch(CurrentDisplay);
573 if (!t)
574 return 0;
575 return (t->GetVideoSyncSGI)(count);
576 }
577
578
579 int glXWaitVideoSyncSGI(int divisor, int remainder, unsigned int *count)
580 {
581 struct _glxapi_table *t = get_dispatch(CurrentDisplay);
582 if (!t)
583 return 0;
584 return (t->WaitVideoSyncSGI)(divisor, remainder, count);
585 }
586
587 #endif
588
589
590 #ifdef GLX_MESA_copy_sub_buffer
591
592 void glXCopySubBufferMESA(Display *dpy, GLXDrawable drawable, int x, int y, int width, int height)
593 {
594 struct _glxapi_table *t = get_dispatch(dpy);
595 if (!t)
596 return;
597 (t->CopySubBufferMESA)(dpy, drawable, x, y, width, height);
598 }
599
600 #endif
601
602
603 #ifdef GLX_MESA_release_buffers
604
605 Bool glXReleaseBuffersMESA(Display *dpy, Window w)
606 {
607 struct _glxapi_table *t = get_dispatch(dpy);
608 if (!t)
609 return False;
610 return (t->ReleaseBuffersMESA)(dpy, w);
611 }
612
613 #endif
614
615
616 #ifdef GLX_MESA_pixmap_colormap
617
618 GLXPixmap glXCreateGLXPixmapMESA(Display *dpy, XVisualInfo *visinfo, Pixmap pixmap, Colormap cmap)
619 {
620 struct _glxapi_table *t = get_dispatch(dpy);
621 if (!t)
622 return 0;
623 return (t->CreateGLXPixmapMESA)(dpy, visinfo, pixmap, cmap);
624 }
625
626 #endif
627
628
629 #ifdef GLX_MESA_set_3dfx_mode
630
631 GLboolean glXSet3DfxModeMESA(GLint mode)
632 {
633 struct _glxapi_table *t = get_dispatch(CurrentDisplay);
634 if (!t)
635 return False;
636 return (t->Set3DfxModeMESA)(mode);
637 }
638
639 #endif
640
641
642
643 /**********************************************************************/
644 /* GLX API management functions */
645 /**********************************************************************/
646
647
648 const char *
649 _glxapi_get_version(void)
650 {
651 return "1.3";
652 }
653
654
655 /*
656 * Return array of extension strings.
657 */
658 const char **
659 _glxapi_get_extensions(void)
660 {
661 static const char *extensions[] = {
662 #ifdef GLX_EXT_import_context
663 "GLX_EXT_import_context",
664 #endif
665 #ifdef GLX_SGI_video_sync
666 "GLX_SGI_video_sync",
667 #endif
668 #ifdef GLX_MESA_copy_sub_buffer
669 "GLX_MESA_copy_sub_buffer",
670 #endif
671 #ifdef GLX_MESA_release_buffers
672 "GLX_MESA_release_buffers",
673 #endif
674 #ifdef GLX_MESA_pixmap_colormap
675 "GLX_MESA_pixmap_colormap",
676 #endif
677 #ifdef GLX_MESA_set_3dfx_mode
678 "GLX_MESA_set_3dfx_mode",
679 #endif
680 NULL
681 };
682 return extensions;
683 }
684
685
686 /*
687 * Return size of the GLX dispatch table, in entries, not bytes.
688 */
689 GLuint
690 _glxapi_get_dispatch_table_size(void)
691 {
692 return sizeof(struct _glxapi_table) / sizeof(void *);
693 }
694
695
696 static int
697 generic_no_op_func(void)
698 {
699 return 0;
700 }
701
702
703 /*
704 * Initialize all functions in given dispatch table to be no-ops
705 */
706 void
707 _glxapi_set_no_op_table(struct _glxapi_table *t)
708 {
709 GLuint n = _glxapi_get_dispatch_table_size();
710 GLuint i;
711 void **dispatch = (void **) t;
712 for (i = 0; i < n; i++) {
713 dispatch[i] = (void *) generic_no_op_func;
714 }
715 }
716
717
718
719 struct name_address_pair {
720 const char *Name;
721 GLvoid *Address;
722 };
723
724 static struct name_address_pair GLX_functions[] = {
725 { "glXChooseVisual", (GLvoid *) glXChooseVisual },
726 { "glXCopyContext", (GLvoid *) glXCopyContext },
727 { "glXCreateContext", (GLvoid *) glXCreateContext },
728 { "glXCreateGLXPixmap", (GLvoid *) glXCreateGLXPixmap },
729 { "glXDestroyContext", (GLvoid *) glXDestroyContext },
730 { "glXDestroyGLXPixmap", (GLvoid *) glXDestroyGLXPixmap },
731 { "glXGetConfig", (GLvoid *) glXGetConfig },
732 { "glXGetCurrentContext", (GLvoid *) glXGetCurrentContext },
733 { "glXGetCurrentDrawable", (GLvoid *) glXGetCurrentDrawable },
734 { "glXIsDirect", (GLvoid *) glXIsDirect },
735 { "glXMakeCurrent", (GLvoid *) glXMakeCurrent },
736 { "glXQueryExtension", (GLvoid *) glXQueryExtension },
737 { "glXQueryVersion", (GLvoid *) glXQueryVersion },
738 { "glXSwapBuffers", (GLvoid *) glXSwapBuffers },
739 { "glXUseXFont", (GLvoid *) glXUseXFont },
740 { "glXWaitGL", (GLvoid *) glXWaitGL },
741 { "glXWaitX", (GLvoid *) glXWaitX },
742
743 #ifdef GLX_VERSION_1_1
744 { "glXGetClientString", (GLvoid *) glXGetClientString },
745 { "glXQueryExtensionsString", (GLvoid *) glXQueryExtensionsString },
746 { "glXQueryServerString", (GLvoid *) glXQueryServerString },
747 #endif
748
749 #ifdef GLX_VERSION_1_2
750 { "glXGetCurrentDisplay", (GLvoid *) glXGetCurrentDisplay },
751 #endif
752
753 #ifdef GLX_VERSION_1_3
754 { "glXChooseFBConfig", (GLvoid *) glXChooseFBConfig },
755 { "glXCreateNewContext", (GLvoid *) glXCreateNewContext },
756 { "glXCreatePbuffer", (GLvoid *) glXCreatePbuffer },
757 { "glXCreatePixmap", (GLvoid *) glXCreatePixmap },
758 { "glXCreateWindow", (GLvoid *) glXCreateWindow },
759 { "glXDestroyPbuffer", (GLvoid *) glXDestroyPbuffer },
760 { "glXDestroyPixmap", (GLvoid *) glXDestroyPixmap },
761 { "glXDestroyWindow", (GLvoid *) glXDestroyWindow },
762 { "glXGetCurrentReadDrawable", (GLvoid *) glXGetCurrentReadDrawable },
763 { "glXGetFBConfigAttrib", (GLvoid *) glXGetFBConfigAttrib },
764 { "glXGetSelectedEvent", (GLvoid *) glXGetSelectedEvent },
765 { "glXGetVisualFromFBConfig", (GLvoid *) glXGetVisualFromFBConfig },
766 { "glXMakeContextCurrent", (GLvoid *) glXMakeContextCurrent },
767 { "glXQueryContext", (GLvoid *) glXQueryContext },
768 { "glXQueryDrawable", (GLvoid *) glXQueryDrawable },
769 { "glXSelectEvent", (GLvoid *) glXSelectEvent },
770 #endif
771
772 #ifdef GLX_SGI_video_sync
773 { "glXGetVideoSyncSGI", (GLvoid *) glXGetVideoSyncSGI },
774 { "glXWaitVideoSyncSGI", (GLvoid *) glXWaitVideoSyncSGI },
775 #endif
776
777 #ifdef GLX_MESA_copy_sub_buffer
778 { "glXCopySubBufferMESA", (GLvoid *) glXCopySubBufferMESA },
779 #endif
780
781 #ifdef GLX_MESA_release_buffers
782 { "glXReleaseBuffersMESA", (GLvoid *) glXReleaseBuffersMESA },
783 #endif
784
785 #ifdef GLX_MESA_pixmap_colormap
786 { "glXCreateGLXPixmapMESA", (GLvoid *) glXCreateGLXPixmapMESA },
787 #endif
788
789 #ifdef GLX_MESA_set_3dfx_mode
790 { "glXSet3DfxModeMESA", (GLvoid *) glXSet3DfxModeMESA },
791 #endif
792
793 { "glXGetProcAddressARB", (GLvoid *) glXGetProcAddressARB },
794
795 { NULL, NULL } /* end of list */
796 };
797
798
799
800 /*
801 * Return address of named glX function, or NULL if not found.
802 */
803 const GLvoid *
804 _glxapi_get_proc_address(const char *funcName)
805 {
806 GLuint i;
807 for (i = 0; GLX_functions[i].Name; i++) {
808 if (strcmp(GLX_functions[i].Name, funcName) == 0)
809 return GLX_functions[i].Address;
810 }
811 return NULL;
812 }
813
814
815
816 /*
817 * This function does not get dispatched through the dispatch table
818 * since it's really a "meta" function.
819 */
820 void (*glXGetProcAddressARB(const GLubyte *procName))()
821 {
822 typedef void (*gl_function)();
823 gl_function f;
824
825 f = (gl_function) _glxapi_get_proc_address((const char *) procName);
826 if (f) {
827 return f;
828 }
829
830 f = (gl_function) _glapi_get_proc_address((const char *) procName);
831 return f;
832 }