glxapi.c revision 783d7dfcbf40f727c85915b3e5ea5ff6682eaa48
1/* $Id: glxapi.c,v 1.20 2000/12/15 04:02:50 brianp Exp $ */
2
3/*
4 * Mesa 3-D graphics library
5 * Version:  3.5
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 <string.h>
38#include "glapi.h"
39#include "glxapi.h"
40
41
42/*
43 * XXX - this really shouldn't be here.
44 * Instead, add -DUSE_MESA_GLX to the compiler flags when needed.
45 */
46#define USE_MESA_GLX 1
47
48
49/* Rather than include possibly non-existant headers... */
50#ifdef USE_SGI_GLX
51extern struct _glxapi_table *_sgi_GetGLXDispatchtable(void);
52#endif
53#ifdef USE_UTAH_GLX
54extern struct _glxapi_table *_utah_GetGLXDispatchTable(void);
55#endif
56#ifdef USE_MESA_GLX
57extern struct _glxapi_table *_mesa_GetGLXDispatchTable(void);
58#endif
59
60
61
62struct display_dispatch {
63   Display *Dpy;
64   struct _glxapi_table *Table;
65   struct display_dispatch *Next;
66};
67
68static struct display_dispatch *DispatchList = NULL;
69
70
71static struct _glxapi_table *
72get_dispatch(Display *dpy)
73{
74   static Display *prevDisplay = NULL;
75   static struct _glxapi_table *prevTable = NULL;
76
77   if (!dpy)
78      return NULL;
79
80   /* try cached display */
81   if (dpy == prevDisplay) {
82      return prevTable;
83   }
84
85   /* search list of display/dispatch pairs for this display */
86   {
87      const struct display_dispatch *d = DispatchList;
88      while (d) {
89         if (d->Dpy == dpy) {
90            prevDisplay = dpy;
91            prevTable = d->Table;
92            return d->Table;  /* done! */
93         }
94         d = d->Next;
95      }
96   }
97
98   /* A new display, determine if we should use real GLX (SGI / Utah)
99    * or Mesa's pseudo-GLX.
100    */
101   {
102      struct _glxapi_table *t = NULL;
103
104#if defined(USE_SGI_GLX) || defined(USE_UTAH_GLX)
105      if (!getenv("MESA_FORCE_SOFTX")) {
106         int ignore;
107         if (XQueryExtension( dpy, "GLX", &ignore, &ignore, &ignore )) {
108            /* the X server has the GLX extension */
109#if defined(USE_SGI_GLX)
110            t = _sgi_GetGLXDispatchtable();
111#elif defined(USE_UTAH_GLX)
112            t = _utah_GetGLXDispatchTable();
113#endif
114         }
115      }
116#endif
117
118#if defined(USE_MESA_GLX)
119      if (!t) {
120         t = _mesa_GetGLXDispatchTable();
121         assert(t);  /* this has to work */
122      }
123#endif
124
125      if (t) {
126         struct display_dispatch *d;
127         d = (struct display_dispatch *) malloc(sizeof(struct display_dispatch));
128         if (d) {
129            d->Dpy = dpy;
130            d->Table = t;
131            /* insert at head of list */
132            d->Next = DispatchList;
133            DispatchList = d;
134            /* update cache */
135            prevDisplay = dpy;
136            prevTable = t;
137            return t;
138         }
139      }
140   }
141
142   /* If we get here that means we can't use real GLX on this display
143    * and the Mesa pseudo-GLX software renderer wasn't compiled in.
144    * Or, we ran out of memory!
145    */
146   return NULL;
147}
148
149
150
151/* Set by glXMakeCurrent() and glXMakeContextCurrent() only */
152static Display *CurrentDisplay = NULL;
153static GLXContext CurrentContext = 0;
154static GLXDrawable CurrentDrawable = 0;
155static GLXDrawable CurrentReadDrawable = 0;
156
157
158
159/*
160 * GLX API entrypoints
161 */
162
163
164XVisualInfo *glXChooseVisual(Display *dpy, int screen, int *list)
165{
166   struct _glxapi_table *t = get_dispatch(dpy);
167   if (!t)
168      return NULL;
169   return (t->ChooseVisual)(dpy, screen, list);
170}
171
172
173void glXCopyContext(Display *dpy, GLXContext src, GLXContext dst, unsigned long 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
182GLXContext 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
191GLXPixmap 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
200void 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
209void 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
218int 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
227GLXContext glXGetCurrentContext(void)
228{
229   return CurrentContext;
230}
231
232
233GLXDrawable glXGetCurrentDrawable(void)
234{
235   return CurrentDrawable;
236}
237
238
239Bool 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
248Bool 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
265Bool 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
274Bool 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
283void 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
292void 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
301void glXWaitGL(void)
302{
303   struct _glxapi_table *t = get_dispatch(CurrentDisplay);
304   if (!t)
305      return;
306   (t->WaitGL)();
307}
308
309
310void 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 GLX_VERSION_1_1
321
322const 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
331const 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
340const 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 GLX_VERSION_1_2
353Display *glXGetCurrentDisplay(void)
354{
355   return CurrentDisplay;
356}
357#endif
358
359
360
361#ifdef GLX_VERSION_1_3
362
363GLXFBConfig *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
372GLXContext 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
381GLXPbuffer 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
390GLXPixmap 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
399GLXWindow 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
408void 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
417void 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
426void 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
435GLXDrawable glXGetCurrentReadDrawable(void)
436{
437   return CurrentReadDrawable;
438}
439
440
441int 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
450GLXFBConfig *glXGetFBConfigs(Display *dpy, int screen, int *nelements)
451{
452   struct _glxapi_table *t = get_dispatch(dpy);
453   if (!t)
454      return 0;
455   return (t->GetFBConfigs)(dpy, screen, nelements);
456}
457
458void glXGetSelectedEvent(Display *dpy, GLXDrawable drawable, unsigned long *mask)
459{
460   struct _glxapi_table *t = get_dispatch(dpy);
461   if (!t)
462      return;
463   (t->GetSelectedEvent)(dpy, drawable, mask);
464}
465
466
467XVisualInfo *glXGetVisualFromFBConfig(Display *dpy, GLXFBConfig config)
468{
469   struct _glxapi_table *t = get_dispatch(dpy);
470   if (!t)
471      return NULL;
472   return (t->GetVisualFromFBConfig)(dpy, config);
473}
474
475
476Bool glXMakeContextCurrent(Display *dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx)
477{
478   struct _glxapi_table *t = get_dispatch(dpy);
479   Bool b;
480   if (!t)
481      return False;
482   b = (t->MakeContextCurrent)(dpy, draw, read, ctx);
483   if (b) {
484      CurrentDisplay = dpy;
485      CurrentContext = ctx;
486      CurrentDrawable = draw;
487      CurrentReadDrawable = read;
488   }
489   return b;
490}
491
492
493int glXQueryContext(Display *dpy, GLXContext ctx, int attribute, int *value)
494{
495   struct _glxapi_table *t = get_dispatch(dpy);
496   assert(t);
497   if (!t)
498      return 0; /* XXX correct? */
499   return (t->QueryContext)(dpy, ctx, attribute, value);
500}
501
502
503void glXQueryDrawable(Display *dpy, GLXDrawable draw, int attribute, unsigned int *value)
504{
505   struct _glxapi_table *t = get_dispatch(dpy);
506   if (!t)
507      return;
508   (t->QueryDrawable)(dpy, draw, attribute, value);
509}
510
511
512void glXSelectEvent(Display *dpy, GLXDrawable drawable, unsigned long mask)
513{
514   struct _glxapi_table *t = get_dispatch(dpy);
515   if (!t)
516      return;
517   (t->SelectEvent)(dpy, drawable, mask);
518}
519
520#endif /* GLX_VERSION_1_3 */
521
522
523#ifdef GLX_SGI_swap_control
524
525int glXSwapIntervalSGI(int interval)
526{
527   struct _glxapi_table *t = get_dispatch(CurrentDisplay);
528   if (!t)
529      return 0;
530   return (t->SwapIntervalSGI)(interval);
531}
532
533#endif
534
535
536#ifdef GLX_SGI_video_sync
537
538int glXGetVideoSyncSGI(unsigned int *count)
539{
540   struct _glxapi_table *t = get_dispatch(CurrentDisplay);
541   if (!t)
542      return 0;
543   return (t->GetVideoSyncSGI)(count);
544}
545
546int glXWaitVideoSyncSGI(int divisor, int remainder, unsigned int *count)
547{
548   struct _glxapi_table *t = get_dispatch(CurrentDisplay);
549   if (!t)
550      return 0;
551   return (t->WaitVideoSyncSGI)(divisor, remainder, count);
552}
553
554#endif
555
556
557#ifdef GLX_SGI_make_current_read
558
559Bool glXMakeCurrentReadSGI(Display *dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx)
560{
561   struct _glxapi_table *t = get_dispatch(dpy);
562   if (!t)
563      return 0;
564   return (t->MakeCurrentReadSGI)(dpy, draw, read, ctx);
565}
566
567GLXDrawable glXGetCurrentReadDrawableSGI(void)
568{
569   struct _glxapi_table *t = get_dispatch(CurrentDisplay);
570   if (!t)
571      return 0;
572   return (t->GetCurrentReadDrawableSGI)();
573}
574
575#endif
576
577
578#if defined(_VL_H) && defined(GLX_SGIX_video_source)
579
580GLXVideoSourceSGIX glXCreateGLXVideoSourceSGIX(Display *dpy, int screen, VLServer server, VLPath path, int nodeClass, VLNode drainNode)
581{
582   struct _glxapi_table *t = get_dispatch(dpy);
583   if (!t)
584      return 0;
585   return (t->CreateGLXVideoSourceSGIX)(dpy, screen, server, path, nodeClass, drainNode);
586}
587
588void glXDestroyGLXVideoSourceSGIX(Display *dpy, GLXVideoSourceSGIX src)
589{
590   struct _glxapi_table *t = get_dispatch(dpy);
591   if (!t)
592      return 0;
593   return (t->DestroyGLXVideoSourceSGIX)(dpy, src);
594}
595
596#endif
597
598
599#ifdef GLX_EXT_import_context
600
601void glXFreeContextEXT(Display *dpy, GLXContext context)
602{
603   struct _glxapi_table *t = get_dispatch(dpy);
604   if (!t)
605      return;
606   (t->FreeContextEXT)(dpy, context);
607}
608
609GLXContextID glXGetContextIDEXT(const GLXContext context)
610{
611   /* XXX is this function right? */
612   struct _glxapi_table *t = get_dispatch(CurrentDisplay);
613   if (!t)
614      return 0;
615   return (t->GetContextIDEXT)(context);
616}
617
618Display *glXGetCurrentDisplayEXT(void)
619{
620   return CurrentDisplay;
621}
622
623GLXContext glXImportContextEXT(Display *dpy, GLXContextID contextID)
624{
625   struct _glxapi_table *t = get_dispatch(dpy);
626   if (!t)
627      return 0;
628   return (t->ImportContextEXT)(dpy, contextID);
629}
630
631int glXQueryContextInfoEXT(Display *dpy, GLXContext context, int attribute,int *value)
632{
633   struct _glxapi_table *t = get_dispatch(dpy);
634   if (!t)
635      return 0;  /* XXX ok? */
636   return (t->QueryContextInfoEXT)(dpy, context, attribute, value);
637}
638
639#endif
640
641
642#ifdef GLX_SGIX_fbconfig
643
644int glXGetFBConfigAttribSGIX(Display *dpy, GLXFBConfigSGIX config, int attribute, int *value)
645{
646   struct _glxapi_table *t = get_dispatch(dpy);
647   if (!t)
648      return 0;
649   return (t->GetFBConfigAttribSGIX)(dpy, config, attribute, value);
650}
651
652GLXFBConfigSGIX *glXChooseFBConfigSGIX(Display *dpy, int screen, int *attrib_list, int *nelements)
653{
654   struct _glxapi_table *t = get_dispatch(dpy);
655   if (!t)
656      return 0;
657   return (t->ChooseFBConfigSGIX)(dpy, screen, attrib_list, nelements);
658}
659
660GLXPixmap glXCreateGLXPixmapWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config, Pixmap pixmap)
661{
662   struct _glxapi_table *t = get_dispatch(dpy);
663   if (!t)
664      return 0;
665   return (t->CreateGLXPixmapWithConfigSGIX)(dpy, config, pixmap);
666}
667
668GLXContext glXCreateContextWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config, int render_type, GLXContext share_list, Bool direct)
669{
670   struct _glxapi_table *t = get_dispatch(dpy);
671   if (!t)
672      return 0;
673   return (t->CreateContextWithConfigSGIX)(dpy, config, render_type, share_list, direct);
674}
675
676XVisualInfo * glXGetVisualFromFBConfigSGIX(Display *dpy, GLXFBConfigSGIX config)
677{
678   struct _glxapi_table *t = get_dispatch(dpy);
679   if (!t)
680      return 0;
681   return (t->GetVisualFromFBConfigSGIX)(dpy, config);
682}
683
684GLXFBConfigSGIX glXGetFBConfigFromVisualSGIX(Display *dpy, XVisualInfo *vis)
685{
686   struct _glxapi_table *t = get_dispatch(dpy);
687   if (!t)
688      return 0;
689   return (t->GetFBConfigFromVisualSGIX)(dpy, vis);
690}
691
692#endif
693
694
695#ifdef GLX_SGIX_pbuffer
696
697GLXPbufferSGIX glXCreateGLXPbufferSGIX(Display *dpy, GLXFBConfigSGIX config, unsigned int width, unsigned int height, int *attrib_list)
698{
699   struct _glxapi_table *t = get_dispatch(dpy);
700   if (!t)
701      return 0;
702   return (t->CreateGLXPbufferSGIX)(dpy, config, width, height, attrib_list);
703}
704
705void glXDestroyGLXPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuf)
706{
707   struct _glxapi_table *t = get_dispatch(dpy);
708   if (!t)
709      return;
710   (t->DestroyGLXPbufferSGIX)(dpy, pbuf);
711}
712
713int glXQueryGLXPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuf, int attribute, unsigned int *value)
714{
715   struct _glxapi_table *t = get_dispatch(dpy);
716   if (!t)
717      return 0;
718   return (t->QueryGLXPbufferSGIX)(dpy, pbuf, attribute, value);
719}
720
721void glXSelectEventSGIX(Display *dpy, GLXDrawable drawable, unsigned long mask)
722{
723   struct _glxapi_table *t = get_dispatch(dpy);
724   if (!t)
725      return;
726   (t->SelectEventSGIX)(dpy, drawable, mask);
727}
728
729void glXGetSelectedEventSGIX(Display *dpy, GLXDrawable drawable, unsigned long *mask)
730{
731   struct _glxapi_table *t = get_dispatch(dpy);
732   if (!t)
733      return;
734   (t->GetSelectedEventSGIX)(dpy, drawable, mask);
735}
736
737#endif
738
739
740#ifdef GLX_SGI_cushion
741
742void glXCushionSGI(Display *dpy, Window win, float cushion)
743{
744   struct _glxapi_table *t = get_dispatch(dpy);
745   if (!t)
746      return;
747   (t->CushionSGI)(dpy, win, cushion);
748}
749
750#endif
751
752
753#ifdef GLX_SGIX_video_resize
754
755int glXBindChannelToWindowSGIX(Display *dpy, int screen, int channel , Window window)
756{
757   struct _glxapi_table *t = get_dispatch(dpy);
758   if (!t)
759      return 0;
760   return (t->BindChannelToWindowSGIX)(dpy, screen, channel, window);
761}
762
763int glXChannelRectSGIX(Display *dpy, int screen, int channel, int x, int y, int w, int h)
764{
765   struct _glxapi_table *t = get_dispatch(dpy);
766   if (!t)
767      return 0;
768   return (t->ChannelRectSGIX)(dpy, screen, channel, x, y, w, h);
769}
770
771int glXQueryChannelRectSGIX(Display *dpy, int screen, int channel, int *x, int *y, int *w, int *h)
772{
773   struct _glxapi_table *t = get_dispatch(dpy);
774   if (!t)
775      return 0;
776   return (t->QueryChannelRectSGIX)(dpy, screen, channel, x, y, w, h);
777}
778
779int glXQueryChannelDeltasSGIX(Display *dpy, int screen, int channel, int *dx, int *dy, int *dw, int *dh)
780{
781   struct _glxapi_table *t = get_dispatch(dpy);
782   if (!t)
783      return 0;
784   return (t->QueryChannelDeltasSGIX)(dpy, screen, channel, dx, dy, dw, dh);
785}
786
787int glXChannelRectSyncSGIX(Display *dpy, int screen, int channel, GLenum synctype)
788{
789   struct _glxapi_table *t = get_dispatch(dpy);
790   if (!t)
791      return 0;
792   return (t->ChannelRectSyncSGIX)(dpy, screen, channel, synctype);
793}
794
795#endif
796
797
798#if defined(_DM_BUFFER_H_) && defined(GLX_SGIX_dmbuffer)
799
800Bool glXAssociateDMPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuffer, DMparams *params, DMbuffer dmbuffer)
801{
802   struct _glxapi_table *t = get_dispatch(dpy);
803   if (!t)
804      return False;
805   return (t->AssociateDMPbufferSGIX)(dpy, pbuffer, params, dmbuffer);
806}
807
808#endif
809
810
811#ifdef GLX_SGIX_swap_group
812
813void glXJoinSwapGroupSGIX(Display *dpy, GLXDrawable drawable, GLXDrawable member)
814{
815   struct _glxapi_table *t = get_dispatch(dpy);
816   if (!t)
817      return;
818   (*t->JoinSwapGroupSGIX)(dpy, drawable, member);
819}
820
821#endif
822
823
824#ifdef GLX_SGIX_swap_barrier
825
826void glXBindSwapBarrierSGIX(Display *dpy, GLXDrawable drawable, int barrier)
827{
828   struct _glxapi_table *t = get_dispatch(dpy);
829   if (!t)
830      return;
831   (*t->BindSwapBarrierSGIX)(dpy, drawable, barrier);
832}
833
834Bool glXQueryMaxSwapBarriersSGIX(Display *dpy, int screen, int *max)
835{
836   struct _glxapi_table *t = get_dispatch(dpy);
837   if (!t)
838      return False;
839   return (*t->QueryMaxSwapBarriersSGIX)(dpy, screen, max);
840}
841
842#endif
843
844
845#ifdef GLX_SUN_get_transparent_index
846
847Status glXGetTransparentIndexSUN(Display *dpy, Window overlay, Window underlay, long *pTransparent)
848{
849   struct _glxapi_table *t = get_dispatch(dpy);
850   if (!t)
851      return False;
852   return (*t->GetTransparentIndexSUN)(dpy, overlay, underlay, pTransparent);
853}
854
855#endif
856
857
858#ifdef GLX_MESA_copy_sub_buffer
859
860void glXCopySubBufferMESA(Display *dpy, GLXDrawable drawable, int x, int y, int width, int height)
861{
862   struct _glxapi_table *t = get_dispatch(dpy);
863   if (!t)
864      return;
865   (t->CopySubBufferMESA)(dpy, drawable, x, y, width, height);
866}
867
868#endif
869
870
871#ifdef GLX_MESA_release_buffers
872
873Bool glXReleaseBuffersMESA(Display *dpy, Window w)
874{
875   struct _glxapi_table *t = get_dispatch(dpy);
876   if (!t)
877      return False;
878   return (t->ReleaseBuffersMESA)(dpy, w);
879}
880
881#endif
882
883
884#ifdef GLX_MESA_pixmap_colormap
885
886GLXPixmap glXCreateGLXPixmapMESA(Display *dpy, XVisualInfo *visinfo, Pixmap pixmap, Colormap cmap)
887{
888   struct _glxapi_table *t = get_dispatch(dpy);
889   if (!t)
890      return 0;
891   return (t->CreateGLXPixmapMESA)(dpy, visinfo, pixmap, cmap);
892}
893
894#endif
895
896
897#ifdef GLX_MESA_set_3dfx_mode
898
899Bool glXSet3DfxModeMESA(int mode)
900{
901   struct _glxapi_table *t = get_dispatch(CurrentDisplay);
902   if (!t)
903      return False;
904   return (t->Set3DfxModeMESA)(mode);
905}
906
907#endif
908
909
910
911/**********************************************************************/
912/* GLX API management functions                                       */
913/**********************************************************************/
914
915
916const char *
917_glxapi_get_version(void)
918{
919   return "1.3";
920}
921
922
923/*
924 * Return array of extension strings.
925 */
926const char **
927_glxapi_get_extensions(void)
928{
929   static const char *extensions[] = {
930#ifdef GLX_EXT_import_context
931      "GLX_EXT_import_context",
932#endif
933#ifdef GLX_SGI_video_sync
934      "GLX_SGI_video_sync",
935#endif
936#ifdef GLX_MESA_copy_sub_buffer
937      "GLX_MESA_copy_sub_buffer",
938#endif
939#ifdef GLX_MESA_release_buffers
940      "GLX_MESA_release_buffers",
941#endif
942#ifdef GLX_MESA_pixmap_colormap
943      "GLX_MESA_pixmap_colormap",
944#endif
945#ifdef GLX_MESA_set_3dfx_mode
946      "GLX_MESA_set_3dfx_mode",
947#endif
948      NULL
949   };
950   return extensions;
951}
952
953
954/*
955 * Return size of the GLX dispatch table, in entries, not bytes.
956 */
957GLuint
958_glxapi_get_dispatch_table_size(void)
959{
960   return sizeof(struct _glxapi_table) / sizeof(void *);
961}
962
963
964static int
965generic_no_op_func(void)
966{
967   return 0;
968}
969
970
971/*
972 * Initialize all functions in given dispatch table to be no-ops
973 */
974void
975_glxapi_set_no_op_table(struct _glxapi_table *t)
976{
977   GLuint n = _glxapi_get_dispatch_table_size();
978   GLuint i;
979   void **dispatch = (void **) t;
980   for (i = 0; i < n; i++) {
981      dispatch[i] = (void *) generic_no_op_func;
982   }
983}
984
985
986
987struct name_address_pair {
988   const char *Name;
989   GLvoid *Address;
990};
991
992static struct name_address_pair GLX_functions[] = {
993   { "glXChooseVisual", (GLvoid *) glXChooseVisual },
994   { "glXCopyContext", (GLvoid *) glXCopyContext },
995   { "glXCreateContext", (GLvoid *) glXCreateContext },
996   { "glXCreateGLXPixmap", (GLvoid *) glXCreateGLXPixmap },
997   { "glXDestroyContext", (GLvoid *) glXDestroyContext },
998   { "glXDestroyGLXPixmap", (GLvoid *) glXDestroyGLXPixmap },
999   { "glXGetConfig", (GLvoid *) glXGetConfig },
1000   { "glXGetCurrentContext", (GLvoid *) glXGetCurrentContext },
1001   { "glXGetCurrentDrawable", (GLvoid *) glXGetCurrentDrawable },
1002   { "glXIsDirect", (GLvoid *) glXIsDirect },
1003   { "glXMakeCurrent", (GLvoid *) glXMakeCurrent },
1004   { "glXQueryExtension", (GLvoid *) glXQueryExtension },
1005   { "glXQueryVersion", (GLvoid *) glXQueryVersion },
1006   { "glXSwapBuffers", (GLvoid *) glXSwapBuffers },
1007   { "glXUseXFont", (GLvoid *) glXUseXFont },
1008   { "glXWaitGL", (GLvoid *) glXWaitGL },
1009   { "glXWaitX", (GLvoid *) glXWaitX },
1010
1011#ifdef GLX_VERSION_1_1
1012   { "glXGetClientString", (GLvoid *) glXGetClientString },
1013   { "glXQueryExtensionsString", (GLvoid *) glXQueryExtensionsString },
1014   { "glXQueryServerString", (GLvoid *) glXQueryServerString },
1015#endif
1016
1017#ifdef GLX_VERSION_1_2
1018   { "glXGetCurrentDisplay", (GLvoid *) glXGetCurrentDisplay },
1019#endif
1020
1021#ifdef GLX_VERSION_1_3
1022   { "glXChooseFBConfig", (GLvoid *) glXChooseFBConfig },
1023   { "glXCreateNewContext", (GLvoid *) glXCreateNewContext },
1024   { "glXCreatePbuffer", (GLvoid *) glXCreatePbuffer },
1025   { "glXCreatePixmap", (GLvoid *) glXCreatePixmap },
1026   { "glXCreateWindow", (GLvoid *) glXCreateWindow },
1027   { "glXDestroyPbuffer", (GLvoid *) glXDestroyPbuffer },
1028   { "glXDestroyPixmap", (GLvoid *) glXDestroyPixmap },
1029   { "glXDestroyWindow", (GLvoid *) glXDestroyWindow },
1030   { "glXGetCurrentReadDrawable", (GLvoid *) glXGetCurrentReadDrawable },
1031   { "glXGetFBConfigAttrib", (GLvoid *) glXGetFBConfigAttrib },
1032   { "glXGetSelectedEvent", (GLvoid *) glXGetSelectedEvent },
1033   { "glXGetVisualFromFBConfig", (GLvoid *) glXGetVisualFromFBConfig },
1034   { "glXMakeContextCurrent", (GLvoid *) glXMakeContextCurrent },
1035   { "glXQueryContext", (GLvoid *) glXQueryContext },
1036   { "glXQueryDrawable", (GLvoid *) glXQueryDrawable },
1037   { "glXSelectEvent", (GLvoid *) glXSelectEvent },
1038#endif
1039
1040#ifdef GLX_SGI_video_sync
1041   { "glXGetVideoSyncSGI", (GLvoid *) glXGetVideoSyncSGI },
1042   { "glXWaitVideoSyncSGI", (GLvoid *) glXWaitVideoSyncSGI },
1043#endif
1044
1045#ifdef GLX_MESA_copy_sub_buffer
1046   { "glXCopySubBufferMESA", (GLvoid *) glXCopySubBufferMESA },
1047#endif
1048
1049#ifdef GLX_MESA_release_buffers
1050   { "glXReleaseBuffersMESA", (GLvoid *) glXReleaseBuffersMESA },
1051#endif
1052
1053#ifdef GLX_MESA_pixmap_colormap
1054   { "glXCreateGLXPixmapMESA", (GLvoid *) glXCreateGLXPixmapMESA },
1055#endif
1056
1057#ifdef GLX_MESA_set_3dfx_mode
1058   { "glXSet3DfxModeMESA", (GLvoid *) glXSet3DfxModeMESA },
1059#endif
1060
1061   { "glXGetProcAddressARB", (GLvoid *) glXGetProcAddressARB },
1062
1063   { NULL, NULL }   /* end of list */
1064};
1065
1066
1067
1068/*
1069 * Return address of named glX function, or NULL if not found.
1070 */
1071const GLvoid *
1072_glxapi_get_proc_address(const char *funcName)
1073{
1074   GLuint i;
1075   for (i = 0; GLX_functions[i].Name; i++) {
1076      if (strcmp(GLX_functions[i].Name, funcName) == 0)
1077         return GLX_functions[i].Address;
1078   }
1079   return NULL;
1080}
1081
1082
1083
1084/*
1085 * This function does not get dispatched through the dispatch table
1086 * since it's really a "meta" function.
1087 */
1088void (*glXGetProcAddressARB(const GLubyte *procName))()
1089{
1090   typedef void (*gl_function)();
1091   gl_function f;
1092
1093   f = (gl_function) _glxapi_get_proc_address((const char *) procName);
1094   if (f) {
1095      return f;
1096   }
1097
1098   f = (gl_function) _glapi_get_proc_address((const char *) procName);
1099   return f;
1100}
1101