1#include <stdlib.h> 2 3#include "glxclient.h" 4#include "glxglvnd.h" 5#include "glxglvnddispatchfuncs.h" 6#include "g_glxglvnddispatchindices.h" 7 8const int DI_FUNCTION_COUNT = DI_LAST_INDEX; 9/* Allocate an extra 'dummy' to ease lookup. See FindGLXFunction() */ 10int __glXDispatchTableIndices[DI_LAST_INDEX + 1]; 11const __GLXapiExports *__glXGLVNDAPIExports; 12 13const char * const __glXDispatchTableStrings[DI_LAST_INDEX] = { 14#define __ATTRIB(field) \ 15 [DI_##field] = "glX"#field 16 17 __ATTRIB(BindSwapBarrierSGIX), 18 __ATTRIB(BindTexImageEXT), 19 // glXChooseFBConfig implemented by libglvnd 20 __ATTRIB(ChooseFBConfigSGIX), 21 // glXChooseVisual implemented by libglvnd 22 // glXCopyContext implemented by libglvnd 23 __ATTRIB(CopySubBufferMESA), 24 // glXCreateContext implemented by libglvnd 25 __ATTRIB(CreateContextAttribsARB), 26 __ATTRIB(CreateContextWithConfigSGIX), 27 __ATTRIB(CreateGLXPbufferSGIX), 28 // glXCreateGLXPixmap implemented by libglvnd 29 __ATTRIB(CreateGLXPixmapMESA), 30 __ATTRIB(CreateGLXPixmapWithConfigSGIX), 31 // glXCreateNewContext implemented by libglvnd 32 // glXCreatePbuffer implemented by libglvnd 33 // glXCreatePixmap implemented by libglvnd 34 // glXCreateWindow implemented by libglvnd 35 // glXDestroyContext implemented by libglvnd 36 __ATTRIB(DestroyGLXPbufferSGIX), 37 // glXDestroyGLXPixmap implemented by libglvnd 38 // glXDestroyPbuffer implemented by libglvnd 39 // glXDestroyPixmap implemented by libglvnd 40 // glXDestroyWindow implemented by libglvnd 41 // glXFreeContextEXT implemented by libglvnd 42 // glXGetClientString implemented by libglvnd 43 // glXGetConfig implemented by libglvnd 44 __ATTRIB(GetContextIDEXT), 45 // glXGetCurrentContext implemented by libglvnd 46 // glXGetCurrentDisplay implemented by libglvnd 47 __ATTRIB(GetCurrentDisplayEXT), 48 // glXGetCurrentDrawable implemented by libglvnd 49 // glXGetCurrentReadDrawable implemented by libglvnd 50 __ATTRIB(GetDriverConfig), 51 // glXGetFBConfigAttrib implemented by libglvnd 52 __ATTRIB(GetFBConfigAttribSGIX), 53 __ATTRIB(GetFBConfigFromVisualSGIX), 54 // glXGetFBConfigs implemented by libglvnd 55 __ATTRIB(GetMscRateOML), 56 // glXGetProcAddress implemented by libglvnd 57 // glXGetProcAddressARB implemented by libglvnd 58 __ATTRIB(GetScreenDriver), 59 // glXGetSelectedEvent implemented by libglvnd 60 __ATTRIB(GetSelectedEventSGIX), 61 __ATTRIB(GetSwapIntervalMESA), 62 __ATTRIB(GetSyncValuesOML), 63 __ATTRIB(GetVideoSyncSGI), 64 // glXGetVisualFromFBConfig implemented by libglvnd 65 __ATTRIB(GetVisualFromFBConfigSGIX), 66 // glXImportContextEXT implemented by libglvnd 67 // glXIsDirect implemented by libglvnd 68 __ATTRIB(JoinSwapGroupSGIX), 69 // glXMakeContextCurrent implemented by libglvnd 70 // glXMakeCurrent implemented by libglvnd 71 // glXQueryContext implemented by libglvnd 72 __ATTRIB(QueryContextInfoEXT), 73 __ATTRIB(QueryCurrentRendererIntegerMESA), 74 __ATTRIB(QueryCurrentRendererStringMESA), 75 // glXQueryDrawable implemented by libglvnd 76 // glXQueryExtension implemented by libglvnd 77 // glXQueryExtensionsString implemented by libglvnd 78 __ATTRIB(QueryGLXPbufferSGIX), 79 __ATTRIB(QueryMaxSwapBarriersSGIX), 80 __ATTRIB(QueryRendererIntegerMESA), 81 __ATTRIB(QueryRendererStringMESA), 82 // glXQueryServerString implemented by libglvnd 83 // glXQueryVersion implemented by libglvnd 84 __ATTRIB(ReleaseBuffersMESA), 85 __ATTRIB(ReleaseTexImageEXT), 86 // glXSelectEvent implemented by libglvnd 87 __ATTRIB(SelectEventSGIX), 88 // glXSwapBuffers implemented by libglvnd 89 __ATTRIB(SwapBuffersMscOML), 90 __ATTRIB(SwapIntervalEXT), 91 __ATTRIB(SwapIntervalMESA), 92 __ATTRIB(SwapIntervalSGI), 93 // glXUseXFont implemented by libglvnd 94 __ATTRIB(WaitForMscOML), 95 __ATTRIB(WaitForSbcOML), 96 // glXWaitGL implemented by libglvnd 97 __ATTRIB(WaitVideoSyncSGI), 98 // glXWaitX implemented by libglvnd 99 100#undef __ATTRIB 101}; 102 103#define __FETCH_FUNCTION_PTR(func_name) \ 104 p##func_name = (void *) \ 105 __VND->fetchDispatchEntry(dd, __glXDispatchTableIndices[DI_##func_name]) 106 107 108static void dispatch_BindTexImageEXT(Display *dpy, GLXDrawable drawable, 109 int buffer, const int *attrib_list) 110{ 111 PFNGLXBINDTEXIMAGEEXTPROC pBindTexImageEXT; 112 __GLXvendorInfo *dd; 113 114 dd = GetDispatchFromDrawable(dpy, drawable); 115 if (dd == NULL) 116 return; 117 118 __FETCH_FUNCTION_PTR(BindTexImageEXT); 119 if (pBindTexImageEXT == NULL) 120 return; 121 122 pBindTexImageEXT(dpy, drawable, buffer, attrib_list); 123} 124 125 126 127static GLXFBConfigSGIX *dispatch_ChooseFBConfigSGIX(Display *dpy, int screen, 128 int *attrib_list, 129 int *nelements) 130{ 131 PFNGLXCHOOSEFBCONFIGSGIXPROC pChooseFBConfigSGIX; 132 __GLXvendorInfo *dd; 133 GLXFBConfigSGIX *ret; 134 135 dd = __VND->getDynDispatch(dpy, screen); 136 if (dd == NULL) 137 return NULL; 138 139 __FETCH_FUNCTION_PTR(ChooseFBConfigSGIX); 140 if (pChooseFBConfigSGIX == NULL) 141 return NULL; 142 143 ret = pChooseFBConfigSGIX(dpy, screen, attrib_list, nelements); 144 if (AddFBConfigsMapping(dpy, ret, nelements, dd)) { 145 free(ret); 146 return NULL; 147 } 148 149 return ret; 150} 151 152 153 154static GLXContext dispatch_CreateContextAttribsARB(Display *dpy, 155 GLXFBConfig config, 156 GLXContext share_list, 157 Bool direct, 158 const int *attrib_list) 159{ 160 PFNGLXCREATECONTEXTATTRIBSARBPROC pCreateContextAttribsARB; 161 __GLXvendorInfo *dd = NULL; 162 GLXContext ret; 163 164 if (config) { 165 dd = GetDispatchFromFBConfig(dpy, config); 166 } else if (attrib_list) { 167 int i, screen; 168 169 for (i = 0; attrib_list[i * 2] != None; i++) { 170 if (attrib_list[i * 2] == GLX_SCREEN) { 171 screen = attrib_list[i * 2 + 1]; 172 dd = GetDispatchFromDrawable(dpy, RootWindow(dpy, screen)); 173 break; 174 } 175 } 176 } 177 if (dd == NULL) 178 return None; 179 180 __FETCH_FUNCTION_PTR(CreateContextAttribsARB); 181 if (pCreateContextAttribsARB == NULL) 182 return None; 183 184 ret = pCreateContextAttribsARB(dpy, config, share_list, direct, attrib_list); 185 if (AddContextMapping(dpy, ret, dd)) { 186 /* XXX: Call glXDestroyContext which lives in libglvnd. If we're not 187 * allowed to call it from here, should we extend __glXDispatchTableIndices ? 188 */ 189 return None; 190 } 191 192 return ret; 193} 194 195 196 197static GLXContext dispatch_CreateContextWithConfigSGIX(Display *dpy, 198 GLXFBConfigSGIX config, 199 int render_type, 200 GLXContext share_list, 201 Bool direct) 202{ 203 PFNGLXCREATECONTEXTWITHCONFIGSGIXPROC pCreateContextWithConfigSGIX; 204 __GLXvendorInfo *dd; 205 GLXContext ret; 206 207 dd = GetDispatchFromFBConfig(dpy, config); 208 if (dd == NULL) 209 return None; 210 211 __FETCH_FUNCTION_PTR(CreateContextWithConfigSGIX); 212 if (pCreateContextWithConfigSGIX == NULL) 213 return None; 214 215 ret = pCreateContextWithConfigSGIX(dpy, config, render_type, share_list, direct); 216 if (AddContextMapping(dpy, ret, dd)) { 217 /* XXX: Call glXDestroyContext which lives in libglvnd. If we're not 218 * allowed to call it from here, should we extend __glXDispatchTableIndices ? 219 */ 220 return None; 221 } 222 223 return ret; 224} 225 226 227 228static GLXPbuffer dispatch_CreateGLXPbufferSGIX(Display *dpy, 229 GLXFBConfig config, 230 unsigned int width, 231 unsigned int height, 232 int *attrib_list) 233{ 234 PFNGLXCREATEGLXPBUFFERSGIXPROC pCreateGLXPbufferSGIX; 235 __GLXvendorInfo *dd; 236 GLXPbuffer ret; 237 238 dd = GetDispatchFromFBConfig(dpy, config); 239 if (dd == NULL) 240 return None; 241 242 __FETCH_FUNCTION_PTR(CreateGLXPbufferSGIX); 243 if (pCreateGLXPbufferSGIX == NULL) 244 return None; 245 246 ret = pCreateGLXPbufferSGIX(dpy, config, width, height, attrib_list); 247 if (AddDrawableMapping(dpy, ret, dd)) { 248 PFNGLXDESTROYGLXPBUFFERSGIXPROC pDestroyGLXPbufferSGIX; 249 250 __FETCH_FUNCTION_PTR(DestroyGLXPbufferSGIX); 251 if (pDestroyGLXPbufferSGIX) 252 pDestroyGLXPbufferSGIX(dpy, ret); 253 254 return None; 255 } 256 257 return ret; 258} 259 260 261 262static GLXPixmap dispatch_CreateGLXPixmapWithConfigSGIX(Display *dpy, 263 GLXFBConfigSGIX config, 264 Pixmap pixmap) 265{ 266 PFNGLXCREATEGLXPIXMAPWITHCONFIGSGIXPROC pCreateGLXPixmapWithConfigSGIX; 267 __GLXvendorInfo *dd; 268 GLXPixmap ret; 269 270 dd = GetDispatchFromFBConfig(dpy, config); 271 if (dd == NULL) 272 return None; 273 274 __FETCH_FUNCTION_PTR(CreateGLXPixmapWithConfigSGIX); 275 if (pCreateGLXPixmapWithConfigSGIX == NULL) 276 return None; 277 278 ret = pCreateGLXPixmapWithConfigSGIX(dpy, config, pixmap); 279 if (AddDrawableMapping(dpy, ret, dd)) { 280 /* XXX: Call glXDestroyGLXPixmap which lives in libglvnd. If we're not 281 * allowed to call it from here, should we extend __glXDispatchTableIndices ? 282 */ 283 return None; 284 } 285 286 return ret; 287} 288 289 290 291static void dispatch_DestroyGLXPbufferSGIX(Display *dpy, GLXPbuffer pbuf) 292{ 293 PFNGLXDESTROYGLXPBUFFERSGIXPROC pDestroyGLXPbufferSGIX; 294 __GLXvendorInfo *dd; 295 296 dd = GetDispatchFromDrawable(dpy, pbuf); 297 if (dd == NULL) 298 return; 299 300 __FETCH_FUNCTION_PTR(DestroyGLXPbufferSGIX); 301 if (pDestroyGLXPbufferSGIX == NULL) 302 return; 303 304 pDestroyGLXPbufferSGIX(dpy, pbuf); 305} 306 307 308 309static GLXContextID dispatch_GetContextIDEXT(const GLXContext ctx) 310{ 311 PFNGLXGETCONTEXTIDEXTPROC pGetContextIDEXT; 312 __GLXvendorInfo *dd; 313 314 dd = GetDispatchFromContext(ctx); 315 if (dd == NULL) 316 return None; 317 318 __FETCH_FUNCTION_PTR(GetContextIDEXT); 319 if (pGetContextIDEXT == NULL) 320 return None; 321 322 return pGetContextIDEXT(ctx); 323} 324 325 326 327static Display *dispatch_GetCurrentDisplayEXT(void) 328{ 329 PFNGLXGETCURRENTDISPLAYEXTPROC pGetCurrentDisplayEXT; 330 __GLXvendorInfo *dd; 331 332 if (!__VND->getCurrentContext()) 333 return NULL; 334 335 dd = __VND->getCurrentDynDispatch(); 336 if (dd == NULL) 337 return NULL; 338 339 __FETCH_FUNCTION_PTR(GetCurrentDisplayEXT); 340 if (pGetCurrentDisplayEXT == NULL) 341 return NULL; 342 343 return pGetCurrentDisplayEXT(); 344} 345 346 347 348static const char *dispatch_GetDriverConfig(const char *driverName) 349{ 350#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL) 351 /* 352 * The options are constant for a given driverName, so we do not need 353 * a context (and apps expect to be able to call this without one). 354 */ 355 return glXGetDriverConfig(driverName); 356#else 357 return NULL; 358#endif 359} 360 361 362 363static int dispatch_GetFBConfigAttribSGIX(Display *dpy, GLXFBConfigSGIX config, 364 int attribute, int *value_return) 365{ 366 PFNGLXGETFBCONFIGATTRIBSGIXPROC pGetFBConfigAttribSGIX; 367 __GLXvendorInfo *dd; 368 369 dd = GetDispatchFromFBConfig(dpy, config); 370 if (dd == NULL) 371 return GLX_NO_EXTENSION; 372 373 __FETCH_FUNCTION_PTR(GetFBConfigAttribSGIX); 374 if (pGetFBConfigAttribSGIX == NULL) 375 return GLX_NO_EXTENSION; 376 377 return pGetFBConfigAttribSGIX(dpy, config, attribute, value_return); 378} 379 380 381 382static GLXFBConfigSGIX dispatch_GetFBConfigFromVisualSGIX(Display *dpy, 383 XVisualInfo *vis) 384{ 385 PFNGLXGETFBCONFIGFROMVISUALSGIXPROC pGetFBConfigFromVisualSGIX; 386 __GLXvendorInfo *dd; 387 GLXFBConfigSGIX ret = NULL; 388 389 dd = GetDispatchFromVisual(dpy, vis); 390 if (dd == NULL) 391 return NULL; 392 393 __FETCH_FUNCTION_PTR(GetFBConfigFromVisualSGIX); 394 if (pGetFBConfigFromVisualSGIX == NULL) 395 return NULL; 396 397 ret = pGetFBConfigFromVisualSGIX(dpy, vis); 398 if (AddFBConfigMapping(dpy, ret, dd)) 399 /* XXX: dealloc ret ? */ 400 return NULL; 401 402 return ret; 403} 404 405 406 407static void dispatch_GetSelectedEventSGIX(Display *dpy, GLXDrawable drawable, 408 unsigned long *mask) 409{ 410 PFNGLXGETSELECTEDEVENTSGIXPROC pGetSelectedEventSGIX; 411 __GLXvendorInfo *dd; 412 413 dd = GetDispatchFromDrawable(dpy, drawable); 414 if (dd == NULL) 415 return; 416 417 __FETCH_FUNCTION_PTR(GetSelectedEventSGIX); 418 if (pGetSelectedEventSGIX == NULL) 419 return; 420 421 pGetSelectedEventSGIX(dpy, drawable, mask); 422} 423 424 425 426static int dispatch_GetVideoSyncSGI(unsigned int *count) 427{ 428 PFNGLXGETVIDEOSYNCSGIPROC pGetVideoSyncSGI; 429 __GLXvendorInfo *dd; 430 431 if (!__VND->getCurrentContext()) 432 return GLX_BAD_CONTEXT; 433 434 dd = __VND->getCurrentDynDispatch(); 435 if (dd == NULL) 436 return GLX_NO_EXTENSION; 437 438 __FETCH_FUNCTION_PTR(GetVideoSyncSGI); 439 if (pGetVideoSyncSGI == NULL) 440 return GLX_NO_EXTENSION; 441 442 return pGetVideoSyncSGI(count); 443} 444 445 446 447static XVisualInfo *dispatch_GetVisualFromFBConfigSGIX(Display *dpy, 448 GLXFBConfigSGIX config) 449{ 450 PFNGLXGETVISUALFROMFBCONFIGSGIXPROC pGetVisualFromFBConfigSGIX; 451 __GLXvendorInfo *dd; 452 453 dd = GetDispatchFromFBConfig(dpy, config); 454 if (dd == NULL) 455 return NULL; 456 457 __FETCH_FUNCTION_PTR(GetVisualFromFBConfigSGIX); 458 if (pGetVisualFromFBConfigSGIX == NULL) 459 return NULL; 460 461 return pGetVisualFromFBConfigSGIX(dpy, config); 462} 463 464 465 466static int dispatch_QueryContextInfoEXT(Display *dpy, GLXContext ctx, 467 int attribute, int *value) 468{ 469 PFNGLXQUERYCONTEXTINFOEXTPROC pQueryContextInfoEXT; 470 __GLXvendorInfo *dd; 471 472 dd = GetDispatchFromContext(ctx); 473 if (dd == NULL) 474 return GLX_NO_EXTENSION; 475 476 __FETCH_FUNCTION_PTR(QueryContextInfoEXT); 477 if (pQueryContextInfoEXT == NULL) 478 return GLX_NO_EXTENSION; 479 480 return pQueryContextInfoEXT(dpy, ctx, attribute, value); 481} 482 483 484 485static void dispatch_QueryGLXPbufferSGIX(Display *dpy, GLXPbuffer pbuf, 486 int attribute, unsigned int *value) 487{ 488 PFNGLXQUERYGLXPBUFFERSGIXPROC pQueryGLXPbufferSGIX; 489 __GLXvendorInfo *dd; 490 491 dd = GetDispatchFromDrawable(dpy, pbuf); 492 if (dd == NULL) 493 return; 494 495 __FETCH_FUNCTION_PTR(QueryGLXPbufferSGIX); 496 if (pQueryGLXPbufferSGIX == NULL) 497 return; 498 499 pQueryGLXPbufferSGIX(dpy, pbuf, attribute, value); 500} 501 502 503 504static void dispatch_ReleaseTexImageEXT(Display *dpy, GLXDrawable drawable, 505 int buffer) 506{ 507 PFNGLXRELEASETEXIMAGEEXTPROC pReleaseTexImageEXT; 508 __GLXvendorInfo *dd; 509 510 dd = GetDispatchFromDrawable(dpy, drawable); 511 if (dd == NULL) 512 return; 513 514 __FETCH_FUNCTION_PTR(ReleaseTexImageEXT); 515 if (pReleaseTexImageEXT == NULL) 516 return; 517 518 pReleaseTexImageEXT(dpy, drawable, buffer); 519} 520 521 522 523static void dispatch_SelectEventSGIX(Display *dpy, GLXDrawable drawable, 524 unsigned long mask) 525{ 526 PFNGLXSELECTEVENTSGIXPROC pSelectEventSGIX; 527 __GLXvendorInfo *dd; 528 529 dd = GetDispatchFromDrawable(dpy, drawable); 530 if (dd == NULL) 531 return; 532 533 __FETCH_FUNCTION_PTR(SelectEventSGIX); 534 if (pSelectEventSGIX == NULL) 535 return; 536 537 pSelectEventSGIX(dpy, drawable, mask); 538} 539 540 541 542static int dispatch_SwapIntervalSGI(int interval) 543{ 544 PFNGLXSWAPINTERVALSGIPROC pSwapIntervalSGI; 545 __GLXvendorInfo *dd; 546 547 if (!__VND->getCurrentContext()) 548 return GLX_BAD_CONTEXT; 549 550 dd = __VND->getCurrentDynDispatch(); 551 if (dd == NULL) 552 return GLX_NO_EXTENSION; 553 554 __FETCH_FUNCTION_PTR(SwapIntervalSGI); 555 if (pSwapIntervalSGI == NULL) 556 return GLX_NO_EXTENSION; 557 558 return pSwapIntervalSGI(interval); 559} 560 561 562 563static int dispatch_WaitVideoSyncSGI(int divisor, int remainder, 564 unsigned int *count) 565{ 566 PFNGLXWAITVIDEOSYNCSGIPROC pWaitVideoSyncSGI; 567 __GLXvendorInfo *dd; 568 569 if (!__VND->getCurrentContext()) 570 return GLX_BAD_CONTEXT; 571 572 dd = __VND->getCurrentDynDispatch(); 573 if (dd == NULL) 574 return GLX_NO_EXTENSION; 575 576 __FETCH_FUNCTION_PTR(WaitVideoSyncSGI); 577 if (pWaitVideoSyncSGI == NULL) 578 return GLX_NO_EXTENSION; 579 580 return pWaitVideoSyncSGI(divisor, remainder, count); 581} 582 583 584 585static void dispatch_BindSwapBarrierSGIX(Display *dpy, GLXDrawable drawable, 586 int barrier) 587{ 588 PFNGLXBINDSWAPBARRIERSGIXPROC pBindSwapBarrierSGIX; 589 __GLXvendorInfo *dd; 590 591 dd = GetDispatchFromDrawable(dpy, drawable); 592 if (dd == NULL) 593 return; 594 595 __FETCH_FUNCTION_PTR(BindSwapBarrierSGIX); 596 if (pBindSwapBarrierSGIX == NULL) 597 return; 598 599 pBindSwapBarrierSGIX(dpy, drawable, barrier); 600} 601 602 603 604static void dispatch_CopySubBufferMESA(Display *dpy, GLXDrawable drawable, 605 int x, int y, int width, int height) 606{ 607 PFNGLXCOPYSUBBUFFERMESAPROC pCopySubBufferMESA; 608 __GLXvendorInfo *dd; 609 610 dd = GetDispatchFromDrawable(dpy, drawable); 611 if (dd == NULL) 612 return; 613 614 __FETCH_FUNCTION_PTR(CopySubBufferMESA); 615 if (pCopySubBufferMESA == NULL) 616 return; 617 618 pCopySubBufferMESA(dpy, drawable, x, y, width, height); 619} 620 621 622 623static GLXPixmap dispatch_CreateGLXPixmapMESA(Display *dpy, 624 XVisualInfo *visinfo, 625 Pixmap pixmap, Colormap cmap) 626{ 627 PFNGLXCREATEGLXPIXMAPMESAPROC pCreateGLXPixmapMESA; 628 __GLXvendorInfo *dd; 629 GLXPixmap ret; 630 631 dd = GetDispatchFromVisual(dpy, visinfo); 632 if (dd == NULL) 633 return None; 634 635 __FETCH_FUNCTION_PTR(CreateGLXPixmapMESA); 636 if (pCreateGLXPixmapMESA == NULL) 637 return None; 638 639 ret = pCreateGLXPixmapMESA(dpy, visinfo, pixmap, cmap); 640 if (AddDrawableMapping(dpy, ret, dd)) { 641 /* XXX: Call glXDestroyGLXPixmap which lives in libglvnd. If we're not 642 * allowed to call it from here, should we extend __glXDispatchTableIndices ? 643 */ 644 return None; 645 } 646 647 return ret; 648} 649 650 651 652static GLboolean dispatch_GetMscRateOML(Display *dpy, GLXDrawable drawable, 653 int32_t *numerator, int32_t *denominator) 654{ 655 PFNGLXGETMSCRATEOMLPROC pGetMscRateOML; 656 __GLXvendorInfo *dd; 657 658 dd = GetDispatchFromDrawable(dpy, drawable); 659 if (dd == NULL) 660 return GL_FALSE; 661 662 __FETCH_FUNCTION_PTR(GetMscRateOML); 663 if (pGetMscRateOML == NULL) 664 return GL_FALSE; 665 666 return pGetMscRateOML(dpy, drawable, numerator, denominator); 667} 668 669 670 671static const char *dispatch_GetScreenDriver(Display *dpy, int scrNum) 672{ 673 typedef const char *(*fn_glXGetScreenDriver_ptr)(Display *dpy, int scrNum); 674 fn_glXGetScreenDriver_ptr pGetScreenDriver; 675 __GLXvendorInfo *dd; 676 677 dd = __VND->getDynDispatch(dpy, scrNum); 678 if (dd == NULL) 679 return NULL; 680 681 __FETCH_FUNCTION_PTR(GetScreenDriver); 682 if (pGetScreenDriver == NULL) 683 return NULL; 684 685 return pGetScreenDriver(dpy, scrNum); 686} 687 688 689 690static int dispatch_GetSwapIntervalMESA(void) 691{ 692 PFNGLXGETSWAPINTERVALMESAPROC pGetSwapIntervalMESA; 693 __GLXvendorInfo *dd; 694 695 if (!__VND->getCurrentContext()) 696 return GLX_BAD_CONTEXT; 697 698 dd = __VND->getCurrentDynDispatch(); 699 if (dd == NULL) 700 return 0; 701 702 __FETCH_FUNCTION_PTR(GetSwapIntervalMESA); 703 if (pGetSwapIntervalMESA == NULL) 704 return 0; 705 706 return pGetSwapIntervalMESA(); 707} 708 709 710 711static Bool dispatch_GetSyncValuesOML(Display *dpy, GLXDrawable drawable, 712 int64_t *ust, int64_t *msc, int64_t *sbc) 713{ 714 PFNGLXGETSYNCVALUESOMLPROC pGetSyncValuesOML; 715 __GLXvendorInfo *dd; 716 717 dd = GetDispatchFromDrawable(dpy, drawable); 718 if (dd == NULL) 719 return False; 720 721 __FETCH_FUNCTION_PTR(GetSyncValuesOML); 722 if (pGetSyncValuesOML == NULL) 723 return False; 724 725 return pGetSyncValuesOML(dpy, drawable, ust, msc, sbc); 726} 727 728 729 730static void dispatch_JoinSwapGroupSGIX(Display *dpy, GLXDrawable drawable, 731 GLXDrawable member) 732{ 733 PFNGLXJOINSWAPGROUPSGIXPROC pJoinSwapGroupSGIX; 734 __GLXvendorInfo *dd; 735 736 dd = GetDispatchFromDrawable(dpy, drawable); 737 if (dd == NULL) 738 return; 739 740 __FETCH_FUNCTION_PTR(JoinSwapGroupSGIX); 741 if (pJoinSwapGroupSGIX == NULL) 742 return; 743 744 pJoinSwapGroupSGIX(dpy, drawable, member); 745} 746 747 748 749static Bool dispatch_QueryCurrentRendererIntegerMESA(int attribute, 750 unsigned int *value) 751{ 752 PFNGLXQUERYCURRENTRENDERERINTEGERMESAPROC pQueryCurrentRendererIntegerMESA; 753 __GLXvendorInfo *dd; 754 755 if (!__VND->getCurrentContext()) 756 return False; 757 758 dd = __VND->getCurrentDynDispatch(); 759 if (dd == NULL) 760 return False; 761 762 __FETCH_FUNCTION_PTR(QueryCurrentRendererIntegerMESA); 763 if (pQueryCurrentRendererIntegerMESA == NULL) 764 return False; 765 766 return pQueryCurrentRendererIntegerMESA(attribute, value); 767} 768 769 770 771static const char *dispatch_QueryCurrentRendererStringMESA(int attribute) 772{ 773 PFNGLXQUERYCURRENTRENDERERSTRINGMESAPROC pQueryCurrentRendererStringMESA; 774 __GLXvendorInfo *dd; 775 776 if (!__VND->getCurrentContext()) 777 return NULL; 778 779 dd = __VND->getCurrentDynDispatch(); 780 if (dd == NULL) 781 return NULL; 782 783 __FETCH_FUNCTION_PTR(QueryCurrentRendererStringMESA); 784 if (pQueryCurrentRendererStringMESA == NULL) 785 return NULL; 786 787 return pQueryCurrentRendererStringMESA(attribute); 788} 789 790 791 792static Bool dispatch_QueryMaxSwapBarriersSGIX(Display *dpy, int screen, 793 int *max) 794{ 795 PFNGLXQUERYMAXSWAPBARRIERSSGIXPROC pQueryMaxSwapBarriersSGIX; 796 __GLXvendorInfo *dd; 797 798 dd = __VND->getDynDispatch(dpy, screen); 799 if (dd == NULL) 800 return False; 801 802 __FETCH_FUNCTION_PTR(QueryMaxSwapBarriersSGIX); 803 if (pQueryMaxSwapBarriersSGIX == NULL) 804 return False; 805 806 return pQueryMaxSwapBarriersSGIX(dpy, screen, max); 807} 808 809 810 811static Bool dispatch_QueryRendererIntegerMESA(Display *dpy, int screen, 812 int renderer, int attribute, 813 unsigned int *value) 814{ 815 PFNGLXQUERYRENDERERINTEGERMESAPROC pQueryRendererIntegerMESA; 816 __GLXvendorInfo *dd; 817 818 dd = __VND->getDynDispatch(dpy, screen); 819 if (dd == NULL) 820 return False; 821 822 __FETCH_FUNCTION_PTR(QueryRendererIntegerMESA); 823 if (pQueryRendererIntegerMESA == NULL) 824 return False; 825 826 return pQueryRendererIntegerMESA(dpy, screen, renderer, attribute, value); 827} 828 829 830 831static const char *dispatch_QueryRendererStringMESA(Display *dpy, int screen, 832 int renderer, int attribute) 833{ 834 PFNGLXQUERYRENDERERSTRINGMESAPROC pQueryRendererStringMESA; 835 __GLXvendorInfo *dd = NULL; 836 837 dd = __VND->getDynDispatch(dpy, screen); 838 if (dd == NULL) 839 return NULL; 840 841 __FETCH_FUNCTION_PTR(QueryRendererStringMESA); 842 if (pQueryRendererStringMESA == NULL) 843 return NULL; 844 845 return pQueryRendererStringMESA(dpy, screen, renderer, attribute); 846} 847 848 849 850static Bool dispatch_ReleaseBuffersMESA(Display *dpy, GLXDrawable d) 851{ 852 PFNGLXRELEASEBUFFERSMESAPROC pReleaseBuffersMESA; 853 __GLXvendorInfo *dd; 854 855 dd = GetDispatchFromDrawable(dpy, d); 856 if (dd == NULL) 857 return False; 858 859 __FETCH_FUNCTION_PTR(ReleaseBuffersMESA); 860 if (pReleaseBuffersMESA == NULL) 861 return False; 862 863 return pReleaseBuffersMESA(dpy, d); 864} 865 866 867 868static int64_t dispatch_SwapBuffersMscOML(Display *dpy, GLXDrawable drawable, 869 int64_t target_msc, int64_t divisor, 870 int64_t remainder) 871{ 872 PFNGLXSWAPBUFFERSMSCOMLPROC pSwapBuffersMscOML; 873 __GLXvendorInfo *dd; 874 875 dd = GetDispatchFromDrawable(dpy, drawable); 876 if (dd == NULL) 877 return 0; 878 879 __FETCH_FUNCTION_PTR(SwapBuffersMscOML); 880 if (pSwapBuffersMscOML == NULL) 881 return 0; 882 883 return pSwapBuffersMscOML(dpy, drawable, target_msc, divisor, remainder); 884} 885 886 887 888static int dispatch_SwapIntervalMESA(unsigned int interval) 889{ 890 PFNGLXSWAPINTERVALMESAPROC pSwapIntervalMESA; 891 __GLXvendorInfo *dd; 892 893 if (!__VND->getCurrentContext()) 894 return GLX_BAD_CONTEXT; 895 896 dd = __VND->getCurrentDynDispatch(); 897 if (dd == NULL) 898 return 0; 899 900 __FETCH_FUNCTION_PTR(SwapIntervalMESA); 901 if (pSwapIntervalMESA == NULL) 902 return 0; 903 904 return pSwapIntervalMESA(interval); 905} 906 907 908 909static void dispatch_SwapIntervalEXT(Display *dpy, GLXDrawable drawable, int interval) 910{ 911 PFNGLXSWAPINTERVALEXTPROC pSwapIntervalEXT; 912 __GLXvendorInfo *dd; 913 914 dd = GetDispatchFromDrawable(dpy, drawable); 915 if (dd == NULL) 916 return; 917 918 __FETCH_FUNCTION_PTR(SwapIntervalEXT); 919 if (pSwapIntervalEXT == NULL) 920 return; 921 922 pSwapIntervalEXT(dpy, drawable, interval); 923} 924 925 926 927static Bool dispatch_WaitForMscOML(Display *dpy, GLXDrawable drawable, 928 int64_t target_msc, int64_t divisor, 929 int64_t remainder, int64_t *ust, 930 int64_t *msc, int64_t *sbc) 931{ 932 PFNGLXWAITFORMSCOMLPROC pWaitForMscOML; 933 __GLXvendorInfo *dd; 934 935 dd = GetDispatchFromDrawable(dpy, drawable); 936 if (dd == NULL) 937 return False; 938 939 __FETCH_FUNCTION_PTR(WaitForMscOML); 940 if (pWaitForMscOML == NULL) 941 return False; 942 943 return pWaitForMscOML(dpy, drawable, target_msc, divisor, remainder, ust, msc, sbc); 944} 945 946 947 948static Bool dispatch_WaitForSbcOML(Display *dpy, GLXDrawable drawable, 949 int64_t target_sbc, int64_t *ust, 950 int64_t *msc, int64_t *sbc) 951{ 952 PFNGLXWAITFORSBCOMLPROC pWaitForSbcOML; 953 __GLXvendorInfo *dd; 954 955 dd = GetDispatchFromDrawable(dpy, drawable); 956 if (dd == NULL) 957 return False; 958 959 __FETCH_FUNCTION_PTR(WaitForSbcOML); 960 if (pWaitForSbcOML == NULL) 961 return False; 962 963 return pWaitForSbcOML(dpy, drawable, target_sbc, ust, msc, sbc); 964} 965 966#undef __FETCH_FUNCTION_PTR 967 968 969/* Allocate an extra 'dummy' to ease lookup. See FindGLXFunction() */ 970const void * const __glXDispatchFunctions[DI_LAST_INDEX + 1] = { 971#define __ATTRIB(field) \ 972 [DI_##field] = (void *)dispatch_##field 973 974 __ATTRIB(BindSwapBarrierSGIX), 975 __ATTRIB(BindTexImageEXT), 976 __ATTRIB(ChooseFBConfigSGIX), 977 __ATTRIB(CopySubBufferMESA), 978 __ATTRIB(CreateContextAttribsARB), 979 __ATTRIB(CreateContextWithConfigSGIX), 980 __ATTRIB(CreateGLXPbufferSGIX), 981 __ATTRIB(CreateGLXPixmapMESA), 982 __ATTRIB(CreateGLXPixmapWithConfigSGIX), 983 __ATTRIB(DestroyGLXPbufferSGIX), 984 __ATTRIB(GetContextIDEXT), 985 __ATTRIB(GetCurrentDisplayEXT), 986 __ATTRIB(GetDriverConfig), 987 __ATTRIB(GetFBConfigAttribSGIX), 988 __ATTRIB(GetFBConfigFromVisualSGIX), 989 __ATTRIB(GetMscRateOML), 990 __ATTRIB(GetScreenDriver), 991 __ATTRIB(GetSelectedEventSGIX), 992 __ATTRIB(GetSwapIntervalMESA), 993 __ATTRIB(GetSyncValuesOML), 994 __ATTRIB(GetVideoSyncSGI), 995 __ATTRIB(GetVisualFromFBConfigSGIX), 996 __ATTRIB(JoinSwapGroupSGIX), 997 __ATTRIB(QueryContextInfoEXT), 998 __ATTRIB(QueryCurrentRendererIntegerMESA), 999 __ATTRIB(QueryCurrentRendererStringMESA), 1000 __ATTRIB(QueryGLXPbufferSGIX), 1001 __ATTRIB(QueryMaxSwapBarriersSGIX), 1002 __ATTRIB(QueryRendererIntegerMESA), 1003 __ATTRIB(QueryRendererStringMESA), 1004 __ATTRIB(ReleaseBuffersMESA), 1005 __ATTRIB(ReleaseTexImageEXT), 1006 __ATTRIB(SelectEventSGIX), 1007 __ATTRIB(SwapBuffersMscOML), 1008 __ATTRIB(SwapIntervalEXT), 1009 __ATTRIB(SwapIntervalMESA), 1010 __ATTRIB(SwapIntervalSGI), 1011 __ATTRIB(WaitForMscOML), 1012 __ATTRIB(WaitForSbcOML), 1013 __ATTRIB(WaitVideoSyncSGI), 1014 1015 [DI_LAST_INDEX] = NULL, 1016#undef __ATTRIB 1017}; 1018