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