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