Fog coordinate stage which drivers may use to replace standard fogging
[mesa.git] / src / mesa / drivers / x11 / glxapi.c
1 /* $Id: glxapi.c,v 1.12 2000/02/25 03:55:40 keithw Exp $ */
2
3 /*
4 * Mesa 3-D graphics library
5 * Version: 3.3
6 *
7 * Copyright (C) 1999 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,
173 GLuint mask)
174 {
175 struct _glxapi_table *t = get_dispatch(dpy);
176 if (!t)
177 return;
178 (t->CopyContext)(dpy, src, dst, mask);
179 }
180
181
182 GLXContext glXCreateContext(Display *dpy, XVisualInfo *visinfo, GLXContext shareList, Bool direct)
183 {
184 struct _glxapi_table *t = get_dispatch(dpy);
185 if (!t)
186 return 0;
187 return (t->CreateContext)(dpy, visinfo, shareList, direct);
188 }
189
190
191 GLXPixmap glXCreateGLXPixmap(Display *dpy, XVisualInfo *visinfo, Pixmap pixmap)
192 {
193 struct _glxapi_table *t = get_dispatch(dpy);
194 if (!t)
195 return 0;
196 return (t->CreateGLXPixmap)(dpy, visinfo, pixmap);
197 }
198
199
200 void glXDestroyContext(Display *dpy, GLXContext ctx)
201 {
202 struct _glxapi_table *t = get_dispatch(dpy);
203 if (!t)
204 return;
205 (t->DestroyContext)(dpy, ctx);
206 }
207
208
209 void glXDestroyGLXPixmap(Display *dpy, GLXPixmap pixmap)
210 {
211 struct _glxapi_table *t = get_dispatch(dpy);
212 if (!t)
213 return;
214 (t->DestroyGLXPixmap)(dpy, pixmap);
215 }
216
217
218 int glXGetConfig(Display *dpy, XVisualInfo *visinfo, int attrib, int *value)
219 {
220 struct _glxapi_table *t = get_dispatch(dpy);
221 if (!t)
222 return GLX_NO_EXTENSION;
223 return (t->GetConfig)(dpy, visinfo, attrib, value);
224 }
225
226
227 GLXContext glXGetCurrentContext(void)
228 {
229 return CurrentContext;
230 }
231
232
233 GLXDrawable glXGetCurrentDrawable(void)
234 {
235 return CurrentDrawable;
236 }
237
238
239 Bool glXIsDirect(Display *dpy, GLXContext ctx)
240 {
241 struct _glxapi_table *t = get_dispatch(dpy);
242 if (!t)
243 return False;
244 return (t->IsDirect)(dpy, ctx);
245 }
246
247
248 Bool glXMakeCurrent(Display *dpy, GLXDrawable drawable, GLXContext ctx)
249 {
250 Bool b;
251 struct _glxapi_table *t = get_dispatch(dpy);
252 if (!t)
253 return False;
254 b = (*t->MakeCurrent)(dpy, drawable, ctx);
255 if (b) {
256 CurrentDisplay = dpy;
257 CurrentContext = ctx;
258 CurrentDrawable = drawable;
259 CurrentReadDrawable = drawable;
260 }
261 return b;
262 }
263
264
265 Bool glXQueryExtension(Display *dpy, int *errorb, int *event)
266 {
267 struct _glxapi_table *t = get_dispatch(dpy);
268 if (!t)
269 return False;
270 return (t->QueryExtension)(dpy, errorb, event);
271 }
272
273
274 Bool glXQueryVersion(Display *dpy, int *maj, int *min)
275 {
276 struct _glxapi_table *t = get_dispatch(dpy);
277 if (!t)
278 return False;
279 return (t->QueryVersion)(dpy, maj, min);
280 }
281
282
283 void glXSwapBuffers(Display *dpy, GLXDrawable drawable)
284 {
285 struct _glxapi_table *t = get_dispatch(dpy);
286 if (!t)
287 return;
288 (t->SwapBuffers)(dpy, drawable);
289 }
290
291
292 void glXUseXFont(Font font, int first, int count, int listBase)
293 {
294 struct _glxapi_table *t = get_dispatch(CurrentDisplay);
295 if (!t)
296 return;
297 (t->UseXFont)(font, first, count, listBase);
298 }
299
300
301 void glXWaitGL(void)
302 {
303 struct _glxapi_table *t = get_dispatch(CurrentDisplay);
304 if (!t)
305 return;
306 (t->WaitGL)();
307 }
308
309
310 void glXWaitX(void)
311 {
312 struct _glxapi_table *t = get_dispatch(CurrentDisplay);
313 if (!t)
314 return;
315 (t->WaitX)();
316 }
317
318
319
320 #ifdef _GLXAPI_VERSION_1_1
321
322 const char *glXGetClientString(Display *dpy, int name)
323 {
324 struct _glxapi_table *t = get_dispatch(dpy);
325 if (!t)
326 return NULL;
327 return (t->GetClientString)(dpy, name);
328 }
329
330
331 const char *glXQueryExtensionsString(Display *dpy, int screen)
332 {
333 struct _glxapi_table *t = get_dispatch(dpy);
334 if (!t)
335 return NULL;
336 return (t->QueryExtensionsString)(dpy, screen);
337 }
338
339
340 const char *glXQueryServerString(Display *dpy, int screen, int name)
341 {
342 struct _glxapi_table *t = get_dispatch(dpy);
343 if (!t)
344 return NULL;
345 return (t->QueryServerString)(dpy, screen, name);
346 }
347
348 #endif
349
350
351
352 #ifdef _GLXAPI_VERSION_1_2
353 Display *glXGetCurrentDisplay(void)
354 {
355 return CurrentDisplay;
356 }
357 #endif
358
359
360
361 #ifdef _GLXAPI_VERSION_1_3
362
363 GLXFBConfig glXChooseFBConfig(Display *dpy, int screen, const int *attribList, int *nitems)
364 {
365 struct _glxapi_table *t = get_dispatch(dpy);
366 if (!t)
367 return 0;
368 return (t->ChooseFBConfig)(dpy, screen, attribList, nitems);
369 }
370
371
372 GLXContext glXCreateNewContext(Display *dpy, GLXFBConfig config, int renderType, GLXContext shareList, Bool direct)
373 {
374 struct _glxapi_table *t = get_dispatch(dpy);
375 if (!t)
376 return 0;
377 return (t->CreateNewContext)(dpy, config, renderType, shareList, direct);
378 }
379
380
381 GLXPbuffer glXCreatePbuffer(Display *dpy, GLXFBConfig config, const int *attribList)
382 {
383 struct _glxapi_table *t = get_dispatch(dpy);
384 if (!t)
385 return 0;
386 return (t->CreatePbuffer)(dpy, config, attribList);
387 }
388
389
390 GLXPixmap glXCreatePixmap(Display *dpy, GLXFBConfig config, Pixmap pixmap, const int *attribList)
391 {
392 struct _glxapi_table *t = get_dispatch(dpy);
393 if (!t)
394 return 0;
395 return (t->CreatePixmap)(dpy, config, pixmap, attribList);
396 }
397
398
399 GLXWindow glXCreateWindow(Display *dpy, GLXFBConfig config, Window win, const int *attribList)
400 {
401 struct _glxapi_table *t = get_dispatch(dpy);
402 if (!t)
403 return 0;
404 return (t->CreateWindow)(dpy, config, win, attribList);
405 }
406
407
408 void glXDestroyPbuffer(Display *dpy, GLXPbuffer pbuf)
409 {
410 struct _glxapi_table *t = get_dispatch(dpy);
411 if (!t)
412 return;
413 (t->DestroyPbuffer)(dpy, pbuf);
414 }
415
416
417 void glXDestroyPixmap(Display *dpy, GLXPixmap pixmap)
418 {
419 struct _glxapi_table *t = get_dispatch(dpy);
420 if (!t)
421 return;
422 (t->DestroyPixmap)(dpy, pixmap);
423 }
424
425
426 void glXDestroyWindow(Display *dpy, GLXWindow window)
427 {
428 struct _glxapi_table *t = get_dispatch(dpy);
429 if (!t)
430 return;
431 (t->DestroyWindow)(dpy, window);
432 }
433
434
435 GLXDrawable glXGetCurrentReadDrawable(void)
436 {
437 return CurrentReadDrawable;
438 }
439
440
441 int glXGetFBConfigAttrib(Display *dpy, GLXFBConfig config, int attribute, int *value)
442 {
443 struct _glxapi_table *t = get_dispatch(dpy);
444 if (!t)
445 return GLX_NO_EXTENSION;
446 return (t->GetFBConfigAttrib)(dpy, config, attribute, value);
447 }
448
449
450 void glXGetSelectedEvent(Display *dpy, GLXDrawable drawable, unsigned long *mask)
451 {
452 struct _glxapi_table *t = get_dispatch(dpy);
453 if (!t)
454 return;
455 (t->GetSelectedEvent)(dpy, drawable, mask);
456 }
457
458
459 XVisualInfo *glXGetVisualFromFBConfig(Display *dpy, GLXFBConfig config)
460 {
461 struct _glxapi_table *t = get_dispatch(dpy);
462 if (!t)
463 return NULL;
464 return (t->GetVisualFromFBConfig)(dpy, config);
465 }
466
467
468 Bool glXMakeContextCurrent(Display *dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx)
469 {
470 struct _glxapi_table *t = get_dispatch(dpy);
471 Bool b;
472 if (!t)
473 return False;
474 b = (t->MakeContextCurrent)(dpy, draw, read, ctx);
475 if (b) {
476 CurrentDisplay = dpy;
477 CurrentContext = ctx;
478 CurrentDrawable = draw;
479 CurrentReadDrawable = read;
480 }
481 return b;
482 }
483
484
485 int glXQueryContext(Display *dpy, GLXContext ctx, int attribute, int *value)
486 {
487 struct _glxapi_table *t = get_dispatch(dpy);
488 assert(t);
489 if (!t)
490 return 0; /* XXX correct? */
491 return (t->QueryContext)(dpy, ctx, attribute, value);
492 }
493
494
495 void glXQueryDrawable(Display *dpy, GLXDrawable draw, int attribute, unsigned int *value)
496 {
497 struct _glxapi_table *t = get_dispatch(dpy);
498 if (!t)
499 return;
500 (t->QueryDrawable)(dpy, draw, attribute, value);
501 }
502
503
504 void glXSelectEvent(Display *dpy, GLXDrawable drawable, unsigned long mask)
505 {
506 struct _glxapi_table *t = get_dispatch(dpy);
507 if (!t)
508 return;
509 (t->SelectEvent)(dpy, drawable, mask);
510 }
511
512 #endif /* _GLXAPI_VERSION_1_3 */
513
514
515 #ifdef _GLXAPI_EXT_import_context
516
517 void glXFreeContextEXT(Display *dpy, GLXContext context)
518 {
519 struct _glxapi_table *t = get_dispatch(dpy);
520 if (!t)
521 return;
522 (t->FreeContextEXT)(dpy, context);
523 }
524
525
526 GLXContextID glXGetContextIDEXT(const GLXContext context)
527 {
528 /* XXX is this function right? */
529 struct _glxapi_table *t = get_dispatch(CurrentDisplay);
530 if (!t)
531 return 0;
532 return (t->GetContextIDEXT)(context);
533 }
534
535
536 Display *glXGetCurrentDisplayEXT(void)
537 {
538 return CurrentDisplay;
539 }
540
541
542 GLXContext glXImportContextEXT(Display *dpy, GLXContextID contextID)
543 {
544 struct _glxapi_table *t = get_dispatch(dpy);
545 if (!t)
546 return 0;
547 return (t->ImportContextEXT)(dpy, contextID);
548 }
549
550 int glXQueryContextInfoEXT(Display *dpy, GLXContext context, int attribute,int *value)
551 {
552 struct _glxapi_table *t = get_dispatch(dpy);
553 if (!t)
554 return 0; /* XXX ok? */
555 return (t->QueryContextInfoEXT)(dpy, context, attribute, value);
556 }
557
558 #endif
559
560
561 #ifdef _GLXAPI_SGI_video_sync
562
563 int glXGetVideoSyncSGI(unsigned int *count)
564 {
565 struct _glxapi_table *t = get_dispatch(CurrentDisplay);
566 if (!t)
567 return 0;
568 return (t->GetVideoSyncSGI)(count);
569 }
570
571
572 int glXWaitVideoSyncSGI(int divisor, int remainder, unsigned int *count)
573 {
574 struct _glxapi_table *t = get_dispatch(CurrentDisplay);
575 if (!t)
576 return 0;
577 return (t->WaitVideoSyncSGI)(divisor, remainder, count);
578 }
579
580 #endif
581
582
583 #ifdef _GLXAPI_MESA_copy_sub_buffer
584
585 void glXCopySubBufferMESA(Display *dpy, GLXDrawable drawable, int x, int y, int width, int height)
586 {
587 struct _glxapi_table *t = get_dispatch(dpy);
588 if (!t)
589 return;
590 (t->CopySubBufferMESA)(dpy, drawable, x, y, width, height);
591 }
592
593 #endif
594
595
596 #ifdef _GLXAPI_MESA_release_buffers
597
598 Bool glXReleaseBuffersMESA(Display *dpy, Window w)
599 {
600 struct _glxapi_table *t = get_dispatch(dpy);
601 if (!t)
602 return False;
603 return (t->ReleaseBuffersMESA)(dpy, w);
604 }
605
606 #endif
607
608
609 #ifdef _GLXAPI_MESA_pixmap_colormap
610
611 GLXPixmap glXCreateGLXPixmapMESA(Display *dpy, XVisualInfo *visinfo, Pixmap pixmap, Colormap cmap)
612 {
613 struct _glxapi_table *t = get_dispatch(dpy);
614 if (!t)
615 return 0;
616 return (t->CreateGLXPixmapMESA)(dpy, visinfo, pixmap, cmap);
617 }
618
619 #endif
620
621
622 #ifdef _GLXAPI_MESA_set_3dfx_mode
623
624 GLboolean glXSet3DfxModeMESA(GLint mode)
625 {
626 struct _glxapi_table *t = get_dispatch(CurrentDisplay);
627 if (!t)
628 return False;
629 return (t->Set3DfxModeMESA)(mode);
630 }
631
632 #endif
633
634
635
636 /**********************************************************************/
637 /* GLX API management functions */
638 /**********************************************************************/
639
640
641 const char *
642 _glxapi_get_version(void)
643 {
644 return "1.3";
645 }
646
647
648 /*
649 * Return array of extension strings.
650 */
651 const char **
652 _glxapi_get_extensions(void)
653 {
654 static const char *extensions[] = {
655 #ifdef _GLXAPI_EXT_import_context
656 "GLX_EXT_import_context",
657 #endif
658 #ifdef _GLXAPI_SGI_video_sync
659 "GLX_SGI_video_sync",
660 #endif
661 #ifdef _GLXAPI_MESA_copy_sub_buffer
662 "GLX_MESA_copy_sub_buffer",
663 #endif
664 #ifdef _GLXAPI_MESA_release_buffers
665 "GLX_MESA_release_buffers",
666 #endif
667 #ifdef _GLXAPI_MESA_pixmap_colormap
668 "GLX_MESA_pixmap_colormap",
669 #endif
670 #ifdef _GLXAPI_MESA_set_3dfx_mode
671 "GLX_MESA_set_3dfx_mode",
672 #endif
673 NULL
674 };
675 return extensions;
676 }
677
678
679 /*
680 * Return size of the GLX dispatch table, in entries, not bytes.
681 */
682 GLuint
683 _glxapi_get_dispatch_table_size(void)
684 {
685 return sizeof(struct _glxapi_table) / sizeof(void *);
686 }
687
688
689 static int
690 generic_no_op_func(void)
691 {
692 return 0;
693 }
694
695
696 /*
697 * Initialize all functions in given dispatch table to be no-ops
698 */
699 void
700 _glxapi_set_no_op_table(struct _glxapi_table *t)
701 {
702 GLuint n = _glxapi_get_dispatch_table_size();
703 GLuint i;
704 void **dispatch = (void **) t;
705 for (i = 0; i < n; i++) {
706 dispatch[i] = (void *) generic_no_op_func;
707 }
708 }
709
710
711
712 struct name_address_pair {
713 const char *Name;
714 GLvoid *Address;
715 };
716
717 static struct name_address_pair GLX_functions[] = {
718 { "glXChooseVisual", (GLvoid *) glXChooseVisual },
719 { "glXCopyContext", (GLvoid *) glXCopyContext },
720 { "glXCreateContext", (GLvoid *) glXCreateContext },
721 { "glXCreateGLXPixmap", (GLvoid *) glXCreateGLXPixmap },
722 { "glXDestroyContext", (GLvoid *) glXDestroyContext },
723 { "glXDestroyGLXPixmap", (GLvoid *) glXDestroyGLXPixmap },
724 { "glXGetConfig", (GLvoid *) glXGetConfig },
725 { "glXGetCurrentContext", (GLvoid *) glXGetCurrentContext },
726 { "glXGetCurrentDrawable", (GLvoid *) glXGetCurrentDrawable },
727 { "glXIsDirect", (GLvoid *) glXIsDirect },
728 { "glXMakeCurrent", (GLvoid *) glXMakeCurrent },
729 { "glXQueryExtension", (GLvoid *) glXQueryExtension },
730 { "glXQueryVersion", (GLvoid *) glXQueryVersion },
731 { "glXSwapBuffers", (GLvoid *) glXSwapBuffers },
732 { "glXUseXFont", (GLvoid *) glXUseXFont },
733 { "glXWaitGL", (GLvoid *) glXWaitGL },
734 { "glXWaitX", (GLvoid *) glXWaitX },
735
736 #ifdef _GLXAPI_VERSION_1_1
737 { "glXGetClientString", (GLvoid *) glXGetClientString },
738 { "glXQueryExtensionsString", (GLvoid *) glXQueryExtensionsString },
739 { "glXQueryServerString", (GLvoid *) glXQueryServerString },
740 #endif
741
742 #ifdef _GLXAPI_VERSION_1_2
743 { "glXGetCurrentDisplay", (GLvoid *) glXGetCurrentDisplay },
744 #endif
745
746 #ifdef _GLXAPI_VERSION_1_3
747 { "glXChooseFBConfig", (GLvoid *) glXChooseFBConfig },
748 { "glXCreateNewContext", (GLvoid *) glXCreateNewContext },
749 { "glXCreatePbuffer", (GLvoid *) glXCreatePbuffer },
750 { "glXCreatePixmap", (GLvoid *) glXCreatePixmap },
751 { "glXCreateWindow", (GLvoid *) glXCreateWindow },
752 { "glXDestroyPbuffer", (GLvoid *) glXDestroyPbuffer },
753 { "glXDestroyPixmap", (GLvoid *) glXDestroyPixmap },
754 { "glXDestroyWindow", (GLvoid *) glXDestroyWindow },
755 { "glXGetCurrentReadDrawable", (GLvoid *) glXGetCurrentReadDrawable },
756 { "glXGetFBConfigAttrib", (GLvoid *) glXGetFBConfigAttrib },
757 { "glXGetSelectedEvent", (GLvoid *) glXGetSelectedEvent },
758 { "glXGetVisualFromFBConfig", (GLvoid *) glXGetVisualFromFBConfig },
759 { "glXMakeContextCurrent", (GLvoid *) glXMakeContextCurrent },
760 { "glXQueryContext", (GLvoid *) glXQueryContext },
761 { "glXQueryDrawable", (GLvoid *) glXQueryDrawable },
762 { "glXSelectEvent", (GLvoid *) glXSelectEvent },
763 #endif
764
765 #ifdef _GLXAPI_SGI_video_sync
766 { "glXGetVideoSyncSGI", (GLvoid *) glXGetVideoSyncSGI },
767 { "glXWaitVideoSyncSGI", (GLvoid *) glXWaitVideoSyncSGI },
768 #endif
769
770 #ifdef _GLXAPI_MESA_copy_sub_buffer
771 { "glXCopySubBufferMESA", (GLvoid *) glXCopySubBufferMESA },
772 #endif
773
774 #ifdef _GLXAPI_MESA_release_buffers
775 { "glXReleaseBuffersMESA", (GLvoid *) glXReleaseBuffersMESA },
776 #endif
777
778 #ifdef _GLXAPI_MESA_pixmap_colormap
779 { "glXCreateGLXPixmapMESA", (GLvoid *) glXCreateGLXPixmapMESA },
780 #endif
781
782 #ifdef _GLXAPI_MESA_set_3dfx_mode
783 { "glXSet3DfxModeMESA", (GLvoid *) glXSet3DfxModeMESA },
784 #endif
785
786 { "glXGetProcAddressARB", (GLvoid *) glXGetProcAddressARB },
787
788 { NULL, NULL } /* end of list */
789 };
790
791
792
793 /*
794 * Return address of named glX function, or NULL if not found.
795 */
796 const GLvoid *
797 _glxapi_get_proc_address(const char *funcName)
798 {
799 GLuint i;
800 for (i = 0; GLX_functions[i].Name; i++) {
801 if (strcmp(GLX_functions[i].Name, funcName) == 0)
802 return GLX_functions[i].Address;
803 }
804 return NULL;
805 }
806
807
808
809 /*
810 * This function does not get dispatched through the dispatch table
811 * since it's really a "meta" function.
812 */
813 void (*glXGetProcAddressARB(const GLubyte *procName))()
814 {
815 typedef void (*gl_function)();
816 gl_function f;
817
818 f = (gl_function) _glxapi_get_proc_address((const char *) procName);
819 if (f) {
820 return f;
821 }
822
823 f = (gl_function) _glapi_get_proc_address((const char *) procName);
824 return f;
825 }