glxcmds.c revision 5a112b11
1/* 2 * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) 3 * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining a 6 * copy of this software and associated documentation files (the "Software"), 7 * to deal in the Software without restriction, including without limitation 8 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 9 * and/or sell copies of the Software, and to permit persons to whom the 10 * Software is furnished to do so, subject to the following conditions: 11 * 12 * The above copyright notice including the dates of first publication and 13 * either this permission notice or a reference to 14 * http://oss.sgi.com/projects/FreeB/ 15 * shall be included in all copies or substantial portions of the Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20 * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 21 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF 22 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 * SOFTWARE. 24 * 25 * Except as contained in this notice, the name of Silicon Graphics, Inc. 26 * shall not be used in advertising or otherwise to promote the sale, use or 27 * other dealings in this Software without prior written authorization from 28 * Silicon Graphics, Inc. 29 */ 30 31#ifdef HAVE_DIX_CONFIG_H 32#include <dix-config.h> 33#endif 34 35#include <string.h> 36#include <assert.h> 37 38#include "glxserver.h" 39#include <GL/glxtokens.h> 40#include <X11/extensions/presenttokens.h> 41#include <unpack.h> 42#include <pixmapstr.h> 43#include <windowstr.h> 44#include "glxutil.h" 45#include "glxext.h" 46#include "indirect_dispatch.h" 47#include "indirect_table.h" 48#include "indirect_util.h" 49#include "protocol-versions.h" 50#include "glxvndabi.h" 51 52static char GLXServerVendorName[] = "SGI"; 53 54_X_HIDDEN int 55validGlxScreen(ClientPtr client, int screen, __GLXscreen ** pGlxScreen, 56 int *err) 57{ 58 /* 59 ** Check if screen exists. 60 */ 61 if (screen < 0 || screen >= screenInfo.numScreens) { 62 client->errorValue = screen; 63 *err = BadValue; 64 return FALSE; 65 } 66 *pGlxScreen = glxGetScreen(screenInfo.screens[screen]); 67 68 return TRUE; 69} 70 71_X_HIDDEN int 72validGlxFBConfig(ClientPtr client, __GLXscreen * pGlxScreen, XID id, 73 __GLXconfig ** config, int *err) 74{ 75 __GLXconfig *m; 76 77 for (m = pGlxScreen->fbconfigs; m != NULL; m = m->next) 78 if (m->fbconfigID == id) { 79 *config = m; 80 return TRUE; 81 } 82 83 client->errorValue = id; 84 *err = __glXError(GLXBadFBConfig); 85 86 return FALSE; 87} 88 89static int 90validGlxVisual(ClientPtr client, __GLXscreen * pGlxScreen, XID id, 91 __GLXconfig ** config, int *err) 92{ 93 int i; 94 95 for (i = 0; i < pGlxScreen->numVisuals; i++) 96 if (pGlxScreen->visuals[i]->visualID == id) { 97 *config = pGlxScreen->visuals[i]; 98 return TRUE; 99 } 100 101 client->errorValue = id; 102 *err = BadValue; 103 104 return FALSE; 105} 106 107static int 108validGlxFBConfigForWindow(ClientPtr client, __GLXconfig * config, 109 DrawablePtr pDraw, int *err) 110{ 111 ScreenPtr pScreen = pDraw->pScreen; 112 VisualPtr pVisual = NULL; 113 XID vid; 114 int i; 115 116 vid = wVisual((WindowPtr) pDraw); 117 for (i = 0; i < pScreen->numVisuals; i++) { 118 if (pScreen->visuals[i].vid == vid) { 119 pVisual = &pScreen->visuals[i]; 120 break; 121 } 122 } 123 124 /* FIXME: What exactly should we check here... */ 125 if (pVisual->class != glxConvertToXVisualType(config->visualType) || 126 !(config->drawableType & GLX_WINDOW_BIT)) { 127 client->errorValue = pDraw->id; 128 *err = BadMatch; 129 return FALSE; 130 } 131 132 return TRUE; 133} 134 135_X_HIDDEN int 136validGlxContext(ClientPtr client, XID id, int access_mode, 137 __GLXcontext ** context, int *err) 138{ 139 /* no ghost contexts */ 140 if (id & SERVER_BIT) { 141 *err = __glXError(GLXBadContext); 142 return FALSE; 143 } 144 145 *err = dixLookupResourceByType((void **) context, id, 146 __glXContextRes, client, access_mode); 147 if (*err != Success || (*context)->idExists == GL_FALSE) { 148 client->errorValue = id; 149 if (*err == BadValue || *err == Success) 150 *err = __glXError(GLXBadContext); 151 return FALSE; 152 } 153 154 return TRUE; 155} 156 157int 158validGlxDrawable(ClientPtr client, XID id, int type, int access_mode, 159 __GLXdrawable ** drawable, int *err) 160{ 161 int rc; 162 163 rc = dixLookupResourceByType((void **) drawable, id, 164 __glXDrawableRes, client, access_mode); 165 if (rc != Success && rc != BadValue) { 166 *err = rc; 167 client->errorValue = id; 168 return FALSE; 169 } 170 171 /* If the ID of the glx drawable we looked up doesn't match the id 172 * we looked for, it's because we looked it up under the X 173 * drawable ID (see DoCreateGLXDrawable). */ 174 if (rc == BadValue || 175 (*drawable)->drawId != id || 176 (type != GLX_DRAWABLE_ANY && type != (*drawable)->type)) { 177 client->errorValue = id; 178 switch (type) { 179 case GLX_DRAWABLE_WINDOW: 180 *err = __glXError(GLXBadWindow); 181 return FALSE; 182 case GLX_DRAWABLE_PIXMAP: 183 *err = __glXError(GLXBadPixmap); 184 return FALSE; 185 case GLX_DRAWABLE_PBUFFER: 186 *err = __glXError(GLXBadPbuffer); 187 return FALSE; 188 case GLX_DRAWABLE_ANY: 189 *err = __glXError(GLXBadDrawable); 190 return FALSE; 191 } 192 } 193 194 return TRUE; 195} 196 197void 198__glXContextDestroy(__GLXcontext * context) 199{ 200 lastGLContext = NULL; 201} 202 203static void 204__glXdirectContextDestroy(__GLXcontext * context) 205{ 206 __glXContextDestroy(context); 207 free(context); 208} 209 210static int 211__glXdirectContextLoseCurrent(__GLXcontext * context) 212{ 213 return GL_TRUE; 214} 215 216_X_HIDDEN __GLXcontext * 217__glXdirectContextCreate(__GLXscreen * screen, 218 __GLXconfig * modes, __GLXcontext * shareContext) 219{ 220 __GLXcontext *context; 221 222 context = calloc(1, sizeof(__GLXcontext)); 223 if (context == NULL) 224 return NULL; 225 226 context->config = modes; 227 context->destroy = __glXdirectContextDestroy; 228 context->loseCurrent = __glXdirectContextLoseCurrent; 229 230 return context; 231} 232 233/** 234 * Create a GL context with the given properties. This routine is used 235 * to implement \c glXCreateContext, \c glXCreateNewContext, and 236 * \c glXCreateContextWithConfigSGIX. This works because of the hack way 237 * that GLXFBConfigs are implemented. Basically, the FBConfigID is the 238 * same as the VisualID. 239 */ 240 241static int 242DoCreateContext(__GLXclientState * cl, GLXContextID gcId, 243 GLXContextID shareList, __GLXconfig * config, 244 __GLXscreen * pGlxScreen, GLboolean isDirect, 245 int renderType) 246{ 247 ClientPtr client = cl->client; 248 __GLXcontext *glxc, *shareglxc; 249 int err; 250 251 /* 252 ** Find the display list space that we want to share. 253 ** 254 ** NOTE: In a multithreaded X server, we would need to keep a reference 255 ** count for each display list so that if one client destroyed a list that 256 ** another client was using, the list would not really be freed until it 257 ** was no longer in use. Since this sample implementation has no support 258 ** for multithreaded servers, we don't do this. 259 */ 260 if (shareList == None) { 261 shareglxc = 0; 262 } 263 else { 264 if (!validGlxContext(client, shareList, DixReadAccess, 265 &shareglxc, &err)) 266 return err; 267 268 /* Page 26 (page 32 of the PDF) of the GLX 1.4 spec says: 269 * 270 * "The server context state for all sharing contexts must exist 271 * in a single address space or a BadMatch error is generated." 272 * 273 * If the share context is indirect, force the new context to also be 274 * indirect. If the shard context is direct but the new context 275 * cannot be direct, generate BadMatch. 276 */ 277 if (shareglxc->isDirect && !isDirect) { 278 client->errorValue = shareList; 279 return BadMatch; 280 } 281 else if (!shareglxc->isDirect) { 282 /* 283 ** Create an indirect context regardless of what the client asked 284 ** for; this way we can share display list space with shareList. 285 */ 286 isDirect = GL_FALSE; 287 } 288 289 /* Core GLX doesn't explicitly require this, but GLX_ARB_create_context 290 * does (see glx/createcontext.c), and it's assumed by our 291 * implementation anyway, so let's be consistent about it. 292 */ 293 if (shareglxc->pGlxScreen != pGlxScreen) { 294 client->errorValue = shareglxc->pGlxScreen->pScreen->myNum; 295 return BadMatch; 296 } 297 } 298 299 /* 300 ** Allocate memory for the new context 301 */ 302 if (!isDirect) { 303 /* Only allow creating indirect GLX contexts if allowed by 304 * server command line. Indirect GLX is of limited use (since 305 * it's only GL 1.4), it's slower than direct contexts, and 306 * it's a massive attack surface for buffer overflow type 307 * errors. 308 */ 309 if (!enableIndirectGLX) { 310 client->errorValue = isDirect; 311 return BadValue; 312 } 313 314 /* Without any attributes, the only error that the driver should be 315 * able to generate is BadAlloc. As result, just drop the error 316 * returned from the driver on the floor. 317 */ 318 glxc = pGlxScreen->createContext(pGlxScreen, config, shareglxc, 319 0, NULL, &err); 320 } 321 else 322 glxc = __glXdirectContextCreate(pGlxScreen, config, shareglxc); 323 if (!glxc) { 324 return BadAlloc; 325 } 326 327 /* Initialize the GLXcontext structure. 328 */ 329 glxc->pGlxScreen = pGlxScreen; 330 glxc->config = config; 331 glxc->id = gcId; 332 glxc->share_id = shareList; 333 glxc->idExists = GL_TRUE; 334 glxc->isDirect = isDirect; 335 glxc->renderMode = GL_RENDER; 336 glxc->renderType = renderType; 337 338 /* The GLX_ARB_create_context_robustness spec says: 339 * 340 * "The default value for GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB 341 * is GLX_NO_RESET_NOTIFICATION_ARB." 342 * 343 * Without using glXCreateContextAttribsARB, there is no way to specify a 344 * non-default reset notification strategy. 345 */ 346 glxc->resetNotificationStrategy = GLX_NO_RESET_NOTIFICATION_ARB; 347 348#ifdef GLX_CONTEXT_RELEASE_BEHAVIOR_ARB 349 /* The GLX_ARB_context_flush_control spec says: 350 * 351 * "The default value [for GLX_CONTEXT_RELEASE_BEHAVIOR] is 352 * CONTEXT_RELEASE_BEHAVIOR_FLUSH, and may in some cases be changed 353 * using platform-specific context creation extensions." 354 * 355 * Without using glXCreateContextAttribsARB, there is no way to specify a 356 * non-default release behavior. 357 */ 358 glxc->releaseBehavior = GLX_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB; 359#endif 360 361 /* Add the new context to the various global tables of GLX contexts. 362 */ 363 if (!__glXAddContext(glxc)) { 364 (*glxc->destroy) (glxc); 365 client->errorValue = gcId; 366 return BadAlloc; 367 } 368 369 return Success; 370} 371 372int 373__glXDisp_CreateContext(__GLXclientState * cl, GLbyte * pc) 374{ 375 xGLXCreateContextReq *req = (xGLXCreateContextReq *) pc; 376 __GLXconfig *config; 377 __GLXscreen *pGlxScreen; 378 int err; 379 380 if (!validGlxScreen(cl->client, req->screen, &pGlxScreen, &err)) 381 return err; 382 if (!validGlxVisual(cl->client, pGlxScreen, req->visual, &config, &err)) 383 return err; 384 385 return DoCreateContext(cl, req->context, req->shareList, 386 config, pGlxScreen, req->isDirect, 387 GLX_RGBA_TYPE); 388} 389 390int 391__glXDisp_CreateNewContext(__GLXclientState * cl, GLbyte * pc) 392{ 393 xGLXCreateNewContextReq *req = (xGLXCreateNewContextReq *) pc; 394 __GLXconfig *config; 395 __GLXscreen *pGlxScreen; 396 int err; 397 398 if (!validGlxScreen(cl->client, req->screen, &pGlxScreen, &err)) 399 return err; 400 if (!validGlxFBConfig(cl->client, pGlxScreen, req->fbconfig, &config, &err)) 401 return err; 402 403 return DoCreateContext(cl, req->context, req->shareList, 404 config, pGlxScreen, req->isDirect, 405 req->renderType); 406} 407 408int 409__glXDisp_CreateContextWithConfigSGIX(__GLXclientState * cl, GLbyte * pc) 410{ 411 ClientPtr client = cl->client; 412 xGLXCreateContextWithConfigSGIXReq *req = 413 (xGLXCreateContextWithConfigSGIXReq *) pc; 414 __GLXconfig *config; 415 __GLXscreen *pGlxScreen; 416 int err; 417 418 REQUEST_SIZE_MATCH(xGLXCreateContextWithConfigSGIXReq); 419 420 if (!validGlxScreen(cl->client, req->screen, &pGlxScreen, &err)) 421 return err; 422 if (!validGlxFBConfig(cl->client, pGlxScreen, req->fbconfig, &config, &err)) 423 return err; 424 425 return DoCreateContext(cl, req->context, req->shareList, 426 config, pGlxScreen, req->isDirect, 427 req->renderType); 428} 429 430int 431__glXDisp_DestroyContext(__GLXclientState * cl, GLbyte * pc) 432{ 433 xGLXDestroyContextReq *req = (xGLXDestroyContextReq *) pc; 434 __GLXcontext *glxc; 435 int err; 436 437 if (!validGlxContext(cl->client, req->context, DixDestroyAccess, 438 &glxc, &err)) 439 return err; 440 441 glxc->idExists = GL_FALSE; 442 if (glxc->currentClient) { 443 XID ghost = FakeClientID(glxc->currentClient->index); 444 445 if (!AddResource(ghost, __glXContextRes, glxc)) 446 return BadAlloc; 447 ChangeResourceValue(glxc->id, __glXContextRes, NULL); 448 glxc->id = ghost; 449 } 450 451 FreeResourceByType(req->context, __glXContextRes, FALSE); 452 453 return Success; 454} 455 456__GLXcontext * 457__glXLookupContextByTag(__GLXclientState * cl, GLXContextTag tag) 458{ 459 return glxServer.getContextTagPrivate(cl->client, tag); 460} 461 462static __GLXconfig * 463inferConfigForWindow(__GLXscreen *pGlxScreen, WindowPtr pWin) 464{ 465 int i, vid = wVisual(pWin); 466 467 for (i = 0; i < pGlxScreen->numVisuals; i++) 468 if (pGlxScreen->visuals[i]->visualID == vid) 469 return pGlxScreen->visuals[i]; 470 471 return NULL; 472} 473 474/** 475 * This is a helper function to handle the legacy (pre GLX 1.3) cases 476 * where passing an X window to glXMakeCurrent is valid. Given a 477 * resource ID, look up the GLX drawable if available, otherwise, make 478 * sure it's an X window and create a GLX drawable one the fly. 479 */ 480static __GLXdrawable * 481__glXGetDrawable(__GLXcontext * glxc, GLXDrawable drawId, ClientPtr client, 482 int *error) 483{ 484 DrawablePtr pDraw; 485 __GLXdrawable *pGlxDraw; 486 __GLXconfig *config; 487 __GLXscreen *pGlxScreen; 488 int rc; 489 490 rc = dixLookupResourceByType((void **)&pGlxDraw, drawId, 491 __glXDrawableRes, client, DixWriteAccess); 492 if (rc == Success && 493 /* If pGlxDraw->drawId == drawId, drawId is a valid GLX drawable. 494 * Otherwise, if pGlxDraw->type == GLX_DRAWABLE_WINDOW, drawId is 495 * an X window, but the client has already created a GLXWindow 496 * associated with it, so we don't want to create another one. */ 497 (pGlxDraw->drawId == drawId || 498 pGlxDraw->type == GLX_DRAWABLE_WINDOW)) { 499 if (glxc != NULL && 500 glxc->config != NULL && 501 glxc->config != pGlxDraw->config) { 502 client->errorValue = drawId; 503 *error = BadMatch; 504 return NULL; 505 } 506 507 return pGlxDraw; 508 } 509 510 /* No active context and an unknown drawable, bail. */ 511 if (glxc == NULL) { 512 client->errorValue = drawId; 513 *error = BadMatch; 514 return NULL; 515 } 516 517 /* The drawId wasn't a GLX drawable. Make sure it's a window and 518 * create a GLXWindow for it. Check that the drawable screen 519 * matches the context screen and that the context fbconfig is 520 * compatible with the window visual. */ 521 522 rc = dixLookupDrawable(&pDraw, drawId, client, 0, DixGetAttrAccess); 523 if (rc != Success || pDraw->type != DRAWABLE_WINDOW) { 524 client->errorValue = drawId; 525 *error = __glXError(GLXBadDrawable); 526 return NULL; 527 } 528 529 pGlxScreen = glxc->pGlxScreen; 530 if (pDraw->pScreen != pGlxScreen->pScreen) { 531 client->errorValue = pDraw->pScreen->myNum; 532 *error = BadMatch; 533 return NULL; 534 } 535 536 config = glxc->config; 537 if (!config) 538 config = inferConfigForWindow(pGlxScreen, (WindowPtr)pDraw); 539 if (!config) { 540 /* 541 * If we get here, we've tried to bind a no-config context to a 542 * window without a corresponding fbconfig, presumably because 543 * we don't support GL on it (PseudoColor perhaps). From GLX Section 544 * 3.3.7 "Rendering Contexts": 545 * 546 * "If draw or read are not compatible with ctx a BadMatch error 547 * is generated." 548 */ 549 *error = BadMatch; 550 return NULL; 551 } 552 553 if (!validGlxFBConfigForWindow(client, config, pDraw, error)) 554 return NULL; 555 556 pGlxDraw = pGlxScreen->createDrawable(client, pGlxScreen, pDraw, drawId, 557 GLX_DRAWABLE_WINDOW, drawId, config); 558 if (!pGlxDraw) { 559 *error = BadAlloc; 560 return NULL; 561 } 562 563 /* since we are creating the drawablePrivate, drawId should be new */ 564 if (!AddResource(drawId, __glXDrawableRes, pGlxDraw)) { 565 *error = BadAlloc; 566 return NULL; 567 } 568 569 return pGlxDraw; 570} 571 572/*****************************************************************************/ 573/* 574** Make an OpenGL context and drawable current. 575*/ 576 577int 578xorgGlxMakeCurrent(ClientPtr client, GLXContextTag tag, XID drawId, XID readId, 579 XID contextId, GLXContextTag newContextTag) 580{ 581 __GLXclientState *cl = glxGetClient(client); 582 __GLXcontext *glxc = NULL, *prevglxc = NULL; 583 __GLXdrawable *drawPriv = NULL; 584 __GLXdrawable *readPriv = NULL; 585 int error; 586 587 /* Drawables but no context makes no sense */ 588 if (!contextId && (drawId || readId)) 589 return BadMatch; 590 591 /* If either drawable is null, the other must be too */ 592 if ((drawId == None) != (readId == None)) 593 return BadMatch; 594 595 /* Look up old context. If we have one, it must be in a usable state. */ 596 if (tag != 0) { 597 prevglxc = glxServer.getContextTagPrivate(client, tag); 598 599 if (prevglxc && prevglxc->renderMode != GL_RENDER) { 600 /* Oops. Not in render mode render. */ 601 client->errorValue = prevglxc->id; 602 return __glXError(GLXBadContextState); 603 } 604 } 605 606 /* Look up new context. It must not be current for someone else. */ 607 if (contextId != None) { 608 int status; 609 610 if (!validGlxContext(client, contextId, DixUseAccess, &glxc, &error)) 611 return error; 612 613 if ((glxc != prevglxc) && glxc->currentClient) 614 return BadAccess; 615 616 if (drawId) { 617 drawPriv = __glXGetDrawable(glxc, drawId, client, &status); 618 if (drawPriv == NULL) 619 return status; 620 } 621 622 if (readId) { 623 readPriv = __glXGetDrawable(glxc, readId, client, &status); 624 if (readPriv == NULL) 625 return status; 626 } 627 } 628 629 if (prevglxc) { 630 /* Flush the previous context if needed. */ 631 Bool need_flush = !prevglxc->isDirect; 632#ifdef GLX_CONTEXT_RELEASE_BEHAVIOR_ARB 633 if (prevglxc->releaseBehavior == GLX_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB) 634 need_flush = GL_FALSE; 635#endif 636 if (need_flush) { 637 if (!__glXForceCurrent(cl, tag, (int *) &error)) 638 return error; 639 glFlush(); 640 } 641 642 /* Make the previous context not current. */ 643 if (!(*prevglxc->loseCurrent) (prevglxc)) 644 return __glXError(GLXBadContext); 645 646 lastGLContext = NULL; 647 if (!prevglxc->isDirect) { 648 prevglxc->drawPriv = NULL; 649 prevglxc->readPriv = NULL; 650 } 651 } 652 653 if (glxc && !glxc->isDirect) { 654 glxc->drawPriv = drawPriv; 655 glxc->readPriv = readPriv; 656 657 /* make the context current */ 658 lastGLContext = glxc; 659 if (!(*glxc->makeCurrent) (glxc)) { 660 lastGLContext = NULL; 661 glxc->drawPriv = NULL; 662 glxc->readPriv = NULL; 663 return __glXError(GLXBadContext); 664 } 665 } 666 667 glxServer.setContextTagPrivate(client, newContextTag, glxc); 668 if (glxc) 669 glxc->currentClient = client; 670 671 if (prevglxc) { 672 prevglxc->currentClient = NULL; 673 if (!prevglxc->idExists) { 674 FreeResourceByType(prevglxc->id, __glXContextRes, FALSE); 675 } 676 } 677 678 return Success; 679} 680 681int 682__glXDisp_MakeCurrent(__GLXclientState * cl, GLbyte * pc) 683{ 684 return BadImplementation; 685} 686 687int 688__glXDisp_MakeContextCurrent(__GLXclientState * cl, GLbyte * pc) 689{ 690 return BadImplementation; 691} 692 693int 694__glXDisp_MakeCurrentReadSGI(__GLXclientState * cl, GLbyte * pc) 695{ 696 return BadImplementation; 697} 698 699int 700__glXDisp_IsDirect(__GLXclientState * cl, GLbyte * pc) 701{ 702 ClientPtr client = cl->client; 703 xGLXIsDirectReq *req = (xGLXIsDirectReq *) pc; 704 xGLXIsDirectReply reply; 705 __GLXcontext *glxc; 706 int err; 707 708 if (!validGlxContext(cl->client, req->context, DixReadAccess, &glxc, &err)) 709 return err; 710 711 reply = (xGLXIsDirectReply) { 712 .type = X_Reply, 713 .sequenceNumber = client->sequence, 714 .length = 0, 715 .isDirect = glxc->isDirect 716 }; 717 718 if (client->swapped) { 719 __GLX_DECLARE_SWAP_VARIABLES; 720 __GLX_SWAP_SHORT(&reply.sequenceNumber); 721 __GLX_SWAP_INT(&reply.length); 722 } 723 WriteToClient(client, sz_xGLXIsDirectReply, &reply); 724 725 return Success; 726} 727 728int 729__glXDisp_QueryVersion(__GLXclientState * cl, GLbyte * pc) 730{ 731 ClientPtr client = cl->client; 732 xGLXQueryVersionReq *req = (xGLXQueryVersionReq *) pc; 733 xGLXQueryVersionReply reply; 734 GLuint major, minor; 735 736 REQUEST_SIZE_MATCH(xGLXQueryVersionReq); 737 738 major = req->majorVersion; 739 minor = req->minorVersion; 740 (void) major; 741 (void) minor; 742 743 /* 744 ** Server should take into consideration the version numbers sent by the 745 ** client if it wants to work with older clients; however, in this 746 ** implementation the server just returns its version number. 747 */ 748 reply = (xGLXQueryVersionReply) { 749 .type = X_Reply, 750 .sequenceNumber = client->sequence, 751 .length = 0, 752 .majorVersion = SERVER_GLX_MAJOR_VERSION, 753 .minorVersion = SERVER_GLX_MINOR_VERSION 754 }; 755 756 if (client->swapped) { 757 __GLX_DECLARE_SWAP_VARIABLES; 758 __GLX_SWAP_SHORT(&reply.sequenceNumber); 759 __GLX_SWAP_INT(&reply.length); 760 __GLX_SWAP_INT(&reply.majorVersion); 761 __GLX_SWAP_INT(&reply.minorVersion); 762 } 763 764 WriteToClient(client, sz_xGLXQueryVersionReply, &reply); 765 return Success; 766} 767 768int 769__glXDisp_WaitGL(__GLXclientState * cl, GLbyte * pc) 770{ 771 xGLXWaitGLReq *req = (xGLXWaitGLReq *) pc; 772 GLXContextTag tag; 773 __GLXcontext *glxc = NULL; 774 int error; 775 776 tag = req->contextTag; 777 if (tag) { 778 glxc = __glXLookupContextByTag(cl, tag); 779 if (!glxc) 780 return __glXError(GLXBadContextTag); 781 782 if (!__glXForceCurrent(cl, req->contextTag, &error)) 783 return error; 784 785 glFinish(); 786 } 787 788 if (glxc && glxc->drawPriv && glxc->drawPriv->waitGL) 789 (*glxc->drawPriv->waitGL) (glxc->drawPriv); 790 791 return Success; 792} 793 794int 795__glXDisp_WaitX(__GLXclientState * cl, GLbyte * pc) 796{ 797 xGLXWaitXReq *req = (xGLXWaitXReq *) pc; 798 GLXContextTag tag; 799 __GLXcontext *glxc = NULL; 800 int error; 801 802 tag = req->contextTag; 803 if (tag) { 804 glxc = __glXLookupContextByTag(cl, tag); 805 if (!glxc) 806 return __glXError(GLXBadContextTag); 807 808 if (!__glXForceCurrent(cl, req->contextTag, &error)) 809 return error; 810 } 811 812 if (glxc && glxc->drawPriv && glxc->drawPriv->waitX) 813 (*glxc->drawPriv->waitX) (glxc->drawPriv); 814 815 return Success; 816} 817 818int 819__glXDisp_CopyContext(__GLXclientState * cl, GLbyte * pc) 820{ 821 ClientPtr client = cl->client; 822 xGLXCopyContextReq *req = (xGLXCopyContextReq *) pc; 823 GLXContextID source; 824 GLXContextID dest; 825 GLXContextTag tag; 826 unsigned long mask; 827 __GLXcontext *src, *dst; 828 int error; 829 830 source = req->source; 831 dest = req->dest; 832 tag = req->contextTag; 833 mask = req->mask; 834 if (!validGlxContext(cl->client, source, DixReadAccess, &src, &error)) 835 return error; 836 if (!validGlxContext(cl->client, dest, DixWriteAccess, &dst, &error)) 837 return error; 838 839 /* 840 ** They must be in the same address space, and same screen. 841 ** NOTE: no support for direct rendering contexts here. 842 */ 843 if (src->isDirect || dst->isDirect || (src->pGlxScreen != dst->pGlxScreen)) { 844 client->errorValue = source; 845 return BadMatch; 846 } 847 848 /* 849 ** The destination context must not be current for any client. 850 */ 851 if (dst->currentClient) { 852 client->errorValue = dest; 853 return BadAccess; 854 } 855 856 if (tag) { 857 __GLXcontext *tagcx = __glXLookupContextByTag(cl, tag); 858 859 if (!tagcx) { 860 return __glXError(GLXBadContextTag); 861 } 862 if (tagcx != src) { 863 /* 864 ** This would be caused by a faulty implementation of the client 865 ** library. 866 */ 867 return BadMatch; 868 } 869 /* 870 ** In this case, glXCopyContext is in both GL and X streams, in terms 871 ** of sequentiality. 872 */ 873 if (__glXForceCurrent(cl, tag, &error)) { 874 /* 875 ** Do whatever is needed to make sure that all preceding requests 876 ** in both streams are completed before the copy is executed. 877 */ 878 glFinish(); 879 } 880 else { 881 return error; 882 } 883 } 884 /* 885 ** Issue copy. The only reason for failure is a bad mask. 886 */ 887 if (!(*dst->copy) (dst, src, mask)) { 888 client->errorValue = mask; 889 return BadValue; 890 } 891 return Success; 892} 893 894enum { 895 GLX_VIS_CONFIG_UNPAIRED = 18, 896 GLX_VIS_CONFIG_PAIRED = 22 897}; 898 899enum { 900 GLX_VIS_CONFIG_TOTAL = GLX_VIS_CONFIG_UNPAIRED + GLX_VIS_CONFIG_PAIRED 901}; 902 903int 904__glXDisp_GetVisualConfigs(__GLXclientState * cl, GLbyte * pc) 905{ 906 xGLXGetVisualConfigsReq *req = (xGLXGetVisualConfigsReq *) pc; 907 ClientPtr client = cl->client; 908 xGLXGetVisualConfigsReply reply; 909 __GLXscreen *pGlxScreen; 910 __GLXconfig *modes; 911 CARD32 buf[GLX_VIS_CONFIG_TOTAL]; 912 int p, i, err; 913 914 __GLX_DECLARE_SWAP_VARIABLES; 915 __GLX_DECLARE_SWAP_ARRAY_VARIABLES; 916 917 if (!validGlxScreen(cl->client, req->screen, &pGlxScreen, &err)) 918 return err; 919 920 reply = (xGLXGetVisualConfigsReply) { 921 .type = X_Reply, 922 .sequenceNumber = client->sequence, 923 .length = (pGlxScreen->numVisuals * 924 __GLX_SIZE_CARD32 * GLX_VIS_CONFIG_TOTAL) >> 2, 925 .numVisuals = pGlxScreen->numVisuals, 926 .numProps = GLX_VIS_CONFIG_TOTAL 927 }; 928 929 if (client->swapped) { 930 __GLX_SWAP_SHORT(&reply.sequenceNumber); 931 __GLX_SWAP_INT(&reply.length); 932 __GLX_SWAP_INT(&reply.numVisuals); 933 __GLX_SWAP_INT(&reply.numProps); 934 } 935 936 WriteToClient(client, sz_xGLXGetVisualConfigsReply, &reply); 937 938 for (i = 0; i < pGlxScreen->numVisuals; i++) { 939 modes = pGlxScreen->visuals[i]; 940 941 p = 0; 942 buf[p++] = modes->visualID; 943 buf[p++] = glxConvertToXVisualType(modes->visualType); 944 buf[p++] = (modes->renderType & GLX_RGBA_BIT) ? GL_TRUE : GL_FALSE; 945 946 buf[p++] = modes->redBits; 947 buf[p++] = modes->greenBits; 948 buf[p++] = modes->blueBits; 949 buf[p++] = modes->alphaBits; 950 buf[p++] = modes->accumRedBits; 951 buf[p++] = modes->accumGreenBits; 952 buf[p++] = modes->accumBlueBits; 953 buf[p++] = modes->accumAlphaBits; 954 955 buf[p++] = modes->doubleBufferMode; 956 buf[p++] = modes->stereoMode; 957 958 buf[p++] = modes->rgbBits; 959 buf[p++] = modes->depthBits; 960 buf[p++] = modes->stencilBits; 961 buf[p++] = modes->numAuxBuffers; 962 buf[p++] = modes->level; 963 964 assert(p == GLX_VIS_CONFIG_UNPAIRED); 965 /* 966 ** Add token/value pairs for extensions. 967 */ 968 buf[p++] = GLX_VISUAL_CAVEAT_EXT; 969 buf[p++] = modes->visualRating; 970 buf[p++] = GLX_TRANSPARENT_TYPE; 971 buf[p++] = modes->transparentPixel; 972 buf[p++] = GLX_TRANSPARENT_RED_VALUE; 973 buf[p++] = modes->transparentRed; 974 buf[p++] = GLX_TRANSPARENT_GREEN_VALUE; 975 buf[p++] = modes->transparentGreen; 976 buf[p++] = GLX_TRANSPARENT_BLUE_VALUE; 977 buf[p++] = modes->transparentBlue; 978 buf[p++] = GLX_TRANSPARENT_ALPHA_VALUE; 979 buf[p++] = modes->transparentAlpha; 980 buf[p++] = GLX_TRANSPARENT_INDEX_VALUE; 981 buf[p++] = modes->transparentIndex; 982 buf[p++] = GLX_SAMPLES_SGIS; 983 buf[p++] = modes->samples; 984 buf[p++] = GLX_SAMPLE_BUFFERS_SGIS; 985 buf[p++] = modes->sampleBuffers; 986 buf[p++] = GLX_VISUAL_SELECT_GROUP_SGIX; 987 buf[p++] = modes->visualSelectGroup; 988 /* Add attribute only if its value is not default. */ 989 if (modes->sRGBCapable != GL_FALSE) { 990 buf[p++] = GLX_FRAMEBUFFER_SRGB_CAPABLE_EXT; 991 buf[p++] = modes->sRGBCapable; 992 } 993 /* Pad with zeroes, so that attributes count is constant. */ 994 while (p < GLX_VIS_CONFIG_TOTAL) { 995 buf[p++] = 0; 996 } 997 998 assert(p == GLX_VIS_CONFIG_TOTAL); 999 if (client->swapped) { 1000 __GLX_SWAP_INT_ARRAY(buf, p); 1001 } 1002 WriteToClient(client, __GLX_SIZE_CARD32 * p, buf); 1003 } 1004 return Success; 1005} 1006 1007#define __GLX_TOTAL_FBCONFIG_ATTRIBS (44) 1008#define __GLX_FBCONFIG_ATTRIBS_LENGTH (__GLX_TOTAL_FBCONFIG_ATTRIBS * 2) 1009/** 1010 * Send the set of GLXFBConfigs to the client. There is not currently 1011 * and interface into the driver on the server-side to get GLXFBConfigs, 1012 * so we "invent" some based on the \c __GLXvisualConfig structures that 1013 * the driver does supply. 1014 * 1015 * The reply format for both \c glXGetFBConfigs and \c glXGetFBConfigsSGIX 1016 * is the same, so this routine pulls double duty. 1017 */ 1018 1019static int 1020DoGetFBConfigs(__GLXclientState * cl, unsigned screen) 1021{ 1022 ClientPtr client = cl->client; 1023 xGLXGetFBConfigsReply reply; 1024 __GLXscreen *pGlxScreen; 1025 CARD32 buf[__GLX_FBCONFIG_ATTRIBS_LENGTH]; 1026 int p, err; 1027 __GLXconfig *modes; 1028 1029 __GLX_DECLARE_SWAP_VARIABLES; 1030 __GLX_DECLARE_SWAP_ARRAY_VARIABLES; 1031 1032 if (!validGlxScreen(cl->client, screen, &pGlxScreen, &err)) 1033 return err; 1034 1035 reply = (xGLXGetFBConfigsReply) { 1036 .type = X_Reply, 1037 .sequenceNumber = client->sequence, 1038 .length = __GLX_FBCONFIG_ATTRIBS_LENGTH * pGlxScreen->numFBConfigs, 1039 .numFBConfigs = pGlxScreen->numFBConfigs, 1040 .numAttribs = __GLX_TOTAL_FBCONFIG_ATTRIBS 1041 }; 1042 1043 if (client->swapped) { 1044 __GLX_SWAP_SHORT(&reply.sequenceNumber); 1045 __GLX_SWAP_INT(&reply.length); 1046 __GLX_SWAP_INT(&reply.numFBConfigs); 1047 __GLX_SWAP_INT(&reply.numAttribs); 1048 } 1049 1050 WriteToClient(client, sz_xGLXGetFBConfigsReply, &reply); 1051 1052 for (modes = pGlxScreen->fbconfigs; modes != NULL; modes = modes->next) { 1053 p = 0; 1054 1055#define WRITE_PAIR(tag,value) \ 1056 do { buf[p++] = tag ; buf[p++] = value ; } while( 0 ) 1057 1058 WRITE_PAIR(GLX_VISUAL_ID, modes->visualID); 1059 WRITE_PAIR(GLX_FBCONFIG_ID, modes->fbconfigID); 1060 WRITE_PAIR(GLX_X_RENDERABLE, 1061 (modes->drawableType & (GLX_WINDOW_BIT | GLX_PIXMAP_BIT) 1062 ? GL_TRUE 1063 : GL_FALSE)); 1064 1065 WRITE_PAIR(GLX_RGBA, 1066 (modes->renderType & GLX_RGBA_BIT) ? GL_TRUE : GL_FALSE); 1067 WRITE_PAIR(GLX_RENDER_TYPE, modes->renderType); 1068 WRITE_PAIR(GLX_DOUBLEBUFFER, modes->doubleBufferMode); 1069 WRITE_PAIR(GLX_STEREO, modes->stereoMode); 1070 1071 WRITE_PAIR(GLX_BUFFER_SIZE, modes->rgbBits); 1072 WRITE_PAIR(GLX_LEVEL, modes->level); 1073 WRITE_PAIR(GLX_AUX_BUFFERS, modes->numAuxBuffers); 1074 WRITE_PAIR(GLX_RED_SIZE, modes->redBits); 1075 WRITE_PAIR(GLX_GREEN_SIZE, modes->greenBits); 1076 WRITE_PAIR(GLX_BLUE_SIZE, modes->blueBits); 1077 WRITE_PAIR(GLX_ALPHA_SIZE, modes->alphaBits); 1078 WRITE_PAIR(GLX_ACCUM_RED_SIZE, modes->accumRedBits); 1079 WRITE_PAIR(GLX_ACCUM_GREEN_SIZE, modes->accumGreenBits); 1080 WRITE_PAIR(GLX_ACCUM_BLUE_SIZE, modes->accumBlueBits); 1081 WRITE_PAIR(GLX_ACCUM_ALPHA_SIZE, modes->accumAlphaBits); 1082 WRITE_PAIR(GLX_DEPTH_SIZE, modes->depthBits); 1083 WRITE_PAIR(GLX_STENCIL_SIZE, modes->stencilBits); 1084 WRITE_PAIR(GLX_X_VISUAL_TYPE, modes->visualType); 1085 WRITE_PAIR(GLX_CONFIG_CAVEAT, modes->visualRating); 1086 WRITE_PAIR(GLX_TRANSPARENT_TYPE, modes->transparentPixel); 1087 WRITE_PAIR(GLX_TRANSPARENT_RED_VALUE, modes->transparentRed); 1088 WRITE_PAIR(GLX_TRANSPARENT_GREEN_VALUE, modes->transparentGreen); 1089 WRITE_PAIR(GLX_TRANSPARENT_BLUE_VALUE, modes->transparentBlue); 1090 WRITE_PAIR(GLX_TRANSPARENT_ALPHA_VALUE, modes->transparentAlpha); 1091 WRITE_PAIR(GLX_TRANSPARENT_INDEX_VALUE, modes->transparentIndex); 1092 WRITE_PAIR(GLX_SWAP_METHOD_OML, modes->swapMethod); 1093 WRITE_PAIR(GLX_SAMPLES_SGIS, modes->samples); 1094 WRITE_PAIR(GLX_SAMPLE_BUFFERS_SGIS, modes->sampleBuffers); 1095 WRITE_PAIR(GLX_VISUAL_SELECT_GROUP_SGIX, modes->visualSelectGroup); 1096 WRITE_PAIR(GLX_DRAWABLE_TYPE, modes->drawableType); 1097 WRITE_PAIR(GLX_BIND_TO_TEXTURE_RGB_EXT, modes->bindToTextureRgb); 1098 WRITE_PAIR(GLX_BIND_TO_TEXTURE_RGBA_EXT, modes->bindToTextureRgba); 1099 WRITE_PAIR(GLX_BIND_TO_MIPMAP_TEXTURE_EXT, modes->bindToMipmapTexture); 1100 WRITE_PAIR(GLX_BIND_TO_TEXTURE_TARGETS_EXT, 1101 modes->bindToTextureTargets); 1102 /* can't report honestly until mesa is fixed */ 1103 WRITE_PAIR(GLX_Y_INVERTED_EXT, GLX_DONT_CARE); 1104 if (modes->drawableType & GLX_PBUFFER_BIT) { 1105 WRITE_PAIR(GLX_MAX_PBUFFER_WIDTH, modes->maxPbufferWidth); 1106 WRITE_PAIR(GLX_MAX_PBUFFER_HEIGHT, modes->maxPbufferHeight); 1107 WRITE_PAIR(GLX_MAX_PBUFFER_PIXELS, modes->maxPbufferPixels); 1108 WRITE_PAIR(GLX_OPTIMAL_PBUFFER_WIDTH_SGIX, 1109 modes->optimalPbufferWidth); 1110 WRITE_PAIR(GLX_OPTIMAL_PBUFFER_HEIGHT_SGIX, 1111 modes->optimalPbufferHeight); 1112 } 1113 /* Add attribute only if its value is not default. */ 1114 if (modes->sRGBCapable != GL_FALSE) { 1115 WRITE_PAIR(GLX_FRAMEBUFFER_SRGB_CAPABLE_EXT, modes->sRGBCapable); 1116 } 1117 /* Pad the remaining place with zeroes, so that attributes count is constant. */ 1118 while (p < __GLX_FBCONFIG_ATTRIBS_LENGTH) { 1119 WRITE_PAIR(0, 0); 1120 } 1121 assert(p == __GLX_FBCONFIG_ATTRIBS_LENGTH); 1122 1123 if (client->swapped) { 1124 __GLX_SWAP_INT_ARRAY(buf, __GLX_FBCONFIG_ATTRIBS_LENGTH); 1125 } 1126 WriteToClient(client, __GLX_SIZE_CARD32 * __GLX_FBCONFIG_ATTRIBS_LENGTH, 1127 (char *) buf); 1128 } 1129 return Success; 1130} 1131 1132int 1133__glXDisp_GetFBConfigs(__GLXclientState * cl, GLbyte * pc) 1134{ 1135 xGLXGetFBConfigsReq *req = (xGLXGetFBConfigsReq *) pc; 1136 1137 return DoGetFBConfigs(cl, req->screen); 1138} 1139 1140int 1141__glXDisp_GetFBConfigsSGIX(__GLXclientState * cl, GLbyte * pc) 1142{ 1143 ClientPtr client = cl->client; 1144 xGLXGetFBConfigsSGIXReq *req = (xGLXGetFBConfigsSGIXReq *) pc; 1145 1146 /* work around mesa bug, don't use REQUEST_SIZE_MATCH */ 1147 REQUEST_AT_LEAST_SIZE(xGLXGetFBConfigsSGIXReq); 1148 return DoGetFBConfigs(cl, req->screen); 1149} 1150 1151GLboolean 1152__glXDrawableInit(__GLXdrawable * drawable, 1153 __GLXscreen * screen, DrawablePtr pDraw, int type, 1154 XID drawId, __GLXconfig * config) 1155{ 1156 drawable->pDraw = pDraw; 1157 drawable->type = type; 1158 drawable->drawId = drawId; 1159 drawable->config = config; 1160 drawable->eventMask = 0; 1161 1162 return GL_TRUE; 1163} 1164 1165void 1166__glXDrawableRelease(__GLXdrawable * drawable) 1167{ 1168} 1169 1170static int 1171DoCreateGLXDrawable(ClientPtr client, __GLXscreen * pGlxScreen, 1172 __GLXconfig * config, DrawablePtr pDraw, XID drawableId, 1173 XID glxDrawableId, int type) 1174{ 1175 __GLXdrawable *pGlxDraw; 1176 1177 if (pGlxScreen->pScreen != pDraw->pScreen) 1178 return BadMatch; 1179 1180 pGlxDraw = pGlxScreen->createDrawable(client, pGlxScreen, pDraw, 1181 drawableId, type, 1182 glxDrawableId, config); 1183 if (pGlxDraw == NULL) 1184 return BadAlloc; 1185 1186 if (!AddResource(glxDrawableId, __glXDrawableRes, pGlxDraw)) 1187 return BadAlloc; 1188 1189 /* 1190 * Windows aren't refcounted, so track both the X and the GLX window 1191 * so we get called regardless of destruction order. 1192 */ 1193 if (drawableId != glxDrawableId && type == GLX_DRAWABLE_WINDOW && 1194 !AddResource(pDraw->id, __glXDrawableRes, pGlxDraw)) 1195 return BadAlloc; 1196 1197 return Success; 1198} 1199 1200static int 1201DoCreateGLXPixmap(ClientPtr client, __GLXscreen * pGlxScreen, 1202 __GLXconfig * config, XID drawableId, XID glxDrawableId) 1203{ 1204 DrawablePtr pDraw; 1205 int err; 1206 1207 err = dixLookupDrawable(&pDraw, drawableId, client, 0, DixAddAccess); 1208 if (err != Success) { 1209 client->errorValue = drawableId; 1210 return err; 1211 } 1212 if (pDraw->type != DRAWABLE_PIXMAP) { 1213 client->errorValue = drawableId; 1214 return BadPixmap; 1215 } 1216 1217 err = DoCreateGLXDrawable(client, pGlxScreen, config, pDraw, drawableId, 1218 glxDrawableId, GLX_DRAWABLE_PIXMAP); 1219 1220 if (err == Success) 1221 ((PixmapPtr) pDraw)->refcnt++; 1222 1223 return err; 1224} 1225 1226static void 1227determineTextureTarget(ClientPtr client, XID glxDrawableID, 1228 CARD32 *attribs, CARD32 numAttribs) 1229{ 1230 GLenum target = 0; 1231 GLenum format = 0; 1232 int i, err; 1233 __GLXdrawable *pGlxDraw; 1234 1235 if (!validGlxDrawable(client, glxDrawableID, GLX_DRAWABLE_PIXMAP, 1236 DixWriteAccess, &pGlxDraw, &err)) 1237 /* We just added it in CreatePixmap, so we should never get here. */ 1238 return; 1239 1240 for (i = 0; i < numAttribs; i++) { 1241 if (attribs[2 * i] == GLX_TEXTURE_TARGET_EXT) { 1242 switch (attribs[2 * i + 1]) { 1243 case GLX_TEXTURE_2D_EXT: 1244 target = GL_TEXTURE_2D; 1245 break; 1246 case GLX_TEXTURE_RECTANGLE_EXT: 1247 target = GL_TEXTURE_RECTANGLE_ARB; 1248 break; 1249 } 1250 } 1251 1252 if (attribs[2 * i] == GLX_TEXTURE_FORMAT_EXT) 1253 format = attribs[2 * i + 1]; 1254 } 1255 1256 if (!target) { 1257 int w = pGlxDraw->pDraw->width, h = pGlxDraw->pDraw->height; 1258 1259 if (h & (h - 1) || w & (w - 1)) 1260 target = GL_TEXTURE_RECTANGLE_ARB; 1261 else 1262 target = GL_TEXTURE_2D; 1263 } 1264 1265 pGlxDraw->target = target; 1266 pGlxDraw->format = format; 1267} 1268 1269int 1270__glXDisp_CreateGLXPixmap(__GLXclientState * cl, GLbyte * pc) 1271{ 1272 xGLXCreateGLXPixmapReq *req = (xGLXCreateGLXPixmapReq *) pc; 1273 __GLXconfig *config; 1274 __GLXscreen *pGlxScreen; 1275 int err; 1276 1277 if (!validGlxScreen(cl->client, req->screen, &pGlxScreen, &err)) 1278 return err; 1279 if (!validGlxVisual(cl->client, pGlxScreen, req->visual, &config, &err)) 1280 return err; 1281 1282 return DoCreateGLXPixmap(cl->client, pGlxScreen, config, 1283 req->pixmap, req->glxpixmap); 1284} 1285 1286int 1287__glXDisp_CreatePixmap(__GLXclientState * cl, GLbyte * pc) 1288{ 1289 ClientPtr client = cl->client; 1290 xGLXCreatePixmapReq *req = (xGLXCreatePixmapReq *) pc; 1291 __GLXconfig *config; 1292 __GLXscreen *pGlxScreen; 1293 int err; 1294 1295 REQUEST_AT_LEAST_SIZE(xGLXCreatePixmapReq); 1296 if (req->numAttribs > (UINT32_MAX >> 3)) { 1297 client->errorValue = req->numAttribs; 1298 return BadValue; 1299 } 1300 REQUEST_FIXED_SIZE(xGLXCreatePixmapReq, req->numAttribs << 3); 1301 1302 if (!validGlxScreen(cl->client, req->screen, &pGlxScreen, &err)) 1303 return err; 1304 if (!validGlxFBConfig(cl->client, pGlxScreen, req->fbconfig, &config, &err)) 1305 return err; 1306 1307 err = DoCreateGLXPixmap(cl->client, pGlxScreen, config, 1308 req->pixmap, req->glxpixmap); 1309 if (err != Success) 1310 return err; 1311 1312 determineTextureTarget(cl->client, req->glxpixmap, 1313 (CARD32 *) (req + 1), req->numAttribs); 1314 1315 return Success; 1316} 1317 1318int 1319__glXDisp_CreateGLXPixmapWithConfigSGIX(__GLXclientState * cl, GLbyte * pc) 1320{ 1321 ClientPtr client = cl->client; 1322 xGLXCreateGLXPixmapWithConfigSGIXReq *req = 1323 (xGLXCreateGLXPixmapWithConfigSGIXReq *) pc; 1324 __GLXconfig *config; 1325 __GLXscreen *pGlxScreen; 1326 int err; 1327 1328 REQUEST_SIZE_MATCH(xGLXCreateGLXPixmapWithConfigSGIXReq); 1329 1330 if (!validGlxScreen(cl->client, req->screen, &pGlxScreen, &err)) 1331 return err; 1332 if (!validGlxFBConfig(cl->client, pGlxScreen, req->fbconfig, &config, &err)) 1333 return err; 1334 1335 return DoCreateGLXPixmap(cl->client, pGlxScreen, 1336 config, req->pixmap, req->glxpixmap); 1337} 1338 1339static int 1340DoDestroyDrawable(__GLXclientState * cl, XID glxdrawable, int type) 1341{ 1342 __GLXdrawable *pGlxDraw; 1343 int err; 1344 1345 if (!validGlxDrawable(cl->client, glxdrawable, type, 1346 DixDestroyAccess, &pGlxDraw, &err)) 1347 return err; 1348 1349 FreeResource(glxdrawable, FALSE); 1350 1351 return Success; 1352} 1353 1354int 1355__glXDisp_DestroyGLXPixmap(__GLXclientState * cl, GLbyte * pc) 1356{ 1357 xGLXDestroyGLXPixmapReq *req = (xGLXDestroyGLXPixmapReq *) pc; 1358 1359 return DoDestroyDrawable(cl, req->glxpixmap, GLX_DRAWABLE_PIXMAP); 1360} 1361 1362int 1363__glXDisp_DestroyPixmap(__GLXclientState * cl, GLbyte * pc) 1364{ 1365 ClientPtr client = cl->client; 1366 xGLXDestroyPixmapReq *req = (xGLXDestroyPixmapReq *) pc; 1367 1368 /* should be REQUEST_SIZE_MATCH, but mesa's glXDestroyPixmap used to set 1369 * length to 3 instead of 2 */ 1370 REQUEST_AT_LEAST_SIZE(xGLXDestroyPixmapReq); 1371 1372 return DoDestroyDrawable(cl, req->glxpixmap, GLX_DRAWABLE_PIXMAP); 1373} 1374 1375static int 1376DoCreatePbuffer(ClientPtr client, int screenNum, XID fbconfigId, 1377 int width, int height, XID glxDrawableId) 1378{ 1379 __GLXconfig *config; 1380 __GLXscreen *pGlxScreen; 1381 PixmapPtr pPixmap; 1382 int err; 1383 1384 if (!validGlxScreen(client, screenNum, &pGlxScreen, &err)) 1385 return err; 1386 if (!validGlxFBConfig(client, pGlxScreen, fbconfigId, &config, &err)) 1387 return err; 1388 1389 pPixmap = (*pGlxScreen->pScreen->CreatePixmap) (pGlxScreen->pScreen, 1390 width, height, 1391 config->rgbBits, 0); 1392 if (!pPixmap) 1393 return BadAlloc; 1394 1395 /* Assign the pixmap the same id as the pbuffer and add it as a 1396 * resource so it and the DRI2 drawable will be reclaimed when the 1397 * pbuffer is destroyed. */ 1398 pPixmap->drawable.id = glxDrawableId; 1399 if (!AddResource(pPixmap->drawable.id, RT_PIXMAP, pPixmap)) 1400 return BadAlloc; 1401 1402 return DoCreateGLXDrawable(client, pGlxScreen, config, &pPixmap->drawable, 1403 glxDrawableId, glxDrawableId, 1404 GLX_DRAWABLE_PBUFFER); 1405} 1406 1407int 1408__glXDisp_CreatePbuffer(__GLXclientState * cl, GLbyte * pc) 1409{ 1410 ClientPtr client = cl->client; 1411 xGLXCreatePbufferReq *req = (xGLXCreatePbufferReq *) pc; 1412 CARD32 *attrs; 1413 int width, height, i; 1414 1415 REQUEST_AT_LEAST_SIZE(xGLXCreatePbufferReq); 1416 if (req->numAttribs > (UINT32_MAX >> 3)) { 1417 client->errorValue = req->numAttribs; 1418 return BadValue; 1419 } 1420 REQUEST_FIXED_SIZE(xGLXCreatePbufferReq, req->numAttribs << 3); 1421 1422 attrs = (CARD32 *) (req + 1); 1423 width = 0; 1424 height = 0; 1425 1426 for (i = 0; i < req->numAttribs; i++) { 1427 switch (attrs[i * 2]) { 1428 case GLX_PBUFFER_WIDTH: 1429 width = attrs[i * 2 + 1]; 1430 break; 1431 case GLX_PBUFFER_HEIGHT: 1432 height = attrs[i * 2 + 1]; 1433 break; 1434 case GLX_LARGEST_PBUFFER: 1435 /* FIXME: huh... */ 1436 break; 1437 } 1438 } 1439 1440 return DoCreatePbuffer(cl->client, req->screen, req->fbconfig, 1441 width, height, req->pbuffer); 1442} 1443 1444int 1445__glXDisp_CreateGLXPbufferSGIX(__GLXclientState * cl, GLbyte * pc) 1446{ 1447 ClientPtr client = cl->client; 1448 xGLXCreateGLXPbufferSGIXReq *req = (xGLXCreateGLXPbufferSGIXReq *) pc; 1449 1450 REQUEST_AT_LEAST_SIZE(xGLXCreateGLXPbufferSGIXReq); 1451 1452 /* 1453 * We should really handle attributes correctly, but this extension 1454 * is so rare I have difficulty caring. 1455 */ 1456 return DoCreatePbuffer(cl->client, req->screen, req->fbconfig, 1457 req->width, req->height, req->pbuffer); 1458} 1459 1460int 1461__glXDisp_DestroyPbuffer(__GLXclientState * cl, GLbyte * pc) 1462{ 1463 ClientPtr client = cl->client; 1464 xGLXDestroyPbufferReq *req = (xGLXDestroyPbufferReq *) pc; 1465 1466 REQUEST_SIZE_MATCH(xGLXDestroyPbufferReq); 1467 1468 return DoDestroyDrawable(cl, req->pbuffer, GLX_DRAWABLE_PBUFFER); 1469} 1470 1471int 1472__glXDisp_DestroyGLXPbufferSGIX(__GLXclientState * cl, GLbyte * pc) 1473{ 1474 ClientPtr client = cl->client; 1475 xGLXDestroyGLXPbufferSGIXReq *req = (xGLXDestroyGLXPbufferSGIXReq *) pc; 1476 1477 REQUEST_SIZE_MATCH(xGLXDestroyGLXPbufferSGIXReq); 1478 1479 return DoDestroyDrawable(cl, req->pbuffer, GLX_DRAWABLE_PBUFFER); 1480} 1481 1482static int 1483DoChangeDrawableAttributes(ClientPtr client, XID glxdrawable, 1484 int numAttribs, CARD32 *attribs) 1485{ 1486 __GLXdrawable *pGlxDraw; 1487 int i, err; 1488 1489 if (!validGlxDrawable(client, glxdrawable, GLX_DRAWABLE_ANY, 1490 DixSetAttrAccess, &pGlxDraw, &err)) 1491 return err; 1492 1493 for (i = 0; i < numAttribs; i++) { 1494 switch (attribs[i * 2]) { 1495 case GLX_EVENT_MASK: 1496 /* All we do is to record the event mask so we can send it 1497 * back when queried. We never actually clobber the 1498 * pbuffers, so we never need to send out the event. */ 1499 pGlxDraw->eventMask = attribs[i * 2 + 1]; 1500 break; 1501 } 1502 } 1503 1504 return Success; 1505} 1506 1507int 1508__glXDisp_ChangeDrawableAttributes(__GLXclientState * cl, GLbyte * pc) 1509{ 1510 ClientPtr client = cl->client; 1511 xGLXChangeDrawableAttributesReq *req = 1512 (xGLXChangeDrawableAttributesReq *) pc; 1513 1514 REQUEST_AT_LEAST_SIZE(xGLXChangeDrawableAttributesReq); 1515 if (req->numAttribs > (UINT32_MAX >> 3)) { 1516 client->errorValue = req->numAttribs; 1517 return BadValue; 1518 } 1519#if 0 1520 /* mesa sends an additional 8 bytes */ 1521 REQUEST_FIXED_SIZE(xGLXChangeDrawableAttributesReq, req->numAttribs << 3); 1522#else 1523 if (((sizeof(xGLXChangeDrawableAttributesReq) + 1524 (req->numAttribs << 3)) >> 2) < client->req_len) 1525 return BadLength; 1526#endif 1527 1528 return DoChangeDrawableAttributes(cl->client, req->drawable, 1529 req->numAttribs, (CARD32 *) (req + 1)); 1530} 1531 1532int 1533__glXDisp_ChangeDrawableAttributesSGIX(__GLXclientState * cl, GLbyte * pc) 1534{ 1535 ClientPtr client = cl->client; 1536 xGLXChangeDrawableAttributesSGIXReq *req = 1537 (xGLXChangeDrawableAttributesSGIXReq *) pc; 1538 1539 REQUEST_AT_LEAST_SIZE(xGLXChangeDrawableAttributesSGIXReq); 1540 if (req->numAttribs > (UINT32_MAX >> 3)) { 1541 client->errorValue = req->numAttribs; 1542 return BadValue; 1543 } 1544 REQUEST_FIXED_SIZE(xGLXChangeDrawableAttributesSGIXReq, 1545 req->numAttribs << 3); 1546 1547 return DoChangeDrawableAttributes(cl->client, req->drawable, 1548 req->numAttribs, (CARD32 *) (req + 1)); 1549} 1550 1551int 1552__glXDisp_CreateWindow(__GLXclientState * cl, GLbyte * pc) 1553{ 1554 xGLXCreateWindowReq *req = (xGLXCreateWindowReq *) pc; 1555 __GLXconfig *config; 1556 __GLXscreen *pGlxScreen; 1557 ClientPtr client = cl->client; 1558 DrawablePtr pDraw; 1559 int err; 1560 1561 REQUEST_AT_LEAST_SIZE(xGLXCreateWindowReq); 1562 if (req->numAttribs > (UINT32_MAX >> 3)) { 1563 client->errorValue = req->numAttribs; 1564 return BadValue; 1565 } 1566 REQUEST_FIXED_SIZE(xGLXCreateWindowReq, req->numAttribs << 3); 1567 1568 if (!validGlxScreen(client, req->screen, &pGlxScreen, &err)) 1569 return err; 1570 if (!validGlxFBConfig(client, pGlxScreen, req->fbconfig, &config, &err)) 1571 return err; 1572 1573 err = dixLookupDrawable(&pDraw, req->window, client, 0, DixAddAccess); 1574 if (err != Success || pDraw->type != DRAWABLE_WINDOW) { 1575 client->errorValue = req->window; 1576 return BadWindow; 1577 } 1578 1579 if (!validGlxFBConfigForWindow(client, config, pDraw, &err)) 1580 return err; 1581 1582 return DoCreateGLXDrawable(client, pGlxScreen, config, 1583 pDraw, req->window, 1584 req->glxwindow, GLX_DRAWABLE_WINDOW); 1585} 1586 1587int 1588__glXDisp_DestroyWindow(__GLXclientState * cl, GLbyte * pc) 1589{ 1590 ClientPtr client = cl->client; 1591 xGLXDestroyWindowReq *req = (xGLXDestroyWindowReq *) pc; 1592 1593 /* mesa's glXDestroyWindow used to set length to 3 instead of 2 */ 1594 REQUEST_AT_LEAST_SIZE(xGLXDestroyWindowReq); 1595 1596 return DoDestroyDrawable(cl, req->glxwindow, GLX_DRAWABLE_WINDOW); 1597} 1598 1599/*****************************************************************************/ 1600 1601/* 1602** NOTE: There is no portable implementation for swap buffers as of 1603** this time that is of value. Consequently, this code must be 1604** implemented by somebody other than SGI. 1605*/ 1606int 1607__glXDisp_SwapBuffers(__GLXclientState * cl, GLbyte * pc) 1608{ 1609 ClientPtr client = cl->client; 1610 xGLXSwapBuffersReq *req = (xGLXSwapBuffersReq *) pc; 1611 GLXContextTag tag; 1612 XID drawId; 1613 __GLXcontext *glxc = NULL; 1614 __GLXdrawable *pGlxDraw; 1615 int error; 1616 1617 tag = req->contextTag; 1618 drawId = req->drawable; 1619 if (tag) { 1620 glxc = __glXLookupContextByTag(cl, tag); 1621 if (!glxc) { 1622 return __glXError(GLXBadContextTag); 1623 } 1624 /* 1625 ** The calling thread is swapping its current drawable. In this case, 1626 ** glxSwapBuffers is in both GL and X streams, in terms of 1627 ** sequentiality. 1628 */ 1629 if (__glXForceCurrent(cl, tag, &error)) { 1630 /* 1631 ** Do whatever is needed to make sure that all preceding requests 1632 ** in both streams are completed before the swap is executed. 1633 */ 1634 glFinish(); 1635 } 1636 else { 1637 return error; 1638 } 1639 } 1640 1641 pGlxDraw = __glXGetDrawable(glxc, drawId, client, &error); 1642 if (pGlxDraw == NULL) 1643 return error; 1644 1645 if (pGlxDraw->type == DRAWABLE_WINDOW && 1646 (*pGlxDraw->swapBuffers) (cl->client, pGlxDraw) == GL_FALSE) 1647 return __glXError(GLXBadDrawable); 1648 1649 return Success; 1650} 1651 1652static int 1653DoQueryContext(__GLXclientState * cl, GLXContextID gcId) 1654{ 1655 ClientPtr client = cl->client; 1656 __GLXcontext *ctx; 1657 xGLXQueryContextInfoEXTReply reply; 1658 int nProps = 5; 1659 int sendBuf[nProps * 2]; 1660 int nReplyBytes; 1661 int err; 1662 1663 if (!validGlxContext(cl->client, gcId, DixReadAccess, &ctx, &err)) 1664 return err; 1665 1666 reply = (xGLXQueryContextInfoEXTReply) { 1667 .type = X_Reply, 1668 .sequenceNumber = client->sequence, 1669 .length = nProps << 1, 1670 .n = nProps 1671 }; 1672 1673 nReplyBytes = reply.length << 2; 1674 sendBuf[0] = GLX_SHARE_CONTEXT_EXT; 1675 sendBuf[1] = (int) (ctx->share_id); 1676 sendBuf[2] = GLX_VISUAL_ID_EXT; 1677 sendBuf[3] = (int) (ctx->config ? ctx->config->visualID : 0); 1678 sendBuf[4] = GLX_SCREEN_EXT; 1679 sendBuf[5] = (int) (ctx->pGlxScreen->pScreen->myNum); 1680 sendBuf[6] = GLX_FBCONFIG_ID; 1681 sendBuf[7] = (int) (ctx->config ? ctx->config->fbconfigID : 0); 1682 sendBuf[8] = GLX_RENDER_TYPE; 1683 sendBuf[9] = (int) (ctx->renderType); 1684 1685 if (client->swapped) { 1686 int length = reply.length; 1687 1688 __GLX_DECLARE_SWAP_VARIABLES; 1689 __GLX_DECLARE_SWAP_ARRAY_VARIABLES; 1690 __GLX_SWAP_SHORT(&reply.sequenceNumber); 1691 __GLX_SWAP_INT(&reply.length); 1692 __GLX_SWAP_INT(&reply.n); 1693 WriteToClient(client, sz_xGLXQueryContextInfoEXTReply, &reply); 1694 __GLX_SWAP_INT_ARRAY((int *) sendBuf, length); 1695 WriteToClient(client, length << 2, sendBuf); 1696 } 1697 else { 1698 WriteToClient(client, sz_xGLXQueryContextInfoEXTReply, &reply); 1699 WriteToClient(client, nReplyBytes, sendBuf); 1700 } 1701 1702 return Success; 1703} 1704 1705int 1706__glXDisp_QueryContextInfoEXT(__GLXclientState * cl, GLbyte * pc) 1707{ 1708 ClientPtr client = cl->client; 1709 xGLXQueryContextInfoEXTReq *req = (xGLXQueryContextInfoEXTReq *) pc; 1710 1711 REQUEST_SIZE_MATCH(xGLXQueryContextInfoEXTReq); 1712 1713 return DoQueryContext(cl, req->context); 1714} 1715 1716int 1717__glXDisp_QueryContext(__GLXclientState * cl, GLbyte * pc) 1718{ 1719 xGLXQueryContextReq *req = (xGLXQueryContextReq *) pc; 1720 1721 return DoQueryContext(cl, req->context); 1722} 1723 1724int 1725__glXDisp_BindTexImageEXT(__GLXclientState * cl, GLbyte * pc) 1726{ 1727 xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *) pc; 1728 ClientPtr client = cl->client; 1729 __GLXcontext *context; 1730 __GLXdrawable *pGlxDraw; 1731 GLXDrawable drawId; 1732 int buffer; 1733 int error; 1734 CARD32 num_attribs; 1735 1736 if ((sizeof(xGLXVendorPrivateReq) + 12) >> 2 > client->req_len) 1737 return BadLength; 1738 1739 pc += __GLX_VENDPRIV_HDR_SIZE; 1740 1741 drawId = *((CARD32 *) (pc)); 1742 buffer = *((INT32 *) (pc + 4)); 1743 num_attribs = *((CARD32 *) (pc + 8)); 1744 if (num_attribs > (UINT32_MAX >> 3)) { 1745 client->errorValue = num_attribs; 1746 return BadValue; 1747 } 1748 REQUEST_FIXED_SIZE(xGLXVendorPrivateReq, 12 + (num_attribs << 3)); 1749 1750 if (buffer != GLX_FRONT_LEFT_EXT) 1751 return __glXError(GLXBadPixmap); 1752 1753 context = __glXForceCurrent(cl, req->contextTag, &error); 1754 if (!context) 1755 return error; 1756 1757 if (!validGlxDrawable(client, drawId, GLX_DRAWABLE_PIXMAP, 1758 DixReadAccess, &pGlxDraw, &error)) 1759 return error; 1760 1761 if (!context->bindTexImage) 1762 return __glXError(GLXUnsupportedPrivateRequest); 1763 1764 return context->bindTexImage(context, buffer, pGlxDraw); 1765} 1766 1767int 1768__glXDisp_ReleaseTexImageEXT(__GLXclientState * cl, GLbyte * pc) 1769{ 1770 xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *) pc; 1771 ClientPtr client = cl->client; 1772 __GLXdrawable *pGlxDraw; 1773 __GLXcontext *context; 1774 GLXDrawable drawId; 1775 int buffer; 1776 int error; 1777 1778 REQUEST_FIXED_SIZE(xGLXVendorPrivateReq, 8); 1779 1780 pc += __GLX_VENDPRIV_HDR_SIZE; 1781 1782 drawId = *((CARD32 *) (pc)); 1783 buffer = *((INT32 *) (pc + 4)); 1784 1785 context = __glXForceCurrent(cl, req->contextTag, &error); 1786 if (!context) 1787 return error; 1788 1789 if (!validGlxDrawable(client, drawId, GLX_DRAWABLE_PIXMAP, 1790 DixReadAccess, &pGlxDraw, &error)) 1791 return error; 1792 1793 if (!context->releaseTexImage) 1794 return __glXError(GLXUnsupportedPrivateRequest); 1795 1796 return context->releaseTexImage(context, buffer, pGlxDraw); 1797} 1798 1799int 1800__glXDisp_CopySubBufferMESA(__GLXclientState * cl, GLbyte * pc) 1801{ 1802 xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *) pc; 1803 GLXContextTag tag = req->contextTag; 1804 __GLXcontext *glxc = NULL; 1805 __GLXdrawable *pGlxDraw; 1806 ClientPtr client = cl->client; 1807 GLXDrawable drawId; 1808 int error; 1809 int x, y, width, height; 1810 1811 (void) client; 1812 (void) req; 1813 1814 REQUEST_FIXED_SIZE(xGLXVendorPrivateReq, 20); 1815 1816 pc += __GLX_VENDPRIV_HDR_SIZE; 1817 1818 drawId = *((CARD32 *) (pc)); 1819 x = *((INT32 *) (pc + 4)); 1820 y = *((INT32 *) (pc + 8)); 1821 width = *((INT32 *) (pc + 12)); 1822 height = *((INT32 *) (pc + 16)); 1823 1824 if (tag) { 1825 glxc = __glXLookupContextByTag(cl, tag); 1826 if (!glxc) { 1827 return __glXError(GLXBadContextTag); 1828 } 1829 /* 1830 ** The calling thread is swapping its current drawable. In this case, 1831 ** glxSwapBuffers is in both GL and X streams, in terms of 1832 ** sequentiality. 1833 */ 1834 if (__glXForceCurrent(cl, tag, &error)) { 1835 /* 1836 ** Do whatever is needed to make sure that all preceding requests 1837 ** in both streams are completed before the swap is executed. 1838 */ 1839 glFinish(); 1840 } 1841 else { 1842 return error; 1843 } 1844 } 1845 1846 pGlxDraw = __glXGetDrawable(glxc, drawId, client, &error); 1847 if (!pGlxDraw) 1848 return error; 1849 1850 if (pGlxDraw == NULL || 1851 pGlxDraw->type != GLX_DRAWABLE_WINDOW || 1852 pGlxDraw->copySubBuffer == NULL) 1853 return __glXError(GLXBadDrawable); 1854 1855 (*pGlxDraw->copySubBuffer) (pGlxDraw, x, y, width, height); 1856 1857 return Success; 1858} 1859 1860/* hack for old glxext.h */ 1861#ifndef GLX_STEREO_TREE_EXT 1862#define GLX_STEREO_TREE_EXT 0x20F5 1863#endif 1864 1865/* 1866** Get drawable attributes 1867*/ 1868static int 1869DoGetDrawableAttributes(__GLXclientState * cl, XID drawId) 1870{ 1871 ClientPtr client = cl->client; 1872 xGLXGetDrawableAttributesReply reply; 1873 __GLXdrawable *pGlxDraw = NULL; 1874 DrawablePtr pDraw; 1875 CARD32 attributes[20]; 1876 int num = 0, error; 1877 1878 if (!validGlxDrawable(client, drawId, GLX_DRAWABLE_ANY, 1879 DixGetAttrAccess, &pGlxDraw, &error)) { 1880 /* hack for GLX 1.2 naked windows */ 1881 int err = dixLookupWindow((WindowPtr *)&pDraw, drawId, client, 1882 DixGetAttrAccess); 1883 if (err != Success) 1884 return __glXError(GLXBadDrawable); 1885 } 1886 if (pGlxDraw) 1887 pDraw = pGlxDraw->pDraw; 1888 1889#define ATTRIB(a, v) do { \ 1890 attributes[2*num] = (a); \ 1891 attributes[2*num+1] = (v); \ 1892 num++; \ 1893 } while (0) 1894 1895 ATTRIB(GLX_Y_INVERTED_EXT, GL_FALSE); 1896 ATTRIB(GLX_WIDTH, pDraw->width); 1897 ATTRIB(GLX_HEIGHT, pDraw->height); 1898 ATTRIB(GLX_SCREEN, pDraw->pScreen->myNum); 1899 if (pGlxDraw) { 1900 ATTRIB(GLX_TEXTURE_TARGET_EXT, 1901 pGlxDraw->target == GL_TEXTURE_2D ? 1902 GLX_TEXTURE_2D_EXT : GLX_TEXTURE_RECTANGLE_EXT); 1903 ATTRIB(GLX_EVENT_MASK, pGlxDraw->eventMask); 1904 ATTRIB(GLX_FBCONFIG_ID, pGlxDraw->config->fbconfigID); 1905 if (pGlxDraw->type == GLX_DRAWABLE_PBUFFER) { 1906 ATTRIB(GLX_PRESERVED_CONTENTS, GL_TRUE); 1907 } 1908 if (pGlxDraw->type == GLX_DRAWABLE_WINDOW) { 1909 ATTRIB(GLX_STEREO_TREE_EXT, 0); 1910 } 1911 } 1912 1913 /* GLX_EXT_get_drawable_type */ 1914 if (!pGlxDraw || pGlxDraw->type == GLX_DRAWABLE_WINDOW) 1915 ATTRIB(GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT); 1916 else if (pGlxDraw->type == GLX_DRAWABLE_PIXMAP) 1917 ATTRIB(GLX_DRAWABLE_TYPE, GLX_PIXMAP_BIT); 1918 else if (pGlxDraw->type == GLX_DRAWABLE_PBUFFER) 1919 ATTRIB(GLX_DRAWABLE_TYPE, GLX_PBUFFER_BIT); 1920#undef ATTRIB 1921 1922 reply = (xGLXGetDrawableAttributesReply) { 1923 .type = X_Reply, 1924 .sequenceNumber = client->sequence, 1925 .length = num << 1, 1926 .numAttribs = num 1927 }; 1928 1929 if (client->swapped) { 1930 int length = reply.length; 1931 1932 __GLX_DECLARE_SWAP_VARIABLES; 1933 __GLX_DECLARE_SWAP_ARRAY_VARIABLES; 1934 __GLX_SWAP_SHORT(&reply.sequenceNumber); 1935 __GLX_SWAP_INT(&reply.length); 1936 __GLX_SWAP_INT(&reply.numAttribs); 1937 WriteToClient(client, sz_xGLXGetDrawableAttributesReply, &reply); 1938 __GLX_SWAP_INT_ARRAY((int *) attributes, length); 1939 WriteToClient(client, length << 2, attributes); 1940 } 1941 else { 1942 WriteToClient(client, sz_xGLXGetDrawableAttributesReply, &reply); 1943 WriteToClient(client, reply.length * sizeof(CARD32), attributes); 1944 } 1945 1946 return Success; 1947} 1948 1949int 1950__glXDisp_GetDrawableAttributes(__GLXclientState * cl, GLbyte * pc) 1951{ 1952 ClientPtr client = cl->client; 1953 xGLXGetDrawableAttributesReq *req = (xGLXGetDrawableAttributesReq *) pc; 1954 1955 /* this should be REQUEST_SIZE_MATCH, but mesa sends an additional 4 bytes */ 1956 REQUEST_AT_LEAST_SIZE(xGLXGetDrawableAttributesReq); 1957 1958 return DoGetDrawableAttributes(cl, req->drawable); 1959} 1960 1961int 1962__glXDisp_GetDrawableAttributesSGIX(__GLXclientState * cl, GLbyte * pc) 1963{ 1964 ClientPtr client = cl->client; 1965 xGLXGetDrawableAttributesSGIXReq *req = 1966 (xGLXGetDrawableAttributesSGIXReq *) pc; 1967 1968 REQUEST_SIZE_MATCH(xGLXGetDrawableAttributesSGIXReq); 1969 1970 return DoGetDrawableAttributes(cl, req->drawable); 1971} 1972 1973/************************************************************************/ 1974 1975/* 1976** Render and Renderlarge are not in the GLX API. They are used by the GLX 1977** client library to send batches of GL rendering commands. 1978*/ 1979 1980/* 1981** Reset state used to keep track of large (multi-request) commands. 1982*/ 1983static void 1984ResetLargeCommandStatus(__GLXcontext *cx) 1985{ 1986 cx->largeCmdBytesSoFar = 0; 1987 cx->largeCmdBytesTotal = 0; 1988 cx->largeCmdRequestsSoFar = 0; 1989 cx->largeCmdRequestsTotal = 0; 1990} 1991 1992/* 1993** Execute all the drawing commands in a request. 1994*/ 1995int 1996__glXDisp_Render(__GLXclientState * cl, GLbyte * pc) 1997{ 1998 xGLXRenderReq *req; 1999 ClientPtr client = cl->client; 2000 int left, cmdlen, error; 2001 int commandsDone; 2002 CARD16 opcode; 2003 __GLXrenderHeader *hdr; 2004 __GLXcontext *glxc; 2005 2006 __GLX_DECLARE_SWAP_VARIABLES; 2007 2008 REQUEST_AT_LEAST_SIZE(xGLXRenderReq); 2009 2010 req = (xGLXRenderReq *) pc; 2011 if (client->swapped) { 2012 __GLX_SWAP_SHORT(&req->length); 2013 __GLX_SWAP_INT(&req->contextTag); 2014 } 2015 2016 glxc = __glXForceCurrent(cl, req->contextTag, &error); 2017 if (!glxc) { 2018 return error; 2019 } 2020 2021 commandsDone = 0; 2022 pc += sz_xGLXRenderReq; 2023 left = (req->length << 2) - sz_xGLXRenderReq; 2024 while (left > 0) { 2025 __GLXrenderSizeData entry; 2026 int extra = 0; 2027 __GLXdispatchRenderProcPtr proc; 2028 int err; 2029 2030 if (left < sizeof(__GLXrenderHeader)) 2031 return BadLength; 2032 2033 /* 2034 ** Verify that the header length and the overall length agree. 2035 ** Also, each command must be word aligned. 2036 */ 2037 hdr = (__GLXrenderHeader *) pc; 2038 if (client->swapped) { 2039 __GLX_SWAP_SHORT(&hdr->length); 2040 __GLX_SWAP_SHORT(&hdr->opcode); 2041 } 2042 cmdlen = hdr->length; 2043 opcode = hdr->opcode; 2044 2045 if (left < cmdlen) 2046 return BadLength; 2047 2048 /* 2049 ** Check for core opcodes and grab entry data. 2050 */ 2051 err = __glXGetProtocolSizeData(&Render_dispatch_info, opcode, &entry); 2052 proc = (__GLXdispatchRenderProcPtr) 2053 __glXGetProtocolDecodeFunction(&Render_dispatch_info, 2054 opcode, client->swapped); 2055 2056 if ((err < 0) || (proc == NULL)) { 2057 client->errorValue = commandsDone; 2058 return __glXError(GLXBadRenderRequest); 2059 } 2060 2061 if (cmdlen < entry.bytes) { 2062 return BadLength; 2063 } 2064 2065 if (entry.varsize) { 2066 /* variable size command */ 2067 extra = (*entry.varsize) (pc + __GLX_RENDER_HDR_SIZE, 2068 client->swapped, 2069 left - __GLX_RENDER_HDR_SIZE); 2070 if (extra < 0) { 2071 return BadLength; 2072 } 2073 } 2074 2075 if (cmdlen != safe_pad(safe_add(entry.bytes, extra))) { 2076 return BadLength; 2077 } 2078 2079 /* 2080 ** Skip over the header and execute the command. We allow the 2081 ** caller to trash the command memory. This is useful especially 2082 ** for things that require double alignment - they can just shift 2083 ** the data towards lower memory (trashing the header) by 4 bytes 2084 ** and achieve the required alignment. 2085 */ 2086 (*proc) (pc + __GLX_RENDER_HDR_SIZE); 2087 pc += cmdlen; 2088 left -= cmdlen; 2089 commandsDone++; 2090 } 2091 return Success; 2092} 2093 2094/* 2095** Execute a large rendering request (one that spans multiple X requests). 2096*/ 2097int 2098__glXDisp_RenderLarge(__GLXclientState * cl, GLbyte * pc) 2099{ 2100 xGLXRenderLargeReq *req; 2101 ClientPtr client = cl->client; 2102 size_t dataBytes; 2103 __GLXrenderLargeHeader *hdr; 2104 __GLXcontext *glxc; 2105 int error; 2106 CARD16 opcode; 2107 2108 __GLX_DECLARE_SWAP_VARIABLES; 2109 2110 REQUEST_AT_LEAST_SIZE(xGLXRenderLargeReq); 2111 2112 req = (xGLXRenderLargeReq *) pc; 2113 if (client->swapped) { 2114 __GLX_SWAP_SHORT(&req->length); 2115 __GLX_SWAP_INT(&req->contextTag); 2116 __GLX_SWAP_INT(&req->dataBytes); 2117 __GLX_SWAP_SHORT(&req->requestNumber); 2118 __GLX_SWAP_SHORT(&req->requestTotal); 2119 } 2120 2121 glxc = __glXForceCurrent(cl, req->contextTag, &error); 2122 if (!glxc) { 2123 return error; 2124 } 2125 if (safe_pad(req->dataBytes) < 0) 2126 return BadLength; 2127 dataBytes = req->dataBytes; 2128 2129 /* 2130 ** Check the request length. 2131 */ 2132 if ((req->length << 2) != safe_pad(dataBytes) + sz_xGLXRenderLargeReq) { 2133 client->errorValue = req->length; 2134 /* Reset in case this isn't 1st request. */ 2135 ResetLargeCommandStatus(glxc); 2136 return BadLength; 2137 } 2138 pc += sz_xGLXRenderLargeReq; 2139 2140 if (glxc->largeCmdRequestsSoFar == 0) { 2141 __GLXrenderSizeData entry; 2142 int extra = 0; 2143 int left = (req->length << 2) - sz_xGLXRenderLargeReq; 2144 int cmdlen; 2145 int err; 2146 2147 /* 2148 ** This is the first request of a multi request command. 2149 ** Make enough space in the buffer, then copy the entire request. 2150 */ 2151 if (req->requestNumber != 1) { 2152 client->errorValue = req->requestNumber; 2153 return __glXError(GLXBadLargeRequest); 2154 } 2155 2156 if (dataBytes < __GLX_RENDER_LARGE_HDR_SIZE) 2157 return BadLength; 2158 2159 hdr = (__GLXrenderLargeHeader *) pc; 2160 if (client->swapped) { 2161 __GLX_SWAP_INT(&hdr->length); 2162 __GLX_SWAP_INT(&hdr->opcode); 2163 } 2164 opcode = hdr->opcode; 2165 if ((cmdlen = safe_pad(hdr->length)) < 0) 2166 return BadLength; 2167 2168 /* 2169 ** Check for core opcodes and grab entry data. 2170 */ 2171 err = __glXGetProtocolSizeData(&Render_dispatch_info, opcode, &entry); 2172 if (err < 0) { 2173 client->errorValue = opcode; 2174 return __glXError(GLXBadLargeRequest); 2175 } 2176 2177 if (entry.varsize) { 2178 /* 2179 ** If it's a variable-size command (a command whose length must 2180 ** be computed from its parameters), all the parameters needed 2181 ** will be in the 1st request, so it's okay to do this. 2182 */ 2183 extra = (*entry.varsize) (pc + __GLX_RENDER_LARGE_HDR_SIZE, 2184 client->swapped, 2185 left - __GLX_RENDER_LARGE_HDR_SIZE); 2186 if (extra < 0) { 2187 return BadLength; 2188 } 2189 } 2190 2191 /* the +4 is safe because we know entry.bytes is small */ 2192 if (cmdlen != safe_pad(safe_add(entry.bytes + 4, extra))) { 2193 return BadLength; 2194 } 2195 2196 /* 2197 ** Make enough space in the buffer, then copy the entire request. 2198 */ 2199 if (glxc->largeCmdBufSize < cmdlen) { 2200 GLbyte *newbuf = glxc->largeCmdBuf; 2201 2202 if (!(newbuf = realloc(newbuf, cmdlen))) 2203 return BadAlloc; 2204 2205 glxc->largeCmdBuf = newbuf; 2206 glxc->largeCmdBufSize = cmdlen; 2207 } 2208 memcpy(glxc->largeCmdBuf, pc, dataBytes); 2209 2210 glxc->largeCmdBytesSoFar = dataBytes; 2211 glxc->largeCmdBytesTotal = cmdlen; 2212 glxc->largeCmdRequestsSoFar = 1; 2213 glxc->largeCmdRequestsTotal = req->requestTotal; 2214 return Success; 2215 2216 } 2217 else { 2218 /* 2219 ** We are receiving subsequent (i.e. not the first) requests of a 2220 ** multi request command. 2221 */ 2222 int bytesSoFar; /* including this packet */ 2223 2224 /* 2225 ** Check the request number and the total request count. 2226 */ 2227 if (req->requestNumber != glxc->largeCmdRequestsSoFar + 1) { 2228 client->errorValue = req->requestNumber; 2229 ResetLargeCommandStatus(glxc); 2230 return __glXError(GLXBadLargeRequest); 2231 } 2232 if (req->requestTotal != glxc->largeCmdRequestsTotal) { 2233 client->errorValue = req->requestTotal; 2234 ResetLargeCommandStatus(glxc); 2235 return __glXError(GLXBadLargeRequest); 2236 } 2237 2238 /* 2239 ** Check that we didn't get too much data. 2240 */ 2241 if ((bytesSoFar = safe_add(glxc->largeCmdBytesSoFar, dataBytes)) < 0) { 2242 client->errorValue = dataBytes; 2243 ResetLargeCommandStatus(glxc); 2244 return __glXError(GLXBadLargeRequest); 2245 } 2246 2247 if (bytesSoFar > glxc->largeCmdBytesTotal) { 2248 client->errorValue = dataBytes; 2249 ResetLargeCommandStatus(glxc); 2250 return __glXError(GLXBadLargeRequest); 2251 } 2252 2253 memcpy(glxc->largeCmdBuf + glxc->largeCmdBytesSoFar, pc, dataBytes); 2254 glxc->largeCmdBytesSoFar += dataBytes; 2255 glxc->largeCmdRequestsSoFar++; 2256 2257 if (req->requestNumber == glxc->largeCmdRequestsTotal) { 2258 __GLXdispatchRenderProcPtr proc; 2259 2260 /* 2261 ** This is the last request; it must have enough bytes to complete 2262 ** the command. 2263 */ 2264 /* NOTE: the pad macro below is needed because the client library 2265 ** pads the total byte count, but not the per-request byte counts. 2266 ** The Protocol Encoding says the total byte count should not be 2267 ** padded, so a proposal will be made to the ARB to relax the 2268 ** padding constraint on the total byte count, thus preserving 2269 ** backward compatibility. Meanwhile, the padding done below 2270 ** fixes a bug that did not allow large commands of odd sizes to 2271 ** be accepted by the server. 2272 */ 2273 if (safe_pad(glxc->largeCmdBytesSoFar) != glxc->largeCmdBytesTotal) { 2274 client->errorValue = dataBytes; 2275 ResetLargeCommandStatus(glxc); 2276 return __glXError(GLXBadLargeRequest); 2277 } 2278 hdr = (__GLXrenderLargeHeader *) glxc->largeCmdBuf; 2279 /* 2280 ** The opcode and length field in the header had already been 2281 ** swapped when the first request was received. 2282 ** 2283 ** Use the opcode to index into the procedure table. 2284 */ 2285 opcode = hdr->opcode; 2286 2287 proc = (__GLXdispatchRenderProcPtr) 2288 __glXGetProtocolDecodeFunction(&Render_dispatch_info, opcode, 2289 client->swapped); 2290 if (proc == NULL) { 2291 client->errorValue = opcode; 2292 return __glXError(GLXBadLargeRequest); 2293 } 2294 2295 /* 2296 ** Skip over the header and execute the command. 2297 */ 2298 (*proc) (glxc->largeCmdBuf + __GLX_RENDER_LARGE_HDR_SIZE); 2299 2300 /* 2301 ** Reset for the next RenderLarge series. 2302 */ 2303 ResetLargeCommandStatus(glxc); 2304 } 2305 else { 2306 /* 2307 ** This is neither the first nor the last request. 2308 */ 2309 } 2310 return Success; 2311 } 2312} 2313 2314/************************************************************************/ 2315 2316/* 2317** No support is provided for the vendor-private requests other than 2318** allocating the entry points in the dispatch table. 2319*/ 2320 2321int 2322__glXDisp_VendorPrivate(__GLXclientState * cl, GLbyte * pc) 2323{ 2324 ClientPtr client = cl->client; 2325 xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *) pc; 2326 GLint vendorcode = req->vendorCode; 2327 __GLXdispatchVendorPrivProcPtr proc; 2328 2329 REQUEST_AT_LEAST_SIZE(xGLXVendorPrivateReq); 2330 2331 proc = (__GLXdispatchVendorPrivProcPtr) 2332 __glXGetProtocolDecodeFunction(&VendorPriv_dispatch_info, 2333 vendorcode, 0); 2334 if (proc != NULL) { 2335 return (*proc) (cl, (GLbyte *) req); 2336 } 2337 2338 cl->client->errorValue = req->vendorCode; 2339 return __glXError(GLXUnsupportedPrivateRequest); 2340} 2341 2342int 2343__glXDisp_VendorPrivateWithReply(__GLXclientState * cl, GLbyte * pc) 2344{ 2345 ClientPtr client = cl->client; 2346 xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *) pc; 2347 GLint vendorcode = req->vendorCode; 2348 __GLXdispatchVendorPrivProcPtr proc; 2349 2350 REQUEST_AT_LEAST_SIZE(xGLXVendorPrivateReq); 2351 2352 proc = (__GLXdispatchVendorPrivProcPtr) 2353 __glXGetProtocolDecodeFunction(&VendorPriv_dispatch_info, 2354 vendorcode, 0); 2355 if (proc != NULL) { 2356 return (*proc) (cl, (GLbyte *) req); 2357 } 2358 2359 cl->client->errorValue = vendorcode; 2360 return __glXError(GLXUnsupportedPrivateRequest); 2361} 2362 2363int 2364__glXDisp_QueryExtensionsString(__GLXclientState * cl, GLbyte * pc) 2365{ 2366 ClientPtr client = cl->client; 2367 xGLXQueryExtensionsStringReq *req = (xGLXQueryExtensionsStringReq *) pc; 2368 xGLXQueryExtensionsStringReply reply; 2369 __GLXscreen *pGlxScreen; 2370 size_t n, length; 2371 char *buf; 2372 int err; 2373 2374 if (!validGlxScreen(client, req->screen, &pGlxScreen, &err)) 2375 return err; 2376 2377 n = strlen(pGlxScreen->GLXextensions) + 1; 2378 length = __GLX_PAD(n) >> 2; 2379 reply = (xGLXQueryExtensionsStringReply) { 2380 .type = X_Reply, 2381 .sequenceNumber = client->sequence, 2382 .length = length, 2383 .n = n 2384 }; 2385 2386 /* Allocate buffer to make sure it's a multiple of 4 bytes big. */ 2387 buf = calloc(length, 4); 2388 if (buf == NULL) 2389 return BadAlloc; 2390 memcpy(buf, pGlxScreen->GLXextensions, n); 2391 2392 if (client->swapped) { 2393 __GLX_DECLARE_SWAP_VARIABLES; 2394 __GLX_DECLARE_SWAP_ARRAY_VARIABLES; 2395 __GLX_SWAP_SHORT(&reply.sequenceNumber); 2396 __GLX_SWAP_INT(&reply.length); 2397 __GLX_SWAP_INT(&reply.n); 2398 WriteToClient(client, sz_xGLXQueryExtensionsStringReply, &reply); 2399 __GLX_SWAP_INT_ARRAY((int *) buf, length); 2400 WriteToClient(client, length << 2, buf); 2401 } 2402 else { 2403 WriteToClient(client, sz_xGLXQueryExtensionsStringReply, &reply); 2404 WriteToClient(client, (int) (length << 2), buf); 2405 } 2406 2407 free(buf); 2408 return Success; 2409} 2410 2411#ifndef GLX_VENDOR_NAMES_EXT 2412#define GLX_VENDOR_NAMES_EXT 0x20F6 2413#endif 2414 2415int 2416__glXDisp_QueryServerString(__GLXclientState * cl, GLbyte * pc) 2417{ 2418 ClientPtr client = cl->client; 2419 xGLXQueryServerStringReq *req = (xGLXQueryServerStringReq *) pc; 2420 xGLXQueryServerStringReply reply; 2421 size_t n, length; 2422 const char *ptr; 2423 char *buf; 2424 __GLXscreen *pGlxScreen; 2425 int err; 2426 2427 if (!validGlxScreen(client, req->screen, &pGlxScreen, &err)) 2428 return err; 2429 2430 switch (req->name) { 2431 case GLX_VENDOR: 2432 ptr = GLXServerVendorName; 2433 break; 2434 case GLX_VERSION: 2435 ptr = "1.4"; 2436 break; 2437 case GLX_EXTENSIONS: 2438 ptr = pGlxScreen->GLXextensions; 2439 break; 2440 case GLX_VENDOR_NAMES_EXT: 2441 if (pGlxScreen->glvnd) { 2442 ptr = pGlxScreen->glvnd; 2443 break; 2444 } 2445 /* else fall through */ 2446 default: 2447 return BadValue; 2448 } 2449 2450 n = strlen(ptr) + 1; 2451 length = __GLX_PAD(n) >> 2; 2452 reply = (xGLXQueryServerStringReply) { 2453 .type = X_Reply, 2454 .sequenceNumber = client->sequence, 2455 .length = length, 2456 .n = n 2457 }; 2458 2459 buf = calloc(length, 4); 2460 if (buf == NULL) { 2461 return BadAlloc; 2462 } 2463 memcpy(buf, ptr, n); 2464 2465 if (client->swapped) { 2466 __GLX_DECLARE_SWAP_VARIABLES; 2467 __GLX_SWAP_SHORT(&reply.sequenceNumber); 2468 __GLX_SWAP_INT(&reply.length); 2469 __GLX_SWAP_INT(&reply.n); 2470 WriteToClient(client, sz_xGLXQueryServerStringReply, &reply); 2471 /** no swap is needed for an array of chars **/ 2472 /* __GLX_SWAP_INT_ARRAY((int *)buf, length); */ 2473 WriteToClient(client, length << 2, buf); 2474 } 2475 else { 2476 WriteToClient(client, sz_xGLXQueryServerStringReply, &reply); 2477 WriteToClient(client, (int) (length << 2), buf); 2478 } 2479 2480 free(buf); 2481 return Success; 2482} 2483 2484int 2485__glXDisp_ClientInfo(__GLXclientState * cl, GLbyte * pc) 2486{ 2487 ClientPtr client = cl->client; 2488 xGLXClientInfoReq *req = (xGLXClientInfoReq *) pc; 2489 const char *buf; 2490 2491 REQUEST_AT_LEAST_SIZE(xGLXClientInfoReq); 2492 2493 buf = (const char *) (req + 1); 2494 if (!memchr(buf, 0, (client->req_len << 2) - sizeof(xGLXClientInfoReq))) 2495 return BadLength; 2496 2497 free(cl->GLClientextensions); 2498 cl->GLClientextensions = strdup(buf); 2499 2500 return Success; 2501} 2502 2503#include <GL/glxtokens.h> 2504 2505void 2506__glXsendSwapEvent(__GLXdrawable *drawable, int type, CARD64 ust, 2507 CARD64 msc, CARD32 sbc) 2508{ 2509 ClientPtr client = clients[CLIENT_ID(drawable->drawId)]; 2510 2511 xGLXBufferSwapComplete2 wire = { 2512 .type = __glXEventBase + GLX_BufferSwapComplete 2513 }; 2514 2515 if (!client) 2516 return; 2517 2518 if (!(drawable->eventMask & GLX_BUFFER_SWAP_COMPLETE_INTEL_MASK)) 2519 return; 2520 2521 wire.event_type = type; 2522 wire.drawable = drawable->drawId; 2523 wire.ust_hi = ust >> 32; 2524 wire.ust_lo = ust & 0xffffffff; 2525 wire.msc_hi = msc >> 32; 2526 wire.msc_lo = msc & 0xffffffff; 2527 wire.sbc = sbc; 2528 2529 WriteEventsToClient(client, 1, (xEvent *) &wire); 2530} 2531 2532#if PRESENT 2533static void 2534__glXpresentCompleteNotify(WindowPtr window, CARD8 present_kind, CARD8 present_mode, 2535 CARD32 serial, uint64_t ust, uint64_t msc) 2536{ 2537 __GLXdrawable *drawable; 2538 int glx_type; 2539 int rc; 2540 2541 if (present_kind != PresentCompleteKindPixmap) 2542 return; 2543 2544 rc = dixLookupResourceByType((void **) &drawable, window->drawable.id, 2545 __glXDrawableRes, serverClient, DixGetAttrAccess); 2546 2547 if (rc != Success) 2548 return; 2549 2550 if (present_mode == PresentCompleteModeFlip) 2551 glx_type = GLX_FLIP_COMPLETE_INTEL; 2552 else 2553 glx_type = GLX_BLIT_COMPLETE_INTEL; 2554 2555 __glXsendSwapEvent(drawable, glx_type, ust, msc, serial); 2556} 2557 2558#include <present.h> 2559 2560void 2561__glXregisterPresentCompleteNotify(void) 2562{ 2563 present_register_complete_notify(__glXpresentCompleteNotify); 2564} 2565#endif 2566