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