glxapi.c revision 5605798e56ca6e9f968623f33b58ee7ca90594af
1/* $Id: glxapi.c,v 1.16 2000/04/10 21:13:19 brianp Exp $ */ 2 3/* 4 * Mesa 3-D graphics library 5 * Version: 3.3 6 * 7 * Copyright (C) 1999-2000 Brian Paul All Rights Reserved. 8 * 9 * Permission is hereby granted, free of charge, to any person obtaining a 10 * copy of this software and associated documentation files (the "Software"), 11 * to deal in the Software without restriction, including without limitation 12 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 13 * and/or sell copies of the Software, and to permit persons to whom the 14 * Software is furnished to do so, subject to the following conditions: 15 * 16 * The above copyright notice and this permission notice shall be included 17 * in all copies or substantial portions of the Software. 18 * 19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 22 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 23 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 24 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25 */ 26 27 28/* 29 * This is the GLX API dispatcher. Calls to the glX* functions are 30 * either routed to real (SGI / Utah) GLX encoders or to Mesa's 31 * pseudo-GLX module. 32 */ 33 34 35#include <assert.h> 36#include <stdlib.h> 37#include "glapi.h" 38#include "glxapi.h" 39 40 41/* 42 * XXX - this really shouldn't be here. 43 * Instead, add -DUSE_MESA_GLX to the compiler flags when needed. 44 */ 45#define USE_MESA_GLX 1 46 47 48/* Rather than include possibly non-existant headers... */ 49#ifdef USE_SGI_GLX 50extern struct _glxapi_table *_sgi_GetGLXDispatchtable(void); 51#endif 52#ifdef USE_UTAH_GLX 53extern struct _glxapi_table *_utah_GetGLXDispatchTable(void); 54#endif 55#ifdef USE_MESA_GLX 56extern struct _glxapi_table *_mesa_GetGLXDispatchTable(void); 57#endif 58 59 60 61struct display_dispatch { 62 Display *Dpy; 63 struct _glxapi_table *Table; 64 struct display_dispatch *Next; 65}; 66 67static struct display_dispatch *DispatchList = NULL; 68 69 70static struct _glxapi_table * 71get_dispatch(Display *dpy) 72{ 73 static Display *prevDisplay = NULL; 74 static struct _glxapi_table *prevTable = NULL; 75 76 if (!dpy) 77 return NULL; 78 79 /* try cached display */ 80 if (dpy == prevDisplay) { 81 return prevTable; 82 } 83 84 /* search list of display/dispatch pairs for this display */ 85 { 86 const struct display_dispatch *d = DispatchList; 87 while (d) { 88 if (d->Dpy == dpy) { 89 prevDisplay = dpy; 90 prevTable = d->Table; 91 return d->Table; /* done! */ 92 } 93 d = d->Next; 94 } 95 } 96 97 /* A new display, determine if we should use real GLX (SGI / Utah) 98 * or Mesa's pseudo-GLX. 99 */ 100 { 101 struct _glxapi_table *t = NULL; 102 103#if defined(USE_SGI_GLX) || defined(USE_UTAH_GLX) 104 if (!getenv("MESA_FORCE_SOFTX")) { 105 int ignore; 106 if (XQueryExtension( dpy, "GLX", &ignore, &ignore, &ignore )) { 107 /* the X server has the GLX extension */ 108#if defined(USE_SGI_GLX) 109 t = _sgi_GetGLXDispatchtable(); 110#elif defined(USE_UTAH_GLX) 111 t = _utah_GetGLXDispatchTable(); 112#endif 113 } 114 } 115#endif 116 117#if defined(USE_MESA_GLX) 118 if (!t) { 119 t = _mesa_GetGLXDispatchTable(); 120 assert(t); /* this has to work */ 121 } 122#endif 123 124 if (t) { 125 struct display_dispatch *d; 126 d = (struct display_dispatch *) malloc(sizeof(struct display_dispatch)); 127 if (d) { 128 d->Dpy = dpy; 129 d->Table = t; 130 /* insert at head of list */ 131 d->Next = DispatchList; 132 DispatchList = d; 133 /* update cache */ 134 prevDisplay = dpy; 135 prevTable = t; 136 return t; 137 } 138 } 139 } 140 141 /* If we get here that means we can't use real GLX on this display 142 * and the Mesa pseudo-GLX software renderer wasn't compiled in. 143 * Or, we ran out of memory! 144 */ 145 return NULL; 146} 147 148 149 150/* Set by glXMakeCurrent() and glXMakeContextCurrent() only */ 151static Display *CurrentDisplay = NULL; 152static GLXContext CurrentContext = 0; 153static GLXDrawable CurrentDrawable = 0; 154static GLXDrawable CurrentReadDrawable = 0; 155 156 157 158/* 159 * GLX API entrypoints 160 */ 161 162 163XVisualInfo *glXChooseVisual(Display *dpy, int screen, int *list) 164{ 165 struct _glxapi_table *t = get_dispatch(dpy); 166 if (!t) 167 return NULL; 168 return (t->ChooseVisual)(dpy, screen, list); 169} 170 171 172void glXCopyContext(Display *dpy, GLXContext src, GLXContext dst, unsigned long mask) 173{ 174 struct _glxapi_table *t = get_dispatch(dpy); 175 if (!t) 176 return; 177 (t->CopyContext)(dpy, src, dst, mask); 178} 179 180 181GLXContext glXCreateContext(Display *dpy, XVisualInfo *visinfo, GLXContext shareList, Bool direct) 182{ 183 struct _glxapi_table *t = get_dispatch(dpy); 184 if (!t) 185 return 0; 186 return (t->CreateContext)(dpy, visinfo, shareList, direct); 187} 188 189 190GLXPixmap glXCreateGLXPixmap(Display *dpy, XVisualInfo *visinfo, Pixmap pixmap) 191{ 192 struct _glxapi_table *t = get_dispatch(dpy); 193 if (!t) 194 return 0; 195 return (t->CreateGLXPixmap)(dpy, visinfo, pixmap); 196} 197 198 199void glXDestroyContext(Display *dpy, GLXContext ctx) 200{ 201 struct _glxapi_table *t = get_dispatch(dpy); 202 if (!t) 203 return; 204 (t->DestroyContext)(dpy, ctx); 205} 206 207 208void glXDestroyGLXPixmap(Display *dpy, GLXPixmap pixmap) 209{ 210 struct _glxapi_table *t = get_dispatch(dpy); 211 if (!t) 212 return; 213 (t->DestroyGLXPixmap)(dpy, pixmap); 214} 215 216 217int glXGetConfig(Display *dpy, XVisualInfo *visinfo, int attrib, int *value) 218{ 219 struct _glxapi_table *t = get_dispatch(dpy); 220 if (!t) 221 return GLX_NO_EXTENSION; 222 return (t->GetConfig)(dpy, visinfo, attrib, value); 223} 224 225 226GLXContext glXGetCurrentContext(void) 227{ 228 return CurrentContext; 229} 230 231 232GLXDrawable glXGetCurrentDrawable(void) 233{ 234 return CurrentDrawable; 235} 236 237 238Bool glXIsDirect(Display *dpy, GLXContext ctx) 239{ 240 struct _glxapi_table *t = get_dispatch(dpy); 241 if (!t) 242 return False; 243 return (t->IsDirect)(dpy, ctx); 244} 245 246 247Bool glXMakeCurrent(Display *dpy, GLXDrawable drawable, GLXContext ctx) 248{ 249 Bool b; 250 struct _glxapi_table *t = get_dispatch(dpy); 251 if (!t) 252 return False; 253 b = (*t->MakeCurrent)(dpy, drawable, ctx); 254 if (b) { 255 CurrentDisplay = dpy; 256 CurrentContext = ctx; 257 CurrentDrawable = drawable; 258 CurrentReadDrawable = drawable; 259 } 260 return b; 261} 262 263 264Bool glXQueryExtension(Display *dpy, int *errorb, int *event) 265{ 266 struct _glxapi_table *t = get_dispatch(dpy); 267 if (!t) 268 return False; 269 return (t->QueryExtension)(dpy, errorb, event); 270} 271 272 273Bool glXQueryVersion(Display *dpy, int *maj, int *min) 274{ 275 struct _glxapi_table *t = get_dispatch(dpy); 276 if (!t) 277 return False; 278 return (t->QueryVersion)(dpy, maj, min); 279} 280 281 282void glXSwapBuffers(Display *dpy, GLXDrawable drawable) 283{ 284 struct _glxapi_table *t = get_dispatch(dpy); 285 if (!t) 286 return; 287 (t->SwapBuffers)(dpy, drawable); 288} 289 290 291void glXUseXFont(Font font, int first, int count, int listBase) 292{ 293 struct _glxapi_table *t = get_dispatch(CurrentDisplay); 294 if (!t) 295 return; 296 (t->UseXFont)(font, first, count, listBase); 297} 298 299 300void glXWaitGL(void) 301{ 302 struct _glxapi_table *t = get_dispatch(CurrentDisplay); 303 if (!t) 304 return; 305 (t->WaitGL)(); 306} 307 308 309void glXWaitX(void) 310{ 311 struct _glxapi_table *t = get_dispatch(CurrentDisplay); 312 if (!t) 313 return; 314 (t->WaitX)(); 315} 316 317 318 319#ifdef _GLXAPI_VERSION_1_1 320 321const char *glXGetClientString(Display *dpy, int name) 322{ 323 struct _glxapi_table *t = get_dispatch(dpy); 324 if (!t) 325 return NULL; 326 return (t->GetClientString)(dpy, name); 327} 328 329 330const char *glXQueryExtensionsString(Display *dpy, int screen) 331{ 332 struct _glxapi_table *t = get_dispatch(dpy); 333 if (!t) 334 return NULL; 335 return (t->QueryExtensionsString)(dpy, screen); 336} 337 338 339const char *glXQueryServerString(Display *dpy, int screen, int name) 340{ 341 struct _glxapi_table *t = get_dispatch(dpy); 342 if (!t) 343 return NULL; 344 return (t->QueryServerString)(dpy, screen, name); 345} 346 347#endif 348 349 350 351#ifdef _GLXAPI_VERSION_1_2 352Display *glXGetCurrentDisplay(void) 353{ 354 return CurrentDisplay; 355} 356#endif 357 358 359 360#ifdef _GLXAPI_VERSION_1_3 361 362GLXFBConfig *glXChooseFBConfig(Display *dpy, int screen, const int *attribList, int *nitems) 363{ 364 struct _glxapi_table *t = get_dispatch(dpy); 365 if (!t) 366 return 0; 367 return (t->ChooseFBConfig)(dpy, screen, attribList, nitems); 368} 369 370 371GLXContext glXCreateNewContext(Display *dpy, GLXFBConfig config, int renderType, GLXContext shareList, Bool direct) 372{ 373 struct _glxapi_table *t = get_dispatch(dpy); 374 if (!t) 375 return 0; 376 return (t->CreateNewContext)(dpy, config, renderType, shareList, direct); 377} 378 379 380GLXPbuffer glXCreatePbuffer(Display *dpy, GLXFBConfig config, const int *attribList) 381{ 382 struct _glxapi_table *t = get_dispatch(dpy); 383 if (!t) 384 return 0; 385 return (t->CreatePbuffer)(dpy, config, attribList); 386} 387 388 389GLXPixmap glXCreatePixmap(Display *dpy, GLXFBConfig config, Pixmap pixmap, const int *attribList) 390{ 391 struct _glxapi_table *t = get_dispatch(dpy); 392 if (!t) 393 return 0; 394 return (t->CreatePixmap)(dpy, config, pixmap, attribList); 395} 396 397 398GLXWindow glXCreateWindow(Display *dpy, GLXFBConfig config, Window win, const int *attribList) 399{ 400 struct _glxapi_table *t = get_dispatch(dpy); 401 if (!t) 402 return 0; 403 return (t->CreateWindow)(dpy, config, win, attribList); 404} 405 406 407void glXDestroyPbuffer(Display *dpy, GLXPbuffer pbuf) 408{ 409 struct _glxapi_table *t = get_dispatch(dpy); 410 if (!t) 411 return; 412 (t->DestroyPbuffer)(dpy, pbuf); 413} 414 415 416void glXDestroyPixmap(Display *dpy, GLXPixmap pixmap) 417{ 418 struct _glxapi_table *t = get_dispatch(dpy); 419 if (!t) 420 return; 421 (t->DestroyPixmap)(dpy, pixmap); 422} 423 424 425void glXDestroyWindow(Display *dpy, GLXWindow window) 426{ 427 struct _glxapi_table *t = get_dispatch(dpy); 428 if (!t) 429 return; 430 (t->DestroyWindow)(dpy, window); 431} 432 433 434GLXDrawable glXGetCurrentReadDrawable(void) 435{ 436 return CurrentReadDrawable; 437} 438 439 440int glXGetFBConfigAttrib(Display *dpy, GLXFBConfig config, int attribute, int *value) 441{ 442 struct _glxapi_table *t = get_dispatch(dpy); 443 if (!t) 444 return GLX_NO_EXTENSION; 445 return (t->GetFBConfigAttrib)(dpy, config, attribute, value); 446} 447 448 449GLXFBConfig *glXGetFBConfigs(Display *dpy, int screen, int *nelements) 450{ 451 struct _glxapi_table *t = get_dispatch(dpy); 452 if (!t) 453 return 0; 454 return (t->GetFBConfigs)(dpy, screen, nelements); 455} 456 457void glXGetSelectedEvent(Display *dpy, GLXDrawable drawable, unsigned long *mask) 458{ 459 struct _glxapi_table *t = get_dispatch(dpy); 460 if (!t) 461 return; 462 (t->GetSelectedEvent)(dpy, drawable, mask); 463} 464 465 466XVisualInfo *glXGetVisualFromFBConfig(Display *dpy, GLXFBConfig config) 467{ 468 struct _glxapi_table *t = get_dispatch(dpy); 469 if (!t) 470 return NULL; 471 return (t->GetVisualFromFBConfig)(dpy, config); 472} 473 474 475Bool glXMakeContextCurrent(Display *dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx) 476{ 477 struct _glxapi_table *t = get_dispatch(dpy); 478 Bool b; 479 if (!t) 480 return False; 481 b = (t->MakeContextCurrent)(dpy, draw, read, ctx); 482 if (b) { 483 CurrentDisplay = dpy; 484 CurrentContext = ctx; 485 CurrentDrawable = draw; 486 CurrentReadDrawable = read; 487 } 488 return b; 489} 490 491 492int glXQueryContext(Display *dpy, GLXContext ctx, int attribute, int *value) 493{ 494 struct _glxapi_table *t = get_dispatch(dpy); 495 assert(t); 496 if (!t) 497 return 0; /* XXX correct? */ 498 return (t->QueryContext)(dpy, ctx, attribute, value); 499} 500 501 502void glXQueryDrawable(Display *dpy, GLXDrawable draw, int attribute, unsigned int *value) 503{ 504 struct _glxapi_table *t = get_dispatch(dpy); 505 if (!t) 506 return; 507 (t->QueryDrawable)(dpy, draw, attribute, value); 508} 509 510 511void glXSelectEvent(Display *dpy, GLXDrawable drawable, unsigned long mask) 512{ 513 struct _glxapi_table *t = get_dispatch(dpy); 514 if (!t) 515 return; 516 (t->SelectEvent)(dpy, drawable, mask); 517} 518 519#endif /* _GLXAPI_VERSION_1_3 */ 520 521 522#ifdef _GLXAPI_EXT_import_context 523 524void glXFreeContextEXT(Display *dpy, GLXContext context) 525{ 526 struct _glxapi_table *t = get_dispatch(dpy); 527 if (!t) 528 return; 529 (t->FreeContextEXT)(dpy, context); 530} 531 532 533GLXContextID glXGetContextIDEXT(const GLXContext context) 534{ 535 /* XXX is this function right? */ 536 struct _glxapi_table *t = get_dispatch(CurrentDisplay); 537 if (!t) 538 return 0; 539 return (t->GetContextIDEXT)(context); 540} 541 542 543Display *glXGetCurrentDisplayEXT(void) 544{ 545 return CurrentDisplay; 546} 547 548 549GLXContext glXImportContextEXT(Display *dpy, GLXContextID contextID) 550{ 551 struct _glxapi_table *t = get_dispatch(dpy); 552 if (!t) 553 return 0; 554 return (t->ImportContextEXT)(dpy, contextID); 555} 556 557int glXQueryContextInfoEXT(Display *dpy, GLXContext context, int attribute,int *value) 558{ 559 struct _glxapi_table *t = get_dispatch(dpy); 560 if (!t) 561 return 0; /* XXX ok? */ 562 return (t->QueryContextInfoEXT)(dpy, context, attribute, value); 563} 564 565#endif 566 567 568#ifdef _GLXAPI_SGI_video_sync 569 570int glXGetVideoSyncSGI(unsigned int *count) 571{ 572 struct _glxapi_table *t = get_dispatch(CurrentDisplay); 573 if (!t) 574 return 0; 575 return (t->GetVideoSyncSGI)(count); 576} 577 578 579int glXWaitVideoSyncSGI(int divisor, int remainder, unsigned int *count) 580{ 581 struct _glxapi_table *t = get_dispatch(CurrentDisplay); 582 if (!t) 583 return 0; 584 return (t->WaitVideoSyncSGI)(divisor, remainder, count); 585} 586 587#endif 588 589 590#ifdef _GLXAPI_MESA_copy_sub_buffer 591 592void glXCopySubBufferMESA(Display *dpy, GLXDrawable drawable, int x, int y, int width, int height) 593{ 594 struct _glxapi_table *t = get_dispatch(dpy); 595 if (!t) 596 return; 597 (t->CopySubBufferMESA)(dpy, drawable, x, y, width, height); 598} 599 600#endif 601 602 603#ifdef _GLXAPI_MESA_release_buffers 604 605Bool glXReleaseBuffersMESA(Display *dpy, Window w) 606{ 607 struct _glxapi_table *t = get_dispatch(dpy); 608 if (!t) 609 return False; 610 return (t->ReleaseBuffersMESA)(dpy, w); 611} 612 613#endif 614 615 616#ifdef _GLXAPI_MESA_pixmap_colormap 617 618GLXPixmap glXCreateGLXPixmapMESA(Display *dpy, XVisualInfo *visinfo, Pixmap pixmap, Colormap cmap) 619{ 620 struct _glxapi_table *t = get_dispatch(dpy); 621 if (!t) 622 return 0; 623 return (t->CreateGLXPixmapMESA)(dpy, visinfo, pixmap, cmap); 624} 625 626#endif 627 628 629#ifdef _GLXAPI_MESA_set_3dfx_mode 630 631GLboolean glXSet3DfxModeMESA(GLint mode) 632{ 633 struct _glxapi_table *t = get_dispatch(CurrentDisplay); 634 if (!t) 635 return False; 636 return (t->Set3DfxModeMESA)(mode); 637} 638 639#endif 640 641 642 643/**********************************************************************/ 644/* GLX API management functions */ 645/**********************************************************************/ 646 647 648const char * 649_glxapi_get_version(void) 650{ 651 return "1.3"; 652} 653 654 655/* 656 * Return array of extension strings. 657 */ 658const char ** 659_glxapi_get_extensions(void) 660{ 661 static const char *extensions[] = { 662#ifdef _GLXAPI_EXT_import_context 663 "GLX_EXT_import_context", 664#endif 665#ifdef _GLXAPI_SGI_video_sync 666 "GLX_SGI_video_sync", 667#endif 668#ifdef _GLXAPI_MESA_copy_sub_buffer 669 "GLX_MESA_copy_sub_buffer", 670#endif 671#ifdef _GLXAPI_MESA_release_buffers 672 "GLX_MESA_release_buffers", 673#endif 674#ifdef _GLXAPI_MESA_pixmap_colormap 675 "GLX_MESA_pixmap_colormap", 676#endif 677#ifdef _GLXAPI_MESA_set_3dfx_mode 678 "GLX_MESA_set_3dfx_mode", 679#endif 680 NULL 681 }; 682 return extensions; 683} 684 685 686/* 687 * Return size of the GLX dispatch table, in entries, not bytes. 688 */ 689GLuint 690_glxapi_get_dispatch_table_size(void) 691{ 692 return sizeof(struct _glxapi_table) / sizeof(void *); 693} 694 695 696static int 697generic_no_op_func(void) 698{ 699 return 0; 700} 701 702 703/* 704 * Initialize all functions in given dispatch table to be no-ops 705 */ 706void 707_glxapi_set_no_op_table(struct _glxapi_table *t) 708{ 709 GLuint n = _glxapi_get_dispatch_table_size(); 710 GLuint i; 711 void **dispatch = (void **) t; 712 for (i = 0; i < n; i++) { 713 dispatch[i] = (void *) generic_no_op_func; 714 } 715} 716 717 718 719struct name_address_pair { 720 const char *Name; 721 GLvoid *Address; 722}; 723 724static struct name_address_pair GLX_functions[] = { 725 { "glXChooseVisual", (GLvoid *) glXChooseVisual }, 726 { "glXCopyContext", (GLvoid *) glXCopyContext }, 727 { "glXCreateContext", (GLvoid *) glXCreateContext }, 728 { "glXCreateGLXPixmap", (GLvoid *) glXCreateGLXPixmap }, 729 { "glXDestroyContext", (GLvoid *) glXDestroyContext }, 730 { "glXDestroyGLXPixmap", (GLvoid *) glXDestroyGLXPixmap }, 731 { "glXGetConfig", (GLvoid *) glXGetConfig }, 732 { "glXGetCurrentContext", (GLvoid *) glXGetCurrentContext }, 733 { "glXGetCurrentDrawable", (GLvoid *) glXGetCurrentDrawable }, 734 { "glXIsDirect", (GLvoid *) glXIsDirect }, 735 { "glXMakeCurrent", (GLvoid *) glXMakeCurrent }, 736 { "glXQueryExtension", (GLvoid *) glXQueryExtension }, 737 { "glXQueryVersion", (GLvoid *) glXQueryVersion }, 738 { "glXSwapBuffers", (GLvoid *) glXSwapBuffers }, 739 { "glXUseXFont", (GLvoid *) glXUseXFont }, 740 { "glXWaitGL", (GLvoid *) glXWaitGL }, 741 { "glXWaitX", (GLvoid *) glXWaitX }, 742 743#ifdef _GLXAPI_VERSION_1_1 744 { "glXGetClientString", (GLvoid *) glXGetClientString }, 745 { "glXQueryExtensionsString", (GLvoid *) glXQueryExtensionsString }, 746 { "glXQueryServerString", (GLvoid *) glXQueryServerString }, 747#endif 748 749#ifdef _GLXAPI_VERSION_1_2 750 { "glXGetCurrentDisplay", (GLvoid *) glXGetCurrentDisplay }, 751#endif 752 753#ifdef _GLXAPI_VERSION_1_3 754 { "glXChooseFBConfig", (GLvoid *) glXChooseFBConfig }, 755 { "glXCreateNewContext", (GLvoid *) glXCreateNewContext }, 756 { "glXCreatePbuffer", (GLvoid *) glXCreatePbuffer }, 757 { "glXCreatePixmap", (GLvoid *) glXCreatePixmap }, 758 { "glXCreateWindow", (GLvoid *) glXCreateWindow }, 759 { "glXDestroyPbuffer", (GLvoid *) glXDestroyPbuffer }, 760 { "glXDestroyPixmap", (GLvoid *) glXDestroyPixmap }, 761 { "glXDestroyWindow", (GLvoid *) glXDestroyWindow }, 762 { "glXGetCurrentReadDrawable", (GLvoid *) glXGetCurrentReadDrawable }, 763 { "glXGetFBConfigAttrib", (GLvoid *) glXGetFBConfigAttrib }, 764 { "glXGetSelectedEvent", (GLvoid *) glXGetSelectedEvent }, 765 { "glXGetVisualFromFBConfig", (GLvoid *) glXGetVisualFromFBConfig }, 766 { "glXMakeContextCurrent", (GLvoid *) glXMakeContextCurrent }, 767 { "glXQueryContext", (GLvoid *) glXQueryContext }, 768 { "glXQueryDrawable", (GLvoid *) glXQueryDrawable }, 769 { "glXSelectEvent", (GLvoid *) glXSelectEvent }, 770#endif 771 772#ifdef _GLXAPI_SGI_video_sync 773 { "glXGetVideoSyncSGI", (GLvoid *) glXGetVideoSyncSGI }, 774 { "glXWaitVideoSyncSGI", (GLvoid *) glXWaitVideoSyncSGI }, 775#endif 776 777#ifdef _GLXAPI_MESA_copy_sub_buffer 778 { "glXCopySubBufferMESA", (GLvoid *) glXCopySubBufferMESA }, 779#endif 780 781#ifdef _GLXAPI_MESA_release_buffers 782 { "glXReleaseBuffersMESA", (GLvoid *) glXReleaseBuffersMESA }, 783#endif 784 785#ifdef _GLXAPI_MESA_pixmap_colormap 786 { "glXCreateGLXPixmapMESA", (GLvoid *) glXCreateGLXPixmapMESA }, 787#endif 788 789#ifdef _GLXAPI_MESA_set_3dfx_mode 790 { "glXSet3DfxModeMESA", (GLvoid *) glXSet3DfxModeMESA }, 791#endif 792 793 { "glXGetProcAddressARB", (GLvoid *) glXGetProcAddressARB }, 794 795 { NULL, NULL } /* end of list */ 796}; 797 798 799 800/* 801 * Return address of named glX function, or NULL if not found. 802 */ 803const GLvoid * 804_glxapi_get_proc_address(const char *funcName) 805{ 806 GLuint i; 807 for (i = 0; GLX_functions[i].Name; i++) { 808 if (strcmp(GLX_functions[i].Name, funcName) == 0) 809 return GLX_functions[i].Address; 810 } 811 return NULL; 812} 813 814 815 816/* 817 * This function does not get dispatched through the dispatch table 818 * since it's really a "meta" function. 819 */ 820void (*glXGetProcAddressARB(const GLubyte *procName))() 821{ 822 typedef void (*gl_function)(); 823 gl_function f; 824 825 f = (gl_function) _glxapi_get_proc_address((const char *) procName); 826 if (f) { 827 return f; 828 } 829 830 f = (gl_function) _glapi_get_proc_address((const char *) procName); 831 return f; 832} 833