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 43extern struct _glxapi_table *_mesa_GetGLXDispatchTable(void); 44 45 46struct 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 82static struct display_dispatch *DispatchList = NULL; 83 84 85/* Display -> Dispatch caching */ 86static Display *prevDisplay = NULL; 87static struct _glxapi_table *prevTable = NULL; 88 89 90static struct _glxapi_table * 91get_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 155XVisualInfo PUBLIC * 156glXChooseVisual(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 166void PUBLIC 167glXCopyContext(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 177GLXContext PUBLIC 178glXCreateContext(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 188GLXPixmap PUBLIC 189glXCreateGLXPixmap(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 199void PUBLIC 200glXDestroyContext(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 210void PUBLIC 211glXDestroyGLXPixmap(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 221int PUBLIC 222glXGetConfig(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 */ 233extern void *XMesaGetCurrentContext(void); 234 235GLXContext PUBLIC 236glXGetCurrentContext(void) 237{ 238 return (GLXContext) XMesaGetCurrentContext(); 239} 240 241 242GLXDrawable PUBLIC 243glXGetCurrentDrawable(void) 244{ 245 __GLXcontext *gc = (__GLXcontext *) glXGetCurrentContext(); 246 return gc ? gc->currentDrawable : 0; 247} 248 249 250Bool PUBLIC 251glXIsDirect(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 261Bool PUBLIC 262glXMakeCurrent(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 275Bool PUBLIC 276glXQueryExtension(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 286Bool PUBLIC 287glXQueryVersion(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 297void PUBLIC 298glXSwapBuffers(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 308void PUBLIC 309glXUseXFont(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 320void PUBLIC 321glXWaitGL(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 332void PUBLIC 333glXWaitX(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 347const char PUBLIC * 348glXGetClientString(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 358const char PUBLIC * 359glXQueryExtensionsString(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 369const char PUBLIC * 370glXQueryServerString(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 382Display PUBLIC * 383glXGetCurrentDisplay(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 395GLXFBConfig PUBLIC * 396glXChooseFBConfig(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 406GLXContext PUBLIC 407glXCreateNewContext(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 417GLXPbuffer PUBLIC 418glXCreatePbuffer(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 428GLXPixmap PUBLIC 429glXCreatePixmap(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 439GLXWindow PUBLIC 440glXCreateWindow(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 450void PUBLIC 451glXDestroyPbuffer(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 461void PUBLIC 462glXDestroyPixmap(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 472void PUBLIC 473glXDestroyWindow(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 483GLXDrawable PUBLIC 484glXGetCurrentReadDrawable(void) 485{ 486 __GLXcontext *gc = (__GLXcontext *) glXGetCurrentContext(); 487 return gc ? gc->currentReadable : 0; 488} 489 490 491int PUBLIC 492glXGetFBConfigAttrib(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 502GLXFBConfig PUBLIC * 503glXGetFBConfigs(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 512void PUBLIC 513glXGetSelectedEvent(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 523XVisualInfo PUBLIC * 524glXGetVisualFromFBConfig(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 534Bool PUBLIC 535glXMakeContextCurrent(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 547int PUBLIC 548glXQueryContext(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 559void PUBLIC 560glXQueryDrawable(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 570void PUBLIC 571glXSelectEvent(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 584int PUBLIC 585glXSwapIntervalSGI(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 599int PUBLIC 600glXGetVideoSyncSGI(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 610int PUBLIC 611glXWaitVideoSyncSGI(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 625Bool PUBLIC 626glXMakeCurrentReadSGI(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 635GLXDrawable PUBLIC 636glXGetCurrentReadDrawableSGI(void) 637{ 638 return glXGetCurrentReadDrawable(); 639} 640 641 642#if defined(_VL_H) 643 644GLXVideoSourceSGIX PUBLIC 645glXCreateGLXVideoSourceSGIX(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 654void PUBLIC 655glXDestroyGLXVideoSourceSGIX(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 669void PUBLIC 670glXFreeContextEXT(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 679GLXContextID PUBLIC 680glXGetContextIDEXT(const GLXContext context) 681{ 682 return ((__GLXcontext *) context)->xid; 683} 684 685Display PUBLIC * 686glXGetCurrentDisplayEXT(void) 687{ 688 return glXGetCurrentDisplay(); 689} 690 691GLXContext PUBLIC 692glXImportContextEXT(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 701int PUBLIC 702glXQueryContextInfoEXT(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 715int PUBLIC 716glXGetFBConfigAttribSGIX(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 725GLXFBConfigSGIX PUBLIC * 726glXChooseFBConfigSGIX(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 735GLXPixmap PUBLIC 736glXCreateGLXPixmapWithConfigSGIX(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 745GLXContext PUBLIC 746glXCreateContextWithConfigSGIX(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 755XVisualInfo PUBLIC * 756glXGetVisualFromFBConfigSGIX(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 765GLXFBConfigSGIX PUBLIC 766glXGetFBConfigFromVisualSGIX(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 779GLXPbufferSGIX PUBLIC 780glXCreateGLXPbufferSGIX(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 789void PUBLIC 790glXDestroyGLXPbufferSGIX(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 799int PUBLIC 800glXQueryGLXPbufferSGIX(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 809void PUBLIC 810glXSelectEventSGIX(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 819void PUBLIC 820glXGetSelectedEventSGIX(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 833void PUBLIC 834glXCushionSGI(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 847int PUBLIC 848glXBindChannelToWindowSGIX(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 857int PUBLIC 858glXChannelRectSGIX(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 867int PUBLIC 868glXQueryChannelRectSGIX(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 877int PUBLIC 878glXQueryChannelDeltasSGIX(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 887int PUBLIC 888glXChannelRectSyncSGIX(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 901Bool PUBLIC 902glXAssociateDMPbufferSGIX(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 916void PUBLIC 917glXJoinSwapGroupSGIX(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 929void PUBLIC 930glXBindSwapBarrierSGIX(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 939Bool PUBLIC 940glXQueryMaxSwapBarriersSGIX(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 953Status PUBLIC 954glXGetTransparentIndexSUN(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 967void PUBLIC 968glXCopySubBufferMESA(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 981Bool PUBLIC 982glXReleaseBuffersMESA(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 995GLXPixmap PUBLIC 996glXCreateGLXPixmapMESA(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 1009Bool PUBLIC 1010glXSet3DfxModeMESA(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 1024void PUBLIC * 1025glXAllocateMemoryNV( 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 1039void PUBLIC 1040glXFreeMemoryNV( 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 1055GLuint PUBLIC 1056glXGetAGPOffsetMESA( 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 1069void PUBLIC 1070glXBindTexImageEXT(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 1079void PUBLIC 1080glXReleaseTexImageEXT(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 1094const char * 1095_glxapi_get_version(void) 1096{ 1097 return "1.3"; 1098} 1099 1100 1101/* 1102 * Return array of extension strings. 1103 */ 1104const 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 */ 1147GLuint 1148_glxapi_get_dispatch_table_size(void) 1149{ 1150 return sizeof(struct _glxapi_table) / sizeof(void *); 1151} 1152 1153 1154static int 1155generic_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 */ 1164void 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 1177struct name_address_pair { 1178 const char *Name; 1179 __GLXextFuncPtr Address; 1180}; 1181 1182static 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 1356glXGetProcAddressARB(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 */ 1371void PUBLIC 1372(*glXGetProcAddress(const GLubyte *procName))() 1373{ 1374 return glXGetProcAddressARB(procName); 1375} 1376 1377 1378/** 1379 * Added in GLX_ARB_create_context. 1380 */ 1381GLXContext PUBLIC 1382glXCreateContextAttribsARB(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