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