ffdfe65ac0d23d306dac8a1d15efc4bf1e984aaa
[mesa.git] / src / mesa / drivers / x11 / glxapi.c
1 /* $Id: glxapi.c,v 1.15 2000/02/27 18:26:54 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 _GLXAPI_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 _GLXAPI_VERSION_1_2
352 Display *glXGetCurrentDisplay(void)
353 {
354 return CurrentDisplay;
355 }
356 #endif
357
358
359
360 #ifdef _GLXAPI_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 void glXGetSelectedEvent(Display *dpy, GLXDrawable drawable, unsigned long *mask)
450 {
451 struct _glxapi_table *t = get_dispatch(dpy);
452 if (!t)
453 return;
454 (t->GetSelectedEvent)(dpy, drawable, mask);
455 }
456
457
458 XVisualInfo *glXGetVisualFromFBConfig(Display *dpy, GLXFBConfig config)
459 {
460 struct _glxapi_table *t = get_dispatch(dpy);
461 if (!t)
462 return NULL;
463 return (t->GetVisualFromFBConfig)(dpy, config);
464 }
465
466
467 Bool glXMakeContextCurrent(Display *dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx)
468 {
469 struct _glxapi_table *t = get_dispatch(dpy);
470 Bool b;
471 if (!t)
472 return False;
473 b = (t->MakeContextCurrent)(dpy, draw, read, ctx);
474 if (b) {
475 CurrentDisplay = dpy;
476 CurrentContext = ctx;
477 CurrentDrawable = draw;
478 CurrentReadDrawable = read;
479 }
480 return b;
481 }
482
483
484 int glXQueryContext(Display *dpy, GLXContext ctx, int attribute, int *value)
485 {
486 struct _glxapi_table *t = get_dispatch(dpy);
487 assert(t);
488 if (!t)
489 return 0; /* XXX correct? */
490 return (t->QueryContext)(dpy, ctx, attribute, value);
491 }
492
493
494 void glXQueryDrawable(Display *dpy, GLXDrawable draw, int attribute, unsigned int *value)
495 {
496 struct _glxapi_table *t = get_dispatch(dpy);
497 if (!t)
498 return;
499 (t->QueryDrawable)(dpy, draw, attribute, value);
500 }
501
502
503 void glXSelectEvent(Display *dpy, GLXDrawable drawable, unsigned long mask)
504 {
505 struct _glxapi_table *t = get_dispatch(dpy);
506 if (!t)
507 return;
508 (t->SelectEvent)(dpy, drawable, mask);
509 }
510
511 #endif /* _GLXAPI_VERSION_1_3 */
512
513
514 #ifdef _GLXAPI_EXT_import_context
515
516 void glXFreeContextEXT(Display *dpy, GLXContext context)
517 {
518 struct _glxapi_table *t = get_dispatch(dpy);
519 if (!t)
520 return;
521 (t->FreeContextEXT)(dpy, context);
522 }
523
524
525 GLXContextID glXGetContextIDEXT(const GLXContext context)
526 {
527 /* XXX is this function right? */
528 struct _glxapi_table *t = get_dispatch(CurrentDisplay);
529 if (!t)
530 return 0;
531 return (t->GetContextIDEXT)(context);
532 }
533
534
535 Display *glXGetCurrentDisplayEXT(void)
536 {
537 return CurrentDisplay;
538 }
539
540
541 GLXContext glXImportContextEXT(Display *dpy, GLXContextID contextID)
542 {
543 struct _glxapi_table *t = get_dispatch(dpy);
544 if (!t)
545 return 0;
546 return (t->ImportContextEXT)(dpy, contextID);
547 }
548
549 int glXQueryContextInfoEXT(Display *dpy, GLXContext context, int attribute,int *value)
550 {
551 struct _glxapi_table *t = get_dispatch(dpy);
552 if (!t)
553 return 0; /* XXX ok? */
554 return (t->QueryContextInfoEXT)(dpy, context, attribute, value);
555 }
556
557 #endif
558
559
560 #ifdef _GLXAPI_SGI_video_sync
561
562 int glXGetVideoSyncSGI(unsigned int *count)
563 {
564 struct _glxapi_table *t = get_dispatch(CurrentDisplay);
565 if (!t)
566 return 0;
567 return (t->GetVideoSyncSGI)(count);
568 }
569
570
571 int glXWaitVideoSyncSGI(int divisor, int remainder, unsigned int *count)
572 {
573 struct _glxapi_table *t = get_dispatch(CurrentDisplay);
574 if (!t)
575 return 0;
576 return (t->WaitVideoSyncSGI)(divisor, remainder, count);
577 }
578
579 #endif
580
581
582 #ifdef _GLXAPI_MESA_copy_sub_buffer
583
584 void glXCopySubBufferMESA(Display *dpy, GLXDrawable drawable, int x, int y, int width, int height)
585 {
586 struct _glxapi_table *t = get_dispatch(dpy);
587 if (!t)
588 return;
589 (t->CopySubBufferMESA)(dpy, drawable, x, y, width, height);
590 }
591
592 #endif
593
594
595 #ifdef _GLXAPI_MESA_release_buffers
596
597 Bool glXReleaseBuffersMESA(Display *dpy, Window w)
598 {
599 struct _glxapi_table *t = get_dispatch(dpy);
600 if (!t)
601 return False;
602 return (t->ReleaseBuffersMESA)(dpy, w);
603 }
604
605 #endif
606
607
608 #ifdef _GLXAPI_MESA_pixmap_colormap
609
610 GLXPixmap glXCreateGLXPixmapMESA(Display *dpy, XVisualInfo *visinfo, Pixmap pixmap, Colormap cmap)
611 {
612 struct _glxapi_table *t = get_dispatch(dpy);
613 if (!t)
614 return 0;
615 return (t->CreateGLXPixmapMESA)(dpy, visinfo, pixmap, cmap);
616 }
617
618 #endif
619
620
621 #ifdef _GLXAPI_MESA_set_3dfx_mode
622
623 GLboolean glXSet3DfxModeMESA(GLint mode)
624 {
625 struct _glxapi_table *t = get_dispatch(CurrentDisplay);
626 if (!t)
627 return False;
628 return (t->Set3DfxModeMESA)(mode);
629 }
630
631 #endif
632
633
634
635 /**********************************************************************/
636 /* GLX API management functions */
637 /**********************************************************************/
638
639
640 const char *
641 _glxapi_get_version(void)
642 {
643 return "1.3";
644 }
645
646
647 /*
648 * Return array of extension strings.
649 */
650 const char **
651 _glxapi_get_extensions(void)
652 {
653 static const char *extensions[] = {
654 #ifdef _GLXAPI_EXT_import_context
655 "GLX_EXT_import_context",
656 #endif
657 #ifdef _GLXAPI_SGI_video_sync
658 "GLX_SGI_video_sync",
659 #endif
660 #ifdef _GLXAPI_MESA_copy_sub_buffer
661 "GLX_MESA_copy_sub_buffer",
662 #endif
663 #ifdef _GLXAPI_MESA_release_buffers
664 "GLX_MESA_release_buffers",
665 #endif
666 #ifdef _GLXAPI_MESA_pixmap_colormap
667 "GLX_MESA_pixmap_colormap",
668 #endif
669 #ifdef _GLXAPI_MESA_set_3dfx_mode
670 "GLX_MESA_set_3dfx_mode",
671 #endif
672 NULL
673 };
674 return extensions;
675 }
676
677
678 /*
679 * Return size of the GLX dispatch table, in entries, not bytes.
680 */
681 GLuint
682 _glxapi_get_dispatch_table_size(void)
683 {
684 return sizeof(struct _glxapi_table) / sizeof(void *);
685 }
686
687
688 static int
689 generic_no_op_func(void)
690 {
691 return 0;
692 }
693
694
695 /*
696 * Initialize all functions in given dispatch table to be no-ops
697 */
698 void
699 _glxapi_set_no_op_table(struct _glxapi_table *t)
700 {
701 GLuint n = _glxapi_get_dispatch_table_size();
702 GLuint i;
703 void **dispatch = (void **) t;
704 for (i = 0; i < n; i++) {
705 dispatch[i] = (void *) generic_no_op_func;
706 }
707 }
708
709
710
711 struct name_address_pair {
712 const char *Name;
713 GLvoid *Address;
714 };
715
716 static struct name_address_pair GLX_functions[] = {
717 { "glXChooseVisual", (GLvoid *) glXChooseVisual },
718 { "glXCopyContext", (GLvoid *) glXCopyContext },
719 { "glXCreateContext", (GLvoid *) glXCreateContext },
720 { "glXCreateGLXPixmap", (GLvoid *) glXCreateGLXPixmap },
721 { "glXDestroyContext", (GLvoid *) glXDestroyContext },
722 { "glXDestroyGLXPixmap", (GLvoid *) glXDestroyGLXPixmap },
723 { "glXGetConfig", (GLvoid *) glXGetConfig },
724 { "glXGetCurrentContext", (GLvoid *) glXGetCurrentContext },
725 { "glXGetCurrentDrawable", (GLvoid *) glXGetCurrentDrawable },
726 { "glXIsDirect", (GLvoid *) glXIsDirect },
727 { "glXMakeCurrent", (GLvoid *) glXMakeCurrent },
728 { "glXQueryExtension", (GLvoid *) glXQueryExtension },
729 { "glXQueryVersion", (GLvoid *) glXQueryVersion },
730 { "glXSwapBuffers", (GLvoid *) glXSwapBuffers },
731 { "glXUseXFont", (GLvoid *) glXUseXFont },
732 { "glXWaitGL", (GLvoid *) glXWaitGL },
733 { "glXWaitX", (GLvoid *) glXWaitX },
734
735 #ifdef _GLXAPI_VERSION_1_1
736 { "glXGetClientString", (GLvoid *) glXGetClientString },
737 { "glXQueryExtensionsString", (GLvoid *) glXQueryExtensionsString },
738 { "glXQueryServerString", (GLvoid *) glXQueryServerString },
739 #endif
740
741 #ifdef _GLXAPI_VERSION_1_2
742 { "glXGetCurrentDisplay", (GLvoid *) glXGetCurrentDisplay },
743 #endif
744
745 #ifdef _GLXAPI_VERSION_1_3
746 { "glXChooseFBConfig", (GLvoid *) glXChooseFBConfig },
747 { "glXCreateNewContext", (GLvoid *) glXCreateNewContext },
748 { "glXCreatePbuffer", (GLvoid *) glXCreatePbuffer },
749 { "glXCreatePixmap", (GLvoid *) glXCreatePixmap },
750 { "glXCreateWindow", (GLvoid *) glXCreateWindow },
751 { "glXDestroyPbuffer", (GLvoid *) glXDestroyPbuffer },
752 { "glXDestroyPixmap", (GLvoid *) glXDestroyPixmap },
753 { "glXDestroyWindow", (GLvoid *) glXDestroyWindow },
754 { "glXGetCurrentReadDrawable", (GLvoid *) glXGetCurrentReadDrawable },
755 { "glXGetFBConfigAttrib", (GLvoid *) glXGetFBConfigAttrib },
756 { "glXGetSelectedEvent", (GLvoid *) glXGetSelectedEvent },
757 { "glXGetVisualFromFBConfig", (GLvoid *) glXGetVisualFromFBConfig },
758 { "glXMakeContextCurrent", (GLvoid *) glXMakeContextCurrent },
759 { "glXQueryContext", (GLvoid *) glXQueryContext },
760 { "glXQueryDrawable", (GLvoid *) glXQueryDrawable },
761 { "glXSelectEvent", (GLvoid *) glXSelectEvent },
762 #endif
763
764 #ifdef _GLXAPI_SGI_video_sync
765 { "glXGetVideoSyncSGI", (GLvoid *) glXGetVideoSyncSGI },
766 { "glXWaitVideoSyncSGI", (GLvoid *) glXWaitVideoSyncSGI },
767 #endif
768
769 #ifdef _GLXAPI_MESA_copy_sub_buffer
770 { "glXCopySubBufferMESA", (GLvoid *) glXCopySubBufferMESA },
771 #endif
772
773 #ifdef _GLXAPI_MESA_release_buffers
774 { "glXReleaseBuffersMESA", (GLvoid *) glXReleaseBuffersMESA },
775 #endif
776
777 #ifdef _GLXAPI_MESA_pixmap_colormap
778 { "glXCreateGLXPixmapMESA", (GLvoid *) glXCreateGLXPixmapMESA },
779 #endif
780
781 #ifdef _GLXAPI_MESA_set_3dfx_mode
782 { "glXSet3DfxModeMESA", (GLvoid *) glXSet3DfxModeMESA },
783 #endif
784
785 { "glXGetProcAddressARB", (GLvoid *) glXGetProcAddressARB },
786
787 { NULL, NULL } /* end of list */
788 };
789
790
791
792 /*
793 * Return address of named glX function, or NULL if not found.
794 */
795 const GLvoid *
796 _glxapi_get_proc_address(const char *funcName)
797 {
798 GLuint i;
799 for (i = 0; GLX_functions[i].Name; i++) {
800 if (strcmp(GLX_functions[i].Name, funcName) == 0)
801 return GLX_functions[i].Address;
802 }
803 return NULL;
804 }
805
806
807
808 /*
809 * This function does not get dispatched through the dispatch table
810 * since it's really a "meta" function.
811 */
812 void (*glXGetProcAddressARB(const GLubyte *procName))()
813 {
814 typedef void (*gl_function)();
815 gl_function f;
816
817 f = (gl_function) _glxapi_get_proc_address((const char *) procName);
818 if (f) {
819 return f;
820 }
821
822 f = (gl_function) _glapi_get_proc_address((const char *) procName);
823 return f;
824 }