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