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