prototyping some new stuff
[mesa.git] / src / mesa / drivers / x11 / glxapi.c
1 /* $Id: glxapi.c,v 1.21 2001/05/24 00:00:57 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 <stdio.h>
38 #include <string.h>
39 /*#include <dlfcn.h>*/ /* XXX not portable? */
40 #include "glapi.h"
41 #include "glxapi.h"
42
43
44 /*
45 * XXX - this really shouldn't be here.
46 * Instead, add -DUSE_MESA_GLX to the compiler flags when needed.
47 */
48 #define USE_MESA_GLX 1
49
50
51 /* Rather than include possibly non-existant headers... */
52 #ifdef USE_SGI_GLX
53 extern struct _glxapi_table *_sgi_GetGLXDispatchTable(void);
54 #endif
55 #ifdef USE_UTAH_GLX
56 extern struct _glxapi_table *_utah_GetGLXDispatchTable(void);
57 #endif
58 #ifdef USE_MESA_GLX
59 extern struct _glxapi_table *_mesa_GetGLXDispatchTable(void);
60 #endif
61
62
63
64 struct display_dispatch {
65 Display *Dpy;
66 struct _glxapi_table *Table;
67 struct display_dispatch *Next;
68 };
69
70 static struct display_dispatch *DispatchList = NULL;
71
72
73 /* Display -> Dispatch caching */
74 static Display *prevDisplay = NULL;
75 static struct _glxapi_table *prevTable = NULL;
76
77
78 static struct _glxapi_table *
79 get_dispatch(Display *dpy)
80 {
81 if (!dpy)
82 return NULL;
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 #define GET_DISPATCH(DPY, TABLE) \
150 if (DPY == prevDisplay) { \
151 TABLE = prevTable; \
152 } \
153 else if (!DPY) { \
154 TABLE = NULL; \
155 } \
156 else { \
157 TABLE = get_dispatch(DPY); \
158 }
159
160
161
162
163 /* Set by glXMakeCurrent() and glXMakeContextCurrent() only */
164 static Display *CurrentDisplay = NULL;
165 static GLXContext CurrentContext = 0;
166 static GLXDrawable CurrentDrawable = 0;
167 static GLXDrawable CurrentReadDrawable = 0;
168
169
170
171 /*
172 * GLX API entrypoints
173 */
174
175
176 XVisualInfo *glXChooseVisual(Display *dpy, int screen, int *list)
177 {
178 struct _glxapi_table *t;
179 GET_DISPATCH(dpy, t);
180 if (!t)
181 return NULL;
182 return (t->ChooseVisual)(dpy, screen, list);
183 }
184
185
186 void glXCopyContext(Display *dpy, GLXContext src, GLXContext dst, unsigned long mask)
187 {
188 struct _glxapi_table *t;
189 GET_DISPATCH(dpy, t);
190 if (!t)
191 return;
192 (t->CopyContext)(dpy, src, dst, mask);
193 }
194
195
196 GLXContext glXCreateContext(Display *dpy, XVisualInfo *visinfo, GLXContext shareList, Bool direct)
197 {
198 struct _glxapi_table *t;
199 GET_DISPATCH(dpy, t);
200 if (!t)
201 return 0;
202 return (t->CreateContext)(dpy, visinfo, shareList, direct);
203 }
204
205
206 GLXPixmap glXCreateGLXPixmap(Display *dpy, XVisualInfo *visinfo, Pixmap pixmap)
207 {
208 struct _glxapi_table *t;
209 GET_DISPATCH(dpy, t);
210 if (!t)
211 return 0;
212 return (t->CreateGLXPixmap)(dpy, visinfo, pixmap);
213 }
214
215
216 void glXDestroyContext(Display *dpy, GLXContext ctx)
217 {
218 struct _glxapi_table *t;
219 GET_DISPATCH(dpy, t);
220 if (!t)
221 return;
222 (t->DestroyContext)(dpy, ctx);
223 }
224
225
226 void glXDestroyGLXPixmap(Display *dpy, GLXPixmap pixmap)
227 {
228 struct _glxapi_table *t;
229 GET_DISPATCH(dpy, t);
230 if (!t)
231 return;
232 (t->DestroyGLXPixmap)(dpy, pixmap);
233 }
234
235
236 int glXGetConfig(Display *dpy, XVisualInfo *visinfo, int attrib, int *value)
237 {
238 struct _glxapi_table *t;
239 GET_DISPATCH(dpy, t);
240 if (!t)
241 return GLX_NO_EXTENSION;
242 return (t->GetConfig)(dpy, visinfo, attrib, value);
243 }
244
245
246 GLXContext glXGetCurrentContext(void)
247 {
248 return CurrentContext;
249 }
250
251
252 GLXDrawable glXGetCurrentDrawable(void)
253 {
254 return CurrentDrawable;
255 }
256
257
258 Bool glXIsDirect(Display *dpy, GLXContext ctx)
259 {
260 struct _glxapi_table *t;
261 GET_DISPATCH(dpy, t);
262 if (!t)
263 return False;
264 return (t->IsDirect)(dpy, ctx);
265 }
266
267
268 Bool glXMakeCurrent(Display *dpy, GLXDrawable drawable, GLXContext ctx)
269 {
270 Bool b;
271 struct _glxapi_table *t;
272 GET_DISPATCH(dpy, t);
273 if (!t)
274 return False;
275 b = (*t->MakeCurrent)(dpy, drawable, ctx);
276 if (b) {
277 CurrentDisplay = dpy;
278 CurrentContext = ctx;
279 CurrentDrawable = drawable;
280 CurrentReadDrawable = drawable;
281 }
282 return b;
283 }
284
285
286 Bool glXQueryExtension(Display *dpy, int *errorb, int *event)
287 {
288 struct _glxapi_table *t;
289 GET_DISPATCH(dpy, t);
290 if (!t)
291 return False;
292 return (t->QueryExtension)(dpy, errorb, event);
293 }
294
295
296 Bool glXQueryVersion(Display *dpy, int *maj, int *min)
297 {
298 struct _glxapi_table *t;
299 GET_DISPATCH(dpy, t);
300 if (!t)
301 return False;
302 return (t->QueryVersion)(dpy, maj, min);
303 }
304
305
306 void glXSwapBuffers(Display *dpy, GLXDrawable drawable)
307 {
308 struct _glxapi_table *t;
309 GET_DISPATCH(dpy, t);
310 if (!t)
311 return;
312 (t->SwapBuffers)(dpy, drawable);
313 }
314
315
316 void glXUseXFont(Font font, int first, int count, int listBase)
317 {
318 struct _glxapi_table *t;
319 GET_DISPATCH(CurrentDisplay, t);
320 if (!t)
321 return;
322 (t->UseXFont)(font, first, count, listBase);
323 }
324
325
326 void glXWaitGL(void)
327 {
328 struct _glxapi_table *t;
329 GET_DISPATCH(CurrentDisplay, t);
330 if (!t)
331 return;
332 (t->WaitGL)();
333 }
334
335
336 void glXWaitX(void)
337 {
338 struct _glxapi_table *t;
339 GET_DISPATCH(CurrentDisplay, t);
340 if (!t)
341 return;
342 (t->WaitX)();
343 }
344
345
346
347 #ifdef GLX_VERSION_1_1
348
349 const char *glXGetClientString(Display *dpy, int name)
350 {
351 struct _glxapi_table *t;
352 GET_DISPATCH(dpy, t);
353 if (!t)
354 return NULL;
355 return (t->GetClientString)(dpy, name);
356 }
357
358
359 const char *glXQueryExtensionsString(Display *dpy, int screen)
360 {
361 struct _glxapi_table *t;
362 GET_DISPATCH(dpy, t);
363 if (!t)
364 return NULL;
365 return (t->QueryExtensionsString)(dpy, screen);
366 }
367
368
369 const char *glXQueryServerString(Display *dpy, int screen, int name)
370 {
371 struct _glxapi_table *t;
372 GET_DISPATCH(dpy, t);
373 if (!t)
374 return NULL;
375 return (t->QueryServerString)(dpy, screen, name);
376 }
377
378 #endif
379
380
381
382 #ifdef GLX_VERSION_1_2
383 Display *glXGetCurrentDisplay(void)
384 {
385 return CurrentDisplay;
386 }
387 #endif
388
389
390
391 #ifdef GLX_VERSION_1_3
392
393 GLXFBConfig *glXChooseFBConfig(Display *dpy, int screen, const int *attribList, int *nitems)
394 {
395 struct _glxapi_table *t;
396 GET_DISPATCH(dpy, t);
397 if (!t)
398 return 0;
399 return (t->ChooseFBConfig)(dpy, screen, attribList, nitems);
400 }
401
402
403 GLXContext glXCreateNewContext(Display *dpy, GLXFBConfig config, int renderType, GLXContext shareList, Bool direct)
404 {
405 struct _glxapi_table *t;
406 GET_DISPATCH(dpy, t);
407 if (!t)
408 return 0;
409 return (t->CreateNewContext)(dpy, config, renderType, shareList, direct);
410 }
411
412
413 GLXPbuffer glXCreatePbuffer(Display *dpy, GLXFBConfig config, const int *attribList)
414 {
415 struct _glxapi_table *t;
416 GET_DISPATCH(dpy, t);
417 if (!t)
418 return 0;
419 return (t->CreatePbuffer)(dpy, config, attribList);
420 }
421
422
423 GLXPixmap glXCreatePixmap(Display *dpy, GLXFBConfig config, Pixmap pixmap, const int *attribList)
424 {
425 struct _glxapi_table *t;
426 GET_DISPATCH(dpy, t);
427 if (!t)
428 return 0;
429 return (t->CreatePixmap)(dpy, config, pixmap, attribList);
430 }
431
432
433 GLXWindow glXCreateWindow(Display *dpy, GLXFBConfig config, Window win, const int *attribList)
434 {
435 struct _glxapi_table *t;
436 GET_DISPATCH(dpy, t);
437 if (!t)
438 return 0;
439 return (t->CreateWindow)(dpy, config, win, attribList);
440 }
441
442
443 void glXDestroyPbuffer(Display *dpy, GLXPbuffer pbuf)
444 {
445 struct _glxapi_table *t;
446 GET_DISPATCH(dpy, t);
447 if (!t)
448 return;
449 (t->DestroyPbuffer)(dpy, pbuf);
450 }
451
452
453 void glXDestroyPixmap(Display *dpy, GLXPixmap pixmap)
454 {
455 struct _glxapi_table *t;
456 GET_DISPATCH(dpy, t);
457 if (!t)
458 return;
459 (t->DestroyPixmap)(dpy, pixmap);
460 }
461
462
463 void glXDestroyWindow(Display *dpy, GLXWindow window)
464 {
465 struct _glxapi_table *t;
466 GET_DISPATCH(dpy, t);
467 if (!t)
468 return;
469 (t->DestroyWindow)(dpy, window);
470 }
471
472
473 GLXDrawable glXGetCurrentReadDrawable(void)
474 {
475 return CurrentReadDrawable;
476 }
477
478
479 int glXGetFBConfigAttrib(Display *dpy, GLXFBConfig config, int attribute, int *value)
480 {
481 struct _glxapi_table *t;
482 GET_DISPATCH(dpy, t);
483 if (!t)
484 return GLX_NO_EXTENSION;
485 return (t->GetFBConfigAttrib)(dpy, config, attribute, value);
486 }
487
488
489 GLXFBConfig *glXGetFBConfigs(Display *dpy, int screen, int *nelements)
490 {
491 struct _glxapi_table *t;
492 GET_DISPATCH(dpy, t);
493 if (!t)
494 return 0;
495 return (t->GetFBConfigs)(dpy, screen, nelements);
496 }
497
498 void glXGetSelectedEvent(Display *dpy, GLXDrawable drawable, unsigned long *mask)
499 {
500 struct _glxapi_table *t;
501 GET_DISPATCH(dpy, t);
502 if (!t)
503 return;
504 (t->GetSelectedEvent)(dpy, drawable, mask);
505 }
506
507
508 XVisualInfo *glXGetVisualFromFBConfig(Display *dpy, GLXFBConfig config)
509 {
510 struct _glxapi_table *t;
511 GET_DISPATCH(dpy, t);
512 if (!t)
513 return NULL;
514 return (t->GetVisualFromFBConfig)(dpy, config);
515 }
516
517
518 Bool glXMakeContextCurrent(Display *dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx)
519 {
520 Bool b;
521 struct _glxapi_table *t;
522 GET_DISPATCH(dpy, t);
523 if (!t)
524 return False;
525 b = (t->MakeContextCurrent)(dpy, draw, read, ctx);
526 if (b) {
527 CurrentDisplay = dpy;
528 CurrentContext = ctx;
529 CurrentDrawable = draw;
530 CurrentReadDrawable = read;
531 }
532 return b;
533 }
534
535
536 int glXQueryContext(Display *dpy, GLXContext ctx, int attribute, int *value)
537 {
538 struct _glxapi_table *t;
539 GET_DISPATCH(dpy, t);
540 assert(t);
541 if (!t)
542 return 0; /* XXX correct? */
543 return (t->QueryContext)(dpy, ctx, attribute, value);
544 }
545
546
547 void glXQueryDrawable(Display *dpy, GLXDrawable draw, int attribute, unsigned int *value)
548 {
549 struct _glxapi_table *t;
550 GET_DISPATCH(dpy, t);
551 if (!t)
552 return;
553 (t->QueryDrawable)(dpy, draw, attribute, value);
554 }
555
556
557 void glXSelectEvent(Display *dpy, GLXDrawable drawable, unsigned long mask)
558 {
559 struct _glxapi_table *t;
560 GET_DISPATCH(dpy, t);
561 if (!t)
562 return;
563 (t->SelectEvent)(dpy, drawable, mask);
564 }
565
566 #endif /* GLX_VERSION_1_3 */
567
568
569 #ifdef GLX_SGI_swap_control
570
571 int glXSwapIntervalSGI(int interval)
572 {
573 struct _glxapi_table *t;
574 GET_DISPATCH(CurrentDisplay, t);
575 if (!t)
576 return 0;
577 return (t->SwapIntervalSGI)(interval);
578 }
579
580 #endif
581
582
583 #ifdef GLX_SGI_video_sync
584
585 int glXGetVideoSyncSGI(unsigned int *count)
586 {
587 struct _glxapi_table *t;
588 GET_DISPATCH(CurrentDisplay, t);
589 if (!t)
590 return 0;
591 return (t->GetVideoSyncSGI)(count);
592 }
593
594 int glXWaitVideoSyncSGI(int divisor, int remainder, unsigned int *count)
595 {
596 struct _glxapi_table *t;
597 GET_DISPATCH(CurrentDisplay, t);
598 if (!t)
599 return 0;
600 return (t->WaitVideoSyncSGI)(divisor, remainder, count);
601 }
602
603 #endif
604
605
606 #ifdef GLX_SGI_make_current_read
607
608 Bool glXMakeCurrentReadSGI(Display *dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx)
609 {
610 struct _glxapi_table *t;
611 GET_DISPATCH(dpy, t);
612 if (!t)
613 return 0;
614 return (t->MakeCurrentReadSGI)(dpy, draw, read, ctx);
615 }
616
617 GLXDrawable glXGetCurrentReadDrawableSGI(void)
618 {
619 struct _glxapi_table *t;
620 GET_DISPATCH(CurrentDisplay, t);
621 if (!t)
622 return 0;
623 return (t->GetCurrentReadDrawableSGI)();
624 }
625
626 #endif
627
628
629 #if defined(_VL_H) && defined(GLX_SGIX_video_source)
630
631 GLXVideoSourceSGIX glXCreateGLXVideoSourceSGIX(Display *dpy, int screen, VLServer server, VLPath path, int nodeClass, VLNode drainNode)
632 {
633 struct _glxapi_table *t;
634 GET_DISPATCH(dpy, t);
635 if (!t)
636 return 0;
637 return (t->CreateGLXVideoSourceSGIX)(dpy, screen, server, path, nodeClass, drainNode);
638 }
639
640 void glXDestroyGLXVideoSourceSGIX(Display *dpy, GLXVideoSourceSGIX src)
641 {
642 struct _glxapi_table *t;
643 GET_DISPATCH(dpy, t);
644 if (!t)
645 return 0;
646 return (t->DestroyGLXVideoSourceSGIX)(dpy, src);
647 }
648
649 #endif
650
651
652 #ifdef GLX_EXT_import_context
653
654 void glXFreeContextEXT(Display *dpy, GLXContext context)
655 {
656 struct _glxapi_table *t;
657 GET_DISPATCH(dpy, t);
658 if (!t)
659 return;
660 (t->FreeContextEXT)(dpy, context);
661 }
662
663 GLXContextID glXGetContextIDEXT(const GLXContext context)
664 {
665 /* XXX is this function right? */
666 struct _glxapi_table *t;
667 GET_DISPATCH(CurrentDisplay, t);
668 if (!t)
669 return 0;
670 return (t->GetContextIDEXT)(context);
671 }
672
673 Display *glXGetCurrentDisplayEXT(void)
674 {
675 return CurrentDisplay;
676 }
677
678 GLXContext glXImportContextEXT(Display *dpy, GLXContextID contextID)
679 {
680 struct _glxapi_table *t;
681 GET_DISPATCH(dpy, t);
682 if (!t)
683 return 0;
684 return (t->ImportContextEXT)(dpy, contextID);
685 }
686
687 int glXQueryContextInfoEXT(Display *dpy, GLXContext context, int attribute,int *value)
688 {
689 struct _glxapi_table *t;
690 GET_DISPATCH(dpy, t);
691 if (!t)
692 return 0; /* XXX ok? */
693 return (t->QueryContextInfoEXT)(dpy, context, attribute, value);
694 }
695
696 #endif
697
698
699 #ifdef GLX_SGIX_fbconfig
700
701 int glXGetFBConfigAttribSGIX(Display *dpy, GLXFBConfigSGIX config, int attribute, int *value)
702 {
703 struct _glxapi_table *t;
704 GET_DISPATCH(dpy, t);
705 if (!t)
706 return 0;
707 return (t->GetFBConfigAttribSGIX)(dpy, config, attribute, value);
708 }
709
710 GLXFBConfigSGIX *glXChooseFBConfigSGIX(Display *dpy, int screen, int *attrib_list, int *nelements)
711 {
712 struct _glxapi_table *t;
713 GET_DISPATCH(dpy, t);
714 if (!t)
715 return 0;
716 return (t->ChooseFBConfigSGIX)(dpy, screen, attrib_list, nelements);
717 }
718
719 GLXPixmap glXCreateGLXPixmapWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config, Pixmap pixmap)
720 {
721 struct _glxapi_table *t;
722 GET_DISPATCH(dpy, t);
723 if (!t)
724 return 0;
725 return (t->CreateGLXPixmapWithConfigSGIX)(dpy, config, pixmap);
726 }
727
728 GLXContext glXCreateContextWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config, int render_type, GLXContext share_list, Bool direct)
729 {
730 struct _glxapi_table *t;
731 GET_DISPATCH(dpy, t);
732 if (!t)
733 return 0;
734 return (t->CreateContextWithConfigSGIX)(dpy, config, render_type, share_list, direct);
735 }
736
737 XVisualInfo * glXGetVisualFromFBConfigSGIX(Display *dpy, GLXFBConfigSGIX config)
738 {
739 struct _glxapi_table *t;
740 GET_DISPATCH(dpy, t);
741 if (!t)
742 return 0;
743 return (t->GetVisualFromFBConfigSGIX)(dpy, config);
744 }
745
746 GLXFBConfigSGIX glXGetFBConfigFromVisualSGIX(Display *dpy, XVisualInfo *vis)
747 {
748 struct _glxapi_table *t;
749 GET_DISPATCH(dpy, t);
750 if (!t)
751 return 0;
752 return (t->GetFBConfigFromVisualSGIX)(dpy, vis);
753 }
754
755 #endif
756
757
758 #ifdef GLX_SGIX_pbuffer
759
760 GLXPbufferSGIX glXCreateGLXPbufferSGIX(Display *dpy, GLXFBConfigSGIX config, unsigned int width, unsigned int height, int *attrib_list)
761 {
762 struct _glxapi_table *t;
763 GET_DISPATCH(dpy, t);
764 if (!t)
765 return 0;
766 return (t->CreateGLXPbufferSGIX)(dpy, config, width, height, attrib_list);
767 }
768
769 void glXDestroyGLXPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuf)
770 {
771 struct _glxapi_table *t;
772 GET_DISPATCH(dpy, t);
773 if (!t)
774 return;
775 (t->DestroyGLXPbufferSGIX)(dpy, pbuf);
776 }
777
778 int glXQueryGLXPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuf, int attribute, unsigned int *value)
779 {
780 struct _glxapi_table *t;
781 GET_DISPATCH(dpy, t);
782 if (!t)
783 return 0;
784 return (t->QueryGLXPbufferSGIX)(dpy, pbuf, attribute, value);
785 }
786
787 void glXSelectEventSGIX(Display *dpy, GLXDrawable drawable, unsigned long mask)
788 {
789 struct _glxapi_table *t;
790 GET_DISPATCH(dpy, t);
791 if (!t)
792 return;
793 (t->SelectEventSGIX)(dpy, drawable, mask);
794 }
795
796 void glXGetSelectedEventSGIX(Display *dpy, GLXDrawable drawable, unsigned long *mask)
797 {
798 struct _glxapi_table *t;
799 GET_DISPATCH(dpy, t);
800 if (!t)
801 return;
802 (t->GetSelectedEventSGIX)(dpy, drawable, mask);
803 }
804
805 #endif
806
807
808 #ifdef GLX_SGI_cushion
809
810 void glXCushionSGI(Display *dpy, Window win, float cushion)
811 {
812 struct _glxapi_table *t;
813 GET_DISPATCH(dpy, t);
814 if (!t)
815 return;
816 (t->CushionSGI)(dpy, win, cushion);
817 }
818
819 #endif
820
821
822 #ifdef GLX_SGIX_video_resize
823
824 int glXBindChannelToWindowSGIX(Display *dpy, int screen, int channel , Window window)
825 {
826 struct _glxapi_table *t;
827 GET_DISPATCH(dpy, t);
828 if (!t)
829 return 0;
830 return (t->BindChannelToWindowSGIX)(dpy, screen, channel, window);
831 }
832
833 int glXChannelRectSGIX(Display *dpy, int screen, int channel, int x, int y, int w, int h)
834 {
835 struct _glxapi_table *t;
836 GET_DISPATCH(dpy, t);
837 if (!t)
838 return 0;
839 return (t->ChannelRectSGIX)(dpy, screen, channel, x, y, w, h);
840 }
841
842 int glXQueryChannelRectSGIX(Display *dpy, int screen, int channel, int *x, int *y, int *w, int *h)
843 {
844 struct _glxapi_table *t;
845 GET_DISPATCH(dpy, t);
846 if (!t)
847 return 0;
848 return (t->QueryChannelRectSGIX)(dpy, screen, channel, x, y, w, h);
849 }
850
851 int glXQueryChannelDeltasSGIX(Display *dpy, int screen, int channel, int *dx, int *dy, int *dw, int *dh)
852 {
853 struct _glxapi_table *t;
854 GET_DISPATCH(dpy, t);
855 if (!t)
856 return 0;
857 return (t->QueryChannelDeltasSGIX)(dpy, screen, channel, dx, dy, dw, dh);
858 }
859
860 int glXChannelRectSyncSGIX(Display *dpy, int screen, int channel, GLenum synctype)
861 {
862 struct _glxapi_table *t;
863 GET_DISPATCH(dpy, t);
864 if (!t)
865 return 0;
866 return (t->ChannelRectSyncSGIX)(dpy, screen, channel, synctype);
867 }
868
869 #endif
870
871
872 #if defined(_DM_BUFFER_H_) && defined(GLX_SGIX_dmbuffer)
873
874 Bool glXAssociateDMPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuffer, DMparams *params, DMbuffer dmbuffer)
875 {
876 struct _glxapi_table *t;
877 GET_DISPATCH(dpy, t);
878 if (!t)
879 return False;
880 return (t->AssociateDMPbufferSGIX)(dpy, pbuffer, params, dmbuffer);
881 }
882
883 #endif
884
885
886 #ifdef GLX_SGIX_swap_group
887
888 void glXJoinSwapGroupSGIX(Display *dpy, GLXDrawable drawable, GLXDrawable member)
889 {
890 struct _glxapi_table *t;
891 GET_DISPATCH(dpy, t);
892 if (!t)
893 return;
894 (*t->JoinSwapGroupSGIX)(dpy, drawable, member);
895 }
896
897 #endif
898
899
900 #ifdef GLX_SGIX_swap_barrier
901
902 void glXBindSwapBarrierSGIX(Display *dpy, GLXDrawable drawable, int barrier)
903 {
904 struct _glxapi_table *t;
905 GET_DISPATCH(dpy, t);
906 if (!t)
907 return;
908 (*t->BindSwapBarrierSGIX)(dpy, drawable, barrier);
909 }
910
911 Bool glXQueryMaxSwapBarriersSGIX(Display *dpy, int screen, int *max)
912 {
913 struct _glxapi_table *t;
914 GET_DISPATCH(dpy, t);
915 if (!t)
916 return False;
917 return (*t->QueryMaxSwapBarriersSGIX)(dpy, screen, max);
918 }
919
920 #endif
921
922
923 #ifdef GLX_SUN_get_transparent_index
924
925 Status glXGetTransparentIndexSUN(Display *dpy, Window overlay, Window underlay, long *pTransparent)
926 {
927 struct _glxapi_table *t;
928 GET_DISPATCH(dpy, t);
929 if (!t)
930 return False;
931 return (*t->GetTransparentIndexSUN)(dpy, overlay, underlay, pTransparent);
932 }
933
934 #endif
935
936
937 #ifdef GLX_MESA_copy_sub_buffer
938
939 void glXCopySubBufferMESA(Display *dpy, GLXDrawable drawable, int x, int y, int width, int height)
940 {
941 struct _glxapi_table *t;
942 GET_DISPATCH(dpy, t);
943 if (!t)
944 return;
945 (t->CopySubBufferMESA)(dpy, drawable, x, y, width, height);
946 }
947
948 #endif
949
950
951 #ifdef GLX_MESA_release_buffers
952
953 Bool glXReleaseBuffersMESA(Display *dpy, Window w)
954 {
955 struct _glxapi_table *t;
956 GET_DISPATCH(dpy, t);
957 if (!t)
958 return False;
959 return (t->ReleaseBuffersMESA)(dpy, w);
960 }
961
962 #endif
963
964
965 #ifdef GLX_MESA_pixmap_colormap
966
967 GLXPixmap glXCreateGLXPixmapMESA(Display *dpy, XVisualInfo *visinfo, Pixmap pixmap, Colormap cmap)
968 {
969 struct _glxapi_table *t;
970 GET_DISPATCH(dpy, t);
971 if (!t)
972 return 0;
973 return (t->CreateGLXPixmapMESA)(dpy, visinfo, pixmap, cmap);
974 }
975
976 #endif
977
978
979 #ifdef GLX_MESA_set_3dfx_mode
980
981 Bool glXSet3DfxModeMESA(int mode)
982 {
983 struct _glxapi_table *t;
984 GET_DISPATCH(CurrentDisplay, t);
985 if (!t)
986 return False;
987 return (t->Set3DfxModeMESA)(mode);
988 }
989
990 #endif
991
992
993
994 /**********************************************************************/
995 /* GLX API management functions */
996 /**********************************************************************/
997
998
999 const char *
1000 _glxapi_get_version(void)
1001 {
1002 return "1.3";
1003 }
1004
1005
1006 /*
1007 * Return array of extension strings.
1008 */
1009 const char **
1010 _glxapi_get_extensions(void)
1011 {
1012 static const char *extensions[] = {
1013 #ifdef GLX_EXT_import_context
1014 "GLX_EXT_import_context",
1015 #endif
1016 #ifdef GLX_SGI_video_sync
1017 "GLX_SGI_video_sync",
1018 #endif
1019 #ifdef GLX_MESA_copy_sub_buffer
1020 "GLX_MESA_copy_sub_buffer",
1021 #endif
1022 #ifdef GLX_MESA_release_buffers
1023 "GLX_MESA_release_buffers",
1024 #endif
1025 #ifdef GLX_MESA_pixmap_colormap
1026 "GLX_MESA_pixmap_colormap",
1027 #endif
1028 #ifdef GLX_MESA_set_3dfx_mode
1029 "GLX_MESA_set_3dfx_mode",
1030 #endif
1031 NULL
1032 };
1033 return extensions;
1034 }
1035
1036
1037 /*
1038 * Return size of the GLX dispatch table, in entries, not bytes.
1039 */
1040 GLuint
1041 _glxapi_get_dispatch_table_size(void)
1042 {
1043 return sizeof(struct _glxapi_table) / sizeof(void *);
1044 }
1045
1046
1047 static int
1048 generic_no_op_func(void)
1049 {
1050 return 0;
1051 }
1052
1053
1054 /*
1055 * Initialize all functions in given dispatch table to be no-ops
1056 */
1057 void
1058 _glxapi_set_no_op_table(struct _glxapi_table *t)
1059 {
1060 GLuint n = _glxapi_get_dispatch_table_size();
1061 GLuint i;
1062 void **dispatch = (void **) t;
1063 for (i = 0; i < n; i++) {
1064 dispatch[i] = (void *) generic_no_op_func;
1065 }
1066 }
1067
1068
1069 #if 00
1070 /*
1071 * Open the named library and use dlsym() to populate the given dispatch
1072 * table with GLX function pointers.
1073 * Return: true = all OK
1074 * false = can't open libName or can't get required GLX function
1075 */
1076 GLboolean
1077 _glxapi_load_library_table(const char *libName, struct _glxapi_table *t)
1078 {
1079 void *libHandle;
1080 void **entry; /* used to avoid a lot of cast/type warnings */
1081
1082 libHandle = dlopen(libName, 0);
1083 if (!libHandle) {
1084 return GL_FALSE;
1085 }
1086
1087 #define GET_REQ_FUNCTION(ENTRY, NAME) \
1088 entry = (void **) &(t->ENTRY); \
1089 *entry = dlsym(libHandle, NAME); \
1090 if (!*entry) { \
1091 fprintf(stderr, "libGL Error: couldn't load %s from %s\n", \
1092 NAME, libName); \
1093 dlclose(libHandle); \
1094 return GL_FALSE; \
1095 }
1096
1097 /* 1.0 and 1.1 functions */
1098 GET_REQ_FUNCTION(ChooseVisual, "glXChooseVisual");
1099 GET_REQ_FUNCTION(CopyContext, "glXCopyContext");
1100 GET_REQ_FUNCTION(CreateContext, "glXCreateContext");
1101 GET_REQ_FUNCTION(CreateGLXPixmap, "glXCreateGLXPixmap");
1102 GET_REQ_FUNCTION(DestroyContext, "glXDestroyContext");
1103 GET_REQ_FUNCTION(GetConfig, "glXGetConfig");
1104 GET_REQ_FUNCTION(IsDirect, "glXIsDirect");
1105 GET_REQ_FUNCTION(MakeCurrent, "glXMakeCurrent");
1106 GET_REQ_FUNCTION(QueryExtension, "glXQueryExtension");
1107 GET_REQ_FUNCTION(QueryVersion, "glXQueryVersion");
1108 GET_REQ_FUNCTION(SwapBuffers, "glXSwapBuffers");
1109 GET_REQ_FUNCTION(UseXFont, "glXUseXFont");
1110 GET_REQ_FUNCTION(WaitGL, "glXWaitGL");
1111 GET_REQ_FUNCTION(WaitX, "glXWaitX");
1112 GET_REQ_FUNCTION(GetClientString, "glXGetClientString");
1113 GET_REQ_FUNCTION(QueryExtensionsString, "glXQueryExtensionsString");
1114 GET_REQ_FUNCTION(QueryServerString, "glXQueryServerString");
1115
1116 #define GET_OPT_FUNCTION(ENTRY, NAME) \
1117 entry = (void **) &(t->ENTRY); \
1118 *entry = dlsym(libHandle, NAME); \
1119 if (!*entry) { \
1120 *entry = (void *) generic_no_op_func; \
1121 }
1122
1123 /* 1.2, 1.3 and extensions */
1124 GET_OPT_FUNCTION(ChooseFBConfig, "glXChooseFBConfig");
1125 GET_OPT_FUNCTION(CreateNewContext, "glXCreateNewContext");
1126 GET_OPT_FUNCTION(CreatePbuffer, "glXCreatePbuffer");
1127 GET_OPT_FUNCTION(CreatePixmap, "glXCreatePixmap");
1128 GET_OPT_FUNCTION(CreateWindow, "glXCreateWindow");
1129 GET_OPT_FUNCTION(DestroyPbuffer, "glXDestroyPbuffer");
1130 GET_OPT_FUNCTION(DestroyPixmap, "glXDestroyPixmap");
1131 GET_OPT_FUNCTION(DestroyWindow, "glXDestroyWindow");
1132 GET_OPT_FUNCTION(GetFBConfigAttrib, "glXGetFBConfigAttrib");
1133 GET_OPT_FUNCTION(GetFBConfigs, "glXGetFBConfigs");
1134 GET_OPT_FUNCTION(GetSelectedEvent, "glXGetSelectedEvent");
1135 GET_OPT_FUNCTION(GetVisualFromFBConfig, "glXGetVisualFromFBConfig");
1136 GET_OPT_FUNCTION(MakeContextCurrent, "glXMakeContextCurrent");
1137 GET_OPT_FUNCTION(QueryContext, "glXQueryContext");
1138 GET_OPT_FUNCTION(QueryDrawable, "glXQueryDrawable");
1139 GET_OPT_FUNCTION(SelectEvent, "glXSelectEvent");
1140 #ifdef GLX_SGI_swap_control
1141 GET_OPT_FUNCTION(SwapIntervalSGI, "glXSwapIntervalSGI");
1142 #endif
1143 #ifdef GLX_SGI_video_sync
1144 GET_OPT_FUNCTION(GetVideoSyncSGI, "glXGetVideoSyncSGI");
1145 GET_OPT_FUNCTION(WaitVideoSyncSGI, "glXWaitVideoSyncSGI");
1146 #endif
1147 #ifdef GLX_SGI_make_current_read
1148 GET_OPT_FUNCTION(MakeCurrentReadSGI, "glXMakeCurrentReadSGI");
1149 GET_OPT_FUNCTION(GetCurrentReadDrawableSGI, "glXGetCurrentReadDrawableSGI");
1150 #endif
1151 #if defined(_VL_H) && defined(GLX_SGIX_video_source)
1152 GET_OPT_FUNCTION(CreateGLXVideoSourceSGIX, "glXCreateGLXVideoSourceSGIX");
1153 GET_OPT_FUNCTION(DestroyGLXVideoSourceSGIX, "glXDestroyGLXVideoSourceSGIX");
1154 #endif
1155 #ifdef GLX_EXT_import_context
1156 GET_OPT_FUNCTION(FreeContextEXT, "glXFreeContextEXT");
1157 GET_OPT_FUNCTION(GetContextIDEXT, "glXGetContextIDEXT");
1158 GET_OPT_FUNCTION(GetCurrentDisplayEXT, "glXGetCurrentDisplayEXT");
1159 GET_OPT_FUNCTION(ImportContextEXT, "glXImportContextEXT");
1160 GET_OPT_FUNCTION(QueryContextInfoEXT, "glXQueryContextInfoEXT");
1161 #endif
1162 #ifdef GLX_SGIX_fbconfig
1163 GET_OPT_FUNCTION(GetFBConfigAttribSGIX, "glXGetFBConfigAttribSGIX");
1164 GET_OPT_FUNCTION(ChooseFBConfigSGIX, "glXChooseFBConfigSGIX");
1165 GET_OPT_FUNCTION(CreateGLXPixmapWithConfigSGIX, "glXCreateGLXPixmapWithConfigSGIX");
1166 GET_OPT_FUNCTION(CreateContextWithConfigSGIX, "glXCreateContextWithConfigSGIX");
1167 GET_OPT_FUNCTION(GetVisualFromFBConfigSGIX, "glXGetVisualFromFBConfigSGIX");
1168 GET_OPT_FUNCTION(GetFBConfigFromVisualSGIX, "glXGetFBConfigFromVisualSGIX");
1169 #endif
1170 #ifdef GLX_SGIX_pbuffer
1171 GET_OPT_FUNCTION(CreateGLXPbufferSGIX, "glXCreateGLXPbufferSGIX");
1172 GET_OPT_FUNCTION(DestroyGLXPbufferSGIX, "glXDestroyGLXPbufferSGIX");
1173 GET_OPT_FUNCTION(QueryGLXPbufferSGIX, "glXQueryGLXPbufferSGIX");
1174 GET_OPT_FUNCTION(SelectEventSGIX, "glXSelectEventSGIX");
1175 GET_OPT_FUNCTION(GetSelectedEventSGIX, "glXGetSelectedEventSGIX");
1176 #endif
1177 #ifdef GLX_SGI_cushion
1178 GET_OPT_FUNCTION(CushionSGI, "glXCushionSGI");
1179 #endif
1180 #ifdef GLX_SGIX_video_resize
1181 GET_OPT_FUNCTION(BindChannelToWindowSGIX, "glXBindChannelToWindowSGIX");
1182 GET_OPT_FUNCTION(ChannelRectSGIX, "glXChannelRectSGIX");
1183 GET_OPT_FUNCTION(QueryChannelRectSGIX, "glXQueryChannelRectSGIX");
1184 GET_OPT_FUNCTION(QueryChannelDeltasSGIX, "glXQueryChannelDeltasSGIX");
1185 GET_OPT_FUNCTION(ChannelRectSyncSGIX, "glXChannelRectSyncSGIX");
1186 #endif
1187 #if defined (_DM_BUFFER_H_) && defined(GLX_SGIX_dmbuffer)
1188 GET_OPT_FUNCTION(AssociateDMPbufferSGIX, "glXAssociateDMPbufferSGIX");
1189 #endif
1190 #ifdef GLX_SGIX_swap_group
1191 GET_OPT_FUNCTION(JoinSwapGroupSGIX, "glXJoinSwapGroupSGIX");
1192 #endif
1193 #ifdef GLX_SGIX_swap_barrier
1194 GET_OPT_FUNCTION(BindSwapBarrierSGIX, "glXBindSwapBarrierSGIX");
1195 GET_OPT_FUNCTION(QueryMaxSwapBarriersSGIX, "glXQueryMaxSwapBarriersSGIX");
1196 #endif
1197 #ifdef GLX_SUN_get_transparent_index
1198 GET_OPT_FUNCTION(GetTransparentIndexSUN, "glXGetTransparentIndexSUN");
1199 #endif
1200 #ifdef GLX_MESA_copy_sub_buffer
1201 GET_OPT_FUNCTION(CopySubBufferMESA, "glXCopySubBufferMESA");
1202 #endif
1203 #ifdef GLX_MESA_release_buffers
1204 GET_OPT_FUNCTION(ReleaseBuffersMESA, "glXReleaseBuffersMESA");
1205 #endif
1206 #ifdef GLX_MESA_pixmap_colormap
1207 GET_OPT_FUNCTION(CreateGLXPixmapMESA, "glXCreateGLXPixmapMESA");
1208 #endif
1209 #ifdef GLX_MESA_set_3dfx_mode
1210 GET_OPT_FUNCTION(Set3DfxModeMESA, "glXSet3DfxModeMESA");
1211 #endif
1212
1213 return GL_TRUE;
1214 }
1215 #endif
1216
1217
1218
1219 struct name_address_pair {
1220 const char *Name;
1221 GLvoid *Address;
1222 };
1223
1224 static struct name_address_pair GLX_functions[] = {
1225 { "glXChooseVisual", (GLvoid *) glXChooseVisual },
1226 { "glXCopyContext", (GLvoid *) glXCopyContext },
1227 { "glXCreateContext", (GLvoid *) glXCreateContext },
1228 { "glXCreateGLXPixmap", (GLvoid *) glXCreateGLXPixmap },
1229 { "glXDestroyContext", (GLvoid *) glXDestroyContext },
1230 { "glXDestroyGLXPixmap", (GLvoid *) glXDestroyGLXPixmap },
1231 { "glXGetConfig", (GLvoid *) glXGetConfig },
1232 { "glXGetCurrentContext", (GLvoid *) glXGetCurrentContext },
1233 { "glXGetCurrentDrawable", (GLvoid *) glXGetCurrentDrawable },
1234 { "glXIsDirect", (GLvoid *) glXIsDirect },
1235 { "glXMakeCurrent", (GLvoid *) glXMakeCurrent },
1236 { "glXQueryExtension", (GLvoid *) glXQueryExtension },
1237 { "glXQueryVersion", (GLvoid *) glXQueryVersion },
1238 { "glXSwapBuffers", (GLvoid *) glXSwapBuffers },
1239 { "glXUseXFont", (GLvoid *) glXUseXFont },
1240 { "glXWaitGL", (GLvoid *) glXWaitGL },
1241 { "glXWaitX", (GLvoid *) glXWaitX },
1242
1243 #ifdef GLX_VERSION_1_1
1244 { "glXGetClientString", (GLvoid *) glXGetClientString },
1245 { "glXQueryExtensionsString", (GLvoid *) glXQueryExtensionsString },
1246 { "glXQueryServerString", (GLvoid *) glXQueryServerString },
1247 #endif
1248
1249 #ifdef GLX_VERSION_1_2
1250 { "glXGetCurrentDisplay", (GLvoid *) glXGetCurrentDisplay },
1251 #endif
1252
1253 #ifdef GLX_VERSION_1_3
1254 { "glXChooseFBConfig", (GLvoid *) glXChooseFBConfig },
1255 { "glXCreateNewContext", (GLvoid *) glXCreateNewContext },
1256 { "glXCreatePbuffer", (GLvoid *) glXCreatePbuffer },
1257 { "glXCreatePixmap", (GLvoid *) glXCreatePixmap },
1258 { "glXCreateWindow", (GLvoid *) glXCreateWindow },
1259 { "glXDestroyPbuffer", (GLvoid *) glXDestroyPbuffer },
1260 { "glXDestroyPixmap", (GLvoid *) glXDestroyPixmap },
1261 { "glXDestroyWindow", (GLvoid *) glXDestroyWindow },
1262 { "glXGetCurrentReadDrawable", (GLvoid *) glXGetCurrentReadDrawable },
1263 { "glXGetFBConfigAttrib", (GLvoid *) glXGetFBConfigAttrib },
1264 { "glXGetSelectedEvent", (GLvoid *) glXGetSelectedEvent },
1265 { "glXGetVisualFromFBConfig", (GLvoid *) glXGetVisualFromFBConfig },
1266 { "glXMakeContextCurrent", (GLvoid *) glXMakeContextCurrent },
1267 { "glXQueryContext", (GLvoid *) glXQueryContext },
1268 { "glXQueryDrawable", (GLvoid *) glXQueryDrawable },
1269 { "glXSelectEvent", (GLvoid *) glXSelectEvent },
1270 #endif
1271
1272 #ifdef GLX_SGI_video_sync
1273 { "glXGetVideoSyncSGI", (GLvoid *) glXGetVideoSyncSGI },
1274 { "glXWaitVideoSyncSGI", (GLvoid *) glXWaitVideoSyncSGI },
1275 #endif
1276
1277 #ifdef GLX_MESA_copy_sub_buffer
1278 { "glXCopySubBufferMESA", (GLvoid *) glXCopySubBufferMESA },
1279 #endif
1280
1281 #ifdef GLX_MESA_release_buffers
1282 { "glXReleaseBuffersMESA", (GLvoid *) glXReleaseBuffersMESA },
1283 #endif
1284
1285 #ifdef GLX_MESA_pixmap_colormap
1286 { "glXCreateGLXPixmapMESA", (GLvoid *) glXCreateGLXPixmapMESA },
1287 #endif
1288
1289 #ifdef GLX_MESA_set_3dfx_mode
1290 { "glXSet3DfxModeMESA", (GLvoid *) glXSet3DfxModeMESA },
1291 #endif
1292
1293 { "glXGetProcAddressARB", (GLvoid *) glXGetProcAddressARB },
1294
1295 { NULL, NULL } /* end of list */
1296 };
1297
1298
1299
1300 /*
1301 * Return address of named glX function, or NULL if not found.
1302 */
1303 const GLvoid *
1304 _glxapi_get_proc_address(const char *funcName)
1305 {
1306 GLuint i;
1307 for (i = 0; GLX_functions[i].Name; i++) {
1308 if (strcmp(GLX_functions[i].Name, funcName) == 0)
1309 return GLX_functions[i].Address;
1310 }
1311 return NULL;
1312 }
1313
1314
1315
1316 /*
1317 * This function does not get dispatched through the dispatch table
1318 * since it's really a "meta" function.
1319 */
1320 void (*glXGetProcAddressARB(const GLubyte *procName))()
1321 {
1322 typedef void (*gl_function)();
1323 gl_function f;
1324
1325 f = (gl_function) _glxapi_get_proc_address((const char *) procName);
1326 if (f) {
1327 return f;
1328 }
1329
1330 f = (gl_function) _glapi_get_proc_address((const char *) procName);
1331 return f;
1332 }