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